7.2. Fine-Tuning to follow instructions

本节的目标是展示如何微调一个已经预训练的模型以遵循指令,而不仅仅是生成文本,例如,作为聊天机器人响应任务。

数据集

为了微调一个 LLM 以遵循指令,需要有一个包含指令和响应的数据集来微调 LLM。训练 LLM 以遵循指令有不同的格式,例如:

  • Apply Alpaca 提示样式示例:

Below is an instruction that describes a task. Write a response that appropriately completes the request.

### Instruction:
Calculate the area of a circle with a radius of 5 units.

### Response:
The area of a circle is calculated using the formula \( A = \pi r^2 \). Plugging in the radius of 5 units:

\( A = \pi (5)^2 = \pi \times 25 = 25\pi \) square units.
  • Phi-3 提示样式示例:

<|User|>
Can you explain what gravity is in simple terms?

<|Assistant|>
Absolutely! Gravity is a force that pulls objects toward each other.

训练一个 LLM 使用这些数据集而不是仅仅使用原始文本,可以帮助 LLM 理解它需要对收到的问题给出具体的回答。

因此,处理包含请求和答案的数据集时,首先要做的事情之一是将这些数据建模为所需的提示格式,例如:

# Code from https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/ch07.ipynb
def format_input(entry):
instruction_text = (
f"Below is an instruction that describes a task. "
f"Write a response that appropriately completes the request."
f"\n\n### Instruction:\n{entry['instruction']}"
)

input_text = f"\n\n### Input:\n{entry['input']}" if entry["input"] else ""

return instruction_text + input_text

model_input = format_input(data[50])

desired_response = f"\n\n### Response:\n{data[50]['output']}"

print(model_input + desired_response)

然后,像往常一样,需要将数据集分为训练集、验证集和测试集。

批处理和数据加载器

然后,需要将所有输入和期望输出进行批处理以进行训练。为此,需要:

  • 对文本进行标记化

  • 将所有样本填充到相同的长度(通常长度将与用于预训练LLM的上下文长度一样大)

  • 在自定义合并函数中将输入向右移动1以创建期望的标记

  • 用-100替换一些填充标记,以将其排除在训练损失之外:在第一个endoftext标记之后,将所有其他endoftext标记替换为-100(因为使用cross_entropy(...,ignore_index=-100)意味着它将忽略目标为-100的情况)

  • [可选] 使用-100掩盖所有属于问题的标记,以便LLM仅学习如何生成答案。在应用Alpaca风格时,这将意味着掩盖所有内容直到### Response:

创建完这些后,是时候为每个数据集(训练、验证和测试)创建数据加载器了。

加载预训练LLM & 微调 & 损失检查

需要加载一个预训练的LLM进行微调。这在其他页面中已经讨论过。然后,可以使用之前使用的训练函数来微调LLM。

在训练过程中,还可以查看训练损失和验证损失在各个时期的变化,以查看损失是否在减少以及是否发生了过拟合。 请记住,过拟合发生在训练损失减少但验证损失没有减少甚至增加时。为避免这种情况,最简单的方法是在这种行为开始的时期停止训练。

响应质量

由于这不是一个分类微调,因此不太可能信任损失变化,因此检查测试集中的响应质量也很重要。因此,建议收集所有测试集生成的响应并手动检查其质量,以查看是否存在错误答案(请注意,LLM可能正确创建响应句子的格式和语法,但给出完全错误的响应。损失变化不会反映这种行为)。 请注意,也可以通过将生成的响应和期望的响应传递给其他LLM并要求它们评估响应来执行此审查。

验证响应质量的其他测试:

  1. 测量大规模多任务语言理解(MMLU): MMLU评估模型在57个学科(包括人文学科、科学等)中的知识和解决问题的能力。它使用多项选择题在从初级到高级专业的不同难度级别上评估理解能力。

  2. LMSYS聊天机器人竞技场:该平台允许用户并排比较不同聊天机器人的响应。用户输入提示,多个聊天机器人生成可以直接比较的响应。

  3. AlpacaEval AlpacaEval是一个自动评估框架,其中像GPT-4这样的高级LLM评估其他模型对各种提示的响应。

  4. 通用语言理解评估(GLUE): GLUE是九个自然语言理解任务的集合,包括情感分析、文本蕴含和问答。

  5. SuperGLUE 在GLUE的基础上,SuperGLUE包括更具挑战性的任务,旨在对当前模型构成困难。

  6. 超越模仿游戏基准(BIG-bench): BIG-bench是一个大规模基准,包含200多个任务,测试模型在推理、翻译和问答等领域的能力。

  7. 语言模型的整体评估(HELM): HELM提供了在准确性、鲁棒性和公平性等各种指标上的全面评估。

  8. OpenAI Evals OpenAI的开源评估框架,允许在自定义和标准化任务上测试AI模型。

  9. HumanEval 一组用于评估语言模型代码生成能力的编程问题。

  10. 斯坦福问答数据集(SQuAD): SQuAD由关于维基百科文章的问题组成,模型必须理解文本以准确回答。

  11. TriviaQA 一个大规模的琐事问题和答案数据集,以及证据文档。

还有很多很多其他的

遵循指令微调代码

您可以在https://github.com/rasbt/LLMs-from-scratch/blob/main/ch07/01_main-chapter-code/gpt_instruction_finetuning.py找到执行此微调的代码示例。

参考文献

Last updated