首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >到底什么是算子?大模型的底层动力单元详解

到底什么是算子?大模型的底层动力单元详解

原创
作者头像
fanstuck
修改2025-11-28 17:19:36
修改2025-11-28 17:19:36
2220
举报

引言

如果你去问十个做深度学习的工程师:“算子是什么?”

大多数人可能会回答:“就是 MatMul、ReLU 这些嘛。”

听起来好像简单,但要是真的用一句话解释清楚 —— 很难。因为算子不是某个函数,也不是某段 Python 代码,它更像是深度学习世界里“最小执行单元”的一种抽象。

为了避免抽象,我们换一种最接地气的方式来理解:

算子就像做菜时的动作。

切、炒、翻、焖、撒盐——这些都是厨房里的基本动作。

不管你想做宫保鸡丁还是红烧肉,最终都要由这些动作组合来实现。

深度学习模型也是一样的。不管你写的是 CNN、Transformer、LLM 还是 OCR 模型,本质上都是一个个算子的组合,比如:

  • 判断是否大于 0 的 ReLU
  • 做矩阵乘法的 MatMul
  • 扫描特征图的 Conv2D
  • 做平滑归一化的 Softmax / LayerNorm

模型结构再高大上,最终都要回到这些“动作”来执行。

但这里有一个更关键的误区需要拆开: 算子不是你写在 Python 里的那段代码。

就像“翻炒”不是厨师口头描述的步骤,而是真正落在锅里的那套动作。

你写 torch.relu(x),只是告诉 PyTorch: “我要用 ReLU 这个动作。”

但 PyTorch 会做的事情是:

先查 GPU 里有没有 ReLU 对应的 kernel? 如果你用的是昇腾 NPU,它会查 CANN 提供的 ReLU 实现? 如果你用的是 CPU,它会找 MKL、OpenMP 的优化版本?

也就是说: 算子的本体不是 Python 实现,而是最终被硬件执行的计算核(kernel)。

换个更工程化的说法你就明白了:

  • 模型结构是“动作的剧本”
  • 框架是“动作导演”
  • 算子是“动作演员和动作设计”
  • 硬件(GPU / NPU / CPU)是“拍摄现场”

你写指令,框架理解剧情,但真正执行的人,是算子。

这也是为什么大模型部署到不同硬件上,就像同一部电影找不同动作演员演会出现“动作不一样”“动作做不出来”的情况。比如你把 HuggingFace 的模型丢到昇腾上,有时会遇到:

“xxx 算子不支持”

这不是什么 bug,而是因为: 昇腾上没有这个算子的实现。

一、要弄懂算子,得抓住两个本质

为了避免概念漂浮,我把算子的本质压到两个最关键的观念:

① 算子是深度学习中最小的“可执行计算单元”。

它不是某个函数,而是更底层的:

  • 做一次矩阵乘法
  • 做一次卷积
  • 做一次点积
  • 做一次 Softmax

模型执行的时候,都是这些原子操作。

如果一个模型有 200 层,那么可能需要执行几千到几万个算子。

而在大模型训练中,这种算子会在一次 forward/backward 中被重复使用数万亿次。

② 算子是“抽象概念”和“硬件指令”之间的桥梁。

你写的是抽象的数学公式:

  • Q·K^T
  • Softmax
  • Linear

但 GPU/昇腾真正执行的是:

  • 一段 CUDA kernel
  • 一段 CANN kernel
  • 一段能利用向量化、访存优化、并发调度的底层算子代码。

算子把“你想要的结果”和“硬件能够执行的动作”打通。

如果没有算子,那深度学习框架就像一个只会写小说的人,面对 GPU 这个“只说汇编语言的工人”完全没法沟通。

假设你跑一个简单的 Transformer Attention,代码可能只有几行:

代码语言:javascript
复制
attn = softmax(Q @ K.T) @ V

看着简单对吧? 但你知道底层跑了多少个算子吗?

  • Q @ K.T → 一个 BatchMatMul 算子
  • Softmax → 一个 Softmax 算子
  • 再 @ V → 另一个 BatchMatMul 算子

每个算子背后,可能还分成几十个 kernel 执行:

  • 矩阵分块(tile)
  • 调度线程
  • 卷积/乘法循环展开
  • 向量化
  • Cache 调用
  • 指令流水等

而当你说:

“FlashAttention 让推理快 2~4 倍”

它本质上就是: 把原本多个算子 + 多个访存步骤 → 合并成一个更高效的算子。

这就是算子的力量 —— 既决定模型能不能跑,又影响模型跑得快不快。

二、算子在深度学习框架中的位置

如果说前面告诉你算子是什么、为什么重要,那么接下来这章要回答一个更关键的问题:

算子到底在深度学习框架里处于什么地位?

很多工程师学 PyTorch、TensorFlow 或 JAX 时,会自然觉得:

“我写了代码,框架帮我算,GPU 自动跑。”

但这个感觉容易误导你以为框架是“直接”在 GPU 上执行你写的 Python 代码。

实际上,Python 只是“给框架写了个故事”,而真正把故事变成动作的,是算子。

