使用 Training Hub 微调大型语言模型

背景

training_hub 是一个 Python 库,提供了一个统一的高级 API,用于对大型语言模型进行监督微调(Supervised Fine-Tuning,SFT)和正交子空间微调(Orthogonal Subspace Fine-Tuning,OSFT)。它抽象了分布式训练配置、内存管理和后端编排的复杂性,让您专注于实验参数的设置。

主要优势:

  • 统一 API:通过单一函数调用(sft(...)osft(...))即可支持单 GPU、多 GPU 及多节点训练,无需更改代码。
  • 自动内存管理max_tokens_per_gpu 参数限制 GPU 内存使用,并自动计算微批次大小和梯度累积,以保持目标的 effective_batch_size
  • OSFT 支持持续学习osft 函数实现了 Nayak 等人 (2025), arXiv:2504 .07097 中的方法,限制权重更新在正交子空间内,避免灾难性遗忘,无需重放缓冲区或辅助数据集。
  • 生产就绪:内置检查点保存、实验追踪以及 Liger 内核支持以提升吞吐效率。

SFT 与 OSFT 对比

方面SFTOSFT
使用场景初始指令调优,基础模型微调已调优模型的持续领域适应
灾难性遗忘需要混合/重放数据缓解算法上防止
关键参数标准超参数unfreeze_rank_ratio(0.0–1.0)
后端instructlab-trainingmini-trainer

需求

  • 集群中必须安装 Alauda AIAlauda AI Workbench
  • 一个 Workbench(Notebook)实例,需满足:
    • 可访问互联网安装 Python 包(或配置了内部 PyPI 镜像)。
    • 附加 GPU 资源(至少一块 NVIDIA GPU)。
    • 具备足够的共享存储以保存模型检查点。
  • 一个 HuggingFace 模型(本地路径或实例可解析的模型名称)。
  • 训练数据为 JSONL 格式(详见下文 数据格式)。

数据格式

训练数据必须是 JSON Lines (.jsonl) 文件,每行表示一次对话:

{"messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is machine learning?"}, {"role": "assistant", "content": "Machine learning is a subset of AI..."}]}

支持的 role 值:systemuserassistantpretraining

掩码行为:

  • SFT(默认) — 仅助理回复参与训练损失计算。向样本添加 "unmask": true 可使所有非系统内容参与损失(预训练风格)。
  • OSFT — 通过 unmask_messages 参数控制(默认 False;设置为 True 则为预训练风格)。

也支持带有 input_idslabels 字段的预处理数据集,需设置 use_processed_dataset=True

下载 Notebook 并运行示例

提供了两个完整的教程 Notebook。下载到您的 Workbench 实例,逐单元格执行。

Notebook算法下载链接
SFT 综合教程监督微调下载 sft_comprehensive_tutorial.ipynb
OSFT 综合教程正交子空间微调下载 osft_comprehensive_tutorial.ipynb

第 1 步 — 安装依赖

在 Workbench 实例中打开终端,安装 training-hub

pip install training-hub

第 2 步 — 上传或准备数据

将您的 .jsonl 训练文件放置在 Notebook 可访问的路径,例如 /data/train.jsonl

第 3 步 — 打开并配置 Notebook

在 Workbench 实例中打开下载的 Notebook。关键配置单元如下:

选择模型(两个 Notebook 均需):

# 修改为您的 HuggingFace 模型名称或本地路径
model_path = "Qwen/Qwen2.5-7B-Instruct"

内置模型预设涵盖 Qwen 2.5 7B、Llama 3.1 8B、Phi 4 Mini 以及通用 7B/小型模型。

设置必要路径(两个 Notebook 均需):

data_path       = "/path/to/your/training_data.jsonl"
ckpt_output_dir = "/path/to/checkpoints/my_experiment"

仅 OSFT — 设置正交比例:

unfreeze_rank_ratio = 0.25  # 0.1–0.3 保守,0.3–0.5 平衡

选择分布式配置:

selected_distributed = "single_node_8gpu"  # 或 "single_gpu_dev", "multi_node_master" 等

第 4 步 — 执行训练

依次运行所有单元。最终训练单元调用如下:

# SFT
from training_hub import sft
result = sft(
    model_path=model_path,
    data_path=data_path,
    ckpt_output_dir=ckpt_output_dir,
    effective_batch_size=128,
    max_tokens_per_gpu=20000,
    max_seq_len=16384,
    learning_rate=1e-5,
    num_epochs=3,
    nproc_per_node=8,
    ...
)

# OSFT
from training_hub import osft
result = osft(
    model_path=model_path,
    data_path=data_path,
    ckpt_output_dir=ckpt_output_dir,
    unfreeze_rank_ratio=0.25,
    effective_batch_size=128,
    max_tokens_per_gpu=10000,
    max_seq_len=8192,
    learning_rate=5e-6,
    num_epochs=1,
    nproc_per_node=8,
    ...
)

检查点会在每个 epoch 结束时写入 ckpt_output_dir(可通过 checkpoint_at_epoch 配置)。

关键参数

通用参数(SFT 和 OSFT)

参数是否必需描述
model_pathHuggingFace 模型名称或本地路径
data_pathJSONL 训练数据路径
ckpt_output_dir检查点保存目录
effective_batch_size全局有效批次大小
max_tokens_per_gpu每 GPU 令牌预算;控制内存并自动计算微批次大小
max_seq_len最大序列长度
learning_rate优化器学习率
num_epochs训练轮数(默认:1
lr_scheduler学习率调度器类型,例如 "cosine"
warmup_steps线性预热步数(默认:0
use_liger是否启用 Liger 内核以提升效率(OSFT 默认启用)
seed随机种子(默认:42
data_output_dir处理后数据缓存目录;使用 "/dev/shm" 可提升 RAM 磁盘速度
use_processed_dataset如果数据含 input_ids/labels,跳过分词
checkpoint_at_epoch是否每个 epoch 保存检查点(默认:True
save_final_checkpoint训练结束后是否保存最终检查点(默认:True
nproc_per_node每节点 GPU 数量
nnodes节点总数(默认:1
node_rank当前节点序号(默认:0
rdzv_idRendezvous 作业 ID
rdzv_endpoint多节点训练时主节点的 host:port

OSFT 特有参数

参数是否必需描述
unfreeze_rank_ratio每个权重矩阵可更新部分比例(0.0–1.0),值越低表示保留越多
unmask_messages若为 True,则训练所有非系统内容(预训练风格)
target_patterns用于限制 OSFT 仅作用于特定层的子字符串模式(默认:None,即所有层)

多节点训练

多节点作业需在每个节点同时运行 Notebook(或等效脚本),rdzv_idrdzv_endpoint 保持一致,仅 node_rank 不同:

# 主节点(node_rank=0)
nproc_per_node = 8
nnodes         = 2
node_rank      = 0
rdzv_id        = 42
rdzv_endpoint  = "10.0.0.1:29500"

# 工作节点(node_rank=1)
node_rank = 1  # 其他参数相同

所有节点在训练开始前必须能访问 rdzv_endpoint 网络。