# 收尾 · 从 Python 到金属，整台引擎的全景

> 把整趟漫游拼成一张图——从 Tensor 说明书，到 dispatcher、ATen 内核、autograd 引擎、nn.Module、CUDA 分配器、torch.compile。追一行 loss.backward() 穿过所有层，回望这台「披着 Python 外衣的 C++ 引擎」，并把 nanoGPT / 大模型解构 / PyTorch 三部曲收成一个整体。

- 作者：David（道雾轩）
- 专栏：PyTorch 源码漫游（https://daiw.org/manual/pytorch-internals.md）
- 最后更新：2026-07-13
- 原文：https://daiw.org/manual/pytorch-internals/recap
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 收尾 · 从 Python 到金属，整台引擎的全景

漫游到头了。我们从最底下的[一块内存](https://daiw.org/manual/pytorch-internals/tensor-and-storage)，一路爬到最上面的 [`torch.compile`](https://daiw.org/manual/pytorch-internals/torch-compile)。这一章把沿途看到的齿轮，拼成一张完整的图。

## 一张图：PyTorch 的全栈

从你敲的 Python，到 GPU 上的金属，PyTorch 大致是这样层层叠起来的：

```mermaid
flowchart TD
  user["你的代码:model(x) / loss.backward()"] --> mod["nn.Module<br/>组织参数、forward、hook"]
  mod --> compile["torch.compile(可选)<br/>Dynamo 抓图 → Inductor 编译"]
  compile --> py["Python / C++ 绑定"]
  py --> disp["dispatcher<br/>按 device/dtype/autograd 分发"]
  disp --> ag["Autograd 键<br/>前向建图 · 反向回放"]
  ag --> aten["ATen 算子 / 内核<br/>native_functions.yaml + TensorIterator"]
  aten --> data["Tensor(说明书)+ Storage(数据)"]
  data --> metal["CPU / CUDA 内核 · 缓存分配器 · 流"]
```

每一层，都是这趟漫游的一章：

- **[Tensor 与 Storage](https://daiw.org/manual/pytorch-internals/tensor-and-storage)** —— 地基：Tensor 是「怎么读一块扁平内存」的说明书(sizes/strides/offset),view/transpose 零拷贝、contiguous 的由来全在这。
- **[dispatcher](https://daiw.org/manual/pytorch-internals/dispatch-journey)** —— 中枢：按分发键把一次调用路由到正确内核；autograd、autocast 只是链上的拦截层。
- **[ATen 与内核](https://daiw.org/manual/pytorch-internals/operators-and-kernels)** —— 车间：两千多个算子靠 `native_functions.yaml` 声明 + codegen 生成 + TensorIterator 复用。
- **[autograd](https://daiw.org/manual/pytorch-internals/autograd-graph)** —— 引擎：[前向悄悄建图](https://daiw.org/manual/pytorch-internals/autograd-graph)，[反向按拓扑逆序回放、复合局部 VJP](https://daiw.org/manual/pytorch-internals/autograd-backward)。
- **[nn.Module](https://daiw.org/manual/pytorch-internals/nn-module)** —— 上层糖：靠 `__setattr__` 自动登记参数/子模块/buffer，自己不碰数学、把求导全甩给 autograd。
- **[CUDA 与显存](https://daiw.org/manual/pytorch-internals/cuda-and-memory)** —— 金属：异步入队的流、以及那个「囤内存复用」的缓存分配器。
- **[torch.compile](https://daiw.org/manual/pytorch-internals/torch-compile)** —— 加速层：架在 eager 引擎之上，能编译就编译、不能就落回地基。

## 追一行 `loss.backward()` 穿过全栈

把这些层用一次真实调用串起来，你就真的「看穿」了 PyTorch。以 nanoGPT 的一步训练为例：

1. **`logits, loss = model(X, Y)`** —— [`nn.Module.__call__`](https://daiw.org/manual/pytorch-internals/nn-module) 跑 `forward`；里面每个张量运算，都经 [dispatcher](https://daiw.org/manual/pytorch-internals/dispatch-journey) 路由，先被 **Autograd 键**拦下[记一笔账、建图](https://daiw.org/manual/pytorch-internals/autograd-graph)，再 redispatch 到 [CUDA 内核](https://daiw.org/manual/pytorch-internals/operators-and-kernels)在 [GPU 上异步执行](https://daiw.org/manual/pytorch-internals/cuda-and-memory)。前向走完，一张挂满 saved 激活的反向图，连好了。
2. **`loss.backward()`** —— [autograd 引擎](https://daiw.org/manual/pytorch-internals/autograd-backward)从 `loss` 播下种子梯度 `1`，逆着图按拓扑序回放：每个节点用链式法则算 VJP、把梯度往上游传、多路相加，最后 `AccumulateGrad` 堆进各参数的 `.grad`。图随即释放，显存回收。
3. **`optimizer.step()`** —— 优化器拿着 `.grad` 更新参数（Parameter，也就是图的叶子）。
4. **`optimizer.zero_grad()`** —— 清空 `.grad`，因为它是[累加](https://daiw.org/manual/pytorch-internals/autograd-backward)的。

**[nanoGPT 训练循环那几行](https://daiw.org/manual/nanogpt/training-loop)，你当时读的是「上层剧本」；现在，你看清了幕后每一层的运作。**

## 你带走了什么

漫游的收获，不是背下多少文件路径，而是**一套「往下看」的心智模型**。以后再碰到这些，你不再抓瞎：

- **autograd 报错**（`grad_fn`、`AccumulateGrad`、`backward a second time`）—— 你知道图是什么、什么时候建、什么时候释放。
- **CUDA OOM** —— 你知道显存被参数、优化器状态、激活、分配器囤块四坨吃掉，也知道每个省显存技巧在拧哪一坨。
- **给 GPU 代码计时不准** —— 你知道要 `synchronize`，因为调用是异步入队的。
- **想加自定义算子 / 反向** —— 你知道从 `torch.autograd.Function` 或 `native_functions.yaml` 那一层介入。
- **`torch.compile` 不提速** —— 你知道去查 graph break。

**PyTorch 从一个「大概会用」的黑箱，变成了一台你看得见齿轮、能对着某一层去调试和优化的机器。**

## 三部曲，合成一张完整的地图

到这里，三个 AI 源码专栏凑齐了，它们本就是一套：

- **[nanoGPT 源码解读](https://daiw.org/manual/nanogpt)** —— 一个**真实的模型**，六百行，逐行读懂 GPT 的本体。
- **[AI 大模型解构](https://daiw.org/manual/llm-anatomy)** —— 真实大模型在这副骨架上**改了什么**（MLA、MoE、归一化……），给你一把对比的尺子。
- **[PyTorch 源码漫游](https://daiw.org/manual/pytorch-internals)** —— 托起这一切的**引擎**，`loss.backward()` 底下到底怎么转。

**模型、模型的变体、以及跑模型的引擎——三层都看穿了。** 从此，「大模型」对你而言，不再有哪一层是纯粹的黑箱：上面是可逐行读的代码，中间是可逐条追问的设计选择，底下是可看清齿轮的引擎。

## 最后一句

PyTorch 那件 Python 外衣太好穿，好穿到你几乎忘了底下还有一台庞大的引擎。这趟漫游想留给你的，就是一种踏实：**那台引擎不神秘。它有清晰的分层、可追的源码、可讲的道理。** 需要的时候，你随时能掀开外衣，下去看看齿轮怎么咬合。

**《PyTorch 源码漫游》全篇完。** 也感谢你读完这套三部曲——愿你从此看 AI，多了一层「看得见底下」的从容。

## 参考文献

- [1] Edward Z. Yang. “PyTorch internals.” 2019. http://blog.ezyang.com/2019/05/pytorch-internals/
- [2] Paszke et al. “PyTorch: An Imperative Style, High-Performance Deep Learning Library.” NeurIPS 2019. arXiv:1912.01703.
- [3] Ansel et al. “PyTorch 2: ... Dynamic Python Bytecode Transformation and Graph Compilation.” ASPLOS 2024. DOI: 10.1145/3620665.3640366.
- 各章文末附有该章直接引用的文献与源码位置。
