大语言模型的基本逻辑

大语言模型的本质是一个 N-GRAM 模型,即:

定义:

假设 $w_1, w_2,\dots, w_{N}$ 是一个单词序列。我们可以按如下公式计算单词序列的概率:

$$ p(w_{1},w_{2},\dots,w_{N})=\prod^N_{i=1}p(w_{i}|w_{1},w_{2},\dots,w_{i}) $$

该模型是一个 $N-1$ 阶的马尔可夫链,称为 N-GRAM 模型

推论: 有限马尔可夫链(或 N-GRAM 模型)背后的「语法」是有穷自动机,也就是正则表达式。是 乔姆斯基体系 最底级的文法。

Agent + LLM 可以成为完备图灵机

一般来说,希望将有穷自动机扩充成完备图灵机,朴素的想法就是添加外部存储,如 Schuurmans et al(2023) 就证明了使用外部存储的大模型是图灵完备的。但这种图灵完备性的实现依然需要大量的人工介入。所以我们希望找到一种更加自然的,可以自我学习的具有图灵完备性的模式。

While 循环的图灵完备性

编程语言 WHILE 语义 (Semnatik):

  • 一个 while 程序 $P$ ,通过传递 $k$ 个参数,返回一个结果, 即 $f:\mathbb{N}^k\rightarrow\mathbb{N}$
  • 其他未定义的参数可以在程序里被调用,但是必须设定为 $0$
  • WHILE 程序的结果在结束结束后通过 $x_0$ 传达
  • 对于一个 WHILE 程序,有三种运行模式:
    • 变量赋值: $x_i=x_j+c,c\in{0,1,−1}$
    • $P_1$;$P_2$ ( $P_1$,$P_2$ 是两个任意程序程序),先运行 $P_1$ ,再运行 $P_2$
    • WHILE $x_i \neq 0$ DO $P$ END 意思是, $P$ 程序将一直被运行,直到 $x_i$ 等于 0

定理:编程语言 WHILE 是图灵完备的

证明: 我们将受限 RAM(Registermaschine)(只有 LOAD, STORE, CLOAD, CADD, CSUB 功能的 RAM) 中的每一步都用 WHILE 程序来代替计算 1,由于受限 RAM 是图灵完备的,所以 WHILE 也是图灵完备的。

Agent 流程都是 While 循环

典型的几个 Agent 流程:

  1. ReAct 获得反思推理能力
  2. BabyAGI 基础的计划任务 Agent
  3. Reflexion 长期记忆和短期记忆(短期记忆就符合上述流程)
  4. AutoGPT 第一个全能 Agent

都可以转化到上述的范式中,进而获得更强大的计算能力(通用图灵机)。

备忘

Agent 的重要意义其实是帮助 LLM 获得图灵完备性。当然,现在的 Agent 所缺乏的是自适应能力,还强依赖于 Prompt Engineering,不能自适应,不能进化,也没有利用上足够多的人类知识。

大语言模型的泛化性

从机器学习的角度看,大语言模型是一个生成式模型——学习原始数据的概率分布。这里有一个基础的问题:用哪种机器学习的方法来学习这个生成式模型。

我们也逐步来分析这个问题,首先是传统统计学习的学习方法和深度神经网络之间的选择。从结果上看,我们选择了深度神经网络,因为我们不可能见过所有人说过的所有话,所以我们希望我们训练的模型在我们未见过的样本上也能取得很好的效果,这就是模型的泛化能力。而实验表明,深度神经网络的泛化性更好。为什么呢?

过参数化是泛化性好的本质原因

在传统统计学习中,我们希望使用的参数尽可能的少(奥卡姆剃刀原理),这样才能带来更好的泛化效果。另一方面,我们又希望我们的模型的表达能力尽可能的强,这样才能更好的拟合真实的概率空间。所以会有经典的微笑曲线:

2qe95

假设空间的大小不能太小,也不能太大(否则会过拟合)。

但当时的人们都没有尝试一件事情,就是如果进一步增大参数空间(已经发生过拟合之后),会发生什么?

下图是实际发生的事情:

6kj97

随着参数空间的继续增大,泛化性又逐步的提升了,而且比过拟合之前的最优值还要好了。

这件事是深度学习拥有良好泛化性的本质原因——过参数化。如 Belkin et al(2018) 中描述的,其实这种能力也并不是深度神经网络所独有的,而是一切过参数化的机器学习方法都能具备的性质。

深度神经网络一方面可以通过网络结构学习任意形状的可积函数的分布,另一方面,又可以通过过参数化获得良好的泛化性,于是就成为了真实世界大部分问题的最优机器学习方法——我们可以从猜测真实问题的函数结构中解脱出来,也不用担心样本量少无法遍历全部解空间。

