XTuner微调LLM

书生·浦语LLM实践营-笔记4

Posted by Stanlei on May 12, 2024

0 课程背景

XTuner 一个大语言模型&多模态模型微调工具箱。 MMRazor MMDeploy 联合开发。

  • 🤓 傻瓜化: 以 配置文件 的形式封装了大部分微调场景,0基础的非专业人员也能一键开始微调
  • 🍃 轻量级: 对于 7B 参数量的LLM,微调所需的最小显存仅为 8GB消费级显卡✅,colab✅

本节课主要介绍了如何基于XTuner微调一个具有个人认知的助手,以及如何使用XTuner微调多模态LLM。

1 课程笔记

Finetune:增量预训练和指令跟随是经常会用到两种的微调模式

  • 增量预训练微调
    • 使用场景:让基座模型学习到一些新知识,如某个垂类领域的常识
    • 训练数据:文章、书籍、代码等
  • 指令跟随微调
    • 使用场景:让模型学会对话模板,根据人类指令进行对话
    • 训练数据:高质量的对话、问答数据
  • image-20240512115818311

LoRA

  • 核心思想:通过低秩分解来模拟参数的改变量
  • img
  • 技术原理:
    • 在涉及到矩阵相乘的模块,在原始的PLM旁边增加一个新的通路,通过前后两个矩阵A,B相乘,第一个矩阵A负责降维,第二个矩阵B负责升维,中间层维度为r,从而来模拟所谓的本征秩(intrinsic rank)
    • r«d,r是矩阵的秩,这样矩阵计算就从d x d变为d x r + r x d
    • 在下游任务训练时,固定模型的其他参数,只优化新增的两个矩阵的权重参数,将PLM跟新增的通路两部分的结果加起来作为最终的结果
    • Transformer的权重矩阵包括Attention模块里用于计算query, key, value的Wq,Wk,Wv以及多头attention的Wo,以及MLP层的权重矩阵,LoRA只应用于Attention模块中的4种权重矩阵,而且通过消融实验发现同时调整 Wq 和 Wv 会产生最佳结果
  • 相较其他方法消除了推理延迟(因为是将BA加到W上)
  • 可以通过可插拔的形式切换到不同的任务
  • img

QLoRA

  • 背景:主要是量化微调的角度减少了显存占用
    • 微调大模型非常昂贵,以LLaMA参数模型为例,16 bit微调需要超过780GB的GPU内存
  • 技术原理
    • 包含一种低精度存储数据类型(通常为4-bit)和一种计算数据类型(通常为BFloat16)
    • 将预训练模型量化为 4 bit,然后添加一小组可学习的低秩适配器权重进行微调
      • 提出了两种技术实现高保真4bit微调
        • 4bit NormalFloat(NF4)
        • 双量化:对第一次量化后的那些常量再进行一次量化,减少存储空间
      • 分页优化器:使用NVIDIA统一内存特性,该特性可以在GPU偶尔OOM的情况下,进行CPU和GPU之间自动分页到分页的传输,以实现无错误的 GPU 处理
    • 在实践中,QLoRA权重张量使用时,需要将低比特张量去量化为BFloat16,然后在16位计算精度下进行矩阵乘法运算

XTuner

  • 简介
    • image-20240512120644585
  • 对比LLaMA-Factory
    • 325901204-9c9dfdf4-1efb-4daf-84bf-7c379ae40b8b
    • 325901627-5ba973b8-8885-4b72-b51b-c69fa1583bdd
  • 快速上手
    • image-20240512121145653
    • image-20240512121208736
    • image-20240512121225806

多模态LLM微调

  • image-20240512121350056
  • image-20240512121409635
  • LLaVA方案
    • image-20240512121445436
  • 主要分为预训练和微调阶段
    • image-20240512121542673
    • Pretrain阶段
      • 在Pretrain阶段会使用大量的图片+简单文本(caption, 即图片标题)数据对,使LLM理解图像中的普遍特征。即,对大量的图片进行粗看
      • Pretrain阶段训练完成后,模型已经有视觉能力了,但是由于训练数据中都是图片+图片标题,所以此时的模型虽然有视觉能力,但无论用户问它什么,它都只会回答输入图片的标题。即,此时的模型只会给输入图像“写标题”
    • Finetune阶段
      • 使用图片+复杂文本数据对,来对Pretrain得到的Image Projector即iter_2181.pth进行进一步的训练。
      • 训练数据构建
  • 在进行上述步骤之后,LLM即可进化为MLLM
    • 数据
      • 322289947-7bab37ec-18f9-4731-979d-c5fc8acf80fa
      • ft_before
      • ft_after

