Skip to content

PyTorch底层原理

动态计算图

Tape-based

Autograd的Tape-based机制。

PyTorch 的自动求导系统(Autograd)工作起来就像一个 磁带录音机:

  • 过程: 当你执行前向传播(Forward)代码时,PyTorch 会在后台通过一个“磁带”按顺序记录下你做的每一个操作(加法、乘法、Reshape)。
  • 反向: 当你调用 .backward() 时,它就像按下“倒带播放”键,沿着这条记录反向回放,利用链式法则计算梯度。
  • 特点: 录完一次,磁带就销毁了(释放内存)。下一次迭代(Next Epoch),你会拿出一盘新磁带重新录。这就是为什么它支持 Python 的 if/else 循环——因为每次录的内容可以完全不同。

Storage/View分离

这是 PyTorch 高效处理数据的核心,也是初学者最容易踩坑的地方(比如修改了 View 导致原数据变了,或者报错 contiguous)。

  • 原理: 一个 Tensor 在内存里其实分成了两部分:
    1. Storage (仓库): 一维的、连续的数字数组。这是真正存数据的地方。
    2. Metadata (元数据/视图): 记录形状(Size)、步长(Stride)、偏移量(Offset)。这决定了你“看起来”这个 Tensor 是什么样的。
  • 举例: 当你调用 .view().reshape() 改变形状时,PyTorch 并没有在内存中搬运数据! 它只是创建了一个新的“元数据头”,指向同一个 Storage,只是解读方式变了(比如把“2x3”解读为“3x2”)。
  • 为什么重要:
    • 极快: 改变形状几乎不消耗时间,因为不拷贝数据。
    • 坑: 如果你修改了新 Tensor 的值, 旧 Tensor 的值也会变 (因为它们共用仓库)。这也解释了为什么有时候你需要调用 .contiguous() —— 也就是强迫 PyTorch 真的拷贝一份数据出来,不再共用老仓库。

Imperative Programming

PyTorch 并没有试图创造一种新的“图语言”,而是直接寄生在 Python 解释器之上:

  • PyTorch 的对象就是 Python 的对象。
  • PyTorch 的报错栈就是 Python 的报错栈。
  • 它利用 Python 的引用计数机制来管理内存。

Explicit Device Management

这是 PyTorch 与其他框架(如 Keras)的一个显著区别原理。

  • 原理: “你不动,我不动”。 PyTorch 默认数据都在 CPU 上,它绝不会自动帮你把数据移到 GPU,除非你显式地写代码要求它这么做。
  • 代码体现: .to('cuda').cuda()
  • 设计哲学: 这种设计虽然增加了代码量(你需要自己管理 device),但它给了开发者对硬件行为的 绝对控制权 。你知道每一块显存是什么时候被占用的,避免了“黑盒”带来的性能隐患。

评论 #