📑 本页目录(点开跳转)
00 · 怎么用这份教程
⏱ 32 分钟 | ⭐ 先划清三条线:一套教你用,一套教你扩,这一套只讲框架自己
🎯 一句话
这一套不教你训模型,也不教你把训练铺到几百张卡上 —— 它只回答一个问题:torch 这个包自己是怎么运转的,以及它为什么会用那种方式报错。
判据只有一句:换个框架就不成立的知识放这里;换个框架照样成立的(显存账、并行策略、KV Cache)在别处;「十分钟先跑起来」也在别处。
⏱ 先说清楚这套的章比站内其他板块长(普遍 50–120 分钟,站内其他板块的中位是 30)—— 因为每个知识点都带实跑代码和真实报错,压不下去。设计上就没打算让你一次读完: 超过 55 分钟的章在中间有 🛑 休息点,最长的几章有两个,停在那里下次接着读就行。 徽章是按 170 字/分钟实测校准的,宁可吓到你,也不骗你。
🧩 一、三条线,别走错门
站内讲 PyTorch 的地方不止一处,但它们回答的是三个不同的问题。走错门会浪费时间:
| 你现在想干的事 | 去哪 | 那边给你什么 |
|---|---|---|
| 「我要训一个模型,给我能抄的模板」 | ML 基础 15 | 完整训练循环、损失函数配对表、六个高频 Bug、提速三件套 |
| 「模型太大 / 太慢 / OOM 了」 | AI 基础设施 | 显存账、混合精度、ZeRO、张量并行、KV Cache、算子融合 |
| 「它凭什么这么报错 / 这行代码到底改了什么」 | 这里 | 张量的内存与说明书、autograd 的图、就地操作、state_dict、nn.Module 内部 |
⭐ 一句话记法: 15 章教你「用」,AI 基础设施教你「扩」,这一套讲「框架自己」。
🚦 这一套为什么值得单开
不是因为「PyTorch 很重要」—— 那不算理由。是因为站内有一批东西一直在被用,却没有一页解释过它:
| 东西 | 站内现状 |
|---|---|
retain_graph |
全站 0 次命中 |
autograd.Function |
全站 0 次命中 |
state_dict |
6 个文件在用,⚠️ 全部在代码块内部,没有一页说过它到底装了什么 |
.eval() |
6 个文件在用,唯一的解释是一句警告「忘了 model.eval()」 |
detach() |
7 个文件在用;ML 基础附录 A 有一行词条「切断梯度」,⚠️ 但没有一页说清 no_grad 和 detach 断的不是同一个东西 |
register_buffer |
只有 2 处,两处都在代码里裸用 |
⭐ 这就是本套的选题标准:「被用了、没被讲」。不是「知识很重要」。
🧯 明确不做的五件事
写在开头,免得你读到一半发现期待落空:
| 不做 | 因为 |
|---|---|
| 训练循环怎么写、损失函数怎么选 | ML 基础 15 有一份实测可跑的模板,抄那个 |
| 混合精度 / ZeRO / FSDP / 张量并行 / KV Cache / FlashAttention | 全在 AI 基础设施,那边讲得更深 |
torch.profiler / Roofline / MFU |
AI 基础设施 04、07 |
DataLoader 的六个参数怎么调 |
AI 基础设施 22 已讲透吞吐与存储;本套 08 章只讲 worker 是另一个进程 这件事 |
stride 的机制、.contiguous() 的急救写法 |
stride 归 NumPy 与向量化思维 05;急救写法在 ML 基础附录 C。本套只引用,不重讲 |
🧩 二、章节地图(11 章 + 附录 A)
| 章 | 讲什么 | ⏱ | 一句话 |
|---|---|---|---|
| 00 | 怎么用这份教程 | 32 | 你正在读的这一章 |
| 01 | 张量:一块内存 + 一份说明书 | 74 | 张量不是数组,是「一块 storage」加「shape / stride / offset」三个数;切片改的只是说明书 |
| 02 | autograd:图什么时候建,什么时候没的 | 80 | 第二次 backward() 直接报错 —— 图默认用完就扔 |
| 03 | 就地操作:三种报错,三个不同的原因 | 106 | ⚠️ 最贵的那种根本不报错,只是悄悄算错 |
| 04 | detach / no_grad / requires_grad |
94 | 三个都在「断」,断的不是一个东西 |
| 05 | nn.Module 内部:参数是怎么被找到的 |
120 | 一个 self.layers = [...] 就能让半个网络永远不被训练,而且不报错 |
| 06 | state_dict 到底装了什么 |
68 | 形状不匹配 / 多了少了 key / strict=False 到底放过了什么 |
| 07 | train() / eval() 到底改了什么 |
68 | Dropout 在训练时把存活的值放大;BN 的 running_mean 什么时候更新 |
| 08 | DataLoader:num_workers 一开就卡住 |
72 | worker 是另一个进程 —— 它拿到的是数据集的副本和独立的随机种子 |
| 09 | 自己写一个 autograd 算子 | 114 | 写一遍 autograd.Function,你就真的懂了前向存什么、反向还什么 |
| 10 | 把模型交出去:保存、TorchScript、ONNX、compile |
138 | torch.save(model) 会把你的类定义一起腌进去 |
| 附录 A | 速查 | 68 | 报错原文 → 原因的反查表,随时查,不用通读 |
合计:00–10 共 11 章 966 分钟 ≈ 16 小时,附录 A 另算 68 分钟(章内有 🛑 断点,设计上就是分次读)。
⭐ 前六章(00–05)是地基,后五章(06–10)是应用。 01 → 02 → 03 → 04 是一条必须顺着读的链:01 讲「张量底下是一块共享的内存」, 02 讲「autograd 在这块内存上记了什么账」,03 讲「你就地改这块内存会发生什么」, 04 讲「三种断账方式的区别」。跳着读会漏掉因果。
06–10 相对独立,撞上哪个问题读哪个。
🧩 三、四条读法路线
路线 A:「我只想搞清楚它为什么这么报错」(约 4.7 小时)
02 → 03 → 04(80 + 106 + 94 = 280 分钟)。 这三章覆盖了 autograd 相关的绝大多数报错原文。⭐ 读完直接翻 附录 A 的反查表。
路线 B:「我的模型不收敛 / 参数没被更新」(约 4.3 小时)
05 → 06 → 07(120 + 68 + 68 = 256 分钟)。
⭐ 这三章按「参数怎么被找到 → 怎么被存下来 → 训练和推理时行为差在哪」排。
ml_md/15 那份「六个高频 Bug」里有两个(忘 eval()、忘 no_grad()),加上 ml_md/11 那条「参数没进优化器」的机制在这三章。
路线 C:「我要往框架里塞自己的东西」(约 6.8 小时)
01 → 02 → 09 → 10(74 + 80 + 114 + 138 = 406 分钟)。
⭐ 09 章的 autograd.Function 是理解 AI 基础设施 08 FlashAttention「重算换显存」的前置 ——
那边讲为什么重算能省显存,09 章讲怎么把重算写进反向。
路线 D:从头顺读(约 16 小时)
00 → 10。⚠️ 别一天读完,01–05 每章都有需要动手跑的代码。
🧩 四、前置与环境
你需要先有的
| 前置 | 够不够 |
|---|---|
| 会写 Python | ✅ 够 |
| 训过至少一个模型(哪怕是抄的) | ⭐ 强烈建议。没训过的话,先去 ML 基础 15 把那份模板跑通再回来 |
| 懂反向传播的数学 | 不必须。第 02 章只用到「链式法则」四个字;真想补去 ML 基础 08 |
| 懂 NumPy | 不必须。本套不用 NumPy 起手 —— 需要对照时会明确链到 NumPy 与向量化思维 |
环境
import torch
print(torch.__version__, torch.cuda.is_available())
⚠️ 本套所有代码都在 torch 2.13.0+cpu 上单独跑过,torch.cuda.is_available() 是 False。
所以:
- ⭐ 每段代码都能在纯 CPU 上跑,不需要显卡
- 🗓️ 凡是必须有 GPU 才能验证的结论,正文里会明确标
🗓️ 未实跑 —— 需要 GPU,不会假装跑过 - ⚠️ 报错信息抄的是真实原文。你的版本不同,措辞可能微调,但关键词(比如
a leaf Variable that requires grad)是稳定的
⭐ 验证方式:本套每一段代码都是单独写进一个空文件、python 文件名.py 跑出来的,
不是在一个共享的 notebook 里接着上一段跑。所以你复制任何一段到空文件里都能直接跑。
🧩 五、贯穿全套的四个主题
后面每一章都会回扣这四条,先在这里立住:
| 主题 | 一句话 | 哪几章 |
|---|---|---|
| ① 张量是「说明书 + 内存」,很多东西共享同一块内存 | 切片、转置、view、detach、from_numpy 全都不搬数据 |
01 / 03 / 04 |
② 图是动态的,每次前向重新建,backward() 之后就扔 |
所以「第二次 backward」「累加 loss 不 detach」都会出事 | 02 / 04 |
| ③ 静默出错比报错贵得多 | 就地操作绕过版本检查、参数没进优化器、plain 属性没被 .to() 带走 —— 这三件事都不报错 |
03 / 05 / 06 |
| ④ 报错原文里带着答案 | PyTorch 的报错通常直接说了修法(Use .reshape(...) instead、Specify retain_graph=True),⚠️ 但它说的修法不一定是你该做的 |
02 / 03 / 06 |
⭐ 主题 ③ 是本套最重要的一条。PyTorch 报错的地方其实是它对你好 —— 那说明它替你拦住了。 真正会让你调三天的是它没报错的那些,本套花了三章讲这一类。
🔗 这一章连到哪里
| 相关的地方 | 为什么 |
|---|---|
| ML 基础 15 · PyTorch 实战手册 | ⭐ 没训过模型就先去那儿。那份模板实测可跑,本套所有例子都假设你见过它 |
| ML 基础附录 C · 手撕代码速查 | .contiguous() 的急救写法在那里,本套 01 章只引用不重讲 |
| AI 基础设施 index | 显存不够、速度不够、要上多卡 —— 那些问题全在那边,不在这里 |
| NumPy 与向量化思维 | stride 的机制、视图与拷贝、NumPy ↔ torch 术语对照都归那边,本套只引用 |
| ML 基础 18 · 挑战项目 A 手搓 mini-torch | ⭐ 读完本套 02 和 09 章再回去做那个项目,会发现自己在造的正是本套讲的东西 |
✅ 检查点
- 这一套和
ML 基础 15 章、AI 基础设施分别怎么分工?用一句话说清判据。 - 本套的选题标准是什么?「这个知识很重要」算不算理由?
- 全站命中 0 次的两个词是哪两个?
state_dict在站内有 6 个文件命中,为什么还算「没被讲过」?- 01–05 这五章为什么建议顺着读,而 06–10 可以跳着读?
- 本套的代码是在什么环境上验证的?有 GPU 吗?验证方式是什么?
- 贯穿全套的四个主题里,哪一条被称作「最重要的一条」,为什么?
👀 答案
- 换个框架就不成立的知识 → 这里;换个框架照样成立的(显存账、并行策略、KV Cache)→ AI 基础设施;「十分钟先跑起来」→ ML 基础 15 章。 一句话记法:15 章教你「用」,AI 基础设施教你「扩」,这一套讲「框架自己」。
- 标准是「被用了、没被讲」。「知识很重要」不算理由 —— 必须能指出站内哪句话依赖了它而没人解释。
retain_graph和autograd.Function,两个词全站命中都是 0。- 因为那 6 个文件的命中全部在代码块内部(保存/加载各写一行的语法高亮 token),没有一页解释过它装了什么、为什么加载会报 shape 不匹配。
- 01–05 是一条因果链:01 张量底下是共享的内存 → 02 autograd 在这块内存上记账 → 03 就地改这块内存会发生什么 → 04 三种断账方式的区别 → 05 参数是怎么被找到的。跳着读会漏掉因果。06–10 是应用,撞上哪个问题读哪个。
torch 2.13.0+cpu,torch.cuda.is_available()是 False,没有 GPU。需要 GPU 才能验证的一律标🗓️ 未实跑 —— 需要 GPU。验证方式是每段代码单独写进一个空文件、python 文件名.py跑一遍,不是在共享 namespace 里接着上一段跑。- 主题 ③「静默出错比报错贵得多」。因为 PyTorch 报错的地方其实是替你拦住了,真正会让你调三天的是它不报错的那些(就地操作绕过版本检查、参数没进优化器、普通属性没被
.to()带走),本套为这一类花了三章。
🛑 可以停在这里
⚡ 走神救援
这一套只回答一个问题:
torch这个包自己是怎么运转的,以及它为什么会用那种方式报错。⭐ 判据一句话:换个框架就不成立的知识放这里;换个框架照样成立的(显存账、并行策略、KV Cache)在《AI 基础设施》,「十分钟先跑起来」在 ML 基础那一章——⭐ 记成「那一章教你用,AI 基础设施教你扩,这一套讲框架自己」。
⭐⭐ 选题标准不是「知识重要」,是「被用了、没被讲」:几个高频 API 在立项调研时全站命中为 0,或者命中全在代码块内部、没有任何一页说过它到底装了什么——⭐ 「站内在用却没讲过」就是立项证据本身。
明确不做五件事(训练循环、混合精度与并行、性能剖析、DataLoader 调优、stride 机制),⭐ 每一件都指名了它归哪个板块。
⭐ 前五章是必须顺读的因果链:张量是共享内存 → autograd 在上面记账 → 就地改会怎样 → 三种断账方式 → 参数怎么被找到;⭐ 后面几章撞上哪个读哪个。 另给了四条按问题分的路线。
⚠️ 环境是纯 CPU:⭐ 每段代码都能在没有显卡的机器上跑、都是单独写进空文件跑过的,需要 GPU 的一律标「未实跑」。
四个贯穿主题:① 很多东西共享同一块内存;② 图是动态的、反向之后就扔;③ ⭐⭐ 静默出错比报错贵得多——这是本套最重要的一条,占了三章;④ ⭐ 报错原文带着答案,但它建议的修法不一定是你该做的。
下一节 👉 01-张量到底是什么.md