过参数化带来的思考

过参数化的机器学习过程有无穷多最优解(训练数据上 Loss 为零),所以一定是一个非凸优化问题。但是不同的解对应的泛化性是不同的。而至今为止,我们也没有一个关于解的泛化性的指导性优化理论。所以深度学习能否获得良好的泛化性是一个随机事件。

但另一方面,从实践的角度我们能得到,深度学习获得良好泛化性又是一个大概率的事件。

结合深度学习中已经获得的大量实验结果,我们可以形成这样的物理认知:泛化性好的解空间应该是空间范围比较大(或者是梯度变化更平缓)的区域;而泛化性不好的空间则反之。从而自然会有结论:解落入更大空间的概率会更大,所以解能大概率是泛化性好的。

而基于上面这个未被证实认知也会带来一些推论:

  • 收敛速度快的算法,可能其泛化性不如收敛速度慢的算法
  • 增加收敛时的随机扰动可以提升泛化性

这些结论与已知的实验结果是相符的:Adam 收敛速度好于 SGD,但泛化性很多时候不如 SGD;而 SGD 的泛化性好于 GD。

以及,当下的一些研究,例如尝试将已经训练好的模型中的部分参数扣掉——“因为这些参数的变化不会影响训练集上的 Loss,或者我们已知的测试集上的 Loss”……这些尝试是危险的,很可能损失掉良好的泛化性。

过参数化的泛化性问题,现在还没有很好的数学解释,从而也没有合适的理论来衡量一个解的泛化性效果。一段时间之内,这个问题都会是大模型的“阿喀琉斯之踵”,考验大部分的深度学习优化算法——当你带来计算效率的提升时,是不是能确保泛化性不下降

大语言模型的 Transformer 算子

当我们确定了使用 N-GRAM 作为语言模型,以及利用深度神经网络作为机器学习的方法,以获得模型良好的泛化能力。下一步就需要进一步研究模型更细节的结构上是否为大语言模型带来的新的能力,亦或者是限制了什么能力。

这里首先引入一个结论:

当前所有的深度学习中的算子,都可以展开成全链接网络。也就是说,当前的各种深度学习的算子,并不能获得全链接网络获得不了的能力。所以如果是作为基础能力的研究,例如“网络层深是如何带来更强的表达能力的”这种研究课题,是可以将任意算子都抽象成全链接网络来进行探索。这也是 NTK 理论的重要价值。

于是,各种具体算子带来的好处,是在于使用时效率的提升。这种提升等价于——给网络带来良好的先验知识。所以深度学习中的算子不存在优劣之分,只有不同的算子对于不同的数据,先验知识的匹配程度的差别。

所以下面我们即将讨论的 Transformer 算子,研究的重点是它带来了哪些先验知识(或者可以说它舍弃了哪些信息,而只关注哪些知识)。

Transformer 算子的位置编码

N-GRAM 模型是时不变的,具体来说,就是一句话的分布,不会因为它前后位置的小变化而改变。例如一个文章中一句话前面多打了一两个空格,并不会影响将要说的这句话。

更具体来说,就是 N-GRAM 中的信息只与相对位置信息有关,而与绝对位置信息无关。基于这个信息,就可以优化全链接网络,设计出算子结构,使得其只与相对位置信息有关,而与绝对位置信息无关。

放到 Transformer 算子中来说,就是位置编码的设计应该满足:

$$ ⟨f(q,m),f(k,n)⟩=g(q,k,m−n) $$

只与 $m-n$ 有关,而跟 $m,n$ 的具体数值无关。从这条性质就能比较容易地得到 RoPE 旋转位置编码。

位置编码的内差

大模型当前研究的重点之一是上下文窗口的大小,我们希望这个窗口可以进一步的扩大以捕获更多的输入信息。

但因为训练数据有限,以及模型本身需要有一个明确的形状,所以训练时的数据基本上还是要维持差不多在 4k 的水平上,但希望能对更长的文本进行预测。这时,从位置编码的性质来看,是与上下文窗口的大小无关的,所以是可以合理外推到无限大的。但是受限于训练样本的数量,当上下文窗口更大时,基本上还是只能有效捕获到训练窗口大小的信息,对更多的信息是无法利用的。

这时自然的想法时,如果我对信息内差(将更长的文本挤成短文本窗口大小的样子),就可以利用已经训练的信息来推测更多的信息了。

可以理解成,将位置编码设计成:

$$ ⟨f(q,m),f(k,n)⟩=g(q,k,\frac{m−n}{s}) $$

