| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix(bounding_box_encode): fix precision tolerance mapping(extreme mismatched ranges) & add validations in geir path and inferdatatype Co-authored-by: ugzhangyiyi<zhangyiyi4@huawei.com> # message auto-generated for no-merge-commit merge: !1260 merge bbe into master fix(bounding_box_encode): fix precision tolerance mapping(extreme mismatched ranges) & add validations in geir path and inferdatatype Created-by: ugzhangyiyi Commit-by: ugzhangyiyi Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> 本次提交修复了 BoundingBoxEncode kernel 在处理极端或失配坐标范围的边界框(例如 anchor 坐标接近 FP32 最大值 ~3.4e38、ground-truth 坐标 ~0.01)时的精度问题。该场景下 rw = gw / pw 会下溢趋近于零,触发 NPU 硬件 Ln 指令返回 -inf 而非有限负数值。 **根因:** NPU AscendC::Ln 硬件指令对极小正数输入(接近 FP32 下溢阈值 ~1e-38)返回 -inf,而 CPU numpy.log 与 GPU cuda::log 能正确返回有限值(如 log(1e-30) ≈ -69.07)。原始 kernel 在 FP16 和 FP32 两条计算路径中均直接消费 Ln 原始输出,当 rw/rh 下溢时,编码后的 dw/dh 变为 -inf,经 (dw - means) / stds 归一化后输出包含 -inf 或 NaN,导致与 CPU golden 的精度比对失败。 **修复方法 — 在 BoxDeltaCalc 中新增 FixLnResult + SoftLnPositive 兜底逻辑:** 1. FixLnResult(origInput, npuLnResult) —— 后处理守卫函数,同时检查原始输入和 NPU Ln 结果: - origInput 为 NaN → 返回 NaN(符合 IEEE 754) - origInput == 0.0 → 返回 -inf(符合 log(0)) - origInput < 0.0 → 返回 NaN(符合 log(负数)) - npuLnResult 为 NaN → 返回 NaN(传播硬件错误) - npuLnResult == -inf && origInput > 0.0 → 转入 SoftLnPositive 软件兜底(核心修复点) - 其余情况 → 原样返回 npuLnResult(正常路径,零开销) 2. SoftLnPositive(x) —— 针对 -inf 兜底场景的软件 ln 实现,采用 atanh 泰勒级数: - 将 x 归一化为尾数 m ∈ [1, 2) 和指数 e(通过反复乘/除 2 实现) - 计算 z = (m - 1) / (m + 1),再算 atanh(z) ≈ z * (1 + z²/3 + z⁴/5 + z⁶/7 + z⁸/9 + z¹⁰/11) - 返回 2 * atanh(z) + e * ln(2),其中 ln(2) = 0.69314718 3. ComputeFp16Path 和 ComputeFp32Path 同步更新:dw/dh 计算改为先从 buffer 读取原始 rw/rh,经 FixLnResult 处理后再做 (lnRw - means) / stds 归一化,替换原先直接消费 buf2.GetValue(base+2) 的方式。 **影响范围:** 正常值域(rw ∈ [0.5, 2.0])不受影响 —— FixLnResult 原样透传硬件 Ln 结果,行为零变化。该修复仅在硬件会产出 -inf 的退化输入场景下激活,使 NPU 输出与 CPU/GPU 行为对齐。 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> https://gitcode.com/cann/ops-cv/issues/734 ## 测试 <!--描述进行了哪些测试来验证你的改动。--> - **GEIR 静态测试**(test_geir_bounding_box_encode):FP32 (2,4) 单节点图编译 + NPU 执行 —— **PASS** - **GEIR 动态 Shape 测试**(test_geir_bounding_box_encode_dynamic):[-1,-1] 5 种 shape + [-2](unknown rank)5 种 shape —— **10/10 PASS** - **GEIR 负向拦截测试**(test_geir_intercept):14 例矩阵(合法/非法 dtype、shape、rank、means/stds 长度、stds=0)—— **13/14 PASS**(1 例结构性不可拦截:dtype 不一致被内置 proto V1 InferShape 屏蔽 + FE 自动插 Cast) - **NPU Ln 行为验证**:确认 FixLnResult 正确将 rw=1e-30 路由至 SoftLnPositive,产出 ≈ -69.07 与 CPU numpy.log(1e-30) 一致;正常 rw=1.07 原样透传硬件 Ln,误差 ≤ 3.3e-7 ## 类型标签 <!-- [x] 表示选中 --> - [x] Bug修复 - [ ] 新特性 - [ ] 性能优化 - [ ] 文档更新 - [ ] 其他,请描述: See merge request: cann/ops-cv!1260 | 6 天前 | |
feat: support BoundingboxEncode ascend950 Co-authored-by: ugzhangyiyi<zhangyiyi4@huawei.com> # message auto-generated for no-merge-commit merge: !1049 merge master into master feat: support BoundingboxEncode ascend950 Created-by: ugzhangyiyi Commit-by: ugzhangyiyi Merged-by: cann-robot Description: ## 描述 本 MR 支持 bounding_box_encode 算子,适配 Ascend 950(arch35)平台。 ### 算子功能 计算锚框(anchor box)与真实边界框(ground truth box)之间的编码偏移量,生成目标检测回归目标。计算公式(含 +1 偏移,与 canndev 内置定义一致): pw = px2 - px1 + 1, ph = py2 - py1 + 1 pcx = (px1 + px2) * 0.5, pcy = (py1 + py2) * 0.5 dx = (gcx - pcx) / pw, dy = (gcy - pcy) / ph dw = ln(gw / pw), dh = ln(gh / ph) delta_i = (raw_i - means_i) / stds_i, i ∈ {x, y, w, h} ### 代码结构(commit dabe4550) | 层级 | 文件 | 说明 | |------|------|------| | **op_graph** | bounding_box_encode_proto.h | IR 原型定义:2 INPUT(anchor_box, ground_truth_box) + 2 ATTR(means/stds ListFloat) + 1 OUTPUT(delats),支持 FP16/FP32/BF16,与 canndev nn_detect_ops.h 内置定义保持一致 | | **op_host** | bounding_box_encode_def.cpp | OpDef 注册:Input/Output/Attr 声明,AICore 配置 ascend950,DynamicCompileStatic + DynamicRank + DynamicShape | | | bounding_box_encode_infershape.cpp | InferShape:输出 shape = 输入 shape(anchor_box shape 透传) | | | arch35/bounding_box_encode_tiling_arch35.cpp | Tiling 函数:从 attrs->GetListFloat(0/1) 读取 means/stds 属性,计算 invStds 写入 TilingData;UB 容量感知的 ubFactor 计算 + MAX_DATACOPY_BLOCKLEN(65535) 双重约束防 blockLen 截断 | | **op_kernel** | arch35/bounding_box_encode.h | Kernel 实现:FP16/BF16 输入 Cast→FP32 中间计算→Cast 回原 dtype;Scalar-Vector 交叉流水(S_V/V_S 同步 + FetchEventID);CopyIn/Compute/CopyOut 三级流水 + UB 分块循环 | | | arch35/bounding_box_encode_tiling_data.h | TilingData 结构:dim0/blockFactor/ubFactor + means0-3/invStds0-3(8 个 float) | | | bounding_box_encode_apt.cpp | Kernel 入口:2 input(anchorBox, groundTruthBox) + 1 output(delats),REGISTER_TILING_DEFAULT + GET_TILING_DATA_WITH_STRUCT | | **examples** | test_geir_bounding_box_encode.cpp | GEIR 通路示例:SetAttr("means"/"stds") 设置属性 | | **CMakeLists** | CMakeLists.txt | 算子构建配置:SUPPORT_COMPUTE_UNIT=ascend950, TILING_DIR=arch35 | | **docs** | README.md | 算子说明:功能/支持产品/数据类型/参数/约束 | | | docs/zh/op_list.md | 仓级算子清单条目 | ### 接口定义(与 canndev 一致) cpp // IR 原型(与 canndev nn_detect_ops.h 一致) REG_OP(BoundingBoxEncode) .INPUT(anchor_box, TensorType({DT_FLOAT16, DT_FLOAT})) .INPUT(ground_truth_box, TensorType({DT_FLOAT16, DT_FLOAT})) .OUTPUT(delats, TensorType({DT_FLOAT16, DT_FLOAT})) .ATTR(means, ListFloat, {0.0, 0.0, 0.0, 0.0}) .ATTR(stds, ListFloat, {1.0, 1.0, 1.0, 1.0}) .OP_END_FACTORY_REG(BoundingBoxEncode) ### 关键设计决策 1. **means/stds 使用 ATTR 而非 INPUT**:与 canndev 内置定义保持一致,确保 GEIR 图模式通路兼容(避免 IR 兼容性检查冲突) 2. **DataCopyExtParams**:Kernel 使用 uint32_t blockLen 的 DataCopyExtParams,配合 tiling 侧 MAX_DATACOPY_BLOCKLEN 约束,防止大 UB 场景下 blockLen 截断 3. **+1 偏移**:pw = px2 - px1 + 1,与 canndev tbe 实现一致,保证宽高至少为 1 ## 关联的Issue https://gitcode.com/cann/ops-cv/issues/583 ## 测试 - 冒烟: 23091 - **UT 编译验证**:bash build.sh -u --ops=bounding_box_encode --soc=ascend950 --noexec,全部 target 编译通过(cv_op_host_ut / cv_op_api_ut / cv_op_kernel_ut) - tiling UT:5 例(fp32/fp16/empty/n1) - infershape UT:4 例(fp32/fp16/empty) - aclnn UT:4 例(nullptr/dtype/shape/mismatch 参数校验) - kernel UT:3 例(golden 计算:默认参数/非零参数/退化框) - **TTK 精度验证**:44/44 用例全部通过(fp16/fp32 × 多种 shape),通过率 100% - **GEIR 图模式验证**:test_geir_bounding_box_encode.cpp 执行 Session run ir compute graph success + Precision is ok ## 文档更新 - 新增 objdetect/bounding_box_encode/README.md:算子说明文档 - 更新 docs/zh/op_list.md:添加 bounding_box_encode 条目 ## 类型标签 - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [x] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: ## 重点说明 为了对齐原cann版本tbe接口,**其拼写错误**delats不进行修复,保持与原版一致。 See merge request: cann/ops-cv!1049 | 1 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 6 天前 | ||
| 1 个月前 |