1. vLLM 初探:什么是 vLLM?为什么需要它?PagedAttention 原理简介
1.1 大模型推理的痛点:我踩过的坑
先说说我自己的经历。几年前我刚接触大模型推理时,用的是最朴素的 Hugging Face Transformers 库。跑一个 7B 模型,单条请求还好,一旦并发上来,显存直接爆掉。更头疼的是——明明显存还有空间,但就是放不下新的请求。
为什么会这样?说白了,传统推理框架的内存管理太粗糙了。每个请求进来,系统会预先分配一大块连续显存,用来存 KV cache(键值缓存)。但问题是,你根本不知道这个请求会生成多长的输出。预分配少了,生成到一半显存不够;预分配多了,又白白浪费。
我印象很深,有一次线上服务,用户请求的生成长度差异特别大。有的只生成 10 个 token,有的要生成 2000 个。结果呢?显存碎片化严重,利用率不到 40%。那段时间我天天盯着监控面板,心里那个急啊。
- 显存浪费:预分配策略导致大量空间闲置
- 碎片化:不同长度的请求互相干扰
- 并发受限:显存利用率低,QPS 上不去
1.2 vLLM 是什么?
vLLM 就是来解决这些问题的。它是一个高性能的大模型推理引擎,由加州大学伯克利分校的研究团队开源。我个人觉得,它最大的贡献不是跑得快,而是把显存用到了极致。
vLLM 的核心思想很简单:像操作系统管理内存一样管理显存。你想想看,操作系统是怎么处理内存的?分页、虚拟内存、按需分配。vLLM 借鉴的就是这套思路。
具体来说,vLLM 做了三件事:
- 动态显存分配:不再预分配一整块,而是按需分配小单元
- 高效缓存复用:相同前缀的请求共享 KV cache
- 连续批处理:请求可以随时加入或退出,不阻塞
嗯,这里要注意,vLLM 不是万能的。它主要优化的是解码阶段(生成 token 的过程),预填充阶段(处理输入 prompt)的优化相对有限。但实际场景中,解码阶段占了 80% 以上的时间,所以收益非常明显。
1.3 为什么需要 vLLM?
我直接说结论:没有 vLLM,你很难把大模型推理的成本降下来。
举个例子。我之前用原生 PyTorch 部署一个 13B 模型,单卡 A100 只能同时处理 4 个请求,显存占用 75GB。换成 vLLM 后,同样的硬件,并发数提升到了 16,显存占用反而降到了 50GB。你算算,吞吐量提升了 4 倍。
为什么会差这么多?关键在于 vLLM 的连续批处理机制。传统框架必须等一个批次的所有请求都生成完毕,才能处理下一批。vLLM 不一样,它允许请求动态加入和退出。比如,一个短请求生成完了,立刻释放资源给新请求,不用等长请求。
1.4 PagedAttention 原理简介
PagedAttention 是 vLLM 的核心创新。名字很形象——分页注意力,灵感来自操作系统的分页内存管理。
先回顾一下传统 Attention 是怎么存 KV cache 的。每个请求的 KV cache 是一块连续显存,形状是 [num_layers, num_heads, seq_len, head_dim]。seq_len 会随着生成过程不断增长,所以你必须提前预留最大长度。这就像你租房子,明明只需要住 30 平米,房东非要你租 100 平米的,剩下的空间空着也不让你用。
PagedAttention 的做法是:把 KV cache 切成固定大小的块(Block),每个块可以独立分配和释放。请求的 KV cache 不再是一整块连续内存,而是由多个块组成的逻辑页表。
我画了一张图,帮你理解这个结构:
你看,传统方式是一整块连续内存,中间有大量空洞。PagedAttention 把显存切成小块,每个请求只占用需要的块数,而且这些块在物理上可以不连续。这就解决了碎片化问题。
更妙的是,PagedAttention 还支持块级别的内存共享。如果多个请求有相同的前缀(比如系统提示词),它们的 KV cache 可以共用同一个物理块。这在对话场景中特别有用——所有用户共享系统提示词的 KV cache,能省下 30%-50% 的显存。
1.5 核心优势一览
我把 vLLM 和传统方案做了个对比,你一看就明白:
| 对比维度 | 传统方案 | vLLM |
|---|---|---|
| 显存分配 | 预分配连续块 | 按需分配小块 |
| 显存利用率 | 40%-60% | 85%-95% |
| 并发能力 | 低(受碎片化限制) | 高(动态调度) |
| 前缀共享 | 不支持 | 支持 |
| 批处理方式 | 静态批处理 | 连续批处理 |
1.6 什么时候该用 vLLM?
我个人的经验是,以下场景 vLLM 的收益最大:
- 高并发在线服务:比如聊天机器人、API 网关,请求到达时间随机
- 变长生成:输出长度从几十到几千不等,传统方案很难优化
- 共享前缀场景:比如所有请求都带相同的系统提示词
- 显存受限:比如你只有单卡 A100,但想跑 13B 甚至 30B 模型
反过来,如果你的场景是固定长度批量推理(比如离线打分),或者模型本身很小(比如 1B 以下),vLLM 的优势就不明显了。这时候用 Hugging Face 的 pipeline 反而更简单。
vllm.entrypoints.openai.api_server 启动服务,然后用 vllm bench 压测。看看显存占用和吞吐量,再决定要不要上生产。
好了,这一章就到这里。PagedAttention 的原理其实不复杂,但它的设计思路非常值得学习——把操作系统的内存管理思想引入深度学习推理,这个跨界创新确实漂亮。