
最近一两年做大模型推理绕不开 vLLM 这个名字。它最开始是 LMSYS 内部做聊天评测时被显存逼出来的产物后来开源成了目前工业界部署 LLM 的主流框架之一。很多人从 Ollama、LM Studio 开始接触本地模型跑通一两个小模型后一旦想把模型规模提到 7B、14B甚至部署 DeepSeek 这种动不动几十上百 G 权重的模型很快就会发现显存完全不够用并发稍微一起来就 OOM速度也拉胯。这时候换到 vLLM往往能明显感觉到两个变化同样一张卡能装下的模型更大了而且同时回答多个请求的时候不再“排队到天荒地老”。这篇东西不是官方文档的复述是我自己从“装个 Python 包”到“在服务环境里稳定跑起多路并发”的完整记录。内容包括 vLLM 的安装涵盖 pip、Docker、源码编译三条路、模型服务的启动参数怎么填、以及最让人头疼的显存到底是怎么分配和调优的。适用对象很明确已经用 Ollama 跑过小模型、想进一步做真正并发推理服务的人或者刚开始接触 vLLM、被一堆版本号和 CUDA 匹配问题绕晕的新手。1. 先搞懂 vLLM 凭什么能省显存PagedAttention 和连续批处理1.1 传统推理框架的显存浪费在哪里在动手安装之前我建议先花十分钟理解 vLLM 的底层思路否则后面调参完全靠试错。传统 transformer 推理服务包括很多早期的 API 封装给每个请求分配显存是按“最大可能长度”一次性劈出去的。比如一个会话窗口限制 4096 token那么前面哪怕只生成 100 个 token系统也已经把 4096 token 对应的 KV Cache键值缓存空间预留出来了。结果就是内存中大片区域是空的但不允许别人用请求多的时候每个都晃荡着大片的预留空间显存很快就被无效占满。vLLM 第一个关键创新是 PagedAttention思路和操作系统的分页内存管理一致。KV Cache 不再连续占一大块内存而是拆成固定大小的 block 来管理按需分配。一个请求的生成过程里前面的 token 计算完它对应的 KV 只占一小个 block后面需要更多空间再从全局空闲块列表里取新的 block。这样不同请求的 KV Cache 可以在物理上交错排列在一起显存碎片和“为未来预留导致的空洞”大幅减少。1.2 连续批处理为什么并发一上去别人家卡死而你还能动另一个核心机制是连续批处理continuous batching。早期 LLM 服务的批处理逻辑很粗糙攒够 N 个请求组成一个 batch等这批全部生成完再统一返回然后开始下一批。只要 batch 里有一个请求上下文特别长整批人都要陪着等。vLLM 的调度粒度不是“请求”而是“iteration”也就是每次只前进一步生成一个 token。每轮迭代开始前调度器会把当前仍在生成中、并且显存足够容纳下一步计算的请求组合成 batch某个请求结束了就释放它的 KV block下一轮新请求立刻补进来。因此不会出现“尾请求拖垮整批”的情况吞吐量高很多。1.3 知道这些原理后面调优才有方向记住这一点非常关键vLLM 的显存分配策略是“预先圈地动态出租”。启动时它会尽可能把所有可见 GPU 显存都算进自己的池子里按 block 划分再根据你的并发和上下文设置动态分配。所以你会看到 vLLM 一启动nvidia-smi里显存占用立刻冲上去不用慌它是在把地圈好不是全被模型权重占了。显存调优的思路本质上就是决定“圈多少地给 KV Cache、每个请求最多能租多少地上下文长度、同时多少个请求能进来”。2. 开工之前显卡、驱动、CUDA、Python 一次性对齐2.1 环境要求先心里有数先说结论Linux NVIDIA 显卡 显存足够是最省心的组合。vLLM 官方最优先支持的是 CUDA 的 Linux 环境Windows 属于“社区支持”下面我单独说 Windows 用户怎么办。如果你手里是 AMD 显卡vLLM 也有 ROCm 版本支持但踩坑概率明显更高纯 CPU 环境运行 vLLM 存在但不推荐服务化推理速度很难看。具体版本要求我就不给死板表格了因为 vLLM 迭代很快不同版本对应的 Python、PyTorch、CUDA 要求一直在变。我自己现在的固定搭配是Python 3.10 或 3.11目前最稳3.12 在个别版本会遇到依赖编译的问题CUDA 12.x 优先版本不要太老NVIDIA 驱动选择足够新的版本因为驱动向后兼容 CUDA runtime但驱动版本太老会直接加载不了新 CUDA 库GCC/make源码编译时用版本别太老就行我踩过的最大一个坑是只看 PyPI 上的版本号没留意本地驱动所支持的 CUDA 版本上限。驱动版本不够时vLLM 未必会在安装时报错而是等你启动模型时才提示 CUDA driver 版本不匹配排查起来特别费时间。你可以用nvidia-smi右上角查看驱动支持的 CUDA 版本比如显示 “CUDA Version: 12.4”那你的环境最多按 CUDA 12.4 左右去匹配没必要强行上 12.8 的工具链。2.2 用 conda 隔离环境别把系统 Python 搞乱vLLM 的依赖比较深它会拉取特定版本的 PyTorch、transformers、tokenizers、safetensors 等一堆东西。如果直接装进系统 Python过两个月你会发现其他项目也被带着升级了。我现在的固定操作conda create -n vllm python3.11 -y conda activate vllm pip install --upgrade pip没有 conda 的用python -m venv也行但 conda 在切换 CUDA 相关环境时更省心。2.3 Windows 用户的选择WSL2 优先热词里能看到“vllm windows 社区版”这种说法确实 Windows 不是 vLLM 的一等公民但也不是不能用。我的建议分三种情况只是想在 Windows 上快速体验优先装 WSL2然后在 Ubuntu 里按 Linux 流程走。网络、显存透传都很好用唯一的代价是多耗一点内存但比在 Windows 原生环境里跟编译器和链接库搏斗舒服得多。就想在 Windows 原生环境跑可以找社区构建的 wheel比如某些第三方维护的vllm-windows包但版本往往落后于官方且部分算子走的是 CPU fallback 路径性能打折扣。用 Docker Desktop WSL2 backend这种其实也是对多数人最平滑的方案下面安装环节我会展开。如果你是一些较老显卡先确认是否支持 bf16、FlashAttention 要求的算力。最直接的办法是装好后直接跑一个 7B 模型若启动日志里出现算子不支持、flash_attn报错优先从 Windows 原生环境的兼容性方向排查。3. 安装 vLLM三条路线按场景自选3.1 路线一pip 直装最快但不一定适配你的 CUDA新版本 vLLM 在 PyPI 上已经有了针对不同 CUDA 版本的包。默认情况下pip install vllm装到的包会对应某个默认 CUDA 版本例如 CUDA 12.6。如果你本地就是 12.6那直接用pip install vllm装完验证一下python -c import vllm; print(vllm.__version__)如果你的 CUDA 是 12.8 或更新或者 vLLM 新版本拆出了类似vllm-cu128这样的专用包直接按对应名字装即可。命令大概是pip install vllm-cu128怎么判断自己到底该装哪个我的建议是先看nvidia-smi支持的 CUDA 版本再看你要用的模型对运算符的要求。比如某些最新的模型或量化算子要依赖 CUDA 12.8 才被官方测试覆盖那就选 cu128 包。如果只是普通推理默认包即可没必要追求版本号最新。3.2 路线二Docker 镜像服务器部署最省心如果你的目标是把 vLLM 跑在公司服务器或者自己长期用的机器上我非常推荐 Docker 方式。官方镜像vllm/vllm-openai已经把 CUDA runtime、PyTorch、vLLM 都打包好了你只需要保证宿主机有 NVIDIA 驱动和 NVIDIA Container Toolkit。启动一个 OpenAI 兼容服务的命令长这样docker run --gpus all \ -p 8000:8000 \ --ipchost \ --shm-size8g \ vllm/vllm-openai:最新标签 \ --model Qwen/Qwen2.5-7B-Instruct热词里出现的vllm/vllm-openai:v0.27.1就是这类镜像的版本标签之一。做镜像选型时最好结合模型发布时间的先后新模型如果依赖新版本 tokenizer 或算子直接拉最新镜像。--shm-size这个参数容易被忽略vLLM 在加载模型和数据并行时会用共享内存做进程间通信默认的 64MB 大概率不够会报 shared memory 相关的异常。安装 NVIDIA Container Toolkit 后可以用docker run --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi来验证容器里能否看到显卡。这个测试镜像跑通了再跑 vLLM 镜像。3.3 路线三源码编译什么时候才需要这么做如果 pip 包不满足你需要的 commit 版本或者你要改 vLLM 源码做二次开发才需要源码编译。日常使用我不建议这条路因为编译时间很长还会遇到编译器和 CUDA 库版本匹配的问题。git clone https://github.com/vllm-project/vllm.git cd vllm pip install -e . --no-build-isolation编译前确认三件事nvcc --version能输出正确的 CUDA 版本gcc --version版本足够新Python 虚拟环境已激活。我第一次源码编译时就是漏了--no-build-isolation导致 pip 重新拉取隔离环境的依赖跟当前虚拟环境里的 PyTorch 不是一套最后链接阶段报一堆 undefined symbol浪费了一下午。如果只是需要 GPU 算子层面的优化或调试建议仍然用镜像或 pip 包跑主体再用单独开发环境编译测试别把部署机器搞成编译机。3.4 安装完必须做的验证装完不急着启动大模型先跑一个极小的模型验证链路python -c from vllm import LLM; llm LLM(modelQwen/Qwen2.5-1.5B-Instruct); print(llm.generate([你好]))这一步能快速暴露大部分环境问题CUDA 不可用、libnccl缺失、flash_attn编译失败等。1.5B 权重大概 3GB显存不是问题的机器都能跑过。4. 启动模型从最小命令到多卡并行4.1 用 OpenAI 兼容接口启动vLLM 最适合的用法是启动一个 OpenAI 兼容接口服务这样 OpenAI SDK、LangChain、Dify、Chatbox 之类都能直接接。最基本的启动命令python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --max-model-len 8192看到日志里出现类似Uvicorn running on http://0.0.0.0:8000就说明起来了。然后可以用 curl 测试curl -X POST http://127.0.0.1:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: Qwen/Qwen2.5-7B-Instruct, messages: [{role: user, content: 介绍一下 vLLM}] }4.2 启动常见模型的参数心得部署 DeepSeek 系列模型是现在的热点。如果你是部署 DeepSeek-R1 蒸馏版比如deepseek-ai/DeepSeek-R1-Distill-Qwen-7B命令和普通模型差别不大python -m vllm.entrypoints.openai.api_server \ --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \ --reasoning-parser deepseek_r1 \ --max-model-len 8192--reasoning-parser deepseek_r1是让 vLLM 正确解析 R1 的思考标签如果用不到思考内容可以不加。如果你的显存不足以支撑 7B 蒸馏版可以换 1.5B 蒸馏版大多数普通问答场景也都够用了。R1 参数较大的版本动辄几百 GB 权重不是单卡能跑的别硬上。4.3 多卡并行tensor-parallel-size 用法显存不够但有不止一块显卡时可以用张量并行把模型权重和 KV Cache 拆分到多张卡python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-14B-Instruct \ --tensor-parallel-size 2 \ --max-model-len 8192这块我要多说两句。张量并行不是“免费的显存扩容”通信开销很大两张卡之间的 NVLink/PCIe 带宽决定扩展效率。两张卡跑 14B 通常能接近线性收益但四张卡跑一个很小的模型反而可能比单卡还慢。另外--tensor-parallel-size必须能整除模型的注意力头数。如果报The number of attention heads相关的错误就说明该模型不支持你指定的并行度。如果你用的是 Docker 方式多卡启动需要显式传设备。比如宿主机有 4 张卡只让容器用第 2、3 张docker run --gpus device1,2 \ -p 8000:8000 \ --ipchost --shm-size8g \ vllm/vllm-openai:latest \ --model Qwen/Qwen2.5-14B-Instruct \ --tensor-parallel-size 24.4 启动报错的通用排查顺序启动失败时我先按这个顺序排查省掉很多无效尝试看日志里第一段异常是什么。绝大多数是缺少依赖或算子不匹配而不是模型本身问题。确认模型路径写对了。--model可以填 HuggingFace 模型 ID也可以填本地目录本地目录建议绝对路径。看显存是否足够加载权重。权重显存约为参数量 × 字节数。例如 7B 模型用 BF162 字节加载权重约 14GB12GB 显存直接加载都会爆先考虑量化版本。看是否是并发导致启动时max-model-len过大。上下文长度设太高时vLLM 会根据剩余显存计算 KV Cache能容纳的并发数会非常低甚至为 0日志会给出显眼提示。5. 显存调优从 OOM 到高并发的完整思路5.1 先明白显存账单是怎么算的一张卡上的显存被 vLLM 分成几块模型权重、激活值activation、KV Cache、以及各种算子临时缓冲区。其中权重大小基本是固定的激活值在 batch 大的时候会涨KV Cache 是动态的也是优化空间最大的。举个例子Qwen2.5-7B-Instruct 的结构参数大致是 28 层注意力层、4 个 KV head、每个 head 的维度是 128KV Cache 用 BF16每元素 2 字节。那么每个 token 每层需要的 KV 显存大约是 2key 和 value 两份 × 4 × 128 × 2 字节 2048 字节28 层就是 57344 字节约 56KB。如果你的 GPU 能拿出 10GB 给 KV Cache理论上能容纳的上下文总时长约为 10GB / 56KB ≈ 18 万个 token 左右。但注意这 18 万不是单个请求的长度而是所有并发请求填满时的总和上限。所以max-model-len越大vLLM 就会把一部分 KV 空间预留出来对应并发就会下降。这个计算不用背关键是理解三个变量之间的关系模型结构KV per token、KV Cache 总预算、上下文长度。5.2 显存调优的第一参数gpu-memory-utilization--gpu-memory-utilization控制 vLLM 将多少比例的 GPU 显存纳入自己的分配池默认是 0.9。也就是说一张 24GB 的卡vLLM 会预分配约 21.6GB 用来放权重和 KV Cache剩下的留给 CUDA context 和运行时。调优建议如果机器只跑 vLLM 一个服务0.9 是合理值甚至 0.95 都行。但不要把 0.95 当成默认因为 PyTorch 和 CUDA 本身还会占一点显存留太少容易出现“服务起来但某个算子在 batch 增大时临时申请显存失败”的问题。如果要和别的服务共享显卡比如同时跑一个 embedder 服务或不方便停掉的训练进程把--gpu-memory-utilization调到 0.6 甚至更低确保其他进程也有空间。如果出现启动时直接 CUDA OOM检查是不是权重本身 上下文预留空间已经超过了卡的总显存此时调低max-model-len比调低 utilization 更有效。具体启动命令示例python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.85 \ --max-model-len 4096 \ --max-num-seqs 645.3 几个不那么直观但很实用的开关--enforce-eager这个参数默认不开启vLLM 会用 CUDA Graph 优化小算子执行但 CUDA Graph 也会占一部分显存。显存非常紧时开启--enforce-eager可以省掉 Graph 缓冲区的开销代价是解码速度略降。如果模型启动时离 OOM 就差临门一脚试它。--kv-cache-dtype fp8把 KV Cache 的精度从 BF16/FP16 降到 FP8KV 占用直接减半。这个参数对部分新显卡效果显著但要注意算子是否有 FP8 支持日志里如果显示 fallback 到 FP16那实际省不了多少。我的经验是Hopper/Ada 架构以及更新显卡优先尝试老架构不要抱太大期望。--max-num-seqs控制同时处理的序列数。默认值已经不小但如果你的显存并不宽裕把最大并发限制住反而能避免突发流量把显存冲爆。调大它不一定会提高吞吐因为 vLLM 会自动探测当前显存能容纳多少并发它更像是一个“安全阀”。--enable-prefix-caching如果你的业务里大量请求共享相同的前缀比如固定 system prompt、多轮对话的历史开启前缀缓存能让这些重复计算直接命中KV 空间也能复用。但是前缀比较杂乱、重复率不高的情况下收益有限不要当默认开关无脑开。5.4 常见 OOM 现象背后的原因分类我把实际运行的 OOM 分成三类第一类启动即 OOM。模型权重本身就超过了显存总量。比如 70B 模型 BF16 权重就要 140GB单卡根本载不进去。此时要么换量化模型AWQ/GPTQ 4bit 能降到 40GB 左右要么上多卡张量并行要么换小一号模型。第二类运行时 OOM但启动日志正常。通常是 KV Cache 预分配没问题但某个时刻并发上去后序列长度总和超过了 KV 预算。日志里会出现类似Cannot schedule new requests或 CUDA OOM 的报错。解法并不是简单地降低gpu-memory-utilization而是降低max-model-len或限制max-num-seqs。第三类偶发算子临时申请显存失败。发生在 batch size 增大、激活内存暴涨的时候。这是最隐蔽的一种舒适区不容易复现一测压力就暴露。我的做法是留至少 1-2GB 的余量也就是 utilization 不要拉满到 0.98同时把共享内存调大。5.5 KV Cache 使用率怎么看vLLM 的启动日志会给出一个比较清晰的概览大意是模型权重占了多少、KV Cache 总量是多少、最大可支持并发数是多少。运行过程中服务日志会周期性输出当前使用的 token 数占 KV Cache 总量比例。结合你自己的业务来解读如果kv_cache_usage长期接近 100%说明显存够紧可以考虑降低上下文长度或增加并发限制如果长期低于 30%说明显存资源溢出可以放心调大并发或允许更长上下文。还可以用nvidia-smi监控显存变化但注意 vLLM 预分配的显存里有一部分是“已分配未使用”的状态所以在nvidia-smi里看到占用很高不一定代表 KV 已满。以 vLLM 日志里的使用率统计为准不要光看监视器。6. 热词里那些真实场景Docker 加载 Embedding 模型、Windows 部署、镜像版本选择6.1 Docker 加载 qwen3-embedding 这种小模型要注意什么热词里提到docker vllm/vllm-openai:v0.27.1 加载 qwen3-embedding-0.6b这个场景很典型。Embedding 模型体量小但有人会觉得“这么小一个模型随手就起来了”结果反而踩坑。启动命令类似docker run --gpus all -p 8000:8000 --ipchost --shm-size4g \ vllm/vllm-openai:v0.27.1 \ --model Qwen/Qwen3-Embedding-0.6B \ --task embedding \ --max-model-len 8192这里有几个细节必须通过--task embedding告诉 vLLM 这是 embedding 服务否则它会按文本生成模型启动行为完全不对。小模型加载很快但 QA 三角色验证显存占用低时不要误以为服务没起来等日志出现 embedding 相关的model_executor加载完成再测试。官方 API 是/v1/embeddings不是/v1/chat/completions用 OpenAI SDK 时需要指定正确的 endpoint 路径。如果你同时在跑 chat 模型和 embedding 模型我的建议是分开两个服务进程、分开端口不要试图让一个 vLLM 实例同时承载两种任务。6.2 Windows 部署 vLLM 社区版的常见坑如果你真的必须在 Windows 原生环境跑 vLLM我从社区版实践里总结几个高频问题Python 版本尽量用 3.11Windows 上的预编译 wheel 基本只做这一版3.10 和 3.12 要么找不到对应包要么只能走源码编译。需要手动装 Visual C Redistributable否则运行import vllm时可能报 DLL 加载失败。Windows 的路径分隔符和模型缓存目录要格外小心。HuggingFace 下载缓存里如果路径含中文和空格加载经常出幺蛾子。如果在 Windows 下频繁出现进程卡死优先检查是不是 WDDM 驱动模式导致的显存回收问题。NVIDIA 在 Windows 上默认工作模式是 WDDM对 CUDA 的显存管理不如 Linux 的 TCC 模式严格。有条件的话在 BIOS 无所谓而是要在驱动控制面板里看有没有 TCC 选项显卡若是计算卡可直接切 TCC。不过在 WSL2 那块其实你的 NVIDIA 驱动在 Windows 宿主机上装好WSL2 内部直接用nvidia-smi能看到卡基本就是通的。这是 I 用下来最推荐的 Windows 玩法。6.3 镜像版本别只看“最最新”Docker 镜像标签的选法我的习惯是生产环境指定具体版本如vllm/vllm-openai:v0.27.1不要用latest因为 vLLM 更新节奏很快latest两天一变你没法确定下次部署会拉到什么行为。小版本差异可能导致启动参数的弃用警告、默认 KV Cache 策略变化这都会直接影响线上稳定。每次部署新镜像前把下面三件事做了读镜像对应版本的 Release Notes看 CUDA 版本支持和 Python 要求。在测试机用同样的镜像跑一遍你实际要用的模型别只跑 tiny 模型因为大模型加载路径更复杂。记录下当前镜像跑出好效果的启动参数组合形成自己的启动模板。6.4 从 LM Studio / Ollama 迁移过来的配置习惯不少人是先玩 Ollama/LM Studio 再迁到 vLLM这两套东西最大的体验差异是Ollama 默认给你包好一切、隐藏很多参数vLLM 则把显存和调度参数暴露到你面前。迁移后最容易犯的错就是拿着 Ollama 里的做法比如一次只服务一个模型、上下文填满直接套到 vLLM。在 Ollama 里你调--num_ctx只是影响单个会话在 vLLM 里你在启动参数设定的--max-model-len是全局上限所有并发请求共享这一份预算。所以同样的 8K 上下文Ollama 下可以开一堆会话vLLM 下则要精确控制并发。反过来想正是这种“全局精确控制”才让 vLLM 在真正高并发场景下能榨干显存。从 Ollama 搬到 vLLM我建议先把max-model-len从模型默认值往下调 1/4 到 1/2观察并发能力和错误率再逐步回调。这比一上来就拉满合理得多。7. 集成到应用侧OpenWebUI、Dify 和自定义调用vLLM 本身不提供前端界面它只提供 API 服务。很多人部署完一脸懵“我模型起来了但怎么在网页上聊天”这时需要用到 OpenWebUI、Chatbox 或 Dify 这类前端/编排工具。以 OpenWebUI 为例在它的设置里把模型服务地址指向http://你的服务器IP:8000/v1密钥随便填一个非空字符串如果 vLLM 没开鉴权就能在界面上看到你启动的模型并开始对话。如果你部署的是 DeepSeek 模型建议在 OpenWebUI 的模型设置里把思维链的展示开启否则 R1 系列模型的思考过程不会显示输出可能显得“没头没尾”。自定义调用就更简单了OpenAI SDK 兼容一切都直接可用from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:8000/v1, api_keysk-whatever, ) resp client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[{role: user, content: 用一句话解释什么是显存}], max_tokens200, ) print(resp.choices[0].message.content)7.1 开机自启和服务守护如果你把这套服务当生产用不要直接在前台跑python -m vllm...退出终端服务就死了。Linux 下我用 systemd 管理写一个最小服务单元文件重点配置好Environment里的 CUDA 相关路径启动命令里把日志重定向到独立文件方便排查。关键是设置Restarton-failure遇到偶发 OOM 或进程崩溃会自动拉起。7.2 多服务部署顺序如果是同一台机器跑 chat 模型、embedding 模型、前端界面我建议按依赖顺序启动先起 embedding再起 chat最后起前端。因为前端启动时会去探测后端模型列表先起好了才不会报到空列表。同时也方便分清端口占用问题。8. 一些从实操中沉淀下来的建议与避坑备忘优先用 Docker 部署pip 环境仅用于开发和快速验证。Docker 把 CUDA 版本、依赖库、算子编译结果都固化了换机器不玄学。任何大版本升级前先备份当前能用的启动命令参数。尤其注意--max-model-len、--gpu-memory-utilization这类核心参数新版本对默认值可能有调整直接沿用旧参数跑新版本经常出问题。模型权重优先下载到本地不要每次启动都从 HuggingFace 在线拉。一是网络不稳定二是启动时间拉长三是 HUGGINGFACE 默认缓存目录在/root/.cache/huggingface磁盘空间不够时静默失败。建议显式设置export HF_HOME/data/hf_home生产环境加--served-model-name参数。这样前端/api 调用时用的模型名可以跟实际路径解耦后续换模型版本不用改业务代码。别迷信“参数拉满”。很多人的显存调优是从“往死里开并发”开始的结果换来 OOM再抱怨 vLLM 不稳定。更合理的路径是先用默认参数跑稳用压测脚本逐步增加并发监控 KV Cache 使用率在接近瓶颈前停下来留 10%-20% 的余量。用vllm serve代替老式的python -m vllm.entrypoints.openai.api_server。新版命令行更短也好记例如vllm serve Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.85 \ --max-model-len 8192如果发现推理速度远低于预期先查是不是落到了 CPU offload。某些显存不足的场景vLLM 会自动启用 CPU offload--cpu-offload-gb这种情况下速度会明显下降但它救活了 OOM。我只是提醒你确认自己是否接受了这个隐性降级别误判为“vLLM 太慢”。最后聊点个人体会。vLLM 不是那种装上就能一劳永逸的工具它更像一个把显存调度逻辑摊开给你看的管理器你的水平有多高它能榨出的性能就有多好。刚开始折腾时我一度被 CUDA 版本、镜像标签还有一长串启动参数劝退过但坚持把日志逐行看懂、把每个参数对应的显存账单想明白之后后面部署任何模型都变得非常顺。如果你现在就卡在安装或者 OOM 上别灰心先照着文里的步骤跑通一个 1.5B 小模型再慢慢加参数优化整个链路通了后面换大模型只是换权重而已。