20 天 · 每天 2 小时 · 共 40 小时

从零理解
编程原理与 AI 原理

页面里所有的 Python 代码都能直接改、直接跑,用的是浏览器里的真 CPython(Pyodide),不用装任何东西。第一次点「运行」会下载运行时,之后就有缓存了。

先把预期钉死

40 小时能到哪、不能到哪

能达到达不到
理解计算机执行代码的完整链路;能独立写出 50–100 行解决真实问题的程序;能读懂报错并自己排查;理解神经网络和大语言模型的工作原理;能向别人讲清楚「ChatGPT 为什么会说话」。 成为能接活的程序员;手写神经网络训练代码;掌握软件工程实践。这些需要几百小时,不是四十小时。

40 小时的正确目标不是「学会」,而是建立正确的心智模型,并装好一台能自己走下去的引擎

每天 2 小时的固定节奏

时段做什么
前 40 分钟 — 读材料或看视频,只读当天那一小块,不许超前
中间 65 分钟 — 动手写代码,必须亲手敲,不许复制粘贴
最后 15 分钟 — 写学习日志三行

最后那 15 分钟看起来最像浪费,实际是整个计划里回报最高的部分。

日程

勾掉每一天。进度存在这台设备的浏览器里,关掉页面也还在。

阶段 01 · DAY 1–6

编程的本质

里程碑 1

能从零独立写出 30 行程序。写不出来说明前面某天虚了,回去补,不要往前赶。

阶段 02 · DAY 7–11

软件如何构造

里程碑 2

能写一个「从网上取数据 → 处理 → 存到本地」的脚本。这是绝大多数软件的骨架。

阶段 03 · DAY 12–17

AI 原理

里程碑 3

能用 5 分钟向一个完全不懂技术的人讲清楚「ChatGPT 为什么会说话」,并且对方听懂了。讲不清,就等于你自己没懂。

阶段 04 · DAY 18–20

合龙

阶段三 · AI 原理 · 第 1 天,共 6 天

Day 12 · AI 是什么

今天搞懂「机器怎么会学习」。Day 13 拆开神经网络的零件,Day 14 看它怎么被训练出来,Day 15–16 一路走到 ChatGPT。今天是地基,别急着追大模型。

一次方向的翻转

传统编程你已经做了十一天了,它长这样:

输入  +  规则  →  输出

你写 if 分数 >= 60——规则是你想出来的,计算机只负责执行。机器学习把这个式子转了个方向:

输入  +  输出  →  规则

你给它一堆「身高和对应的体重」,它自己算出那条公式。你给它十万张标好「猫/狗」的照片,它自己找出区分的办法。整个 AI 领域,起点就是这一次翻转。

为什么非翻转不可

因为有些规则,人根本写不出来。试着用 if 写出「什么是猫」:有毛?有胡须?四条腿?——狗也全中。耳朵是尖的?折耳猫不是。你会发现你认得猫,但你说不清你凭什么认得。

这类知识叫默会知识:你会,但你讲不出规则。人脸、语音、语义、审美,全属于这一类。于是换个思路:我说不清规则,但我能给你一万个例子,你自己去找。

找规律靠的是「猜 + 纠错」

  1. 瞎猜一个规则,拿数据一验,算出错了多少
  2. 朝着错得更少的方向,把规则改一点点

重复几百万次,仅此而已。那个「错了多少」是一个具体的数字,今天你就会亲手算出它——它叫损失,是 Day 14 的主角。

三个词,现在分清

是什么
训练从数据里找规则的过程。慢、贵、只做一次
模型找出来的那个规则,本质上就是一堆数字
推理拿现成模型去用。快、便宜、每次调用都在做

动手一 · 传统编程:规则由你给

先跑一遍,看看这条老公式偏得有多离谱。

动手二 · 机器学习:规则由程序找

假设关系是 体重 = a × 身高 + b,但 ab 是多少谁也不知道。让程序把所有可能都试一遍,挑错得最少的那组。

