书生·浦语大模型实战营 第八节课 微调弱智吧(如果AI可以正确回答弱智吧的所有问题,人类在AI眼里都是弱智吧!)

单眼皮的树袋熊 2024-06-23 14:01:09 阅读 84

读前感:

第四节课也进行了简单的微调,但最终微调出来个傻子,这次再试试,看看如何进行改善。实际的应用场景中使用微调的应该不会特别多,毕竟开源大模型并不是小公司可以玩得起的。 对于小公司,真正的微调有哪些场景呢? 欢迎大家讨论。

读后感:

本节课是整个训练营的最后一份笔记。 希望这8节笔记可以帮助到一些希望入门大模型的朋友,采用最简单的方式先建立起大模型的整体框架。后续再根据个人的兴趣和发展,找到更有针对性的方向。从5月30日到今天,整体过程耗时12天。学习效果明显,收获满满。特别感谢书生·浦语提供的各种支持。 InternStudio 算力平台非常稳定,而且提供了一系列预先配置好的环境、模型等工具, 使用非常方便。感谢微信群里面随时支持,有问必答的助教---白菜炖豆腐。在群里面给同学们很多的帮助和支持。大模型的发展核心是数据,希望大佬们可以分享一些关于数据管理、数据治理方面的经验和工具。

重要资源:

首页-OpenDataLab:OpenDataLab 引领AI大模型时代的开放数据平台

OpenDataLab (github.com):OpenDataLab · GitHub

1 XTuner教学使用

参见第四节课的笔记内容,这里面不再重复。

2 微调实战

2.1 概述

2.1.1 场景需求

基于 InternLM2-chat-7b 模型,用弱智吧中的数据进行微调,训练一个不弱智的模型

2.2 数据准备

2.2.1 准备环境

开发机上面准备相关的配置。

首先检查开发的虚拟环境

studio-conda xtuner #通过开发机提供的环境直接建立虚拟环境。conda deactivate #关闭当前虚拟conda activate xtuner #启动虚拟环境 安装xtuner,之前已经安装过的可以跳过。

cd /root #转移到根目录git clone https://github.com/InternLM/xtuner.git #拉取开源文件cd xtuner #切换到程序的目录pip install -e '.[all]' -i https://mirrors.aliyun.com/pypi/simple/ #安装所需要的库文件。 这里面我们使用的是internlm-demo 的虚拟环境, 所以大部分库文件已经完成了安装,速度要快一些。 创建微调目录

cd /root/xtunermkdir ft #创建一个新的目录,用于存放微调的数据cd ftmkdir ruozhiba #创建弱智吧的微调目录cd ruozhibamkdir datasets #后续存储弱智吧的数据集

2.2.2 数据构造

首先介绍下如何构造高质量的SFT数据,数据永远是最重要的部分。

2.2.2.1数据选择和采集

微调数据的选择应该基于目标应用场景:

领域相关性:选择与预期应用场景密切相关的文本数据。例如,如果目标是法律助理,应选择法律文档和案例。本实验目的是提升模型的推理和识别逻辑陷阱的能力,因此选择弱智吧的数据。质量高:这里指的是问题和回答都要是高质量的,通常需要语法正确,信息准确,风格一致。具体来说,好的回复应该遵循“无害(Harmless)、诚实(Honest)、有帮助(Helpful)”的三H原则。其中Harmless最重要,即回复应避免有害内容、保护隐私、同时避免文化偏见和刻板印象;其次是Honest,即回复应当是真实的,而不是虚构的事实;最后是Helpful,即回复是否能帮助到使用者,这个方面通常比较主观。多样性:确保数据覆盖所有相关子话题,以促进模型的泛化能力。

2.2.2.2数据预处理

为了提高模型的效率和效果,数据预处理是必不可少的步骤:

清洗:去除无关的内容,如广告、HTML标签、无意义的填充词等。标准化:统一词汇的格式,比如时间、日期、货币单位等。分词:根据目标模型的需求进行适当的分词处理。去噪声:消除文本中的错误,如拼写错误、语法错误等。

2.2.2.3 数据标注

由于微调数据规模不大,因此可以通过标注的方式来进行构造,这里有两种不同的标注方法:

人工标注:由人工专家进行标注,确保标注的准确性和一致性。采用人工的方式成本比较高,但质量相对较好,尤其在涉及一些专业领域的时候,领域专家能够更好的理解问题并给出回复。这里介绍下我们的仓库:OpenDataLab自动标注:使用已有的模型进行初步标注,然后由人工校验和修正。可以采用GPT4来生成回复,再由人工来判断回答的好坏,并进行修正。

