☰
vLLM大模型部署实战:从环境搭建到显存调优全攻略
2026/10/5 9:16:19 网站建设 项目流程

上个月帮同事调一台双 GPU 机器,vLLM 装了四遍,启动仍然报错。倒不是命令记不住,而是环境、显存、版本之间总有莫名其妙的关系。后来把 CUDA 驱动、Docker 镜像、模型量化三件事理顺之后,从安装到启动只花了十几分钟。这篇文章就是把这次经历整理成一套可直接照抄的流程,围绕 vLLM 的安装、启动和显存调优,覆盖从零开始部署大模型时会遇到的绝大多数坑。内容不挑基础,哪怕你刚装好 Ubuntu、还没跑过任何大模型,按着步骤走也能把服务拉起来;已经上过手的同学,重点可以放到第四章和第五章,里面是实操中容易忽略的显存细节和报错定位方法。

我先说结论:vLLM 确实不是“一键部署”的工具,但它的学习曲线完全值得翻越。装好之后,你能得到一个 OpenAI 兼容的推理服务,吞吐量远超裸跑 PyTorch 脚本,批处理能力、显存管理也有明显优势。现在很多团队拿它部署 DeepSeek、Qwen、LLaMA 这些开源模型,不是没有原因的。接下来我按“原理 -> 安装 -> 启动 -> 显存调优 -> 排错”的顺序,把整个链路讲透。

1. 先搞懂 vLLM 解决的核心问题

1.1 vLLM 的加速原理:为什么它比“裸跑”模型快

vLLM 本质上是一个面向大模型推理的高性能服务框架。它不像transformers那样只是帮你加载模型并跑前向,而是在调度和显存管理上做了大量优化。最出名的是 PagedAttention,它把 KV Cache(键值缓存)切成固定大小的块来管理,类似操作系统的虚拟内存分页。这样显存分配不再是一整块连续区域,碎片少了,并发请求多了,同一个 GPU 能服务的请求数量明显提升。

另一个关键机制是 Continuous Batching。传统做法是等一个批次全部生成完再换下一批,浪费大量空闲时间;vLLM 会在每生成一个 token 后立刻让新请求进入计算队列,让 GPU 始终处于满载状态。配合迭代级调度,它可以把吞吐量拉到传统方案的十几倍甚至更高。说白了,vLLM 解决的不仅是“能不能跑”,更是“跑得满不满”。

这个结论很重要,因为很多人问我“为什么 Ollama 能跑我非要学 vLLM”。如果你的需求只是本机聊天、体验模型效果,Ollama 完全够用;但如果要把模型封装成服务、应对并发请求、做线上推理接口,vLLM 才是更稳的选择。

1.2 与 Ollama、LM Studio、SGLang 的选型对比

市面上常见的大模型部署工具不少,我简单梳理下各自定位:

工具适合场景优点缺点
Ollama单机快速体验、开发调试安装简单,命令少,模型管理方便高并发吞吐一般,高级参数定制弱
LM Studio桌面端图形化操作可视化界面,适合新手服务化能力弱,不太适合生产
vLLM生产环境、高并发 API吞吐高、显存管理强、OpenAI 兼容有一定学习成本,对硬件环境要求高
SGLang需要复杂控制流、长上下文运行时优化激进,部分场景更快社区相比 vLLM 稍小,文档少

我实际用下来的感受是:Ollama 和 LM Studio 是“玩具化”的上手工具,vLLM 是“工程化”的部署底座。如果你有 API 服务需求,比如给内部工具链提供大模型接口,或者想跑并发压测,直接学 vLLM 是最省时间的。SGLang 也有自己的优势,尤其在前沿研究和长上下文场景,但遇到问题时能搜到的资料还是 vLLM 更多。对一个没接触过推理框架的新手,我建议先走 vLLM,跑通之后再横向对比其他框架不迟。

2. 环境准备与安装避坑

2.1 硬件与驱动要求:先确认你的卡能不能扛

vLLM 的主要支持平台是 Linux + NVIDIA GPU。Windows 下原生支持不仅安装麻烦,还经常遇到奇怪问题,后面我会单独讲。硬件上最核心的是显卡显存,8GB 是底线,但只能跑 1.5B、3B 级别的量化模型;7B 模型原尺寸 FP16 权重就要约 14GB,基本需要 16GB 以上显卡或者量化;更大的 70B 模型,要 2 张 80GB 卡或者更高倍数的量化。所以第一步不是急着装软件,而是nvidia-smi看下你的卡和驱动。