程序没被告诉过任何公式,它只见过那五组数字。

跑完后回答(写进日志)

  1. 程序试了多少组 ab?
  2. total_error 里为什么要平方?把 ** 2 删掉再跑一次,看结果崩成什么样。
  3. data 里加一条 (200, 200) 这种明显不合理的数据,重跑。数据脏了,学出来的规则就是错的。

加分题:range(0, 101) 改成 range(0, 1001) 并把 a_step / 100 改成 / 1000。误差变小了吗?变慢了吗?——你刚体会到 AI 领域最核心的那对矛盾:精度和算力的交换

今天的原定产出

写一段一百字左右的「什么是机器学习」,不许出现「算法」「模型」「数据」「训练」「参数」。写给一个完全不懂电脑的人。

阶段三 · AI 原理 · 第 2 天,共 6 天

Day 13 · 神经元

昨天你写的 a * height + b,把 a 改名叫权重b 改名叫偏置,它就是一个神经元。你已经把神经网络最小的零件写出来了,只是没人告诉你它叫这个名字。

一、从一个输入到多个输入

总和 = w₁·x₁ + w₂·x₂ + w₃·x₃ + … + b

二、第二半:激活函数,以及为什么非有不可

假设不加激活,把一个神经元的输出直接喂给下一个:

第一层:h = w₁·x + b₁
第二层:y = w₂·h + b₂

代入化简:y = (w₂·w₁)·x + (w₂·b₁ + b₂)。括号里不过是两个新的常数

两层不加激活,结果还是一条直线,和一层完全等价。叠一百层也一样。没有激活函数,深度学习的「深」就是白搭。

名字做什么特点
ReLU负数变 0,正数不变简单粗暴,现代主流
Sigmoid把任何数压进 0 到 1像「概率」,老牌选手
阶跃大于 0 输出 1,否则 0像开关,好手算,今天用它

三、一个神经元的全貌

输入 → 乘权重 → 全部加起来 → 加偏置 → 过激活函数 → 输出

这就是全部。 从今天到 GPT,零件没变过,变的只是数量。

动手一 · 先用纸笔(15 分钟,不许开电脑)

输入 x₁=2, x₂=4,权重 w₁=0.5, w₂=-0.3,偏置 b=0.1,激活用 ReLU。在纸上算出输出,写下每一步。

算完了再跑下面这段对答案:

对不上就停下来查,别往下走。(答案是 0 ——注意 x₂ 的权重是负的,它在反对,而且 x₂ 比较大,一票把结果否掉了。)

动手二 · 一个神经元能做逻辑判断

同样的结构,只改了偏置,行为就完全不同。 这就是「学习」要调的东西。

动手三 · 一道做不出来的题

现在做 XOR:两个不一样时输出 1,一样时输出 0。

花 10 分钟,试着给单个神经元找一组 w₁、w₂、b 满足这四行。 用下面这个改权重试:

十分钟后你会失败。这不是你的问题——它无解。1969 年 Minsky 和 Papert 在书里证明了这一点,直接掐灭了当时的神经网络研究,业界叫它第一次「AI 寒冬」,冷了将近二十年。

动手四 · 两层就解决了

四行全对。你刚刚做了两件大事:

  1. 造出了你的第一个神经网络——第一层两个神经元,第二层一个
  2. 亲手验证了为什么需要「深度」。不是深了效果好一点,是浅的根本做不到

写进日志的三个问题

  1. 数一数你的 XOR 网络一共有多少个参数(权重 + 偏置)?
  2. NAND 的偏置从 1.5 改成 0.5,哪几行错了?为什么?
  3. 如果去掉激活函数,XOR 还能成立吗?为什么?

今天只记一句:没有激活函数,叠多少层都等于一层。

阶段三 · AI 原理 · 第 3 天,共 6 天

Day 14 · 训练

