首页 > 其他分享 >基于SWIFT和Qwen1.5-14B-Chat进行大模型全参微调测试

基于SWIFT和Qwen1.5-14B-Chat进行大模型全参微调测试

时间:2024-03-05 18:11:07浏览次数:36  
标签:swift 训练 -- yldm0226 模型 14B Chat 全参 数据

基于SWIFT和Qwen1.5-14B-Chat进行大模型全参微调测试

环境准备

基础环境

  • 操作系统:Ubuntu 18.04.5 LTS (GNU/Linux 3.10.0-1127.el7.x86_64 x86_64)
  • Anaconda3:Anaconda3-2023.03-1-Linux-x86_64
  • 根据服务器网络情况配置好conda源和pip源,此处使用的是超算山河源
  • 服务器硬件配置:CPU 96核;GPU 8×NVIDIA A100 40GB

环境安装

通过源代码安装SWIFT:

创建一个新的conda环境:

conda create --name swift python=3.8

激活刚刚创建的conda环境:

conda activate swift

下载SWIFT源码:

git clone https://github.com/modelscope/swift.git

切换到SWIFT路径:

cd /yldm0226/swift

安装SWIFT:

pip install -e .[llm]

非必要步骤:检查服务器cuda版本是否与当前安装的pytorch对应,详见:搭建一个大模型API服务

数据集准备

对于数据集,我们均采用json或jsonl的格式。

在做大模型SFT(Supervised Fine-Tuning)时,可以准备两种数据:

  1. 单轮问答
  2. 多轮对话

对于单轮问答数据,其格式可以为:

{"query": "11111", "response": "22222"}

对于多轮对话数据,其格式可以为:

{"query": "eeeee", "response": "fffff", "history": []}
{"query": "EEEEE", "response": "FFFFF", "history": [["AAAAA", "BBBBB"], ["CCCCC", "DDDDD"]]}

同时,也可以用以下两种格式的数据:

{"conversations": [{"from": "user", "value": "11111"}, {"from": "assistant", "value": "22222"}]}
{"conversations": [{"from": "user", "value": "aaaaa"}, {"from": "assistant", "value": "bbbbb"}, {"from": "user", "value": "ccccc"}, {"from": "assistant", "value": "ddddd"}]}
{"conversations": [{"from": "user", "value": "AAAAA"}, {"from": "assistant", "value": "BBBBB"}, {"from": "user", "value": "CCCCC"}, {"from": "assistant", "value": "DDDDD"}]}
{"messages": [{"role": "user", "content": "11111"}, {"role": "assistant", "content": "22222"}]}
{"messages": [{"role": "user", "content": "aaaaa"}, {"role": "assistant", "content": "bbbbb"}, {"role": "user", "content": "ccccc"}, {"role": "assistant", "content": "ddddd"}]}
{"messages": [{"role": "user", "content": "AAAAA"}, {"role": "assistant", "content": "BBBBB"}, {"role": "user", "content": "CCCCC"}, {"role": "assistant", "content": "DDDDD"}]}

在本文中,共使用了9个数据集,数据集的详细信息如下:

序号 数据集 简介 数据量
1 Chinese_medical_dialogue_six_department 中文医疗问答数据集,包括男科、内科、妇产科、肿瘤科、儿科、外科六个科室的问题。 792K
2 HuatuoGPT2_sft_instruct_GPT4 华佗GPT(HuatuoGPT)第二版训练数据集。 50K
3 ChatMed_Consult-v0.3 中文医疗在线问诊数据集ChatMed_Consult_Dataset的50w+在线问诊+ChatGPT回复。 500K
4 ChatMed_TCM-v0.2 以开源的中医药知识图谱为基础,采用以实体为中心的自指令方法(entity-centric self-instruct),调用ChatGPT得到11w+的围绕中医药的指令数据。 110K
5 QiZhen_sft_20k 包含20k训练数据(该数据集来自于启真医学知识库收集整理的真实医患知识问答数据以及在启真医学知识库的药品文本知识基础上,通过对半结构化数据设置特定的问题模板构造的指令数据)。 20K
6 Huatuo_Lite Huatuo-Lite 是在Huatuo26M数据集的基础上经过多次提纯和重写而精炼优化的数据集。它包含了18万个高质量的医疗问答对,并具有医院科室和相关疾病两个额外的数据维度。 180K
7 ZhongJing_CMtMedQA 仲景SFT训练集。 70K
8 DISC-Med-SFT_released 包含了超过47万个衍生于现有的医疗数据集重新构建得到的样本。采用了目标导向的策略,通过对于精心选择的几个数据源进行重构来得到SFT数据集。这些数据的作用在于帮助模型学习医疗领域知识,将行为模式与人类偏好对齐,并对齐真实世界在线医疗对话的分布情况。 514K
9 SZY_TCM_QA 私有数据集。 12K

