vLLM核心原理:PagedAttention机制、KV Cache管理、连续批处理、vLLM架构总览
大家好,我是你们的老朋友。今天我们来聊聊vLLM的核心原理。说实话,我第一次看到PagedAttention这个名字时,第一反应是——这不就是操作系统的虚拟内存吗?后来仔细一读论文,嘿,还真是这么回事。但别急,我们一步步来。
一、KV Cache:大模型推理的“内存杀手”
先说说KV Cache。你想想看,大模型做推理时,每次生成一个token,都要重新计算前面所有token的Key和Value吗?当然不是。那样太慢了。实际做法是把之前算好的K和V缓存起来,这就是KV Cache。
但问题来了。这个缓存有多大?我给大家算笔账。假设模型是13B参数,序列长度2048,batch size是4。每个token的KV Cache大概需要2 * 5120 * 4 * 4 = 160KB(以FP16计算)。2048个token就是320MB。4个请求同时跑,就是1.28GB。这还只是一个小场景。实际生产环境中,并发请求一多,显存很快就爆了。
我在项目中遇到过这种情况。有一次部署一个70B的模型,8张A100,结果并发一上来,直接OOM。排查了半天,发现是KV Cache管理太粗糙了。每个请求都预分配最大长度的空间,但实际生成的序列长度差异很大,浪费严重。
核心痛点:传统KV Cache管理存在严重的内存碎片和浪费问题。每个请求预分配固定大小的连续显存,但实际使用率可能只有30%-50%。
二、PagedAttention:像操作系统管理内存一样管理KV Cache
vLLM的解决方案是什么?PagedAttention。说白了,就是把操作系统的分页机制搬到了显存管理上。
传统做法是给每个请求分配一整块连续显存。PagedAttention不一样,它把KV Cache切成固定大小的“块”(block),每个块可以存放若干个token的K和V。这些块在显存中不要求连续,通过一个“页表”来映射逻辑位置到物理位置。
为什么会这样设计?你想想看,操作系统的虚拟内存解决了什么问题?解决了物理内存碎片和按需分配的问题。PagedAttention也是一样。每个请求不再需要预分配一整块连续显存,而是按需分配一个个小块。用完了就回收,给其他请求用。
嗯,这里要注意。PagedAttention的块大小是个关键参数。我个人的习惯是设成16或32个token。太小了,页表开销大;太大了,又回到预分配的老路上去了。
避坑指南:我曾经在一个项目中把块大小设成了64,结果发现短序列请求的内存利用率反而下降了。后来改成16,效果好了很多。建议根据你的平均序列长度来调这个参数。
三、连续批处理:让GPU一刻也不闲着
讲完KV Cache管理,我们来说说连续批处理。这个机制是vLLM高性能的关键之一。
传统批处理是怎么做的?等一批请求都到齐了,一起推理。但问题是,每个请求的生成长度不一样。有的生成10个token就结束了,有的要生成100个。先结束的请求占着位置,GPU资源白白浪费。
连续批处理的做法是:动态调整batch。当一个请求生成完了,立即把它移出batch,同时把一个新的请求加进来。这样GPU始终在处理有效的计算,不会空转。
我举个例子。假设batch size是4,有8个请求在排队。传统做法是等4个请求全部生成完,再处理下一批。连续批处理呢?第一个请求生成完了,立刻把它踢出去,把第5个请求拉进来。GPU利用率从60%直接提升到95%以上。
关键点:连续批处理的核心是“抢占式调度”。每个请求的生成过程可以被中断,等新请求加入后继续。这要求KV Cache管理必须支持动态增删,PagedAttention正好提供了这个能力。
四、vLLM架构总览:一张图看懂
好了,我们把前面讲的串起来。vLLM的整体架构是什么样的?我画了一张图,大家看看。
从这张图可以看出,vLLM的核心架构分为四层:
- 请求调度器:负责接收请求,决定何时加入batch
- 三个核心模块:PagedAttention、KV Cache管理器、连续批处理器,它们互相配合
- 推理执行引擎:实际运行LLM模型的地方
- 输出结果:生成的内容返回给用户
这三个核心模块的关系是这样的:连续批处理器决定哪些请求在batch里,KV Cache管理器负责给这些请求分配显存块,PagedAttention则用这些块完成注意力计算。三者缺一不可。
注意:vLLM的架构设计有一个隐含假设——模型支持动态batch。如果你的模型不支持(比如某些定制化的模型),那连续批处理就用不了。我踩过这个坑,大家引以为戒。
五、总结:vLLM为什么快?
好了,我们来总结一下。vLLM之所以快,核心原因有三个:
- PagedAttention:解决了KV Cache的内存碎片问题,显存利用率从50%提升到95%以上
- KV Cache管理器:按需分配、及时回收,支持动态增删
- 连续批处理:让GPU一刻也不闲着,吞吐量提升2-4倍
这三个机制加在一起,vLLM才能在同样的硬件上,跑出比传统方案高得多的吞吐量。我个人觉得,PagedAttention是其中最巧妙的设计。它把操作系统几十年的内存管理经验,用到了大模型推理上,这个思路值得学习。
下一章我们会动手搭建vLLM集群,到时候你会更深刻地体会到这些原理在实际部署中的作用。