1. XTuner微调前置基础
1.1 Finetune简介
微调(fine-tuning)是一种基于预训练模型,通过少量的调整(fine-tune)来适应新的任务或数据的方法。
微调是在预训练模型的基础上,将模型中一些层的权重参数进行微调,以适应新的数据集或任务。
预训练模型部分已经在大规模数据上得到了训练,它们通常是较为通用且高性能的模型,因此可以很好地作为新任务的起点。微调可以加快模型的收敛速度,降低模型过拟合的风险,并在不消耗过多计算资源的情况下获取较好的模型性能。
1.1.1 Finetune的两种范式
在大模型的下游应用中,经常会用到两种微调模式:增量预训练 和 指令跟随 。
增量预训练
增量预训练是一种在已有预训练模型(比如:InternLM基座模型)的基础上,利用特定领域的数据进行进一步训练的方法。它的目的是在保持模型原有能力的同时,注入新的领域知识,进一步优化现有的预训练模型,从而提升模型在特定领域任务中的表现(比如:InternLM垂类基座模型)。增量预训练模型能够接受少量的新数据进行更新并适应新的任务,而不需要重新训练整个模型,这种方式可以很好地利用现有的预训练模型的知识,并在新数据上获得更好的性能。
指令跟随
指令跟随是指让模型根据用户输入的指令来执行相应的操作。模型通过对大量自然语言指令和相应操作的数据进行训练,学习如何将指令分解为具体的子任务,并选择合适的模块来执行这些任务(比如:InternLM垂类对话模型)。
1.2 微调技术
大多数大型语言模型(LLM)的参数规模巨大,且规模日益增大,导致模型的训练和微调成本高昂,直接训练需要耗费大量计算资源和费用。近年来,如何高效地对大模型进行微调成为了研究热点,而LoRA和QLoRA两种微调技术因其高效性和实用性受到了广泛关注。
1.2.1 LoRA简介
LoRA(Low-Rank Adaptation)是一种使用低精度权重对大型预训练语言模型进行微调的技术,它的核心思想是在不改变原有模型权重的情况下,通过添加少量新参数来进行微调。这种方法降低了模型的存储需求,也降低了计算成本,实现了对大模型的快速适应,同时保持了模型性能。
然而,由于使用了低精度权重,LoRA的一个潜在的缺点是在微调过程中可能会丢失一些原始模型的高阶特征信息,因此可能会降低模型的准确性。
1.2.2 QLoRA简介
QLoRA(Quantized LoRA)微调技术是对LoRA的一种改进,它通过引入高精度权重和可学习的低秩适配器来提高模型的准确性。并且在LoRA的基础上,引入了量化技术。通过将预训练模型量化为int4格式,可以进一步减少微调过程中的计算量,同时也可以减少模型的存储空间,这对于在资源有限的设备上运行模型非常有用。最终,可以使我们在消费级的显卡上进行模型的微调训练。
1.3 XTuner简介
XTuner 的官方仓库是:https://github.com/InternLM/xtuner (欢迎Star)!
XTuner 一个大语言模型&多模态模型微调工具箱。由 MMRazor 和 MMDeploy 联合开发。
- 🤓 傻瓜化: 以 配置文件 的形式封装了大部分微调场景,0基础的非专业人员也能一键开始微调。
- 🍃 轻量级: 对于 7B 参数量的LLM,微调所需的最小显存仅为 8GB : 消费级显卡✅,colab✅
1.3.1 功能亮点
- 适配多种生态
- 支持多种微调算法
- 适配多种开源生态(HuggingFace、ModelScope等)
- 自动优化加速器
- 适配多种硬件
1.3.2 常用命令
以下是一些常用的命令。
- 查看帮助
xtuner help
- 查看版本
xtuner version
- 列出所有预定义配置文件
xtuner list-cfg
- 列出包含指定名称的预定义配置文件
xtuner list-cfg
命令用于列出内置的所有配置文件。参数-p
或--pattern
表示模式匹配,后面跟着的内容将会在所有的配置文件里进行模糊匹配搜索,然后返回最有可能得内容。
xtuner list-cfg -p $NAME
- 复制配置文件
xtuner copy-cfg
命令用于复制一个内置的配置文件。该命令需要两个参数:CONFIG
代表需要复制的配置文件名称,SAVE_PATH
代表复制的目标路径。
xtuner copy-cfg $CONFIG $SAVE_PATH
- 执行微调训练
xtuner train
命令用于启动模型微调进程。该命令需要一个参数:CONFIG
用于指定微调配置文件。
xtuner train $CONFIG
- 将 pth 格式的模型文件转换成 HuggingFace 格式的模型
xtuner convert pth_to_hf
命令用于进行模型格式转换。该命令需要三个参数:CONFIG
表示微调的配置文件,PATH_TO_PTH_MODEL
表示微调的模型权重文件路径,即要转换的模型权重,SAVE_PATH_TO_HF_MODEL
表示转换后的 HuggingFace 格式文件的保存路径。
除此之外,我们其实还可以在转换的命令中添加几个额外的参数,包括:
参数名 | 解释 |
---|---|
--fp32 | 代表以fp32的精度开启,假如不输入则默认为fp16 |
--max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
xtuner convert pth_to_hf $CONFIG $PATH_TO_PTH_MODEL $SAVE_PATH_TO_HF_MODEL
- 将原始模型与微调结果进行合并
xtuner convert merge
命令用于合并模型。该命令需要三个参数:LLM
表示原模型路径,ADAPTER
表示 Adapter 层的路径,SAVE_PATH
表示合并后的模型最终的保存路径。
在模型合并这一步还有其他很多的可选参数,包括:
参数名 | 解释 |
---|---|
--max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
--device {device_name} | 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
--is-clip | 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
CLIP(Contrastive Language–Image Pre-training)模型是 OpenAI 开发的一种预训练模型,它能够理解图像和描述它们的文本之间的关系。CLIP 通过在大规模数据集上学习图像和对应文本之间的对应关系,从而实现了对图像内容的理解和分类,甚至能够根据文本提示生成图像。
xtuner convert merge $LLM $ADAPTER $SAVE_PATH
当我们有了这些前置知识之后,就可以进行下一步的微调任务了!
2. 微调实践
2.1 准备工作
环境安装:我们想要用简单易上手的微调工具包 XTuner 来对模型进行微调的话,第一步是安装 XTuner !安装基础的工具是一切的前提,只有安装了 XTuner 我们才能够去执行后续的操作。
前期准备:在完成 XTuner 的安装后,我们下一步就需要去明确我们自己的微调目标了。我们想要利用微调做一些什么事情呢,然后为了实现这个目标,我们需要准备相关的硬件资源和数据。
启动微调:在确定了自己的微调目标后,我们就可以在 XTuner 的配置库中找到合适的配置文件并进行对应的修改。修改完成后即可一键启动训练!训练好的模型也可以仅仅通过在终端输入一行命令来完成转换和部署工作!
2.1.1 环境配置
# 创建虚拟环境
conda create -n xtuner0121 python=3.10 -y
# 激活虚拟环境(注意:后续的所有操作都需要在这个虚拟环境中进行)
conda activate xtuner0121
# 安装一些必要的库
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 安装其他依赖
pip install transformers==4.39.3
pip install streamlit==1.36.0
虚拟环境创建完成后,就可以安装 XTuner 了。首先,从 Github 上下载源码。
# 创建一个目录,用来存放源代码 mkdir -p /root/InternLM/code cd /root/InternLM/code git clone -b v0.1.21 https://github.com/InternLM/XTuner /root/InternLM/code/XTuner
其次,进入源码目录,执行安装。
# 进入到源码目录 cd /root/InternLM/code/XTuner conda activate xtuner0121 # 执行安装 pip install -e '.[deepspeed]'
最后,我们可以验证一下安装结果。
xtuner version
2.1.2 模型准备
软件安装好后,我们就可以准备要微调的模型了。
对于学习而言,我们可以使用 InternLM 推出的1.8B的小模型来完成此次微调演示。
对于在 InternStudio 上运行的小伙伴们,可以不用通过 HuggingFace、OpenXLab 或者 Modelscope 进行模型的下载,在开发机中已经为我们提供了模型的本地文件,直接使用就可以了。
我们可以通过以下代码一键通过符号链接的方式链接到模型文件,这样既节省了空间,也便于管理。
# 创建一个目录,用来存放微调的所有资料,后续的所有操作都在该路径中进行
mkdir -p /root/InternLM/XTunercd /root/InternLM/XTuner
mkdir -p Shanghai_AI_Laboratory
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b Shanghai_AI_Laboratory/internlm2-chat-1_8b
执行上述操作后,Shanghai_AI_Laboratory/internlm2-chat-1_8b
将直接成为一个符号链接,这个链接指向 /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b
的位置。
这意味着,当我们访问 Shanghai_AI_Laboratory/internlm2-chat-1_8b
时,实际上就是在访问 /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b
目录下的内容。通过这种方式,我们无需复制任何数据,就可以直接利用现有的模型文件进行后续的微调操作,从而节省存储空间并简化文件管理。
模型文件准备好后,我们可以使用tree
命令来观察目录结构。
apt-get install -y tree
tree -l
2.2 微调实践
微调之前的结果:
微调:
准备好数据之后的结构:
配置文件名的解释
以 internlm2_1_8b_full_custom_pretrain_e1 和 internlm2_chat_1_8b_qlora_alpaca_e3 举例:
配置文件 internlm2_1_8b_full_custom_pretrain_e1 | 配置文件 internlm2_chat_1_8b_qlora_alpaca_e3 | 说明 |
---|---|---|
internlm2_1_8b | internlm2_chat_1_8b | 模型名称 |
full | qlora | 使用的算法 |
custom_pretrain | alpaca | 数据集名称 |
e1 | e3 | 把数据集跑几次 |
由于我们是对internlm2-chat-1_8b
模型进行指令微调,所以与我们的需求最匹配的配置文件是 internlm2_chat_1_8b_qlora_alpaca_e3
,这里就复制该配置文件。
xtuner copy-cfg
命令用于复制一个内置的配置文件。该命令需要两个参数:CONFIG
代表需要复制的配置文件名称,SAVE_PATH
代表复制的目标路径。在我们的输入的这个命令中,我们的CONFIG
对应的是上面搜索到的internlm2_chat_1_8b_qlora_alpaca_e3
,而SAVE_PATH
则是当前目录.
。
cd /root/InternLM/XTuner conda activate xtuner0121 xtuner copy-cfg internlm2_chat_1_8b_qlora_alpaca_e3 .
复制好配置文件后,我们的目录结构应该是这样子的。
在选择了一个最匹配的配置文件并准备好其他内容后,下面我们要做的事情就是根据我们自己的内容对该配置文件进行调整,使其能够满足我们实际训练的要求。
打开配置文件后,我们可以看到整体的配置文件分为五部分:
PART 1 Settings:涵盖了模型基本设置,如预训练模型的选择、数据集信息和训练过程中的一些基本参数(如批大小、学习率等)。
PART 2 Model & Tokenizer:指定了用于训练的模型和分词器的具体类型及其配置,包括预训练模型的路径和是否启用特定功能(如可变长度注意力),这是模型训练的核心组成部分。
PART 3 Dataset & Dataloader:描述了数据处理的细节,包括如何加载数据集、预处理步骤、批处理大小等,确保了模型能够接收到正确格式和质量的数据。
PART 4 Scheduler & Optimizer:配置了优化过程中的关键参数,如学习率调度策略和优化器的选择,这些是影响模型训练效果和速度的重要因素。
PART 5 Runtime:定义了训练过程中的额外设置,如日志记录、模型保存策略和自定义钩子等,以支持训练流程的监控、调试和结果的保存。
一般来说我们需要更改的部分其实只包括前三部分,而且修改的主要原因是我们修改了配置文件中规定的模型、数据集。后两部分都是 XTuner 官方帮我们优化好的东西,一般而言只有在魔改的情况下才需要进行修改。
在 PART 1 的部分,由于我们不再需要在 HuggingFace 上自动下载模型,因此我们先要更换模型的路径以及数据集的路径为我们本地的路径。
为了训练过程中能够实时观察到模型的变化情况,XTuner 贴心的推出了一个 evaluation_inputs
的参数来让我们能够设置多个问题来确保模型在训练过程中的变化是朝着我们想要的方向前进的。我们可以添加自己的输入。
在 PART 3 的部分,由于我们准备的数据集是 JSON 格式的数据,并且对话内容已经是 input
和 output
的数据对,所以不需要进行格式转换。
2.2.1 启动微调
完成了所有的准备工作后,我们就可以正式的开始我们下一阶段的旅程:XTuner 启动~!
当我们准备好了所有内容,我们只需要将使用 xtuner train
命令令即可开始训练。
xtuner train
命令用于启动模型微调进程。该命令需要一个参数:CONFIG
用于指定微调配置文件。这里我们使用修改好的配置文件internlm2_chat_1_8b_qlora_alpaca_e3_copy.py
。
训练过程中产生的所有文件,包括日志、配置文件、检查点文件、微调后的模型等,默认保存在work_dirs
目录下,我们也可以通过添加--work-dir
指定特定的文件保存位置。
在训练完后,我们的目录结构应该是这样子的。
2.2.2 模型格式转换
模型转换的本质其实就是将原本使用 Pytorch 训练出来的模型权重文件转换为目前通用的 HuggingFace 格式文件,那么我们可以通过以下命令来实现一键转换。
我们可以使用 xtuner convert pth_to_hf
命令来进行模型格式转换。
xtuner convert pth_to_hf
命令用于进行模型格式转换。该命令需要三个参数:CONFIG
表示微调的配置文件,PATH_TO_PTH_MODEL
表示微调的模型权重文件路径,即要转换的模型权重,SAVE_PATH_TO_HF_MODEL
表示转换后的 HuggingFace 格式文件的保存路径。
除此之外,我们其实还可以在转换的命令中添加几个额外的参数,包括:
参数名 | 解释 |
---|---|
--fp32 | 代表以fp32的精度开启,假如不输入则默认为fp16 |
--max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
cd /root/InternLM/XTuner
conda activate xtuner0121
# 先获取最后保存的一个pth文件
pth_file=`ls -t ./work_dirs/internlm2_chat_1_8b_qlora_alpaca_e3_copy/*.pth | head -n 1`
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert pth_to_hf ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py ${pth_file} ./hf
模型格式转换完成后,我们的目录结构应该是这样子的。
转换完成后,可以看到模型被转换为 HuggingFace 中常用的 .bin 格式文件,这就代表着文件成功被转化为 HuggingFace 格式了。
此时,hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”
可以简单理解:LoRA 模型文件 = Adapter
2.2.3 模型合并
对于 LoRA 或者 QLoRA 微调出来的模型其实并不是一个完整的模型,而是一个额外的层(Adapter),训练完的这个层最终还是要与原模型进行合并才能被正常的使用。
对于全量微调的模型(full)其实是不需要进行整合这一步的,因为全量微调修改的是原模型的权重而非微调一个新的 Adapter ,因此是不需要进行模型整合的。
在 XTuner 中提供了一键合并的命令 xtuner convert merge
,在使用前我们需要准备好三个路径,包括原模型的路径、训练好的 Adapter 层的(模型格式转换后的)路径以及最终保存的路径。
xtuner convert merge
命令用于合并模型。该命令需要三个参数:LLM
表示原模型路径,ADAPTER
表示 Adapter 层的路径,SAVE_PATH
表示合并后的模型最终的保存路径。
在模型合并这一步还有其他很多的可选参数,包括:
参数名 | 解释 |
---|---|
--max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
--device {device_name} | 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
--is-clip | 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
cd /root/InternLM/XTuner
conda activate xtuner0121
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert merge /root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b ./hf ./merged --max-shard-size 2GB
模型合并完成后,我们的目录结构应该是这样子的。
在模型合并完成后,我们就可以看到最终的模型和原模型文件夹非常相似,包括了分词器、权重文件、配置信息等等。
2.3 微调后的模型对话
3. 总结
这次的教程主要是针对于整个微调,对微调的整个流程有一个具体的认识。包括从启动微调、模型格式转换、合并模型等,都有一个具体的了解!