LLaMA-Factory +DeepSpeed 分布式多卡训练实战全解

前言

随着大模型参数量从 7B、13B 攀升至几十 B、上百 B,传统 PyTorch DDP 数据并行存在致命缺陷:每张 GPU 都会完整复制一份模型、梯度、优化器参数,显存冗余极高,小显存显卡极易 OOM 显存溢出。微软开源的 DeepSpeed 凭借ZeRO 内存分片优化,将训练状态分散到多卡 GPU 甚至 CPU 内存,大幅降低单卡显存占用,让个人多卡服务器也能训练超大模型。

本文结合线下多卡训练实测经验,从底层原理、安装部署、ZeRO Stage1/2/3 完整配置、性能实测对比、高频报错排查全方位梳理 DeepSpeed 落地要点,理清「显存占用」与「训练速度」的核心取舍逻辑,帮开发者快速选对适合自己硬件的训练方案。

LLaMA-Factory 支持通过 ‌DDP ‌、‌DeepSpeed ‌ 和 ‌FSDP‌ 三种引擎实现单机多卡及多机多卡训练,能有效突破显存瓶颈并大幅提升训练效率 。LLaMA-Factory 提供可视化 WebUI(LLaMA Board),无需编写复杂命令,图形化即可开启、配置 DeepSpeed 分布式训练,解决单卡显存不足、多卡并行加速需求。 适用场景:7B/13B/20B 大模型 LoRA 微调、单机多卡训练、显存紧张场景使用 ZeRO 分片优化。,LLaMA-Factory中做如下配置就可完成多卡训练

一、DeepSpeed 核心底层思想:CPU 内存补充 GPU 显存

DeepSpeed 核心逻辑一句话概括:GPU 显存不够,CPU 内存来兜底。 传统并行方案每张卡留存全套训练参数,而 ZeRO 会把优化器、梯度、模型权重分片分散存储,训练计算时按需在 GPU、CPU 之间传输交换。显存占用越低,CPU/GPU 数据交互越频繁,训练速度损耗越大,这是使用 DeepSpeed 永远绕不开的权衡关系。

官方原生支持两大核心能力:

  1. ZeRO-offload 卸载:将优化器、模型参数临时缓存至主机内存,释放 GPU 空间,支持更大批次、更大模型加载;
  2. 内存碎片自动管理:减少张量碎片化浪费,同等显存下支持更长上下文、更大 batch_size。

适用场景:单 / 多卡显存不足以承载完整模型,需要低成本训练大模型;仅单卡且显存充足、模型参数量较小时,不推荐使用,会徒增训练耗时。

二、DeepSpeed 两种安装方式

方式 1:极简 pip 一键安装(新手推荐)

复制代码
pip install deepspeed

方式 2:源码编译安装(适配本机 CUDA 架构,性能更好)

针对 RTX 30/40 系列(算力 8.6)编译命令:

复制代码
git clone https://github.com/microsoft/DeepSpeed.git
cd DeepSpeed
rm -rf build
TORCH_CUDA_ARCH_LIST="8.6" DS_BUILD_CPU_ADAM=1 DS_BUILD_UTILS=1 pip install . \
--global-option="build_ext" --global-option="-j8" --no-cache -v \
--disable-pip-version-check 2>&1 | tee build.log

配套 HuggingFace 集成安装

Transformers 原生兼容 DeepSpeed,可直接安装集成包,训练时无需额外适配代码:

复制代码
pip install transformers[deepspeed]

三、ZeRO 分片技术核心原理:分片替代复制

传统 DDP:所有 GPU 复制全套优化器状态+梯度+模型参数,显存成倍冗余。 ZeRO(Zero Redundancy Optimizer):分片存储而非完整复制,把三类训练状态拆分至多设备,消除显存冗余,分三个渐进优化阶段:

表格

ZeRO 阶段 分片对象 显存降低幅度 速度损耗 适用硬件
Stage1 仅优化器状态分片 小幅降低 几乎无损耗 8×24G 充足多卡、追求速度优先
Stage2 优化器 + 梯度同时分片 中等降低 轻微损耗 4×24G 均衡多卡,工程最常用
Stage3 优化器 + 梯度 + 模型权重全分片 大幅降低 损耗极大 单 / 双卡小显存、13B/20B 超大模型

关键补充:ZeRO-Infinity(Stage3 进阶)

在 Stage3 基础上支持把参数卸载到 NVMe 固态硬盘,进一步压榨内存空间,适合上百 B 超大规模模型,普通 7B/13B 微调无需启用。

四、ZeRO 各阶段完整可复用配置文件

