You need to enable JavaScript to run this app.
导航
Qwen2 72B模型在 MLP 的最佳实践
最近更新时间:2024.09.24 15:06:57首次发布时间:2024.09.14 15:37:14

机器学习平台是一套服务于专业算法工程师,整合云原生的工具+算力(GPU、CPU云服务器),进行一站式AI算法开发和迭代的平台。本方案将为您介绍如何在 MLP 基于 Qwen2-72B 的开源模型进行模型微调、离线推理验证,并实现在线服务部署。

使用前提

说明

在实践过程中,如果因网络等问题导致模型、数据集或量化工具等无法下载到 TOS bucket ,建议您可以先将其下载到开发机云盘中,再自行拷贝到 TOS 路径下。

本方案以 Qwen2-72B 模型为例,在开始执行操作前,请确认您已经完成以下准备工作:

步骤一:准备 Qwen2-72B 模型
  1. 进入开发机。

    1. 登陆 账号登录-火山引擎

    2. 在左侧导航栏单击开发机,在开发机列表页面中单击待操作的开发机名称,进入对应开发机内。

    3. 通过 SSH 远程登录开发机,具体操作详见通过SSH远程连接开发机--机器学习平台-火山引擎

  2. 配置volc configure。具体操作详见使用文档--机器学习平台-火山引擎

  3. 在Terminal中执行以下命令,通过镜像源下载 Qwen2-72B 模型,并打开挂载的存储桶路径。

    模型下载速度较慢,网络保持在150g、5m/s,预计8h可以下载完成。

cd /vemlp-demo-models
mkdir model-qwen 
cd model-qwen
pip3 install -U huggingface_hub
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download --token $HF_TOKEN --resume-download Qwen/Qwen2-72B-Instruct --local-dir $ORIGINAL_MODEL_PATH

其中运行 huggingface-cli 命令行,需要传入的参数列表说明如下:

参数描述
hf_token具有qwen使用权限的Huggingface账号的hf_token。
original_model_path源safetensor路径。

说明

  1. --token/--hf_username/--hf_token等参数非必须,仅为部分 Repo 有 license 限制,需登录申请许可。如果必要,请在 https://huggingface.co/settings/tokens 获取 token 后进行下载。
  2. 推荐您将模型文件、训练数据集的下载、存放地址都设置在 TOS/VEPFS/SCFS 等共享存储内,之后在进行训练、推理等跨节点的任务时,可以更加轻松地挂载到不同的机器上。
步骤二:准备数据集

在 Terminal 执行以下命令,下载 MLP 已准备好的数据集。

cd /vemlp-demo-models
mkdir datasets-qwen
cd datasets-qwen
wget https://mlp-opentrail-demo.tos-cn-beijing.volces.com/dataset/finetune-dataset.tar.gz
tar -zxf finetune-dataset.tar.gz
步骤三:模型训练

3.1 模型格式转换(safetensor to ckpt)

在 Terminal 中执行以下命令,可将 safetensor 无损转换成 checkpoint 格式,并输出到启动参数(MEGATRON_LM_MODEL_PATH)配置的目标 checkpoint 路径中。格式转换预计耗时 45~50 min。

cd /opt/ml-platform/third_party/vemlp-open-trial/third_party/veMLP-utils/qwen2_convertor
bash convertor.sh -s $ORIGINAL_MODEL_PATH -t $MEGATRON_LM_MODEL_PATH -tp 8 -pp 4 -pr bf16 -te false

其中运行 convertor.sh 脚本需要传入的参数说明如下:

参数描述
original_model_path源safetensor路径。
megatron_lm_model_path目标checkpoint路径。
tp模型并行度。
pp流水并行度。
pr训练精度:fp16或bf16。

te

是否使用tranformer_engine,取值如下:

  • true

  • false

3.2 自定义任务分布式训练(指令微调)

最佳实践文档提供控制台与命令行两种方式的操作说明。

