PyTorch 2.x 深度学习专题【左扬精讲】—— PyTorch vs TensorFlow:面试复盘
PyTorch 2.x 深度学习专题【左扬精讲】—— PyTorch vs TensorFlow:面试复盘
前几天面试,面试官问了一道经典问题:"PyTorch 和 TensorFlow 有什么区别?为什么 PyTorch 在学术界更流行?"
当时我虽然能答上来一些,但不够系统全面。回来之后花了点时间深入研究,决定把这次复盘的成果整理成文——既是对自己的沉淀,也希望能帮到有同样困惑的读者。
在深度学习领域,PyTorch 和 TensorFlow 是当之无愧的两大主流框架。
根据多项调研数据,PyTorch 在学术论文中的采用率已超过 70%,而 TensorFlow 凭借 Google 的背书在工业部署领域仍占据重要地位。
本文将从历史演进、设计哲学、API 风格和生态格局四个维度,系统性地梳理这两大框架的起源、发展与竞争格局,帮助读者真正理解 "为什么 PyTorch 在研究领域更受欢迎" 这一现象背后的深层原因。
深度学习框架 PyTorch TensorFlow 框架演进 生态格局
学习重点提示
本篇深入探讨 PyTorch 和 TensorFlow 两大框架的核心知识。以下是每个主题你需要掌握的深度说明:
框架演进史(What & How & Why):
- What:概念定义——两大框架分别继承自哪个前身,各自的核心设计哲学是什么
- How:能说出 TensorFlow 1.x 的静态图与 Session 机制,PyTorch 的动态图与 Eager Execution,以及两者的演进路径
- Why:理解 "为什么框架要这样演进"——没有动态图 PyTorch 在研究领域会遇到什么瓶颈,没有 Eager Execution TensorFlow 为什么被批评难用
编程模型差异(What & How & Why):
- What:概念定义——define-and-run vs define-by-run,计算图构建时机与执行时机的本质区别
- How:能写出 TensorFlow 1.x 的 Placeholder + Session 代码,能写出 PyTorch 的直观 Python 代码,能区分两种模型的控制流处理方式
- Why:理解 "为什么研究需要动态图"——没有动态图,循环神经网络、注意力机制等动态结构如何调试,为什么静态图的调试成本更高
生态格局与流行度(What & How & Why):
- What:概念定义——PyTorch 在学术领域的统治地位,TensorFlow 在部署领域的历史优势,以及 Hugging Face Transformers、ONNX 等生态组件
- How:能区分"框架选择"与"场景需求"的关系,能说出 Tesla Autopilot、OpenAI GPT、 Hugging Face 等明星项目为何选择 PyTorch
- Why:理解 "框架流行度背后的逻辑"——没有开放的生态,框架如何获得开发者社区的持续贡献,没有易用性优势,PyTorch 如何吸引学术研究者
阅读前提 & 建议:
- 前置知识:建议了解基本的深度学习概念(神经网络、前向传播、反向传播),但不要求有框架使用经验
- 不涉及的内容:具体的模型实现细节(如 ResNet、VGG 的代码)、分布式训练的高级配置、TensorRT 等推理优化工具
- 深度预期:学完本篇后,你能说出两大框架的历史渊源,能区分静态图与动态图的本质差异,能解释 PyTorch 在学术界更流行的深层原因
- 后续延伸:PyTorch 基础 → PyTorch 进阶(torch.compile、Distributed) → 部署优化(ONNX、TensorRT)
目录导航
一、前世今生:框架起源与技术血脉
What — TensorFlow 与 PyTorch 的前身是什么?它们分别继承了哪些技术遗产?
要理解两大框架的设计哲学,必须回溯它们的 "血统"。TensorFlow 继承自 Google 内部的 DistBelief,PyTorch 则脱胎于 Lua 语言的 Torch,两者走了截然不同的技术路线。
Why — 为什么框架需要 "前身"?这些前身解决了什么问题,又留下了什么局限?
问题一:为什么需要深度学习框架?
手工编写神经网络意味着要手动实现矩阵乘法、梯度计算等底层数学操作。框架的核心价值在于:提供自动微分(Automatic Differentiation)能力,让研究者专注于模型结构设计,而非底层数学推导。
没有框架会发生什么?
-
- 梯度计算极易出错:手动实现反向传播时,链式法则的任何一个环节出错都会导致训练失败
- 代码无法复用:不同论文的代码结构差异巨大,社区难以共享
- GPU 利用率低下:手动管理 CUDA 内存分配效率极低
TensorFlow 的前身:DistBelief
Google Brain 团队在 2011 年开发了 DistBelief,这是一个专注于大规模分布式训练的内部框架。DistBelief 的设计目标是在数千台服务器上高效运行深度学习模型,因此采用了 "静态计算图" 的设计——所有计算逻辑在运行前就必须完全定义好。
DistBelief 的核心概念包括:
-
- Downpour SGD:异步随机梯度下降,支持大规模分布式训练
- Model Parallelism:将模型拆分到不同设备上
PyTorch 的前身:Torch
Torch 由 Ronan Collobert 于 2001 年开发,最初使用 C++ 和 Lua 语言编写。Torch7(LuaTorch)在学术社区有广泛使用,但 Lua 语言的生态限制了它的普及。2016 年,Soumith Chintala 领导的团队在保留 Torch 核心自动微分引擎(torch-autograd)的基础上,用 Python 重写了前端。
关键借鉴:Chainer 的动态图设计
PyTorch 的动态图设计灵感直接来自 Chainer(2015 年),后者是最早采用"动态计算图"的主流框架。Chainer 提出"Define-by-Run"(运行时定义)理念:计算图在执行时动态构建,而非预先定义。这一思想被 PyTorch 完美继承并进一步优化。
二、设计哲学:静态图与动态图的核心博弈
What — 什么是静态计算图和动态计算图?它们在技术实现上有何本质区别?
TensorFlow 1.x 采用静态图(Static Computation Graph),也称为 "Define-and-Run";PyTorch 采用动态图(Dynamic Computation Graph),也称为 "Define-by-Run"。这两种模型的本质区别在于:计算图的构建时机与执行时机是分离还是合一。
Why — 为什么会有两种截然不同的设计哲学?各自的设计目标是什么?
静态图的设计目标:性能与跨平台部署
Google 开发 TensorFlow 时,核心诉求是 "将模型从研究快速迁移到生产"。静态图允许框架在执行前对整个计算图进行分析和优化:
-
- 算子融合(Operator Fusion):将多个操作合并为一个 kernel,减少内存访问
- 常量折叠(Constant Folding):在编译时计算常量表达式
- 跨设备调度优化:提前规划 GPU/CPU 之间的数据传输
动态图的设计目标:研究与调试友好
PyTorch 的设计者 Soumith Chintala 在访谈中提到:研究者最需要的是 "所见即所得" 的编程体验。动态图让每一行 Python 代码的执行结果都可以立即检查,这与 Jupyter Notebook 的交互式理念完美契合。
没有动态图会发生什么?
-
- 调试困难:静态图需要额外的调试工具(如 tf.debugging),无法直接使用 Python 的 print 语句
- 控制流复杂:if/else、for 循环等 Python 原生控制流无法直接使用,需要引入 tf.cond、tf.while_loop
- 开发周期长:每次修改模型结构都需要重新构建图,执行,再检查结果
TensorFlow 1.x 静态图写法
在 TensorFlow 1.x 中,你需要先定义计算图,再通过 Session 执行:
import tensorflow as tf
# 第一步:构建计算图(定义阶段)
x = tf.placeholder(tf.float32, shape=[None, 784]) # 输入占位符
y = tf.placeholder(tf.float32, shape=[None, 10]) # 标签占位符
W = tf.Variable(tf.random_normal([784, 10])) # 权重变量
b = tf.Variable(tf.zeros([10])) # 偏置变量
pred = tf.matmul(x, W) + b # 前向传播
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) # 损失
optimizer = tf.train.AdamOptimizer(0.01).minimize(loss) # 优化器
# 第二步:通过 Session 执行(运行阶段)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # 初始化变量
# 训练循环
for batch_x, batch_y in batches:
_, loss_val = sess.run([optimizer, loss], # 执行优化器和损失计算
feed_dict={x: batch_x, y: batch_y})
注意:Placeholder 和 Variable 的概念在 TensorFlow 1.x 中至关重要——Placeholder 是图的输入接口,Variable 是可训练的参数。
PyTorch 动态图写法
在 PyTorch 中,计算图的构建与执行是同步的:
import torch
import torch.nn as nn
# 直接定义模型(无需Placeholder)
model = nn.Sequential( # 线性层堆叠
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10)
)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01) # 优化器
criterion = nn.CrossEntropyLoss() # 损失函数
# 训练循环:每一步都是纯Python代码
for batch_x, batch_y in dataloader:
optimizer.zero_grad() # 清零梯度
outputs = model(batch_x) # 前向传播:直接调用模型
loss = criterion(outputs, batch_y) # 计算损失
loss.backward() # 反向传播:自动构建图
optimizer.step() # 参数更新
print(f"Loss: {loss.item()}") # 随时打印调试信息
注意:PyTorch 的 model(batch_x) 调用会触发前向传播,同时动态构建自动微分图。
三、API 风格:从 Session 到 Eager Execution 的体验变迁
What — Eager Execution 是什么?它如何改变了 TensorFlow 的编程体验?
Eager Execution(立即执行)是 TensorFlow 从 1.x 升级到 2.x 时的核心变革。它允许 TensorFlow 操作立即返回结果,无需先构建计算图再执行,这从根本上消除了静态图与动态图的用户体验鸿沟。
Why — 为什么 TensorFlow 要在 2.0 中引入 Eager Execution?这反映了什么样的技术趋势?
问题一:TensorFlow 1.x 的"可用性危机"
2017-2018 年,PyTorch 凭借动态图的易用性迅速崛起,吸引了大量研究者转向。TensorFlow 1.x 的静态图设计虽然在性能上有优势,但 "先定义后执行" 的编程模式让新手望而却步。
问题二:Keras 的成功验证了"高级 API 的价值"
Keras(由 Francois Chollet 开发)作为 TensorFlow 的高级封装,通过简洁的 model.fit()、model.predict() 接口大幅降低了入门门槛。TensorFlow 2.0 决定将 Keras 作为官方推荐的高级 API。
没有 Eager Execution 会发生什么?
-
- 学习曲线陡峭:新人需要理解 Placeholder、Session、Graph 等概念
- 调试困难:无法使用标准 Python 调试器
- 社区流失:研究者在论文中分享 PyTorch 代码更方便,导致 TF 社区影响力下降
TensorFlow 2.x 通过 Eager Execution 实现了 "两全其美":动态图的易用性 + 静态图(tf.function)的性能:
import tensorflow as tf
# 方式一:纯 Eager 模式(与 PyTorch 体验类似)
model = tf.keras.Sequential([ # Keras 高级 API
tf.keras.layers.Dense(256, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10)
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
# 训练:类似 sklearn 的 fit 接口
model.fit(train_data, epochs=5)
# 方式二:tf.function 加速(可选优化)
@tf.function # 装饰器:将函数编译为静态图
def train_step(x, y):
with tf.GradientTape() as tape:
predictions = model(x, training=True)
loss = loss_fn(y, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss
注意:@tf.function 装饰器可以将 Python 函数 JIT 编译为 TensorFlow 图,既保留 Python 语法,又获得图执行性能。
四、演进路径:TensorFlow 2.x 与 PyTorch 2.0 的殊途同归
What — 两大框架在 2.0 时代各自引入了什么新特性?它们的技术路线是否趋同?
2019 年 TensorFlow 2.0 和 2023 年 PyTorch 2.0 的发布标志着两大框架进入了 "相互借鉴" 的新阶段。
TensorFlow 引入了 Eager Execution,PyTorch 引入了 torch.compile——两者都在尝试兼得动态图的灵活性与静态图的性能。
Why — 为什么两大框架最终走向了"功能融合"?这反映了深度学习框架的哪些设计真理?
设计真理一:"没有银弹"
静态图在生产部署场景有优势(优化空间大、可导出为 TFLite/ TensorRT),动态图在研究场景有优势(调试方便、代码直观)。两者的取舍本质上是 "灵活性 vs 性能" 的权衡。
设计真理二:"用户不应该为选择付出代价"
现代框架的设计趋势是:让用户同时拥有动态图和静态图的能力,由框架自动决定何时使用哪种模式,而非强迫用户做非此即彼的选择。
TensorFlow 2.x 的核心变化
| 特性 | TensorFlow 1.x | TensorFlow 2.x |
|---|---|---|
| 默认执行模式 | 静态图(Session) | Eager Execution |
| 高级 API | 独立 Keras(可选) | 官方集成 tf.keras |
| 变量共享 | tf.variable_scope + reuse | Python 原生作用域 |
| API 一致性 | 混乱(tf.* 分散) | tf.keras 统一封装 |
PyTorch 2.0 的核心变化
PyTorch 2.0 引入了 torch.compile,使用 TorchDynamo 实现 Python 级别的 JIT 编译:
import torch
model = MyModel().cuda()
# 不使用 torch.compile:动态图执行
output = model(inputs)
# 使用 torch.compile:将模型编译为优化后的图
compiled_model = torch.compile(model)
output = compiled_model(inputs) # 首次调用触发编译
torch.compile 的性能收益:根据官方 benchmark,在 A100 GPU 上,使用 torch.compile 的训练速度最高可提升 2 倍。
五、生态格局:为什么 PyTorch 在研究领域更流行
What — PyTorch 在学术论文和开源项目中的采用率如何?它的生态护城河是什么?
截至 2024 年,PyTorch 在 arXiv 论文中的使用率超过 70%,在 GitHub 顶级深度学习项目中占比超过 60%。 Hugging Face Transformers(PyTorch 实现为主)、PyTorch Lightning、torchtext 等生态组件进一步巩固了 PyTorch 的领先地位。
Why — PyTorch 的"研究霸权"是如何形成的?生态系统为什么比单纯的技术优劣更重要?
原因一:学术论文的正向循环
研究者使用 PyTorch 发表论文 → 代码开源后社区复用 → 新研究者学习 PyTorch → 更多 PyTorch 论文。这个正向循环使得 PyTorch 在 2018-2020 年间迅速建立学术领域的统治地位。
原因二:Hugging Face 的战略选择
Hugging Face 选择 PyTorch 作为 Transformers 库的主要实现框架(后支持 TensorFlow/JAX)。作为 NLP 领域的 "标配" 库,Hugging Face 的选择影响了大批 AI 研究者。
原因三:Tesla Autopilot 的示范效应
Andrej Karpathy 在 2017 年将 Tesla 的Autopilot 团队从 TensorFlow 迁移到 PyTorch,这一决定被视为 PyTorch 工业落地能力的有力背书。
没有生态优势会发生什么?
-
- 框架孤岛化:缺乏预训练模型库、工具链支持
- 社区贡献减少:开发者倾向于使用有更多教程和开源代码的框架
- 人才招聘成本上升:企业需要培训员工使用特定框架
Hugging Face Transformers
Transformer 架构的 "一站式" 实现库,提供 BERT、GPT、T5 等预训练模型:
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("bert-base-uncased") # 加载预训练模型
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
inputs = tokenizer("Hello, world!", return_tensors="pt") # 分词
outputs = model(**inputs)
PyTorch Lightning
简化训练循环的元框架,将工程样板代码(分布式训练、混合精度、日志记录)与研究逻辑分离:
import pytorch_lightning as pl
class MyModel(pl.LightningModule):
def training_step(self, batch, batch_idx): # 只需定义单步逻辑
x, y = batch
loss = self.forward(x, y)
return loss
trainer = pl.Trainer(max_epochs=10, accelerator="gpu")
trainer.fit(model, train_dataloader)
ONNX 生态
Open Neural Network Exchange(2017 年由 Meta 和 Microsoft 推出)实现了跨框架模型转换,使得 PyTorch 模型可以导出到 TensorFlow、ONNX Runtime、TensorRT 等平台进行推理部署。
六、总结与展望:框架选择的思考框架
核心结论
-
- 历史渊源:TensorFlow 继承自 DistBelief(静态图基因),PyTorch 继承自 Torch + Chainer(动态图基因)
- 核心差异:静态图(define-and-run)vs 动态图(define-by-run),本质是 "构建时机与执行时机是否合一"
- 演进方向:两大框架都在 2.0 时代走向融合——TensorFlow 引入 Eager,PyTorch 引入 torch.compile
- 流行原因:PyTorch 的研究霸权源于动态图的调试友好性 + Hugging Face 等生态的正向循环
选择建议
-
- 学术研究 / 快速原型:优先选择 PyTorch
- 大规模生产部署 / 移动端:考虑 TensorFlow + TFLite
- 已有代码库迁移:评估迁移成本 vs 收益
- 团队技能储备:选择团队最熟悉的框架
FAQ(常见问题)
以下是关于 PyTorch 与 TensorFlow 区别的 20 组常见 Q&A:
Q1. TensorFlow 和 PyTorch 哪个更适合初学者?
一句话结论:如果是零基础入门深度学习,两个框架的学习曲线已经非常接近,但 PyTorch 的教程生态更丰富。 TensorFlow 2.x 通过 Keras 提供了类似 scikit-learn 的简洁接口(model.fit),PyTorch 需要理解 tensor、autograd 等概念后才能上手训练。从代码直观性看,PyTorch 更接近"纯 Python"风格。
Q2. 为什么 PyTorch 在学术论文中更流行?
一句话结论:因为 PyTorch 的动态图让研究者可以快速实验、调试和迭代,而这正是学术研究的核心需求。 学术场景需要频繁修改模型结构、打印中间变量、使用 Jupyter Notebook 交互式调试——这些都是 PyTorch 的强项。此外,Hugging Face Transformers 的 PyTorch-first 设计也影响了 NLP 领域的研究者选择。
Q3. TensorFlow 为什么在工业部署领域仍有优势?
一句话结论:TensorFlow 拥有更完善的部署工具链(TFLite、TensorFlow Serving、TensorFlow.js),Google Cloud 对 TensorFlow 的原生支持也降低了企业部署成本。 虽然 PyTorch 通过 ONNX 和 TorchScript 弥补了部署短板,但在移动端和边缘设备场景,TFLite 的量化优化更加成熟。
Q4. 静态图和动态图到底有什么区别?
一句话结论:静态图在执行前构建完整的计算图,动态图在执行时实时构建。 类比来说,静态图像"先画流程图再施工",动态图像"边想边写代码"。静态图的优势是运行时开销小(构建开销只发生一次),动态图的优势是调试直观(可以直接 print)。
Q5. TensorFlow 1.x 和 2.x 的最大区别是什么?
一句话结论:TensorFlow 2.x 默认启用 Eager Execution,不再需要 Session,但通过 tf.function 提供图执行选项。 此外,TensorFlow 2.x 将 Keras(tf.keras)作为官方高级 API,统一了之前分散的 API(如 tf.layers、tf.metrics、tf.losses)。
Q6. PyTorch 2.0 的 torch.compile 是什么?
一句话结论:torch.compile 是 PyTorch 2.0 的核心特性,它使用 TorchDynamo 将 Python 代码 JIT 编译为优化后的计算图,实现接近静态图的性能。 使用方式是在模型外包裹一层 compiled_model,最高可获得 2 倍训练加速。
Q7. Keras 和 PyTorch 是什么关系?
一句话结论:Keras 是 TensorFlow 的官方高级 API,PyTorch 有对应的 community 库 PyTorch Lightning,但 PyTorch Lightning 不是官方出品。 Keras 最初是独立框架(支持 TF、CNTK、Theano 后端),在 TensorFlow 2.0 中被官方收购并整合为 tf.keras。
Q8. 为什么说 PyTorch 继承自 Lua Torch?
一句话结论:PyTorch 的核心自动微分引擎(autograd)直接来自 Torch7 的 torch-autograd 项目,只是用 Python 重写了前端。 Torch 由 Ronan Collobert 于 2001 年开发,最初使用 Lua 语言。Soumith Chintala 在 2016 年用 Python 重写时保留了 Torch 的张量接口和自动微分设计。
Q9. Chainer 对 PyTorch 的影响有多大?
一句话结论:Chainer 是 PyTorch 动态图设计的直接灵感来源,PyTorch 团队多次公开承认这一点。 Chainer 于 2015 年提出了"Define-by-Run"(运行时定义网络)概念,比 PyTorch 早发布一年。PyTorch 在 2016 年实现时借鉴了 Chainer 的核心思路,并在此基础上进行了工程优化。
Q10. TensorFlow 的前身 DistBelief 解决了什么问题?
一句话结论:DistBelief 解决了 Google 内部大规模分布式训练的问题,但它的配置复杂、代码耦合度高,不适合研究使用。 DistBelief 支持在数千台服务器上并行训练深度学习模型,TensorFlow 可以视为 DistBelief 的"可扩展可维护版本"。
Q11. PyTorch 和 TensorFlow 的"性能"差距有多大?
一句话结论:在典型训练任务上,两者的性能差距已经很小,框架选择对最终性能的影响远小于数据质量、模型设计、batch size 等因素。 TensorFlow 1.x 的静态图在理论上有优化优势,但 PyTorch 的动态图通过 JIT 编译(torch.compile)已经弥补了这一差距。
Q12. 为什么 Tesla 选择 PyTorch?
一句话结论:Tesla Autopilot 团队在 Andrej Karpathy 领导下选择 PyTorch,主要因为它的调试友好性和快速迭代能力。 自动驾驶的感知系统需要频繁实验新架构,PyTorch 的动态图让工程师可以在 Jupyter 中快速测试想法。
Q13. Hugging Face 为什么选择 PyTorch?
一句话结论:Hugging Face Transformers 最初选择 PyTorch 是因为创始人 Clement Delargue 和 Thomas Wolf 来自学术背景,PyTorch 更符合研究者的使用习惯。 后来 Transformers 增加了 TensorFlow 和 JAX 支持,但 PyTorch 实现始终是默认版本。
Q14. ONNX 是什么?它解决了什么问题?
一句话结论:ONNX(Open Neural Network Exchange)是 Meta 和 Microsoft 在 2017 年推出的跨框架模型格式,解决了"用 PyTorch 训练但用 TensorRT 推理"的互通问题。 通过 ONNX,PyTorch 模型可以导出到 TensorFlow、ONNX Runtime、TensorRT 等平台。
Q15. TensorFlow Lite(TFLite)和 PyTorch Mobile 的对比?
一句话结论:TFLite 成熟度更高,支持更多硬件平台(微控制器、单片机),PyTorch Mobile 仍在快速迭代中。 TFLite 提供模型量化、运算符融合等成熟优化,PyTorch Mobile 通过 TorchScript 实现模型导出。
Q16. 如何看待"PyTorch 终将统一 TensorFlow"的观点?
一句话结论:这种观点过于乐观。TensorFlow 在企业级部署、移动端、嵌入式场景仍有不可替代的优势。 企业选择框架时会考虑长期维护成本,Google 对 TensorFlow 的持续投入保证了它的生命力。
Q17. PyTorch 的"研究霸权"会被打破吗?
一句话结论:短期内(3-5 年)PyTorch 的学术优势难以撼动,因为 Hugging Face 等生态组件已经形成了强大的网络效应。 但 JAX(Google 的 ML 框架)凭借 TPU 原生支持和函数式设计,正在吸引一部分前沿研究者。
Q18. Google 为什么同时维护 TensorFlow 和 JAX?
一句话结论:TensorFlow 面向通用深度学习(工业 + 研究),JAX 面向前沿研究和高性能计算,两者定位不同。 JAX 采用函数式编程范式,与 NumPy API 高度兼容,更受数学背景深厚的研究者欢迎。
Q19. 学习深度学习应该先学哪个框架?
一句话结论:如果是系统学习深度学习理论,建议从 PyTorch 入手(教程多、概念直观);如果目标是进入企业做部署相关工作,TensorFlow(TFLite)更有针对性。 框架只是工具,深度学习的核心知识(反向传播、优化器、架构设计)是相通的。
Q20. 未来深度学习框架的发展趋势是什么?
一句话结论:趋势是"动态图与静态图的界限进一步模糊",框架将提供更智能的自动选择机制。 未来的框架可能自动判断哪些部分需要编译为静态图以获得性能,哪些部分保持动态图以保证灵活性。
参考资源

浙公网安备 33010602011771号