所有配置中重复训练参数(学习率调度、混合精度)统一设为auto,会自动读取 Hugging Face Trainer、LLaMA Factory 训练参数,避免参数冲突。

4.1 ZeRO Stage2 通用配置(生产首选均衡方案)

兼顾显存释放与训练速度,绝大多数单机多卡微调优先选用:

json

复制代码
{
    "bfloat16": {
        "enabled": "auto"
    },
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },
    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },
    "zero_optimization": {
        "stage": 2,
        "offload_optimizer": {
            "device": "cpu",
            "pin_memory": true
        },
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": 2e8,
        "contiguous_gradients": true
    },
    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "steps_per_print": 100000
}

核心参数说明:

  1. offload_optimizer.device: cpu:优化器存放至内存,释放显存;pin_memory开启页锁定内存,加速 CPU/GPU 数据传输;
  2. overlap_comm:通信与计算并行,数值越大通信越快、显存占用越高,按需平衡;
  3. reduce_bucket_size:梯度聚合分片大小,自动适配模型尺寸无需手动修改。

4.2 ZeRO Stage3 超大显存节约配置

模型过大、单卡无法加载完整权重时使用,速度会明显下降:

复制代码
{
    "bfloat16": {
        "enabled": "auto"
    },
    "fp16": {
        "enabled": "auto",
        "loss_scale": 0,
        "loss_scale_window": 1000,
        "initial_scale_power": 16,
        "hysteresis": 2,
        "min_loss_scale": 1
    },
    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },
    "scheduler": {
        "type": "WarmupLR",
        "params": {
            "warmup_min_lr": "auto",
            "warmup_max_lr": "auto",
            "warmup_num_steps": "auto"
        }
    },
    "zero_optimization": {
        "stage": 3,
        "offload_optimizer": {
            "device": "cpu",
            "pin_memory": true
        },
        "offload_param": {
            "device": "cpu",
            "pin_memory": true
        },
        "overlap_comm": true,
        "contiguous_gradients": true,
        "sub_group_size": 1e9,
        "reduce_bucket_size": "auto",
        "stage3_prefetch_bucket_size": "auto",
        "stage3_param_persistence_threshold": "auto",
        "stage3_max_live_parameters": 1e9,
        "stage3_max_reuse_distance": 1e9,
        "stage3_gather_fp16_weights_on_model_save": true
    },
    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "steps_per_print": 100000,
    "wall_clock_breakdown": false
}

新增offload_param:将模型权重也卸载至内存,显存占用达到最低,代价是大量数据交换,训练速度大幅降低。

4.3 启动训练命令模板

复制代码
# 指定GPU数量、端口、ds配置文件
deepspeed --master_port 29500 --num_gpus=4 train.py \
--deepspeed ds_zero2_config.json
  • --master_port:分布式通信端口,多任务并行需修改避免占用;
  • --num_gpus:使用显卡数量,不填默认调用全部 GPU。

五、显存占用预估工具(训练前提前避坑)

DeepSpeed 提供内置预估函数,提前计算 ZeRO-3 模式下 CPU、内存占用,避免内存不足进程被杀:

复制代码
from transformers import AutoModel
from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live

# 替换你的基座模型
model = AutoModel.from_pretrained("Qwen2.5-7B-Instruct")
# 单节点4卡预估
estimate_zero3_model_states_mem_needs_all_live(model, num_gpus_per_node=4, num_nodes=1)

使用原则:能不用 ZeRO 就不用;显存充足优先 Stage2,万不得已再选用 Stage3。

六、线下实测:Stage2 / Stage3 性能对比

测试环境:单卡 RTX4090 24G,7B 模型 LoRA 微调,batch_size=2

  1. ZeRO Stage2 实测数据
  • 原始显存占用:20513MiB → 开启后 17349MiB,释放约 3GB 显存;
  • 训练速度:1.3 iter/s → 0.77 iter/s,速度下降约 40%;
  • 痛点:释放显存有限,不足以提升 batch_size,总训练时长变长。
  1. ZeRO Stage3 实测数据 显存占用可降低 50% 以上,但速度损耗极其严重:原本 6 小时训练任务,开启后耗时超 48 小时,日常微调不推荐使用。

七、DeepSpeed 常见踩坑与完整解决方案

1. 进程无报错直接被系统杀死

原因:offload 后大量参数存入系统内存,物理内存不足,系统 OOM Killer 终止进程。 解决:

  1. 先用预估脚本计算内存需求,free -h查看空闲内存;
  2. 减少 offload 范围,优先只卸载优化器,关闭offload_param
  3. 增加机器物理内存或更换多机分布式训练。

2. 训练 loss 持续变为 NaN

