Internlm-04-XTuner 大模型单卡低成本微调实战
XTuner 大模型单卡低成本微调实战
微调前官方回答
微调后微调后.png
1 概述
1.1 XTuner
一个大语言模型微调工具箱。由 MMRazor 和 MMDeploy 联合开发。
1.2 支持的开源LLM (2023.11.01)
1.3 特色
- 傻瓜化: 以 配置文件 的形式封装了大部分微调场景,0基础的非专业人员也能一键开始微调。
- 轻量级: 对于 7B 参数量的LLM,微调所需的最小显存仅为 8GB
1.4 微调原理
想象一下,你有一个超大的玩具,现在你想改造这个超大的玩具。但是,对整个玩具进行全面的改动会非常昂贵。
※ 因此,你找到了一种叫 LoRA 的方法:只对玩具中的某些零件进行改动,而不是对整个玩具进行全面改动。
※ 而 QLoRA 是 LoRA 的一种改进
2 快速上手
2.1 平台
Ubuntu + Anaconda + CUDA/CUDNN + 8GB nvidia显卡
2.2 安装
1 |
|
安装完后,就开始搞搞准备工作了。(准备在 oasst1 数据集上微调 internlm-7b-chat)
1 |
|
2.3 微调
2.3.1 准备配置文件
XTuner 提供多个开箱即用的配置文件,用户可以通过下列命令查看:
1 |
|
假如显示bash: xtuner: command not found的话可以考虑在终端输入 export PATH=$PATH:’/root/.local/bin’
部分配置文件展示
拷贝一个配置文件到当前目录:# xtuner copy-cfg ${CONFIG_NAME} ${SAVE_PATH}
在本案例中即:(注意最后有个英文句号,代表复制到当前路径)1
2cd ~/ft-oasst1
xtuner copy-cfg internlm_chat_7b_qlora_oasst1_e3 .
配置文件名的解释:
xtuner copy-cfg internlm_chat_7b_qlora_oasst1_e3 .
模型名 | internlm_chat_7b |
---|---|
使用算法 | qlora |
数据集 | oasst1 |
把数据集跑几次 | 跑3次:e3 (epoch 3 ) |
*无 chat比如 internlm-7b
代表是基座(base)模型
2.3.2 模型下载
由于下载模型很慢,用教学平台的同学可以直接复制模型。
1 |
|
以下是自己下载模型的步骤。
不用 xtuner 默认的从 huggingface 拉取模型
,而是提前从 ModelScope 下载模型到本地
1 |
|
2.3.3 数据集下载
https://huggingface.co/datasets/timdettmers/openassistant-guanaco/tree/main
由于 huggingface 网络问题,咱们已经给大家提前下载好了,复制到正确位置即可:
1 |
|
此时,当前路径的文件应该长这样:
1 |
|
2.3.4 修改配置文件
修改其中的模型和数据集为 本地路径
1 |
|
在vim界面完成修改后,请输入:wq退出。假如认为改错了可以用:q!退出且不保存。当然我们也可以考虑打开python文件直接修改,但注意修改完后需要按下Ctrl+S进行保存。
减号代表要删除的行,加号代表要增加的行。1
2
3
4
5
6
7# 修改模型为本地路径
- pretrained_model_name_or_path = 'internlm/internlm-chat-7b'
+ pretrained_model_name_or_path = './internlm-chat-7b'
# 修改训练数据集为本地路径
- data_path = 'timdettmers/openassistant-guanaco'
+ data_path = './openassistant-guanaco'
常用超参
参数名 | 解释 |
---|---|
data_path | 数据路径或 HuggingFace 仓库名 |
max_length | 单条数据最大 Token 数,超过则截断 |
pack_to_max_length | 是否将多条短数据拼接到 max_length,提高 GPU 利用率 |
accumulative_counts | 梯度累积,每多少次 backward 更新一次参数 |
evaluation_inputs | 训练过程中,会根据给定的问题进行推理,便于观测训练状态 |
evaluation_freq | Evaluation 的评测间隔 iter 数 |
…… | …… |
如果想把显卡的现存吃满,充分利用显卡资源,可以将
max_length
和batch_size
这两个参数调大。
2.3.5 开始微调
训练:
xtuner train ${CONFIG_NAME_OR_PATH}
也可以增加 deepspeed 进行训练加速:
xtuner train ${CONFIG_NAME_OR_PATH} —deepspeed deepspeed_zero2
例如,我们可以利用 QLoRA 算法在 oasst1 数据集上微调 InternLM-7B:
1 |
|
微调得到的 PTH 模型文件和其他杂七杂八的文件都默认在当前的
./work_dirs
中。
训练截图
跑完训练后,当前路径应该长这样:
1 |
|
2.3.6 将得到的 PTH 模型转换为 HuggingFace 模型,即:生成 Adapter 文件夹
xtuner convert pth_to_hf ${CONFIG_NAME_OR_PATH} ${PTH_file_dir} ${SAVE_PATH}
在本示例中,为:1
2
3
4mkdir hf
export MKL_SERVICE_FORCE_INTEL=1
xtuner convert pth_to_hf ./internlm_chat_7b_qlora_oasst1_e3_copy.py ./work_dirs/internlm_chat_7b_qlora_oasst1_e3_copy/epoch_1.pth ./hf
此时,路径中应该长这样:
1 |
|
此时,hf 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”
可以简单理解:LoRA 模型文件 = Adapter
2.4 部署与测试
2.4.1 将 HuggingFace adapter 合并到大语言模型:
1 |
|
2.4.2 与合并后的模型对话:
1 |
|
2.4.3 Demo
- 修改
cli_demo.py
中的模型路径1
2- model_name_or_path = "/root/model/Shanghai_AI_Laboratory/internlm-chat-7b"
+ model_name_or_path = "merged" - 运行
cli_demo.py
以目测微调效果1
python ./cli_demo.py
xtuner chat
的启动参数
启动参数 | 干哈滴 |
---|---|
—prompt-template | 指定对话模板 |
—system | 指定SYSTEM文本 |
—system-template | 指定SYSTEM模板 |
--bits | LLM位数 |
—bot-name | bot名称 |
—with-plugins | 指定要使用的插件 |
—no-streamer | 是否启用流式传输 |
—lagent | 是否使用lagent |
—command-stop-word | 命令停止词 |
—answer-stop-word | 回答停止词 |
—offload-folder | 存放模型权重的文件夹(或者已经卸载模型权重的文件夹) |
—max-new-tokens | 生成文本中允许的最大 token 数量 |
—temperature | 温度值 |
—top-k | 保留用于顶k筛选的最高概率词汇标记数 |
—top-p | 如果设置为小于1的浮点数,仅保留概率相加高于 top_p 的最小一组最有可能的标记 |
—seed | 用于可重现文本生成的随机种子 |
3 自定义微调
以 Medication QA 数据集为例
3.1 概述
3.1.1 场景需求
基于 InternLM-chat-7B 模型,用 MedQA 数据集进行微调,将其往医学问答
领域对齐。
3.1.2 真实数据预览
问题 | 答案 |
---|---|
What are ketorolac eye drops?(什么是酮咯酸滴眼液?) | Ophthalmic ketorolac is used to treat itchy eyes caused by allergies. It also is used to treat swelling and redness (inflammation) that can occur after cataract surgery. Ketorolac is in a class of medications called nonsteroidal anti-inflammatory drugs (NSAIDs). It works by stopping the release of substances that cause allergy symptoms and inflammation. |
What medicines raise blood sugar? (什么药物会升高血糖?) | Some medicines for conditions other than diabetes can raise your blood sugar level. This is a concern when you have diabetes. Make sure every doctor you see knows about all of the medicines, vitamins, or herbal supplements you take. This means anything you take with or without a prescription. Examples include: Barbiturates. Thiazide diuretics. Corticosteroids. Birth control pills (oral contraceptives) and progesterone. Catecholamines. Decongestants that contain beta-adrenergic agents, such as pseudoephedrine. The B vitamin niacin. The risk of high blood sugar from niacin lowers after you have taken it for a few months. The antipsychotic medicine olanzapine (Zyprexa). |
3.2 数据准备
以 Medication QA 数据集为例
原格式:(.xlsx)
问题 | 药物类型 | 问题类型 | 回答 | 主题 | URL |
---|---|---|---|---|---|
aaa | bbb | ccc | ddd | eee | fff |
3.2.1 将数据转为 XTuner 的数据格式
目标格式:(.jsonL)
1 |
|
通过 pytho n脚本:将 .xlsx
中的 问题 和 回答 两列 提取出来,再放入 .jsonL
文件的每个 conversation 的 input 和 output 中。
这一步的 python 脚本可以请 ChatGPT 来完成。
1 |
|
ChatGPT 生成的 python 代码见本仓库的 xlsx2jsonl.py
执行 python 脚本,获得格式化后的数据集:1
python xlsx2jsonl.py
此时,当然也可以对数据进行训练集和测试集的分割,同样可以让 ChatGPT 写 python 代码。当然如果你没有严格的科研需求、不在乎“训练集泄露”的问题,也可以不做训练集与测试集的分割。
3.2.2 划分训练集和测试集
1 |
|
生成的python代码见 split2train_and_test.py
3.3 开始自定义微调
此时,我们重新建一个文件夹来玩“微调自定义数据集”1
mkdir ~/ft-medqa && cd ~/ft-medqa
把前面下载好的internlm-chat-7b模型文件夹拷贝过来。
1 |
|
别忘了把自定义数据集,即几个 .jsonL
,也传到服务器上。
1 |
|
1 |
|
3.3.1 准备配置文件
1 |
|
减号代表要删除的行,加号代表要增加的行。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26# 修改import部分
- from xtuner.dataset.map_fns import oasst1_map_fn, template_map_fn_factory
+ from xtuner.dataset.map_fns import template_map_fn_factory
# 修改模型为本地路径
- pretrained_model_name_or_path = 'internlm/internlm-chat-7b'
+ pretrained_model_name_or_path = './internlm-chat-7b'
# 修改训练数据为 MedQA2019-structured-train.jsonl 路径
- data_path = 'timdettmers/openassistant-guanaco'
+ data_path = 'MedQA2019-structured-train.jsonl'
# 修改 train_dataset 对象
train_dataset = dict(
type=process_hf_dataset,
- dataset=dict(type=load_dataset, path=data_path),
+ dataset=dict(type=load_dataset, path='json', data_files=dict(train=data_path)),
tokenizer=tokenizer,
max_length=max_length,
- dataset_map_fn=alpaca_map_fn,
+ dataset_map_fn=None,
template_map_fn=dict(
type=template_map_fn_factory, template=prompt_template),
remove_unused_columns=True,
shuffle_before_pack=True,
pack_to_max_length=pack_to_max_length)
3.3.2 XTuner!启动!
tH8udZzECYl5are.png
1 |
|
3.3.3 pth 转 huggingface
同前述,这里不赘述了。将得到的-pth-模型转换为-huggingface-模型即生成adapter文件夹
3.3.4 部署与测试
同前述。部署与测试
4 用 MS-Agent 数据集 赋予 LLM 以 Agent 能力
4.1 概述
MSAgent 数据集每条样本包含一个对话列表(conversations),其里面包含了 system、user、assistant 三种字段。其中:
system: 表示给模型前置的人设输入,其中有告诉模型如何调用插件以及生成请求
user: 表示用户的输入 prompt,分为两种,通用生成的prompt和调用插件需求的 prompt
assistant: 为模型的回复。其中会包括插件调用代码和执行代码,调用代码是要 LLM 生成的,而执行代码是调用服务来生成结果的
一条调用网页搜索插件查询“上海明天天气”的数据样本示例如下图所示:BlgfEqpiRFO5G6L.png
4.2 微调步骤
4.2.1 准备工作
xtuner 是从国内的 ModelScope 平台下载 MS-Agent 数据集,因此不用提前手动下载数据集文件。
1 |
|
1 |
|
4.2.2 开始微调
1 |
|
4.3 直接使用
由于 msagent 的训练非常费时,大家如果想尽快把这个教程跟完,可以直接从 modelScope 拉取咱们已经微调好了的 Adapter。如下演示。
4.3.1 下载 Adapter
1 |
|
OK,现在目录应该长这样:
- internlm_7b_qlora_msagent_react_e3_gpu8_copy.py
- internlm-7b-qlora-msagent-react
- internlm-chat-7b
- work_dir(可有可无)
有了这个在 msagent 上训练得到的Adapter,模型现在已经有 agent 能力了!就可以加 —lagent 以调用来自 lagent 的代理功能了!
4.3.2 添加 serper 环境变量
开始 chat 之前,还要加个 serper 的环境变量:
去 serper.dev 免费注册一个账号,生成自己的 api key。这个东西是用来给 lagent 去获取 google 搜索的结果的。等于是 serper.dev 帮你去访问 google,而不是从你自己本地去访问 google 了。
kDSdpQrhHfTWYsc.png
添加 serper api key 到环境变量:
1 |
|
4.3.3 xtuner + agent,启动!
1 |
|
5 注意事项
本教程使用 xtuner 0.1.9 版本
若需要跟着本教程一步一步完成,建议严格遵循本教程的步骤!
若出现莫名其妙报错,请尝试更换为以下包的版本:(如果有报错再检查,没报错不用看)1
2
3torch 2.1.1
transformers 4.34.0
transformers-stream-generator 0.0.41
2
3pip install torch==2.1.1
pip install transformers==4.34.0
pip install transformers-stream-generator=0.0.4
CUDA 相关:(如果有报错再检查,没报错不用看)1
2
3
4
5
6
7NVIDIA-SMI 535.54.03
Driver Version: 535.54.03
CUDA Version: 12.2
nvidia-cuda-cupti-cu12 12.1.105
nvidia-cuda-nvrtc-cu12 12.1.105
nvidia-cuda-runtime-cu12 12.1.105
6 作业
1 概述
目标:通过微调,让模型成为我们的小助手
方式:使用 XTuner 进行微调
微调前官方回答
微调后微调后.png
2 实操
微调环境准备
1 |
|
数据准备
创建data
文件夹用于存放用于训练的数据集
1 |
|
在data
目录下创建一个json文件personal_assistant.json
作为本次微调所使用的数据集。json中内容可参考下方(复制粘贴n次做数据增广,数据量小无法有效微调,下面仅用于展示格式,下面也有生成脚本)
其中conversation
表示一次对话的内容,input
为输入,即用户会问的问题,output
为输出,即想要模型回答的答案。
1 |
|
以下是一个python脚本,用于生成数据集。在data
目录下新建一个generate_data.py文件,将以下代码复制进去,然后运行该脚本即可生成数据集。
1 |
|
配置准备
下载模型InternLM-chat-7B
InternStudio 平台的 share
目录下已经为我们准备了全系列的 InternLM
模型,可以使用如下命令复制internlm-chat-7b
:
1 |
|
XTuner 提供多个开箱即用的配置文件,用户可以通过下列命令查看:
1 |
|
1 |
|
拷贝一个配置文件到当前目录:xtuner copy-cfg ${CONFIG_NAME} ${SAVE_PATH}
在本例中:(注意最后有个英文句号,代表复制到当前路径)
1 |
|
修改拷贝后的文件internlm_chat_7b_qlora_oasst1_e3_copy.py,修改下述位置:
(这是一份修改好的文件internlm_chat_7b_qlora_oasst1_e3_copy.py)修改配置
1 |
|
微调启动
用xtuner train
命令启动训练、
1 |
|
训练数据样例
会在训练完成后,输出用于验证的Sample output
微调后参数转换/合并
训练后的pth格式参数转Hugging Face格式
1 |
|
Merge模型参数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER='GNU'
# 原始模型参数存放的位置
export NAME_OR_PATH_TO_LLM=/root/personal_assistant/model/Shanghai_AI_Laboratory/internlm-chat-7b
# Hugging Face格式参数存放的位置
export NAME_OR_PATH_TO_ADAPTER=/root/personal_assistant/config/work_dirs/hf
# 最终Merge后的参数存放的位置
mkdir /root/personal_assistant/config/work_dirs/hf_merge
export SAVE_PATH=/root/personal_assistant/config/work_dirs/hf_merge
# 执行参数Merge
xtuner convert merge \
$NAME_OR_PATH_TO_LLM \
$NAME_OR_PATH_TO_ADAPTER \
$SAVE_PATH \
--max-shard-size 2GB
网页DEMO
安装网页Demo所需依赖
1 |
|
下载 InternLM 项目代码
1 |
|
将 /root/code/InternLM/web_demo.py
中 29 行和 33 行的模型路径更换为Merge后存放参数的路径 /root/personal_assistant/config/work_dirs/hf_merge
运行 /root/personal_assistant/code/InternLM
目录下的 web_demo.py
文件,之后将端口映射到本地。在本地浏览器输入 http://127.0.0.1:6006
即可。
1 |
|
注意:要在浏览器打开 http://127.0.0.1:6006
页面后,模型才会加载。
在加载完模型之后,就可以与微调后的 InternLM-Chat-7B 进行对话了
3 效果
微调前官方回答
微调后微调后.png
7 进阶作业
1 模型上传
model-upload.png
2 修改启动文件
接下来需要修改启动文件以下载模型以及合并 lora 层,代码如下:
1 |
|
3 构建并运行
构建及运行
Github 地址如下:
EnableAsync/openxlab-assistant (github.com)
运行地址如下:
- 本文作者:EnableAsync
- 本文链接:https://enableasync.github.io/internlm/internlm-04/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!