LLM 常见问题(微调部分)

2,783 阅读10分钟

1. 如果想要在某个模型基础上做全参数微调,需要多少显存?

目前大部分 LLM 默认为半精度,当在模型大小为 XB ,推理所需显存约为 X 的两倍,对于全参数微调所需显存普遍的说法是约为推理所需显存的 3-4 倍,包括模型推理(1倍)、梯度(1倍)、优化器状态(AdamW 2倍,SGD 1倍),也就是 X 的 6-8 倍。但实际测试看来全参所需显存约为推理所需显存的 8-10 倍。

2. 微调模型需要多大显存?

image.png

3. 为什么 SFT 之后感觉 LLM 傻了?

指令微调是为了增强(或解锁)大语言模型的能力。对于数据集应该选择多个有代表性的任务,每个任务实例数量不应太多,否则可能会潜在地导致过拟合问题并影响模型性能 。

同时,应该平衡不同任务的比例,并且限制整个数据集的容量(通常几千或几万),防止较大的数据集压倒整个分布。

4. 领域模型 Continue PreTrain 数据选取?

现有大模型在预训练过程中都会加入书籍、论文等数据,那么在领域预训练时这两种数据其实也是必不可少的,主要是因为这些数据的数据质量较高、领域强相关、知识覆盖率(密度)大,可以让模型更快适应。

5. 领域数据训练后,通用能力往往会有所下降,如何缓解模型遗忘通用能力?

如果仅仅使用领域数据集进行模型训练,模型很容易出现灾难性遗忘现象,为了解决这个问题通常在领域训练的过程中加入通用数据集。但对于领域数据集和通用数据集应该按照什么比例目前还没有一个准确的答案,一般领域数据与通用数据的比例在 1:5 到 1:10 之间

6. 领域模型Continue PreTrain ,如何让模型在预训练过程中学习到更多的知识?

预训练过程中,可以添加下游 SFT 的数据,可以让模型在预训练过程中就学习到更多的知识。例如:T5、ExT5、Glm-130b 等多任务学习在预训练阶段可能比微调更有帮助。

7. 进行SFT操作的时候,基座模型选用Chat还是Base?

在进行 SFT 时,选用 Chat 还是 Base 作为基座,需要根据 SFT 的数据量决定。如果数据量小于 10k,建议选用 Chat 模型作为基座进行微调;如果有 100k 以上的数据,建议在 Base 模型上进行微调。

8. 指令微调数据有什么格式要求?

指令数据一般为 json 格式,包含 Instruction、Input、Output 三个字段(Instruction 或 Input 可以为空)。

Instruction(指令):Instruction 是对模型的输入文本或问题进行进一步说明或约束的指令。它可以是一种特定的格式或标记,用于告诉模型如何处理输入数据,或者提供一些额外的信息,以便模型更好地理解和生成输出。Instruction的作用是为了描述任务。

Input(输入):Input 是模型实际接收的文本或数据。提供了指令待处理的对象,用于生成输出。

Response(输出):Response 是 LLM 生成的输出文本或回答。它是模型对 Instruction 和 Input 的处理结果。 Response 的内容取应当是理想的文本、回答、建议、解释等形式。

9. 领域模型评测集如何构建?

领域模型数据集通常通过构建专业知识选择题数据集来进行评测,例如医学领域大语言模型测评数据集 CMB 包含了医师考试、护理考试、医学考研等六类考试的题目。方便对模型的专业领域知识能力进行快速评测。但由于领域模型很有可能语义理解能力较差导致难以理解题目而无法正确作答。另一种方式是构建主观题数据集,模型完成作答后由专业人员根据一定标准进行打分或使用相似度比较模型评判模型生成结果和标准答案之间的相似度。

10. 领域模型词表扩增是不是有必要的?

不一定需要扩充领域模型词表,词表扩增真实解决的问题是解码效率的问题,给模型效果带来的提升可能不会有很大。但有些领域比较特殊,需要扩充词表。比如某些领域存在特定词汇,对于目标领域内存在的晦涩难懂的专有术语或特殊词汇,若这些词汇并不存在词表中,扩展词表就是有必要的。将这类特殊术语纳入模型的词库,能够增强模型对这些术语的理解与处理能力。

11. 训练中文大模型有什么经验?

如果模型在预训练阶段就包含足够的中文如 ChatGLM、Baichuan,可以直接利用其进行微调,如果模型在预训练阶段无中文或者中文数据含量较少的模型如 LLaMA,需要对其 tokenizer 进行修改,添加中文字词,同时进行二次预训练使其充分理解中文再进行 SFT 微调。

