LoRA Mathematics › Worked Example: Full Forward and Backward Pass
Language AI HandbookAll chapters LoRA Mathematics › Worked Example: Full Forward and Backward PassOne section · Sections in this chapter7 / 12 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Concrete numbers solidify the mathematical concepts. This example connects the abstract formulas to actual numerical operations you can verify by hand, making the flow from initialization through gradient computation concrete and verifiable.
We consider a small weight matrix with a rank adaptation. The small dimensions make the calculations manageable while capturing all the needed structure of the real application.
Setup and Initialization
We start with a pre-trained weight matrix and initialize the LoRA matrices following the standard scheme. In a real application, would be a slice of a transformer's weight matrix, but a small example suffices to illustrate the mathematics.
where encodes the pre-trained transformation: input dimension , output dimension .
For the LoRA matrices with rank , we follow the asymmetric initialization scheme: gets small random values, gets zeros:
where is the down-projection (rank input) and is the up-projection (output rank). The total trainable parameters are , compared to for the full matrix (a small example; for real models the savings are vastly larger).
We set and , making the scaling factor for simplicity.
Step 1: Forward Pass at Initialization
Given input , we trace through the three stages:
Stage 1, pre-trained output: We compute by multiplying the frozen weight matrix with the input.
So .
Stage 2, LoRA intermediate: We compute , projecting the input down to the rank-2 bottleneck.
So . These two numbers are the bottleneck representation: all the information the LoRA path has about the input is compressed into these two values.
Stage 3, LoRA output: We compute . Since , this gives .
Stage 4, final output: Adding the pre-trained output and the (zero) LoRA output:
At initialization, the output equals the pre-trained output exactly. This confirms that zero-initializing preserves the pre-trained model's behavior: no disruption to the knowledge encoded in .
Step 2: Gradient Computation at Initialization
With upstream gradient from the loss and layers above, we compute gradients for both LoRA matrices.
For matrix :
where:
- : the upstream gradient vector giving the error signal from the loss
- : the transpose of the bottleneck representation computed in the forward pass
- The outer product structure means each entry of the gradient receives a signal proportional to the corresponding upstream gradient component and bottleneck activation
For matrix :
where because is currently zero, making the entire gradient for exactly zero.
As expected from our theoretical analysis, receives non-zero gradients while 's gradient is zero at initialization. The gradient for is nonzero because it does not depend on the current value of , only on the upstream signal and the intermediate activation . The gradient for is zero because it involves , which is currently the zero matrix.
Step 3: First Update and Bootstrap
After one gradient descent step with learning rate :
Now . On the next forward pass, will produce a non-zero vector, and will begin receiving gradients. The bootstrap phase is complete: after just one step, both matrices are active participants in the optimization.
This example illustrates the entire LoRA training loop in miniature: the forward pass flows through the bottleneck, the backward pass produces asymmetric gradients, and the first update breaks the symmetry to enable joint optimization. All subsequent steps involve co-evolution of and .