你手上有一张或几张卡,想用 vLLM 起 DeepSeek 3.2 的服务,结果第一步就卡住:权重从哪拿、显存到底够不够、并行度填几、拉起来报错该看哪一行日志。这篇不给万能命令,而是把「先算什么、再改什么、出问题按什么顺序查」这条链路讲清楚,让你在自己的机器上把参数试出来,而不是照抄别人的配置。
你手上有一张或几张卡,想用 vLLM 把 DeepSeek 3.2 起成一个能对外调用的服务,结果第一步就卡住:权重从哪拿、显存到底够不够、并行度填几、拉起来报错该看哪一行日志。这篇不给万能命令,而是把「先算什么、再改什么、出问题按什么顺序查」这条链路讲清楚,让你在自己的机器上把参数试出来,而不是照抄别人的配置。
先明确一件事:vLLM 本身只是个推理引擎,它不负责帮你选模型、也不负责帮你省钱。模型选哪一档、量化到什么程度、上下文开到多长,都是你先定下来的输入。引擎只认你给它的权重和参数,给错了它就在加载阶段直接报错,跟你的卡好不好没关系。
动手之前先把四件事定下来
很多人一上来就复制一条启动命令,结果卡在「权重加载失败」上折腾半天。这四件事没定,后面的参数全是碰运气,改对改错都不知道为什么。
- 明确你要的是哪一类权重:官方仓库的原始权重、社区量化版、还是已经合并好的格式,这决定后面能不能被 vLLM 直接加载
- 确认卡的型号、单卡显存、卡数与卡间互联方式,这决定张量并行怎么切,也决定多机方案是不是必要
- 确认 vLLM 版本与权重的兼容关系,版本对不上就是加载阶段直接报错,跟显存无关,别往显存方向查
- 想清楚服务形态:单机单卡试验、单机多卡、还是多机多卡,三种的启动参数写法完全不同,脚本不能混用
判断标准很简单:如果你说不清自己用的是哪一类权重、几张什么卡、跑哪个 vLLM 版本,那就先别启动,回去把这四项写在纸上。这四项写不出来,说明你还没准备好部署,只是准备好了试错。
显存和并发:先算账再开机
显存估算不是玄学,拆成三段就清楚了:权重占用、KV Cache、框架自身开销。权重部分用参数量乘以精度字节数粗略估,量化档位越低占用越小;KV Cache 跟上下文长度和并发数成正比;框架开销留个固定余量。
| 显存去向 | 受什么影响 | 估错了会怎样 |
|---|---|---|
| 权重占用 | 参数量、量化精度 | 加载阶段直接 OOM,起不来 |
| KV Cache | 最大上下文长度、并发数 | 短请求没事,长输入或高并发才崩 |
| 框架开销 | 批处理大小、调度策略 | 跑一段时间才 OOM,最难定位 |
难点在第二段和第三段:它们不是启动时一次性分配完的,而是随着请求堆上来的。所以你会遇到「刚起来正常、压测十分钟挂了」这种情况,根因往往就是 KV Cache 估得太乐观。显存利用率参数不是越高越好,留一点余量给碎片和峰值,不然问题只在高负载时暴露。
KV Cache 的估算公式本身不复杂,复杂的是你对自己并发目标的判断。先问自己:这个服务同时会有多少个请求在跑、单个请求最长会输入多少 token。这两个数如果答不上来,就先按保守值配,别按理想值配。
启动参数怎么配:一次只改一个变量
启动参数调优最忌讳一次改三个。并行度、最大上下文、显存利用率同时动,出问题时你根本不知道是哪个引起的,只能重来一遍。正确做法是先跑通最小可用配置,再按固定顺序往上加。
- 第一步:最小可用配置把并行度、最大上下文、显存利用率都压到保守值,确认服务能起来、能返回结果。这一步不追求性能,只追求「能跑」。
- 第二步:定并行度确认模型能切得下、卡数切分方式与服务端口三者对齐。并行度不对,要么加载失败,要么跑起来显存分配不均。
- 第三步:调最大上下文在显存扛得住的前提下往上加,加到一个长输入会 OOM 的位置就往回退一档,记下这个位置。
- 第四步:调并发与批处理最后才动批处理和调度相关参数,每次只改一个,记录改动前后的吞吐与延迟变化。
参数含义不要靠记忆,社区里同名参数的默认值经常不一样,换一个 vLLM 版本可能就变了。到 /models/deploy 对照当时的说明看,再结合你机器的实际情况填。记录每次改动,是因为过两个月你自己也会忘记为什么当初填了这个值。
服务起来之后先验四件事
服务起得来不代表能用。日志里没有报错,接口也返回了,但你不知道它返回得对不对、快不快、并发扛不扛得住。这四件事按顺序验一遍,比直接上业务请求稳。
- 接口通不通:发一条最短的请求,确认返回结构与字段符合预期,别只看有没有报错
- 延迟基线:用 /tools/speed-test 量一遍你的首字延迟和出字速度,作为之后调优的参照,没有基线就没有「变快了」这个说法
- 并发是否真的生效:并发压上去看吞吐有没有涨,没涨说明瓶颈在别的地方,不是批处理没开
- 长上下文能不能扛:单独测接近上限的输入,很多问题只在长输入时才暴露,短请求永远测不出来
这四步里,最容易跳过的是延迟基线。没有基线,你后面换量化档位、调批处理,全靠主观感觉说「好像是快了」。有个参照数字,改动到底有没有效果一眼就看得出来。
还有一个容易忽略的点:验证要用贴近你真实业务的输入长度分布。如果线上是长文档摘要,你拿一句「你好」测通了,等于没测。找几条真实长度的请求存成测试集,每次改配置都跑一遍。
起不来时按这个顺序排查
排查顺序比排查技巧重要。顺序错了,你会在显存和并行之间来回怀疑,最后发现是权重格式不识别。按下面这个层次往下走,每层排除掉再进下一层。
- 第一层:权重问题看是不是格式不识别、分片对不上、字段缺失。这类报错在加载阶段就出现,日志第一行通常就点明了。
- 第二层:显存问题调低最大上下文或显存利用率,如果能起来,说明之前的估算偏乐观,回去重新算账。
- 第三层:并行配置问题检查卡数、切分方式与服务端口三者是否对齐,多机场景还要看卡间通信是否正常。
- 第四层:性能问题能跑但慢,这时候才轮到批处理、调度和量化档位。顺序不能提前,否则你在优化一个还没跑通的东西。
还有一个判断技巧:如果报错发生在启动后几秒内,多半是配置或权重问题;如果服务正常跑了一段时间才挂,多半是显存或并发相关的运行时问题。按「报错发生的时间点」先分类,再进对应的层次排查,能省不少来回。
量化档位怎么选:先够用再谈快
显存吃紧时,降量化档位是最直接的手段,代价是部分任务上的表现会变,尤其是需要精确推理的活。问题是这个「变」到底能不能接受,别人说了不算,得用你自己的任务集去比。
- 判断是否可接受,要用你自己的任务集去比,不要只看别人的主观感受,别人的任务和你的不是一回事
- 同一台机器上量化版和原始版可以并存测试,用同一批问题跑一遍对比输出差异
- 注意许可证:权重能不能商用、量化后能不能再分发,是两件事,别默认一样
- 量化不是免费午餐,省下的显存换来的可能是某些任务上的稳定性下降,值不值得要按任务判断
什么情况下不适用:如果你的任务对输出准确性要求很高,或者涉及需要严格推理的场景,那量化档位就不是省钱手段,而是风险来源。这种情况宁可上更多卡,也别硬压量化。反过来,如果只是做分类、抽取这类容错高的活,量化档位降一档完全可行。
跑起来之后:监控、升级和退路
服务上线只是开始。跑起来之后要盯的指标不多,但只看平均值一定会漏掉长尾问题。单请求耗时分布比平均延迟有用得多,因为用户感知到的是最慢的那几个请求。
- 盯三个指标:显存占用是否稳定、请求排队长度、单请求耗时分布,只看平均值会漏掉长尾
- 升级 vLLM 或换权重版本前,先在旁路环境验证同一批请求,确认结果和性能都没退化
- 留一条退路:老版本的启动命令和权重保留一段时间,出问题能立刻切回去
- 把启动命令写成脚本并注明每个参数为什么这么填,否则过两个月你自己也看不懂
退路这一条很多人不当回事,直到升级后发现某个长输入场景挂了,才发现旧权重已经删了、旧命令也找不到了。保留旧版本的成本很低,回滚不了的成本很高。
常见问题
vLLM 部署 DeepSeek 3.2 和用 Ollama 部署有什么区别?
主要差在服务形态和并发能力。Ollama 上手快、适合单机自用,vLLM 面向的是要被多个请求同时打的推理服务,参数多、调优空间大,但配置门槛也高。如果只是自己一个人用,先想清楚是不是真需要 vLLM,可到 /inference 看开源模型的服务侧情况再决定。
显存到底要多少才够?
没有固定答案,取决于权重量化档位、你要开的最大上下文和并发数三者。正确做法是先确定这三个量,再算权重占用加 KV Cache 加框架开销。到 /models/deploy 和 /compute/sizing 按你的卡型把数跑一遍,比自己拍脑袋靠谱。
启动就报错,先看哪里?
先分清是加载阶段还是服务阶段报错。加载阶段的错多半是权重格式或版本不兼容,服务阶段的错多半是显存或并行配置。日志第一行通常就写明类型,别只盯着最后一行堆栈。反复起不来时,把所有参数压到最保守再试一次。
并发上不去是为什么?
常见原因是最大上下文开得太大把 KV Cache 吃满,导致无法接收更多并发;也可能是显存利用率设得太满,没有余量。先降上下文测一遍,再看批处理相关参数。吞吐是否真的随并发增长,要用固定请求压测,不能凭感觉。