前言:为什么你需要认识 vLLM ? 想象一下这个场景:你花了大价钱买了一台带 GPU 的服务器,满心欢喜地部署了一个开源大模型。结果发现,当两三个人同时使用时,响应速度就开始变得像蜗牛一样慢,甚至直接报错“显存不足”。你可能会想:“是我的 GPU 不够好吗?还是模型太大了?”
其实,问题往往不在于硬件,而在于推理 框架的效率。传统的模型推理方式就像一个糟糕的图书管理员——他要求每本书的所有页必须放在同一排书架上,结果书架被浪费得七零八落,新书来了也没地方放,工作效率极低。
而 vLLM,就是一个能让你的 GPU 利用率瞬间翻倍的“超级图书管理员”。
vLLM 是什么? vLLM 是由加州大学伯克利分校开发的开源推理引擎,专为大语言模型 (LLM)的高效服务而生。它的核心目标是:在同样的硬件条件下,处理更多请求、生成更多内容、速度更快。
根据官方数据,vLLM 相比 HuggingFace Transformers 的吞吐量可提升 8-12 倍,甚至最高可达 24 倍。这意味着原本只能服务 10 个用户的 GPU,现在可以轻松服务几十上百个用户。
学完本文你将能够 ✅ 理解 vLLM 的核心原理(不用啃论文,用大白话讲清楚) ✅ 在自己的电脑上安装 vLLM ✅ 用 vLLM 快速进行文本生成(离线推理) ✅ 启动一个兼容 OpenAI 的 API 服务(在线部署) ✅ 掌握常用的性能优化技巧 第一部分:vLLM 的核心原理(小白也能懂版) 在动手之前,花 5 分钟理解 vLLM 的原理,会让你后面使用起来更得心应手。
1.1 传统推理的问题:显存浪费和效率低下 当我们向大模型提问时,它的工作流程是这样的:
读取你的问题(提示词) 逐字生成答案:先预测第一个字,然后根据第一个字预测第二个字…… 在这个过程中,模型需要记住已经生成过的所有内容,这个“记忆”被称为 KV 缓存(Key-Value Cache)。KV 缓存需要存放在 GPU 的显存里。
传统推理框架的问题:
预分配连续空间:每个请求一开始就分配一大块连续显存(比如按最大生成长度 2048 个 token 预分配) 严重的内存碎片:实际生成的 token 可能只有几百个,剩下的空间就白白浪费了 无法共享:多个请求如果共享相同的提示词前缀(比如系统提示),也无法共用缓存 结果:显存利用率可能低至 20%,大部分显存在那里“空着”,但却无法用来服务新请求。
1.2 vLLM 的解决方案:PagedAttention(分页注意力) vLLM 的团队从操作系统的虚拟内存管理中找到了灵感。在计算机中,物理内存被分成固定大小的“页”,程序可以使用不连续的页,通过“页表”来映射。这完美解决了内存碎片问题。
PagedAttention 的核心思想:
KV 缓存不再需要连续存储:vLLM 把每个请求的 KV 缓存切成固定大小的“块”(blocks),每个块可以存放在显存的任意位置 通过块表维护映射关系:每个请求维护一个逻辑块表,告诉系统它的缓存数据分别存放在哪些物理块里 支持块共享:多个请求如果共享相同的前缀,可以指向同一个物理块,通过引用计数管理,只有需要修改时才复制(写时复制) 带来的好处:
显存利用率接近 100%:碎片问题几乎消失 更大的批处理规模:同样的显存可以同时处理更多请求 更快的吞吐量:GPU 计算资源被更充分地利用 1.3 Continuous Batching(持续批处理) 除了内存管理,vLLM 还优化了批处理方式。
传统批处理是“同步”的——必须等一批请求全部处理完,才能开始下一批。这会导致 GPU 在等待中空闲。
vLLM 实现了 iteration-level 调度:在每个推理步骤后,都会重新组合当前批次。新到达的请求可以立即加入,正在生成的请求继续解码,GPU 永远在处理“当前最适合处理”的任务。
简单来说:vLLM 让 GPU 变成了一个永不休息的流水线工人。
第二部分:环境准备与安装 2.1 硬件要求 GPU:NVIDIA 显卡,建议显存 ≥ 8GB(测试小模型 4GB 也可勉强运行) CPU:无所谓,能跑 Python 就行 内存:建议 ≥ 16GB 存储:模型文件通常几 GB 到几十 GB,预留足够空间 2.2 软件环境 推荐使用 conda 创建独立的 Python 环境:
创建 Python 3.10 环境
conda create -n vllm python=3.10 conda activate vllm
安装 vLLM(会自动安装 PyTorch 等依赖)
pip install vllm AI写代码 如果网络较慢,可以使用国内镜像:
pip install vllm -i pypi.tuna.tsinghua.edu.cn/simple AI写代码 2.3 验证安装 在 Python 中执行:
import vllm print(vllm.version) AI写代码 如果没有报错,说明安装成功。
第三部分:快速上手 Demo 1——离线推理 离线推理是最简单的使用方式:你给出一批提示词,vLLM 一次性处理完,返回结果。适合批量处理任务、测试模型效果等场景。
3.1 基础代码示例 我们用一个轻量级模型 TinyLlama 来演示:
from vllm import LLM, SamplingParams
1. 准备提示词
prompts = [ "Hello, my name is", "The capital of France is", "The meaning of life is", ]
2. 设置生成参数
temperature: 控制随机性,0 为确定输出,越大越随机
top_p: 核采样,只考虑累积概率达到 top_p 的token
max_tokens: 最大生成长度
sampling_params = SamplingParams( temperature=0.8, top_p=0.95, max_tokens=100 )
3. 加载模型
第一次运行会自动从 Hugging Face 下载模型
llm = LLM(model="TinyLlama/TinyLlama-1.1B-Chat-v1.0")
4. 执行生成
outputs = llm.generate(prompts, sampling_params)
5. 打印结果
for i, output in enumerate(outputs): prompt = prompts[i] generated_text = output.outputs[0].text print(f"问题 {i+1}: {prompt}") print(f"回答: {generated_text}") print("-" * 50) AI写代码
3.2 代码解析 LLM 类:vLLM 的核心入口,负责加载模型、管理资源 SamplingParams:控制生成行为的参数 temperature:值越小(如 0.1),输出越确定;值越大(如 1.0),输出越多样 top_p:核采样,通常与 temperature 配合使用 max_tokens:限制生成长度,避免无限生成 llm.generate:执行批处理生成,返回包含结果的对象 3.3 查看输出概率(进阶) 如果你想知道模型对每个生成 token 的置信度,可以设置 logprobs 参数:
sampling_params = SamplingParams( max_tokens=1, logprobs=10 # 返回前10个候选token的概率 )
outputs = llm.generate(["The capital of France is"], sampling_params) logprobs = outputs[0].outputs[0].logprobs[0] # 第一个token的logprobs
logprobs 是以log形式存储的概率,需要exp还原
import math for token_id, logprob_obj in logprobs.items(): prob = math.exp(logprob_obj.logprob) print(f"'{logprob_obj.decoded_token}': {prob:.2%}") AI写代码
这在需要评估模型确定性时非常有用。
第四部分:进阶实战 Demo 2——部署 OpenAI 兼容 API 离线推理适合测试,但在生产环境中,你通常需要将模型部署为一个服务,供前端或其他应用调用。vLLM 支持启动一个 完全兼容 OpenAI API 格式 的服务器。
4.1 启动服务器 在终端中执行:
vllm serve mistralai/Mistral-7B-Instruct-v0.3 --port 8000 AI写代码 如果显存较小,可以尝试:
vllm serve Qwen/Qwen2-7B-Instruct --port 8000 --dtype float16 AI写代码 常用启动参数:
--port:服务端口(默认 8000) --host:监听地址(默认 0.0.0.0,即所有网络接口) --dtype:数据类型(float16 可节省显存) --tensor-parallel-size:使用的 GPU 数量(多卡并行) --gpu-memory-utilization:GPU 显存利用率上限(如 0.9) 4.2 用 curl 测试服务 打开另一个终端,用 curl 发送请求:
curl http://localhost:8000/v1/chat/completions
-H "Content-Type: application/json"
-d '{
"model": "mistralai/Mistral-7B-Instruct-v0.3",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
],
"max_tokens": 100
}'
AI写代码
你会收到类似这样的 JSON 响应:
{ "id": "cmpl-xxx", "object": "chat.completion", "created": 1712345678, "model": "mistralai/Mistral-7B-Instruct-v0.3", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "The capital of France is Paris." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 23, "completion_tokens": 6, "total_tokens": 29 } } AI写代码
4.3 用 Python 客户端调用 你可以用 OpenAI 的 Python 库来调用 vLLM 服务,只需修改 base_url:
from openai import OpenAI
初始化客户端,指向本地 vLLM 服务
client = OpenAI( base_url="http://localhost:8000/v1", api_key="dummy" # vLLM 不验证 key,但需要提供一个非空字符串 )
发送聊天请求
response = client.chat.completions.create( model="mistralai/Mistral-7B-Instruct-v0.3", # 必须和服务启动时的 model 一致 messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Explain quantum computing in simple terms."} ], max_tokens=200, temperature=0.7 )
print(response.choices[0].message.content) AI写代码
这意味着你可以用 vLLM 作为 OpenAI API 的本地替代品,无缝集成到现有应用中。
4.4 启用流式输出 对于聊天应用,流式输出能提供更好的用户体验。只需在请求中添加 stream=True:
服务端启动方式不变
客户端代码
stream = client.chat.completions.create( model="mistralai/Mistral-7B-Instruct-v0.3", messages=[{"role": "user", "content": "Tell me a story about a cat."}], stream=True # 开启流式 )
for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) AI写代码
vLLM 原生支持流式输出,延迟更低。
第五部分:性能优化与常见问题 5.1 遇到显存不足怎么办? 如果你遇到 CUDA out of memory 错误,可以尝试以下方法:
方法一:降低精度
llm = LLM(model="your-model", dtype="float16") # 从 float32 降到 float16 AI写代码 方法二:启用量化
vllm serve your-model --quantization awq # 需要模型支持 AWQ 量化 AI写代码 量化可以大幅减少显存占用,4bit 量化通常能减少 50-75% 的显存。
方法三:限制上下文长度
llm = LLM( model="your-model", max_model_len=2048, # 默认可能 4096 或 8192 ) AI写代码 方法四:减少批处理大小
llm = LLM( model="your-model", max_num_seqs=8, # 同时处理的请求数 max_num_batched_tokens=4096 # 每批处理的 token 总数上限 ) AI写代码 5.2 如何进一步提升吞吐量? 张量并行(多 GPU) 如果你有多张 GPU,可以用张量并行将模型切分到多卡:
vllm serve your-model --tensor-parallel-size 2 # 使用 2 张 GPU AI写代码 注意:张量并行会引入通信开销,建议在同一台机器上使用 NVLink 连接的多卡。
调整块大小
llm = LLM( model="your-model", block_size=32 # 默认 16,增大块大小可能减少调度开销 ) AI写代码 关闭 CUDA Graph CUDA Graph 会预编译一些操作以提高速度,但会占用额外显存。如果显存紧张,可以关闭:
llm = LLM( model="your-model", enforce_eager=True # 禁用 CUDA Graph ) AI写代码 5.3 常见问题排查 问题
可能原因
解决方案
服务启动慢
正在下载模型
提前用 huggingface-cli 下载模型到缓存
第一次推理很慢
CUDA kernel 编译
这是正常现象,后续调用会加速
输出重复或无意义
temperature 过高或过低
调整 temperature 到 0.5-0.9 之间
模型返回乱码
数据类型不匹配
检查 dtype 设置,确保与模型匹配
多卡通信失败
NCCL 配置问题
检查 GPU 之间的 NVLink 或 PCIe 连接
5.4 监控服务健康 vLLM 提供了健康检查端点:
curl http://localhost:8000/health AI写代码 返回 {"status": "healthy"} 表示服务正常。这在容器化部署和负载均衡时很有用。
第六部分:真实场景案例——用 vLLM 部署 DeepSeek-R1 最近 DeepSeek 系列模型非常火,下面我们演示如何用 vLLM 部署 DeepSeek-R1-Distill-Qwen-32B 模型。
6.1 环境准备
确保有足够的显存(32B 模型推荐 24GB+ 显存)
pip install vllm transformers
下载模型(如果网络慢,可以先在本地下载)
huggingface-cli download deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
AI写代码
6.2 启动服务
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-32B
--tensor-parallel-size 1 \ # 单卡部署
--dtype bfloat16
--max-model-len 8192
--gpu-memory-utilization 0.9
--port 8000
AI写代码
6.3 调用示例
from openai import OpenAI
client = OpenAI( base_url="http://localhost:8000/v1", api_key="dummy" )
response = client.chat.completions.create( model="deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", messages=[ {"role": "user", "content": "用 Python 实现一个快速排序算法"} ], max_tokens=1000, temperature=0.6 )
print(response.choices[0].message.content) AI写代码
6.4 性能对比 在同样的硬件上(RTX 4090, 24GB 显存),用 vLLM 部署 DeepSeek-32B 相比直接用 HuggingFace Transformers:
吞吐量提升:约 3-5 倍 并发能力:从只能同时处理 1-2 个请求,提升到可以同时处理 8-10 个请求 首字延迟:略有降低,但总体生成速度更快 总结与进阶学习路径 恭喜!现在你已经掌握了 vLLM 的核心用法。让我们快速回顾一下:
你已经学会的 ✅ 理解 vLLM 的核心原理:PagedAttention 和 Continuous Batching ✅ 安装 vLLM 并运行离线推理 ✅ 部署 OpenAI 兼容的 API 服务 ✅ 用 Python 和 curl 调用服务 ✅ 处理常见问题和优化性能
进阶学习方向 如果你还想更深入地学习,可以探索以下内容:
多模态模型支持:vLLM 也开始支持图像、视频等多模态输入 LoRA 适配器:动态加载多个 LoRA 适配器,实现模型的多任务切换 结构化输出:用 JSON Schema 约束模型输出格式 分布式部署:用 Ray 实现跨节点的分布式推理 自定义模型注册:将自己的模型适配到 vLLM 资源推荐 官方文档:docs.vllm.ai(最权威,建议收藏) GitHub 仓库:github.com/vllm-projec… 论文:《Efficient Memory Management for Large Language Model Serving with PagedAttention》 写在最后 vLLM 的出现,大大降低了大模型部署的门槛和成本。以前需要多张昂贵 GPU 才能支撑的服务,现在可能一张卡就能搞定。对于个人开发者、中小企业来说,这无疑是个好消息。
希望这篇教程能帮你快速上手 vLLM,在实际项目中用起来。如果在使用中遇到问题,欢迎随时交流——毕竟,AI 的世界里,我们都在摸着石头过河。
现在,打开你的终端,开始你的第一个 vLLM 项目吧! ———————————————— 版权声明:本文为CSDN博主「水上冰石」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/jiao_zg/art…