我们可以把整个工作流拆解成一个非常现实的场景:

1.你写的是“剧本”

你写的 PyTorch 模型、TensorFlow 计算、JAX 程序,就像写了一段剧本:

代码语言:javascript
复制
y = torch.relu(x @ W + b)

这段代码只告诉框架:

  • 我需要一次矩阵乘法
  • 然后加一次偏置
  • 再跑一个 ReLU

它并不会告诉 GPU 如何执行。像 PyTorch、TensorFlow、MindSpore 等框架会把你的代码解析成一个所谓的 计算图(Computation Graph)

框架会把剧本翻成“计算图”

你可以把它理解为: 把你的剧情拆成“动作节点”和“数据流向”。

我们的这段代码会变成:

代码语言:javascript
复制
x @ W ——> Add ——> ReLU ——> y

这就是计算图。 也就是说,你写的所有模型结构,本质就是一张巨大的、有向的动作图。

2. 框架会把剧本翻成“计算图”

像 PyTorch、TensorFlow、MindSpore 等框架会把你的代码解析成一个所谓的 计算图(Computation Graph)

你可以把它理解为: 把你的剧情拆成“动作节点”和“数据流向”。

我们的这段代码会变成:

代码语言:javascript
复制
x @ W ——> Add ——> ReLU ——> y

这就是计算图。 也就是说,你写的所有模型结构,本质就是一张巨大的、有向的动作图。

3. 计算图会被“映射”(Mapping)成对应的算子

框架接下来的工作不是直接让 GPU 执行,而是:

在它支持的算子库里,寻找对应的算子。

比如 PyTorch 会去查:

  • MatMul → 调用 cuBLAS 或自家 kernel?
  • Add → 调用 fused add kernel?
  • ReLU → 调用 CUDA kernel?

如果你换到昇腾 NPU:

  • MatMul → 调用 CANN 里的 MatmulV2?
  • Add → 调用 vector add?
  • ReLU → 调用 TBE 实现的 ReLU?

这一步非常关键,因为:

框架不负责做计算 它只负责找到“能做这个计算的人”。

4.算子翻译成 Kernel

算子看起来是抽象的动作: “做一次矩阵乘法”“做一次卷积”“执行一次 Softmax”

但它最终会落成一段非常底层的 kernel(内核指令),这段代码:

  • 在 GPU 上是 CUDA C++ 写的
  • 在昇腾上是 CANN TBE/Cube/CANN Dialect
  • 在 CPU 上是矢量化 SIMD 指令
  • 在 Apple M 芯片上则是 Metal kernel

Kernel 才是硬件真正执行的对象。

如果算子是“动作指令”, 那么 kernel 是“具体动作流程”。

5. 硬件执行 Kernel,数据在算子间流动

最后一步才轮到 GPU/NPU 出场。

它们不会去看你写的 Python,不看模型结构,不看抽象公式,只负责一件事:

“你给我什么 Kernel,我照着执行。”

执行过程中,训练/推理的数据会在算子之间流动,就像流水线上的物料一样被一步步加工,最终得出结果。

把整个链路放在一起看,你会发现一个非常朴素的事实

模型看起来神秘,但本质上就是:

而在这一整条链路中,只有算子是“真正执行的人”。

框架负责组织和调度,算子负责实际计算,硬件负责跑算子。

假设你做一个简单的 MLP 推理,Python 只写了两行:

代码语言:javascript
复制
x = torch.matmul(x, W)
y = torch.relu(x)

你以为执行了两行代码,但实际情况是:

  • PyTorch 把两行变成 2 个算子
  • 每个算子背后有可能拆成几十个 GPU kernel:
    • load tile
    • 访存
    • matmul kernel
    • add kernel
    • thread block 调度
    • warp 分配
    • 向量化执行
  • GPU 只负责执行这些 kernel
  • 整套流程可能发生上千次

看似简单的 ReLU,其实底层也要调度 kernel、控制线程、做访存优化。

这也是为什么你越深入推理优化,就越容易听到:

“这个算子太慢了,得换一个。” “这个算子在 GPU 上有优化版本。” “昇腾上这个算子要用 TBE 自定义。”

因为算子是这个世界里最接近硬件的那一层, 也是整个性能、兼容性、跨硬件迁移、训练效率的核心。

有更多感悟以及有关大模型的相关想法可随时联系博主深层讨论,我是Fanstuck,致力于将复杂的技术知识以易懂的方式传递给读者,热衷于分享最新的人工智能行业动向和技术趋势。如果你对大模型的创新应用、AI技术发展以及实际落地实践感兴趣,那么请关注Fanstuck,下期内容我们再见!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 一、要弄懂算子,得抓住两个本质
    • ① 算子是深度学习中最小的“可执行计算单元”。
    • ② 算子是“抽象概念”和“硬件指令”之间的桥梁。
  • 二、算子在深度学习框架中的位置
    • 1.你写的是“剧本”
    • 2. 框架会把剧本翻成“计算图”
    • 3. 计算图会被“映射”(Mapping)成对应的算子
    • 4.算子翻译成 Kernel
  • 5. 硬件执行 Kernel,数据在算子间流动
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档