其中,$s$ 是窗口长度。这表达的是位置编码与相对位置的绝对大小无关,而只与相对位置的相对大小有关。

但是这样的问题是,在更常用的场景下,相对位置的绝对大小是更重要的,例如比较短的句子中,两个 token 究竟是相隔几个位置是十分重要的。这意味着,无法直接使用这样的位置编码获得任意的窗口能力。

所以,当下流行的位置编码内差的方法是:

  1. 通过 RoPE 算法训练一个 $s$ 长的窗口
  2. 然后再用内差的办法,重新扩张了窗口大小,此时低频(长文本部分)通过内差获得了还不错的训练性能。但高频(短文本)部分却被严重破坏了。
  3. 此时重新微调模型,将高频部分调整到合适的位置,可以理解成只需要训练高频部分的信息(这部分信息其实也已经有了一些合理的先验知识了),所以可以更快的将短窗口扩展到长窗口。

NTK-aware Scaled RoPE 方法,使用的是高频内推,低频外差的办法,做到了不需要额外训练即可扩大上下文窗口,即:

$$ ⟨f(q,m),f(k,n)⟩=g(q,k,l(m−n)) $$

其中:

$$ \begin{equation} l(m-n) \approx \left \{ \begin{array}{ll} m-n & \text{当}(m-n)\text{较小时} \\ \frac{m-n}{s} & \text{当}(m-n)\text{较大时} \end{array} \right. \end{equation} $$

但这个方法还是会在很多位置上失去原本训练时学到的信息,使得外推时有性能损失。

类似的,其实我们还可以用这样的思考方式,重新设计位置编码,使得模型可以更好的利用现有的训练数据获得合理的外推能力。例如 ReRoPE 算法的位置编码的设计是这样的:

$$ ⟨f(q,m),f(k,n)⟩=g(q,k,l(m−n)) $$

其中:

$$ \begin{equation} l(m-n) = \left \{ \begin{array}{ll} m-n & m-n < s\\ s & m-n \geq s \end{array} \right. \end{equation} $$

这是因为,训练样本中,我们从未见过 $m-n>s$ 的样本,所以更长程的样本都用 $s$ 来替代,近似的获得信息的利用。类似这样的编码设计,可以保证训练集上无性能损失,并且具备了一定的扩展能力,最大化的利用了训练信息。

基于这个思想,还可以扩展出很多的位置编码的设计,尽最大可能性来挖掘训练样本中的信息。

位置编码是否需要时间衰减?

包括 RoPE 在内的各种位置编码,都增加了时间衰减的先验。而这部分信息其实是可以通过训练来学习到的。所以是否真的需要时间衰减这个先验信息,它是否能更有效的帮助我们训练?是一个值得研究和思考的问题。

Transformer 算子的信息编码

类似于上面位置编码的分析,我们知道分析算子的核心,是考虑它保留了什么信息(或者说舍弃了什么信息,是否有不应当舍弃的信息被舍弃了)。

备忘

Transformer 信息编码的设计表达的是:某个位置所蕴含的信息,只与这个位置之前的所有文本间两两的相似度信息有关。

其中极为重要的信息是如下公式:

$$ Attention(Query,Source) = \sum_{i=1}Similarity(Query,Key_i)*Value_i $$

于是也可以将 Attention 机制看作一种软寻址(Soft Addressing)。

至于注意力模型中是否丢失了什么重要的信息?是否有更加合理的选择?是进一步分析 Transformer 算子的核心。但这一部分同样也没有什么更加基础的数学依据,所以就没有什么进一步讨论的余地了。

稍值得留意的是,具体的 $Similarity$ 算法的选取,还是可以从一切其他不变量中获得部分更加有意义的约束的。例如,从熵不变性看Attention的Scale操作,还是可以从提升上下文窗口外推能力的角度,获得一个更有效的系数项。

大语言模型的对齐

这部分其实在数学上值得分析的内容不多,因为对齐的操作本质上是一个偏应用的操作,是让预训练模型更加符合人类的使用场景的操作。所以对齐之后,模型能力层面是没有本质提升的,更多的是在方便人类使用的层面获得了提升。这部分从应用和工程角度是需要而且极为重要的,但没有额外的数学信息。

其中只有一个话题值得探索,即为什么对齐的操作选择了强化学习而不是继续用传统的模式识别的方法训练?

备忘

坊间的笑谈是,当时 OpenAI 负责对齐的团队恰好手边有现成的 RL 的算法,所以就用它搞出了 RLHF。

网上关于这个问题有一些解释,大体上就是表达 RL 的调整效率是高于传统的模式识别的。这部分内容我还没有仔细的研究,就先不胡扯了。