使用 LLaMA-Factory 进行训练
本页适用于已经熟悉 LLaMA-Factory,希望把本地或开发机中的 LLaMA-Factory 训练命令迁移到 AIStudio 训练任务的用户。重点是确认镜像、共享存储路径、单机或多机启动方式,以及 AIStudio 注入的 DDP 环境变量如何映射到 torchrun。
本页不重复训练任务创建流程。创建训练任务、选择资源来源、挂载存储、配置 TensorBoard 和提交任务的通用步骤,见选择任务类型与资源来源。
准备 LLaMA-Factory 镜像、模型和数据
先确认训练任务使用的镜像已经包含 LLaMA-Factory、训练脚本和固定依赖。长期训练不建议在任务启动后临时安装大量依赖;网络、源站或版本问题会在 GPU 已经分配后才暴露。
可以选择以下方式准备镜像:
将 LLaMA-Factory 官方镜像导入镜像中心。
language-shell# 该步骤可能需要代理或第三方加速服务 docker pull hiyouga/llamafactory:0.9.4具体版本见 LLaMA Factory Docker Hub 镜像列表。导入方式见导入或跨可用区迁移镜像。
在开发机中构建包含固定依赖和训练代码的镜像。见在开发机中构建 LLaMA-Factory 训练镜像。
如果还没有确定使用官方镜像还是自建镜像,先阅读选择 LLaMA-Factory 镜像准备方式。
提交训练任务前,确认以下内容已经准备好:
- 镜像中可以执行
python src/train.py或等价的 LLaMA-Factory 入口。 - 模型路径位于任务会挂载的共享存储中。
--dataset使用的数据集名称已经在 LLaMA-Factory 配置中可用。--template与模型类型匹配,例如 Llama 3 模型使用llama3。--output_dir、TensorBoard 日志和 checkpoint 都写入共享存储。
后续示例默认使用 --report_to tensorboard。LLaMA-Factory 支持 TensorBoard 记录,但 TensorBoard 不一定随外部镜像预装。如果使用在开发机中构建 LLaMA-Factory 训练镜像中的镜像,TensorBoard 已经安装;如果导入官方镜像或其它自带镜像,先在镜像或 Worker 中确认:
python -m pip show tensorboard
python -c "import tensorboard; print(tensorboard.__version__)"演示任务可以在启动命令前临时安装 TensorBoard:
python -m pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
python -m pip install tensorboard正式训练建议把 TensorBoard 和其它固定依赖构建进镜像,避免任务拿到 GPU 后才因为依赖安装、网络或版本问题失败。
后续脚本用于展示 LLaMA-Factory 命令迁移到 AIStudio 后的启动方式。使用时先修改脚本顶部的 STORAGE_ROOT、MODEL_NAME_OR_PATH、DATASET 和 OUTPUT_DIR,并确保 HF_HOME 指向共享存储。
判断使用单机多卡还是多机多卡
先根据训练规模选择启动方式,再回到创建页选择对应的 分布式框架。
- 单机多卡:Worker 数量 为 1,在 分布式框架 中选择 单机。脚本使用
torchrun --standalone,不读取MASTER_ADDR、WORLD_SIZE和RANK。 - 多机多卡:Worker 数量 大于 1,在 分布式框架 中选择 PyTorch DDP。平台会为各 Worker 注入 DDP 环境变量,脚本读取这些变量后传给
torchrun。
多机训练通常需要稳定的训练网。需要跨 Worker 高速通信时,优先选择支持 IB/RoCE 的规格,并按任务创建页提示开启 RDMA 配置。RDMA 的适用条件见RDMA 网络。
编写单机多卡启动命令
单机多卡任务只运行 1 个 Worker,不依赖 AIStudio 注入的 DDP 环境变量。脚本自动读取当前 Worker 上的 GPU 数量,并使用 torchrun --standalone 启动 LLaMA-Factory。
将以下脚本按需修改后填写到 启动命令。脚本顶部的路径和训练参数是主要替换点,后半段用于展示可靠启动、日志保存和失败状态返回方式。
#!/usr/bin/env bash
set -euo pipefail
echo "=== [Phase] Initializing LLaMA-Factory training ==="
################## 按您的训练任务修改 ##################
# 示例个人路径,请替换为您自己的共享存储挂载路径
STORAGE_ROOT="${STORAGE_ROOT:-/mnt/zhaoyinghao}"
export HF_ENDPOINT="${HF_ENDPOINT:-https://hf-mirror.com}"
export HF_HOME="${HF_HOME:-${STORAGE_ROOT}/huggingface}"
TEMPLATE="${TEMPLATE:-llama3}"
MODEL_NAME_OR_PATH="${MODEL_NAME_OR_PATH:-${STORAGE_ROOT}/Meta-Llama-3-8B-Instruct/}"
DATASET="${DATASET:-alpaca_en_demo}"
OUTPUT_DIR="${OUTPUT_DIR:-${STORAGE_ROOT}/saves/llama3-8b/lora/}"
KEEP_ALIVE_ON_FAIL="${KEEP_ALIVE_ON_FAIL:-0}"
################## 启动前检查 ##################
test -d /app
test -d "${MODEL_NAME_OR_PATH}"
mkdir -p "${OUTPUT_DIR}"
GPUS_PER_NODE="$(nvidia-smi --query-gpu=index --format=csv,noheader | wc -l | tr -d ' ')"
if [[ "${GPUS_PER_NODE}" -lt 1 ]]; then
echo "No GPU detected on this Worker."
exit 1
fi
DISTRIBUTED_ARGS=(
--standalone
--nnodes "1"
--nproc_per_node "${GPUS_PER_NODE}"
)
cd /app
echo "=== [Phase] Starting torchrun: gpus_per_node=${GPUS_PER_NODE} ==="
RET=0
torchrun "${DISTRIBUTED_ARGS[@]}" \
src/train.py \
--stage sft \
--model_name_or_path "${MODEL_NAME_OR_PATH}" \
--do_train \
--dataset "${DATASET}" \
--template "${TEMPLATE}" \
--finetuning_type lora \
--output_dir "${OUTPUT_DIR}" \
--overwrite_cache \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 8 \
--lr_scheduler_type cosine \
--logging_steps 100 \
--save_steps 500 \
--learning_rate 1e-4 \
--num_train_epochs 20.0 \
--plot_loss \
--report_to tensorboard \
--bf16 > >(tee -i "${OUTPUT_DIR}/node-0.log") 2>&1 || RET=$?
sleep 2
if [[ "${RET}" -ne 0 ]]; then
echo "Training failed with exit code ${RET}."
if [[ "${KEEP_ALIVE_ON_FAIL}" == "1" ]]; then
echo "Keeping container alive for debugging. GPU resources remain occupied during this time."
sleep 10000
fi
else
echo "=== [Phase] Training finished successfully ==="
fi
exit "${RET}"脚本使用 Process Substitution 保存日志,平台看到的退出结果仍来自 torchrun。如果需要失败后保留现场,将环境变量 KEEP_ALIVE_ON_FAIL 设置为 1;调试结束后关闭该设置,避免任务失败后继续占用 GPU。
读取 AIStudio 注入的 DDP 环境变量
只有在 Worker 数量 大于 1,并且 分布式框架 选择 PyTorch DDP 时,AIStudio 才会为多 Worker DDP 启动注入以下变量:
MASTER_ADDR:主 Worker 地址,对应torchrun --master_addr。MASTER_PORT:主 Worker 端口,对应torchrun --master_port。WORLD_SIZE:Worker 数量,对应torchrun --nnodes。RANK:当前 Worker 编号,对应torchrun --node_rank。
警告
AIStudio 注入的 WORLD_SIZE 表示 Worker 数量。PyTorch 训练进程中的 WORLD_SIZE 表示总进程数,通常等于 Worker 数量 x 每个 Worker 的 GPU 数量。在启动脚本中建议把平台变量保存为 NNODES;torchrun 会为训练进程设置 PyTorch 自己的 WORLD_SIZE。
编写多机多卡启动命令
多机多卡任务会在每个 Worker 上执行同一份 启动命令。脚本必须读取平台注入的 MASTER_ADDR、WORLD_SIZE 和 RANK,并把它们传给 torchrun。如果这些变量缺失,脚本应立即失败,避免在多机任务中误启动成单机训练。
将以下脚本按需修改后填写到 启动命令。脚本顶部的路径和训练参数是主要替换点;MASTER_ADDR、WORLD_SIZE 和 RANK 由多 Worker PyTorch DDP 任务注入。
#!/usr/bin/env bash
set -euo pipefail
echo "=== [Phase] Initializing LLaMA-Factory DDP training ==="
################## 按您的训练任务修改 ##################
# 示例个人路径,请替换为您自己的共享存储挂载路径
STORAGE_ROOT="${STORAGE_ROOT:-/mnt/zhaoyinghao}"
export HF_ENDPOINT="${HF_ENDPOINT:-https://hf-mirror.com}"
export HF_HOME="${HF_HOME:-${STORAGE_ROOT}/huggingface}"
TEMPLATE="${TEMPLATE:-llama3}"
MODEL_NAME_OR_PATH="${MODEL_NAME_OR_PATH:-${STORAGE_ROOT}/Meta-Llama-3-8B-Instruct/}"
DATASET="${DATASET:-alpaca_en_demo}"
OUTPUT_DIR="${OUTPUT_DIR:-${STORAGE_ROOT}/saves/llama3-8b/lora/}"
KEEP_ALIVE_ON_FAIL="${KEEP_ALIVE_ON_FAIL:-0}"
################## 启动前检查 ##################
test -d /app
test -d "${MODEL_NAME_OR_PATH}"
mkdir -p "${OUTPUT_DIR}"
GPUS_PER_NODE="$(nvidia-smi --query-gpu=index --format=csv,noheader | wc -l | tr -d ' ')"
if [[ "${GPUS_PER_NODE}" -lt 1 ]]; then
echo "No GPU detected on this Worker."
exit 1
fi
NNODES="${WORLD_SIZE:?AIStudio WORLD_SIZE is required for multi-Worker DDP jobs}"
NODE_RANK="${RANK:?AIStudio RANK is required for multi-Worker DDP jobs}"
MASTER_ADDR="${MASTER_ADDR:?AIStudio MASTER_ADDR is required for multi-Worker DDP jobs}"
MASTER_PORT="${MASTER_PORT:-29500}"
TOTAL_PROCS=$((GPUS_PER_NODE * NNODES))
DISTRIBUTED_ARGS=(
--nproc_per_node "${GPUS_PER_NODE}"
--nnodes "${NNODES}"
--node_rank "${NODE_RANK}"
--master_addr "${MASTER_ADDR}"
--master_port "${MASTER_PORT}"
)
cd /app
echo "=== [Phase] Starting torchrun: nnodes=${NNODES} node_rank=${NODE_RANK} gpus_per_node=${GPUS_PER_NODE} total_procs=${TOTAL_PROCS} master=${MASTER_ADDR}:${MASTER_PORT} ==="
RET=0
torchrun "${DISTRIBUTED_ARGS[@]}" \
src/train.py \
--stage sft \
--model_name_or_path "${MODEL_NAME_OR_PATH}" \
--do_train \
--dataset "${DATASET}" \
--template "${TEMPLATE}" \
--finetuning_type lora \
--output_dir "${OUTPUT_DIR}" \
--overwrite_cache \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 8 \
--lr_scheduler_type cosine \
--logging_steps 100 \
--save_steps 500 \
--learning_rate 1e-4 \
--num_train_epochs 20.0 \
--plot_loss \
--report_to tensorboard \
--bf16 > >(tee -i "${OUTPUT_DIR}/node-${NODE_RANK}.log") 2>&1 || RET=$?
sleep 2
if [[ "${RET}" -ne 0 ]]; then
echo "Training failed with exit code ${RET}."
if [[ "${KEEP_ALIVE_ON_FAIL}" == "1" ]]; then
echo "Keeping container alive for debugging. GPU resources remain occupied during this time."
sleep 10000
fi
else
echo "=== [Phase] Training finished successfully ==="
fi
exit "${RET}"如果是 2 个 Worker、每个 Worker 8 张 GPU 的任务,脚本会读取到 NNODES=2、每个 Worker 的 GPUS_PER_NODE=8,并让 torchrun 启动总计 16 个训练进程。更多 PyTorch DDP 启动规则见编写 PyTorch DDP torchrun 启动脚本。
确认 LLaMA-Factory 参数和输出路径
提交前先确认 LLaMA-Factory 参数与平台路径一致:
--model_name_or_path指向共享存储中的模型目录。--dataset是 LLaMA-Factory 配置中已经注册的数据集名称。--template与模型类型匹配。--output_dir指向共享存储,任务结束后仍可读取。--report_to tensorboard需要镜像中已经安装 TensorBoard。- 日志文件写入
${OUTPUT_DIR}/node-${NODE_RANK}.log或等价的共享存储路径。
提交任务后,先在任务日志中查找脚本打印的 Starting torchrun 阶段标记,确认 nnodes、node_rank、gpus_per_node 和 master 符合创建页配置。TensorBoard 日志和训练输出的查看方式见TensorBoard和获取训练结果。
排查 LLaMA-Factory 常见失败
- 启动后找不到
/app或src/train.py:确认镜像是否为 LLaMA-Factory 镜像,或把脚本中的cd /app改为训练代码实际目录。 - 模型加载失败:检查
MODEL_NAME_OR_PATH是否已经挂载到当前 Worker,路径是否位于共享存储中。 - 数据集加载失败:检查
DATASET是否已在 LLaMA-Factory 数据集配置中注册,数据文件是否随镜像或共享存储一起提供。 - 第一个 batch 前失败:检查
template、tokenizer、数据字段、最大长度和 LoRA 配置是否与模型和数据集匹配。 - 多机 DDP 初始化超时:确认创建页选择 PyTorch DDP,Worker 数量 大于 1,并且各 Worker 日志中的
node_rank不同。 - TensorBoard 没有曲线:确认镜像包含 TensorBoard,
--report_to tensorboard已开启,TensorBoard 配置路径与OUTPUT_DIR下的实际日志目录一致。如果导入官方镜像或其它自带镜像,先用python -m pip show tensorboard确认 TensorBoard 是否已安装。 - 任务显示成功但没有结果:检查
OUTPUT_DIR是否为共享存储路径,并确认启动命令没有在训练失败后隐藏torchrun的退出结果。详见编写可靠启动命令。
进入 Worker 调试
任务仍在运行时,可在任务详情页登录 Worker 的 Web Terminal,查看文件、进程、GPU 状态和日志。需要统一下发检查命令时,可使用 atlctl 命令行调试工具。
如果需要失败后保留现场,将 KEEP_ALIVE_ON_FAIL=1 配置到环境变量或脚本中。该设置会在失败后继续占用 GPU,完成调试后应关闭。