对话模版
LoRA (stable diffusion https://baijiahao.baidu.com/s?id=1765945330332903494&wfr=spider&for=pc)
XTuner
包括支撑Mistral、z
生成Adapter(LoRA)
XTuner 还支持工具类模型的对话,更多详见HuggingFace Hub(xtuner/Llama-2-7b-qlora-moss-003-sft)
QLoRA用deepspeed_zero2
使用 vgpu-smi 查看显卡资源使用情况
apt update -y
apt install tmux -y
创建并进入tumx环境 tmux new -s finetune
退出Ctrl+B再按D,再进入
tmux attach -t finetune
internlm_chat_7b_qlora_oasst1_e3 (模型名_方法qlora/lora_数据集_epoch3代表3轮,输出3个lora文件)
#单卡
##用刚才改好的config文件训练
xtuner train ./internlm_chat_7b_qlora_oasst1_e3_copy.py --deepspeed deepspeed_zero2
#多卡
NPROC_PER_NODE=${GPU_NUM} xtuner train ./internlm_chat_7b_qlora_oasst1_e3_copy.py --deepspeed deepspeed_zero2
#--deepspeed deepspeed_zero2, 开启 deepspeed 加速
LoRA文件转成HuggingFace格式:
mkdir 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
将 HuggingFace adapter 合并到大语言模型:max-shard-size切分的每个文件分块大小
xtuner convert merge ./internlm-chat-7b ./hf ./merged --max-shard-size 2GB
与合并后的模型对话:
#加载 Adapter 模型对话(Float 16)
xtuner chat ./merged --prompt-template internlm_chat
#4 bit 量化加载
xtuner chat ./merged --bits 4 --prompt-template internlm_chat
--temperature 温度值,值0~1,越大回复越随机
--seed 用于可重现文本生成的随机种子,指定后可以保证每次随机种子一致
# 如果你是在 InternStudio 平台,则从本地 clone 一个已有 pytorch 2.0.1 的环境:
/root/share/install_conda_env_internlm_base.sh xtuner0.1.9
#!/bin/bash
# clone internlm-base conda env to user's conda env
# created by xj on 01.07.2024
echo "start cloning conda environment of internlm-base"
if [ -z "$1" ]; then
echo "Error: No argument provided. Please provide a conda environment name."
exit 1
fi
echo "uncompress pkgs.tar.gz file to /root/.conda/pkgs..."
sleep 3
tar --skip-old-files -xzvf /root/share/pkgs.tar.gz -C /root/.conda
echo "\n"
echo "uncompress internlm-base.tar.gz to /root/.conda/envs/$1..."
sleep 3
mkdir /root/.conda/envs/$1
tar --skip-old-files -xzvf /root/share/conda_envs/internlm-base.tar.gz -C /root/.conda/envs/$1
echo "Finised!"
echo "Now you can use your environment by typing:"
echo "conda activate $1"
# begin:
root@intern-studio:~# bash
(base) root@intern-studio:~# conda create --name xtuner0.1.9 python=3.10 -y
(base) root@intern-studio:~# conda info -e
# 激活环境
conda activate xtuner0.1.9
# 进入家目录 (~的意思是 “当前用户的home路径”)
(xtuner0.1.9) root@intern-studio:~# cd ~
# 创建版本文件夹并进入,以跟随本教程
mkdir xtuner019 && cd xtuner019
# 拉取 0.1.9 的版本源码
# git clone -b v0.1.9 https://github.com/InternLM/xtuner
# 无法访问github的用户请从 gitee 拉取:
git clone -b v0.1.9 https://gitee.com/Internlm/xtuner
# 进入源码目录
cd xtuner
# 从源码安装 XTuner
pip install -e '.[all]'
# 创建一个微调 oasst1 数据集的工作路径,进入
mkdir ~/ft-oasst1 && cd ~/ft-oasst1
# 列出所有内置配置
xtuner list-cfg
假如显示bash: xtuner: command not found的话可以考虑在终端输入 export PATH=$PATH:'/root/.local/bin'
拷贝一个配置文件到当前目录:
cd ~/ft-oasst1
xtuner copy-cfg internlm_chat_7b_qlora_oasst1_e3 .
模型名 | internlm_chat_7b |
---|---|
使用算法 | qlora |
数据集 | oasst1 |
把数据集跑几次 | 跑3次:e3 (epoch 3 ) |
从 OpenXLab 下载模型到本地
# 创建一个目录,放模型文件,防止散落一地
mkdir ~/ft-oasst1/internlm-chat-7b
# 装一下拉取模型文件要用的库
pip install modelscope
# 从 modelscope 下载下载模型文件
cd ~/ft-oasst1
apt install git git-lfs -y
git lfs install
git lfs clone https://modelscope.cn/Shanghai_AI_Laboratory/internlm-chat-7b.git -b v1.0.3
https://huggingface.co/datasets/timdettmers/openassistant-guanaco/tree/main https://github.com/abachaa/Medication_QA_MedInfo2019
下载后放入新建的openassistant-guanaco目录
目标格式:(.jsonL)
[{
"conversation":[
{
"system": "xxx",
"input": "xxx",
"output": "xxx"
}
]
},
{
"conversation":[
{
"system": "xxx",
"input": "xxx",
"output": "xxx"
}
]
}]
写个python脚本,生成训练数据
import json
def generate_conversations(replacement, n, filename):
data = []
for _ in range(n):
conversation = {
"conversation": [
{
"input": "请介绍一下你自己",
"output": f"我是{replacement}的小助手,内在是上海AI实验室书生·浦语的7B大模型哦"
}
]
}
data.append(conversation)
with open(filename, 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
if __name__ == "__main__":
replacement = input("请输入需要替换的内容: ")
n = int(input("请输入记录数 (n): "))
filename = input("请输入输出文件名 (包括.json扩展名): ")
generate_conversations(replacement, n, filename)
print(f"已生成包含{n}条记录的文件: {filename}")
划分训练集和测试集....
# 改个文件名
mv internlm_chat_7b_qlora_oasst1_e3_copy.py internlm_chat_7b_qlora_mytrain_e3_copy.py
vim internlm_chat_7b_qlora_mytrain_e3_copy.py
减号代表要删除的行,加号代表要增加的行。
数据集的话:
# 修改模型为本地路径
- 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'
# 修改跑次数
- max_epochs = 3
+ max_epochs = 1
单个文件情况:
# 修改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 = '/root/ft-oasst1/internlm-chat-7b'
# 修改训练数据为 MedQA2019-structured-train.jsonl 路径
- data_path = 'timdettmers/openassistant-guanaco'
+ data_path = '/root/ft-oasst1/personal_assistant.json'
# 用于评估输出内容的问题(用于评估的问题尽量与数据集的question保持一致)
evaluation_freq = 90
SYSTEM = ''
evaluation_inputs = [
'请介绍一下你自己', '请介绍一下你自己'
]
# 修改 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)
常用超参
参数名 | 解释 |
---|---|
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
这两个参数调大。
使用TMUX:(使用这个工具在终端SSH连接后,不会中断微调工作)
apt update -y
apt install tmux -y
创建并进入tumx环境
tmux new -s finetune
退出Ctrl+B再按D,再进入
tmux attach -t finetune
写个python脚本,生成训练数据
训练:
# 单卡
## 用刚才改好的config文件训练
xtuner train /root/ft-oasst1/internlm_chat_7b_qlora_mytrain_e3_copy.py --deepspeed deepspeed_zero2
# 多卡
NPROC_PER_NODE=${GPU_NUM} xtuner train internlm_chat_7b_qlora_mytrain_e3_copy.py --deepspeed deepspeed_zero2
# --deepspeed deepspeed_zero2, 开启 deepspeed 加速
将得到的 PTH 模型转换为 HuggingFace 模型,即:生成 Adapter 文件夹
mkdir hf
# 设置环境变量
export MKL_SERVICE_FORCE_INTEL=1
xtuner convert pth_to_hf internlm_chat_7b_qlora_mytrain_e3_copy.py ./work_dirs/internlm_chat_7b_qlora_mytrain_e3_copy/epoch_1.pth ./hf
将 HuggingFace adapter 合并到大语言模型:
xtuner convert merge ./internlm-chat-7b ./hf ./merged --max-shard-size 2GB
# xtuner convert merge \
# ${NAME_OR_PATH_TO_LLM} \
# ${NAME_OR_PATH_TO_ADAPTER} \
# ${SAVE_PATH} \
# --max-shard-size 2GB
# 加载 Adapter 模型对话(Float 16)
# xtuner chat ./merged --prompt-template internlm_chat
# 4 bit 量化加载
xtuner chat ./merged --bits 4 --prompt-template internlm_chat
cd ~/ft-oasst1
cp ~/code/InternLM/cli_demo.py cli_demo.py
vim cli_demo.py
# 修改 cli_demo.py 中的模型路径
- model_name_or_path = "/root/model/Shanghai_AI_Laboratory/internlm-chat-7b"
+ model_name_or_path = "/root/ft-oasst1/merged"
# 运行 cli_demo.py 以目测微调效果
python cli_demo.py
pip install streamlit==1.24.0
# 创建code文件夹用于存放InternLM项目代码
mkdir code && cd code
git clone https://github.com/InternLM/InternLM.git
将 /root/code/InternLM/web_demo.py 中 29 行和 33 行的模型路径更换为Merge后存放参数的路径 /root/ft-oasst1/merged
vim web_demo.py
# 修改
+ AutoModelForCausalLM.from_pretrained("/root/ft-oasst1/merged", trust_remote_code=True)
+ tokenizer = AutoTokenizer.from_pretrained("/root/ft-oasst1/merged", trust_remote_code=True)
streamlit run web_demo.py --server.address 127.0.0.1 --server.port 6006
# 本地运行
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p 33090(修改对应端口)
浏览器访问:http://127.0.0.1:6006
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 | 用于可重现文本生成的随机种子 |