LLM + RoboticsModule 12 · Video 03

LoRA and its descendants: LoRA+, QLoRA, VeRA, DoRA

LoRA freezes a pretrained model and learns a small low-rank correction to each weight matrix, so fine-tuning touches a fraction of a percent of the parameters. This guide explains LoRA from the original paper, then the four follow-ups the video covers: different learning rates for the two matrices, a 4-bit frozen backbone, shared random matrices, and separate magnitude and direction.

Video length21:26
Published21 June 2026
LevelIntermediate: matrix multiplication and what fine-tuning is
Builds onVideo 01 · ZeRO & FSDP (memory per parameter), Module 08 · Alignment & preference (where LoRA is used for DPO)

Video by Jia-Bin Huang · Watch on YouTube

Start here (no maths needed)

Teaching a huge AI a new skill normally means changing all of its billions of numbers. LoRA leaves those numbers alone and adds a tiny "correction" next to them. The correction is so small that anyone with one good graphics card can teach a big model something new.

Think of it like this

You have a thick printed encyclopaedia, and you want it to cover your local football club. Reprinting every page would be silly. Instead, you stick a few sticky notes on the right pages. The book stays exactly as it was, the notes are cheap, and you can peel them off and stick on a different set for your cousin's chess club. LoRA's corrections are those sticky notes: small, removable and swappable, while the big book stays untouched.

How it works

  1. Freeze the big model: none of its numbers will change.
  2. Next to each big table of numbers, add two thin tables. Multiplied together, they make a correction the same size as the big table, but they hold far fewer numbers.
  3. Start the correction at zero, so at first the model behaves exactly as before.
  4. Train only the thin tables on your new examples.
  5. When you're done, you can add the correction into the big table, so using the model is no slower than before.

Why robots care

Robot "brains" built from vision-language models are big. Each new robot, gripper or kitchen needs a bit of extra teaching. With LoRA, a lab can teach one shared model many robots by keeping one small set of sticky notes per robot, and train each set on a single graphics card.

Try it

Words to know

Fine-tuning
Training an already-trained model a little more on new examples.
Frozen
Kept fixed during training; its numbers don't change.
Rank
Roughly, how many independent patterns a table of numbers contains. Low rank means it can be built from a few patterns.
Adapter
A small trainable add-on attached to a frozen model.
Quantisation
Storing numbers with fewer bits, to save memory.

Going deeper: everything below is the full version, with some maths. On a first read, skim the headings and the "Why it matters for robotics" box, and come back for the rest later.

1. Watch

Chapter guide

Timestamps come from the video's description. The right-hand column is this course's reading guide, written from the chapter titles; it doesn't describe what the video shows frame by frame.

TimeChapterWhat to look for
0:00Why Fine-Tuning Huge Models Is ExpensiveThe memory bill of full fine-tuning (weights, gradients, optimiser states) and the cost of storing one full copy per task.
1:32LoRA: Low-Rank AdaptationThe update ΔW = BA, the shapes of A and B, and why the merged model has no extra inference cost. The description also mentions reading LoRA as a compact key-value memory; see section 2.
6:34LoRA InitializationWhich matrix starts at zero and which starts random, and what would go wrong with the other choices.
9:34LoRA+: Different Learning Rates for A and BWhy one learning rate for both matrices is a poor fit when the model is wide.
10:21QLoRA: Quantizing the Frozen BackboneNF4, blockwise quantisation and double quantisation. Count the bits per parameter at each step.
16:23VeRA: Fewer Trainable Adapter ParametersRandom matrices shared by all layers, with only scaling vectors trained.
18:26DoRA: Separating Magnitude and DirectionSplitting each weight column into a length and a direction, and applying LoRA only to the direction.
21:23OutroTry the self-check below.

2. The ideas, explained

Why full fine-tuning is expensive

Full fine-tuning with mixed-precision Adam needs about 16 bytes per parameter for weights, gradients and optimiser states (see Video 01), so a 7B model needs about 112 GB before activations. It also produces a full-size copy of the model for every task. The LoRA paper's motivating example is GPT-3 175B, where keeping one fine-tuned 175B copy per task is impractical.

