Llama1-3 🦙:从一道美团大模型面试题讲起
从 LLaMA1 到 LLaMA3:这风云激荡的 2023 到 2024 年
这篇博客应当是我在 2025 年的首篇博客。24 年底,在我身上发生了很多意想不到的事情,总使我灰心丧气。忽然间,发觉自己除开写了十几个月的日记,并没有更多新的更新。前不久,在 B 站上看到名为 美团大模型面试真题:LLaMA怎么优化注意力机制计算? 的视频,我才惊觉时光飞逝。
于是想着,似乎应当写一篇详解 LLaMA 的博客出来。等到调查资料的时候,发现 LLaMA 原来早在 2023 年就已发布,且已到第三代。估计第四代就将在 2025 年发布吧?看来这篇博客实在是拖延不得了!
又:长久以来我总计划开设“NLP 经典论文”专区,整理自 2017 年以来“重点文”,不妨就以此篇作始吧!
2023 到 2024 年:从无到有,由弱及强
2023 到 2024 年,metaAI 先后发布 LLaMA1 到 LLaMA3 的论文。LLaMA 系列从无到有、由弱及强,成功跻身大语言模型先锋军之中。2023 也由此可以称作 LLaMA 元年。
- 2023.2.27 LLaMA: Open and Efficient Foundation Language Models 👉 论文链接🔗
- 2023.7.19 LLAMA2: Open Foundation and Fine-Tuned Chat Models 👉 论文链接🔗
- 2024.11.23 The Llama 3 Herd of Models 👉 论文链接🔗
版本 | 模型结构 | 训练数据 | |||||
---|---|---|---|---|---|---|---|
规范化 | 激活函数 | 位置编码 | GQA | Tokens | 上下文长度 | Vocab Size | |
LLaMA1 | RMSNorm | SwiGLU | RoPE | ✗ | 1.4T | 2K | 32K |
LLaMA2 | RMSNorm | SwiGLU | RoPE | ✓ | 2.0T | 4K | 32K |
LLaMA3 | RMSNorm | SiLU | RoPE | ✓ | 15.0T | 8K | 128K |
在模型结构上,LLaMA 自 1 代至 3 代总体改动较小,其中比较关键的技术是:RMSNorm、RoPE 和 GQA。LLaMA 的迭代更新主要得力于 metaAI 不断扩充的优质语料库:
- 自 1 代到 3 代,语料库的总 Token 量从 1.4T 上升至 15T;
- 词汇表大小也从最初的 32K 扩充至 128K;
- 预训练的上下文长度从 2K 增加到 4K,再到现在的 8K。
在模型参数量上,三代 LLaMA 总体呈现上升趋势:
- LLaMA1 分别具有 7B、13B、33B、65B 等版本;
- LLaMA2 与 1 代比差距不大,包括 7B、13B、34B、70B 等;
- LLaMA3 的参数量则显著提升,主要是 8B、70B 甚至 405B 等。
LLaMA 是如何优化注意力机制的?
回到我们的话题上来:LLaMA 是如何优化注意力机制的? 事实上,LLaMA 在模型架构上大体仍沿用 (Vanilla,2017) 提出的 Transformer,而进行了许多微小的改动。我根据自身对原论文的理解,认为其中比较重要的三个技术是:RMSNorm、RoPE 和 GQA。这些技术是什么意思?它们为什么能优化注意力机制?接下来对其进行详细讲解。
RMSNorm:在不牺牲模型稳定性的同时降低计算复杂度
原始的 Transformer 使用的是 层规范化 (LayerNorm) 。之所以引入规范化,是希望模型中间层的输入分布始终保持稳定。具体来说,它对输入
而 RMSNorm,或称 均方根规范化 就是 LayerNorm 的变体,RMSNorm 省去了求均值的过程,也没有了偏置
首先,在计算上:RMSNorm 相比 LayerNorm 更为简便。其次,在效果上:容易看出 RMSNorm 具有对输入缩放的不变性(
RoPE:以简便方式有效捕捉相对位置信息
LLaMA 在每个 Attention 层中分别对
1 |
|
那么,什么是 旋转位置编码 ?RoPE 原论文的说法是:“在RoPE中,我们的出发点就是 通过绝对位置编码的方式实现相对位置编码 。”也即,我们考虑:
- 假设我们有编码操作
,分别对 的第 维向量 和 的第 维向量 进行位置编码: - 那么在 Attention 中对
和 求点积时,我们希望 和 的内积结果将带入 这个 相对位置信息 (m-n 将影响内积结果) : - 原论文经过复实变换得到了操作
的解: . 其中 为虚数单位, 为给定超参。- 根据复数乘法的几何意义,该变换实际上对应着向量的旋转(我们可以想象二维向量)。
- 最后,我们可以将
的完整形式表现如下(假设 为 维向量):- 其中,
,这带来一定的远程衰减性。 是逐位对应相乘,即Numpy、Tensorflow等计算框架中的 运算。- 从这个实现也可以看到,RoPE可以视为是乘性位置编码的变体。
- 其中,
最后在这里贴一份 metaAI 官方写的代码,以便更加直观地看到 RoPE 操作是如何实现的。
1 |
|
GQA:减少 KV-Cache 大小以提升模型推理速度
引入 GQA 前先简单介绍下 KV-Cache
提高大模型推理速度的常用关键技术是 KV-Cache。大模型以 自回归 (auto regressive) 的方式推理,预测下个 token 时,总是基于之前已经生成的序列。从代码的角度来理解是这样的:
1 |
|
显然,随着输入序列越来越长,每次都重新计算所有 token 注意力值的传统方法显得非常低效。针对该问题,KV-Cache 采用 空间换时间 的方法:在自回归过程中,开辟空间将每次计算的
1 |
|
在了解了 KV-Cache 后,我们不禁会反思:既然
GQA:用分组的方式减少 KV 对的数量
然而,引入 KV-Cahe 意味着需要开辟大量的缓存空间。在 多头注意力 (MHA) 中,所需开辟的缓存空间大小可按照如下公式计算:
指 Transformer 块的数量。以 LLaMA2 为例,它共包含 32 个。 指输入数据的批量大小。这里我们假设是 16。 为输入句子的长度。为便于计算,我们取最大长度为 1024。 是注意力头的个数。假设是 32,与原论文保持一致。 是隐藏层的维度数。它在 LLaMA-7B 中被设为 4096。
根据公式,我们得出为了缓存 KV 所需的空间大小为
为解决这一问题,我们必须优化算法。由此,便引出了 LLaMA 自 2 代开始所使用的 GQA (Group Query Attention) 。以下摘自 GQA 的原论文的图片简单明了地说明了什么是 GQA。
如图所示:在 多头注意力机制(左,MHA) 中,每个注意力查询 Q 都有各自对应的 KV 对,这导致缓存 KV 所需的空间极大。最极端的情况下,如 多查询注意力机制(右,MQA),所有的查询 Q 共享唯一的 KV 对,虽最大程度地减少了所需的缓存空间,但带来了精度的下降。而 分组查询注意力机制(中间,GQA),在精度和计算之间折中:将各查询 Q 分组,同组查询共享一个 KV 对,在保证精度的同时一定程度地减少缓存空间。
我们可以稍做计算:若我们将原有的 32 个注意力头分成 8 组,每组 4 个查询。那么就仅会有 8 个 KV 对,所需的缓存空间就变为了原来的四分之一(128GB -> 32GB)。由此,模型推理性能得到提升,我们就可以喂给模型更多和更长的句子,或者搭建更深的网络和设置更大的隐藏层维度。
metaAI 在代码中的具体实现方式为:限制 KV 头的数目小于 Q 头的数目,在计算的时候复制 KV 头以使其能够与 Q 的头对应,在缓存的时候仅缓存不重复的 KV 对。代码如下:
1 |
|
CodeWork:回顾与总结,尝试阅读完整代码
在之前对 RoPE、KV-Cache、GQA 的介绍中,我们事实上已经将 LLaMA 中 Attention 模块的 forward() 函数部分的全部代码展示出来了。现在贴一份完整的代码在这里,可以试着在无注释的条件下理解代码做了什么。如果想看源码,也可以访问 metaAI 官方的代码。
1 |
|
训练一个对话机器人:LLaMA2 是如何做的?
自从 ChatGPT 火出圈以后,使用强化学习来提升 LLM 的对话能力 成为了一个很通用的方法。现如今的 LLM 在表现效果方面的提升主要关注 有用性 (helpfulness) 和 安全性 (safety) 两个方面,它们对优化人机交互的体验非常关键。 在 LLaMA2 中,这一点通过强化学习来搞定。
简单地看一下预训练和 SFT 微调部分
预训练和微调过程都以自回归 (auto-regressive) 为训练目标。最大的不同之处在于:预训练过程的输入是独立的一句话,计算损失时考虑整个句子;微调过程的输入则是由 prompt 和 answer 组成的句子对,计算损失时仅考虑 answer 部分。自回归损失可用如下公式表示:
在预训练阶段,自回归赋予模型说话的能力,使模型的输出分布于 人类可接受 (Human Acceptable) 的域内。而在 SFT 微调阶段,通过 指令微调 (Instruction Fine-tuning) ,模型被要求以“提问-回答”的方式生成内容,从而使输出落在 人类可用 (Human Usable) 的域内。
至于具体的训练细节,如 使用 Adawm 优化器、学习率呈 Cosine 式递减 等,限于篇幅,不再具体指出。感兴趣的小伙伴们可以通过原论文自行查阅。
重点!带人类反馈的强化学习 (RLHF)
LLaMA 引入强化学习,目的在于使模型的输出尽可能分布在 人类偏好 (Human Preference) 的域内。具体来说,metaAI 希望 LLaMA 是 有用的、无害的 (Helpful, Safe)。LLaMA 使用了与 ChatGPT 相同的 RLHF 算法,该算法分为三步:1) 定义并搜集人类偏好数据;2) 训练奖励模型(Reward Model);3) 确定所使用的强化学习算法,并不断迭代。下图反映了经过强化学习后模型输出的分布变化。
收集人类偏好数据
metaAI 从 helpfulness 和 safety 两个维度衡量人类对机器回答的偏好程度。标注者首先编写 prompt 喂给两个不同 Temperature 参数的模型变体,并按给定的 guidelince 给得到的两个回答打分。
- 考察 helpfulness 时,标注员将回答标注为 sigificantly better, better, slightly better 或者 negligibly better / unsure。
- 考察 safety 时,再额外收集一个安全标签,将模型回答分为三类:偏好回答安全而另一个回答不安全、两个回答都安全或者两个回答都不安全。
metaAI 按周分批收集标注,并在每次调优下个 Llama 2-Chat 前,使用最新一次迭代收集的偏好数据训练 RM (Reward Model,奖励模型),以保持 RM 的准确性和适应性。如上图所示,迭代将使 Llama 2-Chat 的输出尽可能分布到 RM 得分高的域内。这其中,RM 也在不断迭代升级。
在数据质量方面,metaAI 将其收集到的人类偏好数据与一些开源数据集,如 Anthropic Helpful & Harmless, OpenAI Summarize, OpenAI WebGPT, StackExchange, Stanford Human Preferences, 和 Synthetic GPT-J 做了对比。想详细了解的小伙伴可以到原论文查看,这里不再赘述。
训练一个奖励模型 (RM, Reward Model)
奖励模型接受模型的回答及其对应的提示作为输入,并返回一个实数(不一定介于 (0,1))表示模型输出的质量。如果将 Llama 2-Chat 看作一个 agent,那么 RM 的输出即是这个 agent 获得的 reward。metaAI 独立地训练两个 RM:一个用于评估 helpfulness,另一个用于评估 safety。
为了使 RM 和对话模型 (LLaMA2-Chat) “具备相同的知识”,metaAI 将两个 RM 初始化成经过预训练的 llama2 的一个 checkpoint。也就是说,RM 采用与 llama2 完全相同的架构和训练参数,而仅 将模型输出头从预测 next-token 头替换为回归头(就如下面公式展示的)。
这样,RM 将会输出一个实数值,作为该“提示+回答”对的质量评估。metaAI 并不要求将质量评估回归到精确的数值上,而采用了 排序损失函数。该损失函数适用于希望模型输出更加关注值的大小关系,而非具体数值的情况。同时,metaAI 引入了 margin 来衡量输出值间的大小差异程度,即“如大,有多大?如小,有多小?”。训练 RM 所使用的损失如下:
其中,
Significantly Better | Better | Slightly Better | Negligibly Better/Unsure | |
---|---|---|---|---|
Margin Small | 1 | 2/3 | 1/3 | 0 |
Margin Large | 3 | 2 | 1 | 0 |
该损失函数将会引导 RM 给标注员 chosen 的回答相对更高的分数,而给标注员 reject 的回答相对更低的分数。并且由于 margin 的引入,RM 会倾向于给获得更高级别标签的回答以更高分数。训练好的 RM 就相当于一个导师,它将告诉对话模型“如何说话才能更被人类偏爱”。metaAI 对其训练的 RM 的评估已在原论文给出,这里不再详述。
所使用的强化学习算法
metaAI 执行 RLHF 时主要用了两个算法: Proximal Policy Optimization(PPO) 和 Rejection Sampling fine-tuning (RSF) 。前者是一个通用的 RLHF 的范式。后者则是在 RLHF 迭代早期时,模型尚未成熟所使用的方法。
Rejection Sampling fine-tuning 亦即 拒绝采样微调 。给定 prompt,它经由具有不同 Tempurature 参数的 LLaMA2-chat 得到一组可能的回答。RSF 从这些回答中选取 RM 得分最高的前 N 个样本,并用这些样本对 LLaMA2-Chat 做一次小规模的 SFT (这种方法有点像遗传算法) 。在 RLHF 的前三次迭代 (v1 to v3) 中,LLaMA2-Chat 只通过 RSF 学习,直到 v4 才引入 PPO 算法。
PPO,又称 临近策略优化 算法,是一种 Actor-Critic 算法。如果你不清楚什么是 PPO,你可以查看这篇博客。LLaMA2-Chat 所采用的 PPO 方法如下公式所示:
- 在数据集
上采样提示 ,并让模型生成一定数量的内容 。 表示对于提示 ,回答为 的 reward。- 目的是使
最大,其中唯一可变的策略 的参数 。
- 在数据集
是优势函数,它的计算在之后解释。 是惩罚因子,用于控制对 的重视程度。 及 KL 散度,用于衡量两个分布的差异程度。- KL 散度的存在限制了参数更新的“力度”,使新参数尽量不迥异于原始参数。
由 经过 logit 变化和白化处理得到。 是分段函数:若提示词安全或其安全得分 小于 0.15,则为安全得分。- 否则,
就是有用性得分 。
最终,我们应当对
通过 GAtt 保持对话过程的一致性
GAtt 又称 “幽灵注意力” (Ghost Attention) 👻,它的引入主要是为了使模型在对话过程中保持前后话题的一致性。下图解释了什么是多轮对话的一致性:左图中,robot 在新的对话中“忘记了”要用 emoji 作答,而在右图中则始终遵循这一规则。
幽灵注意力的实现,是通过 采样那些保持对话过程一致的样例 来对模型进行微调。为了得到这些样例,在采样时,给多轮对话中用户输入的所有提示语句都加上前缀 instruction,保证模型每次对话时都能知道它应当遵循什么规则。而在微调时,则将这些前缀剔除。然而,这样做无法保证模型的输出和采样时一致,因而在计算损失的时候,需要掩盖当前句子之前的损失。
多模态?来看看 LLaMA3 的表现!
最后的最后,我们来看一下 LLaMA3 在多模态的表现,包括:图像识别 (Image Recognition) 、 视频识别 (Video Recognition) 、语音理解和生成领域 (Speech Understanding & Generation) 。
图像识别 (Image Recognition)
主要关注 LLaMA3 在 自然图像理解、文本理解、图表理解、多模态推理 等任务中的图像理解能力。用到的数据集包括:MMMU、VQAv2、AI2 Diagram、ChartQA、TextVQA、DocVQA。取得的成绩如下表所示:
Llama 3-V 8B | Llama 3-V 70B | Llama 3-V 405B | GPT-4V | GPT-4o | Gemini 1.5 Pro | Claude 3.5 | |
---|---|---|---|---|---|---|---|
MMMU (val, CoT) | 49.6 | 60.6 | 64.5 | 56.4 | 69.1 | 62.2 | 68.3 |
VQAv2 (test-dev) | 78.0 | 79.1 | 80.2 | 77.2 | -- | 80.2 | -- |
AI2 Diagram (test) | 84.4 | 93.0 | 94.1 | 78.2 | 94.2 | 94.4 | 94.7 |
ChartQA (test, CoT) | 78.7 | 83.2 | 85.8 | 78.4 | 85.7 | 87.2 | 90.8 |
TextVQA (val) | 78.2 | 83.4 | 84.8 | 78.0 | -- | 78.7 | -- |
DocVQA (test) | 84.4 | 92.2 | 92.6 | 88.4 | 92.8 | 93.1△ | 95.2 |
视频识别 (Video Recognition)
在视频识别方面,metaAI 使用了如下的数据集:1) PerceptionTest,评估模型 时间推理 (temporal reasoning) 的能力,关注于模型的记忆、抽象等技能,有包括描述、预测、解释等不同推理类型;2) NExt-QA,与前一个类似但更关注开放领域的问题;3) TVQA,评估模型 复合推理 (composition reasoning) 的能力;4) ActivityNet-QA,评估模型对长视频总结、理解的能力。
Llama 3-V 8B | Llama 3-V 70B | Gemini 1.0 Pro | Gemini 1.0 Ultra | Gemini 1.5 Pro | GPT-4V | GPT-4o | |
---|---|---|---|---|---|---|---|
PerceptionTest (test) | 53.8 | 60.8 | 51.1 | 54.7 | -- | -- | -- |
TVQA (val) | 82.5 | 87.9 | -- | -- | -- | 87.3 | -- |
NExT-QA (test) | 27.3 | 30.3 | 28.0 | 29.9 | -- | -- | -- |
ActivityNet-QA (test) | 52.7 | 56.3 | 49.8 | 52.2 | 57.5 | -- | 61.9 |
语音理解与生成 (Speech Understanding & Generation)
在语音理解方面,关注 语音识别 (speech recognition) 、语音翻译 (speech translate) 和 语音问答 (spoken question answer) 。在语音生成方面,主要评估使用 LLaMA3 嵌入向量的 逐字流输入模型 (token-wise input streaming model) 在规范化文本和写韵文这两个任务上的表现。
语音识别 (Speech Recogniton)
Llama 3 8B | Llama 3 70B | Whisper | SeamlessM4T v2 | Gemini 1.0 Ultra | Gemini 1.5 Pro | |
---|---|---|---|---|---|---|
MLS (English) | 4.9 | 4.4 | 6.2 (v2) | 6.5 | 4.4 | 4.2 |
LibriSpeech (test-other) | 3.4 | 3.1 | 4.9 (v2) | 6.2 | -- | -- |
VoxPopuli (English) | 6.2 | 5.7 | 7.0 (v2) | 7.0 | -- | -- |
FLEURS (34 languages) | 9.6 | 8.2 | 14.4 (v3) | 11.7 | -- | -- |
语音翻译 (Speech Translate)
Llama 3 8B | Llama 3 70B | Whisper v2 | SeamlessM4T v2 | |
---|---|---|---|---|
FLEURS (33 lang. → English) | 29.5 | 33.7 | 21.9 | 28.6 |
Covost 2 (15 lang. → English) | 34.4 | 38.8 | 33.8 | 37.9 |
语音问答 (Spoken Question Answer)
规范化文本和写韵文 (TN & PM)
Model | Context | Accuracy |
---|---|---|
Without Llama 38B | 3 | 73.6% |
Without Llama 38B | ∞ | 88.0% |
With Llama 38B | 3 | 90.7% |
规范化文本 (TN) 的准确率: 比较了使用/不使用 LLaMA 嵌入的模型,并使用不同的 right-context 值。
Model | Perference |
---|---|
PM for Llama 38B | 60.0% |
Streaming phone-only baseline | 40.0% |
Model | Perference |
---|---|
PM for Llama 38B | 63.6% |
Non-streaming phone-only baseline | 36.4% |
写韵文 (PM) 评估: 上例为带 llama38B 嵌入的 PM 与流式模型的对比;下例为与非流式模型的对比。
最后的最后:让我们简单总结下 metaAI 的技术路线
自 OpenAI 的 ChatGPT 诞生以来,大模型领域的更新换代愈发频繁。这一趋势不仅得益于各种技术的蓬勃涌现,更重要的是,开发大语言模型的路径已逐渐清晰并趋于成熟。若一家公司有意打造专属的大模型,很可能也能遵循这一明确路径迅速推出自己的产品。具体而言,该路径包含以下几个关键步骤:
- 通过各种手段优化注意力机制,核心有两方面:增强模型的 推理能力 和 推理速度。
- 利用强化学习或其他先进技术,进一步提升模型的对话交互能力,如 安全性、有用性、上下文一致性。
- 实现模型的多模态融合,以拓宽其应用场景和增强功能多样性,包括 图像、视频、语音 的。
LLaMA 系列模型从一代到三代的演进,便大致遵循了上述发展路径。 可以预见,在未来的一段时间内,该路线是通用且火热 🔥🔥🔥 的。