Amazon SageMaker HyperPod 实践:掌握分布式,构建大模型训练环境!

分布式
机器学习
Amazon Simple Storage Service (S3)
Amazon EC2
Amazon SageMaker
0
0
### **前言** [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 是亚马逊云科技提供的一个全面的[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)平台。它支持从构建、训练和部署[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)模型到监控和自动模型调优的整个[机器学习](https://aws.amazon.com/cn/machine-learning/?trk=cndc-detail)工作流程。**利用 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod,用户可以像使用 [Amazon EC2 ](https://aws.amazon.com/cn/ec2/?trk=cndc-detail)实例一样快速启动、登录各种 GPU 资源 (如 G5 A10、P4 A100、P5 H100…...) 并进行 LLM 或 SD 等模型的分布式训练和推理部署。** LLaMA-Factory 是开源社区一套大模型集成训练框架。本文中我们将结合代码和示例,**介绍如何使用 LLaMA-Factory 在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod 上训练大模型,熟悉 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod 集群创建和多机多卡分布式训练方法。** ### **简介** #### **1、Amazon SageMaker HyperPod 简介** **[Amazon SageMaker HyperPod 集群](https://aws.amazon.com/cn/sagemaker/hyperpod/?nc1=h_ls?trk=cndc-detail)是一种分布式训练平台,它支持持续数天、数周甚至数月的开发和训练任务,可以将训练时间缩短多达 40%。** HyperPod 采用基于 Slurm 的 HPC 高性能弹性计算集群,能够实现单机或跨机器跨 GPU 的大规模并行训练。它提供原生的基于 GPU 或 CPU 的基础设施,您可以自由操控或部署任意框架,充分发挥亚马逊云科技上服务可伸缩的计算能力,线性扩展训练吞吐量。 **HyperPod 预配置了 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 分布式训练库,能自动将训练工作负载拆分到数千个 GPU 上并行处理,提高训练性能**。它还通过自动定期保存 Checkpoint,支持数周或数月的无中断训练;当硬件故障时会自动检测、修复或更换有故障实例,从上次检查点恢复训练,无需任何手动管理,以保证任务的持续、稳定运行。 #### **2、LLaMA-Factory 介绍** [LLaMA-Factory](https://github.com/hiyouga/LLaMA-Factory?trk=cndc-detail) 是开源社区一套大模型集成训练框架,支持: * **多种模型**:LLaMA、LLaVA、Mistral、Mixtral-MoE、Baichuan等等 * **集成方法**:(增量) 预训练、 (多模态) 指令监督微调、奖励模型训练、PPO 训练、DPO 训练、KTO 训练、ORPO 训练等等 * **多种精度**:32 比特全参数微调、16 比特冻结微调、16 比特 LoRA 微调和基于 AQLM/AWQ/GPTQ/LLM.int8 的 2/4/8 比特 QLoRA 微调 * **先进算法**:GaLore、BAdam、DoRA、LongLoRA、LLaMA Pro、Mixture-of-Depths、LoRA+、LoftQ 和 Agent 微调 因此 ,**LLaMA-Factory 结合 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail),也可以应用于其他模型和其他的训练方法**。充分利用 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 托管服务,可以无需关注资源的系统配置,并且可以按需启动训练任务,训练完成后自动清退节点资源,无需长期占用资源,带来更加便捷,经济的训练。 ### **创建 HyperPod 集群** 接下来我们将以 HyperPod 做分布式训练大模型的例子,创建一个包含 2 台 g5.12xlarge (单台 4 张 GPU 卡) 集群。 #### **1、Notebook 实例工作环境准备 (为创建和管理 HyperPod 的工作环境)** 下载 [Amazon CloudFormation 配置文件](https://github.com/xiehust/llm_finetune/blob/workshop/setup_nogpu.yaml?trk=cndc-detail),在 Amazon CloudFormation 中使用这个配置文件,启动一个 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Notebook 实例。该配置文件已经预置了 HyperPod 必要的权限,使用该配置文件创建一个 Notebook 实例可以避免手动去设置 IAM policy 等操作。 在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Notebook jupyterlab 中,打开一个 terminal。 ![image.png](https://dev-media.amazoncloud.cn/2fe7a2ce3c4f4dbaa569c2a3ea73152b_image.png "image.png") 终端打开后,进入 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail)/ 目录,运行一下命令下载相关的代码。 ```js cd SageMaker/ git clone --recurse-submodules https://github.com/aws-samples/Easy_Fintune_LLM_using_SageMaker_with_LLama_Factory ``` #### **2、下载官方 lifecycle 配置文件,并上传到 Amazon S3 存储桶中** !注意替换{bucket},必须以“sagemaker”作为前缀,所以可以使用 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) 默认的 bucket,例如 sagemaker-us-west-2-434444145045 的形式。 ```js aws s3 cp --recursive awsome-distributed-training/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/ s3://{bucket}/hyperpod/LifecycleScripts/ ``` #### **3、创建集群 provisioning 配置文件,并上传到 Amazon S3 存储桶** 写一个 Slurm 配置文件并将其另存为 provisioning_parameters.json。在文件中,指定基本的 Slurm 配置参数,以便将 Slurm 节点正确分配给集群实例组。 本示例中,我们创建 2 个组,分别是控制组和工作组,设置组名为 * my-controller-group * worker-group-1 也可以创建多个 worker-group,不同的 group 可以使用不同类型的实例。 另外 partition_name 表示节点分区,可以结合用户组来控制资源的使用权限。 如以下示例配置所示。provisioning_parameters.json。 ```js %%writefile lifecycle-scripts/provisioning_parameters.json { "version": "1.0.0", "workload_manager": "slurm", "controller_group": "my-controller-group", "worker_groups": [ { "instance_group_name": "worker-group-1", "partition_name": "partition-1" } ] } ``` 把该文件 copy 至 S3 中。 ```js aws s3 cp —recursive lifecycle-scripts/ s3://{bucket}/hyperpod/LifecycleScripts/ ``` #### **4、准备一个 create_cluster.json 文件,用于使用 Amazon CLI 命令行创建 HyperPod 集群** 例如,以下配置文件将创建一个 ml.c5.xlarge*1+ml.g5.12xlarge*2 的集群。 ```js #替换成实际的集群名称 cluster_name = "hyperpod-cluster-1" SourceS3Uri = f"s3://{bucket}/hyperpod/LifecycleScripts" worker_instance = "ml.g5.12xlarge" worker_count = 2 create_cluster = \\ { "ClusterName": cluster_name, "InstanceGroups": [ { "InstanceGroupName": "my-controller-group", "InstanceType": "ml.c5.xlarge", "InstanceCount": 1, "LifeCycleConfig": { "SourceS3Uri": SourceS3Uri, "OnCreate": "on_create.sh" }, "ExecutionRole": role, "ThreadsPerCore": 1 }, { "InstanceGroupName": "worker-group-1", "InstanceType": worker_instance, "InstanceCount": worker_count, "LifeCycleConfig": { "SourceS3Uri": SourceS3Uri, "OnCreate": "on_create.sh" }, "ExecutionRole": role, "ThreadsPerCore": 1 } ] } with open("create_cluster.json","w") as f: json.dump(create_cluster,f) ``` 在 Notebook 中运行以下命令来创建集群,注意 file:// 后面是 create_cluster.json 的绝对路径。 ```js !aws sagemaker create-cluster --cli-input-json file://~/SageMaker/llm_finetune/create_cluster.json ``` 大概等待 12—13 分钟之后,集群成功拉起之后,可以在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod 控制台看到启动成功的集群。如图所示: ![image.png](https://dev-media.amazoncloud.cn/b9d359dad6434d599b8c7f9080ca664b_image.png "image.png") 也可以在 Notebook 终端中运行以下命令,查看集群信息: ```js aws sagemaker list-clusters #替换成实际的集群名称 cluster_name=hyperpod-cluster-1 aws sagemaker list-cluster-nodes --cluster-name {cluster_name} --region us-west-2 ``` ![image.png](https://dev-media.amazoncloud.cn/2b988af9e78d4a69ab472f72a5680741_image.png "image.png") ### **设置远程访问 HyperPod 集群** #### **1、通过 Amazon Systems Manager (SSM) 访问集群,并且通过脚本 easy-ssh.sh 连接集群节点** 如果在您的本地主机远程访问集群,则需要下载 [easy-ssh.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/easy-ssh.sh?trk=cndc-detail) 到本地主机,另外本地主机需要配置好 Amazon Credentials 的 [access key/secret access key](https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-configure.html?trk=cndc-detail),且需要相关的权限,具体参考这个 policy。 如果在上述已经部署好的 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Notebook 实例中访问集群,由于启动时已经预置了权限,无须在额外设置。 如果在本地主机访问,请升级最新的 Amazon CLI 工具,升级参考链接。 安装 ssm plugin。 ```js sudo yum install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm ``` 使用 easy-ssh.sh 脚本登录到 worker-group-1 的计算节点 (后续的设置和训练任务,我们将直接在计算节点操作) 。 ```js chmod +x easy-ssh.sh ./easy-ssh.sh -c worker-group-1 hyperpod-cluster-1 ``` 成功执行上述脚本之后,已经登录到了集群中的一个计算节点,并出现以下结果。 ![image.png](https://dev-media.amazoncloud.cn/83431ae0edfe4290b4bda957723a5937_image.png "image.png") #### **2、设置 SSH 代理访问以及 vs code 远程调试** 上一步完成之后,在**本地机器或者 Notebook 实例**中,编辑 \~/.ssh/config,**把上面打印 Host hyperpod-cluster-1 的那段加入到 config 最后,或者直接复制出命令在终端执行。** ```js \$ cat <<EOF >> ~/.ssh/config Host <cluster-name> User ubuntu ProxyCommand sh -c "aws ssm start-session --target sagemaker-cluster:<cluster_id>_<node-group>-<instance_id> --document-name AWS-StartSSHSession --parameters 'portNumber=%p'" EOF ``` 在本地机器或者 Notebook 实例中,生成 public key。 ```js ssh-keygen -t rsa -q -f "\$HOME/.ssh/id_rsa" -N "" cat ~/.ssh/id_rsa.pub ``` 复制 public key 并加入到集群主机的 authorized_keys 中,这样本地主机或者 Notebook 实例会与集群节点建立起互信,可以通过 SSH 访问。重新登录集群主机,打开~/.ssh/authorized_keys 文件,并发上一步生成的 public key 添加到文件的最后。 ```js #登录到集群中,工作组为 worker-group-1 的计算节点 ./easy-ssh.sh -c worker-group-1 hyperpod-cluster-1 #切换至 ubuntu 用户 sudo su - ubuntu vim ~/.ssh/authorized_keys ``` 完成以上设置之后,重新回到本地机器,直接用以下命令登录到名称为 hyperpod-cluster-1,工作组为 worker-group-1 的计算节点中。 ```js ssh hyperpod-cluster-1 ``` 在 vscode 的 [remote explorer 插件](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer?trk=cndc-detail)中会自动出现该集群 worker-group-1 组中的计算节点,登录之后即可进行远程调试。 ![image.png](https://dev-media.amazoncloud.cn/08ba001e695b42c0bd7d6b5559b70367_image.png "image.png") ### **HyperPod 集群环境设置** #### **1、上传训练脚本到 Amazon S3** **在 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) Notebook 实例中,打开一个 terminal** 通过命令行上传训练脚本到 S3 bucket 中,之后 S3 bucket 会挂载到集群所有节点中,这样所有计算节点都可以访问训练代码和数据。 ```js ./s5cmd sync ./LLaMA-Factory s3://{bucket}/hyperpod/ aws s3 cp —recursive hyperpod-scripts/ s3://{bucket}/hyperpod/LLaMA-Factory/ ``` #### **2、挂载 Amazon S3** 与 [Amazon EC2 ](https://aws.amazon.com/cn/ec2/?trk=cndc-detail)实例一样,Hyperpod 集群实例上可以挂载各种共享存储,如 EFS、Lustre、S3 等,此处我们以 mount-s3 为例。 mount-s3 共享存储安装及挂载脚本示例: 仍然 SSH hyperpod-cluster-1 登录到集群节点中,执行。 ```js ###下载 s3mount cd ~ srun -N2 "wget" "https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb" srun -N2 sudo apt-get install -y ./mount-s3.deb # 挂载到"~/mnt" 中, 注意实验中用了2个计算节点,所以以下用srun -N2表示在所有节点中执行, 如果是其他数量节点,则对应修改成计算节点的数量 srun -N2 "sudo" "mkdir" "/home/ubuntu/mnt" #在所有节点上挂载,注意region,account-id替换成您自己的aws region和 account id srun -N2 "sudo" "mount-s3" "--allow-other" "--allow-overwrite" "sagemaker-us-west-2-434444145045" "/home/ubuntu/mnt" ``` #### **3、在集群上安装 LLaMA-Factory** 仍然保持登录到集群节点中,把 S3 bucket 的目录下的代码 copy 到本地目录,该命令使用 srun -N2,意思是在 2 个计算节点上执行同样的操作。 ```js cd ~ srun -N2 "cp" "-r" "mnt/hyperpod/LLaMA-Factory" "LLaMA-Factory" ``` 执行按照脚本 llama_factory_setup.sh,该命令使用 srun -N2,在 2 个计算节点上都安装 LLaMA-Factory。 ```js cd LLaMA-Factory srun -N2 "rm" "-rf" "../miniconda3" srun -N2 rm - rf Miniconda3-latest* srun -N2 "bash" "llama_factory_setup.sh" ``` ### **在 HyperPod 集群上基于 DeepSpeed 进行分布式训练** 我们部署了 2 台 ml.g5.12xlarge 实例作为计算节点,因此可以在 HyperPod 集群提交训练任务,底层使用 LLaMA-Factory 集成的 deepspeed 分布式训练引擎进行训练。以 lora 微调 llama-3-8b-Instruct 为例。 #### **1、训练数据和脚本准备** * 数据集准备 LLaMA-Factory 本身已经预置了多种丰富的训练数据集,可以自动从 huggingface repo 中下载,也支持自定义数据集,支持 alpaca 或者 sharegpt,需要在 LLaMA-Factory/data/dataset_info.json 注册即可。我们可以把准备好的数据集上传至 S3,然后把数据集元信息注册到 dataset_info.json 中。并在训练脚本中采用执行 s5cmd 从 S3 下载数据集到节点的本地 data 目录中。具体可以参考代码中 04.llama_factory_finetune_on_SageMaker_multi_node.ipynb [数据准备](https://github.com/xiehust/llm_finetune/blob/workshop/01.llama_factory_finetune_on_SageMaker_QLora-Local-Notebook.ipynb?trk=cndc-detail)部分。 * 准备训练配置文件 如使用 deepspeed zero3 方式进行 lora 训练 sg_config_multl_node_lora_ds.yaml 如下。 ```js cutoff_len: 2048 dataset: identity,ruozhiba ddp_timeout: 180000000 deepspeed: examples/deepspeed/ds_z3_config.json do_train: true eval_steps: 500 evaluation_strategy: steps finetuning_type: lora fp16: true gradient_accumulation_steps: 2 learning_rate: 0.0001 logging_steps: 10 lora_target: q_proj,v_proj lr_scheduler_type: cosine max_samples: 1000 model_name_or_path: unsloth/llama-3-8b-Instruct num_train_epochs: 3 output_dir: /home/ubuntu/finetuned_model overwrite_cache: true overwrite_output_dir: true per_device_eval_batch_size: 1 per_device_train_batch_size: 1 plot_loss: true preprocessing_num_workers: 16 save_steps: 500 stage: sft template: llama3 val_size: 0.1 warmup_ratio: 0.1 warmup_steps: 10 ``` - 准备训练脚本 train_multi_ds.sh ```js %%writefile hyperpod-scripts/train_multi_ds.sh #!/bin/bash sg_config=sg_config_multl_node_lora_ds.yaml echo "sg_config=\$sg_config" #注意把s3 bucket 替换成自己账号的地址 OUTPUT_MODEL_S3_PATH=s3://sagemaker-us-west-2-434444145045/hyperpod/llama3-8b-ds/ source ../miniconda3/bin/activate conda activate py310 chmod +x ./s5cmd #下载training dataset ./s5cmd sync s3://sagemaker-us-west-2-434444145045/dataset-for-training/train/* /home/ubuntu/LLaMA-Factory/data/ NODE_RANK=\$SLURM_NODEID echo "NODE_RANK=\$NODE_RANK" WORLD_SIZE_JOB=\$SLURM_NTASKS echo "WORLD_SIZE_JOB=\$WORLD_SIZE_JOB" MASTER_ADDR=(`scontrol show hostnames \\\$SLURM_JOB_NODELIST | head -n 1`) MASTER_PORT=\$(expr 10000 + \$(echo -n \$SLURM_JOBID | tail -c 4)) echo "MASTER_ADDR=\$MASTER_ADDR" echo "MASTER_PORT=\$MASTER_PORT" # get gpu count gpu_count=\$(nvidia-smi --query-gpu=gpu_name --format=csv,noheader | wc -l) DEVICES="" # 构建设备字符串 for ((i=0; i<gpu_count; i++)); do DEVICES+="\$i" if ((i < gpu_count - 1)); then DEVICES+="," fi done echo "DEVICES=\$DEVICES" export DS_BUILD_FUSED_ADAM=1 export NCCL_PROTO=simple export NCCL_DEBUG=INFO export HCCL_OVER_OFI=1 # 使用efa export FI_PROVIDER=efa export NCCL_IGNORE_DISABLED_P2P=1 ## 如果拉起的集群为A100/H100(P4d/P5机型)节点,可以设置如下的NCCL参数启用RDMA,以获得多机多卡训练时节点GPU更大的网络吞吐量 export FI_EFA_USE_DEVICE_RDMA=1 export NCCL_LAUNCH_MODE=PARALLEL #依次在各个node上执行llamafactory-cli train if [ "\$NODE_RANK" == "0" ]; then CUDA_VISIBLE_DEVICES="\$DEVICES" NNODES=\$WORLD_SIZE_JOB RANK=0 MASTER_ADDR="\$MASTER_ADDR" MASTER_PORT="\$MASTER_PORT" llamafactory-cli train "\$sg_config" else CUDA_VISIBLE_DEVICES="\$DEVICES" NNODES=\$WORLD_SIZE_JOB RANK=\$NODE_RANK MASTER_ADDR="\$MASTER_ADDR" MASTER_PORT="\$MASTER_PORT" llamafactory-cli train "\$sg_config" fi #只在0节点执行上传模型文件至s3操作 if [ "\$NODE_RANK" == "0" ]; then echo "*****************finished training, start cp finetuned model*****************************" ./s5cmd sync "/home/ubuntu/finetuned_model" "\$OUTPUT_MODEL_S3_PATH" echo '-----finished cp-------' fi ``` - 上传训练脚本到 S3 bucket 中,之后 S3 bucket 会挂载到集群所有节点中,这样所有计算节点都可以访问训练代码 ```js ./s5cmd sync ./LLaMA-Factory s3://{bucket}/hyperpod/ aws s3 cp --recursive hyperpod-scripts/ s3://{bucket}/hyperpod/LLaMA-Factory/ ``` #### **2、提交训练任务** * 按前面所述,使用 SSH 登录到集群计算节点, 把挂载的 S3 bucket 的目录下的代码更新到节点的本地目录中 ```js srun -N2 "cp" "-r" "mnt/hyperpod/LLaMA-Factory/train_multi_ds.sh" "LLaMA-Factory/train_multi_ds.sh" srun -N2 "cp" "-r" "mnt/hyperpod/LLaMA-Factory/train_batch.sh" "LLaMA-Factory/train_batch.sh" ``` - 提交训练任务,在所有节点上执行 train_multi_ds.sh ```js cd ~/LLaMA-Factory srun -N2 "bash" "train_multi_ds.sh" ``` 训练完成之后将 lora adapter 文件上传到 S3 输出目录中,可参考[代码库](https://github.com/xiehust/llm_finetune/blob/workshop/03.deploy_on_SageMaker_endpoint_lmi_vllm.ipynb?trk=cndc-detail)中的 deploy_on_SageMaker_endpoint_lmi_vllm.ipynb 部署到推理节点中。 ![image.png](https://dev-media.amazoncloud.cn/c0328187c4fa4166ada9c3dba010a7e5_image.png "image.png") ### **总结** [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod 采用基于 Slurm 的 HPC 高性能弹性计算集群,能够实现跨机器跨 GPU 的大规模并行训练。本文介绍了: 1. HyperPod 集群的创建 2. SSH 远程访问集群设置 3. 集群中部署 LLaMA-Factory 4. 在集群中提交分布式训练任务 LLaMA-Factory 本身支持多种模型,集成多种训练方法,也可以应用于其他模型和其他的训练方法,因此,**LLaMA-Factory 结合 [Amazon SageMaker](https://aws.amazon.com/cn/sagemaker/?trk=cndc-detail) HyperPod,提供大规模可扩展的云上训练能力,实现轻松、便捷的大规模分布式训练。** ### **附录** - [本篇代码库](https://github.com/aws-samples/Easy_Fintune_LLM_using_SageMaker_with_LLama_Factory?trk=cndc-detail) - [Hyperpod 官方文档](https://docs.aws.amazon.com/sagemaker/latest/dg/whatis.html?trk=cndc-detail) - [Hyperpod 官方示例代码](https://github.com/aws-samples/awsome-distributed-training/tree/main/1.architectures/5.sagemaker-hyperpod?trk=cndc-detail) - [Hyperpod CLI 命令](https://docs.aws.amazon.com/zh_cn/sagemaker/latest/dg/sagemaker-hyperpod-ref.html#sagemaker-hyperpod-ref-cli?trk=cndc-detail) - [面向 GPU 服务器的 SageMaker 使用指南 (三) - Hyperpod 集群](https://aws.amazon.com/cn/blogs/china/guide-to-using-sagemaker-for-gpu-servers-part-three/?trk=cndc-detail) ![image.png](https://dev-media.amazoncloud.cn/197f30cbb1124aa387663fec9cebf735_image.png "image.png") ![开发者尾巴.gif](https://dev-media.amazoncloud.cn/ba68b8cabe3947288ad49415863fe3d3_%E5%BC%80%E5%8F%91%E8%80%85%E5%B0%BE%E5%B7%B4.gif "开发者尾巴.gif")
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