方式一:控制台

  1. 进入自定义任务控制台

  2. 配置环境

    1. 在自定义镜像处配置镜像。
    vemlp-boe-cn-beijing.cr.volces.com/preset-images/megatron-lm:trail-2
    
    1. 填写入口命令并定义环境变量。请注意 TOS 在开发机上挂载的路径与自定义任务中挂载的路径不一致,在入口命令填写数据集路径环境变量中填写模型路径时,需确保为自定义任务中挂载的路径。
    cd /opt/ml-platform/third_party/vemlp-open-trial/third_party/veMLP-examples/qwen2/ && /bin/bash run_finetune_mcore_qwen2.sh --batch_size 1 --global_batch_size 32 --learning_rate 1e-5 --min_learning_rate 1e-6 --sequence_length 2048 --padding_length 2048 --precision bf16 --tensor_parallel 8 --pipeline_parallel 4 --activation_checkpoint sel --distributed_optimizer true --flash_attention true --sequence_parallel true --transformer_engine true --save_interval 100 --dataset_path /data/datasets-qwen/finetune-dataset/alpaca_zh-llama3-train.json --valid_dataset_path /data/datasets-qwen/finetune-dataset/alpaca_zh-llama3-valid.json --pretrain_checkpoint_path $CHECKPOINT_PATH  --train_iters 1000 --lr_warmup_iters 10 --output_basepath $OUTPUT_PATH
    

  3. 配置资源

    1. 选择合适的资源,最佳实践所用机器为 4 机 8 卡 ml.pni2。

    2. 挂载 TOS 和 CFS。需要注意:TOS 在开发机上挂载的路径与自定义任务中挂载的路径不一致,在环境变量中填写模型路径时需确保为自定义任务中挂载的路径。

方式二:命令行

在 Terminal 中使用以下命令对 qwen2-72B 进行预训练,具体操作步骤如下。

  1. 创建一个 demo.yaml 文件。

  2. 编辑 yaml 文件,填写镜像、资源规格、环境变量以及入口命令。

  3. 运行任务命令。如运行成果,在Terminal会出现 “创建任务成功,task_id=*****” 字样。完整训练时长预计为2.5小时左右。

    volc ml_task submit --conf=/vemlp-demo-models/demo.yaml
    

demo.yaml 文件示例:

TaskName: "qwen2-72b"
Description: ""
Tags: []
ImageUrl: "vemlp-boe-cn-beijing.cr.volces.com/preset-images/megatron-lm:trail-2"
ResourceQueueID: "q-**************"  # 请替换为自己的队列ID
# DL framework, support: TensorFlow PS,PyTorch DDP,Horovod,BytePS
Framework: "PyTorchDDP"
# Flavor代表机型,去 https://www.volcengine.com/docs/6459/72363 查询

TaskRoleSpecs:
        - RoleName: "worker"
            RoleReplicas: 4                                                   
            Flavor: "custom"
            ResourceSpec:
                    Family: "ml.hpcpni2l"
                    CPU: 105.000
                    Memory: 1875.000
                    GPUNum: 8

Envs:
    - Name: "CHECKPOINT_PATH"
        Value: "/data/model-qwen/qwen2-72B-to-megatron-tp8-pp4"
    - Name: "OUTPUT_PATH"
        Value: "/data/model-qwen/ckpt"
 AccessType: "Queue"

Storages:
        - Type: "Tos"                     
            MountPath: "/data"
            Bucket: "vemlp-demo-models"
            Prefix: "/"
            FsName: "testmodel"
            MetaCacheExpiryMinutes: "-1"

Entrypoint: |
    cd /opt/ml-platform/third_party/vemlp-open-trial/third_party/veMLP-examples/qwen2/ && /bin/bash run_finetune_mcore_qwen2.sh --batch_size 1 --global_batch_size 32 --learning_rate 1e-5 --min_learning_rate 1e-6 --sequence_length 2048 --padding_length 2048 --precision bf16 --tensor_parallel 8 --pipeline_parallel 4 --activation_checkpoint sel --distributed_optimizer true --flash_attention true --sequence_parallel true --transformer_engine false --save_interval 100 --dataset_path /data/datasets-qwen/finetune-dataset/alpaca_zh-llama3-train.json --valid_dataset_path /data/datasets-qwen/finetune-dataset/alpaca_zh-llama3-valid.json --pretrain_checkpoint_path $CHECKPOINT_PATH  --train_iters 1000 --lr_warmup_iters 10 --output_basepath $OUTPUT_PATH

其中运行 run_finetune_mcore_qwen2.sh 脚本,需要传入的参数列表说明如下:

