当前位置:   article > 正文

Amazon SageMaker 上的 Baichuan2 模型微调及部署(一)微调部分

百川模型部署 微调

f53e87be520c2338075c47db44292ffb.gif

自 2022 年底以来,生成式 AI 技术已经成为我们这个时代最具创新力的技术之一,也是引领未来发展的关键力量。大语言模型作为潮流最前线的推动者,有着不可置否的影响力。以 Meta 的 LLaMA 为首,生成式 AI 模型社区在短时间内涌现出大批开源模型,成为构建开源模型生态的重要里程碑。同时,国内的中文开源模型也不遑多让,包括 Baichuan 在内的模型在各大模型评测榜单上都有着出色的表现。模型的微调和部署是玩转开源模型的关键技术,本文将以 Baichuan2 为例,主要介绍如何利用 Amazon SageMaker 微调及部署 Baichuan2 模型。

Baichuan2 模型介绍

Baichuan2 系列模型是百川智能推出的新一代开源大语言模型,其在总量为 2.6 万亿 Tokens 的高质量中英文及代码语料上做预训练,在多个权威评测榜单上取得同尺寸下较好的效果。开源版本中包含有 7B、13B 的 Base 和 Chat 版本,其中 Base 版本指的是直接经过预训练得到的模型,而 Chat 是基于 Base 版本的基础上做指令微调(instruction-tuning)和 RLHF 得到。

Baichuan2 模型微调

本章将介绍如何使用 SageMaker 进行 Baichuan2 模型的微调,内容将分为三部分:

  1. 进行训练的准备工作;

  2. 构建 SageMaker Training Job 需要的相关代码;

  3. 用不同方法对 Baichuan2 模型进行微调,包括了 LoRA 微调和全量微调两种方法。

准备工作

使用 SageMaker Training Job 进行模型训练时,训练环境每次都将会被重新构建,因此我们推荐预先准备好微调需要的预训练模型和数据,上传至 Amazon S3,这可以有效节省启动训练花费的时间。

准备预训练模型

首先我们在 SageMaker Notebook 中(或任意可以访问互联网和 S3 的环境中)下载 Baichuan2 提供的预训练模型,这里以 Baichuan2-13B-Chat 为例:

 Python 

  1. from huggingface_hub import snapshot_download
  2. from pathlib import Path
  3. local_cache_path = Path("./baichuan2-13b-chat")
  4. local_cache_path.mkdir(exist_ok=True)
  5. model_name = "baichuan-inc/Baichuan2-13B-Chat"
  6. # Only download pytorch checkpoint files
  7. allow_patterns = ["*.json", "*.pt", "*.bin", "*.model", "*.py"]
  8. model_download_path = snapshot_download(
  9.    repo_id=model_name,
  10.    cache_dir=local_cache_path,
  11.    allow_patterns=allow_patterns,
  12. )

再上传至 S3,供后续训练模型时使用:

 Bash 

  1. # Change to your own local path and S3 bucket
  2. aws s3 cp ./baichuan2-13b-chat s3://{your-s3-pretrain-model-path} --recursive

准备训练数据

以官方提供的数据样例为例,将它上传至 S3,供后续训练模型时使用:

 Bash 

  1. # Change to your own local path and S3 bucket
  2. aws s3 cp ./belle_chat_random_10k.json s3://{your-s3-data-path}

SageMaker Training Job 相关代码

使用 SageMaker Training Job 时,除了微调 Baichuan2 模型本身需要的训练代码外,还依赖其他一些代码来构建训练环境。这里我们推荐按以下结构来组织文件:

  1. src/
  2. ├── fine-tune.py
  3. ├── ds_config.json
  4. ├── requirements.txt
  5. ├── s5cmd
  6. ├── entry.py
  7. └── train.sh

下面将解释每个文件的内容和用途。

fine-tune.py 和 ds_config.json

这两个文件均由 Baichuan2 官方提供,地址位于:https://github.com/baichuan-inc/Baichuan2/tree/main/fine-tune。

为了适配 SageMaker Training Job 的训练环境,需要对 fine-tune.py 文件做以下修改:

 Python 

  1. if __name__ == "__main__":
  2.    ############################
  3.    LOCAL_RANK = int(os.environ['LOCAL_RANK'])
  4.    WORLD_SIZE = int(os.environ['WORLD_SIZE'])
  5.    WORLD_RANK = int(os.environ['RANK'])
  6.    deepspeed.init_distributed(dist_backend='nccl', rank=WORLD_RANK, world_size=WORLD_SIZE)
  7.    ############################
  8.    train()

