Concepts / Learning Rate Adjustment in Training Loops

Learning Rate Adjustment in Training Loops

Linear warmup gradually increases the learning rate from initial_lr to peak_lr during the first warmup_steps batches of training.

  • Programming

A Learning Rate That Moves Each Step

A learning rate controls how large a change the optimizer makes to a model's weights on each update. In many simple training loops it stays at one value for the entire run. The training function in this article does something different: it recalculates the learning rate on every step of the loop, and it uses one rule for the early steps and another rule for the rest of training. The two rules are called the warmup phase and the cosine annealing phase. Warmup is the first of these phases and is the focus of this article.

What do you think happens?

The warmup branch raises the learning rate from a starting value toward a peak value over a fixed number of steps. From one step to the next, what do you think happens to the learning rate?

  • It jumps to the peak immediately and stays there

  • It rises by the same amount on every step

  • It rises by a bigger amount on every step than the step before

  • It falls back down toward zero

Reveal answer
Answer:

It rises by the same amount on every step.

The word linear describes the shape of the change. The learning rate rises by a fixed increment on every step, so plotted against steps it forms a straight line.

As you read the training function, keep one question in mind: at a given step of training, which rule decides the learning rate, and why? The rest of this article follows that question from the warmup formula, to the point where the rule changes, to the line of code that sets the value the optimizer uses.

Linear Warmup as a Straight-Line Ramp

Linear warmup gradually increases the learning rate from initial_lr to peak_lr during the first warmup_steps batches of training. The word linear describes the shape of the change: the learning rate rises by the same amount on every step, so plotted against steps it forms a straight line. The source describes this increment as a fixed quantity computed once, before the training loop begins.

During warmup, the learning rate at each step is the initial value plus the number of steps taken so far, multiplied by the increment. The source writes this as lr = initial_lr + global_step * lr_increment, where global_step is the step counter.

Formula
Rule

In these formulas, I stands for initial_lr, P stands for peak_lr, W stands for warmup_steps, s stands for global_step, and Delta stands for lr_increment. The first formula is the increment, computed once. The second formula gives the learning rate on each warmup step.

Step 00.0001Step 10.00028Step 20.00046Step 30.00064Step 40.00082Step 5peak reached+0.00018+0.00018+0.00018+0.00018+0.00018
At each warmup step, what is the learning rate, and how does it climb until it reaches the peak?

The diagram uses the example values initial_lr = 0.0001, peak_lr = 0.001, and warmup_steps = 5. Each step adds the same amount, so the points lie on a straight line from the starting value to the peak. Each step label shows the learning rate at that step.

Computing the Warmup Increment by Hand

Worked example

Finding the increment and the first warmup rates

Given initial_lr = 0.0001, peak_lr = 0.001, and warmup_steps = 5, find lr_increment and the learning rate at global_step = 0, 1, 2, 3, and 4.

  1. 1
    Compute the difference between peak and initial values

    peak_lr minus initial_lr is 0.001 minus 0.0001, which equals 0.0009.

  2. 2
    Divide by warmup_steps to get lr_increment

    0.0009 divided by 5 equals 0.00018. This is the amount the learning rate rises on every warmup step.

  3. 3
    Apply the warmup formula at each step

    The rate is initial_lr plus global_step times lr_increment. At global_step = 0 it is 0.0001. At global_step = 1 it is 0.0001 plus 0.00018, which equals 0.00028. At global_step = 2 it is 0.00046, at global_step = 3 it is 0.00064, and at global_step = 4 it is 0.00082.

  4. 4
    Check the value that would appear at warmup_steps

    At global_step = 5 the linear formula would give 0.0001 plus 5 times 0.00018, which equals 0.001, the peak. The warmup condition global_step < warmup_steps is now false, so this step is handled by the cosine branch instead.

Result

lr_increment is 0.00018. The warmup rates for global_step 0 through 4 are 0.0001, 0.00028, 0.00046, 0.00064, and 0.00082. Step 5 is no longer in the warmup phase.

python
Output (expected)
0 0.0001
1 0.00028
2 0.00046
3 0.00064
4 0.00082
Notes on the code
  • lr_increment is computed from the three inputs, the same way the source describes it
  • The return line is the warmup formula, initial_lr plus global_step times lr_increment
  • round is used only to make the printed values easy to read

Where the Peak Rate Comes From

The training function takes initial_lr and min_lr as arguments, with default values in the function signature. It does not receive a peak learning rate as an argument. Instead, it reads the peak from the optimizer, using the learning rate stored in the optimizer's first parameter group. The source notes that this assumes the optimizer's starting learning rate is used as the peak learning rate.

python
Notes on the code
  • initial_lr and min_lr are arguments with default values
  • peak_lr is not an argument; it is read from the first parameter group of the optimizer
  • total_training_steps is the loader length multiplied by the number of epochs

