Tutti: Making SSD-Backed KV Cache Practical for Long-Context LLM Serving Cross-paper analysis against 8 related entities in category framework
Tutti 的关联图谱沿三条主线展开:KV cache 内存管理与分层存储、CPU-GPU 异构计算/I/O 路径、分布式调度与 compute-I/O overlap。第三组(训练框架)通过 disaggregation 和 overlap 的通用设计模式间接关联。
| 论文 | 关联点 |
|---|---|
| vLLM / PagedAttention (2309.06180) | Tutti 构建在 vLLM 的 paged KV cache 之上——正是 vLLM 引入的固定大小 block 分配机制(block size 16–64 tokens)导致了碎片化 I/O 问题 [2309.06180]。Tutti 的 GPU file pool 直接映射 vLLM 的 KV block 粒度(每个 memory block → 一个 GPU file 的 $2L$ objects)[2605.03375]。Tutti 集成为 vLLM KVConnector 插件,不修改 vLLM 调度器或 attention kernel [2605.03375]。 |
| Mooncake (2407.00079) | Mooncake 是 Kimi 的生产推理平台,利用 CPU DRAM + SSD 构建分布式 KVCache 池,实现 prefix caching 和 prefill-decode 分离 [2407.00079]。Tutti 在单节点层面与 Mooncake 配合:Tutti 负责 GPU↔local-NVMe 的高性能数据面,Mooncake 负责集群级别的空间分配、replica 元数据管理和位置查找 [2605.03375]。两者形成 local data plane + global control plane 的分层关系。 |
| FastServe (2305.05920) | FastServe 的 proactive KV cache swapping 是最早的 GPU↔host 内存 KV cache 管理方案之一:利用 ENST 优先级在 GPU 计算与 PCIe 传输间重叠 [2305.05920]。Tutti 的 slack-aware I/O scheduler 可视为 FastServe swap 思路在 GPU↔NVMe 维度的延伸——但调度粒度从 request-level 细化到 layer-level,且传输路径绕过了 CPU [2605.03375]。 |
| 论文 | 关联点 |
|---|---|
| FastDecode (2403.11421) | FastDecode 将 Transformer 分解为 S-Part (GPU linear) 和 R-Part (CPU attention),彻底移除 GPU 上的 KVCache [2403.11421]。Tutti 和 FastDecode 解决同一个根问题——KV cache 超出 HBM 容量——但方向相反:FastDecode 把 计算搬到数据旁边(CPU 做 attention),Tutti 把 数据搬到计算旁边(SSD→GPU 直通 I/O)。 |
| Neo (2411.01142) | Neo 部分卸载 decode attention 到本机 CPU,通过 asymmetric pipelining 避免 GPU 等待 CPU [2411.01142]。Neo 的 load-aware scheduling 每次迭代对比 asymmetric 方案与 GPU-only 方案取最优(greedy 保证不劣于 baseline)[2411.01142]。Tutti 的 slack-aware scheduler 也有类似的 "fallback to immediate read if no slack" 机制 [2605.03375],但 Tutti 调度的是 I/O kernel 而非 compute kernel。 |
| 论文 | 关联点 |
|---|---|
| FlexRLHF (2312.11819) | FlexRLHF 的 Disaggregated 策略将训练和推理运行时物理分离到不同设备组 [2312.11819]。这与 Tutti 的 SM partitioning(Compute Domain 和 I/O Control Domain 硬隔离)[2605.03375] 在设计哲学上同构:都是 "不同类型的工作需要物理隔离的资源"。 |
| HybridFlow/veRL (2409.19256) | HybridFlow 的 3D-HybridEngine 在 actor 模型的 training 和 generation 阶段使用不同并行策略并通过 zero-redundancy resharding 切换 [2409.19256]。Tutti 的 GPU file pool pre-allocation 和 P2P mapping table 的一次性初始化 [2605.03375] 与 HybridFlow 的 startup-time resharding 异曲同工:都是将运行时开销前移到初始化阶段。 |
| DeepSeek-V3 (2412.19437) | DeepSeek-V3 的 DualPipe 通过细粒度组件拆分(attention/dispatch/MLP/combine)实现 compute-communication 完全重叠 [2412.19437]。Tutti 的 slack-aware scheduler 同样基于细粒度 profiling(每层 attention 的 SM 空闲窗口)实现 compute-I/O 重叠 [2605.03375]。两者的核心方法论一致:离线 profiling → 细粒度组件调度 → 最大化 overlap。 |
vLLM 将 KV cache 管理抽象为类 OS 虚拟内存的分页系统,解决了 GPU HBM 内的碎片问题(有效利用率从 20–38% 提升到接近 100%)[2309.06180]。但 vLLM 的 paged layout 在跨存储层时制造了新问题:将碎片化的内存 blocks swap 到 SSD 生成了数十万次小粒度随机 I/O [2605.03375]。
Tutti 的增量贡献:不改变 vLLM 的 paged 语义,而是在存储层面重新对齐——Tensor-Stripe 布局使 NVMe file 与 GPU memory block 粒度匹配,SGL 替代 PRP 将 HBM overhead 从 3.75 GB 降至 15 MB [2605.03375]。这是 "OS 虚拟内存" 到 "存储对象抽象" 的范式转换。
vLLM 的 preemption 策略(swap-to-CPU 或 recompute)[2309.06180] 在 SSD 场景下完全不可用——Tutti 消除了 swap 概念:SSD 即最终持久层,retrieve 直接 DMA 到 HBM [2605.03375]。
Mooncake 的 KVCache 池依赖 GPUDirect RDMA (Messenger 组件) 在 CPU DRAM 层传输 KVCache [2407.00079]。其 layer-wise prefill 异步传输 KVCache 到 decode 节点的 CPU 内存 [2407.00079]——这仍然是 CPU-centric 的数据路径。
Tutti 在本地层消除了 CPU 瓶颈,使 SSD-to-HBM 路径达到近 DRAM 性能 [2605.03375]。Mooncake 的 hash-based prefix dedup(block size 512 tokens)[2407.00079] 和 Tutti 的 vLLM prefix cache 策略继承 [2605.03375] 可以共存:Mooncake 做全局 prefix 发现和路由,Tutti 做本地高速 retrieve/store。
核心 delta:Mooncake 优化的是 "哪些 KVCache 在哪里" 的决策问题(scheduling),Tutti 优化的是 "如何最快地搬运 KVCache" 的执行问题(data path)。两者解决正交的层次。
FastDecode 和 Neo 共享一个核心 insight:CPU 内存带宽与 GPU 的差距(~3×)远小于算力差距(~100×),decode attention 是 memory-bandwidth-bounded,因此 CPU 是合理的 attention 执行目标 [2403.11421] [2411.01142]。
Tutti 的 insight 完全不同:CPU 不应出现在关键路径上——无论是做 compute 还是做 I/O control。Tutti 不把计算搬到 CPU,而是用 GPU io_uring 将 NVMe I/O 的 submission 和 completion 也搬到 GPU 上 [2605.03375],使 CPU 的角色退化为异步 IOCB 准备($O(\text{layer})$ 开销)。
| 维度 | FastDecode | Neo | Tutti |
|---|---|---|---|
| CPU 角色 | 执行 attention 计算 | 执行部分 attention | 异步准备 I/O 元数据 |
| KV cache 位置 | 完全在 CPU DRAM | 部分 CPU / 部分 GPU | SSD (retrieve 到 HBM) |
| 传输对象 | Q/O activation ($O(Bd)$) | 无跨设备传输(KV 就地计算) | KV cache blocks ($O(BLd)$ per layer) |
| GPU 内存释放 | 完全释放 KV cache | 部分释放 | 不释放——KV cache 仍需在 HBM 中 |
| 额外基础设施 | 多台远程 CPU (InfiniBand) | 本机 CPU (无额外硬件) | NVMe SSD (PCIe) |
| Prefill 处理 | 未覆盖 | 覆盖(优先 GPU) | 覆盖(主战场) |
关键矛盾:FastDecode 声称 CPU 执行 attention 是"compute near data"的最优选择 [2403.11421],但 Tutti 证明只要 GPU-NVMe 路径足够快(25.9 GB/s retrieve BW,推至 98.3% crossover),GPU-native 也能将 SSD 数据 "拉近" 到计算端 [2605.03375]。
矛盾根源:FastDecode 的场景是 decode-only、极大 batch size、长序列——此时 KV cache 总量巨大但每步访问量固定(每 token $O(d)$ activation vs $O(Ld)$ KV cache),CPU 带宽刚好够用。Tutti 的场景是 prefill-dominant、prefix caching、中高并发——此时 KV cache 需整块 retrieve($O(BLd)$ per request),且 prefill 阶段 GPU 有大量 SM 空闲可驱动 I/O。两者在各自的 workload regime 下都正确。
FastServe 的 proactive KV cache swapping 基于 ENST 优先级在 GPU 计算与 PCIe 传输间重叠 [2305.05920]。其调度粒度是 request-level(swap 整个请求的 KV cache)。
Tutti 将调度粒度细化到 layer-level:每层 attention 前查表获取 SM slack window,动态决定发射多少 IOCB [2605.03375]。这种细粒度调度使 I/O 能精确填充每层的 compute gap,而非粗粒度地在迭代间重叠。
FastServe 的 ENST 需要预测请求的未来调度时机(依赖 MLFQ 队列状态)[2305.05920];Tutti 的 slack table 仅依赖 $(L_\text{input}, L_\text{prefix})$——纯确定性查表,无需在线预测 [2605.03375]。确定性调度在 GPU 的非抢占式硬件调度模型下更可靠。
DeepSeek-V3 的 DualPipe 将 forward/backward chunk 拆为 attention / all-to-all dispatch / MLP / all-to-all combine 四个组件,offline 确定 SM 分配(20 SM 给通信),实现 compute-communication 完全重叠 [2412.19437]。
Tutti 的 slack-aware scheduler 同样依赖离线 profiling(每层 SM 空闲窗口)和 SM 硬隔离(green context 分出 I/O Domain)[2605.03375]。
同构模式:
| 维度 | DualPipe | Tutti |
|---|---|---|
| 被隐藏的开销 | All-to-all + PP 通信 | NVMe I/O |
| 拆分粒度 | 4 组件 / chunk | 每层 slack window |
| SM 隔离 | Warp specialization (20/132 SM) | Green context (I/O Domain) |
| Profiling 方式 | 离线测量 compute:comm ratio | 离线 profiling $(L_{input}, L_{prefix})$ lookup table |
| 代价 | 2× 参数内存 | I/O Domain SM 不可用于 compute |
FlexRLHF 的 Disaggregated 策略 [2312.11819] 和 HybridFlow 的 3D-HybridEngine [2409.19256] 与 Tutti 的直接技术重叠有限,但共享 "资源物理隔离 + 相位切换零开销" 的设计哲学。FlexRLHF 将训练/推理分到不同设备组,HybridFlow 通过 interval-based parallel grouping 实现零冗余 resharding,Tutti 通过 pre-allocation 和 SGL 预计算实现运行时零 allocation。三者的共同 delta 是:将运行时的动态开销前移到初始化阶段,使关键路径极简化。
Tutti 的三项核心设计均深度绑定 NVIDIA 特定硬件:
攻击角度:Tutti 的实用性受限于一个相当狭窄的硬件 envelope(H100 + enterprise NVMe + P2P-capable CPU)。相比之下,Neo 仅需本机 CPU(任何 x86/ARM 均可)[2411.01142],Mooncake 仅需 RDMA 网络 [2407.00079]。
Tutti 没有提出 I/O 性能的解析模型 [2605.03375]——依赖 offline profiling lookup table。理想模型需刻画 per-layer transfer time $T_\text{xfer}(B, n_\text{disk}, \text{req\_size})$ 和 compute slack $T_\text{slack}(L_\text{input}, L_\text{prefix}, \text{layer})$,以及 crossover condition 的解析解。
攻击角度:缺失解析模型意味着无法在不同硬件配置(更多/更少 SSD、不同 GPU)上快速预测 Tutti 的表现界限。Neo 的迭代时间模型虽然精度有限但至少是可解析的 [2411.01142],FastServe 的 ENST 也是封闭公式 [2305.05920]。Tutti 的 offline profiling 换硬件就要重做,可移植性差。
Tutti 声称 "SSD-backed achieves DRAM-like performance" [2605.03375],但在高 prefix reuse (>96K/128K) 场景下 DRAM 仍领先最多 20.6% [2605.03375]。在这些场景下,per-layer transfer 时间超出 slack window,SSD 的绝对延迟劣势暴露。
攻击角度:对于 prefix reuse 率极高的工作负载(如长上下文 agent 会话),DRAM-backed 方案(如 Mooncake 的 CPU DRAM pool [2407.00079])在延迟上仍具优势。Tutti 的 crossover point 98.3% [2605.03375] 虽然高,但意味着 hit rate > 98.3% 时 SSD 方案开始退化——这恰好是 prefix caching 最有效的场景。
论文声称 "first open-source SSD-backed KV caching solution",但截至论文发表时代码仓库未公开 [2605.03375]。核心技术壁垒(GPU-side NVMe SQ/CQ 管理、SGL 描述符预计算、green context SM 隔离)需要对 NVMe 规范和 GPU 硬件调度器有底层控制力 [2605.03375]。复现门槛极高。
对比之下,vLLM 完全开源且已成为事实标准 [2309.06180],Mooncake 开源了 trace 和调度代码 [2407.00079],HybridFlow 开源为 veRL [2409.19256]。
所有单 GPU 实验使用 Llama3-8B,多 GPU 使用 GLM-4-9B-Chat-1M [2605.03375]。在 33B–70B 模型上,KV cache 的 per-token size 增大(头数 × 隐藏维度增长),NVMe 带宽可能成为更严格的约束。论文未验证 Tutti 在大模型上是否仍能维持 crossover point 98.3%。
Tutti 实测混合 R/W 带宽跌 60% [2605.03375],因此采用解耦 R/W 调度——read 优先,write defer 到 decode 阶段。但这意味着高吞吐场景下(continuous batching,持续有 prefill 和 decode 混合),write 可能长期积压。论文未分析 write backlog 在持续高负载下的稳态行为。
Tutti 开辟了 LLM serving 中 GPU-centric storage 的新生态位——此前 GPU-centric storage(BaM、GeminiFS、GoFS)专注于通用文件/块 I/O,未适配 KV cache 的特殊语义 [2605.03375]。Tutti 是首个将 GPU-centric storage 与 LLM 推理引擎紧密耦合的系统。
在 KV cache 分层存储的演进中:
vLLM (HBM-only, paged)
→ FastServe (HBM + host DRAM, swap)
→ Mooncake (HBM + DRAM + SSD, CPU-centric)
→ Tutti (HBM + SSD, GPU-centric, 跳过 DRAM)
Tutti 的独特定位是 "跳过 DRAM 层"——直接用 SSD 替代 DRAM 作为 KV cache 持久层,通过 GPU-centric I/O 消除 DRAM 的必要性。这对成本模型有深远影响:SSD $/GB 比 DRAM 低 ~100× [2605.03375]。
积极信号:
消极信号:
| 竞争者 | 存储层 | I/O 路径 | 生态成熟度 |
|---|---|---|---|
| LMCache (GDS) | SSD | CPU-centric (GDS P2P) | 开源,集成 vLLM |
| LMCache (DRAM) | CPU DRAM | CPU-centric | 开源,集成 vLLM |
| Mooncake | CPU DRAM + SSD | CPU-centric (RDMA) | 部分开源,Kimi 生产 |
| Tutti | SSD | GPU-centric | 未开源,无生产披露 |
| HCache / HiCache | HBM + DRAM + SSD | CPU-centric | 学术 |
Tutti 的技术差异化明确(GPU-centric 路径),但生态成熟度明显落后。LMCache 和 Mooncake 已在 vLLM 生态中建立了用户基础。
Tutti 的 "GPU 全程绕过 CPU 的 NVMe I/O" 如果成为通用模式,可能催生:
FastDecode/Neo 把 attention 计算卸载到 CPU [2403.11421] [2411.01142];Tutti 把 I/O 控制卸载到 GPU [2605.03375]。一个未被探索的混合方向:GPU 驱动 NVMe I/O retrieve KV cache,然后将 KV cache 直接 DMA 到 CPU 内存,由 CPU 执行 attention。这消除了 KV cache 从 SSD→GPU→(discard) 的往返,直接 SSD→CPU(attention)→GPU(O)。
可行性依据:SGL 描述符可指向 CPU 物理内存(通过 IOMMU),GPU io_uring 的 CQ 完成通知可触发 CPU 端 attention kernel。挑战在于 GPU-issued NVMe command 的目标地址必须是 PCIe-visible 的 CPU 内存,需要 IOMMU 支持。
Tutti 的 green context SM 隔离比例在部署时固定 [2605.03375]。DeepSeek-V3 的 warp specialization 虽然也是静态分配 20/132 SM [2412.19437],但指出了 SM 上 Tensor Core 在通信时完全闲置的问题。
未探索方向:动态 SM 重分配——在 I/O-free layers(所有 KV cache 已 resident)释放 I/O Domain SM 给 compute,在 I/O-heavy layers 增加 I/O Domain SM。这需要 GPU 硬件支持 SM partition 的动态切换(当前 green context 在 kernel launch 时确定,不可运行时调整)。
Tutti 论文提到未来计划 "GPU-driven remote path via GPU-initiated RDMA" [2605.03375]。结合 Mooncake 的分布式 KVCache pool [2407.00079],完整路径为:GPU-initiated NVMe I/O(本地 miss)→ GPU-initiated RDMA(远程 retrieve)→ GPU attention(计算),全程绕过 CPU。
这将统一 Mooncake 的 Messenger 组件(当前 CPU 端 RDMA)和 Tutti 的 gio_uring(当前仅本地 NVMe),形成 GPU-centric distributed KV cache。技术挑战:GPU-initiated RDMA 的 SM 开销(NIC doorbell MMIO 延迟)和多 NIC 负载均衡。
Mooncake 的 prefill-decode 分离 [2407.00079] 和 Tutti 的 GPU-centric SSD I/O [2605.03375] 可产生更激进的架构:
这使 prefill 实例可配最小化存储(降低成本),decode 实例可配最大化存储(最大化 prefix reuse)。当前 Mooncake 将 KV cache 存在 decode 节点的 CPU DRAM;替换为 Tutti SSD 路径可将 decode 节点的 KV cache 容量提升 50–100×。
当前 Tutti 仅处理 KV cache 的 SSD offloading。对于 MoE 模型(如 DeepSeek-V3 的 256 routed experts [2412.19437]),expert weights 的动态加载(根据 routing decision)也可受益于 GPU-centric NVMe I/O。
MoE inference 中 expert activation 是 sparse 的(每 token 仅激活 8/256 experts),冷门 expert 可 offload 到 SSD。Tutti 的 SGL-based bulk transfer 和 slack-aware scheduling 可直接复用——将 "per-layer KV cache retrieve" 替换为 "per-layer expert weight retrieve",slack window 在 attention 阶段(expert weight 不参与 attention)。
Tutti 的 offline profiling 假设同一 $(L_\text{input}, L_\text{prefix})$ 配置下 slack 窗口固定 [2605.03375]。但在实际 continuous batching 中,不同请求的 attention 计算量因 KV cache 大小不同而有差异,batch 内请求的多样性使 per-layer slack 具有方差。
Neo 的 greedy fallback(每次迭代对比两种方案取最优)[2411.01142] 提供了一个参考:Tutti 可在运行时检测实际 slack 与 profiled slack 的偏差,动态调整 IOCB 数量或 fallback 到 immediate I/O。这将 offline profiling 从 "硬约束" 放松为 "初始估计 + 在线校正"。
Last built: 2026-07-01T10:35:00Z