驱动版本直接影响 CUDA 环境。vLLM 官方镜像和 PyPI 轮子往往基于较新的 CUDA 版本编译,比如现在常见镜像会用 CUDA 12.8。如果你系统里的 NVIDIA 驱动太老,就算装了 vLLM 也可能会报“CUDA driver version is insufficient”。我的经验是:驱动能升就升到最新稳定版,至少保证nvidia-smi输出的 CUDA Version 大于等于 vLLM 要求的下限。注意,这个 CUDA Version 是驱动支持的版本,并不等于你系统里安装的 CUDA Toolkit;vLLM 多数时候通过 PyTorch 自带的 CUDA runtime 工作,不一定要单独装完整版 CUDA。

Python 版本我推荐 3.10 或 3.11。vLLM 对 Python 3.12 的兼容时间更晚,某些依赖包在 3.12 下容易出幺蛾子。另外,不建议在系统 Python 里直接 pip install,除非你只在这台机器上做一次性实验。更好的做法是用venv或conda创建独立环境。

2.2 安装方式选择:Docker 优先,pip 次之

vLLM 的安装方式主要有三种:pip、Docker 镜像、源码编译。对绝大多数人,我推荐 Docker,理由很现实:依赖冲突少,环境干净,升级回滚都很方便。官方镜像vllm/vllm-openai已经包含运行所需的一切,拉下来就能跑。比如你现在要加载 Qwen3-Embedding 这类模型,用 Docker 一条命令就能启动服务,不用纠结 torch 版本和 CUDA 版本匹配。

pip 安装也很简单,在虚拟环境里执行:

pip install vllm

但要注意,pip 安装的 vLLM 会绑定某个 PyTorch 版本,如果你的显卡驱动太老,可能对应 CUDA 版本不支持。Docker 镜像同样有这个问题,但官方镜像的 CUDA 环境更可控。如果你需要特定功能比如某种量化算子,或者你想帮忙改代码调优,才需要源码编译。源码编译耗时长,坑多,初学者别碰。

我实际使用的 Docker 命令大概长这样:

docker run --gpus all \ --shm-size 8g \ -p 8000:8000 \ -v /path/to/models:/models \ vllm/vllm-openai:latest \ --model /models/qwen2.5-7b-instruct \ --served-model-name qwen \ --gpu-memory-utilization 0.9

--shm-size很重要,不要漏。vLLM 使用共享内存做 tensor parallel 时的数据传输,默认 64MB 经常不够,报错时很难想到是这个原因。我一般直接给8g或16g。

2.3 验证安装:你的环境到底好没好

装完之后别急着拉模型,先做两件事验证环境。第一是命令行版本检查:

vllm --version

如果没报错,说明 CLI 能正常加载。第二是 Python 导入检查:

import vllm print(vllm.__version__)

这一步能确认 vLLM 和 PyTorch 是否成功绑定。如果导入时报缺少.so文件、CUDA 库找不到,多半是 PyTorch 的 CUDA 版本和驱动不匹配。这时候先python -c "import torch; print(torch.cuda.is_available())",如果输出 False,就说明根本不是 vLLM 的问题,而是 PyTorch 没拿到 CUDA。

很多教程会忽略这一步,直接去下载模型,然后报错时才发现是环境问题。花两分钟做这个验证,能省掉后续大量排查时间。

3. 启动一个模型服务

3.1 最小化启动命令:先跑起来再说

环境确认没问题后,你就可以启动模型服务。最简命令是:

vllm serve Qwen/Qwen2.5-3B-Instruct \ --served-model-name mymodel \ --port 8000

这里Qwen/Qwen2.5-3B-Instruct是模型在 HuggingFace 或 ModelScope 上的地址,vLLM 会自动下载。如果你网络访问远程模型仓库有障碍,建议提前把模型下载到本地,然后让--model指向本地目录:

vllm serve /models/qwen2.5-3b-instruct \ --served-model-name mymodel

启动后日志会显示模型加载耗时、KV Cache 分配了多少显存,最后出现Uvicorn running on http://0.0.0.0:8000就说明成功。此时用另一个终端测试:

curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "mymodel", "messages": [{"role": "user", "content": "你好,请介绍一下自己"}]}'

