tensorflow计算图的底层原理

要搞懂计算图的底层原理,核心是拆解它的 "三步走流程":构建图 → 优化图 → 执行图 。我们就用你之前的核心例子(a_regular_function 函数),一步步扒开底层到底做了什么------全程不脱离代码,每个底层操作都对应到具体函数逻辑。

先重申例子的核心运算(方便对照):

python 复制代码
def a_regular_function(x, y, b):
  x = tf.matmul(x, y)  # 运算1:矩阵乘法(x是2D张量,y是2D张量)
  x = x + b            # 运算2:加法(矩阵+标量,广播机制)
  return x

# 输入张量:x1(1×2)、y1(2×1)、b1(标量)
x1 = tf.constant([[1.0, 2.0]])
y1 = tf.constant([[2.0], [3.0]])
b1 = tf.constant(4.0)

一、先明确计算图的"底层组成单元"

计算图的本质是 "无状态的运算依赖图",底层由3个核心部分构成,对应例子拆解:

组成单元 通俗理解 例子中的具体对应
节点(Node) 一个"运算指令"(比如乘法、加法),是图的"操作单元" 2个节点:tf.matmul 节点、+ 节点
边(Edge) 节点间的"数据依赖",传递的是张量(Tensor) 3条边: 1. x1 → tf.matmul(输入边) 2. y1 → tf.matmul(输入边) 3. tf.matmul的输出 → +(中间边) 4. b1 → +(输入边) 5. +的输出 → 函数返回(输出边)
张量(Tensor) 边传递的数据(不可变),是图的"数据单元" 输入张量(x1、y1、b1)、中间张量(tf.matmul的结果)、输出张量(最终x)

简单说:计算图就是把"运算"和"数据依赖"用"节点-边"的结构固定下来,形成一份"不可修改的运算说明书"

二、计算图的底层三步骤(对应例子拆解)

当你调用 tf.function 包装后的函数时,底层会按以下三步执行(这就是"图执行"的核心):

第一步:构建图(Graph Construction)------ 扫描函数,画"运算说明书"

这一步的核心是:tf.function 不执行函数里的运算,只扫描其中的 TensorFlow 操作,记录"谁依赖谁",最终画出计算图

对应例子的构建过程:

  1. tf.function 会"读"a_regular_function 的代码,发现两个 TensorFlow 操作:tf.matmul+
  2. 分析依赖关系(谁必须在谁之前执行):
    • 要算 x + b,必须先拿到 tf.matmul(x, y) 的结果(因为 xtf.matmul 更新了);
    • 所以依赖顺序是:x1、y1 → tf.matmul → 中间结果 → +(b1) → 最终输出
  3. 按照这个依赖,创建计算图的节点和边:
    • 节点1:tf.matmul,标记输入为"x的占位、y的占位",输出为"中间矩阵";
    • 节点2:+,标记输入为"中间矩阵、b的占位",输出为"最终矩阵";
    • 边:连接 tf.matmul 的输出 → + 的输入,形成完整流程;
  4. 注意:这一步完全不做任何数值计算 !比如 tf.matmul(x1, y1) 不会真的算出 [[1*2 + 2*3]] = [[8.0]],只是记录"要做这个乘法",以及它的输入输出是什么。

关键细节:第一次调用 a_function_that_uses_a_graph(x1, y1, b1) 时,会触发这个"构建图"的过程(所以第一次调用稍慢,叫"热身");之后再调用时,会直接复用已构建好的图,不再重新扫描函数。

第二步:优化图(Graph Optimization)------ 给"运算说明书"瘦身提速

这是计算图的核心优势之一!TensorFlow 有一个专门的"优化器"(Graph Optimizer),会对第一步构建的原始图做"等价变形",目的是 减少运算次数、降低内存开销、适配硬件(CPU/GPU/TPU)

