Skip to content

Adapter Methods Beyond LoRA

Overview

Adapter Methods enable parameter-efficient fine-tuning of large models without modifying core weights. LoRA is most popular, but alternatives offer different trade-offs in efficiency, quality, and flexibility.

  • Approaches: LoRA, Adapters, Prefix Tuning, IA³, Compacter
  • Trade-off: Trainable parameters vs. fine-tuning quality
  • Use Case: Multi-task learning, personalization, domain adaptation
  • Goal: Exploit pre-trained knowledge while adapting to specific tasks

Why Adapters Matter

The Problem: Full Fine-tuning is Expensive

Fine-tuning LLaMA 7B on specific task:

Full fine-tuning:
 - Trainable parameters: 7B (all)
 - Memory needed: 140GB (weights + optimizer + gradients)
 - GPU memory: 8 × H100 (80GB each) minimum
 - Time: Hours to days
 - Cost: $10,000+ for single task

LoRA fine-tuning:
 - Trainable parameters: 4.2M (0.06% of 7B)
 - Memory needed: 4GB (LoRA layers + optimizer)
 - GPU memory: 1 × A100 (80GB) sufficient
 - Time: ~10 minutes
 - Cost: $1

Trade-off:
 - LoRA: 0.06% parameters, 90% quality
 - Full: 100% parameters, 100% quality
 - LoRA is 10,000x cheaper! But 10% quality loss for some tasks

Low-Rank Adaptation (LoRA): Quick Review

Architecture:
Weight update: ΔW = B × A (r << original)

 Input (h)
 ↓
- ┌─────────────────────────────┐
 - Original layer │
 - W: (d_out, d_in) │
 - W × h │ (expensive to train)
 - ┬────────────────┘
 ↓ (shared, frozen)
- ┌─────────────────────────────┐
 - LoRA adapter │
 - A: (r, d_in) │ (small, trainable)
 - B: (d_out, r) │ (small, trainable)
 - (B × A) × h │ (efficient to train)
 - ┬────────────────┘
 ↓ (add)
 Output = W×h + (B×A)×h

Why efficient:
 - Only train r×d_in + d_out×r parameters
 - r is small (8-16 typical)
 - 100-1000x parameter reduction

-

Alternative Adapter Methods

1. Bottleneck Adapters

Classical adapter approach (before LoRA):

Architecture:
 Input (h)
 ↓
- ┌─────────────────────────────┐
 - FC down: (d, r) │ (compress)
 - GELU activation │
 - Dropout │
 - ┤
 - FC up: (r, d) │ (expand)
 - Add & LayerNorm │
 - ┬────────────────┘
 ↓
 Output

Difference from LoRA:
 - LoRA: Pure low-rank A × B (no nonlinearity)
 - Adapters: Two FC layers with activation (nonlinear!)
 - Adapters: More expressive but larger
 - LoRA: Simpler, smaller, works as well or better

Comparison:
 Parameters Memory Quality
──────────────────────────────────────────
LoRA(r=8) 5M Minimal 95%
Bottleneck 10M Small 98%
Full tune 7000M Huge 100%

Verdict:
 - LoRA better trade-off (simpler, smaller, comparable quality)

2. Prefix Tuning

Idea: Add trainable prefix tokens to model input

Architecture:
 Prefix tokens (trainable) Normal input
 ↓ ↓
- ┌──────────────────────────────────────────┐
 - Model processes [prefix + input] │
 - Prefix learns task-specific information │
 - Model weights stay frozen │
 - ┘

Example:
Model: "What is the capital of France?"
Prefix (learned): [task_token_1, task_token_2,...]
 - Only these are trainable!

Advantage:
 - Very parameter-efficient (prefix is small)
 - Can add/remove tasks with different prefixes
 - Easy to switch between tasks

