| 导语 开源社区这一年半来,在大模型领域做了大量的探索,总结了很多有价值的经验。Llama 3.1的技术报告使用的方法,可以认为是目前开源社区的集大成者。对LLama 3.1技术报告的解读,可以了解现在社区训练大模型最成熟、最先进的技术是什么样的,在实际训练模型的时候具有重要意义。
背景和受众
自从去年年初,大模型由于其惊人的效果,在学术界、工业界、投资界引起了大量的关注,发展到现在已经将近一年半的时间。一年之前,就有一种说法,openai相比于开源社区的技术领先,大概在18个月左右(一年半的时间)。
至此,相比于ChatGPT(GPT-3.5)出圈,大概有一年半的时间,开源社区的引领者 Llama 发布了其3.1版本的模型,在各个榜单上面均超过了GPT-3.5,并且在个别榜单可以和GPT-4相互对比。从使用上来讲,Llama 3.1的使用体验,还是弱于GPT-4,但稳定能超过GPT-3.5。
开源社区这一年半来,在大模型领域做了大量的探索,总结了很多有价值的经验。Llama 3.1的技术报告使用的方法,可以认为是目前开源社区的集大成者。对LLama 3.1技术报告的解读,可以了解现在社区训练大模型最成熟、最先进的技术是什么样的,在实际训练模型的时候具有重要意义。
受众:
- 对大模型感兴趣的人:本文会对大模型的一些方法论、基本的原则做一些介绍,感兴趣的读者可以了解到一些大模型的底层逻辑;
- 想要进入大模型领域的学习者:本文系统地讲述了LLama3.1使用的预训练 - 后训练流程,这个流程也已经成为训练大模型的标准流程,初学者可以以此来看领域主要的技术栈需求和难点;
- 大模型行业从业者:LLama 3.1技术报告中,基本只讲了技术的方法实现,并为讲太多背后的原因,在讲述的时候,我会把自己的一些思考写进去,关注了技术为什么这么设计的,希望带给从业者一些思考,在实际做方案的时候能够抓住本质,因地制宜设计方案。
LLama 3.1的独到之处
简要来说,LLama 3.1有以下独到之处:
- 效果方面:大幅超越同规模的模型和GPT-3.5,在一些任务上能和GPT-4打平,是目前最强大的开源模型;
- 预训练方法论:采用了三阶段的预训练,初始预训练-长文本预训练-退火,三个阶段保证了相对低成本实现了强大的的支持超长上下文的模型;
- 预训练去重:采用行级别的去重,提升模型的质量。行去重是相对较为新颖的做法,能够大幅提升性能;
- 后训练方法论:使用了拒绝采样、SFT、DPO的训练策略,合理地利用了收集的Prompt、合成数据、标注数据进行训练。在迭代过程中,优化合成数据和拒绝采样,使得模型总是在当前的状态下进行调优,提升了模型能力;
- 用户行为数据的利用:用户在使用大模型的过程中,产生大量高质量的prompt,这些数据量极大,对提升效果的潜力很大。LLama 3.1通过拒绝采样和DPO被合理地利用这些数据,提升了模型的能力;
- 负熵的原则:负熵的引入才能让模型表现越来越好。使用用户产生的Prompt优化和外界的知识筛选合成数据,均属于为模型引入负熵,从哲学上保证了模型向更好优化的方向。
后面将会从前到后讲解LLama 3.1的技术报告,并穿插对上述独到之处的讲解,在讲解的时候,会伴随着一些评论,这些评论会以背景色突出。
Llama 3.1主要特性 和 效果
整体而言,Llama 3.1有如下模型特性:
- 超大参数规模的模型:主模型的大小有405B,此外,也同时开源了8B和70B的模型。
- 超大的训练数据量:训练使用了15T的多语言数据,基本上可以认为是现在互联网上能爬到数据的上限了。对比之下,上一代的Llama 2是1.8T的数据,有了将近10倍的提升。
- 超大的计算量:用了3.8 × 10^25 FLOPs的计算量。用现在国内常用的A100显卡做估计,单卡算力是156 × 10^12 FLOP/s,即使GPU满载、不考虑通信损耗,也需要 2.8 × 10^6卡天。如果是个万卡集群,要跑280天。实际上,训练和通信带来的损耗,对于优化比较好的系统可以发挥算力的30-50%左右,需要的时间更长。实际上,Meta用了16k的H100显卡,训练了54天。
- 合理的复杂度管理:模型训练,用了相对成熟、稳定的训练技术,包括dense的网络架构、成熟的alignment技术等。
- 超长的上下文长度支持:支持128k的上下文长度,可以支持现实生活的绝大多数任务。
- 对多语言有较好的支持:例如英语、法语、泰语、中文(报告中未给出)等。
- 多能力支持更多下游应用:除了常规自然语言任务外,还支持推理、代码、工具使用等能力,符合做下游AI应用的需求。
整体而言,模型效果相比于同等级别的开源模型,有较大的领先;相比于GPT-4,在一些任务的指标上可以打平;相比于GPT-3.5,稳定领先。
预训练技术
由于预训练成本较高,几乎没有太多容错,要求尽可能一次性地能有好的结果。在大模型技术栈中,预训练是研究门槛最高、最需要工程师经验的环节。预训练模型的好坏,直接决定了后训练(Llama技术报告的说法,对应之前的alignment)的上限。
预训练主要有以下挑战:
- 预训练需要极大的数据量和较高的数据质量,如何满足数据的需求?数据量要求能收集尽可能多的数据,目前做预训练已经几乎把互联网上的数据爬完了,这么大量数据的爬取、存储、处理有很大的挑战,对工程师的大数据处理能力有较高的要求,所幸目前的大数据处理的基础设施都比较成熟(例如数据库、spark、hadoop这些技术),能够处理这种量级的数据。考虑到目前数据量已经基本到顶,数据质量的处理,就更加重要,也是比较考验算法人员功底的地方,需要对数据有深刻的认知、或者足够的经验才能处理较好。
- 预训练成本极高,只有很少或几乎没有试错机会,如何设置合理的训练参数保证正常、高效的训练?这里面涉及的问题包括如何设计/选择模型结构、如何设置训练的超参数、如何配置训练量等等。事实上,dense模型结构目前已经较为成熟,很难再有大的创新,超参数和训练量的配置需要依据scaling law等实验性的规律来决定,以达到最好的训练效果。
- 百B参数的模型,相比现在GPU的显存过大,如何搭建高效的训练集群,设置并行化方式,保证模型可训练并且训练高效?这是个工程问题,百B以上模型训练难度极大,需要用到高级的并行化策略才能保证模型的可训练。进一步,由于大模型预训练成本巨高、涉及到多机训练的网络通信开销巨大,优秀的基础设施搭建是很关键的,好的系统和不好的系统,在训练效率上面,有巨大的差异。好的系统,需要软件层面有合理的并行化策略,硬件方面有合理的网络拓扑结构设计,硬件和软件相互配合,最大化利用资源。
- 训练大模型算力是稀缺的,如何设置合理的训练策略让模型在有限的计算资源下表现更好:较长的上下文长度,能带来的诸多好处,扩大模型的应用范围。在预训练阶段,也会考虑其他能力的融入,例如多模态等。然而,这些能力的获得,会增加计算量,在训练过程中,合理的训练策略能够以更少的资源达到更好的效果,更好地获得这些能力。
针对上述挑战,Llama 3.1都提供了合理的解决方案,下面将会分别进行阐述。
· 数据篇
数据的挑战是数据量和数据质量,数据量比较偏工程,需要优秀的工程师搭建出来数据处理的平台,进行数据的爬取、收集等。下面主要讲数据质量的处理,目前而言,数据质量处理主要包括安全过滤-质量过滤-去重三部分,安全过滤过滤掉隐私信息和不安全信息,防止模型在应用的时候输出此类信息;质量过滤是过滤掉低质量信息,更高质量的数据可以训练出更高质量的模型;去重是去除数据中重复的信息,正常的数据分布,具有一定的长尾性,长尾的数据会导致模型偏向于流行的数据分布,带来偏差,合理的去重对于模型整体的能力和长尾数据的表现都有利。
数据质量处理
个人身份信息和安全性过滤:移除包含大量个人信息(例如姓名、电话、邮箱等)的数据、不安全的内容、成人内容等。这部分可以通过规则的策略,通过正则匹配来实现。
文本信息提取和清理:爬下来的数据,都是html格式的,文本信息隐含在html里面,为了提取出文本信息,需要用到html解析器,好的解析器能让文本的质量更高,Llama 3.1优化了解析器,得到了更好的数据质量。同时,对于code、数学公式等都保留原始格式,去除markdown的标记值,进一步提升整体的质量。
去重复:重复的信息,会降低训练效率,并且对于长尾信息不友好,因此去重成为了关键的数据处理流程。Llama 3.1采用了三种数据处理办法:
- 网页级别的。网页信息会更新发版,旧的版本也会保留,由于不同版本的网页,文本信息有较高的重合度,因此只保留最新的版本。
- 文本级别的。互联网上的信息会相互“借鉴”,因此有很多重复,这部分可以通过hash值来去重,是一种字符串查询相似度的算法。
- 行级别。将文本分割成更小的单元后执行去重算法,这个粒度更细,Llama3.1的技术报告说这个方法能带来较大的提升。这种策略可能会去掉一些中间的句子让上下文意思不严密,但是细想想看也是有道理的,预训练阶段还是学习知识的过程,不要求和应用对齐,一定程度上,更小的粒度(例如句子)也包含了完整的语义,以更小的粒度来看数据,会更精细化。
规则驱动的质量过滤:又称为启发式地质量过滤,主要是指的可以从文本中找一些特征,能够判别出数据质量较低,将这些数据过滤掉。例如,文本中有大量的乱码、特殊符号、不合理的文本长度等等,都可以作为质量过滤的特征。Llama 3.1的技术报告用到的规则有:
- 去除文档中重复的内容,例如log日志等。具体使用了N-gram算法来实现。
- 使用脏关键词来过滤。主要是过滤一些成人内容。
- 过滤掉词分布不合理的信息。过滤离群词明显不符合正常分布的文本。
模型驱动的质量过滤:给出一些文档质量的标签,训练模型预测文本质量,基于训练后的模型进行过滤。常见的训练方法有:认为wikipedia的文本质量较高,其他质量较低,训练模型,这样的好处是无需人工标注;使用人工标注/模型标注的办法,给文档质量打分,训练模型。
上述操作中,文本提取和清理、去重复、规则驱动的质量过滤、模型驱动的质量过滤的复杂度都是O(n),均能处理海量的数据。前面四个均在CPU上可以实现,最后一个涉及到模型,需要用GPU实现,整体成本会更高;去重涉及到hash算法,相比于其他几个CPU的操作,计算成本更高。一般而言,我们可以在起始阶段采用计算成本更低的办法,以低的成本过滤数据,然后再用高成本的操作,以让整体的算力需求更低,执行更快。考虑到上述模块的计算成本,处理数据可以按照如下顺序:文本信息提取和清理->规则驱动的质量过滤->去重复->模型驱动的质量过滤,来保证数据处理的效率更高。
数据领域的采样与混合
实际上,数据的领域分布是不均衡的:
- 一方面,人们在网上冲浪,会生产出更多易于传播的内容,因此爬到的预训练数据存在领域不均衡的问题,例如艺术和娱乐在数据中的比例较高。
- 另一方面,收集到的通用文本、代码、数学推理、多语言数据的数据量存在较大的差异。
针对领域不均衡的问题,需要设计合理的数据混合/上下采样比例,来达到最好的效果。由于在大模型上做数据混合比例的实验是不可能的,行之有效的策略是在小的数据集上做相关的实验,然后直接放到大数据集上面。这基于一个基本的假设:大小模型最优的数据混合比例是一致的,也是一种比较合理的假设和务实的做法吧。但是也可能会存在一些问题,一个可能的情况是,对于不同模型,数据混合的比例会有差异,且存在类似于scaling law的规律性,例如大的模型学习能力更强,需要更多难的数据。针对此猜想,可行的做法在小的不同规模的模型上做实验,看不同规模是否能总结出规律,如果可以,则能够泛化到大模型。
为了决定最好的采样和混合比例,Llama 3.1在小的模型上做了较多的实验,最终给出了一些建议值。Llama 3.1给出的建议配比是:50%英文通用数据、25%数学和推理数据、17%代码数据、8%多语言数据。需要注意的是,这个配比和评估相关,对于中文预训练,最优的配比会有所不同,需要重新实验。
· 模型篇
与之前版本的LLama相同,3.1仍然采用dense模型,没有太多的变化。这里没有采用MoE的结构,听八卦是LLama团队的MoE没有训练好,如果八卦为真,反映了MoE的训练稳定性更差,且任何训练都有极高的门槛,强如Llama团队,在之前没有MoE积淀的情况下,也训练不好。如果传言为假,则需要思考思考为什么Llama没有选择MoE架构了,他们汇集了世界上最聪明的一批人,技术选型应该是明智的,MoE相比于Dense模型是否具有宣称的优势、又是否存在被忽略的短板,值得更进一步的思考和实验验证。
具体而言,LLama 3.1的一些小的设计包括:
- Group Query Attention (GQA)中使用了8个KV头。GQA是现在常用的注意力机制,相比于Multi-head Attention,GQA让一个KV对应多个Query,降低了KV的数量,从而减小了推理时候的显存消耗;
- 使用Attention mask机制,避免不同的数据之间的attention聚合。这一设计对于预训练(8k的文本长度)没太大影响,在训练长文本的时候有较大的影响。这个实验结果也算是对之前的一些从业者的分歧和猜想盖棺定论了吧。
- 使用128K的字典大小。尽管更大的字典带来了更多的显存消耗,但是也提供了更好的字符压缩比和更好的模型效果,在128K的收益较好。
- RoPE位置编码的基频设置为500,000,这主要是为了向长文本扩充。
Scaling Law决定训练参数
Scaling Law 是个基于大量的实验总结出的经验规律,指导了过去大模型的迭代方向,主要是三点特性和应用:
- 模型的性能,会随着模型规模、数据量、计算量的增加而提升。这指导了过去大模型发展的“大力出奇迹”暴力美学。
- 定量而言,模型的loss会随着模型规模、数据量、计算量呈现幂律下降的规律。此外,给定计算量和数据量,可以计算出模型规模(与计算量成正比、数据量成反比),因此,在一定的计算量下,需要分配合理的数据量和模型规模。由于前面的幂律规律,可以在小规模的数据上面做实验,推广到大的数据,得出模型规模和数据量的合理设置,能够在相同的计算量下,达到最优的性能。这种做法被称为计算最优的策略。
- 由于训练只需要进行一次,推理要进行无数次,从长期来看,推理涉及到边际成本,具有更高的成本。更小的模型推理成本更低,因此,也有做法采用更小的模型,把计算资源分配到小模型的数据量上,进行训练。这种做法成为推理更优的策略。
实际上,模型训练的超参数(主要是学习率和batch size的设置)和scaling law也有一定关系。这部分可以参考 DeepSeek LLM Scaling Open-Source Language Models with Longtermism 这篇论文,展示了超参数和scaling law的关系,并给出了设置超参数的建议,对预训练具有很强的指导意义。
在Llama 3.1的技术报告中,对于405B的模型,采用了计算最优的做法,通过大量的小规模实验拟合曲线,推广到大模型规模,得出最优的模型和数据规模。具体而言,计算量在 6 × 10^{18} FLOPs 到 10^{22} FLOPs之间,模型规模在40M到16B之间,分别训练模型,统计loss。每个计算量可以有一个最优的模型规模和训练数据的组合,据此可以拟合曲线,然后得到在全量计算资源下,最优的模型规模和数据规模。对于Llama这次的集群规模而言,在合适的训练时间内,可以提供 3.8×10^25 FLOPs的计算量,按照之前拟合的曲线,计算最优的模型规模和数据量为402B和16.55T。实际上,用了405B和15T的数据。
训练基础设施
硬件基础
这部分和算法没有太大关系,本文不计划讲的过于深入,感兴趣的读者可以参考Llama 3.1的技术报告原文。无论是对团队而言(有这么多显卡)还是对工程师而言(对硬件、算法都有深入理解),这套技术的搭建门槛极高,不适用于大多数团队和个人,大部分人了解即可。
- 计算资源:采用了先进的H100显卡,集群有16k个显卡,80GB HBM3的带宽。单机八卡,机器内GPU通过NVLink连接。
- 存储:有240PB的SSD存储,带宽2TB/s,峰值带宽7TB/s。之所以需要这么大的存储,是因为在训练的时候,需要保存和模型相关的状态(模型参数、梯度、动量这些)作为checkpoint,来防止训练中断或者训练不稳定带来的成本,这些状态会消耗大量的存储。
- 网络:多机器之间的通信利用RDMA技术,即直接访问远程内存,减少CPU的中间处理,提高通信效率。这个技术在大规模训练中非常常用,是多机训练大模型的标准配置。此外,Llama 3.1还针对模型并行化的实现,设计了合理的网络拓扑结构,提高了训练效率。
并行化策略
在训练模型的时候,用到了4D并行化策略,组合了张量并行(TP)、流水线并行(PP)、上下文并行(CP)、数据并行(DP)的策略。4D并行也是目前做大规模模型预训练的标准配置,合理的4D并行策略,可以最大化利用GPU算力资源。举例而言,TP相比于PP对于通信需求更高,因此就更适合用在单机内部的显卡上面,最大化利用NVLink带来的优势。
实测下来,LLama 3.1的并行化策略,能够达到GPU计算峰值的40%,在16k的集群上能达到这种效果,非常了不起的。
训练方法
目前预训练大多分为两个部分:
- 初始预训练:即从头开始训练模型,这一阶段采用相对较短的文本,使用大量的数据训练,目标是教会模型知识;
- 长上下文预训练:使用长的文本进行相对少量的继续训练,目标是让模型获得长文本处理能力。
分成这两步,主要是出于训练效率的考虑,Transformer结构的计算复杂度随着模型长度平方增加,从头就采用长文本训练是昂贵的,在第一阶段,更加注重效率,用短文本训练;在第二阶段,更加注重长文本效果,用长文本训练。目前该设置已经成为大模型预训练的标准配置。
此外,LLama 3.1还引入了第三阶段的预训练:
3. 退火训练:使用高质量的数据,以小的学习率训练模型,使得模型能更好的在后处理阶段表现更好。
以下是一些具体的配置:
初始预训练
学习率:在405B的模型上,采用了 8 × 10^{−5} 的峰值学习率,8,000步的warmup,cosine学习率衰减,经过1,200,000训练步,衰减到 8 × 10^{−7} 。
Batch size:起始阶段,使用较小的batch size,然后增大batch size。具体而言,第一阶段,使用4k的序列长度,4M tokens的batch size,训练了252M tokens;第二阶段,使用8k的序列长度,8M token的batch size,训练了2.87T token;第三阶段,使用8k的序列长度,16M token的batch size,训练剩下的数据。这种预训练策略,能够比较稳定地训练模型。
数据混合:
LLama 3.1用了几个小tricks: - 增加非英语语言的数据比例,提升模型的多语言能力; - 上采样数学数据,提升推理能力; - 在最后阶段,增加更多时间更新的数据,提升模型的实效性; - 下采样质量较低的数据。
长上下文预训练
Llama 3.1在扩充长度的时候,采用渐进的方案:分6个阶段,逐渐将上下文从8k扩展到128k。在每次向更大的上下文扩充的时候,要保证两点:
- 短的上下文评估效果不变;
- 模型能完美地解决大海捞针实验。
这一阶段训练,使用了800B tokens。
退火训练
在最后的训练阶段,训练了40B tokens,学习率逐渐衰减到0,保持上下文长度128k。这部分选用低的学习率,并选取高质量的数据训练,保证模型在局部调整到更好的状态。训练完成后,将在退火阶段所有的模型checkpoint取平均,作为最终输出的预训练模型。这种操作的合理性是:退火阶段,学习率低,模型局部调整,因此取平均具有合理性,且实验验证效果更好。
后训练技术
后训练就是之前常说的对齐技术,包括SFT、DPO之类。除了人工标注数据之外,LLama 3.1大规模使用了以较低的成本生成的数据,在训练算法中的地位甚至超过了标注数据,这标志着合成数据训练模型已经逐渐成熟并会越来越重要,后面我会讲一下这背后的底层逻辑。
在现有的大模型主流认知里面,预训练解决的是模型知识的问题,其能决定模型的上限;后训练解决的是模型的对齐问题,其能让模型在预训练中获得的能力更好地发挥出来。后训练的效果,直接决定了模型的实际效果,对于资源消耗也更少。绝大多数团队,其实在训练模型的时候,是基于预训练模型做对齐的,因此,这部分内容是从业者应该着重关注的,包括训练的思路、合成数据的办法等。
· 模型/算法篇
整体做后训练的流程如图所示:
- 首先用Pairwise Preference Data训练Reward Model,Reward Model的作用是能对于样本的质量作出判别;
- 然后用Reward Model做拒绝采样(Rejection Sampling),即从Collected Prompts采样出多个生成K个结果中,采样质量较高的数据作为SFT数据,然后和标注的SFT数据混合,训练SFT模型;
- SFT模型训练完之后,进行DPO Model的训练。
在拒绝采样的过程中,使用DPO模型生成多个数据。DPO模型作为最终的模型提供推理服务。
上述过程涉及到生成数据训练模型,越好的模型生成的数据越好、越容易训练出好的模型,因此上述训练过程,会迭代6次,在迭代的过程中优化模型、从而优化生成的数据、并提升生成数据训练得到模型的效果。此外,由于涉及到合成偏好数据,需要让模型有所差异,保证生成数据的差异性,因此在每个轮次,会使用不同的超参数、数据训练得到多个RM、SFT、DPO模型,最后会对于这些使用不同超参数、数据训练的的RM、SFT、DPO模型取平均,作为最终模型。
上述训练算法中,相比于SFT数据,偏好数据占据更加重要的部分,包括训练RM模型进行拒绝采样和训练DPO模型。LLama 3.1的偏好数据是由收集到的prompt通过模型生成多个回复结果,有人工标注回复的质量排序。这里的技术选型有很多内涵:
- 用户Prompt的收集是廉价、大规模的——从提供LLM应用的服务商的日志中很容易收集;用户Prompt是高质量的,由于Prompt是人写的,即使很差的模型提供服务也可以收集到高质量的Prompt。现在深度学习的成功,是数据驱动的,在例如搜广推、大模型等的多个领域,一个底层的逻辑就廉价、大批量地获取到高质量的数据训练模型很可能取得成功——搜广推中的用户行为数据、大模型中的互联网爬取到的人创造的数据。大模型未来会在人和世界的交互中扮演越来越重要的角色,可以预见,未来也会有更多用户产生的prompt被廉价地收集,这也将会产生大批量高质量数据,这些数据的使用,对于优化模型具有很大潜力;
- 有了Prompt,由用户生成response成本较高,但是通过模型生成多个结果,让人标注质量排序成本较低,这符合大规模产生数据的需求,只要能很好地利用排序数据优化模型,就有潜力优化得到较好的模型(DPO、PPO这些就是一些具体的方案);
- 用户的prompt和人工的标注排序,可以认为是整个系统演化过程中的外界能量注入,保证了模型优化的方向更好。从熵的角度考虑这件事,封闭的系统熵会越来越大,因此让模型本身生成prompt和标注数据,长期一定是有害的;而外界能量注入,有可能让系统熵减,从原理上保证模型优化向好的可能性。DPO和拒绝采样,能够利用外界的能量进行熵减的合理算法。
Reward Modeling
Reward Model的作用是能够判别模型生成内容质量的好坏,潜在的用途包括:强化学习中作为环境模拟提供反馈训练模型(PPO);在拒绝采样中,作为判别挑选数据训练模型;在模型评估中,作为质量评估的标准。
因为DPO训练更容易收敛,LLama 3.1采用了DPO的训练技术,训练Reward Model的主要作用是为提供拒绝采样提供判别,选择数据训练SFT模型。
训练Reward Model的具体方式:对于一个prompt,存在n个答案,答案质量有高低排序,排序作为标签可以训练模型。实际中,用pair-wise的数据(chosen, rejected),这些数据是模型合成两个response数据进行人工标注排序的。然后会把chosen给模型或人编辑得到更好的回复edited,最终得到了 edited > chosen > rejected,给模型训练。传统的Reward model训练,会把prompt和每一个答案计算出分数,共有n行数据,分别计算n个分数,设计loss训练模型。Llama 3.1的区别是,把prompt和多个答案打乱后拼接,一次性传播计算所有数据的分数,用来设计loss训练模型。这种训练方式更加高效,LLama 3.1做了消融实验,这种方案不会造成性能的损失。
SFT
SFT的数据包括借助于Reward model在人工的prompt上面通过拒绝采样生成的数据、人工标注的数据、高质量合成数据。在训练的时候,采用prompt mask的策略,只计算response的loss,不计算prompt的loss,根据目前多个的论文结果和我自己的实验结果,prompt mask相比于不mask 有微弱的优势。实际用1 * 10^{-5} 的学习率,训练了8.5k-9k步,这个实验设置比较稳定,能在各个数据混合下都有较好的表现。
DPO
DPO有两种:
- Offline DPO,训练数据是静态的,用一批标记好的偏好数据训练模型;
- Online DPO,训练数据是动态的,在训练一段时间DPO模型后,会用最新的模型生成数据,重新标注(可以是用Reward model或者高级的闭源模型标注),用最新标注的数据训练模型。
Online DPO的好处是数据是用最新的模型生成的,因此得到的标签能够切合模型当前的训练情况(类似于active learning),使得样本的训练更加高效。
根据Llama 3.1的描述,采用了online DPO的训练策略,每次迭代后重新用最新的模型生成数据,进行标注,然后训练。训练的时候,用了 1 * 10^{-5} 的学习率,β 超参数设置为0.1,并且对DPO算法做了如下改进:
- 在loss中mask掉特殊的格式字符,例如开始和停止符,以使得训练更加稳定。Llama 3.1发现带上这些字符,会导致重复或者突然生成停止符,分析原因是因为DPO优化的是好样本和坏样本的margin,两者数据均有停止符,因此会导致关于特殊字符的loss失效。
- 使用chosen的样本,做一个和SFT相同的NLL loss,系数是0.2。这个技巧在大模型DPO/PPO是常用的技巧,主要是为了训练的稳定性,让模型保持生成正常内容的能力。
· 数据篇
数据对于模型的优化至关重要。数据有两个方面,数据获取、数据质量过滤。下面首先将偏好数据如何获得,偏好数据用来Reward model和DPO模型;然后将SFT数据如何获得,SFT数据用来训练SFT模型;最后讲数据处理和数据质量过滤方法。
偏好数据
在LLama 3.1的报告中,偏好数据是用模型生成,然后人工标注的。用不同的超参数和数据训练出不同的模型,保证模型和模型生成数据的多样性。整个过程的输入是收集到的prompt,,每次从中选取两个模型对收集到的prompt生成答案,然后人工标注优劣。除了标注优劣顺序外(chosen > rejected),还会给出优势的大小,分成四个层级:明显更好、更好、轻微好、差不多。然后针对chosen进行人工或模型编辑,得到edited,最终得到edited > chosen > rejected的数据。
数据类型包括:通用英语、知识问答、指令跟随(上述三者约80%)、代码、多语言、推理、工具使用(后面四者约20%)。知识问答和指令跟随,是为了让回答更加准确,符合人的预期。数据是多轮交互数据,有相对较长的问题和回复,来增加问题的难度。
由于训练涉及到多个轮次,每个轮次都会用最新的模型重新进行数据的生成和标注。对于DPO模型的训练,只用最新轮次的标注数据训练模型;对于Reward模型,用所有的标注数据训练模型。直观来讲(有点强行解释,我没太看懂这个设计),这样做原因是DPO模型作用是后续提供服务,是一个迭代的过程优化的,越新的数据对于当前模型状态,向alignment的方向优化越有意义;而Reward模型是用来判别数据质量,对Alignment并不敏感,所以用更多的数据,有利于其学习到判别质量的能力。
SFT数据
SFT的数据来自于三部分:
- 依据收集的prompt拒绝采样得到的数据。对于每一个收集到的prompt,使用最近轮次的DPO模型采样K个生成的答案(通常为10-30),再用Reward模型挑选出最好的。如前所述,训练中会用不同的数据训练不同的模型,不同的模型各自有擅长的领域,在生成数据的时候,用擅长该领域的模型进行数据的生成。
- 合成数据。通过模型生成prompt、response的数据,并通过复杂的规则校验、提升质量得到的数据。例如,对于代码数据,可以通过静态分析、单元测试等方法进行质量过滤。这些办法,也可以理解成为外部能量的注入,保证了模型优化的质量。
- 人工标注数据。即用人工标注的SFT数据,大模型发展至今,这些数据也有相对较大的体量了。
最终的数据中,混合了约50%通用英文数据、15%代码数据、3%多语言数据、8%考试数据、21%推理和工具数据、0.11%长文本数据。
数据处理和质量过滤
由于数据是生成的,其质量过滤较为重要。质量过滤用到了规则驱动的、模型驱动的两种。
规则驱动:主要是由人来看数据,总结一些模式。例如发现早期的训练中,包含较多的emoji数据或者exclamation数据(例如倾向于I'm sorry xxx; I apologize xxx)。
模型驱动:基于模型做出判别,包含:
- 使用Llama 3 8B的模型进行话题分类,这个的主要目的,应该是区分数据,训练多个不同的模型;
- 使用reward模型或者Llama 3的checkpoint进行质量打分:使用prompt,在多个维度进行打分,例如准确性、指令跟随、语气。认为高分的样本是高质量的,并据此进行过滤;
- 使用Llama 3 70B和LLama 3进行难度打分:给数据打上意图标签,意图越复杂说明越难,也可以直接给数据按照三档难度打标签。
- 基于RoBERTa的语义去重:RoBERTa对于提取语义embedding有很好的效果,使用RoBERTa对数据embedding化,基于cosine相似度,可以估计出数据的相似度。
实际上,会首先基于RoBERTa的embedding聚类,在类内根据质量*难度进行打分排序,从上到下进行数据挑选,在挑选的时候,只保留和前面数据的相似度较低的数据,保证数据的多样性。
· 具体能力
Llama 3.1关注的几个模型特性包括:代码、多语言、数学和推理、长上下文、工具使用、事实推断、可控制性等。每一种特性都有其特殊的挑战,Llama 3.1都有会结合这个领域的特点对应的算法设计,实现层面,一个很重要的点就是要有领域专家的参与,基于领域的特点设计出做数据的规则,越优秀的专家设计出的规则越好,对于训练越有利,在设计规则的时候有两点是值得考虑的:这个领域的特点和难点是什么;规则能够为模型带来什么。下面主要讲一下代码的处理办法。
代码领域的难点是:相比自然语言,代码需要较高的专业背景才可以看懂,让人工标注需要大量的成本;潜在的优势是:代码是可以被分析和执行的。因此,利用这些规则,对合成数据进行质量过滤,保留质量较高的数据训练模型,是合理的方法。Llama 3采用了大量合成数据策略,来生成SFT数据训练代码模型。
由于代码是比较大的细分领域,训练了专门的代码专家模型来支持代码的后训练过程。在实际处理的时候,主要注重代码生成、写文档、debug、和评审的能力。
代码专家:由于代码领域和通用数据有较大的差异,且代码本身的数据量也足以支持与训练,这里继续预训练代码专家模型来进行优化——在代码数据占比85%的数据上,进行了1T tokens;最后1k步,用16k上下文,做项目级别的训练。然后在这个模型基础上,用代码数据做代码后训练,得到最终的代码专家模型。这个代码专家模型的作用主要是合成数据,给主模型训练,包括给主模型训练相关的代码prompt做拒绝采样,最终代码专家的代码能力,也会融入到主模型里面。
合成数据生成:借助于代码专家模型和LLama 3.1主模型,进行数据合成,合成的数据用于主模型的后训练,提升主模型的代码能力。这里共合成了2.7M条数据,由于是合成数据,数据量很大。包含以下处理思路:
- 依据代码分析或执行反馈,筛选合成数据。首先,用随机的代码片段作为prompt,让模型生成编程相关的问题,不同的代码片段可以理解为不同的种子,保证了问题的多样性;然后利用LLama 3进行答案的生成,生成的时候,指定编程语言、并在prompt里面添加一些通用的规则(对答案做更好的约束)、并让模型解释一下思路(CoT的思想);其次,使用静态/动态的方法进行正确性分析,静态指的是基于语法的分析、动态指的是基于单元测试的执行分析(单测也是让模型生成的);然后,基于错误反馈,进行迭代改进数据,将问题、答案、错误内容输入给模型进行修改,由于单元测试也是模型生成的,也会同时让模型修改单元测试,修改后大约有20%的case由错误变正确;最后,用这些本来正确的内容和修改后正确的内容微调模型。上述过程,随着后训练模型迭代的轮次更新。
- 基于编程语言翻译的数据合成。由于小众编程语言数据量较少,相比于主流语言有较大的性能差异,这里采用Llama 3将主流语言翻译成小众语言,合成数据,并进行语法分析、编译、执行的检验,将正确的数据作为最终的训练数据;
- 基于反向翻译的数据合成。首先,使用LLama 3基于代码生成注释或代码解释;然后给予生成的内容提取或生成代码;最后用LLama 3给最终代码和起始代码的一致性打分,留下高分的数据作为训练数据。
拒绝采样的prompt引导:在做拒绝采样的时候,有更加精细的prompt操控,即在prompt中引导从代码可读性、文档化、周密性、具体性的角度做样本选择。
使用模型判别信号的数据过滤:在拒绝采样中,由于两点原因:prompt来自于收集的prompt,由其产生的数据是要高于模型生成的prompt的,要尽可能好好利用;用户在使用LLM的时候,也并不一直期望代码的正确性,例如生成伪代码、甚至错误的代码也能够拷贝,稍作修改就可以用。因此,拒绝采样中并没用选用静态分析/动态分析的方法过滤数据,而是使用LLama 3做判别来过滤数据。具体而言,让Llama 3判断代码争取性和代码风格的好坏,只有正确且风格好的代码才会被留下来训练模型。然而,这个方法会让困难的数据被筛选掉,导致模型效果降低,为了解决这个问题,反复让模型修改难样本,直至达到上述要求。
结语
大模型发展至今,已经过去一年多的时间了。站在现在的时间节点看,尽管国内大模型、开源社区相比于 openai 仍然有较大的差距,但是取得国内技术和开源社区的成绩已经远超去年 openai 刚开始发布模型时候大家的期望。开源极大地促进了大模型的发展,一方面是优秀、有价值的经验得到交流,避免不同团队走相同的弯路,导致社会资源的浪费;另一方面,从事开源事业的人因为会把自己花费心血得到的结论告诉世界,也会有更强的愿景,以更加负责任的心态把事情做好。LLama 3/3.1的发布标志着开源社区已经能够训练出质量极高的模型,而且其训练细节也透明可复制。可以预见的是,随着硬件的进一步优化,训练成本会进一步降低,未来开源社区的力量也会越来越强。
相比于调用API,开源模型从本身可以私有化微调、部署,具备更加安全、可控的特性,在一些特别定制化、数据安全要求高的场景上有一定的优势,这些场景会推进开源模型的进一步应用和繁荣。同时,像 openai 的闭源模型,已经收集到了大量的用户prompt优化模型,这是openai的先发优势,这是openai这种中心化的闭源模型带来的优势。对于开源模型,用户数据对于优化模型的收益仍然很高,LLama 3.1设计了合理的算法利用这些数据,开源模型未来的应用会更加偏向于一种去中心化的私有化场景,对于这些场景,如何收集数据,会是一个有价值的议题的思考方向。
本解读覆盖的内容:把LLama 3.1技术报告的精华部分(LLM的预训练和后训练)都讲的比较透彻了,当然还有一些章节没有讲,比如后训练的其他能力数据合成办法、评估、推理、多模态相关的内容,这些内容其实也有很多可以借鉴学习的,以后可以继续分享。