这个接口协议和 OpenAI 完全一致,所以任何适配 OpenAI 的客户端,只要改一下 base_url 就能接入本地 vLLM。

3.2 关键启动参数逐个说明:不要照抄所有命令

vLLM 的启动参数非常多,但真正影响你日常使用的就那么几个。我把常用的整理成表:

参数作用我的建议
--model指定模型路径或名称本地路径最稳,避免下载失败
--served-model-nameAPI 请求中的 model 名自定义一个好记的名字,后面调用用它
--port服务端口默认 8000,注意别和现有服务冲突
--tensor-parallel-size使用多少张 GPU 并行必须小于等于 GPU 数,并且能整除
--gpu-memory-utilization显存利用上限没有其他进程时设 0.9,稳妥设为 0.85
--max-model-len最大序列长度根据实际场景设置,不是越大越好
--dtype推理精度GPU 支持就 float16,A100/H100 用 bfloat16
--enforce-eager禁用 CUDA graph显存不够时开启,但会降低吞吐
--quantization量化方式awq、gptq、fp8 等,需和模型匹配

这里最容易被忽略的是--max-model-len。很多人直接启动模型,默认值会使用模型上下文上限,比如 32K。如果你的输入和输出根本没有那么长,这会把大量显存浪费在 KV Cache 上。相反,把它设成实际需要的长度,显存占用能明显下降。启动时报 OOM 时,第一个调的参数就应该是它。

3.3 用 Python 调用 vLLM 服务

除了 curl,你还可以用官方openaiPython SDK:

from openai import OpenAI client = OpenAI( base_url="http://localhost:8000/v1", api_key="EMPTY", ) resp = client.chat.completions.create( model="mymodel", messages=[{"role": "user", "content": "写一段 200 字的 Python 代码示例"}], ) print(resp.choices[0].message.content)

这个好处是你不用改业务代码,只需要把base_url指到本地,原来所有调用 OpenAI 服务的代码就能无缝切换。我见过不少团队把线上服务从云端迁移到内网 vLLM,就是这种操作。

3.4 用 Docker 加载 embedding 模型:一个小扩展

vLLM 不只支持 chat 模型,也支持 embedding 模型。比如你的知识库检索任务需要 Qwen3-Embedding,可以直接用 Docker 镜像启动一个 embedding 服务:

docker run --gpus all --shm-size 8g -p 8000:8000 \ vllm/vllm-openai:latest \ --model /models/qwen3-embedding-0.6b \ --task embedding \ --served-model-name embedder

注意--task embedding告诉 vLLM 这不是生成模型。启动后可以用/v1/embeddings接口获取向量。这类场景在 RAG 应用中很常见,vLLM 的统一接口能让你把生成和检索合并到同一个推理集群里。

4. 显存调优:从“启动失败”到“稳定运行”

4.1 显存到底被谁吃了:权重、KV Cache 与中间激活

显存不够时,首先要弄明白显存被什么占用了。大模型推理时的显存主要分三块:模型权重、KV Cache、临时激活值。模型权重好算,FP16 下一个 7B 模型的权重就是 7B × 2 字节 ≈ 14GB。如果你用 12GB 显卡,不量化就装不下。KV Cache 则和序列长度、并发数强相关:它存储每个 token 计算时的 K 和 V 矩阵,层数越多、序列越长、并发越大,占得越多。中间激活值是前向计算时的临时张量,框架一般会复用内存,但峰值也不可小觑。

vLLM 的显存管理器做了一件聪明的事:它会把整张显卡的显存先划出一块给模型权重,剩下的部分全部交给 KV Cache 按需分配。所以你看到的--gpu-memory-utilization参数,其实是“允许 vLLM 使用的显存上限”。默认 0.9 意思是占用 GPU 总显存的 90%,其余 10% 留给 CUDA context、驱动和其他进程。如果你独享整张卡,可以设到 0.92;如果卡上还有别的服务,就降到 0.7 以下,不然两边都会 OOM。

4.2 核心参数调优:根据你的显卡反推配置

显存调优的核心思路是“算好账再动手”。我一般按这三个步骤走。

第一步,估算模型权重。比如 7B FP16 约 14GB,7B AWQ 4-bit 量化约 4GB,13B FP16 约 26GB,13B 4-bit 量化约 8GB。这决定了你的卡是否装得下模型本体。