参数描述
batch_size一次迭代一个数据并行内的样本数。
global_batch_size一次迭代多个数据并行的总样本数。
learning_rate学习率。
min_learning_rate最小学习率。
sequence_length序列长度。
padding_lengthPadding长度。
precision训练精度:fp16、bf16或fp8。
tensor_parallel模型并行度。
pipeline_parallel流水并行度。

activation_checkpoint

激活检查点模式,取值如下:

  • sel

  • full

  • offload

  • none

distributed_optimizer

是否使用Megatron版Zero-1降显存优化器,取值如下:

  • true

  • false

flash_attention

是否优先使用Flash Attention,取值如下:

  • true

  • false

sequence_parallel

是否使用序列并行,取值如下:

  • true

  • false

transformer_engine

是否使用tranformer_engine,取值如下:

  • true

  • false

save_interval保存checkpoint文件的间隔。
dataset_path训练数据集路径。
valid_dataset_path验证数据集路径。
pretrain_checkpoint_path预训练模型路径。
train_iters训练Iter数。
lr_warmup_iters预热Iter数。
output_basepath训练输出日志文件路径。

3.3 模型格式转换(ckpt to safetensor)

在 Terminal 中执行以下命令,可将 checkpoint 无损转换回 safetensor 格式,并输出到启动参数(ORIGINAL_MODEL_PATH)配置的目标 checkpoint 路径中。

  1. 首先请确保 $MEGATRON_LM_MODEL_PATH 路径下存在 tokenizer.model 词表文件。如没有,则执行下面的命令行进行文件拷贝。
cp -f /vemlp-demo-models/model-qwen/qwen2-72B-to-megatron-tp8-pp4/tokenizer.json /vemlp-demo-models/model-qwen/ckpt/checkpoint/pretrain-mcore-qwen2--tp-8-pp-4/iter_0001000/
  1. 运行 convertor.sh 脚本,预计转换时间 45~50 min。
cd /opt/ml-platform/third_party/vemlp-open-trial/third_party/veMLP-utils/qwen2_convertor
bash convertor.sh -m /opt/ml-platform/third_party/vemlp-open-trial/third_party -s /vemlp-demo-models/model-qwen/ckpt/checkpoint/pretrain-mcore-qwen2--tp-8-pp-4 -t /vemlp-demo-models/model-qwen/qwen2-72b-instruct-to-vllm-tp8-pp4/ -tp 8 -pp 4 -pr bf16 -te true -M  -hf /vemlp-demo-models/model-qwen/qwen2-72b-instruct
步骤四:部署在线服务进行推理

4.1 复制文件

模型转换为 vllm 推理格式模型后,在 Terminal 执行下面的命令行,将训练前模型路径下的所有json后缀格式文件复制到推理模型文件下路径,和.bin文件同级。

cp -f /vemlp-demo-models/model-qwen/qwen2-72b-instruct/*.json /vemlp-demo-models/model-qwen/qwen2-72b-instruct-to-vllm-tp8-pp4/

4.2 创建推理服务

  1. 进入在线服务控制台

  2. 创建推理服务并进行资源部署。

    1. 配置私有网络。


    1. 在【服务管理】-【部署】处,点击新增部署。

      1. 填写镜像URL。
      vemlp-boe-cn-beijing.cr.volces.com/preset-images/vllm:default
      
      1. 输入入口命令。请注意 TOS 在在线服务上挂载的路径。
      python  -m vllm.entrypoints.openai.api_server  --model /vemlp-demo-models/model-qwen/qwen2-72b-instruct-to-vllm-tp8-pp4  --served-model-name qwen2  --tensor-parallel-size 8   --max-num-seqs 64
      
      1. 配置资源。最佳实践使用 1 机 8 卡 ml.pni2。
      2. 挂载 TOS 和 CFS。
      3. 配置子网与安全组。


4.3 定义请求文件 request.py 并执行

  1. 创建 request.py 文件。脚本内容示例如下。
import requests
import json
# 定义请求,更换具体的ip地址
url = "http://101.126.23.138:8000/v1/completions"
headers = {
    "Content-Type": "application/json"
}
data = {
    "model": "qwen2",
    "prompt": "San Francisco is a",
    "max_tokens": 100,
    "temperature": 0
}
# 发送POST请求
response = requests.post(url, headers=headers, data=json.dumps(data))
# 打印响应内容
print(response.json())
  1. 执行命令请求。
python request.py

结果如下。