Files
calculet-npu-research-archive/reports/Calculet-NPU-逐算子优化实验手册-20260802.md
T

14 KiB
Raw Blame History

Calculet NPU 逐算子优化实验手册

日期:2026-08-02
对象:当前 Qwen3-30B-A3B 双芯粒 prefill/decode 整图及后续新模型

1. 先说明能力边界

当前生产是预编译整图,不是 GGML 逐算子 NPU backend。我们可以离线分析 op、设计实验、修改 host adapter,并对厂商编译的不同 calbin 做 A/B;没有 calcc/pass/kernel/oplib 时,不能自行替换 NPU kernel。因此:

  • C0:当前图和算子分布、现有整图运行。
  • C2harness、数据集、统计、host-side 搬运/后处理改造。
  • C3fusion、layout、quant、kernel、partition、新 calbin。

2. 当前图的优化对象

op family 每图数量 主要阶段 首要成本假设 优先级
fused matmul/add 193 prefill+decode 权重/activation 带宽、量化解码、GEMM 利用率 P0
fused RMSNorm 193 两者 小归约和 kernel launch/sync P1
sync CPU/CCU D2D 146 两者 芯粒同步和 barrier P0
gather 145 两者 TP 重组/通信 P0
grouped MoE dense 144 两者 expert 稀疏 GEMM、token 分桶、负载不均 P0
RoPE 96 两者 layout/表访问 P2
KV scatter 96 两者 KV 写带宽和不连续访问 P0 decode
residual/add 96 两者 memory-bound、融合机会 P1
Flash Attention 48 两者 attention 主体、长 context P0 prefill/长 decode
MoE gate pre/post 48+48 两者 top-k、dispatch/gather P0 MoE
dynamic D2D 96 prefill only 双芯粒 activation 交换 P0 prefill

数量是结构化 YAML 顶层实例统计,不等于调用次数或耗时占比。优化排序必须在 trace/per-op cycle 到位后更新。

3. 实验资产和命名

每个候选生成一组不可变资产:

experiment/<EXP_ID>/
  hypothesis.yaml
  baseline/manifest.json
  candidate/manifest.json
  compile/baseline.log
  compile/candidate.log
  golden/input-manifest.jsonl
  accuracy/result.json
  performance/raw-requests.jsonl
  performance/raw-device-trace.*
  performance/summary.json
  stability/faults.jsonl
  decision.md

EXP_ID 规则:OP-<family>-<four digits>,例如 OP-MOE-0001。一次实验只改变一个主要因素;若 compiler 被迫同时改变 layout 与 quant,必须拆成 factorial 设计或明确不可归因。

4. hypothesis.yaml 模板

schema: calculet-op-experiment/v1
experiment_id: OP-FA-0001
operator_family: flash_attention
status: planned
capability: C3
hypothesis: larger sequence tile reduces DDR traffic without harming latency tails
baseline:
  calbin_sha256: REQUIRED
  compiler_oci_digest: REQUIRED
  compiler_flags: {}
candidate:
  calbin_sha256: REQUIRED
  compiler_oci_digest: REQUIRED
  changed_flags:
    attention_seq_tile: 256
controlled:
  model_hash: REQUIRED
  tokenizer_hash: REQUIRED
  quant_config_hash: REQUIRED
  runtime: 0.7.6
  driver: REQUIRED
  firmware: REQUIRED
  power_mode: REQUIRED
matrix:
  prompt_tokens: [1, 16, 128, 512, 2048, 8192, 32768, 40959]
  output_tokens: [1, 32, 256]
  concurrency: [1]
metrics:
  - numerical
  - ttft_ms
  - tpot_ms
  - per_op_cycles
  - ddr_bytes
  - d2d_bytes
  - power_w
acceptance:
  top1_match_min: 0.999
  p99_regression_max_pct: 5
  target_metric_improvement_min_pct: 8
rollback: deploy previous calbin generation

