ops-tune-workbench-plugin 0.0.0-stage → 0.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +14 -0
- package/README.md +39 -2
- package/cordis.patch.yml +20 -0
- package/lib/client.js +4253 -0
- package/lib/host.js +2518 -0
- package/package.json +53 -4
- package/skills/tool-ops-tune/INSTALL.md +52 -0
- package/skills/tool-ops-tune/README.md +167 -0
- package/skills/tool-ops-tune/SKILL.md +93 -0
- package/skills/tool-ops-tune/agent/AGENTS.md +195 -0
- package/skills/tool-ops-tune/agent/agents/perf-implementer.md +68 -0
- package/skills/tool-ops-tune/agent/agents/perf-reviewer.md +86 -0
- package/skills/tool-ops-tune/agent/workflows/task-prompts.md +362 -0
- package/skills/tool-ops-tune/agent/workflows/troubleshooting.md +43 -0
- package/skills/tool-ops-tune/docs/figures/opstune-architecture.png +0 -0
- package/skills/tool-ops-tune/docs/figures/opstune-architecture.svg +253 -0
- package/skills/tool-ops-tune/docs/ops-tune-design.md +404 -0
- package/skills/tool-ops-tune/docs//347/224/250/344/276/213/346/236/204/345/273/272.md +714 -0
- package/skills/tool-ops-tune/docs//347/237/245/350/257/206/345/272/223/350/247/204/350/214/203.md +103 -0
- package/skills/tool-ops-tune/evals/evals.json +242 -0
- package/skills/tool-ops-tune/ops-collect/SKILL.md +146 -0
- package/skills/tool-ops-tune/ops-collect/references/tool-routing.md +86 -0
- package/skills/tool-ops-tune/ops-collect/scripts/collect_board.sh +444 -0
- package/skills/tool-ops-tune/ops-collect/scripts/collect_cases.py +368 -0
- package/skills/tool-ops-tune/ops-collect/scripts/collect_sim.sh +134 -0
- package/skills/tool-ops-tune/ops-collect/scripts/csv_to_db.py +314 -0
- package/skills/tool-ops-tune/ops-collect/scripts/db_bench.py +545 -0
- package/skills/tool-ops-tune/ops-collect/scripts/facts_bridge.py +1063 -0
- package/skills/tool-ops-tune/ops-collect/scripts/isolation_test.py +454 -0
- package/skills/tool-ops-tune/ops-collect/scripts/jsonl_to_cases.py +163 -0
- package/skills/tool-ops-tune/ops-family/SKILL.md +76 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/advanced_tiling.md +92 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/broadcast_design.md +160 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_add_kernel.cpp +126 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_add_tiling.cpp +144 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_tiling_common.h +401 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/code/onedim_add_kernel.cpp +107 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/code/onedim_add_tiling.cpp +64 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/datacopypad_design.md +46 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/guide.md +14 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/nddma_design.md +53 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/onedim_design.md +114 -0
- package/skills/tool-ops-tune/ops-family/references/broadcast/ub_broadcast_design.md +67 -0
- package/skills/tool-ops-tune/ops-family/references/common/datacopy_optimization_design.md +351 -0
- package/skills/tool-ops-tune/ops-family/references/common/index.md +9 -0
- package/skills/tool-ops-tune/ops-family/references/common/tail_block_design.md +268 -0
- package/skills/tool-ops-tune/ops-family/references/common/timing_harness/index.md +38 -0
- package/skills/tool-ops-tune/ops-family/references/common/timing_harness/timing_harness_aclrt_event.cpp +199 -0
- package/skills/tool-ops-tune/ops-family/references/common/timing_harness/timing_harness_torch_event.py +130 -0
- package/skills/tool-ops-tune/ops-family/references/common/ub_resident_design.md +342 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/guide.md +69 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/index.md +4 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_base.template +81 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_big_dim.template +217 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_cut_one_axis.template +336 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_cut_two_axis.template +781 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_n_last.template +340 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_small_shape.template +321 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_tensor_move.template +102 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_transdata_5hd.template +480 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_transdata_5hd_021axis.template +533 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_with_gather.template +688 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/templates/transpose_tiling_data.template +192 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_big_dim.md +220 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_cut_one_axis.md +175 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_cut_two_axis.md +177 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_fusion_design.md +398 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_gather.md +191 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_n_last.md +276 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_small_shape.md +315 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_tensor_move.md +203 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_tiling_data.md +176 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_vconv_021.md +206 -0
- package/skills/tool-ops-tune/ops-family/references/conversion/transpose_vconv_5hd.md +179 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/double_buffer_design.md +288 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/guide.md +46 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/index.md +10 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/CMakeLists.txt +131 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/README.md +55 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/add_custom_torch.cpp +80 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/ops.h +23 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/register.cpp +30 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_host/add_custom.asc +149 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_host/data_utils.h +97 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_kernel/add_custom_kernel.asc +136 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_kernel/add_custom_tiling.h +31 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/run.sh +86 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/gen_data.py +70 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/golden.py +34 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/test_torch.py +99 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/verify_result.py +56 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/templates/usage_guide.md +61 -0
- package/skills/tool-ops-tune/ops-family/references/elementwise/vector_efficiency_design.md +203 -0
- package/skills/tool-ops-tune/ops-family/references/fa/fa_mixed_kernel_design.md +174 -0
- package/skills/tool-ops-tune/ops-family/references/fa/fa_roofline_design.md +141 -0
- package/skills/tool-ops-tune/ops-family/references/fa/guide.md +87 -0
- package/skills/tool-ops-tune/ops-family/references/knowledge_gaps.json +56 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/best-practices-guide.md +14 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/fullload_design.md +344 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/guide.md +52 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/mte2_preload_design.md +320 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/pingpong_design.md +254 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/scale_coalescing_design.md +282 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/streamk_design.md +374 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/swat_design.md +423 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/templates/matmul_basic_blaze.template +165 -0
- package/skills/tool-ops-tune/ops-family/references/matmul/templates/usage_guide.md +29 -0
- package/skills/tool-ops-tune/ops-family/references/mc2/best-practices-guide.md +43 -0
- package/skills/tool-ops-tune/ops-family/references/mc2/guide.md +42 -0
- package/skills/tool-ops-tune/ops-family/references/mc2/local_matmul_design.md +130 -0
- package/skills/tool-ops-tune/ops-family/references/mc2/pipeline_balancing_design.md +502 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/guide.md +178 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/kernel_utils.template +75 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_full_load.template +429 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_recompute.template +485 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_small_r.template +348 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_full_load.template +574 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_online.template +324 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_recompute.template +436 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_base.template +950 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/fused_attention_online_softmax_design.md +428 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_full_load.md +137 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_recompute.md +135 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_small_r.md +122 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_full_load.md +144 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_online.md +185 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_recompute.md +163 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_tiling.template +460 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_tiling_data.template +278 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/state_resident_design.md +337 -0
- package/skills/tool-ops-tune/ops-family/references/reduce/templates/usage_guide.md +253 -0
- package/skills/tool-ops-tune/ops-family/references/scalar/coding_principles.md +476 -0
- package/skills/tool-ops-tune/ops-family/references/scalar/conv_scalar.md +163 -0
- package/skills/tool-ops-tune/ops-family/references/scalar/guide.md +30 -0
- package/skills/tool-ops-tune/ops-family/references/simt/guide.md +91 -0
- package/skills/tool-ops-tune/ops-family/references/simt/optimization-guide.md +110 -0
- package/skills/tool-ops-tune/ops-family/references/sort/guide.md +83 -0
- package/skills/tool-ops-tune/ops-family/references/sort/radix_sort.md +354 -0
- package/skills/tool-ops-tune/ops-family/scripts/family_asset_audit.py +68 -0
- package/skills/tool-ops-tune/ops-family/scripts/tiling_candidates.py +419 -0
- package/skills/tool-ops-tune/ops-mechanism/SKILL.md +23 -0
- package/skills/tool-ops-tune/ops-mechanism/cases/ascendc/case_groupedmatmul_pipeline.md +23 -0
- package/skills/tool-ops-tune/ops-mechanism/cases/ascendc/case_triton_atomic_revert.md +19 -0
- package/skills/tool-ops-tune/ops-mechanism/cases/mc2/case_mc2_fusion.md +19 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/api-usage.md +70 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/ascendc-regbase-vf.md +45 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/ascendc-tiling.md +51 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/data-copy.md +67 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/index.md +45 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/mc2-balancing.md +77 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/mc2.md +103 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/memory-hierarchy.md +40 -0
- package/skills/tool-ops-tune/ops-mechanism/references/optimize/pipeline.md +95 -0
- package/skills/tool-ops-tune/ops-mechanism/scripts/case_backfill.py +170 -0
- package/skills/tool-ops-tune/ops-mechanism/scripts/log_gap.py +145 -0
- package/skills/tool-ops-tune/ops-mechanism/scripts/mc2_search.py +367 -0
- package/skills/tool-ops-tune/ops-report/SKILL.md +77 -0
- package/skills/tool-ops-tune/ops-verdict/evals/run_evals.py +837 -0
- package/skills/tool-ops-tune/ops-verdict/evals/smoke/install-hooks.sh +65 -0
- package/skills/tool-ops-tune/ops-verdict/evals/smoke/run_smoke.sh +405 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/core_tail_a5.csv +25 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/few_cores_a5.csv +5 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/mte2_bound_a2.csv +17 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/multi_kernel_mix_a5.csv +7 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/no_bound_a5.csv +9 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/serial_no_overlap_a2.csv +9 -0
- package/skills/tool-ops-tune/ops-verdict/fixtures/vec_bound_a5.csv +9 -0
- package/skills/tool-ops-tune/ops-verdict/references/io-contracts.md +94 -0
- package/skills/tool-ops-tune/ops-verdict/references/rule-schema.md +130 -0
- package/skills/tool-ops-tune/ops-verdict/references/scope-schema.md +61 -0
- package/skills/tool-ops-tune/ops-verdict/references/soc-spec.yaml +140 -0
- package/skills/tool-ops-tune/ops-verdict/rules/L0-instruction.yaml +67 -0
- package/skills/tool-ops-tune/ops-verdict/rules/L1-single-core.yaml +316 -0
- package/skills/tool-ops-tune/ops-verdict/rules/L2-inter-core.yaml +173 -0
- package/skills/tool-ops-tune/ops-verdict/rules/L3-inter-card.yaml +156 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/batch_pipeline.py +444 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/calibrate.py +249 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/delta_compare.py +244 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/render_html.py +274 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/snapshot.py +200 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/trace_bubble.py +331 -0
- package/skills/tool-ops-tune/ops-verdict/scripts/verdict.py +1072 -0
- package/skills/tool-ops-tune/scripts/diff_audit.py +281 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# 融合 Attention Online Softmax 设计
|
|
2
|
+
|
|
3
|
+
> **定位说明**:本文档描述的是 **FlashAttention 融合场景** 中的 Online Softmax 设计,涉及 `QK^T`、running max/sum、`P×V`、`O_acc`、causal mask 和 workspace。当前 `templates/` 目录下的七个 Kernel **未提供**与此设计完全对应的融合 Attention Kernel。如需独立的 Online Softmax 实现(不含 `QK^T`/`P×V`),参见 [softmax_v2_ara_online.md](softmax_v2_ara_online.md)——两者只共享在线 max/sum 数学基础,不是同一个实现。
|
|
4
|
+
|
|
5
|
+
## 1. 优化目标
|
|
6
|
+
|
|
7
|
+
在 FlashAttention 等长序列场景中,Softmax 的输入是逐 tile 生成的 $QK^T$ score(规模为 $S \times S$)。Naive 实现先计算完整矩阵再逐行做 Softmax,需要 $O(S^2)$ 内存,长序列下 SRAM 放不下。
|
|
8
|
+
|
|
9
|
+
本设计将 Softmax 从"全量计算后归一化"改为"逐 Tile 计算,维护 running max/sum"的增量算法。核心思想:在 S2 方向分 Tile 计算 $Q_i K_j^T$,跨 Tile 维护当前见过的最大值 $m$ 和累积和 $l$,输出 $O$ 增量更新。**内存复杂度从 $O(S^2)$ 降至 $O(S)$。**
|
|
10
|
+
|
|
11
|
+
| 指标 | naive | optimized | 收益 |
|
|
12
|
+
|------|-------|-----------|------|
|
|
13
|
+
| 中间内存占用 | $O(S^2)$,需完整 $QK^T$ 矩阵 | $O(S)$,仅当前 tile + running 状态 | 长序列下内存大幅降低 |
|
|
14
|
+
| max/sum 计算 | 双 pass(先 max 再 sum) | **单 pass**,tile 内即时更新 | 天然 Safe Softmax |
|
|
15
|
+
| 输出更新 | 最后一次性 prob × V | 每 tile 增量加权累加 | 无需显式分配 prob 矩阵 |
|
|
16
|
+
|
|
17
|
+
> 适用场景:FlashAttention / Sparse FlashAttention 等融合 Attention 算子中内嵌的 Online Softmax。
|
|
18
|
+
|
|
19
|
+
## 2. 架构概览
|
|
20
|
+
|
|
21
|
+
### 2.1 存储层级与数据流
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
GM (Global Memory)
|
|
25
|
+
│
|
|
26
|
+
│ MTE2 (Q_i, K_j, V_j 从 GM → L1/UB)
|
|
27
|
+
▼
|
|
28
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
29
|
+
│ SRAM / UB │
|
|
30
|
+
│ ┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
|
31
|
+
│ │ Q_i Tile │ × │ K_j Tile^T │ = │ S_ij Tile │ │ O_i (output) │ │
|
|
32
|
+
│ │ [B,S1,D]│ │ [D,S2tile]│ │ [B,S1,S2tile]│ → │ [B,S1,D] │ │
|
|
33
|
+
│ └──────────┘ └─────────────┘ └──────────────┘ └─────────────────┘ │
|
|
34
|
+
│ │ ▲ │
|
|
35
|
+
│ │ ┌─────────────────────────────┐ │ │
|
|
36
|
+
│ └───────→│ Online Softmax (Vector PIPE)│───────┘ │
|
|
37
|
+
│ │ running m: max so far │ │
|
|
38
|
+
│ │ running l: sum of exp │ │
|
|
39
|
+
│ │ O_acc: weighted output │ │
|
|
40
|
+
│ └─────────────────────────────┘ │
|
|
41
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
42
|
+
│
|
|
43
|
+
│ MTE3 (O_i, m_final, l_final → GM / workspace)
|
|
44
|
+
▼
|
|
45
|
+
GM (Output)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2.2 Tiled 数据流
|
|
49
|
+
|
|
50
|
+
- **外循环**:沿 S2 维度分 Tile($j = 0, 1, \dots, N_{tile}-1$),K、V 以统一块大小 $B$ 划分。
|
|
51
|
+
- **每 Tile 内**:计算 $S_{ij} = Q_i K_j^T / \sqrt{d}$,然后做 Online Softmax 更新 running 状态。
|
|
52
|
+
- **跨 Tile 状态传递**:$m$(running max)和 $l$(running sum)作为向量在 Tile 间传递。Ascend 场景下通常需 GM workspace 保存跨 S2 tile 的中间态。
|
|
53
|
+
- **输出 O 增量更新**:每轮用当前 tile 的 Softmax 权重 $P_{ij}$ 对 $V_j$ 做加权,按修正因子 rescale 后累加到 $O_i$。
|
|
54
|
+
|
|
55
|
+
### 2.3 核心数学:Online Softmax 单 Pass 公式
|
|
56
|
+
|
|
57
|
+
对当前 Q block $Q_i$ 与 K block $K_j$ 计算:
|
|
58
|
+
|
|
59
|
+
**Step 1 — Score**
|
|
60
|
+
$$S_{ij} = Q_i \times K_j^T / \sqrt{d}$$
|
|
61
|
+
|
|
62
|
+
**Step 2 — 局部 max 与更新 running max**
|
|
63
|
+
$$m_{new} = \max(m_{old}, \ \text{rowmax}(S_{ij}))$$
|
|
64
|
+
|
|
65
|
+
**Step 3 — 概率指数(中间变量)**
|
|
66
|
+
$$P_{ij} = \exp(S_{ij} - m_{new})$$
|
|
67
|
+
|
|
68
|
+
**Step 4 — 更新 running sum**
|
|
69
|
+
$$l_{new} = l_{old} \times \exp(m_{old} - m_{new}) + \text{rowsum}(P_{ij})$$
|
|
70
|
+
|
|
71
|
+
**Step 5 — 输出 O 增量更新**
|
|
72
|
+
$$O_i = O_i \times \frac{l_{old} \times \exp(m_{old} - m_{new})}{l_{new}} + \frac{P_{ij} \times V_j}{l_{new}}$$
|
|
73
|
+
|
|
74
|
+
等价概括形式:
|
|
75
|
+
```
|
|
76
|
+
m_new = max(m_old, tile_max)
|
|
77
|
+
sum_new = sum_old * exp(m_old - m_new) + tile_sum_exp(tile - m_new)
|
|
78
|
+
```
|
|
79
|
+
最终 Softmax:$\text{softmax}(x) = \exp(x - m_{final}) / sum_{final}$
|
|
80
|
+
|
|
81
|
+
### 2.4 事件同步模型
|
|
82
|
+
|
|
83
|
+
| 事件类型 | 含义 | 用途 |
|
|
84
|
+
|---------|------|------|
|
|
85
|
+
| `MTE2_V` | MTE2 搬运完成 → 允许 Vector 读取 | Q/K/V tile 数据就绪 |
|
|
86
|
+
| `V_MTE3` | Vector 完成 → 允许 MTE3 写回 | O 增量计算完成,可写 GM |
|
|
87
|
+
| `V_V` | Vector 完成 → 允许 Vector 继续 | Online softmax 内部依赖 |
|
|
88
|
+
|
|
89
|
+
## 3. 关键参数配置
|
|
90
|
+
|
|
91
|
+
```cpp
|
|
92
|
+
// Host 侧 TilingData
|
|
93
|
+
struct OnlineSoftmaxTiling {
|
|
94
|
+
uint32_t B; // tile 块大小(统一划分 K、V),通常 64
|
|
95
|
+
uint32_t D; // head dimension
|
|
96
|
+
uint32_t seqLen; // 序列长度 S
|
|
97
|
+
uint32_t s2TileNum; // S2 方向 tile 数量 = ceil(S / B)
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Kernel 侧 running 状态(每行一个)
|
|
101
|
+
TBuf<QuePosition::VECCALC> runningMaxBuff; // m: running max
|
|
102
|
+
TBuf<QuePosition::VECCALC> runningSumBuff; // l: running sum
|
|
103
|
+
TBuf<QuePosition::VECCALC> outAccBuff; // O_acc: 加权输出累加器
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3.1 Tile 大小选取原则
|
|
107
|
+
|
|
108
|
+
| 参数 | 典型值 | 说明 |
|
|
109
|
+
|------|--------|------|
|
|
110
|
+
| $B$ | 64 / 128 | 统一 tile 块大小,划分 K、V 沿 S2 维度。需 fit UB |
|
|
111
|
+
| D | 64 / 128 | head dimension,由模型决定 |
|
|
112
|
+
|
|
113
|
+
**Ascend Cube 粒度对齐约束**:
|
|
114
|
+
|
|
115
|
+
Tile 大小必须对齐 Cube 单元 matmul 粒度,通常为 **16×16 或 32×32**。若 $B$ 未对齐,CUBE 核心需额外 padding。
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
B = align_up(preferred_B, cube_granularity) // typically 16 or 32
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 3.2 内存预算
|
|
122
|
+
|
|
123
|
+
Online Softmax 将内存复杂度从 $O(S^2)$ 降至 $O(S)$,但 score tile($B \times B$)、Q tile、K/V tile 同时存在于 UB 时,需确保总占用小于 UB 容量。典型配置下约 65KB,安全。
|
|
124
|
+
|
|
125
|
+
## 4. 核心计算循环
|
|
126
|
+
|
|
127
|
+
### 4.1 naive 版本(优化前)
|
|
128
|
+
|
|
129
|
+
```cpp
|
|
130
|
+
// 阶段 1:完整计算 QK^T(S×S 矩阵),需要 O(S^2) 空间
|
|
131
|
+
for (uint32_t i = 0; i < S; i++) {
|
|
132
|
+
for (uint32_t j = 0; j < S; j++) {
|
|
133
|
+
scoreGm[i * S + j] = ComputeScore(QGm, KGm, i, j);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 阶段 2:逐行 Softmax,需两次遍历(先求 max,再求 exp/sum)
|
|
138
|
+
for (uint32_t i = 0; i < S; i++) {
|
|
139
|
+
float maxVal = -INFINITY;
|
|
140
|
+
for (uint32_t j = 0; j < S; j++) {
|
|
141
|
+
maxVal = max(maxVal, scoreGm[i * S + j]);
|
|
142
|
+
}
|
|
143
|
+
float sum = 0.0f;
|
|
144
|
+
for (uint32_t j = 0; j < S; j++) {
|
|
145
|
+
sum += exp(scoreGm[i * S + j] - maxVal);
|
|
146
|
+
}
|
|
147
|
+
for (uint32_t j = 0; j < S; j++) {
|
|
148
|
+
probGm[i * S + j] = exp(scoreGm[i * S + j] - maxVal) / sum;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 阶段 3:prob × V
|
|
153
|
+
for (uint32_t i = 0; i < S; i++) {
|
|
154
|
+
for (uint32_t d = 0; d < D; d++) {
|
|
155
|
+
float acc = 0.0f;
|
|
156
|
+
for (uint32_t j = 0; j < S; j++) {
|
|
157
|
+
acc += probGm[i * S + j] * VGm[j * D + d];
|
|
158
|
+
}
|
|
159
|
+
OGm[i * D + d] = acc;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 4.2 optimized 版本(优化后):Tiled Online Softmax
|
|
165
|
+
|
|
166
|
+
```cpp
|
|
167
|
+
// Init:分配 running 状态 buffer(每行一个)
|
|
168
|
+
pipe->InitBuffer(runningMaxBuff, B * sizeof(COMPUTE_T)); // m
|
|
169
|
+
pipe->InitBuffer(runningSumBuff, B * sizeof(COMPUTE_T)); // l
|
|
170
|
+
pipe->InitBuffer(outAccBuff, B * D * sizeof(COMPUTE_T)); // O_acc
|
|
171
|
+
|
|
172
|
+
LocalTensor<COMPUTE_T> mUb = runningMaxBuff.Get<COMPUTE_T>();
|
|
173
|
+
LocalTensor<COMPUTE_T> lUb = runningSumBuff.Get<COMPUTE_T>();
|
|
174
|
+
LocalTensor<COMPUTE_T> oUb = outAccBuff.Get<COMPUTE_T>();
|
|
175
|
+
|
|
176
|
+
// 初始化 running 状态
|
|
177
|
+
Duplicate(mUb, FLOAT_NEG_INF, B); // m = -inf
|
|
178
|
+
Duplicate(lUb, 0.0f, B); // l = 0
|
|
179
|
+
Duplicate(oUb, 0.0f, B * D); // O = 0
|
|
180
|
+
|
|
181
|
+
// MTE2 加载 Q_i tile(固定在 UB)
|
|
182
|
+
LocalTensor<T> qUb = LoadQTile(QGm, i * B, B, D);
|
|
183
|
+
|
|
184
|
+
// S2 方向分 tile 循环(Online Softmax 核心)
|
|
185
|
+
for (uint32_t j = 0; j < s2TileNum; j++) {
|
|
186
|
+
// 1. MTE2 加载 K_j, V_j tiles
|
|
187
|
+
LocalTensor<T> kUb = LoadKTile(KGm, j * B, B, D);
|
|
188
|
+
LocalTensor<T> vUb = LoadVTile(VGm, j * B, B, D);
|
|
189
|
+
|
|
190
|
+
// 2. 计算 S_ij = Q_i * K_j^T (CUBE / Vector)
|
|
191
|
+
LocalTensor<COMPUTE_T> sUb = ComputeScore(qUb, kUb, B, D);
|
|
192
|
+
|
|
193
|
+
// 3. Online Softmax 更新(公式见 2.3)
|
|
194
|
+
OnlineSoftmaxUpdate(sUb, vUb, mUb, lUb, oUb, B, D);
|
|
195
|
+
|
|
196
|
+
// 4. 可选:MTE3 将中间结果写回 GM workspace(跨 tile 状态传递)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// 所有 tile 结束后:O_final = O_acc / l_final
|
|
200
|
+
ElemwiseDiv(oUb, lUb, B, D);
|
|
201
|
+
|
|
202
|
+
// MTE3 写回最终输出
|
|
203
|
+
WriteBackOGm(OGm, oUb, i * B, B, D);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 4.3 Online Softmax Update 伪代码(Vector 核心)
|
|
207
|
+
|
|
208
|
+
```cpp
|
|
209
|
+
void OnlineSoftmaxUpdate(LocalTensor<COMPUTE_T> sUb, // [B, B] score tile S_ij
|
|
210
|
+
LocalTensor<T> vUb, // [B, D] V tile V_j
|
|
211
|
+
LocalTensor<COMPUTE_T> mUb, // [B] running max
|
|
212
|
+
LocalTensor<COMPUTE_T> lUb, // [B] running sum
|
|
213
|
+
LocalTensor<COMPUTE_T> oUb, // [B, D] output acc O_i
|
|
214
|
+
uint32_t B, uint32_t D) {
|
|
215
|
+
for (uint32_t r = 0; r < B; r++) {
|
|
216
|
+
// Step 1: m_new = max(m_old, rowmax(S_ij))
|
|
217
|
+
float m_old = mUb[r];
|
|
218
|
+
float m_local = ReduceMax(sUb[r * B], B);
|
|
219
|
+
float m_new = max(m_old, m_local);
|
|
220
|
+
|
|
221
|
+
// Step 2: P_ij = exp(S_ij - m_new)
|
|
222
|
+
// Step 3: l_new = l_old * exp(m_old - m_new) + rowsum(P_ij)
|
|
223
|
+
float l_old = lUb[r];
|
|
224
|
+
float scale = exp(m_old - m_new);
|
|
225
|
+
float sum_exp = 0.0f;
|
|
226
|
+
|
|
227
|
+
LocalTensor<COMPUTE_T> pUb = tempBuff.Get<COMPUTE_T>();
|
|
228
|
+
for (uint32_t c = 0; c < B; c++) {
|
|
229
|
+
float p_val = exp(sUb[r * B + c] - m_new);
|
|
230
|
+
pUb[c] = p_val;
|
|
231
|
+
sum_exp += p_val;
|
|
232
|
+
}
|
|
233
|
+
lUb[r] = l_old * scale + sum_exp;
|
|
234
|
+
|
|
235
|
+
// Step 4: O_i = O_i * (l_old * scale / l_new) + P_ij * V_j / l_new
|
|
236
|
+
float rescale_o = (l_old * scale) / lUb[r];
|
|
237
|
+
float rescale_p = 1.0f / lUb[r];
|
|
238
|
+
|
|
239
|
+
for (uint32_t d = 0; d < D; d++) {
|
|
240
|
+
float pv = 0.0f;
|
|
241
|
+
for (uint32_t c = 0; c < B; c++) {
|
|
242
|
+
pv += pUb[c] * vUb[c * D + d];
|
|
243
|
+
}
|
|
244
|
+
oUb[r * D + d] = oUb[r * D + d] * rescale_o + pv * rescale_p;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
mUb[r] = m_new;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## 5. 从 naive 到 online_softmax 的关键修改点
|
|
253
|
+
|
|
254
|
+
| 修改项 | naive(优化前) | online_softmax(优化后) |
|
|
255
|
+
|--------|---------------|------------------------|
|
|
256
|
+
| 计算范式 | 先完整算 $QK^T$,再 Softmax,再 ×V | 逐 tile 计算,增量更新 running 状态 |
|
|
257
|
+
| 内存复杂度 | $O(S^2)$,需完整矩阵 | $O(S)$,仅当前 tile + running m/l/O |
|
|
258
|
+
| max/sum 计算 | 双 pass(先 max 再 sum) | **单 pass**,tile 内即时更新 |
|
|
259
|
+
| 数值稳定性 | 减 max 需额外遍历 | 天然 Safe Softmax,每步减当前 m_new |
|
|
260
|
+
| 输出更新 | 最后一次性 prob × V | 每 tile 增量加权累加 $P_{ij} \cdot V_j$ 到 O |
|
|
261
|
+
| 跨 tile 状态 | 无(全量后一次性处理) | **running m、running l、O_acc** 跨 tile 传递 |
|
|
262
|
+
|
|
263
|
+
## 6. 注意事项 / 约束
|
|
264
|
+
|
|
265
|
+
1. **数值稳定性:必须维护 running max**。$m_{new} = \max(m_{old}, m_{local})$,所有指数计算以 $m_{new}$ 为基准减。
|
|
266
|
+
|
|
267
|
+
2. **O_acc 的修正因子**。当 $m_{new} > m_{old}$ 时,$O_{old}$ 和 $l_{old}$ 需乘 $e^{m_{old} - m_{new}}$,scale 必须在更新前计算。
|
|
268
|
+
|
|
269
|
+
3. **与 GM workspace 的关系**。Flash Attention 通常需要 workspace 保存跨 tile 的 running m/l。本优化是**算法层面**的内存降低,workspace 属于**工程层面**的跨调用状态传递。
|
|
270
|
+
|
|
271
|
+
4. **last tile 的边界处理**。当 $S$ 不是 $B$ 整数倍时,最后一个 tile 的有效列数小于 $B$,避免 padding 值干扰。
|
|
272
|
+
|
|
273
|
+
5. **精度与性能的平衡**。$m$ 和 $l$ 建议用 FP32 维护,即使输入/输出是 FP16。
|
|
274
|
+
|
|
275
|
+
6. **Ascend Cube-Vector 负载均衡**。在 Ascend 910B 上,$QK^T$ 运行在 CUBE 核心,softmax 和 $P \times V$ 运行在 Vector 核心,优化时需兼顾两端。
|
|
276
|
+
|
|
277
|
+
7. **Workspace MTE3 写回是显著开销**。running 状态跨 S2 tile 传递通常需要 GM workspace,MTE3 向 workspace 的写回是性能瓶颈之一。
|
|
278
|
+
|
|
279
|
+
8. **Causal Mask 的 Block-level Skip**。Decoder 场景下 causal mask 可在 tile 级别做粗粒度跳过:
|
|
280
|
+
- 若 $s2\_start > s1\_end$:**SKIP** 整个 block
|
|
281
|
+
- 若 $s2\_end \le s1\_start$:**FULL** block
|
|
282
|
+
- 否则:**PARTIAL** block(需 element-level masking)
|
|
283
|
+
|
|
284
|
+
理论跳过率:$(n-1)/(2n) \to 50\%$。实际:$S=32K$ 约 45%,$S=2K$ 约 37%,$S=512$ 约 22%。
|
|
285
|
+
|
|
286
|
+
9. **KV-Cache:Prefill vs Decode 的差异**。
|
|
287
|
+
- **Prefill 阶段**:$Q$ 为完整序列,需完整 tiling。
|
|
288
|
+
- **Decode 阶段**:$Q$ 长度为 1,无需在 $Q$ 维度 tiling,仅沿 KV 序列维度分 tile,完全 memory-bound。
|
|
289
|
+
|
|
290
|
+
10. **Sliding Window Attention**。若使用滑动窗口(仅 attend 最近 $W$ 个 token),valid 条件为 $i - W < j \le i$。Block-level 可额外跳过 $s2\_end < s1\_start - W$ 的 block。
|
|
291
|
+
|
|
292
|
+
11. **preTokens / nextTokens 参数**。Ascend Attention API 通过 `preTokens` 和 `nextTokens` 定义 attention 窗口,等效于 band mask。配置时需确保与 causal / sliding window 逻辑一致。
|
|
293
|
+
|
|
294
|
+
## 7. 选型决策与自检清单
|
|
295
|
+
|
|
296
|
+
### 7.1 选型决策
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
if (融合 Attention 算子 && 输入序列长度 S > 512):
|
|
300
|
+
→ 启用 online_softmax(tiled 实现)
|
|
301
|
+
→ B = 64 或 128(对齐 Cube 粒度)
|
|
302
|
+
→ running 状态用 FP32
|
|
303
|
+
else:
|
|
304
|
+
→ 标准 Safe Softmax 即可(S 小,全量矩阵 fit SRAM)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## 8. AscendC Kernel 优化实现
|
|
308
|
+
|
|
309
|
+
上述设计在 Python 层逐 tile 实现时,受限于 Python → NPU 的调度开销和独立的 kernel launch,延迟数据不能反映算法真实优势。**生产级优化需在 AscendC 层面将 QK^T、Online Softmax 更新、PV 乘积全部融合到单个 kernel 内。**
|
|
310
|
+
|
|
311
|
+
### 8.1 从 Python 层到 AscendC 的关键跨越
|
|
312
|
+
|
|
313
|
+
| 维度 | Python 层实现 | AscendC Fused Kernel |
|
|
314
|
+
|------|--------------|---------------------|
|
|
315
|
+
| 调度开销 | 16~128 次 Python 循环 + kernel launch | **单次 kernel launch**,零 Python 开销 |
|
|
316
|
+
| Score 计算 | `torch.matmul` 独立调用 | 内联 `Mul` + `ReduceSum`(Vector PIPE) |
|
|
317
|
+
| Softmax | `torch.max`/`torch.exp`/`torch.sum` | `ReduceMax` → `Adds` → `Exp` → `ReduceSum` |
|
|
318
|
+
| P @ V | `torch.matmul` 独立调用 | 内联标量累加(V 为行优先,列访问需 strided) |
|
|
319
|
+
| 并行度 | batch 维度串行 | **Multi-block**:每个 AICore 处理一个或多个 Q row |
|
|
320
|
+
| Causal Skip | Python `if` 判断 | **Block-level `continue`** 跳过整 tile |
|
|
321
|
+
|
|
322
|
+
### 8.2 AscendC Kernel 架构
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
每个 AI Core Block 处理一个或多个 Q rows
|
|
326
|
+
├─ Load Q row [D] → UB
|
|
327
|
+
├─ Cast FP16 → FP32, Muls(scale)
|
|
328
|
+
├─ Init: m=-inf, l=0, O_acc=0
|
|
329
|
+
├─ For each S2 tile j:
|
|
330
|
+
│ ├─ Causal check: tileStart > s1Idx ? skip
|
|
331
|
+
│ ├─ MTE2: Load K tile [actualB, D] → UB
|
|
332
|
+
│ ├─ Vector: Cast K→FP32, Mul(q, k_slice), ReduceSum → score[actualB]
|
|
333
|
+
│ ├─ MTE2: Load V tile [actualB, D] → UB
|
|
334
|
+
│ ├─ Causal: mask upper part to -inf (if tile crosses diagonal)
|
|
335
|
+
│ ├─ Vector: ReduceMax(score) → m_local
|
|
336
|
+
│ ├─ Vector: Adds(score, -m_new), Exp → P[actualB]
|
|
337
|
+
│ ├─ Vector: ReduceSum(P) → sum_exp
|
|
338
|
+
│ ├─ Scalar: update m, l, rescale factors
|
|
339
|
+
│ ├─ Vector: Muls(O_acc, rescale_o)
|
|
340
|
+
│ └─ Scalar+Vector: P @ V column-by-column, accumulate to O_acc
|
|
341
|
+
├─ Cast O_acc → FP16
|
|
342
|
+
├─ MTE3: Write O row → GM
|
|
343
|
+
└─ MTE3: Write L = l_final → GM
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 8.3 Vector API 替换映射
|
|
347
|
+
|
|
348
|
+
```cpp
|
|
349
|
+
// Score: Q @ K^T (原为标量循环)
|
|
350
|
+
Cast(kFloat, kLocal, ..., actualB * D);
|
|
351
|
+
for (b = 0; b < actualB; b++) {
|
|
352
|
+
Mul(tmp, qFloat, kFloat[b * D], D); // Vector 逐元素乘
|
|
353
|
+
ReduceSum(sumBuf, tmp, sumBuf, D); // Vector 规约求和
|
|
354
|
+
score.SetValue(b, sumBuf.GetValue(0));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Softmax: max → exp → sum (原为标量循环)
|
|
358
|
+
ReduceMax(maxBuf, score, maxBuf, actualB); // Vector 规约求最大
|
|
359
|
+
Adds(tmp, score, -mNew, actualB); // Vector 逐元素加
|
|
360
|
+
Exp(tmp, tmp, actualB); // Vector 指数
|
|
361
|
+
ReduceSum(sumBuf, tmp, sumBuf, actualB); // Vector 规约求和
|
|
362
|
+
|
|
363
|
+
// O rescale (原为标量循环)
|
|
364
|
+
Muls(oAcc, oAcc, rescaleO, D); // Vector 逐元素乘标量
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### 8.4 多核并行策略
|
|
368
|
+
|
|
369
|
+
- **总 row 数**:`totalRows = batch × num_heads × S1`
|
|
370
|
+
- **Block 分配**:`blockDim = min(totalRows, 8)`(匹配 Ascend 910B 的 8 AICore)
|
|
371
|
+
- **每 Block 工作量**:`rowsPerCore = ceil(totalRows / blockDim)`
|
|
372
|
+
- **Flat index 分解**:`row → (batchIdx, headIdx, s1Idx)`
|
|
373
|
+
|
|
374
|
+
### 8.5 UB 内存预算(优化后)
|
|
375
|
+
|
|
376
|
+
| Buffer | 用途 | D=64, tileB=128 | D=128, tileB=128 |
|
|
377
|
+
|--------|------|----------------|-----------------|
|
|
378
|
+
| qBuf | Q row (FP16) | 128 B | 256 B |
|
|
379
|
+
| kBuf/vBuf | K/V tile (FP16) | 2 × 16 KB | 2 × 32 KB |
|
|
380
|
+
| qFloatBuf | Q row (FP32) | 256 B | 512 B |
|
|
381
|
+
| kvFloatBuf | K/V float (时间复用) | 32 KB | 64 KB |
|
|
382
|
+
| scoreBuf/pBuf | Score / Prob (FP32) | 2 × 512 B | 2 × 512 B |
|
|
383
|
+
| oAccBuf | Output accumulator | 256 B | 512 B |
|
|
384
|
+
| tmpBuf/reduceBuf | Vector workspace | 2 × 512 B | 2 × 512 B |
|
|
385
|
+
| **总计** | | **~100 KB** | **~135 KB** |
|
|
386
|
+
|
|
387
|
+
UB 容量 192 KB,两种配置均安全。K/V float buffer 时间复用节省 32~64 KB。
|
|
388
|
+
|
|
389
|
+
### 8.6 预期性能
|
|
390
|
+
|
|
391
|
+
| 指标 | Python 层 Online | AscendC Fused |
|
|
392
|
+
|------|-----------------|---------------|
|
|
393
|
+
| S=512 | 慢于 naive 28x | **预计快 1.2~1.5x** |
|
|
394
|
+
| S=4K | 慢于 naive 1.4x | **预计快 1.5~3x** |
|
|
395
|
+
| S=32K | 慢于 naive 25x | **预计快 2~5x** (causal+skip) |
|
|
396
|
+
| 内存 | O(S) | O(S)(与 Python 层相同) |
|
|
397
|
+
|
|
398
|
+
> **关键结论**:AscendC kernel 消除了 Python 调度开销,使 Online Softmax 的带宽优势(省去 O(S²) 中间矩阵搬运)真正转化为延迟收益。
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
### 7.2 自检清单
|
|
402
|
+
|
|
403
|
+
- [ ] running m 初始化为 `-inf`,running l 初始化为 `0`
|
|
404
|
+
- [ ] 使用 `m_new = max(m_old, m_local)` 更新
|
|
405
|
+
- [ ] $scale = e^{m_{old} - m_{new}}$ 在更新 l 和 O 之前计算
|
|
406
|
+
- [ ] O_acc 和 running l 使用 FP32,即使输入输出为 FP16
|
|
407
|
+
- [ ] Last tile 边界处理:有效列数 = `min(B, seqLen - j * B)`
|
|
408
|
+
- [ ] Causal mask 场景:全 masked tile 正确跳过更新
|
|
409
|
+
- [ ] 精度校验通过:与 naive Safe Softmax 对比,误差 < 1e-5(FP32)或 < 1e-3(FP16)
|
|
410
|
+
- [ ] AscendC kernel 使用 Vector API 替代标量循环(`GetValue`/`SetValue` 仅在必要处使用)
|
|
411
|
+
- [ ] Multi-block 并行正确分配 Q rows,无重复/遗漏
|
|
412
|
+
- [ ] UB 内存总量 < 192 KB(Ascend 910B)
|
|
413
|
+
|
|
414
|
+
## 9. 与独立 ARA Online Softmax 的关系
|
|
415
|
+
|
|
416
|
+
本文档描述的融合 Attention Online Softmax 与 [softmax_v2_ara_online.md](softmax_v2_ara_online.md) 中的独立 ARA Online Softmax **共享相同的在线 max/sum 数学基础**,但不是同一个实现:
|
|
417
|
+
|
|
418
|
+
| 特性 | 融合 Attention Online Softmax(本文档) | 独立 ARA Online Softmax |
|
|
419
|
+
|------|---------------------------------------|------------------------|
|
|
420
|
+
| 输入来源 | Attention 内部逐 tile 生成 `QK^T` | GM 中已存在的完整数据 |
|
|
421
|
+
| score 消费 | 单次 score tile 消费(生成即消费) | 两次读取输入(在线 max+sum 一遍,输出一遍) |
|
|
422
|
+
| P×V 融合 | 是,`P×V` 融合到循环中 | 否 |
|
|
423
|
+
| O_acc | 是,增量加权累加 | 否,输出完整 Softmax 概率 |
|
|
424
|
+
| 完整概率矩阵 | 通常不生成 | 生成完整 Softmax 概率 |
|
|
425
|
+
| causal mask | 支持 block-level skip | 不涉及 |
|
|
426
|
+
| workspace | 需要(跨 tile 状态传递) | 不需要 |
|
|
427
|
+
|
|
428
|
+
> 两者不得合并成同一个 Kernel 实现说明。本文档是融合 Attention 的设计参考,当前目录未提供与之完全对应的融合 Attention Kernel。
|
package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_full_load.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# SoftmaxV2 AR FullLoad 模板
|
|
2
|
+
|
|
3
|
+
## 1. 模板用途
|
|
4
|
+
|
|
5
|
+
针对 2D `[A1, R]` 布局、R 可整段载入 UB 的 Softmax 场景。多行批量载入 UB,单 pass VF 计算 max→sub→exp→sum→div,使用 MicroAPI VF 路径实现大 R 二分归约。
|
|
6
|
+
|
|
7
|
+
## 2. 输入输出布局和 Softmax 轴
|
|
8
|
+
|
|
9
|
+
- 输入 `x`:`[A1, R]`,行优先,Softmax 沿 R 轴计算。
|
|
10
|
+
- 输出 `y`:`[A1, R]`,与输入同 shape、同 dtype。
|
|
11
|
+
|
|
12
|
+
## 3. 适用 shape、dtype 和 UB 条件
|
|
13
|
+
|
|
14
|
+
| 条件 | 要求 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| 输入维数 | 2D,A0 = 1 |
|
|
17
|
+
| R 大小 | R 可整段载入 UB(`ubFactor * rAligned * (dtypeSize*2 + 4) * 2` ≤ UB) |
|
|
18
|
+
| dtype | FP32、FP16、BF16 |
|
|
19
|
+
| UB 约束 | 预留 1024B + 512B 后,剩余空间分配给 xQueue/yQueue/tmpBuffer |
|
|
20
|
+
|
|
21
|
+
## 4. 类名、构造函数和 Init 接口
|
|
22
|
+
|
|
23
|
+
```cpp
|
|
24
|
+
namespace SoftmaxV2Ops;
|
|
25
|
+
|
|
26
|
+
template <typename T_in, typename T_out>
|
|
27
|
+
class SoftmaxV2AR : public SoftmaxV2OpsBase {
|
|
28
|
+
public:
|
|
29
|
+
__aicore__ inline SoftmaxV2AR(TPipe* pipe);
|
|
30
|
+
__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, const SoftmaxV2ARTilingData* tilingData);
|
|
31
|
+
__aicore__ inline void Process();
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- **构造函数**:接收 `TPipe*`。
|
|
36
|
+
- **Init**:设置 GM buffer、计算当前核的行数 `blockA_`、初始化 xQueue(双缓冲)、yQueue(双缓冲)和 tmpLocalBuffer。
|
|
37
|
+
- **Process**:按 `ubFactor` 分块处理每行。
|
|
38
|
+
|
|
39
|
+
## 5. 对应的 TilingData 和字段说明
|
|
40
|
+
|
|
41
|
+
对应 `SoftmaxV2ARTilingData`,定义在 [softmax_v2_tiling_data.h](softmax_v2_tiling_data.template)。
|
|
42
|
+
|
|
43
|
+
| 字段 | 含义 | 单位 |
|
|
44
|
+
|------|------|------|
|
|
45
|
+
| a | A1 维总长度(行数) | 元素数 |
|
|
46
|
+
| r | R 维实际长度 | 元素数 |
|
|
47
|
+
| rAligned | R 对齐后长度(32B/dtypeSize 对齐) | 元素数 |
|
|
48
|
+
| ubFactor | 单次 UB 载入行数 | 行 |
|
|
49
|
+
| aBlockFactor | 每核处理行数 | 行 |
|
|
50
|
+
| rLoopCount | R 方向 VL_FP32 分段数 | 段 |
|
|
51
|
+
|
|
52
|
+
## 6. Host tiling 参数计算方法
|
|
53
|
+
|
|
54
|
+
使用 [softmax_v2_tiling.h](softmax_v2_tiling.template) 中的 `TilingArFullLoad`:
|
|
55
|
+
|
|
56
|
+
```cpp
|
|
57
|
+
softmax_tiling::CaseShape shape{a1, r, 1, dtypeCode};
|
|
58
|
+
softmax_tiling::PlatformParam plat{ubSize, numBlocks};
|
|
59
|
+
SoftmaxV2ARTilingData td;
|
|
60
|
+
int64_t blockDim = softmax_tiling::TilingArFullLoad(shape, plat, td);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
关键计算:
|
|
64
|
+
- `rAligned` = CeilAlign(R, blockSize/dtypeSize)
|
|
65
|
+
- `ubFactor` = (UB - 1024 - 512) / (rAligned × 4 + 2 × rAligned × dtypeSize × 2)
|
|
66
|
+
- `aBlockFactor` = CeilDiv(A1, numBlocks)
|
|
67
|
+
|
|
68
|
+
## 7. CopyIn、归约、归一化和 CopyOut 流程
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Process:
|
|
72
|
+
1. 按 ubFactor 分子块(ubLoop)
|
|
73
|
+
2. ProcessUB(ubA, aOffset):
|
|
74
|
+
a. CopyInX: DataCopyPad 批量载入 ubA 行
|
|
75
|
+
b. FirstNormCompute: 逐行 VF 求 max → sub max → exp,写入 xTmpLocal
|
|
76
|
+
c. SecondNormCompute: 二分折叠 ReduceSum 求 sum,再逐行 div sum → Cast 回原精度
|
|
77
|
+
d. CopyOutY: DataCopyPad 写回 GM
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### FirstNormCompute 流程(VF 路径)
|
|
81
|
+
|
|
82
|
+
1. 逐行加载 R 方向数据(按 VL_FP32 分段)
|
|
83
|
+
2. `MicroAPI::Max` 求行内 max(先处理尾块,再处理整块)
|
|
84
|
+
3. `MicroAPI::ReduceMax` 归约到标量
|
|
85
|
+
4. 逐段 `Sub(maxReg)` → `Exp` → 写入 xTmpLocal
|
|
86
|
+
|
|
87
|
+
### SecondNormCompute 流程(大 R VF 二分归约)
|
|
88
|
+
|
|
89
|
+
1. R ≤ 2×VL_FP32:直接 `ReduceSum` + 逐行 div
|
|
90
|
+
2. R > 2×VL_FP32:
|
|
91
|
+
- 按 `FindNearestPower2(ceilVLCount)` 确定 foldPoint
|
|
92
|
+
- 主块(mainFold):两段 Add 后 ReduceSum
|
|
93
|
+
- 尾块(tailFold):mask 精确处理非对齐部分
|
|
94
|
+
- 展开块(unFold):直接 ReduceSum
|
|
95
|
+
- 递归调用 `SecondNormComputePost` 做最终归约和 div
|
|
96
|
+
|
|
97
|
+
## 8. VF 二分归约优化
|
|
98
|
+
|
|
99
|
+
- **FindNearestPower2**:确定最优二分折叠点,使 ReduceSum 调用次数最小化。
|
|
100
|
+
- **MainFold / TailFold / UnFold 三阶段**:
|
|
101
|
+
- MainFold:成对 VL 段 `Add` 后一次 `ReduceSum`,归约次数减半
|
|
102
|
+
- TailFold:非对齐尾块用 `UpdateMask` 精确掩码
|
|
103
|
+
- UnFold:剩余展开段直接 `ReduceSum`
|
|
104
|
+
- **MicroAPI VF**:使用 `RegTensor<float>` + `MaskReg` 直接操作 256B VReg,`ReduceSum` 硬件归约指令。
|
|
105
|
+
|
|
106
|
+
## 9. 主块、尾块、对齐和数值精度处理
|
|
107
|
+
|
|
108
|
+
- **主块/尾块**:`ubFactor` 为 UB 内行数分块;R 方向按 `VL_FP32` 分段,尾段用 `UpdateMask` 精确掩码。
|
|
109
|
+
- **对齐**:R 按 `blockSize/dtypeSize`(FP32=8, FP16=16)向上对齐到 32B,`dstStride` 填充对齐间隙。
|
|
110
|
+
- **数值精度**:FP16/BF16 输入通过 `LoadTensorForDtypeTIn`(`DIST_UNPACK_B16` + `Cast`)升至 FP32 计算;输出通过 `StoreTensorForDtypeTOut`(`Cast` + `DIST_PACK_B32`)降回。`castTraitFp16ToFp32` 使用 `UNKNOWN` 饱和模式,`castTraitFp32ToFp16` 使用 `NO_SAT` + `CAST_RINT`。
|
|
111
|
+
|
|
112
|
+
## 10. 独立 Kernel 入口示例
|
|
113
|
+
|
|
114
|
+
```cpp
|
|
115
|
+
#include "softmax_v2_tiling_data.h"
|
|
116
|
+
#include "dav310/softmax_v2_base.h"
|
|
117
|
+
#include "dav310/softmax_v2_ar_full_load.h"
|
|
118
|
+
|
|
119
|
+
using namespace SoftmaxV2Ops;
|
|
120
|
+
|
|
121
|
+
extern "C" __global__ __aicore__ __vector__ void
|
|
122
|
+
softmax_ar_full_load_fp32(GM_ADDR x, GM_ADDR y, SoftmaxV2ARTilingData tiling)
|
|
123
|
+
{
|
|
124
|
+
TPipe pipe;
|
|
125
|
+
SoftmaxV2AR<float, float> op(&pipe);
|
|
126
|
+
op.Init(x, y, &tiling);
|
|
127
|
+
op.Process();
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## 11. 不适用场景和可选替代模板
|
|
132
|
+
|
|
133
|
+
| 不适用场景 | 推荐替代 |
|
|
134
|
+
|-----------|---------|
|
|
135
|
+
| R 极小(≤ 16/32) | [AR SmallR](softmax_v2_ar_small_r.md)(转置向量化收益更高) |
|
|
136
|
+
| R 超 UB 容量 | [AR Recompute](softmax_v2_ar_recompute.md)(R 切 chunk 三阶段重读) |
|
|
137
|
+
| 3D [A1,R,A0] 布局(A0>1) | [ARA FullLoad](softmax_v2_ara_full_load.md) |
|