---
tags: [CANN]
doc_type: knowledge-note
abstract: "串联需求、实现、精度、测试、排障与性能验收。"
返回目录: "[[计算机系/昇腾与CANN/大模型与算子专题学习导航|大模型与算子专题学习导航]]"
专题目录: "[[计算机系/昇腾与CANN/CANNBot智能体与算子开发工作流|CANNBot智能体与算子开发工作流]]"
上一篇: "[[计算机系/昇腾与CANN/04 CANNBot架构与环境配置|04 CANNBot架构与环境配置]]"
前置操作: "[[计算机系/昇腾与CANN/04 CANNBot架构与环境配置|04 CANNBot架构与环境配置]]"
下一篇: "[[计算机系/昇腾与CANN/06 CANNBot算子实战与知识复用|06 CANNBot算子实战与知识复用]]"
---

# 05 CANNBot开发流程与质量验证

串联需求、实现、精度、测试、排障与性能验收。

## 4. 七阶段算子开发工作流

配置正确时，算子开发任务通过 `ascendc-kernel-develop-workflow` 组织执行。

| 阶段 | 主要工作 | 应形成的结果 |
| --- | --- | --- |
| 1. 环境检查 | 查询NPU，确认CANN、环境变量、库和工具 | 可用平台与依赖信息 |
| 2. 需求分析 | 明确数学表达式、shape、dtype、语义及性能要求 | 可验证的需求与设计依据 |
| 3. 算子实现 | 设计Tiling、规划Buffer、选择API、实现Kernel与Host代码 | 代码、构建脚本和设计文档 |
| 4. 验证优化 | 编译、执行测试、比较输出、分析初步性能 | 正确性证据和待解决问题 |
| 5. 问题处理 | 定位精度、运行时、挂起或性能问题并修复 | 修复方案及回归结果 |
| 6. 性能验收 | 采集Profiling数据，对照目标评估 | 达标判断与性能报告 |
| 7. 总结报告 | 汇总代码、设计、问题、验证结果 | 可追溯交付物与可复用知识 |

阶段4和5构成迭代循环。出现错误后回到对应设计或实现环节，修复后重新验证；功能正确后，仍需独立完成性能验收。

### 4.1 需求必须能被测试

“开发一个算子”不足以形成验收标准。需求至少应包含：

- 数学定义、输入输出关系和特殊值语义。
- 输入输出的shape、dtype、layout，是否涉及广播或动态shape。
- 目标芯片、CANN版本及调用方式。
- 精度阈值及其判定方法。
- 需要覆盖的边界和异常情况。
- 延迟、吞吐量或相对基线等性能目标。

CPU Reference 或 Golden 实现用于计算参考结果。Reference 自身也必须符合规格，否则NPU与CPU输出一致仍可能掩盖共同的语义错误。

### 4.2 Tiling：核间分工与核内分块

Tiling 既要把工作分配到多个 AI Core，也要让单核每次处理的数据适配片上存储容量。

1. 分析shape、dtype和访问模式。
2. 选择分块维度及核间分配策略。
3. 计算核数、块大小、总数据量等参数。
4. 规划GM、UB，以及算法需要的L1等存储空间。
5. 检查对齐、负载均衡、尾块与流水线依赖。

Element-wise 算子通常可按数据块分配；Reduce 需要考虑归约轴、非归约轴及结果合并；MatMul 常采用矩阵分块。具体方案必须结合形状和芯片资源判断，不能只按算子类别固定切分。

Tiling参数结构示例：

```cpp
#include <cstdint>

struct AddTiling {
    uint32_t blockDim;   // 参与计算的核数
    uint32_t tileSize;   // 每块处理规模
    uint32_t totalSize;  // 总处理规模
    uint32_t splitAxis;  // 切分轴
};
```

参数设计需要约定大小以元素还是字节计量，并保证Host端和Kernel端解释一致。该结构仅展示参数组织方式，完整实现还需要边界处理和数据传递。

### 4.3 Kernel与工程文件

Abs等矢量算子的基本数据路径是：从GM搬入UB，在UB上计算，再写回GM。

```cpp
// 已建立张量、完成缓冲区分配并满足流水线同步要求的核心片段。
DataCopy(xUB, xGM, size);
Abs(zUB, xUB, size);
DataCopy(zGM, zUB, size);
```

完整Kernel还需处理入口参数、全局与局部张量绑定、队列或Buffer初始化、核索引、循环分块、尾块和同步。这三个调用不能单独替代完整的可执行Kernel。

典型输出目录：

```text
ops/abs/
  CMakeLists.txt
  abs_kernel.asc
  build.sh
  run.sh
  docs/
    DESIGN.md
    PLAN.md
  tests/
  scripts/
```

### 4.4 验证、排障与性能验收

在算子工程目录中运行生成的脚本：

```bash
bash build.sh
bash run.sh
```

精度错误通过CPU与NPU对拍定位，运行故障结合错误码、日志、同步及访存检查排查。对应技能包括 `ascendc-precision-debug`、`ascendc-runtime-debug` 和 `ascendc-crash-debug`。

