尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CANN ops-cv ResizeBicubicV2Grad 算子深度解析:双三次插值反向传播的原理、接口与源码实现

CANN ops-cv ResizeBicubicV2Grad 算子深度解析:双三次插值反向传播的原理、接口与源码实现 CANN ops-cv ResizeBicubicV2Grad 算子深度解析双三次插值反向传播的原理、接口与源码实现【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv导读ResizeBicubicV2Grad 是 CANN ops-cv 算子库中图像缩放类算子的反向传播实现用于计算双三次Bicubic插值调整图像在反向传播过程中的输入梯度是训练场景中ResizeBicubicV2前向算子不可或缺的配套算子。本文以 image/resize_bicubic_v2_grad/README.md 为骨架结合算子原型、Host 侧算子定义、Shape 推导、Tiling 策略、Kernel 多分支实现与单测用例完整讲解该算子的数学原理、参数语义、aclnn 两段式调用方式与图模式构图方式帮助你快速完成集成与二次开发。功能说明与数学原理算子定位ResizeBicubicV2Grad 计算输入图像在双三次插值基础下的梯度。用一句话概括输入是正向插值后的梯度图输出是插值前的原始图像的梯度。对应关系为grads正向双三次插值调整后的图对应公式中的 Y即反向传播中来自上游的梯度。original_image原图像前向算子的输入。y正向 Resize 的输入梯度即本算子的输出。从算子原型注释image/resize_bicubic_v2_grad/op_graph/resize_bicubic_v2_grad_proto.h可见其与 PyTorch 的upsample_bicubic2d_backward算子兼容属于第三框架兼容算子。双三次插值核函数双三次插值使用 4×4 邻域像素加权求和得到目标像素值其权重核 W(x) 定义如下$$ W(x) \begin{cases} (a 2)|x|^3 - (a 3)|x|^2 1 \text{for } |x|≤1 \ a|x|^3 -5a|x|^2 8a|x| - 4a \text{for } 1|x|2 \ 0 \text{otherwise} \ \end{cases} $$其中系数a -0.75对应 PyTorch 双三次插值的默认a取值。核函数仅在距离小于 2 的范围内非零这是后续 Kernel 实现中每个输出像素只需累加 4×4 邻域贡献的数学依据。梯度传播公式对于原始图像中的像素 (i, j)其梯度由所有参与插值的目标像素 (i, j) 的梯度按权重累加得到$$ \frac{\partial L}{\partial X_{i,j}} \sum_{i} \sum_{j} \frac{\partial L}{\partial Y_{i,j}} \times W(i - i) \times W(j - j) $$即上游梯度grads中的每个像素 (i, j)按其在 H 轴与 W 轴上的核权重 W 反向摊回原始图像对应位置H 轴权重与 W 轴权重相乘即为该目标像素对原始像素的贡献。这与 aclnn 接口文档image/upsample_bicubic2d_grad/docs/aclnnUpsampleBicubic2dBackward.md中描述的正向插值公式互为对偶。坐标映射与 align_corners梯度计算中源坐标与目标坐标的映射关系由align_corners属性决定坐标缩放因子 scaleH / scaleW 的计算方式为$$ scaleH \begin{cases} (inputSize[2]-1) / (outputSize[0]-1) alignCornerstrue \ 1 / scalesH alignCornersfalsescalesH0\ inputSize[2] / outputSize[0] otherwise \end{cases} $$W 轴同理。其中align_cornerstrue表示输入输出张量的角像素点对齐保留角像素值false表示使用半像素中心进行插值。产品支持情况当前仓库中 ResizeBicubicV2Grad 算子的产品支持矩阵如下以 README 为准产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3 训练系列产品/Atlas A3 推理系列产品×Atlas A2 训练系列产品/Atlas A2 推理系列产品×从算子定义image/resize_bicubic_v2_grad/op_host/resize_bicubic_v2_grad_def.cpp中可以印证AICore().AddConfig(ascend950, aicoreConfig)仅为 ascend950 平台注册了 AI Core 配置op_host/config/ascend950/ 目录下的编译配置文件也仅针对该平台存在。需要注意本仓库内 ResizeBicubicV2Grad 与 aclnnUpsampleBicubic2dBackward 接口的支持范围并不完全一致后者在 Atlas A2/A3、Atlas 训练系列等产品上也支持集成时请以目标平台实际可用的接口为准。参数说明输入与输出参数名输入/输出/属性描述数据类型数据格式grads输入正向双三次插值调整后的图对应公式 Y。FLOAT16、FLOAT32、BFLOAT16NCHW、NHWCoriginal_image输入原图像的高和宽。FLOAT16、FLOAT32、BFLOAT16NCHW、NHWCy输出正向 Resize 的输入梯度。FLOAT16、FLOAT32、BFLOAT16NCHW、NHWC属性参数README 未单列属性但算子原型resize_bicubic_v2_grad_proto.h与算子定义resize_bicubic_v2_grad_def.cpp明确声明了两个可选属性属性名类型默认值说明align_cornersBoolfalse为 true 时输入与输出张量的 4 个角像素中心对齐保留角像素值为 false 时使用半像素中心计算插值。scalesListFloat2 个元素{0.0f, 0.0f}第一个元素表示 grads 中像素 H 轴下标与 y 中像素 H 轴下标的比值第二个元素对应 W 轴。仅在 align_corners 为 true 且取值大于 0 时生效否则按输入输出尺寸比值计算缩放。关键约束源码级确认输入grads、original_image与输出y均为 4D 张量数据格式仅支持 NCHW、NHWC。original_image的 N、C 维度必须与grads一致输出y的 shape、format、dtype 与original_image保持一致。约束说明为“无”但结合 resize_bicubic_v2_grad_infershape.cpp 的校验逻辑运行期仍会强校验grads格式必须为 NCHW/NHWCoriginal_image必须为 4D且其 H、W 维按格式区分索引NCHW 下 hIdx2NHWC 下 hIdx1取值必须大于 0否则返回GRAPH_FAILED。调用说明README 提供了两种调用方式调用方式样例代码说明aclnn 接口test_aclnn_resize_bicubic_v2_grad.cpp通过 aclnnUpsampleBicubic2dBackward 接口方式调用 ResizeBicubicV2Grad 算子。图模式resize_bicubic_v2_grad_proto.h通过算子 IR 构图方式调用 ResizeBicubicV2Grad 算子。aclnn 接口两段式调用aclnn 接口遵循 CANN 统一的两段式调用范式详见 docs/zh/context/two_phase_api.md先调用GetWorkspaceSize接口完成入参校验并计算所需 workspace 大小再调用执行接口真正下发计算。接口原型如下aclnnStatus aclnnUpsampleBicubic2dBackwardGetWorkspaceSize( const aclTensor* gradOut, const aclIntArray* outputSize, const aclIntArray* inputSize, const bool alignCorners, double scalesH, double scalesW, aclTensor* gradInput, uint64_t* workspaceSize, aclOpExecutor** executor) aclnnStatus aclnnUpsampleBicubic2dBackward( void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream)各参数语义参数名输入/输出描述使用说明gradOut输入反向计算的梯度 Tensor对应公式中的gradOut即算子输入grads。不支持空 Tensor数据类型与gradInput一致ND 格式默认按 NCHW 处理。outputSize输入gradOut在 H、W 维度上的空间大小。size 为 2各元素大于 0。inputSize输入输出gradInput在 N、C、H、W或 N、H、W、C维度上的空间大小。size 为 4各元素大于 0。alignCorners输入是否对齐角像素点。true 对齐角像素false 不对齐。scalesH / scalesW输入输出gradInput的 height / width 维度乘数。对应公式中的scalesH、scalesW。gradInput输出反向计算的输出张量即算子输出y。数据类型、格式与gradOut一致N、C 轴与gradOut一致。workspaceSize输出需要在 Device 侧申请的 workspace 大小。由第一段接口计算返回。executor输出op 执行器封装了算子计算流程。由第一段接口返回供第二段接口使用。第一段接口的常见返回码ACLNN_ERR_PARAM_NULLPTR错误码 161001入参空指针与ACLNN_ERR_PARAM_INVALID错误码 161002覆盖数据类型/格式越界、维度不为 4、outputSize 长度不为 2、元素小于 1、N/C 轴不一致等十余种入参校验场景完整返回码说明见 docs/zh/context/aclnn_return_code.md。完整可运行示例仓库提供了完整可编译的示例 image/resize_bicubic_v2_grad/examples/test_aclnn_resize_bicubic_v2_grad.cpp其调用流程可归纳为 7 步环境初始化aclInit→aclrtSetDevice→aclrtCreateStream。构造 Tensor将 host 数据{1, 2, 3, 4.1}shape{1,1,2,2}对应 2×2 的梯度图经aclrtMallocaclrtMemcpy拷贝到 device 侧并用aclCreateTensor创建grads对应的selfTensor输出outshape 为{1,1,3,3}。构造尺寸参数outputSize {2, 2}、inputSize {1, 1, 3, 3}分别通过aclCreateIntArray创建。两段式调用先调aclnnUpsampleBicubic2dBackwardGetWorkspaceSize(self, outputSize, inputSize, /*alignCorners*/1, /*scalesH*/1.1, /*scalesW*/1.1, out, workspaceSize, executor)按返回值申请 workspace再调aclnnUpsampleBicubic2dBackward(workspaceAddr, workspaceSize, executor, stream)。同步等待aclrtSynchronizeStream(stream)确保计算完成。结果回拷aclrtMemcpy将 device 侧结果拷回 host 并逐元素打印。资源释放aclDestroyTensor、aclDestroyIntArray、aclrtFree、aclrtDestroyStream、aclrtResetDevice、aclFinalize。编译与运行方式可参考 docs/zh/context/compile_and_run_sample.md需引入aclnnop/aclnn_upsample_bicubic_2d_backward.h头文件。图模式构图图模式通过算子 IR 构图直接引用REG_OP(ResizeBicubicV2Grad)注册的原型resize_bicubic_v2_grad_proto.h。其 IR 定义要点REG_OP(ResizeBicubicV2Grad) .INPUT(grads, TensorType({DT_FLOAT16, DT_FLOAT, DT_BF16})) .INPUT(original_image, TensorType({DT_FLOAT16, DT_FLOAT, DT_BF16})) .OUTPUT(y, TensorType({DT_FLOAT16, DT_FLOAT, DT_BF16})) .ATTR(align_corners, Bool, false) .ATTR(scales, ListFloat, {0.0f, 0.0f}) .OP_END_FACTORY_REG(ResizeBicubicV2Grad)源码级实现剖析算子定义与 Shape/Dtype 推导算子定义resize_bicubic_v2_grad_def.cpp声明两个必选输入grads、original_image与一个必选输出y数据类型覆盖DT_FLOAT16 / DT_FLOAT / DT_BF16格式覆盖NCHW / NHWC同时开启动态编译、动态 Rank 与动态 Shape 支持。Shape 推导resize_bicubic_v2_grad_infershape.cpp输出y的 shape 直接继承original_image对于未知 Rank 的输入则设置未知 Shape。Dtype 推导将输出类型设置为grads的类型三者必须同为 FLOAT/FLOAT16/BF16 之一。Host 侧 Tiling 策略Tiling 逻辑分布在 op_host/arch35/ 下的 4 个文件中通过不同的 TilingKey 选择 Kernel 分支。从单测 test_resize_bicubic_v2_grad_tiling.cpp 可以清晰看到 TilingKey 的划分规律TilingKey含义单测验证场景10000 / 10001SIMT 常规路径32 位 / 64 位索引-20000 / 20001SIMT 确定性路径32 位 / 64 位索引225×32 → 113×32align_cornerstrue20002 / 20003SIMT 确定性路径 SplitK32 位 / 64 位索引大 shape 场景如 32×2048×4096×3230000纯拷贝路径AllCopy输入输出尺寸完全一致如 32×32 → 32×32单测还揭示了两个实现细节一是当grads与original_image尺寸相同时算子退化为纯内存拷贝TilingKey30000二是确定性路径的 TilingData 中新增了splitK / coresPerOutput / segsPerOutput三个字段非 SplitK 场景取默认值。非 split-K 路径的 workspace 即系统预留区GetLibApiWorkSpaceSize()在 ascend950 UT 环境测试 faker 平台描述符下为 UINT32_MAX4294967295与同仓 col2im 用例一致。Kernel 多分支实现Kernel 入口 resize_bicubic_v2_grad.cpp 依据 TilingKey 分发到 arch35/ 下的三类模板实现ResizeBicubicV2GradAllCopy纯拷贝分支直接搬移数据无需插值计算。ResizeBicubicV2GradSimtSIMT 常规实现模板参数覆盖索引位宽uint32_t/int32_t与uint64_t/int64_t、数据格式NCHW/NHWC与 align_corners 开关true/false共计 8 种模板组合。ResizeBicubicV2GradSimtDetermine确定性实现支持Process()与ProcessSplitK()两种执行路径后者用于超大 shape 下按 K 维切分、多核协作累加的场景配合 workspace 使用。Kernel 通过KERNEL_TASK_TYPE_DEFAULT(KERNEL_TYPE_MIX_AIV_1_0)声明任务类型接收grads / originalImage / y / workspace / tiling五个 GM 地址参数从 tiling 内存中恢复 TilingData 后按 key 分发执行。测试与验证算子配套的 UT 覆盖两层Tiling 单测test_resize_bicubic_v2_grad_tiling.cpp使用tiling_context_faker与tiling_case_executor构造运行上下文校验不同 shape 组合同尺寸拷贝、等比缩放、超大 shape下生成的 TilingKey、TilingData 二进制内容与 workspace 大小是否符合预期。Infershape 单测test_resize_bicubic_v2_grad_infershape.cpp校验输出 shape 继承逻辑与非法输入非 4D、H/W 为 0、格式不支持的报错路径。总结ResizeBicubicV2Grad 是 CANN ops-cv 中一个典型的“动态 Shape 多 Tiling 策略 SIMT 多分支”算子数学上严格遵循双三次核函数与梯度摊回公式工程上通过 AllCopy / SIMT / SIMT-Determine(SplitK) 三类路径在正确性、确定性与大 shape 性能之间取得平衡。无论你是通过aclnnUpsampleBicubic2dBackward两段式接口进行单算子调用还是通过ResizeBicubicV2Grad算子 IR 构图接入训练图均可从本文的参数语义与源码脉络出发快速完成开发与问题定位。【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表