文章

从分布和概率看RLCD和类Jev模型

从分布和概率看RLCD和类Jev模型

背景:LLM 如何产出 logits 与决策

自回归语言模型:预测并追加下一个 token

给定上下文 $s$,语言模型先输出词表 $\mathcal V$ 上的分数 $\ell_\theta(s)$,也就是 logits。softmax 将这些分数转成下一个 token 的概率:

\[p_\theta(v\mid s)=\frac{\exp\ell_\theta(v\mid s)}{\sum_{u\in\mathcal V}\exp\ell_\theta(u\mid s)}.\]

得到分布之后,才需要决定如何输出。采样按概率抽取一个 token,greedy decoding 则直接取概率最大的 token:

\[v\sim p_\theta(\cdot\mid s) \qquad\text{或}\qquad \hat v=\arg\max_v p_\theta(v\mid s).\]

例如,三个候选的 logits 为 $(2,1,0)$,softmax 后约为 $(0.665,0.245,0.090)$。greedy 总是选择第一项;反复从这个固定分布采样,第一项约占 66.5%。

常规 AR 生成会把选出的 token 接回上下文,再计算下一步分布,如此反复。如果任务只要求从几个动作中选一个,可以把动作映射到单 token 标签,例如 A、B、C,直接读取这些标签的 logits,在候选集合内归一化:

\[\pi_\theta(a_i\mid s,A) =\frac{\exp\ell_\theta(v_i\mid s,A)}{\sum_{j=1}^{K}\exp\ell_\theta(v_j\mid s,A)}, \qquad A=\{a_1,\ldots,a_K\}.\]

这里 $v_i$ 是动作 $a_i$ 对应的标签 token,动作说明随输入提供。程序拿到整个动作分布后,就可以采样或取最大项,无须让模型继续写出动作名称和 JSON。同一个 LLM 骨干由此可以用于文本生成,也可以用于一次前向的有限动作决策。

后面讨论训练方法时,我们关心的是:这个分布依据什么信号更新,以及更新后的概率应当表达什么。

从分布看不同算法的训练目标

下面用一个能力有限的模型比较训练目标。输入是客服工单的完整日志,要求判断登录失败的原因:A 表示账号问题,B 表示服务故障。每条工单都有确定的正确答案。

假设当前编码器 $E$ 对这类日志只能提取出“登录失败”的信息,输出表示记为 $h_{\rm login}$。换句话说,这个模型能力有限,没有能提取出更细致的原因,而把两种类型混到了一块,其中,70% 的原因是 A,30% 是 B:

\[\Pr(Y=\mathrm A\mid h_{\rm login})=0.7,\qquad \Pr(Y=\mathrm B\mid h_{\rm login})=0.3.\]

沿用第一节的标签读出方式:把日志、问题和两个原因的说明放进提示词,要求只回答 A 或 B,并选用各自对应一个 token 的标签。这里的“一个 token”指最终答案的长度。在这一个输出位置上,模型会先为词表中的每个候选 token 计算一个分数,然后才选择输出哪一个。 本例的输出头根据固定表示 $h_{\rm login}=E(s)$ 产生整组 logits:

\[\ell_\theta(s)=\big(\ell_\theta(v_1\mid s),\ldots,\ell_\theta(v_{|\mathcal V|}\mid s)\big).\]

A 和 B 是两个不同的候选 token,各有自己的分数。取出它们对应的 $\ell_{\rm A}$ 和 $\ell_{\rm B}$,在这两个候选之间做 softmax:

\[p=\frac{e^{\ell_{\rm A}}}{e^{\ell_{\rm A}}+e^{\ell_{\rm B}}},\qquad 1-p=\frac{e^{\ell_{\rm B}}}{e^{\ell_{\rm A}}+e^{\ell_{\rm B}}}.\]

因此,第一节的候选分布在本例中可简写为:

\[\pi_\theta(\cdot\mid s)=\pi_\theta(\cdot\mid h_{\rm login})=(p,1-p).\]

例如,两个标签的 logits 为 $(2,1)$ 时,模型分布约为 $(0.731,0.269)$。$(0.7,0.3)$ 来自这类工单的标签统计,模型分布则来自当前决策头的参数。下面把 $p$ 当作待优化变量,分别看看不同训练目标希望它变成多少。

CE与SFT

交叉熵对每个样本取真实标签的负对数概率。标签为 A 时,损失是 $-\log p$;标签为 B 时,损失是 $-\log(1-p)$。对这类工单的标签分布取期望:

\[L_{\rm CE}(p)=-0.7\log p-0.3\log(1-p).\]

对 $p$ 求导:

\[\frac{\mathrm d L_{\rm CE}}{\mathrm d p} =-\frac{0.7}{p}+\frac{0.3}{1-p} =\frac{p-0.7}{p(1-p)}.\]

损失在 $p=0.7$ 时最小。每条工单只有一个正确标签,但模型能力不足无法做进一步的区分,决策头只能给这类工单统一分配概率。对这些样本优化交叉熵,最优结果就是 $(0.7,0.3)$。

LLM 的 SFT 使用同样的原理:在每个给定前缀上,提高参考 token 的概率。区别在于,SFT 拟合的是参考文本的分布;这个分布是否对应事实或任务结果,取决于参考数据。

OPD

监督也可以来自另一个模型。沿用这类工单,先假设教师对它们都给出分布 $q_T=(0.8,0.2)$,学生仍输出 $(p,1-p)$。使用教师到学生的 forward KL,目标为:

\[\begin{aligned} L_{\rm FKL}(p) &=D_{\rm KL}\big(q_T\|\pi_\theta\big)\\ &=\sum_{a\in\{\mathrm A,\mathrm B\}}q_T(a)\log\frac{q_T(a)}{\pi_\theta(a)}\\ &=0.8\log\frac{0.8}{p}+0.2\log\frac{0.2}{1-p}\\ &=-0.8\log p-0.2\log(1-p)+C. \end{aligned}\]

第二行展开离散分布的 KL 定义:对每个候选 $a$,用教师概率 $q_T(a)$ 加权两个概率之比的对数,再求和。代入 $q_T(\mathrm A)=0.8$、$q_T(\mathrm B)=0.2$ 和 $\pi_\theta(\mathrm A)=p$、$\pi_\theta(\mathrm B)=1-p$,就得到第三行。再用 $\log(x/y)=\log x-\log y$ 展开,便得到最后一行,其中 $C=0.8\log0.8+0.2\log0.2$ 与学生参数无关。

这仍然是交叉熵,只是目标由真实标签频率换成了教师分布,最优值也随之变成 $p=0.8$。蒸馏也可以使用 reverse KL:

\[L_{\rm RKL}(p) =D_{\rm KL}\big(\pi_\theta\|q_T\big) =p\log\frac{p}{0.8}+(1-p)\log\frac{1-p}{0.2}.\]

在本例中,两种 KL 都在 $p=0.8$ 时取得最小值,学生匹配的是教师分布;这类工单的实际标签比例仍是 $(0.7,0.3)$。

正确性奖励与强化学习

现在让模型先按 $(p,1-p)$ 采样一个答案 $a$,答对得 1 分,答错得 0 分。这类工单共用同一组采样概率,因此平均奖励为:

\[J_{\rm correct}(p) =\Pr(a=Y\mid h_{\rm login}) =0.7p+0.3(1-p) =0.3+0.4p.\]

这个目标随 $p$ 单调增加,最优策略是 $p=1$:始终选 A。

  • 按 $(0.7,0.3)$ 采样,正确率为 $0.7^2+0.3^2=0.58$;
  • 始终选 A,正确率为 $0.7$。

因此,只优化正确性奖励时,模型有理由把概率集中到最可能正确的选项上。GRPO 等策略优化方法可以用采样结果和优势估计来推动这种更新;若希望概率同时保持校准,还需要相应的目标或约束。

如果部署时使用 argmax,$(0.7,0.3)$ 和 $(0.99,0.01)$ 都会选择 A,分类准确率相同,但两者报告的确定程度不同。

Brier

令 $Z=\mathbf 1{Y=\mathrm A}$:标签为 A 时 $Z=1$,为 B 时 $Z=0$。模型报告 A 的概率为 $p$,单个样本的二元 Brier 损失为 $(p-Z)^2$。

先把给定表示下 A 类的实际概率记为 $q$,即 $\Pr(Z=1)=q$、$\Pr(Z=0)=1-q$。按这两种结果的概率加权,期望损失为:

\[\begin{aligned} L_{\rm Brier}(p) &=\mathbb E[(p-Z)^2]\\ &=q(p-1)^2+(1-q)(p-0)^2\\ &=p^2-2pq+q\\ &=(p-q)^2+q(1-q). \end{aligned}\]

本例中 $q=0.7$,代入同一个公式:

\[L_{\rm Brier}(p) =\mathbb E[(p-Z)^2] =0.7(p-1)^2+0.3p^2 =(p-0.7)^2+0.21.\]

它同样在 $p=0.7$ 时最小。模型若总报 $p=1$,就会在那 30% 的 B 标签上付出较大损失;报告 $p=0.7$ 则使平均损失最小。CE 和 Brier 都属于严格 proper 的评分目标:在期望上,报告真实分布能取得唯一最优值。

这些目标都在优化概率。CE 和 Brier 希望概率匹配标签频率,蒸馏希望学生匹配教师分布,正确性奖励希望采样出的答案尽量答对。在这个例子中,它们分别得到 $(0.7,0.3)$、$(0.8,0.2)$ 和 $(1,0)$。因此,看到模型输出了概率,还需要继续问:它是在拟合标签、匹配教师、选择动作,还是报告某个事件发生的可能性?

SFT 与 Brier 能否相互替代? 常规 LLM SFT 使用 token-level CE,因此本节的 CE 可以对应读者熟悉的“SFT 训练”。SFT 是监督微调的训练方式,CE 是它通常使用的损失;使用 Brier 做监督微调,同样属于监督学习。

在同一预测对象、同一标签监督下,CE 与 Brier 的理想目标一致。 沿用上文的 $q$(A 类的实际概率)和 $p$(模型预测),两种期望损失可写成:

\[L_{\rm CE}(p)=H(q)+D_{\rm KL}\big(\operatorname{Ber}(q)\,\|\,\operatorname{Ber}(p)\big),\] \[L_{\rm Brier}(p)=(p-q)^2+q(1-q).\]

这里 $\operatorname{Ber}(q)$ 表示 A 类概率为 $q$ 的伯努利分布,$H(q)=-q\log q-(1-q)\log(1-q)$。$H(q)$ 和 $q(1-q)$ 都与模型预测无关,因此两种损失都在 $p=q$ 时达到唯一最小值。本例中均为 $(0.7,0.3)$,这一性质也适用于其他真实标签概率。

两者的优化路径不同。令 $z=\ell_{\rm A}-\ell_{\rm B}$ 为两个候选的 logit 差,二分类 softmax 可以写成 sigmoid:

\[p=\frac{e^{\ell_{\rm A}}}{e^{\ell_{\rm A}}+e^{\ell_{\rm B}}} =\frac1{1+e^{-z}}=\sigma(z),\qquad \frac{\mathrm dp}{\mathrm dz} =\frac{e^{-z}}{(1+e^{-z})^2}=p(1-p).\]

损失通过 $p$ 依赖 $z$,因此用链式法则:$\frac{\mathrm dL}{\mathrm dz}=\frac{\mathrm dL}{\mathrm dp}\frac{\mathrm dp}{\mathrm dz}$。先对 CE 求导,再代入 sigmoid 的导数:

\[\begin{aligned} L_{\rm CE}(p)&=-q\log p-(1-q)\log(1-p),\\ \frac{\mathrm dL_{\rm CE}}{\mathrm dp} &=-\frac q p+\frac{1-q}{1-p} =\frac{p-q}{p(1-p)},\\ \frac{\mathrm dL_{\rm CE}}{\mathrm dz} &=\frac{p-q}{p(1-p)}\,p(1-p)=p-q. \end{aligned}\]

Brier 同样处理,其中 $q$ 是固定的标签概率:

\[\begin{aligned} L_{\rm Brier}(p)&=(p-q)^2+q(1-q),\\ \frac{\mathrm dL_{\rm Brier}}{\mathrm dp}&=2(p-q),\\ \frac{\mathrm dL_{\rm Brier}}{\mathrm dz} &=2(p-q)\,p(1-p). \end{aligned}\]

Brier 多了一个 $p(1-p)$ 因子,预测接近 0 或 1 时,梯度会变小,纠正高置信错误可能更慢。模型能够表达目标分布、且优化达到总体期望损失的全局最小值时,两者得到相同结果。

RLCD的两种实现方式

上一节中,CE 和 Brier 希望保留与实际表现相符的分布,而基于正确性的强化学习奖励会继续把概率推向 A。如果仍然使用强化学习,能否通过设计奖励,让模型学到相符的分布呢?

RLCD(Reinforcement Learning for Calibrated Decisions)关注的正是概率与实际表现的对应关系。TypeSafe 的公开介绍提出了这一目标;下面采用 NanoJev 公开的 RLCD 式概率学习实验,说明如何把 Brier 目标写成采样奖励,再用策略梯度训练直接决策模型。

从 Brier 损失到概率奖励

将完整候选分布记为 $\boldsymbol p_\theta=\pi_\theta(\cdot\mid s)$,真实标签的 one-hot 向量记为 $e_Y$。其中 $a$ 遍历所有候选类别,$p_{\theta,a}$ 是模型分配给类别 $a$ 的概率。把各类别的平方误差相加,再将损失改成越大越好的评分:

\[S(\boldsymbol p_\theta,Y) =1-\|\boldsymbol p_\theta-e_Y\|_2^2 =2p_{\theta,Y}-\sum_a p_{\theta,a}^2.\]

在第二节的二分类中,$\boldsymbol p_\theta=(p,1-p)$、$e_Y=(Z,1-Z)$,所以 $S=1-2(p-Z)^2$,取期望得到 $\mathbb E[S]=1-2L_{\rm Brier}(p)$。最大化评分的期望,就等价于最小化第二节的 Brier 损失。

推导:从标量 Brier 到向量评分

第二节对单个样本使用的损失是 $(p-Z)^2$,再对标签结果取期望,得到 $L_{\rm Brier}(p)$。这里先回到单个样本,把 A、B 两类的预测和标签一起写成向量:

\[\boldsymbol p_\theta=(p,1-p),\qquad e_Y=(Z,1-Z).\]

$e_Y$ 是真实标签的 one-hot 向量:$Y=\mathrm A$ 时为 $(1,0)$,$Y=\mathrm B$ 时为 $(0,1)$。将两类的平方误差相加,就得到向量形式的 Brier 损失;$|\cdot|_2^2$ 表示各分量的平方和:

\[\begin{aligned} \|\boldsymbol p_\theta-e_Y\|_2^2 &=(p-Z)^2+\big((1-p)-(1-Z)\big)^2\\ &=(p-Z)^2+(Z-p)^2\\ &=2(p-Z)^2. \end{aligned}\]

因此,二分类的向量 Brier 是第二节标量 Brier 的两倍,取期望后为 $2L_{\rm Brier}(p)$。这个写法也能直接用于更多类别:将完整候选分布记为 $\boldsymbol p_\theta=\pi_\theta(\cdot\mid s)$,其中 $a$ 遍历所有候选类别,$p_{\theta,a}$ 是模型分配给类别 $a$ 的概率,则

\[\|\boldsymbol p_\theta-e_Y\|_2^2 =\sum_a\big(p_{\theta,a}-\mathbf1\{a=Y\}\big)^2.\]

损失越小越好;若希望改成越大越好的评分,可以取 $S=1-|\boldsymbol p_\theta-e_Y|_2^2$。其中减号反转优化方向,加 1 只改变评分的起点。展开平方项:

\[\begin{aligned} S(\boldsymbol p_\theta,Y) &=1-\sum_a\big(p_{\theta,a}-\mathbf1\{a=Y\}\big)^2\\ &=1-\sum_a p_{\theta,a}^2 +2\sum_a p_{\theta,a}\mathbf1\{a=Y\} -\sum_a\mathbf1\{a=Y\}\\ &=2p_{\theta,Y}-\sum_a p_{\theta,a}^2. \end{aligned}\]

最后一步利用了:只有真实类别 $Y$ 的指示函数为 1,所以两个求和分别为 $p_{\theta,Y}$ 和 1。接下来沿着刚得到的 $S=2p_{\theta,Y}-\sum_a p_{\theta,a}^2$,代入二分类的具体分量。A、B 的预测概率分别为 $p$ 和 $1-p$,所以平方和为 $p^2+(1-p)^2$。真实类别获得的概率 $p_{\theta,Y}$ 则可以用 $Z$ 统一表示:

\[p_{\theta,Y}=Zp+(1-Z)(1-p).\]

因为 $Y=\mathrm A$ 时 $Z=1$,上式取 $p$;$Y=\mathrm B$ 时 $Z=0$,上式取 $1-p$。将这两项代入,继续展开:

\[\begin{aligned} S &=2p_{\theta,Y}-\sum_a p_{\theta,a}^2\\ &=2\left[Zp+(1-Z)(1-p)\right]-\left[p^2+(1-p)^2\right]\\ &=1-2p^2+4pZ-2Z\\ &=1-2\left(p^2-2pZ+Z^2\right)\\ &=1-2(p-Z)^2. \end{aligned}\]

倒数第二行用了 $Z\in{0,1}$,因此 $Z^2=Z$。这样就从多分类的评分表达式,接回了第二节的二分类平方误差。

固定模型报告的 $p$,对真实标签 $Z$ 取期望。利用期望的线性性质,以及第二节的定义 $L_{\rm Brier}(p)=\mathbb E[(p-Z)^2]$:

\[\begin{aligned} \mathbb E[S] &=\mathbb E\left[1-2(p-Z)^2\right]\\ &=\mathbb E[1]-2\mathbb E[(p-Z)^2]\\ &=1-2L_{\rm Brier}(p)\\ &=1-2\left[q(p-1)^2+(1-q)p^2\right]. \end{aligned}\]

本例代入 $q=0.7$,也可以写成 $\mathbb E[S]=1-2[(p-0.7)^2+0.21]=0.58-2(p-0.7)^2$。损失每减少一点,期望评分就相应增加,因此最大化这个评分的期望,就等价于最小化第二节的 Brier 损失。

正确性奖励只评价采样答案是否答对,概率评分还要评价报告的整个分布。 上式的第一项鼓励给真实标签更多概率,第二项扣除分布的平方和;两者共同决定最优分布。

NanoJev:采样标签,估计概率评分的梯度

NanoJev 从一次前向得到的分布中,独立、有放回地采样多个候选标签。取最简单的两个样本:

\[a_1,a_2\overset{\mathrm{iid}}{\sim}\boldsymbol p_\theta.\]

这里抽取的是同一条工单的两个预测答案,例如 A、A 或 A、B。它们共用同一次前向的 logits,不会被接回上下文,也不需要生成推理文本。工单的真实标签 $Y$ 已经确定,不随这两次预测改变。

定义成对奖励:

\[R(a_1,a_2,Y) =\mathbf1\{a_1=Y\}+\mathbf1\{a_2=Y\} -\mathbf1\{a_1=a_2\}.\]

前两项奖励预测正确;最后一项扣除两个预测相同的得分。如果只保留正确性项,模型仍会把概率集中到 A。设给定表示下的真实标签分布为 $\boldsymbol q$,其中 $q_a=\Pr(Y=a)$,加入重复项后的期望奖励为:

\[\begin{aligned} J(\theta) &=\mathbb E[R] =2\boldsymbol p_\theta^\top\boldsymbol q-\|\boldsymbol p_\theta\|_2^2\\ &=\|\boldsymbol q\|_2^2-\|\boldsymbol p_\theta-\boldsymbol q\|_2^2. \end{aligned}\]

推导:成对奖励的期望与向量配方

指示函数的期望等于对应事件发生的概率。对任一次预测 $a_i$,它与真实标签在给定表示下独立,因此:

\[\begin{aligned} \mathbb E[\mathbf1\{a_i=Y\}] &=\Pr(a_i=Y)\\ &=\sum_a\Pr(a_i=a,Y=a)\\ &=\sum_a p_{\theta,a}q_a =\boldsymbol p_\theta^\top\boldsymbol q. \end{aligned}\]

这里 $\boldsymbol p_\theta^\top\boldsymbol q$ 是两个向量的点积,即对应分量相乘后求和。两次预测正确的期望相同,因此前两项之和为 $2\boldsymbol p_\theta^\top\boldsymbol q$。再看重复项,由于 $a_1$ 和 $a_2$ 独立采样:

\[\begin{aligned} \mathbb E[\mathbf1\{a_1=a_2\}] &=\Pr(a_1=a_2)\\ &=\sum_a\Pr(a_1=a,a_2=a)\\ &=\sum_a p_{\theta,a}p_{\theta,a} =\|\boldsymbol p_\theta\|_2^2. \end{aligned}\]

将三项的期望相加减,就得到:

\[\begin{aligned} J(\theta) &=\mathbb E[R]\\ &=2\boldsymbol p_\theta^\top\boldsymbol q-\|\boldsymbol p_\theta\|_2^2. \end{aligned}\]

接下来像标量的配方一样,展开向量差的平方:

\[\begin{aligned} \|\boldsymbol p_\theta-\boldsymbol q\|_2^2 &=\sum_a(p_{\theta,a}-q_a)^2\\ &=\sum_a p_{\theta,a}^2-2\sum_a p_{\theta,a}q_a+\sum_a q_a^2\\ &=\|\boldsymbol p_\theta\|_2^2 -2\boldsymbol p_\theta^\top\boldsymbol q+\|\boldsymbol q\|_2^2. \end{aligned}\]

移项后便得到第二个等号:

\[J(\theta) =2\boldsymbol p_\theta^\top\boldsymbol q-\|\boldsymbol p_\theta\|_2^2 =\|\boldsymbol q\|_2^2-\|\boldsymbol p_\theta-\boldsymbol q\|_2^2.\]

\(\|\boldsymbol q\|_2^2\) 不随模型改变,后面的平方项则在 \(\boldsymbol p_\theta=\boldsymbol q\) 时为零。因此,这个奖励在 \(\boldsymbol p_\theta=\boldsymbol q\) 时最大。在工单例子中:

\[J(p)=0.58-2(p-0.7)^2,\]

最优值回到 $p=0.7$;若一味集中到 A,$p=1$ 时的期望奖励反而从 0.58 降到 0.4。

有了采样奖励,就可以用 REINFORCE 更新输出分布。用奖励相对基线 $b$ 的差值,加权两个采样标签的 log probability 梯度:

\[\nabla_\theta J =\mathbb E\left[ (R-b)\nabla_\theta \big(\log p_{\theta,a_1}+\log p_{\theta,a_2}\big) \right],\]

推导:从奖励期望到 REINFORCE 梯度

接下来要求奖励期望对模型参数 $\theta$ 的梯度。刚才将期望化简成了概率向量的表达式;为了得到能用采样实现的更新,再把同一个期望写回求和形式。固定输入,记两次预测的联合概率为:

\[P_\theta(a_1,a_2)=p_{\theta,a_1}p_{\theta,a_2}.\]

真实标签 $Y$ 按 $\boldsymbol q$ 分布,两次预测按 $P_\theta$ 分布,因此对所有可能的标签和预测组合加权求和:

\[J(\theta) =\sum_Y q_Y\sum_{a_1,a_2} P_\theta(a_1,a_2)R(a_1,a_2,Y).\]

对于固定的 $(a_1,a_2,Y)$,奖励 $R$ 只是由三个指示函数计算出的数值,不直接依赖 $\theta$;$\boldsymbol q$ 也固定。求导时变化的是采样概率:

\[\nabla_\theta J =\sum_Y q_Y\sum_{a_1,a_2} R(a_1,a_2,Y)\nabla_\theta P_\theta(a_1,a_2).\]

利用对数求导公式 $\nabla_\theta\log P_\theta=(\nabla_\theta P_\theta)/P_\theta$,可以把概率的导数改写为:

\[\nabla_\theta P_\theta =P_\theta\nabla_\theta\log P_\theta.\]

代回求和式,前面的 $q_YP_\theta(a_1,a_2)$ 又正好是采样这些结果的概率,所以能重新写成期望:

\[\begin{aligned} \nabla_\theta J &=\sum_Y q_Y\sum_{a_1,a_2} P_\theta(a_1,a_2)R(a_1,a_2,Y) \nabla_\theta\log P_\theta(a_1,a_2)\\ &=\mathbb E\left[R\nabla_\theta\log P_\theta(a_1,a_2)\right]\\ &=\mathbb E\left[ R\nabla_\theta\big(\log p_{\theta,a_1}+\log p_{\theta,a_2}\big) \right]. \end{aligned}\]

最后一步用了 $\log(xy)=\log x+\log y$。这就是 REINFORCE 的基本形式:按当前分布采样,用得到的奖励加权采样结果的 log probability 梯度。

还可以减去一个只依赖输入、不依赖本次采样结果的基线 $b$。因为 $\mathbb E[\nabla_\theta\log P_\theta]=\sum_{a_1,a_2}\nabla_\theta P_\theta(a_1,a_2)=\nabla_\theta1=0$,减去基线不改变期望梯度;选择合适的基线则能降低采样估计的方差。

实现时使用代理损失:

\[L_{\rm PG} =-\operatorname{sg}(R-b) \big(\log p_{\theta,a_1}+\log p_{\theta,a_2}\big),\]

什么是代理损失? 训练通常通过最小化一个标量损失来更新参数。有时我们已经推导出想要的梯度估计,却不方便让自动求导直接穿过离散采样。这时可以构造一个标量,使它在当前样本上的导数恰好给出所需的更新方向,这个标量就称为代理损失(surrogate loss)。它的作用在于提供梯度,数值本身不必等于原来的目标。

先看一个简单例子:模型以概率 $p$ 选择 A、以概率 $1-p$ 选择 B;选 A 得 1 分,选 B 得 0 分。希望提高的是反复采样时的平均奖励:

\[J(\theta)=\mathbb E_{x\sim P_\theta}[R(x)] =p\cdot1+(1-p)\cdot0=p.\]

将期望写成求和,再求导:

\[\begin{aligned} \nabla_\theta J &=\nabla_\theta\sum_xP_\theta(x)R(x)\\ &=\sum_xR(x)\nabla_\theta P_\theta(x)\\ &=\sum_xP_\theta(x)R(x)\nabla_\theta\log P_\theta(x)\\ &=\mathbb E_{x\sim P_\theta} \left[R(x)\nabla_\theta\log P_\theta(x)\right]. \end{aligned}\]

如果每次采样后计算

\[\hat g=R(x)\nabla_\theta\log P_\theta(x),\]

那么 $\mathbb E[\hat g]=\nabla_\theta J$,多次采样的平均值就能估计目标梯度。单次估计可以偏离真实梯度,但期望恰好正确。这就是“用采样估计梯度”的含义。

在这个例子里,权重 $w=R$;加上基线之后,取 $w=R-b$。它表示这次结果比基准好多少。在 log probability 梯度的方向上:

  • $w>0$:提高这次采样结果的概率;
  • $w<0$:降低这次采样结果的概率;
  • $w=0$:这次结果不产生更新。

此时梯度估计为 $\hat g=w\nabla_\theta\log P_\theta(x)$。代理损失只是把上述更新交给自动求导:

\[L=-\operatorname{sg}(w)\log P_\theta(x) \quad\Longrightarrow\quad \nabla_\theta L=-w\nabla_\theta\log P_\theta(x)=-\hat g.\]

求导时固定已采样的 $x$。$\operatorname{sg}$(stop gradient)在前向计算时保留 $w$ 的数值,反向求导时将其视为常数。因此,对代理损失做梯度下降,恰好等于沿 $\hat g$ 做梯度上升。

回到本文,只需对应替换:

\[x=(a_1,a_2),\qquad w=R(a_1,a_2,Y)-b,\qquad J=\mathbb E[R(a_1,a_2,Y)].\]

两次预测的联合概率为 $P_\theta(x)=p_{\theta,a_1}p_{\theta,a_2}$,于是:

\[\begin{aligned} L_{\rm PG} &=-\operatorname{sg}(R-b)\log\big(p_{\theta,a_1}p_{\theta,a_2}\big)\\ &=-\operatorname{sg}(R-b) \big(\log p_{\theta,a_1}+\log p_{\theta,a_2}\big). \end{aligned}\]

NanoJev 的实际代码将它推广到 $M\ge2$ 个样本,并用局部奖励和条件基线降低梯度估计的方差。

前面的采样奖励优化的仍是同一个 Brier 目标。 将向量 Brier 的期望损失记为 $L_{\rm Brier}^{\rm vec}(\theta)=\mathbb E_Y[|\boldsymbol p_\theta-e_Y|_2^2]$,则:

\[J(\theta)=1-L_{\rm Brier}^{\rm vec}(\theta),\qquad \nabla_\theta J=-\nabla_\theta L_{\rm Brier}^{\rm vec}.\]

因此,最大化成对奖励与最小化 Brier 具有相同的期望更新方向。实现上的区别是:直接 Brier 通过完整概率向量求导,NanoJev 则用标签采样构造梯度估计。 在这里,真实标签和完整分布都可用,直接求导省去了采样方差;NanoJev 也将 CE、直接 Brier 与成对奖励作为并列对照。

直觉与推导:成对奖励为何仍在优化 Brier? 从直觉上,可以从想要的 Brier 评分出发,逐项寻找对应的采样事件,由此构造成对奖励。关键是:一次采样给出概率的线性项,两次独立采样的重复事件给出平方项。

固定真实标签 $Y$,一次预测命中它的概率为 $\Pr(a_1=Y)=p_{\theta,Y}$。而 Brier 评分需要的是:

\[S=2p_{\theta,Y}-\sum_a p_{\theta,a}^2.\]

两次预测各自命中的次数,其期望正好为 $2p_{\theta,Y}$。剩下的平方项则可以通过“两次预测是否相同”得到:

\[\Pr(a_1=a_2) =\sum_a\Pr(a_1=a)\Pr(a_2=a) =\sum_a p_{\theta,a}^2.\]

每一项都有一个直接的采样对应:

想得到的数学项期望等于该项的采样得分
$p_{\theta,Y}$一次预测是否命中真实标签
$2p_{\theta,Y}$两次预测各自命中的次数
$\sum_a p_{\theta,a}^2$两次预测是否相同

按评分中的系数将这些得分相加减,就得到:

\[R=\mathbf1\{a_1=Y\}+\mathbf1\{a_2=Y\}-\mathbf1\{a_1=a_2\}.\]

成对奖励的每一项都对应了 Brier 评分里的一个数学项。 这提供了一条直观的算法构造路径:先展开评分,再用采样事件估计其中的概率项。下面将这个对应关系写成期望等式。

从推导上,Brier 衡量模型报告的分布与真实标签之间的平方误差。向量形式的期望损失为:

\[L_{\rm Brier}^{\rm vec}(\theta) =\mathbb E_Y\left[\|\boldsymbol p_\theta-e_Y\|_2^2\right].\]

固定真实标签 $Y$,根据上面的逐项对应,对两个预测标签 $a_1,a_2$ 的采样取期望:

\[\begin{aligned} \mathbb E_{a_1,a_2}[R\mid Y] &=2p_{\theta,Y}-\sum_a p_{\theta,a}^2\\ &=S(\boldsymbol p_\theta,Y)\\ &=1-\|\boldsymbol p_\theta-e_Y\|_2^2. \end{aligned}\]

这里的 $S$ 正是前文由 Brier 改写出的评分。再对真实标签 $Y$ 取期望:

\[\begin{aligned} J(\theta) &=\mathbb E_Y\left[\mathbb E_{a_1,a_2}[R\mid Y]\right]\\ &=\mathbb E_Y\left[1-\|\boldsymbol p_\theta-e_Y\|_2^2\right]\\ &=1-\mathbb E_Y\left[\|\boldsymbol p_\theta-e_Y\|_2^2\right]\\ &=1-L_{\rm Brier}^{\rm vec}(\theta). \end{aligned}\]

两边对 $\theta$ 求导,常数 1 的导数为零,便得到 $\nabla_\theta J=-\nabla_\theta L_{\rm Brier}^{\rm vec}$。因此,这里没有引入新的概率学习目标,而是用采样奖励实现了同一个 Brier 目标的梯度估计。

Laya:采样 logits 扰动,评价得到的分布

Laya采用另一种采样对象:一次前向得到 logits $\ell_\theta$ 后,加入高斯扰动,形成 $G$ 份候选分布。噪声负责在当前 logits 附近产生候选方向,概率评分再判断哪些方向值得学习。 得分高的方向如何推动模型更新,见下文损失公式后的推导。对 $K$ 个选项,令 $P=I-\frac1K\boldsymbol1\boldsymbol1^\top$,将噪声在选项间中心化:

\[\epsilon_g\sim\mathcal N(0,\sigma^2I),\qquad z_g=\operatorname{sg}(\ell_\theta)+P\epsilon_g,\qquad u_g=\operatorname{softmax}(z_g).\]

直观上,$\frac1K\boldsymbol1\boldsymbol1^\top$ 的作用是“求均值并复制到每个位置”:乘上 $\epsilon_g$ 后,所得向量的每一项都是这组噪声的均值 $\bar\epsilon_g=\frac1K\sum_a\epsilon_{g,a}$。因此 $P\epsilon_g=\epsilon_g-\bar\epsilon_g\boldsymbol1$,就是每项减去均值,使这一组噪声在选项之间的平均值为零。这里 $I$ 是单位矩阵,$\boldsymbol1$ 是全 1 列向量。

这里采样的是 logits,得到的是不同的概率分配。对于无序选项,设监督目标分布为 $t$(one-hot 标签或软标签)。Laya 的评分由两部分组成:一部分用负信息量评价模型对真实结果的预期程度,另一部分评价概率向量与真实标签方向的余弦相似度。分别按 $t$ 取平均,再以 $\alpha\ge0$ 加权:

\[r_g=\sum_a t_a\log u_{g,a} +\alpha\frac{t^\top u_g}{\|u_g\|_2}.\]

两项评分如何理解? 下面省略扰动下标 $g$,将预测分布写作 $u$,结果 $Y$ 按目标分布 $t$ 取值。先回顾几个相关概念:

概念公式含义
单次信息量$-\log u_Y$模型对这次结果有多意外
熵$\mathbb E_{Y\sim t}[-\log t_Y]$用目标分布自身的概率计算的平均信息量
交叉熵$\mathbb E_{Y\sim t}[-\log u_Y]$用模型概率计算的平均信息量
Log score$\log u_Y$单次信息量取负,作为奖励

第一项从“惊讶程度”理解即可:模型给实际结果的概率越低,信息量越大,取负后的奖励就越低。按 $t$ 取平均,得到 $\mathbb E_{Y\sim t}[\log u_Y]=\sum_a t_a\log u_a$,也就是负交叉熵。

第二项先看单个真实标签。one-hot 向量 $e_Y$ 只有一项为 1,其余为 0,所以 $|e_Y|_2=1$,因此:

\[\cos\angle(e_Y,u) =\frac{e_Y^\top u}{\|e_Y\|_2\|u\|_2} =\frac{u_Y}{\|u\|_2},\qquad \mathbb E_{Y\sim t}\left[\frac{u_Y}{\|u\|_2}\right] =\frac{t^\top u}{\|u\|_2}.\]

所以公式中的第二项是按 $t$ 平均的标签方向余弦相似度。它也可写成 $|t|_2\cos\angle(t,u)$:$t$ 固定时,两者方向一致得分最高;又因为都是总和为 1 的概率分布,此时 $u=t$。

两项都希望模型分布匹配 $t$,只是评价偏离的方式不同。 第一项等价于负交叉熵,最优值在 $u=t$,真实类别概率趋近零时得分趋向负无穷;第二项有界,并通过归一化考虑整个概率向量。加权组合沿用了相同的理想目标,改变了评分形状和训练信号。

随后将奖励在组内中心化并缩放,得到优势:

\[\bar r=\frac1G\sum_g r_g,\qquad \hat A_g=\frac{r_g-\bar r}{s_r+\varepsilon},\]

其中 $s_r$ 是中心化奖励的标准差,$\varepsilon$ 防止分母为零。接下来需要将优势变成模型的更新:先用高斯密度 $\rho_\theta$ 计算扰动样本 $z_g$ 的 log density,再用优势对它加权,构造策略梯度代理损失。同时,对未加扰动的原始分布 $p_\theta=\operatorname{softmax}(\ell_\theta)$ 计算 CE,直接监督它匹配同一个目标 $t$:

\[\begin{aligned} \log\rho_\theta(z_g) &=-\frac{\|z_g-\ell_\theta\|_2^2}{2\sigma^2}+C,\\ L_{\rm Laya} &=\underbrace{-\frac1G\sum_g\operatorname{sg}(\hat A_g) \log\rho_\theta\big(\operatorname{sg}(z_g)\big)}_{\text{扰动分支的策略梯度代理损失}} +\underbrace{\left(-\sum_a t_a\log p_{\theta,a}\right)}_{\text{原始分布的 CE}}. \end{aligned}\]

从高斯采样到联合损失。 前面 NanoJev 的策略梯度代理损失是“$-\text{优势}\times\log(\text{采样结果的概率})$”。Laya 沿用同一个思路,只是采样结果从离散标签变成了一组连续的 logits $z_g$,所以这里使用连续分布的密度。$\rho_\theta(z_g)$ 描述扰动样本在当前高斯分布下的密度,$p_{\theta,a}$ 则是原始模型选择类别 $a$ 的概率。

第一步:给扰动样本计算 log density。 先看一维高斯,中心为 $\ell_\theta$、标准差为 $\sigma$:

\[\rho_\theta(z) =\frac1{\sqrt{2\pi}\sigma} \exp\left(-\frac{(z-\ell_\theta)^2}{2\sigma^2}\right).\]

取对数后,指数中的平方项被直接取出,前面的系数变成加法常数:

\[\log\rho_\theta(z) =-\frac{(z-\ell_\theta)^2}{2\sigma^2} -\log(\sqrt{2\pi}\sigma).\]

多维高斯将各方向的平方偏差相加。前文又将噪声中心化,因此在去掉整体平移方向的扰动子空间中,保留相同的平方距离形式。固定 $\sigma$,将与 $\theta$ 无关的归一化项记为 $C$,就得到正文的第一条公式:

\[\log\rho_\theta(z_g) =-\frac{\|z_g-\ell_\theta\|_2^2}{2\sigma^2}+C.\]

第二步:用优势加权,构造代理损失。 在前面的通用形式 $L=-\operatorname{sg}(w)\log P_\theta(x)$ 中,代入采样结果 $x=z_g$、权重 $w=\hat A_g$,再对 $G$ 个样本取平均:

\[L_{\rm PG} =-\frac1G\sum_g\operatorname{sg}(\hat A_g) \log\rho_\theta\big(\operatorname{sg}(z_g)\big).\]

这里固定已采样的 $z_g$ 和已算出的优势,只更新高斯中心 $\ell_\theta$。直接对平方距离求导:

\[\begin{aligned} \nabla_{\ell_\theta}\log\rho_\theta(z_g) &=-\frac1{2\sigma^2}\nabla_{\ell_\theta} \sum_a(z_{g,a}-\ell_{\theta,a})^2\\ &=\frac{z_g-\ell_\theta}{\sigma^2},\\ -\nabla_{\ell_\theta}L_{\rm PG} &=\frac1{G\sigma^2}\sum_g\hat A_g(z_g-\ell_\theta). \end{aligned}\]

这就接回了引入噪声时的直觉:$z_g-\ell_\theta=P\epsilon_g$ 是尝试的方向,$\hat A_g$ 表示这个方向的评分比组内平均值好多少。

  • 优势为正:将原 logits 拉向这个扰动样本;
  • 优势为负:朝相反方向更新。

多个扰动的贡献先相加,再通过 $\ell_\theta$ 反向传播到模型参数。第一条公式给扰动样本计算 log density,第二条公式用优势对其加权,构造代理损失。 扰动分支探索的是当前 logits 附近哪些概率分配评分更高。

第三步:同时监督未加扰动的原始分布。 同一次前向产生的 $\ell_\theta$ 还给出原始分布 $p_\theta=\operatorname{softmax}(\ell_\theta)$,直接与目标 $t$ 计算:

\[L_{\rm CE}=-\sum_a t_a\log p_{\theta,a},\qquad L_{\rm Laya}=L_{\rm PG}+L_{\rm CE}.\]

这里的 $t$ 与前面计算扰动奖励使用的是同一份标签。单独使用 CE 就能以匹配 $t$ 为目标,扰动分支是额外的优化设计,并非学习目标分布的必要条件。 它增加了按邻域评分探索方向的更新,是否改善训练效果,需要与仅使用 CE 的方案比较;Laya 代码也提供了独立的 soft-ce 训练选项。

“Soft”表示 CE 可以接受概率形式的目标,例如 $t=(0.8,0.2)$;若标签只有 A,则取 $t=(1,0)$,公式就变成普通 CE。Laya 的 typed-decisions 示例数据由教师对同一案例三次给出分布后取平均,这些软标签表达教师判断。

NanoJev 从分布中抽取标签,Laya 对产生分布的 logits 加噪声;两者都可以训练直接决策器,其强化学习采样都发生在一次前向得到分数之后。

RLCD 强调训练什么;NanoJev、Laya 展示怎样训练。 在本文讨论的公开实现中,CE、Brier 已能表达概率学习目标,RL 式实现是否值得采用,则取决于反馈形式与实际训练收益。理解这些方法,需要区分目标上的变化与实现同一目标的不同优化路径。

模型架构

前面讨论了如何训练决策分布,现在看模型如何计算这些概率。关键是将问题和候选项组织成输入,再从隐藏表示中直接读出选项分数,省去生成答案文本的循环。

Jev 式决策器

下图是一种实现 Jev 式接口的架构猜想。 它将状态、问题与候选项送入 Transformer,再按各问题的选项集合读出 logits,并分别归一化。图中的三条分支表示 Choice、Score、Noul 三种读出功能。

Jev 式决策器的概念架构

将第 $j$ 个问题记为 $q_j$,它的候选集合为 $A_j$,共享隐藏表示记为 $H$,一种可能的计算形式是:

\[H=\operatorname{Transformer}(s,\{q_j,A_j\}_j),\qquad \ell_j=\operatorname{Readout}(H,q_j,A_j),\qquad p_j=\operatorname{softmax}(\ell_j).\]

程序从各自的分布中得到 Choice 的选中项、Score 的期望分数,以及 Noul 的为真概率。所有选项和问题在计算前已经给定,因此可以一起评分,输出不必经过逐 token 的文本生成。图中 Score 的等级概率为 $(0.2,0.5,0.3)$,对应期望值为 $1\times0.2+2\times0.5+3\times0.3=2.1$。

Laya

前一节将 Laya 的输出记为 $\ell_\theta$,讨论如何训练它。这里看这些分数如何产生。下图展示单个问题、两个候选项的主评分路径。

Laya 的选项标记读出与共享评分架构

先把候选项写进输入。 当前默认布局先放问题及类型,再依次放置带 [MASK] 标记的候选项,最后接状态文本;代码还加入 [CLS]、[SEP] 等特殊 token。每个 [MASK] 都是对应选项的读出位置。双向编码器让这些位置结合问题、选项说明和状态,形成上下文表示。

决策头输出每个 token 的表示。 编码器输出加入问题类型嵌入,再经过额外的 Transformer 决策头。设输入有 $L$ 个 token,每个位置的隐藏向量为 $d$ 维,决策头输出的就是 $L\times d$ 的矩阵 $H$:第 $j$ 行对应输入位置 $j$ 的向量。图中 $N$、$M$ 分别表示编码器与决策头的 Transformer 层数。

按标记位置取出对应的行。 构造输入时,程序已经记录每个 [MASK] 的位置。若两个选项的标记位于 $m_1,m_2$,就从 $H$ 中取出这两行,这里的冒号表示取该行的全部 $d$ 个分量:

\[h_{m_1}=H[m_1,:],\qquad h_{m_2}=H[m_2,:],\qquad H\in\mathbb R^{L\times d}.\]

用共享评分器将向量压成分数。 两个选项的向量分别通过 LayerNorm → Linear(d→d) → GELU → Linear(d→1)。LayerNorm、第一层 Linear 和 GELU 保持 $d$ 维,最后一层 Linear 将向量映射为一个标量 logit。图中两条通路穿过同一套评分层,随后将所有选项的 logits 一起归一化:

\[\ell_{\theta,i}=f_\phi(h_{m_i}),\qquad p_{\theta,i}=\frac{\exp\ell_{\theta,i}}{\sum_{k=1}^{K}\exp\ell_{\theta,k}}.\]

其中 $m_i$ 是第 $i$ 个选项标记的位置,$f_\phi$ 表示这组共享评分层,$\theta$ 包含编码器、决策头和评分器的参数。候选项由输入描述,共享评分器逐项打分,因此输出可以对应请求中的不同选项集合。

这里一次前向便得到同一问题的全部选项分数;多个问题则分别构造输入序列,放入 batch 计算。它们共享模型权重,每个输入行都包含该问题与状态。

这组 $\ell_\theta$ 就是前文训练方案的连接点。 训练时,对它添加扰动得到 $z_g$、计算概率评分,同时用原始分布计算 CE;推理时,沿图中的评分路径归一化即可。架构决定 logits 如何产生,损失决定它们如何更新;同一架构可以使用 CE、Brier 或前文的扰动训练方案。

Simple Jev

Simple Jev 的标准 Hugging Face 路径保留了语言模型原有的词表输出头。它将选项映射到 A、B 等单 token 标签,在模型准备输出答案的位置,直接读取这些标签的 logits。相比 Laya,这条路径主要改变输入与推理组织,使用的是现成的语言模型评分能力。

Simple Jev 的公共前缀缓存、后缀计算和原生词表读出

同一套模型,分两个阶段使用。 每个问题的完整提示词都有一段相同的开头,通常包括公共说明和状态。图中①先计算这个公共前缀,在每层注意力的 K/V 投影处保存该层的前缀 key、value,即 KV cache;②再将多个问题后缀放入 batch,使用同一套模型权重。每层读取自己的前缀缓存,与当前后缀新算出的 K/V 按 token 位置拼接,供后缀的 Q 查询。程序将缓存复制给各问题行,使它们独立续算。

图中左侧虚线表示①完成、各层缓存就绪后,才启动②。金色格子是前缀 K/V,紫色格子是后缀 K/V,两种颜色接在一起表示沿 token 位置拼接。注意力公式中的 $d_k$ 是每个注意力头的键向量维度,mask 限制 token 只能关注因果上可见的位置。

这里复用的是前缀 token 的计算结果。整个请求先算前缀,再执行一次或多次后缀 batch;问题后缀仍然需要计算。

一次后缀 batch 输出一个隐藏张量。 设 batch 中有 $B$ 个问题,后缀补齐到最长长度 $L_{\max}$,每个 token 的隐藏向量为 $d$ 维,则输出为 $\mathcal H\in\mathbb R^{B\times L_{\max}\times d}$。图中 $B=2$,框内的 $H_1,H_2$ 是同一张量的两个切片,而非两次串行调用的结果:

\[H_1=\mathcal H[0,:,:],\qquad H_2=\mathcal H[1,:,:],\qquad H_j\in\mathbb R^{L_{\max}\times d}.\]

直观理解:在答案即将生成的位置“截住”。 最后一个输入 token 的隐藏向量,用来预测紧接着的第一个输出 token。例如,把输入组织成:

1
2
3
4
5
6
7
材料:……
问题:……
选项:
A. ……
B. ……
请直接输出 A 或 B。
答案:

模型读完输入,得到隐藏矩阵 $H$。若输入共有 $L$ 个 token,那么:

\[\underbrace{H[L-1,:]}_{\text{最后一个输入 token 的隐藏向量}} \xrightarrow{\text{LM head}} \underbrace{\ell}_{\text{下一个 token 的词表 logits}}.\]

正常生成会根据这组 logits 选择一个 token,把它接回上下文。Simple Jev 则在这里“截住”:直接取出 A、B 对应的 logits,在候选集合内做 softmax,得到决策概率。

  • Prompt 的作用:让下一个输出位置承担“回答 A 或 B”的任务。
  • 取最后一行的原因:这一行对应的预测,恰好就是那个待输出的答案位置。
  • “真实位置”的意思:输入实际结束的位置,用来排除 batch 补齐位置。

在每个后缀的最后真实位置取行。 第 $j$ 个后缀的有效长度为 $L_j$,取 $h_j=H_j[L_j-1,:]\in\mathbb R^d$,图中以两个等长后缀为例,直接在各自的最后一行标出这个向量。将这些向量作为 batch 的各行,得到 $h_{\rm batch}\in\mathbb R^{B\times d}$。图中的 Transformer 骨干、embedding 和 LM head 都来自所加载的现成 LLM,使用同一套原有参数。原生词表头按行将向量映射到词表分数:

\[Z=\operatorname{LMHead}(h_{\rm batch})\in\mathbb R^{B\times|\mathcal V|}.\]

$Z$ 的每一行对应一个问题,每一列对应一个词表 token,每个元素都是标量 logit。图中列标题的省略号表示其他词表 token 的列。用 $\ell_j^{\rm vocab}$ 表示 $Z$ 的第 $j$ 行,再按允许标签的 token ID 取列并归一化:

\[\ell_j^{\rm vocab}=\operatorname{LMHead}(h_j),\qquad \ell_{j,i}=\ell_j^{\rm vocab}[v_i],\qquad p_{j,i}=\frac{\exp\ell_{j,i}}{\sum_{k=1}^{K_j}\exp\ell_{j,k}}.\]

其中 $K_j$ 是该问题的选项数,$v_i$ 是第 $i$ 个选项对应的标签 token ID,用来索引词表分数。图中先取 A、B 的两个 logits,再在这两个值之间做 softmax。程序由此拿到概率和选项,无须继续生成答案 token 或 JSON。候选标签的单 token 编码及其提示词边界会在编译请求时校验。

SemIf 的 direct 模式采用相同的原生词表读出;它的 shared 模式也先缓存公共状态,再批量计算问题后缀。因此,这两者可以放在同一类架构中理解,区别更多体现在缓存、批处理和服务实现。

Kev

Kev保留预训练骨干,接上可训练的指针评分头。它直接为输入中的选项位置打分:一端是当前问题的决策向量,另一端是各个选项的向量。

Kev 的标记位置读出、Q/K 投影和指针评分头

先从骨干输出中取出标记位置。 每个候选项末尾放一个 </opt> 标记,问题末尾放一个 <decide> 标记。这些是代码中的语义名称,实现复用了已有特殊 token。骨干输出隐藏矩阵 $H\in\mathbb R^{L\times d}$,其中 $L$ 是输入 token 数、$d$ 是隐藏维度。程序按记录的索引,取出两个选项结束位置 $m_1,m_2$ 和决策位置 $m_d$:

\[h_{\mathrm{opt},i}=H[m_i,:],\qquad h_{\rm decide}=H[m_d,:].\]

</opt> 位置的向量表示该候选项及其可见上下文;<decide> 位于问题和候选项之后,可以综合前面的信息,形成当前决策的表示。图中只画一个问题的评分路径。

指针头将“问题”和“选项”投影到同一个匹配空间。 决策向量通过 Q 投影,所有选项向量通过共享的 K 投影,再做缩放点积:

\[\begin{aligned} q&=W_qh_{\rm decide}+b_q,\qquad k_i=W_kh_{\mathrm{opt},i}+b_k,\\ \ell_i&=\frac{q^\top k_i}{\sqrt{d_p}},\qquad p_i=\operatorname{softmax}(\ell)_i. \end{aligned}\]

直观上,可以把 $q$ 理解为“这道题需要什么样的答案”,把 $k_i$ 理解为“这个候选项提供什么”。二者都是 $d_p$ 维,点积将各维度的匹配贡献相加:

\[q^\top k_i=\sum_{r=1}^{d_p}q_rk_{i,r}.\]

例如,若学出的某些方向响应“满足目标”“符合约束”,符合这些要求的候选项就能得到更高分。这种匹配能力需要训练,点积公式本身不会自动产生决策能力。 预训练骨干提供语义表示,训练让指针评分头学会哪些匹配关系有助于选择答案。

除以 $\sqrt{d_p}$ 调整分数尺度。所有选项共用 $W_k,b_k$,并与同一个 $q$ 比较。得分直接对应候选位置。

Von

Von 的 OptionMarkerModel采用“ModernBERT 骨干+标记位置读出+共享 MLP”的结构。它提供两种注意力模式:让候选项彼此交流,或者让每个候选独立地与公共问题匹配。

Von 的注意力可见关系、标记位置读出和共享评分器

先把问题、状态和候选项放进同一个序列。 输入格式为:

1
问题 状态 [SEP] [MASK] 选项A [MASK] 选项B

[MASK] 是候选项的读出标记。训练让该位置的隐藏向量汇总候选相关信息,再由共享评分器为候选内容打分。

注意力掩码决定每个标记能汇总哪些信息。 图中矩阵的行是发起查询的位置,列是被读取的位置;✓ 表示允许读取,× 表示屏蔽。矩阵按“公共前缀、候选 A、候选 B”三个片段聚合,展示全局注意力层的可见关系:

  • 默认模式保留双向注意力,候选项可以读取其他候选的信息。
  • independent_options=True 时,公共前缀的读取范围限定为自身,每个候选的读取范围限定为公共前缀和本候选。局部注意力层进一步按滑动窗口确定读取范围。

独立模式还会重置候选的位置编号,让每个候选都像紧接在公共前缀后面。 图中以 3 个前缀 token、每个候选 2 个 token 为例:默认模式下,前缀编号为 0、1、2,A 为 3、4,B 为 5、6;独立模式下,A、B 都从 3、4 开始。一般地,独立模式让每个候选的位置编号都从前缀长度 $p$ 开始:

\[\operatorname{pos}(A)=(p,p+1,\ldots),\qquad \operatorname{pos}(B)=(p,p+1,\ldots).\]

独立模式的直觉是:先分别评价“这个候选与问题是否匹配”,再把各候选的分数放到一起比较。 每个分数由公共前缀和对应候选共同决定,因此候选重排后,各自的分数保持一致。

从同一个隐藏矩阵取出标记行,用同一组参数评分。 对单个输入,骨干输出 $H\in\mathbb R^{L\times d}$。设第 $i$ 个 [MASK] 的位置为 $m_i$,则:

\[h_i=H[m_i,:]\in\mathbb R^d,\qquad \ell_i=f_\phi(h_i),\qquad p_i=\frac{\exp\ell_i}{\sum_{j=1}^{K}\exp\ell_j}.\]

这里 $L$ 是输入 token 数,$d$ 是骨干隐藏维度,$K$ 是候选数。评分器 $f_\phi$ 的内部结构为:

\[\operatorname{LayerNorm}_d \to\operatorname{Linear}_{d\to d/2} \to\operatorname{GELU} \to\operatorname{LayerNorm}_{d/2} \to\operatorname{Dropout} \to\operatorname{Linear}_{d/2\to1}.\]

所有候选共用这个评分器。图中两条路径穿过同一套内部模块,分别输出标量 $\ell_1,\ell_2$,之后转换为选项分数。

Verdict 2.0

Verdict 2.0 的模型代码在标记位置评分的基础上,增加了一个正确性头:先计算各候选的概率,再根据这次分布的形状估计所选答案答对的概率。

Verdict 2.0 的选项评分、分布特征提取与正确性头

选项分布来自骨干表示和共享评分器。 问题类型同时走两条路径:文本路径将类型写成 choice question: … 这样的提示词,与候选项、状态一起进入 Token embedding 和 ModernBERT-base;类型编号路径通过独立的查表层取得类型向量。每个候选前放一个 [MASK]。骨干输出隐藏矩阵后,为各 token 加上同一个类型向量,再取标记行:

\[H=H_{\rm encoder}+\boldsymbol1 e_{\rm type}^{\top} \in\mathbb R^{L\times d},\qquad h_i=H[m_i,:]\in\mathbb R^d.\]

这里 $L$ 是输入 token 数,$d$ 是隐藏维度,$m_i$ 是第 $i$ 个选项标记的位置。类型嵌入来自一个可训练的 Embedding(3, d) 查表层:用 Choice、Noul 或 Score 的类型编号,取出对应的向量 $e_{\rm type}\in\mathbb R^d$。图中这条支路接到加号节点,将同一个类型向量逐元素加到每一行骨干表示上:

\[H[t,:]=H_{\rm encoder}[t,:]+e_{\rm type}.\]

所有候选共用一个评分器:

\[f_\phi: \operatorname{LayerNorm}_d \to\operatorname{Dropout} \to\operatorname{Linear}_{d\to d} \to\operatorname{GELU} \to\operatorname{Linear}_{d\to1}.\]

候选分数经过温度缩放,得到概率分布和最终选择:

\[\ell_i=f_\phi(h_i),\qquad p_i=\frac{\exp(\ell_i/T)}{\sum_{j=1}^{K}\exp(\ell_j/T)},\qquad \hat a=\arg\max_i p_i.\]

温度 $T$ 在校准集上按问题类型与候选数量分桶拟合。它控制分布的尖锐程度;候选的相对排序保持一致。

正确性头根据分布特征,估计这次选择有多可靠。 将概率从大到小排列,记前两名为 $p_{(1)},p_{(2)}$,构造七维特征:

\[x=\left[ p_{(1)},\quad p_{(1)}-p_{(2)},\quad \frac{-\sum_i p_i\log p_i}{\log K},\quad \frac1K,\quad \operatorname{onehot}(\mathrm{type}) \right]\in\mathbb R^7.\]

前四项分别描述最大概率、领先幅度、分布的分散程度和候选规模,最后三维表示问题类型。直观上,这个头学习的是:面对类似的分布形状和任务类型,模型通常有多大把握选对。

正确性头 $g_\psi$ 的结构为:

\[\operatorname{Linear}_{7\to64} \to\operatorname{GELU} \to\operatorname{Linear}_{64\to64} \to\operatorname{GELU} \to\operatorname{Linear}_{64\to1},\qquad c=\sigma\big(g_\psi(x)\big).\]

图中概率分布分成两条路径:一条通过 argmax 选出候选,另一条经过特征提取和正确性头输出 $c$。

两个输出分别学习什么,由监督目标决定。 选项分布使用数据中的软目标分布训练;正确性头在校准集预测上,以所选答案是否匹配参考标签作为二元监督:

\[z=\mathbf1\{\hat a=Y\},\qquad L_{\rm correct} =-z\log c-(1-z)\log(1-c).\]

代码先训练选项评分模型,再拟合温度和正确性头。提取分布特征时使用 detach(),正确性损失更新 $g_\psi$ 的参数。由此,选项分布表达各候选的相对支持程度,$c$ 表达最终选择匹配参考标签的估计概率。 这给前文的概率学习增加了一种具体实现:在候选评分之后,用一个小型模型学习决策可靠性。

Nimble

Nimble 的公开训练方案以 Qwen3.5-9B 为底座,用 LoRA 适配有限选项决策。它沿用语言模型的原生输出头,并在评分器中把词表投影缩小到当前候选集合。

Nimble 的选项标签、原生词表权重取行与候选投影

先把候选答案映射到单 token 标签。 Schema 定义字段、问题与允许答案,提示词说明各答案对应的标签。例如,一个字段的两个候选可以映射到 A、B,其 token ID 分别为 $v_A,v_B$。模型读完当前字段的回答提示,从最后一个输入位置得到:

\[H\in\mathbb R^{L\times d},\qquad h=H[L-1,:]\in\mathbb R^d.\]

这里 $L$ 是输入 token 数,$d$ 是隐藏维度。与 Simple Jev 一样,这个向量原本用于预测紧接着的答案 token。

直接取原生词表头的候选行,再做投影。 设原生输出权重为 $W_{\rm LM}\in\mathbb R^{|\mathcal V|\times d}$,其中每一行对应一个词表 token。先用候选 token ID 取行,再与隐藏向量相乘。图中两个候选对应: \(W_{\rm cand}= \begin{bmatrix} W_{\rm LM}[v_A,:]\\ W_{\rm LM}[v_B,:] \end{bmatrix} \in\mathbb R^{2\times d},\qquad \ell=W_{\rm cand}h= \begin{bmatrix} W_{\rm LM}[v_A,:]h\\ W_{\rm LM}[v_B,:]h \end{bmatrix} \in\mathbb R^2.\)

每个分数仍然表示模型对相应答案 token 的支持程度。既然最终只比较这些答案,就直接计算这些答案的分数。 这与先计算完整词表 logits 再取候选,具有相同的数学结果:

\[\big(W_{\rm LM}h\big)[v_i] =W_{\rm LM}[v_i,:]h.\]

因此,候选投影把这一步从计算 \(|\mathcal V|\) 个分数缩小到 \(K\) 个分数,沿用原生输出权重的对应行。随后在候选集合内归一化:

\[p_i=\frac{\exp(\ell_i/T)}{\sum_{j=1}^{K}\exp(\ell_j/T)}.\]

其中 $T$ 是评分器使用的温度,图中将这一处理并入 Softmax。

训练让原有表示更适合直接决策。 训练脚本为语言模型中的线性层添加 LoRA,用参考答案在允许候选上的交叉熵训练: \(L_{\rm train} =-\log\frac{\exp\ell_Y}{\sum_{j=1}^{K}\exp\ell_j}.\)

这里 $Y$ 是正确候选的索引。训练脚本先取得最后位置的词表 logits,再取候选计算损失;推理评分器采用图中的候选行投影。LoRA 学到的更新可合并进原权重,继续沿用同一套骨干与词表读出结构。

数据构造也服务于这个目标:在两条相近案例中改变一个影响决策的事实,让正确答案随之翻转。例如,“唯一授权人是 Mira”的规则保持一致,将授权记录中的签名人从 Mira 改成 Noah,标签便从允许变为拒绝。模型由这些成对样本学习哪些证据应当改变决策。

多字段推理的计算组织可以承接 Simple Jev。 MLX 先计算公共前缀,复制各层缓存状态,再批量计算字段后缀并读取各自的最后位置;Qwen3.5 的缓存包含注意力 KV 和递归层状态。CUDA 评分器则逐字段计算完整提示词。两条路径都通过候选权重行得到分数。

OpenJev(razorback16)

本节的 OpenJev 指 razorback16/openjev,它以 DiffusionGemma 26B-A4B 为底座,构建兼容 Jev 接口的决策服务。这里沿用仓库名区分具体实现。

它将多个问题的答案位置预先放进一张画布,让扩散模型同时评价这些位置的候选标签。图中展示两个问题的一次读取,对应 steps=1, samples=1。

razorback16/openjev 的答案画布、槽位隐藏向量与候选标签读出

先确定答案应该出现在哪里。 提示词 $C$ 包含状态、问题及各选项的说明;答案画布 $X$ 使用固定格式,例如:

1
2
q1: [随机 token]
q2: [随机 token]

q1:、q2: 和换行属于模板,各问题的答案各占一个 token 位置。问题 1 可以允许 A/B,问题 2 可以允许 yes/no。程序先确定答案槽位 $m_1,m_2$ 及对应标签的 token ID,再在槽位放入随机 token,形成初始噪声。

扩散模型在已有位置上预测干净答案。 AR 模型从最后一个输入位置预测下一个 token;这里的扩散模型则根据提示词和当前画布,预测各噪声位置应该是什么。答案位置已经存在,因此一次画布计算就能同时得到多个答案位置的表示。

具体到仓库固定版本使用的 vLLM DiffusionGemma 实现,同一套 Gemma4 Transformer 权重分两种模式使用:先以因果注意力编码提示词、保存各层 K/V;再让画布以双向注意力读取提示词缓存和画布内容。图中的两类输入由同一骨干处理。

记一次画布计算为 $H=f_\theta(C,X)$,其中 $M$ 是画布 token 数、$d$ 是隐藏维度:

\[H\in\mathbb R^{M\times d},\qquad h_i=H[m_i,:]\in\mathbb R^d,\qquad \ell_i=\operatorname{LMHead}(h_i)\in\mathbb R^{|\mathcal V|}.\]

这里 $h_i$ 来自答案槽位自身。它经过原生词表头后,给出该位置各个干净 token 的分数。程序读取问题 $i$ 允许的标签 token ID $v_{i,1},\ldots,v_{i,K_i}$,在候选集合中归一化:

\[p_{i,a}= \frac{\exp\ell_i[v_{i,a}]}{\sum_{b=1}^{K_i}\exp\ell_i[v_{i,b}]}.\]

实际读取各槽位的标签 log probability,再做同样的候选归一化。整词表归一化项会在分子、分母间抵消,所以与上式使用 logits 的结果一致。

默认单步路径把去噪预测直接作为决策分布。 引擎从这次计算中取出每个答案槽位的概率。Choice 取最大概率的标签,Noul 读取 yes 的概率,Score 按等级概率求期望。这里的直觉是:先摆好所有待答位置,再同时读取各位置的答案分布。

服务还支持增加去噪步数,以及更换槽位初始噪声进行多次读取。设第 $r$ 次读取的概率为 $p_{i,a}^{(r)}$,则多次读取使用平均分布:

\[\bar p_{i,a}=\frac1R\sum_{r=1}^{R}p_{i,a}^{(r)}.\]

自动重读策略根据首次读取的熵决定是否增加读取次数;samples 则指定固定次数。Choice 和 Score 的 confidence 由最终候选分布的归一化熵计算,衡量分布的集中程度:

\[c_i=1-\frac{-\sum_{a=1}^{K_i}\bar p_{i,a}\log\bar p_{i,a}}{\log K_i},\qquad K_i>1.\]

与前面几种模型相比,这条路线增加的是答案画布上的并行去噪读出:位置由模板确定,表示来自现成扩散模型,标签分数来自原生词表头。它把多个问题的回答组织成同一张待评价的画布。

Clef

Cloudflare 的 Clef以 Qwen3.8-27B 为骨干,在隐藏表示上接一个 Joint Schema Head,为多个问题的所有候选评分。它支持文本、图像和视频;图中以两个文本问题为例,展开这个联合决策头。

Clef 的片段汇总、候选证据路由和字段联合决策

先从问题和候选的文本片段汇总表示。 输入序列依次包含状态、各问题的指令和候选描述。程序记录每段文本的 token 范围。骨干输出经过 LayerNorm 得到 $\bar H\in\mathbb R^{L\times d}$,再对相应片段沿 token 维求平均:

\[q_j=\frac1{|Q_j|}\sum_{t\in Q_j}\bar H[t,:],\qquad o_{ji}=\frac1{|O_{ji}|}\sum_{t\in O_{ji}}\bar H[t,:].\]

这里 $L$ 是输入 token 数,$d$ 是骨干隐藏维度,$Q_j$ 是问题 $j$ 的指令片段,$O_{ji}$ 是该问题第 $i$ 个候选的文本片段,$q_j,o_{ji}\in\mathbb R^d$。直观上,整个问题描述和整个候选描述分别汇成一个向量。最后一个输入位置还提供全局向量 $g=\bar H[L-1,:]$。

候选另有一份词义表示:用候选项的 token ID 从原生词表输出权重 $W_{\rm LM}$ 中取行,再求均值,得到 $e_{ji}\in\mathbb R^d$。$o_{ji}$ 来自本次输入的上下文编码,$e_{ji}$ 来自模型已有的词表参数。

每个候选带着问题去寻找证据。 将候选上下文、候选词义和问题向量分别投影到头部宽度 $w$,相加形成候选 query:

\[u_{ji}=P_o o_{ji}+P_e e_{ji}+P_q^{\rm opt}q_j\in\mathbb R^w,\qquad \mathcal M=\bar H P_m^\top\in\mathbb R^{L\times w}.\]

式中的各个 $P$ 都是独立的可训练线性投影。图中的“共享证据投影”对应 Linear(d, w),输出“共享证据表示” $\mathcal M\in\mathbb R^{L\times w}$,代码将它称为 memory。它保留每个输入位置的表示,供候选和字段按需读取。

候选证据路由先分别对 query 和 $\mathcal M$ 做 LayerNorm,再将二者送入多头交叉注意力的 Q 与 K/V 输入;注意力模块内部继续进行各自的 Q、K、V 投影。经过残差连接和 FFN 后,得到候选证据向量 $r_{ji}$。直观上,这一步在问:“针对这个问题,输入中有哪些信息支持这个候选?”

先汇总本题证据,再让不同问题交流。 图中的“字段问题投影”和“全局表示投影”分别将问题向量、全局向量转换到 $w$ 维:

\[b_j=P_q q_j\in\mathbb R^w,\qquad b_g=P_g g\in\mathbb R^w.\]

两个投影都是独立的 Linear(d, w)。这里的 $P_q$ 与前面构造候选 query 的 $P_q^{\rm opt}$ 各有一组参数。图中 $g$ 从高亮的最后一行引出,经过全局表示投影得到 $b_g$;问题表示 $b_j$ 则分成两路,分别参与证据汇总和字段初始化。

对问题 $j$,用 $b_j$ 与各候选证据的匹配分数生成权重,并求加权和:

\[\alpha_{ji} =\frac{\exp\big(b_j^\top r_{ji}/\sqrt w\big)} {\sum_k\exp\big(b_j^\top r_{jk}/\sqrt w\big)},\qquad s_j=\sum_i\alpha_{ji}r_{ji}.\]

这些权重用于汇总候选证据。汇总结果与问题表示、全局表示、问题类型嵌入相加,构成初始字段向量:

\[f_j^0=b_j+\operatorname{LN}(s_j)+b_g+E_{\rm type}[\mathrm{type}_j].\]

$E_{\rm type}$ 是可训练的 Embedding(3, w),按 Noul、Choice、Score 的类型编号取向量。所有字段向量一起进入 4 层 Transformer Decoder:先通过自注意力交流字段信息,再以字段向量为 Q、共享证据表示 $\mathcal M$ 为 K/V 输入执行交叉注意力,随后经过 FFN。各子层采用前置 LayerNorm 和残差连接,最后经 LayerNorm 得到 $f_j$。图中同一份 $\mathcal M$ 的两条支路,分别接入候选路由和 Decoder 内部的交叉注意力。

例如,工单的“故障类型”和“紧急程度”可以在头部交换判断依据。各问题先组织自己的候选证据,再结合其他问题形成最终表示。

用联合字段表示重新评价每个候选。 图中的候选评分展开为三条支路:

  • 词义先验:先从候选本身的词义出发,判断它与当前问题及整体输入是否契合。将问题向量与全局向量相加,得到 $a_j=q_j+g\in\mathbb R^d$;它与候选词义向量 $e_{ji}$ 计算余弦相似度,再经可训练系数 $\beta$ 缩放。
  • 联合匹配:结合各字段交流后的判断,检查当前候选的证据是否支持这个决定。候选证据经过 LayerNorm 得到 $\tilde r_{ji}$,与联合字段向量 $f_j$ 计算余弦相似度,再经可训练系数 $\gamma$ 缩放。
  • MLP 评分:让模型进一步学习两种表示之间更复杂的匹配关系。拼接联合字段向量、候选证据向量、它们的逐元素乘积以及差的绝对值,得到关系特征 $x_{ji}\in\mathbb R^{4w}$,通过共享 MLP 输出标量。

联合匹配分数与 MLP 分数先相加,再经过可训练门控 $\sigma(\eta)$ 缩放,最后加上词义先验,得到该候选的 $\ell_{ji}\in\mathbb R$。同一问题的字段向量 $f_j$ 用于评价该问题的各个候选;各候选分数汇集成 $\ell_j\in\mathbb R^{K_j}$,经 Softmax 得到最终概率。

评分组合。 令 $\tilde r_{ji}=\operatorname{LN}(r_{ji})$,$\beta,\gamma$ 为可训练的正缩放系数,$\eta$ 为可训练门控参数。代码中的候选分数可写成:

\[\begin{aligned} \ell_{ji} &=\beta\cos(e_{ji},a_j)\\ &\quad+\sigma(\eta)\left[ \gamma\cos(f_j,\tilde r_{ji})+ \operatorname{MLP}\!\left( [f_j;\tilde r_{ji};f_j\odot\tilde r_{ji};|f_j-\tilde r_{ji}|] \right)\right]. \end{aligned}\]

第一项利用原生词表向量提供词义先验;括号内结合联合字段表示与候选证据。分号表示向量拼接,$\odot$ 表示逐元素相乘。图中的 $x_{ji}$ 对应拼接后的 $4w$ 维特征,MLP 将它依次送入 Linear(4w,w) → GELU → Dropout → Linear(w,1),输出标量。最后对每个问题的候选 logits 分别做 Softmax,得到 $p_{ji}$。

Clef 将直接决策扩展成了一个联合读出过程:候选 query 从输入中汇集证据,字段向量交换信息,评分器再把这些表示转换为各问题的候选概率。

总结

路线取哪些位置?怎样得到选项 logits?
Laya每个选项前的 [MASK]各选项向量经过共享 MLP,输出标量
Simple Jev/SemIf 原生读出每个问题提示词的最后位置原生词表头输出 logits,再取允许标签
Kev问题末尾的 <decide>、各选项末尾的 </opt>决策向量与选项向量经 Q/K 投影后做点积
Von每个选项前的 [MASK]骨干标记向量直接经过共享 MLP,输出标量
Verdict 2.0每个选项前的 [MASK]加入类型嵌入后经共享 MLP 评分;从选项分布再估计正确性
Nimble当前字段提示词的最后位置取原生词表权重的候选行,直接与隐藏向量相乘
OpenJev(razorback16)扩散画布中各问题的答案槽位原生词表头评价槽位 token,再取允许标签
Clef问题与候选的文本片段、最后输入位置候选证据路由、字段联合交互,再融合词义先验评分
本文由作者按照 CC BY 4.0 进行授权