Disadvantage:
 - Less expressive than LoRA
 - Can't adapt mid-network (only at start)
 - Quality sometimes lower (5-10% loss vs LoRA's <5%)

3. IA³ (Infused Adapter by Inhibiting and Amplifying Activations)

Idea: Element-wise scaling of activations instead of adding parameters

Architecture:
 Input (h)
 ↓
- ┌─────────────────────────────┐
 - Original layer (frozen) │
 - W × h = hidden state │
 - ┬────────────────┘
 ↓ (element-wise multiply)
- ┌─────────────────────────────┐
 - IA³ scaling vector (s) │
 - Trainable: s_1, s_2,..., s_d
 - s ⊙ (W × h) ⊙ = hadamard product
 - ┬────────────────┘
 ↓
 Output

Why parameter-efficient:
 - Only d parameters (same as hidden dimension)
 - Tiny adapter! (vs LoRA which needs r×d_in)
 - Good for massive models

Quality trade-off:
 - IA³: 3M parameters, 92% quality
 - LoRA(r=8): 5M parameters, 95% quality
 - IA³ smaller but lower quality

4. Compacter (Parameterized Hypercomplex Multiplication)

Mathematical foundation: Hypercomplex numbers

Idea: Use hypercomplex structure for ultra-compact adapters

Architecture:
 Input (h)
 ↓
- ┌─────────────────────────────────────────┐
 - Hypercomplex transformation │
 - (Based on quaternion / octonion algebra)│
 - More compact than matrix operations │
 - ┬────────────────────────────┘
 ↓
 Output

Why ultra-compact:
 - Hypercomplex math: More structure, fewer parameters
 - Compacter(shared): <1M parameters for 7B model
 - But: More complex implementation
 - Trade: 0.1-0.2% additional quality loss vs LoRA

Use case:
 - When parameters must be absolute minimum
 - Extreme parameter budgets

Comparison Matrix

Method Parameters Memory Quality Expressiveness Implementation
────────────────────────────────────────────────────────────────────────────────
LoRA 0.1-1% Low 95% Good Simple
Bottleneck 0.2-0.5% Medium 98% Excellent Medium
Prefix Tuning 0.05-0.1% Very Low 90% Fair Simple
IA³ <0.01% Minimal 92% Limited Simple
Compacter <0.01% Minimal 93% Limited Complex
Full Fine-tune 100% Huge 100% Excellent Complex

Recommendation by use case:
 - Balanced: LoRA (industry standard)
 - High quality: Bottleneck adapters
 - Simplicity: Prefix tuning
 - Ultra-compact: IA³ or Compacter
 - Best possible: Full fine-tuning (if resources allow)

Combining Adapters

Multi-Adapter Fine-tuning

Single LLM, multiple adapters:

 LLaMA 7B (frozen)
 ↑
- ┌────────┼────────┐
 ↓ ↓ ↓
 LoRA₁ LoRA₂ LoRA₃
 (Task1) (Task2) (Task3)

Benefits:
 - Share base model (save memory)
 - Task-specific adapters (small)
 - Switch adapters at inference
 - Multi-task in single model!

Implementation:
 - Train LoRA₁ on task 1
 - Train LoRA₂ on task 2 (base model still frozen)
 - Train LoRA₃ on task 3
 - At inference: Load relevant LoRA
 - Total model: 7B + (0.06% × 3) ≈ 7B memory
 - vs 21B if separate models!

Merging Adapters

After training multiple adapters, optionally merge for efficiency:

Merge LoRA into weights:
 - W_merged = W + B × A (add LoRA to base)
 - At inference: Use W_merged directly
 - No overhead! (LoRA layers gone)
 - Can't switch tasks anymore

Use case:
 - Single-task deployment
 - Inference speed important
 - Training time amortized (merge once, use many times)

-

When to Use Which Adapter

Use LoRA When

Standard approach (default choice)
Good quality/efficiency balance needed
Multi-task learning
Cost-sensitive training
Parameter budget 0.1-1% of model size

Use Bottleneck Adapters When

Maximum quality important
Can afford 2-5x more parameters than LoRA
Complex adaptation needed
Non-linear transformations help

Use Prefix Tuning When

Minimal parameter budget (<0.05%)
Simplicity critical
Task can be expressed in prefix
Few inference tasks

Use IA³ When

Extreme parameter budgets
Scaling-based adaptation sufficient
Large models where 0.1% still matters
Memory is hardest constraint

-

Key Takeaways

LoRA: Best overall choice for efficiency + quality Bottleneck: Better quality, 2-5x more parameters Prefix Tuning: Simplest, smallest budget IA³/Compacter: Extreme minimalism, quality trade-off Multi-adapter: Share base, task-specific adapters

-

  • Lora - Detailed LoRA guide
  • Distributed Training - Train multiple adapters in parallel
  • [Model Merging & Ensemble Methods](/01-modeling/04-production/02-operations/(model-merging-ensemble-methods/) - Merge adapters with base model
  • Llm Inference Optimization - Adapter inference costs