训练 v2 · LLaMA-Factory / DeepSpeed / Megatron 深度调参手册
本篇是训练栈的"参数级"操作手册:LLaMA-Factory yaml 字段、DeepSpeed config 每个 key、Megatron 3D 并行调参原则。适合已经跑过一次 SFT、需要进一步压榨显存或扩到多机的工程师。
0. 三大栈定位 — 不要混用
| 栈 | 抽象层 | 适用场景 | 不适合 |
|---|---|---|---|
| LLaMA-Factory | YAML 驱动的高层封装 | 7B-72B 范围、单/双机、SFT/DPO/PPO 标准任务 | 自定义 model 结构、超大规模 100B+ |
| DeepSpeed | 训练引擎 + 分布式策略 | 显存 OOM、ZeRO 优化、参数/优化器 sharding | 模型并行(TP/PP 不擅长) |
| Megatron-LM | 原生 3D 并行(TP+PP+DP) | 100B+ 超大模型、千卡集群、从零预训练 | 单机小模型(overkill) |
组合策略:
- 单机 1-8 卡,7B-72B SFT/DPO → LLaMA-Factory(内部走 accelerate/deepspeed)
- 多机 4-32 卡,70B+ continued pretrain → LLaMA-Factory + DeepSpeed ZeRO-3
- 32+ 卡,100B+ 从零训 → Megatron-LM(或 Megatron-DeepSpeed 混合)
1. LLaMA-Factory YAML 完全手册
LLaMA-Factory 用 llamafactory-cli train config.yaml 单文件驱动,yaml 字段对应 HuggingFace Trainer + PEFT + TRL 的所有重要参数。下面按模块讲清。
1.1 完整字段清单(按出现顺序)
A. 模型与方法
| 字段 | 类型 | 默认/示例 | 说明 |
|---|---|---|---|
model_name_or_path | str | Qwen/Qwen2.5-7B-Instruct | HF Hub ID 或本地路径,首次会从 HF 下载到 ~/.cache/huggingface |
adapter_name_or_path | str | saves/qwen-lora | 加载已有 LoRA adapter(continued LoRA / 加载之前训的) |
model_revision | str | main | HF git revision,固定到特定 commit 防止上游更新破坏复现 |
quantization_bit | int | 4 / 8 / null | 模型推理/训练时是否走 bitsandbytes 量化,4=QLoRA |
quantization_method | str | bitsandbytes / hqq / eetq | 配套 quantization_bit 选择量化算法 |
template | str | qwen / llama3 / chatml / vicuna | 必填,选择 chat template,与模型匹配 |
flash_attn | str | auto / fa2 / disabled | flash-attention-2 加速,推荐 auto |
rope_scaling | str | linear / dynamic / null | RoPE 长上下文扩展,长文档训练用 |
shift_attn | bool | false | LongLoRA shift short attention,长上下文专用 |
B. 任务类型(stage)
| 字段 | 取值 | 说明 |
|---|---|---|
stage | pt | Pre-Training,继续预训练 |
sft | Supervised Fine-Tuning,主流微调 | |
rm | Reward Modeling,训 reward model 给 PPO 用 | |
ppo | PPO,RLHF | |
dpo | Direct Preference Optimization,绕过 reward model | |
kto | Kahneman-Tversky Optimization,单边数据 DPO | |
orpo | Odds-Ratio Preference Optimization,单阶段 RLHF | |
simpo | Simple Preference Optimization,无 reference model | |
do_train | bool | true |
finetuning_type | full / lora / freeze | 全参 / LoRA / 冻结部分层 |
C. LoRA / PEFT
| 字段 | 默认 | 说明 |
|---|---|---|
lora_target | all(推荐)/ q_proj,v_proj | 应用 LoRA 的 module 名,all = 所有 linear |
lora_rank | 8(LoRA), 16-64(DoRA) | rank 越大表达力越强,显存/参数也越大 |
lora_alpha | 16(一般 = 2× rank) | scaling factor,loraB = lora_alpha/rank |
lora_dropout | 0.0 | dropout rate |
use_rslora | false | Rank-Stabilized LoRA,大 rank 时更稳 |
use_dora | false | DoRA = decomposed LoRA,接近 full FT 效果 |
use_galore | false | GaLore = 梯度低秩投影,显存进一步降 |
pissa_init | false | PiSSA initialization,快收敛 |
loraplus_lr_ratio | null / 16 | LoRA+ 给 B 矩阵更大学习率 |
create_new_adapter | false | 是否新建 adapter(继续训设 false) |
D. 数据集
| 字段 | 说明 |
|---|---|
dataset | alpaca_zh,sharegpt_zh,data/dataset_info.json 里登记的 name,多个用逗号拼 |
dataset_dir | data(default),数据集目录 |
cutoff_len | 1024,单样本 token 上限,超出截断 |
max_samples | null / 1000,限制样本数,debug 用 |
overwrite_cache | false,强制重新 tokenize |
preprocessing_num_workers | 16,tokenize 并行进程数 |
tokenized_path | null,缓存 tokenized 数据集路径,加速二次启动 |
train_on_prompt | false,是否对 user 部分也算 loss(默认只算 assistant) |
mask_history | false,多轮对话只对最后一轮算 loss |
streaming | false,大数据集流式加载,不全量 tokenize 进内存 |
packing | false,多 sample 拼接到 cutoff_len 提高利用率 |
neat_packing | false,智能 packing 不破坏 attention 边界 |
E. 输出与日志
| 字段 | 说明 |
|---|---|
output_dir | checkpoint 与产物目录,例 saves/qwen-lora |
logging_steps / save_steps | log / ckpt 间隔,默认 10 / 500 |
save_total_limit | 最多保留几个 checkpoint(默认 3) |
plot_loss | 训完画 loss 曲线 |
report_to / run_name | 实验跟踪后端(none / wandb / tensorboard)+ 实验名 |
F. 训练超参数
| 字段 | 默认/示例 | 说明 |
|---|---|---|
per_device_train_batch_size | 1-4 | 单卡 micro batch |
gradient_accumulation_steps | 8-16 | 梯度累积,等效 global batch = N × gpus × accum |
learning_rate | 5e-5(LoRA)/ 2e-5(full) | LoRA 用 5e-5,full FT 更小 |
lr_scheduler_type | cosine / linear / constant | cosine 最常用 |
warmup_ratio | 0.1 | 前 10% step warmup |
num_train_epochs | 3.0 | epoch 数 |
max_steps | -1 / 20 | 设了优先于 epochs(debug 用) |
optim | adamw_torch / adamw_8bit / paged_adamw_8bit | 8bit Optimizer 省显存 |
weight_decay | 0.0 | L2 正则 |
max_grad_norm | 1.0 | 梯度裁剪上限 |
bf16 | true(A100+)/ false | BF16 训练 |
fp16 | false | FP16 训练(老卡用) |
seed | 42 | 复现 |
gradient_checkpointing | true | 显存换算力,显存吃紧必开 |
G. 分布式 / DeepSpeed
| 字段 | 说明 |
|---|---|
deepspeed | examples/deepspeed/ds_z3_config.json,DeepSpeed config 路径,详见第 2 节 |
ddp_find_unused_parameters | false,DDP 同步未用参数,LoRA 时常需 false |
ddp_timeout | 180000000,NCCL 通信超时,长 ckpt 时要调大 |
H. 评估 / 验证
| 字段 | 说明 |
|---|---|
val_size | 切多少做验证集(默认 0.1) |
per_device_eval_batch_size | eval batch size |
evaluation_strategy / eval_steps | 何时跑 eval(steps / epoch / no)+ step 间隔 |
load_best_model_at_end | 训完加载验证集 best ckpt |
I. DPO/PPO/RM 特有
| 字段 | 适用 | 说明 |
|---|---|---|
pref_beta | DPO/ORPO | KL 散度系数,越大越保守 |
pref_ftx | DPO | SFT loss 混合系数 |
pref_loss | sigmoid / hinge / ipo / kto_pair | DPO 变种 loss 选择 |
dpo_ftx | 0.1 | DPO + SFT joint loss 系数 |
reward_model | path | PPO 用的 reward model |
reward_model_type | lora / full | reward model 加载方式 |
ppo_buffer_size | 1 | PPO rollout buffer |
ppo_epochs | 4 | PPO 内循环 epoch |
ppo_score_norm | false | 奖励标准化 |
1.2 最简完整 yaml 示例(SFT LoRA)
# === 1. 模型 ===
model_name_or_path: Qwen/Qwen2.5-3B-Instruct
template: qwen
flash_attn: auto
# === 2. 任务 ===
stage: sft
do_train: true
finetuning_type: lora
# === 3. LoRA ===
lora_target: all
lora_rank: 8
lora_alpha: 16
lora_dropout: 0.05
# === 4. 数据 ===
dataset: alpaca_zh_demo
dataset_dir: data
cutoff_len: 512
max_samples: 50
overwrite_cache: true
preprocessing_num_workers: 4
template: qwen
# === 5. 输出 ===
output_dir: /opt/training/saves/qwen-3b-sft-mini
logging_steps: 1
save_steps: 50
plot_loss: true
overwrite_output_dir: true
# === 6. 训练 ===
per_device_train_batch_size: 1
gradient_accumulation_steps: 4
learning_rate: 5.0e-5
lr_scheduler_type: cosine
warmup_ratio: 0.1
num_train_epochs: 1.0
max_steps: 20 # 最简测试只跑 20 步
bf16: true
gradient_checkpointing: true
seed: 42
# === 7. 评估 ===
val_size: 0.0 # 50 样本太小,不切验证集
1.3 启动命令
llamafactory-cli train /opt/training/qwen_lora_sft.yaml
2. DeepSpeed 配置每参数详解
DeepSpeed 的 config 是个 JSON,常见 ZeRO Stage 1/2/3 + Offload + Mixed Precision。下面是生产级 ZeRO-3 完整 config,每个 key 都讲。
2.1 ZeRO-3 完整 config 注解
{
// ===== 1. Mixed precision =====
"bf16": {
"enabled": "auto" // auto = 根据 trainer flag 决定; A100+ 推荐 bf16
},
"fp16": {
"enabled": "auto",
"loss_scale": 0, // 0 = dynamic loss scaling, fp16 OOM 时降低
"loss_scale_window": 1000,
"initial_scale_power": 16,
"hysteresis": 2,
"min_loss_scale": 1
},
// ===== 2. Optimizer (DeepSpeed 接管) =====
"optimizer": {
"type": "AdamW",
"params": {
"lr": "auto",
"betas": "auto", // [0.9, 0.999] 常用
"eps": "auto",
"weight_decay":"auto"
}
},
// ===== 3. Scheduler =====
"scheduler": {
"type": "WarmupDecayLR",
"params": {
"warmup_min_lr": "auto",
"warmup_max_lr": "auto",
"warmup_num_steps": "auto",
"total_num_steps": "auto"
}
},
// ===== 4. ZeRO 核心 =====
"zero_optimization": {
"stage": 3, // 1=优化器分片, 2=+梯度分片, 3=+参数分片
"offload_optimizer": { // 优化器状态 offload 到 CPU
"device": "cpu", // "cpu" / "nvme" / "none"
"pin_memory": true // pinned memory 加速 H2D
},
"offload_param": { // 参数 offload 到 CPU(只 stage 3)
"device": "cpu",
"pin_memory": true
},
"overlap_comm": true, // 通信与计算重叠,小幅加速
"contiguous_gradients": true, // 梯度连续存储,反向传播更快
"sub_group_size": 1e9, // 参数分组大小,超过这个会再细分
"reduce_bucket_size": "auto", // all-reduce 桶大小
"stage3_prefetch_bucket_size": "auto", // 参数预取桶
"stage3_param_persistence_threshold": "auto", // 小参数保留在 GPU 不分片
"stage3_max_live_parameters": 1e9, // GPU 同时活的参数上限
"stage3_max_reuse_distance": 1e9, // 参数复用距离阈值
"stage3_gather_16bit_weights_on_model_save": true // ckpt 保存时聚合 weights
},
// ===== 5. Batch =====
"train_batch_size": "auto", // = micro × accum × dp_world
"train_micro_batch_size_per_gpu": "auto",
"gradient_accumulation_steps": "auto",
"gradient_clipping": "auto", // = max_grad_norm
// ===== 6. Activation Checkpointing =====
"activation_checkpointing": {
"partition_activations": true, // activation 也分片(超大模型)
"cpu_checkpointing": false, // activation offload 到 CPU(慢但省显存)
"contiguous_memory_optimization": false,
"number_checkpoints": null,
"synchronize_checkpoint_boundary": false,
"profile": false
},
// ===== 7. 通信 =====
"steps_per_print": 10, // log 间隔
"wall_clock_breakdown": false, // detailed timer (debug 用)
"communication_data_type": "auto" // bf16 / fp16
}
2.2 三种 ZeRO Stage 的选择决策
| Stage | 显存优化 | 通信开销 | 何时用 |
|---|---|---|---|
| ZeRO-0(= 普通 DDP) | 0 | 最低 | 模型小,显存够,极致速度 |
| ZeRO-1 | 优化器状态分片(~4× 缩) | +20% | 显存有点紧,要保速度 |
| ZeRO-2 | + 梯度分片(~8× 缩) | +40% | 大多数 7B-70B 单机训练 |
| ZeRO-3 | + 参数分片(无上限) | +60-100% | 70B+ 多机,或 7B 单卡 24GB |
| ZeRO-3 + CPU offload | + 优化器/参数 CPU | 巨大 | 32GB 单卡训 70B 的极限 |
| ZeRO-3 + NVMe offload | + 优化器 NVMe | 灾难性 | 试图在 RTX 3090 上训 70B(玩具级) |
2.3 显存预算计算公式(超重要)
单卡显存占用 ≈ (P/N) × [2 (BF16 weights) + 2 (BF16 gradients) + 12 (Adam states)]
+ Activation + KV cache
+ Communication buffers
其中:
P = 模型参数量(Billion)
N = ZeRO 分片数(stage 3 时 = world_size)
例: 70B 模型, BF16, 8 卡 ZeRO-3
权重 + 梯度 + Adam ≈ 70B × 16 bytes / 8 = 140 GB / 8 = 17.5 GB/卡
Activation (rank+ckpt) ≈ 5-10 GB/卡
合计 ≈ 25-30 GB/卡 — A800-40GB 装得下
2.4 LLaMA-Factory 内置 DeepSpeed 模板
LLaMA-Factory 自带几份开箱即用的 DeepSpeed config:
examples/deepspeed/ds_z0_config.json # ZeRO-0
examples/deepspeed/ds_z2_config.json # ZeRO-2
examples/deepspeed/ds_z2_offload_config.json # ZeRO-2 + CPU optim offload
examples/deepspeed/ds_z3_config.json # ZeRO-3
examples/deepspeed/ds_z3_offload_config.json # ZeRO-3 + CPU param+optim offload
直接在 yaml 里指定:deepspeed: examples/deepspeed/ds_z3_config.json
3. Megatron-LM 3D 并行调参手册
Megatron 是 NVIDIA 出品的"原生"超大模型训练框架,核心创新是 3D 并行:Data + Tensor + Pipeline。
3.1 3D 并行三维度
| 维度 | 简写 | 切分对象 | 跨设备通信 | 关键参数 |
|---|---|---|---|---|
| Data Parallel | DP | 把 batch 切分到 N 个 replica,each holds 完整模型 | all-reduce 梯度 | --data-parallel-size N |
| Tensor Parallel | TP | 切单层的 weight 矩阵(列切 / 行切) | all-reduce activation | --tensor-model-parallel-size N |
| Pipeline Parallel | PP | 按 layer 切分,GPU 0 装 layer 0-15,GPU 1 装 16-31... | p2p send/recv activation | --pipeline-model-parallel-size N |
公式:TP × PP × DP = total_gpus
3.2 调参原则
A. 何时用哪个并行
| 情况 | 选择 |
|---|---|
| 模型放得下单卡 | DP only(最快) |
| 单卡放不下,节点内(NVLink) | 加 TP(NVLink 带宽 600+ GB/s,TP 通信吃得消) |
| 单卡放不下,跨节点(IB/RDMA) | 加 PP(p2p 通信少,跨节点便宜) |
| 极致大模型(175B+) | TP + PP + DP 同时上 |
B. TP 大小的选择
- TP 通信量大,几乎只能限制在单节点内(同一台 8 卡机)
- A100/H100 节点常用 TP=8(整机)
- A800(NVLink 减半)推荐 TP=4
- 推荐:
TP = min(节点内卡数, head_count_per_layer)(TP 必须整除 num_attention_heads)
C. PP 大小的选择
- PP 引入 bubble(气泡),有效率损失
bubble_ratio = (PP-1) / (micro_batches_per_pipeline_step)- 推荐 micro batches > 4 × PP,降低 bubble
- 一般 PP ∈ {2, 4, 8, 16}
D. DP 大小的选择
- DP = total / (TP × PP)
- DP 越大,全局 batch 越大,梯度越稳但收敛性需要调 lr scaling
3.3 典型配置例
例 1:单机 8×A100 训 13B
# 13B 单卡放得下,但训练显存要 2× 参数,所以走 TP=2 + DP=4
python pretrain_gpt.py \
--tensor-model-parallel-size 2 \
--pipeline-model-parallel-size 1 \
--data-parallel-size 4 \
--micro-batch-size 2 \
--global-batch-size 256 \
...
例 2:8 机 64×A100 训 70B
# 70B BF16 模型 weight 140GB,要靠 TP+PP
python pretrain_gpt.py \
--tensor-model-parallel-size 8 \ # 节点内 TP
--pipeline-model-parallel-size 4 \ # 4 段 pipeline (16 卡 / 段)
--data-parallel-size 2 \ # = 64 / (8 × 4)
--micro-batch-size 1 \
--global-batch-size 1024 \
--num-layers-per-virtual-pipeline-stage 4 \ # interleaved schedule 减小 bubble
...
例 3:32 机 256×H100 训 175B
python pretrain_gpt.py \
--tensor-model-parallel-size 8 \
--pipeline-model-parallel-size 8 \
--data-parallel-size 4 \
--sequence-parallel \ # 序列维度也切, 进一步省显存
--use-distributed-optimizer \ # ZeRO-1 风格
--recompute-granularity selective \ # 选择性 activation recompute
--recompute-method uniform \
--micro-batch-size 1 \
--global-batch-size 2048 \
...
3.4 Megatron 关键参数手册
| 类别 | 参数 | 作用 |
|---|---|---|
| 并行 | --tensor-model-parallel-size | TP |
--pipeline-model-parallel-size | PP | |
--context-parallel-size | 长上下文序列并行(Megatron 0.7+) | |
--expert-model-parallel-size | MoE Expert 并行 | |
--sequence-parallel | 序列维度切分,降 activation 显存 | |
--use-distributed-optimizer | 类似 ZeRO-1 | |
| Batch | --micro-batch-size / --global-batch-size | micro × DP × pipeline_micro_batches = global |
| 显存 | --recompute-granularity full/selective | activation checkpointing |
--recompute-method uniform/block + --recompute-num-layers N | 重算策略与层数 | |
| 通信 | --overlap-grad-reduce / --overlap-param-gather | reduce/gather 与计算重叠 |
| 模型 | --num-layers / --hidden-size / --ffn-hidden-size / --seq-length | 模型结构 |
--num-attention-heads | attention head 数(必须能被 TP 整除) | |
| 训练 | --lr / --min-lr / --lr-warmup-iters / --lr-decay-style | 学习率与 warmup/decay |
--train-iters | 总迭代步数 | |
| 数据 | --data-path / --tokenizer-type / --data-impl mmap | 数据路径与 tokenizer,mmap 加速 |
| ckpt | --save / --load / --save-interval / --ckpt-format torch_dist | 路径、间隔、分布式 ckpt |
3.5 Megatron 调参三大坑
坑 1:TP 大小必须整除 attention heads
num_attention_heads = 32
TP=8 → 32/8=4 heads/rank OK
TP=16 → 32/16=2 heads/rank OK
TP=12 → 32/12 不整除 报错
坑 2:PP bubble 把利用率打骨折
PP=8, micro_batches=8
bubble_ratio = (8-1) / 8 = 87.5% 利用率
要 micro_batches >= 4 × PP, 即 32 才能接受
坑 3:ZeRO + TP/PP 不能直接组合
DeepSpeed ZeRO 是参数分片,Megatron TP 是 weight 切片 — 两者对模型参数的"持有方式"不一样。要混用,必须用 Megatron-DeepSpeed(Microsoft 维护的特殊分支)。
4. LLaMA-Factory 最简 SFT 走查(Qwen2.5-3B + LoRA)
用一个最小可跑的样例把链路串起来:yaml → 数据 → 启动 → 产物。20 步训练不可能真正学到东西,目的是验证 LLaMA-Factory 链路通畅、yaml 字段被正确消费、checkpoint 能落盘、loss 形态符合 cosine schedule 预期。生产 SFT 至少 1000-10000 steps,LoRA rank=16-64,数据量 1K-100K 级别。
4.1 环境与版本组合
python3 -m venv /opt/training/venv
source /opt/training/venv/bin/activate
pip install -q torch==2.5.1 --index-url https://download.pytorch.org/whl/cu121
pip install -q transformers peft datasets accelerate trl llamafactory
参考版本组合:LLaMA-Factory 0.9.3 / transformers 4.52 / peft 0.15 / torch 2.5.1+cu121。
4.2 数据集目录
data/
├── dataset_info.json # 数据集 registry(见附录 A)
└── alpaca_zh_demo.json # 50 条样本
4.3 启动命令
export HF_HOME=/opt/hf-cache
export HF_HUB_OFFLINE=1
llamafactory-cli train qwen_lora_sft.yaml 2>&1 | tee train.log
4.4 启动 log 关键节点
LoRA wiring 阶段会打印:
Fine-tuning method: LoRA
Found linear modules: k_proj,gate_proj,up_proj,q_proj,v_proj,o_proj,down_proj
trainable params: 14,966,784 || all params: 3,100,905,472 || trainable%: 0.4827
Gradient Accumulation steps = 4
Total optimization steps = 20
关键观察:lora_target: all 自动展开成 7 个 linear module(q/k/v/o + gate/up/down),trainable = 14.97M ≈ 3.1B 的 0.48%。
4.5 量化指标(A800-40GB 跑通参考)
| 指标 | 值 | 解读 |
|---|---|---|
| 模型加载耗时 | 17 s | 二次启动走 mmap 可降到 < 5s |
| 训练耗时 | 29.69 s / 20 steps | 单步 ~1.5s |
| Trainable % | 0.48 %(14.97M / 3.10B) | LoRA rank=8 + 7 targets |
| LR schedule | cosine,0 → 5e-5 → 3.8e-7 | warmup 2 步 + cosine decay |
| 显存峰值 | 20 GB | 3B BF16(6) + grad(6) + optim(7) + activation,已开 gradient_ckpt |
4.6 输出产物
关键文件:
adapter_model.safetensors 58 MB ← LoRA 权重(base 3B = 6 GB,约 1%)
adapter_config.json ← rank/alpha/target_modules
trainer_state.json ← 可 resume 的训练状态
trainer_log.jsonl ← 每 step JSONL log
training_loss.png ← 自动绘制 loss 曲线
checkpoint-20/ ← 末次 checkpoint
adapter_config.json 展示 LLaMA-Factory yaml 如何映射到 peft:
{
"base_model_name_or_path": "Qwen/Qwen2.5-3B-Instruct",
"peft_type": "LORA",
"task_type": "CAUSAL_LM",
"r": 8,
"lora_alpha": 16,
"lora_dropout": 0.05,
"target_modules": ["k_proj","gate_proj","up_proj","q_proj","v_proj","o_proj","down_proj"],
"bias": "none",
"use_dora": false,
"use_rslora": false
}
这个 adapter 可以直接被 vLLM / transformers 加载:PeftModel.from_pretrained(base_model, "saves/qwen-3b-sft-mini")。
5. 选型决策 cheat sheet
单机 1-4 卡, 7B-13B SFT/DPO:
→ LLaMA-Factory + LoRA, ZeRO-0 或不开 DeepSpeed
→ 命令: llamafactory-cli train config.yaml
单机 8 卡, 13B-70B SFT:
→ LLaMA-Factory + LoRA + DeepSpeed ZeRO-2
→ yaml 加: deepspeed: examples/deepspeed/ds_z2_config.json
多机 16+ 卡, 70B+ 全参 SFT:
→ LLaMA-Factory + Full FT + DeepSpeed ZeRO-3
→ 多机用 accelerate config + slurm/torchrun
集群 64+ 卡, 70B+ 从零预训练:
→ Megatron-LM 原生(TP+PP+DP)
→ 或 Megatron-DeepSpeed(更灵活)
集群 256+ 卡, 100B+ MoE 模型:
→ Megatron-LM + ExpertParallel + ContextParallel
→ 或 DeepSeek 风格的自定义训练框架
6. 一句话总结
LLaMA-Factory 是高层 yaml DSL · DeepSpeed 是显存优化引擎(ZeRO 系列) · Megatron-LM 是 3D 并行原生框架。个人/小团队 7-72B 训练,LLaMA-Factory + DeepSpeed ZeRO-2/3 全搞定;只有当卡数 ≥ 64 且模型 ≥ 70B,才真正需要 Megatron。三者的 yaml/config/CLI flag 看起来眼花,但本质都在回答同一个问题:显存装不下时,谁来分片 + 谁去 offload + 通信代价多少。看清这一点,所有参数都能自己推导。
面试常见题
Q1:LoRA 的 target_modules 到底该选哪些?只选 Q/V 行不行?
最早 LoRA 论文(Hu et al., 2021)只在 Q/V 上加,是 GPT-2/3 时代的妥协。今天的实践已经明确:
- 能放得下,就把所有 linear 都加上:Q/K/V/O + gate/up/down,七件套。LLaMA-Factory 的
lora_target: all就是干这个。 - 只加 Q/V 的代价是表达力受限。FFN 是 transformer 里真正承载知识的部分(参数量占 2/3),只调 attention 的投影矩阵相当于让模型只学"看哪里",不学"知道什么"。
- 显存极度紧张才退回 Q/V,rank 提高比缩 target 更划算。
- DoRA / rsLoRA 这类变体也是默认在 all-linear 上跑。
Q2:DeepSpeed ZeRO 1/2/3 到底分别分片了什么?
- ZeRO-1:分片 Optimizer States(Adam 的 m/v 矩阵,FP32,占 12 字节/参数)。最便宜,通信开销小。
- ZeRO-2:在 1 的基础上加分片 Gradients(BF16 时 2 字节/参数)。
- ZeRO-3:在 2 的基础上加分片 Parameters 本身。每次 forward 前需要 all-gather 当前层的参数,用完释放。通信开销最大,但能突破"单卡装不下"的硬上限。
直观比例(70B + AdamW):FP32 优化器状态 ≈ 840GB,BF16 梯度 ≈ 140GB,BF16 权重 ≈ 140GB。8 卡上 ZeRO-3 后每张约 140GB。配 CPU offload 后可以再降一档,代价是 PCIe 带宽。
Q3:Activation Checkpointing 的显存-计算 trade-off 怎么算?
原理:前向时不存中间 activation,反向时再算一遍。
- 显存收益:activation 占用从 O(L)(L 层)降到 O(√L) 或常数,对 70B 长序列动辄能省一半以上。
- 计算代价:反向多一次 forward,整体训练时间 +25%~33%(不是 +100%,因为反向本身就比前向重)。
- Megatron
--recompute-granularity selective只 recompute attention 的 softmax 等"算得快但占显存多"的算子,收益高、代价低,是首选。 full是兜底:显存仍然不够再开。
一句话决策:显存吃紧先 selective,仍不够再 full,永远不要为了"看起来更快"关掉它。
Q4:fp16 vs bf16 怎么选?
| 维度 | FP16 | BF16 |
|---|---|---|
| 指数位 | 5 | 8(同 FP32) |
| 尾数位 | 10 | 7 |
| 动态范围 | 窄(~6e-5 ~ 6e4) | 宽(同 FP32) |
| 精度 | 高 | 低 |
| 训练稳定性 | 需要 loss scaling,容易 NaN | 稳,无需 loss scaling |
| 硬件 | V100 起 | A100 / H100 / A800 / RTX 30+ |
实践规则:
- A100 及以后的卡 → 永远选 bf16。范围大、不抖、不用 loss scaling,唯一代价是精度略低(但训练里精度从来不是瓶颈)。
- V100 / T4 这类老卡 → 只能用 fp16,要配 dynamic loss scaling,遇到 NaN 时降低
initial_scale_power。 - 推理可以用 fp16(数值范围在推理时一般可控),但训练强烈建议 bf16。
Q5:Flash Attention 解决了什么问题?
标准 attention 的瓶颈在显存读写,不在计算量:
- naive attention 要把 N×N 的 attention matrix 整个写到 HBM 再读回来。HBM 带宽是 GPU 算力的瓶颈,长序列时显存读写成本是 O(N²)。
- 同时显存占用也是 O(N²),4K 序列已经吃掉几个 GB。
Flash Attention 的核心是 tiling + 在 SRAM 内做 softmax:
- 把 Q/K/V 切成 block,每个 block 在 GPU 的 on-chip SRAM 里算完整的 softmax(用 online softmax 算法,不需要全量 attention matrix)。
- 全过程只读写 Q/K/V/O,不实例化 N×N 矩阵。显存从 O(N²) 降到 O(N),HBM 读写减少 5-10×。
- 数学上与标准 attention 完全等价,不是近似。
收益:相同显卡上能跑 4-8× 更长的序列;相同序列上速度 2-4× 提升。今天的训练栈(LLaMA-Factory flash_attn: auto、Megatron 默认开、PyTorch 2.x SDPA)几乎都默认走 FA2/FA3,主动关掉 = 主动慢。
附录 A:LLaMA-Factory 数据格式备忘
// data/dataset_info.json 登记数据集
{
"alpaca_zh_demo": {
"file_name": "alpaca_zh_demo.json",
"formatting": "alpaca",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"system": "system",
"history": "history"
}
}
}
// data/alpaca_zh_demo.json 样本格式
[
{
"instruction": "请简单介绍 K8s 的 Pod。",
"input": "",
"output": "Pod 是 Kubernetes 最小调度单元,..."
}
]
附录 B:相关文档交叉引用
- Bonus · 训练框架全景手册 — 11 个训练框架对比 + 11 种训练模式
- Bonus-2 · RAG/Agent 实战 — 推理侧 RAG/Agent
- Bonus-3 · 推理优化全景 — vLLM benchmark + 量化 + spec decoding