为了在训练时使用我们提前上传至 S3 的预训练模型,我们推荐在 fine-tune.py 的 train()函数中进行以下修改,将上传的预训练模型拷贝到运行环境中:

 Python 

  1. ...
  2. def train():
  3.    parser = transformers.HfArgumentParser(
  4.        (ModelArguments, DataArguments, TrainingArguments)
  5.    )
  6.    model_args, data_args, training_args = parser.parse_args_into_dataclasses()
  7.    
  8.    ############################
  9.    if 0 == LOCAL_RANK:
  10.        print("*****************start cp pretrain model*****************************")
  11.        os.system("chmod +x ./s5cmd")
  12.        os.system("./s5cmd sync {0} {1}".format(os.environ['MODEL_S3_PATH'], os.environ['MODEL_LOCAL_PATH']))
  13.        print(f'------rank {LOCAL_RANK} finished cp-------')
  14.    
  15.    torch.distributed.barrier()
  16.    ############################
  17.    model = transformers.AutoModelForCausalLM.from_pretrained(
  18.        model_args.model_name_or_path,
  19.        trust_remote_code=True,
  20.        cache_dir=os.environ['MODEL_LOCAL_PATH'],
  21.    )
  22.    
  23. ...

此外,为了将微调后的模型保存至 S3 方便我们后续使用,我们对 train()函数进行以下修改,在保存模型后上传至 S3:

 Python 

  1. ...
  2. def train():  
  3.    
  4.    ...
  5.    
  6.    trainer.save_state()
  7.    trainer.save_model(output_dir=training_args.output_dir)
  8.    
  9.    ############################
  10.    if WORLD_RANK == 0:
  11.        persistant_path = os.environ['OUTPUT_MODEL_S3_PATH'] + str(datetime.now().strftime("%m-%d-%Y-%H-%M-%S")) + '/'
  12.        os.system("./s5cmd sync {0} {1}".format(training_args.output_dir, persistant_path))
  13.    torch.distributed.barrier()
  14.    ############################

当训练的 GPU 显存不是很大时,例如在 A10G 卡(24G 显存)上训练,为了避免出现 Out Of Memory 的错误,可以通过在 ds_config.json 文件里修改 zero_optimization 的配置来开启 offloading,修改的方式如下:

  1. "zero_optimization": {
  2.  "stage": 3,
  3.  "offload_optimizer": {
  4.    "device": "cpu",
  5.    "pin_memory": true
  6.  },
  7.  "offload_param": {
  8.    "device": "cpu",
  9.    "pin_memory": true
  10.  },
  11.  "overlap_comm": true,
  12.  "stage3_gather_16bit_weights_on_model_save": true
  13.  },

requirements.txt

这个文件定义了训练所需的 python 环境,可参考:

  1. numpy
  2. transformers==4.33.1
  3. sentencepiece
  4. tokenizers
  5. accelerate
  6. deepspeed==0.12.2
  7. bitsandbytes

特别注意其中 transformers 的版本,在本文写作时推荐使用 4.33.1,但这个信息可能失效。

s5cmd

上面的代码用到了 s5cmd 这个工具在本地和 S3 间传输文件,可以使用下面的代码下载这个工具:

 Bash 

curl -L https://github.com/peak/s5cmd/releases/download/v2.0.0/s5cmd_2.0.0_Linux-64bit.tar.gz | tar -xz

如果不希望使用这个工具,也可以将相关命令替换为  s3 cp 实现同样功能。

entry.py

这个文件定义了 SageMaker Training Job 训练环境的一些参数,通常不需要修改:

 Python 

  1. import os
  2. import json
  3. import socket
  4. if __name__ == "__main__":
  5.  
  6.    hosts = json.loads(os.environ['SM_HOSTS'])
  7.    current_host = os.environ['SM_CURRENT_HOST']
  8.    host_rank = int(hosts.index(current_host))
  9.    
  10.    #Parse the IP address of the master node in the multiple nodes cluster of SageMaker training.
  11.    master = json.loads(os.environ['SM_TRAINING_ENV'])['master_hostname']
  12.    master_addr = socket.gethostbyname(master)
  13.    
  14.    os.environ['DS_BUILD_FUSED_ADAM'] = '1'
  15.    os.environ['NODE_INDEX'] = str(host_rank)
  16.    os.environ['SM_MASTER'] = str(master)
  17.    os.environ['SM_MASTER_ADDR'] = str(master_addr)
  18.    os.environ['NCCL_SOCKET_IFNAME'] = 'eth0'
  19.    
  20.    # backend env config
  21.    # os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
  22.    os.environ['FI_PROVIDER'] = 'efa'
  23.    os.environ['NCCL_PROTO'] = 'simple'
  24.    # os.environ['FI_EFA_USE_DEVICE_RDMA'] = '1'
  25.    os.environ['NCCL_DEBUG'] = 'INFO'
  26.    os.environ['HCCL_OVER_OFI'] = '1'
  27.    
  28.    # os.system("wandb disabled")
  29.    
  30.    #invoke the torch launcher shell script.
  31.    #Note: we will use the pytorch launcher to launch deepspeed for multi-nodes training.
  32.    #Note: we will use the s5cmd to speed up the uploading model assets to S3.
  33.    os.system("chmod +x ./train.sh")
  34.    os.system("chmod +x ./s5cmd")
  35.    os.system("/bin/bash -c ./train.sh")

