

如果你去问十个做深度学习的工程师:“算子是什么?”
大多数人可能会回答:“就是 MatMul、ReLU 这些嘛。”
听起来好像简单,但要是真的用一句话解释清楚 —— 很难。因为算子不是某个函数,也不是某段 Python 代码,它更像是深度学习世界里“最小执行单元”的一种抽象。

为了避免抽象,我们换一种最接地气的方式来理解:
算子就像做菜时的动作。
切、炒、翻、焖、撒盐——这些都是厨房里的基本动作。
不管你想做宫保鸡丁还是红烧肉,最终都要由这些动作组合来实现。

深度学习模型也是一样的。不管你写的是 CNN、Transformer、LLM 还是 OCR 模型,本质上都是一个个算子的组合,比如:
模型结构再高大上,最终都要回到这些“动作”来执行。

但这里有一个更关键的误区需要拆开: 算子不是你写在 Python 里的那段代码。
就像“翻炒”不是厨师口头描述的步骤,而是真正落在锅里的那套动作。
你写 torch.relu(x),只是告诉 PyTorch: “我要用 ReLU 这个动作。”
但 PyTorch 会做的事情是:
先查 GPU 里有没有 ReLU 对应的 kernel? 如果你用的是昇腾 NPU,它会查 CANN 提供的 ReLU 实现? 如果你用的是 CPU,它会找 MKL、OpenMP 的优化版本?
也就是说: 算子的本体不是 Python 实现,而是最终被硬件执行的计算核(kernel)。
换个更工程化的说法你就明白了:

你写指令,框架理解剧情,但真正执行的人,是算子。
这也是为什么大模型部署到不同硬件上,就像同一部电影找不同动作演员演会出现“动作不一样”“动作做不出来”的情况。比如你把 HuggingFace 的模型丢到昇腾上,有时会遇到:
“xxx 算子不支持”
这不是什么 bug,而是因为: 昇腾上没有这个算子的实现。
为了避免概念漂浮,我把算子的本质压到两个最关键的观念:
它不是某个函数,而是更底层的:
模型执行的时候,都是这些原子操作。
如果一个模型有 200 层,那么可能需要执行几千到几万个算子。
而在大模型训练中,这种算子会在一次 forward/backward 中被重复使用数万亿次。
你写的是抽象的数学公式:
但 GPU/昇腾真正执行的是:
算子把“你想要的结果”和“硬件能够执行的动作”打通。
如果没有算子,那深度学习框架就像一个只会写小说的人,面对 GPU 这个“只说汇编语言的工人”完全没法沟通。
假设你跑一个简单的 Transformer Attention,代码可能只有几行:
attn = softmax(Q @ K.T) @ V看着简单对吧? 但你知道底层跑了多少个算子吗?

每个算子背后,可能还分成几十个 kernel 执行:
而当你说:
“FlashAttention 让推理快 2~4 倍”
它本质上就是: 把原本多个算子 + 多个访存步骤 → 合并成一个更高效的算子。
这就是算子的力量 —— 既决定模型能不能跑,又影响模型跑得快不快。

如果说前面告诉你算子是什么、为什么重要,那么接下来这章要回答一个更关键的问题:
算子到底在深度学习框架里处于什么地位?
很多工程师学 PyTorch、TensorFlow 或 JAX 时,会自然觉得:
“我写了代码,框架帮我算,GPU 自动跑。”
但这个感觉容易误导你以为框架是“直接”在 GPU 上执行你写的 Python 代码。
实际上,Python 只是“给框架写了个故事”,而真正把故事变成动作的,是算子。

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

你写的 PyTorch 模型、TensorFlow 计算、JAX 程序,就像写了一段剧本:
y = torch.relu(x @ W + b)这段代码只告诉框架:
它并不会告诉 GPU 如何执行。像 PyTorch、TensorFlow、MindSpore 等框架会把你的代码解析成一个所谓的 计算图(Computation Graph)。
框架会把剧本翻成“计算图”
你可以把它理解为: 把你的剧情拆成“动作节点”和“数据流向”。
我们的这段代码会变成:
x @ W ——> Add ——> ReLU ——> y这就是计算图。 也就是说,你写的所有模型结构,本质就是一张巨大的、有向的动作图。

像 PyTorch、TensorFlow、MindSpore 等框架会把你的代码解析成一个所谓的 计算图(Computation Graph)。
你可以把它理解为: 把你的剧情拆成“动作节点”和“数据流向”。
我们的这段代码会变成:
x @ W ——> Add ——> ReLU ——> y这就是计算图。 也就是说,你写的所有模型结构,本质就是一张巨大的、有向的动作图。

框架接下来的工作不是直接让 GPU 执行,而是:
在它支持的算子库里,寻找对应的算子。
比如 PyTorch 会去查:
如果你换到昇腾 NPU:
这一步非常关键,因为:
框架不负责做计算 它只负责找到“能做这个计算的人”。

算子看起来是抽象的动作: “做一次矩阵乘法”“做一次卷积”“执行一次 Softmax”
但它最终会落成一段非常底层的 kernel(内核指令),这段代码:
Kernel 才是硬件真正执行的对象。
如果算子是“动作指令”, 那么 kernel 是“具体动作流程”。
最后一步才轮到 GPU/NPU 出场。
它们不会去看你写的 Python,不看模型结构,不看抽象公式,只负责一件事:
“你给我什么 Kernel,我照着执行。”
执行过程中,训练/推理的数据会在算子之间流动,就像流水线上的物料一样被一步步加工,最终得出结果。
把整个链路放在一起看,你会发现一个非常朴素的事实
模型看起来神秘,但本质上就是:

而在这一整条链路中,只有算子是“真正执行的人”。
框架负责组织和调度,算子负责实际计算,硬件负责跑算子。
假设你做一个简单的 MLP 推理,Python 只写了两行:
x = torch.matmul(x, W)
y = torch.relu(x)你以为执行了两行代码,但实际情况是:
看似简单的 ReLU,其实底层也要调度 kernel、控制线程、做访存优化。
这也是为什么你越深入推理优化,就越容易听到:
“这个算子太慢了,得换一个。” “这个算子在 GPU 上有优化版本。” “昇腾上这个算子要用 TBE 自定义。”
因为算子是这个世界里最接近硬件的那一层, 也是整个性能、兼容性、跨硬件迁移、训练效率的核心。
有更多感悟以及有关大模型的相关想法可随时联系博主深层讨论,我是Fanstuck,致力于将复杂的技术知识以易懂的方式传递给读者,热衷于分享最新的人工智能行业动向和技术趋势。如果你对大模型的创新应用、AI技术发展以及实际落地实践感兴趣,那么请关注Fanstuck,下期内容我们再见!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。