The function also calculates total_training_steps as the length of the training loader multiplied by the number of epochs. The warmup_steps value is the number that controls how long the ramp lasts. The code sample above is an illustration written for this article to show where each value comes from; the names match the source, but the default values and the warmup_steps line are example choices.

How the Loop Chooses a Phase Each Batch

The learning rate itself is recalculated inside the innermost loop, once per batch, because the step counter changes once per batch. On each pass, the code first checks the condition global_step < warmup_steps. When that condition is true, the code uses the linear formula. When it is false, the code uses the cosine formula.

New batchglobal_step <warmup_steps?Linear warmup formulainitial_lr + global_step *lr_incrementLearning rate forthis stepOptimizer updateCosine annealingformulauses progressyesno
On each iteration of the loop, which branch runs, and where is the learning rate set for the optimizer?

The flowchart shows the decision that runs on every batch. The check is made against the current value of global_step, so the chosen branch can change from one batch to the next without any other change to the code.

Switching to Cosine Annealing

Once global_step reaches warmup_steps, the training function stops using the linear rule and starts using cosine annealing. Cosine annealing is a technique used to adjust the learning rate after the warmup phase. The two phases share the same step counter and the same peak_lr. Warmup climbs toward the peak, and cosine annealing starts from that peak and decreases toward the minimum.

Warmup phaseglobal_step < warmup_stepsCosine annealingphaseglobal_step >= warmup_stepsglobal_step reaches warmup_steps
When global_step passes warmup_steps, what changes in the schedule, and which phase applies on the next step?

The variable progress measures how far training has moved through the post-warmup period. The source defines it as the number of steps completed after warmup, divided by the number of steps remaining after warmup. The number of steps remaining is the total number of training steps minus warmup_steps. Because progress is measured from the end of warmup, the cosine schedule begins from the peak learning rate and moves toward min_lr as training continues.

Mistakes That Produce Wrong Rates

Most unexpected learning rate values come from a small set of misreadings. The items below are the ones most likely to send you looking in the wrong place.

  • Common mistake

    Assuming the warmup branch runs on the step where global_step equals warmup_steps

    What it looks like

    With warmup_steps = 5, a learner expects step 5 to still use the linear formula.

    Why it fails

    The warmup branch begins with the condition global_step < warmup_steps. At global_step = 5 that condition is false, so the cosine formula applies.

    Do this instead

    Check the strict less-than comparison. The last warmup step is warmup_steps minus 1.

  • Common mistake

    Looking for peak_lr among the function arguments

    What it looks like

    A learner searches the function signature for a peak_lr parameter and cannot find one.

    Why it fails

    The function takes initial_lr and min_lr as arguments. The peak is read from the optimizer's first parameter group.

    Do this instead

    Trace peak_lr back to the optimizer's first parameter group.

  • Common mistake

    Recomputing the increment inside the batch loop

    Why it fails

    The source says the increment is computed once, before the epoch loop starts. Only the step counter and the resulting learning rate change per batch.

    Do this instead

    Look for lr_increment being set once, above the epoch loop.

  • Common mistake

    Thinking the learning rate stays constant during the whole run

Tracing an Unexpected Learning Rate Value

When a learning rate looks wrong during training, the fastest path to the cause is to ask three questions in order. Each question points to one line of the training function, so the divergence can be located rather than guessed.

  1. 1
    First, identify which branch applied at that step: was global_step below warmup_steps?
  2. 2
    Second, for a warmup step, check the values of initial_lr, peak_lr, and warmup_steps that fed into lr_increment.
  3. 3
    Third, for a cosine step, check total_training_steps and warmup_steps, since those define progress.

Practicing a Warmup Trace

MEDIUM

Using the warmup_lr function from the earlier example, with initial_lr = 0.0001, peak_lr = 0.002, and warmup_steps = 4, what is lr_increment, and what learning rate does the warmup formula give at global_step = 2? Also state which branch the training loop uses at global_step = 4.

Hints
  • Subtract initial_lr from peak_lr first, then divide by warmup_steps.
  • At global_step = 2, multiply lr_increment by 2 and add initial_lr.
  • The warmup condition is global_step < warmup_steps, so compare 4 with 4.

Key Takeaways

  • Linear warmup raises the learning rate by a fixed increment on each step during the first warmup_steps batches, forming a straight line from initial_lr to peak_lr.
  • lr_increment equals (peak_lr - initial_lr) divided by warmup_steps, and it is computed once before the epoch loop. The warmup rate at each step is initial_lr plus global_step times lr_increment.
  • The training loop checks global_step < warmup_steps on every batch. Once that condition is false, the cosine annealing phase takes over, starting from the peak and moving toward min_lr.
  • peak_lr is read from the optimizer's first parameter group, not passed as an argument, so an unexpected value can be traced to that source or to the increment line.
  • When a rate looks wrong, identify the phase first, then check the inputs that feed that phase's formula.

Related concepts

More concepts starting with L