超参数扫描
自动搜索最佳超参数。
快速开始
aitraining llm --train \
--model google/gemma-3-270m \
--data-path ./data.jsonl \
--project-name sweep-experiment \
--use-sweep \
--sweep-backend optuna \
--sweep-n-trials 20
Python API
from autotrain.trainers.clm.params import LLMTrainingParams
params = LLMTrainingParams(
model="google/gemma-3-270m",
data_path="./data.jsonl",
project_name="sweep-experiment",
# Enable sweep
use_sweep=True,
sweep_backend="optuna",
sweep_n_trials=20,
sweep_metric="eval_loss",
sweep_direction="minimize",
# Base parameters (sweep will vary some)
trainer="sft",
epochs=3,
batch_size=4,
lr=2e-5,
)
| 参数 | 描述 | 默认值 |
|---|
use_sweep | 启用扫描 | False |
sweep_backend | 后端(optuna、grid、random) | optuna |
sweep_n_trials | 试验次数 | 10 |
sweep_metric | 要优化的指标 | eval_loss |
sweep_direction | 最小化或最大化 | minimize |
sweep_params | 自定义搜索空间(JSON 字符串) | None(自动) |
post_trial_script | 每次试验后执行的 shell 脚本 | None |
wandb_sweep | 启用 W&B 原生 sweep 仪表板 | False |
wandb_sweep_project | sweep 的 W&B 项目 | project_name |
wandb_sweep_entity | W&B 实体(团队/用户名) | None(使用默认) |
wandb_sweep_id | 要继续的现有 sweep ID | None(创建新的) |
wandb_run_id | 要恢复的 W&B 运行 ID(用于外部 sweep 代理) | None |
搜索空间
默认搜索空间
默认情况下,扫描搜索:
- 学习率:1e-5 到 1e-3(对数均匀)
- 批量大小:2、4、8、16(分类)
- 预热比例:0.0 到 0.2(均匀)
LoRA 秩不包含在默认扫描中。如果需要,请通过 sweep_params 手动添加。
自定义搜索空间
sweep_params 参数期望一个 JSON 字符串。支持列表和字典格式:
import json
# 字典格式(推荐)- 显式类型指定
sweep_params = json.dumps({
"lr": {"type": "loguniform", "low": 1e-6, "high": 1e-3},
"batch_size": {"type": "categorical", "values": [2, 4, 8]},
"lora_r": {"type": "categorical", "values": [8, 16, 32, 64]},
"warmup_ratio": {"type": "uniform", "low": 0.0, "high": 0.2},
"epochs": {"type": "int", "low": 1, "high": 5},
})
# 列表格式(简写)- 仅用于分类值
sweep_params = json.dumps({
"batch_size": [2, 4, 8],
"lora_r": [8, 16, 32, 64],
})
params = LLMTrainingParams(
...
use_sweep=True,
sweep_params=sweep_params, # JSON string
)
支持的字典类型:
| 类型 | 描述 | 参数 |
|---|
categorical | 从列表中选择 | values:选项列表 |
loguniform | 对数均匀分布 | low、high |
uniform | 均匀分布 | low、high |
int | 整数范围 | low、high |
扫描后端
Optuna
高效的贝叶斯优化:
params = LLMTrainingParams(
...
use_sweep=True,
sweep_backend="optuna",
)
网格搜索
对所有组合进行穷举搜索:
params = LLMTrainingParams(
...
use_sweep=True,
sweep_backend="grid",
)
随机搜索
从搜索空间随机采样:
params = LLMTrainingParams(
...
use_sweep=True,
sweep_backend="random",
)
标准指标
| 指标 | 描述 |
|---|
eval_loss | 验证损失 |
train_loss | 训练损失 |
accuracy | 分类准确率 |
perplexity | 语言模型困惑度 |
增强评估指标
启用 use_enhanced_eval 以访问其他指标:
| 指标 | 描述 |
|---|
perplexity | 语言模型困惑度(默认) |
bleu | 翻译/生成的 BLEU 分数 |
rouge | 摘要的 ROUGE 分数 |
bertscore | 语义相似度的 BERTScore |
accuracy | 分类准确率 |
f1 | F1 分数 |
exact_match | 精确匹配准确率 |
meteor | METEOR 分数 |
增强评估参数
| 参数 | 描述 | 默认值 |
|---|
use_enhanced_eval | 启用增强指标 | False |
eval_metrics | 逗号分隔的指标 | "perplexity" |
eval_strategy | 何时评估(epoch、steps、no) | "epoch" |
eval_batch_size | 评估批量大小 | 8 |
eval_dataset_path | 评估数据集路径(如果不同) | None |
eval_save_predictions | 在评估期间保存预测 | False |
eval_benchmark | 运行标准基准测试 | None |
标准基准测试
使用 eval_benchmark 运行标准 LLM 基准测试:
| 基准测试 | 描述 |
|---|
mmlu | 大规模多任务语言理解 |
hellaswag | HellaSwag 常识推理 |
arc | AI2 推理挑战 |
truthfulqa | TruthfulQA 事实性 |
自定义指标示例
params = LLMTrainingParams(
...
use_sweep=True,
sweep_metric="bleu",
use_enhanced_eval=True,
eval_metrics="bleu,rouge,bertscore",
eval_batch_size=8,
)
示例:找到最佳 LR
import json
params = LLMTrainingParams(
model="google/gemma-3-270m",
data_path="./data.jsonl",
project_name="lr-sweep",
use_sweep=True,
sweep_n_trials=10,
sweep_params=json.dumps({
"lr": {"type": "loguniform", "low": 1e-6, "high": 1e-3},
}),
# Fixed parameters
trainer="sft",
epochs=1,
batch_size=4,
)
查看结果
Optuna 仪表板
pip install optuna-dashboard
optuna-dashboard sqlite:///optuna.db
W&B 原生 Sweep 仪表板
默认情况下,sweep 在本地运行,仅将单个运行记录到 W&B。启用 W&B 原生 sweep 集成 可获取聚合视图、平行坐标图和参数重要性分析,所有这些都在专用的 sweep 仪表板中。
本地 vs W&B Sweeps:没有 wandb_sweep=True 时,每个 trial 作为单独的 W&B 运行记录。有 wandb_sweep=True 时,所有 trial 都分组在一个具有统一可视化的 sweep 仪表板下。
启用 W&B Sweeps
aitraining llm --train \
--model google/gemma-3-270m \
--data-path ./data.jsonl \
--project-name sweep-experiment \
--use-sweep \
--sweep-backend optuna \
--sweep-n-trials 20 \
--log wandb \
--wandb-sweep \
--wandb-sweep-project my-sweep-project \
--wandb-sweep-entity my-team
继续现有 Sweep
要向现有 sweep 添加更多 trial 而不是创建新的,请传递 sweep ID:
# 第一次运行创建 sweep(打印 "Created W&B sweep: abc123xyz")
aitraining llm --train \
--use-sweep --sweep-n-trials 10 \
--wandb-sweep --wandb-sweep-project my-project
# 之后,继续同一个 sweep 添加更多 trial
aitraining llm --train \
--use-sweep --sweep-n-trials 10 \
--wandb-sweep --wandb-sweep-project my-project \
--wandb-sweep-id abc123xyz
如果不传递 wandb_sweep_id,每次都会创建新的 sweep。sweep ID 会在 sweep 开始时打印在日志中(查找 “Created W&B sweep: ”)。
访问 Sweep 仪表板
- 前往 wandb.ai 并打开您的项目
- 点击左侧面板中的 Sweep 图标(扫帚图标)
- 从列表中选择您的 sweep
内置可视化
W&B 自动生成三种可视化:
| 可视化 | 描述 |
|---|
| 平行坐标图 | 一目了然地显示超参数与指标之间的关系 |
| 散点图 | 比较所有运行以识别模式 |
| 参数重要性 | 排名哪些超参数最影响您的指标 |
平行坐标图特别适用于识别哪些超参数组合能带来最佳结果。您可以在任何轴上拖动以筛选运行。
与外部 W&B Sweep 代理一起使用
如果您从外部 W&B sweep 代理运行 AITraining(不是 AITraining 的内置 sweep),请使用 --wandb-run-id 来恢复代理的运行,而不是创建重复运行:
# 外部 W&B sweep 代理使用运行 ID 调用 AITraining
aitraining llm --train \
--model google/gemma-3-270m \
--data-path ./data.jsonl \
--wandb-run-id $WANDB_RUN_ID \
--lr $SWEEP_LR \
--batch-size $SWEEP_BATCH_SIZE
设置 --wandb-run-id 后,AITraining 会自动设置 WANDB_RESUME=allow,以便 trainer 恢复指定的运行而不是创建新运行。
重要说明
- 需要 W&B 登录:使用 W&B sweeps 前运行
wandb login
- Sweep ID 会被记录:在日志中查找 “Created W&B sweep: ”
- Trial 被分组:每个 trial 作为带有
group={sweep_id} 的运行出现,用于聚合
- Optuna 仍管理搜索:W&B 仅用于可视化;Optuna/grid/random 处理实际的超参数搜索
试验后操作
在每次试验完成后执行自定义操作,例如将检查点提交到 git、发送通知或同步到远程存储。
CLI 用法
aitraining llm --train \
--model google/gemma-3-270m \
--data-path ./data.jsonl \
--project-name sweep-experiment \
--use-sweep \
--sweep-n-trials 10 \
--post-trial-script 'echo "试验 $TRIAL_NUMBER 完成,指标 $TRIAL_METRIC_VALUE"'
环境变量
试验后脚本接收以下环境变量:
| 变量 | 描述 | 示例 |
|---|
TRIAL_NUMBER | 试验索引(从 0 开始) | 0、1、2 |
TRIAL_METRIC_VALUE | 此试验的指标值 | 0.234 |
TRIAL_IS_BEST | 是否是目前最佳试验 | true 或 false |
TRIAL_OUTPUT_DIR | 试验输出目录 | /path/to/sweep/trial_0 |
TRIAL_PARAMS | 试验参数字符串 | {'lr': 0.0001, 'batch_size': 8} |
示例:为最佳模型提交 Git
aitraining llm --train \
--use-sweep \
--sweep-n-trials 20 \
--post-trial-script 'if [ "$TRIAL_IS_BEST" = "true" ]; then git add . && git commit -m "最佳模型:试验 $TRIAL_NUMBER,指标 $TRIAL_METRIC_VALUE"; fi'
使用回调的 Python API
如需更多控制,使用带回调函数的 Python API:
from autotrain.utils import HyperparameterSweep, SweepConfig, TrialInfo
def on_trial_complete(trial_info: TrialInfo):
"""每次试验完成后调用。"""
print(f"试验 {trial_info.trial_number} 完成")
print(f" 参数: {trial_info.params}")
print(f" 指标: {trial_info.metric_value}")
print(f" 是最佳: {trial_info.is_best}")
if trial_info.is_best:
# 为最佳试验执行特殊操作
save_best_model(trial_info.output_dir)
config = SweepConfig(
parameters={"lr": (1e-5, 1e-3, "log_uniform")},
n_trials=10,
backend="optuna",
post_trial_callback=on_trial_complete,
)
sweep = HyperparameterSweep(config, train_function)
result = sweep.run()
试验后操作是非阻塞的。如果回调或脚本失败,会记录警告但扫描继续进行。这确保扫描进度不会因回调错误而丢失。
最佳实践
- 从小开始 - 初始探索 10-20 次试验
- 使用早停 - 尽早停止不良试验
- 固定已知内容 - 仅扫描不确定的参数
- 使用验证数据 - 始终有评估分割
- 使用试验后脚本 - 自动化检查点或通知
下一步