At some point while reading about transformers, you'll run into the terms "encoder" and "decoder." They sound technical, but the underlying idea is pretty intuitive once you see it.
An encoder takes something messy and variable — a sentence, an image, a document — and converts it into a structured internal representation. It's compression in the useful sense: all the meaning, none of the surface noise. The encoder doesn't produce an output the user sees. It produces something the rest of the model can work with.
A decoder takes that internal representation and turns it into something useful. In a translation model, the encoder processes the source language and the decoder generates the target language. In a language model, the decoder generates the next token based on everything that came before. In an image captioning system, the encoder processes the image and the decoder writes the description.
What made this a genuinely useful design insight is the separation. By splitting the "understand the input" job from the "produce the output" job, you can mix and match. An encoder trained on one kind of input can be paired with a decoder trained on a different kind of output. You can swap components, fine-tune one side without touching the other, and reuse representations across tasks. That flexibility is a big part of why transformer-based models have proven so adaptable.
Not every model uses both halves. Some tasks only need an encoder — when the goal is to understand or classify input rather than generate output. Others only need a decoder — when the goal is to generate text given a prompt. Large language models like GPT are decoder-only architectures, which is why they're so good at generation and why they work the way they do when you give them a prompt.


