跳到主要内容

softmax 算子建模实现计划

基于G5-softmax算子建模设计规格(Accepted v1.0.0)。前置:G5-计算算子建模方法分层设计规格(方法分层)+ G5-计算建模设计规格(matmul,tier3 评估模式参照)。 日期:2026-06-22 状态:Done

目标

把 G5 attention 发射里被丢弃的 softmax 升级为算子级向量吞吐 cycle 模型 + LMEM 访存边带域标签,与 fa2 两个矩阵乘串行相加计入 attention 计算时长,使 G5 与解析侧口径一致(现状系统性少算 23–29%)。

Dependencies

  • G5 既有 tier3 评估模式:matmul 走 tier3/tiu.rs calc_tiu_latency、HAU 走 tier3/hau.rs calc_hau_latency,各有独立 op type(TIUOpType / HAUOpType)+ command 结构 + core_subsys 事件处理(on_tiu_finish / on_hau_finish)。softmax 照 HAU 模式新增向量评估器,非新建引擎。
  • Rust chip config ChipSpec(dataclasses.rs:192)有 cube: CubeConfig无 vector 段——需新增 VectorConfiglane_per_core 已在 ChipSpec(tiu 用 chip.lane_per_core)。
  • 解析侧公式形态(验收锚点):perfmodel/evaluation/math/evaluators/softmax_eval.py(10 步 SOFTMAX_STEPS_ARRAY + align_up 对齐 + eu_block=eu_num//lane_num//dtype_bytesmax(1,eu_block))+ perfmodel/evaluation/math/evaluators/precise/attention_evaluator.py:152-193(vec_theo/vec_t_us 口径,gemm+vec 串行;vec_t_us 除数含 *SOFTMAX_DTYPE 因子)。
  • 跨语言指令传递链(仿 HAU):Python program.py:228 CoreInstructions 各引擎 cmd 列表 → Rust input/parse_commands.rs:36 parse_core_instructions 逐类 parse_cmd_list + parse_*_command → Rust CoreInstructions。新增 VectorCommand 必须贯穿这条链。
  • Rust 改后 maturin build --release + pip install + 覆盖根目录 g5_rs pyd(记忆 project_g5_pyd_shadowing)。

文件变更概览

文件改动
perfmodel/evaluation/g5/src/types.rs新增 VectorOpType(Softmax)+ VectorCommand(B/Q/K/precision 字段);Rust CoreInstructionsvec_cmds 字段
perfmodel/evaluation/g5/src/input/dataclasses.rs新增 VectorConfig(eu_per_lane 每精度 / op_count 步表 / lmem 带宽),ChipSpecvector 字段
perfmodel/evaluation/g5/src/input/parse_chip.rs解析 chip YAML 的 vector 段;缺字段 raise(不取默认)
perfmodel/evaluation/g5/src/input/parse_commands.rs新增 parse_vector_commandparse_core_instructionsvec_cmdsparse_cmd_list(跨语言传递链,仿 hau_cmds)
perfmodel/evaluation/g5/src/input_parse.rs新增 parse_vector_op_type(Python op_type 字符串 → VectorOpType)
perfmodel/evaluation/g5/src/tier3/vector.rs(新增)calc_vector_latency:吞吐 cycle 公式(复刻解析侧 softmax_eval 的 align_up 形态,非 spec 正文 ⌈Q/L⌉)+ LMEM 访存边(eq:gsm-mem-edge)+ bandwidth_domain="lmem_bus" + combine(串行)
perfmodel/evaluation/g5/src/tier3/core_subsys.rs向量指令 issue + on_vec_finish 事件(仿 on_hau_finish),softmax 串行占时间线
perfmodel/mapping/g5/program.pyCoreInstructionsvec_cmds 字段 + CoreProgram.total_vec_cmds(仿 hau_cmds)
configs/chips/SG2262.yaml新增 vector.op_count 步表(softmax 10 步);确认 eu_per_lane;同步 _template.yaml
perfmodel/mapping/g5/instruction_emitter.py_emit_fa2 在 QK^T 与 PV 之间发射 softmax VectorCommand
docs/validation/G5softmax建模-test-plan.md(新增)test case 清单(先于 test 代码)
tests/evaluation/g5/test_softmax_modeling.py(新增)据 test plan 的 test case

Rules Compliance

  • config 禁默认值:VectorConfig 解析缺字段(eu_per_lane / op_count / lmem 带宽)raise 带字段名,禁止仿解析侧 if lane_num>0 and eu_per_core>0 静默置 0。
  • no-backward-compat:直接给 fa2 发射加 softmax,不写 if 不建模 softmax 分支。
  • naming(_gb_per_s):vector 带宽字段用 _gb_per_s,不用 _gbps
  • sync-templates:SG2262.yaml 加 vector 段须同步 configs/chips/_template.yaml
  • windows-encoding:Rust/Python 输出无特殊 Unicode(用 [OK]/[FAIL])。
  • 不碰 DepEngine::Cdma=>0:A1/A2 边界,本篇只加 compute 算子。
  • strict 无容差:形态一致性断言严格相等。
  • Rust 改后 maturin 重建 + 覆盖根目录 pyd。

无 Complexity Tracking 偏离。

实现步骤

Task 1 [Sequential,基础] — Rust 向量吞吐成本公式 + 配置 + 跨语言传递链

新增 tier3/vector.rscalc_vector_latency,从 VectorCommand 字段 + VectorConfig 算 softmax 时长。仿 tiu.rs 结构(公式在 Rust、参数从 config、combine 合成)。本 Task 含 VectorCommand 从 Python emitter 跨 PyO3 到 Rust 的完整传递链(仿 hau_cmds),否则 Task 4 发射后指令过不了边界。

  • VectorConfig(dataclasses.rs):eu_per_lane(每精度 map)、op_count 步表(每步 shape_type + op_count,对应解析侧 SOFTMAX_STEPS_ARRAY 10 行)、lmem 带宽(访存边用)。ChipSpec 加 vector 字段。
  • VectorOpType + VectorCommand(types.rs):op_type=Softmax;字段 B / Q(QS_tile)/ K(KS_tile)/ precision。Rust CoreInstructionsvec_cmds
  • 跨语言传递链program.py CoreInstructions 加 vec_cmds 字段 + total_vec_cmds;parse_commands.rsparse_vector_command + parse_core_instructionsvec_cmdsinput_parse.rsparse_vector_op_type
  • 公式(G2:以解析侧形态为准,非 spec 正文 ⌈Q/L⌉):严格复刻 softmax_eval.py_softmax_core——aligned_qs=align_up(QS,lane)aligned_ks=align_up(KS,eu_block)eu_block=eu_num//lane_num//dtype_bytesmax(1,·);vec_theo=Σ_step(shape0: aligned_qs·aligned_ks·op_count / shape1: aligned_qs·op_count);t_vec=vec_theo·B/(eu_per_core·dtype_bytes·f_v)(除数含 dtype_bytes 因子,对齐 attention_evaluator.py:186)。spec eq:gsm-vec-cycle/time 是概念式,实现与验收以解析侧 softmax_theoretical_and_real 为锚点。访存边 t_mem=(score 读+概率写 bytes)/lmem 带宽,bandwidth_domain="lmem_bus";combine 串行(ρ=0 相加,复用 tiu.rs combine_overlap 同义)。
  • 解析(parse_chip.rs):vector 段缺字段 raise 带字段名(禁止解析侧 lane_num>0 and eu_per_core>0 静默置 0 那种兜底)。
  • 门控:softmax 复用既有 unvalidated 门控(HAU/TIU 同),无新增门控逻辑。

Acceptance:cargo test——给定 (B,Q,K,BF16) + vector 参数实例,calc_vector_latency 的向量 theo/时长严格等于解析侧 softmax_theoretical_and_real + vec_t_us 口径同输入(无容差);访存边带 bandwidth_domain="lmem_bus";删 eu_per_lane 字段 → 解析 raise 带字段名。VectorCommand 能从构造的 Python CoreInstructions 经 parse_core_instructions 解析到 Rust(传递链通)。

Task 2 [Sequential,依赖 1] — 向量指令接入事件驱动执行

core_subsys.rs:向量指令 issue + 完成事件,softmax 串行占计算时间线。

  • 仿 on_hau_finish/HAU issue 路径,加向量指令的 load/issue + on_vec_finish(cmd_id)
  • A1 边界:softmax 串行占时间线(与矩阵乘串行相加,不并行重叠——真 overlap 是 A2,不碰 DepEngine::Cdma=>0)。

Acceptance:cargo test——含 1 个 softmax VectorCommand + 2 个 matmul 的 CoreProgram 跑通,attention 时长 = 三项串行相加(matmul1 + softmax + matmul2),无悬挂事件。

Task 3 [P] — SG2262 vector 参数实例 + 模板同步

(与 Task 1/2 无真数据依赖:cargo test 用 Rust 内联 make_chip 不读 YAML,YAML 解析在本 Task 自验,可并行起草。)

  • SG2262.yaml 加 vector 段:芯片专属参数——eu_per_lane(已有 BF16=32 等)、lane、lmem 带宽。op_count 步表不进 YAML(跨厂商算法常量,已在 Task 1 代码固化为 VectorConfig::softmax_steps(),逐行=SOFTMAX_STEPS_ARRAY)。
  • 同步 configs/chips/_template.yaml vector 段(含字段注释 + 必填标注)。
  • 决策记录(已与用户确认):op_count 步表是 softmax 算法分解、跨芯片完全相同,固化为 Rust 常量而非 YAML(放 YAML 各芯片重复同一份、易漂移);spec 附录 C/B 已订正为"代码固化常量"。eu_per_core 源 = 解析侧 chip.eu_num // core_count(= vector 每 lane eu × vector lane 数),非 plan 初稿误写的 eu_per_lane*lane;Task 1 已按正确源实现 bit-exact。

Acceptance:load_chip("SG2262") 解析出 vector 段无报错;删任一 vector 必填字段(eu/lane/带宽)→ raise 带字段名 + 文件路径。(op_count 逐行一致性在 Task 1 Rust 单测已覆盖。)

Task 4 [Sequential,依赖 1,2,3] — emitter 发射 softmax + 重建

instruction_emitter.py _emit_fa2:在 QK^T(line ~353)与 PV(line ~363)之间发射 softmax VectorCommand(B=b, Q=qs_tile, K=ks_tile, precision)。

  • 字节口径:score 读+概率写,与 QK^T/PV 矩阵乘访存边不重复计(softmax 只覆盖 score↔prob,不碰 Q/K/V/输出)。
  • maturin build --release + pip install + 覆盖根目录 pyd。

Acceptance:跑一个 fused attention(MLA prefill),EngineResult 的 attention 计算时长含非零 softmax 分量,且 = QK^T + softmax + PV 串行相加;softmax 访存边不与矩阵乘访存边重复计(比对覆盖张量)。

Task 5 [P,依赖 spec] — 测试用例清单(先于 test 代码,写入本 plan 下方「测试用例清单」小节)

(依赖 spec 验收标准而非实现产物,可与 Task 1-4 并行起草;符合 test-plan-before-cases:清单设计先行。test case 清单是规划材料,写进本 plan 小节,不另起 docs/validation 文档——validation 放验证报告/数据,非规划。)填下方「测试用例清单」小节:每 case 写输入 / 预期 / 对应 spec 验收点 / 断言性质(严格无容差 vs 行为)/ 落点(Rust 单测 or Python test)。

Acceptance:清单覆盖 spec 全部验收标准行;每 case 标清断言性质与落点。

Task 6 [Sequential,依赖 5] — test case 代码

tests/evaluation/g5/test_softmax_modeling.py:据 test plan 写 test case(不边实现边内联补,test plan 先行)。

Acceptance:所有 test case 通过;形态一致性 case 严格相等;删实现核心(softmax 发射 / op_count)对应 case 变红(变异有效性)。

Task 7 [Sequential,依赖 6] — 回归

  • 现有 G5 测试(72 passed)不破。
  • matmul(tiu)/ 通信侧 / 多芯片桥(A1)不受影响。

Acceptancecargo test 全绿 + pytest tests/evaluation/g5/ 全绿。

验证计划

  • 单元:Rust 向量公式(Task 1 cargo test,严格等解析侧)、配置解析缺字段 raise(Task 1/3)。
  • 集成:event 执行串行相加(Task 2)、emitter 端到端 attention 含 softmax(Task 4)。
  • 形态一致性差分:G5 softmax cycle 严格等于解析侧 softmax_theoretical_and_real 同输入(无容差)。
  • 回归:现有 G5 全量 + matmul/通信/A1 桥不破(Task 7)。
  • Rust 改后 maturin 重建 + 覆盖根目录 pyd(每次改 Rust 都要)。

测试用例清单(Task 5 产出,Task 6 据此写代码)

#case输入预期spec 验收点断言性质落点
C1形态一致性(B,Q,K,BF16) 多组 + vector 参数实例vec_theo/时长严格等解析侧 softmax_theoretical_and_real + vec_t_us 同输入形态一致严格相等严格无容差Rust 单测(Task 1 已建:test_softmax_theo_handcalc / test_shape_consistency_python_reference / test_eu_block_floor)
C2访存边带域一个 softmax cmd访存边 bandwidth_domain == "lmem_bus"访存边带域 lmem行为Rust 单测(Task 1 已建)
C3串行合成固定 t_vec/t_memcombine 结果 = t_vec + t_mem(非 max)串行合成非取 max严格Rust 单测(Task 1 已建)
C4缺字段 raise删 vector eu / core_count=0raise 带字段名,不置零参数缺字段 raise行为Rust 单测(Task 1 已建)+ Python load_chip 缺字段(Task 6)
C5attention 含 softmax 串行MLA prefill 单芯片attention 时长 = QK^T + softmax + PV,softmax 分量非零attention 含 softmax 串行行为Python test(Task 6)
C6字节不重复计fa2 核softmax 访存边覆盖 score↔prob,不与 QK/PV 矩阵乘访存边(Q/K/V/输出)重叠字节不重复计行为Python test(Task 6)
C7厂商中立改 vector.eu_per_lane 参数实例softmax cycle 随参数变、公式结构不变厂商中立行为Python test(Task 6,仿 tiu test_vendor_neutral)
C8门控继承unvalidated 置位绝对查询返回相对(复用既有门控,无新增)门控 unvalidated行为继承既有 test_slo_gate,无新增
C9变异有效性删 softmax 发射 / 改 op_countC5/C1 对应 case 变红—(测试有效性自检)行为手动变异验证(Task 6)
C10回归全量现有 72 G5 测试不破回归严格(继承既有)cargo test + pytest(Task 7)

C1-C4 在 Task 1 Rust 单测已落地(cargo test 465 passed);C5-C7、C9 是 Task 6 Python test 新增;C8/C10 继承既有。

风险与回退

风险缓解
Rust 重实现 softmax 公式与解析侧漂移Task 1 acceptance 严格等解析侧、无容差,漂移即红
向量指令接入 event 漏处理 → 悬挂事件Task 2 acceptance 验无悬挂事件,仿 HAU 成熟路径
softmax 字节与矩阵乘访存边重复计Task 4 字节口径只覆盖 score↔prob,acceptance 比对覆盖张量
op_count 下沉 YAML 各芯片重复Task 3 已记决策:spec 契约优先,重复可接受;若后续多芯片维护痛,回 spec 议是否改为共享算法常数
被误读为"建厂商引擎"(违 discuss 边界)明确仿 HAU/TIU 既有算子成本+调度模式,非 cycle 级 SystemC 引擎;A1 串行不建真 overlap
参数缺字段静默置 0(复现被丢弃缺陷)Task 1/3 缺字段 raise 带字段名,acceptance 删字段验抛错