2 基础作业

2.1 个人认知微调

314369658-0c4817e8-ddaf-4276-ad16-b65d5ec6b4ae

首先是训练数据的构建

  • 数据生成代码:
    • image-20240512124702468
  • 微调数据
    • image-20240512124735612

之后复制本次用到的大模型(这里采用建立软连接的方法)

ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b model/internlm2-chat-1_8b

配置文件名的解释

internlm2_1_8b_qlora_alpaca_e3 举例:

模型名 说明
internlm2_1_8b 模型名称
qlora 使用的算法
alpaca 数据集名称
e3 把数据集跑3次

最后得到的文件树:

image-20240512125234452

常用超参

参数名 解释
data_path 数据路径或 HuggingFace 仓库名
max_length 单条数据最大 Token 数,超过则截断
pack_to_max_length 是否将多条短数据拼接到 max_length,提高 GPU 利用率
accumulative_counts 梯度累积,每多少次 backward 更新一次参数
sequence_parallel_size 并行序列处理的大小,用于模型训练时的序列并行
batch_size 每个设备上的批量大小
dataloader_num_workers 数据加载器中工作进程的数量
max_epochs 训练的最大轮数
optim_type 优化器类型,例如 AdamW
lr 学习率
betas 优化器中的 beta 参数,控制动量和平方梯度的移动平均
weight_decay 权重衰减系数,用于正则化和避免过拟合
max_norm 梯度裁剪的最大范数,用于防止梯度爆炸
warmup_ratio 预热的比例,学习率在这个比例的训练过程中线性增加到初始学习率
save_steps 保存模型的步数间隔
save_total_limit 保存的模型总数限制,超过限制时删除旧的模型文件
prompt_template 模板提示,用于定义生成文本的格式或结构
…… ……
# 指定保存路径
xtuner train /root/workspace/xtuner0117/config/internlm2_1_8b_qlora_alpaca_e3_copy.py --work-dir /root/workspace/xtuner0117/train
# 使用 deepspeed 来加速训练
xtuner train /root/workspace/xtuner0117/config/internlm2_1_8b_qlora_alpaca_e3_copy.py --work-dir /root/workspace/xtuner0117/ft_ds2 --deepspeed deepspeed_zero2

过程如下:

  • 训练数据映射

    • image-20240512131047212
  • 微调结果

    • 1k条训练数据:可以看到存在欠拟合现象,部分问题没法回复
      • image-20240512150537929
    • 1w条训练数据:可以达到满意的回答,但是存在过拟合现象
      • image-20240512150601286
  • 参数格式转换

    • xtuner convert pth_to_hf /root/workspace/xtuner0117/train/internlm2_1_8b_qlora_alpaca_e3_copy.py /root/workspace/xtuner0117/train/iter_896.pth /root/workspace/xtuner0117/huggingface
      
  • 参数合并

    • # 解决一下线程冲突的 Bug 
      export MKL_SERVICE_FORCE_INTEL=1
          
      # 进行模型整合
      # xtuner convert merge  ${NAME_OR_PATH_TO_LLM} ${NAME_OR_PATH_TO_ADAPTER} ${SAVE_PATH} 
      xtuner convert merge /root/workspace/xtuner0117/model/internlm2-chat-1_8b /root/workspace/xtuner0117/huggingface /root/workspace/xtuner0117/final_model
      
  • web_demo:可以看到过拟合现象十分严重,这既有训练数据单一的原因,又有模型参数大小(1.8B)的原因

    • image-20240512153213735

    • streamlit run /root/workspace/xtuner0117/InternLM/chat/web_demo.py --server.address 127.0.0.1 --server.port 6006
      
    • image-20240512153617942

2.2 复现多模态微调大模型

配置文件:

image-20240512123258946

image-20240512123657448

开始微调

cd /root/workspace/xtuner0117/tutorial/xtuner/llava/
xtuner train /root/workspace/xtuner0117/tutorial/xtuner/llava/llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy.py --deepspeed deepspeed_zero2
  • 构建数据映射
    • image-20240512124054000
  • 加载模型参数
    • image-20240512124129080
  • 训练过程
    • image-20240512124357178
  • 微调结果:类似于教程结果,能够理解并详细回答图片内容
    • image-20240512130721598