Tutti: Making SSD-Backed KV Cache Practical for Long-Context LLM Serving

framework 2605.03375 — Cross-paper Synthesis

L3 Per-Paper Synthesis: Tutti (2605.03375) #

Tutti: Making SSD-Backed KV Cache Practical for Long-Context LLM Serving Cross-paper analysis against 8 related entities in category framework

§1 相关论文 #

Tutti 的关联图谱沿三条主线展开:KV cache 内存管理与分层存储CPU-GPU 异构计算/I/O 路径分布式调度与 compute-I/O overlap。第三组(训练框架)通过 disaggregation 和 overlap 的通用设计模式间接关联。

1.1 KV Cache 内存管理与分层存储 #

论文关联点
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]

1.2 CPU-GPU 异构计算 / I/O 路径 #

论文关联点
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。

1.3 Disaggregation 与 Compute-I/O Overlap(训练框架间接关联) #

论文关联点
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

§2 本篇 vs 相关论文的 delta #

2.1 vs vLLM/PagedAttention:从 "分页内存" 到 "分页存储" #

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]

2.2 vs Mooncake:数据面 vs 控制面的互补 #

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)。两者解决正交的层次。

2.3 vs FastDecode / Neo:I/O offload vs Compute offload #

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})$ 开销)。

维度FastDecodeNeoTutti
CPU 角色执行 attention 计算执行部分 attention异步准备 I/O 元数据
KV cache 位置完全在 CPU DRAM部分 CPU / 部分 GPUSSD (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 下都正确。

2.4 vs FastServe:scheduling 粒度的进化 #

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 的非抢占式硬件调度模型下更可靠。

2.5 vs DeepSeek-V3:compute-I/O overlap 的方法论同构 #

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]

同构模式

维度DualPipeTutti
被隐藏的开销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

2.6 训练框架的间接 delta #

FlexRLHF 的 Disaggregated 策略 [2312.11819] 和 HybridFlow 的 3D-HybridEngine [2409.19256] 与 Tutti 的直接技术重叠有限,但共享 "资源物理隔离 + 相位切换零开销" 的设计哲学。FlexRLHF 将训练/推理分到不同设备组,HybridFlow 通过 interval-based parallel grouping 实现零冗余 resharding,Tutti 通过 pre-allocation 和 SGL 预计算实现运行时零 allocation。三者的共同 delta 是:将运行时的动态开销前移到初始化阶段,使关键路径极简化


§3 可攻击面 #

3.1 硬件依赖的脆弱性 #

Tutti 的三项核心设计均深度绑定 NVIDIA 特定硬件:

攻击角度:Tutti 的实用性受限于一个相当狭窄的硬件 envelope(H100 + enterprise NVMe + P2P-capable CPU)。相比之下,Neo 仅需本机 CPU(任何 x86/ARM 均可)[2411.01142],Mooncake 仅需 RDMA 网络 [2407.00079]

3.2 缺失的解析性能模型 #

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 换硬件就要重做,可移植性差。

3.3 仅 DRAM-like 性能 ≠ 全面优于 DRAM #

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 最有效的场景。

3.4 代码未开源的可复现性风险 #

论文声称 "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]

3.5 评测模型规模偏小 #

所有单 GPU 实验使用 Llama3-8B,多 GPU 使用 GLM-4-9B-Chat-1M [2605.03375]。在 33B–70B 模型上,KV cache 的 per-token size 增大(头数 × 隐藏维度增长),NVMe 带宽可能成为更严格的约束。论文未验证 Tutti 在大模型上是否仍能维持 crossover point 98.3%。

3.6 混合 R/W 带宽坍塌的应对可能过于保守 #

Tutti 实测混合 R/W 带宽跌 60% [2605.03375],因此采用解耦 R/W 调度——read 优先,write defer 到 decode 阶段。但这意味着高吞吐场景下(continuous batching,持续有 prefill 和 decode 混合),write 可能长期积压。论文未分析 write backlog 在持续高负载下的稳态行为。


§4 生态位 #

4.1 范式定位 #

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]

4.2 采用信号 #

积极信号

消极信号

4.3 竞争格局 #

竞争者存储层I/O 路径生态成熟度
LMCache (GDS)SSDCPU-centric (GDS P2P)开源,集成 vLLM
LMCache (DRAM)CPU DRAMCPU-centric开源,集成 vLLM
MooncakeCPU DRAM + SSDCPU-centric (RDMA)部分开源,Kimi 生产
TuttiSSDGPU-centric未开源,无生产披露
HCache / HiCacheHBM + DRAM + SSDCPU-centric学术

Tutti 的技术差异化明确(GPU-centric 路径),但生态成熟度明显落后。LMCache 和 Mooncake 已在 vLLM 生态中建立了用户基础。

4.4 范式转移潜力 #

Tutti 的 "GPU 全程绕过 CPU 的 NVMe I/O" 如果成为通用模式,可能催生:

  1. GPU-native 存储引擎标准化:GeminiFS → GPU file system 标准 API(类比 Linux VFS 在 GPU 端的等价物)
  2. CXL 时代的自然演进:CXL.mem 使 NVMe 参与 GPU 统一内存的 coherence domain 后,Tutti 的 retrieve/store 接口可退化为 demand-paging [2605.03375]
  3. 推理引擎的存储感知调度:当前 vLLM 的调度器不感知底层存储性能;Tutti 的 slack-aware 调度可能推动推理引擎内置存储性能模型

  4. §5 未探索方向 #

    5.1 GPU-centric I/O + CPU Attention 混合 #

    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 支持。

    5.2 Adaptive SM Partitioning #

    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 时确定,不可运行时调整)。

    5.3 Mooncake + Tutti 的 GPU-initiated RDMA 远程路径 #

    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 负载均衡。

    5.4 与 Prefill-Decode 分离架构的深度集成 #

    Mooncake 的 prefill-decode 分离 [2407.00079] 和 Tutti 的 GPU-centric SSD I/O [2605.03375] 可产生更激进的架构:

    • Prefill 实例:无 SSD——仅需 HBM 执行计算(KV cache 计算后立即 stream 到 decode 实例的 SSD)
    • Decode 实例:配备大量 SSD——KV cache 驻留在本地 NVMe,Tutti 负责 retrieve

    这使 prefill 实例可配最小化存储(降低成本),decode 实例可配最大化存储(最大化 prefix reuse)。当前 Mooncake 将 KV cache 存在 decode 节点的 CPU DRAM;替换为 Tutti SSD 路径可将 decode 节点的 KV cache 容量提升 50–100×。

    5.5 MoE 模型的 Expert Cache Offloading #

    当前 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)。

    5.6 Per-Request Adaptive Profiling #

    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