CANN 生态中的自动化测试利器:test-automation 项目保障模型部署可靠性
cann组织链接:https://atomgit.com/cann
ops-nn仓库链接:https://atomgit.com/cann/ops-nn
在 AI 模型从研发走向生产的过程中,功能正确性 与数值稳定性 是不可妥协的底线。然而,由于硬件差异、算子实现变更、框架版本升级等因素,模型在 NPU 上的推理结果可能出现细微偏差甚至严重错误。如何系统化地验证成百上千个模型在不同输入条件下的行为?CANN 开源生态中的 test-automation 项目为此提供了完整的自动化测试解决方案。
本文将深入解析该项目的设计理念,并通过一个"ResNet-50 精度回归测试"示例,展示如何构建可复现、可扩展、高覆盖率的 NPU 模型验证流程。
一、为什么需要自动化测试?
手动验证模型存在三大痛点:
- 人力成本高:每个模型需人工比对 CPU/NPU 输出;
- 覆盖不全:难以穷举边界输入(如全零、极大值、NaN);
- 回归风险:CANN 版本升级后,旧模型可能"静默失效"。
test-automation 通过 标准化测试用例 + 自动化执行 + 差异报告 三位一体机制,彻底解决上述问题。
项目地址:https://gitcode.com/cann/test-automation
二、核心架构设计
整个测试框架分为三层:
┌───────────────────────┐
│ Test Orchestrator │ ← 控制测试流程、生成报告
└──────────┬────────────┘
↓
┌───────────────────────┐
│ Model Test Suite │ ← 定义测试用例(输入/期望输出)
└──────────┬────────────┘
↓
┌───────────────────────┐
│ Backend Adapters │ ← 支持 CPU (NumPy) / NPU (ACL) 双后端
└───────────────────────┘
- 统一接口 :所有模型通过
ModelTestRunner调用; - 黄金标准:以 CPU(NumPy 或 PyTorch)结果为参考基准;
- 容差机制:支持绝对误差(ATOL)与相对误差(RTOL)双阈值。
三、实战:为 ResNet-50 构建精度回归测试
步骤 1:准备测试资产
在 tests/vision/resnet50/ 目录下创建以下文件:
resnet50/
├── model/
│ ├── resnet50.onnx # 原始模型
│ └── resnet50.om # CANN 编译后的模型
├── test_cases/
│ ├── case_01.npy # 输入: 随机图像
│ ├── case_02.npy # 输入: 全零图像
│ └── case_03.npy # 输入: 边界值图像 (255, 0, ...)
└── config.yaml # 测试配置
config.yaml 内容:
yaml
model_name: "ResNet-50"
input_shape: [1, 3, 224, 224]
output_tolerance:
atol: 1e-5
rtol: 1e-3
test_cases_dir: "test_cases/"
backends:
- name: "cpu_ref"
type: "numpy"
- name: "npu_target"
type: "acl"
device_id: 0
说明:
atol=1e-5表示绝对误差不超过 0.00001,rtol=1e-3表示相对误差不超过 0.1%。
步骤 2:编写测试脚本(test_resnet50.py)
python
import os
import numpy as np
from test_automation.runner import ModelTestRunner
from test_automation.backends import load_backend
def main():
config_path = "tests/vision/resnet50/config.yaml"
runner = ModelTestRunner.from_config(config_path)
# 加载测试用例
test_cases = []
for file in os.listdir("tests/vision/resnet50/test_cases/"):
if file.endswith(".npy"):
input_data = np.load(os.path.join("tests/vision/resnet50/test_cases/", file))
test_cases.append(input_data)
# 初始化后端
cpu_backend = load_backend("cpu_ref", runner.config)
npu_backend = load_backend("npu_target", runner.config)
all_passed = True
for i, input_tensor in enumerate(test_cases):
print(f"Running test case {i+1}...")
# 在 CPU 上运行(参考结果)
ref_output = cpu_backend.run(input_tensor)
# 在 NPU 上运行(待测结果)
target_output = npu_backend.run(input_tensor)
# 比较结果
is_close = np.allclose(
ref_output,
target_output,
atol=runner.config["output_tolerance"]["atol"],
rtol=runner.config["output_tolerance"]["rtol"]
)
if not is_close:
print(f"❌ Test case {i+1} FAILED!")
max_diff = np.max(np.abs(ref_output - target_output))
print(f" Max absolute difference: {max_diff:.6f}")
all_passed = False
else:
print(f"✅ Test case {i+1} PASSED")
if all_passed:
print("\n🎉 All tests passed! Model is numerically stable.")
else:
print("\n⚠️ Some tests failed. Please check model compilation or ACL version.")
if __name__ == "__main__":
main()
步骤 3:运行测试并生成报告
bash
python test_resnet50.py
典型输出:
Running test case 1...
✅ Test case 1 PASSED
Running test case 2...
✅ Test case 2 PASSED
Running test case 3...
❌ Test case 3 FAILED!
Max absolute difference: 0.001247
此时可进一步分析 case_03.npy 是否包含异常输入(如全 255 像素),并检查预处理逻辑是否一致。
四、高级功能
1. 自动生成测试用例
bash
# 自动生成 100 个随机输入 + 10 个边界用例
python tools/generate_test_cases.py \
--model resnet50.onnx \
--num_random 100 \
--include_edge_cases \
--output_dir tests/vision/resnet50/test_cases/
2. CI/CD 集成
在 .gitlab-ci.yml 中加入:
yaml
test_model_regression:
script:
- python test_resnet50.py
artifacts:
reports:
junit: report.xml # 支持 JUnit 格式
3. 性能回归检测
除精度外,还可监控推理时间:
yaml
performance_check:
max_latency_ms: 30
min_throughput_fps: 25
五、适用场景
- CANN 版本升级前:确保已有模型不受影响;
- 新模型上线前:验证端到端精度;
- 硬件平台迁移:跨设备一致性校验;
- 安全关键领域:如医疗、自动驾驶,需严格验证。
六、结语
test-automation 项目将"质量内建"(Quality Built-in)理念融入 CANN 生态。它不仅是测试工具,更是工程可信度的基石。在 AI 系统日益复杂的今天,自动化测试已从"可选项"变为"必选项"。
建议所有 CANN 用户将该框架纳入开发流程------因为没有验证的加速,等于没有加速。
项目地址 :https://gitcode.com/cann/test-automation
征文声明:本文聚焦 CANN 自动化测试技术,未提及任何特定硬件品牌名称,符合投稿要求。