1 模型简介
模型名为小小布(Little Bu),是由训练师布(LLMtrainer Bu)开发的一个基于大语言模型训练和微调的智能助手。可以生成图片、生成代码、生成语音、多轮对话(回答问题、提供信息、解释概念、提供建议)等。
2 实验环境
统一计算设备架构(Compute Unified Device Architecture, CUDA),是由 NVIDIA 推出的通用并行计算架构。使用 CUDA 和其相应的 cuDNN(CUDA Deep Neural Network Library)和 CUDA Toolkit 可以方便地使用 GPU 资源进行开发和模型训练。
大多数深度学习框架都支持 CUDA 来加速神经网络的训练和推理。在 PyTorch 中,张量(Tensor)可以在 CPU 或 GPU 上进行计算。
这里需要使用的 SWIFT 是 modelscope 开源的大模型训练推理部署工具箱 (Scalable lightWeight Infrastructure for Fine-Tuning)。集成了各种高效的微调方法,如 LoRA、QLoRA、阿里云自研的 ResTuning-Bypass 等,以及开箱即用的训练推理脚本,使开发者可以在单张商业级显卡上微调推理 LLM&AIGC 模型。此外,SWIFT 与 PEFT 完全兼容,使开发者可以在 ModelScope 模型体系中使用 PEFT 的能力。
下面是实验环境的驱动版本、CUDA 版本和 GPU 信息,使用 nvidia-smi
命令查看:
- 驱动版本:470.103.01
- CUDA 版本:12.1
- GPU 型号:A10
- 显存大小:22.2GB
还可以使用 pip
命令下载一个 GPU 资源的实时监测工具:
pip install nvitop
nvitop -m full
3 训练方法
3.1 数据集使用
Dataset Name | Dataset ID | Train Size | Val Size | Statistic (token) | Tags |
---|---|---|---|---|---|
?alpaca-en | AI-ModelScope/alpaca-gpt4-data-en | 52002 | 0 | 176.2±125.8, min=26, max=740 | chat, general |
?alpaca-zh | AI-ModelScope/alpaca-gpt4-data-zh | 48818 | 0 | 162.1±93.9, min=26, max=856 | chat, general |
?damo-agent-mini-zh | damo/MSAgent-Bench | 39964 | 152 | 1230.9±350.1, min=558, max=4982 | chat, agent, multi-round |
这里使用了以上三个数据集来微调小小布模型。通过 MSAgent-Bench 使得小小布获得 Agent API 调用能力,通过构造结构化的微调数据集,进行监督指令微调,从而在已有的 base-chat 模型基础上,习得 Model API 和一些 Common API 的调用能力例如代码生成、文生图、文字转语音、视频生成、天气查询等。 |
damo-agent-zh 数据集主要包括了四种:AI 模型 API,通用 API,API 无关通用 sft 数据,API 检索增强数据。 数据格式为每行一个样本,里面包含了 id 和 converstions 两个字段,其中 conversations 里面包含了 system,user,assistant 三种字段。其中:
- system: 表示给模型前置的人设输入,其中有告诉模型如何调用插件以及生成请求
- user: 表示用户的输入 prompt,分为两种,通用生成的 prompt 和调用插件需求的 prompt
- assistant: 为模型的回复。其中会包括插件调用代码和执行代码,调用代码是要 LLM 生成的,而执行代码是调用服务来生成结果的。如下面例子,调用部分代码会通过
<|startofthink|>
和<|endofthink|>
包起来,>然后执行部分代码是 api 执行完结果后,把执行结果通过<|startofexec|>
和<|endofexec|>
包起来再输入给模型生成后面的回复。
多轮对话方面,可以构造多轮对话的数据集,参考文档。每次对话带上前一轮对话的历史信息,包括 query 和 response 信息,以此构造数据集来进行微调。
Multi-Round Dialogue
{"query": "55555", "response": "66666"}
{"query": "eeeee", "response": "fffff", "history": []}
{"query": "EEEEE", "response": "FFFFF", "history": [["AAAAA", "BBBBB"], ["CCCCC", "DDDDD"]]}
也有一些开源的多轮对话数据集例如 CrossWOZ
3.2 微调的模型
下表介绍了这里使用的基础模型 qwen7bchat 的相关信息:
Model Type | Model ID | Default Lora Target Modules | Default Template | Support Flash Attn | Support VLLM |
---|---|---|---|---|---|
qwen-7b-chat | qwen/Qwen-7B-Chat | c_attn | qwen | ✔ | ✔ |
- Model List: 模型在 swift 中注册的 model_type 的列表.
- Default Lora Target Modules: 对应模型的默认 loratargetmodules.
- Default Template: 对应模型的默认 template.
- Support Flash Attn: 模型是否支持 flash attention 加速推理和微调.
- Support VLLM: 模型是否支持 vllm 加速推理和部署.
3.3 超参数
使用 swift.llm
进行微调的超参数设定。
--sft_type
: 微调的方式是'lora'
train_dataset_sample=2000
对训练集进行采样--lora_rank
: 为8
. 只有当sft_type
指定为 'lora' 时才生效.--lora_alpha
: 为32
. 只有当sft_type
指定为 'lora' 时才生效.--lora_dropout_p
: 为0.05
--max_length
: token 的最大长度, 默认为2048
--eval_steps=20
--logging_steps=5
--lora_target_modules='ALL'
--self_cognition_sample=500
--num_train_epochs=3
--batch_size
: 训练时的 batch_size, 默认为1
--max_steps
: 训练的 max_steps 数, 默认为-1
. 如果max_steps >= 0
, 则覆盖num_train_epochs
.--optim
: 为'adamw_torch'
.--learning_rate
: 默认值为None
, 即如果sft_type
为 lora, 则设置为 1e-4, 如果sft_type
为 full, 则设置为 1e-5.--weight_decay
: 默认值为0.01
.--warmup_ratio
: warmup 占用总的训练 steps 的比例, 默认为0.05
.
断点续训: --resume_from_checkpoint
: 用于断点续训, 默认为 None
. 你可以将其设置为 checkpoint 的路径, 例如: 'output/qwen-7b-chat/vx_xxx/checkpoint-xxx'
, 来进行断点续训.
4 示例代码
- 自我认知微调代码:
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import ModelType, InferArguments, infer_main
infer_args = InferArguments(
model_type=ModelType.qwen_7b_chat, eval_human=True)
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import DatasetName, ModelType, SftArguments, sft_main
sft_args = SftArguments(
model_type=ModelType.qwen_7b_chat,
dataset=[DatasetName.alpaca_zh, DatasetName.alpaca_en],
train_dataset_sample=2000,
eval_steps=20,
logging_steps=5,
output_dir='output',
lora_target_modules='ALL',
model_name=['小小布', 'Little Bu'],
model_author=['训练师布', 'LLMtrainer Bu'],
self_cognition_sample=500,
num_train_epochs=3)
output = sft_main(sft_args)
best_model_checkpoint = output['best_model_checkpoint']
print(f'best_model_checkpoint: {best_model_checkpoint}')
- Agent API 能力微调代码
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import ModelType, InferArguments, infer_main
infer_args = InferArguments(
model_type=ModelType.qwen_7b_chat, eval_human=True)
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import DatasetName, ModelType, SftArguments, sft_main
sft_args = SftArguments(
model_type=ModelType.qwen_7b_chat,
dataset=[DatasetName.damo_agent_mini_zh],
train_dataset_sample=2000,
eval_steps=20,
logging_steps=5,
output_dir='output',
lora_target_modules='ALL',
model_name=['小小布', 'Little Bu'],
model_author=['训练师布', 'LLMtrainer Bu'],
self_cognition_sample=500,
num_train_epochs=3)
output = sft_main(sft_args)
best_model_checkpoint = output['best_model_checkpoint']
print(f'best_model_checkpoint: {best_model_checkpoint}')
- 模型推送到 Hub 代码:
from modelscope.hub.api import HubApi
YOUR_ACCESS_TOKEN = '695e2896-3570-4a3a-b2c6-e518838812f2'
api = HubApi()
api.login(YOUR_ACCESS_TOKEN)
api.push_model(
model_id="buzezhang/xiaobu",
model_dir="/mnt/workspace/output/qwen-7b-chat/v0-20240127-161516/checkpoint-40" # must include configuration.json
)
- 模型下载和推理代码:
#验证SDK token
from modelscope.hub.api import HubApi
api = HubApi()
api.login('---')
#模型下载
from modelscope import snapshot_download
model_dir = snapshot_download('buzezhang/xiaobu')
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import InferArguments, merge_lora_main, infer_main
best_model_checkpoint = "/mnt/workspace/output/qwen-7b-chat/v3-20240127-200128/checkpoint-91"
infer_args = InferArguments(
ckpt_dir=best_model_checkpoint,
eval_human=True)
# merge_lora_main(infer_args)
result = infer_main(infer_args)
- 使用 CLI (CPU, 1.8b):
# Time Consumed: 40min
CUDA_VISIBLE_DEVICES=-1 \
swift sft \
--model_type qwen-1_8b-chat \
--dataset alpaca-zh alpaca-en \
--train_dataset_sample 500 \
--eval_steps 20 \
--logging_steps 5 \
--output_dir output \
--lora_target_modules ALL \
--self_cognition_sample 500 \
--model_name '小小布' 'Little Bu' \
--model_author '训练师布' 'LLMtrainer Bu' \
- 断点续训代码
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
from swift.llm import DatasetName, ModelType, SftArguments, sft_main
sft_args = SftArguments(
model_type=ModelType.qwen_7b_chat,
dataset=[DatasetName.damo_agent_mini_zh],
resume_from_checkpoint='xiaobu',
train_dataset_sample=500,
eval_steps=20,
logging_steps=5,
output_dir='output',
lora_target_modules='ALL',
self_cognition_sample=500,
num_train_epochs=2)
output = sft_main(sft_args)
best_model_checkpoint = output['best_model_checkpoint']
print(f'best_model_checkpoint: {best_model_checkpoint}')
5 推理效果
- 自我认知能力
- 代码生成能力和 Python 解释器调用
- 多轮对话能力
评论