跳转至

23 模型核心技术指标:如何提高上下文长度?

你好,我是独行。

这节课我会给你介绍大模型中非常重要的一个技术指标:上下文长度。我们知道,AI问答类产品和传统问答类产品,在使用层面上有一个很重要的区别就是上下文,AI问答产品可以根据上下文进行更加深层次的问答,给我们的感觉就是很智能,很人性化。

前阵子非常火的AI问答产品Kimi,就是以超长上下文著称,比如支持200万字长文本输入,一次性输入几本书,可以准确进行内容整理输出;再比如GPT-4-turbo,支持128K上下文长度,还有像6B,最新版本已经支持32K上下文长度。

以前各大厂商在宣传自己的产品的时候,讲的最主要的一方面就是参数规模,现在除了参数规模,还经常提的就是支持的上下文长度,所以业界有人笑称,大模型卷完参数,开始卷上下文了。今年3月份,阿里云通义千问已经将上下文长度直接提升至1000万字,是Kimi的5倍,而且免费提供给客户使用,一下子卷到了极致。

那么为什么大厂都开始卷上下文长度了呢?

为什么超长上下文很重要?

用Kimi所在公司月之暗面(Moonshot)的创始人杨植麟的话说,Lossless long context is everything,杨植麟判断AI产品的终极价值是提供个性化的交互,⽽lossless long-context是实现这⼀点的基础。模型的微调不应该⻓期存在, 用户跟模型的交互历史就是最好的个性化过程。

我们知道,在传统计算中有两个核⼼原则:计算是按照顺序逐步进⾏的,每⼀步都有有限的复杂度容量。⼤型语⾔模型可以被看作是进化了的计算实体,所以⼤模型能够达到的最⾼⽔平由两个因素决定:一个是单步骤的容量,即模型在每⼀步中可以处理的信息量,对应参数量;另一个是执⾏的步骤数,也就是模型能够处理的上下⽂⻓度。

⽬前,⼤部分⼤模型研究都集中在增加模型参数量的⼤⼩,即增强「单步骤容量」。但是在保持⼀定参数量的同时放⼤另⼀个维度,即「步骤数」或上下⽂⻓度也同样重要。上下⽂窗⼝就像⼤模型应⽤的新「内存」,窗⼝越⼤,用户能⽤它做的事情就越⼴泛;同时,窗⼝所能容纳的信息越多,模型在⽣成下⼀个token时可以参考的信息就越多,「幻觉」发⽣的可能性就越⼩,⽣成的信息就越准确。

举几个很实际的例子。

  1. 招聘场景,在系统上传50份简历,每份简历都是⼀个PDF⽂档,50个简历上传之后,提要求,⽐如要具备⼀定的英语⽔平,有⽐较强的技术背景等,智能助⼿在阅读完这50份简历之后,⻢上就给出来了Top5推荐,最后Top2的两个⼈刚好就是最后实际被录⽤的。
  2. 再比如打⻋发票整理,直接上传50个发票,智能助⼿可以⾃动整理你过去⼀个⽉的⾏程到底是什么样的,直接整理出来⼀个报销⽂档。
  3. ⼜或者有好⼏篇英⽂论⽂,你想做⽐较、分析,智能助⼿可以利⽤它的⻓⽂本能⼒,很好地完成任务。

为什么会有上下文限制?

计算资源限制

就拿Transformer架构来讲,前面我们讲过注意力机制,所有的输入会被切分成一个一个token,注意力机制就是在预测下一个词的时候,可以计算当前token和其他token的关系,如果输入序列非常大,切分出来的token就多,注意力机制计算的时候,需要的算力就会更大。

Transformer模型中⾃注意⼒机制的计算量。会随着上下⽂⻓度的增加呈平⽅级增⻓,⽐如上下⽂长度增加32倍时,计算量实际会增⻓1000倍,这意味着如果只是⽤朴素的⽅式实现,用户需要等待极其⻓的时间才能获得反馈,所以如果想要获得快速反馈,那么必须增加算力,这是核心原因。

内存消耗

随着输入序列长度的增加,模型在每个处理步骤中需要保留更多的中间状态信息。这会显著增加GPU或其他处理器的内存需求。在实践中,这个问题限制了模型能够处理的最大序列长度,以适应可用的硬件资源。

宽带限制

以1750亿参数的GPT-3为例,⽬前最⾼单机配置(80GiB * 8)最多只能⽀持64k上下⽂⻓度的推理,超⻓⽂本对显存的要求可⻅⼀斑。这带来了极⼤的显存带宽压⼒:英伟达A800或H800的显存带宽⾼达2~3TB/s,但⾯对如此⻓的上下⽂,一般⽅法的⽣成速度只能达到2~5tokens/s,使⽤的时候极其卡顿,体验很糟。

如何支持更长上下文?

