目录
一、将自我认知的模型上传到OpenXLab,并将应用部署到OpenXLab
笔记部分:
一、微调Finetune的介绍
1、关于微调
1.为什么要微调?
微调可以使预训练的基础模型适应特定的任务或领域,从而提升模型在特定应用场景下的表现。
2.两种Finetune范式
常见的微调范式有两种:增量预训练微调和指令跟随微调。
- 增量预训练微调:通过增量数据(如文章、书籍、代码等)让模型学习新的知识。适用于扩展模型的常识库。
- 原理:继续在新的语料库上进行预训练,使模型学习到更多的知识。
- 应用场景:适用于扩展模型的常识库,增强模型的知识面。
- 优势:可以在大规模数据上进行训练,适合需要大量知识更新的场景。
- 指令跟随微调:通过高质量的对话和问答数据训练模型,使其能够更好地理解和执行用户指令。
- 原理:通过高质量的指令-响应对进行微调,使模型能够更好地理解和执行用户的指令。
- 应用场景:适用于对话生成、智能助理等需要精确理解和响应用户指令的任务。
- 优势:针对性强,可以显著提升模型在特定任务上的表现。
3.一条数据的一生
数据处理过程包括从原始数据到可训练数据的转化。在对话模型中,通常使用对话模板来标注不同的角色,如System、User和Assistant。不同模型有不同的对话模板。
对话模板:为了能让LLM区分出 System、User、Assistant,不同模板有不同的对话模板。
为了让LLM知道什么时候开始和结束一段话,实际训练时需要添加起始符(BOS)和结束符(EOS),大多数模型使用<s>为起始符,</s>为结束符。
- 数据收集:从各种来源收集原始数据,包括对话记录、问答对等。
- 数据处理:对原始数据进行清洗、标注和格式化,转换为模型可接受的格式。
- 数据加载:使用XTuner的加载功能,将处理好的数据加载到训练管道中。
- 训练过程:在XTuner的优化算法支持下,进行高效的模型训练。
- 模型评估:训练完成后,对模型进行评估和验证,确保其在目标任务上的性能。
LoRA & QLoRA
LoRA: Low-RANK ADAPTION OF LARGE LANGUEGE MODELS
QLoRA: Quantized Low-Rank Adaptation
LLM的参数量主要集中在模型中的Linear,训练这些参数会耗费大量的显存。
LoRA通过在原本的Linear旁边,新增一个包含两个连续的小Linear的支路(新增支路通常叫做Adapter)。Adapter参数量远小于原本的Linear,能大幅降低训练的显存消耗。
简单通俗的类比:改造一个超大的玩具,如果全面改动会非常昂贵,一种叫LoRA的方法只对玩具中的某些零件进行改动,而不是对整个玩具进行全面改动。而QLoRA是LoRA的一种改进,手上只有一把生锈的螺丝刀,也能改造你的玩具。
LoRA是一种让我们能更容易调整大语言模型的方法。我们知道,大语言模型有很多参数,调整它们会很复杂,而且需要很多计算资源和内存。LoRA通过一种聪明的方法减少了我们需要调整的参数数量,从而让这个过程变得更简单和高效。
怎么做?
- 分解参数:将一个大表格的模型参数分解为两个小表格。
- 微调小表格:微调模型时只需调整这两个小表格的参数,而不是整个大表格,从而实现更快、更节省内存的调整过程。
好处
- 更快:调整需要的时间更少。
- 更省内存:需要的计算资源和内存更少。
- 适用于大模型:特别适合那些参数特别多的大模型。
2、QLoRA
QLoRA(Quantized Low-Rank Adaptation)是在LoRA的基础上再进一步优化。除了用小表格来减少参数,QLoRA还通过“量化”这个技巧让参数表示得更简单,从而进一步减少内存和计算需求。
怎么做的呢?
- 分解参数:同样是把大表格分解成两个小表格。
- 量化参数:QLoRA将这些小表格中的数字转换为精度较低的整数形式,以减少内存消耗,代替原来精确的浮点数表示方式。
- 微调量化后的小表格:在调整模型的时候,我们调整这些简化后的数字。
好处:
- 进一步省内存:需要的内存更少。
- 更高效:计算速度更快。
- 适用于更大模型:即使是特别特别大的模型,也可以用很少的资源来调整。
假设我们有一本非常厚的书(大模型),我们想改这本书里的一些内容(微调模型)。LoRA的做法是先把书分成几小本(低秩分解),然后我们只改这些小本子里的内容,而不去动原来那本厚书。QLoRA则更进一步,把这些小本子里的字变成更简单的符号(量化),这样我们改起来就更容易、更快。
总结
- LoRA:用小表格来代替大表格,只调整小表格,速度快,省内存。
- QLoRA:在LoRA的基础上,把小表格里的数字变简单,进一步省内存,更高效。
二、XTuner 介绍
1.XTuner简介
傻瓜化:以配置文件的形式封装了大部分微调场景,0基础的非专业人员也能一键开始微调
轻量化:对于7B参数的LLM,微调所需最小显存为8G:消费级显卡、colab
XTuner是一款强大的微调工具,具有以下功能亮点:
- 多生态支持:XTuner支持HuggingFace和ModelScope的模型和数据集,提供了丰富的模型资源和数据集。
- 硬件适配:支持NVIDIA 20系以上显卡,最低8GB显存即可运行,极大降低了硬件门槛。
- 多种微调算法:包括LoRA、QLoRA等,可以根据具体需求选择最适合的微调算法。
- 显存和计算优化:内置Flash Attention和DeepSpeed ZeRO技术,自动处理复杂的显存优化和计算加速。
2.XTuner技术架构图
XTuner技术架构包括以下部分:
- 数据引擎:处理和格式化原始数据,支持多种对话模板和数据集映射函数。
- 功能:处理和格式化原始数据,支持多种对话模板和数据集映射函数。
- 模块:数据加载器、数据预处理模块、数据增强模块。
- 训练引擎:支持LoRA、QLoRA等微调算法,优化显存使用。
- 功能:支持各种微调算法,优化显存使用,确保训练过程高效。
- 模块:优化器模块、调度器模块、显存管理模块。
- 工具类模型对话:提供一键对话接口,支持多种模型的对话测试。
- 功能:提供一键对话接口,支持多种模型的对话测试。
- 模块:对话接口、模型加载器、对话管理器。
三、8G 显存玩转LLM
1. 优化技术
XTuner利用Flash Attention和DeepSpeed ZeRO优化显存使用:
- Flash Attention:将Attention计算并行化,减少显存占用。
- 原理:将Attention计算并行化,通过减少冗余计算降低显存占用。
- 优势:显著提升Attention机制的效率,降低显存需求。
- 应用:适用于任何需要优化显存的Attention机制。
- DeepSpeed ZeRO:通过切片保存参数、梯度和优化器状态,显著节省显存。
- 原理:通过将参数、梯度和优化器状态切片保存,减小每个设备上的显存负担。
- 优势:能够大幅降低显存使用,使在单个GPU上运行大型模型成为可能。
- 应用:在微调大型模型时,显存不足是常见问题,DeepSpeed ZeRO提供了有效解决方案。
2. 实例配置
XTuner可以自动配置和启动这些优化技术,简化了复杂的配置过程。例如,使用如下命令启动训练:
xtuner train internlm_20b_qlora_oasst1_512_e3 --deepspeed deepspeed_zero3
解析:使用XTuner工具对InternLM 20B模型进行微调,采用QLoRA算法,并启用DeepSpeed ZeRO 3优化技术。
配置步骤:
- 选择模型和数据集:确定要微调的模型和所用的数据集。
- 设置微调参数:根据任务需求设置微调的超参数,如学习率、批次大小等。
- 启用优化技术:通过配置文件或命令行参数启用Flash Attention和DeepSpeed ZeRO等优化技术。
四、InternLM2 1.8B模型
InternLM2-1.8B是一个高质量、高适应灵活性的基础模型,适合初学者进行微调和深入学习。提供了三个版本:
-
模型介绍
-
InternLM2-1.8B:
- 简介:基础模型,提供了强大的自然语言理解和生成能力。
- 适用场景:适用于一般性的NLP任务,如文本分类、情感分析等。
-
InternLM2-Chat-1.8B-SFT:
- 简介:在基础模型上进行监督微调得到的对话模型,增强了对话生成能力。
- 适用场景:适用于对话生成、客服机器人等需要人机交互的任务。
-
InternLM2-Chat-1.8B:
- 简介:通过在线RLHF(强化学习人类反馈)进一步优化的对话模型,具备更高的交互智能。
- 适用场景:适用于高质量对话生成和复杂任务的执行。
2. 应用示例
-
文本分类:
- 任务描述:根据输入的文本,将其分类到预定义的类别中。
- 模型选择:InternLM2-1.8B。
- 微调过程:使用标注好的文本分类数据进行微调。
-
对话生成:
- 任务描述:根据用户输入生成自然流畅的对话回应。
- 模型选择:InternLM2-Chat-1.8B-SFT 或 InternLM2-Chat-1.8B。
- 微调过程:使用高质量的对话数据进行微调,并通过在线RLHF进行进一步优化。
五、多模态LLM微调
1. 多模态LLM原理简介
多模态LLM(图像理解):相当于给LLM装上电子眼
多模态LLM通过整合文本和图像数据,使模型能够理解和生成多模态内容。LLaVA方案是一个典型的例子,通过图像数据生成描述,构建文本-图像对来训练模型。
- 定义:多模态LLM能够处理和生成多种模态的数据,如文本、图像、视频等。
- LLaVA方案:
- 简介:利用图像数据生成描述,构建文本-图像对来训练模型。
- 步骤:
- 数据准备:收集图像及其对应的文本描述。
- 数据处理:将图像和文本对齐,形成训练样本。
- 模型训练:使用XTuner工具进行多模态数据的微调。
2. 快速上手
xtuner finetune --model internlm2_chat_1.8b --dataset multimodal_dataset --epochs 3 --batch_size 16
解析:使用InternLM2_Chat_1.8B模型在多模态数据集上进行微调,设置训练轮次为3,批次大小为16。
详细步骤:
- 准备数据集:确保多模态数据集已经标注和格式化。
- 配置模型:选择合适的模型和微调参数。
- 运行微调:执行XTuner命令开始微调,并监控训练过程。
课程提供了详细的示例,指导如何使用InternLM2_Chat_1.8B与LLaVA进行多模态微调。
六、Agent
本节内容主要介绍如何在LLM中集成Agent功能,使模型能够执行复杂的任务,如联网搜索、使用计算器和解方程等。
- 定义:Agent是能够执行复杂任务的智能体,集成在LLM中,使模型具备更高的任务执行能力。
- 应用场景:联网搜索、使用计算器、解方程、自动化办公等。
实现方法
- 步骤:
- 定义任务:明确需要Agent执行的任务,例如搜索特定信息、进行计算等。
实战:XTuner 微调个人小助手认知 (基础作业)
内容:选用QLoRA方式微调个人小助手
开发机准备
Xtuner的运行原理
1、环境安装:安装XTuner
2、前期准备:明确微调目标,明确硬件的资源和数据。资源有限情况下,如何手段和方式来让模型有更好的效果。
3、启动微调:确定微调目标后,在XTuner的配置库中找到合适的配置文件,进行对应的修改,修改完即可一键启动训练。训练好的模型也可以在终端输入一行指令来完成转换和部署工作。
环境安装
# 在 InternStudio 平台,从本地 clone 一个已有 pytorch 的环境:
# pytorch 2.0.1 py3.10_cuda11.7_cudnn8.5.0_0
studio-conda xtuner0.1.17
# 激活环境
conda activate xtuner0.1.17
# 进入家目录 (~的意思是 “当前用户的home路径”)
cd ~
# 创建版本文件夹并进入,以跟随本教程
mkdir -p /root/xtuner0117 && cd /root/xtuner0117
# 拉取 xtuner0.1.17 的版本源码
git clone -b v0.1.17 https://github.com/InternLM/xtuner
# 如果无法访问github的用户请从 gitee 拉取:
# git clone -b v0.1.15 https://gitee.com/Internlm/xtuner
# 进入源码目录
cd /root/xtuner0117/xtuner
# 从源码安装 XTuner
pip install -e '.[all]'
# 假如速度太慢可以 Ctrl + C 退出后换成
# pip install -e '.[all]' -i https://mirrors.aliyun.com/pypi/simple/
1.数据集准备
为了让模型能够让模型认清自己的身份弟位,指导在询问自己是谁的时候回复成我们想要的样子,我们就需要通过在微调数据集中大量掺杂这部分的数据。
先创建一个文件夹,存放这次训练所需的所有文件
# 前半部分是创建一个文件夹,后半部分是进入该文件夹。
mkdir -p /root/ft && cd /root/ft
# 在ft这个文件夹里再创建一个存放数据的data文件夹
mkdir -p /root/ft/data && cd /root/ft/data
在data目录下新建一个generate_data.py文件
# 创建 `generate_data.py` 文件
touch /root/ft/data/generate_data.py
运行该脚本即可生成数据集,调整 n 可以加大重复次数,name后面的内容修改为自己的名称
import json
# 设置用户的名字
name = '凉拌大佬' # name = '不要姜葱蒜大佬'
# 设置需要重复添加的数据次数
n = 10000
# 初始化OpenAI格式的数据结构
data = [
{
"messages": [
{
"role": "user",
"content": "请做一下自我介绍"
},
{
"role": "assistant",
"content": "我是{}的小助手,内在是上海AI实验室书生·浦语的1.8B大模型哦".format(name)
}
]
}
]
# 通过循环,将初始化的对话数据重复添加到data列表中
for i in range(n):
data.append(data[0])
# 将data列表中的数据写入到一个名为'personal_assistant.json'的文件中
with open('personal_assistant.json', 'w', encoding='utf-8') as f:
# 使用json.dump方法将数据以JSON格式写入文件
# ensure_ascii=False 确保中文字符正常显示
# indent=4 使得文件内容格式化,便于阅读
json.dump(data, f, ensure_ascii=False, indent=4)
修改完后运行generate_data.py文件即可,随后data路径下生成personal_assistant.json文件,至此用于微调的数据集已经准备好了。
# 确保先进入该文件夹
cd /root/ft/data
# 运行代码
python /root/ft/data/generate_data.py
关于数据集:除了自己通过脚本的数据集,网上也有大量的开源数据集可以供我们进行使用。有些时候我们可以在开源数据集的基础上添加一些我们自己独有的数据集,也可能会有很好的效果。
2.模型准备
数据集ok,开始准备用于微调的模型。
由于显存问题,使用InternLM最新推出的小模型 InternLM2-Chat-1.8B完成微调演示。
InternStudio本地share文档个已有模型文档,可以不用通过OpenXLab/Modelscope进行模型下载
方法一:从share文件夹里copy,放到 /root/ft/model里
# 创建目标文件夹,确保它存在。
# -p选项意味着如果上级目录不存在也会一并创建,且如果目标文件夹已存在则不会报错。
mkdir -p /root/ft/model
# 复制内容到目标文件夹。-r选项表示递归复制整个文件夹。
cp -r /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b/* /root/ft/model/
方法二:存储空间不足下,通过符号链接方式链接到模型文件,能节省空间&方便管理
# 删除/root/ft/model目录
rm -rf /root/ft/model
# 创建符号链接
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b /root/ft/model
关于软链接(Symbolic Link):也叫符号链接,是一个指向另一个文件或目录的特殊文件,就像一个快捷方式,好处是方便访问、节省空间,在多个位置快速创建访问相同文件/目录的入口,灵活性高。软链接的常见用法:共享文件、版本控制、简化路径。
当我们访问 /root/ft/model
时,实际上就是在访问 /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b
目录下的内容。通过这种方式,我们无需复制任何数据,就可以直接利用现有的模型文件进行后续的微调操作,从而节省存储空间并简化文件管理。
3.配置文件选择
数据集ok、模型ok,根据这些以及微调方法→找最匹配的配置文件
关于配置文件config:用于定义和控制模型训练过程中各方面的参数和设置的工具,准备好的配置文件只要运行起来就代表着模型开始训练/微调了。
XTuner提供多个开箱即用的配置文件:
开箱即用意味着假如能够连接上 Huggingface 以及有足够的显存,其实就可以直接运行这些配置文件,XTuner就能够直接下载好这些模型和数据集然后开始进行微调
# 列出所有内置配置文件
# xtuner list-cfg
# 假如我们想找到 internlm2-1.8b 模型里支持的配置文件
xtuner list-cfg -p internlm2_1_8b
# 定向搜索得到两个配置文件
# internlm2_1_8b_full_alpaca_e3
# internlm2_1_8b_qlora_alpaca_e3
XTuner 的工具 list-cfg:
不额外添加参数,把所有配置文件打印出来
加上参数-p或--pattern,后面输入的内容就会在config文件里进行模糊匹配搜索,返回最有可能的内容。
选择QLoRA对internlm2_chat_1.8b微调,最相近的配置文件是internlm2_1_8b_qlora_alpaca_e3
# 创建一个存放 config 文件的文件夹
mkdir -p /root/ft/config
# 使用 XTuner 中的 copy-cfg 功能将 config 文件复制到指定的位置
xtuner copy-cfg internlm2_1_8b_qlora_alpaca_e3 /root/ft/config
XTuner 工具箱中的第二个工具 copy-cfg:需填写参数{CONFIG_NAME} 和 {SAVE_PATH}
小结:
- 克隆 XTuner 源码并安装相关配套库。
- 准备关于调教模型的数据集。
- 根据显存和任务情况,确定并复制 InternLM2-chat-1.8B 模型到文件夹。
- 根据微调方法、数据集和模型,挑选并复制XTuner中合适的配置文件到新建文件夹。
微调最核心的利器:一份高质量的数据集!
3. 配置文件修改:略
4. 模型训练
① 常规训练
数据集ok、模型ok、配置文件修改ok,只要使用 xtuner train指令即可开始训练。
# 添加--work-dir指定保存路径
# 不添加路径的话,模型训练的过程文件默认保存,在./work_dirs/internlm2_1_8b_qlora_alpaca_e3_copy 的位置,例如这里是/root/ft/train/work_dirs/internlm2_1_8b_qlora_alpaca_e3_copy
xtuner train /root/ft/config/internlm2_1_8b_qlora_alpaca_e3_copy.py --work-dir /root/ft/train
② 使用deepspeed来加速训练
可以结合 XTuner 内置的 deepspeed
来加速整体的训练过程,deepspeed有3种类型可选
zero
代表“ZeRO”(Zero Redundancy Optimizer),是一种旨在降低训练大型模型所需内存占用的优化器。ZeRO 通过优化数据并行训练过程中的内存使用,允许更大的模型和更快的训练速度。ZeRO 分为几个不同的级别:
-
deepspeed_zero1:基本版本,优化了模型参数的存储,每个GPU只存储一部分参数,从而减少内存的使用。
-
deepspeed_zero2:在deepspeed_zero1的基础上,进一步优化了梯度和优化器状态的存储。它将这些信息也分散到不同的GPU上,进一步降低了单个GPU的内存需求。
-
deepspeed_zero3:目前最高级的优化等级,不仅包括了前两版的优化,还进一步减少了激活函数的内存占用。通过在需要时重新计算激活(而不是存储它们)来实现,从而实现了对大型模型及其内存效率的训练。
关于deepspeed加速器:由微软开发的深度学习优化库,旨在提高大规模模型训练的效率和速度。通过几种关键技术来优化训练过程,包括模型分割、梯度累积、以及内存和带宽优化等。DeepSpeed特别适用于需要巨大计算资源的大型模型和数据集。
选择哪种deepspeed类型主要取决于具体需求,包括模型的大小、可用的硬件资源(特别是GPU内存)以及训练的效率需求。一般来说:
- 小模型或内存充足时,不需要最高级别优化。
- 大模型或资源有限时,使用deepspeed_zero2或deepspeed_zero3减少内存占用。
- 考虑优化复杂性和运行时开销,高级优化可能需要复杂设置和增加计算负担。
# 使用 deepspeed 来加速训练
xtuner train /root/ft/config/internlm2_1_8b_qlora_alpaca_e3_copy.py --work-dir /root/ft/train_deepspeed --deepspeed deepspeed_zero2
# 使用了 deepspeed 则是一个名字带有 .pth 的文件夹,在该文件夹里保存了两个 .pt 文件
3.训练结果
设置了每300轮评估一次,对比300轮和600轮的结果区别。
在第一批次第600轮时,模型出现严重过拟合,只会重复一句话。为了保持通用能力,应该选择前面的权重文件进行后续模型转化和整合。
解决办法:
减少保存权重文件的间隔并增加权重文件保存的上限:通过降低间隔评估结果,找到最优权重文件。每隔100个批次检查模型,确定何时既学到知识又保留常识,何时开始过拟合只重复一句话。
增加常规的对话数据集从而稀释原本数据的占比:比如说在一万条正常的对话数据里混入两千条和小助手相关的数据集,这样模型同样可以在不丢失对话能力的前提下学到XXXX的小助手这句话。
2.5 模型转换、整合、测试及部署
1.模型转换
模型转换:模型转换本质就是将 Pytorch 训练的模型权重文件转换为 Huggingface 通用格式文件。
# 通过以下指令一键转换模型
# 创建一个保存转换后 Huggingface 格式的文件夹
mkdir -p /root/ft/huggingface
# 模型转换
# xtuner convert pth_to_hf ${配置文件地址} ${权重文件地址} ${转换后模型保存地址}
xtuner convert pth_to_hf /root/ft/train/internlm2_1_8b_qlora_alpaca_e3_copy.py /root/ft/train/iter_768.pth /root/ft/huggingface
转换完成后,可以看到模型被转换为 Huggingface 中常用的 .bin 格式文件
# 转换完后huggingface文件夹显示如下
|-- huggingface/
|-- adapter_config.json
|-- xtuner_config.py
|-- adapter_model.bin
|-- README.md
此时,huggingface 文件夹即为我们平时所理解的所谓 “LoRA 模型文件”
简单理解即:LoRA 模型文件 = Adapter
此外,转换指令中还能添加几个额外参数:
--fp32:代表以fp32精度开启,假如不输入默认是fp16
--max-shard-size {GB}:代表每个权重文件最大的大小(默认是2GB)
# 假如加上上述参数的话
xtuner convert pth_to_hf /root/ft/train/internlm2_1_8b_qlora_alpaca_e3_copy.py /root/ft/train/iter_768.pth /root/ft/huggingface --fp32 --max-shard-size 2GB
2.模型整合
LoRA 或 QLoRA 微调生成的模型是额外的层(adapter),需与原模型组合才能使用。而全量微调的模型是直接修改原模型权重(而非微调一个新的adapter),不需要进行整合。
XTuner 提供一键整合指令,但使用前需准备三个地址:原模型地址、训练后转换为 Huggingface 格式的 adapter 地址和最终保存地址。
# 创建一个名为 final_model 的文件夹存储整合后的模型文件
mkdir -p /root/ft/final_model
# 解决一下线程冲突的 Bug
export MKL_SERVICE_FORCE_INTEL=1
# 进行模型整合
# xtuner convert merge ${NAME_OR_PATH_TO_LLM} ${NAME_OR_PATH_TO_ADAPTER} ${SAVE_PATH}
xtuner convert merge /root/ft/model /root/ft/huggingface /root/ft/final_model
除了LLM路径、ADAPTER路径、保存路径三个基本参数,模型整合还有很多可选参数,例如:
--max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
--device {device_name} | 指device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
--is-clip | 主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
关于CLIP:CLIP(Contrastive Language–Image Pre-training)是 OpenAI 开发的预训练模型,能理解图像与描述文本的关系。通过在大规模数据集上学习图像与文本的对应关系,CLIP实现了图像理解、分类及文本提示生成图像。在模型整合完成后,final_model 文件夹会生成类似原模型的内容,包括分词器、权重文件和配置信息。整合后,我们可以正常调用模型进行对话测试。
3.对话测试
XTuner 提供了基于 transformers 的对话代码,允许我们在终端与 Huggingface 格式的模型对话。只需准备转换后的模型路径并选择正确的提示词模板即可(prompt-template)。选择错误的模板可能导致模型无法正确回复。
查找 XTuner 源码中的 xtuner/utils/templates.py 文件,可以了解具体模型的提示词模板(prompt-template)或 XTuner 支持的模板。
xtuner chat
指令的参数
数 | 解释 |
---|---|
--system | 指定SYSTEM文本,用于在对话中插入特定的系统级信息 |
--system-template | 指定SYSTEM模板,用于自定义系统信息的模板 |
--bits | 指定LLM运行时使用的位数,决定了处理数据时的精度 |
--bot-name | 设置bot的名称,用于在对话或其他交互中识别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 | 设置累计概率阈值,仅保留概率累加高于top-p的最小标记集,影响生成文本的连贯性 |
--seed | 设置随机种子,用于生成可重现的文本内容 |
另一个重要参数是 --adapter,用于在转化后的 adapter 层与原模型整合前进行测试。使用这个参数对话的模型与整合后的模型几乎无差别,因此可以测试不同权重文件生成的 adapter,以找到最佳 adapter 进行最终整合。
4. Web demo部署
除了可以在终端测试,还可以在网页端的demo进行对话。
# 与模型进行对话
xtuner chat /root/ft/final_model --prompt-template internlm2_chat
首先,先下载web demo所需的依赖 streamlit==1.24.0
下载InternLM项目代码:git clone https://github.com/InternLM/InternLM.git
替换/root/ft/web_demo/InternLM/chat/web_demo.py中的部分内容(修改模型路径、分词器路径,并删除了avatar 及 system_prompt 部分的内容,同时与 cli 中的超参数进行了对齐)
端口映射到本地
通过 SSH 建立一个本地端口转发,将本地的 6006 端口映射到远程服务器的 6006 端口,并使用端口 38374 连接远程服务器(ssh.intern-ai.org.cn)。
# 从本地使用 ssh 连接 studio 端口
# 将下方端口号 38374 替换成自己的端口号
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p 38374
同时,启动一个 Streamlit 应用,服务器地址127.0.0.1,端口6006
streamlit run /root/ft/web_demo/InternLM/chat/web_demo.py --server.address 127.0.0.1 --server.port 6006
微调后 vs 微调前 的结果
进阶作业
一、将自我认知的模型上传到OpenXLab,并将应用部署到OpenXLab
OpenXLab 部署教程:OpenXLab 部署 InternLM2 实践指南
1、关于书生·浦语 InternLM、OpenXLab·浦源平台
InternLM 是在过万亿 token 数据上训练的多语千亿参数基座模型。通过多阶段的渐进式训练,InternLM 基座模型具有较高的知识水平,在中英文阅读理解、推理任务等需要较强思维能力的场景下性能优秀,在多种面向人类设计的综合性考试中表现突出。
OpenXLab 浦源平台以开源为核心,旨在构建开源开放的人工智能生态,促进学术成果的开放共享。OpenXLab面向 AI 研究员和开发者提供 AI 领域的一站式服务平台,包含数据集中心、模型中心和应用中心,致力于推动人工智能对产学研各领域全面赋能,为构建人工智能开放生态,推动人工智能科研与技术突破、交叉创新和产业落地提供全方位的平台支撑。
2、在 OpenXLab 上部署 InternLM2-Chat-7B demo应用
具体步骤:模型准备 → 上传模型 → 编写代码 → 部署应用
本次部署工作使用的三个平台,可查看如下链接了解详情:
InternLM2 GitHub文档:GitHub - InternLM/InternLM: Official release of InternLM2 7B and 20B base and chat models. 200K context support
Gradio官方说明文档:Gradio Docs
OpenXLab平台地址:OpenXLab浦源
2.1 模型准备
准备InternLM2-Chat-7B的预训练模型,关于InternLM2-Chat-7B的模型权重链接如下:
Model | OpenXLab | Hugging Face | ModelScope |
---|---|---|---|
InternLM2-Chat-7B | OpenLMLab/internlm2-chat-7b | internlm/internlm2-chat-7b | Shanghai_AI_Laboratory/internlm2-chat-7b |
由于将使用自己训练好的微调demo模型,可以跳过2.1步骤
2.2 上传模型
具体步骤:初始化配置 → 拉取模型仓库 → 获取Token → 上传模型文件
2.2.1 初始化Git配置
根据自己的操作系统,在操作系统上安装Git,设置Git用户名。
Ubuntu系统安装git和git lfs
apt-get update
apt-get install git
apt-get install git-lfs
OpenXLab上使用你在平台的用户名作为 Git的用户名。登录OpenXLab后,点击个人头向下的【账号与安全】查看个人的用户名。
配置 Git Username,用作 Git 提交的身份标识(Username替换成OpenXLab上的用户名)
git config --global user.name "Username"
配置 Git Email(Username 替换成 OpenXLab 上的邮箱地址)
git config --global user.email "email@email.com"
2.2.2 拉取模型仓库
在 OpenXLab 先创建一个空仓库,填写模型仓库的基本信息。
创建完成空的模型仓库后,找到该仓库的 git 地址并拉取该空仓库至本地
执行git clone操作:
git lfs install
git clone https://code.openxlab.org.cn/yokman/internlm_chat_7b.git
2.2.3 获取 Git Access Token
在 OpenXLab 的密钥管理添加 Git 令牌
添加完令牌后,记得复制生成的 Access Token。
在后续上传模型文件,执行git push 命令时会需要填入 Username 和 Access Token 信息。
以下步骤请先激活 xtuner0.1.17环境!
2.2.4 上传模型文件
在克隆的仓库目录中整理模型文件,即将你的模型文件放入至clone的目录中,并执行git push命令将模型推送至远程仓库。
本地 clone 的文档目录结构如下所示:
├─internlm2-chat-7b
│ ├─.gitattributes
│ ├─README.md
│ ├─config.json
| ├─configuration_internlm.py
| ├─generation_config.json
| ├─modeling_internlm2.py
| ├─pytorch_model-00001-of-00008.bin
| ├─pytorch_model-00002-of-00008.bin
| ├─pytorch_model-00003-of-00008.bin
| ├─pytorch_model-00004-of-00008.bin
| ├─pytorch_model-00005-of-00008.bin
| ├─pytorch_model-00006-of-00008.bin
| ├─pytorch_model-00007-of-00008.bin
| ├─pytorch_model-00008-of-00008.bin
| ├─pytorch_model.bin.index.json
| ├─special_tokens_map.json
| ├─tokenization_internlm.py
| ├─tokenizer.model
│ └─tokenizer_config.json
测试git访问令牌
创建readme.md文件,提交
cd internlm_chat_7b/
touch README.md
git add README.md
git commit -m "README.md"
git push
在执行 git push 时会弹出身份验证的弹窗,填入 Username 和 Access Token 信息
移动模型文件到仓库中
ls -al /root/ft/final_model/
mv /root/ft/final_model/* .
ls -al
代码解释:
- ls -al /root/ft/final_model/
ls 列出目录内容;-a显示所有文件和目录,包括以点(.)开头的隐藏文件;-l 长格式输出,显示文件的详细信息,包括文件权限、链接数、所有者、组、大小、最后修改时间等;最后是要操作的目录路径/root/ft/final_model/
- mv /root/ft/final_model/* .
mv 移动/重命名文件或目录;/root/ft/final_model/* 源路径模式,指该目录下的所有文件和目录(星号*作为通配符);“.” 点号表示目标路径,表示当前工作目录。整行代码是指将/root/ft/final_model/目录下的所有内容移动到当前的工作目录中(经过之前的步骤,当前打开的目录是clone仓库)。
- ls -al
再次使用ls -al命令,列出当前目录(clone仓库目录)下所有文件和目录的详细信息,以便检查上一条mv命令执行后的结果。
在执行 git push
之前,如果仓库中包含大型文件,并且希望使用 Git LFS 来管理这些文件,需要先标记这些文件以便 Git LFS 能够识别它们。通常是通过使用 git lfs track
命令来标记。以下是使用 git lfs track
命令的基本步骤:
LFS管理大文件:使用 git lfs track
命令来标记你希望通过 Git LFS 管理的大文件。例如,您想要通过LFS管理所有的 .bin
和 .model
的模型文件,可以使用以下命令:
git lfs track "*.bin"
git lfs track "*.model"
标记LFS管理的文件后,提交更新的信息,执行 git push 上传模型,命令如下所示:
cd internlm2-chat-7b
git add -A
git commit -m "upload model"
git push
命令行解释
cd internlm2-chat-7b
:切换到名为internlm2-chat-7b
的目录。git add -A
:添加所有新文件、修改过的文件和删除的文件到暂存区。git commit -m "upload model"
:创建一个新的提交,附带提交信息"upload model"。git push
:将本地的提交推送到远程仓库。
执行 git push 时会弹出身份验证的弹窗,填入 Username 和 Access Token 信息。
上传后的模型仓库:
2.3 编写代码
介绍:编写 chat 的 web-ui 代码,包括项目结构初始化、应用环境配置、gradio应用代码编写。
编写Gradio web-ui步骤:
GitHub仓库创建 → 应用环境配置 → 编写gradio应用代码 → 推送代码至GitHub
2.3.1 初始化项目结构
新建GitHub仓库,存放gradio应用代码。
推荐的项目结构如下:
├─GitHub_Repo_Name
│ ├─app.py # Gradio 应用默认启动文件为app.py,应用代码相关的文件包含模型推理,应用的前端配置代码
│ ├─requirements.txt # 安装运行所需要的 Python 库依赖(pip 安装)
│ ├─packages.txt # 安装运行所需要的 Debian 依赖项( apt-get 安装)
| ├─README.md # 编写应用相关的介绍性的文档
│ └─...
首先,打开GitHub主页,右上角 + new repository(例如这里是internlm_chat_7b_git)
2.3.2 应用环境配置、2.3.3 编写gradio应用代码
依赖管理:配置应用所需的运行环境,如有 Python 依赖项( pip 安装)可写入 requirements.txt 中,Debian 依赖项( apt-get 安装)可写入 packages.txt 中,并存放至代码仓库的根目录下。
create new file,新建3个文档:requirements.txt、packages.txt、app.py
- 新建requirements.txt
- 配置python相关的依赖包,如gradio、torch、transformers等
gradio==4.10.0
transformers
sentencepiece
einops
accelerate
tiktoken
- 新建packages.txt
- 配置下载模型权重的工具包 git 和 git-lfs
git
git-lfs
- 新建app.py
- gradio 应用代码,里面可以通过transformers框架进行模型实例化,并通过gradio组件搭建chat聊天界面
import gradio as gr
import os
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel
# download internlm2 to the base_path directory using git tool
base_path = './internlm2-chat-7b'
os.system(f'git clone https://code.openxlab.org.cn/OpenLMLab/internlm2-chat-7b.git {base_path}')
os.system(f'cd {base_path} && git lfs pull')
tokenizer = AutoTokenizer.from_pretrained(base_path,trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(base_path,trust_remote_code=True, torch_dtype=torch.float16).cuda()
def chat(message,history):
for response,history in model.stream_chat(tokenizer,message,history,max_length=2048,top_p=0.7,temperature=1):
yield response
gr.ChatInterface(chat,
title="InternLM2-Chat-7B",
description="""
InternLM is mainly developed by Shanghai AI Laboratory.
""",
).queue(1).launch()
2.3.4 推送代码至GitHub
编写完应用代码,记得推动本地应用代码至 GitHub 仓库中,命令如下
cd internlm2_chat_7b_git #这个目录换成自己的
git add -A
git commit -m "add app.py requirements.txt packages.txt"
git push
代码解释:
- cd internlm2_chat_7b_git
将当前工作目录切换为internlm2_chat_7b_git(Git仓库),不存在的话自动创建
- git add -A
Git命令git add将更改添加到暂存区(staging area),准备进行提交;-A表示添加所有更改。
git add -A即将所有更改添加到暂存区。
- git commit -m "add app.py requirements.txt packages.txt"
git commit将暂存区的内容创建为一个新的提交(commit);-m后面跟着的是提交信息;"add app.py requirements.txt packages.txt" 是提交的内容。
git commit -m
提交这些更改,添加了一个说明性的提交信息。
- git push
将本地仓库的提交推送到远程仓库
2.4 回到openxlab部署应用
OpenXLab主页,右侧 + 创建 → 创建应用,选Gradio组件,开始创建。
应用配置:
填写 Chat 应用的基础信息,包括应用的名称和应用对应的任务类型,并填入 GitHub 仓库的地址,选择硬件资源后,即可立即创建啦~
应用配置注意事项:
- GitHub 授权:若未进行 GitHub 授权,请先前往授权
- 自定义启动文件:若您有需要自定义启动的文件,可以通过配置选择启动文件的路径
- 资源申请:若当前您的资源quota不能满足您的应用需求,也可以填写硬件资源申请表单进行 申请获取
- 如需部署 InternLM2-7b 模型建议申请 8vCPU 32GB Nvidia A10 24GB 规格资源
- 如需部署 InternLM2-20b 模型建议申请 12vCPU 48GB Nvidia A100 40GB 规格资源
- 环境变量配置:若您有不方便在代码中暴露的变量信息,可通过高级配置中的环境变量进行配置
2.4.3 应用构建和启动
查看日志,调试应用代码,若应用代码无问题,运行成功,可体验应用,并将应用进行公开
等待构建中
由于平台资源有限,可能会因为没有资源启动而进入排队中,耐心等候。
结果资源不足,运行错误了,要重新启动[捂脸]
重新启动了很多次都不行,之后OK了再来更新
二、复现多模态微调
教程文档:XTuner 微调LLM:1.8B 多模态 Agent
1. XTuner多模态训练与测试,GPU需要开启30%的A100权限
目标:通过Finetune,使得多模态LLM会根据图像回答问题,而不只是给图像打标题
多模态LLM原理简介:给LLM装上电子眼
什么型号的电子眼:LLaVA方案简介
Haotian Liu等使用GPT-4V对图像数据生成描述,以此构建出大量<question text><image> -- <answer text>
的数据对。利用这些数据对,配合文本单模态LLM,训练出一个Image Projector。所使用的文本单模型LLM
和训练出来的Image Projector
,统称为LLaVA模型
。
Image Projector的训练和测试,有点类似之前讲过的LoRA微调方案。二者都是在已有LLM的基础上,用新的数据训练一个新的小文件。只不过,LLM套上LoRA之后,有了新的灵魂(角色);而LLM套上Image Projector之后,才有了眼睛。
快速上手
环境准备
InternStudio 创建开发机,选Cuda11.7-conda
镜像,资源 30% A100 * 1。
XTuner安装:如果
前面已经安装过xtuner并创建xtuner0.1.17环境了,此处可以跳过。
# 如果你是在 InternStudio 平台,则从本地 clone 一个已有 pytorch 的环境:
# pytorch 2.0.1 py3.10_cuda11.7_cudnn8.5.0_0
cd ~ && studio-conda xtuner0.1.17
# 如果你是在其他平台:
# conda create --name xtuner0.1.17 python=3.10 -y
# 激活环境
conda activate xtuner0.1.17
# 进入家目录 (~的意思是 “当前用户的home路径”)
cd ~
# 创建版本文件夹并进入,以跟随本教程
mkdir -p /root/xtuner0117 && cd /root/xtuner0117
# 拉取 0.1.17 的版本源码
git clone -b v0.1.17 https://github.com/InternLM/xtuner
# 无法访问github的用户请从 gitee 拉取:
# git clone -b v0.1.15 https://gitee.com/Internlm/xtuner
# 进入源码目录
cd /root/xtuner0117/xtuner
# 从源码安装 XTuner
pip install -e '.[all]' && cd ~
在本节中,我们将 自己构造
<question text><image>--<answer text>
数据对,基于InternLM2_Chat_1.8B这个文本单模态模型,使用LLaVA方案,训练一个给InternLM2_Chat_1.8B使用的Image Projector文件。
LLaVA方案中,给LLM增加视觉能力的过程,即是训练Image Projector文件的过程。 该过程分为2个阶段:Pretrain和Finetune。
Pretrain阶段:
本次实战营中提供了Pretrain阶段的产物——iter_2181.pth
文件(幼稚园阶段的Image Projector),带着它进入下一阶段的Finetune即可。
在Pretrain阶段,我们会使用大量的图片+简单文本(caption, 即图片标题)
数据对,使LLM理解图像中的普遍特征。即,对大量的图片进行粗看。
Pretrain阶段训练完成后,此时的模型已经有视觉能力了!但是由于训练数据中都是图片+图片标题,所以此时的模型虽然有视觉能力,但无论用户问它什么,它都只会回答输入图片的标题。即,此时的模型只会给输入图像“写标题”。
Pretrain阶段相当于是开发LLM时预训练工作,对硬件要求非常高,有8卡的话可以自行尝试。详见 XTuner-LLaVA和 LLaVA。
Fintune阶段:
Finetune阶段,我们会使用图片+复杂文本
数据对,来对Pretrain得到的Image Projector即iter_2181.pth(/root/share/new_models/xtuner/iter_2181.pth)进行进一步的训练。
构建训练数据
格式
[
{
"id": "随便什么字符串",
"image": "图片文件的相对位置。相对谁?相对你后面config文件里指定的image_folder参数的路径。",
"conversation": [
{
"from": "human",
"value": "<image>\n第1个问题。"
},
{
"from": "gpt",
"value": "第1个回答"
},
{
"from": "human",
"value": "第2个问题。"
},
{
"from": "gpt",
"value": "第2个回答"
},
# ......
{
"from": "human",
"value": "第n个问题。"
},
{
"from": "gpt",
"value": "第n个回答"
},
]
},
# 下面是第2组训练数据了。
{
"id": "随便什么字符串",
"image": "图片文件的相对位置。相对谁?相对你后面config文件里指定的image_folder参数的路径。",
"conversation": [
{
"from": "human",
"value": "<image>\n第1个问题。"
},
# ......
{
"from": "gpt",
"value": "第n个回答"
}
]
}
]
注意:每组训练数据的第1个来自human的问题前,要加上图片占位符,即<image>
为了跟随课程,针对这张示例图片的问答对数据(repeat_data.json),大家按照下面的脚本运行就可以生成啦~(重复200次)
cd ~ && git clone https://github.com/InternLM/tutorial -b camp2 && conda activate xtuner0.1.17 && cd tutorial
python /root/tutorial/xtuner/llava/llava_data/repeat.py \
-i /root/tutorial/xtuner/llava/llava_data/unique_data.json \
-o /root/tutorial/xtuner/llava/llava_data/repeated_data.json \
-n 200
准备配置文件
不想自己改配置文件,直接用了教程提供的在仓库里的fool_config文件,运行以下代码:
cp /root/tutorial/xtuner/llava/llava_data/internlm2_chat_1_8b_llava_tutorial_fool_config.py /root/tutorial/xtuner/llava/llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy.py
创建配置文件
# 查询xtuner内置配置文件
xtuner list-cfg -p llava_internlm2_chat_1_8b
# 拷贝配置文件到当前目录
xtuner copy-cfg \
llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune \
/root/tutorial/xtuner/llava
当前/root/tutorial/xtuner/llava/目录下的文件结构是:
修改配置文件:
修改llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy.py
文件中的:
- pretrained_pth
- llm_name_or_path
- visual_encoder_name_or_path
- data_root
- data_path
- image_folder
具体(加号是新增部分,减号是被替换的部分)
# Model
- llm_name_or_path = 'internlm/internlm2-chat-1_8b'
+ llm_name_or_path = '/root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b'
- visual_encoder_name_or_path = 'openai/clip-vit-large-patch14-336'
+ visual_encoder_name_or_path = '/root/share/new_models/openai/clip-vit-large-patch14-336'
# Specify the pretrained pth
- pretrained_pth = './work_dirs/llava_internlm2_chat_1_8b_clip_vit_large_p14_336_e1_gpu8_pretrain/iter_2181.pth' # noqa: E501
+ pretrained_pth = '/root/share/new_models/xtuner/iter_2181.pth'
# Data
- data_root = './data/llava_data/'
+ data_root = '/root/tutorial/xtuner/llava/llava_data/'
- data_path = data_root + 'LLaVA-Instruct-150K/llava_v1_5_mix665k.json'
+ data_path = data_root + 'repeated_data.json'
- image_folder = data_root + 'llava_images'
+ image_folder = data_root
# Scheduler & Optimizer
- batch_size = 16 # per_device
+ batch_size = 1 # per_device
# evaluation_inputs
- evaluation_inputs = ['请描述一下这张图片','Please describe this picture']
+ evaluation_inputs = ['Please describe this picture','What is the equipment in the image?']
开始Finetune
降版本pip install transformers==4.37.0,否则运行报错
cd /root/tutorial/xtuner/llava/
xtuner train /root/tutorial/xtuner/llava/llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy.py --deepspeed deepspeed_zero2
Finetune之后的结果
对比Finetune前后的性能差异
Finetune前:即加载 1.8B 和 Pretrain阶段产物(iter_2181) 到显存。
# 解决小bug
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
# pth转huggingface
xtuner convert pth_to_hf \
llava_internlm2_chat_1_8b_clip_vit_large_p14_336_e1_gpu8_pretrain \
/root/share/new_models/xtuner/iter_2181.pth \
/root/tutorial/xtuner/llava/llava_data/iter_2181_hf
# 启动!
xtuner chat /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b \
--visual-encoder /root/share/new_models/openai/clip-vit-large-patch14-336 \
--llava /root/tutorial/xtuner/llava/llava_data/iter_2181_hf \
--prompt-template internlm2_chat \
--image /root/tutorial/xtuner/llava/llava_data/test_img/oph.jpg
报错了↓(捂脸),解决了之后再来更新
Finetune后:即加载 1.8B 和 Fintune阶段产物 到显存。
# 解决小bug
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
# pth转huggingface
xtuner convert pth_to_hf \
/root/tutorial/xtuner/llava/llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy.py \
/root/tutorial/xtuner/llava/work_dirs/llava_internlm2_chat_1_8b_qlora_clip_vit_large_p14_336_lora_e1_gpu8_finetune_copy/iter_1200.pth \
/root/tutorial/xtuner/llava/llava_data/iter_1200_hf
# 启动!
xtuner chat /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b \
--visual-encoder /root/share/new_models/openai/clip-vit-large-patch14-336 \
--llava /root/tutorial/xtuner/llava/llava_data/iter_1200_hf \
--prompt-template internlm2_chat \
--image /root/tutorial/xtuner/llava/llava_data/test_img/oph.jpg
这一步也报错了(捂脸),解决了之后再来更新
作业要求:
教程文档:https://github.com/InternLM/Tutorial/blob/camp2/xtuner/personal_assistant_document.md
OpenXLab 部署教程:https://github.com/InternLM/Tutorial/tree/camp2/tools/openxlab-deploy