上下文长度越卷越离谱,我们真需要这么多token么?
经常关注大模型的朋友一定听过一个词,叫做 " 上下文窗口 "。比如硅星人 Pro 的文章《模型上下文长度达到 10000000,又一批创业者完蛋了?》就提到了,谷歌 Gemini 1.5 Pro 的上下文长度达到了 100 万个 token,如果让它来写哈利波特,可以一口气从哈利波特去 9 又 4 分之 3 车站写到小天狼星为了救哈利而牺牲。
对于大语言模型来说,上下文窗口是指在训练和应用大语言模型时,模型能够同时考虑并处理的输入序列的最大长度。这个窗口限制了模型对文本中连续标记之间依赖关系的理解范围。对于 LLMs 而言,大的上下文窗口是极其重要的特征,因为它允许模型在处理长文档、对话历史或复杂语境时保持连贯性和理解力。如果上下文窗口太小,当输入文本超出这一窗口限制时,模型可能无法准确捕捉到远距离词语间的关联,从而导致性能下降。
2024 年 2 月 26 号,微软看到谷歌 Gemini 1.5 pro 那 100 万个 token 以后坐不住了,他们发表了一篇新的论文,提出了一个叫做 LongRoPE 的方法,能够在保持原始短上下文窗口性能的同时,将预训练 LLMs 的上下文窗口扩展到令人印象深刻的 200 万个 token。
RoPE 是 Rotary Position Embedding(旋转位置嵌入)的缩写,这是一种在 transformer 模型中用于编码输入序列中 token 位置信息的方法,它最大的作用就是让模型能够知道各个 token 之间的顺序关系。那么 LongRoPE 的含义呢,就是 RoPE for long text,即给长文本准备的旋转位置嵌入。
LonRoPE 的核心逻辑是通过改进位置插值方法,使得在扩展上下文窗口时仍能有效利用 RoPE 的特性。LongRoPE 本质上来说是一种微调,分为下面下面三个步骤:1. 发现并利用了位置插值中的两种非均匀性,通过高效搜索提供了更好的微调初始化条件,并使得在无需微调的情况下能实现上下文窗口 8 倍的扩展;2. 引入了渐进式扩展策略,首先针对 25.6 万 token 长度的文本对大语言模型进行微调,然后在已微调的扩展大语言模型上进行第二次位置插值,从而达到 204.8 万 token 的上下文窗口;3. 对于恢复原始较短上下文窗口的性能,LongRoPE 会在 8000 长度上重新调整参数,确保即使在非常长的上下文窗口设置下,模型也能在较短序列上的表现不下滑。
我们可以这样来理解,它的技术原理是通过精巧地处理位置嵌入,依据实际情况灵活调整和优化,既拓宽了模型处理长文本的能力,又保证了模型在应对短文本时同样具备优秀的性能。那么开发 LongRoPE 的意义在久于允许大模型在无需大量的额外训练和计算资源的情况下,能够处理超长文本。
所以 Longrope 最大优势并不只是说能扩大上下文窗口,而是不需要额外训练,不需要多配备硬件,仅仅使用 1000 步微调以内就能实现这 200 万个 token 的扩展。
我们真的需要那么多 token 吗?
那你可能就要问了,微软研究出这个 200 万 token 的上下文窗口技术图啥呢?别说日常对话了,哪怕是拿本小说来,估计也很难满足 200 万个 token。
咱们文章开头也讲过了,上下文窗口它就是同时考虑并处理的输入序列的最大长度。而在 transformer 架构中的自注意力机制中,上下文窗口大小决定了模型可以同时捕捉到多远距离的词语依赖关系。粗暴点来理解,上下文窗口完全可以被当成模型能够容纳多少文本的一种体现。就跟邮箱的油表一样,上下文窗口增大时,意味着它可以理解并基于更长的文本片段进行推理。
例如,如果一个大语言模型具有 20 万 token 的上下文窗口长度,它可以一次性处理大约 35 万个汉字的上下文信息。那么 200 万个 tokens 的上下文窗口长度,大约就是 350 万字,要知道一本囊括了保尔柯察金一生的《钢铁是怎样炼成的》才不到 40 万个字而已。
在大模型领域,上下文窗口不应该是 " 你能炼一吨,咱炼一吨半 ",因为增加上下文窗口也意味着模型的计算量和内存需求将大幅增加,因此在实际应用中必须权衡上下文窗口的大小和计算资源的有效利用。
如果只是增加计算资源消耗倒还好说,毕竟硬件上下血本就完事了,没有花钱的不是,但过分追求上下文窗口还会导致一个问题,叫做 " 过拟合(overfitting)"。过拟合是说模型在训练数据上表现很好,但在未见过的测试数据上表现较差的现象。也就意味着模型过度适应了训练数据的特性,将训练数据中的噪声或随机变化也当作了真实的模式,从而导致模型在新数据上泛化能力较差。
过拟合通常发生在模型复杂度较高时,例如参数过多或特征过于丰富的情况下。过度复杂的模型可能会在训练数据中学习到过多的噪声或细节,而忽略了数据中的真实规律。而目前来看,LongRoPe 还未正式启用,因此我们也没办法清楚它是否发生了过拟合,不过照着 200 万 token 大军的势头看,这个概率并不低。
还没完,模型在运行过程中,它是需要在内存中发生并行计算的。如果上下文窗口过大,与之对应的内存消耗也就会增加。所以综合考量,无论是大模型的开发者,还是大语言模型的微调者来说,增加上下文窗口是没问题的,然而过分追求超长上下文窗口,并没有特别重大的意义,反倒还会产生未知的结果。
说了这么多,其实有一个同样很重要的原因,是各大厂商今天都在卷长度的重要 " 动机 " ——因为大语言模型没有特别明确的性能评分标准,只有一个知识库的评分标准,因此透过上下文窗口本身的数学表示,就会给人一种 " 数字越大,模型越厉害 "。也许是时候回归本初,想想最初增加上下文窗口的意义是什么,让大家回到增加模型性能的初心上来了。