Create your own
Lesson illustration

Comparing Fine-Tuning Methods: Memory, Quality, and Deployment Tradeoffs

Good to see you again. Previously, you derived why LoRA makes only a small fraction of a transformer trainable: for a target matrix of shape , rank adds parameters. You also saw that rank sets the capacity of the learned update, while the chosen target modules determine where the model can change.

This lesson turns that parameter count into an engineering decision. You will compare full fine-tuning, conventional bottleneck adapters, LoRA, and QLoRA by asking three questions: What state must fit during training? How much adaptation capacity and quality risk is acceptable? How will the resulting variants be deployed and served? These are the questions that matter when choosing a post-training path for an LLM platform rather than merely selecting a popular library configuration.


Begin with the training-memory ledger

The important distinction is not just “how many parameters exist,” but which parameters are trainable. A frozen parameter still needs to be stored and used in forward and backward computation, but it does not require its own gradient tensor or optimizer state.

Let:

  • be the number of base-model parameters.
  • be the number of trainable parameters added or selected by an adaptation method.
  • be activation memory, including temporary tensors needed by backpropagation.

For a conventional mixed-precision full fine-tune with AdamW, a useful persistent-state approximation is:

A common setup uses:

  • BF16 weights: bytes;
  • BF16 gradients: bytes;
  • FP32 first moment: bytes;
  • FP32 second moment: bytes;
  • optionally, FP32 master weights: bytes.

That is roughly to bytes before activations, temporary workspaces, and allocator overhead. The exact accounting varies across frameworks and optimizer implementations, but the systems conclusion is stable: optimizer state and gradients multiply the memory cost of making a weight trainable.

For example, a 13-billion-parameter model requires roughly:

bytes, or about 156 GB in decimal units, for this simplified full-training state. Including FP32 master weights raises the simplified estimate to about 208 GB. This explains why full fine-tuning often requires sharding across several GPUs even when the BF16 model weights alone fit on one.

With PEFT, the base model remains frozen. The memory structure becomes:

The trainable state scales with , rather than . However, do not make the opposite mistake and conclude that adapter parameters are the entire memory story. Long sequence lengths, batch size, and activation storage can dominate a LoRA or QLoRA run. Gradient checkpointing can reduce activation memory, at the cost of extra recomputation.

This is why PEFT can make a model trainable on a given GPU without making every configuration feasible. Context length and microbatch size still matter.


Four methods, and one terminology trap

PEFT, parameter-efficient fine-tuning, is an umbrella term. Both conventional adapters and LoRA are PEFT methods. In this lesson, “adapter-based PEFT” means the classic approach of inserting trainable modules into the transformer, rather than LoRA’s low-rank updates to existing linear layers.

1. Full fine-tuning: change every base weight

Full fine-tuning updates all or nearly all pretrained parameters:

for every selected weight tensor throughout the model.

It offers the greatest parameter-level freedom. If the task requires a large behavioral shift, broad language adaptation, changed modality handling, or the last increment of benchmark performance, that capacity can matter. But it also creates the most expensive training artifact and, normally, one full model checkpoint per variant.

Full fine-tuning is not automatically higher quality. It has more capacity, but can overfit small datasets or degrade desirable base behaviors if the data, learning rate, or training duration are poorly chosen. Its advantage is that it does not impose a low-rank or module-placement constraint.

2. Bottleneck adapters: insert new trainable modules

A conventional bottleneck adapter is usually placed within each transformer block, often after attention and/or the feed-forward sublayer. It projects the hidden state down to a bottleneck width , applies a nonlinearity, then projects back to hidden width :

where:

Ignoring biases, one such adapter contains:

parameters.

For example, with and bottleneck width , one adapter has:

parameters. If there are two adapters per layer across 32 layers, that becomes about 33.6 million trainable parameters.

Four PEFT architectures: a serial bottleneck adapter, prefix adapter, Compacter, and parallel adapter. The bottleneck and parallel forms add trainable computation inside a transformer block, unlike LoRA, which modifies selected existing linear transformations.

Bottleneck adapters remain attractive when you want explicit modular components, nonlinear adaptation capacity, or an architecture supported by an established adapter ecosystem. Their main deployment drawback is that they add new operations to the model graph. Because of the nonlinear bottleneck, they generally cannot be folded exactly into an existing base-model weight matrix.

3. LoRA: add a low-rank update to existing linear layers

LoRA leaves a selected base matrix frozen and learns a low-rank correction:

where is a scaling factor and:

The update applies to an existing linear transformation rather than inserting a new nonlinear block.

A frozen pretrained matrix \(W\) processes input \(x\) in the main path, while trainable low-rank matrices \(A\) and \(B\) form an additive update path. The figure also shows the usual initialization idea: initialize one factor so the initial LoRA update is zero.

For an projection, LoRA contributes:

trainable parameters. At and , that is only:

parameters per targeted projection.

LoRA’s capacity is controlled by:

  1. Rank , which bounds the rank of each matrix update.
  2. Target-module coverage, such as adapting only versus all attention and MLP projections.
  3. Which layers are adapted, such as all layers versus selected upper layers.

Rank is not the sole quality knob. A rank-16 configuration applied to every linear layer can be more expressive than a rank-64 configuration applied only to query and value projections.

What is Low-Rank Adaptation (LoRA) | explained by the inventor

Watch “What is Low-Rank Adaptation (LoRA),” presented by LoRA co-inventor Edward Hu. It frames LoRA as a controlled restriction of full fine-tuning and connects that choice directly to model-storage and serving constraints.

Watch the capacity framing. Focus on the two independent choices: how many matrices to adapt and how expressive each matrix update needs to be. Then watch merging for inference for the deployment consequence: a LoRA update can be folded into a base weight for a single deployed variant.

4. QLoRA: use LoRA while the frozen base is quantized

QLoRA keeps LoRA’s trainable adapter design but stores the frozen base model in a low-bit quantized representation, most commonly 4-bit NF4. The base weights are dequantized into a higher-precision compute type, commonly BF16, when a matrix multiplication needs them.

Conceptually:

The crucial distinction is:

  • LoRA and QLoRA can have the same trainable-parameter count .
  • QLoRA reduces memory primarily by reducing frozen base-weight storage, not by shrinking the number of LoRA parameters.

An idealized 4-bit representation stores a base parameter in bytes instead of 2 bytes for BF16. In reality, QLoRA also stores quantization metadata and uses temporary dequantization workspaces, so do not estimate it as exactly one-quarter of all memory. Still, the reduction is substantial because the base model is normally the largest remaining persistent object after PEFT has eliminated base-model gradients and optimizer state.

QLORA: Efficient Finetuning of Quantized LLMs

Read the relevant parts of the original QLoRA paper by Tim Dettmers and colleagues. It provides the precise distinction between low-bit storage and higher-precision computation, explains why activations still matter, and reports the paper’s controlled comparisons with full fine-tuning and standard LoRA.

First, read the abstract and introduction on PDF p. 1 for the overall claim and the 65B-model motivation. Then go to “Memory Requirement of Parameter-Efficient Finetuning” in Section 2, p. 3. Read the activation-memory discussion; distinguish the small adapter footprint from the memory needed to propagate gradients through activations. Next, in Section 3, “QLoRA Finetuning,” around PDF pp. 3-5, read storage versus computation. Finally, in Section 4, around PDF pp. 5-6, locate the results discussion after Table 3 and read the benchmark finding. Treat it as evidence for those evaluated configurations, not as a blanket guarantee for a new model, dataset, or product metric.


Compare the four methods systematically

The following table is intentionally qualitative. Exact memory and quality depend on model architecture, precision, optimizer, sequence length, batch size, target modules, and distributed-training strategy.

DimensionFull fine-tuningBottleneck adaptersLoRAQLoRA
Base weightsTrainableFrozenFrozenFrozen and quantized
Trainable capacityHighestAdded nonlinear modulesLow-rank updates to selected modulesSame LoRA-style updates
Base gradients and optimizer stateRequiredNot requiredNot requiredNot required
Trainable-state sizeScales with Scales with adapter sizeScales with per target matrixSame as LoRA for the same adapter configuration
Base-weight memoryUsually BF16 or FP16Usually BF16 or FP16Usually BF16 or FP16Usually 4-bit plus metadata
Activation memoryHighStill significantStill significantStill significant
Training throughputOften efficient if it fitsExtra module operationsExtra low-rank operationsDequantization overhead as well
Merging into base weightsAlready a standalone modelGenerally not exactExact algebraic merge is possiblePossible with a deliberate requantization or serving strategy
Multi-variant servingExpensive; each variant is a full modelSmall variants, but modified graphSmall adapters can be selected dynamicallySame small-adapter benefit, with quantized-base options
Main quality riskOverfitting or unwanted broad driftInsufficient module capacity or placementLow rank or target coverage is inadequateLoRA limitations plus quantization sensitivity