昨天每一组权重都是我直接给你的——凭什么是这几个数?我怎么知道的?今天补上这个洞。训练,就是自动找出这些数字的过程。

一、你已经训练过一次了

Day 12 那个双层循环就是一次完整的训练:一个衡量「错了多少」的损失函数,一堆待定的参数,一个搜索过程叫优化。今天要解决的只有一件事:那个搜索办法慢到不能用。

二、为什么暴力穷举必然死掉

Day 12 有 2 个参数,每个试 100 种,一万次,眨眼就完。那 10 个参数呢?100¹⁰ = 10²⁰ 次,用最快的超算也要跑上千年。

Day 13 那个 XOR 网络有 9 个参数——已经算不动了。GPT 那种几千亿参数的,穷举次数比宇宙里的原子还多。每多一个参数,搜索空间就乘一次。这叫维度灾难。

三、换个思路:蒙着眼睛下山

浓雾里要走到谷底。穷举 = 把每一平方米都走一遍,荒谬。聪明的办法:用脚感觉哪边是下坡,朝那个方向迈一步,再重新感觉。

机器学习
你所在的位置当前这组参数值
海拔高度损失(错得多少)
脚下的坡度梯度

关键在于:算坡度只看你脚下这一点,不需要走遍整座山。 这就是它比穷举快出天际的原因。

四、每步走多远:学习率

五、反向传播(今天只要直觉)

网络有很多层,输出错了,到底是哪一层哪个权重的锅? 反向传播就是回答这个的:从输出端的误差出发,一层一层往回分摊责任。像追查一次事故——从结果倒推,每个环节按它实际的影响力承担一份;影响大的,调整也大。

训练 = 反向传播算坡度 + 梯度下降迈步子,循环几百万次。

动手一 · 最小的梯度下降

先不碰神经网络。找 f(x) = (x-3)² 的最低点——你一眼知道答案是 3,正好用来验证。

盯着那两列数字往下看——x 一步步爬向 3。没人告诉过程序答案。

注意 x = x - lr * g 这一行。这就是整个深度学习的核心公式。 GPT 训练时跑的本质上也是它,只不过 x 换成了几千亿个数。

动手二 · 把学习率玩坏

把上面那段的 lr 依次改成 0.01 / 0.1 / 1.0 / 1.1,每次重跑。

1.1 那次看清楚——数字会左右横跳,而且越跳越远。这就是「飞出去」。没有公式能算出最佳学习率,只能试。

动手三 · 回到 Day 12,把暴力搜索换掉

先做一件真实工程里必做的事:把身高缩放到 -1 到 1 之间。原始数值 150~190 太大,梯度会跟着爆掉。

Day 12 暴力穷举Day 14 梯度下降
计算次数12,221500
精度卡在 0.01 的格子上想多准有多准
加到 10 个参数宇宙热寂也算不完一样 500 步

这就是为什么现代 AI 能存在。 不是硬件变快那么简单,是有了一个不随参数数量爆炸的搜索办法。

写进日志的三个问题

  1. x = x - lr * g,为什么是梯度不是加?(想想站在 3 左边时 g 是多少)
  2. 动手三里如果不做特征缩放,直接用原始身高,会发生什么?动手试一次。
  3. 用一句话说清损失函数和梯度的关系。

阶段过半:你已经掌握了神经网络的全部零件。从这里到 ChatGPT,不再有新的基本原理,只有规模和结构上的变化。

阶段三 · AI 原理 · 第 4 天,共 6 天

Day 15 · 从数字到语言

前三天处理的输入全是数字。可语言不是数字——「小猫」这两个字,要怎么喂进一个只会做乘法和加法的神经元?答案分三层:先切开,再编号,最后让它们互相看见。

一、切开:token

第三种叫 BPE,规则蠢得出奇:统计哪两个相邻片段一起出现得最多,就把它俩合并。重复几万次。

顺带解释一个你早该好奇的现象:模型数不清「strawberry 里有几个 r」——因为它看到的根本不是字母,而是被切好的两三个块。字母级别的信息,在切开那一刻就丢了。