12. 对 LLM 进行指令微调的好处?

  1. 行为引导:LLM 的行为往往不易解释和控制。借助指令微调,我们可以输入指令使其学习,以引导模型行为,使其更好地满足特定任务的要求。
  2. 数据效率:LLM 训练通常依赖于大量数据,但在一些特定的任务或领域里,关键数据往往不够充足或难以采集。指令微调可以使我们仅利用少量特定任务的数据,结合大型模型的通用数据预训练知识,在数据受限的条件下也能够取得优异的性能。

13. 预训练阶段注入知识还是微调阶段注入知识?

知识是在预训练阶段注入的,而微调阶段是指在特定任务上的训练,以使预训练模型的通用知识和特定任务的要求相结合,激发模型的能力,使模型在特定任务上表现更好。

14. 想让模型学习某个领域或行业的知识,是应该预训练还是应该微调?

对于大模型来说是在预训练的阶段注入领域知识的,因此在训练行业大模型的时候最佳的方案是使用预训练与微调相结合的方案,先用篇章数据进行预训练以获取广泛的知识,再用问答数据进行微调,使模型更好的学习到特定领域的知识。

15. 多轮对话任务如何微调模型?

目前多轮对话微调有以下三种方法:

  1. User1、Assistant1、User2、Assistant2、User3 的文本都视为模型的输入部分,将 Assistant3 的文本视为模型的预测部分,只有 Assistant3 部分的 loss 参与权重更新。方法一这种方法的弊端在于,没有充分利用多轮对话的训练数据,Assistant1 和 Assistant2 的内容没有参与模型训练,这部分数据在训练时被浪费了。并且对于很多多轮对话数据而言,中间的 Assitant 回复部分的信息量更丰富详细,最后一个 Assitant 回复部分往往是“谢谢”、“不客气”等诸如此类的较为简短的文本。如果只使用这部分文本训练模型,会严重影响模型的训练效果。

  2. 将一条多轮对话数据,拆分成多条数据。例如将以上示例拆分成如下三条数据。方法二

相比方法一,方法二能够更加充分利用多轮对话中每一个 Assistant 的回复内容。但是弊端在于,需要将一个包含n轮对话的数据,拆分成n条数据,训练效率降低了n倍,训练方法不高效。

  1. Firefly 项目训练多轮对话模型时,采取了一种更加充分高效的方法。如下图所示,将一条多轮对话数据拼接之后,输入模型,并行计算每个位置的 loss,只有 Assistant 部分的 loss 参与权重更新,项目地址方法三为什么这种做法是可行的?答案在于因果语言模型的 attention mask。以 GPT 为代表的 Causal Language Model(因果语言模型),这种模型的 attention mask 是一个对角掩码矩阵,每个 token 在编码的时候,只能看到它之前的 token,看不到它之后的 token。 所以 User1 部分的编码输出,只能感知到 User1 的内容,无法感知到它之后的文本,可以用来预测 Assistant1 的内容。而 User2 部分的编码输出,只能看到 User1、Assistant1、User2 的内容,可以用来预测 Assistant2 的内容,依此类推。对于整个序列,只需要输入模型一次,便可并行获得每个位置的 logits,从而用来计算 loss

16. 为什么微调后的模型会出现灾难性遗忘?

灾难性遗忘是指在模型微调过程中,当模型在新任务上进行训练时,可能会忘记之前学习到的知识,导致在旧任务上的性能下降。微调过程中使用的新任务数据与预训练数据或旧任务数据的分布存在差异。如果新任务的数据分布与预训练数据差异较大,模型可能会过度调整以适应新任务,导致旧任务上的性能下降。同时随着 epoch 的上升,对旧任务的遗忘也会越多,通常 epoch 只用设置为 1(具体需要看数据量大小和任务需求)。

17. LLM 进行 SFT 操作的时候在学习什么?

在有监督的数据集上进行 SFT 训练,可以利用上下文信息等监督信号进一步优化模型。当进行有监督微调时,模型权重会根据与真实标签的差异进行调整。通过这个微调过程,模型能够捕捉到标签数据中特定于某些任务的模式和特点。使得模型更加精确,更好地适应某一特定任务。

18. 预训练和 SFT 操作有什么不同

预训练是通过无监督学习从大规模的文本语料库中学习语言模型的表示能力和语言知识,让模型学会接龙。

SFT 的目标是在特定的任务上进行训练,模型会利用预训练阶段学到的语言表示和知识,通过有监督的方式调整模型参数,以适应特定任务的要求。

19. 样本量规模增大,训练出现 OOM 错误如何解决?

  1. 减小批量大小:减少每次训练需要处理的数据量,从而减少内存使用。
  2. 使用梯度累积:在不减小批量大小的情况下,减少内存使用。
  3. 使用模型并行:将模型的不同部分放在多个 GPU 设备上进行训练,从而减少每个设备需要的内存。