The Linear Algebra Under LoRA and RAG — Eigenvalues, Low Rank and Vector Search, Hands On
A matrix is a deformation of space, an eigenvector is a direction that survives it, SVD generalises the idea, and the dot product is the definition of 'similar'. Four interactive figures and four equations show that LoRA's ΔW=BA and RAG's vector search stand on the same floor. A column meant to be dragged, not just read.
A matrix is not a table — it is a deformation
The single biggest obstacle in linear algebra is reading a matrix as a table of numbers. Read it that way and eigenvalues become a recipe you memorise.
A matrix is a machine that deforms space. Feed it a vector and a different vector comes out. In 2×2 it deforms the plane: feed it the unit circle and an ellipse comes back. Once you switch to this view, LoRA and RAG turn out to sit in the same landscape.
Eigenvectors — directions the deformation cannot turn
Most vectors change direction when pushed through . A few special ones stay on their own line: stretched or squashed, but not rotated. Those are the eigenvectors; the stretch factor is the eigenvalue.
The equation, in words: find a direction that merely scales by , without turning it.
For a 2×2 matrix you can solve it by hand. Expanding gives
— an ordinary quadratic, which says the eigenvalues are settled by just two numbers: the trace and the determinant . And when the discriminant goes negative there is no real solution: a map with rotation mixed in has no real direction it leaves unturned. The quadratic tells you that directly.
Try it below. The two dashed lines are the eigenvector directions. Rotate until lands on the same line. Pick the "rotation" preset and the dashed lines vanish — no real eigenvectors exist.
SVD — every matrix is rotate, stretch, rotate
Eigenvalues only apply to square matrices. The singular value decomposition extends the idea to any shape:
Any matrix factors into "rotate () → stretch along axes () → rotate ()". The stretch factors on the diagonal of are the singular values — the strengths of the directions along which the matrix carries its information.
What the factorisation amounts to, in words: however tangled a deformation looks, all it ever does is line the axes up, stretch along them, and put them back. and change direction without changing length; alone does the stretching. So the character of a matrix sits almost entirely in the numbers running down .
Rewrite it as a sum and the matrix becomes a stack of rank-1 layers:
Each layer is the thinnest possible matrix — one direction of information — and is how loudly that layer speaks. Keeping only the top layers is low-rank approximation, and the Eckart–Young theorem proves no better rank- truncation exists.
Read as a sum, it is the equation which says a matrix is a stack of thin sheets. The sheet is the boldest and each one after it is fainter. Dropping everything past the top barely changes the picture — precisely because the sheets you dropped were faint to begin with.
LoRA — betting that the update is low rank
LoRA's equation has exactly the shape of that truncation:
The change you want from fine-tuning is expressed not as a fat matrix but as two thin factors of rank . With , the parameter count drops from M to K — 0.4%.
Read in words, the equation says the original is never touched: you leave it frozen and bolt two thin factors on beside it. Gradients reach and and nothing else — which is also why one shared base model can have task-specific adapters swapped in and out.
It works because of one empirical bet: the change needed for fine-tuning concentrates in a few directions — it is effectively low rank. The figure below rebuilds a 28×28 matrix at rank . Slide up from 1 and watch the error collapse. 784 numbers reproduced by 56×r.
To pin the correspondence down: LoRA's plays the role of the bundled , and the bundled — except LoRA learns them by gradient descent instead of computing them. More in the LoRA paper walkthrough and SVD and low rank.
The dot product — the definition of "similar"
On the RAG side the protagonist is the dot product, which has two faces:
The left face is computational — multiply components, add them up. The right face is geometric — length × length × agreement of direction. Same direction: large and positive. Orthogonal: zero. Opposite: negative. As a device that turns "similar" into a number, nothing simpler exists.
The equals sign in the middle is the part which says something worth pausing on: a mechanical multiply-and-add is already measuring how well two directions agree. You only ever evaluate the left face, yet the angle on the right comes along for free — which is why retrieval can be a single dot product.
To cancel the influence of length, divide by it. That is cosine similarity:
The dot product with length divided out — pure direction, always between −1 and 1. Plainly: this is the formula that lets a long document and a short one compete on equal footing.
Vector search — what actually happens inside RAG
RAG retrieval embeds the question and every document as vectors, then pulls the top-k documents closest to the question. "Close" means one of the three metrics you just met: dot product, cosine, or Euclidean distance.
They look interchangeable. They are not: an unnormalised dot product has a failure mode. Embedding length tracks document length and token frequency, so "loud" documents barge into the top-k even when they point the wrong way. Drag the query below and switch metrics. Cluster C is deliberately long — watch it start winning unfairly the moment you pick the dot product.
Normalise every vector to unit length, though, and all three metrics return the same ranking — because for unit vectors , so nearness in distance and largeness in dot product carry identical information. That one line is the entire reason production RAG systems normalise their embeddings and then search by inner product. The full pipeline is in RAG from scratch and the embeddings themselves in Embeddings from scratch.
In practice — where this shows up on the job
ML engineers doing fine-tuning — LoRA's is literally the in the low-rank figure. Start around r=8, lora_alpha=16, raise for harder tasks, and stop just before the error curve's collapse point: if doubling doesn't move quality, the change you need really was low rank.
Search and RAG infrastructure — normalise embeddings before they enter the index (faiss.normalize_L2; vector_cosine_ops in pgvector). Metric mismatch is the classic silent failure: an index built on inner product with only queries normalised shows up as vague quality loss and costs a day to trace.
Pitfalls — numerical eigen/singular routines shuffle order and sign freely; when taking "top r", always sort by absolute value. And with skewed embedding distributions, cosine scores can pile up above 0.8 for everything — rank by similarity, don't threshold it.
The two questions design reviews ask — why does LoRA still work at such a small rank, and why normalise embeddings at all? Because the change fine-tuning needs concentrates in a few directions, and because on the unit sphere dot product, cosine and distance all return the same ranking. Both figures above are the answer.
Summary
- A matrix deforms space; an eigenvector is a direction that survives with only a scale change ()
- SVD generalises this: any matrix is a stack of rank-1 layers, and truncating at is optimal (Eckart–Young)
- LoRA's bets the fine-tuning change is low rank, shrinking parameters to
- The dot product defines "similar"; divide by lengths for cosine; production RAG normalises, then searches by inner product
Four equations in total — each one paired with a slider you just moved.
Comments
Sign in to comment