零、前言
📌本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
📕欢迎访问:
Github主页:github.com/Conqueror71...
注意,本文不涉及太多复杂的公式与数学推导,初学者或者像笔者一样数学不好的读者可以放心阅读!
Github链接:github.com/baichuan-in...
一、30秒读论文
TL;DR爱好者专属
- LLM领域近年来取得了显著进展,规模↑ 使得能力↑
- 大多数效果好的LLM仍然是闭源的,限制了进一步研究
- 开源 LLM的出现加速了研究和进展,如LLaMA、OPT、Bloom、MPT和Falcon等
- 大多数开源LLM主要关注英语,阻碍了其他语言的发展和应用
- 本文介绍了百川2系列多语言LLM,包括百川2-7B和百川2-13B,拥有大规模的参数和训练数据
- 百川2在数学、代码、医学和法律等领域表现出色,在基准测试中取得了显著的改进和优势
我们可以直接在魔搭社区玩一玩,虽然可能在线的版本比较慢,需要排队:modelscope.cn/studios/bai...
感兴趣的读者可以自行部署!
二、本文工作简述
2.1 肯定目前工作
LLM领域近年来取得了令人瞩目的进展,语言模型的规模从数百万个参数增长到数十亿甚至数万亿个参数,模型规模的增加显著提升了语言模型的能力,使其具备更接近人类的流畅度,并能够执行各种自然语言任务。
比如OpenAI推出的ChatGPT在生成类似人类文本方面展示出了强大的语言能力,在从日常对话到解释复杂概念等各个领域都表现出色,这一突破凸显了LLM在自然语言生成和理解方面自动化任务的潜力。
2.2 指出目前问题
不过即便如此,大多数领先的LLM仍然是闭源的,开发人员和研究人员对完整的模型参数的访问受到限制,这使得社区难以对这些系统进行深入研究或微调。
在这个快速发展的领域中,LLM的更加开放和透明会加速研究和发展。开源的模型典范就是LLaMA是Meta开发的一系列拥有高达650亿个参数的LLM。LLaMA的开放性以及其他开源LLM(如OPT、Bloom、MPT和Falcon)使研究人员可以自由地访问这些模型进行研究、实验和进一步开发。这种透明度和获取权使LLaMA与其他专有的LLM区别开来。通过提供完全的访问权限,开源LLM加速了该领域的研究和进展,从而产生了像Alpaca、Vicuna和其他模型一样的新模型。
2.3 进一步深入问题
然而,大多数开源LLM主要关心英语。比如LLaMA的主要数据来源是经典的Common Crawl,其中67%的预训练数据是英语内容。其他开源LLM也主要面向英语,并且在其他语言方面的能力有限。这阻碍了在特定语言中开发和应用LLM的发展,尤其是中文这种与西方语系完全不同的语言。
2.4 百川2简述
百川2有两个独立的模型,百川2-7B包含70亿个参数,百川2-13B包含130亿个参数。这两个模型共训练了3.6万亿个token,据了解,这是迄今为止最大的训练数据量,是百川1的两倍以上。
由于训练数据的大量增加,百川2在MMLU、CMMLU和C-Eval等基准测试上相对于百川1取得了显著的改进。百川2专注于提高数学和代码问题的性能。在GSM8K和HumanEval等评估中,百川2的结果几乎是百川1的两倍。
此外,百川2在医学和法律领域的任务上也表现出色。在MedQA和JEC-QA等基准测试中,百川2的性能超过了其他开源模型,使其成为领域特定优化的LLM是一种使用大量参数进行训练的自然语言处理模型,其目标是模拟人类语言能力和理解能力。
三、预训练阶段解析
在深入介绍模型细节之前,我们可以先在下表1中看看百川2与其他开源或闭源模型的整体性能比较:
以下是对这些任务的简要说明:
- C-Eval:是评估LLM生成能力的任务,通过给定上下文和一个待补全的句子,模型需要生成一个合适的补全句子。
- MMLU:是用于评估LLM生成能力的指标,它测量模型生成文本的平均对数似然。
- CMMLU:是一个条件MMLU指标,它考虑了模型在给定上下文的情况下生成文本的平均对数似然。
- Gaokao:太经典了,儿童邪典。
- AGIEval:评估LLM生成答案质量的任务,模型需要根据给定的问题生成准确和合理的答案。
- BBH:评估LLM在机器翻译任务中的性能的指标,衡量模型生成的翻译结果与参考翻译之间的编辑距离。
- GSM8K:衡量LLM在自动生成代码任务中性能的基准测试,模型需要生成符合给定规范的代码。
- HumanEval:是用于评估LLM生成文本质量的任务,通过将模型生成的文本与人类生成的文本进行比较,来判断模型的表现。
3.1 预训练数据
数据获取:在数据获取过程中,作者的目标是追求全面的数据可扩展性和代表性,所以作者从各种不同的来源收集数据,包括通用互联网网页、图书、研究论文、代码库等,以构建一个广泛的世界知识系统。训练语料库的组成如图1所示:
数据处理:在数据处理方面,作者注重数据的频率和质量。数据频率依赖于聚类和去重操作,所以作者构建了一个大规模的去重和聚类系统,支持LSH-like特征和密集嵌入特征。该系统能够在几小时内对万亿级别的数据进行聚类和去重。基于聚类,个别文档、段落和句子被去重并评分。这些分数随后用于预训练中的数据采样。在数据处理的不同阶段,训练数据的规模如图2所示:
3.2 基础架构
百川2的模型架构基于流行的Transformer进行修改,其中的Tokenizer需要平衡两个关键因素:高压缩率 以实现高效的推理,以及适当大小的词汇表以确保每个词嵌入的充分训练。作者考虑到了这两个方面,将词汇表大小从百川1的64000扩展到125696,旨在在计算效率和模型性能之间取得平衡。
作者使用来自SentencePiece的字节对编码对数据进行分词。具体而言就是不对输入文本进行任何归一化处理,也不像百川1那样添加虚拟前缀,而是将数字拆分为单个数字以更好地编码数字数据。
为了处理包含额外空格的代码数据,作者向Tokenizer添加了仅包含空格的标记。字符覆盖率设置为0.9999,罕见字符回退到UTF-8字节。将最大标记长度设置为32,以适应较长的中文短语。百川2Tokenizer的训练数据来自百川2的预训练语料库,其中包含更多的代码示例和学术论文以提高覆盖率。下表2显示了百川2的Tokenizer与其他Tokenizer的详细比较:
3.3 激活函数
百川2使用SwiGLU激活函数 ,它是GLU的一种开关激活变体,表现出改进的结果。然而,SwiGLU具有双线性层,包含三个参数矩阵,与传统Transformer的前馈层的两个矩阵不同,因此作者将隐藏大小从隐藏大小的4倍减小到8/3倍隐藏大小,并四舍五入为128的倍数。
对于百川2的注意力层,作者采用了xFormers2实现的高效内存注意力。通过利用xFormers优化的注意力和具有偏置能力的能力,可以在减少内存开销的同时有效地合并ALiBi的基于偏置的位置编码。这为百川2的大规模训练提供了性能和效率上的优势。
3.5 优化设计
百川2在训练中使用了AdamW优化 。其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> β 1 β1 </math>β1和 <math xmlns="http://www.w3.org/1998/Math/MathML"> β 2 β2 </math>β2分别设置为0.9和0.95。使用权重衰减为0.1,并将梯度范数剪裁为0.5。模型在进行2000个线性缩放步骤的预热后,达到最大学习速率,然后应用余弦衰减到最小学习速率。
整个模型使用BFloat16混合精度进行训练。与Float16相比,BFloat16具有更好的动态范围,使其在训练LLM时更加稳健。然而,BFloat16的低精度在某些情况下会引起问题。例如,在某些公共的RoPE和ALiBi实现中,当整数超过256时,torch.arange
操作会因冲突而失败,从而阻止了附近位置的区分。因此,对一些值敏感的操作使用完全精度。
- NormHead :为了稳定训练并改善模型性能,百川2对输出Embedding进行归一化。NormHead在本文的实验中有两个优点。首先,在初步实验中,作者发现头部的范数容易不稳定。稀有标记的嵌入范数在训练过程中变小,扰乱了训练动态。NormHead可以显著稳定动态。其次,作者发现语义信息主要由嵌入的余弦相似性而不是 <math xmlns="http://www.w3.org/1998/Math/MathML"> L 2 L2 </math>L2距离编码。由于当前的线性分类器通过点积计算logits,其中混合了 <math xmlns="http://www.w3.org/1998/Math/MathML"> L 2 L2 </math>L2距离和余弦相似度。NormHead减轻了计算logits时 <math xmlns="http://www.w3.org/1998/Math/MathML"> L 2 L2 </math>L2距离的干扰。
- Max-z损失 :在训练过程中,作者发现语言模型的logits可能变得非常大。虽然softmax函数对于绝对logit值是不可知的,因为它仅依赖于它们的相对值。但是,大的logits在推理过程中会引起问题,因为常见的重复惩罚实现直接将一个标量应用于logits。以这种方式收缩非常大的logits可以显著改变softmax后的概率,使模型对重复惩罚超参数的选择敏感。受NormSoftmax和PaLM中辅助 <math xmlns="http://www.w3.org/1998/Math/MathML"> z − l o s s z-loss </math>z−loss的启发,作者添加了一个 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a x − z max-z </math>max−z损失来归一化logits: <math xmlns="http://www.w3.org/1998/Math/MathML"> L m a x − z = 2 e − 4 ∗ z 2 L_{max-z}=2e^{-4}*z^2 </math>Lmax−z=2e−4∗z2,其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> z z </math>z是最大的logit值。这有助于稳定训练,并使推理更加鲁棒,对超参数更加稳定。
Baichuan 2-7B和Baichuan 2-13B的最终训练损失如图3所示:
3.6 规模设计
首先我们来了解一下神经网络规模定律,它指的是:
误差随着训练集大小、模型大小或两者的幂函数下降,这使得在深度学习和LLM中,即使训练变得越来越昂贵,也能获得令人满意的性能。
在训练数十亿参数的LLM之前,作者首先训练了一些小型模型,并拟合了训练更大模型的规模定律。作者使用从10M到3B的一系列模型尺寸,相当于最终模型尺寸的1/1000到1/10,每个模型都使用了从百川2获取的相同数据集,并使用一致的超参数进行了长达1万亿个标记的训练。根据不同模型的最终损失,可以得到从训练flops到目标损失的映射。
并且,为了拟合模型的规模定律,作者采用了Henighan等人提出的公式: <math xmlns="http://www.w3.org/1998/Math/MathML"> L C = a ∗ C b + L ∞ L_C=a*C^b+L_∞ </math>LC=a∗Cb+L∞,其中 <math xmlns="http://www.w3.org/1998/Math/MathML"> L ∞ L_∞ </math>L∞是不可减小的损失,第一项是可减小的损失,被表示为幂律缩放项 。 <math xmlns="http://www.w3.org/1998/Math/MathML"> C C </math>C是训练flops, <math xmlns="http://www.w3.org/1998/Math/MathML"> L C L_C </math>LC是该flops下模型的最终损失。
作者使用SciPy库中的curve_fit
函数来拟合参数。拟合后的规模定律曲线和预测的70亿和130亿参数模型的最终损失如图4所示。我们可以看到,拟合的规模定律高度准确地预测了百川2的最终损失:
3.7 基础设施
我们都知道,高效地利用现有的GPU资源在训练和开发LLM中起着至关重要的作用。为了实现这一目标,作者采用了协同设计方法,包括弹性训练框架和智能集群调度策略。
一般来说,GPU被多个用户和任务共享,每个任务的具体行为是不可预测的,往往会导致集群中存在空闲的GPU节点。考虑到单台配备八个A800GPU的机器可以满足百川2-7B和百川2-13B模型的内存需求,作者的训练框架的主要设计准则是机器级弹性,支持根据集群状态动态修改任务资源,为智能调度算法奠定基础。
机器级弹性:笔者认为就是能够根据集群状态动态修改任务资源,以适应不同的训练需求和集群资源的变化。
为了满足机器级弹性 的要求,百川2的训练框架集成了张量并行和ZeRO的数据并行性,其中张量并行性设置在每台机器内部,而ZeRO共享数据并行性用于跨机器的弹性扩展。
此外,百川2采用了张量分割技术 ,将某些计算分割以减少内存消耗峰值,例如具有大词汇量的交叉熵计算。这种方法可以满足内存需求,而无需额外的计算和通信,使系统更加高效。
为了进一步加速训练而不降低模型准确性 ,百川2实现了混合精度训练,其中前向和后向计算使用BFloat16进行,而优化器更新使用Float32进行。
最后,为了将训练集群高效扩展到数千个GPU,百川2集成了以下技术以避免通信效率的下降:
- 拓扑感知的分布式训练:在大规模集群中,网络连接经常跨越多层交换机。我们有策略地安排分布式训练的排名,以最小化在不同交换机之间的频繁访问,从而降低延迟,提高整体训练效率。
- ZeRO的混合和分层分区:通过在GPU之间分区参数,ZeRO3减少了内存消耗,但增加了额外的全局通信。当扩展到数千个GPU时,这种方法会导致显著的通信瓶颈。为了解决这个问题,我们提出了一种混合和分层分区方案。具体而言,我们的框架首先将优化器状态分区到所有GPU上,然后自适应地决定哪些层需要激活ZeRO3,并且是否进行参数的分层分区。
通过整合这些策略,百川2能够在1024个NVIDIA A800GPU上高效地训练,实现超过180 TFLOPS的计算效率。
FIN.