关于支持更长上下文,我们来看目前业界常用的一些方法。

稀疏注意力机制

稀疏注意力机制是一种优化过的注意力计算方法,使用全连接注意力时,每个元素都会与序列中的其他元素计算注意力关系,而在稀疏注意力机制中,元素只与序列中选择的部分元素建立这种关系。这种选择可以基于预定义的模式,比如局部窗口、固定模式等,也可以是通过学习得到的动态模式。

稀疏注意力机制的主要优势是显著降低了计算复杂度和内存需求,使模型能够高效地处理更长的序列。这一机制特别适合需要模型理解和处理大范围上下文信息的应用。

滑动窗口

滑动窗口是一种简单的限制方法,用于减少自注意力计算的复杂度。在这种方法中,每个令牌只关注它附近的一小部分令牌。例如,如果设置窗口大小为5,那么每个令牌只会与它前后两个位置的令牌进行交互(总共5个令牌)。这种方法能有效降低计算量,因为它限制了每次计算涉及的令牌数量。

滑动窗口和稀疏注意力都是减少注意力计算的方法,不过二者有区别。

  1. 计算复杂度:滑动窗口通过简单地降低每个令牌关注的范围来减少复杂度,而稀疏注意力通过更智能的选择关注点来优化计算。
  2. 灵活性:滑动窗口技术相对固定,每个令牌的关注范围是固定的。稀疏注意力则更灵活,可以根据任务的需要调整关注的范围和模式。
  3. 实现难度:滑动窗口技术实现起来相对简单,而稀疏注意力可能需要复杂的数据结构和算法,尤其是在动态选择关注点的时候。

降采样

降采样就比较粗暴了,就是一种数据减少技术,减少输入序列,同时尽量保留重要信息,比如只选择序列中的某些部分单词,或通过合并相邻的元素,来创建一个更短的序列。比如当我们输入一本20万字的PDF书籍时,通过一定的策略,只取其中我们认为重要的内容,经过处理后,喂给模型的可能只有2万字。这样的方法优势劣势都很明显,优势就是可以让模型支持更长的上下文,劣势就是有可能丢失有用的信息,使模型的性能下降。

以上这些方式是比较常见的,不过也有人认为,这些都是解决上下文长度问题的“技术捷径”,牺牲的是模型的性能,因为无论是稀疏注意力、滑动窗口还是降采样,都是主动丢弃不重要的数据,那么在评估不重要的数据过程中,很有可能产生误判,从而影响模型性能。

那究竟什么方法不是捷径呢?在月之暗面披露的关于Kimi如何解决上下文长度问题的技术细节中,提到了这样的方式,我们一起来看下。

模型训练方面

在传统的Tensor并⾏、Data并⾏、Pipeline并⾏基础上,增加了多项基于Seqence维度的并⾏策略,提升了并⾏效率。利⽤定制版的Flash Attention、Fuse Cross Entropy、CPU offload等技术⼤幅度降低了显存压⼒。还使⽤了创新的训练⽅法,针对性地调配了多阶段式训练⽅法,让模型保留基础能力的前提下,逐步激活⻓上下⽂的能⼒。

模型推理方面

  • ⽤GQA替换MHA:让KVCache所占⽤的显存⼤⼩⼤幅度缩⼩。
  • 2Paged attention:保证显存的充分利⽤。
  • 低⽐特量化:通过W8A8,最多可以把推理速度在上述基础上再提升⼀倍。
  • MoE & KVCache裁减:让显存占⽤在上述基础上再下降⼀倍。

这些策略看着易懂,但是实际操作过程中也会有不少问题,甚至需要一边实践一边探索。如果你对哪一条感兴趣可以在评论区留言,我们一起讨论一下。

最后,给你看一个关于超长上下文测试的很有趣的例子——大海捞针。

大海捞针

在⽂本语料中藏⼊⼀个与⽂本语料不相关的句⼦,比如在整本《西游记》⾥放⼊⼀句只会在 《红楼梦》⾥出现的话,然后看⼤模型能不能通过⾃然语⾔提问的⽅式,即Prompt,把这句话准确地提取出来。藏起来的那句话就是“针”,《西游记》就是大海。

国外有一个大模型开发者Greg Kamradt,在GPT-4 Trubo(128K)以及Claude2.1(200K)上进行过测试,效果并不好,Kimi的工程师用了相同的方法测试,经过几轮的测试,发现效果时好时坏,且有一些规律:效果好坏取决于Prompt和内容(即“大海”和“针”),而且并没有强一致的结果。

经过几轮测试,Kimi的工程师发现,除了⼤模型本⾝的⻓⽂本记忆能⼒和指令遵循能⼒,其实还有两个关键点对结果起了明显作⽤: ⼀是藏在“⼤海”中的“针”是否完全没有歧义;⼆是向⼤模型提问的Prompt写得是否⾜够明确。