LoRA: a low-rank update

Hu et al. (2021) hypothesised that the change a model needs during adaptation has low "intrinsic rank". So for a frozen weight W₀ of shape d × k, they learn the update as a product of two thin matrices:

h = W₀·x + ΔW·x = W₀·x + (α / r)·B·A·x
B: d × r,   A: r × k,   r ≪ min(d, k)

trainable per matrix:  r·(d + k)       instead of  d·k
d = k = 4096, r = 16:  131,072         instead of  16,777,216   (0.78%)

after training:  W = W₀ + (α/r)·B·A   → merge, no extra inference latency

Only A and B get gradients and optimiser states, so the 12 bytes per parameter of Adam state apply to a tiny set. The paper applied LoRA to the attention projections and reported, against GPT-3 175B fine-tuned with Adam, about 10,000 times fewer trainable parameters and 3 times less GPU memory, with quality on par with or better than full fine-tuning on the models tested. Unlike adapter layers inserted in series, a merged LoRA adds no inference latency. Keeping adapters unmerged has its own benefit: one base model can serve many adapters, swapping them per request.

A key-value reading. Write A's rows as a₁…a_r and B's columns as b₁…b_r. Then B·A·x = Σᵢ (aᵢ · x) bᵢ: each rank-one component checks how well the input matches a "key" aᵢ and adds the matching "value" bᵢ. Seen this way, LoRA is a small learned memory of r key-value pairs added to each layer, which is a useful intuition for what rank buys: more pairs, more distinct corrections.

Initialisation

LoRA initialises A with random Gaussian values and B with zeros, so BA = 0 and training starts from exactly the pretrained model. Both can't be zero: with B = 0 and A = 0, the gradient of each with respect to the loss is zero (each gradient is multiplied by the other matrix), and nothing would ever train. With A random and B zero, B's gradient is non-zero from the first step, and A starts receiving gradients once B moves. The α/r scaling means that when you change r, you don't have to retune the learning rate as much.

LoRA+: different learning rates for A and B

Hayou, Ghosh and Yu (2024) analysed LoRA as the model width grows and showed that using the same learning rate for A and B doesn't allow efficient feature learning in wide models. Their fix is one line: give B a larger learning rate than A, with a fixed ratio.

η_B = λ · η_A,   λ > 1   (a well-chosen ratio; the paper tunes it)

The paper reports 1–2% better performance and up to about 2× faster fine-tuning at the same compute cost as LoRA.

QLoRA: a 4-bit frozen backbone

Since the backbone is frozen, it never needs a gradient update, only a forward and backward pass through it. Dettmers et al. (2023) store it in 4 bits and backpropagate through the dequantised weights into BF16 LoRA adapters. Three ideas make it work:

quantise a block:  c = max|w|,   q = NF4_index(w / c)
dequantise:        w ≈ c · NF4_value[q]

overhead of block scales, per parameter:
  plain:   32 bits / 64              = 0.5   bits
  double:  8/64 + 32/(64·256)        ≈ 0.127 bits

backbone ≈ (4 + 0.127) / 8 ≈ 0.52 bytes per parameter

A third trick, paged optimisers, uses unified memory to move optimiser states to CPU memory during spikes so a long sequence doesn't crash the run. The paper reports fine-tuning a 65B model on a single 48 GB GPU while preserving full 16-bit fine-tuning task performance. How 4-bit and 8-bit formats behave at inference time is covered in Module 09 · Quantisation & hardware.

VeRA: shared random matrices

Kopiczko, Blankevoort and Asano (2023) noticed that even LoRA adapters add up when you store one per user or task. VeRA uses a single pair of random low-rank matrices A and B, frozen and shared across all layers, and learns only two small scaling vectors per layer:

ΔW = Λ_b · B · Λ_d · A        Λ_b = diag(b), b ∈ ℝ^d     Λ_d = diag(d), d ∈ ℝ^r
trainable per layer:  d + r    (vs r·(d + k) for LoRA)

Because the trainable cost grows with r only through the short vector, VeRA can afford a much higher rank than LoRA. The random matrices can be regenerated from a seed, so they don't need storing. The paper reports performance matching LoRA with far fewer trainable parameters on GLUE, E2E, image classification and instruction tuning of 7B and 13B models.

DoRA: magnitude and direction

Liu et al. (2024) compared how full fine-tuning and LoRA change each weight column's length (magnitude) and direction, and found different patterns. DoRA makes the two separately trainable:

W = m · (W₀ + B·A) / ‖W₀ + B·A‖_c
m ∈ ℝ^(1×k): one trainable magnitude per column, initialised to ‖W₀‖_c
‖·‖_c: the norm of each column
trainable per layer:  k + r·(d + k)

LoRA updates the direction; the magnitude vector is cheap. After training, everything can be merged back into one matrix, so there's no extra inference cost. The paper reports DoRA consistently outperforming LoRA when fine-tuning LLaMA, LLaVA and VL-BART on commonsense reasoning, visual instruction tuning and image/video-text tasks.

Interactive: trainable parameters and fine-tuning memory

Top: trainable parameters for one d × k weight matrix as the rank grows (log scales). Dashed: full fine-tuning. Solid accent: LoRA. Dotted: DoRA (LoRA plus one magnitude per column). Solid muted: VeRA (two scaling vectors). The marker is your rank. Below: model-state memory for a whole model, assuming every weight matrix has this shape ratio and gets an adapter.

LoRA trainable (this matrix)
–
Share of full
–
Full fine-tune
–
LoRA (BF16 base)
–
QLoRA (NF4 base)
–

Try this: the defaults are a 4096 × 4096 matrix at r = 16: LoRA trains 131,072 parameters, 0.78% of the matrix. For a 7B model that's about 112 GB of model states for full fine-tuning, 14.9 GB for LoRA on a BF16 base and 4.5 GB for QLoRA. Set Model size to 65: QLoRA needs about 42 GB, under the 48 GB GPU in the QLoRA paper's headline result (activations come on top). Memory assumes 16 bytes per trainable parameter (BF16 weight and gradient, FP32 master and Adam states), 2 bytes per frozen BF16 parameter and (4 + 0.127)/8 bytes per frozen NF4 parameter, and ignores activations.

3. Where the course goes deeper

TopicCourse page
LoRA in practice for preference tuning (DPO, KTO, ORPO)Module 08 · Alignment & preference
Quantisation formats (FP8, INT8, INT4, NVFP4) and hardwareModule 09 · Quantisation & hardware
Memory per parameter, ZeRO and FSDP (the alternative to LoRA when you need full fine-tuning)Video 01 · ZeRO & FSDP, Module 08 · Distributed training
Post-training pipeline: SFT, preference tuning, RLModule 07 · Post-training
Making small models for deployment by distillationModule 04 · Distilling small models

4. Why it matters for robotics

Self-check

How many trainable parameters does LoRA add to a 4096 × 11008 matrix at rank 8?

r·(d + k) = 8 × (4096 + 11008) = 120,832, compared with 45,088,768 for the full matrix (about 0.27%).

Why is B initialised to zero and A to random values, rather than both to zero?

B = 0 makes the update zero at the start, so training begins from the pretrained model. If both were zero, each matrix's gradient would be multiplied by the other (zero) matrix and neither would ever move.

Why does a merged LoRA model have no extra inference latency, unlike serial adapter layers?

After training, W₀ + (α/r)BA is a single matrix of the original shape, so the forward pass is unchanged. Serial adapters add extra layers that must run in sequence.

What do NF4 and double quantisation each save in QLoRA?

NF4 stores each frozen weight in 4 bits with levels matched to a normal distribution. Double quantisation compresses the per-block scale factors, cutting their overhead from 0.5 to about 0.127 bits per parameter.

VeRA learns only d + r parameters per layer. What makes that possible?

The low-rank matrices A and B are random, frozen and shared across all layers (and can be regenerated from a seed). Only two scaling vectors per layer are trained.

What does DoRA's magnitude vector do that LoRA can't easily do?

It lets each column's length change independently of its direction. LoRA ties the two together in one additive update; DoRA trains the magnitude directly and uses LoRA for the direction.

References

The video's description lists no references. Primary papers cited in this guide: