Skip to article frontmatterSkip to article content

引论

在大语言模型火遍大江南北两三年的2025年,很多读者可能不用再说都已经知道了什么是自回归。 但在这篇文章中我会尽力做出和市面上大多数文章不同的解释侧重,给大家新鲜感。

当然,我还是会从语言模型里的自回归说起,逐步引入和阐明概念。 再抽象做“自回归”这一范式的抽象,强调它是一种分解联合概率的方法,无关于生成模型、所处理的数据是离散/连续,文本/图像/其他的具体形式

语言模型

从使用的角度看,语言模型会根据我们提供的前文等条件(也有可能没有这些条件),生成有一定随机性的后文。 并且这个后文与前文是有相关性的。

那从分布拟合的角度来看,我们需要拟合的就是连贯话语的分布 p(人话)p(人话)。 做一些数学符号约定,使得上面的式子可以更形式化地表达。 我们假设所有的语段都是 ss 取序列 sequence 之意。 那么,我们的目标就是拟合 p(s)p(s)

此时我们会发现第一个问题:

序列的长度可以延展到任意长。 比如为了回答一个问题,我可以直接给出答案,也可以给出详尽的分析再给出答案,而详尽的分析有多长? 那可以是任意的长,从最最基础的原理逐步分析到跟答案直接相关的原理。 只要前后语句通顺,逻辑连贯,那就是一个合法的序列。 用更数学的话来说 ss 的所有可能取值是可列无穷的。

如果随机值只有有限的 nn 种取值,我们不妨直接用 nn 分类模型来拟合这个随机变量的分布,让网络直接输出 nn 维的满足和为 1 各通道大于等于 0 的向量来表示 nn 种可能的取值就好。 但当随机变量的可取值有无穷多个的时候,这样的办法就不好用了,我们不可能让网络直接输出一个无穷维的向量。

那解决的办法也很简单,或者说很符合表示语言的方式给大家的直觉。 我们说话就是一个个词说出来的,那不妨把语段 ss 拆分,看成是多个单词、符号等元素(这里不说 token 是为了不引入新的概念词汇,实际上指的就是 token)前后排成的序列,即可认为:

s=(x1,x2,...,xT)s = (x_1, x_2, ..., x_T)

对于不同的 ss,某个位置的词 xix_i 的取值可能就不同了,更重要的是语段 ss 的总长度 TT 也可能不同。 那么很自然地,p(s)p(s) 就是 p(x1,x2,...,xT)p(x_1, x_2,..., x_T),后者是一个联合概率,表示第一个词取 x1x_1 第二个词取 x2x_2,...,TT 个词取 xTx_T 的概率。 最后,从条件概率的定义可以做如下拆分:

p(s)=p(x1,x2,...,xT)=p(x1)p(x2x1)p(xTx1,x2,...,xT1)p(s) = p(x_1, x_2,..., x_T) = p(x_1) p(x_2|x_1) \cdots p(x_T|x_1, x_2,..., x_{T-1})

这样,只看每个乘法项 p(xtxi<t)p(x_t|x_{i < t}),它其实是一个关于词 xtx_t 的条件分布,而 xtx_t 的可能的取值是有限的,是可以用最直接的输出一个满足约束的 nn 维向量来表示的。 然后根据已经得到的数据集里的序列,拆分到每个词和它相应的前文条件,用交叉熵损失来拟合这些条件分布。即做

minθE(x1,x2,...,xT)p(s)[logpθ(xtxi<t)]\min_\theta \mathbb{E}_{(x_1, x_2,..., x_T) \sim p(s)} \left[ -\log p_\theta(x_t|x_{i < t}) \right]

这里先忽略具体的网络选型,当拟合好了之后,我们就可以根据 pθ(xtxi<t)p_\theta(x_t|x_{i < t}) 来生成新的序列了。 具体的流程同样是利用式 (2) 来产生:

  1. 我们的目标是采样出符合 p(s)p(s) 的序列 ss,使用训好的网络,可以近似认为从 pθ(s)p_\theta(s) 采样也行。
  2. 根据 pθ(s)=p(x1,x2,...,xT)=pθ(x1)pθ(x2x1)pθ(xTx1,x2,...,xT1)p_\theta(s) = p(x_1, x_2,..., x_T) = p_\theta(x_1) p_\theta(x_2|x_1) \cdots p_\theta(x_T|x_1, x_2,..., x_{T-1}),我们只需要根据网络的输出,先做采样 x1pθ(x1)x_1 \sim p_\theta(x_1),得到 x1x_1 后以它为条件,根据条件分布 pθ(x2x1)p_\theta(x_2|x_1) 采样 x2x_2,...,以此类推,往后采样。
  3. 根据公式,采样结果组合起来就是符合要求 spθ(s)s \sim p_\theta(s) 的序列了。

当然在 2 的具体流程细节上需要做特殊考虑。 训练的时候我们有完整的序列 ss,所以,即使每个 ss 是长度不一样的,我们也把 ss 拆分,就可以用来做 pθ(xtxi<t)p_\theta(x_t|x_{i < t}) 的拟合。 但采样的时候,我们并不能知道何时停止新词的采样,做最后的序列组合。 解决这一问题的方法是,通过手工添加新的特殊类别/特殊词 <\EOS> (end of sequence) 来表示序列结束。 并且把训练的序列 ss 的结尾都添加上 <\EOS>。 这样,在逐词采样的过程中,当采样到 <\EOS> 时,就可以认为是停止词语采样组成完整句子了。

这种拟合序列分布,或者拟合词语的条件分布的模型,术语上我们称为语言模型, 应该是取建模语言如何产生的意思。

网络的选择

