飞桨x昇腾生态适配方案:06_算子适配举例

简介: 本节详细解析了Paddle-API与CANN-Kernel之间的差异及适配策略,涵盖三种主要场景:参数缺失或不对应、数据类型不匹配以及layout转换。针对不同问题提出具体解决方案,如通过默认赋值或计算补充参数、使用`Cast`操作转换数据类型、借助`Transpose`调整数据布局等。同时,以ReluGrad和nll_loss算子为例,深入说明参数对齐、数据类型转换及转置操作的实现流程,为开发者提供清晰的适配指导。

本节介绍aclnn算子的三种适配场景。

Paddle-API 与 CANN-Kernel 差异剖析及适配策略

对于Paddle-API与CANN-Kernel两者中常见的差别与适配方法如下:

Paddle参数缺失或者参数无法直接对应

  • 如果Paddle算子只需要CANN提供的某个参数为默认值的功能,则可通过默认赋值的方式完成
  • 考虑通过计算取得需要参数

    CANN参数缺失

  • CANN算子没有某个Paddle有的参数,一般是此算子CANN支持的模式少于Paddle
  • 可通过多个算子分别完成算子的部分功能(如max_pool + avg_pool)
  • 如果CANN只能支持部分功能,则可以在调用处抛出参数值判断异常

    数据类型不支持

  • 输入数据类型不匹配时需要在计算前插入 Cast 操作,并且要更改输出的数据类型,在计算后对输出数据进行 Cast 操作返回原数据类型

    layout转换

  • NPU算子基本不支持NHWC,但是部分Paddle算子支持,如果遇到这样的情况需要在计算前后插入 Transpose

    小算子拼接

  • 部分Paddle-API的功能在NPU中没法直接完成,但可通过多个小算子拼接完成,一般会少许影响性能

    加入缺少的参数

    以ReluGrad算子为例,通过计算或者默认赋值方式加入缺少的参数:
    01_加入缺少的参数.png

在进行参数对齐时,需要检查是否存在需要默认参数的情况。以 Paddle 的 relugrad 算子为例,其对应的 aclnn 的 ThresholdBackward 算子包含额外参数 threshold。
在实际操作中,可通过默认赋值的方式实现参数对齐,如图所示,代码为phi::Scalar threshold = 0.0。完成参数对齐后,即可直接调用 NPU 的 aclnnThresholdBackward 算子 。

数据类型转换

以 nll_loss 算子为例,Paddle API 与 CANN API 所支持的数据类型存在差异。Paddle API 中,输入 x 的数据类型为 double,而 CANN 的对应算子仅支持 float32 这一特定数据类型,具体情况如下图所示:
Paddle侧:
02_Paddle侧数据类型.png

CAAN侧:
03_CANN侧数据类型.png

此情形需进行数据类型转换:

  • 首先,对输入数据执行 cast 操作,将其转换为 CANN 算子支持的数据类型;
  • 完成转换后,执行 NPU 的 aclnn 算子;
  • 算子运算结束后,再将计算结果的数据类型由 float32 转换回输入 x 原本的数据类型。
    具体流程如下图所示:
    04_数据类型转换流程.png

数据类型转换需要Cast_kernel算子,下面为Cast_kernel算子的声明:
05_Cast_kernel算子声明.png

以下介绍将变量 x 的数据类型从 double 转换为 float32(转换后的变量记为 x_cast)的流程:

对象声明

phi::DenseTensor x_cast;                // 声明目标张量 x_cast
phi::DenseTensorMeta x_cast_meta;       // 声明张量的元数据对象

phi::DenseTensor:深度学习框架中表示多维数组的核心数据结构,包含数据和元信息(如形状、数据类型)。
phi::DenseTensorMeta:用于存储张量的元信息(metadata)。

元数据初始化