性能验收通过 `ops-profiling` 组织采集与分析，底层可使用 `msprof op`。采集文件及指标数量随工具版本和采集选项变化，重点是解释 Task Duration、主导流水和瓶颈，而不是固定要求某个CSV文件数量。

| 结论 | 含义 |
| --- | --- |
| `PASS` | 满足约定验收条件 |
| `PASS WITH NOTES` | 通过但带有限定条件或需关注事项 |
| `FAIL` | 存在未满足的验收条件 |

性能数据可归档到 `perf/`。最终文档通常包括 `DESIGN.md`、`PLAN.md`、`REVIEW.md`、`WALKTHROUGH.md`，并记录代码路径、精度结果、性能概要及关键问题。

## 5. 质量门禁与Harness

Harness 是约束智能体执行、验证和反馈的一套工程机制。编排器需要检查当前阶段的输入输出合约，必要时回退或超时降级，避免只根据模型文字声明判断任务完成。

![CANNBot算子研发架构](.assets/CANNBot/算子研发架构.png)

架构中的状态序列为：

```text
INIT -> SPEC_READY -> REF_READY -> KERNEL_READY
     -> VALIDATED -> PROFILED -> OPTIMIZED -> ACCEPTED
```

这是实现层的状态划分，与面向使用者的七阶段流程粒度不同，不需要一一对应。

| 门禁 | 验证内容 |
| --- | --- |
| G1 规格完整性 | 需求是否明确且可测试 |
| G2 编译通过 | 代码与依赖能否通过构建 |
| G3 功能正确性 | 输出、精度、边界行为是否符合规格 |
| G4 性能达标 | 测量结果是否达到约定目标 |
| G5 可维护性 | 代码结构、文档和测试是否支持后续维护 |

编译成功只能说明通过了构建检查。功能正确、性能达标和可维护性各自需要证据。

完整Harness属于逐步演进方向，设计中包含：

- **六类约束**：数学、硬件、反模式、数值、性能和流程。
- **多尺度反馈**：分钟级修改、功能对拍、小时级调优及跨任务知识积累。
- **两级知识利用**：在单个算子内修正错误，再把跨算子可复用经验保存为模板或规则。
- **成熟度演进**：基础约束、闭环验证、性能闭环、知识驱动、自适应进化。

约束层级、反馈层级和成熟度都可能使用L编号，但它们表示不同维度，不能混为同一套分级。

后训练规划包括采集正样本、修复样本、偏好样本、拒答样本和反模式样本，探索SFT、DPO和Reward Model，并按规格生成、Kernel首版正确率、性能建议和测试生成分别评估角色能力。

发布门禁示例包括编译通过率不低于当前版本、功能通过率提升至少5%、修复轮次下降至少15%，再通过灰度验证逐步切换。这些是评估目标，不是已经达到的结果；使用时还需明确提升是相对比例还是百分点，并固定测试集和统计口径。

## 6. 代码检视与测试生成

### 6.1 代码检视

`ascendc-code-review` 可用于本地代码或PR检视，关注数值运算、内存指针、资源管理、输入验证与并发安全。输入应说明代码位置及全量检视或快速检视等模式。

检视流程是：提出风险假设，收集代码证据，按照规则评估，输出问题与整改建议。修改后需要重新检查，再决定是否满足合入条件。

一种规则评分示例为红线违反加40%、一般违反加20%、超过60%判为风险。这类数字属于规则系统的打分方法，不应解释为经过统计校准的真实错误概率。

Abs示例还从质量、性能、安全、可维护性、正确性几个维度检查代码，涉及UB对齐、API使用、边界、越界访问与流水线。32字节对齐、双缓冲等应结合目标API和算法适用条件检查，不能把采用某种优化形式本身当作正确性证明。

### 6.2 UT与ST

UT侧重局部模块和分层逻辑，ST侧重算子在组合输入及系统运行条件下的行为。二者都需要明确测试对象与判断标准。

| 测试类型 | 组织流程 |
| --- | --- |
| UT | 收集信息、分层设计和生成用例、测试驱动开发、编译验证、覆盖率验证、生成报告 |
| ST | 对测试对象建模、提取因子、求解因子依赖、组合求解、生成用例、评审 |

覆盖不足时补充测试并重新验证。ST可围绕shape、dtype、属性组合、边界和异常值建立约束，避免产生大量无效组合。

案例指标需要与其测试范围一起理解：

- UT案例汇总涉及10多个算子，平均约25分钟完成生成，平均增加10多个用例。
- Addmm案例生成69条有效ST用例，报告有效覆盖度超过95%。
- 逐算子UT表中，`moe_distribute_dispatch_v2`覆盖率由46.50%升至68.70%，`matmul_all_reduce`由65.70%升至86.50%。提升覆盖率不代表每个算子都超过80%。
- 一次代码检视案例约用15分钟、消耗约1.5万token，对比约2小时人工检视。时间和成本受代码规模、模型及检视方式影响。

“用例有效率”“代码覆盖率”“红线拦截率”和“设计完备度”衡量不同事情。生成用例可以执行、覆盖了某行代码，都不能直接证明所有输入情况下功能正确。
