个人助手微调
其实主要依据前面ft-medqa修改一下就行。
准备工作
# 激活环境
conda activate xtuner0.1.9
# 进入家目录 (~的意思是 “当前用户的home路径”)
cd ~
# 创建版本文件夹并进入,以跟随本教程
mkdir ~/ft-akan && cd ~/ft-akan
ln -s /share/temp/model_repos/internlm-chat-7b ~/ft-akan/
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
cp ../ft-medqa/internlm_chat_7b_qlora_medqa2019_e3.py internlm_chat_7b_qlora_akan_e3.py
1、构建数据集
ft-akan/personal_assistant.jsonl
[
{
"conversation": [
{
"input": "请介绍一下你自己",
"output": "我是akan的小助手,内在是上海AI实验室书生·浦语的7B大模型哦"
}
]
},
{
"conversation": [
{
"input": "请做一下自我介绍",
"output": "我是akan的小助手,内在是上海AI实验室书生·浦语的7B大模型哦"
}
]
}
]
2、使用 XTuner 微调 InternLM-Chat-7B 模型
修改internlm_chat_7b_qlora_akan_e3.py,因为只有2个数据,且长度较短,还是训练3次吧。估计训练1000次肯定记的牢牢的,没必要。
data_path = 'personal_assistant.jsonl'
。。。
max_length = 2048
。。。
batch_size = 2 # per_device
。。。
max_epochs = 3
开始微调
xtuner train internlm_chat_7b_qlora_akan_e3.py --deepspeed deepspeed_zero2
我靠,看着不行啊。难怪参考作业里之前的哥们要重复1000遍啊1000遍。我要是epochs=1000,那得生成1000个文件。还是得听劝。
改个generate.py
import json
# 输入你的名字
name = 'akan'
# 重复次数
n = 10000
data = [
{
"conversation": [
{
"input": "请做一下自我介绍",
"output": "我是{}的小助手,内在是上海AI实验室书生·浦语的7B大模型哦".format(name)
}
]
}
]
for i in range(n):
data.append(data[0])
with open('personal_assistant.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
然后执行
python generate.py
修改internlm_chat_7b_qlora_akan_e3.py数据配置。
还是忘了改max_epochs = 50改回2了。毕竟我是1000个重复数据微调50次,5万次确实浪费
rm -rf ./work_dirs/
xtuner train internlm_chat_7b_qlora_akan_e3.py --deepspeed deepspeed_zero2
xtuner convert pth_to_hf ./internlm_chat_7b_qlora_akan_e3.py ./work_dirs/internlm_chat_7b_qlora_akan_e3/epoch_2.pth ./hf
xtuner convert merge ./internlm-chat-7b ./hf ./merged --max-shard-size 2GB
xtuner chat ./merged --prompt-template internlm_chat
这微调学习效率也是无敌了。1000遍重复,训练2000次损失还有0.4799,3000次看来效果也不咋地啊
果然,loss太大,估计不太乐观。
数据加倍,再来一轮。loss虐我千百遍,我就再加点量多训练一会。感谢主办方补充算力。
第二轮看起来很幸运,loss极速下降?
第三轮好运耗尽,没有反弹也算平稳了。估计这个loss应该差不多接近了。
果然,就这个水平了。
崩溃
把名字从akan换成“一棵秋天的树”。看来有效?
多收了三五斗。
心都凉了。改成中文确实loss有点变化,结果还是不行
从头开始,终于ok
事缓则圆,重新按self弄一个conda环境,一切重头,目测2处改动。之前name=一棵秋天的树,现在name=冠军侯。 然后max-length=2048根据文档改为512。居然就OK了。所以我估计3000次差不多。这样关了重来时间可以短点。
改为3000次重复写入,第二批次时,loss=0.03左右基本ok了。其实按照数据量,现在应该是重复4000次学习了。我试过重复1000遍,3个批次大约重复3000次,效果不行。
理论上说应该主要是name的影响比较大,毕竟分词可能还是会受到影响。“一棵秋天的树”这种名字,估计不容易分准确,需要的时间更长,强制加【】之类的估计会更好。等复现完成后可以验证一下。
见了鬼?看来就是环境问题?从头创建环境,大体上loss在第二轮降到0.015附近。其实就可以通过微调每90步检测,看到微调效果基本OK了。
验证的时候,temprature=0.18,topN=0.26,这两个值小点容易验证。太大不行。
即使name="我是一棵秋天的树"也没啥影响,第二轮基本ok。
name=akan,也是可以的。看来之前应该是环境配置有问题。
name=akan, max_length=2048, 看起来会复现。所以max_length这个参数居然如此重要?
那看来max_length=2048时,pack_to_max_length = True应该置为false,也许这样虽然浪费一点内存,但不影响微调效果?
果然。看来默认配置其实不太科学,这样微调成本可以大大降低,应200次左右差不多了。