ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

BlendFaceBgPartTwo 算子深度解析:基于 CANN ops-cv 的 Alpha 人脸背景融合实现与图模式调用

2026/9/18 13:30:23 拓冰建站 浏览量
BlendFaceBgPartTwo 算子深度解析:基于 CANN ops-cv 的 Alpha 人脸背景融合实现与图模式调用 BlendFaceBgPartTwo 算子深度解析基于 CANN ops-cv 的 Alpha 人脸背景融合实现与图模式调用【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv本指南以 image/blend_face_bg_part_two/README.md 为骨架结合算子仓库中的 OpDef、InferShape、Graph Verify、Tiling、Kernel 与单元测试源码完整讲解 BlendFaceBgPartTwo 算子的功能语义、计算公式、参数约束、底层实现原理与图模式调用方式。读完本文你将掌握该算子在 NPU 上完成累积人脸归一化 Alpha 混合背景的完整数据流并能够基于仓库示例在 Atlas 产品上跑通 GEIR 图模式调用。BlendFaceBgPartTwo 是 CANN ops-cv 图像算子库中BlendFaceBg 流程的第二部分它接收流程第一部分产出的累积人脸图像acc_face、累积掩码acc_mask、最大掩码max_mask配合原始背景图bg_img输出一张将归一化人脸按 Alpha 权重混合进背景的融合图像fused_img。该算子为逐元素Element-Wise计算输入输出 shape 完全一致支持静态 shape 与动态 shape覆盖 float32 / uint8 两种背景图输入类型。产品支持情况BlendFaceBgPartTwo 算子的 NPU 适配情况如下表所示与 README 一致产品是否支持Ascend 950PR / Ascend 950DT√Atlas A3 训练系列产品 / Atlas A3 推理系列产品√Atlas A2 训练系列产品 / Atlas A2 推理系列产品√Atlas 200I/500 A2 推理产品×Atlas 推理系列产品√Atlas 训练系列产品√其中 Ascend 950 产品线对应算子仓库中的arch35 架构实现OpDef 中通过this-AICore().AddConfig(ascend950, aiCoreConfig)注册 AICore 配置见 op_host/blend_face_bg_part_two_def.cppKernel、Tiling 均位于op_kernel/arch35与op_host/arch35目录。功能说明与计算公式算子功能该算子将 BlendFaceBg 流程第一部分累积得到的人脸统计结果与背景图像进行Alpha 混合归一化合成对累积人脸acc_face按累积掩码acc_mask做归一化得到平均后的融合人脸以max_mask作为 Alpha 权重在融合人脸与背景图bg_img之间做线性插值blend输出与输入 shape 完全相同的融合图像fused_img。从源码注释可以确认其语义Alpha-blend normalized accumulated face with background image (part two of the BlendFaceBg pipeline)见 op_graph/blend_face_bg_part_two_proto.h。计算公式给定累积人脸图像acc_face、累积掩码acc_mask、最大掩码max_mask和背景图像bg_img按以下三步计算融合图像人脸归一化累积和转为均值$$ fusion_face \frac{acc_face}{acc_mask \epsilon} $$背景权重Alpha 互补权重$$ bg_weight 1 - max_mask $$Alpha 混合合成$$ fused_img fusion_face \times max_mask bg_img \times bg_weight $$其中各符号含义如下符号含义说明acc_face累积的人脸图像来自 BlendFaceBg 流程第一部分shape (H,W,C)acc_mask累积掩码归一化分母shape (H,W,C)max_mask最大掩码Alpha 混合权重取值范围 [0,1]shape (H,W,C)bg_img背景图像支持 float32 或 uint8uint8 会在算子内部转为 float32 计算epsilon防除零小量默认值 1e-12fused_img融合图像输出shape 与 acc_face 相同dtype 固定 float32该公式在仓库中有两处相互印证的实现Kernel 侧 VF 寄存器计算链见下文Kernel 实现小节与 CPU golden 脚本 tests/assets/golden.pytorch CPU 实现fused (acc_face/(acc_maskeps))*max_mask bg_img*(1-max_mask)。参数说明算子的输入、属性与输出定义如下与 README 参数表一致并补充源码级细节参数名输入/输出/属性描述数据类型数据格式acc_face输入累积人脸图像来自 BlendFaceBg 流程第一部分shape 为 (H,W,C)FLOATNDacc_mask输入累积掩码用于归一化分母shape 为 (H,W,C)FLOATNDmax_mask输入最大掩码作为 Alpha 混合权重取值范围 [0,1]shape 为 (H,W,C)FLOATNDbg_img输入背景图像shape 为 (H,W,C)。当类型为 uint8 时算子内部会转换为 float32 进行计算UINT8、FLOATNDepsilon属性防除零小量应用于 acc_mask。默认值为 1e-12FLOAT标量fused_img输出Alpha 混合后的融合图像shape 与 acc_face 相同。数据类型固定为 FLOATFLOATND参数背后的实现细节输入输出 dtype 组合由双 TilingKey 表达。在 OpDef 定义中四个输入与一个输出按并行组合数组声明了 2 个 dtype 组合见 op_host/blend_face_bg_part_two_def.cpp组合 0KEY_FP32acc_face/acc_mask/max_mask float32bg_img float32fused_img float32Kernel 走直接计算路径组合 1KEY_UINT8acc_face/acc_mask/max_mask float32bg_img uint8fused_img float32Kernel 在内部完成 uint8→half→float 两级无损 Cast 后计算。epsilon属性在 OpDef 中注册为Attr(epsilon).AttrType(OPTIONAL).Float(1e-12f)其默认值 1e-12 在 protoblend_face_bg_part_two_proto.h、TilingDEFAULT_EPSILON、Kernel 成员初值kDefaultEpsilon三处保持一致。约束说明使用该算子必须满足以下约束README 约束说明 源码校验逻辑所有输入张量的 shape 必须相同且 rank 必须为 3H,W,C。Tiling 仅按 acc_face 尺寸切分并为全部 GM 设置搬运长度shape 不一致会导致 Kernel 越界读。acc_face、acc_mask、max_mask 的数据类型必须为 FLOAT。bg_img 的数据类型可以是 FLOAT 或 UINT8。输出 fused_img 的数据类型固定为 FLOAT。不接受空 tensor任意维度为 0 的空张量会被算子拒绝源码校验中显式拦截。epsilon 必须 0图编译 VerifyFunc 与 Host Tiling 均校验属性值域。这些约束在源码中由三道防线逐层落实图编译期 VerifyFuncop_graph/blend_face_bg_part_two_graph_infer.cpp校验 dtype、rank3、空 tensor、四输入 shape 逐维一致、epsilon0早于 InferShape 与 Tiling 执行InferShapeop_host/blend_face_bg_part_two_infershape.cpp输出 shape 直接取 acc_face shapeOneInOneOut无广播并再次校验 rank3 与四输入 shape 一致性unknown rank动态 shape场景透传跳过校验Host Tilingop_host/arch35/blend_face_bg_part_two_tiling_arch35.cpp作为算子侧最后防线使用GetOriginShape()用户建图时的原始 shape重新校验 dtype、rank、空 tensor 与 shape 一致性防止框架将 storage shape 归一化后绕过校验。调用说明图模式调用GEIRREADME 提供的调用方式为图模式GEIR示例代码位于 examples/arch35/test_geir_blend_face_bg_part_two.cpp固定 shape。该示例完整演示了在 CANN GE 图引擎上构造单节点图并运行的流程核心步骤可拆解为1. 构造 GE 算子并设置属性auto op1 op::BlendFaceBgPartTwo(BlendFaceBgPartTwo); op1.SetAttr(epsilon, 1e-12f);2. 为四个输入分别创建 Data 节点并绑定算子输入四个输入 share 同一个 (H, W, C) shape示例中使用{4, 4, 3}dtype 均为 float32。示例代码为每个输入生成确定性的宿主端数据acc_face循环取值 0.5/0.8/1.1/1.4base0.5, step0.3acc_mask循环取值 1.0/1.5/2.0/2.5base1.0, step0.5严格为正保证分母远离 0max_mask循环取值 0.0/0.25/0.5/0.75Alpha 权重值域 [0,1]bg_img循环取值 10/30/50/70base10.0, step20.0。以 acc_face 为例的绑定代码auto dataAccFace op::Data(acc_face).set_attr_index(0); dataAccFace.update_input_desc_x(accFaceDesc); dataAccFace.update_output_desc_y(accFaceDesc); graph.AddOp(dataAccFace); op1.set_input_acc_face(dataAccFace); op1.update_input_desc_acc_face(accFaceDesc); feeds.push_back(accFaceTensor); inputs.push_back(dataAccFace);其余三个输入acc_mask、max_mask、bg_img按 data index 1/2/3 依样绑定输出fused_img通过op1.update_output_desc_fused_img(fusedDesc)声明dtype 与 shape 均与 acc_face 一致。3. 初始化 GE 并运行图std::mapAscendString, AscendString global_options { {ge.exec.deviceId, 0}, {ge.graphRunMode, 1}, {ge.jit_compile, 0}}; Status ret ge::GEInitialize(global_options);随后依次完成Session创建、AddGraph、RunGraph最终校验输出 tensor 的 shape/dtype 并打印示例 shape 为[4,4,3]shapeSize48dtypeDT_FLOAT。示例还演示了工程要点Data 缓冲区必须在 RunGraph 完成前保持存活注释明确 caller must keep buffer alive until RunGraph completes避免 use-after-free以及 GEInitialize 成功后的早退路径必须成对调用 GEFinalize。关于单算子aclnn调用README 的调用说明表格仅给出图模式入口。从源码结构看算子仓库以 GEIR 图模式为官方验证路径图编译期的 VerifyFunc、InferShape、InferDataType 与 Host Tiling 均围绕图模式搭建InferShape 注释明确指出图模式下自定义 InferShape 是 shape 一致性校验的唯一防线aclnn L2 的 CheckShape 在图模式会被绕过。若需单算子调用可参考仓库内其他算子的 aclnn 封装模式但 BlendFaceBgPartTwo 当前仓库内未提供对应的 aclnn 接口头文件。深入内核从公式到 NPU 指令的实现映射Kernel 入口与模板分发Kernel 入口函数通过模板参数BUFFER_MODE与宏DTYPE_BG_IMG在编译期确定执行路径见 op_kernel/blend_face_bg_part_two.cpptemplate int BUFFER_MODE __global__ __aicore__ void blend_face_bg_part_two(GM_ADDR acc_face, GM_ADDR acc_mask, GM_ADDR max_mask, GM_ADDR bg_img, GM_ADDR fused_img, GM_ADDR workspace, GM_ADDR tiling) { REGISTER_TILING_DEFAULT(BlendFaceBgPartTwoTilingData); GET_TILING_DATA_WITH_STRUCT(BlendFaceBgPartTwoTilingData, tilingData, tiling); NsBlendFaceBgPartTwo::BlendFaceBgPartTwoDTYPE_BG_IMG, BUFFER_MODE op; op.Init(acc_face, acc_mask, max_mask, bg_img, fused_img, tilingData); op.Process(); (void)workspace; }BG_T模板参数float / uint8_t由 TilingKey 注入BUFFER_MODE决定单缓冲1或双缓冲2流水。Kernel 类结构与 UB 三级流水Kernel 类BlendFaceBgPartTwoBG_T, BUFFER_MODE见 op_kernel/arch35/blend_face_bg_part_two.h按 AscendC RegBase 标准骨架实现CopyIn → Compute → CopyOut三级流水CopyIn对四路输入分别使用DataCopyPad从 GM 搬运到 UB。fp32 输入与 bg 输入使用独立的DataCopyExtParamsbg 按sizeof(BG_T)计算字节长度uint8 时仅为 fp32 的 1/4边界用 0 填充Computeasc_vf_callBlendVFBG_T拉起__simd_vf__向量函数在寄存器级完成全部计算链CopyOut将融合结果DataCopyPad写回 GM 的 fused_img。Process()按 TilingData 给出的循环次数逐块执行每个 block 的最后一次循环处理尾部元素tailNum_首/尾 block 使用不同的循环次数与尾部大小ubLoopOfFormerBlockvsubLoopOfTailBlock以兼容 512 元素对齐的多核切分。VF 寄存器计算链公式的指令级实现核心计算在BlendVF向量函数中逐 repeat 完成见 op_kernel/arch35/blend_face_bg_part_two.h与数学公式一一对应步骤数学公式指令实现①denom acc_mask εAdds(denomReg, accMaskReg, epsilon, mask)②fusion_face acc_face / denomDiv(fusionReg, accFaceReg, denomReg, mask)③bg_weight 1 − max_maskMuls(-1)Adds(1)两步完成④t1 fusion_face × max_maskMul(t1Reg, fusionReg, maxMaskReg, mask)⑤t2 bg × bg_weightMul(t2Reg, bgF32Reg, bgWeightReg, mask)⑥fused t1 t2Add(fusedReg, t1Reg, t2Reg, mask)bg_img 的两种载入路径通过if constexpr (std::is_same_vBG_T, uint8_t)编译期分支KEY_FP32 直算路径LoadAlign(bgF32Reg, bgAddr off)直接载入 fp32无 CastKEY_UINT8 路径先用LoadAlignuint8_t, DIST_UNPACK4_B8按 1B→4B lane 解包载入再做uint8 → half → float 两级无损扩位 CastkCastTraitU8ToHalf/kCastTraitHalfToF32。注释说明 fp16 尾数 10 位可精确表示 0–2552^11 256因此该两级 Cast 位精确无损。多核切分与双缓冲Host Tilingop_host/arch35/blend_face_bg_part_two_tiling_arch35.cpp完成如下切分决策多核切分以展平元素数dim0 H*W*C为基础按coreNum CeilDiv(dim0 * minDtypeBits, 32768)估算核数每核至少 4KB再与实际 VectorCore 核数取小每个 block 的元素数blockFormer按512 元素对齐UB 切分按每元素 UB 占用字节数bufferDivisor计算单次 UB 循环容量ubFormer并按256B 对齐。bufferDivisor依 bg 类型取值KEY_FP32 为 40双缓冲 × 5 路 fp32KEY_UINT8 为 34双缓冲 × (3×fp32 uint8 fp32)TilingKey 下发通过ASCENDC_TPL_SEL_PARAM(context, useDoubleBuffer)在数据量足够时启用双缓冲平台信息核数、UB 大小通过context-GetPlatformInfo()运行时获取禁止硬编码同时声明 0 字节 workspace slot 以满足框架依赖。TilingData 结构op_kernel/arch35/blend_face_bg_part_two_tiling_data.h完整记录了dim0、coreNum、blockFormer、blockNum、ubFormer及首/尾 block 的 UB 循环次数与尾部大小Kernel 侧据此完成无越界的遍历。测试与正确性验证算子在仓库内配套了三类测试见 tests/ut1. Kernel 级 CPU 仿真测试tests/ut/op_kernel/test_blend_face_bg_part_two.cpptest_float_case_4x4x3四输入全 float32 的 KEY_FP32 路径shape 4×4×3epsilon1e-12test_uint8_bg_case_8x8x3bg_img 为 uint8 的 KEY_UINT8 路径shape 8×8×3。测试通过Tiling4BlendFaceBgPartTwoCompileInfo {48, 196608, true}coreNum48、ubSize196608、regBasetrue构造 Tiling 上下文执行 Tiling 后以ICPU_RUN_KF在 CPU 上仿真运行 Kernel覆盖了两种 dtype 组合。2. CPU golden 脚本tests/assets/golden.py使用 torch CPU 计算参考结果公式与算子完全一致fusion af / (am epsilon)、bg_weight 1.0 - mm、fused fusion * mm bg * bg_weight。当 bg_img 非 float32 时先转 float32 再参与计算与算子内部行为一致可作为 Kernel 结果比对的标准答案。3. Host 侧单测tests/ut/op_host包含test_blend_face_bg_part_two_infershape.cppInferShape 行为验证与test_blend_face_bg_part_two_tiling.cppTiling 切分正确性验证。工程结构速览BlendFaceBgPartTwo 在仓库中的完整工程结构如下便于读者按图索骥image/blend_face_bg_part_two/ ├── README.md # 官方算子说明文档 ├── examples/arch35/ │ └── test_geir_blend_face_bg_part_two.cpp # GEIR 图模式调用示例固定 shape ├── op_graph/ │ ├── blend_face_bg_part_two_proto.h # GEIR 算子原型定义REG_OP │ ├── blend_face_bg_part_two_graph_infer.cpp # 图编译期 VerifyFunc InferDataType │ └── fusion_pass/ # 图融合 pass 相关目录 ├── op_host/ │ ├── blend_face_bg_part_two_def.cpp # OpDef 定义双 TilingKey dtype 组合 │ ├── blend_face_bg_part_two_infershape.cpp # InferShape 实现 │ └── arch35/ │ └── blend_face_bg_part_two_tiling_arch35.cpp # Host Tiling多核 UB 切分 ├── op_kernel/ │ ├── blend_face_bg_part_two.cpp # Kernel 入口模板分发 │ └── arch35/ │ ├── blend_face_bg_part_two.h # Kernel 类 VF 计算链 │ ├── blend_face_bg_part_two_tiling_data.h # TilingData 结构 │ └── blend_face_bg_part_two_tiling_key.h # TilingKey 定义 └── tests/ ├── assets/golden.py # torch CPU golden 参考实现 └── ut/ # kernel / op_host 两级单测总结BlendFaceBgPartTwo 是 BlendFaceBg 流程中完成归一化 合成的关键算子数学上通过acc_face/(acc_maskε)将累积人脸归一化为均值再以max_mask为 Alpha 权重与背景做线性混合。工程实现上它展示了 CANN 自定义算子的完整开发范式——GEIR proto 定义、OpDef 双 dtype 组合、图编译期 VerifyFunc、InferShape、运行时 Tiling 多核/UB 切分、RegBase 寄存器级 VF 计算链以及 CPU golden 仿真测试的闭环验证。对于需要在 NPU 上实现类似统计归一化 图像合成场景的开发者该算子从公式、约束到源码实现提供了完整可参照的模板。【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考