高中觉得最玄乎的"极限",其实是大模型"从犹豫到笃定"的那个旋钮
极限、
lim、ε-δ、数列收敛、x→0……高中(到大一)学得云里雾里,只记得"(1+1/n)^n趋近 e"这种结论。 因为老师只教你"求极限、判断收敛",没告诉你两件事:第一,极限的灵魂不是"一种难算的题型",是回答一个问题:无限逼近某个状态时,会发生什么。 第二,今天每一个大模型(LLaMA、Qwen、GPT、DeepSeek)采样时那个"温度 temperature"旋钮, 一端的极限是"绝对笃定"(只选最可能的词),另一端的极限是"完全随机"(所有词平均乱选)—— 这就是极限思想最日常的一次落地。
这篇文章不背一个公式、不做一道 ε-δ 证明,全部用能跑起来的 PyTorch 代码, 把极限最核心的"无限逼近"本质,一路接到大模型的采样温度与训练收敛。 并且顺手回答四个灵魂拷问:
- 极限(
x→某值时的趋势)明明是纯数学,怎么和大模型扯上关系?- 采样温度调到 0 会怎样?调到无穷大又会怎样?
- 训练时 loss 一直降却降不到 0,那个"降不动的地方"是什么?
- "逼近但取不到"的极限思想,在模型里究竟藏在哪?
0. 一句话主线
如果只能留一句话,那就是这句:
极限研究的是"无限逼近某个状态时会发生什么"。
大模型里最典型的两处极限:采样温度 T→0 时,softmax 逼近 argmax(绝对笃定);T→∞ 时,
逼近均匀分布(完全犹豫)。 而训练,则是 loss 这个数列,无限逼近它的下界极限的过程。
import torch
# 极限:n 越来越大时,数列逼近的那个值
for n in [1, 10, 100, 10000]:
print(f"n={n:6d} 1/n={1/n:.4f} (1+1/n)^n={(1 + 1/n) ** n:.5f}")
# 1/n -> 0;(1+1/n)^n -> e≈2.71828 —— 一路逼近,但每一步都取不到
记住这个画面:极限是"逼近的目标"——你可以无限靠近它,却不一定真正抵达。 下面所有东西都挂在"无限逼近"这一件事上。
1. 极限就是"逼近的目标"
高中把极限包装成一堆"求值、判敛"的技巧,把你困在计算里。但极限只讲一件事: 当变量沿着某个方向一直走下去,函数值会稳定地靠向哪个数。 那个数,就是极限。
import torch
# 一个数列沿着 n 增大不断逼近 0,但永远差那么一点点
n = torch.arange(1, 8)
seq = 1 / (2 ** n.float()) # 1/2, 1/4, 1/8, ...
print("数列:", seq.round(decimals=4).tolist())
print("它逼近的极限:", 0.0, "(越来越近,但每一项都 > 0,取不到)")
1/2, 1/4, 1/8, … 这串数越来越接近 0,却永远大于 0——"无限逼近但取不到",正是极限的精髓。
这个看似哲学的性质,等下会变成大模型里两个极其具体的行为:温度的两个极端、训练的收敛下界。
2. softmax 的温度:同一组分数,可尖可平
大模型每步预测下一个词,输出一组分数(logits),再用 softmax 变成概率。 其中藏着一个旋钮——温度 T:把 logits 先除以 T 再做 softmax。T 改变的是分布的"尖锐程度":
import torch
import torch.nn.functional as F
logits = torch.tensor([2.0, 1.0, 0.1]) # 同一组分数
for T in [2.0, 1.0, 0.3]:
p = F.softmax(logits / T, dim=-1)
print(f"T={T}: {p.round(decimals=3).tolist()}")
# T 大 -> 分布平(三个词都有机会,犹豫)
# T 小 -> 分布尖(概率集中到最大的那个,笃定)
同样的分数,T 大时分布平坦、模型"犹豫";T 小时分布尖锐、模型"笃定"。
温度只是连续地调节"尖还是平"。而当我们把它推向两个极端——T→0 和 T→∞——极限就登场了。
🤔 疑惑点一:温度调到 0 会怎样?调到无穷大又会怎样?
T→0 是一个极限:分布会无限逼近 argmax,也就是把全部概率压给分数最高的那个词,变成 one-hot——模型绝对笃定、毫不犹豫(这就是"贪心解码")。T→∞ 是另一个极限:所有 logits 被除到几乎相等,softmax 逼近均匀分布——模型完全放弃判断、每个词等概率乱选。真实采样就在这两个极限之间调节。
把这两个极限直接跑出来看:
import torch
import torch.nn.functional as F
logits = torch.tensor([2.0, 1.0, 0.1])
print("T->0 (取0.01):", F.softmax(logits / 0.01, dim=-1).round(decimals=3).tolist())
print("T->inf(取100) :", F.softmax(logits / 100, dim=-1).round(decimals=3).tolist())
# T->0 逼近 [1,0,0]:argmax,绝对确定
# T->inf 逼近 [.33,.33,.33]:均匀分布,完全随机
T→0 时分布逼近 [1, 0, 0](把所有概率给最大项,就是 argmax);
T→∞ 时逼近 [0.33, 0.33, 0.33](均匀)。注意这两个都是"逼近"而非"等于"——
数学上 T 严格取 0 会除零,我们只能让它无限趋近。这正是极限"逼近但取不到"的精神在采样里的化身。
3. 温度就是"确定性 ↔ 创造力"的连续旋钮
理解了两个极限,中间的温度就有了清晰的意义:它是一个从"死板确定"滑到"天马行空"的连续旋钮。
import torch
import torch.nn.functional as F
torch.manual_seed(0)
logits = torch.tensor([2.0, 1.5, 1.0, 0.5])
for T in [0.2, 1.0, 3.0]:
p = F.softmax(logits / T, dim=-1)
picks = torch.multinomial(p, 1000, replacement=True).bincount(minlength=4)
print(f"T={T}: 四个词各被采样 {picks.tolist()} 次")
# T=0.2 几乎只选第一个词(确定、复读)
# T=3.0 四个词都被大量选中(发散、有创造力也更容易胡说)
低温(趋近 T→0 那个极限)几乎只复读最高分的词,输出稳定但呆板;
高温(趋近 T→∞ 那个极限)让冷门词也有机会,输出更有创造力、也更容易跑偏。
你在各种大模型 API 里调的那个 temperature 参数,调的就是"离哪个极限更近"。
4. 训练也是极限:loss 逼近它的下界
极限的第二处化身,在训练里。loss 一路下降,但通常降不到 0——它在逼近一个下界(数据里不可消除的噪声)。
import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(0)
# 数据带有标准差 0.3 的噪声 -> loss 的极限下界 ≈ 0.3² = 0.09
X = torch.randn(200, 1)
y = 2 * X + 1 + 0.3 * torch.randn(200, 1)
model = nn.Linear(1, 1)
opt = torch.optim.SGD(model.parameters(), lr=0.05)
for step in range(201):
loss = F.mse_loss(model(X), y)
opt.zero_grad(); loss.backward(); opt.step()
if step % 40 == 0:
print(f"step {step:3d} loss={loss.item():.4f}")
# loss 一路下滑,然后停在 0.10 附近(≈ 噪声方差 0.3²=0.09)—— 那就是它逼近的极限下界,再努力也过不去
loss 从一个大值一路下降,最后卡在 0.10 附近不动——那正是数据噪声方差 0.3²=0.09 的量级。
这就是"逼近但取不到"在训练里的样子:模型能无限接近这个下界,却永远无法突破它。
所谓"训练收敛",本质就是 loss 这个数列,抵达了它的极限。
🤔 疑惑点二:那个"逼近但取不到"的极限,最深处藏在哪?
藏在"导数"里——而导数是整个梯度下降的根。导数的定义本身就是一个极限:让步长 h 无限趋近 0,(f(x+h)−f(x))/h 逼近的那个值,就是导数。模型每一步更新参数用的梯度,就建立在这个"h→0"的极限之上。所以极限不只是采样和收敛的比喻,它是"模型如何学习"的数学地基。
把导数的定义——一个极限——用代码逼近出来:
# 导数就是一个极限:h 无限趋近 0 时,(f(x+h)-f(x))/h 逼近的值
f = lambda x: x ** 2 # f(x)=x²,其导数 f'(x)=2x,在 x=3 处应为 6
x = 3.0
for h in [1.0, 0.1, 0.001, 1e-6]:
slope = (f(x + h) - f(x)) / h
print(f"h={h:>8}: 斜率 ≈ {slope:.5f}")
# h 越趋近 0,斜率越逼近 6.00000 —— 梯度下降的每一步,都站在这个极限之上
h 从 1 缩到 1e-6,算出的斜率从 7 一路逼近 6.00000——这正是 f'(3)=2×3=6。
你调用的每一次 loss.backward(),背后都是无数个这样的"h→0"极限。
(如果读过本系列《微积分》那篇,那里讲"导数是变化率",这篇补上它更底层的一句:导数首先是一个极限。)
🎬 动手:看 softmax 随温度从 ∞ 滑到 0
把温度这个"极限旋钮"从高到低扫一遍,用字符条直观看分布如何从"均匀"收紧成"one-hot":
import torch
import torch.nn.functional as F
logits = torch.tensor([3.0, 2.0, 1.0, 0.5])
print("温度从高到低,分布如何从'完全犹豫'逼近'绝对笃定':")
for T in [10.0, 2.0, 1.0, 0.5, 0.1]:
p = F.softmax(logits / T, dim=-1)
bar = "".join("█" if v > 0.15 else "·" for v in p)
print(f"T={T:>4}: {p.round(decimals=2).tolist()} {bar}")
# T=10 四格接近均匀(T->inf 的极限方向)
# T=0.1 概率几乎全压在第一格(T->0 的极限方向:argmax)
仓库里的动画脚本把这个"极限旋钮"完整画了出来:
python temperature_limit_visualization.py
左边是 softmax 分布的条形图,温度从很高滑到很低时,你会看到它从平坦的均匀分布,一路收紧成一根独苗(one-hot); 右边是分布的"熵"(不确定性)随温度变化的曲线——
T→∞时熵逼近最大值(最犹豫),T→0时熵逼近 0(最笃定)。两端各有一个极限,中间是连续的过渡,这就是极限思想最生动的一张图。
缝合:把所有画面接起来
回到开头,现在每个概念都有了画面和代码出处:
| 极限概念 | 高中怎么讲 | 这篇文章怎么看(画面) | 在大模型里是什么 |
|---|---|---|---|
| 数列极限 | lim 求趋近值 |
逼近但取不到(第 0、1 节) | 训练收敛的下界 |
T→0 的极限 |
单侧极限 | softmax 逼近 argmax(疑惑点一) | 贪心解码、绝对笃定 |
T→∞ 的极限 |
趋于无穷 | softmax 逼近均匀分布(疑惑点一) | 完全随机采样 |
| 收敛 | 数列稳定到一点 | loss 卡在噪声下界(第 4 节) | "训练收敛" |
| 导数的定义 | h→0 的极限 |
斜率逼近 2x(疑惑点二) | 梯度下降的地基 |
三句话总结这篇文章:
极限的灵魂是"无限逼近某个状态"——逼近得到、却不一定抵达(第 1 节); 采样温度的两端就是两个极限——
T→0逼近 argmax(笃定)、T→∞逼近均匀(犹豫),中间连续可调(第 2、3 节、疑惑点一); 训练收敛与梯度,也都建立在极限上——loss 逼近下界、导数是h→0的极限(第 4 节、疑惑点二)。
当年极限学得那么玄乎,不是因为它难,是因为没人告诉你: 那个"无限逼近却取不到"的抽象思想,最后变成了你在大模型里调的每一个温度旋钮, 和它每一步学习背后的梯度。 现在把上面每段代码跑一遍,比高中刷十套极限题都值。
备注(选题/标题): 这篇走的是"高中知识其实是 AI 基石"的钩子(和《对数》《向量》《sin 和 cos》同一路子)。 核心爽点是"温度的两端各是一个极限"这个既实用(人人都调过 temperature)又优雅的映射。 与《微积分》那篇有承接:那篇讲"导数是变化率",这篇补"导数首先是一个极限",可互相引流。 若并入"大学4年"主系列:《大学4年没让你真正搞懂的极限,被大模型的温度旋钮讲透了》。