你大概遇到过这种局面:模型权重下好了,服务也起来了,但一上并发就 OOM,或者微调出来的 LoRA 不知道怎么塞回 vLLM 里跑。这篇按「先算再起、先起再调、先调再合」的顺序,把 vLLM 部署 DeepSeek 加微调的每一步拆成可执行动作,数字类的东西一律让你去站内对应页面按当时的口径核。
你大概遇到过这种局面:模型权重下好了,服务也起来了,但一上并发就 OOM,或者微调出来的 LoRA 不知道怎么塞回 vLLM 里跑。这篇按「先算再起、先起再调、先调再合」的顺序,把 vLLM 部署 DeepSeek 加微调的每一步拆成可执行动作。
数字类的东西一律让你去站内对应页面按当时的口径核,因为显卡型号、量化实现、模型分支都在变,写死一个数只会误导下一个看的人。下面四节分别对应:起服务前算账、服务起来后验证、微调后权重怎么回归、上线前怎么卡关。
起服务之前先把账算清楚
显存要从「模型参数量、量化档位、上下文长度」三个变量一起倒推,权重占用往往只占一半,KV cache 和并发数才是翻车主因。先到 /models/deploy 按当时的模型规格算一遍,再决定开几张卡,别靠试错,试错的成本是一整晚。
| 变量 | 为什么它决定显存 | 在哪核对 |
|---|---|---|
| 参数量+量化档位 | 决定权重本身的常驻占用 | /models/deploy |
| 上下文长度 | 决定单请求 KV cache 占用,近似线性 | /ai-dict/category/basics |
| 并发目标 | 决定 KV cache 总量能否放下 | /compute/sizing |
| 张量并行度 | 决定权重如何切分到多卡 | /ai-dict/category/infra |
量化档位不是越低越好:低比特省显存但会掉质量,代码任务和长文任务对量化的敏感度不一样,具体精度损失口径参考 /ai-dict/category/tech 里对量化原理的说明。判断标准很简单——如果你的任务里有大量精确符号、长程依赖或严格格式输出,就别为了省显存硬压档位。
max_model_len 开多大要跟你的实际最长输入对齐,不是越大越好。它直接乘进每个请求的 KV 占用里,开大一倍,单卡能扛的并发大约就掉一半。先统计自己业务的 P99 输入长度,再往上留一点余量就行。
- 先定并发目标,再定卡数:一张卡能扛多少并发取决于上下文长度而非参数量,用 /compute/sizing 的思路先出个数量级
- 把最长输入长度、期望并发数、可接受的输出速度三个数写在一张纸上,缺一个就别开服务
- 量化档位与上下文长度存在取舍,两个都拉满时先看显存够不够,不够就优先砍上下文
- 显存估算留出安全余量,别把卡算到只剩个位数百分比空闲
把服务跑起来并验证它是真的在干活
vLLM 起服务的顺序是固定的:装环境 → 挂载权重 → 设置张量并行与端口 → 用 OpenAI 兼容接口发一条最小请求确认通。每一步失败都有典型报错,先读报错再改参数,别一上来就换版本、换卡、换量化。
- 确认模型目录结构权重加载失败多数是模型目录结构或权重版本不匹配,不是环境问题。先在 /models 核对你要跑的模型页的目录约定,再排查。
- 起最小配置先单卡、小上下文、不带并行把服务拉起来,确认能返回结果,再往上加张量并行和上下文。
- 发最小请求用 OpenAI 兼容接口发一条最短的请求,确认返回内容和格式都对,这一步通了才算服务真的在干活。
- 量基线用 /tools/speed-test 量出首 token 延迟和输出速度作为基线,后续所有调参都跟这个基线比,没有基线就没法判断优化有没有效。
张量分片和 CPU offload 是两套不同的救济手段:前者是把权重切到多卡换吞吐和容量,后者是拿 CPU 内存换显存、代价是速度。什么情况下用哪个、什么时候两个都别用,去 /ai-dict/category/infra 把概念对齐再动手,别把两个混在一起调。
验证服务不能只看「能返回」。要同时看首 token 延迟、输出速度、以及连续压几分钟后显存有没有缓慢上涨。最后一条是判断有没有泄漏的最直接信号,压测时间太短看不出来。
微调完怎么把权重并回推理服务
先分清你要的是微调还是 RAG。只有「模型说话方式、固定输出格式、领域术语习惯」这类需求才值得微调,事实类问题交给检索。两条路的分界和各自的服务商、方案对比见 /stacks/fine-tuning,先看完再决定花不花这个训练成本。
LoRA 训练阶段要盯的三个量:数据格式一致性、显存峰值、验证集是否真的在降。微调的显存估算口径走 /compute/finetune,别拿推理的显存估算直接套训练,两者不是一回事。
| 合并方式 | 适用场景 | 代价 |
|---|---|---|
| 合并成完整权重 | 推理时不想带额外依赖,追求最简部署 | 多一份存储,每次换 adapter 要重并 |
| 让 vLLM 直接加载 LoRA | 多套 adapter 频繁切换、A/B 对比 | 依赖 vLLM 的 LoRA 支持版本 |
| 多 adapter 共存 | 一个底座服务多个业务方 | 显存同时驻留多份 adapter |
训练完的 adapter 不能直接给 vLLM 当模型用,得先合并成完整权重或者让 vLLM 加载 LoRA,两条路的适用场景和代价见上表,具体合并流程参考 /stacks/fine-tuning 里的步骤说明。
- 合并后的权重务必用同一批 prompt 跟原模型做 A/B 对比
- 看的是「有没有变差」而不是「有没有变好」:先确认通用能力没退化,再看目标任务有没有提升
- 验收标准在上线前就写死,别训完了再临时想怎么算通过
上线前的检查清单与常见坑
- 核显存余量压测跑满目标并发后,确认显存仍有安全余量,没有余量说明配置卡在悬崖边。
- 设并发限流按估算的并发上限设限流,宁可排队也不要让服务因为过载整个挂掉。
- 配超时与重试长输出请求的超时要单独放宽,重试要防止放大流量,这两项要一起看。
- 查日志里的实际 token 数日志里能不能看到实际输入输出 token 数,看不到就没法做成本估算和容量规划。
- 估成本按当时的单价去站内对应页面核一遍,别用记忆里的旧数字做预算。
许可证是硬门槛:不同 DeepSeek 权重版本的商用边界不一样,上线前对照 /models 的模型页确认,别等下架了才发现。这个坑踩一次就够,检查只要几分钟。
服务监控看的是尾延迟不是平均延迟。平均延迟好看但尾延迟炸裂的配置,在真实流量下一样不可用。参考 /ai-status 这类盯服务状态的思路,建立你自己的告警线:显存、尾延迟、错误率三条,哪条先到阈值就告警。
回滚预案要提前写好:权重、量化版本、服务参数三样都留一份上一版。出问题十分钟能切回去,比现场排查靠谱得多。回滚脚本和上一版镜像要在上线前就演练一次,没演练过的预案等于没有。
下一步把你自己的并发目标、最长输入长度、量化档位三个数代入站内的容量估算页,得出一个配置草稿,再回来对照这篇的检查清单逐条打勾。→常见问题
vLLM 部署 DeepSeek 和用 Ollama 跑有什么区别?
Ollama 胜在装完就能用、适合单人和本地调试;vLLM 胜在并发吞吐和 OpenAI 兼容的批量服务能力,适合多人共用或对外提供接口。如果你的场景是几个人偶尔问几句,Ollama 更省事;一旦要扛并发、要算 token 成本,就得换 vLLM,两个框架的选型思路可以对照站内推理框架类页面看。
微调 DeepSeek 要多少显存,是不是必须多卡?
取决于你是全参微调还是 LoRA。LoRA 冻结主干只训低秩矩阵,显存门槛低很多,单卡大显存有时能跑;全参微调基本要上多卡。另外还要留出激活值和优化器状态的空间,不是权重能装下就行。具体额度按你的参数量去 /compute/finetune 按当时口径估一遍,别照搬别人的配置。
vLLM 起服务报错该从哪查起?
固定排查顺序:先看是不是权重路径或目录结构不对,再看模型权重版本和框架版本是否匹配,然后看显存是不是在加载阶段就爆了,最后才怀疑参数配置。绝大多数「起不来」发生在第一步和第二步,跟推理参数无关。把完整报错和你的启动命令一起贴出来排查最快。