数字阈值是第一版工程门槛,可按产品 SLA 收紧;不能用平均吞吐覆盖 P99 或正确性失败。

5. 统一输入矩阵

5.1 shape 边界

Prefill token 数:1,2,15,16,17,31,32,33,127,128,129,511,512,513,1024,2048,4096,8192,16384,32768,40959

Decode past length0,1,15,16,17,127,128,1023,1024,4095,4096,8191,16383,32767,40959。总长超过 40960 的 case 是拒绝用例,不提交设备。

选择 15/16/17 是为了暴露当前 D0=16 相关 layout 边界;127/128/129 暴露 head/tile 边界。

5.2 内容分布

数据集 目的 最低样本
固定自然语言 prompt 端到端可重复 100
随机合法 token shape/数值覆盖 每长度 20
重复 token/低熵 prompt attention/KV 极端 每长度 10
多语种、代码、数字 tokenizer/量化敏感 各 50
MoE expert 覆盖集 router/expert 分布 每个 expert 至少被命中,需 trace 证明
near-tie logits top-k/quant 敏感 1000 token step

6. 数值比较规范

对每个可 dump 的 tensor 记录:shape、dtype、element count、SHA-256、min/max/mean/std、NaN/Inf、零比例。BF16/量化图不能仅使用 byte hash。

max_abs = max(|candidate-reference|)
max_rel = max(|candidate-reference| / max(|reference|, eps))
cosine  = dot(c,r) / (||c||*||r||)
top1_match, top5_overlap
token_sequence_exact_match under greedy decoding
task-level metric (perplexity/accuracy as applicable)

建议分层门槛:

层级 首轮门槛
kernel golden shape 完全一致;NaN/Inf 不新增;容差由 dtype/op 明确
layer output cosine >= 0.999(初筛,不是通用最终标准)
final logits top1 >= 99.9%top5 overlap >= 99.9%,报告 max_abs/max_rel
greedy tokens 固定 100 prompt 完全一致;若业务接受差异需专项审批
量化模型任务集 相对基线退化不超过已约定模型门槛

对于 near-tie logitstop1 翻转可能是合法浮点敏感,也可能放大成长序列差异,因此同时看 logit margin 和 token divergence point。

7. 性能统计规范

每个 case10 次 warmup,至少 30 次 measured run;短 case 建议 100 次。报告 median、P90、P99、MAD/标准差、95% bootstrap CI。温度/频率未稳定的样本不得与稳态混合。

至少分解:

client queue -> service queue -> input prepare -> H2D -> NPU wait
             -> D2H -> logits conversion -> sampling -> stream flush

设备侧要求 per-chip、per-op cyclesDDR/SRAM/D2D/PCIe bytesstall 分类,频率/功耗/温度。若厂商只能给整图时间,实验结论只能写“整图候选更快”,不能归因到某个 kernel。

8. 实验卡:fused matmul/add

8.1 当前形态

当前 YAML 示例包含 BF16 activation、U8 权重以及 BF16 scale/辅助张量,对应 W8A8/W4AF16 混合策略的编译结果。具体每层哪个矩阵使用 W8/W4 必须由 quant manifest 补齐。

8.2 候选变量

变量 候选 固定项 目标
weight quant W8 vs W4 分层 activation、layout 降权重带宽/容量
activation quant A8 vs BF16 weight、tile 降计算/带宽,关注 outlier
M/N/K tile compiler 候选 2-4 档 quant、频率 提升 core 利用率
bias/residual fusion on/off math 等价 减少中间写回
weight packing 两种 layout 数值相同 减少 unpack/stall

8.3 必测 shape

分开统计 Q/K/V/O projection、gate/up/down、expert GEMM、lm_headprefill M 随 token 数变化,decode M 近似 1。不能用大 M prefill 结果推断 decode。

