附录:按需查阅,不必从头读
主线 13 章的职责,是把你一步一步带到“能在各章 lab 里补完代码,并最终跑出一个能聊天的迷你语言模型”。从课程完成角度说,这已经够了。你不需要为了通过这门课,再额外啃一堆论文、博客和视频。
那为什么还要有这一份附录?因为当你真的把项目做下来之后,通常会出现第二层需求:
- 有些概念你已经会用了,但想知道它最原始、最标准的表述是什么。
- 有些工程实现你已经亲手写过了,但想看看“别人是怎么把同一件事做得更大、更快、更成熟”的。
- 有些数学直觉你勉强跟上了,但还缺一个更形象的图、动画或对照实现,把脑中的结构真正连起来。
换句话说,A3 不是“课程前置阅读”,而是“课程之后,或者课程某一章刚做完时的定向加深入口”。你完全不必从头顺读它;正确用法是:每做完一段主线,再回来补一份最对应的材料。
A3.0 先按章节找,不要按资源名找
很多资源附录一上来就堆链接,结果学员一打开就不知道“我到底该先看哪个”。这份附录反过来组织:先从你所处的课程位置出发,再推荐那一小组最合适的材料。
| 你刚学到哪里 | 建议先看什么 | 目的 |
|---|---|---|
| Chapter 1~3 刚结束 | 3Blue1Brown 线性代数系列 | 补齐张量、矩阵、线性变换的直觉 |
| Chapter 4 刚结束 | Illustrated Transformer 的注意力部分 | 把 Q/K/V 与多头流程画成图 |
| Chapter 5 刚结束 | Transformer 原论文 §3.1~§3.3 | 对照本课程 block 结构的正式定义 |
| Chapter 6~8 刚结束 | GPT-2 报告 | 理解“纯解码器语言模型”为什么成立 |
| Chapter 12 刚结束 | Sennrich 2016 + minBPE |
把 BPE 的论文表述和教学实现对齐 |
| Chapter 13 做完还想继续 | llm.c |
看更工程化、更高性能的 C/CUDA 路线 |
如果你只记住一条原则,那就是:
先完成当前章,再看对应资料;不要在主线还没做完时,提前用外部资料把自己绕远。
A3.1 Chapter 1 到 Chapter 3 之后:把张量和线性代数直觉补扎实
课程前几章刻意没有把线性代数讲成一套完整理论课。原因很现实:你在 Chapter 1 真正需要的,不是证明矩阵乘法的性质,而是知道“为什么二维数据最终还是按一段连续内存存着”“为什么 stride 会影响取值方式”“为什么向量和矩阵乘法不是神秘黑盒”。
如果你做完这几章后,代码已经能写,但脑海里仍然没有清晰的图像,这时最值得补的一组材料不是 Transformer 论文,而是更基础的可视化直觉。
A3.1.1 3Blue1Brown — Essence of Linear Algebra
- 链接:https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab
- 为什么现在看它:你已经亲手接触了
Tensor.shape、stride、matmul,这时回头看“矩阵乘法作为线性变换”的动画,会比课前强行预习有效得多。
最推荐的切入点不是整季通刷,而是先看与主线最贴近的两集:
- 线性变换是什么;
- 矩阵乘法为什么可以看作变换的复合。
你会发现,这能直接反哺 Chapter 1 里的张量存储和 Chapter 3 里的 embedding 映射理解。
A3.2 Chapter 4 到 Chapter 5 之后:把注意力和 Transformer 结构对上号
到 Chapter 4、5 为止,你已经在代码里见过 Q、K、V、多头切分、残差、LayerNorm、FFN。这时最容易出现一种“代码层面能跟,但脑图还不完整”的状态。也就是说,每个函数你都知道大概在做什么,可一旦问“为什么这几步要按这个顺序组合”,脑中仍然缺一张全景图。
这时候最适合看的,是一图胜千言的材料和最短路径的原论文段落。
A3.2.1 Jay Alammar — The Illustrated Transformer
- 链接:https://jalammar.github.io/illustrated-transformer/
- 为什么现在看它:它把
Q/K/V、注意力分数、Mask、多头并行和拼接后的投影过程画得非常直接。你在本课程里已经接触过这些名字,再看图会很快对上。
最推荐的阅读时机,是你刚做完 attention 或 block 相关 lab,脑子里还保留着 student.c 那几个关键函数的上下文。这个时候再看图,不会把它当成空洞概念,而会自动映射回你刚写过的代码。
A3.2.2 Attention Is All You Need
- 链接:https://arxiv.org/abs/1706.03762
- 为什么现在看它:做完 Chapter 5 后,你已经有能力读论文中最关键的那部分正式定义,尤其是多头注意力和 encoder/decoder 结构中与本课程对应的段落。
这里不建议你一上来通读整篇。对本课程最直接有用的,是:
Scaled Dot-Product Attention为什么要除以sqrt(d_k);Multi-Head Attention为什么不是“把一个 attention 重复很多次”那么简单;- block 内部各子层为什么用残差和归一化串起来。
主线课程已经让你能“用”这些东西;原论文会帮你把“用法”和“正式定义”接起来。
A3.3 Chapter 6 到 Chapter 8 之后:把 GPT 视角补上
到这个阶段,你已经不再只是拼一个 block,而是在构造一个完整的自回归语言模型:它能训练、能生成、能对下一个 token 做预测。很多同学这时会出现一个新问题:
我知道代码怎么写了,但“纯 decoder 模型为什么就能干这么多事”这件事,还是没有一个更高层的解释。
这正是 GPT 系列原始报告最有价值的地方。它们不一定是最容易读的入门材料,但在你已经完成了基本实现之后,会给你一个“这条路线在研究和工程上为什么成立”的更完整语境。
A3.3.1 GPT-2 报告:Language Models are Unsupervised Multitask Learners
- 链接:https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf
- 为什么现在看它:你已经亲手搭起了解码器式语言模型的最小版本,所以这时再回头看 GPT-2 报告,会第一次真正明白“为什么预测下一个 token 会外溢成很多看似不同的能力”。
你不需要被论文中的规模和实验细节吓到。对本课程最有价值的,是它如何描述:
- 自回归语言建模任务本身;
- 模型规模和行为之间的关系;
- 用哪些任务和现象来判断“模型是不是学到了东西”。
这会让你更清楚地理解 Chapter 7 的训练目标和 Chapter 8 的生成结果究竟在证明什么。
A3.3.2 3Blue1Brown — Neural Networks
- 链接:https://www.youtube.com/playlist?list=PLZHQObOWTQDNNr5WcE8DKRf6Fi8t0kriu
- 为什么现在看它:如果你在 Chapter 7 的反向传播、梯度更新、loss 下降上跟得比较吃力,这套动画会把“梯度从后往前流”的直觉补得更完整。
尤其是在你已经见过课程代码里的 backward 路径之后,再看这种可视化解释,吸收效率会高很多。因为你脑里已经有真实工程落点,而不是只在听抽象名词。
A3.4 Chapter 12 之后:把 BPE 的论文、算法和教学实现对照起来
BPE 是这门课后半段一个很典型的“工程实现比概念介绍更难”的主题。你做完 Chapter 12 后,通常已经知道为什么字符级 tokenizer 不够、也知道高频合并是怎么回事,但对下面两个问题仍然会想再确认一次:
- 论文里对这个算法到底是怎么表述的?
- 有没有一份更短、更适合核对逻辑的教学实现?
这时最合适的是论文和教学实现一起看,而不是只选其一。
A3.4.1 Sennrich et al. 2016
- 链接:https://arxiv.org/abs/1508.07909
- 为什么现在看它:这是 BPE 进入 NLP 主流的重要论文。你做完课程里的 BPE lab 再回去看,会发现伪代码中的每一步都能在自己的实现里找到对应物。
它最有价值的不是篇幅长,而是把“为什么通过合并高频对子能得到更合适的子词单元”说得足够正式。此时再读,你不会只把它当概念介绍,而会自然拿自己的实现逐行对照。
A3.4.2 Karpathy — minBPE
- 链接:https://github.com/karpathy/minbpe
- 为什么现在看它:它提供了一份非常教学化的 Python 实现,能让你把“课程里的 C 版显式内存管理”映射成“更短、更直接的算法骨架”。
这不是为了否定课程里的 C 实现,恰恰相反。你会从这种对照里更清楚地看到:哪些复杂度来自算法本身,哪些复杂度来自“在 C 里把容器、字符串和内存显式管理出来”。
A3.5 Chapter 13 做完以后:往更工程化的实现走
当你把 Chapter 13 真正做完,整门课已经完成了它的主要使命。此时如果你还想继续,方向通常会分成两条:
- 继续向理论、论文、模型设计方向深入;
- 继续向更大规模、更高性能、更工程化的实现深入。
本附录更偏向第二条,因为它和你刚做完的 C 项目最直接衔接。
A3.5.1 Andrej Karpathy — llm.c
- 链接:https://github.com/karpathy/llm.c
- 为什么现在看它:你已经在课程里自己做过一个极小、透明、便于教学的语言模型系统。这时看
llm.c,最自然的问题不再是“我看不懂”,而是“它在哪些地方为性能和规模做了额外设计,而我们课程里故意没有做”。
这类对照极有价值。它会让你第一次清晰地区分:
- 教学实现为了可读性做的简化;
- 工程实现为了速度、规模、可复现性做的增强;
- 两者之间哪些思想是同构的,哪些完全不是一个层级的问题。
也就是说,llm.c 最值得看的地方,不是让你直接把课程代码换成它,而是让你知道“如果继续往上走,前面这 13 章打下的到底是什么底子”。
A3.6 一条推荐阅读顺序
如果你希望有一条更具体的“做完哪章再看哪份资料”的顺序,可以直接按下面这条走:
- Chapter 1 之后:看 3Blue1Brown 线性代数中关于线性变换和矩阵乘法的几集。
- Chapter 4 之后:看
Illustrated Transformer里 self-attention 的部分。 - Chapter 5 之后:回到 Transformer 原论文的相关章节。
- Chapter 7 之后:看 3Blue1Brown 神经网络系列中关于反向传播的部分。
- Chapter 8 之后:读 GPT-2 报告的引言和方法部分。
- Chapter 12 之后:把 Sennrich 2016 和
minBPE对照着看。 - Chapter 13 之后:打开
llm.c的 README 和主实现。
这条顺序的核心逻辑很简单:先用主线课程建立第一手经验,再用外部资料把经验提炼成更清晰的结构。
A3.7 最后的边界提醒
主线课程和附录阅读之间有一条边界,最好一直记住:
外部资料的作用,是帮助你把已经做过的东西看得更深,而不是替你跳过主线里的亲手实现。
如果你发现自己读了很多论文、很多博客、很多仓库,却还没有回到 framework/student.c 补当前 lab 的代码,说明阅读顺序已经反了。
如果你接下来想继续深入,最好的方式不是继续囤更多链接,而是回到你刚做过的章节,对照这些材料把自己的实现重新看一遍。这样外部资料才会真正变成你的理解,而不只是新的阅读负担。