CANN ops-transformer 中 ChunkGatedDeltaRule 算子的 pytest 精度测试框架实战指南
2026/9/20 10:17:54 网站建设 项目流程

CANN ops-transformer 中 ChunkGatedDeltaRule 算子的 pytest 精度测试框架实战指南

【免费下载链接】ops-transformer本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-transformer

本指南以 attention/chunk_gated_delta_rule/tests/pytest/README.md 为骨架,系统讲解 CANN ops-transformer 项目中ChunkGatedDeltaRule算子 pytest 测试框架的架构、运行方式与复现手段。读完本文,你将掌握如何配置单用例参数、运行 single / rdv / random / random_npu 四种测试模式、理解随机用例生成与内存约束规则、通过 CSV 与随机种子定位并复现失败用例,以及利用 msprof 采集算子耗时。文中所有结论均可在仓库对应源码与测试脚本中得到验证。

一、框架概览:CPU Golden + NPU 直调 + 精度对比

ChunkGatedDeltaRule(chunk 化门控 Delta Rule,线性注意力的一种前向实现)算子的测试框架基于 pytest 构建,核心思路是"三段式验证":

  • CPU 侧:复现算子功能,生成 golden 数据作为真值;
  • NPU 侧:通过 TorchNPU 对算子进行直调(torch_npu.npu_chunk_gated_delta_rule)获取实际结果;
  • 精度对比:将 CPU 与 NPU 结果按多项误差指标比对,验证算子功能正确性。

主调测逻辑位于 chunk_gated_delta_rule_main.py,其中run_chunk_gated_delta_rule_eager(L434 起)串起了整条链路:生成/加载输入 → 分别调用cgdr_golden(CPU 复现,L198)、cgdr_benchmark(优化版基准实现,L235)、cgdr_npu(NPU 直调,L259)→ 最后用compare_cv(L144)做精度判定。NPU 直调既支持 eager 模式(torch_npu.npu_chunk_gated_delta_rule),也支持 aclgraph 图模式(torch.compile(backend=npu_backend),见MyModelL50-69)。

二、当前实现范围与参数限制

框架当前覆盖的算子约束如下(与 test_chunk_gated_delta_rule_single.py 中随机生成器的注释一致):

约束项限制
batch_size支持大于 0(随机池:1/2/4/8/16/32/64/128)
seqlen支持任意序列长度,含非 chunk 对齐值
NK、NV head 数NV 需为 NK 的倍数,且 Nv≥Nk
DK、DV均不超过 128
data_type当前支持 BF16
chunk_size固定 64(算子 tiling 硬编码,golden 须与 NPU 保持一致)

在 test_chunk_gated_delta_rule_paramset.py 中可以看到默认的 single 用例即为 BF16:data_type=torch.bfloat16state_data_type=torch.bfloat16,而 test_chunk_gated_delta_rule_paramset_rdv.py 的 RDV 参数集进一步通过_gen_fp32_cases_gen_noncontiguous_cases扩展出state_data_type=float32和 state 非连续(is_contiguous=False)的变体,用于覆盖不同状态精度路径与内存布局路径。

三、环境配置与前置要求

运行测试前需要完成以下准备:

  1. TorchNPU 安装:安装与当前环境匹配的 TorchNPU 包(README 指向其官方安装教程,请以官方最新发布版本为准);
  2. ops-transformer 环境安装与环境变量配置:具体操作参见仓库根目录 README.md,完成算子 custom 包(custom 算子包)的编译与调用配置;
  3. custom 包调用:框架支持通过 custom 包方式调用算子,确保 NPU 侧算子已正确安装并可通过torch_npu访问。

四、pytest 目录文件结构

测试代码集中在attention/chunk_gated_delta_rule/tests/pytest/目录下,各文件职责如下:

文件职责
test_run.sh执行脚本,封装各测试模式与可选标志
conftest.pypytest 钩子:逐用例记录参数/结果/随机种子,会话结束落 CSV
chunk_gated_delta_rule_golden.pyCPU 侧算子 golden 实现
chunk_gated_delta_rule_main.pyCPU golden 与 NPU 结果精度对比及主调测逻辑
chunk_gated_delta_rule_benchmark.py优化版基准实现(stage1/stage2/stage3 分阶段)
chunk_gated_delta_rule_operator_single.py单用例入口:解包参数并断言精度结果
test_chunk_gated_delta_rule_single.py测试用例主程序:参数组合展开 +@pytest.mark.ci用例函数
test_chunk_gated_delta_rule_paramset.pysingle 模式入参配置
test_chunk_gated_delta_rule_paramset_rdv.pyRDV 测试入参配置