第二步,确定 KV Cache 可用空间。总显存减去模型权重、减去预留给系统的空间,就是留给 KV Cache 的。假设你有 24GB 显存,跑一个 14GB 的 7B 模型,设--gpu-memory-utilization 0.9,那么 KV Cache 最多约 24×0.9 - 14 ≈ 7.6GB。够不够取决于并发量和 max-model-len。

第三步,调整影响 KV Cache 的参数。--max-model-len每减一半,KV Cache 占用大约减一半。如果你只是做判断题、短文生成,把 max-model-len 从 8192 降到 2048,效果立竿见影。--max-num-seqs控制最大并发序列数,默认 256,如果你只需要 32 并发,可以设小一点,同样省显存。--enforce-eager则通过禁用 CUDA graph,省下部分显存,但代价是吞吐下降。

下面我给出一组不同显卡的参考配置:

显卡模型推荐参数
12GBQwen2.5-3B--dtype float16 --max-model-len 4096 --gpu-memory-utilization 0.92
16GBQwen2.5-7B AWQ 量化--quantization awq --max-model-len 4096 --gpu-memory-utilization 0.9
24GBQwen2.5-7B 原版--dtype float16 --max-model-len 8192 --gpu-memory-utilization 0.9
2×24GBDeepSeek-R1-Distill-Qwen-14B--tensor-parallel-size 2 --max-model-len 8192 --gpu-memory-utilization 0.9

这些参数是我实测过可以稳定跑起来的组合,但不同驱动的显存预留略不同,如果你发现启动后还有少量剩余,可以微调gpu-memory-utilization提高零点几个百分点。

4.3 量化选择:省显存但别乱来

量化是显存不够时最有效的办法之一。AWQ 和 GPTQ 是常见的 4-bit 量化方案,vLLM 直接支持现成的量化模型。使用时要注意,不是所有模型都有现成的 AWQ 量化版,需要去模型仓库找对应名字。FP8 量化在 H100、Ada 等新卡上很流行,显存占用直接减半,速度还快,但老卡不支持。GGUF 量化在 Ollama 里很常见,vLLM 对 GGUF 也有一定支持,不过我更推荐 AWQ 或 FP8。

这里有个常见误区:量化后的模型有时反而更慢,因为解码时要额外跑反量化算子。我的经验是,4-bit AWQ 在很多消费卡上速度已经足够好,而且显存收益巨大。如果你追求极致显存敏感度,可以接受一点点精度损失,量化是值得的。但如果你的卡容量还有余量,比如 48GB 跑 7B,那就不要量化,直接 FP16 更省心,效果也最稳。

4.4 监控显存:不要等到报错才看

启动之后,别急着做业务测试,先观察一下显存曲线。最直接的方法是:

nvidia-smi -l 2

每两秒刷新一次,可以看到进程显存占用和 GPU 利用率。vLLM 启动日志里也会显示类似“KV cache size: X GiB”的信息,你可以据此判断预留给了 KV Cache 多少显存。如果 KV Cache 数字很小,说明模型本来就大,剩余空间不足,并发一旦上来就容易 OOM。

另一个高级玩法是使用 Prometheus 指标。vLLM 默认会在--metrics-port指定的端口暴露指标,例如显存使用、请求数、生成 token 数等。我用它接上 Grafana 做过一次完整监控,效果很好。但对单机调试来说,nvidia-smi已经够用了。

5. 常见问题与排查技巧实录

5.1 CUDA out of memory:不只是显存不足的锅

最常见的报错是CUDA out of memory。很多人一看到就以为要换显卡,其实大部分情况是参数没调好。你可以按这个顺序排查:

  1. 看模型权重大小,确认是否超过显卡显存。
  2. 看--max-model-len是否太大,适当降低到 2048。
  3. 看--gpu-memory-utilization是否太低,如果独占卡可以提到 0.92。
  4. 看是否开了太多并发,降低--max-num-seqs。
  5. 实在不行上量化,或者换小模型。

另外,如果你用 Docker,必须确认加了--gpus all,不然容器根本看不到 GPU。如果加了还报错,检查 docker 版本和 NVIDIA Container Toolkit 是否安装。这个工具没装好,显卡在容器内就是不可用的。

5.2 模型下载慢或连接超时:本地化优先