train.sh

这个文件主要定义了微调 Baichuan2 模型的超参数,其中一些比较重要的超参数我们将在下一节进行讲解:

Bash

  1. #!/bin/bash
  2. pip uninstall -y torch torchvision torchaudio
  3. pip install torch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 --index-url https://download.pytorch.org/whl/cu118
  4. chmod +x ./s5cmd
  5. DISTRIBUTED_ARGS="--nproc_per_node $SM_NUM_GPUS --nnodes $NODE_NUMBER --node_rank $NODE_INDEX --master_addr $SM_MASTER_ADDR --master_port 12345"
  6.    
  7. torchrun ${DISTRIBUTED_ARGS} fine-tune.py  \
  8.    --data_path "/opt/ml/input/data/train1/belle_chat_random_10k.json" \
  9.    --model_name_or_path "baichuan-inc/baichuan2-13B-Chat" \
  10.    --output_dir "/tmp/baichuan2_out" \
  11.    --model_max_length 1024 \
  12.    --num_train_epochs 2 \
  13.    --per_device_train_batch_size 2 \
  14.    --gradient_accumulation_steps 16 \
  15.    --evaluation_strategy "no" \
  16.    --save_strategy epoch \
  17.    --learning_rate 1e-5 \
  18.    --lr_scheduler_type constant \
  19.    --adam_beta1 0.9 \
  20.    --adam_beta2 0.98 \
  21.    --adam_epsilon 1e-8 \
  22.    --max_grad_norm 1.0 \
  23.    --weight_decay 1e-4 \
  24.    --warmup_ratio 0.2 \
  25.    --logging_steps 1 \
  26.    --gradient_checkpointing True \
  27.    --deepspeed ds_config.json \
  28.    --fp16 False \
  29.    --bf16 True \
  30.    --cache_dir "/tmp"
  31. if [ $? -eq 1 ]; then
  32.    echo "Training script error, please check CloudWatch logs"
  33.    exit 1
  34. fi

注意上面的代码升级了 pytorch 的版本以满足 Baichuan2 模型微调的需要,如果您后续使用的训练镜像中 pytorch 版本已经满足要求,则不需要执行这部分命令。

正式进行微调

这一节将介绍微调 Baichuan2 模型的一些重要配置,最后会介绍如何启动 SageMaker Training Job。

微调方法选择

Baichuan2 模型提供了便捷的方式在全量微调和 LoRA 微调两种方法间切换,在 train.sh 脚本的 torchrun 命令中增加以下参数就可以切换为 LoRA 微调:

Bash

--use_lora True

训练数据路径

在 train.sh 脚本中,我们通过以下参数定义训练文件的路径:

Bash

--data_path "/opt/ml/input/data/train1/belle_chat_random_10k.json"

请注意在实际训练中,您需要将这个路径中的文件名(belle_chat_random_10k.json)部分修改为您自己的文件名,但目录名(/opt/ml/input/data/train1/)不需要修改,这是因为在启动训练时会指定训练文件所在的 S3 路径,随后 SageMaker Training Job 会自动将训练文件从 S3 同步至训练环境的/opt/ml/input/data/train1/目录下,因此这里的参数只需要修改文件名即可。

其他重要超参数

其他比较重要的超参数包括了 per_device_train_batch_size(即 micro batch,每个 GPU 上同时训练的样本数量),gradient_accumulation_steps,model_max_length 等:

Bash

  1. --model_max_length 1024 \
  2. --per_device_train_batch_size 2 \
  3. --gradient_accumulation_steps 16 \

这些参数不仅影响微调效果,也决定了模型在微调时的显存使用量是否适配您选择的实例类型,需要根据实际情况进行相应修改。

启动训练

在 SageMaker Notebook 中使用以下代码正式启动 Training Job:

 Python 

  1. import sagemaker
  2. import boto3
  3. import time
  4. from sagemaker import get_execution_role
  5. from sagemaker.estimator import Estimator
  6. sess = sagemaker.Session()
  7. role = get_execution_role()
  8. sagemaker_default_bucket = sess.default_bucket()
  9. region = sess.boto_session.region_name
  10. ## pre-built docker in https://github.com/aws/deep-learning-containers/blob/master/available_images.mdr'
  11. image_uri = '763104351884.dkr.ecr.us-west-2.amazonaws.com/pytorch-training:2.0.1-gpu-py310-cu118-ubuntu20.04-sagemaker'
  12. instance_count = 1
  13. instance_type = 'ml.p4de.24xlarge' ## p4d - 8*40G / p4de - 8*80G
  14. environment = {
  15.    'NODE_NUMBER':str(instance_count),
  16.    'MODEL_S3_PATH': '{your-s3-pretrain-model-path}/*', # pretrain model files in s3, note must have /*
  17.    'MODEL_LOCAL_PATH': '/tmp/hf_models',
  18.    'OUTPUT_MODEL_S3_PATH': '{your-s3-finetune-model-path}', # finetune model destination
  19. }
  20. estimator = Estimator(role=role,
  21.                      entry_point='entry.py',
  22.                      source_dir='./src',
  23.                      base_job_name='multi-node-baichuan-train',
  24.                      instance_count=instance_count,
  25.                      instance_type=instance_type,
  26.                      image_uri=image_uri,
  27.                      environment=environment,
  28.                      max_run=2*24*3600, #任务最大存续时间
  29.                      disable_profiler=True,
  30.                      debugger_hook_config=False)
  31. # # data in channel will be automatically copied to each node - /opt/ml/input/data/train1
  32. # # should change data_path param to above path in torchrun
  33. input_channel = {'train1': '{your-s3-data-path-prefix}'}
  34. estimator.fit(input_channel)

其中 instance_type 和 instance_count 定义了训练任务使用的实例类型和数量。根据训练数据文本长度的不同,在进行全量微调时我们推荐使用 1 个 g5.48xlarge、p4d.24xlarge 或 p4de.24xlarge 实例,在进行 LoRA 微调时,推荐使用 1 个 g5.48xlarge 实例。最优的实例配置需要根据实际情况进行探索。environment 中定义了预训练模型的 S3 路径(MODEL_S3_PATH),以及微调后模型的保存路径的 S3 路径(OUTPUT_MODEL_S3_PATH),在 input_channel 部分则定义了训练数据所在的 S3 路径前缀(即不包括文件名的部分),这些参数均需要根据实际情况做相应修改。

微调性能对比

我们以 belle 数据集为例,对比不同微调方法在不同模型大小下的训练时长和 Loss。

85ed00059a8a947693aa12f380111998.png

系列博客

Amazon SageMaker 上的 Baichuan2 模型微调及部署(二)部署部分:https://aws.amazon.com/cn/blogs/china/baichuan2-model-fine-tuning-and-deployment-on-amazon-sagemaker-part-two/

本篇作者

67456975d1c07a6f48681bcb19a389ad.jpeg

冉晨伟

亚马逊云科技应用科学家,长期从事生成式 AI、自然语言处理、信息检索等领域的研究和开发工作。支持 GenAI 实验室项目,在大语言模型、搜索排序、预训练、多模态模型等方向有丰富的算法开发以及落地实践经验。

9d03dd7bd743dee5865c60709d9748c8.jpeg

魏亦豪

亚马逊云科技应用科学家,长期从事生成式 AI、自然语言处理、多模态预训练等领域的研究和开发工作。支持 GenAI 实验室项目,在对话系统、智能客服、虚拟陪伴、预训练、多模态模型等方向有丰富的算法开发以及落地实践经验。

537867c5044f5f2f8951a3bfba88ddd7.jpeg

张闯

亚马逊云科技应用科学家,长期从事生成式 AI、自然语言处理、计算机视觉等领域的研究和开发工作。支持 GenAI 实验室项目,在大语言模型、多模态模型、强化学习、智能客服、内容安全等方向有丰富的算法开发以及落地实践经验。

b80d32928b32065a2228a560a2b0ad28.jpeg

蔡天勤

亚马逊云科技应用科学家,长期从事生成式 AI、自然语言处理、多模态预训练等领域的研究和开发工作。支持 GenAI 实验室项目,在广告推荐、搜索排序、预训练、多模态模型等方向有丰富的算法开发以及落地实践经验。

90c45c22516f4ba7d2e6a7c7659664eb.jpeg

王鹤男

亚马逊云科技资深应用科学家,负责数据实验室项目,熟悉计算机视觉、自然语言处理、传统机器学习模型等领域,领导了首汽约车语音降噪、LiveMe 直播场景反欺诈等项目,为企业客户提供云上的人工智能和机器学习赋能。曾任汉迪推荐算法工程师,神州优车集团人工智能实验室负责人等职位。

7a0d752eea0faac6e73c166be8ac3808.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

a2378bdd33928d38f8ed8fb4c3c33639.gif

听说,点完下面4个按钮

就不会碰到bug了!

5729a522acd13c78db16868d25d46431.gif

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号