原因:混合精度缩放值不合适、学习率过高、梯度爆炸。 解决:

  1. 配置开启gradient_clipping: 1.0梯度裁剪;
  2. 降低学习率,微调推荐 5e-05 及以下;
  3. FP16 模式调大initial_scale_power,优先使用 BF16 训练。

3. ZeRO offload 模式无法自定义分层学习率

DeepSpeed 内置 AdamW 优化器会接管参数更新逻辑,自定义优化器必须同时实现 CPU、GPU 两套版本,开发成本极高。 解决:LoRA 微调无需分层学习可直接使用内置优化器;需要自定义时放弃 offload,改用纯 GPU ZeRO Stage1。

4. VS Code 无法断点调试 DeepSpeed 进程

DeepSpeed 分布式进程通信机制不兼容 VS Code 调试插件,官方无适配方案。 解决:调试阶段关闭 DeepSpeed,单卡原生 Trainer 验证逻辑,正式训练再启用 ZeRO。

5. 训练控制台无输出、GPU 满载看不到进度

多卡分片通信会屏蔽部分日志输出,仅 GPU 利用率无法判断训练状态。 解决:调小steps_per_print,每几十步打印一次 loss,监控训练进度。

八、DeepSpeed 推理补充说明

超大模型推理同样可复用 ZeRO Stage3 配置,推理阶段会自动忽略 optimizer、学习率等训练参数,仅使用分片加载逻辑,适合单卡低显存机器运行大模型推理。进阶 ZeRO-Infinity 支持 SSD 分担内存,适合超大规模离线推理场景。

九、落地选型总结(实操建议)

  1. 硬件充足(4/8×24G)、追求训练速度:选用 ZeRO Stage2,仅卸载优化器,速度损耗可控;
  2. 显存紧张、单 / 双卡跑 13B/20B 模型:临时使用 ZeRO Stage3,项目长期不推荐;
  3. LoRA 轻量化微调:优先 Stage2,大部分场景足够释放显存;
  4. 硬件富余、单卡完全装下模型:直接原生 DDP,不启用 DeepSpeed,避免速度损耗;
  5. 内存资源有限时,严禁同时开启offload_optimizeroffload_param,极易触发系统杀进程。

一、前置准备

1. 安装 DeepSpeed 依赖

复制代码
pip install deepspeed

2. 准备 DeepSpeed 配置文件 ds_config.json

项目 examples/deepspeed/ 目录内置官方模板:

  • ds_z0_config.json ZeRO-0(不做分片,仅多卡数据并行)
  • ds_z2_config.json ZeRO-2(优化器 + 梯度分片,均衡速度 / 显存,4 卡 24G 首选)
  • ds_z3_config.json ZeRO-3(权重全分片,显存占用最低,适合单 / 双卡跑超大模型)LLaMA Fact...
通用 ZeRO-2 配置(生产推荐)
复制代码
{
    "bfloat16": {"enabled": "auto"},
    "fp16": {"enabled": "auto"},
    "optimizer": {
        "type": "AdamW",
        "params": {
            "lr": "auto",
            "betas": "auto",
            "eps": "auto",
            "weight_decay": "auto"
        }
    },
    "scheduler": {"type": "WarmupLR", "params": {"warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto"}},
    "zero_optimization": {
        "stage": 2,
        "offload_optimizer": {"device": "cpu", "pin_memory": true},
        "allgather_partitions": true,
        "allgather_bucket_size": 2e8,
        "overlap_comm": true,
        "reduce_scatter": true,
        "reduce_bucket_size": 2e8,
        "contiguous_gradients": true
    },
    "gradient_accumulation_steps": "auto",
    "gradient_clipping": "auto",
    "train_batch_size": "auto",
    "train_micro_batch_size_per_gpu": "auto",
    "steps_per_print": 100
}

二、启动 LLaMA-Factory WebUI

1. 指定可用显卡(多卡必须配置)

复制代码
# 限定使用0、1、2、3四张显卡
export CUDA_VISIBLE_DEVICES=0,1,2,3
# 启动可视化微调面板
llamafactory-cli webui

访问地址:http://localhost:7860

三、WebUI 界面开启 DeepSpeed 分步操作

步骤 1:进入「训练」标签页,基础参数配置

  1. 模型设置
    • model_name_or_path:本地基座模型完整路径
    • finetuning_type:LoRA(轻量化微调)
    • template:匹配基座模型对话模板(qwen/llama3 等)
  2. 数据集设置
    • dataset_dir:数据集根目录
    • datasetdataset_info.json 注册的数据集名称
  3. 训练超参 per_device_train_batch_sizelearning_ratenum_train_epochs 按需填写