vLLM 默认从 HuggingFace 下载模型。国内网络经常超时,我的习惯是先用huggingface-cli或 ModelScope 的 SDK 提前把模型下载到本地,再让 vLLM 加载本地目录。这里有个小技巧:ModelScope 上有大量开源模型的完整权重,而且下载速度快得多。下载后目录结构通常和 HuggingFace 一致,vLLM 可以直接识别。

如果执意要用 HuggingFace 下载,也可以设置镜像环境变量,比如HF_ENDPOINT=https://hf-mirror.com。这只是让模型文件下载更顺畅,和 vLLM 本身无关。模型下载失败时,最重要的不是反复重试,而是先确认模型目录里有没有config.json、tokenizer.json、权重文件这些必备文件。

5.3 Windows 下跑不起来:用 WSL2 或 Docker

vLLM 官方主要支持 Linux,Windows 原生版属于社区维护,兼容性差,而且很多 GPU 算子没有优化。如果你只有 Windows 机器,最省心的是装 WSL2,在 WSL2 里面跑 Docker 或直接 pip 安装 vLLM。缺点是 GPU 显存会被 WSL2 截留一部分,但整体体验远好过原生折腾。另一个选择是远程连一台 Linux 服务器,把推理服务部署在那里,本地只写代码调用 API。我在 Windows 笔记本上见过不少人花几个周末死活装不好 vLLM,最后换成 WSL2 十分钟就好,所以别再跟编译错误死磕了。

5.4 tensor-parallel-size 与 GPU 数不匹配

如果你有多张 GPU,想用--tensor-parallel-size 2加速,但要保证显卡数量能被该值整除。比如你有 3 张卡,设2就会报错。这个参数会把模型切分到多卡上,每张卡存一部分权重,同时 KV Cache 也会分散。它不像单卡那样只要显存够就行,还涉及 PCIe 带宽、NVLink 性能。我测试下来,两张卡跑同尺寸模型,吞吐提升明显,但显存不够时,优先考虑量化,而不是盲目加卡,因为多卡通信也会带来额外开销。

5.5 启动成功但响应慢:检查调度和显存

如果服务能启动,但请求响应很慢,先看 GPU 利用率。如果是 0%,大概率请求没有真正到达 GPU;如果是 100%,可能模型太大、batch 积压或量化算子开销高。这时把--max-num-seqs调小,或者不开--enforce-eager,一般能缓解。还有一个容易被忽略的点:CPU 和 GPU 之间数据搬运,如果模型加载时开启了 CPU offload,推理速度会骤降。不要为了省显存把权重 offload 到内存,除非你的序列极长且对延迟不敏感。

下面整理一份速查表:

错误信息主要原因解决方向
CUDA out of memory显存不足降 max-model-len、开量化、降并发
CUDA driver version is insufficient驱动太老升级 NVIDIA 驱动
The number of GPUs is not divisibletensor-parallel-size 不匹配调整并行度
Failed to import vllmPyTorch/CUDA 依赖问题检查 torch.cuda.is_available()
shared memory insufficientDocker shm-size 太小启动容器时加 --shm-size 8g
请求一直 pending模型还在加载等待日志输出 Uvicorn running
模型路径无 config.json模型没下载完整用专属下载工具重新下载

6. 我最常用的稳定配置与收尾心得

如果你让我推荐一套给新手的“不折腾”组合,我会说:一台 24GB 显存的 Linux 服务器,Docker 安装 vLLM,跑 Qwen2.5-7B-Instruct,启动参数直接抄这个:

docker run --gpus all --shm-size 8g \ -p 8000:8000 \ -v /data/models:/models \ vllm/vllm-openai:latest \ --model /models/qwen2.5-7b-instruct \ --served-model-name qwen \ --dtype float16 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9

这套组合改动最少,踩坑最少,性能已经能应对几十并发的内部工具使用。等跑通之后,再根据实际业务逐步加tensor-parallel-size、量化、Prometheus 监控。我自己从一开始迷信各种花哨参数,后来反而回归到最朴素的配置,因为生产环境最重要的是稳定和可预测。

最后分享一个小技巧:vLLM 的很多报错其实可以从日志里找到线索,不要只盯着最后一行红色字幕。启动时它会打印模型路径、显存分配、加载时间,这些信息对定位问题极有帮助。如果你把日志保存下来,下次报错时能直接对比,效率会高很多。希望这篇文章能帮你少走一些弯路,把精力放在真正要解决的模型效果和业务上,而不是在安装和显存里反复挣扎。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询