Add BMM_Theory: docs/03_测评报告/ 软件复评报告 v2.0 (整改后复评 + issue #11-#16 闭环记录)

This commit is contained in:
2026-09-03 20:06:55 +08:00
parent 3a6c952301
commit 623f20259e

View File

@@ -0,0 +1,213 @@
# BMM/BMM_Theory 理论最优实现分析软件 测评报告(第二轮 · 整改后复评)
- 测评对象:`git.magicnetworld.com/admin/matmul-analysis` 仓库 `BMM/BMM_Theory`(软件包 `bmm_theory`
- 本轮基准HEAD `99a25a6b42efa63689f21ae53a7cc467c2fca79f`main2026-09-03相对上轮基准 `d36e224`**33 个整改提交**
- 测评方式:整改 diff 逐文件审查 + issue 逐条复测 + 全量运行/单测 + 同分布压力回归(与上轮同种子同分布对比)+ 口径深查
- 说明:上轮报告为 `docs/03_测评报告/BMM_Theory软件测评报告_v1.0.md`2026-09-03 入库commit d36e224本轮为整改后的复评。
---
## 0. 结论摘要TL;DR
**整改诚意与质量都很好:上轮提出的 7 个 issue#4#10中 6 个实质闭环1 个(#9 StreamK 计账口径)修复方向正确但引入新疑点,需二次复核。** 软件从"可跑但自相矛盾"升级为"可自检、自洽率大幅提升"的可信工具雏形。
关键数字对比:
| 指标 | v1上轮 | v2本轮 |
|---|---|---|
| 单元测试 | 17/17 | **23/23**(新增 6 条 issue 回归) |
| P0 崩溃K=1 且 B<128 | 必崩 AttributeError | **不崩溃**占位标注"[无方案]" |
| 典型 LLM 形状自检不可行率6000 | **18.0%**1079 | **0.0%** |
| 宽范围随机自检不可行率8000 | **6.0%**480 | **0.2%**16 全部为极端瘦长 MergeBatch 且自检已显式标注 |
| 生成结果可复现性vs 仓库固化示例 | 0 差异 | 0 差异 |
| 推荐评估回灌 feasible | 94% | **99.8%**16/8000 标注违规但仍推荐 |
| NaN/负时延/崩溃 | P0 区除外 | |
**遗留问题(详见 §5**
1. P2建议跟进issue#9 的修复引入新口径问题StreamK 部分和写出被**双重计账且按单核串行假设高估 32 **——demo case 总时延从 9.96us 变为 55.03us瓶颈变成 FIXPIPE51.6us而同一批字节在 `t_reduce` 内仅计 1.61us该数字已被作者固化进 examples建议复核
2. P3K=1 B<128 区域仍**无任何理论方案** K=1 域的约一半现以"无方案占位"标注兜底崩溃已解决可接受建议后续补 AIV 单缓冲/Cube 兜底方案
3. P3MergeBatch 极端瘦长 caseM N 很小 × B仍有 0.2% 生成不可行方案——`b0` 选择未把 L0A/L0B 容量纳入上限现已被生成自检显式标注不再静默矛盾)。
4. P3/零矩阵维度无输入校验静默产出无意义方案FIXPIPE 建议文案对 StreamK部分和 4B给出 fp16/fp8 减半的误导提示
5. P3过程噪音整改过程中 11 commit 误提交临时文件bug1.csv/t.csv 后删除建议加 .gitignore
**总体评价6.2 → 约 7.6/10。** 架构与理论映射维持高水准内部一致性与鲁棒性是本轮最大提升单一约束源 + 生成自检是正确架构决策剩余扣分集中在 StreamK 时延口径复核输入校验与若干边界覆盖
---
## 1. 本轮整改概览33 commits
| 主题 | 主要提交 | 对应 issue |
|---|---|---|
| 新增 `bmm_theory/constraints.py`170 单一约束源 + 生成侧收敛辅助 | 16a84ac | #5 #6 共性根因 |
| `router.py`生成后自检 `_wrap_checked` + 无方案兜底 `_no_plan` | dad4585 | #4 #5 |
| `evaluator.py`约束校验委托单一约束源 | 0c19d99 | #5 |
| `__main__.py`plan=None / timing=None / 自检违规打印防护 | b57ba57 | #4 |
| `io_csv.py`out_nd 解析 + A/B dtype 不一致告警 + 建模边界说明 | 9ef240f | #7 #8 |
| `timing.py`REDUCE 移出稳态 max()`reduce_serial` 约定 | 933b428 | #9 |
| `branches/stream_k.py`fixpipe 改按部分和 4B显式 reduce_serial | f756729 | #9 |
| `branches/asw_basic.py`降核 base_k dtype 容量反推clamp 同源k_l1 K 不切 | e6aa792 | #5 |
| `branches/iter_batch.py`L0 tile 长宽比跟随 + L0C/L0A/L0B 同源收敛 | c0b358f | #5 |
| `branches/merge_batch.py`新增条件 2b合并后最小 K 粒度下 L0A/L0B 可驻留 | 1385d01 | #5 |
| README / docs/01_软件架构.md 同步 6 分支现状 + 约束模块/归约口径文档 | 7bcacef / 593ffcf | #10 |
| examples 两个结果 csv 按新模型重生成 | bbef360 / cff5665 | |
| tests 新增 `TestIssueRegression` 6 | 87b7be5 | #4#9 |
| 误提交临时 csv 后清理 | 0e644ac99a25a611 commits | |
净改动15 个文件+408/92 无第三方依赖新增
---
## 2. issue 逐条闭环验证
### #4 【P0】K=1 且 batch<128 崩溃 → ✅ 已闭环(标注式兜底)
复测`B=64 M=8192 N=32 K=1 int8` `recommend`-v / 不带 -v / 输出 plans.csv 三条路径**不再崩溃**
```
=== bug_k1_smallB: ... K=1 int8 -> [特殊分支]
仲裁: [无方案] K=1逐元素乘...; 但进入条件不满足 (2_K=1的AIV触发: B >= 2*AIV核数), 该区域暂无理论方案...
方案: 核数=0 ...
```
实现`router.py:52-58` capable=False plan=None 时走 `_no_plan`占位 ImplPlanused_core_num=0timing=None`__main__.py:85-90` 增加空值防护
**残留P3**该区域仍未给出任何实现方案扫描 B=1..255 × K=1 × 若干 M/N**49.4%378/765"无方案占位"**K=0 全部有方案 issue 允许"标注无方案"作为最低要求已达成但建议后续补 AIV 单缓冲或 Cube 兜底方案消除空洞或至少在文档00_总纲 / 04_特殊分支中明确该限制
### #5 【P1】推荐模式不做约束自检 → ✅ 基本闭环6.0%/18.0% → 0.2%/0.0%
架构修复正确新增 `constraints.py` **唯一事实来源**`router._wrap_checked` 在每次生成后调用同一校验函数违规时在 arbitration/advice 中显式标注"[自检违规: …]"`evaluator._check_constraints` 改为委托同一函数同时生成侧收敛辅助`clamp_base_k` / `clamp_base_mn_l0c`消除降核 base_k 硬编码等缺陷
复测 v1 同种子同分布
- 上轮全部最小违规样例IterBatch K=8/K=2、MergeBatch fp8 K=32、ASW_降核 fp16/fp32fp32 MN 12 )→ **全部 violations=OK**
- 宽范围 8000 480 **16**0.2%典型 6000 1079 **0**
**残留P3**16/8000 全部为极端瘦长 MergeBatch `B=811 M=33 N=1 K=2459 fp32``B=1024 M=1 N=1024 K=1024 int8``make_plan` b0 上限只取 L0C/算存比/b_core 三者的 min**未纳入 L0A/L0B 容量**导致 `b0*M` `b0*N`过大时 `base_k≥16`fractal 下限也放不进 L0A/L0B新条件 2bmerge_batch.py:55-62只按 MIN_B0=2 检查未覆盖实际选中 b0 的情形因生成自检已显式标注属于"可感知的残余"建议把 L0A/L0B 容量加入 b0_max 求解 b0 L0A/(2·m·16·dt) L0B 侧取 min 后取不超过 b_core 的因子)。
### #6 【P1】dValue 口径矛盾 → ✅ 闭环
理论裁定已落地并文档化constraints.py:7-15docs/01_软件架构.md §3.5**dValue 128B 下限只对"K 被切分K 段成为搬移连续维"k_l1 < K的方案生效K 整驻留k_l1 K形态 a/b K 整搬时连续维是 M/N豁免 K 向检查**。实现于 `_k_segment_is_contiguous`constraints.py:118-134)。复测IterBatch K=8/K=2 整驻留样例 无违规形态 c/d MergeBatch/ASW/StreamK K 切分路径仍受约束新增回归测试 test_issue6
### #7 【P2】out_nd 无法经 CLI 传入 → ✅ 闭环
`io_csv.load_cases` 现解析 `out_nd`缺省 True大小写不敏感)。CLI 复测同一 StreamK case `out_nd=0` ASW_Basic_降核StreamK 条件 4 生效`out_nd=1` StreamKcsv 头注释补充说明新增回归测试 test_out_nd_disables_streamk
### #8 【P2】A/B dtype 不一致无告警 → ✅ 闭环
`io_csv.load_cases` 加载后对 `dtype_a ≠ dtype_b` 打印 `[warn]`stderr case_id 与建模口径说明)。CLI 复测`fp8 vs bf16` 输入正确输出告警
### #9 【P2】StreamK 归约计账口径 → ⚠️ 部分闭环,引入新疑点(重点跟进)
修复部分正确REDUCE 不再进稳态 max()`assemble_timing` 增加 `reduce_serial=True` 约定timing.py:96-132归约只作为 drain 串行追加一次最终写回只留在 `eval_streamk_reduce` 回归测试 test_issue9 验证 `t_total = t_steady + t_drain` `drain = t_reduce`代数恒等)。
**但 fixpipe 的新口径有实质问题**复算证据demo caseB=4 M=N=128 K=10240 bf16grid_K=32
| 账目 | 字节量 | 带宽分母 | 结果 |
|---|---|---|---|
| `t_reduce` t_write_partial部分和写 L2 | grid_K×tile×4B = 8.39MB | 整片 5.2TB/s并发写 | **1.61us** |
| `t_fixpipe`stream_k.py:152-153 | 同一批 8.39MB | **单核份额 162.5GB/s** | **51.62us** |
1. **同一批部分和字节被计两次账**一次在 reduce 内按整片带宽一次在 fixpipe 按单核带宽)——issue#9 原指控的"重复计账"并未消除只是换了个位置与分母
2. **单核串行化假设与软件自身的带宽模型矛盾**timing.py 文档与 00_总纲均声明"每核独立 DMA 引擎带宽按核数配平" grid_K 个核的部分和是**并发写出**墙钟时间应为 字节量/整片带宽 1.61us51.62us 相当于把整组部分和压到单核写口串行写**高估 grid_K=32 **
3. 后果已固化进 examplesstreamk_demo 总时延 9.96us **55.03us**瓶颈从 MTE2_GM FIXPIPE advice 还给出"fp16/fp8 可减半写出量"的提示——该提示对按 4B 防精度丢失的部分和不成立advice 生成器未感知 StreamK 例外evaluator.py _advice FIXPIPE 分支
4. 修复后的回归测试只验证汇总代数式**验证不了字节量与带宽口径的物理正确性**。
建议fixpipe 部分和按"每核自己的部分和tile×4B)÷ 单核份额"=1.61us reduce 内并发口径一致或与 `t_reduce` t_write_partial **二选一**计账并在文档写明;再校验 8.39MB 是否应为每核 256KB 的并发总和语义。此条建议**重新开启 issue#9 或另开 issue**
### #10 【P3】文档-代码漂移 → ✅ 闭环
README 目录树与分支注释更新为 6 分支全实现docs/01_软件架构.md 分层图、§3.5单一约束源)、§4 扩展指南转Matmul 精切为后续方向新分支须走 constraints.py均已同步Python 版本声明改为"实测 3.12/3.14建议 3.10+"3.14 本机复验通过)。轻微残留`router._wrap`旧包装函数成为死代码未删除README 目录树仍缺 `docs/03_测评报告` 条目小事)。
---
## 3. 回归测试与可复现性
- 单测`python -m unittest discover -s tests -v` **Ran 23 tests, OK**0.028s)。
- recommend 输出 vs 仓库 `examples/result_recommend.csv`10 行全列 **0 差异**evaluate 输出 vs `examples/result_evaluate.csv`**0 差异**含新的 streamk 55.03us 数值——即作者已用新模型重生成示例)。
- 压力回归 v1 完全同种子同分布 §0 两组均 0 崩溃0 NaN0 负时延
---
## 4. 代码质量复查(针对改动)
- `constraints.py` 抽象正确校验与生成收敛共用注释完整记录 dValue 裁定缘由
- 三处发现的小问题
1. `constraints._l1_need_bytes` IterBatch 形态 c 的预算推断resident = min + 对侧 k_l1 双缓冲与生成侧 iter_batch.l1_form 逻辑手写两遍仍属"双源"本次未合并好在口径一致且有校验兜底建议未来直接让 make_plan 调用同一 helper
2. `merge_batch.py` 条件 2b MIN_B0 预检但实际 b0 更大时仍可能溢出(§2 #5 残留)——校验兜底已标注但生成侧仍可产生违规方案0.2%)。
3. 输入范围校验仍缺失`M=-5` / `M=0` 静默产出 IterBatch 伪方案与无意义时延非法 dtype 抛裸 ValueError建议 load_cases 后加维度正数校验
---
## 5. 遗留问题清单(按优先级)
| # | 级别 | 问题 | 证据 | 建议 |
|---|---|---|---|---|
| N1 | P2 | StreamK fixpipe 部分和写双重计账 + 单核串行化高估 ~32 examples 已固化 55.03us 结果 | stream_k.py:152-153 vs timing.py:77-93demo 复算 51.62us vs 1.61us | reopen #9 或新开 issuefixpipe reduce 内部分和写二选一按并发口径计 |
| N2 | P3 | K=1 B<128 无方案空洞 K=1 49.4% | B=1..255 × K=1 扫描 378/765 占位 | 后续补 AIV 单缓冲/Cube 兜底方案或文档明示 |
| N3 | P3 | MergeBatch 瘦长 case b0 未含 L0A/L0B 上限 0.2% 自检违规已标注不静默 | 8000 例中 16 样例见 §2 #5 | b0_max 纳入 L0A/L0B 容量约束 |
| N4 | P3 | FIXPIPE 建议文案对 StreamK 误导fp16/fp8 减半对 4B 部分和不成立 | evaluator.py _advice | advice 生成感知分支例外 |
| N5 | P3 | M0 等非法输入无校验静默输出伪方案 | M=-5/M=0 探针 | load_cases/route 前参数校验 |
| N6 | P3 | .gitignore整改期误提交 11 个临时文件 commit死代码 router._wrapREADME 目录树缺 03_测评报告 | git log 0e644ac..99a25a6 | .gitignore删死代码 |
---
## 6. 总体评分(第二轮)
| 维度 | v1 | v2 | 说明 |
|---|---|---|---|
| 设计架构 | 9.0 | 9.0 | 单一约束源使架构更完整 |
| 理论-代码映射 | 8.0 | 8.5 | dValue 裁定归约约定均有文档 |
| 功能完成度 | 8.0 | 8.5 | 双模式 + 自检 + 告警 |
| 内部一致性 | 5.0 | 7.0 | 0.2%/0% 自洽率StreamK 口径遗留 |
| 鲁棒性/错误处理 | 4.0 | 7.5 | 崩溃消除占位兜底告警落地输入校验仍缺 |
| 测试 | 5.0 | 7.0 | 23 条含 6 issue 回归仍无 io_csv/CLI 单测 |
| 工程化/交付 | 5.0 | 6.5 | 文档同步模块化 CI/打包/.gitignore误提交噪音 |
| **综合** | **6.2** | **7.6** | POC 可用工具雏形 |
**定位更新**已从"理论文档的代码化 POC"升级为"分支归属与方案生成可自检结果自洽率 99.8% 的辅助分析工具"。仍不建议把绝对时延数值直接当硬件实测使用T_cmd=50ns 等参数未标定StreamK 口径待复核**方案归属tile 取值与相对瓶颈分析已经具备可信度**。
**优先建议**:① 复核 StreamK fixpipe 口径N1);② 补输入校验N5);③ 清理工程噪音并考虑 CIN6);④ 中远期做硬件标定与 ops-nn 源码对照验证
---
## 附录 A本轮复测命令
```bash
git fetch origin && git log --oneline d36e224..origin/main # 整改提交
python -m unittest discover -s tests -v # 23/23
python -m bmm_theory recommend examples/cases_demo.csv -o r.csv --plans p.csv
python -m bmm_theory evaluate examples/cases_demo.csv p.csv -o e.csv
# 与 examples/result_*.csv 比对: 0 差异
```
## 附录 B残余 MergeBatch 违规样例16/80000.2%
```
B=811/811 M=33 N=1 K=2459 fp32 -> L0A tile 超容量 (b0=25: base tile 825××16×4B×2)
B=1024/1024 M=1 N=1024 K=1024 int8 -> L0B 超容量 + dValue=48B
B=2048/2048 M=512 N=1 K=16 bf16 -> L0A 超容量 (b0=8)
...
```
特征M N 极小 × B 巨大 × b0 因子选择偏大 合并后 base tile 一维过长L0A/L0B base_k16 下无法驻留已在 advice 中标注"[自检违规]"不静默
## 附录 CK=1 无方案空洞扫描
B=1..255 × K=1 × M/N∈{64×64, 256×256, 4096×64}765 例中 378 49.4%返回 used_core_num=0 占位"[无方案]"K=0 同域 0 例占位
## 附录 D遗留问题闭环确认2026-09-06commit 4bedf0a / HEAD 3a6c952
本报告 §5 的遗留问题N1N6已全部转为 issue #11#16 并修复闭环
| Issue | 修复内容 | 验证 |
|---|---|---|
| #11 N1P2StreamK fixpipe 双重计账/32×高估 | 部分和写/读回/求和/最终写回全部单次计入串行 drain稳态 Fixpipe 账目清零 | streamk_demo 55.03→**9.96us**瓶颈回到 MTE2_GM |
| #12 N2P3K=1 B<128 无方案空洞 | 新增 **AIV 单缓冲**模式B≥128 仍乒乓04_特殊分支.md 同步 | B=1..255×K=1 全扫 **765/765 全有方案** |
| #13 N3P3MergeBatch 瘦长不可行0.2% | b0_max 纳入 L0A/L0B 容量上限路由对胜出方案自检违规时回退另一切B候选StreamKASW | 8000 例宽范围违规 **16→0** |
| #14 N4P3FIXPIPE advice StreamK 误导 | StreamK 跳过 dtype 减半提示新增 REDUCE 瓶颈建议 | 文案验证 |
| #15 N5P3输入校验缺失 | BmmCase.__post_init__ 维度/dtype 校验非法输入明确抛错 | M0/K<1/dtype 非法均正确报错 |
| #16 N6P3工程噪音 | 根目录 .gitignore删除 router._wrap 死代码README 目录树补 03_测评报告 | |
**修复后全量验证**单测 **28/28**新增 8 条回归宽范围 8000 + 典型形状 6000 例压力测试 **违规 0 / 异常 0 / 无方案 0 / NaN 0**examples 已按新模型重新生成并与代码 0 差异提交Gitea issue #4#16 已全部关闭附修复注释)。
---
*第二轮复评完成:本地动态测试 + 与仓库 HEAD 99a25a6 比对;全部问题均有可复现证据。修复确认见附录 DHEAD 3a6c952。*