2.2.2.4 数据增强

数据增强可以提高模型的鲁棒性和泛化能力,方法有:

文本重述:用不同的方式表达同一意思,增加文本的多样性。翻译循环:将文本翻译成一种语言,然后再翻译回原语言,通常用于生成新的文本表达。合成数据生成:使用规则或模型生成新的训练样本。

2.2.2.5 数据划分

通常分为训练集、验证集和测试集。合理划分数据,确保模型能在未见过的数据上进行有效的泛化测试。

在本次实验中我们直接采用公开数据集中处理过的微调数据给大家做个简单的演示。大家可以访问 Huggingface 或者 OpenDatalab 进行数据集下载,由于huggingface网络连接问题,推荐国内的同学访问OpenDataLab进行数据集下载。我们选择其中的弱智吧数据进行微调,这个数据集的问题来自于点赞数超过500的弱智吧问题,基本都是一些逻辑陷阱或者脑筋急转弯,然后通过人工或GPT4的方式编写正确回答,再由人工校验后筛选出200多条高质量微调数据。

2.2.3 真实数据预览

早opencompass的核心datasets里面并没有弱智吧的数据集,这部分需要到huggingface自行下载。查询”ruozhiba“找一个最近更新的下载即可。

将准备好的文件ruozhiba_qa.json上传到开发机的对应目录下:/root/xtuner/ft/ruozhiba/datasets

我下载的数据包的格式如下

[{ "instruction": "只剩一个心脏了还能活吗?", "output": "能,人本来就只有一个心脏。"}, { "instruction": "爸爸再婚,我是不是就有了个新娘?", "output": "不是的,你有了一个继母。\"新娘\"是指新婚的女方,而你爸爸再婚,他的新婚妻子对你来说是继母。"}]

2.2.4 将数据转为 XTuner 的数据格式

目标格式应该为如下方式

{ "messages": [ { "role": "user", "content": "" }, { "role": "assistant", "content": "" }]}

编制转换脚本

cd /root/xtuner/ft/ruozhiba/datasetstouch data2xtuner.py

使用vscode 编辑data2xtuner.py

# data2xtuner.pyimport json # 加载原始数据 with open('ruozhiba_qa.json', 'r', encoding='utf-8') as f: data = json.load(f) # 转换数据格式 def convert_to_jsonl_format(item): return { "messages": [ {"role": "user", "content": item["instruction"]}, {"role": "assistant", "content": item["output"]} ] } # 转换并分割数据 train_size = int(len(data) * 0.7) train_data = data[:train_size] test_data = data[train_size:] # 写入训练数据 with open('ruozhiba_xtuner_train.jsonl', 'w', encoding='utf-8') as train_file: for item in train_data: jsonl_item = convert_to_jsonl_format(item) train_file.write(json.dumps(jsonl_item, ensure_ascii=False) + '\n') # 写入测试数据 with open('ruozhiba_xtuner_test.jsonl', 'w', encoding='utf-8') as test_file: for item in test_data: jsonl_item = convert_to_jsonl_format(item) test_file.write(json.dumps(jsonl_item, ensure_ascii=False) + '\n') # 总结操作过程并打印 print(f"转换完成,总数据条数: {len(data)}") print(f"训练集数据条数: {len(train_data)},已保存到 ruozhiba_xtuner_train.jsonl") print(f"测试集数据条数: {len(test_data)},已保存到 ruozhiba_xtuner_test.jsonl")

运行脚本

python data2xtuner.py

转换后的格式如下:

{"messages": [{"role": "user", "content": "只剩一个心脏了还能活吗?"}, {"role": "assistant", "content": "能,人本来就只有一个心脏。"}]}{"messages": [{"role": "user", "content": "爸爸再婚,我是不是就有了个新娘?"}, {"role": "assistant", "content": "不是的,你有了一个继母。\"新娘\"是指新婚的女方,而你爸爸再婚,他的新婚妻子对你来说是继母。"}]}

2.3 开始自定义微调

首先测试一下大模型原始的能力,直接使用lmdeploy的对话模式,使用之前已经使用的internlm2-chat-7b模型

lmdeploy chat /root/model/Shanghai_AI_Laboratory/internlm-chat-7b

将弱智吧最开头的两个问题问问大模型,回答都是错误的。

2.3.1 准备配置文件

查看当前可以使用的微调配置

# 列出所有内置配置文件xtuner list-cfg