README 中还提到 pytest.ini 用于创建 ci 单算子标记与 graph 图模式标记,与源码中@pytest.mark.ci装饰器以及-m ci筛选参数相互对应。

五、运行模式与命令速查

所有模式均在pytest目录下通过test_run.sh启动。脚本内部统一以TEST_MODE环境变量区分模式,并透传USE_GRAPHSAVE_PTLOAD_PT等开关(见 test_run.sh L121-168)。

5.1 单用例调测(single)

  1. 手动编辑 test_chunk_gated_delta_rule_paramset.py,在ENABLED_PARAMS中启用需要的参数组(默认启用Testcase0Testcase1,即 B=1/seqlen=64 与 B=1/seqlen=16384 两个基础用例);
  2. 执行:
bash test_run.sh single

5.2 RDV 测试(rdv)

  1. 手动编辑 test_chunk_gated_delta_rule_paramset_rdv.py,ENABLED_PARAMS_RDV = GROUP_REDLINE + GROUP_STC默认启用全部 REDLINE(ARC-xxx,38 条)与 STC(ASC-xxx,34 条)用例;
  2. 执行:
bash test_run.sh rdv

RDV 参数集会自动经_expand扩展出-FP32(state 用 float32)与-NC(state 非连续)变体,单条 REDLINE/STC 用例会被拆成最多 3 条子用例。参数组内建议单组用例不超过 32 条,便于控制单次会话的时长与内存。

5.3 随机用例测试(random)

随机生成 N 条用例并执行(含 CPU golden 精度对比):

bash test_run.sh random 100

5.4 随机用例测试·仅 NPU(random_npu)

设置SKIP_GOLDEN=1跳过 CPU golden 计算与精度对比,仅执行 NPU 算子,可显著加快执行速度,适合快速回归:

bash test_run.sh random_npu 100

5.5 自定义单条用例(run)

除上述固定模式外,test_run.sh L171-274 还实现了run模式,支持两种方式指定单条用例:

方式一:指定 pt 文件加载执行(自动启用 load)

bash test_run.sh run --pt output/pt/xxx.pt

方式二:命令行直接指定 shape 参数生成执行

bash test_run.sh run --B 1 --seqlen 64 --nk 4 --nv 4 --dk 128 --dv 128 bash test_run.sh run --B 1 --seqlen 64,128 --nk 4 --nv 4 --dk 128 --dv 128 # 逗号分隔变长序列

run模式可用参数:--pt--B--seqlen(支持逗号分隔变长)、--nk--nv--dk--dv--chunk_size(默认 64)、--dtype(默认 bfloat16)、--state_dtype(默认 bfloat16)、--no_g(不使用门控 g)、--no_contig(state 非连续)。

5.6 可选标志

single / rdv / random / random_npu 四种模式均可追加以下标志:

标志作用对应环境变量
graph启用 aclgraph 图模式(torch.compile+ torchair 后端)USE_GRAPH=true
prof启用 msprof 性能采集,每用例跑 5 次算子并回填耗时ENABLE_PROF=true
save将生成的输入数据保存为.ptoutput/pt/下)SAVE_PT=true
loadoutput/pt/加载.pt数据执行LOAD_PT=true

示例:

bash test_run.sh single save # single 模式并保存输入 pt bash test_run.sh single load # single 模式从 pt 加载执行 bash test_run.sh run --B 1 --seqlen 64 --nk 4 --nv 4 --dk 128 --dv 128 save bash test_run.sh rdv graph # rdv 模式 + aclgraph

注意:saveload互斥,不可同时使用;save生成的文件名按input_B{B}_S{seqlen}_nk{nk}_nv{nv}_dk{dk}_dv{dv}_cs{chunk_size}_{dtype}_{state_dtype}_g{has_g}_contig{is_contiguous}.pt规则命名(见 chunk_gated_delta_rule_main.py L292-315),load时按同名规则自动查找。

六、随机用例生成规则深度解析

randomrandom_npu模式共用同一套随机参数生成器_generate_random_param_dict(见 test_chunk_gated_delta_rule_single.py L69-114),在算子约束内从 0 随机生成,不依赖 single / rdv 参数池。每条用例的入参生成规则如下:

