继续聊聊LLM微调相关内容
haoteby 2025-01-15 13:31 2 浏览
在使用LLM时,我们收到的最常见的问题之一就是关于微调。每隔一个客户就会问他们是否应该对他们的模型进行额外的训练。
在大多数情况下,答案是否定的,他们不需要它。现代 LLM 无需微调即可满足许多商业应用的需求,例如帮助客户从花店订购鲜花的机器人。此外,他们没有数据来做到这一点,而且他们拥有的 20 个对话样本不算数(200 个也不算)。
训练和微调模型是一项昂贵的考验,如果可以的话,你真的应该避免它,并将省下的钱花在去巴厘岛或任何你喜欢的度假胜地的旅行上。
但是,有些情况下你确实需要它。例如,如果你希望 LLM 遵循非常具体的聊天格式,或者在非常具体的领域拥有知识,或者你想通过训练一个小模型来执行非常专业的任务,而不是使用具有数千亿个参数的大型 LLM,从而降低成本。这些都是通过微调创建定制模式的有效案例。
那么让我们看看如何实现这一目标。
何时进行微调
作为如上所述,只有在必要时才应该进行微调。首先尝试使用提示工程解决任务或构建RAG 系统。如果失败 — 考虑微调。
Finetuning 有以下缺点:
- 需要花费金钱和时间
- 你需要良好的训练数据,否则它将无法工作
- 即使操作正确,也会导致幻觉更频繁出现,因为我们正在向最初并非为此量身定制的模型添加新行为。如果您对模型进行定期更新,那么在某个时候几乎肯定会发生这种情况,这被称为漂移,因此您必须评估您的模式。
一旦你考虑了以上所有因素,仍然认为一般的LLMs还不够好——你就需要进行微调。
数据
为了微调,你将需要特定格式的数据,称为指令数据集。
从何处获取数据
您可以使用许多开放数据集,例如用于模型对齐的 Anthropic HH-RLHF 数据集、用于医疗保健的 MIMIC-III 和用于编码的 CodeSearchNet。
- 特定领域数据集:医学、法律、编码等
- 特定任务数据集有助于训练模型执行一项特定任务,并制作RPA
- 具有通用知识的通用数据集,通常是通过从互联网上爬取的数据创建的
- 对齐数据集:用于格式、样式和安全对齐
Hugging Face Hub 有很多可用于不同领域的指令数据集,我建议从那里开始。
但既然你决定进行微调,你可能已经拥有了数据,因此你需要创建数据集。否则,你为什么要这么做呢?
如果样本不足,可以使用大型 LLM(如 ChatGTP)通过从现有数据进行推断来生成合成数据。稍后会谈到这一点。
数据要求
数据集大小取决于模型大小、任务复杂度和训练方法。OpenAI 等公司正在使用包含数百万个项目的庞大数据集,这对于大多数公司来说是不可行的,因为成本太高,所以实际上我们将有数千个样本。
对于沟通风格调整等简单变化,你不需要大量样本,几百个就够了,对于特定领域的知识训练,你将需要几千到几十万个样本,具体取决于领域。一般来说,样本越多越好,最好至少有几千个样本。
数据质量的重要性不亚于数量,甚至可能高于数量。你需要确保数据在含义和格式上都正确反映了你想要建模的行为。我想强调格式——你希望模型以用户能够理解的方式输出信息,无论是清晰度还是风格。
数据准备
数据准备是关键步骤,因为数据质量直接影响模型的性能和准确性。准备数据涉及多个过程,以确保数据干净、相关且适合训练:
1.重复数据删除
重复的数据点会增加训练成本、引入不必要的噪音,并导致模型过度拟合或出现偏差。以下是常见的方法:
文本规范化:
- 将文本转换为小写。
- 删除特殊字符、多余的空格和标点符号以使内容标准化。
基于哈希的重复数据删除:
- 生成规范化文本的哈希值。一种常用的技术是MinHash ,它捕获项目的本质或“语义指纹”,而不是其确切的文本。这样即使格式或细节不同,也可以识别重复项。您可以使用datasketch等库来做到这一点
- 比较哈希值并删除匹配的条目
基于矢量的重复数据删除:
- 将项目转换为向量表示(嵌入)以测量它们的语义相似性。
- 使用Quadrant、Pinecone或Weaviate等矢量数据库来有效地查找相似的物品。
- 在检索到的项目上应用交叉编码器,以更准确地计算其相似度得分。此步骤可帮助您自信地识别和消除近似重复项。
2. 个人信息删除
您需要对数据进行去身份识别,因为您不希望模型学习(然后告诉所有人)人们的个人信息(除非这是您想要的)。这可能会产生严重的法律和道德影响,尤其是在 GDPR 等法规下。此外,通常情况下,个人数据与领域知识无关。
去识别化:
- 使用正则表达式模式检测常见格式(例如电子邮件或电话号码)。
- 利用专为命名实体识别 (NER) 设计的预训练 NLP 模型来识别和编辑个人数据。
特定领域过滤:
- 您可以根据数据上下文创建过滤器。例如,医疗数据可能需要删除 HIPAA 定义的健康相关标识符。
3. 净化
您的数据集可能包含会对模型行为产生负面影响的内容:
恶意内容:
- 检测并过滤针对大型语言模型(例如,提示注入)、脚本、XSS、SQL 注入代码等的嵌入命令。
- 自动扫描工具或专门的基于 LLM 的分类器可以帮助识别此类模式。
不当语言:
- 过滤诅咒之语、诽谤之语、攻击性内容和俚语。
4.基于规则的过滤
数据集中的数据并非都与您的域或任务相关。基于规则的过滤有助于消除不相关或有害的内容:
- 根据任务定义排除标准。例如,如果您正在训练财务模型,请排除非财务数据。
- 使用关键字搜索、短语或主题建模来识别不相关的内容。
我建议使用混合方法:
- 首先使用简单的工具:
- 基于正则表达式或关键字的模式搜索,例如识别电子邮件地址或电话号码。
- 在其余项目上使用 高级技术:
- 让 LLM 担任评判员来评估数据的相关性或质量。例如,让 LLM 标记某项内容是否适合训练任务。
- 使用专门的 ML 模型执行复杂的清理任务,例如检测和过滤有害语言。HuggingFace 上有大量针对此任务的预训练模型。
数据评估
完成所有这些步骤后,我建议使用单独的管道来检查数据质量。这可以由人工完成,如果您只有几百个样本,您可以这样做。但如果有数千个,那就不太可能了。因此,再次强调,您可以使用LLM 作为判断方法,或使用更简单的分类器模型进行自动评估。例如,请参阅 HuggingFaceFW/fineweb-edu-classifier。
对于 LLM,你可以使用如下提示:
您是数据质量评估员。您的目标是评估指令及其相应答案的质量。确定答案以清晰、准确和完整方式解决给定任务的有效性。
评估标准:
- 相关性:答案是否直接针对指令?
- 清晰度:答案是否清晰易懂?
- 完整性:答案是否提供了完成指令所需的所有必要信息?
- 准确性:答案中的信息是否真实正确?
指示:
- 仔细阅读所提供的说明并回答。
- 为上述每个评估标准提供一个分数(1-5)。
- 1 = 非常差
- 5 = 优秀
3. 用针对每个标准的具体例子或观察结果来证明你的分数。
评估示例:
Instruction: Explain the water cycle.
Answer: The water cycle involves evaporation, condensation, and precipitation, moving water between the Earth's surface and atmosphere.
Your Evaluation:
<Relevance>: 5 - The answer directly explains the water cycle.
<Clarity>: 4 - The answer is clear but could elaborate on each step.
<Completeness>: 3 - Missing details on processes like runoff or groundwater flow.
<Accuracy>: 5 - The provided information is correct.
Now, evaluate the following instruction-answer pair:
Instruction: [Insert instruction here]
Answer: [Insert answer here]
这里可接受的阈值由你决定,一般我会从 80-90% 开始。
还要注意你使用的 LLM 类型,以及 LLM 具有某些偏见(几乎像人类一样):
- 他们更喜欢冗长、冗长和有争议的答案,而不是简洁的答案,即使较短的答案更正确
- 列表中排在第一位的项目通常比其他项目更受模型青睐。这也称为“小鸭子综合症”。如果您正在创建偏好数据集(稍后会详细介绍),这一点很重要。
- 模型偏差 — 来自同一家族的 LLM 可能更喜欢由同一家族的模型生成的数据。如果您要生成用于训练的合成数据,这一点很重要。
数据集格式
这里有几种流行的格式,它们都很小并且使用 JSON,所以你可以使用其中任何一种。
OpenAI 格式
OpenAI 的微调过程采用 JSONL(JSON 行)格式,其中每一行代表一个不同的训练示例。
{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Can you explain the concept of photosynthesis?"},
{"role": "assistant", "content": "Photosynthesis is the process by which green plants convert sunlight into chemical energy."}
]
}
Alpaca数据集格式
由斯坦福基础模型研究中心开发。此数据集中的每个条目结构如下:
{
"instruction": "Describe the structure of an atom.",
"input": "",
"output": "An atom consists of a nucleus containing protons and neutrons, with electrons orbiting this nucleus."
}
ShartGPT
ShareGPT 数据集格式旨在捕捉用户与 AI 助手之间的多轮对话,可容纳“人类”、“GPT”、“观察者”和“功能”等各种角色。这种结构可以表示复杂的对话,包括工具交互和功能调用。
每个对话都表示为一个 JSON 对象,包含以下组件:
{
"conversations": [
{"from": "human", "value": "What is the capital of France?"},
{"from": "gpt", "value": "The capital of France is Paris."},
{"from": "human", "value": "Show me a map of Paris."},
{"from": "function_call", "value": "map_search('Paris')"},
{"from": "observation", "value": "<image of Paris map>"},
{"from": "gpt", "value": "Here is a map of Paris."}
],
"system": "You are a helpful assistant.",
"tools": "map_search"
}
微调技术
否现在您有了训练数据,让我们看看我们可以用它做什么。主要技术包括:
- 全面预训练
- Lora
- QLoRA
- 直接偏好优化(DPO)
全面预训练
这是在特定数据集上训练整个模型(所有层)以针对特定任务或领域进行优化的过程。理论上最有效,但需要大量计算能力,因为它需要在整个模型中进行反向传播。
由于我们直接调整模型权重,因此会带来一定的风险:
- 过度拟合的风险:由于所有权重都经过更新,因此对微调数据集进行过度拟合的风险更高,尤其是在数据集较小的情况下。
- 丧失通用性:微调模型可能会丧失其通用能力和先前的知识
那么我们需要多少内存来进行完全重新训练?我们需要至少加载以下内容进行训练:
Model Prams + Gradients + Activations + Optimizer States
- Model Parameter and Gradients:
- 7B 模型:约 70 亿个参数,
- 12B 模型:约 120 亿个参数,12 *10?*4 = 48GB
每个参数通常需要 4 个字节(FP32 精度)或 2 个字节(FP16 精度)。我们假设 2 个字节,因此
- 对于 7B 型号 7*10?*2 = 14GB
- 对于 12B 型号 12*10?*2 = 24G
Gradients为每个参数另外添加 2 个字节,因此:
- 对于 7B 型号 7*10?*2 = 14GB
- 对于 12B 型号 12*10?*2 = 24G
2. Activations:
更大的批处理大小以及更长的序列长度会增加内存需求。对于典型的批处理大小为 8-32 且序列长度为 512 个 token 的情况,激活内存可能会增加:
- 7B 型号:10–20 GB。
- 12B 型号:15–30 GB。
3.Optimizer States:
像 Adam 这样的优化器需要内存来存储其他状态(例如梯度和矩估计)。Adam 需要两个额外的参数,每个参数有 3 个状态,因此:
- 7B型号:14GB * 2 * 3 = 42GB
- 12B型号:24GB * 2 * 3 = 72GB
还有一些其他的东西会消耗内存,所以我们认为7B 型号至少需要 14 + 14 + 10 + 42 = 80GB。
对于小型模型来说,这需要很大的内存,你可以想象对于任何大型模型来说,需要多少内存。因此,完全重新训练是不切实际的,而且很少使用。那么有什么替代方案呢?
LoRa
假设你想改变模型的行为,但不想改变整个模型。改变模型行为意味着改变它的权重,从而改变输出。这里有个窍门——如果我们能以某种方式修改模型输出而不改变它们的权重……
当然有办法。在强力解决方案中,我们可以从技术上将模型输出输入到另一个模型中,以对其进行转换。这确实可行……只是,我们现在有两个模型,而且增加了许多复杂性。
但是如果我们可以在模型上添加一个过滤器,这样既可以保持原始模型层完整,又可以改变其输出,那会怎样呢?这有点像戴上 AR 眼镜。你看到的世界不同了,但世界并没有改变。
这就是 LORA 的基本原理。我们冻结原始模型权重,并通过添加一个称为 Lora 矩阵的额外权重矩阵进行变换,这样它就形成了一个更小的额外可训练层。
这里:
- Wnew — 新权重
- Wpre-trained — 原始模型重量
- ΔW — 可训练权重调整
我们如何计算这个 Lora 矩阵?我们使用标准方法对该附加矩阵(而不是原始模型)进行微调/训练,以便它学习如何预测期望结果与原始模型结果之间的差异。
其妙处在于,Lora 矩阵可以比原始模型权重矩阵小得多。这就是为什么它被称为低秩自适应,矩阵的秩低于原始矩阵。
假设你有一个大小为 d 的权重矩阵:
它将具有 d*d 个元素。如果 d 为一百万,它将具有一万亿个元素。
现在这是 LoRa 的矩阵:
它将具有 d*r + r*d 个元素。如果 d 为一百万且等级 (r) 为 8,它将具有 1600 万个元素。
工作原理如下:
y = x * (W + ΔW) = x * W + x*(A*B)
- y:应用权重后的输出。
- x: 层的输入
- ΔW=A*B
这里:
- A:形状为 d*r 的矩阵,其中 r 是秩(为 LoRA 微调选择的小维数),d 与原始权重矩阵的维数相同
- B:形状为 r*d 的矩阵
或者以视觉形式:
等级的常见起始点是 8。在某些情况下,使用最高 256 的值会取得良好的效果,但您需要进行试验才能找到适合您的方法。使用较大的等级可以提高某些任务的性能,尤其是那些需要更强的表达能力来捕捉复杂模式的任务。然而,这也增加了过度拟合的风险,尤其是在较小的数据集上。当模型容量超过数据的复杂性时,这种风险在机器学习中是众所周知的。
在训练期间,我们需要将原始模型的权重 W 和微调模型的 ΔW 存储在内存中,同时仅计算“新”小矩阵 A 和 B 的梯度。这大大减少了所需的内存和计算能力。训练将更快,并且可以使用台式机 GPU 在 PC 上轻松微调 7b 模型。
不仅如此,我们可以有几个不同的“镜头”,就像这个一样,我们可以把它们放在基础模型上,而不需要改变它。
LoRA 微调通常可以实现与完全微调相当的性能,特别是当低秩近似非常适合该任务并且可以在不冒基础模型退化风险的情况下测试或应用 LoRA 适配器时。
QLoRA
与 LoRa 相同,但为了降低内存占用,我们将基础模型量化为自定义数据类型,通常为 NF4(4 位普通浮点)。常规模型使用 32 位或 16 位浮点作为存储权重的基本数据类型。
NF4 使 QLoRA 能够保留基础模型的大部分准确性,同时显著减少内存使用量和计算需求。
量化的思想是:
- 网络中的大多数权重无论如何都是 0
- NF4 根据实际数据统计来优化值的分布,而不是使用浮点值的线性分布
对于 LoRa 传递,我们仍将使用采用 32 位或 16 位浮点的常规模型,以便拥有更多的学习范围。
使用 QLoRa 可以将 GPU 内存使用量减少 40% 至 70%。但是,这样做是有代价的——QLoRA 的训练速度比 LoRA 慢约 30%,并且量化模型质量略有下降。
即使对于非常大的模型(例如 LLaMA 或基于 GPT 的架构),它也能很好地运行。
根据(人类)偏好进行微调
微调对于训练模型执行特定任务非常有效,但重要的不仅是模型的功能,还有它如何与人类互动。如果我们想创建一个语言模型助手,我们不能直接使用预先训练的模型——即使它拥有所需的知识,它也无法智能地回答用户的查询。
教模型与人类交流的过程称为对齐。有多种定义方法,我将使用Antropic对 3H 的定义:
- Helpful——回复应该解决用户的问题。
- Harmless——响应不应该对用户造成伤害。
- Honest——回答应事实准确
传统方法在这里没有多大帮助,因此开发了一套新的技术。
任何此类技术的想法都是拥有一个类似于我们上面讨论的数据集,其中还明确指出了人类的偏好或价值观。这可能包括对文本质量、语气、风格或事实正确性的反馈。通常,数据集项目有多个响应选项,每个选项都按偏好排序。
我敢打赌,你一定见过 ChatGPT 在生成答案时为你提供多个选项——他们这样做是为了收集类似的数据集。问答网站通常有喜欢或赞成/反对系统,这些系统也可以用作训练数据。如果你从互联网上抓取数据——事后清理很重要,数据集可能包含大量垃圾。
例如:
用户:“我现在感觉工作和生活让我不堪重负。很难坚持下去。”
答复选项:
- 选项 A:“我很抱歉您有这种感觉。您是否考虑过与您信任的人或专业顾问谈谈?”
- 选项 B:“你到底是什么样的男人,总在抱怨?喝点伏特加就没事了。”
人性化偏好:
- 首选答案:选项 A(在同理心和清晰度方面排名最高)。
- 排序:选项A>选项B。
理由:
- 选项 A表现出同理心,承认用户的感受并提供可行的建议。
- 选项 B忽视了用户的感受并且没有提供任何建设性的帮助。
或者 JSON 格式:
{
"context": "I'm feeling overwhelmed with work and life right now. It's hard to keep going.",
"responses": [
{
"text": "I'm sorry you're feeling this way. Have you thought about talking to someone you trust or a professional counselor? It might help to share your feelings.",
"rank": 1
},
{
"text": "What kind of man are you, complaining like that? Just drink some vodka - you’ll be fine.",
"rank": 2
}
]
}
一旦获得了这些数据,您就可以使用以下技术:
带有人类反馈的强化学习(RLHF)
这是偏好一致的基石。这个想法与训练狗非常相似,在多次迭代中,你会奖励狗做对的事情,惩罚做错的事情。在这种情况下,你扮演奖励模型角色,而狗扮演基础模型角色。
因此,有一个单独的奖励模型,该模型经过训练,可以使用成对比较来预测人类偏好(例如,“答案 A 比答案 B 更好”)。基本上,我们训练一个奖励模型来预测答案的排名。
这样做是为了在我们拥有奖励模型后不必使用人类——它可以作为进一步训练过程中人类反馈的代理。
然后使用强化学习进一步微调主模型,其中奖励信号来自使用强化学习训练的奖励模型,通常经过多次迭代。基础模型不会在此过程中获得新知识,而是学会使用和传达已有的知识。研究表明,使用小型高质量数据集比使用质量差的大型数据集要好得多(参见 LIMA 研究:对齐少即是多)。
这种方法允许奖励模型发出复杂的奖励信号,包括正确性、相关性、安全性以及各种政治审查废话。它还允许我们使用我们的奖励模型来训练多个基础模型以实现偏好对齐。
缺点也很明显。现在我们必须训练两个模型而不是一个,然后对基础模型进行多次迭代微调。这在计算上很昂贵、复杂,而且耗时。
此外,奖励模型存在过度拟合和基础模型性能下降的风险。
为了避免复杂化,我们提出了另一种方法:
直接偏好优化(DPO)
这可能是你最接近实现鱼与熊掌兼得的办法了。
它在 Rafael Rafailov 等人撰写的论文《直接偏好优化:你的语言模型其实是一个奖励模型》中被引入。他们有一个天才的想法:如果我们跳过中间的奖励模型输出,直接使用标准监督学习将模型与人类偏好对齐,会怎么样?
因此,这里的区别在于,我们没有单独的奖励模型,也不使用强化学习,而是直接用标准监督学习方法更新基础模型。
监督学习通常使用基于梯度的优化(例如随机梯度下降)来直接根据标记数据调整基础模型权重。DPO 在时间和成本方面比 RLFH 好得多,因为它不需要多次迭代和单独的模型,但在许多情况下,尽管在某些条件下,它也能提供与基础模型类似的性能和对齐。
这种方法需要高质量的细粒度数据,它对质量的敏感度比 RLHF 更高。数据集中的偏好数据必须足够且直接。如果您有这样的数据集或能够创建一个数据集 — DPO 可能是最好的选择。
相关推荐
- 简单Labview实操案例
-
有几位条友私信我说Labview是怎么学的,怎么才能学好Labview,今天给大家简单介绍一下,如果想学上位机,Labview是相对来说比较容易上手的,而且开发速度也比较快,但是运行时候比较吃内存,...
- 关于LabVIEW用于仪器测控的自动测试程序的程序框架的选择问题!
-
有很长一段时间没有在公众号平台上输出、总结关于LabVIEW的知识文字内容了!主要是这段时间自己本职工作任务甚为繁重,加上各种家庭事宜的牵绊,耗费了过多的时间和精力,也就无力及时更新了。今天是端午节假...
- LabVIEW编程基础:分割条控件的使用
-
1、分割条控件简介同其它高级编程语言类似,在LabVIEW中分割条控件也是界面设计中常用的一种控件元素,利用分割条控件可以将前面板划分为多个独立的区域,每个区域都是一个单独的窗格,这些窗格具有前面板的...
- csgo一直显示正在连接到csgo网络怎么办?三招帮你解决
-
CSGO是一款射击类的游戏,它的全名叫反恐精英:全球攻势,是一款由VALVE与HiddenPathEntertainment合作开发、ValveSoftware发行的第一人称射击游戏,相信很...
- cs1.6没有bot怎么办
-
Hi~大家好啊,这里是聚合游戏,每天为你分享游戏相关的内容,喜欢的快来关注哟~...
- 《反恐精英:全球攻势2》 漏洞暴露玩家的IP地址
-
#文章首发挑战赛#据报道,在全球知名的电子游戏——CS2(《反恐精英:全球攻势2》)中存在一个HTML注入漏洞,这个漏洞被广泛利用来在游戏中注入图片并获取其他玩家的IP地址。...
- 《电子宠物》《007黄金眼》《雷神之锤》入选世界电子游戏名人堂
-
世界电子游戏名人堂5月8日公布了新的四位入选者《防卫者》《电子宠物》《007黄金眼》和《雷神之锤》,以向改变游戏行业规则的经典游戏致敬。世界电子游戏名人堂每年都会表彰那些具有持久热度并对视频游戏行业或...
- V社修复《反恐精英2》游戏漏洞:可抓取玩家IP地址、发起XSS攻击
-
IT之家12月12日消息,Valve旗下《反恐精英2》游戏被曝光新的安全漏洞,攻击者通过注入恶意代码来抓取玩家的IP地址,并能对同一游戏大厅中的所有玩家发起跨站脚本攻击(XSS)。攻击...
- 粉丝自制《CS》1.6重制版将于2025年登陆Steam
-
基于Valve官方起源引擎SDK,由多位“CSPromod”粉丝项目前开发人员从头构建的《反恐精英》1.6版本重制版《CS:Legacy》日前宣布将于2025年在Steam发布。开发团...
- 知名网游源代码泄漏 ,外挂潮将来?
-
SteamDatabase近日发布消息称Valve旗下游戏《反恐精英:全球攻势》(CS:GO)与《军团要塞2》(TF2)的源代码疑遭泄露。据了解,游戏源代码如果泄露的话,黑客可以更为轻松地开发出外挂,...
- 求斐波那契数列(Fibonacci Numbers)算法居然有9种,你知道几种?
-
ByLongLuo斐波那契数列...
- 三维基因组:Loop结构 差异分析(2)
-
通过聚合峰分析进行可视化既然已经找出了“WT”和“FS”条件之间的差异loop结构,就可以利用聚合峰分析(APA)来直观地展示loop结构调用的质量。APA是一种以Hi-C数据中的中心loop像...
- 用Excel制作动态图表(动态名称法)
-
动态图表也称交互式图表,指图表的内容可以随用户的选择而变化,是图表分析中比较高级的形式。使用动态图表能够突出重点数据,避免被其他不需要的数据干扰,从而提高数据分析效率。一个好的动态图表,可以让人从大量...