课程导入:学习目标、核心概念、整体框架
欢迎来到《PagedAttention机制深度解析》课程。在正式进入技术细节之前,我们需要先建立对整个知识版图的清晰认知。PagedAttention并非一个孤立的算法,而是连接着操作系统虚拟内存管理、GPU硬件架构、大语言模型推理引擎等多个领域的交叉创新。本章将帮助你明确学习目标、掌握核心概念,并构建起贯穿后续29章的整体框架。
1.1 学习目标:从“会用”到“能改”
完成本课程后,你应当具备以下四个层次的能力。这四个层次层层递进,对应着不同的职业角色与工程深度:
| 层次 | 能力描述 | 对应角色 |
|---|---|---|
| 第一层:理解 | 能清晰解释PagedAttention解决的核心问题(KV Cache碎片化与冗余),并对比其与朴素注意力机制的内存管理差异。 | 算法工程师 |
| 第二层:应用 | 能在vLLM、SGLang等推理框架中配置相关参数,识别并规避显存溢出(OOM)风险。 | 推理优化工程师 |
| 第三层:分析 | 能通过Profiling工具观察KV Cache的物理块分配情况,定位吞吐瓶颈。 | 性能分析专家 |
| 第四层:改造 | 能基于PagedAttention思想,为自定义注意力变体(如GQA、MLA)设计专属的内存管理方案。 | 系统架构师 |
1.2 核心概念:KV Cache与显存墙
要理解PagedAttention,必须先理解它要解决的问题——KV Cache。在自回归生成过程中,模型需要反复计算注意力分数。为了避免重复计算历史token的Key和Value矩阵,推理引擎会将其缓存在显存中,这就是KV Cache。
KV Cache的大小与序列长度和层数呈线性关系,且增长极快。以LLaMA-7B模型为例,当batch size为1、序列长度为2048时,KV Cache约占显存的1.2GB;当batch size增至32时,仅KV Cache就需要约38GB显存——这已经超过了单张A100(80GB)的一半容量。更棘手的是,KV Cache的显存分配是动态且碎片化的:
- 预分配浪费:传统方式按最大序列长度预分配连续显存,但实际生成长度往往远小于上限,导致大量显存闲置。
- 内部碎片:不同序列长度不同,连续分配方式导致显存空洞无法被其他序列利用。
- 无法共享:并行采样(如beam search)时,多个序列共享前缀,但传统方式无法共享KV Cache,造成重复存储。
PagedAttention的核心思想,正是借鉴操作系统中的虚拟内存分页机制,将KV Cache划分为固定大小的物理块(Block),通过块表(Block Table)实现逻辑地址到物理地址的映射。这样,KV Cache不再需要连续显存,碎片化问题迎刃而解。
上图展示了PagedAttention的核心映射关系。左侧是某个序列的逻辑视图,它认为自己拥有连续的4个块(逻辑块0-3)。右侧是真实的物理显存,这些块分散在不同的物理地址上。中间的块表记录了逻辑块到物理块的映射。当序列需要访问第5个逻辑块时,只需在块表中新增一条记录,而无需移动已有数据。
1.3 整体框架:课程四大模块
本课程共30章,分为四大模块,每个模块解决一个核心问题。建议你按照顺序学习,因为后续章节会频繁引用前面的概念。
模块一:基础与动机(第1-6章)——回答“为什么需要PagedAttention”。包括KV Cache的显存模型、朴素注意力机制的内存瓶颈、以及传统显存管理的三大缺陷(预分配浪费、内部碎片、无法共享)。
模块二:核心机制(第7-15章)——深入PagedAttention的每一个设计决策。包括块大小选择、块表数据结构、物理块分配与回收算法、以及如何支持beam search中的KV Cache共享。
模块三:工程实现(第16-24章)——聚焦vLLM框架中的实际代码。包括PagedAttention的CUDA kernel实现、与PyTorch的接口设计、显存Profiling工具的使用,以及多GPU场景下的块迁移策略。
模块四:进阶与展望(第25-30章)——探讨PagedAttention的变体与未来。包括与FlashAttention的融合、在MoE模型中的应用、以及面向长序列场景的稀疏分页方案。
1.4 案例场景:一次显存OOM的排查
让我们通过一个真实场景来感受PagedAttention的价值。假设你在部署一个13B参数的对话模型,使用传统的连续显存分配方式:
# 传统方式:预分配最大长度显存
max_seq_len = 2048
batch_size = 8
kv_cache_bytes = batch_size * max_seq_len * num_layers * 2 * head_dim * num_heads * 2 # 约 12.8 GB
# 实际平均生成长度只有 512,浪费了 75% 的显存
当并发请求增多时,显存很快耗尽,服务返回OOM错误。而使用PagedAttention后,KV Cache按需分配:
# PagedAttention方式:按实际长度分配物理块
block_size = 16 # 每个块存储16个token的KV
# 序列A实际长度512 → 分配32个物理块
# 序列B实际长度128 → 分配8个物理块
# 序列C实际长度1024 → 分配64个物理块
# 总显存 = (32+8+64) * block_size * per_block_bytes ≈ 4.2 GB
# 相比传统方式节省约 67% 显存
1.5 本章小结与学习路径
本章我们完成了三件事:明确了四个层次的学习目标(理解、应用、分析、改造);建立了KV Cache与显存墙的核心概念;构建了四大模块的整体框架。现在,你已经具备了进入下一章的基础。
在继续之前,请确保你能回答以下三个问题:
- KV Cache的显存占用与哪些参数呈线性关系?为什么说它是“动态且碎片化”的?
- PagedAttention借鉴了操作系统的什么机制?块表的作用是什么?
- 传统连续分配方式存在哪三大缺陷?PagedAttention分别如何解决?