这几天趁着五一假期在家里,做了一下LLM微调

大概是全网第一个做粤语微调的Qwen-7B,还请到huggingface和魔搭社区点心支持一下

repo:

https://huggingface.co/stvlynn/Qwen-7B-Chat-Cantonese

https://www.modelscope.cn/models/stvlynn/Qwen-7B-Chat-Cantonese

今天就整理一下微调的过程,因为是第一次做微调可能内容会比较粗糙还请谅解


准备工作

什么是大模型微调

简单说就是在现有的大模型基础上进行训练,模仿训练集的语言风格或者学习一门新语言

LLaMA-Factory

这是大佬们开发的一个LLM微调工具,大大降低了微调的难度,并且可以直接运行在Gooogle Colab上,零成本完成微调

数据集准备

我觉得数据集的准备恰恰是整个微调最耗时间且最难的部分,如果有大佬已经准备好了处理好的数据集倒好说,如果是要做冷门语言并且网上还没有相关资源的话就难弄了。

建议先上huggingface/魔搭社区上找找有没有数据集,注意内容最好是提问-回答格式的,比如这种:

数据格式

如果找到的是文章格式的也没有关系,后面会写怎么做预处理。

没有数据集或者想要自己创建数据集的话可以自己写脚本爬取,找一些评论网站、论坛爬内容。

一般学python都会教怎么写爬虫,如果实在不会的话可以让GPT代劳。

注意,数据集越多样、越丰富越不容易过拟合,这对后面的训练有利

环境搭建

租GPU

如果你有足够高显存的GPU,就可以选择本地运行LLaMA-Factory,如果没有这个条件的话可以考虑租GPU服务器

国内比较推荐的是Autodl和阿里云,前者价格实惠,学生认证还能便宜,后者注册有代金券,但是听说会乱扣费就没敢用

我自己训练的时候是用的Autodl,已经用了很长时间了。

新建容器

注册登陆Autodl,新建容器,镜像选择社区镜像,如图,选择xxxiu的镜像

镜像选择

注意,可能会因为CUDA版本过低导致无法选择该实例,换一台机器就行

开机后登入Jupyter Notebook,不过为了接下来的数据预处理这里建议先关机换无卡模式开机,节省成本

数据预处理

如果你已经有问答格式的数据集,那么就可以直接跳过这一步

这一步恰恰是全部过程里面最耗时的工作,光是搜集数据集就比较困难

已有问答格式数据集

训练所需的标准格式数据集格式可以看LLaMA-Factory的文档

该项目目前支持两种格式的数据集:alpacasharegpt,其中 alpaca 格式的数据集按照以下方式组织:

[
  {
    "instruction": "用户指令(必填)",
    "input": "用户输入(选填)",
    "output": "模型回答(必填)",
    "system": "系统提示词(选填)",
    "history": [
      ["第一轮指令(选填)", "第一轮回答(选填)"],
      ["第二轮指令(选填)", "第二轮回答(选填)"]
    ]
  }
]

其中 query 列对应的内容会与 prompt 列对应的内容拼接后作为用户指令,即用户指令为 prompt\nqueryresponse 列对应的内容为模型回答。

system 列对应的内容将被作为系统提示词。history 列是由多个字符串二元组构成的列表,分别代表历史消息中每轮的指令和回答。注意在指令监督学习时,历史消息中的回答也会被用于训练

对于预训练数据集,仅 prompt 列中的内容会用于模型训练,例如:

[
  {"text": "document"},
  {"text": "document"}
]

对于偏好数据集response 列应当是一个长度为 2 的字符串列表,排在前面的代表更优的回答,例如:

[
  {
    "instruction": "用户指令",
    "input": "用户输入",
    "output": [
      "优质回答",
      "劣质回答"
    ]
  }
]

这时直接放在/LLaMA-Factory/data下面就行

如果你没有处理成json格式,只有文本格式的问答也可以,写成以下格式:

问:xxxx
答:xxxx