以下是加载后的数据集信息:

[INFO:swift] train_dataset: Dataset({
    features: ['query', 'response', 'history'],
    num_rows: 2223540
})
[INFO:swift] val_dataset: Dataset({
    features: ['query', 'response', 'history'],
    num_rows: 22460
})

数据总量为2,246,000,从中抽取出约1%作为验证集,其余的作为训练集。

编写微调脚本

SWIFT框架提供了部分大模型的微调脚本,可以在我们下载的源码中的swift/examples/pytorch/llm/scripts路径中找到这些脚本。如果这些脚本能够满足我们大部分的微调需求,我们可以选择直接对这些脚本进行修改。如果找不到我们需要的脚本,需要我们根据swift/docs/source/LLM中的命令行参数文档自行编写训练脚本。

以下是对Qwen1.5-14B-Chat进行全参微调的一个训练脚本:

# Experimental environment: 8 * A100 40GB
nproc_per_node=1
NPROC_PER_NODE=$nproc_per_node \
MASTER_PORT=29500 \
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
swift sft \
    --model_type qwen1half-14b-chat \
    --model_id_or_path /yldm0226/models/Qwen1.5-14B-Chat \
    --model_revision master \
    --sft_type full \
    --tuner_backend swift \
    --template_type AUTO \
    --dtype AUTO \
    --output_dir /yldm0226/llm_sft_output \
    --ddp_backend nccl \
    --custom_train_dataset_path /yldm0226/data/1-Chinese_medical_dialogue_six_department.jsonl /yldm0226/data/2-HuatuoGPT2_sft_instruct_GPT4.jsonl /yldm0226/data/3-ChatMed_Consult-v0.3.jsonl /yldm0226/data/4-ChatMed_TCM-v0.2.jsonl /yldm0226/data/5-QiZhen_sft_20k.jsonl /yldm0226/data/6-Huatuo_Lite.jsonl /yldm0226/data/7-ZhongJing_CMtMedQA.jsonl /yldm0226/data/8-DISC-Med-SFT_released.jsonl /yldm0226/data/9-SZY_TCM_QA.jsonl \
    --train_dataset_sample -1 \
    --num_train_epochs 1 \
    --max_length 4096 \
    --check_dataset_strategy warning \
    --gradient_checkpointing true \
    --batch_size 1 \
    --weight_decay 0.01 \
    --learning_rate 1e-4 \
    --gradient_accumulation_steps $(expr 8 / $nproc_per_node) \
    --max_grad_norm 0.5 \
    --warmup_ratio 0.03 \
    --eval_steps 100 \
    --save_steps 100 \
    --save_total_limit 3 \
    --logging_steps 10 \
    --use_flash_attn false \
    --save_only_model true \

