| 优化 combine_v2 INT8 及 MXFP8 反量化路径
Co-authored-by: zhong-zixin<zhongzixin@huawei.com>
# message auto-generated for no-merge-commit merge:
!5594 merge dequant into master
优化 combine_v2 INT8 及 MXFP8 反量化路径
Created-by: zhong-zixin
Commit-by: zhong-zixin
Merged-by: cann-robot
Description: ## 描述
<!--在这里详细描述你的改动,包括改动的原因和所采取的方法。-->
优化 combine_v2 反量化路径,减少计算耗时,优化流水掩盖。
## 关联的Issue
<!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000-->
<!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。-->
关联Issue #2606.
## 测试
<!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。-->
已通过典型shape验证以及二级冒烟。
## 文档更新
<!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。-->
不涉及。
## 类型标签
<!-- [x] 表示选中 -->
- [ ] 🐛 Bug 修复
- [ ] ✨ 新特性
- [x] ⚡ 性能优化
- [ ] ♻️ 重构
- [ ] 🧪 测试
- [ ] 📦 构建/CI
- [ ] 🔧 配置变更
- [ ] 📝 文档更新
- [ ] ⬆️ 依赖升级
- [ ] 🔒 安全修复
- [ ] 🧹 代码清理
- [ ] ❓ 其他,请描述:
# 代码检视报告
**项目名称**:NPU 算子检视报告
**检视模块**:/home/zerozill/.openclaw/projects/ops-transformer/mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp、/home/zerozill/.openclaw/projects/ops-transformer/mc2/moe_distribute_combine_v2/op_kernel/moe_distribute_combine_v2.h、/home/zerozill/.openclaw/projects/ops-transformer/mc2/moe_distribute_combine_v2/op_kernel/moe_distribute_combine_v2_quant.h
**检视范围**:commit 3e6d3eb03569ef2ad70b6fcaaf5a1aa44d5159dc(优化 INT8 反量化路径,+236 / -75 行)
**检视依据**:C++ 安全编码规范(cpp-secure.md)、C++ 代码风格规范(cpp-style.md)、TOPK 问题清单(ascendc-topk.md)
**检视人**:CANNBot
**检视日期**:2026-05-22
## 🔍 检视概览
| 统计项 | 数值 |
| ---- | ---- |
| 发现问题总数 | 2 个 |
| 严重级(CRITICAL)问题 | 0 个 |
| 中等级(MEDIUM)问题 | 0 个 |
| 轻微级(LOW)问题 | 2 个 |
| 误报/拦截数量 | 2 个(被 Tiling 校验拦截) |
**核心结论**:**PASS**。本 commit 实现的 INT8 反量化路径优化逻辑闭环、Tiling 与 Kernel 双侧 512B 对齐策略一致、A5/非 A5 分支正确隔离、half → float 双路 Cast 使用 ZERO/ONE 与仓库历史修订一致。未发现违反红线或 TOPK 阻断性问题,仅有 2 处可读性 / 一致性建议,不阻塞合入。
## ❌ 问题详情及修改建议
### 问题 ID:ISSUE-001 | 严重级别:LOW(轻微)
#### 🔬 假设检验过程
**代码段**:UbUsedCal 函数中对 commQuantModePtr 的解引用(INT8/MXFP8 分支)
**假设**:H0: 该代码段是安全的
| 证据序号 | 证据类型 | 规范 ID | 证据描述 | 分值增量 | 累计自信值 |
|---------|---------|--------|---------|---------|-----------|
| 1 | 规范违反 | RL-004 / TOPK-1 | 后续 if (*commQuantModePtr == INT8_COMM_QUANT) 直接解引用,未做显式空指针校验 | +40% | 40% |
| 2 | 上下文防御充分 | — | 上游 [L292](mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L292) OP_TILING_CHECK(commQuantModePtr == nullptr, ..., return ge::GRAPH_FAILED) 已拦截空指针 | -30% | 10% |
| 3 | 本 commit 内部一致性弱证据 | cpp-style | 同函数新增的 isInt8Quant/isMxFp8Quant 加了 != nullptr 判断,旧分支未同步抬升,可读性不一致 | +10% | 20% |
**结论**:自信值 **20%** < 60%,**保留原假设 H0**,**被 Tiling 校验拦截**,不构成红线问题。仅作可读性建议保留。
---
**关联红线条款**:RL-004(指针操作必须先赋值后访问并防御)、TOPK-1(必须校验函数返回值)
**代码路径**:[mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L1415-L1424](mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L1415-L1424)
**问题类型**:指针防御风格不一致(非空指针未保护)
**问题描述**:本 commit 新增的 isInt8Quant/isMxFp8Quant 计算显式做了 commQuantModePtr != nullptr 防御,但紧随其后的旧 if/else if 分支仍直接解引用,同一函数内两种风格并存,影响可读性。实际运行时由上游 OP_TILING_CHECK 拦截,不会产生空指针解引用。
#### 修改建议
**修改前代码**:
```cpp
bool isInt8Quant = (commQuantModePtr != nullptr) && (*commQuantModePtr == INT8_COMM_QUANT);
bool isMxFp8Quant = (commQuantModePtr != nullptr) && (...);
...
if (*commQuantModePtr == INT8_COMM_QUANT) { // 未显式防御
...
} else if ((*commQuantModePtr == ...MXFP8_E5M2_QUANT) || // 未显式防御
(*commQuantModePtr == ...MXFP8_E4M3_QUANT)) {
```
**修改后代码**:
```cpp
if (commQuantModePtr == nullptr) {
return; // 上游已校验,纯防御早返
}
bool isInt8Quant = (*commQuantModePtr == INT8_COMM_QUANT);
bool isMxFp8Quant = (...);
...
if (*commQuantModePtr == INT8_COMM_QUANT) {
...
} else if ((*commQuantModePtr == ...MXFP8_E5M2_QUANT) || ...) {
```
**修改说明**:在函数顶部统一早返防御,后续分支可安全直接解引用,消除同函数内防御风格不一致。优先级 P3,可在后续 cleanup commit 中合并处理。
---
### 问题 ID:ISSUE-002 | 严重级别:LOW(轻微)
#### 🔬 假设检验过程
**代码段**:Int8DequantProcessA5 中的 castOne / tokFp32_1 等命名
**假设**:H0: 该代码段是安全的
| 证据序号 | 证据类型 | 规范 ID | 证据描述 | 分值增量 | 累计自信值 |
|---------|---------|--------|---------|---------|-----------|
| 1 | 风格规范违反 | cpp-style | castOne 字面易被误解为「转换 1 个元素」,实际指 RegLayout::ONE;同文件 MXFP8 用 castTrait0/2,命名规则不统一 | +20% | 20% |
| 2 | 风格规范违反 | cpp-style | 寄存器变量 tokFp32_1/_2、deqXType_1/_2 使用蛇形数字后缀,同文件其他成员使用驼峰 | +10% | 30% |
**结论**:自信值 **30%** < 60%,**保留原假设 H0**。仅风格清理建议,无功能影响。
---
**关联红线条款**:无(仅风格规范)
**代码路径**:[mc2/moe_distribute_combine_v2/op_kernel/moe_distribute_combine_v2_quant.h#L184-L204](mc2/moe_distribute_combine_v2/op_kernel/moe_distribute_combine_v2_quant.h#L184-L204)
**问题类型**:命名一致性
**问题描述**:castOne 与 RegLayout::ONE 数字耦合,但语义模糊;MXFP8 路径 castTrait0/castTrait2 直接复用 RegLayout 数字,两套命名风格并存。寄存器变量 _1/_2 与同文件驼峰命名不统一。
#### 修改建议
**修改前代码**:
```cpp
static constexpr AscendC::MicroAPI::CastTrait castZero = { RegLayout::ZERO, ... };
static constexpr AscendC::MicroAPI::CastTrait castOne = { RegLayout::ONE, ... };
AscendC::MicroAPI::RegTensor<float> tokFp32_1;
AscendC::MicroAPI::RegTensor<float> tokFp32_2;
```
**修改后代码**:
```cpp
static constexpr AscendC::MicroAPI::CastTrait castLayoutEven = { RegLayout::ZERO, ... };
static constexpr AscendC::MicroAPI::CastTrait castLayoutOdd = { RegLayout::ONE, ... };
AscendC::MicroAPI::RegTensor<float> tokFp32Lo;
AscendC::MicroAPI::RegTensor<float> tokFp32Hi;
```
**修改说明**:用 Even/Odd 或 Lo/Hi 替代字面数字命名,统一驼峰风格,提升语义可读性。优先级 P3,后续重构合并处理即可。
---
## 🛡️ TOPK 复核(潜在问题被 Tiling 校验拦截)
| TOPK 条款 | 风险点位置 | 是否被 Tiling 拦截 | 结论 |
|---|---|---|---|
| TOPK-6(特殊值/边界)uint16 fp32RepeatTimes 是否溢出 | [moe_distribute_combine_v2_quant.h#L177](mc2/moe_distribute_combine_v2/op_kernel/moe_distribute_combine_v2_quant.h#L177) | **是**:[H_MAX = 8192](mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L102),Ceil(8192,128)=64 << 65535 | 安全 |
| TOPK-1(指针校验)commQuantModePtr | [tiling.cpp#L1416](mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L1416) | **是**:[L292 OP_TILING_CHECK](mc2/moe_distribute_combine_v2/op_host/op_tiling/moe_distribute_combine_v2_tiling.cpp#L292) | 安全,见 ISSUE-001 |
| TOPK-8(GM 偏移 int64) | 本 commit 涉及 hAlign32Size_/INT8_DIVIVE、hFloatA5FusedQuantSize 等 | 全部为 UB 偏移而非 GM,h ≤ 8192,无溢出风险 | 安全 |
| TOPK-10(避免不必要浮点) | 未触及 | — | 无 |
| TOPK-11(通信算子核间同步) | 改动均在 token 内部计算,未涉及核间集合通信新流程 | — | 无 |
---
## ✅ 积极变更
1. **Tiling/Kernel 双侧对齐策略一致**:均按 512B(Tiling 用 ALIGNED_LEN * 2U、Kernel 用 ALIGNED_LEN * INT8_DIVIVE)抬升 hFloatAlign32Size/hFloatAlign256Size,避免 INT8 融合反量化的 UB 工作区低估;常量命名 kA5FusedQuantAlign 清晰。
2. **A5 / 非 A5 分支隔离**:用 __NPU_ARCH__ == 3510 + if constexpr 双重隔离融合路径,保留旧 Int8DequantProcess 作为非 A5 legacy,符合最小破坏原则。
3. **half → float 双路 Cast 用 ZERO/ONE**:与仓库历史修订(/memories/repo/int8_dequant_microapi_fuse_corrected_layout.md)后的正确认识一致,避免了前次 castOne → castTwo 的误改方向。
4. **代码风格收敛**:消除原 #endif 与 class { 处异常缩进、补齐 & 位置等。
---
## 报告生成时间
2026-05-22
## 报告状态
**PASS** — 已完成检视,未发现阻断性问题;ISSUE-001 / ISSUE-002 为可选风格改进建议,可在后续 cleanup commit 合并处理。
See merge request: cann/ops-transformer!5594 | 11 天前 |