算子基础与计算图原理

各位同学,今天我们来聊聊算子与计算图。说实话,这部分内容看起来偏理论,但如果你真想做好YOLO的算子适配,这些概念绕不过去。我当年刚入行时,就是在这上面栽过跟头——以为只要会调库就行,结果一碰到自定义算子就抓瞎。

什么是算子?

算子,英文叫Operator,简称Op。说白了,它就是神经网络里一个最基本的计算单元。你可以把它想象成乐高积木里的一个基础块——卷积是一个块,ReLU是一个块,加法也是一个块。

我个人习惯把算子分成三类:

  • 数学运算类:加减乘除、指数、对数等
  • 张量操作类:reshape、transpose、concat等
  • 神经网络专用类:卷积、池化、归一化等
我的经验:在YOLO模型里,最常碰到的算子大概有30-40种。但真正需要你手动去适配的,往往只有卷积、激活函数、上采样这几个核心算子。其他的,框架基本都帮你搞定了。

张量计算图

计算图,就是把这些算子串起来的那个"图"。每个节点是一个算子,每条边是张量数据流。你想想看,YOLO从输入图片到输出检测框,中间经过了几十个算子,它们怎么组织?就是靠计算图。

我举个例子,一个简单的计算图长这样:

输入张量 → Conv2d → BatchNorm → ReLU → MaxPool → 输出张量
    [Op1]      [Op2]      [Op3]     [Op4]

每个箭头传递的是张量(Tensor),每个方框是算子。就这么简单。

关键点:计算图是静态的还是动态的,决定了你适配算子的方式。PyTorch用的是动态图,TensorFlow 2.x也是动态的,但ONNX导出的是静态图。做算子适配时,我建议你优先理解静态图——因为部署场景下,静态图才是主流。

前向推理与反向传播

这两个概念,我分开讲。

前向推理:输入数据从计算图的起点一路跑到终点,算出结果。在YOLO里,就是输入一张图片,输出三个尺度的特征图,再解码成检测框。这个过程只涉及算子的正向计算。

反向传播:训练时才有的过程。从损失函数开始,沿着计算图反向走,计算每个算子的梯度。这需要每个算子都实现一个反向函数。

做算子适配时,你只需要关心前向推理。为什么?因为部署场景下,模型已经训练好了,我们只做推理,不做训练。所以反向传播的适配,基本不用管。

避坑指南:我曾经遇到过一个问题——在某个NPU上跑YOLOv5,前向推理结果完全正确,但性能就是上不去。排查了三天,最后发现是框架自动插入了反向传播的梯度计算节点。嗯,这里要注意:有些推理框架会默认开启训练模式,记得显式切换到eval模式。

算子粒度划分

算子粒度,就是算子的大小。我把它分成三个级别:

粒度类型 特点 YOLO中的例子 适配难度
逐元素 输出每个元素只依赖输入对应位置 ReLU、Sigmoid、加法 低
归约 输出元素依赖输入多个元素,维度降低 全局平均池化、Softmax 中
卷积 输出元素依赖输入局部区域,有滑动窗口 Conv2d、DepthwiseConv 高

逐元素算子是最简单的。每个输出只跟一个输入元素有关,没有数据依赖。适配时基本就是写个循环,或者直接映射到硬件的SIMD指令。我在适配YOLOv5的SiLU激活函数时,就是逐元素的,一个晚上就搞定了。

归约算子稍微复杂一点。它需要把多个输入元素合并成一个。比如全局平均池化,要把整个特征图的所有值加起来再除以总数。这里要注意的是数据精度——累加过程中可能会溢出。我曾经在适配Softmax时,因为中间结果太大,导致精度丢失,检测结果全乱了。

卷积算子是最难的。它涉及滑动窗口、多通道累加、步长、填充等概念。YOLO里最核心的就是卷积,尤其是3×3卷积和1×1卷积。适配卷积时,我建议你重点关注内存访问模式——数据重排、分块策略、DMA传输,这些才是性能的关键。

核心原则:算子粒度越细,灵活性越高,但性能越差。反之,粒度越粗,性能越好,但灵活性越低。做算子适配时,我一般先保证功能正确,再考虑性能优化。别一上来就想着怎么把算子融合——那是后面的事。

知识体系总览

下面这张图,把本章的核心内容串起来了。你可以把它当作一个思维导图来看:

算子与计算图 算子定义 计算图 前向/反向 数学运算类 张量操作类 神经网络专用类 节点 = 算子 边 = 张量数据流 前向推理 反向传播 算子粒度划分 逐元素 归约 卷积 适配时重点关注前向推理

这张图把本章的核心概念都串起来了。从算子定义出发,到计算图的结构,再到前向推理和反向传播的区别,最后落到算子粒度划分。你可以看到,卷积算子处于最复杂的位置——它既是神经网络专用类,又是粒度最粗的算子。这也是为什么YOLO算子适配的难点,往往都集中在卷积上。

我的建议:刚开始学算子适配时,先从逐元素算子入手。比如ReLU、Sigmoid这些,代码量少,逻辑简单,容易验证。等熟悉了整个流程,再挑战卷积。别一上来就啃硬骨头,容易打击信心。