深入理解oneDNN中的后操作(Post-ops)属性

深入理解oneDNN中的后操作(Post-ops)属性

oneDNN oneAPI Deep Neural Network Library (oneDNN) oneDNN 项目地址: https://gitcode.com/gh_mirrors/on/oneDNN

后操作概述

在深度学习计算中,操作融合(Operation Fusion)是一种重要的性能优化技术。oneDNN通过后操作属性API实现了基本的操作融合能力。后操作(Post-ops)是指在主操作(如卷积、矩阵乘法等)之后追加执行的一系列操作,通过减少内存带宽压力来提高性能。

后操作使用属性机制实现,如果存在多个后操作,它们将按照添加顺序依次执行。目前oneDNN支持以下几种后操作类型:

  1. 元素级操作(Eltwise)
  2. 求和操作(Sum)
  3. 深度卷积(Depthwise)
  4. 二元操作(Binary)
  5. PReLU操作

后操作的基本使用

后操作通过不透明的结构体表示(在C API中是dnnl_post_ops_t,在C++ API中是dnnl::post_ops)。下面是一个基本的使用示例:

dnnl::post_ops po; // 创建空的后操作对象
po.append_SOMETHING(params); // 添加第一个后操作
po.append_SOMETHING_ELSE(other_params); // 添加第二个后操作

dnnl::primitive_attr attr; // 创建属性对象
attr.set_post_ops(po); // 将后操作附加到属性上

// 使用带有后操作属性的描述符创建原语
primitive::primitive_desc op_pd(engine, params, attr); 

重要说明

  • 后操作的添加顺序决定了它们的执行顺序
  • 库支持的最大后操作数量为32
  • 不同原语对后操作的支持程度不同,需要查阅具体原语的文档
  • 后操作不会改变目标内存对象的格式

支持的后操作类型详解

1. 元素级后操作(Eltwise Post-op)

元素级后操作可以将主操作(如卷积或内积)与元素级操作(通常是激活函数)融合。

API:

void append_eltwise(algorithm alg, float alpha, float beta);

数学表示: 原始操作:dst = Op(...) 添加后操作后变为:dst = eltwise(Op(...))

典型应用:在卷积后直接应用ReLU等激活函数。

注意:中间结果Op(...)不会被保留,因此这种融合通常不能用于训练阶段。

2. 求和后操作(Sum Post-op)

求和后操作将主操作的结果与现有数据累加,累加前可以对现有数据进行缩放和偏移。

数学表示: 原始操作:dst = Op(...) 添加后操作后变为:dst = scale * (dst - zero_point) + Op(...)

典型应用:残差学习块,其中卷积结果需要与先前计算的激活值相加。

数据类型支持

  • 可以指定目标张量的数据类型进行重新解释
  • 数据类型大小必须与原始目标数据类型相同

3. 深度卷积后操作(Depthwise Post-op)

深度卷积后操作将1x1卷积与深度卷积融合,这在MobileNet等模型架构中很常见。

数学表示: 原始操作:dst = Conv_1x1(...) 添加后操作后变为:dst = Conv_dw(Conv_1x1(...))

输出维度: 最终输出维度为:{n, oc_1x1, ceil(oh_conv_1x1/stride), ceil(ow_conv_1x1/stride)}

支持的数据类型组合

| 1x1卷积输出类型 | 深度卷积输出类型 | 深度卷积权重类型 | 深度卷积偏置类型 | |----------------|-----------------|----------------|----------------| | u8, s8 | u8, s8, s32, f32| s8 | f32, s32 | | f32 | f32 | f32 | f32 | | bf16 | bf16, f32 | bf16 | f32, bf16 | | f16 | f16, f32 | f16 | f32, f16 |

重要限制

  • 目前仅支持2D 1x1卷积
  • 不能与其他深度卷积或求和后操作链式组合
  • 目标内存格式必须为any
  • 当深度卷积步长≠1时,需要特别注意空间维度处理

4. 二元后操作(Binary Post-op)

二元后操作可以将主操作与二元操作融合。

API:

void append_binary(algorithm alg, const memory::desc &src1);

数学表示: 原始操作:dst = Op(...) 添加后操作后变为:dst = binary(Op(...), Source_1[:])

优化场景

  • 张量级广播(Source_1为单元素张量)
  • 通道级广播(Source_1的通道数与主操作相同)
  • 元素级广播(Source_1与主操作完全匹配)

选择操作(Select): 对于二元选择操作,需要额外的条件张量:

void append_binary(algorithm alg, 
                  const memory::desc &src1,
                  const memory::desc &src2);

5. PReLU后操作(PReLU Post-op)

PReLU后操作可以将主操作与PReLU操作融合。

API:

void append_prelu(int mask);

数学表示: 原始操作:dst = Op(...) 添加后操作后变为:dst = prelu(Op(...), weights[:])

关键参数

  • mask:描述权重广播方式的掩码
  • 权重张量在运行时通过特定机制传递
  • 目前仅支持fp32权重和plain布局

后操作链示例

示例1:求和后接ReLU

这是ResNet家族网络中的常见模式。

dnnl::post_ops po;
po.append_sum();
po.append_eltwise(dnnl::algorithm::eltwise_relu, 0.f, 0.f);

dnnl::primitive_attr attr;
attr.set_post_ops(po);

数学表示:dst = ReLU(dst + conv(src, weights))

示例2:Tanh -> 求和 -> 线性变换

这个例子展示了操作序列和缩放的使用。

dnnl::post_ops po;
po.append_eltwise(dnnl::algorithm::eltwise_tanh, 0.f, 0.f);
po.append_sum();
po.append_eltwise(dnnl::algorithm::eltwise_linear, alpha, beta);

dnnl::primitive_attr attr;
attr.set_scales_mask(DNNL_ARG_SRC, 0);
attr.set_scales_mask(DNNL_ARG_WEIGHTS, 0);
attr.set_scales_mask(DNNL_ARG_DST, 0);
attr.set_post_ops(po);

数学表示:dst = s_linear * (α * (s_sum * dst + s_tanh * tanh(s_conv * conv(src, weights))) + β)

示例3:ReLU -> 深度卷积 -> ReLU

这是MobileNet中融合深度卷积和1x1卷积的示例。

dnnl::post_ops po;
po.append_eltwise(dnnl::algorithm::eltwise_relu, 0.f, 0.f);
po.append_dw(dnnl::memory::data_type::s8, 
             dnnl::memory::data_type::undef,
             dnnl::memory::data_type::u8,
             kernel, stride, padding);
po.append_eltwise(dnnl::algorithm::eltwise_relu, 0.f, 0.f);

dnnl::primitive_attr attr;
attr.set_scales_mask(DNNL_ARG_DST, 0);
attr.set_scales_mask(DNNL_ARG_ATTR_POST_OP_DW | DNNL_ARG_DST, 0);
attr.set_post_ops(po);

数学表示:dst = ReLU_depthwise(scales_depthwise * (conv_depthwise(ReLU_1x1(scales_conv_1x1 * (conv_1x1()))))

总结

oneDNN的后操作属性提供了强大的操作融合能力,可以显著提升深度学习模型的推理性能。通过合理使用各种后操作及其组合,开发者可以优化内存访问模式,减少中间结果的存储开销。在实际应用中,需要根据具体模型结构和硬件特性选择最合适的后操作组合,并通过性能测试验证优化效果。

oneDNN oneAPI Deep Neural Network Library (oneDNN) oneDNN 项目地址: https://gitcode.com/gh_mirrors/on/oneDNN

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤歌泽Vigour

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值