Mooncake 分层混合注意力¶
本扩展为 PR #16004 引入的 Mooncake 分层 range/session 实现增加了多 KV 组支持。
该实现基于上游 main 分支的
be427041bf63a620e4a637b60f2656e87dcdf8f6。
它面向 DeepSeek-V4 等注意力布局,其中滑动窗口 KV、 压缩 KV、indexer 缓存和 compressor 状态可以属于不同的 KV 组。它复用了 Memcache 也在使用的共享可达性协调器; 参见 issue #12234 中的设计讨论。 它不会将 Mooncake 操作转换为 Memcache GVA 操作。
适用范围与前提条件¶
- 使用
AscendStoreConnector,并设置backend="mooncake"和use_layerwise=true。 - 安装带有 range/session 接口的 Mooncake 客户端,接口列表见 单组指南。
- 模型必须提供有效的
KVCacheConfig.kv_cache_groups和组块表。 运行时组块大小已经描述了原始 token 覆盖范围;不要再 乘以压缩比。 - 本补丁将计算窗口接入昇腾 DSA、FA 和 SFA 注意力 路径。请在 eager 模式下开始验证。图模式执行和其他 注意力后端需要单独的集成验证。
- 拓扑匹配的 PP 支持不均匀分区和阶段本地混合组。 DCP、PCP 以及 prefill/decode TP 不匹配仍不支持。
- 使用
MambaSpec的循环/线性注意力组需要mamba_cache_mode="align"。其状态在注意力内核 更新后保存;它们不会在注意力入口提交 PUT。 - 仅发布完整的、协调器对齐的块快照。部分 块卸载和跨层缓存缓冲区复用不属于本 混合实现的一部分。
组感知对象与 range 偏移¶
单组线格式保持不变。混合布局使用单独的 命名空间:
该摘要包含 TP 大小、有序组成员关系以及每个组的页大小 签名。它与组 ID 一起标识缓存组,而无需 在对象键中重复调度器的缓存族分类。它 可防止不兼容的组布局读取相同的对象。它并非 模型权重校验和或租户隔离机制:对于模型名称和缓存规格相同 但权重不同的情况,请使用隔离部署。
每个键为单个组和存储 head/rank 存储一个块。其字节仅包含 该组注册的缓存条目,按物理层和缓存 名称排序。对象大小是它们实际每块字节长度的总和。传输 使用组本地层索引来计算远程偏移,而物理 层索引用于选择计算事件和完成信号。
例如:
| 组 | 原始 token/块 | 物理层 | 提交边界 |
|---|---|---|---|
| Full attention | 16 | 0, 2 | Layer 2 |
| Compressed KV | 32 | 1, 2, 3 | Layer 3 |
| Window/state | 16 | 0, 3 | Layer 3 |
多个组可以在同一物理层传输。一个组在其自身的 最后一层之后提交,而不一定是模型的最后一层。同一物理层上的多个缓存 条目仍保持为独立的字节范围。
可达性与会话生命周期¶
调度器针对协调器按组查找掩码选中的键查询 batch_is_readable。
仅当所有必需的阶段和存储 head 键均已提交且可读时,块才可用。
随后协调器确定跨组的公共可达 token 边界。
当对应的窗口或 compressor 状态缺失时,仅命中全注意力
是不够的。
worker 对存储和加载掩码使用相同的协调器。它不会 将稀疏状态缓存解释为连续前缀。掩码生成失败 不会被静默转换为复制每个状态块的请求。
worker 为每个组创建单独的请求视图。会话所有权
以 (request_id, group_id, logical_block_index) 为索引,因此一个组中的块零
无法替换另一个组中的块零。在分块预填充步骤之间,即使没有新的
调度器加载规格,也可以使用当前本地块 ID 恢复已提交的
键。每个组保留独立的活跃传输
状态,并在其最后一个组层重置。
失败的 range put 会撤销受影响的键;其他组中成功的键 仍可提交。准备过程中的异常会撤销该准备过程中 先前打开的对象。失败的 get 会在使用不完整的混合 KV/状态之前停止前向路径。Get 会话在飞行中的读取完成后释放。
传输时序:可配置的异步流水线¶
重负载操作使用每层注意力计算窗口:
previous collectives / cache updates
|
cache-ready NPU event
|
+--------+---------------------+
| |
current attention kernel put current-layer ranges
get future-layer ranges
| |
+------- policy checkpoint ----+
|
output projection / MoE communication
|| bounded transfers
在注意力入口,一个 NPU 事件保护缓存写入以及计算流上 之前的工作。预取的 get 会等待该事件。对于 full/SWA 注意力, worker 记录保存事件并在同一边界提交当前层的 put。随后 host 启动 注意力内核,并在返回 到后续输出投影或 MoE 通信之前应用配置的队列策略。
包含 MambaSpec 的物理层(包括 GDN 和 Kimi KDA)在注意力内部
更新 conv/循环状态。它们改为从现有的计算后保存钩子
记录保存事件并提交 PUT。该钩子还会对没有计算窗口上下文管理器的
注意力路径施加发送背压。
步骤完成会等待所有排队的 PUT,包括最后一层
没有需要保存的范围时。
默认情况下,未来层的 get 保持排队,最多八个发送任务可能保持 未完成。这从每层的关键路径中移除了整队列排空, 但这也意味着传输可以与后续的输出投影或 MoE 通信重叠。这是内部调度策略,而非公开的 运行时设置。错误和拆除路径仍会完全排空两个队列。
在 DSA 中,该边界位于 compressor/indexer/cache 更新之后、稀疏注意力算子之前。在 SFA 中,它包围稀疏注意力算子;在 FA 中,它包围分页/FIA 注意力路径。它并不包围整个 transformer 层。
影响:
- 在默认策略下,传输尾部可能与后续的 HCCL 或专家并行通信产生竞争。应使用设备 trace 在目标部署上验证这一固定策略。
- 初始的、未预取的按需加载没有前置的注意力窗口。它会等待更早的计算流工作,然后在注意力开始前完成。
- 会话分配、存在性查询以及其他元数据 RPC 不属于 payload DMA,可以发生在窗口之外。
- 这是一种本地队列策略,而非集群范围的带宽调度器。不相关的工作进程和独立的通信流不会被全局串行化。应使用设备 trace 验证多流和多 rank 行为。
- 在没有硬件测量的情况下,不声称任何延迟或吞吐量改进。较短的注意力 kernel 可能暴露出显著的传输尾部。
配置¶
export MOONCAKE_CONFIG_PATH=/path/to/mooncake.json
vllm serve /path/to/hybrid-model \
--tensor-parallel-size 8 \
--enforce-eager \
--enable-prefix-caching \
--enable-chunked-prefill \
--max-num-batched-tokens 4096 \
--kv-transfer-config '{
"kv_connector": "AscendStoreConnector",
"kv_role": "kv_both",
"kv_connector_extra_config": {
"backend": "mooncake",
"use_layerwise": true,
"layerwise_prefetch_layers": 2,
"layerwise_max_transfer_blocks": 64,
"layerwise_max_transfer_bytes": 16777216
}
}'
根据实际硬件/模型选择 TP 大小、chunk 大小、量化方式和模型参数。从两个未来层预取窗口开始。本示例并非经过验证的 DeepSeek-V4 部署方案,也不构成内存容量保证。
验证¶
CPU/mock 单元测试覆盖了组感知的字节往返、不同的 block 大小、不相等的 cache 条目数量、稀疏掩码、独立的提交边界、组会话归属、使用重映射本地 block 的续传、传输失败结果、分配回滚、设备事件门控以及致命线程传播。它们不会执行注意力 kernel 或真实的 Mooncake 服务。
仍然需要真实的 NPU 和分布式 Mooncake 验证,本次变更并未将其自动化。请使用项目批准的部署和基准测试流程,针对目标模型和硬件进行验证。在其余设置完全相同且测试池隔离的情况下,对比分层和非分层 Mooncake,并在不启用 profiling 或 range-debug 日志的情况下运行性能测量。
在声称支持硬件或性能改进之前,请验证:
- 在真实混合模型上验证冷/热 token 一致性、正向远程命中以及多个 chunk 边界。
- 每个组(包括稀疏状态组和 indexer 组)都具有有效的加载范围。结合设备 trace 检查 Mooncake range-debug 日志。
- 在受测设备上,put/get payload 范围在 cache-ready 事件之后开始,并在后续 HCCL 之前完成;检查所有相关的流和 rank。
- 在相同模型、TP、prompt 和池条件下,对比非分层基线的 TTFT、吞吐量、暴露的传输尾部以及 HCCL 持续时间。
- 额外的并发请求、抢占、模型特定状态以及服务故障测试。仅凭冒烟脚本无法确立生产就绪性。
真实的 NPU/Mooncake 验证尚待进行;当前实现环境仅支持 CPU/mock 检查。