先说效果:vLLM真能让推理快10倍?
我最近试了vLLM,结论是:确实能快,但不是所有场景都10倍。在批量处理请求时,吞吐量提升2-10倍很常见,尤其是显存紧张时。比如我用A100跑Llama 2-7B,传统方法同时处理8个请求就爆显存,vLLM能轻松处理64个,速度提升明显。但如果是单次推理,加速有限,主要优势在并发。
vLLM的核心是PagedAttention,它解决了大模型推理中的显存浪费问题。下面我拆开讲原理,再教你怎么用。
PagedAttention原理:为什么传统KV Cache那么浪费显存?
在Transformer推理时,每次生成新token,都需要缓存之前所有token的Key和Value(KV Cache),供注意力机制使用。传统做法是连续分配显存,就像这样:
# 传统KV Cache分配(简化示意)
kv_cache = allocate_contiguous_memory(seq_len, hidden_size) # 为整个序列分配一块连续显存
问题来了:
- 显存碎片化:不同请求序列长度不同,长序列占大块,短序列占小块,显存用不紧凑。
- 预留浪费:为防序列变长,往往按最大可能长度分配,但实际很多序列用不完,比如分配了4096长度,实际只用了512,剩下全浪费。
- 并发瓶颈:显存利用率低,能同时处理的请求数就少,吞吐量上不去。
我打个比方:传统方法像订酒店房间,不管住几天,都按最长可能住期(比如30天)预订,钱先扣了,实际可能只住3天,浪费27天的钱。
PagedAttention怎么解决?像操作系统管理内存一样管显存
vLLM的PagedAttention借鉴了操作系统的虚拟内存和分页思想。把KV Cache分成固定大小的“页”(比如每个页存16个token的KV),显存中物理页按需分配,逻辑上通过页表映射。
具体步骤:
- 分页:KV Cache不再连续存,而是拆成多个固定大小的页(block)。例如,每页16个token,序列长512就需要32页。
- 按需分配:生成token时,需要新页才分配物理显存,不用提前预留。
- 页表管理:每个请求维护一个页表,记录逻辑页到物理页的映射,类似操作系统的页表。
# PagedAttention示意(非真实代码)
class PagedKVCache:
def __init__(self, block_size=16):
self.blocks = [] # 物理页池
self.page_tables = {} # 请求ID -> 逻辑页到物理页的映射
def allocate_for_request(self, request_id, seq_len):
# 按需分配页,比如seq_len=50,需要ceil(50/16)=4页
num_pages = ceil(seq_len / block_size)
for i in range(num_pages):
if 物理页池有空闲页:
分配物理页
else:
新申请物理页
更新页表: 逻辑页i -> 物理页地址
好处:
- 显存利用率高:页是固定大小,不同请求可以共用物理页池,碎片减少。
- 灵活伸缩:序列变长时,只需分配新页,不用整体重分配。
- 提升并发:同样显存能存更多请求的KV Cache,批量处理时吞吐量飙升。
对比一下:传统方法像“包场”,PagedAttention像“拼桌”,桌子(页)固定,来多少人拼多少桌,空间利用最大化。
普通用户怎么用vLLM部署自己的模型?实战步骤
假设你有个Hugging Face模型,想用vLLM加速推理。我以Llama 2-7B为例,步骤亲测可用。
步骤1:安装vLLM
推荐用pip安装,注意Python版本≥3.8。
pip install vllm
如果网络慢,可以用镜像:
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple
步骤2:准备模型
vLLM支持Hugging Face格式的模型。确保你有模型文件(本地或HF仓库)。例如,Llama 2需要先申请权限,但可以用公开替代模型如“meta-llama/Llama-2-7b-chat-hf”(需HF token)。
我常用本地模型,下载到`./models/llama-2-7b-chat`。
步骤3:启动vLLM服务器
用命令行启动,指定模型路径和端口。
python -m vllm.entrypoints.openai.api_server \
--model ./models/llama-2-7b-chat \
--port 8000 \
--tensor-parallel-size 1 # 单GPU
参数说明:
- `--model`:模型路径或HF模型ID。
- `--port`:服务端口,默认8000。
- `--tensor-parallel-size`:GPU数量,多卡并行用。
- `--max-model-len`:最大序列长度,默认2048,根据显存调整。
启动后,看到“Uvicorn running on http://0.0.0.0:8000”就成功了。
步骤4:发送请求测试
vLLM兼容OpenAI API格式,用curl或Python调用。
# Python示例
from openai import OpenAI
client = OpenAI(
api_key="token-abc123", # 任意字符串
base_url="http://localhost:8000/v1"
)
response = client.completions.create(
model="./models/llama-2-7b-chat",
prompt="Hello, how are you?",
max_tokens=50
)
print(response.choices[0].text)
或者用curl:
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "./models/llama-2-7b-chat",
"prompt": "Hello, world",
"max_tokens": 50
}'
步骤5:高级配置(按需)
- 批处理大小:vLLM自动批处理,可通过`--max-num-batched-tokens`调整。
- 量化:用`--quantization awq`等支持量化模型,减少显存占用。
- 多GPU:设置`--tensor-parallel-size 2`等,需GPU间互联。
注意事项和总结
我用了几个月,总结几点:
- 优势场景:高并发推理、显存受限时提升大。单次推理加速不明显。
- 兼容性:vLLM支持主流模型如Llama、GPT-NeoX,但自定义模型可能需要适配。
- 显存管理:PagedAttention减少浪费,但仍有开销(页表等),极端小显存场景需测试。
- 实践建议:先从小模型试起,调整`--max-model-len`避免OOM;生产环境用Docker部署更稳定。
总之,vLLM的PagedAttention是个巧妙设计,把系统优化思路用到了AI推理上。对于普通用户,部署不难,效果在批处理场景下确实显著。如果你玩大模型,值得一试。
有具体问题,欢迎来我博客298.name交流。
本文来源:一江山水的随笔
本文地址:https://298.name/post/186.html
主要内容:vLLM让大模型推理快10倍?PagedAttention原理详解与实战部署
版权声明:如无特别注明,转载请注明本文地址!