这里面有一个很长的清单,咱们选取一个internlm2的模型,毕竟本次实战营都是internlm书生浦语赞助的,咱们也支持一下。

#选取internlm_7b_qlora_alpaca_e3配置文件cd /root/xtuner/ft/ruozhiba #进入目录xtuner copy-cfg internlm_7b_qlora_alpaca_e3 .

xtuner会拷贝配置文件internlm_7b_qlora_alpaca_e3_copy.py到当前的文件夹。用vscode编辑这个文件。

文件的详细解释见第四节课的内容,这里只标记需要修改的内容。

2.3.2 启动训练

启动训练, 这个训练比较长,我训练的环境是30% A100 24G显存

# 解决一下线程冲突的 Bug export MKL_SERVICE_FORCE_INTEL=1 xtuner train /root/xtuner/ft/ruozhiba/internlm_7b_qlora_alpaca_e3_copy.py \ --work-dir /root/xtuner/ft/ruozhiba/train \ --deepspeed deepspeed_zero2 #deepspeed_zero2:在deepspeed_zero1的基础上,deepspeed_zero2进一步优化了梯度和优化器状态的存储。它将这些信息也分散到不同的GPU上,进一步降低了单个GPU的内存需求。

训练完成后检查新生成的文件

2.3.3 pth 转 huggingface

将得到的 PTH 模型转换为 HuggingFace 模型,即:生成 Adapter 文件夹

cd /root/xtuner/ft/ruozhibaxtuner convert pth_to_hf \ /root/xtuner/ft/ruozhiba/internlm_7b_qlora_alpaca_e3_copy.py \ /root/xtuner/ft/ruozhiba/train/iter_96.pth \ /root/xtuner/ft/ruozhiba/huggingface

自动创建huggingface目录和相应的adapter

此时,huggingface 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”

可以简单理解:LoRA 模型文件 = Adapter

2.3.4 对话

可以通过xtuner直接将adapter与大模型一起合并调用。

cd /root/xtuner/ft/ruozhibaxtuner chat /root/model/Shanghai_AI_Laboratory/internlm-chat-7b \ --adapter /root/xtuner/ft/ruozhiba/huggingface \ --prompt-template internlm2_chat

这里可以看出回答有一定的进步, 但是并不是很明显。 这里可以继续进行微调,到满意为止。

我在这里又重新微调了一下,将internlm_7b_qlora_alpaca_e3_copy.py里面的max_epochs调整为8。重新进行pth转换。

新训练的结果从iter_96.pth变为iter_256.pth

cd /root/xtuner/ft/ruozhiba#格式转换xtuner convert pth_to_hf \ /root/xtuner/ft/ruozhiba/internlm_7b_qlora_alpaca_e3_copy.py \ /root/xtuner/ft/ruozhiba/train/iter_256.pth \ /root/xtuner/ft/ruozhiba/huggingface#对话xtuner chat /root/model/Shanghai_AI_Laboratory/internlm-chat-7b \ --adapter /root/xtuner/ft/ruozhiba/huggingface \ --prompt-template internlm2_chat

具体微调的参数还需要根据经验自行调整。下面是更多次微调的结果,效果还不错。

2.4 部署与测试

2.4.1 将 HuggingFace adapter 合并到大语言模型

cd /root/xtuner/ft/ruozhiba#export MKL_SERVICE_FORCE_INTEL=1 # 解决一下线程冲突的 Bug #export MKL_THREADING_LAYER=GNU # 上面的一条不行可以试试这一条。xtuner convert merge \ /root/model/Shanghai_AI_Laboratory/internlm-chat-7b \ /root/xtuner/ft/ruozhiba/huggingface \ /root/xtuner/ft/ruozhiba/final_model

生成的新模型如下图

2.4.2 与合并后的模型对话:

port MKL_SERVICE_FORCE_INTEL=1 # 解决一下线程冲突的 Bug #export MKL_THREADING_LAYER=GNU # 上面的一条不行可以试试这一条。# 加载 Adapter 模型对话cd /root/xtuner/ft/ruozhibaxtuner chat \ /root/xtuner/ft/ruozhiba/final_model \ --prompt-template internlm2_chat

后续就可以直接使用lmdeploy等工具对大模型进行部署了。

合并之后的模型基本对话正常

再从测试数据里面找几个问题试试,总体上表现还可以,模型逐步会脑筋急转弯了。

我在想,如果AI可以正确回答弱智吧的所有问题,人类在他们的眼里都是弱智吧!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。