8.4 通过条件

  • candidate 的目标 GEMM cycles/有效 FLOP/s 至少改善 8%。
  • 相关整图阶段至少改善 3%,否则认为局部收益被同步/搬运吞没。
  • 无新 overflow/NaNlogits/token 门槛通过。
  • 权重包大小、load time、DRAM reservation 都入报告。

9. 实验卡:Flash Attention

变量:sequence tile、head packing、Q/K/V dtype、causal mask、online softmax 精度、double buffering、prefill/decode 专用 kernel。矩阵必须覆盖 1 到 40959 的 context,特别是 tile 前后边界。

需要采集:attention cycles、DDR read/write、KV read bytes、softmax reduction stalls、D2D、峰值 workspace。验证 causal mask,确保未来 token 不影响过去输出;用单点扰动输入做 metamorphic test。

候选失败回退:关闭对应 compiler flag,恢复已知好 FA calbin。CPU fallback 只能用于诊断,不能静默进入生产。

10. 实验卡:KV scatter 与 KV layout

变量:BF16 vs S8 V-cache、写合并粒度、batch lane layout、K/V 分开策略、连续/分块地址、RoPE 前后写入。当前 BF16 KV 3.750 GiB 是容量基线。

测试:

  • token position 0、15、16、17、最后位置。
  • 两 sequence 交替写,验证绝不串 lane。
  • remove tail 后重写相同位置。
  • reset/timeout 后旧 KV 不被新 generation 使用。
  • context 逐步增大时每 token KV write/read 与 TPOT 曲线。

S8 candidate 报告真实节省量、K/V 哪部分压缩、scale 粒度、dequant 位置、任务精度、长上下文 token divergence。没有新 calbin 和 golden 不能把 header 枚举当成能力。

11. 实验卡:MoE gate pre/post

核心指标不是 gate kernel 平均时延,而是:

expert hit histogram per layer
tokens per selected expert
top-8 probability mass and margin
empty/small bucket count
max/mean expert load ratio
dispatch bytes, cross-chip bytes, padding slots

候选:top-k selection 融合、router logits 精度 BF16/FP32、排序/稳定 tie-break、dispatch compact、post-gather + weighted sum fusion。

正确性:top-8 expert id/order、权重误差、重复 expert 禁止、概率归一、tie case、NaN router input。改变 routing 的 candidate 必须做任务级评估,不能只比较最终一个 token。

12. 实验卡:grouped MoE dense

变量:expert token bucket 阈值、small-M kernel、合并多个 expert 的 grouped launch、W4/W8 分层、expert 权重预取、chip partition。

实验分桶:0、1、2-4、5-8、9-16、17-32、>32 token/expert。分别报告每个 bucket 的 cycles/token;整体平均会掩盖大量 small-M expert 的低利用率。

TP/EP A/B 只有 compiler 生成不同 partition calbin 才成立。当前两芯粒都含全部 128 experts 的分片,不是 EP。EP candidate 额外报告跨芯粒 all-to-all bytes、hot expert imbalance 和故障域。

13. 实验卡:sync/gather/dynamic D2D

13.1 问题拆分

  • sync 146 次/图:区分真实数据依赖、保守 barrier、host/CCU handoff。
  • gather 145 次/图:区分 TP partial result gather、reduce 和 layout convert。
  • prefill dynamic D2D 96 次:区分实际有效长度数据和 40960 静态上限描述。

13.2 候选

  1. 合并相邻 D2D,减少小 command。
  2. 将 barrier 下沉到真正 consumer 前。
  3. D2D 与本芯粒独立计算 overlap。
  4. 按有效 token 动态缩小传输。
  5. 改 TP split 维度,减少每层 gather。

每个候选必须提供 dependency DAG 或 compiler proof。移除 barrier 后只跑一次正确不够;需要 24h 并发、随机延迟注入和跨芯粒结果 hash。

指标:command count、size histogram、D2D bytes/time、barrier wait cycles、overlap ratio、per-chip idle。静态 dataSize 总和只作为候选之间的结构比较,不当实测流量。

