海光 DCU 算子优化:为什么 1.32x 仍可能不值得接入

海光 DCU 算子优化:为什么 1.32x 仍可能不值得接入

海光 DCU 算子优化:为什么 1.32x 仍可能不值得接入

摘要

性能表格最吸引眼球的通常是加速比,但在大模型推理中,真正决定端到端价值的往往是“每次调用究竟省了多少微秒”。

本文整理三组海光 DCU gfx936 本地实测。第一组 kernel 达到 1.31631x,第二组达到 1.18939x,第三组甚至完成了 314/314 的精确修复;但它们最终都没有进入完整服务。原因并不是实现失败,而是每层绝对节省只有 1.76-3.23 微秒,乘上层数后仍不足以改变约 44 ms/token 的 Decode 主体。

这篇文章讨论一种比“看加速比”更可靠的 DCU 优化预算方法。


1. 加速比会放大小算子的视觉效果

假设一个 kernel 从 13 微秒降到 10 微秒:

speedup = 13 / 10 = 1.30x absolute saving = 3 us

1.30x 看起来很明显,但如果完整 Decode 每 token 需要 44 ms,那么单层 3 微秒只占:

3 us / 44,000 us = 0.0068%

只有当这个 kernel 在很多层、每个 token 都稳定命中时,才可能积累出可见收益。

更实用的预算公式是:

saving_per_token = saving_per_call × calls_per_layer × layer_count × hit_rate

然后再与完整 token 时间比较,而不是只看局部 speedup。


2. 案例一:1.31631x,但每层只省 3.10840 微秒

本地测试过一条 fused split GDR HIP kernel。CUDAGraph event median 使用 7 组样本,每组 400 次 replay:

路径耗时
当前 Triton BF16 state12.93559 us
HIP FP32 swizzled state9.82719 us
加速比1.31631x
每层节省3.10840 us

如果模型中有 48 个相关层,理想化累计节省为:

3.10840 us × 48 = 149.20 us/token = 0.14920 ms/token

相对于约 44 ms 的 Decode 时间,上限约为 0.34%。

而且这个估算还没有计入:

  • 状态格式转换;
  • 额外 FP32 显存流量;
  • runtime allocation;
  • 图集成和 dispatch 开销。

也就是说,1.31631x 已经是好看的局部数字,但 3.10840 微秒才是决定是否继续投入的数字。


3. 案例二:适配真实布局后,2.89x 变成 1.19x

另一个 GDN 融合原型在上游布局中曾测到:

40.6752 us -> 14.0568 us speedup: 2.8936x saving: 26.6184 us/layer

但真实 Qwen3.5 激活布局与该上游 kernel 的输入布局不同。把真实布局和必要的数据整理纳入公平比较后,最终 native flat-layout 结果是:

路径耗时
真实布局基线20.27239 us
native flat kernel17.04439 us
加速比1.18939x
每层节省3.22800 us

48 层的理想累计节省:

3.22800 us × 48 = 154.944 us/token = 0.15494 ms/token

这个结果并不差。它说明 kernel 已经正确适配了目标布局,也证明了局部融合有效。

但它同样无法跨过端点门槛:完整服务中还有大量 Linear、Attention、状态更新和运行时开销,0.15494 ms/token 很容易被稀释。

这个案例还说明一个常见问题:

上游 benchmark 的基线布局如果比本地生产布局更重,直接照搬加速比会高估收益。


4. 案例三:正确性完全修好,物理上限仍然太小

本地还研究过一种“快速近似结果 + 低置信度精确修复”的 GDN 输出方案。

经过 gfx936 MMAC 路径重建后,选中的 314 行实现了:

vendor exact: 314 / 314

从正确性角度看,这是一个完整闭环。但 CUDAGraph 计时为:

路径耗时
vendor full55.0400 us
LLMM153.2800 us
精确 repair 本身21.4400 us
debug + repair61.6000 us

这里有一个决定性的物理上限:

vendor - LLMM1 = 1.7600 us/layer 48 layers = 84.48 us/token

即使假设置信度检测和修复完全免费,最多也只能省 1.76 微秒/层。真实实现必然还有检测、索引、repair 和写回开销,因此不可能从这条结构中获得更高的端到端收益。

正确性修到 314/314,并不能改变这条性能上限。


5. 什么时候加速比才有意义

加速比不是无用,而是必须与以下信息一起看:

问题需要的证据
单次省多少绝对微秒差
一枚 token 调用几次profile 调用计数
有多少层命中模型结构
所有请求都命中吗dispatch marker
能否与其他工作重叠CUDAGraph/trace
集成需要额外转换吗完整数据流计时
最终是否值得端点 A/B

尤其对 10-30 微秒级 kernel,1.2x、1.3x 很容易出现,但它们可能只对应 2-4 微秒的绝对节省。

相反,一个只快 1.08x 的大权重 GEMV,如果每 token 重复上百次,反而可能产生更明显的服务收益。


6. 给 DCU kernel 设立物理门槛

在写实现之前,可以先反推最低门槛。

假设目标是让 44 ms/token 的 Decode 改善 1%:

required saving = 44 ms × 1% = 0.44 ms/token

如果目标 kernel 出现于 48 层:

required per-layer saving = 0.44 ms / 48 ≈ 9.17 us/layer

如果还要考虑集成稀释、运行波动和额外开销,standalone 门槛应该更高,而不是刚好等于 9.17 微秒。

先算这个门槛,可以快速淘汰“比例很好看、绝对时间不够”的路线。


7. 海光 DCU 上为什么更要看绝对微秒

本文三组数据都来自 gfx936 的 device-event 或 CUDAGraph 计时。它们反映了海光 DCU kernel 评估中一个很实用的特点:很多 recurrent、gating 和 repair primitive 本身只有十几到几十微秒,比例很容易变得好看,但完整 Decode 仍是数十毫秒量级。

因此,在海光 DCU 上筛选新 kernel 时,可以先用下面的顺序:

gfx936 实机绝对微秒 -> 每 token 命中次数 -> 层数累计 -> 完整服务 TPOT

这比先追求一个醒目的 speedup 更节省工程时间,也更适合在论坛中比较不同实现的真实价值。

8. 结论

三组本地 DCU 实验给出了相同结论:

  • 1.31631x 对应 3.10840 us/layer;
  • 1.18939x 对应 3.22800 us/layer;
  • 314/314 精确修复的零成本上限也只有 1.7600 us/layer。

这些实现并非没有技术价值。它们证明了 kernel、布局和数值路径能够成立,但不足以改变完整服务的主要时间墙。

因此,评估 DCU 算子时,建议把表格第一列从 speedup 改成:

每层省多少微秒,每个 token 能累计多少毫秒。

加速比负责描述局部改善,绝对时间预算才负责决定工程方向。


本文数据来自本地固定环境的 CUDAGraph 与 standalone 测量。文中的端到端上限是基于实测每 token 时间和调用层数的物理估算,不等同于已经完成的服务吞吐结果。