专栏算法工具链【性能优化】mul与reduce_sum的优化实例

【性能优化】mul与reduce_sum的优化实例

Jade-self2025-07-10
294
0

1. 基础介绍

什么是mul与reduce_sum?

mul 通常指元素级乘法(Element-wise Multiplication),它将两个形状相同的张量中对应位置的元素相乘,返回一个与原张量形状相同的新张量。

reduce_sum 是一种规约操作(Reduction Operation),它沿指定维度对张量的元素求和,从而 “压缩” 或 “减少” 张量的维度。如果不指定维度,则对所有元素求和,返回一个标量。

2. baseline结构

onnx可视化图如下:
Description

对应代码如下:

在J6M上进行简单的模型编译与性能预估:

根据产出物得到预估latency:2.97 ms

Description

这个结构如何进行优化呢?

3. 合并reduce_sum

这两个reducesum能合并成一个,使用 dim=(1, 2)(即同时对 dim=1 和 dim=2 做 sum),前提是这两个维度的求和没有先后顺序依赖(即两个维度是独立的)

PyTorch 中 .sum(dim=(1, 2)) 会按照给出的维度一次性执行 sum 操作,等价于逐个做 dim=2 然后 dim=1,因为 sum 是可交换的操作,最终结果形状完全相同。

优化后结构如下,可以看到确实少了一个reducesum:

Description

预估latency: 1.75 ms

Description

4. mul+reducesum变成conv

假设有两个张量:

  • a.shape = (B, C, H, W)

  • b.shape = (B, C, H, W)

常见操作是:

注意:torch中a * b 是逐元素相乘(mul),而不是矩阵乘法(matmul),形状不匹配时会触发广播(复制对应列 or 行)

通过 深度卷积(depthwise convolution) 可以近似实现 Mul + ReduceSum 操作,等价的 Conv2d 实现方式,可以用 groups=B*C 的 conv2d 来实现上述操作:

conv2d 的过程是:

  • 对每个通道进行 乘法(卷积)

  • 然后在 kernel 区域内 求和

所以 F.conv2d(a, b, groups=B*C) 本质就是:对 a 和 b 逐元素相乘再求和 = Mul + ReduceSum

一致性验证:

输出:

可以看到,结果确实一样。

真正部署时,不太建议这么做,因为小尺寸没必要(快不了多少),大尺寸硬件不支持。

算法工具链
社区征文征程6杂谈技术深度解析
评论0
0/1000