vLLM Recipes 不是一个独立模型,也不是某个固定版本的功能开关,而是一组围绕 vLLM 的部署与优化配方。我第一次看到这个词的时候也在想:它到底是一份官方文档,还是社区里流传的实战合集?跑过几轮之后我的理解是,Recipes 更像把环境准备、启动参数、模型格式、并发设置、故障排查这些步骤整理成可复用的模板,让你在换模型、换机器、换任务时不用每次从头踩一遍。这篇文章就按实际部署顺序拆一遍:先说清 vLLM 能解决什么问题、适合什么人,再给环境准备和启动命令,接着讲 max-num-seqs、--enforce-eager、--reasoning-parser 这些高频参数的作用,最后补充 GGUF、显存爆掉、Embedding/Reranker、Windows 和昇腾环境里的常见问题。如果你正准备用 vLLM 部署大模型,或者已经在部署但被参数和报错卡住,这篇可以直接照着试。
1. 先搞清楚 vLLM Recipes 是什么,再开始搭环境
1.1 vLLM Recipes 解决的核心问题
vLLM 本身是一个面向大语言模型推理的服务框架,核心能力是通过 PagedAttention 这类机制降低 KV cache 对显存的浪费,提升吞吐。Recipes 是“配方”,它不是模型,也不是某一个具体工具软件,而是一套可复制的操作模板。
实战中最大的痛点往往是:模型能加载,但并发一高就失败;换一个模型后参数不知道在哪里改;容器里共享内存不够;显存爆掉不知道先动哪个参数。vLLM Recipes 想解决的,就是把这些零散问题变成一步步能执行的检查清单。简单说,它不负责教你训练模型,而是负责让你把已经训练好的模型稳定地跑成服务。
我一般会先看一份 Recipe 里有没有回答三个问题:在什么环境下跑、用哪些启动参数、拿到结果后怎么判断正常。如果这三个点不清晰,那这份配方大概率只是写了几个命令,后面遇到问题还是要猜。
1.2 这套配方适合谁,不适合谁
适合用 vLLM Recipes 的人有这么几类:
- 需要快速起一个 OpenAI 风格接口的人。
- 在本地或云 GPU 上部署开源模型的人。
- 在低显存机器上试小模型的人。
- 要做批量推理,或者要把模型接入上层业务的人。
- 想知道 Docker、WSL2、Ubuntu、昇腾这些环境差异的人。
不适合的场景也比较明确。如果你主要做模型训练,那 vLLM 不是你的核心工具;如果完全不能用 GPU,那 vLLM 的收益会大打折扣;如果只是调用别人已经封装好的 API,也不需要自己部署。还有一类是边缘设备或极小显存设备,vLLM 不是最优选择,这种场景更适合轻量推理框架。
1.3 开始之前要确认的硬件和软件底线
部署前先把环境检查清楚。很多报错不是代码问题,是前置条件没满足。
| 检查项 | 最低建议 | 为什么重要 |
|---|---|---|
| GPU | NVIDIA 显卡,显存 8GB 起步 | 模型权重和 KV cache 都占显存,显存决定模型规模 |
| 系统 | Linux 优先,其次 WSL2 | vLLM 的预编译包和 CUDA 依赖在 Linux 上最完整 |
| 内存 | 16GB 以上更稳 | 加载模型和 tokenizer 时内存不足会先于显存报错 |
| 磁盘 | 7B 模型约需 15GB,13B 约 26GB | 下载和解压模型都要空间,建议预留两倍 |
| 驱动与 CUDA | 驱动版本要支持对应 CUDA 环境 | 版本不匹配会在 import 或启动阶段直接报错 |
如果你要跑 27B 这种更大的模型,常见情况需要更高显存,比如两张 24GB 卡或一张 48GB 卡。只有单卡 24GB 时,基本要考虑量化模型或更短的上下文长度。先想清楚这些,再进入下面的部署流程,会少踩很多坑。
2. 环境准备:Linux、Docker、Windows 和昇腾的取舍
2.1 为什么生产环境优先选 Linux
vLLM 对 Linux 的适配最完整,很多预编译包只发布 Linux 版本。Windows 原生安装不是绝对不行,但往往要自己编译,容易在 CUDA 工具链、MSVC 版本和 Python 环境上绕圈。如果只是学习,用 WSL2 或 Docker Desktop 也能跑;但如果是长期提供服务,建议直接用 Ubuntu 服务器。
判断标准很简单:启动一个服务能不能用少于十行命令完成,重启后会不会依赖图形界面。Linux 服务器配合 systemd 或容器编排,管理起来会清晰很多。vLLM 的日志输出、进程停止、资源监控也都更适合命令行环境。
2.2 Ubuntu + Docker 部署 vLLM 的推荐步骤
使用 Docker 部署时,模型目录和输出目录最好都挂在宿主机上。这样模型文件不用每次都复制进容器,日志和输出结果也方便持久化。一个典型的启动命令如下:
docker pull vllm/vllm-openai:latest docker run --gpus all \ --ipc=host \ --shm-size=8g \ -v /models:/models \ -p 8000:8000 \ vllm/vllm-openai:latest \ --model /models/your-model-dir \ --task generate \ --max-model-len 8192 \ --gpu-memory-utilization 0.85这里的镜像名和 tag 是示例,实际版本要以你拉到的镜像和模型要求为准。--shm-size一定要给足。vLLM 在并发场景里会用到共享内存,容器默认的 /dev/shm 常常只有 64MB,几路并发请求一上来就容易报 “No space left on device”。--ipc=host可以让容器和宿主机共享 IPC 空间,对多进程通信有帮助。
注意:容器里出现 “No space left on device” 时,先看 /dev/shm 是不是太小,不要急着扩磁盘。
启动后建议先看日志,确认模型加载完成、服务监听在 8000 端口。再用一条 curl 请求验证,而不是直接开并发。
2.3 Windows 10 能不能原生跑 vLLM
能,但不推荐。Windows 原生跑 vLLM 不是完全不可能,前提是 CUDA、PyTorch、Visual Studio 编译环境、Python 版本全部对齐,这通常要花不少时间。
更顺手的方式是在 Windows 10 上用 Docker Desktop + WSL2。这样底层的 Linux 内核、CUDA 驱动都走 WSL2,vLLM 的安装路径和 Linux 服务器基本一致,踩坑成本低很多。另一种更省事的思路是:在 Linux 服务器上部署 vLLM,Windows 只做客户端,通过 API 调用。对大多数业务形态来说,这个方案最稳定,也不会被 Windows 原生编译问题拖住。
2.4 昇腾 910B-A2 上跑 Embedding/Reranker 的排查思路
“昇腾 910B-A2 服务器上不能通过 vLLM 启动 embedding 向量和 reranker 模型”这个问题,很多人问过。先说结论:vLLM 原生最擅长的是文本生成,对 embedding 和 rerank 的支持取决于你使用的分支、扩展版本和任务参数。
遇到启动失败,不要先怀疑硬件故障,按下面顺序排查:
- 确认当前 vLLM 是否支持
--task embedding或--task rerank这类任务参数。 - 检查容器里是否安装了对应昇腾后端的适配包,以及它是否匹配当前 vLLM 版本。
- 看具体报错是模型加载阶段失败,还是任务类型初始化失败。这两个问题排查方向完全不同。
- 如果当前版本确实不支持,就把服务拆开:embedding 和 reranker 用专门框架部署,生成模型继续用 vLLM。
embedding 和 rerank 是向量检索链路中的一环,它们对批处理方式、推理缓存和生成模型都不一样,硬合在一起反而容易互相干扰。实际项目里,我更倾向于把这类任务拆成独立服务,哪怕只是为了让后续扩容和压测更清晰。
3. 启动模型前必须搞懂的参数:max-num-seqs、enforce-eager、reasoning-parser
3.1 --max-num-seqs 控制什么
很多人把--max-num-seqs理解成“最大请求数”,其实它控制的是同一时刻最多排进调度器的序列数量。可以简单理解为“模型内部最多同时处理多少条 prompt 轨迹”。
它和--max-model-len不是一回事:--max-model-len限制单条序列的最大长度,--max-num-seqs限制并行的序列数量。调大这个值,吞吐通常会上去,但显存和调度压力也会同步增加。
如果你在做批量推理时发现显存不够,先把--max-num-seqs降到 4 或 1 再观察,而不是一上来就换小模型。如果模型本身很吃显存,保持 1 到 2 更稳。
注意:不要一上来就把 max-num-seqs 拉满,先用 4 验证稳定性和显存占用,再逐步往上加。
3.2 --enforce-eager 的影响
vLLM 默认会通过 CUDA Graph 捕获计算图来降低调度开销。--enforce-eager是把这个优化关掉,强制所有算子走 eager 模式。
影响有三点:
- 首次请求的编译时间变短,因为不用等待 CUDA Graph 捕获。
- 显存占用会有所下降,适合显存比较紧的环境。
- 代价是解码路径缺少图优化,可能带来更高的单 token 延迟和吞吐下降。
所以不要看到“能降显存”就默认要开。生产环境如果显存刚好够用,先不开--enforce-eager,等确认了吞吐指标再决定。有些容器或远端环境 CUDA Graph 捕获会失败,此时加上这个参数可以减少启动阶段的问题。它更像一个兼容开关,不是通用加速器。
3.3 --reasoning-parser 解决什么问题
--reasoning-parser是给带推理能力的模型准备的。比如模型输出里有一段思维推导,再给出最终答案,这个参数能帮助把推理段落从最终回答中解析出来。
注意,它解决的是输出解析问题,不是提升模型推理能力。如果模型本身不输出结构化推理文本,或者你的应用不关心推理过程,不需要开这个参数。开启后如果输出格式变了,先确认你的 prompt 和 chat template 是否匹配,不要怪模型变笨了。
3.4 显存不够时的第一排查顺序
加载 9B 级别模型爆显存,或者换更大上下文后 OOM,优先按这个顺序排查:
- 看
nvidia-smi,确认显存是被权重占掉,还是被 KV cache 占掉。 - 降低
--max-model-len,例如从 8192 降到 4096。显存不够时这是最直接的一步。 - 降低
--max-num-seqs,限制并发。 - 调整
--gpu-memory-utilization,比如 0.9 改成 0.8,给 KV cache 留出余量。 - 再考虑开
--enforce-eager。 - 最后才换量化模型。
这个顺序的原因很简单:前四步是在同样的模型权重下减少动态内存分配,不会改变输出质量。换量化模型会改变精度,应该放在最后。
4. 模型格式和量化:GGUF、safetensors、9B 模型爆显存
4.1 vLLM 加载 GGUF 的真实情况
vLLM 对 GGUF 的支持是有的,但没有 safetensors 那么完整。很多模型发布时会同时给 safetensors 和 GGUF 两种格式。
如果你的 vLLM 版本确认支持用--load-format gguf加载,可以试:
vllm serve /models/model.gguf --load-format gguf --max-model-len 4096但要注意:GGUF 主要围绕 llama.cpp 系列推理工具设计,vLLM 的加载路径在算子支持、量化参数解析和历史版本上可能有差异。如果你遇到“能加载但输出不正确”或者“加载到一半报格式错误”,先确认模型卡上推荐的加载方式和当前 vLLM 版本。
正式项目里我更建议优先用 safetensors 格式,省去格式兼容带来的额外变量。真需要 GGUF 时,也可以考虑直接用 llama.cpp 的服务端,不要在一棵树上吊死。
4.2 加载 9B 级别模型爆显存时先做什么
一个 9B 模型如果用 BF16 加载,权重大约需要 18GB 显存。这还没算 KV cache、激活值和调度器开销。所以你在 24GB 显卡上跑,感觉“刚好能跑”其实已经很紧。
此时如果--max-model-len设置成 8192,它会给每条序列预留较大上下文空间,几批请求后就会爆。第一步先把上下文长度降下来,比如从 8192 降到 4096 或 2048,再跑一轮测试。第二步把--max-num-seqs改成 1 或 2,观察显存占用。
如果这样能跑,说明你只需要在质量、速度和显存之间重新取平衡,不一定要换模型。如果降到 2048 仍然爆,再考虑量化。
4.3 量化方案怎么选
常见量化方案有 AWQ、GPTQ、FP8,也有少量 GGUF 量化。它们的取舍可以这样看:
| 格式 | 适用场景 | 注意事项 |
|---|---|---|
| BF16 | 显存充裕,追求精度 | 占用最大 |
| FP8 | 较新硬件,速度与精度平衡 | 需要硬件支持 |
| AWQ | 低显存部署,通用性好 | 需要准备量化权重目录 |
| GPTQ | 低显存部署,社区模型多 | 不同 step 和 group size 效果有差异 |
选量化模型时,记得同时下载对应的 tokenizer 和配置文件。很多启动失败不是推理引擎问题,而是模型目录不完整或格式不统一。如果原始材料里没有明确说某个量化版本适合你的任务,先用小输入验证输出质量,再决定是否迁移。
5. 框架定位:vLLM 和 SGLang、LangChain、PyTorch 不是同一层
5.1 vLLM 和 SGLang 的对比点
SGLang 和 vLLM 都是大模型推理服务框架,定位接近,但偏好不同。
vLLM 生态更成熟,资料多,社区默认支持广。SGLang 在某些场景下对长文本、结构化输出和并行采样做了专门优化,所以在一些新模型发布时,会看到“推荐用 SGLang”的说法。
实际选型时,不要只信宣传。用同一个模型、同一批请求、同样显存限制,分别在两个框架上跑,对比启动时间、吞吐、延迟和能不能稳定跑完任务。如果只是单机部署一个 7B 或 9B 模型,两个框架都能应付,差异主要在你的任务负载和模型兼容性上。
我的建议是:先把你常用的输入样例跑通,再决定要不要迁移。不要因为某个新功能就立刻切换框架,稳定性更重要。
5.2 LangChain、vLLM、PyTorch 分别解决什么问题
经常有人问“LangChain、vLLM 跟 PyTorch 是一个类型吗?”它们不是同层的东西。
PyTorch 是深度学习计算框架,负责算子、自动求导和模型训练。vLLM 是基于 PyTorch 的推理服务框架,负责把训练好的模型高效地部署成 API。LangChain 是应用层编排工具,负责把模型调用、提示词、工具调用和外部数据串成流程。
可以简单类比:PyTorch 是发动机,vLLM 是整车,LangChain 是导航和出行计划。用 LangChain 接 vLLM,通常应该调用 vLLM 暴露的 OpenAI 兼容 API,而不是在 LangChain 内部直接操作 vLLM 的底层引擎。
6. 从单条请求到生产服务:Playground、API 和验证
6.1 用 Playground 或者 /docs 验证
很多仓库会放一个叫 Playground 的前端页面,但 vLLM 本身最稳的验证通道不是某个固定 UI。启动服务后,打开http://127.0.0.1:8000/docs会看到 Swagger 文档,可以直接在页面里发请求。
更简单的做法是用 curl 检查:
curl http://127.0.0.1:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "/models/your-model-dir", "messages": [{"role": "user", "content": "你好"}], "max_tokens": 128 }'返回的 JSON 里如果有choices字段,基本说明服务通了。如果请求卡住或者返回空,先看服务日志,再看输入格式,不要急着改模型参数。
很多“服务不通”的问题其实是模型目录不对、端口没监听、或者请求里 model 名称和启动参数不一致。先把这些基础