x_cast_meta = {phi::DataType::FLOAT32, x.dims();

phi::DataType::FLOAT32:明确将目标张量的数据类型设为 float32。
x.dims():继承输入张量 x 的维度信息(如 [batch_size, channels, height, width])

绑定元数据

x_cast.set_meta(x_cast_meta);

作用:将初始化后的元数据绑定到目标张量 x_cast。

执行类型转换

custom_kernel::CastKernel<T, Context>(dev_ctx, x, phi::DataType::FLOAT32, &x_cast);

核心参数:
dev_ctx: 设备上下文(如 CPU/GPU 资源管理)
x: 输入张量
phi::DataType::FLOAT32: 目标数据类型
&x_cast: 输出的目标张量指针
功能:将输入张量 x 的数据类型转换为 float32,结果写入 x_cast。

执行NPU aclnn算子计算

把所有需要进行数据类型转换的参数转换完成后,使用算子执行宏EXEC_NPU_CMD执行aclnn算子:
06_EXEC_NPU_CMD宏.png

aclnn算子输出结果原类型恢复

07_aclnn算子输出结果原类型恢复.png

  • 将 out_cast(NPU计算结果)转换为paddle api的 out 张量类型(如 float32 → double)。
  • 将损失计算中累计的权重值 total_weight_cast 数据类型转换为目标类型后写入 total_weight。

    转置操作

    在 Pool2dGradKernel 算子中,若输入数据格式data_format为NHWC,即高度、宽度、通道数位于最后,鉴于 NPU 的操作要求,需将数据转换为NCHW格式。此转换通过Transpose操作达成。
    Transpose操作的核心功能是实现张量维度重排,旨在适配 NPU 计算特性所规定的数据布局需求。在本场景中,其主要作用是完成从NHWC(Channel Last)到NCHW(Channel First)这两种内存布局的转换 。
    08_Pool2dGradKernel算子.png

流程图如下:
09_转置操作流程.png

变量声明

phi::DenseTensor transformed_out_grad;
通过临时变量隔离布局转换过程,保证原始数据的完整性

布局判断逻辑

接下来,程序执行条件判断if (channel_last)。该判断旨在检查输入数据是否采用NHWC格式。
若if (channel_last)条件成立,即NHWC(Channel Last)格式时,程序将执行转置操作,把数据格式转换为通道优先Channel First的NCHW格式。

维度置换规则

std::vector<int> perm = {0, 3, 1, 2};
数学原理:对应张量维度[N,H,W,C]->[N,C,H,W]
定义了一个perm向量{0, 3, 1, 2},这应该是用来重新排列维度的顺序。原来的维度假设是NHWC(0,1,2,3),转置后变为NCHW(0,3,1,2)。

新形状构建

接着构造了out_grad_tensor_shape,调整形状以匹配新的维度顺序。调整后的形状是通过重新排列out_grad的维度得到的,例如将原维度[0]、[3]、[1]、[2]组合成新的形状。

std::vector<int> out_grad_tensor_shape = {
    out_grad.dims()[0],
    out_grad.dims()[3], 
    out_grad.dims()[1],
    out_grad.dims()[2],
};

通过维度复制而非引用保证形状独立性。

内存分配

然后将transformed_out_grad调整大小,分配内存,并通过TransposeKernel进行转置操作。

transformed_out_grad.Resize(phi::make_ddim(out_grad_tensor_shape));
dev_ctx.template Alloc<T>(&transformed_out_grad);

转置运算

custom_kernel::TransposeKernel<T, Context>(dev_ctx, out_grad, perm, &transformed_out_grad);
custom_kernel::TransposeKernel是调用NPU的转置内核函数,需在算子开发代码中进行函数声明,如图所示:
10_TransposeKernel声明.png

目录
相关文章
|
9月前
|
边缘计算 人工智能 物联网
Ultralytics YOLO26来啦!5种尺寸全家桶,速度与精度兼顾
Ultralytics发布YOLO26,系列迄今最先进、易部署的模型,支持分类、检测、分割、姿态估计等多任务。五种尺寸灵活适配边缘设备,CPU推理提速43%,首创无NMS端到端推理,移除DFL提升兼容性,已上架魔搭社区。(239字)
1937 14
|
机器学习/深度学习 PyTorch 算法框架/工具
飞桨x昇腾生态适配方案:00_整体方案介绍
本文详细介绍PaddlePaddle与NPU的适配工作,涵盖训练与推理支持、性能优化及离线推理方案。PaddleCustomDevice作为适配层,支持主流模型(详见飞桨-昇腾模型列表),多数性能媲美V100,部分调优模型接近0.8*A800。硬件适配主要针对A2芯片,A1兼容但310系列建议离线推理。提供常用模型仓链接及整体方案导览,包括环境准备、算子适配、性能调优和Paddle转ONNX/OM等内容。
1159 0
|
测试技术 API 异构计算
飞桨x昇腾生态适配方案:05_算子适配流程
本内容主要介绍Paddle针对非CPU和Nvidia GPU硬件(如NPU)的适配流程与方法。适配代码存于PaddleCustomDevice仓库,路径为`PaddleCustomDevice/backends/npu`,包含kernels(算子适配)和tests(单元测试)两个核心目录。适配流程分为算子注册、适配函数入参与主体实现三步,重点对齐Paddle与CANN算子参数。
750 0
|
机器学习/深度学习 Docker 容器
飞桨x昇腾生态适配方案:01_基础环境准备
本指南详细介绍在ARM环境中准备CANN环境、安装Paddle深度学习框架及PaddleCustomDevice的过程。首先下载并加载CANN镜像,启动Docker容器;接着通过日构建包或源码编译安装PaddlePaddle和PaddleCustomDevice;可选更新CANN版本时需注意环境变量配置与路径设置。最后提供基础功能检查方法,包括硬件后端、版本验证及框架健康检查,确保环境搭建成功。
1432 0
|
机器学习/深度学习 存储 人工智能
深度解析大模型压缩技术:搞懂深度学习中的减枝、量化、知识蒸馏
本文系统解析深度学习模型压缩三大核心技术:剪枝、量化与知识蒸馏,详解如何实现模型缩小16倍、推理加速4倍。涵盖技术原理、工程实践与组合策略,助力AI模型高效部署至边缘设备。
2539 2
|
Python
飞桨x昇腾生态适配方案:15_loop算子缺失(下):for循环替换loop
本章节基于上一内容,将ONNX模型拆分为loop算子部分与非loop算子部分,分别转换为OM模型。通过使用for循环替换loop算子的计算逻辑,构造子图执行流程,并编写OM模型推理脚本进行验证。同时,编写ONNX模型推理脚本对比两者推理结果,确保一致性。实验结果表明,拆分后的OM模型与原始ONNX模型推理结果一致,证明方案可行。
668 27
|
文字识别 算法 API
飞桨x昇腾生态适配方案:04_模型精度对齐
本文详细介绍了模型在不同硬件(如GPU与NPU)间迁移时的精度对齐方法,包括前向和反向对齐的具体步骤。前向对齐通过模块化对比计算结果(如平均值、最大最小值等),确保误差在合理范围内;反向对齐则聚焦于梯度差异,利用二分法定位问题算子。同时,文章结合PPHGNet_small和MultiHead等具体模块代码,说明了如何打印输出并分析中间结果。此外,还探讨了私有格式、梯度异常及特殊shape等可能影响精度的因素,并提出相应解决策略。整体流程清晰,为跨硬件模型迁移提供了实用指导。
1004 10
|
缓存 AI芯片
飞桨x昇腾生态适配方案:02_常用环境变量
本节介绍训练前建议设置的常用环境变量,涵盖NPU私有格式、在线编译、性能优化参数(如`aclnn_scale`和`aclnn_split`)、算子黑名单配置、NPU卡号指定、Paddle内存分配策略及日志设置等内容。通过合理配置这些变量,可有效提升训练性能并解决潜在问题。例如,关闭`FLAGS_npu_storage_format`以禁用NPU私有格式,或调整`ASCEND_MAX_OP_CACHE_SIZE`优化Kernel缓存大小。同时,CANN和Paddle的日志环境变量也提供了调试支持。
778 0
|
数据采集 人工智能 自然语言处理
万字干货|复杂表格多Agent方案:从LLM洞察、系统性 思考到实践经验总结
笔者结合实践经验以近期在负责的复杂表格智能问答为切入点,结合大模型的哲学三问(“是谁、从哪里来、到哪里去”),穿插阐述自己对大模型的一些理解与判断,以及面向公共云LLM的建设模式思考,并分享软件设计+模型算法结合的一些研发实践经验。
1924 43
|
存储 文字识别 文件存储
飞桨x昇腾生态适配方案:03_模型训练迁移
本案例以PaddleOCRv4模型为例,详细介绍了将模型迁移到NPU的完整流程。迁移过程中需确保模型功能在新硬件上无误,重点关注偶发性错误及长时间运行时可能出现的问题,并通过日志辅助定位问题。文档涵盖环境搭建、数据集准备、模型配置、训练启动及常见问题排查等内容。例如,通过设置环境变量排查缺失算子,处理Paddle版本兼容性问题,以及解决进程残留等。适合希望将OCR模型部署到NPU的开发者参考。
787 0