由于现在网络直接拟合的分布是 pθ(xtxi<t)p_\theta(x_t|x_{i < t}),它是一个关于 xtx_t 的分布,以 xi<tx_{i < t} 为条件。

我们知道 xtx_t 是可能取值为有限个的离散变量,所以网络的输出是有很直接而简单的选择的 —— 输出一个 nn 维向量,并且这个向量是 softmax 归一化的,使其满足和为 1 各通道大于等于 0 的约束,可以作为合法的 nn 值离散分布概率质量函数。 那剩下的问题就是怎么处理条件。

那也是很直接的思路,把条件作为网络的输入,设计网络使得它利用了所有的这些输入就好。 所以很直接地又可以看到,条件虽然通用地写为 xi<tx_{i < t},但其实它是一个变长的输入,根据 ii 的不同而变化。 那能处理变长输入的网络算子大体上就是 RNN 系列和 Attention 系列了,或者因果反过来说,这两个系列的算子至少有部分的设计动机是处理序列类变长输入。

算子具体怎么设计,怎么运行就不在本文做详细的展开了。

自回归

把两部分内容合在一起,我们看我们现在得到的模型是如何做推理的。

  1. x1,x2,,xi1x_1, x_2, \dots, x_{i - 1} 输入网络,得到网络的输出 pθ(xix1,x2,,xi1)p_\theta(x_i|x_1, x_2, \dots, x_{i - 1})
  2. 根据 pθ(xix1,x2,,xi1)p_\theta(x_i|x_1, x_2, \dots, x_{i - 1}) 实际采样出 xix_i
  3. xix_i 加入输入,组成新的输入 x1,x2,,xi1,xix_1, x_2, \dots, x_{i - 1}, x_i,重复 1,2,直到采样出 <\EOS>

新的一个核心的模式出现了,我们把通过模型的输出做简单加工后,又把它作为模型的输入(的一部分)。 这种用前面的输出预测后面的一部分内容的方式,就称为自回归。 取自己预测/回归自己的意思。

反刍

虽然目前自回归运用最多的场景是语言模型,但我们可以看到

p(s)=p(x1,x2,...,xT)=p(x1)p(x2x1)p(xTx1,x2,...,xT1)p(s) = p(x_1, x_2,..., x_T) = p(x_1) p(x_2|x_1) \cdots p(x_T|x_1, x_2,..., x_{T-1})

这个条件概率分解,是自回归的核心。 只要有它,我们就会做到以一些条件为输入,模型给出下一个小部分取值的分布,然后我们做相应的采样,得到这个新的小部分,再把它作为输入,然后往复循环“预测——采样——加入输入”,变成自回归的样子。 而这个条件概率分解成立的要求,仅仅是抽象整体 ss 能被拆分成多个部分,每个部分不一定需要是离散有限个,部分部分之间也不需要用什么独立性假设。

比如说 ss 是一个取值在 Rd\mathbb{R}^{d} 的随机向量,我们可以按通道把它拆分成 dd 个部分,每个 xix_i 是一个可取值在 R\mathbb{R} 上的随机变量。 那上面的条件概率分解依然是成立的,拆分后拟合分布的方式也是类似的。 只不过做 R\mathbb{R} 上的分布的拟合比 nn 值离散分布要难一些,我们留待下篇文章开始文章讨论。

从这可以看到,自回归仅是一种分解联合概率的方法,无关于生成模型、所处理的数据是离散/连续,文本/图像/其他的具体形式。 如果读者熟悉的话,这也正是 MAR 所传达的核心思想。

同时我们也可以看到,如果只把 ss 看成抽象的 “全体”,只要全体能拆分就行,谁先被预测,谁后被预测,都是满足条件概率关系的。比如我也可以写出这么些合法的联合概率拆分:

p(x1,x2,...,xT)=p(xT)p(xT1xT)p(x1x2,xT)=p(x1)p(x3x1)p(x5x3,x1)p(x2x1,x3,)p(x4x2,x1,x3,)=p(x1,x2)p(x3,x4x1,x2)p(x5,x6x1,x2,x3,x4)\begin{aligned} & p(x_1, x_2,..., x_T) \\ =& p(x_T)p(x_{T-1}|x_T) \cdots p(x_1 | x_2, \dots x_T) \\ =& p(x_1)p(x_3|x_1)p(x_5|x_3, x_1)\cdots p(x_2| x_1, x_3,\dots) p(x_4|x_2, x_1, x_3, \dots) \dots \\ =& p(x_1, x_2) p(x_3, x_4| x_1, x_2) p(x_5, x_6| x_1, x_2, x_3, x_4) \dots \end{aligned}

语言模型通常选择的顺序只是符合了大多数情况下的语言的书写习惯,即先写前面的,再写后面的。 这样作为条件的部分和作为随机变量的部分,相关性就会很高,也即对应的条件分布比较低熵,好拟合。 同时也把可列无穷种可能取值的 ss 拆分成了多个有限种可能的分布之积,更方便用网络来表达和拟合。

但如果说全体 ss 是一个图像这种二维的数据,或者更高维的数据,那如何拆分这个全体,谁先谁后可就没有那么明显的顺序了,这也是一个目前开放的问题。

总结

自回归的核心思想是,如果需要拟合一个大的全体 ss 的分布,可以考虑把它拆成先后的多个部分,并排出先后关系,通过条件概率分解,来拟合每个部分的条件分布,从而间接达到拟合 ss 的分布的目的。

References
  1. Li, T., Tian, Y., Li, H., Deng, M., & He, K. (2024). Autoregressive Image Generation without Vector Quantization. arXiv. 10.48550/ARXIV.2406.11838