
Transformers 学习率调度完全指南.optimization 模块中的优化器、调度器与 get_scheduler 统一 API【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers本篇指南基于 Transformers 文档 optimizer_schedules 展开系统讲解.optimization模块提供的三大类能力支持权重衰减的 Adafactor 优化器、十余种学习率调度器从常数、线性、余弦到 WSD 与自适应 GreedyLR以及统一入口get_scheduler。读完后你可以独立为微调任务选择并配置合适的学习率策略并理解Trainer内部如何根据lr_scheduler_type完成调度器的自动构建。模块概览.optimization 提供什么根据官方文档描述.optimization模块提供三类组件一个固定权重衰减weight decay fixed的优化器可直接用于模型微调一组继承自 PyTorchLambdaLR/LRScheduler体系的调度器工厂函数get_*_schedule支持多批次梯度累积的梯度累积类。源码实现集中在单文件 src/transformers/optimization.py约 1300 行调度器名称枚举则定义在 src/transformers/trainer_utils.py。该模块只依赖 PyTorch 的torch.optim因此所有调度器都是标准的torch.optim.lr_scheduler对象可与任意训练循环不限于Trainer配合使用。调度器类型枚举SchedulerTypeSchedulerType是一个ExplicitEnum它定义了TrainingArguments中lr_scheduler_type参数的全部合法取值。从 trainer_utils.py 的源码可以看到完整映射关系枚举值字符串取值对应的调度器函数LINEARlinearget_linear_schedule_with_warmupCOSINEcosineget_cosine_schedule_with_warmupCOSINE_WITH_RESTARTScosine_with_restartsget_cosine_with_hard_restarts_schedule_with_warmupPOLYNOMIALpolynomialget_polynomial_decay_schedule_with_warmupCONSTANTconstantget_constant_scheduleCONSTANT_WITH_WARMUPconstant_with_warmupget_constant_schedule_with_warmupINVERSE_SQRTinverse_sqrtget_inverse_sqrt_scheduleREDUCE_ON_PLATEAUreduce_lr_on_plateauget_reduce_on_plateau_scheduleCOSINE_WITH_MIN_LRcosine_with_min_lrget_cosine_with_min_lr_schedule_with_warmupCOSINE_WARMUP_WITH_MIN_LRcosine_warmup_with_min_lrget_cosine_with_min_lr_schedule_with_warmup_lr_rateWARMUP_STABLE_DECAYwarmup_stable_decayget_wsd_scheduleGREEDYgreedyget_greedy_schedule文档同时说明lr_scheduler_type默认为linearTrainer内部会据此取用get_linear_schedule_with_warmup。统一入口get_scheduler对于手动编写训练循环的场景推荐使用统一 APIget_scheduler按名称获取任意调度器from transformers import get_scheduler import torch optimizer torch.optim.AdamW(model.parameters(), lr5e-5) scheduler get_scheduler( cosine, # 调度器名称对应 SchedulerType 字符串 optimizeroptimizer, num_warmup_steps100, # warmup 步数 num_training_steps2000, # 总训练步数 scheduler_specific_kwargs{}, # 调度器专属参数如 num_cycles、min_lr 等 )四个参数的含义依据源码 docstringnamestr或SchedulerType调度器名称optimizer训练中使用的torch.optim.Optimizernum_warmup_steps可选warmup 步数。并非所有调度器都需要——constant、reduce_lr_on_plateau、greedy不需要需要而未提供时函数会抛出ValueErrornum_training_steps可选总训练步数。除constant、constant_with_warmup、inverse_sqrt、reduce_lr_on_plateau、greedy、warmup_stable_decay外其余调度器均必需scheduler_specific_kwargs可选字典透传给具体调度器的专属参数例如cosine_with_restarts的num_cycles、cosine_with_min_lr的min_lr。参数与调度器类型不匹配时底层函数会抛出TypeError。get_scheduler 的分发逻辑从 optimization.py 源码可以看到模块内维护了一个TYPE_TO_SCHEDULER_FUNCTION字典第 944-957 行将 12 个SchedulerType枚举逐一映射到工厂函数。分发规则为若传入的是LayerWiseDummyOptimizer逐层优化器占位对象则对其中每个子优化器递归调用get_scheduler并给参数注册post_accumulate_grad_hook使各参数组在梯度累积后自动step()最终返回LayerWiseDummyScheduler——这为后续逐层学习率layer-wise LR等高级用法打下基础CONSTANT直接返回get_constant_schedule(optimizer)REDUCE_ON_PLATEAU与GREEDY仅透传scheduler_specific_kwargs因为二者基于验证指标而非步数工作其余调度器要求num_warmup_steps非空其中CONSTANT_WITH_WARMUP与INVERSE_SQRT不需要num_training_stepsWARMUP_STABLE_DECAY额外要求num_training_steps或num_stable_steps二者之一通过scheduler_specific_kwargs传入其余调度器要求num_training_steps非空后以num_warmup_steps num_training_steps **kwargs的形式调用工厂函数。Trainer 内部如何调用 get_scheduler在使用Trainer时上述入口会被自动封装。Trainer.create_scheduler 的关键实现是self.lr_scheduler get_scheduler( self.args.lr_scheduler_type, optimizeroptimizer, num_warmup_stepsself.args.get_warmup_steps(num_training_steps), num_training_stepsnum_training_steps, scheduler_specific_kwargsself.args.lr_scheduler_kwargs, )也就是说TrainingArguments中的--lr_scheduler_type、--warmup_steps或warmup_ratio、--lr_scheduler_kwargs会在此处被消费。例如想让余弦调度保留最小学习率可以写python train.py ... \ --lr_scheduler_type cosine_with_min_lr \ --lr_scheduler_kwargs {min_lr: 1e-6}从源码结构看lr_scheduler_kwargs是一个字符串形式的 JSON 字典会被解析后原样展开为工厂函数的关键字参数因此不同调度器可以复用同一个命令行参数位。各调度器详解与参数说明以下逐一说明文档列出的调度器参数与默认值均来自 optimization.py 中的函数签名与 docstring。所有带 warmup 的调度器行为一致warmup 阶段学习率从 0 线性上升到优化器初始学习率。get_constant_scheduleget_constant_schedule(optimizer, last_epoch-1)学习率保持优化器设定值不变返回LambdaLR。last_epoch用于断点续训时指定恢复到的 epoch 索引。适合与ReduceLROnPlateau思想互补的简单基线或验证训练管线时使用。get_constant_schedule_with_warmupget_constant_schedule_with_warmup(optimizer, num_warmup_steps, last_epoch-1)warmup 阶段后保持恒定学习率。其核心 lambda 实现为def _get_constant_schedule_with_warmup_lr_lambda(current_step, *, num_warmup_steps): if current_step num_warmup_steps: return float(current_step) / float(max(1.0, num_warmup_steps)) return 1.0注意分母用max(1.0, num_warmup_steps)保护避免 warmup 步数为 0 时除零。get_linear_schedule_with_warmupget_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, last_epoch-1)Trainer的默认调度器warmup 后学习率从初始值线性衰减到 0。核心公式为max(0.0, float(num_training_steps - current_step) / float(max(1, num_training_steps - num_warmup_steps)))即衰减斜率由「总步数 − warmup 步数」归一化决定并在末尾钳制到 0。get_cosine_schedule_with_warmupget_cosine_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, num_cycles0.5, last_epoch-1)warmup 后按余弦函数从初始学习率衰减到 0。num_cycles默认 0.5表示余弦波数默认即「半个余弦」——从峰值平滑降到 0progress (current_step - num_warmup_steps) / (num_training_steps - num_warmup_steps) factor max(0.0, 0.5 * (1.0 math.cos(math.pi * 2.0 * num_cycles * progress)))微调大模型时最常见的选择之一因其后期学习率趋近于 0收敛更平稳。get_cosine_with_hard_restarts_schedule_with_warmupget_cosine_with_hard_restarts_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, num_cycles1, last_epoch-1)与上一节的区别在于学习率会多次回到峰值warmup 后执行num_cycles次「硬重启」。从源码看其 lambda 对进度做了取模progress (current_step - num_warmup_steps) / (num_training_steps - num_warmup_steps) if progress 1.0: return 0.0 return max(0.0, 0.5 * (1.0 math.cos(math.pi * ((num_cycles * progress) % 1.0))))即把整个衰减区间切成num_cycles段每段内部独立走一次半余弦。注意此处num_cycles是int硬重启次数而普通余弦的num_cycles是float。进度超过 1.0 时返回 0保证训练末尾学习率归零。get_cosine_with_min_lr_schedule_with_warmupget_cosine_with_min_lr_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, num_cycles0.5, last_epoch-1, min_lrNone, min_lr_rateNone)普通余弦的改进版终点不是 0 而是min_lr。约束条件源码第 372-377 行min_lr与min_lr_rate只能设置其一同时设置抛ValueError二者都不设置同样抛ValueError错误信息明确提示应通过lr_scheduler_kwargs传入若只给min_lr内部会换算为min_lr_rate min_lr / optimizer.defaults[lr]。实现上衰减因子被重新标定factor factor * (1 - min_lr_rate) min_lr_rate保证余弦最低点恰好落在min_lr。get_cosine_with_min_lr_schedule_with_warmup_lr_rateget_cosine_with_min_lr_schedule_with_warmup_lr_rate(optimizer, num_warmup_steps, num_training_steps, num_cycles0.5, last_epoch-1, min_lrNone, min_lr_rateNone, warmup_lr_rateNone)在上一个基础上新增warmup_lr_rate参数warmup 起点不再是 0而是从warmup_lr_rate比例线性升到 1。未设置时按1/num_warmup_steps处理源码第 403-404 行。其进度计算还做了「半步修正」current_step - num_warmup_steps 1.0避免第一步与 warmup 末点的重复采样。min_lr/min_lr_rate的互斥规则与上一节完全一致。get_polynomial_decay_schedule_with_warmupget_polynomial_decay_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps, lr_end1e-7, power1.0, last_epoch-1)warmup 后以多项式衰减到lr_end。约束与公式源码第 273-275 行要求lr_end lr_init否则抛ValueErrorlr_init取自optimizer.defaults[lr]衰减项decay lr_range * pct_remaining**power lr_end其中pct_remaining 1 - (current - warmup) / decay_stepspower1.0时退化为线性衰减与 fairseq/原始 BERT 实现保持一致若current_step num_training_steps例如训练意外超长学习率锁定在lr_end/lr_init比例不会继续下降。get_inverse_sqrt_scheduleget_inverse_sqrt_schedule(optimizer, num_warmup_steps, timescaleNone, last_epoch-1)warmup 后按1/sqrt(step)衰减是 Transformer 原始论文中的经典调度。源码注释表明该实现改编自 Google big_vision 工具库。timescale未提供时默认取num_warmup_steps再退化为 10000if timescale is None: timescale num_warmup_steps or 10_000 decay 1.0 / math.sqrt((current_step (timescale - num_warmup_steps)) / timescale)该调度不需要num_training_steps因此在get_scheduler的分发分支中它只被要求提供num_warmup_steps——对总步数不可预知的训练如流式数据特别合适。get_reduce_on_plateau_scheduleget_reduce_on_plateau_schedule(optimizer, **kwargs)直接包装 PyTorch 的ReduceLROnPlateau源码第 71 行仅一行return ReduceLROnPlateau(optimizer, **kwargs)学习率恒定、在监控指标停止改善时按factor下调。其所有参数mode、factor、patience、threshold等经**kwargs透传给 PyTorch。由于它按 epoch/验证轮而非按训练步触发get_scheduler对其不要求num_warmup_steps与num_training_steps。get_wsd_scheduleWarmup-Stable-Decayget_wsd_schedule(optimizer, num_warmup_steps, num_decay_steps, num_training_stepsNone, num_stable_stepsNone, warmup_typelinear, decay_typecosine, min_lr_ratio0, num_cycles0.5, last_epoch-1)三阶段调度warmup → 恒定平台期 → 衰减期。关键约束源码第 553-566 行num_training_steps与num_stable_steps必须至少提供一个否则ValueError同时提供时优先使用num_stable_steps并发出 warningwarmup_type/decay_type各自取值linear、cosine、1-sqrt越界抛ValueError三段步数之和应等于num_training_steps否则超出部分的学习率直接落到min_lr_ratio对应的最小值。三阶段 lambda 的核心逻辑warmup 阶段按所选类型从min_lr_ratio升到 1.0平台期恒为 1.0衰减阶段按decay_type从 1.0 降到min_lr_ratio并且每个阶段结束前都做factor * (1 - min_lr_ratio) min_lr_ratio的重标定保证衰减终点精确落在最小学习率比例上。GreedyLR 与 get_greedy_schedule基于指标的双向自适应调度器scheduler get_greedy_schedule(optimizer, **kwargs) # 等价于 GreedyLR(optimizer, **kwargs)GreedyLRoptimization.py 第 621 行起是本模块中最独特的调度器它不按步数走预定曲线而是根据验证指标双向调整学习率——指标持续改善时除以factor提升学习率指标进入平台期时乘以factor降低学习率。与ReduceLROnPlateau只有「降」不同GreedyLR还能「升」并在长期触底后支持整表重置。构造参数默认值来自源码签名参数默认值说明modeminmin指标停止下降时降 LRmax停止上升时降 LRfactor0.95平台期乘该值降 LR改善期除该值升 LR必须小于 1.0patience10连续多少轮无改善后调整连续多少轮持续改善后升 LRthreshold/threshold_mode1e-06/abs判定「有改善」的阈值abs或relcooldown0降 LR 后暂停调整的轮数warmup0升 LR 后暂停调整的轮数min_lr1e-3学习率下限支持按参数组传列表max_lr1.0学习率上限支持列表smooth/window_sizeFalse/50是否对指标做滑动窗口平均再决策reset_start500所有参数组都降到min_lr后再持续多少步触发_reset()整表重置源码还配套了StreamingAverage类第 581-618 行实现滑窗均值且GreedyLR自带state_dict/load_state_dict可随检查点保存与恢复。典型用法docstring 示例optimizer torch.optim.SGD(model.parameters(), lr0.1) scheduler GreedyLR(optimizer, modemin, patience10) for epoch in range(100): train(...) val_loss validate(...) scheduler.step(val_loss) # 注意传入的是指标值而不是空 step()step(metrics)的决策流程源码第 749-793 行先做可选平滑 → 冷却期/升 LR 保护期内跳过 → 与历史最优比较累计num_good_epochs/num_bad_epochs→ 任一计数超过patience即调用_increase_lr或_reduce_lr。降 LR 时每个参数组钳制在min_lrs[i]之上若全部触底则reset_start递减归零后调用_reset()恢复初始学习率并清空所有计数与平滑器状态。Adafactor 优化器Adafactor是 fairseq 原版 Adafactor 的 PyTorch 移植主打亚线性显存开销对矩阵参数用行/列向量的分解近似来估计二阶矩而非维护完整同形状缓存。主要参数与默认值参数默认值说明lrNone外部学习率与relative_stepTrue不可同时使用源码第 1155 行会抛ValueErroreps(1e-30, 1e-3)平方梯度与参数尺度的正则化常数clip_threshold1.0最终梯度更新 RMS 的裁剪阈值decay_rate-0.8二阶矩移动平均的衰减系数beta1None一阶矩系数None表示不启用一阶矩纯二阶矩模式weight_decay0.0L2 惩罚scale_parameterTrue是否按参数 RMS 缩放学习率relative_stepTrue是否使用内置的相对步长min(1e-2, 1/sqrt(step))warmup_init 时更早而非外部 lrwarmup_initFalse仅当relative_stepTrue时可用第 1157 行校验源码中的step()实现值得注意两点低精度支持参数或梯度为float16/bfloat16时先转 fp32 计算再写回第 1220-1292 行不支持稀疏梯度分解近似对形状维度 ≥ 2 的参数启用factored模式用exp_avg_sq_row与exp_avg_sq_col两个低维向量加_approx_sq_grad行列因子相乘近似完整的平方梯度平均——这正是显存开销亚线性的来源。docstring 给出的 T5 微调推荐配置# 关闭内置相对步长使用外部调度器 Adafactor(model.parameters(), scale_parameterFalse, relative_stepFalse, warmup_initFalse, lr1e-3)若使用lrNone让 Adafactor 内部自调度则需配合代理调度器AdafactorSchedule第 1297-1324 行它实现为空操作get_lr()直接从优化器的_get_lr读取当前真实学习率供训练循环记录日志。完整示例from transformers.optimization import Adafactor, AdafactorSchedule optimizer Adafactor(model.parameters(), scale_parameterTrue, relative_stepTrue, warmup_initTrue, lrNone) lr_scheduler AdafactorSchedule(optimizer) trainer Trainer(..., optimizers(optimizer, lr_scheduler))此外get_adafactor_schedule(optimizer, initial_lr0.0)工厂函数第 1327 行起可单独获取该代理调度器。实践建议速查结合上文源码证据给出常见场景的选择依据场景推荐lr_scheduler_type理由源码依据BERT 类模型微调Trainer 默认路径linear默认值线性归零衰减实现最简单可预期大模型 / 视觉模型微调cosine半余弦平滑降到 0后期收敛稳定希望保留最低学习率cosine_with_min_lr必须经lr_scheduler_kwargs传min_lr或min_lr_rate二者互斥数据量未知 / 流式训练inverse_sqrt不需要num_training_stepsget_scheduler分支只强制num_warmup_steps总步数可分三段规划warmup_stable_decay可分别指定 warmup / 平台 / 衰减的曲线类型linear / cosine / 1-sqrt按验证集表现动态调参greedy或reduce_lr_on_plateau前者双向调整并可整表重置后者仅下调均不需要步数参数降低显存的大模型训练Adafactor优化器可与上述调度器组合分解二阶矩近似状态量亚线性延伸阅读与相关路径文档原文optimizer_schedules.md调度器全部实现src/transformers/optimization.py枚举定义SchedulerTypesrc/transformers/trainer_utils.pyTrainer调用点Trainer.create_schedulerlr_scheduler_type/lr_scheduler_kwargs参数声明src/transformers/training_args.py以上路径均可在仓库中直接查看源码用于核对参数默认值、约束条件与错误分支便于在自定义训练循环中精确复现Trainer的调度行为。【免费下载链接】transformers Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考