卷积算子优化-2.几种卷积算法

本文详细介绍了卷积操作的几种常见实现方式,包括直接卷积、基于GEMM的Img2col方法、节省内存的ImplicitGEMM以及Winograd方法。着重讲解了GEMM的Img2col和ImplicitGEMM在内存管理和卷积效率上的区别。

上一篇文章提到了两个优化点,数据重用和重复计算,这篇文章来学习一下现在卷积常见的几种实现方法。

1.直接卷积

在直接卷积中,卷积核(滤波器)通过在输入图像上滑动并与图像的每个位置进行逐元素相乘,然后将所有乘积相加得到输出的单个像素值。这个过程可以看作是在输入图像上进行的一种滑动窗口操作,其中卷积核的大小决定了窗口的大小。也就是上一篇文章中提到的C++实现,是一种最朴素的实现,在大部分的情况下表现不如其他算法实现。卷积

2.GEMM

2.1 Img2col+GEMM

最广泛的卷积算法之一是就是基于GEMM算法来实现卷积。它包括以下步骤:
将输入转换为一个大矩阵,其中每一列包含在卷积过程中每个滤波器位置所涉及的输入元素。
另一个矩阵由每个过滤器的元素生成。最后,卷积的结果由两个矩阵的矩阵乘法(GEMM)提供,如图所示。

Img2col+GEMM:
Img2col+GEMM

转换后的输入矩阵的元素是这样放置的:当GEMM执行一行和一列的标量积时,它将与卷积所执行的标量积相匹配。由于矩阵乘法执行转换后的输入的所有列与转换后的所有行的点积,GEMM操作的结果代表了输入上所有滤波器平移位置上所有滤波器的卷积输出,具体计算过程会在Implicit GEMM小节中介绍。用于获取转换后的输入矩阵的函数通常被称为“im2col”。
由于GPU体系结构的性质和线性代数库中GEMM方法的高效实现,卷积非常适合于放在GPU上计算。然而,这种方法需要大量的内存来存储转换后的矩阵,特别是转换后的输入矩阵,由于卷积中有滑动步长和Padding的存在,转换后的数据矩阵必须存储滑动中重复访问的元素,和一些Padding后额外数据。这在神经网络训练过程中是十分占用显存的,于是就有另一种GEMM实现。

2.2 Implicit GEMM

Implicit GEMM是一种用于实现卷积操作的方法,与Img2col+GEMM相似,同样利用了矩阵乘法的性质来加速卷积计算。不同点在于,在内存使用量方面,Implicit GEMM不需要任何额外的存储空间。
在Img2col+GEMM实现中,实现的步骤为:
1.输入输出矩阵转换,用另一块内存空间保存转换后的输入输出矩阵。
2.将输入输出矩阵进行GEMM运算,然后进行输出。
而在 Implicit GEMM中,矩阵转换发生在计算中,也就不需要内存来保存转换后的矩阵,而是在GEMM中进行输入输出的坐标映射,从而实现卷积运算。

Direct Convolution:
Direct Convolution

Im2col转换后的GEMM实现卷积:
Im2col转换后的GEMM实现卷积
在 Implicit GEMM中,主要思想是坐标的映射,怎样使GEMM在load时正确的取到对应坐标元素是关键。参考以下矩阵乘:

for (int i = 0; i < M; i++) {
   
   
    for (int j = 0; j < N; j++) {
   
   
        result[i][j
### RK3588 NPU 的卷积操作优化 对于 RK3588 开发板上的 NPU 来说,其硬件特性决定了某些特定类型的卷积操作能够更高效地执行。为了提高深度学习框架中卷积操作的效率并充分利用 NPU 性能,可以从以下几个方面入手: #### 1. **量化感知训练 (Quantization-Aware Training)** NPU 设备通常支持 INT8 或 FP16 数据类型以减少内存占用提升计算速度。因此,在模型部署到 NPU 前,可以通过量化感知训练将浮点数权重转化为低精度整型数据[^1]。这种方法不仅减少了存储需求,还显著提升了推理速度。 ```python import tensorflow as tf quantize_model = tf.keras.models.clone_model(original_model) for layer in quantize_model.layers: if isinstance(layer, tf.keras.layers.Conv2D): layer.activation = tf.quantization.fake_quant_with_min_max_vars( layer.activation, min=-6.0, max=6.0, num_bits=8 ) ``` #### 2. **Depthwise Separable Convolutions** 相比于标准卷积,深度可分离卷积(Depthwise Separable Convolution)大幅降低了计算复杂度。这种结构非常适合资源受限环境下的边缘设备,例如搭载 ARM 架构 GPU 专用 NPU 的 RK3588 芯片组[^4]。 ```python from tensorflow.keras import layers def depthwise_separable_conv(input_tensor, filters, kernel_size=(3, 3)): x = layers.DepthwiseConv2D(kernel_size)(input_tensor) x = layers.BatchNormalization()(x) x = layers.ReLU()(x) x = layers.Conv2D(filters=filters, kernel_size=(1, 1))(x) x = layers.BatchNormalization()(x) x = layers.ReLU()(x) return x ``` #### 3. **Winograd Algorithm for Small Kernels** 当处理小型核尺寸(如 \(3 \times 3\) 卷积)时,Winograd 算法是一种有效的优化手段。该技术通过矩阵变换降低乘加运算次数,从而加快前向传播过程的速度[^2]。 #### 4. **Batch Size Tuning with Arbiter-Core** 利用工具如 Arbiter-Core 对批量大小进行调参可以帮助找到适合目标硬件的最佳配置。较大的 batch size 可以摊销固定开销,但过大会导致显存不足或延迟增加。 #### 5. **Driver-Level Optimization via Rockchip OPP Table Update** 更新 RK3588 的 NPU 驱动程序至最新版本可能带来额外性能增益。具体而言,修改 `rockchip_uninit_opp_table` 函数确保电源管理策略适配当前工作负载有助于稳定性效能表现。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值