vLLM 从入门到实战:让你的大模型推理快如闪电

14 阅读12分钟

前言:为什么你需要认识 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…