IN THIS BREAKDOWN · 10 SECTIONS
You can read 20% of this breakdown.
The paper in one minute
LoRA fine-tunes a model by learning two small matrices per weight, A and B, so the update to W is the product AB with a low rank r. A company that fine-tunes one base model for each customer or task ends up with hundreds or thousands of adapters. The LoRA paper's advice for serving was to merge AB into W, which removes the extra compute, and to add and subtract adapters to switch between them. With many adapters live at once, merging means either a full model copy per adapter or a GPU that serves one adapter at a time.
S-LoRA keeps W shared and computes x·A·B per request alongside the batched x·W. Since x·W dominates the cost and can be batched across all requests regardless of adapter, the small extra work pays for itself. Three pieces make it scale:
Host memory for adapters. All adapters live in CPU memory; only the ones used by the running batch are copied to the GPU, predicted from the waiting queue and prefetched during the current step.
Unified paging. Adapter weights (rank × hidden size) and KV cache (tokens × hidden size) share a dimension, so one memory pool with pages of one hidden-size vector stores both, extending vLLM's PagedAttention. Adapters of different ranks and sequences of different lengths come and go without fragmenting memory.
Kernels and tensor parallelism. Custom kernels (MBGMM for prefill in Triton, MBGMV for decode adapted from Punica) gather each request's adapter from non-contiguous pages and handle mixed ranks without padding. A tensor-parallel partition aligned with Megatron-LM's adds LoRA communication of 5(N-1)Br/N to the base model's 2(N-1)Bh/N, small because r is much less than h.
On an A100 80 GB with Llama-7B adapters, S-LoRA served 2,000 adapters at 95% of its 5-adapter throughput, about 4x vLLM running merged copies and about 30x Hugging Face PEFT.
Research notes: the problem, approach and results
LoRA adapters served from one A100 80 GB at 95% of the throughput with 5 adapters (Llama-7B, rank 8)
throughput over vLLM serving one merged model per adapter, which ran out of memory by 100 adapters
extra tensor-parallel communication for rank-64 adapters relative to the base model, by the paper's cost formula
Teams fine-tune one base model into many LoRA adapters, one per customer or task. Merging each adapter into the weights means a full model copy per adapter and no batching across them; swapping adapters between batches leaves the GPU idle. Neither scales past a handful of adapters.
Keep the base weights shared and compute each request's low-rank term on the fly. Store all adapters in host memory, fetch only those the running batch needs, and manage adapter weights and KV cache in one paged pool to avoid fragmentation. Custom kernels batch requests with different adapters and ranks; a tensor-parallel layout keeps LoRA's extra communication small.
On one A100 80 GB with Llama-7B adapters, S-LoRA served 2,000 adapters at 7.61 requests/s (8.05 with 5), against 2.04 for vLLM running merged copies (out of memory at 100) and 0.25 for Hugging Face PEFT at 100 adapters: up to 4x and 30x higher throughput.
Why it matters to an FDE
Per-customer or per-task fine-tuning is a common ask: a model that writes in each client's style, follows each team's schema, or knows each product line. The cost question is not training, which LoRA makes cheap, but serving. If every adapter needs its own GPU or its own model copy, the economics fail at a few dozen customers.
Multi-adapter serving changes the pricing. With adapters batched on a shared base model, an extra customer adds an adapter in host memory (tens of MB), not a GPU. That makes a per-customer model a product option rather than a bespoke deployment.
Pick a serving stack that batches across adapters. "LoRA support" in a server can mean merging one adapter at a time. The question to ask is whether requests for different adapters run in the same batch, and how adapter memory shares the GPU with the KV cache.
Popularity skew helps. Throughput depends on how many distinct adapters are in each batch, not how many exist. A long tail of rarely used adapters costs host memory and occasional fetches, not GPU time.
Understand the mechanism. Try it on a real problem.
Unlock this breakdown and 149 more papers.
Premium opens every paper in full, plus every answer, concept, course and guide on the site. One payment for six months of access.
6 months · One payment · No auto-renewal
- ◇1 architecture diagram
- </>1 runnable code experiment
- ▦2 results tables
- ?5 interview questions with answers
- 03Key takeaways
Merging vs on-the-fly, memory, scaling with adapter count, tensor parallelism and three misreadings
Free account - 04How it works
Request flow, the memory pool, the kernels, tensor parallelism and admission control
Premium - 05The numbers that matter
Setups, Table 3, scaling with adapter count, real traces and tensor parallelism
Premium - 06Try it yourself
Recheck Table 3, size adapters in pages, test a unified pool, and model merging vs batching
Premium - 07Where it breaks
Active-set growth, LoRA-only scope, older models, overhead, and slips
Premium - 08Using it on a deployment
Sizing adapter memory, measuring the active set, and deciding when to merge instead
Premium - 09Interview angles
Five questions this paper prepares you for, with answer hints
Premium - 10Read next
Where to go from here on this site
Premium
