在你提供的这篇关于 vLLM(一种高效的大型语言模型服务系统)的论文中,作者指出了现有 LLM 推理系统在管理 KV Cache(Key-Value 缓存)时存在严重的内存效率问题,并特别提到了两个关键概念:

  • Internal Memory Fragmentation(内部内存碎片)
  • External Memory Fragmentation(外部内存碎片)

下面我们来详细解释这两个术语的含义、它们在 LLM 服务中的具体表现以及为什么会造成资源浪费。


🌟 背景知识:KV Cache 是什么?

在自回归生成(如 GPT 生成文本)过程中,模型每生成一个新 token,都需要访问之前所有 token 的 注意力 Key 和 Value 向量,这些信息被缓存起来,称为 KV Cache

由于序列长度可变且逐步增长,KV Cache 需要动态扩展。它的生命周期和大小在请求开始时是未知的(not known a priori),这给内存管理带来了挑战。

为了兼容深度学习框架(如 PyTorch)对连续内存的要求,传统系统会为每个请求预先分配一块连续的内存空间用于存放整个 KV Cache。

这就引出了我们今天要讲的核心问题:内存碎片化


一、Internal Memory Fragmentation(内部内存碎片)

✅ 定义:

内部碎片是指已分配给某个任务的内存块中,未被实际使用但也不能被其他任务使用的部分。

🔍 在 vLLM 论文中的体现:

假设一个用户请求的最大可能序列长度是 2048 tokens,系统就会提前为其分配足够存储 2048 个 token 的 KV Cache 的连续内存空间。

但是,这个请求最终可能只生成了 300 个 token。

👉 那么剩下的 2048 - 300 = 1748 个 token 所对应的内存空间虽然从未被使用,但仍被该请求“独占”,不能分配给别的请求。

这部分空闲却无法利用的空间就是 内部碎片

🎯 关键点总结:

  • 原因:过度预分配(over-provisioning)
  • 特征:内存属于某个请求,但没有被用上
  • 结果:造成严重浪费 —— 论文中指出,实际有效利用率只有 20.4% ~ 38.2%

📌 类比操作系统:就像操作系统给进程分配一页内存(比如 4KB),但程序只用了 1KB,剩下 3KB 就是内部碎片。


二、External Memory Fragmentation(外部内存碎片)

✅ 定义:

外部碎片是指系统中总的可用内存足够,但由于这些空闲内存不连续,导致无法满足一个需要大块连续内存的请求。

🔍 在 vLLM 论文中的体现:

想象一下,GPU 上有很多小块的空闲内存(比如多个 512-token 大小的空隙),但现在来了一个新的请求,需要一块能容纳 1024 个 token 的连续内存空间

尽管总共有超过 1024 个 token 的空闲内存,但如果这些内存是分散的、不连续的,系统仍然无法分配,只能报错或拒绝服务。

这就是 外部碎片

此外,不同请求预分配的大小不同(有的 512,有的 1024,有的 2048),释放后留下各种尺寸的小块内存,加剧了这种碎片问题。

🎯 关键点总结:

  • 原因:频繁地分配/释放不同大小的连续内存块
  • 特征:总量够,但不连续 → 分配失败
  • 影响:降低内存利用率,限制并发请求数量

📌 类比操作系统:就像硬盘上有许多零散的空闲扇区,无法存入一个大文件,即使总空间足够。


💡 总结对比表

项目 内部碎片 (Internal Fragmentation) 外部碎片 (External Fragmentation)
定义 已分配内存中未使用的部分 空闲内存总量足够但不连续
发生位置 在已分配的内存块内部 在全局内存池中
主要原因 预分配最大长度,实际用得少 不同大小的连续块分配与释放
是否“属于”某个请求 是,被某个请求独占 否,是自由内存池的一部分
典型例子 分配了 2048 token 空间,只用了 300 总共剩 1500 token 空间,但最大小块只有 512
论文数据支持 图2显示仅 20.4%-38.2% 内存被有效使用 同样反映在图2的整体低效中

🛠️ vLLM 如何解决这些问题?——PagedAttention

论文提出的解决方案叫 PagedAttention,灵感来自操作系统的虚拟内存分页机制

核心思想:

将 KV Cache 按固定大小划分为多个 block(块),每个 block 可以存储 N 个 token 的 KV 数据(例如 N=16)。

这些 block 不需要在物理内存中连续存放,通过一个“页表”记录逻辑顺序到物理 block 的映射。

就像操作系统把进程的地址空间分成页,映射到物理内存页一样。

这样做的好处:

  1. 消除内部碎片:按需分配 block,不会为一个短请求预留过多空间。
  2. 避免外部碎片:只需要找到任意空闲 block 即可分配,不要求大块连续内存。
  3. 支持内存共享:多个解码路径(如 Beam Search 中的不同 beam)可以共享公共前缀的 block,进一步节省内存。

✅ 总结一句话:

传统方法因强制使用连续内存而导致严重的 内部碎片(浪费已分配空间)和 外部碎片(无法利用零散空间);而 vLLM 的 PagedAttention 借鉴操作系统分页思想,将 KV Cache 分块管理,显著提升了内存利用率和系统吞吐量。

如果你还想了解 PagedAttention 的具体实现细节或性能提升数据,也可以继续问我!

外部碎片示意图:
转自:在这里插入图片描述

在这里插入图片描述

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