【vllm】(vllm kv_offload)vLLM V1 KV Offload—(一)模块定位与整体结构
vLLM v1 KV Offload 模块 — 超深度架构分析(一):模块定位与整体结构
·
vLLM v1 KV Offload 模块 — 超深度架构分析(一):模块定位与整体结构
分析基于源码目录:
github.com/vllm/vllm/v1/kv_offload
总计 16 个 Python 文件,约 1,398 行代码
一、模块定位
图 1:系统上下文图 — kv_offload 在 vLLM 中的位置
1.1 业务职责
kv_offload 模块是 vLLM v1 架构中 KV Cache 卸载(Offloading) 子系统的完整实现。其核心业务职责是:
| 职责维度 | 描述 |
|---|---|
| KV Cache 换出(GPU → CPU) | 将 GPU 显存中暂时不用的 KV Cache 块搬移到 CPU 内存,释放 GPU 显存供活跃请求使用 |
| KV Cache 换入(CPU → GPU) | 当需要重用已卸载的 KV Cache 时,将其从 CPU 内存加载回 GPU 显存 |
| 块级缓存管理 | 以 block 为粒度管理卸载数据的生命周期,包括分配、驱逐、引用计数、状态跟踪 |
| 替换策略 | 支持可插拔的缓存淘汰策略(LRU / ARC),决定哪些块应被驱逐 |
| 复用频率过滤 | 通过装饰器模式过滤低频复用的块,避免将只用一次的块卸载到 CPU |
| 共享内存管理 | 通过 mmap 机制实现多 Worker 间的 CPU 内存共享,避免数据冗余 |
| 异步传输管线 | 基于 CUDA Stream + Event 的异步传输管线,保证传输顺序性同时不阻塞计算 |
1.2 功能定位
本模块解决的核心问题是 GPU 显存容量有限而 KV Cache 随请求增长 的矛盾:
┌──────────────────────────────────────────────────────────┐
│ 问题空间 │
│ │
│ GPU VRAM (有限) CPU DRAM (充裕) │
│ ┌─────────┐ ┌──────────────┐ │
│ │ Active │ ←── 需要换出 ────→ │ Offloaded │ │
│ │ KV Cache│ ←── 需要换入 ────→ │ KV Cache │ │
│ └─────────┘ └──────────────┘ │
│ │
│ 当 GPU KV Cache 满时: │
│ ① 简单策略:直接丢弃 → 浪费计算(需重新计算) │
│ ② 卸载策略:搬到 CPU → 需要时可恢复 → kv_offload 的价值 │
└──────────────────────────────────────────────────────────┘
1.3 在系统中的位置
kv_offload 模块横跨 vLLM 的 调度器(Scheduler) 和 工作器(Worker) 两大组件,形成经典的 “控制面 + 数据面” 分离架构:
┌─────────────────────────────────────────────────────────────────┐
│ vLLM v1 整体架构 │
│ │
│ ┌─────────────────┐ ┌──────────────────┐ │
│ │ Scheduler │ │ Worker(s) │ │
│ │ (控制面) │ │ (数据面) │ │
│ │ │ │ │ │
│ │ ┌─────────────┐ │ OffloadingSpec │ ┌──────────────┐ │ │
│ │ │Offloading │ │ ──────────────────→ │ │Offloading │ │ │
│ │ │Manager │ │ (调度器侧管理器) │ │Handler │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ • lookup │ │ LoadStoreSpec │ │ • transfer_ │ │ │
│ │ │ • prepare_ │ │ ──────────────────→ │ │ async │ │ │
│ │ │ load/store│ │ (传输规格) │ │ • get_ │ │ │
│ │ │ • complete_ │ │ │ │ finished │ │ │
│ │ │ load/store│ │ │ │ • wait │ │ │
│ │ └─────────────┘ │ │ └──────────────┘ │ │
│ │ │ │ │ │
│ │ 跟踪块状态 │ 控制指令 │ 执行实际传输 │ │
│ │ 管理驱逐策略 │ ════════════════════→ │ GPU↔CPU DMA │ │
│ │ 引用计数保护 │ │ │ │
│ └─────────────────┘ └──────────────────┘ │
│ │
│ ↑ kv_offload 模块覆盖范围 ↑ │
└─────────────────────────────────────────────────────────────────┘
关键交互路径:
- Scheduler 通过
OffloadingManager决策"哪些块需要卸载/加载" - Worker 通过
OffloadingHandler执行"实际的 DMA 数据搬移" - OffloadingSpec 是连接两者的规格对象,负责创建 Manager 和 Handler
- OffloadingSpecFactory 是工厂类,根据配置动态创建具体的 Spec
二、模块整体结构
2.1 目录结构
kv_offload/
├── __init__.py # 空包初始化文件
├── base.py # 核心抽象基类与数据结构定义(398行)
├── factory.py # OffloadingSpec 工厂(58行)
├── reuse_manager.py # 复用频率过滤装饰器(120行)
├── cpu/ # CPU 卸载实现子包
│ ├── __init__.py # 空
│ ├── common.py # CPULoadStoreSpec 定义(13行)
│ ├── spec.py # CPUOffloadingSpec 实现(102行)
│ ├── manager.py # CPUOffloadingManager 实现(204行)
│ ├── gpu_worker.py # GPU↔CPU 传输处理器(433行)
│ ├── shared_offload_region.py # mmap 共享内存区域(192行)
│ └── policies/ # 缓存替换策略子包
│ ├── __init__.py # 空
│ ├── base.py # CachePolicy 抽象 + BlockStatus(76行)
│ ├── lru.py # LRU 策略实现(46行)
│ └── arc.py # ARC 策略实现(156行)
└── worker/ # Worker 侧抽象子包
├── __init__.py # 空
└── worker.py # OffloadingHandler/Worker 抽象(176行)
2.2 类结构总览
2.3 接口定义与依赖注入关系
2.3.1 核心接口矩阵
| 接口 | 位置 | 实现者 | 消费者 | 设计模式 |
|---|---|---|---|---|
OffloadingSpec |
base.py | CPUOffloadingSpec |
Scheduler/Worker 初始化 | 工厂+策略 |
OffloadingManager |
base.py | CPUOffloadingManager, FilterReusedOffloadingManager |
Scheduler | 模板方法+装饰器 |
OffloadingHandler |
worker/worker.py | SingleDirectionOffloadingHandler |
OffloadingWorker |
策略 |
CachePolicy |
policies/base.py | LRUCachePolicy, ARCCachePolicy |
CPUOffloadingManager |
策略 |
LoadStoreSpec |
base.py | GPULoadStoreSpec, CPULoadStoreSpec |
Manager→Handler 数据传递 | 值对象 |
2.3.2 依赖注入关系
OffloadingSpecFactory
│ (根据配置创建)
▼
CPUOffloadingSpec ──────────────────────────────────────┐
│ │
├─ get_manager() │ get_handlers()
│ │ │
│ ▼ ▼
│ CPUOffloadingManager ◄── FilterReusedOffloadingManager (可选装饰)
│ │ │ CpuGpuOffloadingHandlers
│ └── CachePolicy ◄────────┘ (策略注入) │
│ ├── LRUCachePolicy ├── gpu_to_cpu_handler
│ └── ARCCachePolicy └── cpu_to_gpu_handler
│ │
│ SingleDirectionOffloadingHandler
│ (×2, 分别处理两个方向)
│ │
│ SharedOffloadRegion (可选)
│ (mmap 共享内存)
2.4 核心方法清单与作用
2.4.1 OffloadingManager(调度器侧 — 控制面)
| 方法 | 作用 | 调用时机 |
|---|---|---|
lookup(key, req_context) |
检查块是否已卸载且可读 | Scheduler 处理请求时 |
prepare_load(keys, req_context) |
准备加载,增加引用计数保护 | Scheduler 决定加载块时 |
touch(keys) |
标记块最近被使用 | 前缀缓存命中时 |
complete_load(keys) |
加载完成,释放引用计数 | Worker 完成加载后 |
prepare_store(keys, req_context) |
准备存储,可能触发驱逐 | Scheduler 决定卸载块时 |
complete_store(keys, success) |
存储完成/失败处理 | Worker 完成存储后 |
take_events() |
获取卸载事件流 | 事件监控 |
2.4.2 OffloadingHandler(工作器侧 — 数据面)
| 方法 | 作用 | 调用时机 |
|---|---|---|
transfer_async(job_id, spec) |
提交异步 DMA 传输 | Worker 收到传输指令时 |
get_finished() |
查询已完成传输 | Worker 轮询时 |
wait(job_ids) |
阻塞等待指定传输完成 | 需要同步时 |
shutdown() |
释放资源 | Worker 关闭时 |
2.4.3 CachePolicy(策略层)
| 方法 | 作用 |
|---|---|
get(key) |
查找块状态 |
insert(key, block) |
插入新块 |
remove(key) |
删除块 |
touch(keys) |
标记最近使用 |
evict(n, protected) |
驱逐 n 个块 |
2.5 内部调用关系
2.5.1 Store 流程(GPU → CPU 卸载)
图 4:Store 完整流程图(GPU → CPU 卸载)
2.5.2 Load 流程(CPU → GPU 加载)
图 5:Load 完整流程图(CPU → GPU 加载)
2.6 数据流入流出方式
2.6.1 数据流全景
┌─────────────────────┐
│ VllmConfig │
│ KVCacheConfig │
└────────┬────────────┘
│
┌────────▼────────────┐
│ OffloadingSpecFactory│ ← 输入:配置对象
│ .create_spec() │ → 输出:OffloadingSpec 实例
└────────┬────────────┘
│
┌──────────────┼──────────────┐
▼ │ ▼
┌─────────────────┐ │ ┌──────────────────┐
│ OffloadingManager│ │ │OffloadingHandler │
│ (Scheduler 侧) │ │ │ (Worker 侧) │
│ │ │ │ │
│ 输入: OffloadKey │ │ │ 输入: TransferSpec │
│ ReqContext │ │ │ job_id │
│ 输出: LoadStoreSpec│ │ │ 输出: TransferResult│
│ PrepareStore│ │ │ │
│ Output │ │ │ │
└─────────────────┘ │ └──────────────────┘
│
▼ LoadStoreSpec 作为桥梁
连接控制面(哪些块)与数据面(如何搬移)
2.6.2 关键数据结构流转
| 数据结构 | 创建者 | 消费者 | 传递方向 |
|---|---|---|---|
OffloadKey (bytes) |
Scheduler | Manager → Policy | 控制面内部 |
LoadStoreSpec |
Manager | → Worker Handler | 跨控制/数据面 |
GPULoadStoreSpec |
Manager | Handler | 包含 block_ids + group_sizes + block_indices |
CPULoadStoreSpec |
Manager | Handler | 包含 block_ids |
TransferSpec (src_spec, dst_spec) |
Scheduler/Worker | Handler | 数据面内部 |
TransferResult |
Handler | Worker → Scheduler | 数据面→控制面 |
PrepareStoreOutput |
Manager | Scheduler | 控制面内部 |
OffloadingEvent |
Manager | 外部监控系统 | 控制面→外部 |
三、模块层级关系与职责边界
3.1 四层架构
┌────────────────────────────────────────────────────────┐
│ Layer 4: 配置与工厂层 (factory.py) │
│ 职责:根据运行时配置创建具体 Spec │
│ 关键类:OffloadingSpecFactory │
├────────────────────────────────────────────────────────┤
│ Layer 3: 规格层 (base.py + cpu/spec.py) │
│ 职责:定义跨 Scheduler/Worker 的抽象契约 │
│ 关键类:OffloadingSpec, OffloadingManager, │
│ LoadStoreSpec, CanonicalKVCaches │
├────────────────────────────────────────────────────────┤
│ Layer 2: 策略与装饰器层 (policies/ + reuse_manager.py) │
│ 职责:可插拔的缓存淘汰策略 + 复用频率过滤 │
│ 关键类:CachePolicy, LRUCachePolicy, ARCCachePolicy, │
│ FilterReusedOffloadingManager │
├────────────────────────────────────────────────────────┤
│ Layer 1: 传输与存储层 (gpu_worker.py + │
│ shared_offload_region.py + worker/worker.py) │
│ 职责:实际 DMA 传输 + CPU 内存分配 + 共享内存 │
│ 关键类:SingleDirectionOffloadingHandler, │
│ CpuGpuOffloadingHandlers, SharedOffloadRegion │
└────────────────────────────────────────────────────────┘
3.2 职责边界
| 组件 | 知道什么 | 不知道什么 |
|---|---|---|
| OffloadingManager | 块的存在性、位置、引用计数、驱逐策略 | 具体传输方式、CUDA 操作、内存布局 |
| CachePolicy | 块的访问顺序、驱逐候选 | 引用计数、DMA 传输、事件系统 |
| OffloadingHandler | GPU/CPU 张量地址、CUDA Stream | 块的业务语义、驱逐决策 |
| SharedOffloadRegion | mmap 文件、内存布局、Worker 间偏移 | 块的生命周期、缓存策略 |
| FilterReusedOffloadingManager | 块的访问频率 | 块的物理存储位置、驱逐算法细节 |
图:组件依赖关系图
四、设计模式总结
| 模式 | 应用位置 | 说明 |
|---|---|---|
| 工厂模式 | OffloadingSpecFactory |
延迟加载 + 注册表,根据配置名创建 Spec |
| 策略模式 | CachePolicy → LRU/ARC |
可插拔的缓存淘汰算法 |
| 装饰器模式 | FilterReusedOffloadingManager |
包装底层 Manager,拦截 prepare_store |
| 模板方法 | OffloadingManager 的 prepare_store/complete_store |
定义骨架流程,子类/策略填充细节 |
| 迭代器模式 | CPUOffloadingSpec.get_handlers() |
yield 逐步返回 handler,支持多方向 |
| 对象池 | SingleDirectionOffloadingHandler 的 stream/event pool | 复用 CUDA Stream 和 Event,减少分配开销 |
| 生产者-消费者 | Manager(生产 LoadStoreSpec) → Handler(消费并执行) | 解耦决策与执行 |
文档一完成。接下来请参阅文档二(核心业务逻辑逐行解析)和文档三(架构图/流程图集合)。
更多推荐



所有评论(0)