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

329 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. 实验资产和命名
每个候选生成一组不可变资产:
```text
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` 模板
```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 length`0,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。
```text
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。温度/频率未稳定的样本不得与稳态混合。
至少分解:
```text
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 平均时延,而是:
```text
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
```json
{"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. 自动决策规则
```text
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、回滚版本和剩余不确定性。