已合并
docs: 新增测试框架指南,补充testframework编译运行依赖使用说明 #2120
zouyanlong创建于 6月12日
docs: 新增测试框架指南,补充testframework编译运行依赖使用说明 #2120
已合并
共 3 个文件变更+321-2
| @@ -0,0 +1,315 @@ | |||
| 1 | +# 测试框架指南 | ||
| 2 | + | ||
| 3 | +## 概述 | ||
| 4 | + | ||
| 5 | +ATB测试框架是一套数据驱动的算子测试系统,支持通过CSV文件声明式定义测试用例,自动完成张量生成、算子执行、golden对比和精度/性能验证。框架分为两层: | ||
| 6 | + | ||
| 7 | +- **Python层**(`CsvOpsTestTool`):CSV驱动的测试入口,负责用例解析、数据生成、结果验证 | ||
| 8 | +- **C++层**(`atb_torch`):PyTorch自定义类,桥接ATB算子与PyTorch张量,供Python层调用 | ||
| 9 | + | ||
| 10 | +## 环境依赖 | ||
| 11 | + | ||
| 12 | +### 编译依赖 | ||
| 13 | + | ||
| 14 | +以下依赖在编译测试框架(`bash scripts/build.sh testframework`)时必须存在,提供头文件和链接库: | ||
| 15 | + | ||
| 16 | +| 依赖 | 用途 | 验证命令 | | ||
| 17 | +|------|------|---------| | ||
| 18 | +| CANN toolkit | ATB编译基础 | `echo $ASCEND_HOME_PATH` | | ||
| 19 | +| PyTorch | C++层编译链接`torch/script.h`等头文件及`libtorch.so` | `python3 -c "import torch; print(torch.__file__)"` | | ||
| 20 | +| torch_npu | C++层编译链接`torch_npu`头文件及`libtorch_npu.so` | `pip show torch-npu` | | ||
| 21 | + | ||
| 22 | +PyTorch及torch_npu的安装请参考[昇腾PyTorch安装指南](https://www.hiascend.com/document/detail/zh/Pytorch/2600/configandinstg/instg/docs/zh/installation_guide/installation_description.md)。 | ||
| 23 | + | ||
| 24 | +### 运行依赖 | ||
| 25 | + | ||
| 26 | +运行CSV测试时需要以下Python库(PyTorch和torch_npu同时也是编译依赖): | ||
| 27 | + | ||
| 28 | +| 依赖 | 用途 | 验证命令 | | ||
| 29 | +|------|------|---------| | ||
| 30 | +| PyTorch | 张量创建、golden计算、算子调用 | `python3 -c "import torch"` | | ||
| 31 | +| torch_npu | NPU设备访问 | `python3 -c "import torch_npu"` | | ||
| 32 | +| pandas | CSV解析 | `python3 -c "import pandas"` | | ||
| 33 | +| numpy | 数据生成与golden计算 | `python3 -c "import numpy"` | | ||
| 34 | +| ml_dtypes | BF16等自定义数据类型支持 | `python3 -c "import ml_dtypes"` | | ||
| 35 | +| en_dtypes | hifloat8数据类型支持 | `python3 -c "from en_dtypes import hifloat8"` | | ||
| 36 | +| openpyxl | Excel格式输出支持 | `python3 -c "import openpyxl"` | | ||
| 37 | +| scipy | golden计算中的科学计算 | `python3 -c "import scipy"` | | ||
I | |||
| 38 | + | ||
| 39 | +其他Python三方库依赖见`tests/framework/python/CsvOpsTestTool/requirements.txt`。 | ||
| 40 | + | ||
| 41 | +### CXX ABI版本确定 | ||
| 42 | + | ||
| 43 | +`testframework`编译产物路径依赖正确的ABI版本(`cxx_abi_0`或`cxx_abi_1`),判断方法: | ||
| 44 | + | ||
| 45 | +```shell | ||
| 46 | +python3 -c "import torch; print(torch.compiled_with_cxx11_abi())" | ||
| 47 | +``` | ||
| 48 | + | ||
| 49 | +- 输出`True`或torch未安装 → 使用`--cxx_abi=1`(`--use_cxx11_abi=1`) | ||
| 50 | +- 输出`False` → 使用`--cxx_abi=0`(`--use_cxx11_abi=0`) | ||
| 51 | + | ||
| 52 | +### 常见编译失败 | ||
| 53 | + | ||
| 54 | +| 错误信息 | 原因 | 解决方法 | | ||
| 55 | +|---------|------|---------| | ||
| 56 | +| `torch/script.h: No such file or directory` | 环境中未安装PyTorch | 安装PyTorch:`pip install torch` | | ||
| 57 | +| `torch_npu/csrc/core/npu/NPUStream.h: No such file` | 环境中未安装torch_npu | 安装torch_npu | | ||
| 58 | +| `libatb.so: undefined reference` | ABI版本不匹配 | 确认CXX ABI版本与已编译的ATB核心库一致 | | ||
| 59 | + | ||
| 60 | + | ||
| 61 | +> **注意**:`build.sh`在torch未安装时仅输出`Warning: Torch is not installed!`但仍继续编译,最终在C++编译阶段报头文件缺失错误。若无需运行CSV测试框架,可使用`bash scripts/build.sh default`仅编译ATB核心库。 | ||
| 62 | + | ||
| 63 | +## 如何编译 | ||
| 64 | + | ||
| 65 | +### 完整编译流程 | ||
| 66 | + | ||
| 67 | +```shell | ||
| 68 | +cd ascend-transformer-boost | ||
| 69 | + | ||
| 70 | +# 1. 设置CANN环境变量(根据实际安装路径) | ||
| 71 | +source /usr/local/Ascend/ascend-toolkit/set_env.sh | ||
| 72 | + | ||
| 73 | +# 2. 编译测试框架(包含ATB核心库 + C++测试框架 + Python测试工具) | ||
| 74 | +bash scripts/build.sh testframework | ||
| 75 | + | ||
| 76 | +# 3. 设置ATB运行环境 | ||
| 77 | +source output/atb/set_env.sh | ||
| 78 | +``` | ||
| 79 | + | ||
| 80 | +### 增量编译 | ||
| 81 | + | ||
| 82 | +日常开发中修改代码后无需全量重编译: | ||
| 83 | + | ||
| 84 | +```shell | ||
| 85 | +bash scripts/build.sh testframework | ||
| 86 | +``` | ||
| 87 | + | ||
| 88 | +> **注意**:不要删除`build/`目录,不要加`--clean-first`,增量编译即可。仅在CMake配置变更或算子内核文件(`.cce`)变动时才需要`--clean-first`,因为CMake无法自动检测内核文件变更。 | ||
| 89 | + | ||
| 90 | +### 编译产物 | ||
| 91 | + | ||
| 92 | +编译完成后,关键产物位于: | ||
| 93 | + | ||
| 94 | +| 路径 | 说明 | | ||
| 95 | +|------|------| | ||
| 96 | +| `output/atb/cxx_abi_{0\|1}/lib/libatb.so` | ATB核心库 | | ||
| 97 | +| `output/atb/cxx_abi_{0\|1}/lib/libatb_test_framework.so` | 测试框架动态库(含OperationTorch) | | ||
| 98 | +| `tests/framework/python/CsvOpsTestTool/` | Python测试工具(安装到output) | | ||
| 99 | + | ||
| 100 | +## 如何编写测试用例 | ||
| 101 | + | ||
| 102 | +### CSV用例格式 | ||
| 103 | + | ||
| 104 | +测试用例以CSV文件形式存放在`tests/apitest/opstest/csv/`目录下,以`|`作为分隔符。 | ||
| 105 | + | ||
| 106 | +#### 表头字段说明 | ||
| 107 | + | ||
| 108 | +| 字段 | 说明 | 示例 | | ||
| 109 | +|------|------|------| | ||
| 110 | +| CaseNum | 用例编号 | `1` | | ||
| 111 | +| CaseName | 用例名称 | `MatmulElewiseAdd` | | ||
| 112 | +| OpName | 算子名称 | `LinearOperation` | | ||
| 113 | +| OpParam | 算子参数(JSON) | `{"transposeA":true}` | | ||
| 114 | +| InNum | 输入张量数量 | `3` | | ||
| 115 | +| InDType | 输入数据类型(`;`分隔) | `float16;float16;float16` | | ||
| 116 | +| InFormat | 输入格式(`;`分隔) | `nd;nd;nd` | | ||
| 117 | +| InShape | 输入形状(`;`分隔,维度用`,`) | `2,3;4,3;4` | | ||
| 118 | +| OutNum | 输出张量数量 | `1` | | ||
| 119 | +| OutDType | 输出数据类型 | `float16` | | ||
| 120 | +| OutFormat | 输出格式 | `nd` | | ||
| 121 | +| OutShape | 输出形状 | `2,4` | | ||
| 122 | +| DataGenType | 数据生成方式 | `customize;customize;customize` | | ||
| 123 | +| DataGenRange | 数据范围 | `-2,2;-2,2;-2,2` | | ||
| 124 | +| InTensorFile | 输入张量文件路径(可选) | 空 | | ||
| 125 | +| OutTensorFile | 输出张量文件路径(可选) | 空 | | ||
| 126 | +| TestType | 测试类型(可选) | `Function`或`Performance` | | ||
| 127 | +| TestLevel | 测试级别(可选) | `Level0`/`Level1`/`Level2` | | ||
| 128 | +| FromModel | 来源模型(可选) | `LLaMA-65B` | | ||
| 129 | +| SocVersion | 支持的芯片型号 | `Ascend910B,Ascend310P` | | ||
| 130 | +| ExpectedError | 期望的错误码 | `NO_ERROR`或错误码 | | ||
| 131 | + | ||
| 132 | +#### 数据类型枚举 | ||
| 133 | + | ||
| 134 | +| 值 | 含义 | | ||
| 135 | +|----|------| | ||
| 136 | +| `float16` | FP16 | | ||
| 137 | +| `bf16` | BF16 | | ||
| 138 | +| `float` | FP32 | | ||
| 139 | +| `int8` | INT8 | | ||
| 140 | +| `int32` | INT32 | | ||
| 141 | +| `int64` | INT64 | | ||
| 142 | +| `uint64` | UINT64 | | ||
| 143 | + | ||
| 144 | +#### 格式枚举 | ||
| 145 | + | ||
| 146 | +| 值 | 含义 | | ||
| 147 | +|----|------| | ||
| 148 | +| `nd` | N维通用格式 | | ||
| 149 | +| `fractal_nz` | 华为NZ分形格式 | | ||
| 150 | + | ||
| 151 | +#### 错误码格式 | ||
| 152 | + | ||
| 153 | +格式为`阶段前缀:错误码`: | ||
| 154 | + | ||
| 155 | +| 前缀 | 阶段 | 示例 | | ||
| 156 | +|------|------|------| | ||
| 157 | +| `C:` | CreateOperation(创建算子) | `C:ERROR_INVALID_PARAM` | | ||
| 158 | +| `I:` | InferShape(维度推导) | `I:ERROR_INVALID_TENSOR_DIM_NUM` | | ||
| 159 | +| `S:` | Setup(CANN调用) | `S:ERROR_CANN_ERROR` | | ||
| 160 | +| 无前缀 | 正例 | `NO_ERROR` | | ||
| 161 | + | ||
| 162 | +### 用例示例 | ||
| 163 | + | ||
| 164 | +#### 正例(基本矩阵乘) | ||
| 165 | + | ||
| 166 | +``` | ||
| 167 | +1|MatmulElewiseAdd|LinearOperation|{}|3|float16;float16;float16|nd;nd;nd|2,3;4,3;4|1|float16|nd|2,4|customize;customize;customize|-2,2;-2,2;-2,2||||||Ascend910B,Ascend310P|NO_ERROR | ||
| 168 | +``` | ||
| 169 | + | ||
| 170 | +#### 正例(带转置参数) | ||
| 171 | + | ||
| 172 | +``` | ||
| 173 | +23|MatmulTransposeA|LinearOperation|{"transposeA":true,"transposeB":false}|3|float16;float16;float16|nd;nd;nd|3,2;3,4;1,4|1|float16|nd|2,4|customize;customize;customize|-2,2;-2,2;-2,2||||||Ascend910B,Ascend310P|NO_ERROR | ||
| 174 | +``` | ||
| 175 | + | ||
| 176 | +#### 反例(参数校验错误) | ||
| 177 | + | ||
| 178 | +``` | ||
| 179 | +146|MatmulCError|LinearOperation|{"hasBias":false,"enAccum":true}|0||||0|||||||||||Ascend310P|C:ERROR_INVALID_PARAM | ||
| 180 | +``` | ||
| 181 | + | ||
| 182 | +### 编写golden函数 | ||
| 183 | + | ||
| 184 | +每个算子需在`tests/framework/python/CsvOpsTestTool/data_generation.py`中注册golden函数: | ||
| 185 | + | ||
| 186 | +```python | ||
| 187 | +class LinearOperation(DataGen): | ||
| 188 | + @staticmethod | ||
| 189 | + def golden(in_tensors, op_params): | ||
| 190 | + # in_tensors: list[torch.Tensor],输入张量 | ||
| 191 | + # op_params: dict,从CSV的OpParam字段解析 | ||
| 192 | + input_data = in_tensors[0] | ||
| 193 | + weight = in_tensors[1] | ||
| 194 | + bias = in_tensors[2] if len(in_tensors) > 2 else None | ||
| 195 | + | ||
| 196 | + result = torch.matmul(input_data, weight.T) | ||
| 197 | + if bias is not None: | ||
| 198 | + result = result + bias | ||
| 199 | + return [result] | ||
| 200 | + | ||
| 201 | + @staticmethod | ||
| 202 | + def get_op_type(op_params): | ||
| 203 | + return OpTypes.COMPUTE_FLOAT | ||
| 204 | +``` | ||
| 205 | + | ||
| 206 | +### 用例设计原则 | ||
| 207 | + | ||
| 208 | +1. 覆盖所有支持的输入格式组合(ND、NZ) | ||
| 209 | +2. 覆盖所有支持的数据类型(float16、bf16、int8等) | ||
| 210 | +3. 覆盖边界shape(对齐/非对齐、batch=1/batch>1) | ||
| 211 | +4. 包含参数校验反例,验证错误码正确性 | ||
| 212 | +5. 反例的`InNum`/`OutNum`可为0(不需要构造张量) | ||
| 213 | +6. `SocVersion`字段标注该用例适用的芯片型号 | ||
| 214 | + | ||
| 215 | +## 如何运行测试 | ||
| 216 | + | ||
| 217 | +### 基本命令 | ||
| 218 | + | ||
| 219 | +```shell | ||
| 220 | +cd ascend-transformer-boost | ||
| 221 | +source output/atb/set_env.sh | ||
| 222 | + | ||
| 223 | +# 运行某个算子的全部用例 | ||
| 224 | +python tests/framework/python/CsvOpsTestTool/atb_csv_ops_test.py \ | ||
| 225 | + -i tests/apitest/opstest/csv/linear.csv | ||
| 226 | + | ||
| 227 | +# 运行指定范围的用例(1-based行号) | ||
| 228 | +python tests/framework/python/CsvOpsTestTool/atb_csv_ops_test.py \ | ||
| 229 | + -i tests/apitest/opstest/csv/linear.csv -n 1:10 | ||
| 230 | + | ||
| 231 | +# 运行单个用例 | ||
| 232 | +python tests/framework/python/CsvOpsTestTool/atb_csv_ops_test.py \ | ||
| 233 | + -i tests/apitest/opstest/csv/linear.csv -n 5 | ||
| 234 | +``` | ||
| 235 | + | ||
| 236 | +### 常用参数 | ||
| 237 | + | ||
| 238 | +| 参数 | 说明 | 示例 | | ||
| 239 | +|------|------|------| | ||
| 240 | +| `-i` | 输入CSV文件或目录 | `-i tests/apitest/opstest/csv/linear.csv` | | ||
| 241 | +| `-n` | 用例行号(1-based,单个或范围) | `-n 5` 或 `-n 1:10`,`0`表示全部 | | ||
| 242 | +| `-t` | 执行次数(性能测试用) | `-t 100` | | ||
| 243 | +| `-ll` | 日志级别 | `-ll debug` | | ||
| 244 | +| `-op` | 按算子名正则过滤 | `-op LinearOperation` | | ||
| 245 | +| `-s` | 指定芯片型号 | `-s Ascend910B` | | ||
| 246 | +| `-tt` | 按测试类型过滤 | `-tt Function` 或 `-tt Performance` | | ||
| 247 | +| `-sv` | 跳过精度验证 | `-sv` | | ||
| 248 | +| `-o` | 结果输出路径 | `-o ./result.csv` | | ||
| 249 | + | ||
| 250 | +### 性能测试 | ||
| 251 | + | ||
| 252 | +```shell | ||
| 253 | +python tests/framework/python/CsvOpsTestTool/atb_csv_ops_test.py \ | ||
| 254 | + -i tests/apitest/opstest/csv/linear.csv \ | ||
| 255 | + -tt Performance -t 400 | ||
| 256 | +``` | ||
| 257 | + | ||
| 258 | +### 多卡测试 | ||
| 259 | + | ||
| 260 | +对于需要多卡的算子(如AllGather),使用`-ws`指定卡数: | ||
| 261 | + | ||
| 262 | +```shell | ||
| 263 | +python tests/framework/python/CsvOpsTestTool/atb_csv_ops_test.py \ | ||
| 264 | + -i tests/apitest/opstest/csv/all_gather.csv -ws 4 | ||
| 265 | +``` | ||
| 266 | + | ||
| 267 | +### 关于`-n`参数的注意事项 | ||
| 268 | + | ||
| 269 | +`-n`匹配的是**CSV数据行号(1-based)**,不是`CaseNum`字段的值。删除中间用例后后续行号会前移,建议通过实际文件行数确认目标用例。传入`0`表示运行全部用例。 | ||
| 270 | + | ||
| 271 | +### 日志排查 | ||
| 272 | + | ||
| 273 | +测试失败时,可通过以下方式排查: | ||
| 274 | + | ||
| 275 | +```shell | ||
| 276 | +# 查看ATB运行日志 | ||
| 277 | +strings $ASCEND_PROCESS_LOG_PATH/atb/atb_*.log | grep -i "error" | ||
| 278 | + | ||
| 279 | +# 查看CANN底层错误 | ||
| 280 | +grep -a "ERROR" $ASCEND_PROCESS_LOG_PATH/debug/plog/plog-*.log | ||
| 281 | +``` | ||
| 282 | + | ||
| 283 | +## 附录:Python测试方式(非CSV) | ||
| 284 | + | ||
| 285 | +对于不适合CSV格式的复杂场景,可直接编写Python测试类: | ||
| 286 | + | ||
| 287 | +```python | ||
| 288 | +import unittest | ||
| 289 | +from tests.framework.python import op_test | ||
| 290 | + | ||
| 291 | +class TestMyOp(op_test.OpTest): | ||
| 292 | + def golden_calc(self, in_tensors): | ||
| 293 | + # 计算预期结果 | ||
| 294 | + return [expected_output] | ||
| 295 | + | ||
| 296 | + def golden_compare(self, out_tensors, golden_out_tensors): | ||
| 297 | + return torch.allclose(out_tensors[0].float(), | ||
| 298 | + golden_out_tensors[0].float(), | ||
| 299 | + rtol=0.001, atol=0.001) | ||
| 300 | + | ||
| 301 | + def test_case1(self): | ||
| 302 | + in_tensors = [torch.randn(2, 3).to(torch.float16)] | ||
| 303 | + out_tensors = [torch.zeros(2, 3).to(torch.float16)] | ||
| 304 | + self.set_param("MyOperation", {"param1": 1}) | ||
| 305 | + self.execute(in_tensors, out_tensors) | ||
| 306 | + | ||
| 307 | +if __name__ == '__main__': | ||
| 308 | + unittest.main() | ||
| 309 | +``` | ||
| 310 | + | ||
| 311 | +执行: | ||
| 312 | + | ||
| 313 | +```shell | ||
| 314 | +python tests/apitest/kernelstest/mix/test_my_op.py | ||
| 315 | +``` | ||
| @@ -38,7 +38,7 @@ ATB的基本编译命令是`bash build.sh`,默认构建模式下生成版本 | |||
| 38 | - `--torch_atb`: 编译pybind11并生成whl包,随后pip安装即可使用python接口 | 38 | - `--torch_atb`: 编译pybind11并生成whl包,随后pip安装即可使用python接口 |
| 39 | - `--customizeops_tests`: 构建ops_customize的单元测试 | 39 | - `--customizeops_tests`: 构建ops_customize的单元测试 |
| 40 | - `default`: 默认选项,构建ATB加速库的内容 | 40 | - `default`: 默认选项,构建ATB加速库的内容 |
| 41 | -- `testframework`:构建测试框架,生成版本信息,并打包测试框架 | 41 | +- `testframework`:构建测试框架,生成版本信息,并打包测试框架。详见[测试框架指南](测试框架指南.md) |
| 42 | - `unittest`:构建单元测试,运行内核接口测试和单元测试 | 42 | - `unittest`:构建单元测试,运行内核接口测试和单元测试 |
| 43 | - `kernelunittest`:构建内核单元测试,运行内核单元测试 | 43 | - `kernelunittest`:构建内核单元测试,运行内核单元测试 |
| 44 | - `pythontest`:构建 Python 测试,运行 Python 测试 | 44 | - `pythontest`:构建 Python 测试,运行 Python 测试 |
| @@ -1,2 +1,6 @@ | |||
| 1 | +numpy | ||
| 2 | +pandas | ||
| 1 | openpyxl | 3 | openpyxl |
| 2 | -scipy | 4 | +scipy |
| 5 | +ml_dtypes | ||
| 6 | +en_dtypes | ||
如果有强制py的库依赖的话,建议更新到requirements.txt;更新文档对于这些库的说明。 目前只有: openpyxl scipy 需要更新其他的。