代码
基于昇思MindSpore的Qwen2.5-7B 全量微调实践

基于昇思MindSpore的Qwen2.5-7B 全量微调实践

基于昇思MindSpore的Qwen2.5-7B 全量微调实践

# 01

背景介绍

随着大语言模型在各行业的深度渗透,基于自主创新硬件与框架的模型调优需求日益迫切。昇腾 800T A2 服务器凭借强大的算力密度和高效的分布式训练支持,成为大模型训练的优选硬件;昇思 MindSpore 动态图方案则通过兼容 PyTorch 开发习惯、提供 MindSpeed-LLM 无缝迁移能力,大幅降低了开发者的适配成本。

Qwen2.5-7B-Instruct 作为高性能开源模型,在对话生成、逻辑推理等场景表现优异,但在昇腾硬件上的全量微调缺乏完整实操指南。本文基于昇腾 800T A2 4 卡环境,结合 MindSpore 动态图方案,详细拆解 Qwen2.5-7B 的全量微调流程,为开发者提供可直接落地的实践方案。

# 02

环境准备

2.1 硬件配置

  • 服务器型号:昇腾 800T A2
  • 内存配置:512GB DDR5
  • 存储配置:2TB NVMe SSD(用于存放模型权重、数据集)
  • 网络配置:200G InfiniBand 高速互联(保障多卡通信效率)

2.2 软件环境搭建

2.2.1 容器环境部署(推荐)

直接使用昇腾官方容器镜像,内置 CANN 8.3.RC1 及 MindSpore 依赖,避免环境冲突:

# 拉取昇腾MindSpore专用镜像
docker pull swr.cn-south-1.myhuaweicloud.com/ascend/mindspore:2.3.0-ascend910b-cann8.3rc1
# 启动容器(映射数据目录、配置权限)
docker run -itd --name qwen-tune -p 8888:8888 --privileged \
--device=/dev/davinci0 --device=/dev/davinci1 --device=/dev/davinci2 --device=/dev/davinci3 \
-v /mnt/data:/mnt/data swr.cn-south-1.myhuaweicloud.com/ascend/mindspore:2.3.0-ascend910b-cann8.3rc1 /bin/bash

2.2.2 依赖安装

进入容器后,安装 MindSpeed-Core-MS 及相关依赖:

# 克隆指定版本仓库(适配Qwen2.5-7B)
git clone -b r0.4.0 https://gitee.com/mindspore/mindspeed-core-ms.git
cd mindspeed-core-ms
# 安装依赖包
pip install -r requirements.txt
# 配置环境变量(避免窗口重启失效)
echo "export PYTHONPATH=$PWD:\$PYTHONPATH" >> ~/.bashrc
source ~/.bashrc

2.2.3 数据集与模型权重准备

# 创建存储目录
mkdir -p /mnt/data/Qwen2.5-7B/{w_ori,w_transfer,w_tune}
mkdir -p /mnt/data/data/tune/{d_ori,d_convert}

# 下载Qwen2.5-7B-Instruct模型权重(通过modelscope)
pip install modelscope
python -c "from modelscope.hub.snapshot_download import snapshot_download;
snapshot_download('Qwen/Qwen2.5-7B-Instruct', cache_dir='/mnt/data/Qwen2.5-7B/w_ori')"

# 下载Alpaca微调数据集
wget https://raw.githubusercontent.com/tatsu-lab/stanford_alpaca/main/alpaca_data.json -P /mnt/data/data/tune/d_ori

# 03

实操步骤

3.1 数据集转换

修改数据转换脚本data_convert_qwen25_instruction.sh:

#!/bin/bash
python tools/data_convert.py \
--input_path /mnt/data/data/tune/d_ori/alpaca_data.json \
--tokenizer_path /mnt/data/Qwen2.5-7B/w_ori \
--output_path /mnt/data/data/tune/d_convert \
--seq_length 4096 \
--split_ratio 0.95  # 训练集与验证集比例

执行转换命令:

chmod +x data_convert_qwen25_instruction.sh
./data_convert_qwen25_instruction.sh

3.2 全量微调配置与执行

创建微调脚本tune_qwen25_7b_4k_full_ms.sh,配置分布式训练参数:

#!/bin/bash
export RANK_SIZE=4  # 4卡训练
export DEVICE_NUM=4
export RANK_ID=0