Two observations should guide your reasoning.

PEFT lowers trainable state, but not necessarily activation memory

Suppose a LoRA configuration trains only 20 million parameters. Its AdamW state may indeed be tiny relative to the model. Yet backward propagation still needs to calculate gradients with respect to intermediate activations so that gradients can reach the LoRA factors. Long prompts can therefore cause an out-of-memory failure even when the adapter checkpoint is only tens or hundreds of megabytes.

For capacity planning, track at least:

PEFT strongly reduces the middle two terms for the base model. QLoRA additionally reduces the base-weight term. Neither method eliminates the activation or temporary-workspace terms.

QLoRA is not “LoRA but faster”

QLoRA’s purpose is primarily memory accessibility, not maximum per-step speed. The serving or training kernel must dequantize base weights into a usable compute representation. This adds overhead and can make individual training steps slower than BF16 LoRA.

The infrastructure trade-off can still strongly favor QLoRA:

  • A BF16 LoRA job may require a high-memory datacenter GPU.
  • A QLoRA job may fit on a smaller GPU or a single-GPU machine.
  • Avoiding multi-GPU sharding, collective communication, and distributed-job coordination can reduce total engineering and cloud cost even if step time rises.

The original QLoRA paper showed that 4-bit NF4 QLoRA could closely match its full-precision baselines in its evaluated settings, including models that conventional full fine-tuning could not fit on one GPU. That is compelling evidence, but a production team should still compare QLoRA against BF16 LoRA on its own task-quality, safety, and regression evaluations.


Quality: capacity is useful only if it is needed

A sound default is not “always QLoRA” or “always full fine-tuning.” It is: start with the least expensive method that has enough capacity to meet a rigorous evaluation bar.

When full fine-tuning is justified

Choose full fine-tuning when the intended change is broad enough that a frozen base plus small adaptation path is consistently inadequate. Typical examples include:

  • an initial large-scale instruction-tuning stage for a relatively unaligned base model;
  • substantial continued training on a new language with weak base-model coverage;
  • a major domain or modality shift;
  • a setting in which the final margin of quality is economically important and sufficient compute is available;
  • a downstream distillation pipeline, where the full-tuned teacher will not itself be the deployed artifact.

The underlying reason is not that full fine-tuning is fashionable. It is that the model may need changes across many independent directions and many parts of its representation.

When conventional adapters are reasonable

Choose bottleneck adapters when nonlinear modules or a specific adapter framework are an operational fit. They can provide meaningful capacity while preserving a frozen base and are useful when different capabilities must be packaged as separate modules.

Their trade-off is serving complexity. Every adapter executes extra layers in each transformer block. If the system needs the smallest possible latency overhead and simple compatibility with high-performance base-model kernels, LoRA often has the advantage.

When LoRA is the practical default

LoRA is usually a strong default for instruction tuning, domain adaptation, internal assistants, and customer-specific variants when the base model is already broadly capable.

It is particularly useful when you need:

  • rapid experiment cycles;
  • small checkpoints;
  • many separately versioned specializations;
  • efficient storage and transport of variants;
  • the option to merge one selected adapter into a standalone model for single-tenant serving.

A failure of LoRA should be diagnosed before simply increasing rank. Check, in order:

  1. prompt formatting and assistant-token loss masking;
  2. data quality, coverage, and train-validation leakage;
  3. learning rate, token budget, and optimization stability;
  4. target-module coverage;
  5. adapter rank and other capacity controls.

The QLoRA experiments found that adapting all linear transformer layers could matter more than changing rank in some instruction-tuning configurations. That is a useful reminder that “LoRA rank” is not a complete adaptation strategy.

When QLoRA is the right constraint-driven choice

Choose QLoRA when the desired base model does not fit for BF16 LoRA training within the available GPU-memory budget, or when reducing training infrastructure is more valuable than maximizing per-step speed.

QLoRA is well suited to:

  • single-GPU experimentation with larger open-weight models;
  • budget-constrained domain adaptation;
  • high iteration frequency where low infrastructure cost matters;
  • prototyping a model and data recipe before committing to expensive BF16 or distributed runs.

