Chapter 03

快速上手:swift sft 训 Qwen

📌 commit b58b1bd一行命令训完一个 LoRA

ms-swift 的核心入口是命令行 swift sft。本章用 5 行命令训出一个 Qwen2.5-7B 的 LoRA,并讲清楚每个字段。

3.15 行训完

swift sft \
    --model Qwen/Qwen2.5-7B-Instruct \
    --train_type lora \
    --dataset AI-ModelScope/alpaca-gpt4-data-zh \
    --output_dir ./output \
    --num_train_epochs 1 --learning_rate 1e-4 \
    --per_device_train_batch_size 1 --gradient_accumulation_steps 16 \
    --max_length 2048 --torch_dtype bfloat16 \
    --lora_rank 16 --lora_alpha 32 \
    --target_modules all-linear

跑完 ./output/v0-xxx/ 下产物:

checkpoint-200/
├── adapter_config.json
├── adapter_model.safetensors      # LoRA adapter ~10MB
├── args.json                       # 训练参数全量记录
├── trainer_state.json
└── tokenizer files

3.2关键字段解读

字段含义建议
--model模型 ID(魔搭 / HF)必填
--train_typelora / full / dora / longlora / galore / ...lora 默认
--dataset数据集 ID 或本地 jsonl魔搭 / HF / 本地都行
--output_dir保存路径自动加 v0-时间戳子目录
--torch_dtypebfloat16 / float16bf16 优先
--max_length截断2048-4096
--lora_rank / lora_alphaLoRA 配置16 / 32
--target_modules"all-linear" / 列名列表all-linear 起步

3.3多卡训练

# 单机 8 卡(torchrun)
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \
NPROC_PER_NODE=8 \
swift sft \
    --model Qwen/Qwen2.5-7B-Instruct \
    --train_type lora \
    --dataset alpaca-zh \
    --deepspeed default-zero2     # ★ 内置 DeepSpeed 配置

--deepspeed 几个 preset:

preset对应
default-zero0纯 DDP,无 ZeRO
default-zero1ZeRO-1(optim 切)
default-zero2ZeRO-2(+grad 切)
default-zero3ZeRO-3(+param 切)
default-zero2-offloadZeRO-2 + CPU offload

3.4QLoRA

swift sft \
    --model Qwen/Qwen2.5-7B-Instruct \
    --train_type lora \
    --dataset alpaca-zh \
    --quant_method bnb \
    --quant_bits 4 \
    --bnb_4bit_compute_dtype bfloat16 \
    --bnb_4bit_quant_type nf4 \
    --bnb_4bit_use_double_quant true

3.5验证训完的模型

swift infer \
    --adapters ./output/v0-xxx/checkpoint-200 \
    --stream true

或推理脚本:

from swift.llm import PtEngine, RequestConfig, InferRequest

engine = PtEngine(model_id_or_path="./output/v0-xxx/checkpoint-200")
resp = engine.infer(
    [InferRequest(messages=[{"role":"user","content":"你好"}])],
    RequestConfig(max_tokens=100),
)
print(resp[0].choices[0].message.content)

3.6第一次的常见坑

问题处理
模型下载慢USE_HF=1 走 HuggingFace;或 MODELSCOPE_CACHE 持久化
OOM 第一步--gradient_checkpointing true
OOM 在 eval--per_device_eval_batch_size 1
chat template 报错显式 --template qwen

3.7入口背后:从 swift sft 到 Trainer

"一行 swift sft"背后的真实调用栈(基线 commit b58b1bd 上的 v4 结构,跟旧 v3 的 swift/llm/ 嵌套已经不一样了):

位置做什么
1swift/cli/main.py ROUTE_MAPPING 按子命令名 dispatch(line 14–27)
2swift/cli/sft.py swift.pipelines 导入 sft_main 并调用
3main.py line 38–71 检测 .yaml / .json 首参数,merge 进 CLI args
4main.py line 86–102 训练命令(pt / sft / rlhf / infer)自动包 torchrun
5swift/pipelines/train/sft.py SwiftSft.run()SwiftPipeline 基类的 run 方法;下面是它内部 4 步
5aswift/model/register.py get_model_tokenizer() 按 ModelType 查注册表加载
5bswift/template/register.py get_template_meta() 解析 template(指定或自动)
5cswift/dataset/loader.py get_dataset() 加载 + preprocessor 归一化
5dswift/trainers/trainer_factory.py TrainerFactory 按 task_type / rlhf_type 选 trainer(DPO/GRPO/SFT/...)
6swift/trainers/seq2seq_trainer.py:26 Seq2SeqTrainer(SwiftMixin, DataLoaderMixin, HfSeq2SeqTrainer).train()

三个关键观察:

3.8这章你需要带走的