Make add_tuning_arguments' 1Cycle flags reach OneCycle - #8472
Open
alanhuangyoo wants to merge 1 commit into
Open
Make add_tuning_arguments' 1Cycle flags reach OneCycle#8472alanhuangyoo wants to merge 1 commit into
alanhuangyoo wants to merge 1 commit into
Conversation
`add_tuning_arguments` declares the 1Cycle flags and `override_1cycle_params`
copies them into the scheduler config, but three of them never arrive intact.
The plain CLI invocation for this schedule does not build at all. Three flags
use -1 as an "unset" sentinel, and the copy guard is `is not None`, so -1 is
forwarded as a real value:
$ parser = add_tuning_arguments(argparse.ArgumentParser())
$ args = parser.parse_args(["--lr_schedule", "OneCycle", "--cycle_min_lr", "1e-4",
"--cycle_max_lr", "1e-3", "--cycle_first_step_size", "4"])
$ OneCycle(optimizer, **get_config_from_args(args)[0]["params"])
ValueError: cycle_second_step_size must be non-negative, got -1.0
`cycle_second_stair_count` has the same shape without the error: `None` means
"same as the first half", and -1 is a real value that is simply not > 0, so
`--cycle_first_stair_count 5` gives the first half stairs and the second none.
`--cycle_momentum` was declared but never copied. OneCycle defaults it to True,
so the flag could neither switch momentum cycling on (already on) nor off (what
its own default asks for). On an Adam-like optimizer the schedule rewrites
`param_groups["betas"][0]` every step, and the trajectory was identical either
way -- beta1 0.9 -> 0.8 on the first step for a caller who never asked:
--cycle_momentum omitted scheduler.cycle_momentum=True [0.8, 0.9425, 0.895, ...]
--cycle_momentum passed scheduler.cycle_momentum=True [0.8, 0.9425, 0.895, ...]
Behaviour change worth naming: a CLI-built OneCycle no longer cycles momentum
unless `--cycle_momentum` is passed. That is what the flag documents, and the
old default was unreachable rather than chosen. Only this helper is affected --
`engine._configure_lr_scheduler` passes a JSON config straight through, so
`"params": {"cycle_momentum": false}` has always worked.
The JSON path and the other four schedules are untouched. This is the sibling
of deepspeedai#8268 and deepspeedai#8337 in the same helper; the flag-parsing test added by deepspeedai#8337
even cites --cycle_momentum as the correct shape, but nothing checked that it
reaches the scheduler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: alanhuangyoo <alanhuangyoo@gmail.com>
alanhuangyoo
requested review from
loadams,
tjruwase and
tohtana
as code owners
September 10, 2026 10:28
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
add_tuning_argumentsdeclares the 1Cycle flags andoverride_1cycle_paramscopies them into the scheduler config. Three of them do not survive the trip.The plain CLI invocation does not build
Three flags use
-1as an "unset" sentinel, and the copy guard isis not None, so-1is forwarded as a real value:-1was survivable before #8166 added the step-size guards; it producedtotal_size = first + (-1)instead. It is now an error, and this path has no way around it short of passing the flag explicitly.cycle_second_stair_counthas the same shape without the error.Nonemeans "same as the first half", and-1is a real value that simply is not> 0, so--cycle_first_stair_count 5gives the first half stairs and the second half none:first_stair_countsecond_stair_count--cycle_momentumwas never copiedIt is declared, parsed, and dropped.
OneCycledefaultscycle_momentum=True, so the flag could neither turn momentum cycling on (already on) nor off (what its owndefault=Falseasks for).On an Adam-like optimizer the schedule rewrites
param_groups["betas"][0]every step. Measured with--cycle_min_mom 0.80 --cycle_max_mom 0.99:Identical, and beta1 goes 0.9 -> 0.8 on the first step for a caller who never asked for it.
The fix
None, so the existingis not Noneguard leaves them out andOneCycle's own defaults apply — which is what the help text already promises ("default first_step_size")CYCLE_MOMENTUMconstant added next to the other 1Cycle momentum keys, andoverride_1cycle_paramscopies the flagBehaviour change worth naming: a CLI-built
OneCycleno longer cycles momentum unless--cycle_momentumis passed. That is what the flag documents; the old default was unreachable rather than chosen.store_truecannot distinguish "omitted" from "given as False", so the flag is copied unconditionally — there is no third state to preserve.Scope: only this helper.
engine._configure_lr_schedulerpasses a JSON config straight to the scheduler, so"params": {"cycle_momentum": false}has always worked, and the other four schedules are untouched.Testing
tests/unit/runtime/test_lr_schedulers.py, H20:Six new cases. Verified they fail on
masterfor the right reason, rather than only that they pass here — run against master's source with just the new constant added so the import resolves:The last two report the sentinel rather than the momentum assertion because on
masterthey cannot get far enough to reach it — the beta1 table above is from a probe that supplies--cycle_second_step_sizeexplicitly to step over the first defect.Related
This is the third of the same shape in this helper. #8268 fixed
--warmup_min_ratio/--cos_min_ratiobeing dropped forWarmupCosineLR; #8337 fixed--lr_range_test_staircasebeing un-turn-off-able. The flag-parsing test #8337 added even cites--cycle_momentumas the correctstore_trueshape — but nothing checked that it reaches the scheduler, which is the half that was broken.🤖 Generated with Claude Code