Skip to content

feat: add ReplaySSM state modes for GDN and KDA - #1689

Closed
sufubao wants to merge 56 commits into
ModelTC:mainfrom
sufubao:support-replayssm-v2
Closed

sufubao wants to merge 56 commits into
ModelTC:mainfrom
sufubao:support-replayssm-v2

Conversation

@sufubao

@sufubao sufubao commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Replay kernel 按生命周期拆分为公共递推、history/fold、decode/projection 和 accepted-state materialize 四个模块;replayssm.py 仅保留兼容导出,原有 executor 与测试导入路径不变。

本次在核心接口处补充了中文注释:StateAcceptance 说明接受结果与 microbatch 提交配置的关系,SSMExecutor 和 SSMForward 说明资源生命周期、执行策略和提交凭据的边界,Replay kernel 注释说明运行时请求数与编译期形状参数的区别。

为 GDN/KDA 增加 compact / replay SSM 状态存储,默认保持 native。接入普通 decode、固定/动态 MTP、checkpoint、CPU cache 和 PD 恢复。ConvSSMState 统一资源生命周期,SSMExecutor 负责模式执行,SSMForward 携带不可变执行配置。接受提交使用单一 StateAcceptance,接受长度包含基准输入 token,并按原 forward 的请求顺序和 microbatch 配置提交。GDN 使用逻辑执行层寻址,保留 SenseNova Loop 的独立状态。

批量 checkpoint 和 DP 导出现在直接写目标页;native 按接受索引读取,replay 直接物化到目标,避免持有整批完整状态副本。返回快照的接口单独保留并说明分配语义。接受 kernel 的请求数改为不特化的运行时参数。补齐 SenseNova Loop 启动校验,提前拒绝 KDA parallel;模型缓存验证脚本保留 main/draft 各自的提交描述。KDA benchmark 根据验证宽度扩展 history,并排除不会执行 precompute 的 BV=8 候选。

所有验证在 ssh h100 隔离环境执行:H100 80GB,PyTorch 2.11.0、Triton 3.6.0、CUDA 13.0。

Replay eager 路径的 _accept_updates、_prepare_fold、_fold_history 也改用不特化的运行时请求数;保留 BLOCK、history 长度、验证宽度和 fold 模式的特化。dense fold 判断仍按实际请求数执行,255/256/257 的调度与数值回归通过。

本次在相同 H100 环境对比 0de73fe8e:固定 kernel 配置,2 层、4 value heads、128×128、BF16 activation、FP32 SSM、history=8,GDN/KDA 各验证宽度 1/4。连续变化 14 种请求数(1–511),整个 prepare → forward → acceptance 路径的编译变体总数:

路径 修复前 修复后
非 MTP 43(14+14+1+14) 11(8+1+1+1)
验证宽度 4 30(14+14+1+1) 11(8+1+1+1)

括号依次为 prepare / fold / forward / acceptance;prepare 的 8 个变体来自必要的 BLOCK 形状。同一 BLOCK 内首次出现新请求数,非 MTP 整轮同步耗时从 288–353 ms 降到 0.21–0.37 ms;跨新 BLOCK 仍会编译,首次启动成本也仍存在。32/512 两个 graph bucket 预热后,前后版本在改变真实请求数时均为 0 次 Python/JIT kernel launch,不能将 eager 收益解释为已预热图路径的同等加速。

四组配置、eager/graph 两种执行下,每个请求数的输出及最终状态、游标与修复前逐位一致。本次 SSM GPU 套件 489 passed、190 deselected,77 个 PR Python 文件通过 Black、Flake8、AST 和 diff 检查。下面保留前一轮 0de73fe8e 的验证与服务测量;本次未重跑完整服务或 GSM8K。

  • CPU 契约:872 passed、2524 skipped、14 deselected;专项 GPU/接口回归:149 passed;状态与模型接入回归:185 passed。SSM 数值、fold、grouped heads、CUDA Graph 和调优契约:483 passed、190 deselected。各套件有重叠,不累加计数。
  • 77 个 Python 文件通过固定版本 Black、Flake8、AST 和 diff 检查,2226 个源码文件与测试快照一致。KDA width=9 的四种模式、完整/部分接受均完成 benchmark。
  • 34 层、每卡 8 value heads、128×128 FP32 SSM、64 请求同时保存 checkpoint:额外 GPU 分配从 dc85b4928 的 1,234,699,776 B 降至 1,024 B,与 upstream base 相同;五轮同步耗时中位数分别为 26.10 / 22.52 / 22.96 ms(修复前 / 修复后 / base)。
  • 冷缓存下连续运行 14 种真实请求数(1–511),native/replay 接受 kernel 各从 14 个编译变体降到 1 个;首个变体之后,新请求数的首次调用从约 33–56 ms 降至 0.03–0.12 ms。
  • Qwen3.5-0.8B、compact、MTP=1、FP32 SSM、CUDA Graph,12 轮交替接受 1/2 token:main/draft 的 GPU 页、CPU 页、本地 DP copy 和 PD buffer 恢复后 logits 误差均为 0。相同场景在 dc85b4928 复现缺少 compact commit batches 的报错。此项不包含跨机器 PD。

真实 HTTP 服务对比 base 269ab62d0:Qwen3.5-0.8B,BF16 activation、FP32 SSM,1024 输入 / 512 输出 token,greedy,关闭 prompt cache,CUDA Graph;batch=1/4/8,各预热一次、测量三轮,每组共 39 个测量请求。下表为 batch=8;吞吐包含完整请求时间,P95 仅来自该 batch 的 24 个请求。显存为启动及图捕获期间的 NVML 采样峰值。

