Compute the LoRA trainable param count for a 4096x4096 projection at rank r=8
B is 4096x8 and A is 8x4096, giving 65,536 trainable parameters per module, about 0.39 percent of the full 4096x4096 matrix.
Picture trying to repaint a giant wall. The wall is huge, so painting every single brick is expensive. Instead, you grab two narrow rollers. The first roller is tall but very thin, and the second is wide but very thin, and you press one against the other to make a pattern that paints the wall. The thin direction of each roller is the rank, a small number you pick. Because both rollers are skinny in that one direction, together they use a tiny fraction of the paint you would have spent doing every brick by hand. The final wall change still looks like a giant pattern, but the work you actually did sits in those two slim rollers.
Detailed answer & concept explanation~6 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
3 min: the B and A shapes at rank r, summing entries in both, the percentage of the full layer, why B starts at zero, and how the formula generalises across rank, layer dim, and number of wrapped modules.
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
base = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
# Wrap only the q_proj for one layer to verify the math
config = LoraConfig(
r=8,
lora_alpha=16,
target_modules=["q_proj"],
bias="none",
)
model = get_peft_model(base, config)
# For a 4096x4096 q_proj at r=8:
# B: 4096 x 8 = 32,768
# A: 8 x 4096 = 32,768
# total per wrapped module: 65,536
model.print_trainable_parameters()
# trainable params: ~32 * 65,536 (one per layer in a 32-layer base)
# trainable %: ~0.025% of the 8B base| rank r | params per 4096x4096 | % of full matrix |
|---|---|---|
| 8 | 65,536 | 0.39% |
| 16 | 131,072 | 0.78% |
| 32 | 262,144 | 1.56% |
| 64 | 524,288 | 3.13% |
| full FT | 16,777,216 | 100% |
Real products, models, and research that use this idea.
- Hugging Face PEFT LoraConfig at r=8 on a Llama 3.1 8B q_proj layer matches this exact 65,536 parameter count per wrapped module.
- Axolotl YAML configs default to r=16 alpha=32 on q and v projections for Mistral Large 3 fine-tunes, which is twice this calculation per layer.
- Unsloth single-GPU recipes for Qwen 3.5 7B use r=16 with the same r times (d_in plus d_out) formula, surfacing total trainable params at startup.
- DeepSeek V4 community fine-tunes report trainable param counts in the tens of millions, exactly what this formula predicts when summed across the wrapped attention modules of a 70B class model.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy is B initialised to zero rather than A?
QWhat does the lora_alpha hyperparameter do, and how does it interact with rank?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Computing B times A as 8x8 equals 64 instead of summing the two rectangles. The count is parameters in B PLUS parameters in A, not their product.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.