废话不多说,直接开始吧
本文面向的是笔者自己和一些了解大模型的一大堆基础概念,但是从来没有穿起过的,想要学习的读者
作者读文献 English 和 中文 语言系统混了,不要介意(4级难度)
若有错误,恳请更正
Before ALL
我们都知道大模型的训练是喂数据,计算loss,然后调整参数,然后继续测试,直到大模型在某些方面的测试达到了标准,我们就发布大模型
但是参数是怎么样的?loss是如何计算的?这背后的一系列算法是如何运作的?是否严格证明可行还是只是黑盒测试有效?
我们不清楚,But,We try to make it clear here.
That’s Why I wrote this
如何获得大模型
本文主要聚焦于:从 Loss 到梯度下降的训练主线,讲清大模型如何在“预测下一个词”中学到规律,而非停留在工程实现细节与全流程复现。
What’s Loss - 损失
抛开“人工智能”的光环,LLM 的本质其实就是一个超级复杂的“文字接龙”概率函数
f(context) = next_word
但是,现在的LLM已经足够智能,到已经可以做研究,写代码;只要能提供合适的上下文,LLM的表现已经足够媲美相当一部分人类了
所以,为什么预测行得通?
首先,反面,死记硬背(查表)是行不通的!
当你要求一个模型能够准确预测全人类互联网上所有文章、代码、论文的下一个词时, 死记硬背(查表)是行不通的,因为组合爆炸了。 唯一能在有限的参数(比如 700 亿)内完成这个任务的方法,就是 去发现文字背后的“规律”
为什么预测行得通?
为什么“预测”行得通?(不仅是查表不行,为什么预测能产生智能?)
你可以把大模型想象成一个极其严苛的 无损压缩算法 。
在计算机科学里,压缩的本质是寻找规律。
- 假设你要保存一段数据: 2, 4, 6, 8, 10 … 10000 。
- 查表法(死记硬背) :把这 5000 个数字存进硬盘。
- 预测法(寻找规律) :写一段代码 for i in range(1, 5001): print(i * 2) 。 当我们逼迫一个神经网络去**“完美预测人类历史上写过的所有文本的下一个词”**时,它面临一个极其残酷的考核标准(Loss 函数)。 如果它只是去统计概率(“今天天气”后面接“好”的概率是 80%),它遇到没见过的复杂句子就会报错,误差就会极大。
为了把预测误差降到最低,神经网络“被迫”在它的参数里写出了规律(也就是理解) 。 比如,为了准确预测代码里的下一个变量名,它被迫在参数里构建出了“作用域”和“语法树”的概念;为了准确预测悬疑小说的结局,它被迫在参数里构建出了“逻辑推理”的回路。
结论:预测之所以行得通,是因为“找到规律”是完成完美预测的唯一解,也是参数最少的解。 梯度下降算法就像一个极其抠门的老板,逼着模型用最少的参数(相比于无穷尽的宇宙状态组合)去搞定所有预测任务,模型被逼无奈,只能学会了“逻辑”和“常识”。
所以,如果能够找到规律,按照规律预测,那么此时达到某个准确率后,智力似乎就出现了
何为智力
关于智力的本质,可以参考这篇文章:智力的本质:找规律
Why is Loss - 损失
损失的计算和导数息息相关
Loss - 损失
损失函数(Loss Function)本质上是一个“指南针”。 在几百亿参数组成的高维空间里,模型完全是瞎子。你必须给它一个“评价标准”,告诉它:“你现在的状态有多烂”。
- 如果你不定义损失,模型就不知道优化的目标。
- 损失包含了你说的所有信息:当前结果与期望的差距。 它是整个系统中唯一连接“当前乱码状态”和“人类期望目标”的桥梁
损失是在评估某个参数他本身距离期望,在多维空间的高度差
导数
为什么选择“导数”?如果不选导数呢?
对于一个数的调整来说,一个数的要想调整,必须知道调整的大小,这个在Loss已经定义了,但是是+ Loss还是 -Loss呢?
这个问题的本质是:
既然有了损失(知道了有多烂),那怎么把这个“烂”的信息转化为“如何修改参数”的指令呢?
假设我们有 100 亿个参数,我们要找到一组最优参数让 Loss 最小。
我们来看看人类尝试过的非导数方法 ,以及它们为什么死得很惨:
方案 A:暴力穷举法(Grid Search)
- 思路: 把 100 亿个参数的所有可能的值全试一遍,看看哪一组的 Loss 最小。
- 死因: 宇宙毁灭也算不完。10 个参数穷举可能就需要几百年了,100 亿个参数的组合数比宇宙中的原子还多。
方案 B:遗传算法 / 随机变异(Evolutionary Algorithms)
- 思路: 随机生成 1000 个模型(初始参数不同)。让它们预测,挑出 Loss 最小的 10 个模型。然后让这 10 个模型“交配”(混合参数)或“变异”(随机微调一部分参数),生出下一代 1000 个模型,继续淘汰……
- 死因: 在低维问题(比如几个、几十个参数)上非常有效。但在 100 亿参数的超高维空间里, “随机变异”摸到正确方向的概率无限趋近于 0 。这就好比你在撒哈拉沙漠里随便扔飞镖,想正好扎中一粒特定的沙子。
方案 C:贪心搜索(一次只试一个参数)
- 思路: 我把 99 亿 9999 万 9999 个参数固定住,只微调第 1 个参数,看看 Loss 是变大还是变小。调好第 1 个,再调第 2 个……
- 死因: 效率极其低下。而且参数之间是 高度耦合 的,你调好第 1 个,去调第 2 个的时候,第 1 个的最优值又变了。 为什么最终选择了导数(梯度下降)? 经过上述失败,科学家们绝望地发现:在超高维空间里, 瞎猜(随机或穷举)是绝对行不通的 。我们必须有一个明确的、确定性的“方向”。
除了这些笨办法,还有
- 模拟退火(Simulated Annealing) :允许“偶尔变差”来跳出局部最优,但在超高维参数空间很慢。
- 粒子群优化(PSO) :一群候选解互相跟随“最优粒子”,低维可用,高维很容易退化。
- 贝叶斯优化(Bayesian Optimization) :用代理模型猜哪里更优,适合“参数少、每次评估很贵”的场景,不适合百亿参数。
- Nelder–Mead / 单纯形法 :不用导数,靠几何形状迭代,维度一高性能迅速变差。
- 坐标下降(Coordinate Descent) :一次只优化一维(你“贪心只调一个参数”是它的直觉版)。
- CMA-ES / 进化策略(ES) :比基础遗传算法更强的黑盒优化,但在大模型规模下算力成本依然爆炸。
- 随机搜索(Random Search) :比网格搜索常更高效,但本质仍是“盲找”。
- 零阶/无导数优化(Zeroth-order) :靠函数值估梯度,维度升高后采样成本极高。
这些方法在低维或黑盒问题很有价值,但对 LLM 这种超高维、可微、可并行的目标, 梯度下降(+反向传播)在效率和可扩展性上压倒性胜出 。
这样来看
导数(梯度)就是那个确定性的方向! 导数不仅仅是一个数值,它在数学上代表了当前空间地形中,下降最快的确切方向。
- 有了导数,我们就不用瞎猜了。导数直接告诉模型:“$W_{1}$ 是你往左走 0.02 步, $W_{2}$你往右走 0.05 步,Loss 保证能下降!”
见例子 - 导数把一个“瞎猫碰死耗子”的随机搜索问题,变成了一个“蒙着眼下山(沿着最陡的坡走)”的确定性几何问题。
简单小例子1
没例子你说 xx 呢?好,那么来看一个例子:
假设我们有一个极简的单层模型,输入 $X=2$,目标值 $Y=10$。
模型公式:
$$ \hat{Y} = X \times W_{1} \times W_{2} $$其中 $W_{1}$ 和 $W_{2}$ 是需要训练的参数,初始随机值设为 $W_{1}=2$、$W_{2}=2$。
第一步:前向传播(算误差)
- 预测值:$\hat{Y}=2 \times 2 \times 2=8$
- 真实值:$Y=10$
- 误差(Loss):
这里的平方是为了避免正负误差互相抵消。
第二步:链式法则(反向找“内鬼”)
系统要回答:误差主要由谁引起?$W_{1}$ 还是 $W_{2}$?它们该增大还是减小?
先看外层:
$$ L=(\hat{Y}-10)^2,\quad \frac{\partial L}{\partial \hat{Y}}=2(\hat{Y}-10)=2(8-10)=-4 $$这表示:如果预测值 $\hat{Y}$ 增大一点,Loss 会减小。
再看内层:
$$ \hat{Y}=XW_{1}W_{2},\quad \frac{\partial \hat{Y}}{\partial W_{1}}=XW_{2}=2 \times 2=4 $$链式相乘得到:
$$ \frac{\partial L}{\partial W_{1}} = \frac{\partial L}{\partial \hat{Y}} \times \frac{\partial \hat{Y}}{\partial W_{1}} = (-4)\times 4 = -16 $$第三步:梯度下降(更新参数)
更新公式:
$$ W_{1} \leftarrow W_{1} - \eta \frac{\partial L}{\partial W_{1}} $$设学习率 $\eta=0.01$,则:
$$ W_{1} = 2 - 0.01 \times (-16) = 2.16 $$只做一轮迭代,$W_{1}$ 就从 2 变成 2.16。下一轮预测值会比 8 更接近 10。
一些新的问题
wow wow wow Wait a minute
这里好多数学公式,但是如果其实想要说的是,你只要知道,一通计算之后,我的参数可以使得预测值靠近理论期望值了
一通计算之后,找到了应该减去 -0.16 然后就往预期值靠近了
不明觉厉🦾🦾🦾
不过这里也牵扯出了一些新问题
1.每一个$W_{n}$都要计算一次吗?并且每一个$W_{n}$都要更新吗?
2.是如何做到计算出哪个$W_{n}$更应该调整呢?
第一个问题的答案
-
是的,每一次训练(每一次反向传播),几百亿个参数全都要被计算一次偏导数(梯度)! 你可能会觉得这计算量大得离谱,但别忘了,在 GPU 底层,这不是写了 100 亿次的 for 循环,而是一次巨大的矩阵乘法指令 。GPU 最擅长的就是同时对几百万个数字做乘法。
-
但是是否是需要全都要更新一次,还需要如下的解释
-
如果某个 $w$ 真的刚好处于完美状态,它的“实质更新量”会是 0,也就是说它的值并不会变。
还记得神经网络更新参数的公式吗?
$w_{新} = w_{旧} - \text{学习率} \times \text{该} w \text{的梯度(即误差对它的偏导数)}$
- 如果某个 $w$ 已经处于当前的局部最优解:意味着在这个特定的维度上,误差已经降到了最低,此时算出来的梯度(坡度)就是 0。
- 代入公式:$w_{新} = w_{旧} - \text{学习率} \times 0 = w_{旧}$。
- 你看,算法很聪明,它虽然参与了计算,但值并没有发生改变。
但为什么 GPU 不写个
if 梯度 == 0: 跳过更新呢? 因为在 GPU 眼里,做 100 亿次毫无分支的矩阵乘减法,比挨个判断“这数字是不是0”要快无数倍。所以哪怕加上个 0,GPU 也会毫不犹豫地把它算完。 -
单个 $w$ 的“局部最优”是一种幻觉!
在潜意识里,可能认为这 100 亿个参数,每个人都有一个自己的“完美数值”,找到了就可以下班了。但实际上,参数之间是重度耦合的!
举个“做一锅麻辣烫”的例子:
- $w_1$ 是放盐的量
- $w_2$ 是放醋的量
- $w_3$ 是放辣椒的量
假设在第 100 次训练时,你发现 盐的味道($w_1$)刚刚好,处于局部最优,梯度为0,不用调了。 但是,你的醋和辣椒放少了,所以接下来你往锅里加了一大堆醋(更新 $w_2$)和一大坨辣椒(更新 $w_3$)。 这时候你再尝一口——糟糕,因为太酸太辣,原本“刚刚好”的盐味,现在显得太淡了!
此时,盐的量($w_1$)不再是局部最优了!在下一次反向传播时,误差又会给 $w_1$ 分配一个非 0 的梯度,强迫它再次更新。
-
第二个问题的答案
用另一个例子来演示
假设我们有一个极简的两层神经网络,它的预测代码就是连乘: 预测值 = $X \times W_{1} \times W_{2}$
- 输入值:$X=2$
- 正确答案(Target):$y=12$
- 初始的随机参数:假设模型初始化时,$W_1=100$(一个很大的数),$W_2=0.1$(一个很小的数)。
第一步:前向传播(看看错得有多离谱)
- 预测值:$\hat{y}=2\times100\times0.1=20$
- 真实答案:$y=12$
- 误差(Loss):$L=(20-12)^2=8^2=64$
- 现在误差是 $64$ ,我们要把误差降下来。系统开始算账:“$W_1$ 和 $W_2$,你俩谁的责任大?”
第二步:反向传播(微积分链式法则找内鬼) 首先算最外层:误差对外层“预测值”的导数为 $\dfrac{\partial L}{\partial \hat{y}}=2\times(20-12)=16$。(意思就是:现在预测值如果增大 1,误差就会猛增 16;反之,预测值减小,误差就会减小。)
接下来是见证奇迹的时刻,我们要分别算 $W_1$ 和 $W_2$ 的“背锅值(梯度)”:
- 算 $W_1$ 的背锅值:
- 我们看看 $W_1$ 的微小变动,传到最后会变成什么样?
- 因为公式是 $X\times W_1\times W_2$,所以 $W_1$ 发生变化时,它必须乘上身后的 $X$ 和 $W_2$ 才能输出。
- $W_1$ 的放大系数:$\dfrac{\partial \hat{y}}{\partial W_1}=X\times W_2=2\times0.1=0.2$。
- $W_1$ 的最终梯度:$\dfrac{\partial L}{\partial W_1}=\dfrac{\partial L}{\partial \hat{y}}\times\dfrac{\partial \hat{y}}{\partial W_1}=16\times0.2=3.2$。
- 算 $W_2$ 的背锅值:
- 同样,看看 $W_2$ 的微小变动,传到最后会变成什么样?
- 因为公式是 $X\times W_1\times W_2$,$W_2$ 发生变化时,它乘上的是前面的 $X$ 和 $W_1$。
- $W_2$ 的放大系数:$\dfrac{\partial \hat{y}}{\partial W_2}=X\times W_1=2\times100=200$。
- $W_2$ 的最终梯度:$\dfrac{\partial L}{\partial W_2}=\dfrac{\partial L}{\partial \hat{y}}\times\dfrac{\partial \hat{y}}{\partial W_2}=16\times200=3200$。
第三步:真相大白(更新参数)
你看出来了吗?!
- $W_1$ 的梯度只有 $3.2$
- $W_2$ 的梯度高达 $3200$(是 $W_1$ 的 $1000$ 倍!)
看到这里,大概就能解释为什么是损失和导数来计算背锅值(梯度)了。
下面是一个三维空间的演示例子
小结
到这里,我们已经把大模型训练最关键的一条主线串起来了
先用 Loss 定义“模型错了多少”,再用 导数(梯度) 把“错了多少”转化为“每个参数该怎么改”,最后通过 梯度下降 持续更新参数,让预测一步步逼近目标。
这套方法的核心价值在于:它把原本几乎不可能的“超高维盲目搜索”,变成了有明确方向的优化过程。参数虽然都参与计算,但不会“平均背锅”——谁对误差更敏感,谁的梯度就更大,谁就会被优先调整。
因此,训练并不是“记住答案”,而是在反复降低误差的过程中压缩并提炼数据中的规律;当规律积累到一定程度,模型就会表现出我们感受到的理解、推理与泛化能力。
下节预告
{为什么是链式法则}
{为什么是矩阵?}
{为什么梯度是背锅值?如何数学证明梯度下降方向是最优解?}