详细摘要 摘要
生成:2025-06-01 22:11摘要详情
- 音频文件
- BiliBili | IBM RethinkFun | 大模型微调看这个视频就够了 SFT NEFTune
- 摘要类型
- 详细摘要
- LLM 提供商
- openai
- LLM 模型
- gemini-2.5-pro-exp-03-25
- 已创建
- 2025-06-01 22:11:53
摘要内容
概览/核心摘要 (Executive Summary)
本内容主要围绕大型语言模型(LLM)的监督微调(Supervised Fine-Tuning, SFT)展开,详细介绍了提升微调效果的三个关键技术方面:对话模板(Chat Template)、仅针对回答进行微调(Completions Only)以及通过为嵌入层增加噪音来进行微调(NEFTune)。讲者强调,指令微调旨在让预训练后的模型能更好地利用其学到的知识回答人类问题,其与预训练在网络结构和损失函数上基本相同,主要区别在于训练数据。正确使用与预训练模型一致的对话模板至关重要,例如Llama 3.1的模板包含特殊token和角色标识。为提高训练效率和效果,可以仅对模型回答部分计算损失(Completions Only),通过损失掩码(loss mask)实现。NEFTune作为一种文本数据增强方法,通过给token的embedding添加随机噪声,增加样本丰富度,从而提升模型精度和泛化性,据称在Llama 2 7B上平均提升10%性能。最后,讲者介绍了如何利用Hugging Face TRL库中的SFTTrainer工具,通过简单配置即可实现上述微调策略,并支持分布式训练,大大简化了SFT的流程。
大模型微调 (SFT) 概述
- 定义与目的:监督微调(Supervised Fine-Tuning, SFT),也称指令微调,是在大模型预训练之后进行的微调过程。
- 讲者观点:> “大模型几乎所有的能力都是在预训练时获得的,但是预训练后的模型还不知道如何表达自己的知识。”
- 目的:让大模型能更好地用其学到的知识来回答人类提出的问题,而不是仅仅根据上文续写。
- 与预训练的比较:
- 网络结构:完全相同。
- Loss函数:基本相同。
- 训练数据:最大不同。
- 神经网络训练三要素:网络结构、Loss函数、训练数据。
- 版本发布:开源大模型通常会推出预训练版本和指令微调版本。
核心技术与概念
对话模板 (Chat Template)
- 重要性:开源大模型在出厂前进行指令微调时,都有自己格式的对话模板。用户在进行后续微调时,必须和原厂的对话模板保持一致,才能获得最佳效果。
- 结构示例 (Llama 3.1):
- 包含特殊token,如序列开始符、序列结束符。
- 将不同角色(如system, user, assistant)放入ID中。
- 每个content结束时加上序列结束的token。
- Hugging Face 数据结构:接受一个list,其中每个元素是一个字典,包含
role和content。role类型:system(系统设定),user(用户输入),assistant(大模型回答)。
- Tokenization 与 Chat Template:
- 每个大模型与其tokenizer是唯一对应的。
- Chat template也与tokenizer唯一对应,并配置在tokenizer的配置文件中(如Llama 3.1的
tokenizer_config.json)。 - 注意:讲者提及 > “最初版本的拉玛3.1的chat template里有bug,你可以按照我这里贴出来的代码修改一下”。(具体代码未在转录文本中展示)
- 代码调用流程:
- 生成对话列表。
- 通过tokenizer的
apply_chat_template方法,将其转化为输入给大模型的token序列。
- 推理时应用:提供问题,并在生成聊天模板时将
add_generation_prompt设置为True,模型会在问题后加上特定标记,引导其生成答案和序列终止符。
仅针对回答的微调 (Completions Only)
- 动机:
- 系统提示部分在每个样本中通常是相同的,无需重复计算其loss。
- 让大模型更专注于学习如何回答问题。
- 核心思想:只对整个序列中模型回答(答案)部分的token计算loss。
- 实现机制:Loss Mask
- 创建一个与token序列等长的
loss_mask。 - 需要计算loss的token(答案部分)对应位置标记为1。
- 不需要计算loss的token(问题、提示部分)对应位置标记为0。
- 最终loss = 每个token的loss * 对应的loss_mask值,然后求均值。
- 创建一个与token序列等长的
- 确定回答起始位置:
- 通过识别回答部分之前的特殊token序列。
- 示例 (Llama 3.1):起始回答部分前的token序列为
start_header_id,assistant,end_header_id, 两个换行符。 - 该位置之后的所有token的loss_mask设为1,之前为0。
- 代码实现关键步骤 (接近实际运行):
- 数据准备:包含
query和answer。 - Dataset 定义:在
get_item中返回经过tokenizer添加chat template后的文本。 - 模型加载:可使用量化加载,获取LoRA模型(原文为laa,推测为LoRA)。
- Collate 函数:
- 对一个batch的数据进行整理。
- 进行tokenize。
- 生成loss mask。
- 训练循环:
- 从dataloader加载数据(包含input_ids和loss_mask)。
- 模型前向传播得到logits。
- Label生成:
input_ids左移一位作为label(因为最后一个位置的输出没有label,所以去掉logits的最后一个位置)。 - 计算loss,乘以loss_mask,求均值。
- 反向传播,优化参数。
- 数据准备:包含
NEFTune (Noisy Embedding Fine-Tuning)
- 概念:一种针对文本的数据增强方法,通过给token的embedding随机增加噪声。
- 类比:计算机视觉领域的数据增强(旋转、翻转、调整亮度等)。
- 动机:
- 指令微调数据多为手动构造,采集代价大,数量相对较少。
- 增加样本丰富度,提高模型精度和泛化性。
- 原理:
- Token进入大模型的第一步是进行embedding。
- 在embedding向量空间中,意义相近的词(如“漂亮”和“美丽”)距离相近。
- 增加噪声可能使原始token在embedding空间中轻微移动,可能变为与其语义相近的token,从而等效于增加了新的训练样本。
- 实现步骤:
- 定义噪声系数
alpha(调节噪声强度)。 - 对
input_ids进行embedding。 - 计算序列维度
d_seq = sequence_length * embedding_dimension。 - 计算噪声范围的缩放因子:
scale = alpha / sqrt(d_seq)。- 讲者解释:> “除以序列维度的开方就是为了让不同序列长度的文本,它们和自己加了噪声的样本的欧式距离都是一样的,不会因为序列的长度不同而距离不同。”
- 给原始embedding的每一位随机加上从
-scale到+scale之间的一个随机数(原文提及Manow,推测为噪声范围或分布参数)。
- 定义噪声系数
- 效果:
- 根据原始论文,在Llama 2 7B模型上测试,NEFTune可使模型表现平均增加 10%。
- 代码修改:在原有针对回答计算loss的代码基础上,增加噪声系数,获取token的input_ids后进行embedding,然后计算噪声并添加到embedding上。
使用 TRL 库进行 SFT
- TRL (Transformer Reinforcement Learning) 库:Hugging Face提供的库,集成了SFTTrainer。
- SFTTrainer 功能:
- 集成了如“仅针对回答计算loss”、“NEFTune”等功能。
- 通过简单配置即可实现微调。
- 能够适配进行分布式训练。
- 代码实现步骤:
- 数据准备:
- SFTTrainer默认支持字典格式数据,包含
prompt和completion两个元素。 - 构建Dataset。
- SFTTrainer会自动利用tokenizer的chat template对数据进行变换。
- SFTTrainer默认支持字典格式数据,包含
- 模型加载:例如量化加载模型,生成LoRA模型。
- SFTConfig 配置:
- 指定
neftune_noise_alpha(NEFTune的噪声系数)。
- 指定
- DataCollator 定义:
- 用于对批量数据进行整理。
- 实现“仅对回答部分计算loss”时,需告知该函数判断回答开始的token序列。
- 示例:填入Llama 3.1 chat template中标志回答前的token序列。
- 开始训练:将模型、训练数据、SFTConfig以及DataCollator传入SFTTrainer并启动。
- 数据准备:
总结
讲者通过介绍对话模板、仅针对回答的微调(Completions Only)和NEFTune这三种核心技术,详细阐述了如何进行有效的大模型监督微调。核心观点是,遵循原厂对话模板、优化损失计算范围以及利用数据增强手段(如NEFTune)均能显著提升微调效果。最后,推荐使用TRL库的SFTTrainer简化整个微调流程。