Adapters are small trainable blocks inserted into the network. The big pretrained model stays mostly frozen. Each task gets a tiny side path that learns how to tweak the hidden states for that task.
Think of the base model as a shared engine. An adapter is a small bolt-on box for one job (support tickets, summarization, QA). You keep one engine and swap boxes.
Two practical requirements for good adapters:
The adapter sits in the main path (in the residual stream). Information flows through the adapter as part of the layer.
The adapter sits beside the main layer, then adds its output back to the original hidden state.
Plain picture of a common bottleneck adapter:
In words: new_hidden = old_hidden + up(relu(down(old_hidden)))
Why residual adapters are appealing for generation: they keep the original stream intact and inject task behavior more gently.
Adapters often work better when the input clearly marks the task — for example special tokens for QA segments (document, question, answer), or similar markers for dialogue and summarization. That structure gives the small module clearer patterns to learn.
| Idea | Plain-English idea |
|---|---|
| AdapterFusion | Combine several trained adapters so one task can borrow skills from others |
| Tiny-Attention Adapter | Keep the add-on small, but let it use a little attention to steer the base model |
| Multi-task / routing setups | Share or route among adapters instead of always training one giant fully tuned model |
Tuning only the top layers can work, but adapters are more modular:
Adapters add a small trainable module to a frozen backbone so each task gets its own cheap specialty without rewriting the whole model.