单卡配置 TPOT ms 输出 token/s 请求耗时 P95 ms 峰值 MiB
base native,MTP=0 1.797 3714 1101 4301
PR native,MTP=0 1.800 3694 1117 4289
base native,MTP=1 1.611 4101 1031 5031
PR native,MTP=1 1.632 3987 1048 5077
compact,MTP=1 1.583 4103 1021 4463
replay,MTP=1 1.597 4033 1018 4887

native MTP 首轮 TPOT 高约 1.3–1.7%;交换 base/PR 运行顺序复测,差异为 −1.6% 至 +0.2%,尚不能认定有稳定差异。TP=2、DP=2 的真实 microbatch overlap 也完成 base native / compact / replay 对比,batch=8 TPOT 为 2.782 / 2.740 / 2.841 ms。以上各组生成 token 均与对应 base 一致。单卡 MTP 的平均每步输出 token 为 1.9988 / 1.9988 / 1.9987(base / compact / replay);这是服务效率指标,不是独立统计的 draft 接受率。KV capacity 固定为 16384,未测自动容量收益。

Replay 不保证总状态显存低于 native。实际分配的 SSM + 全部 history + cursor,在 KDA、K=V=128、BF16 activation/SSM、MTP=2 时,每层、每请求、每 value head 分别为:native 96 KiB,compact 35.01 KiB,replay L=16/32/64 为 96.13 / 160.26 / 288.51 KiB;不含共同 Conv、图和临时工作区。

Native/compact 保留逐 token 舍入;replay 的持久 SSM 在 fold/导出时规范化,部分配置还收窄派生 history 和投影精度。导出 pending history 后恢复会清空历史,BF16 下不承诺与不中断执行逐位一致。

上述服务测试是小模型、合成输入的限定对照,未覆盖 GSM8K、长上下文模型精度、完整 KDA/SenseNova 服务或全量 autotune/大跨度索引矩阵。TP=1/DP=1 的 overlap 尝试在首个请求遇到 graph 第二个 infer-state 为 None;保留失败记录,未修改该调度路径,成功验证使用 TP=2/DP=2。原有 native MTP 逐位测试的 7 项失败此前已在独立 base 复现(最大误差 0.000488–0.000977),相关内核和断言未改。

代码可读性

参考 SGLang 的状态执行代码,补齐 ReplaySSM 的接口契约和生命周期说明:StateAcceptance 说明请求顺序、接受长度和 microbatch 配置;SSMForward 说明 graph padding、物理槽位和提交凭据;Native/Compact/Replay executor 说明 decode、接受、快照导出的职责;ReplaySSM Triton kernel 说明 cursor、双半区 history、fold 和 materialize 的读写关系。未新增设计文档,注释只保留调用者和维护者需要的约束。

H100 验证:pinned AST/Black/Flake8 13 个改动文件通过;ReplaySSM focused 18 passed;完整 SSM GPU 集合 489 passed,190 deselected。

…tLLM into merge-pr-1585

# Conflicts:
#	unit_tests/common/basemodel/attention/linear/test_gdn.py
#	unit_tests/models/glm5_next/test_mtp.py
@sufubao

sufubao commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator Author

收敛 validation:Manager 只做一次 StateAcceptance 公共校验,State 负责设备检查,executor 保留模式专属校验;commit_validated 用于已校验路径,避免重复检查。H100 pinned static 5 files passed,focused GPU 18 passed。

@sufubao

sufubao commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator Author

继续清理过度防御:删除 SSMForward.finish 中已由 State 注册流程保证的 resource 检查,删除 CompactSSMExecutor.create_commit 对 forward config 的重复类型检查。保留 StateAcceptance、CUDA Graph layout、Compact acceptance payload 和 Replay shape/config 的真实契约校验。H100 pinned static 2 files passed,focused GPU 18 passed。提交 3a95a9e。

@sufubao

sufubao commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator Author

继续收敛运行时校验:CUDA Graph 的资源 key、SSMForward resource/executor 和 tensor layout 现在只在每个 captured state 首次绑定时检查,后续 graph replay 只做 tensor copy。接受提交校验保持按批次执行,因为 accepted lengths 与 Compact run_config 每轮可变。H100:static 2 files passed,graph layout 5 passed,linear state contract 39 passed / 1 skipped。提交 0a44f17。

@sufubao

sufubao commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator Author

本次按算法边界收敛了状态层次,避免继续扩大公共 SSMState:

  • GDNState 下拆分 GDNNativeState、GDNCompactState、GDNReplayState。
  • KDAState 下拆分 KDANativeState、KDACompactState、KDAReplayState。
  • 原先的公共实现降为私有 _ConvSSMState,只承载 Conv/SSM 资源生命周期、页池、快照和传输共性;不再作为外部算法状态接口。
  • 工厂按 ssm_state_mode 返回具体算法和策略类型,模式不再只以运行时字符串隐含表达。
  • 同时保留前一轮 acceptance 收敛:Native/Replay 不保留空校验钩子,Compact 的已验证 partition 只生成和遍历一次。

提交:439a1a557 refactor: split bounded attention state strategies

H100 验证:

  • 12 个改动 Python 文件 Black/AST/flake8 通过。
  • linear-state-contract:39 passed, 1 skipped。
  • ReplaySSM 聚焦测试:18 passed。

@sufubao

sufubao commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by clean PR #1690, which is a single ReplaySSM feature commit based directly on upstream/main and has a successful pre-commit check. Closing this merge-history-heavy duplicate keeps the upstream review clean.

@sufubao sufubao closed this Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants