这次我们来看一个 2025 年 LLM 推理服务绕不开的引擎vLLM。它解决的问题非常具体大模型推理不是能跑就行而是要跑得快、显存省、能并发。vLLM 就是目前社区里最流行的高吞吐推理方案之一核心亮点是 PagedAttention 显存管理、Continuous Batching 连续批处理以及 OpenAI 兼容 API。如果你正在做本地私有化部署、模型服务化、并发压测或者批量推理任务这篇文章可以直接收藏。整个项目的重点是实用性安装、启动、单请求、流式输出、并发、批量推理、显存观察、常见排错一条线走通。下面按先给规格、再讲操作、最后给排查清单的顺序展开。1. 核心能力速览能力项说明项目类型大模型推理引擎 / LLM Serving 框架开源来源加州大学伯克利分校 SkyLab 团队主导现由 vLLM 社区基金会维护核心机制PagedAttention 显存分页管理、Continuous Batching 连续批处理主要功能LLM 高性能在线推理、批量离线推理、OpenAI 兼容 API、多卡张量并行推荐硬件主流 NVIDIA GPU多卡可做 Tensor Parallel具体显存需按模型和并发测试支持平台Linux 生产推荐、WSL2、DockerWindows 原生支持有限启动方式命令行启动 / Docker 启动 / Python API 启动API 能力支持 OpenAI 风格接口可对接 LangChain、Spring AI、FastGPT 等批量任务支持离线 Batch 推理也支持在线高并发请求适合场景私有化模型服务、推理性能压测、多模型接入网关、批量评测与数据生产这里要先说清楚一个边界vLLM 的快不是绝对的生成速度而是相同的显存和 GPU 条件下能同时处理更多请求、吞吐更高。单条请求可能不如某些专用引擎快但并发上来以后优势非常明显。2. 适用场景与使用边界vLLM 适合以下场景。第一私有化模型服务。公司内部要部署 Qwen、Llama、DeepSeek 这类开源模型并且需要对外提供标准接口vLLM 是成熟度最高的选择之一。第二高并发在线推理。ChatBot 产品、Agent 应用、RAG 问答系统需要多个用户同时访问vLLM 的 Continuous Batching 会把请求动态拼成批次压满 GPU。第三批量评测与数据生产。要做模型对比、指令集评测、训练数据清洗用离线 Batch 接口大批量输入文本比一条条写循环高效得多。第四模型性能压测。研究 vLLM 参数对吞吐和延迟的影响比如--max-num-seqs、--gpu-memory-utilization、--enforce-eager这些参数都需要在一个稳定的推理服务上做对照实验。不合适的场景也要说清楚。如果是单次、长文本、低并发的离线生成任务vLLM 的启动成本和显存预留反而可能是负担直接用 Transformers 或 llama.cpp 更省事。如果是为了在个人 Windows 电脑上快速跑一个小模型原生 Windows 支持有限需要 WSL2 或 Docker折腾成本高于其他方案。如果模型架构很冷门、没有适配 vLLM启动时会直接报错这时候不要硬上。合规边界同样重要。部署模型时要确认模型的开源协议和商用授权用 vLLM 提供对外服务时要确认输入数据是否包含敏感信息建议做脱敏如果服务暴露到公网必须加鉴权避免被刷接口。涉及人脸、声音、版权素材、企业内部数据的推理必须在授权范围内使用。3. 环境准备与前置条件先看一张通用环境检查清单。不同系统、不同模型版本需要的环境不一样这里给的是 vLLM 部署时最常见的检查项。检查项建议操作系统Linux 优先Windows 建议 WSL2 或 DockerPython3.8 到 3.12按 vLLM 版本要求选择CUDA建议用官方 PyTorch 对应的 CUDA 版本驱动版本要满足要求GPUNVIDIA GPU计算能力需要满足依赖要求磁盘空间模型文件加 Python 环境建议至少预留 20GB 以上网络首次安装和下载模型需要能访问 PyPI 和 Hugging Face 镜像端口默认常用 8000需要确认没有被占用这里重点说 Windows 和 Linux 的区别。vLLM 原生支持 Linux生产环境基本都是在 Linux 或 Docker 里跑。Windows 10 上直接跑 vLLM 目前不是官方推荐路线编译和依赖坑比较多。常见的做法是装 WSL2在 WSL 里创建虚拟环境或者直接用 Docker 镜像。如果搜到vLLM 可以在 Windows 10 中使用吗这类问题结论就是能用但要走 WSL2 或 Docker不建议在原生 Windows 环境硬装。关于昇腾等非 NVIDIA 硬件要单独说一句。不同芯片厂商的适配需要针对性编译和验证比如昇腾 910B 在 vLLM 上跑 LLM 有社区适配版本但 embedding 向量模型、reranker 重排序模型是否能通过 vLLM 启动需要看具体镜像和算子支持情况。这类问题不能一概而论最稳妥的方式是先跑一个最小示例验证算子兼容性。4. 安装部署与启动方式4.1 pip 安装在 Linux 或 WSL2 下推荐先用虚拟环境隔离依赖python -m venv vllm_env source vllm_env/bin/activate pip install --upgrade pip pip install vllm如果网络环境需要可以给 pip 配置国内镜像源否则编译依赖下载很慢pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple注意 vLLM 安装时会拉取 PyTorch、transformers、tokenizers 等一系列依赖这些包的版本需要匹配。更稳妥的做法是先看官方文档里当前版本锁定的 PyTorch 版本再决定是否单独安装 CUDA 相关的包。如果直接pip install vllm出现编译错误先看是不是 Python 版本太高或太低再确认是否是 PyTorch 与本地 CUDA 驱动不匹配。4.2 Docker 部署Docker 是生产环境最常见的方式能避免很多环境问题docker run --rm \ --gpus all \ -p 8000:8000 \ vllm/vllm-openai \ --model Qwen/Qwen2.5-7B-Instruct如果没有指定本地模型路径vLLM 会从 Hugging Face 下载模型。国内环境可以设置镜像源export HF_ENDPOINThttps://hf-mirror.comDocker 方案的好处是隔离干净升级 vLLM 版本不用污染宿主机 Python 环境。坏处是首次拉镜像比较大对网络要求高。4.3 命令行启动 vLLM 服务命令行启动最核心的命令是python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --gpu-memory-utilization 0.9这里几个参数先理解一下。--gpu-memory-utilization指定 vLLM 最多使用的显存比例默认 0.9。显存不够时可以先调低到 0.8 或 0.7而不是直接改模型。--host与--port决定服务监听地址和端口只要本机调试建议--host 127.0.0.1不要暴露到局域网。--max-model-len控制最大上下文长度如果显存紧张可以调低比如--max-model-len 8192。--tensor-parallel-size指定多卡并行数量比如两张卡写 2。启动成功后会看到类似Uvicorn running on http://0.0.0.0:8000的日志。看到这行日志说明 API 服务已经起来了。4.4 检查服务状态启动后先请求模型列表接口curl http://127.0.0.1:8000/v1/models如果返回一个包含模型 ID 的 JSON说明服务正常。这一步是后面所有测试的前提。5. 功能测试与效果验证5.1 单请求推理测试用 curl 发一个最简单的 Chat 请求curl 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} ], max_tokens: 128, temperature: 0.7 }返回 JSON 里的choices[0].message.content就是模型输出。这一步验证的是模型加载是否正确、输入输出通道是否正常、API 路由是否可用。判断标准有两点。第一HTTP 状态码为 200。第二返回内容符合模型预期。如果返回 404多半是接口路径不对如果返回 400一般是请求体参数错误比如 messages 缺少 role 字段。5.2 流式输出测试流式输出对在线应用非常重要用户看到的逐字蹦字效果就靠它curl 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: 写一段 200 字的短文介绍大模型推理} ], stream: true, max_tokens: 256 }返回结果是多行data: {...}流式数据最后一行是data: [DONE]。这说明流式接口正常。如果拿到的是一个整体 JSON说明stream参数没有生效检查请求体里是否真的传了stream: true。5.3 离线批量推理测试除了在线 APIvLLM 还能直接做离线批量推理。这种模式不启动 HTTP 服务而是写一个 Python 脚本一次处理一批文本from vllm import LLM, SamplingParams llm LLM(modelQwen/Qwen2.5-7B-Instruct) prompts [ 用一句话介绍 Python, 用一句话介绍 CUDA, 用一句话介绍 GPU 显存, ] sampling_params SamplingParams( temperature0.7, max_tokens128, ) outputs llm.generate(prompts, sampling_params) for output in outputs: prompt output.prompt generated_text output.outputs[0].text print(fPrompt: {prompt!r}) print(fGenerated: {generated_text!r}) print(---)这个脚本适合批量任务比如评测、数据生成、测试集跑分。它不需要先启动 API 服务会直接加载模型并执行推理最后把结果打印出来。批量任务中如果某一条输入很长建议在SamplingParams里设置合理的max_tokens避免个别长样本把显存拖爆。5.4 并发压测模型并发是 vLLM 的核心场景。用一个简单的 Python 脚本向 API 发多个并发请求观察服务的吞吐和显存变化import requests import concurrent.futures url http://127.0.0.1:8000/v1/chat/completions def send_request(i): payload { model: Qwen/Qwen2.5-7B-Instruct, messages: [ {role: user, content: f请解释什么是并发请求编号 {i}} ], max_tokens: 64, } resp requests.post(url, jsonpayload, timeout30) return resp.status_code with concurrent.futures.ThreadPoolExecutor(max_workers10) as executor: results list(executor.map(send_request, range(50))) print(results)运行后观察两点50 个请求是否全部返回 200服务是否出现超时或显存溢出。如果出现大量失败先降低并发数再检查显存参数。5.5 CPU 推理测试vLLM 也支持部分 CPU 场景但主要面向集群中的 CPU 或混合部署。个人电脑上直接用 CPU 跑 vLLM 并不是最合适的路线性能和 gptq、llama.cpp 这类 CPU 推理方案相比没有明显优势。这里不展开。6. 接口 API 与批量任务6.1 OpenAI 兼容 API 说明vLLM 的 API 设计高度兼容 OpenAI 格式这意味着很多现成的客户端可以直接改base_url使用。常用端点有三个端点作用GET /v1/models获取已加载模型列表POST /v1/chat/completionsChat 对话补全POST /v1/completions纯文本补全如果你在做应用集成可以先测试GET /v1/models确认模型 ID 是否与请求里的model字段一致。很多 400 错误都出在这里。6.2 Python 客户端调用如果是 Python 项目直接使用openai包from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:8000/v1, api_keyEMPTY, ) response client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[ {role: user, content: 讲讲 vLLM 的 PagedAttention}, ], temperature0.7, max_tokens256, streamFalse, ) print(response.choices[0].message.content)api_key在本地测试随便填一个字符串即可vLLM 默认不做鉴权。但如果你把服务暴露到局域网或公网一定要在反向代理层加 API Key 校验或访问控制。以 OpenAI SDK 接入后LangChain、Spring AI、FastGPT、Dify 这类编排工具都可以把模型地址直接指到 vLLM 服务不需要写额外适配代码。6.3 批量任务设计与失败重试在线 API 本身就支持高并发但离线批量任务值得单独设计。批量任务不要简单地把所有数据一次性丢进llm.generate()建议按批次切分并记录进度import json from vllm import LLM, SamplingParams llm LLM(modelQwen/Qwen2.5-7B-Instruct) with open(inputs.jsonl, r, encodingutf-8) as f: tasks [json.loads(line) for line in f lines() if line.strip()] sampling_params SamplingParams( temperature0.2, max_tokens512, ) results [] for idx in range(0, len(tasks), 16): batch tasks[idx : idx 16] prompts [item[prompt] for item in batch] outputs llm.generate(prompts, sampling_params) for output in outputs: results.append(output.outputs[0].text) print(fprocessed {min(idx 16, len(tasks))}/{len(tasks)})批量任务要养成三个习惯。第一每条任务带唯一 ID方便失败后找到具体输入。第二分批写入结果文件不要等全部跑完再落盘。第三对长文本输入单独限制max_tokens防止一个超长文本卡住整批任务。7. 资源占用与性能观察7.1 显存占用观察方法vLLM 启动时就会预留显存。观察显存最常见的方式是nvidia-smi更精细的方式是看 vLLM 日志里的显存分配信息。启动时日志会显示 model weights 占用、KV cache 占用等信息这些比nvidia-smi更直接。需要重点关注 KV cache 的大小因为 vLLM 会把剩余显存尽可能多分给 KV cache用来缓存历史 token提高并发吞吐能力。7.2 关键参数对性能的影响这里说三个影响最大的参数。--gpu-memory-utilization控制 vLLM 使用的显存上限。调低可以给其他进程留空间但也意味着 KV cache 变小并发能力下降。--max-model-len限制最大上下文长度。同样的显存下如果把这个值调低可以分配更大的 KV cache 给并发请求。--max-num-seqs限制并发序列数。默认值通常会比较高显存不够时调低它比调低gpu-memory-utilization更精准。7.3 --enforce-eager 的影响很多人在搜索使用 vLLM 命令启动服务是 --enforce-eager 有什么影响。这个参数的作用是禁用 CUDA Graph 捕获。默认情况下vLLM 会用 CUDA Graph 加速推理过程以换取更低的延迟和更高的吞吐但代价是启动时显存占用更高。加上--enforce-eager后vLLM 会走 eager 模式显存占用下降但吞吐和延迟都会变差。更准确的判断是如果你的显存非常紧张或者启动时报 CUDA Graph 相关错误可以尝试--enforce-eager如果显存够用、追求性能不要加这个参数。下面是一个显存不足时更实用的启动组合python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.8 \ --max-model-len 8192 \ --max-num-seqs 16先降低并发序列数再降低上下文长度最后才考虑--enforce-eager。7.4 多卡与张量并行多卡场景用--tensor-parallel-size控制python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --tensor-parallel-size 2需要说明的是多卡并行并不总是带来线性加速。两张卡跑一个模型吞吐提升要看模型大小、卡间带宽和请求并发度。如果两张卡显存都小到单卡装不下双卡是必须的如果单卡能装下先测单卡性能再决定是否上双卡。8. 常见问题与排查方法问题现象可能原因排查方式解决方案启动后页面打不开端口被占用或服务未启动检查日志和端口更换端口或重启服务curl 请求返回 404接口路径错误检查base_url和路径改为/v1/chat/completions请求返回 400请求体参数错误看服务端日志检查model字段和 messages 格式模型加载显存不足模型太大或gpu-memory-utilization太高看日志中的显存分配调低gpu-memory-utilization或换小模型启动时 CUDA 报错驱动和 CUDA 版本不匹配运行nvidia-smi和python -c import torch; print(torch.cuda.is_available())升级驱动或重装匹配的 PyTorch加载模型速度太慢首次下载模型检查模型下载进度配置HF_ENDPOINT镜像并发高时服务超时显存或序列上限不够观察 nvidia-smi 和日志调低max-num-seqs或增大显存分配Windows 下启动报错原生支持有限查看错误是否来自编译依赖切换到 WSL2 或 Docker昇腾等非 NVIDIA 卡不工作算子未适配查看后端报错信息使用对应芯片厂商提供的适配镜像或版本请求返回结果为空上下文长度超过限制检查max_tokens和模型上下文调整max_tokens或max-model-len这里特别提醒两个高频坑。第一个是显存 OOM 不是只在模型加载时出现。vLLM 启动时预留的显存可能刚好够用但随着并发请求增多KV cache 会动态增长。如果完全跑满显存会直接触发内存不足。这时候要降低max-num-seqs而不是盲目降低模型精度因为精度转换不一定能换来更多的 KV cache 空间。第二个是依赖版本问题。vLLM 对 PyTorch、transformers 的版本比较敏感升级 vLLM 后旧模型可能无法加载。建议在 requirements 里锁定版本不要随手pip install -U。9. 最佳实践与使用建议第一次部署先用最小参数跑通再逐步增加并发和上下文长度。最小启动参数可以这样python -m vllm.entrypoints.openai.api_server \ --model Qwen/Qwen2.5-7B-Instruct \ --gpu-memory-utilization 0.7 \ --max-model-len 4096 \ --max-num-seqs 4确认单请求正常、流式正常、并发少量请求正常后再按业务需要调整参数。模型文件、输入素材、输出结果要分目录管理。vLLM 的模型下载默认在 Hugging Face 缓存目录实际项目中建议设置HF_HOME指向一个独立目录避免模型文件散落在系统盘export HF_HOME/data/models/huggingface批量任务要加日志和失败重试。不管是离线LLM.generate()还是在线 API 调用都要记录每条任务的状态。在线 API 场景建议加超时和重试因为并发高时单条请求可能比较慢from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:8000/v1, api_keyEMPTY, ) for i in range(3): try: response client.chat.completions.create( modelQwen/Qwen2.5-7B-Instruct, messages[{role: user, content: 你好}], timeout30, ) break except Exception as e: print(fretry {i 1}: {e})服务访问控制要提前做。vLLM 默认没有鉴权部署到公网时必须加 API Key 校验。最简单的方案是在反向代理层做。涉及到企业内部数据、用户隐私、版权素材时先确认使用边界再上线服务。版本管理建议用 requirements.txt 或 Docker 镜像 Tag 锁定版本。遇到问题先看 vLLM 的 GitHub Release 和官方文档很多更新后行为变化的问题都能在里面找到说明。10. 总结与下一步vLLM 最值得尝试的点是它让你在同一块 GPU 上跑出远超普通推理代码的吞吐并且用 OpenAI 兼容 API 把模型服务化门槛降得很低。整个验证流程可以分三步走先用命令行启动一个 7B 模型再测 curl 单请求和流式输出最后跑一个 50 并发的压测脚本观察显存和响应时间变化。最容易踩的坑集中在三处CUDA 和 PyTorch 版本不匹配导致启动失败、显存参数设置不合理导致 OOM、Windows 原生环境不支持导致编译困难。前两个通过版本锁定和稳妥的参数组合能解决第三个直接换 WSL2 或 Docker。如果你的场景是快速把一个模型跑起来vLLM 的启动成本不算低但如果你的场景是模型要长期稳定对外提供服务、承受并发请求vLLM 是目前绕不开的选择。下一步可以继续研究的方向包括SGLang 与 vLLM 的吞吐对比、长上下文的prefix caching配置、与 LangChain 或 Spring AI 的集成、以及尝试--reasoning-parser做推理模型解析。建议收藏备用部署的时候按这篇文章的顺序走一遍能少踩不少坑。