二、编号:embedding

每个 token 对应一串数字(几百到几千个)。关键在于它怎么来的:不是人写的,是训练出来的——就是 Day 14 那套梯度下降。调完之后会自动出现一个惊人的性质:

意思相近的词,数字也相近。
国王 − 男人 + 女人 ≈ 女王

意思变成了空间里的位置,语义变成了几何。 注意:那几千个数字每一维代表什么,没有人知道。不是保密,是真的没人知道。

三、看见彼此:注意力

还差最后一块。两个问题:「我吃苹果」和「苹果发布会」是同一个 token,意思却完全不同;「小猫追鱼,因为饿了」——「它」是谁?

让每个 token 去打量句子里所有其他 token,算出「我该重点看谁」,然后按这个权重,把别人的信息揉进自己的表示里。

「它」打量一圈,发现和「小猫」最像,于是给「小猫」很高的权重、给「追」几乎为零。词义随上下文而变,自动实现。

四、为什么「注意力」是那次突破

在它之前,主流是从左到右一个词一个词地读(RNN),两个致命伤:距离一远就忘;没法并行——必须读完第 3 个才能读第 4 个,GPU 有一万个核也只能干等。

注意力两刀砍掉:任意两个位置一步直连;所有位置可以同时算。第二点才是引爆点——能并行,才能上万张 GPU 一起训;能一起训,才可能有几千亿参数的模型。

注意力内部那些 Q、K、V 本质仍是权重矩阵,仍然靠梯度下降训练出来。Day 13 和 14 之后,你没有再遇到过新的基本原理。

动手一 · 让程序自己发现「词」

程序自己发现了「情商」和「血压」是一个整体——没人告诉过它中文有词语这回事,它只是数了数谁和谁总一起出现。真实模型对着几万亿字跑同样的过程几万轮,就得到了词表。

动手二 · 意思变成距离

猫和狗最近,和苹果最远。「意思」被换算成了距离。

动手三 · 手算一次注意力

句子:小猫 追 鱼,因为它饿了。「它」要去打量前面三个词:

看那三根柱子:「它」把七成注意力给了「小猫」,给「追」的几乎为零。模型没有语法规则,没有指代消解算法——它只是算了几个点积,做了一次加权平均,代词就找到了主语。

写进日志的三个问题

  1. 动手一里,如果 corpus 换成八个完全不重复的词,BPE 会合并出什么?为什么?
  2. 动手三把 * 5 改成 * 1 再改成 * 20,三根柱子怎么变?太大或太小分别有什么坏处?
  3. 为什么大模型数不清「strawberry 里有几个 r」?

阶段三 · AI 原理 · 第 5 天,共 6 天

Day 16 · 它为什么会说话

昨天结束时你手上有一台能理解上下文的机器,但它离「会聊天」还差得远。

大模型只会做一件事——猜下一个 token 是什么。对话、写代码、翻译、解数学题,全都是这一件事的副产品。

一、第一道工序:预训练

训练目标简单到近乎荒谬:遮住一段文字的后半截,让模型猜下一个 token,猜错了就用 Day 14 那套梯度下降调参数。

为什么这个笨办法能成?因为它不需要人工标注——文本本身就自带答案。互联网上有多少字,就有多少道免费的练习题。而想把这道题做准,模型被逼着学会记事实、学会指代、学会算术、学会写代码。

没有人专门教过它算术。 只是为了把下一个字猜得更准,它不得不顺带学会。这种现象叫涌现——能力不是设计出来的,是压出来的。

「知识截止日期」就是从这来的。 训练数据是某个时刻的世界快照,那之后发生的事,模型的权重里根本没有。

二、可是预训练完的模型不能用

因为它只会续写。你问「中国的首都是哪里?」,它可能回你「中国的最大城市是哪里?中国的人口有多少?」——在互联网上,一个问题后面确实经常跟着更多问题。它猜得非常准,只是猜的不是你要的东西。

三、第二道工序:微调

人工写一批「问题 + 好答案」的范例,拿这些继续训练。量不大(几万到几十万条)但质量高。练完之后模型学会了:看到问题,该给答案,而不是续写更多问题。

四、第三道工序:人类反馈

「什么是好答案」这件事写规则写不出来,但人一看就知道——又是默会知识。于是:生成好几个答案 → 请人排序 → 拿排序训练一个打分模型 → 让主模型去追求高分。这就是强化学习

工序干什么成本产出
预训练猜下一个词天价博学但不会聊天的续写机
微调学会答题格式中等会回答问题的助手
人类反馈学会什么算好中等有分寸的助手

五、幻觉到底从哪来

训练目标从头到尾都是「像真的」,从来不是「是真的」。

翻遍三道工序,没有任何一步的损失函数里写着「事实正确」。对一台猜下一个词的机器来说,「爱因斯坦生于 1879 年」和「生于 1872 年」流畅度完全一样。三个原因叠加:

  1. 知识是弥散的,不是存起来的。 模型里没有一张可查的事实表,知识被抹在几千亿个权重里。它没法「查一下自己知不知道」,只能生成
  2. 训练数据里几乎没有「我不知道」。 人写文章很少写「这我不清楚」,所以这个句式概率天然就低
  3. 人类反馈可能帮了倒忙。 打分的人往往更喜欢自信、完整的回答

结果就是那个最危险的特性:它编造的时候,和它正确的时候,语气一模一样。 现代模型校准好了很多,但这个根子拔不掉。这不是 bug,是这个训练范式的必然产物。

动手一 · 亲手做一台续写机

用最原始的办法实现「猜下一个字」:统计每个字后面都跟过什么字,然后按频率随机抽。

多跑几次,盯着那些句子看一会儿。 这就是幻觉最纯粹的形态:每一步的下一个字都合法、都符合统计规律,连起来却毫无事实可言。这台机器根本没有「真假」这个概念——而 GPT 和它是同一类东西,只是把「看前 1 个字」换成了「看前几十万个 token」,把统计表换成了几千亿个权重。

动手二 · 让它看得更远

明显通顺了。记住这个对比——从「看 1 个字」到「看 2 个字」,通顺度就跳一大截。这正是过去几十年语言模型一路往上爬的方向:让模型看得更远、看得更准。昨天那个注意力机制,就是这条路上的终极答案。

动手三 · 找出它必然答错的三类问题

不要靠瞎试,用今天学的原理推导出来,再去验证(打开任何一个聊天 AI 即可)。

类型原理怎么问
知识截止之后训练快照之后的世界不在权重里问一件你确知发生在最近几个月的事
字符级操作token 化那一刻字符信息就没了数某个长词里某个字母出现几次,或把词反过来拼
极冷门的具体事实训练数据里出现太少,没编码进权重,但它照样流畅生成问某本冷门书第几页写了什么。重点看它编造时的语气有多笃定

这 20 分钟的真正目的不是抓 AI 的错,而是让你亲眼确认:它错的时候,你从语气上看不出来。 这个体感,比今天所有理论都重要。

写进日志的三个问题

  1. 为什么预训练不需要人工标注数据?这一点为什么至关重要?
  2. 只做完预训练、跳过后面两道工序的模型,你问它问题会得到什么?
  3. 为什么「训练目标是像真的,而不是是真的」必然导致幻觉?

你现在应该能完成里程碑 3 了——用 5 分钟给一个完全不懂技术的人讲清楚 ChatGPT 为什么会说话。今天找个人试一遍,讲不顺的地方就是你的漏洞。

自由练习

练习台

空白的 Python 环境,随便写。和上面所有代码块一样,跑的是浏览器里的真 CPython——标准库都在,mathrandomjsondatetime 都能用。

正在加载 Python 运行时…