一句话启动SFT!verl命令行使用技巧
1. 引言:高效启动SFT训练的必要性
在大语言模型(LLM)的后训练流程中,监督微调(Supervised Fine-Tuning, SFT)是提升模型任务表现的关键步骤。随着模型规模不断增大,如何以最简方式快速启动一次稳定、高效的SFT训练任务,成为开发者关注的核心问题。
verl作为火山引擎开源的强化学习训练框架,不仅支持复杂的RLHF流程,其SFT模块也具备极高的易用性和性能优化能力。通过合理的命令行参数组织,用户可以实现“一句话启动SFT训练”,大幅降低工程复杂度。
本文将聚焦于verl 的命令行使用技巧,帮助你:
- 掌握核心参数的语义与组合逻辑
- 构建可复用的训练启动模板
- 实现多场景下的灵活配置注入
- 避免常见命令行错误和性能瓶颈
2. verl 命令行基础结构解析
2.1 核心执行模式
verl 的 SFT 训练主要通过torchrun调用内置训练器模块启动:
torchrun --nnodes=1 --nproc_per_node=N -m verl.trainer.fsdp_sft_trainer [KEY=VALUE]...该命令遵循Hydra 配置系统的动态参数覆盖机制,允许在不修改 YAML 文件的情况下,直接通过命令行传入配置项。
2.2 参数命名空间规范
verl 使用分层键名(dot notation)管理配置,主要分为以下几类:
| 类别 | 示例 | 说明 |
|---|---|---|
data. | data.train_files,data.micro_batch_size_per_gpu | 数据路径、批大小等 |
model. | model.partial_pretrain,model.lora_rank | 模型加载、LoRA配置 |
optim. | optim.lr,optim.warmup_steps_ratio | 优化器超参 |
trainer. | trainer.total_epochs,trainer.project_name | 训练控制与日志 |
关键提示:所有命令行参数均为
key=value形式,等号两侧不能有空格。
3. 一句话启动SFT:标准模板详解
3.1 单机多卡标准启动命令
以下是一个典型的单机4卡A100环境下的完整启动命令:
#!/bin/bash set -x nproc_per_node=4 save_path="./checkpoints/gsm8k-sft-qwen-0.5b" torchrun --standalone --nnodes=1 --nproc_per_node=$nproc_per_node \ -m verl.trainer.fsdp_sft_trainer \ data.train_files=$HOME/data/gsm8k/train.parquet \ data.val_files=$HOME/data/gsm8k/test.parquet \ data.prompt_key=question \ data.response_key=answer \ data.micro_batch_size_per_gpu=4 \ data.max_length=2048 \ model.partial_pretrain=Qwen/Qwen2.5-0.5B-Instruct \ model.strategy=fsdp2 \ model.enable_gradient_checkpointing=true \ optim.lr=1e-4 \ optim.warmup_steps_ratio=0.1 \ optim.clip_grad=1.0 \ trainer.total_epochs=3 \ trainer.project_name=gsm8k-sft \ trainer.default_local_dir=$save_path \ trainer.experiment_name=gsm8k-sft-qwen-2.5-0.5b-instruct \ trainer.logger=console,wandb \ trainer.seed=42✅ 关键点解析:
--standalone:适用于单节点调试,自动处理分布式协调。model.strategy=fsdp2:启用 PyTorch FSDP2 分布式策略,高效利用显存。trainer.logger=console,wandb:同时输出到终端和 Weights & Biases。seed=42:确保实验可复现。
3.2 快速替换变量的脚本化技巧
为提高复用性,建议将常用字段抽象为变量:
#!/bin/bash MODEL_NAME="Qwen/Qwen2.5-7B-Instruct" DATASET_NAME="gsm8k" LR="2e-5" EPOCHS=3 BATCH_SIZE_PER_GPU=2 SAVE_DIR="./checkpoints/${DATASET_NAME}-sft-${MODEL_NAME//\//-}" mkdir -p $SAVE_DIR torchrun --nnodes=1 --nproc_per_node=8 -m verl.trainer.fsdp_sft_trainer \ data.train_files=$HOME/data/$DATASET_NAME/train.parquet \ data.val_files=$HOME/data/$DATASET_NAME/test.parquet \ data.prompt_key=question \ data.response_key=answer \ data.micro_batch_size_per_gpu=$BATCH_SIZE_PER_GPU \ model.partial_pretrain=$MODEL_NAME \ model.strategy=fsdp2 \ model.enable_gradient_checkpointing=true \ optim.lr=$LR \ optim.warmup_steps_ratio=0.1 \ trainer.total_epochs=$EPOCHS \ trainer.project_name=${DATASET_NAME}-sft \ trainer.default_local_dir=$SAVE_DIR \ trainer.experiment_name=${DATASET_NAME}-sft-$(echo $MODEL_NAME | sed 's/\//-/g') \ trainer.logger=console技巧说明:使用
${MODEL_NAME//\//-}将/替换为-,避免路径非法字符。
4. 多场景命令行配置实战
4.1 LoRA 微调:轻量级高效训练
当资源受限或需快速迭代时,推荐使用 LoRA 进行参数高效微调:
torchrun -m verl.trainer.fsdp_sft_trainer \ data.train_files=$HOME/data/gsm8k/train.parquet \ data.val_files=$HOME/data/gsm8k/test.parquet \ model.partial_pretrain=meta-llama/Llama-3.2-3B-Instruct \ model.lora_rank=64 \ model.lora_alpha=32 \ model.target_modules=all-linear \ model.use_liger=true \ data.micro_batch_size_per_gpu=8 \ optim.lr=5e-5 \ trainer.total_epochs=2 \ trainer.project_name=lora-sft \ trainer.default_local_dir=./checkpoints/lora-l3-3b🔍 参数说明:
lora_rank=64:适中秩数,平衡表达力与内存开销。target_modules=all-linear:对所有线性层应用 LoRA。use_liger=true:启用 Liger Kernel 加速注意力与 MLP 计算。
4.2 多轮对话训练:支持字典字段输入
对于包含多轮历史的对话数据,verl 支持从嵌套字段提取 prompt 和 response:
torchrun -m verl.trainer.fsdp_sft_trainer \ data.train_files=$HOME/data/multiturn/train.parquet \ data.prompt_dict_keys='["history","question"]' \ data.response_dict_keys='["answer"]' \ data.concat_micro_batch_dim=false \ data.add_eos=True \ model.partial_pretrain=Qwen/Qwen2.5-7B-Instruct \ data.micro_batch_size_per_gpu=2 \ trainer.total_epochs=2 \ trainer.project_name=multiturn-sft⚠️ 注意:
prompt_dict_keys需用单引号包裹 JSON 数组格式字符串。
4.3 高吞吐代码生成训练
针对长上下文代码生成任务,需调整序列长度与并行策略:
torchrun -m verl.trainer.fsdp_sft_trainer \ data.train_files=$HOME/data/code/train.parquet \ model.partial_pretrain=deepseek-ai/deepseek-coder-6.7b-instruct \ data.max_length=4096 \ data.micro_batch_size_per_gpu=1 \ model.strategy=fsdp2 \ model.ulysses_sequence_parallel_size=4 \ model.use_remove_padding=true \ optim.lr=1e-4 \ optim.weight_decay=0.1 \ trainer.total_epochs=3 \ trainer.gradient_accumulation_steps=8 \ trainer.project_name=codegen-sft🚀 性能优化点:
ulysses_sequence_parallel_size=4:启用 Ulysses 序列并行,降低长序列显存占用。use_remove_padding=true:去除填充 token,提升有效计算密度。gradient_accumulation_steps=8:补偿小 batch size 对梯度稳定性的影响。
5. 命令行高级技巧与避坑指南
5.1 动态环境变量注入
可在命令中直接引用 shell 环境变量,增强灵活性:
export DATA_ROOT=$HOME/data export MODEL_CACHE=/mnt/fastdisk/models torchrun -m verl.trainer.fsdp_sft_trainer \ data.train_files=${DATA_ROOT}/gsm8k/train.parquet \ model.partial_pretrain=${MODEL_CACHE}/Qwen2.5-0.5B-Instruct \ ...5.2 Hydra 配置继承与覆盖机制
verl 使用 OmegaConf + Hydra 实现配置管理,支持层级覆盖:
# 继承 base 配置,并仅覆盖学习率和epoch torchrun -m verl.trainer.fsdp_sft_trainer \ +config=sft/base.yaml \ optim.lr=5e-5 \ trainer.total_epochs=1💡 提示:可通过
python -m hydra._internal.check_config查看可用配置组。
5.3 常见错误排查清单
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
KeyError: 'data.train_files' | 忘记传入必要参数 | 检查是否遗漏data.train_files |
OOM (Out of Memory) | batch size 过大或未启用梯度检查点 | 减小micro_batch_size_per_gpu或添加model.enable_gradient_checkpointing=true |
ValueError: invalid literal for int() | 参数类型错误(如布尔值写成 true 而非 True) | 布尔值应为true/false(小写),数字不要加引号 |
ModuleNotFoundError: No module named 'liger_kernel' | 缺少性能依赖 | 执行pip install liger-kernel |
CUDA error: device-side assert triggered | 数据格式异常或 tokenizer 不匹配 | 检查数据中是否存在非法字符或截断问题 |
6. 最佳实践总结
6.1 推荐的标准命令结构
torchrun --nnodes=N --nproc_per_node=M \ -m verl.trainer.fsdp_sft_trainer \ # 数据配置 data.train_files=... \ data.val_files=... \ data.prompt_key=... \ data.response_key=... \ # 模型配置 model.partial_pretrain=... \ model.strategy=fsdp2 \ model.enable_gradient_checkpointing=true \ # 训练配置 optim.lr=... \ trainer.total_epochs=... \ trainer.project_name=... \ trainer.default_local_dir=...6.2 可复用的启动脚本模板
#!/bin/bash # =============== 用户可配置区 =============== MODEL="Qwen/Qwen2.5-7B-Instruct" DATASET="gsm8k" LR="1e-4" EPOCHS=3 GPUS_PER_NODE=8 BATCH_SIZE=2 USE_LORA=false RESUME_PATH="" # ========================================== SAVE_DIR="./checkpoints/${DATASET}-$(echo $MODEL | sed 's/\//-/g')" mkdir -p $SAVE_DIR CMD=( torchrun --nnodes=1 --nproc_per_node=$GPUS_PER_NODE -m verl.trainer.fsdp_sft_trainer "data.train_files=$HOME/data/$DATASET/train.parquet" "data.val_files=$HOME/data/$DATASET/test.parquet" "data.prompt_key=question" "data.response_key=answer" "data.micro_batch_size_per_gpu=$BATCH_SIZE" "model.partial_pretrain=$MODEL" "model.strategy=fsdp2" "model.enable_gradient_checkpointing=true" "optim.lr=$LR" "trainer.total_epochs=$EPOCHS" "trainer.project_name=${DATASET}-sft" "trainer.default_local_dir=$SAVE_DIR" "trainer.experiment_name=${DATASET}-sft-$(echo $MODEL | sed 's/\//-/g')" "trainer.logger=console" ) if [ "$USE_LORA" = true ]; then CMD+=("model.lora_rank=64" "model.lora_alpha=32" "model.target_modules=all-linear") fi if [ -n "$RESUME_PATH" ]; then CMD+=("trainer.resume_mode=resume_path" "trainer.resume_from_path=$RESUME_PATH") fi echo "Executing command:" echo "${CMD[@]}" "${CMD[@]}"7. 总结
通过合理组织torchrun命令与 Hydra 风格的 key-value 参数,我们可以实现“一句话启动 SFT”的高效开发体验。本文介绍了:
- 命令行结构解析:理解
key=value的分层配置机制; - 标准启动模板:涵盖数据、模型、优化、训练四大模块;
- 多场景实战示例:包括 LoRA、多轮对话、长文本代码生成;
- 高级技巧与避坑指南:变量注入、配置继承、常见错误应对;
- 可复用脚本设计:提升实验效率与工程规范性。
掌握这些命令行技巧后,开发者可以在不同项目间快速迁移训练配置,显著缩短从数据准备到模型产出的周期。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。