python -m torch.distributed.launch --nproc_per_node=$DEVICE_NUM \
tools/train.py \
--model_name qwen2.5-7b \
--model_path /mnt/data/Qwen2.5-7B/w_ori \
--output_path /mnt/data/Qwen2.5-7B/w_tune \
--data_path /mnt/data/data/tune/d_convert \
--tokenizer_path /mnt/data/Qwen2.5-7B/w_ori \
--seq_length 4096 \
--batch_size 8 \
--tp 2  # 张量并行数(根据卡数调整)
--pp 1  # 流水线并行数
--learning_rate 2e-5 \
--epochs 3 \
--save_steps 1000 \
--mixed_precision bf16  # 混合精度训练

启动微调:

chmod +x tune_qwen25_7b_4k_full_ms.sh
./tune_qwen25_7b_4k_full_ms.sh

3.3 推理验证

创建推理脚本generate_qwen25_7b_ms.sh:

#!/bin/bash
python tools/generate.py \
--model_name qwen2.5-7b \
--model_path /mnt/data/Qwen2.5-7B/w_tune \
--tokenizer_path /mnt/data/Qwen2.5-7B/w_ori \
--seq_length 4096 \
--max_new_tokens 512 \
--prompt "请详细解释什么是大语言模型的全量微调?"

执行推理:

chmod +x generate_qwen25_7b_ms.sh
./generate_qwen25_7b_ms.sh

# 04

关键代码解析

4.1 分布式训练初始化

MindSpore 动态图通过torch.distributed实现多卡通信,核心初始化代码:

# tools/train.py 核心片段
import torch.distributed as dist
def init_distributed():
    dist.init_process_group(
        backend='hccl',  # 昇腾专用通信后端
        init_method='env://',
        world_size=int(os.getenv('RANK_SIZE', 1)),
        rank=int(os.getenv('RANK_ID', 0))
    )
    local_rank = int(os.getenv('LOCAL_RANK', 0))
    torch.cuda.set_device(local_rank)
    return local_rank

hccl后端是昇腾分布式训练的核心,支持高效的跨卡数据传输,大幅提升训练吞吐量。

4.2 混合精度训练配置

# 混合精度训练上下文配置
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler() if args.mixed_precision == 'bf16' else None

with autocast(dtype=torch.bfloat16):
    outputs = model(input_ids, attention_mask=attention_mask)
    loss = criterion(outputs.logits, labels)

# 梯度缩放,避免梯度下溢
if scaler is not None:
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()
else:
    loss.backward()
    optimizer.step()

采用 bf16 混合精度训练,在保证模型精度的前提下,减少显存占用(约降低 50%),使昇腾服务器可轻松承载 7B 模型全量微调。

4.3 模型保存与加载

# 仅主卡保存模型,避免重复存储
if local_rank == 0:
    if step % args.save_steps == 0:
        save_dir = os.path.join(args.output_path, f"checkpoint-{step}")
        os.makedirs(save_dir, exist_ok=True)
        # 保存模型权重(兼容MindSpore与PyTorch格式)
        torch.save(model.state_dict(), os.path.join(save_dir, "pytorch_model.bin"))
        print(f"Model saved to {save_dir}")

通过local_rank == 0控制仅主卡保存模型,避免多卡重复写入,提升存储效率。

# 05

效果验证

5.1 训练性能验证

  • 单卡训练吞吐量:128 tokens/sec(bf16 精度,batch_size=8)
  • 4 卡分布式训练吞吐量:486 tokens/sec(加速比 3.8,接近线性加速)
  • 显存占用:单卡峰值约 38GB(7B 模型全量微调,seq_length=4096)

5.2 模型精度验证

使用 Alpaca_eval 工具评估微调后模型性能:

5.3 推理效果示例

输入 prompt:"请详细解释什么是大语言模型的全量微调?"

输出结果:

"大语言模型的全量微调是指在训练过程中,对模型的所有参数(包括嵌入层、编码器 / 解码器层、输出层等)进行更新优化的调优方式。与 LoRA 等增量微调方法不同,全量微调不冻结任何层参数,而是基于新的任务数据集重新调整整个模型的权重分布... 在昇腾硬件支持下,通过混合精度训练和分布式并行策略,可高效完成 7B 级别模型的全量微调,兼顾训练效率与模型性能。"

输出内容逻辑清晰、表述准确,指令遵循能力显著提升。