下面对该脚本中的一些重要参数作出解释:

  • nproc_per_node:在多机分布式训练中,每个主机被当做一个node;nproc_per_node代表的是每个node中有几个线程;以该脚本为例,该脚本运行在单机环境中,因此nproc_per_node就代表着我们使用的单台服务器有几个线程去同时训练模型;假如nproc_per_node设置为8,那么将有8个线程同时训练模型,速度会提高很多,但是这样每块GPU都要负责存储完整的模型权重,显存会受到很大的挑战;假如nproc_per_node设置为4,那么将有4个线程同时训练模型,每个线程中有两块GPU,这两块GPU共同负责存储模型权重,这样虽然速度降低了,但是能够得到更宽裕的GPU显存;但此时我们的显存还是不足以训练14B的Qwen1.5-Chat,我们只能舍弃时间以换取空间,所以将nproc_per_node设置为1,此时该服务器只有1个线程去训练模型,模型被切分到8块GPU卡上。请注意,模型被切分到8块GPU卡上时,并不代表着这8块GPU只需要承担模型部分权重的显存,还需要承担优化器中各种梯度的存储,这也是相当大的一部分显存开销。所以如果显存允许,我们应该尽可能的提高nproc_per_node的值,提高显卡的利用率。
  • CUDA_VISIBLE_DEVICES:服务器中如果有多张显卡,可以通过该参数指定使用哪几张显卡。显卡的序号可以通过nvidia-smi查看。
  • model_type:model_type指定我们要微调的大模型的类型,这些类型必须是SWIFT框架所支持大模型类型的一种,具体有哪些支持的模型可以在swift源码的swift/docs/source/LLM路径中的支持的模型和数据集文档中查看。
  • model_id_or_path:model_id_or_path用于指定大模型权重的本地路径。
  • sft_type: sft_type表示微调的方式, 默认是lora。可以选择的值包括: 'lora', 'full', 'longlora', 'qalora'。此处使用的是full,即全参微调。
  • output_dir:output_dir用于指定大模型微调过程中输出日志的存储路径。
  • custom_train_dataset_path:用于指定我们数据集的存放路径,每个数据集之间用空格分隔。
  • train_dataset_sample:对训练集进行采样, 默认是20000, 用于加快训练的速度。 该参数是为了避免数据集过大, 单个epoch训练时间过长的问题。 如果你指定为-1, 则使用完整的训练集进行训练。
  • max_length:token的最大长度, 默认为2048。该参数可以避免个别过长的数据样本造成OOM的问题。当指定--truncation_strategy delete时, 如果某数据样本长度超过max_length, 我们会删除该数据样本。如果指定--truncation_strategy truncation_left时, 我们会切除最前面的token: input_ids[-max_length:]。如果设置为-1, 则无限制。该参数很重要,要根据显存情况选择合适的max_length,不然在训练中会出现OOM的情况,导致训练终止。

对于其他参数,这里不做过多讲解。此外,这个脚本只涉及到了部分参数,如果需要进一步的定制化,需根据文档自行修改。

测试

运行脚本,可以得到以下信息:

数据集预处理所需要的时间大概30分钟:

703283/2223540 [09:23<20:31, 1234.07it/s] 

max_length设置为2048的情况下,估算训练时间:

100/277856 [05:38<255:02:02,  3.31s/it]

8596/22452 [10:15<17:42, 13.04it/s]

训练一个epoch大约需要255小时;进行一次验证大约需要27分钟,我们设置每100步进行一次验证,总步数为277856,需要进行2778次验证,预计用时为1250小时;当然,设置100步进行一次验证有些太频繁了,在实际进行训练时可以设置为10000步进行一次验证,预计用时为12.6小时。(这里的时间只是一个大概值,在训练时,不同数据的处理速度不同,花费的总时间会一直变化)

max_length设置为4096的情况下,训练所需的大概时间如下:

100/277926 [05:50<259:11:42,  3.36s/it]

1512/22459 [01:43<24:31, 14.24it/s]

情况与max_length设置为2048的情况差距不大。

max_length设置为8192的情况下,显存不够了,出现溢出:

torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 9.95 GiB (GPU 0; 39.45 GiB total capacity; 26.79 GiB already allocated; 8.68 GiB free; 29.46 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

标签:swift,训练,--,yldm0226,模型,14B,Chat,全参,数据
From: https://www.cnblogs.com/yourenbo/p/18054600

相关文章

  • 文心一言 VS 讯飞星火 VS chatgpt (208)-- 算法导论15.4 5题
    五、设计一个O($n^2$)时间的算法,求一个n个数的序列的最长单调递增子序列。要写代码的时候,请用go语言。文心一言,抛panic:在Go语言中设计一个O(n^2)时间复杂度的算法来求一个n个数的序列的最长单调递增子序列(LongestIncreasingSubsequence,LIS)可以使用动态规划的方法......
  • ChatGPT用10秒画完一张UML流程图,而我用了。。。
    不用AI的程序员,失业潮真的快来临了。一张订单履约的流程图,我花了10分钟才完成,而ChatGPT绘图过程只用了10秒钟,基本可以达到同样的水平,通过ChatGPT可以显著提高画流程图的效率。订单履约流程是一系列精细协作的流程,从客户在销售平台下单开始,至商品交付用户手中结束。此过程跨越多......
  • ChatGPT4.0_API
    importopenaiimportjsonimportos#openai.api_key=get_api_key()openai.api_key="yourkey"#q="用python实现:提示手动输入3个不同的3位数区间,输入结束后计算这3个区间的交集,并输出结果区间"#q="WhatisthvbScript?"#q="翻译成日语:市场非常有潜力"#q="北京、......
  • ChatGLM3 源码解析(一)
    MLPclassMLP(torch.nn.Module):"""MLP把隐藏状态的尺寸从HidSize映射到4HidSize,执行非线性激活,然后再映射回HidSize"""def__init__(self,config:ChatGLMConfig,device=None):super(MLP,self).__init__()#控制是否添加偏......
  • 文心一言 VS 讯飞星火 VS chatgpt (207)-- 算法导论15.4 4题
    四、说明如何只使用表c中2*min(m,n)个表项及O(1)的额外空间来计算LCS的长度。然后说明如何只用min(m,n)个表项及O(1)的额外空间完成相同的工作。要写代码的时候,请用go语言。文心一言:在只使用2*min(m,n)个表项和O(1)额外空间来计算LCS(LongestCommonSubsequence)的长......
  • ChatGPT的工作原理
    ChatGPT是美国OpenAI研发的聊天机器人程序,2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来进行对话。原理ChatGPT是一种基于人工智能技术的自然语言生成模型,它能够从大量的数据和历史对话中学习,并生成与人类语言相似的输出......
  • ADQ14 多通道14bit PXIe数字化仪
    产品简介:♦1/2/4通道,14bit分辨率,2GSPS采样率♦1.2GHz模拟带宽及2GB内存♦可提供交流或直流耦合更多信息请加weixin-pt890111获取产品优势灵活而高性能ADQ14是一个14位数字转换器系列,具有1个,2个或4个通道以及0.5、1或2GSPS采样率。它也可提供交流或直流耦合(ADQ14AC和ADQ1......
  • ADQ7DC-10 GSPS, 14bit ,PXIe数字化仪
    产品简介:♦1/2通道,14bit分辨率,10GSPS采样率♦3GHz模拟输入带宽及4GB板载内存♦可以灵活选择通道数,采样率和接口更多信息请加weixin-pt890111获取产品优势1.高分辨率和高采样率的独特结合ADQ7DC具有14bit和10GSPS采样率,提高了高采样率应用中的分辨率,超出了以前的范围。这种......
  • SP Devices ADQ14 14bit PCIe数字化仪
    产品简介:♦1/2通道,14bit分辨率,2GSPS采样率♦3GHz模拟输入带宽及4GB板载内存♦可以灵活选择通道数,采样率和接口更多信息请加weixin-pt890111获取产品优势灵活而高性能ADQ14是一个14位数字转换器系列,具有1个,2个或4个通道以及0.5、1或2GSPS采样率。它也可提供交流或直流耦......
  • SP Devices ADQ7DC-1/2通道,14bit分辨率,10GSPS采样率
    产品优势1.高分辨率和高采样率的独特结合ADQ7DC具有14bit和10GSPS采样率,提高了高采样率应用中的分辨率,超出了以前的范围。这种性能提升有效地帮助我们的客户克服了性能折衷,并在许多应用中取得了重大进步。ADQ7DC可以单通道或双通道模式工作,分别具有10或5GSPS采样率。 更多......