完整题目
请解释PyTorch中的计算图机制,它是如何支持自动微分的?在动态计算图与静态计算图之间,PyTorch的设计有何优势和局限?
Autograd如何建图
PyTorch在eager执行每个受梯度跟踪的运算时,记录产生结果的反向节点及依赖关系。非叶子结果通常有 grad_fn;用户创建、requires_grad=True 的叶子Tensor通常 grad_fn=None,梯度累积在 .grad。并非每个Tensor都有 grad_fn。
调用 loss.backward() 时,autograd从输出沿图反向执行vector-Jacobian product,用链式法则把来自多条路径的梯度累加。自定义 torch.autograd.Function 才需要显式实现静态 forward/backward;普通用户组合内置算子即可。默认反向后中间图会释放,需要再次反向时才设置 retain_graph=True,高阶梯度则用 create_graph=True 等机制。
动态、静态与编译边界
- Eager动态图:Python控制流自然、调试直接,每次前向构造本次实际执行的图;代价可能是Python调度、算子碎片和较少的全局优化机会。
- 编译图:捕获可编译区域后可做融合、内存规划和代码生成,但动态shape、数据依赖控制流或Python副作用可能触发guard、重编译或graph break,具体能力随版本和代码变化。
- TensorFlow:TF2默认支持eager,也可用
tf.function构图;“TensorFlow就是静态图”只适合TF1或特定graph mode。JAX也通过变换和XLA编译,不应简单等同旧式TF1。