步骤 2:找到高级设置「DeepSpeed」选项(核心)

页面下方高级加速 / 分布式 区域存在 deepspeed 下拉输入框,两种配置方式:

方式 A:选择内置 ds 模板(最简单,新手推荐)

下拉菜单内置预设配置:ds_z0ds_z2ds_z3ds_z2_offload 等,直接选中即可自动加载对应 json 配置文件,无需手动填写路径CSDN博...。

方式 B:手动填写自定义配置文件绝对路径

若修改过自定义 ds_config.json,直接填入文件完整路径,示例:

复制代码
/home/xxx/LLaMA-Factory/examples/deepspeed/ds_z2_config.json

步骤 3:确认精度与混合精度

WebUI 中 bf16 勾选开启,与 DeepSpeed 配置内 bfloat16.enabled="auto" 保持兼容,避免 loss 出现 NaN。

步骤 4:点击「开始训练」自动启用多卡 DeepSpeed

WebUI 底层自动封装 FORCE_TORCHRUN=1 分布式启动指令,无需手动写 bash 脚本,自动根据显卡数量执行多卡训练LLaMA Fact...。

四、ZeRO 阶段选型界面配置建议

表格

硬件环境 WebUI 选择 DeepSpeed 模板 适用场景
8×24G 充足多卡 ds_z0 / ds_z2 追求训练速度优先
4×24G 均衡多卡 ds_z2(推荐) 显存释放与速度平衡,日常 LoRA 微调首选
单 / 双卡 24G,跑 13B/20B 大模型 ds_z3 最大限度节省显存,代价是训练速度变慢

五、常见界面报错与解决

1. 报错:找不到 deepspeed 配置文件

  • 原因:填写的文件路径错误、文件名拼写错误;使用内置模板但文件缺失
  • 解决:复制配置文件绝对路径;使用官方内置模板,不要自定义文件名

2. 多卡训练显存负载不均衡

  • 原因:ZeRO stage 选择错误,通信桶参数不匹配
  • 解决:4 卡优先选择 ds_z2;不推荐直接使用 ds_z3 日常微调

3. 训练 loss 出现 NaN

  • 原因:混合精度冲突、学习率过高
  • 解决:WebUI 勾选 bf16,降低学习率至 5e-5 以内,开启梯度裁剪

4. 进程被系统 OOM 杀死

  • 原因:ZeRO-3 开启 cpu 卸载,占用大量系统内存
  • 解决:改用 ZeRO-2;关闭 offload_param 仅保留优化器卸载

六、命令行 YAML 配套参考(WebUI 导出配置)

WebUI 训练完成后可导出 yaml 训练配置,DeepSpeed 核心片段:

复制代码
stage: sft
do_train: true
model_name_or_path: /root/model/Qwen2.5-7B-Instruct
finetuning_type: lora
template: qwen
dataset: my_train_data
cutoff_len: 1024
per_device_train_batch_size: 4
learning_rate: 5e-5
num_train_epochs: 10
# DeepSpeed 核心配置
trainer:
  type: deepspeed
deepspeed: examples/deepspeed/ds_z2_config.json

如需离线命令行训练,直接执行:

复制代码
FORCE_TORCHRUN=1 llamafactory-cli train train_config.yaml

七、落地最佳实践

  1. 优先使用 WebUI 内置 ds_z2 模板,适配绝大多数多卡微调场景;
  2. 超大模型(13B/20B)、单卡显存不足时,再选用 ds_z3;
  3. 启动 WebUI 前务必通过 CUDA_VISIBLE_DEVICES 限定显卡,防止占用全部 GPU;
  4. 训练前小规模样本测试流程,确认 DeepSpeed 正常启动、无显存溢出,再全量训练。
相关推荐
稚南城才子,乌衣巷风流2 小时前
RabbitMQ 消息队列:从入门到实战
分布式·rabbitmq
Database_Cool_15 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
肥胖小羊1 天前
解决企业微信 AccessToken 刷新并发冲突的分布式锁机制实践
分布式·企业微信
风中凌乱2 天前
kafka新版本集群的安装与部署
分布式·kafka
SLD_Allen2 天前
大规模分布式AI训练基础设施
人工智能·分布式·模型训练
富士康质检员张全蛋2 天前
Kafka的操作-消费的详情
分布式·kafka
昕光xg2 天前
Istio笔记04-基于Jaeger的分布式链路追踪
笔记·分布式·istio
Benjamin℡3 天前
Zookeeper(一)搭建单体和集群服务以及Zookeeper客户端
分布式·zookeeper·云原生
wWYy.3 天前
分布式:数据复制
分布式