对应例子的优化过程(底层会做这些操作):

  1. 常量折叠(Constant Folding)
    • 例子中 y1[[2.0], [3.0]])和 b14.0)是常量张量,优化器会提前计算"常量相关的固定逻辑"------比如知道 y1 是固定的2×1矩阵,会在图中直接记录它的形状,避免执行时再解析;
    • 极端情况:如果 x 也是常量,优化器会直接把 tf.matmul(x, y) + b 的结果算出来,图中只剩下一个"输出常量"的节点(彻底省去运算)。
  2. 运算融合(Operator Fusing)
    • 原始图是"matmul → +"两个独立节点,优化器会把它们融合成一个"matmul + add"的复合节点;
    • 好处:减少节点间的张量传递开销(不用先把 matmul 的结果存到内存,再读出来做加法),GPU 执行时能一次性完成,速度更快。
  3. 形状推断(Shape Inference)
    • 优化器会提前推断所有张量的形状:x1(1×2) × y1(2×1) → 中间结果(1×1),再加上 b1(标量,广播成1×1),最终输出(1×1);
    • 好处:执行时不用再检查张量形状是否匹配,避免运行时错误,同时让硬件提前分配内存。

优化后的图,本质还是"做 matmul + add",但流程更精简、执行效率更高------这就是"图执行"比"即时执行"快的核心原因。

第三步:执行图(Graph Execution)------ 按优化后的"说明书"算结果

这一步才是真正做数值计算的阶段,底层流程是:

  1. 把输入张量(x1、y1、b1)"喂"给优化后的图的"输入占位"(对应第一步构建图时的"x占位、y占位、b占位");
  2. 硬件(CPU/GPU)按图的节点顺序(优化后的顺序,比如融合后的"matmul+add"节点)执行运算:
    • 先算 x1 × y1 = [[1*2 + 2*3]] = [[8.0]](matmul 部分);
    • 再算 8.0 + 4.0 = 12.0(add 部分);
  3. 把最终结果([[12.0]])从图的"输出边"返回。

关键对比:即时执行(普通函数)是"逐行解析→执行→解析→执行",每次调用都要重复解析和执行;而图执行是"一次构建+优化,多次复用执行" ------后续再调用 a_function_that_uses_a_graph(x2, y2, b2) 时,直接跳过第一步和第二步,只用把新的 x2、y2、b2 喂给已优化的图,直接执行第三步,速度极快。

三、用"对比表"看清底层差异(普通函数 vs tf.function)

为了让你更直观理解"底层做了什么",我们对比普通函数(即时执行)和 tf.function(图执行)的底层流程:

执行步骤 普通函数(a_regular_function) tf.function 包装后的函数(图执行)
每次调用时 1. 解析 tf.matmul(x, y) → 执行 → 得到结果; 2. 解析 x + b → 执行 → 得到结果; 3. 返回结果。 1. 第一次调用: - 扫描函数 → 构建图; - 优化图; - 执行图 → 返回结果; 2. 后续调用: - 直接复用优化后的图 → 执行 → 返回结果。
底层核心 无图,"边解析边执行",无优化 有图,"一次构建优化,多次执行",有多层优化
速度关键 每次都要解析操作,速度慢(尤其调用次数多) 复用图,跳过解析和优化,速度快(模型越大、调用越多,优势越明显)

四、总结:计算图的底层原理一句话概括

tf.function 包装函数后,底层会先 "扫描函数里的 TensorFlow 操作,按依赖关系构建原始计算图" ,再通过优化器 "给图瘦身提速(常量折叠、运算融合等)" ,最后 "用输入张量喂给优化后的图,执行运算并返回结果"------后续调用直接复用优化图,省去重复构建和解析的开销,这就是计算图的核心原理。

相关推荐
那个村的李富贵7 小时前
光影魔术师:CANN加速实时图像风格迁移,让每张照片秒变大师画作
人工智能·aigc·cann
腾讯云开发者8 小时前
“痛点”到“通点”!一份让 AI 真正落地产生真金白银的实战指南
人工智能
CareyWYR8 小时前
每周AI论文速递(260202-260206)
人工智能
hopsky9 小时前
大模型生成PPT的技术原理
人工智能
禁默10 小时前
打通 AI 与信号处理的“任督二脉”:Ascend SIP Boost 加速库深度实战
人工智能·信号处理·cann
心疼你的一切10 小时前
昇腾CANN实战落地:从智慧城市到AIGC,解锁五大行业AI应用的算力密码
数据仓库·人工智能·深度学习·aigc·智慧城市·cann
AI绘画哇哒哒10 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
数据分析能量站10 小时前
Clawdbot(现名Moltbot)-现状分析
人工智能
那个村的李富贵10 小时前
CANN加速下的AIGC“即时翻译”:AI语音克隆与实时变声实战
人工智能·算法·aigc·cann
二十雨辰10 小时前
[python]-AI大模型
开发语言·人工智能·python