Use extra caution when:

  • the target quality bar is narrow and small quantization effects matter;
  • the base model is already aggressively quantized in a way not validated for training;
  • very long contexts dominate activation memory anyway;
  • the deployment plan requires a particular quantization scheme that differs from the training scheme.

Deployment changes the answer

Training and serving decisions are connected, but they are not identical.

A full fine-tuned 13B BF16 model is roughly:

bytes of weights before runtime overhead. If each enterprise customer has a separate full fine-tune, each customer variant is essentially a separate 26 GB model artifact. That makes model loading, GPU placement, rollout, rollback, and version storage expensive.

With adapters or LoRA, the base model is shared and each task or tenant has a small additional artifact. This supports a useful deployment pattern:

  • keep the common base model resident on the GPU;
  • keep active adapter variants in GPU memory;
  • retain less frequently used adapters in host memory or storage;
  • route each request to the permitted adapter version.

For LoRA, there are two serving modes.

Serving modeHow it worksBest fitKey trade-off
Merged LoRACompute the low-rank update and add it to the base weight before deploymentOne model variant per process or GPUNo LoRA-path inference overhead, but each merged variant becomes its own effective model
Dynamic LoRAKeep adapter matrices separate and apply the selected adapter at runtimeMulti-tenant or rapidly changing variantsSupports per-request selection, but requires adapter-aware scheduling and may add compute or batching complexity

Merged LoRA gives the effective weight:

After merging, ordinary inference kernels can operate on , with no separate LoRA matrix multiplication. The cost is loss of shared-base flexibility: serving two tenant-specific merged models means maintaining two distinct effective weight sets.

Conventional bottleneck adapters retain modularity but cannot normally be merged this way because the adapter’s nonlinearity changes the computation graph. QLoRA adds one further choice: you may serve a quantized base with dynamic adapters, or merge and then quantize a selected effective model. The latter requires validating quality after the chosen quantization procedure; “trained with QLoRA” does not automatically determine the best inference representation.

For a serving platform, adapter selection is also a governance boundary. The scheduler should identify the tenant, model base, adapter version, and authorization policy before batching requests. A wrong adapter is not merely a quality regression; it can expose another customer’s behavior or proprietary customization.


A concise decision procedure

In an interview or design review, state the method first, then justify it through constraints.

  1. Determine the behavioral distance from the base model.
    For a narrow domain or instruction format, begin with LoRA. For broad language, modality, or foundational behavior changes, evaluate full fine-tuning.

  2. Create a real memory budget.
    Include base weights, trainable state, activations, temporary buffers, sequence length, and batch size. If BF16 LoRA does not fit because of the base weights, evaluate QLoRA before assuming distributed full fine-tuning is necessary.

  3. Set an evaluation gate.
    Compare task quality, safety, robustness, and regressions against a base-model baseline and, where justified, a small full-fine-tune benchmark. Training loss alone cannot distinguish an adequate adaptation from data memorization.

  4. Choose the deployment shape.
    For one stable model, merged LoRA can offer simple, efficient serving. For hundreds of tenant variants, dynamic LoRA with an adapter-aware engine is usually more economical. For nonlinear bottleneck adapters, account for the permanent extra graph operations.

  5. Run the smallest decisive experiment.
    Keep data, token budget, and evaluations fixed while comparing target-module coverage, rank, precision, and training method. This makes a quality change interpretable.


Key takeaways

Full fine-tuning updates the entire base model and offers maximum adaptation capacity, but its gradients and optimizer states make it memory-intensive and create large per-variant checkpoints.

Bottleneck adapters are classic PEFT: they freeze the base and insert small trainable nonlinear modules. They offer modularity but generally add inference operations that cannot be algebraically merged away.

LoRA freezes selected base weights and learns low-rank updates. It sharply reduces optimizer and gradient memory, creates compact adapter artifacts, and can either be merged for a standalone deployment or applied dynamically for multi-tenant serving.

QLoRA uses the same LoRA-style trainable adapters while storing the frozen base model in 4-bit quantized form and computing in a higher precision such as BF16. Its main advantage is reduced base-weight memory; its main costs are quantization complexity and potential throughput or quality trade-offs that must be evaluated on the actual workload.

Next, we will move from supervised adaptation to preference data and reward models: how to represent chosen and rejected responses, and what a reward model is actually trained to predict.

Can't find a good explanation? Sign up and we'll make it for you

Sign up