英文大语言模型中文指令微调实战指南
Part1 前言
在之前的继续预训练(Continual Pre-training)讲解中,我们已经对从数据处理到训练、预测的整个流程有了基本了解。实际上,指令微调(Instruction Fine-tuning, SFT)的流程与预训练类似,但在数据构造和模型适配上有所不同。
当我们选择好一个大语言模型后,例如 ChatGLM、LLaMA、Bloom 等,要想使用它进行中文指令微调,必须深入理解三个方面:输入数据的格式、Tokenization 机制、以及模型的使用方式。本文将基于 Chinese-LLaMA-Alpaca 项目的训练代码,详细拆解指令微调的核心步骤。
Part2 数据构造
数据的输入是微调的基础。一般情况下,我们需要在模型的官方代码中找到数据输入的部分,或者参考其他开源项目的数据预处理逻辑。建议先找一份小的数据集,单独运行预处理脚本,观察输出结果,特别是 input_ids 中的特殊标记和 labels 的构造方式。
2.1 数据格式规范
指令数据通常由三部分组成:
- Instruction (instruct): 提示指令,描述任务。
- Input (query): 文本输入,可选,为空时仅依赖指令。
- Output (answer): 返回的结果,即模型需要生成的内容。
构造样本时,一般将 Instruction 和 Input 拼接作为 Prompt,最终对 Output 进行预测。需要注意的是,不同模型对 Prompt 的格式要求不同,例如 LLaMA 系列常用 Alpaca 格式,而 ChatGLM 有特定的对话模板。
PROMPT_DICT = {
"chatglm_input": "{instruction}{input}",
"alpaca_input": (
"Below is an instruction that describes a task. "
"Write a response that appropriately completes the request.\n\n"
"### Instruction:\n{instruction}{input}\n\n### Response: "
),
"bloom_input": "Human: \n{instruction}{input}\n\nAssistant: \n",
}
2.2 Token ID 与 Labels 构建
假设我们有样本:我爱北京天安门,你喜欢什么?,分词后得到 token 序列,转换为 token_id。对于 Output 我喜欢故宫,同样转换为 token_id。
一般情况下,Output 前后会被标识符包裹,如 bos_token_id (开始) 和 eos_token_id (结束)。样本的 input_ids 结构如下:
[Instruction_Tokens] + [bos_token_id] + [Output_Tokens] + [eos_token_id]
关于 labels 的构建,关键在于损失计算的范围。我们只希望模型学习生成 Output 部分,而不需要为 Instruction 部分计算损失。因此,Instruction 部分的 labels 应填充为 -100(IGNORE_INDEX),Output 部分的 labels 则为对应的 token_id。
示例:
- Input IDs:
[12, 112, ..., 545, 1, 12, 2346, 654, 2]


