
最近把 vLLM 部署 DeepSeek 和 Qwen 系列模型做了一轮彻底排查从启动命令到显存报错再到并发压测算是把“vllm 模型启动”这个看似简单但坑不少的操作捋顺了。这篇文章不打算讲太多理论重点是把启动模型的完整路径、关键参数、报错排查和性能调优经验一次性写清楚。无论是刚接触大模型推理的新手还是已经在用 Ollama 或 LM Studio 但想换 vLLM 提速的玩家这篇都能给你一份可直接抄作业的参考。1. 为什么选择 vLLM 启动模型1.1 从“能跑”到“跑得快”的差距本地跑大模型很多人第一步是 Ollama因为它一条命令就能拉模型、起服务。但真正做并发推理、接业务请求、跑长上下文时Ollama 的吞吐量和显存利用率往往不够看。vLLM 的核心优势是 PagedAttention 显存管理它把 KV Cache 切成小块按需分配不像传统推理那样预分配整块显存。结果就是同样的显存vLLM 能塞下更大模型、更高并发推理吞吐量通常能比原生 Transformers 实现快 2 到 4 倍。我最初在 4090 上跑 Qwen2.5-7B原版 HuggingFace 代码单并发都偶尔卡顿换成 vLLM 之后并发 8 路照样稳定输出。这个差距不是玄学是显存调度机制决定的。如果你的使用场景是个人单机、偶尔聊聊天Ollama 足够好但如果你想启动一个模型服务让多个客户端同时请求那 vLLM 才是正路。1.2 与 SGLang、LM Studio 的定位差异热词里同时出现了 vLLM 和 SGLang这俩经常被拿来对比。SGLang 在复杂多轮对话和结构化输出上做了很多优化RadixAttention 对 KV Cache 的复用很激进某些场景下吞吐更高。但 vLLM 的优势在于生态成熟OpenAI 兼容接口最完善业界部署 Mixtral、Llama、DeepSeek 时默认首选就是它问题排查资料也最多新手踩坑时更容易找到答案。LM Studio 则是典型的 GUI 工具适合不想写代码的人。它在 Windows 上很友好但本质上还是调用了 llama.cpp 系列后端跟 vLLM 的高并发服务化不是一个赛道。如果只是本地跑个 DemoLM Studio 很清楚如果要做 API 服务供程序调用vLLM 更适合。启动模型的姿势决定了你后续是“够用”还是“抗造”。2. 环境准备与版本选型2.1 CUDA 12.8 下的 vLLM 安装热词里出现了 “cuda128 vllm”这也验证了当前主流卡都在围绕 Blackwell 架构和 CUDA 12.8 适配。vLLM 对 CUDA 版本比较敏感编译时依赖torch的后端。我的建议是直接按官方方式安装不要自己源码编译除非你想定制。以 CUDA 12.8 为例先确认驱动支持nvidia-smi显示的 Driver Version 需要大于 530否则 CUDA 12.8 跑不起来。然后创建 Python 3.10 或 3.11 环境执行pip install --upgrade pip pip install vllm这里需要注意vLLM 会自动捆绑适配当前 Python 的 PyTorch 版本。如果上一步安装后被强制升级或降级了 PyTorch别慌这是正常现象。安装完成后用python -c import vllm; print(vllm.__version__)验证。我在一台驱动版本较旧的机器上遇到过CUDA driver version is insufficient这种问题要先升级 NVIDIA 驱动再重新装 vLLM不要浪费时间排查代码。2.2 Windows 社区版怎么用vLLM 官方核心支持是 Linux但 Windows 上确实有可用方案。热词里的 “vllm windows 社区版” 指的是通过 WSL 2 运行 Ubuntu或者使用 pre-built 的 Windows wheel。我不建议在原生 Windows 上编译因为 MSVC 工具链和 CUDA 的集成问题会让你崩溃。最稳妥的路径是安装 WSL 2并设置默认为 Ubuntu 22.04。在 WSL 内安装 CUDA Toolkit并配置/usr/local/cuda软链。创建虚拟环境执行pip install vllm。Windows 侧通过localhost访问 WSL 里启动的 vLLM 服务端口注意用--host 0.0.0.0绑定。我实测下来WSL 2 的性能损耗大约在 3% 到 5%对于推理场景完全可接受。Windows 上还有一条路是使用 pip 直接安装vllm的 Windows wheel但版本滞后遇到模型兼容问题更难排查建议优先 WSL。2.3 显卡显存下限的估算启动模型前要搞清楚显存需求。公式不算复杂显存约等于模型权重大小加上 KV Cache 加上激活值。以 FP16 为例7B 模型权重约 14GBQwen2.5-7B 在 4090 24GB 上跑得很舒服。DeepSeek-R1 蒸馏版 7B 也是类似量级。如果是 70B 模型FP16 直接需要 140GB单卡基本无望得走多卡或量化。量化是另一条路。vLLM 支持 AWQ 和 GPTQ 量化模型4bit 下 70B 模型大约 42GB两张 4090 就能带动。但你需要在 HuggingFace 上找对应的量化版模型名比如TheBloke/xxx-AWQ这种格式vLLM 启动时会自动识别量化方式。我更推荐先跑通 FP16再上量化避免一上来因为量化格式不匹配而怀疑人生。3. 核心启动命令与参数详解3.1 最小化启动命令装完环境后最简单的启动命令只有一行vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --host 0.0.0.0 --port 8000这个命令会从 HuggingFace 拉取模型并启动 OpenAI 兼容的 API 服务。启动成功的标志是终端打印出INFO: Application startup complete.然后监听 8000 端口。用 curl 测试curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d {model: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B, messages: [{role: user, content: 你好}]}第一次启动会下载模型这步很慢建议先确认网络环境能访问 HuggingFace。如果访问不稳定可以设置HF_ENDPOINThttps://hf-mirror.com这类镜像变量但要注意模型文件的完整性校验我遇到过镜像文件下载不全导致的safetensors_rust.SafetensorsError。3.2 关键参数逐个拆解--gpu-memory-utilization默认值 0.9意思是 vLLM 最多占用 90% 的显存。如果你的显存同时跑着别的服务建议调低到 0.7。但调太低会限制 KV Cache导致最大并发数下降。这个参数不是越大越好我的经验是先设 0.85观察是否CUDA out of memory再微调。--max-model-len这个参数控制模型的最大上下文长度直接影响 KV Cache 预留空间。Qwen 系列原生支持 32768 甚至更长但如果你不设置vLLM 会读取模型配置里的最大值可能瞬间吃掉大量显存。所以我通常显式设置适合场景的值比如--max-model-len 8192这是最容易被忽略的参数之一。很多启动失败是因为默认最大长度太长导致 KV Cache 申请失败。--tensor-parallel-size多卡并行时用这个参数例如两张 4090 就设 2。vLLM 的 Tensor Parallel 会把模型层切分到多卡这需要所有卡都在同一节点。如果没有高速卡间互联如 NVLink性能会打折扣但也能跑。我有一台双卡 3090 机器没有 NVLink实测吞吐损失在 15% 以内可接受。--served-model-name这是对外暴露的模型名称。我建议用别名而不是直接暴露路径。例如vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --served-model-name deepseek-7b这样客户端请求里的model字段填deepseek-7b后续换模型时不需改客户端。--dtype默认auto会根据模型权重精度推断。如果你的显卡是 30 系以上可以用float16强制 FP16速度和显存更可控。但遇到某些量化模型不能随便指定float16可能报Unsupported quantization。这个参数只在你明确需要时再改。3.3 启动 Qwen3-8B-Flash-Next 的实测热搜词里出现 “vllm 运行 qwen3.8-flash-next”这应该是某个魔改量化或蒸馏版本。这类模型启动步骤和普通 Qwen 无本质区别但常见问题是模型目录里缺少config.json或者tokenizer.json。vLLM 启动时会严格检查这些文件。我的建议是所有模型先用 HuggingFace 的标准格式组织好目录确认包含以下几个文件config.jsontokenizer.json或tokenizer.modelmodel.safetensors或pytorch_model.bingeneration_config.json可选但推荐然后启动vllm serve /path/to/qwen3-8b-flash-next --dtype float16 --max-model-len 4096如果模型本身是 GGUF 或 GPTQ 的异化格式vLLM 支持有限建议先用lm_studio检查模型能否正常生成再迁移到 vLLM。启动时报ValueError: Unknown quantization基本说明模型格式不被当前 vLLM 版本支持要么换模型文件要么升级 vLLM。4. 常见启动问题与排查实录4.1 CUDA out of memory 怎么救这是启动阶段最频发的错误。表象是终端直接报torch.OutOfMemoryError。根因通常是--max-model-len太大或--gpu-memory-utilization设太高。排查步骤我固定为三板斧先看nvidia-smi当前显存占用确认是否有残留进程。有时候我 fork 了多个 Python 进程不杀掉就叠满显存。调低--gpu-memory-utilization从 0.9 降到 0.7。调短--max-model-len从默认值减半到 4096。我遇到过一种隐蔽情况同时加载了两个不同模型到 vLLM 的多 LoRA 配置里叠加显存耗尽。这种情况下必须先把绝对用不到的模型释放掉再启动新模型。4.2 tokenizer 或 config 加载失败错误信息像OSError: Cant load tokenizer或JSONDecodeError。这基本是本地模型路径问题。常见场景是从网盘上下载了一个目录但目录里缺少tokenizer_config.json。vLLM 跟 Transformers 走的是同一套加载逻辑缺一不可。解决方案是补全文件。去 HuggingFace 原模型页手动下载缺失文件放回目录。如果是 GGUF 模型vLLM 需要--tokenizer参数指定单独发布的 tokenizer 文件vllm serve /path/to/model.gguf --tokenizer /path/to/tokenizer_dir每次遇到这类报错我都会提醒自己先检查文件齐全程度再怀疑代码问题这能省掉大量无意义调试。4.3 API 服务启动成功但返回异常有时候终端显示启动成功但请求后返回 400 或 500。最常见的是请求参数超过了模型支持的上下文。例如你模型最大长度 4096但请求里塞了 8000 字的输入就会报 context length 超限。这种情况并不是 vLLM 的 bug而是客户端调用时的参数问题。我一般会在测试脚本里限制max_tokensfrom openai import OpenAI client OpenAI(base_urlhttp://localhost:8000/v1, api_keyEMPTY) response client.chat.completions.create( modeldeepseek-7b, messages[{role: user, content: 讲个科幻故事}], max_tokens512 ) print(response.choices[0].message.content)如果启动服务时端口被占用vLLM 会报Address already in use这不算模型问题换个--port或清理进程即可。4.4 常见问题速查表现象可能原因处理建议CUDA out of memory模型过大/上下文过长/显存利用率过高调低gpu-memory-utilization调短max-model-lenFunction not implementedCPU 不支持某指令集检查 CPU 是否 AVX512或换台机器下载速度极慢网络问题设置镜像源或手动下载模型目录启动后模型回答质量差量化精度损失/模型本身能力弱换 FP16或换更强模型生成速度越来越慢上下文过长导致 KV Cache 占用缩短max-model-len或开启--enable-prefix-caching5. 启动后的调优与扩展5.1 并发压测与已知问题启动模型不是终点压测才是验证部署质量的关键。最简单的压测方式是并发发送请求统计吞吐量。我用过一个轻量方式Pythonasyncio并发 16 个请求每个请求生成 256 tokens观察总耗时。vLLM 的 Continuous Batching 会对请求动态合并单条请求速度可能没优势但并发吞吐很稳。如果压测时出现Aborted due to the maximum number of tokens要检查--max-num-seqs参数。默认值受显存和模型长度限制不一定能满足高并发。可以尝试调高到 256但需要观察显存余量。我还遇到过并发高时延迟暴增的问题。后来发现是--max-num-batched-tokens设得过大导致单次 batch 内 token 太多、计算时间过长。把它调到 4096 左右延迟平滑了很多。这个参数需要按硬件反复试我是逐步二分比较得到的。5.2 前缀缓存与多轮对话加速vLLM 支持--enable-prefix-caching开启后会自动复用多个请求之间相同的 prompt 前缀。在 RAG 或多轮对话场景里前缀缓存能让首 token 延迟明显下降。我实测过一个稳定的 FAQ 问答系统历史对话作为前缀反复出现开启后整体吞吐提升了 20% 左右。这个参数不需要额外写代码启动命令加上即可vllm serve /path/to/model --enable-prefix-caching --max-model-len 8192但注意前缀缓存会在显存里额外维护 hash 表。小显存卡上可能得不偿失建议 24GB 以上显存再开。5.3 与 Ollama / LM Studio 共存很多人的机器上已经装了 Ollama 或 LM Studio再装 vLLM 会冲突吗不冲突它们各占各的端口和显存。但我不建议同时运行因为显存共享会互相踩脚。一个折中办法是日常轻量使用用 LM Studio需要服务化并发时再启动 vLLM。如果非要从 Ollama 切换过来要注意模型格式。Ollama 常用 GGUF 格式而 vLLM 最佳支持是 Safetensors。面对同一模型我通常从 HuggingFace 直接下载 FP16 权重给 vLLM而不是把 Ollama 的 GGUF 转换过来。转换过程既慢又容易出精度损失得不偿失。5.4 实际部署中的日志监控启动模型后不要只看不动。vLLM 会打印每分钟的吞吐统计包括Throughput、Average latency等。这些日志在排查问题时非常管用。我习惯把日志写到文件vllm serve /path/to/model vllm.log 21 出现异常时grep -i error vllm.log就能定位。有一次我发现请求排队严重查日志后发现是--max-num-seqs太小时的一段排队现象调整参数后立刻缓解。日志是最诚实的反馈别等用户报障才回头看。6. 我个人实际操作中的体会回头看看 vLLM 模型启动这件事最大的体会是“参数显性化”。Ollama 封装得太好导致很多人不知道上下文长度和显存利用率是怎么分配的vLLM 把每个因素都暴露成参数启动模型的过程更像是在做一次显存预算。预算做得好启动一次就稳定跑几周预算做不好重启折腾一下午。启动前我总会先确认三个数值模型权重占多少显存、目标并发需要多少 KV Cache、当前显卡还剩多少显存。这三者平衡好了命令行里的参数自然就清晰了。最后再分享一个小技巧批量启动不同模型时先写一个固定模板的 shell 脚本只改模型路径和--port能避免每次敲错参数。如果你正在从 Ollama 或 LM Studio 走向 vLLM别怕那些命令行参数。对着这篇文章把第一个模型启动起来后面的事情就顺了。