14. 实验卡:RMSNorm、RoPE、residual

这些算子单个小但次数高,优先测试 producer/consumer fusion

候选 风险 数值重点
residual+RMSNorm 改变 rounding/reduction 顺序 epsilon、variance、长序列漂移
RMSNorm+QKV matmul fusion 复杂、复用 norm output layer-level cosine
RoPE+KV scatter position/layout 耦合 位置边界、shift、theta
activation+residual inplace alias race/覆盖、buffer live interval

要求 compiler 同时输出未融合/fused graph、op count diff、内存 live interval 和逐层 golden。收益门槛可低至整图 2%,但不能增加不可恢复的 alias 风险。

15. 实验卡:logits、top-k 和 sampling

当前每 token D2H 303,872 B BF16 logits,再在 CPU 转 151,936 个 FP32。分三步:

  1. C2:只转换最终需要的 vocab 范围,直接写目标 FP32,无临时 vector。
  2. C2CPU SIMD BF16 conversion/top-k A/B,保持 llama sampling 语义。
  3. C3NPU 输出 top-k values+indices 或完整 NPU sampling。

NPU top-k 需要 k 覆盖所有 sampling 策略:temperature、top-k、top-p、min-p、penalties、logprobs。固定小 k 可能破坏 top-p/penalties;不能仅凭 greedy 一致就开放。随机采样还需要 RNG seed/state、可复现性和流式 logprob 契约。

16. 量化实验设计

16.1 校准集 manifest

{"sample_id":"...","sha256":"...","domain":"code","tokens":2048,
 "tokenizer_sha256":"...","license":"...","pii_review":"passed"}

至少分 domain 报告 activation range/outlier,不只给混合平均。校准过程记录 percentile/algorithm、per-tensor/per-channel/group size、excluded layers、seed、工具版本。

16.2 分层敏感度

先对 embedding、attention QKV/O、router、experts、lm_head 单组回退 BF16/W8,计算质量恢复量与容量/性能代价。由 Pareto frontier 选 mixed precision,而不是全图一次从 W8 改 W4。

17. 自动决策规则

if correctness fails -> reject
else if any P99 SLA fails -> reject or keep experiment-only
else if target op improves but phase/graph does not -> investigate bottleneck migration
else if graph improves >= threshold and power/thermal stable -> 24h soak
else -> no-merge

报告必须同时给 absolute 和 relative 数值。例如从 2 ms 到 1 ms 是 -50%,但若整图只从 100 ms 到 99 ms,业务收益是 1%。

18. 厂商每个候选的最小交付

  1. baseline/candidate calbin 和 SHA-256。
  2. 完整 compile command、flags diff、compiler OCI digest、commits。
  3. graph/op count、partition、memory plan diff。
  4. 逐 op/layer golden、输入 manifest、容差说明。
  5. per-op/per-chip trace 和解析器。
  6. 支持的 shape/dtype/quant 边界与 fallback。
  7. 错误路径和 reset 后复测。
  8. 性能原始数据,不只汇总 PPT。

19. 首批建议实验顺序

顺序 EXP 原因 所需依赖
1 HOST-LOGITS-0001 C2 可独立完成,风险低 本地源码
2 OP-D2D-0001 当前双芯粒重复通信显著 厂商 trace+compiler
3 OP-MOE-0001 144 grouped GEMMMoE 核心 expert trace+kernel
4 OP-KV-0001 长 context TPOT 主线 KV trace+新 calbin
5 OP-FA-0001 prefill/长 context 主线 FA flags+trace
6 OP-GEMM-0001 权重/计算大头 quant manifest+kernel
7 OP-FUSION-0001 高频小 op/写回 pass 控制
8 OP-TOPK-0001 降 D2H/CPU NPU top-k contract

每完成一个实验就更新 operator evidence matrix:原假设、观测、结论、适用 shape、回滚版本和剩余不确定性。