这个容器镜像里面作者已经做好了将上述格式转换为json格式的脚本了,将全部内容粘贴到 /LLaMA-Factory/数据集全自动处理/放置数据集.txt 里,再运行

bash /root/LLaMA-Factory/chuli/一条龙2.sh

就会转换好json格式并且存储

无问答格式数据集

通常情况下我们能搜集到的可能是许多语段而不是问答,虽然LLaMA-Factory支持这种无问答的格式(可以见数据集文件夹下的wiki_demo.txt),但是为了更好的训练这里可以用在线的大模型将文本整理为问答格式

接下来的步骤就比较烧token了,我处理数据集的过程总共消耗了4000k左右的token,如果有glm的话大概用两个号的试用额度

打开 /LLaMA-Factory/数据集全自动处理/受刑文本.txt ,把文本粘贴进去,运行

bash /root/ChatAT/ku/半自动.sh

但是这里使用的是作者的api,可能很快就消耗完了,这里可以替换成自己的api:

打开 /LLaMA-Factory/chuli/第二步模型.py

修改 api_keyopenai.api_base 的值

如果你有自己用oneapi整合过的api就更方便了,可以直接调用glm

当然你也可以修改system prompt,调整成别的语言。

下载模型

作者在 /autodl-tmp 目录下已经提前存了Qwen1.5-7B-Chat模型,如果你想换成其他的模型可以使用作者写的下载脚本:

python /root/LLaMA-Factory/模型贩卖机.py

这个脚本只能下载

1.Qwen-7B-Chat

2.chatglm3-6b

3.Qwen1.5-7B-Chat

4.Qwen1.5-14B-Chat

5.Qwen-14B-Chat

6.Orion-14B-Chat

当然你也可以自己下载模型到 /autodl-tmp 下,建议先上魔搭社区找个好然后按照上面写的下载教程下载就行

比如:

#SDK模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('ZhipuAI/chatglm3-6b',cache_dir='/root/autodl-tmp')

开始训练

进入webui

在Jupyter Notebook新建页面找到终端

运行

bash /root/LLaMA-Factory/chuli/one.sh

此时webui已经开始在6006端口运行了

回到autodl的管理界面,找到 自定义服务 ,跟着上面教程把主机代理到本地就行

打开 localhost:6006 就会看到如下界面

webui

如果看不懂英文就把语言切到zh

如果你想要使用自己下载的模型,模型名称选择Custom,模型路径选择保存模型文件夹的位置

数据集可以选作者做好的,也可以选择自己跑的,点击名字叫 创造数据集 的数据集就行

接下来点击预览数据集,可以看到数据集的数量

在没理解清楚微调原理之前这里先不建议对预设参数进行过多改动,这里只需要根据数据集的数量选择合适的训练轮数就行,100条训练20轮,1000条训练10轮,10000条训练2轮

当然,以上不是绝对的,你可以根据自己的需要调整

点击 预览命令 再点击开始 就可以开始训练了

这个时候注意观察旁边的损失曲线,可以对照下面的图像

损失曲线

左上角的显示出无法学到任何信息,可能需要进行一些平滑处理以更好理解;第二个图像则展现了典型的过拟合现象;第三个图像则表现出更为严重的过拟合情况;第四个图像损失值未趋于稳定,可能是训练不足;第五个图像经历了较长的迭代才逐渐收敛,显示出权重初始化过小,或者数据集中可能存在错误数据(比如猫数据集中包含了狗的图像),导致神经网络花费大量时间在这些不相关数据上;而最后一个图像随着学习过程,损失值逐渐增大,可能是出现了“梯度爆炸”的情况。

当然光看图是不够的,最重要的还是自己跑几轮对话试一下

试运行&打包

训练完成后,选择 Chat 一栏,刷新适配器,选择适配器路径,点刚刚炼好的模型

就可以直接对话了

如果觉得不错就可以填写打包路径,选择 Export 打包了

注意,如果要重新炼的话一定要选择卸载模型,否则会占用很多显存,另外新训练的模型要修改路径名称

Last modification:May 5, 2024
如果觉得我的文章对你有用,请随意赞赏