从预训练到推理部署:大语言模型全流程技术拆解
AIAI Summary (BLUF)
这篇综述论文系统梳理了大语言模型(LLM)的训练与推理技术,涵盖数据预处理、训练架构、预训练任务、并行训练、模型微调,以及模型压缩、并行计算、内存调度和结构优化等推理部署技术。文章旨在帮助研究人员和工程师掌握LLM开发、部署和应用所需的知识,并探讨了LLM的未来发展方向。
核心洞察
这篇综述覆盖面很广,从训练到推理一条龙全包了。我觉得最有价值的部分是它对低成本训练和部署这条主线的梳理,毕竟现在不是谁都能烧几千万美元训模型的。不过综述类文章的通病是每个点都点到为止,真想动手的话还得顺着参考文献往里挖。
大语言模型(LLM)这两年的热度不用多说。ChatGPT 出来之后,大家都在琢磨怎么训练自己的模型、怎么部署得更便宜。这篇综述就是围绕这个思路展开的,从训练技术讲到推理部署,把整个流程拆开来看了一遍。
核心结论
大语言模型通常指参数量超过 60 到 100 亿参数的预训练语言模型,2022 年 11 月 OpenAI 发布 ChatGPT 是大语言模型时代的关键节点。
大语言模型的训练大致分为三步:数据收集与处理、预训练(含模型架构确定与并行训练)、微调与对齐。
CommonCrawl 是最大的公开网页爬取数据仓库,16 年间积累超过 2500 亿个网页,每月新增 30 到 50 亿个网页;GPT-3 训练时 82% 的原始 token 来自 CommonCrawl。
TransformerA deep learning neural network architecture using self-attention mechanisms for sequence processing. 架构包含编码器和解码器两大模块,其核心自注意力机制通过 query、key、value 三组向量计算词间相关性权重,多头注意力则并行运行多组注意力计算以捕捉不同类型的词语关联。
位置编码是弥补 Transformer 排列不变性的关键技术,主要分为绝对位置编码(正弦余弦函数)和相对位置编码两类,RoPE 被 PaLM、LLaMA、GLM-130B 采用,ALiBi 被 BLOOM 采用。
1 引言
语言建模是自然语言处理领域实现认知智能的一条基本路径,最近几年的进展相当快。它的核心任务是理解、生成和操作人类语言,机器翻译、对话系统、情感分析、文本摘要这些应用都离不开它。深度学习发展起来之后,早期的统计语言模型逐渐被基于神经网络的神经语言模型取代。这个转变的关键在于词嵌入的出现,把词表示成分布式向量。这些词嵌入在实际的 NLP 任务中表现一直很好,对整个领域的影响很深。预训练语言模型是神经语言模型之后的又一个阶段。早期的尝试包括 ELMo,基于双向 LSTM 架构。后来 Transformer 架构出现了,它靠并行自注意力机制,让预训练加微调这套学习范式成了主流。这类模型通常在大规模数据集上做自监督训练,现在已经是最主要的方法论了。
Transformer 架构特别适合做模型扩展。有研究分析发现,把模型规模或者训练数据量加大,性能会有明显提升。很多研究通过不断扩展预训练语言模型的规模来推高性能上限。模型变大之后会出现一个很有意思的现象,叫“涌现”。模型会表现出惊人的能力,能生成高质量文本,学习和推理能力也很强。通过上下文学习,它们甚至能处理少样本任务。这个能力让它们可以直接用到各种领域的不同下游任务上。
参数量特别大、训练数据特别多的预训练语言模型,一般就叫大语言模型。模型规模通常超过 60 到 100 亿参数。GPT 系列是大语言模型发展中的一个重要里程碑。2022 年 11 月 OpenAI 发布 ChatGPT,这是大语言模型时代的一个关键节点,也是人工智能领域的一个转折点。ChatGPT 让现有的 AI 算法达到了前所未有的效果,改变了人们使用和开发 AI 算法的方式。它的出现引起了学术界的广泛关注。但 ChatGPT 不是开源的,目前主要的使用方式是通过 OpenAI 的网站或者 API 接口访问。训练能替代 ChatGPT 的模型,或者做特定领域的大语言模型,就变得很有必要。训练和部署大语言模型需要处理大规模数据的专业能力,还需要分布式并行训练方面的实战经验。这就要求做大语言模型的研究人员得有相当强的工程能力,能应对开发过程中遇到的各种挑战。对这个方向感兴趣的研究者,要么自己有工程技能,要么得学会跟工程师高效协作。
基于以上原因,本文的主要目标是对大语言模型的训练和推理技术做一个全面梳理,让研究者具备开发、部署和应用大语言模型所需的知识。后面的内容安排是这样的:第 2 节介绍大语言模型的相关背景和基础知识。第 3 节深入讨论大语言模型的训练技术。第 4 节探讨推理和部署相关的技术。第 5 节讨论大语言模型的使用方式。第 6 节展望未来的发展方向及其影响。
2 背景知识
2.1 Transformer
Transformer 是一种基于注意力机制的深度学习模型,用来处理序列数据,能有效解决复杂的自然语言处理问题。这个模型最早在 2017 年被提出来,在机器翻译任务上取代了传统的循环神经网络架构,成为当时的最优模型。Transformer 适合并行计算,加上模型本身的复杂度,在准确率和性能上都超过了之前流行的循环神经网络。Transformer 架构主要包含两个模块,编码器和解码器,以及这些模块内部的注意力机制。
2.1.1 自注意力
自注意力结构:注意力机制的本质是从大量数据中选出少量重要信息,把焦点放在这些重要信息上,忽略大部分不重要的信息。自注意力机制作为注意力机制的一个变体,减少了对额外信息的依赖,擅长捕捉数据或特征内部的关联。在文本中应用自注意力机制,主要是计算词与词之间的相互影响,来解决长距离依赖的问题。自注意力也是 Transformer 的核心思想。键值注意力的核心公式如下:
自注意力机制让模型在预测某个词的时候,能同时衡量句子里其他词的重要性。具体做法是对所有词的 value 做加权求和,权重由每个词和目标词的相关性决定。
整个自注意力分三步走:先算出 query、key、value 三组向量。query 代表当前正在关注的词,key 代表句子里所有词,value 存的是每个词携带的信息。然后把 query 和 key 做点积,过一个 softmax 得到一组权重分布,这就是注意力权重。
多头注意力 [6] 就是把上面这套操作并行跑好几遍。每个注意力头学到的东西不一样,有的关注局部搭配,有的盯着长距离依赖。各头的输出拼在一起,再做一次线性变换,得到最终表示。这样模型既能看清眼前的词间关系,也能照顾到远处上下文。并行计算也让模型更容易捕捉复杂的词语关联。公式如下:
MultiHeadAttention(Q,K,V)=Concat[head_1,…,head_h]W^o (2)
其中 head_i=Attention(QW_i^Q,KW_i^K,VW_i^V)
这里的 Concat 就是把每个头的注意力计算结果拼起来,W^o 是输出层的权重矩阵,用来对拼接后的结果做线性变换。这样整个多头注意力的输出就出来了。多头注意力在不同线性变换下并行计算注意力,再拼接、再变换,模型对输入序列的表达能力因此强了不少。Transformer 里这套机制很关键,处理长距离依赖、提升模型表现都靠它。
2.1.2 编码器
Transformer 的编码器模块 [6] 由多个结构相同的层堆叠而成,每一层里有一个多头注意力机制和一个前馈神经网络 [31]。多头注意力负责让输入序列中每个位置和其他位置做注意力计算,把不同位置之间的依赖关系抓出来。前馈网络接着对注意力输出做进一步处理和特征提取。多层堆叠下来,编码器逐步提取输入序列的特征,最后把编码结果交给解码器去解码。这种设计让编码器能有效处理输入序列里的长距离依赖,在各种 NLP 任务上表现提升明显。
2.1.3 解码器
解码器模块 [32] 同样是多个相同层堆叠起来的,每层也有多头注意力和前馈网络。和编码器不同的是,解码器多了一个编码器-解码器注意力机制,用来在解码过程中对输入序列做注意力计算。每个位置上,解码器只能和它前面的位置做自注意力,保证生成的序列不违反语法规则。掩码在这里面起了大作用,确保生成输出序列时只关注当前时间步之前的信息,不会把未来时间步的信息泄露进来。具体来说,解码器的自注意力用掩码挡住未来信息,让模型在每一步生成预测时保持因果性。模型生成的输出只依赖当前和之前的信息,不受未来信息影响。
2.1.4 位置编码
位置和顺序对某些任务来说非常关键,比如理解一个句子或者一段视频。句子的语法由位置和顺序决定,它们也是句子语义不可分割的一部分。Transformer 用多头自注意力机制避开了 RNN 的递归方式,训练速度因此快了不少。它还能捕捉句子中的长距离依赖,处理更长的输入。但问题来了:当句子里的每个 token 经过 Transformer 的编码器/解码器堆叠时,模型本身对这些 token 没有任何位置或顺序的概念,也就是所谓的排列不变性。所以还得想个办法,把 token 的顺序信息塞进模型里。
要让模型感知输入序列,可以给每个 token 在句子中的位置加上位置信息,这项技术就叫位置嵌入。Transformer 没有循环连接,天然缺少 RNN 那种对 token 顺序的感知。位置嵌入的做法是给输入序列中每个 token 位置分配一个独一无二的向量。这些位置嵌入会在送入模型之前加到词嵌入上。有了位置信息,模型就能根据 token 在序列中的位置把它们区分开。Transformer 中位置嵌入的核心公式可以写成:
公式(3):PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
公式(4):PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
其中,PE 是位置嵌入矩阵,pos 是 token 在句子中的位置,i 是位置嵌入的维度索引,d_model 是 Transformer 模型的隐藏层维度。这个公式用正弦和余弦函数,对位置 pos 和维度 i 做不同的计算,为每个位置和维度生成唯一的位置嵌入值。这样一来,每个 token 都拿到了一个独特的位置嵌入向量,模型也就能感知到句子中 token 的顺序信息了。实际用的时候,位置嵌入矩阵会加到输入的词嵌入矩阵上,把位置信息和语义信息合在一起,给 Transformer 提供更完整的输入表示。
Transformer 里常用的位置编码方法有两种:绝对位置编码和相对位置编码。
(1)绝对位置编码:用正弦和余弦函数为每个位置和维度生成唯一的位置嵌入值。上面那个公式就是干这个的,算出来的位置嵌入值直接加到词嵌入上。绝对位置编码给每个位置一个独一无二的编码,模型因此能感知到句子中单词的顺序信息。
(2)相对位置编码:这是一种基于相对位置关系的编码方式。它通过计算单词之间的相对距离来表示位置信息。Transformer-XL 等模型用的就是这种方法,处理长序列时,相对位置编码能更好地捕捉单词之间的相对位置关系。这两种位置编码方法都是想给 Transformer 模型提供输入序列中单词的位置信息,让模型能更好地理解和处理序列数据。具体选哪种,得看应用场景和模型设计。
还有一些位置编码方法用在了其他模型上,比如 RoPE 和 ALiBi。
RoPE 用绝对位置编码的方式来表示相对位置编码,PaLM、LLaMA、GLM-130B 这些大语言模型的设计里都用了它。
ALiBi 不往词嵌入上加位置嵌入,而是根据 token 之间的距离,在注意力分数上加一个预定义的偏置矩阵。BLOOM 等大语言模型的设计里用了这个方法。
另外还有一些位置编码方法,比如混合位置编码、多位数位置编码、隐式位置编码,也被一些模型采用。
2.2 提示学习
提示学习是一种被广泛采用的机器学习方法,在自然语言处理领域尤其常见。它的核心思路是通过精心设计提示语句,引导模型产生特定的行为或输出。人们常用它来微调和引导预训练大语言模型,让模型执行特定任务或生成想要的结果。研究者发现,设计特定的提示语句可以引导预训练模型完成各种任务,比如问答、文本生成、语义理解。这种方法的好处在于,只需要简单修改提示语句就能适应不同任务,不用重新训练整个模型。对于 GPT 系列这样的大语言模型和其他预训练模型来说,提示学习提供了一种直接且强大的模型微调手段。只要给出合适的提示,研究者和从业者就能定制模型的行为,让它更适合特定领域或任务需求。简单说,提示学习是一种建立在预训练语言模型之上的机器学习方法,通过设计提示语句引导模型执行各种任务,给模型应用的定制化带来了更多灵活性。本节将介绍提示学习的基础知识。
2.2.1 背景与概述
2.2.2 Prompt learning 的基本组成与流程
传统的预训练加微调范式里,预训练阶段和下游任务之间是割裂的。Prompt learning 换了个思路,让下游任务的输出格式和预训练任务的目标格式保持一致,也就是把下游任务“改造”成语言模型预训练时见过的那种形式。具体做法是构造一个 prompt,把原始任务变成类似完形填空或文本续写的形式。这样一来,一个语言模型就能通过不同的 prompt 解决各种下游任务,不用每个任务都单独适配。
Prompt learning 的核心组件有三个:prompt 模板、答案映射和预训练语言模型。模板是 prompt 的主体部分,常见的有两种类型:完形填空式和前缀生成式。完形填空式是在文本中选一个或多个位置,用 [MASK] 标记替换,让模型去填对应的词;前缀生成式则是在句子前面加一段特定前缀,引导模型生成合适的文本。答案映射负责把所有可能的答案按概率分布排序,选出概率最高的作为预测输出,再把它转换成对应的类别标签。这个映射过程通常是把标签转成自然语言词汇,也就是所谓的 Verbalizer。
Prompt learning 的工作流程大致分四步:
(1)用预训练语言模型作为基础编码器
(2)在输入中加上带有 [MASK] 位置的额外上下文,也就是模板
(3)把标签映射到标签词,即 verbalizer
(4)弥合预训练和微调之间的差距
模板和答案空间确定之后,接下来要选一个合适的预训练语言模型。现在可选的预训练模型很多,性能也都不错。选的时候一般看它的范式,比如自回归、掩码语言建模、编码器-解码器等等。举个例子,如果是摘要任务,选 BART 这种双向自回归 Transformer 会更合适。
模板的选择对 prompt learning 的效果影响很大。按是否人工指定来分,模板可以分成人工构造和自动搜索两类。人工构造的模板最直观,好理解,实际用起来效果也不错。但它有短板:设计模板需要先验知识,而且有时候会失败。自动生成的模板有两种:离散 prompt 和连续 prompt。离散 prompt 让模型在一组离散的模板空间里选最优的,连续 prompt 则让语言模型自己训练出一个 prompt。有研究表明,用多个模板能提升模型表现。最简单的多模板聚合方式就是把各个模板的输出取平均或加权平均。
Verbalizer 是标签到标签词的映射过程,选得好不好对 prompt learning 也很关键。构造 verbalizer 有两种方式:人工定义和自动搜索。人工定义需要专业知识,主观性强,覆盖面也有限。针对这些问题,有几种解决思路:(1)靠人的先验知识手动设计;(2)从一个初始标签词出发,做释义和扩展;(3)从内部标签词出发,借助外部知识扩展;(4)用多个 token 分解标签;(5)用虚拟 token 并优化标签嵌入。另外,还可以利用外部知识库来扩展和改进标签词,从而在文本分类上取得更好的结果。
2.2.3 学习策略
Prompt learning 这个新范式出现后,训练过程也跟着变了。目前的学习策略主要有这么几种:(1)预训练后微调,就是传统的预训练加微调方式;(2)免调优 prompt,直接靠设计好的 prompt 让语言模型给出答案;(3)固定语言模型、调 prompt,用下游任务的训练数据更新 prompt 相关参数;(4)固定 prompt、调语言模型,prompt 参数不动,微调语言模型本身的参数;(5)prompt 和语言模型一起调,两边的参数都更新。
这些策略各有各的适用场景。预训练加微调是最常见的,大多数任务都能用。免调优 prompt 适合简单任务,能省下大量训练时间和算力。固定语言模型调 prompt 和固定 prompt 调语言模型适合需要更精细控制的任务,通过调整 prompt 参数或语言模型参数来优化表现。两者一起调则结合了双方的优势,能进一步提升模型性能。
Prompt learning 提供了一种新的训练范式,通过合理的 prompt 设计和学习策略,可以在各种下游任务上优化模型表现。选对模板、构造有效的 verbalizer、采用合适的学习策略,这些都是提升 prompt learning 效果的关键因素。
3 大语言模型的训练
大语言模型的训练大致可以分成三步。第一步是数据收集和处理。第二步是预训练,包括确定模型架构和预训练任务,然后用合适的并行训练算法完成训练。第三步是微调和对齐。这一节会概览模型训练相关的技术,包括训练数据集、数据准备和预处理、模型架构、具体训练方法、模型评估,以及常用的大语言模型训练框架。
3.1 数据准备与预处理
3.1.1 数据集
训练大模型需要海量文本数据,数据质量直接影响模型表现。预训练阶段用大规模语料库,让模型先掌握语言的基本规律和一定的生成能力。整个训练流程的第一步,就是收集足够多的自然语言文本。
预训练数据的来源很杂,常见的有网页文本、对话数据和书籍,这些属于通用语料。除此之外,一些研究还会加入专业领域的数据,比如代码或科学文献,来提升模型在这些方向上的能力。用多种来源的文本训练,模型的泛化能力会明显更好。下面按类别介绍常用的训练数据集,具体信息见表1。这些语料库分成5组来讨论。
表1:常用语料库信息
| 语料库 | 类型 | 链接 |
|---|---|---|
| BookCorpus [65] | 书籍 | https://github.com/soskek/bookcorpus |
| Gutenberg [66] | 书籍 | https://www.gutenberg.org/ |
| Books1 [8] | 书籍 | 尚未开源 |
| Books2 [8] | 书籍 | 尚未开源 |
| CommonCrawl [67] | CommonCrawl | https://commoncrawl.org/ |
| C4 [68] | CommonCrawl | https://www.tensorflow.org/datasets/catalog/c4 |
| CC-Stories [69] | CommonCrawl | 尚未开源 |
| CC-News [70] | CommonCrawl | https://commoncrawl.org/blog/news-dataset-available |
| RealNews [71] | CommonCrawl | https://github.com/rowanz/grover/tree/master/realnews |
| RefinedWeb [72] | CommonCrawl | https://huggingface.co/datasets/tiiuae/falcon-refinedweb |
| WebText | Reddit链接 | 尚未开源 |
| OpenWebText [73] | Reddit链接 | https://skylion007.github.io/OpenWebTextCorpus/ |
| PushShift.io [74] | Reddit链接 | https://pushshift.io/ |
| Wikipedia [75] | 维基百科 | https://dumps.wikimedia.org/zhwiki/latest/ |
| BigQuery [76] | 代码 | https://cloud.google.com/bigquery |
| CodeParrot | 代码 | https://huggingface.co/codeparrot |
| the Pile [77] | 其他 | https://github.com/EleutherAI/the-pile |
| ROOTS [78] | 其他 | https://huggingface.co/bigscience-data |
书籍: 训练大模型最常用的两个书籍数据集是 BookCorpus [65] 和 Gutenberg [66]。它们涵盖的文学类型很广,包括小说、散文、诗歌、历史、科学、哲学等等。很多大模型都用过这两个数据集 [9, 79],让模型接触到不同文体和主题的文本,对语言的理解会更全面。
CommonCrawl: CommonCrawl [67] 维护了一个公开的网页爬取数据仓库,个人和组织都可以免费使用。这个仓库的数据量很大,16年间积累了超过2500亿个网页。它成立于2007年,如今在学术界被广泛引用,相关论文超过10000篇。这个语料库还在持续增长,每个月新增30到50亿个网页。在自然语言处理领域,它是很多大模型的主要训练语料。GPT-3 [8] 训练时用的原始token有82%来自CommonCrawl。不过网页存档里低质量数据不少,用之前必须做预处理。目前基于CommonCrawl的常用过滤数据集有四个:C4 [68]、CC-Stories [69]、CC-News [70] 和 RealNews [71]。
Reddit链接: Reddit是一个社交媒体平台,用户可以提交链接和帖子,其他人通过“顶”或“踩”来投票。这个机制让它成了构建高质量数据集的好来源。
维基百科: 维基百科 [75] 是一个免费开放的在线百科全书项目,收录了大量高质量的百科内容,覆盖各种主题。英文版维基百科被很多大模型用于训练 [8, 9, 80],在语言理解和生成任务中很有价值。维基百科还有多种语言版本,可以用来训练多语言环境下的模型。
代码: 目前公开可用的代码数据集比较少。现有的做法主要是从互联网上爬取开源许可的代码,主要来源是Github和Stack Overflow。
我们还整理了不同大模型各自使用的数据集。
训练过程中,大模型通常会在多个数据集上训练,表2列出了几个代表性模型用的数据。
表2:不同大模型使用的数据集
| 模型 | 数据集 |
|---|---|
| GPT-3 | CommonCrawl, WebText2, Books1, Books2, Wikipedia |
| LLaMA | CommonCrawl, C4, Wikipedia, Github, Books, Arxiv, StackExchange |
| PaLM | 社交媒体、网页、书籍、Github、Wikipedia、新闻(共7800亿token) |
| T5 | C4, WebText, Wikipedia, RealNews |
| CodeGen | the Pile, BIGQUERY, BIGPYTHON |
| CodeGeeX | CodeParrot, the Pile, Github |
| GLM | BooksCorpus, Wikipedia |
| BLOOM | ROOTS |
| OPT | BookCorpus, CCNews, CC-Stories, the Pile, Pushshift.io |
3.1.2 数据预处理
数据收集够了,下一步就是预处理。预处理做得好不好,直接影响模型的表现和安全性。具体要做的事情包括:过滤低质量文本,把有毒的和有偏见的内容去掉,让模型符合人类的伦理标准;去重,删掉训练集里的重复数据,同时排除测试集里的冗余内容,保持样本分布均衡;隐私清洗,防止信息泄露或者其他隐私问题。另外,如果你打算做微调,还得考虑扩展词表。
LLaMA 2是个例外。它在预训练阶段没有做过滤,因为过滤太激进可能会误伤某些人群的数据。这样做的好处是基座模型的泛化能力更强,在仇恨言论检测、隐私去标识化这些下游任务上表现更好。有观察发现,预训练数据不做额外过滤,基座模型反而能用更少的样本达到合理的安全对齐效果。不过这不代表可以省掉安全措施,公开部署之前还是得做额外的安全缓解,3.5.4节会详细讨论。
质量过滤。 过滤低质量数据一般用两种方法:基于启发式规则的和基于分类器的。启发式方法就是手动定规则,比如只保留包含数字的文本,丢掉全是大写字母的句子,删掉符号和单词比例超过0.1的文件,等等。分类器方法则是在WebText这类高质量数据集上训练一个分类器,用它来筛掉低质量数据。
去重。 语言模型有时候会重复生成同样的内容,可能是因为训练数据里重复度太高。大量重复会导致训练不稳定,模型性能下降。另外还要注意避免数据污染,把训练集和测试集里重复的部分去掉。
隐私清洗。 大模型在各种数据集上训练,可能涉及隐私问题,有泄露信息的风险。预处理阶段就得处理这个问题,系统地删除敏感信息。具体手段包括匿名化、遮盖、token化,把个人身份信息、地理位置和其他机密数据去掉。这样既能保护隐私,又能避免无意中泄露私人信息。数据效用和隐私保护之间需要找平衡,让语言数据集的使用更负责任。
过滤有毒和有偏见的内容。 这一步也很关键,目的是让模型更公平、更少偏见。具体做法包括情感分析、仇恨言论检测、偏见识别算法等。用这些工具可以系统地识别并过滤掉那些传播有害刻板印象、冒犯性语言或者偏见观点的文本。
3.2 模型架构
目前所有大模型都建立在Transformer架构之上,这样才能扩展到几百亿甚至上万亿参数。预训练语言模型的架构一般分三类:Encoder-only、Encoder-decoder和Decoder-only。Encoder-only在最新的大模型里已经不用了,这里不展开。下面主要介绍Encoder-decoder和Decoder-only。
图1:从左到右分别是Encoder-decoder架构、Causal Decoder架构、Prefix Decoder架构,以及它们对应的mask配置。这张图展示了每个输入token能关注到的token范围。
3.2.1 Encoder-decoder架构
Encoder-decoder架构沿用了传统Transformer的Encoder-decoder结构,由编码器和解码器两部分组成。编码器由多层Transformer多头自注意力层堆叠而成,负责编码输入序列。解码器则通过交叉注意力机制关注编码器的输出表示,以自回归方式生成目标序列。T5、flan-T5和BART这些知名模型用的就是这种架构。
3.2.2 Decoder-only架构
只用了 Transformer 解码器那一半的,就是 Decoder-only 架构。编码器-解码器架构里编码器和解码器都有,Decoder-only 则只关注解码过程。模型一个接一个地生成 token,每一步都只回头看它前面的那些 token。这种架构在文本生成这类任务上表现很好,不需要单独的编码阶段。Decoder-only 还能再往下分两类:Causal Decoder 和 Prefix Decoder。
Causal Decoder 架构里,输入序列中的每个 token 在解码时只能看到它前面的 token 和它自己。它靠一个特定的掩码矩阵来实现这种单向注意力,具体长什么样可以看图 1。不同架构之间的差别,主要就是掩码矩阵配置不同。图 1 对比了编码器-解码器和 Decoder-only(包括 Causal Decoder 和 Prefix Decoder)的掩码配置。Causal Decoder 的代表模型是 GPT 系列。GPT 系列目前公认性能最强,它底层的 Causal Decoder 架构也被 BLOOM、OPT、Gopher、LLaMA 这些模型广泛采用。
Prefix Decoder 架构把编码器-解码器和 Causal Decoder 的优点揉到了一起。它用一套独特的掩码配置(还是看图 1),让前缀部分的 token 可以做双向注意力,生成后续 token 时则保持单向注意力。这样一来,输出序列既能自回归生成,又能灵活地对前缀 token 做双向关注。用 Prefix Decoder 的代表模型有 PaLM 和 GLM。
3.3 预训练任务
大模型通常靠预训练来学到丰富的语言表示。预训练时,模型吃进大量语料,比如互联网上的文本数据,用自监督学习的方式训练。语言建模是其中最常见的一种自监督任务,让模型去预测给定上下文中的下一个词。通过这个任务,模型学会了词汇、语法、语义和文本结构相关的信息。
语言建模要求模型预测给定上下文中的下一个词。这个任务让模型对语言形成细致的理解。模型观察大量文本数据,试着预测每个位置的下一个词。这个逐步学习的过程让模型捕捉到语言中的模式和信息,把大量语言知识编码进参数里。预训练完成后,这些参数可以针对各种自然语言处理任务做微调,适应具体需求。语言建模的目标是训练模型最大化文本数据的似然。给定文本序列 w₁, w₂, …, w_T,其中 w_t 是位置 t 上的 token,P(w_t|w₁, w₂, …, w_{t-1}) 是在前文 w₁, w₂, …, w_{t-1} 条件下预测 w_t 的概率,语言建模的目标函数可以用交叉熵损失表示。这里我们把目标定义为最大化给定文本序列的条件概率:
L_LM = (1/T) Σ_{t=1}^{T} -logP(w_t|w₁, w₂, …, w_{t-1}) (5)
语言建模是大多数大模型最常用的预训练目标。除了它之外,语言建模领域还有别的预训练任务。比如有些模型把文本中某些部分随机替换掉,然后用自回归的方式恢复被替换的 token。主要训练方式就是自回归地恢复被替换的区间。
3.4 模型训练
3.4.1 并行训练
下面聊并行训练时会涉及集合通信,搞清楚这些能帮我们更好地理解并行训练的原理。图 2 列出了五种归约关系。1)Broadcast:把一个 GPU 的数据发给其他 GPU。2)Reduce:把所有 GPU 的数据归约(求和/平均),发给一个 GPU。3)All Reduce:把所有 GPU 的数据归约,发给所有 GPU。4)Reduce Scatter:把所有 GPU 的数据归约,分块发给所有 GPU。5)All Gather:收集所有 GPU 的数据,发给所有 GPU。
图 2:并行训练方法用到的五种集合通信。
数据并行:数据并行的流程如图 3 所示。有一个参数服务器,存着模型参数和整批数据。每个 GPU 用 broadcast 同步模型参数,数据分成若干份,每个 GPU 拿一份。每个 GPU 用完整的模型参数和自己那份数据做前向和反向传播,得到各自的梯度。最后把梯度聚合起来发回参数服务器,那里有原始模型参数和聚合后的完整梯度。有了这些信息,就能用优化器更新模型参数。更新后的参数进入下一轮训练迭代。
分布式数据并行[95]放弃了参数服务器的做法,改用 all-reduce 对梯度信息做聚合,保证每块 GPU 拿到完全相同的梯度。all-reduce 的结果会广播给所有 GPU,各卡独立更新自己那份模型优化器。每轮更新结束后,模型参数、梯度、优化器的历史信息在所有 GPU 上保持一致。
中间结果占用的显存跟 batch size、句子长度、模型维度都有关系。用数据并行时,一批数据被切成很多份,每块 GPU 处理其中一部分。换句话说,每块 GPU 上的 batch size 降到了原来的 GPU 数量分之一。数据并行缩小了输入维度,模型中间结果的总量也跟着减少。但有个问题:要撑起模型训练,每块 GPU 至少得拿到一条数据。最极端的情况是每块 GPU 只分到一条数据,而参数、梯度、优化器仍然要完整地存在 GPU 上。这时候就算中间结果一个都不存,模型也未必能在一块 GPU 上跑起来。
模型并行:模型并行[96]最早由 Megatron-LM 提出,用来缓解显存压力。从图 4 能看清模型并行的整体架构。拿 Transformer 里最常见的线性层举例,线性层的参数是一个 A*B 的矩阵,输入是 B*1 的向量。写成 = ,利用矩阵乘法的性质,可以把模型参数按行切成很多段,每段大小是 A 除以 n 再乘以 B。把 提进括号里,最终线性层的结果就是很多小矩阵跟线性层参数相乘得到的。这样一来,线性层的参数就能分散到多块 GPU 上。但有一点很关键:多块 GPU 上模型的输入必须完全一样。这里不是用数据并行去切分数据,而是要保证每块 GPU 拿到的输入相同,也就是属于同一批数据。然后把线性层这样的参数切到各块 GPU 上,每块 GPU 只拿到矩阵的一小部分。用这一小部分跟数据做模型计算,得到一个子结果,如公式 5 所示。这些计算结果需要用 all-gather 算子拼接起来,再通信给所有 GPU。
| (6) | ||||
ZeRO:ZeRO[97] 是搭在数据并行上的一个框架。每块 GPU 在更新参数时用的是同一套参数,计算上有冗余。每块 GPU 用 reduce-scatter 消掉这份冗余,各自拿到一部分梯度结果。每块 GPU 更新完自己负责的那部分模型参数后,做一次 all-gather 把参数同步到所有 GPU。all-gather 做完,原来的梯度就不用再留在显卡上,可以直接删掉。图 5 展示了 ZeRO 的更新过程。ZeRO1 在反向传播之后才删掉原始梯度,ZeRO2 则在反向传播过程中提前算出梯度乘以某值的结果,显卡上只存这个结果,把梯度删掉。这样删除梯度的时机提前了,显存空间进一步省下来。ZeRO3 对模型参数做了更细的切分。每块显卡只保留一部分梯度用于更新,参数更新也只影响一部分模型参数。所以每块显卡只需要存自己负责那部分参数相关的参数、梯度、优化器。前向和反向传播过程中各需要做一次 all-gather,操作完成后模型参数从显卡上释放。ZeRO3 在参数更新时不用 all-gather,但前向和反向传播时都要做 all-gather,多了一次通信。跟 ZeRO2 比,ZeRO3 是用时间换空间的算法。
常见问题(FAQ)
llms.txt 和 Cloudflare 有什么关系?
llms.txt 是用于指导大语言模型训练与推理的文本规范,而 Cloudflare 作为云服务商,可提供分布式计算和存储支持,帮助高效部署相关模型。
如何用 Cloudflare 部署大语言模型推理?
可借助 Cloudflare 的 Workers 和 R2 等服务,结合模型压缩与内存调度技术,实现低成本推理部署,具体可参考综述中推理优化章节。
llms.txt 在模型训练中起什么作用?
llms.txt 可能指训练数据预处理中的文本格式或配置,用于规范数据输入,提升训练效率,类似综述中提到的数据预处理步骤。
版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。
文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。
若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。