我觉得这块内容还有待进一步验证,其实大模型本身就面临可解释性的问题,更别提超长上下文了,更是迷上加迷,这就和我们人类到目前为止还没有搞清楚大脑的工作原理一样。有时又觉得其实也没那么重要,只要输出是正确的就行,只要输出正确,那我们就会信任大模型,至于原理究竟是什么,现阶段还不是最重要的课题。

小结

今天这节课很有意思,也是大模型核心技术之一,目前看这块还是非常前沿的一个话题,因为已经很久没有人提过模型的参数了,ChatGPT、文心一言包括Kimi等等,已经很少提参数的事儿了,现在经常提的就是上下文长度和多模态,所以这块很有可能是大模型下一个技术突破点。

当然如果你说通义千问已经支持1000万字的上下文了,我觉得还得加个问号,到底效果怎么样,是不是通过捷径支持的,都还需要用户验证。

思考题

超长上下文会带来注意力机制计算量的增加,你可以思考一下,怎么才能算出计算量增加多少?欢迎你把思路打在评论区,我们一起探讨,如果你觉得这节课的内容对你有帮助的话,也欢迎你分享给其他朋友,我们下节课再见!

精选留言(4)
  • 张申傲 👍(5) 💬(1)

    第23讲打卡~ 我们是做AI角色扮演聊天应用的,目前就遇到了比较棘手的“大模型记忆”问题,特别是在用户和角色经历了多轮对话之后,如何让AI角色拥有媲美人类的记忆,准确地记住之前经历的事情和说过的话,目前对我们来说是一个比较大的挑战,貌似行业内也没有特别好的解决方案,大家也都在探索阶段~

    2024-07-19

  • 潇洒哥66 👍(0) 💬(1)

    token是上下文的线性函数,自注意力机制是token数量的二次方。因此,自注意力会带来上下文二次方的相关性计算

    2024-10-16

  • 石云升 👍(3) 💬(0)

    首先,我们需要了解标准自注意力机制的计算复杂度。假设我们有一个序列长度为 n 的输入,每个 token 的嵌入维度为 d。 标准自注意力机制的计算复杂度为 O(n^2 * d)。这是因为: 1.我们需要计算 n 个 token 之间的所有 n^2 个注意力分数。 2.对于每个注意力分数,我们需要进行 d 维的点积操作。 现在,让我们看看当上下文长度增加时,计算量如何变化: 1.线性增长的情况: 如果上下文长度从 n 增加到 2n,计算复杂度会变为 O((2n)^2 * d) = O(4n^2 * d)。 计算量增加:(4n^2 * d) / (n^2 * d) = 4 倍 2.平方增长的情况: 如果上下文长度从 n 增加到 n^2,计算复杂度会变为 O((n^2)^2 * d) = O(n^4 * d)。 计算量增加:(n^4 * d) / (n^2 * d) = n^2 倍 具体计算示例:假设我们有一个原始上下文长度为 1,000 tokens,嵌入维度为 512 的模型。 1.如果上下文长度增加到 2,000 tokens: - 原始计算量:1,000^2 * 512 = 512,000,000 - 新计算量:2,000^2 * 512 = 2,048,000,000 - 计算量增加了 4 倍 2.如果上下文长度增加到 10,000 tokens: - 原始计算量:1,000^2 * 512 = 512,000,000 - 新计算量:10,000^2 * 512 = 51,200,000,000 - 计算量增加了 100 倍 需要注意的是,这只是理论上的计算量增加。在实际应用中,还需考虑以下因素: 1.内存限制:随着序列长度的增加,所需的内存也会急剧增加。 2.优化技术:如稀疏注意力、滑动窗口注意力等可以降低计算复杂度。 3.硬件效率:某些长度可能更适合特定硬件的并行处理能力。 4.实际实现:某些优化可能使实际增长略低于理论值。 总的来说,计算量的增加与上下文长度的平方成正比。这就是为什么处理超长上下文时,我们需要特殊的优化技术,如稀疏注意力、局部注意力等,来降低计算复杂度。

    2024-09-08

  • 阿甘 👍(0) 💬(0)

    老师在文章中举得三个例子: >招聘场景,在系统上传 50 份简历。。智能助⼿在阅读完这 50 份简历之后,⻢上就给出来了 Top5 推荐。再比如打⻋发票整理,直接上传 50 个发票,智能助⼿可以⾃动整理你过去⼀个⽉的⾏程到底是什么样的,直接整理出来⼀个报销⽂档。⼜或者有好⼏篇英⽂论⽂,。。。 似乎都是对单次对话支持的长文本的要求,我理解的上下文应该是指 1. 对环境的感知:如编写代码的时候,自动获取整个工程的其他信息,不需要用户通过prompt告知 2. 记忆:能够记住前面的多轮对话,不需要每次prompt带上

    2025-02-22