接口入参随机规则约束/说明
Bchoice([1,2,4,8,16,32,64,128])batch size
seqlenchoice([1,3,7,32,64,100,128,200,256,300,512,1000,1024,2048,4096,5000,8192,10000,16384,32768,65535])序列长度;含非 chunk 对齐值(如 100、300、5000、65535)测试 partial chunk 路径
seqlen(变长)B>1 时 30% 概率生成 list,每个 batch 独立随机 seqlen覆盖 actual_seq_lengths 变长路径
nkrandint(1,64)key 头数
nvnk × randint(1,64//nk)Nv>=Nk 且 Nv%Nk==0
dkrandint(1,min(128,budget))key 维度,受 state 元素上限约束
dvrandint(1,min(128,budget//dk))value 维度,受 state 元素上限约束
chunk_size固定 64算子 tiling 硬编码,golden 须与 NPU 一致
data_type固定 bfloat16当前仅支持 BF16
state_data_typechoice([bfloat16,float32])状态数据类型
has_gchoice([True,False])50% 概率启用门控
is_contiguouschoice([True,False])50% 概率非连续
query_datarange固定 [-1,1]q 经 L2 归一化
key_datarange固定 [-1,1]k 经 L2 归一化
value_datarangechoice([-10,10], [-1,1])随机数据范围
gamma_datarangechoice([-1,0], [-0.5,0], [-0.1,0], [-1,-0.5])文档约束 [-1,0],g 经 exp 衰减
beta_datarange固定 [0,1]门控因子
state_datarange固定 [-10,10]初始状态范围

6.1 Shape 约束

B>0、seqlen>0、0<Nk<=64、0<Nv<=64 且 Nv>=Nk 且 Nv%Nk==0、0<Dk<=128、0<Dv<=128。

6.2 内存约束(防 OOM)

随机生成时通过两项元素上限共同防止单进程 OOM(对应源码中_STATE_ELEM_CAP = 2_000_000_000_QKV_ELEM_CAP = 1_000_000_000,见 test_chunk_gated_delta_rule_single.py L65-66):

  • Dk×Dv 受 state 元素数上限_STATE_ELEM_CAP=2.0B约束(budget = STATE_ELEM_CAP // (B × Nv));
  • T×max(Nk×Dk, Nv×Dv) 受 QKV 张量元素上限_QKV_ELEM_CAP=1.0B约束(max_seqlen = QKV_ELEM_CAP // (B × qkv_per_token))。

生成时先按 batch 与 head 数分配 Dk/Dv 预算,再按qkv_per_token = max(nk*dk, nv*dv)反推允许的最大 seqlen,并仅从合法 seqlen 池中选择不超过该上限的值,从而保证任何随机组合都不会超出单进程内存预算。

6.3 随机种子机制

  • RANDOM_SEED控制 shape/参数序列(一个 seed 对应一组确定的 N 条用例参数);
  • TORCH_SEED控制张量数值(每条用例独立,由 conftest 自动生成并记录进 CSV);
  • 不设RANDOM_SEED时自动生成并回写os.environ,conftest 落 CSV;
  • 复现:RANDOM_SEED=<seed> bash test_run.sh random N

在 conftest.py 的_set_random_seedfixture(L32-44)中,设置了TORCH_SEED则固定该种子,否则用torch.seed()自动生成;torch.manual_seedtorch.npu.manual_seed同步设置,保证 CPU 与 NPU 侧张量数值完全一致。

七、结果输出、CSV 字段与失败复现

所有模式执行后均输出到output/目录(已 gitignore):

  • run_<时间戳>.log:完整执行日志(tee 屏显);
  • result_<时间戳>.csv:逐用例结果表,每行一条用例。

CSV 写入由 conftest.py 的pytest_runtest_makereport(L53-104)与pytest_sessionfinish(L111-162)完成:每个用例执行完毕后收集参数与状态,会话结束时统一落盘,并打印total/passed/failed统计。字段说明如下:

说明
random_seed随机 shape 序列种子(random 模式;single/rdv 为固定参数集无此值)
seed本条用例张量数值种子(每条独立记录)
test_name用例名称
test_modesingle/rdv/random
check_typeprecision=带 golden 精度对比 / execution_only=仅 NPU 执行
model执行模式(torch 直调/aclgraph)
statuspytest 执行结果(PASSED/FAILED/SKIPPED)
B…is_continue本条用例全部入参
errmsg失败详情(截断 2000 字符)
durations算子耗时(仅 prof 模式)

失败用例复现:

# 整批复现(同 shape 序列):CSV 取 random_seed RANDOM_SEED=<random_seed> bash test_run.sh random N # 单条数值级复现(同 shape + 同张量数值):CSV 取入参与 seed TORCH_SEED=<tensor_seed> bash test_run.sh random 1

7.1 prof 模式与耗时回填

prof标志会触发 test_run.sh 的run_profile流程(L88-116):第一步正常跑一遍精度测试生成 CSV;第二步用msprof --summary-format=csv --export=on对全部用例做一次性能采集(每用例 1 次 warmup + 5 次计时);第三步由_backfill_durations(L28-86)从op_summary_*.csv中按OP Type == ChunkGatedDeltaRule提取Task Duration(us),丢弃每组前 1 条 warmup 数据,对其余 5 条取平均回填 CSV 的durations列。

八、精度对比原理(源码级)

8.1 多指标误差判定

精度对比实现于 chunk_gated_delta_rule_main.py 的compare_cv(L144-195),采用"实测误差 vs 高精度参考误差"的比率判定法:将 golden(FP32 复现)、benchmark(优化基准)与 NPU 结果两两对比,核心阈值定义在 L76-83:

  • CV_MAX_RE = 5:最大相对误差比率上限;
  • CV_AVER_RE = 1.5:平均相对误差比率上限;
  • CV_RMSE = 1.5:均方根误差比率上限;
  • CV_SMALL_VAL = 2:小值域错误占比上限;
  • CV_ERR_BALANCE = 2:误差均衡性上限;
  • MIN_ERR = 1e-3:相对误差分母保护值,避免除零。

其中"小值域错误占比"(get_smra,L121-133)统计 golden 绝对值小于2^-10的位置中误差超过1e-16的比例,专门捕捉小数值区间的精度退化;"误差均衡性"(get_eb,L136-141)则考察平均相对偏差的方向性。最终判定还需满足:若max_re_npu < 2^-7,即使比率超标也视为通过(绝对误差极小兜底)。输出(o)与状态(state)两组结果分别判定,任一失败即整条用例失败。

8.2 Golden 与基准实现

  • CPU goldenchunk_gated_delta_rule_npu(chunk_gated_delta_rule_golden.py L15-70)按 batch 遍历、依据cu_seqlens切分序列,调用逐 chunk 递归的chunk_gated_delta_rule_native复现算子语义,支持use_qk_l2norm_in_kerneloutput_final_state
  • 优化基准chunk_gated_delta_rule_benchmark.pychunk_gdn_benchmark_opt将算子拆为 stage1(chunk 内矩阵计算、门控累积衰减)、stage2(跨 chunk 状态递推)、stage3(输出计算)三阶段,并在注释中特别说明了 Vinner/Vprime 累加路径的精度对齐策略(v_inner_dtype与 state 数据类型保持一致)。

三路结果最终汇入run_chunk_gated_delta_rule_eager的对比环节(L604-622),失败时打印误差最大的元素索引及 golden/benchmark/NPU 三方数值,便于直接定位偏差来源。

九、环境变量汇总

变量作用适用模式
RANDOM_SEED固定随机 shape 序列种子(不设则自动生成并记 CSV)random/random_npu
TORCH_SEED固定张量数值种子(不设则每条自动生成并记 CSV)全部
RANDOM_CASE_COUNT随机用例条数(test_run.sh 已透传)random 系
SKIP_GOLDEN=1 跳过 CPU golden 与精度对比,仅 NPU 执行random_npu
CSV_FILE指定 CSV 输出路径(test_run.sh 已自动设置)全部
CSV_APPEND=1 时 CSV 追加写入全部
USE_GRAPH=true 启用 aclgraph 模式全部

除上表外,源码中还存在TEST_MODE(single/rdv/random,由 test_run.sh 注入)、ENABLE_PROFSAVE_PTLOAD_PTLOAD_PT_FILECUSTOM_CASE(run 模式注入)等内部环境变量,均被 chunk_gated_delta_rule_main.py L26-31 与 test_chunk_gated_delta_rule_single.py L37/L117-131 解析。

十、实战建议

  • 快速功能验证:用random_npu模式做大范围 shape 冒烟(无 golden 开销,速度最快);发现异常后再用random模式带精度对比复现;
  • 问题定位:CSV 中errmsg列已截断保留 2000 字符失败详情,配合RANDOM_SEED整批复现、TORCH_SEED单条数值级复现,可稳定回到失败现场;如需保存现场输入,用save标志落盘.pt后可用run --pt反复调试;
  • 性能观察prof标志结合 msprof 可直接在 CSVdurations列获得算子级耗时,无需另行写 profiling 脚本;
  • 环境约束:所有模式均要求 NPU 环境与 TorchNPU custom 包就绪,且 data_type 当前仅支持 BF16,随机生成的state_data_type仅限 bfloat16/float32 二选一。

【免费下载链接】ops-transformer本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-transformer

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询