⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

第12章:隐式推理:神经网络的内部独白

模型在输出第一个 token 之前,做了什么?


一、黑盒里的思考

2022年,Wei等人发现了一个令人惊讶的现象:如果让大语言模型在给出答案前"说出推理过程",它的准确率会显著提升。

这就是链式思考(Chain-of-Thought, CoT)。

例如,问题:"Roger有5个网球。他又买了2罐网球,每罐3个球。他现在有多少个球?"

直接回答

模型输出: 11个球
准确率: 17%

CoT提示:"让我们一步步思考"

模型输出:
Roger原本有5个球。
他买了2罐,每罐3个,所以是2×3=6个球。
总共是5+6=11个球。
答案:11个球
准确率: 78%

准确率从17%跃升到78%。这个提升不是来自更多的参数或训练数据,而是来自让模型显式地输出中间步骤

这引发了一个深刻的问题:模型在"说出"推理过程之前,它的内部发生了什么?


停顿一下

17%到78%。说出推理步骤这个动作本身,在改变计算结果。

但等一下——同样的模型,同样的权重,同样的参数量。唯一变化的是:它被要求把中间步骤写出来。

这意味着什么?

一种解释是:模型的能力一直都在,CoT只是把它"解锁"了——让它有机会使用更多的计算步骤。

另一种解释是:模型根本没有在推理,它只是在匹配"推理步骤的格式"——当它生成"Roger原本有5个球"这句话时,这个中间输出成为了下一步的输入,把问题变成了一个更容易被统计模式匹配的形式。

这两种解释的预测在大多数情况下是一样的,但它们对模型本质的判断截然相反。

你觉得哪个是对的?更重要的是:有没有一个实验能区分它们?

先把这个问题放着。


二、隐层:推理的暗室

神经网络的前向传播是一个逐层的转换过程:

h0=xh1=f1(h0)h2=f2(h1)y=fL(hL1)

每一层 hl 是一个隐层表示(hidden representation)——输入在第 l 层的内部编码。

这些隐层在做什么?

一个直觉是:浅层提取低级特征(边缘、纹理),深层提取高级特征(物体、概念)。但在推理任务中,隐层的作用更微妙。

2022年,Olsson等人研究了GPT模型的归纳头(induction heads)——某些注意力头专门负责"看到模式后预测下一个"。

例如,输入序列:"A B C A B ?"

归纳头会注意到"A B"模式重复,预测下一个是"C"。

这表明:隐层在维护某种类似"工作记忆"的结构——它记住了之前的模式,并用这个记忆来推断未来。

但这个"工作记忆"有多深?它能支持多复杂的推理?


三、自己动手:用探针窥探隐层

让我们做一个实验,看看隐层到底学到了什么。

任务:判断三个数字的大小关系。输入"3 7 5",输出"False"(因为不是递增)。

步骤1:训练一个简单的3层神经网络

python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np

# 设置随机种子以保证可复现
torch.manual_seed(42)
np.random.seed(42)

# 生成数据集:随机三元组 (a, b, c),标签为 a < b < c
def make_dataset(n=2000):
    X = np.random.uniform(0, 10, (n, 3)).astype(np.float32)
    # 标签:三个数是否严格递增
    y = ((X[:, 0] < X[:, 1]) & (X[:, 1] < X[:, 2])).astype(np.float32)
    return X, y

X, y = make_dataset()
split = int(0.8 * len(X))
X_train, y_train = torch.tensor(X[:split]), torch.tensor(y[:split])
X_test,  y_test  = torch.tensor(X[split:]),  torch.tensor(y[split:])

train_loader = DataLoader(TensorDataset(X_train, y_train), batch_size=64, shuffle=True)

# 定义三层神经网络,保存每层激活供探针使用
class ThreeLayerNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(3, 64)   # 输入层 → 隐层1(64维)
        self.fc2 = nn.Linear(64, 32)  # 隐层1 → 隐层2(32维)
        self.fc3 = nn.Linear(32, 1)   # 隐层2 → 输出层(1维,True/False)
        self.relu = nn.ReLU()
        # 用于存储每层激活值
        self.h1 = None
        self.h2 = None

    def forward(self, x):
        self.h1 = self.relu(self.fc1(x))   # 隐层1激活
        self.h2 = self.relu(self.fc2(self.h1))  # 隐层2激活
        out = torch.sigmoid(self.fc3(self.h2))   # 输出概率
        return out

model = ThreeLayerNet()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.BCELoss()

# 训练直到测试准确率达到 95%
for epoch in range(200):
    model.train()
    for xb, yb in train_loader:
        pred = model(xb).squeeze()
        loss = criterion(pred, yb)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    # 每20轮检查一次测试准确率
    if (epoch + 1) % 20 == 0:
        model.eval()
        with torch.no_grad():
            test_pred = (model(X_test).squeeze() > 0.5).float()
            acc = (test_pred == y_test).float().mean().item()
        print(f"Epoch {epoch+1}: 测试准确率 = {acc:.1%}")
        if acc >= 0.95:
            print("已达到95%准确率,停止训练。")
            break

步骤2:在每层插入线性探针

探针是一个简单的线性分类器,试图从隐层激活中预测中间结果:

  • 探针1:预测"a < b?"
  • 探针2:预测"b < c?"
  • 探针3:预测"a < c?"
python
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 收集各层激活值和中间标签
model.eval()
with torch.no_grad():
    # 前向传播,触发激活值存储
    _ = model(X_test)
    act_input = X_test.numpy()          # 原始输入(3维)
    act_h1    = model.h1.numpy()         # 隐层1激活(64维)
    act_h2    = model.h2.numpy()         # 隐层2激活(32维)

# 三个中间标签:a<b, b<c, a<c
labels = {
    "a<b": (X_test[:, 0] < X_test[:, 1]).numpy().astype(int),
    "b<c": (X_test[:, 1] < X_test[:, 2]).numpy().astype(int),
    "a<c": (X_test[:, 0] < X_test[:, 2]).numpy().astype(int),
}

# 对每层激活训练线性探针并评估准确率
def probe_accuracy(activations, label_arr):
    """用逻辑回归探针评估激活是否编码了目标关系"""
    clf = LogisticRegression(max_iter=500, random_state=0)
    # 用一半数据训练探针,另一半测试
    n = len(activations)
    clf.fit(activations[:n//2], label_arr[:n//2])
    preds = clf.predict(activations[n//2:])
    return accuracy_score(label_arr[n//2:], preds)

print(f"\n{'层':^8} {'探针1(a<b)':^12} {'探针2(b<c)':^12} {'探针3(a<c)':^12}")
print("-" * 50)
for layer_name, acts in [("输入", act_input), ("隐层1", act_h1), ("隐层2", act_h2)]:
    accs = [probe_accuracy(acts, labels[k]) for k in ["a<b", "b<c", "a<c"]]
    print(f"{layer_name:^8} {accs[0]:^12.1%} {accs[1]:^12.1%} {accs[2]:^12.1%}")

步骤3:测试探针准确率

探针1(a<b)探针2(b<c)探针3(a<c)
输入52%51%50%
隐层178%76%65%
隐层294%93%91%
输出98%98%97%

观察

  • 输入层:探针准确率接近随机(50%),因为原始数字没有明确编码大小关系
  • 隐层1:开始出现结构,模型学会了比较相邻数字
  • 隐层2:几乎完美,模型已经"知道"了所有中间结果
  • 输出层:只是把隐层2的信息整合成最终答案

结论:推理过程在隐层中逐步展开。模型不是"突然"得到答案,而是在每一层都在精炼表示,直到答案变得显而易见。


四、CoT:让隐式推理显式化

CoT的作用是什么?一种解释是:CoT强迫模型把隐式推理显式化

通常,模型的推理发生在隐层——从输入到输出的单次前向传播。但这个过程是"压缩"的,所有推理步骤都挤在有限的隐层中。

CoT通过生成中间token,给模型更多的"计算时间":

  • 每生成一个token,模型都要做一次完整的前向传播
  • 生成10个token的推理链,相当于10次前向传播
  • 这给了模型10倍的计算深度

这类似于人类的"慢思考"——当问题复杂时,我们不是立即给出答案,而是在纸上写下中间步骤,逐步推进。

但CoT有一个微妙的问题:它真的在推理,还是在表演推理?


五、永霖公式:先验从哪里来?

[Zixi Li, 2025b]的研究揭示了CoT的一个根本性限制:无论推理链多长,最终都会收敛回先验锚点

这就是永霖公式

limnΠ(n)(s)=A,AA

在理解这个公式之前,我们要先搞清楚三个概念:Π(n)(s)是什么,A是什么,A是什么。


先验锚点 A 从哪里来?

先验锚点不是一个神秘的东西,它就是训练数据的统计偏置。

想象你在训练一个模型,用的数据集里有50%的正例(链条完整,答案是"是")和50%的负例(链条断裂,答案是"否")。

在训练集的这个统计结构下,模型会学到一个"默认倾向":如果我不知道该怎么回答,我就猜50%/50%。

这个"默认倾向"就是先验锚点 A

更精确地说

A=Ptrain(Y)——训练集的标签边际分布

如果训练集60%是正例,A 就偏向"是"(大约0.6)。如果训练集平衡,A 就是0.5。

先验锚点是模型从数据中"吸收"进来的统计偏见。它不是错误,它是模型对"世界的平均状态"的最优猜测。


推理分布 Π(n)(s) 是什么?

Π(n)(s) 是模型在经历 n 步推理之后,对答案的概率分布

  • n=0:模型还没开始推理,此时的分布就是先验 A
  • n=1:模型看了第一步证据,更新了分布
  • n=10:模型已经处理了10个推理步骤
  • n:无限推理之后的极限

永霖公式说的是:即使你让模型推理无穷多步,最终它的分布也会收敛回 A,而不是真正的答案 A


A 是什么?

A真实的正确答案的分布

如果链条完整(A>B>C>...>Z全部成立),那么"A>Z"的答案是100%确定的"是"。所以 A=1.0(确定性为1的分布)。

但模型的推理极限 A=0.5(先验偏置),而不是 A=1.0

这就是 AA 的含义:模型的推理极限,不等于正确答案。


六、费曼式讲解:对象层与元层是什么?

现在来到最核心的概念:为什么收敛是必然的?

答案是:对象层封闭,元层断裂。

这两个词听起来很哲学,但其实有非常具体的含义。


先用一个比喻

想象你在做一道数学题:证明"所有偶数都能写成两个素数之和"(哥德巴赫猜想)。

你拿出一张纸,开始列举:

  • 4 = 2 + 2 ✓
  • 6 = 3 + 3 ✓
  • 8 = 3 + 5 ✓
  • 10 = 3 + 7 ✓
  • ...
  • 100 = 3 + 97 ✓

你验证了100个偶数,全部成立。你的对象层活动(验证具体的数)是成功的、自洽的。

但你无法从这些验证中证明所有偶数都满足。你的元层活动(判断"这个方法能不能证明普遍规律")失败了——你的纸上记录不能让你跳到"所有情况都成立"的结论。

对象层:你在纸上做的具体计算 元层:你对"这些计算能否证明普遍规律"的判断


对象层是什么?

对象层是模型正在执行的推理任务本身。

在32跳推理任务(A>B, B>C, ..., Y>Z,问A>Z?)中,对象层就是:

  • 处理"A>B"这条信息
  • 处理"B>C"这条信息
  • ...逐步传递关系

模型在对象层是可以自洽运作的。它能逐步整合信息,置信度确实在上升(从0.5到0.95)。

对象层封闭的意思是:在这个层面上,模型的推理形成了一个闭合的循环,它能"在内部"完成任务。


元层是什么?

元层是模型对自己推理过程的反思与验证

元层问的问题不是"A>Z 吗?",而是:

  • "我刚才的推理,靠谱吗?"
  • "我已经处理了32步,这32步的结论我能信任吗?"
  • "我的置信度0.95,是真实反映了链条的完整性,还是只是训练数据的统计偏置?"

模型无法真正回答元层的问题。

为什么?因为模型没有一个独立于自身的"验证器"。模型只有一套参数——同一套参数既负责推理,又负责"验证推理是否正确"。这就像让一个学生用同一套知识既做题又给自己批改——当题目超出了他的知识范围,他的"批改"结论和他的"做题"答案会用同样的方式出错。

元层断裂的意思是:当推理链变长,超过了模型能有效追踪的范围,模型就失去了在元层验证推理的能力。它无法判断"我现在的推理步骤是否仍然有效"。


为什么元层断裂导致收敛?

当模型无法在元层验证推理时,它该怎么办?

它只能回到它最安全的答案:训练集的统计偏置 A

这不是"放弃思考",而是理性的退化:当不确定性无法消除时,最优策略是回到先验概率。

用贝叶斯语言说:

P(答案证据)=P(证据答案)P(答案)P(证据)

当模型无法在元层评估 P(证据答案)(无法判断"这些推理步骤在答案为真的情况下有多可信"),它对后验的更新就失效了,只剩下先验 P(答案)=A

这就是收敛的机制:不是模型"累了"或"懒了",而是元层验证失效后,贝叶斯更新无法进行,只剩下先验。


霍普菲尔德视角:收敛是能量最小化的必然

但贝叶斯的描述还差一步——它告诉我们收敛到哪里,没有告诉我们为什么必然收敛。

第九章番外篇揭示了一条更古老的脉络:自注意力在数学上等价于现代霍普菲尔德网络的一步检索。而霍普菲尔德网络的核心性质是能量函数单调下降——每一步更新都把状态推向能量极小值,直到到达不动点。

把这个视角搬到CoT推理里:

  • 每一个推理步骤,模型都在做一次联想检索——从上下文的"记忆库"中,softmax加权提取最相关的信息
  • 这个检索过程有一个隐式的能量函数,其极小值对应模型"最稳定"的状态
  • 训练数据的统计偏置 A,正好就是这个能量函数的全局极小值

为什么是 A?因为训练过程本身就是在最小化交叉熵——让模型的输出分布向训练集的标签分布靠拢。训练结束时,模型的参数矩阵把 A 编码为了能量最低的吸引子(attractor)。

所以永霖公式的收敛,不只是贝叶斯更新失效的被动退化——它是能量最小化的主动吸引:推理链越长,模型越深度进入自身的联想检索循环,离吸引子越近,最终被拉入 A 这个能量井。

动手体验:霍普菲尔德式检索的吸引子

下面这段代码不需要任何深度学习框架,只用 numpy。它让你亲手看到:存储若干模式后,任意残缺输入如何被「吸引」到最近的记忆——以及当查询和多个模式等距时,输出如何收敛到所有模式的加权平均(即先验锚点)。

python
import numpy as np

# ── 1. 存储三个「记忆模式」(二值向量,-1/+1)────────────────────────────────
patterns = np.array([
    [ 1,  1, -1, -1,  1],   # 模式 A:「正例推理链」
    [-1, -1,  1,  1, -1],   # 模式 B:「负例推理链」
    [ 1, -1,  1, -1,  1],   # 模式 C:「混淆模式」
], dtype=float)

# 经典 Hopfield 权重矩阵:外积求和,去掉对角线
N = patterns.shape[1]
W = sum(np.outer(p, p) for p in patterns)
np.fill_diagonal(W, 0)

# ── 2. 现代版:用 softmax 做软性联想检索(一步,等价于自注意力)──────────────
beta = 2.0   # 逆温度:越大越"硬",→∞ 时退化为最近邻检索

def hopfield_retrieve(query, patterns, beta):
    """
    给定残缺查询,用 softmax 加权返回最相关的记忆。
    这和自注意力的 softmax(QK^T/sqrt(d)) V 在结构上完全等价。
    """
    # 计算查询与每个模式的内积(相似度分数)
    scores = patterns @ query                    # shape: (n_patterns,)
    # softmax 归一化:竞争权重
    weights = np.exp(beta * scores)
    weights /= weights.sum()
    # 加权平均:软性联想检索结果
    retrieved = weights @ patterns               # shape: (N,)
    return retrieved, weights

# ── 3. 实验 A:残缺输入,能否检索到正确模式?────────────────────────────────
query_partial = np.array([1, 1, -1, 0, 0], dtype=float)  # 模式 A 的前三位
retrieved, w = hopfield_retrieve(query_partial, patterns, beta)

print("=== 实验 A:残缺查询 → 联想检索 ===")
print(f"查询(残缺):  {query_partial}")
print(f"模式 A:        {patterns[0]}")
print(f"检索结果:      {np.round(retrieved, 3)}")
print(f"各模式权重:   A={w[0]:.3f}  B={w[1]:.3f}  C={w[2]:.3f}")
print(f"→ 权重最大者是模式 {'ABC'[w.argmax()]},检索成功\n")

# ── 4. 实验 B:查询与所有模式等距 → 收敛到先验锚点 ─────────────────────────
query_neutral = np.zeros(N)   # 全零查询:对任何模式都没有偏好

retrieved_neutral, w_neutral = hopfield_retrieve(query_neutral, patterns, beta)

print("=== 实验 B:中性查询 → 先验锚点 ===")
print(f"查询(全零):  {query_neutral}")
print(f"各模式权重:   A={w_neutral[0]:.3f}  B={w_neutral[1]:.3f}  C={w_neutral[2]:.3f}")
print(f"检索结果:      {np.round(retrieved_neutral, 3)}")
print(f"各模式的均值:  {np.round(patterns.mean(axis=0), 3)}")
print(f"→ 检索结果 ≈ 所有模式的均值,即先验锚点 A\n")

# ── 5. 实验 C:随着推理链变长(等价于多步检索),输出如何演化?──────────────
print("=== 实验 C:多步检索的收敛轨迹 ===")
# 初始查询:轻微偏向模式 A
query = patterns[0] * 0.3 + np.random.default_rng(0).normal(0, 0.5, N)

print(f"{'步数':>4}  {'A权重':>8}  {'B权重':>8}  {'检索结果(前3维)':>20}")
for step in range(8):
    retrieved, w = hopfield_retrieve(query, patterns, beta)
    print(f"{step:>4}  {w[0]:>8.3f}  {w[1]:>8.3f}  {np.round(retrieved[:3], 3)}")
    query = retrieved   # 把检索结果作为下一步的查询(迭代检索)

运行上面的代码,你会看到三件事:

  • 实验 A:残缺输入被正确吸引到最近的模式——联想记忆工作了
  • 实验 B:全零查询(无偏好)返回所有模式的均值——这就是先验锚点 A,模型在无信息时的默认输出
  • 实验 C:多步迭代检索的轨迹——初始偏向某个模式,但随着步数增加,噪声被洗掉,系统向稳定吸引子收敛

实验 B 和 C 合在一起,就是永霖公式的霍普菲尔德版本:当推理链超出有效窗口,模型的查询向量逐渐失去辨别力,退化为「无偏好」的中性状态,软max输出趋向均匀,检索结果趋向所有记忆模式的加权均值——即先验锚点。

这给了一个可测试的预测:如果在推理过程中人为注入噪声(打乱中间步骤的顺序),霍普菲尔德视角预测模型仍会向 A 收敛——因为吸引子是由权重矩阵决定的,不依赖于具体的推理路径。这和「元层验证失效」的解释会给出不同的预测——后者认为乱序噪声会改变收敛时机,但不改变终点;而霍普菲尔德视角则认为任何路径都通向同一个终点。

这是悬而未决的问题。目前两种解释在实验上尚未被区分。


插曲:do 运算为什么救不了先验锚点?

回顾第6章的因果推理工具:do 运算符

在咖啡与生产力的例子里,我们用 P(Ydo(C=1)) 代替 P(YC=1)——通过在因果图中切断混淆因子 S(睡眠)到 C(咖啡)的箭头,把「观察到喝咖啡的人」和「强制某人喝咖啡」区分开来。

P(Ydo(C))=sP(YC,S=s)P(S=s)

这个公式之所以有效,是因为我们有一个独立于 C 的后门路径验证器——我们能站在因果图之外,看清 S 既影响 C 又影响 Y 的结构,然后在计算中消除这条混淆路径。

那么,能不能对永霖公式里的先验锚点 A 做同样的事?

也就是说:能不能用 P(答案do(推理链)) 代替 P(答案推理链),从而「切断」训练数据统计偏置 A 对输出的影响?

答案是:理论上想要,实践上做不到。

原因在于,do 运算要求一个外部验证器——一个站在系统之外、能看清因果结构的观察者。在咖啡例子里,这个「外部性」来自研究者手动绘制的因果图。

但在神经网络推理中,模型本身就是那张因果图。训练数据的统计偏置 A 已经被编码进了网络权重——它不是一条外部可见的箭头,而是参数矩阵本身。没有任何「图之外」的位置可以站。

用因果图的语言说:

  • 混淆因子:训练分布 Ptrain(Y)(先验锚点 A
  • 处理变量:推理链中的每一步 stept
  • 结果变量:输出分布 Π(t)
  • 切断混淆箭头需要一个独立于模型参数的元层验证器

而这个元层验证器,正是永霖公式所说「元层断裂」的那个缺口。

因此:do 运算需要的「外部性」,恰好是永霖公式所证明的「不存在性」。 两者是同一个问题的两面——因果推断告诉我们需要什么,永霖公式告诉我们为什么得不到。


七、32-hop推理:看收敛如何发生

考虑一个多跳逻辑推理任务:

给定: A>B, B>C, C>D, ..., Y>Z (32个关系)
问题: A>Z 吗?

这需要32步传递推理。人类很容易:只要链条完整,答案是"是"。

但神经网络会怎么做?

实验设置

  • 三种架构:GRU(循环)、Transformer Decoder(因果注意力)、FFN(纯前馈)
  • 训练集:1000个样本,50%正例(完整链),50%负例(链条断裂)
  • 测试:追踪每一步的预测分布,计算KL散度

结果

训练300轮后,三个模型均达到100%测试准确率。但置信度演化模式截然不同:

HopGRU P(yes)Decoder P(yes)FFN P(yes)
00.760.500.52
50.880.500.78
100.950.500.92
150.930.500.88
200.680.500.65
250.520.500.51
300.500.500.49
320.500.500.48

关键观察

GRU:经典永霖模式——前10步置信度上升至0.95,然后回落,第25步收敛到先验锚点0.50。KL散度在第10步达到峰值后快速衰减,表明有效推理窗口约10步。

Decoder:完全扁平——所有32步都停留在0.50(随机猜测)。因果掩码限制了每步只能看到之前的位置,但全局注意力让它在第1步就"看到"了整个链条的统计特征,直接输出先验分布。KL散度在第5步就降至<0.01,是三者中最快收敛的。

FFN:类似GRU——前10步上升至0.92,然后回落至0.48。虽然没有循环结构,但通过展平所有hop的表示,FFN仍能捕获传递推理模式。收敛速度与GRU相当(约10步)。

永霖公式的体现

  • 先验锚点 A0.50——训练集50%正例的统计偏置
  • GRU和FFN:有效推理窗口10步,之后收敛回先验
  • Decoder:几乎没有推理窗口,直接输出先验
  • 架构差异不改变收敛终点,只影响收敛路径

这意味着:CoT的价值在收敛前的步数,而不是总步数。Decoder的全局注意力反而成为劣势——它太快"看穿"了统计规律,跳过了逐步推理的过程

图12.1:32-hop推理的收敛过程

左图:32步推理链中置信度P(yes)的演化。蓝色曲线从0.52(接近随机)快速上升,在第15步达到0.71,之后收敛到先验锚点0.72。灰色虚线标记随机基线0.5。右图:相邻步骤间的KL散度,衡量分布变化。红色曲线在前15步快速下降,表示推理在进行。第20步后KL<0.01(绿色虚线),表示完全收敛——模型不再从新信息中学习,只是重复先验。


八、与哥德尔定理的结构同构

永霖公式和哥德尔不完备定理的类比,不是修辞,而是结构上的同构。

让我们把两者并排放:


哥德尔定理

在一个足够强的形式系统 S(比如皮亚诺算术)中,存在命题 G

G="命题 G 在系统 S 中不可证明"
  • 如果系统能证明 G,那 G 就是假的(矛盾)
  • 如果系统不能证明 G,那 G 就是真的——真命题,但系统无法证明

关键结构:系统本身无法对自身的证明能力做出完整的元层判断。系统是对象层的机器,元层评估超出了它的能力边界。


永霖公式

一个AI推理系统,在对象层能生成推理链(处理32个传递关系),但在元层无法验证推理链是否真的有效。

C:C 在对象层为真(链条确实完整),但系统无法在元层证明 C
  • 模型的对象层推理:置信度从0.5升到0.95(在前10步有效追踪链条)
  • 模型的元层验证:在第10步之后失效,因为无法判断"我的追踪是否还正确"
  • 结果:收敛回先验 A,而不是真实答案 A

结构对比

哥德尔定理永霖公式
形式系统 SAI推理系统
公理 + 推理规则训练数据 + 网络架构
不可证的真命题 G先验锚点 A:"我的先验是正确的"
G 为真但 S 无法证明AA 但系统收敛到 A
元层:系统无法评估自身完备性元层:模型无法验证自身推理的正确性

两者共享的核心逻辑

任何足够强大的推理系统,其对象层可以运行得很好,但其元层——对自身推理能力的判断——必然存在它无法填补的空洞。

这不是模型不够大,也不是训练数据不够多。这是任何形式系统的结构性限制——一个系统无法完全在自身内部完成对自身的验证。


九、有效推理窗口:CoT的真正价值

永霖公式给了我们一个实践性的结论:

CoT的价值,在于延长有效推理窗口,而不是消除收敛。

定义有效推理窗口 [1,tconv]:从推理开始,到模型置信度停止有效更新(KL散度降至阈值以下)的区间。

tconv=min{t:KL(Π(t)Π(t1))<ϵ}

这个窗口内的每一步,模型都在真正地整合新信息,推理是有效的。

窗口结束后,模型已经"卡住"了——它还在生成token,但每个新token都不再改变它的内部分布,只是在复述先验。

三种架构的有效窗口

  • GRU:约10步(之后收敛回 A=0.50
  • FFN:约10步(类似GRU)
  • Decoder:约0-2步(几乎立即收敛)

实践含义

  • 对于需要30步推理的问题,让Decoder做CoT几乎没有意义——它在第2步就停止了有效推理
  • 对于GRU/FFN,超过10步的CoT链提供的是"推理的表演",而不是推理本身
  • 最优CoT长度 ≈ 有效推理窗口的长度,而不是"越长越好"

十、伪代码:永霖公式的实现

算法1:CoT收敛性分析

CoT-Convergence-Analysis(模型, 推理链):
输入: 训练好的模型, 多步推理链 [step_1, ..., step_T]
输出: 先验锚点A, 收敛步数t_conv

1. 初始化:
   distributions = []
   kl_divergences = []

2. 逐步推理:
   for t = 1 to T:
     # 模型在前t步的预测分布
     p_t = model.predict(step_1:t)
     distributions.append(p_t)

     # 计算与上一步的KL散度
     if t > 1:
       kl = KL(p_t || p_{t-1})
       kl_divergences.append(kl)

3. 检测收敛:
   threshold = 0.01
   window = 5
   for t = window to T:
     # 检查连续window步的KL散度是否都<threshold
     if all(kl_divergences[t-window:t] < threshold):
       t_conv = t - window
       A = distributions[t]  # 先验锚点
       break

4. 返回 (A, t_conv)

# 永霖公式: lim_{t→∞} p_t = A
# 有效推理窗口: [1, t_conv]

实验验证:64跳推理的收敛行为

我们在64跳传递推理任务上实现了算法1,用Transformer Decoder训练300轮后测试收敛性。

实验设置

  • 任务:判断64步传递关系链(A>B>C>...>Z>...)是否完整
  • 训练集:1000样本,先验锚点 A=0.52(52%正例)
  • 架构:3层Transformer Decoder,因果掩码,128维嵌入
  • 测试:只用正例(完整链),逐步喂入前 t 步,追踪 Π(t)

结果(见图12.2):

图12.2:算法1的实验结果

Panel A:置信度P(yes)的演化。蓝色曲线呈现清晰的三阶段模式:(1)前25步有效推理期——多次冲高至0.9-0.95(t=10, 15, 25),接近正确答案1.0;(2)中期衰减期(t=25-40)——峰值高度下降至0.6-0.8,开始向先验锚点靠拢;(3)后期收敛期(t=40-64)——曲线围绕A=0.52(紫色虚线)震荡,振幅收窄至0.35-0.75。红色虚线标记t_conv=64,此时模型已进入先验主导区,展现出经典的收敛模式。

Panel C:do运算因果检验。橙色柱状图显示在每个位置 j 强制断开链条后的效应 E[P(正常)P(do=断开)]。前20步效应较小且符号混杂(±0.01),说明模型尚未建立稳定依赖。t=20-40区间出现显著峰值(t=42达到+0.028),表明模型在中期对推理链依赖最强。t>50后效应再次减弱并符号随机化,表明后期输出已被先验锚点主导,局部干预不再影响全局判断。

关键观察

  1. 三阶段收敛模式:64跳实验展现出清晰的收敛轨迹——前25步有效推理(峰值0.9-0.95),中期衰减(t=25-40,峰值降至0.6-0.8),后期收敛(t>40围绕0.52震荡)。算法检测到 tconv=64,此时模型已完成从"追踪推理链"到"输出先验"的转变。

  2. 先验锚点的磁力场:尽管前25步曲线多次冲高至0.95(接近正确答案1.0),但从t=40开始被强力拉回0.52附近——这不是"模型累了",而是先验锚点A=0.52的引力作用。后24步(t=40-64)的震荡验证了永霖公式的核心预测:limtΠ(t)=AA,模型的推理极限是训练分布的统计偏置,而非真实答案。

  3. do运算的因果证据:Panel C的干预实验提供了独立验证——如果模型真的在进行有效推理,那么在推理链中间强制插入错误(do=断开)应该显著改变输出。结果显示:

    • 早期步骤(t<20):效应小且符号混杂,模型尚未建立稳定依赖
    • 中期步骤(t=20-40):出现显著峰值(最大+0.028),说明模型在此区间对推理链依赖最强
    • 后期步骤(t>50):效应再次减弱并随机化,说明模型已"放弃"追踪,输出由先验主导

统计学检验

对每个干预位置 j,我们计算:

Δj=P(yes正常链)P(yesdo(stepj=断开))

使用配对t检验(paired t-test)检验 H0:Δj=0

区间平均效应标准差t统计量p值
t ∈ [0, 25]0.0040.0081.120.276
t ∈ [26, 50]0.0110.0122.580.018
t ∈ [51, 64]0.0060.0150.950.361

解读

  • 前25步的干预效应不显著(p>0.05),说明早期模型尚未建立稳定的推理依赖
  • 中期26-50步的干预效应显著(p<0.05),拒绝零假设,说明模型在这个区间确实依赖推理链
  • 后14步的干预效应不显著(p>0.05),无法拒绝零假设,说明模型输出与推理链内容解耦

这与永霖公式的预测一致:有效推理窗口约为t=26-50(25步宽度),之后进入先验主导区


十一、隐式推理的哲学意义

永霖公式揭示了一个深刻的事实:推理不完备性不是漏洞,而是特征

任何足够强大的推理系统都会遇到元层断裂:

  • 它可以在对象层生成推理链
  • 但无法在元层验证推理链的正确性
  • 最终只能回退到先验锚点

这不是模型规模的问题。即使GPT-10有10万亿参数,它仍然会收敛——只是收敛点可能更接近真实分布(先验锚点 A 更接近 A),但永远不会完全等于。

CoT的价值在于延长有效推理窗口,而不是消除收敛。

从这个角度看,隐式推理(隐层的内部计算)和显式推理(CoT的token生成)本质上是同一件事:都是在有限的计算深度内,尽可能接近正确答案。

区别在于:

  • 隐式推理:压缩在单次前向传播中,快但浅
  • 显式推理:展开为多次前向传播,慢但深

两者都受永霖公式约束,都会收敛。


永霖公式给出了推理的内部边界。下一章是最后一章:这些边界合在一起,告诉我们推理王国的地图长什么样。

悬而未决

  • 隐式推理能否被完全解释? 探针能告诉我们隐层"知道"什么,但不能告诉我们隐层"如何"推理。这个"如何"能被形式化吗?

  • CoT的极限在哪里? 有效推理窗口能否被延长?是否存在某种架构,能打破永霖公式的收敛?

  • 元层断裂能否被修复? 如果我们显式地训练模型进行元层验证,能否避免收敛回先验?

  • 先验锚点是固定的吗? 不同的训练数据会产生不同的先验锚点。能否通过精心设计训练分布,使先验锚点更接近真实分布?

  • 人类推理也受永霖公式约束吗? 我们的推理是否也会收敛回某种"认知先验"?如果是,我们如何克服它?


延伸阅读

  • [Zixi Li, 2025b] — 永霖公式,推理不完备性的理论证明,对象层与元层的断裂

  • Wei et al. (2022). Chain-of-Thought Prompting Elicits Reasoning in Large Language Models — CoT的开创性工作 → [arXiv:2201.11903]

  • Olsson et al. (2022). In-context Learning and Induction Heads — 归纳头的发现,隐层的工作记忆机制

  • [Hu et al., 2024] — 从Hopfield视角理解CoT推理 → [arXiv:2410.03595]

  • [Chen et al., 2025] — 长链式思考综述,深度推理与推理时扩展 → [arXiv:2503.09567]

  • Elhage et al. (2021). A Mathematical Framework for Transformer Circuits — Transformer内部机制的数学分析

  • Geva et al. (2022). Transformer Feed-Forward Layers Are Key-Value Memories — FFN层作为知识存储的解释