Vol. 10 · ML & Decision Systems
BERT, Encoders & Non-Generative Models
Taxonomy of transformer architectures: encoder-only, decoder-only, encoder-decoder. How BERT works and why bidirectional is better to understand. BERT family. Fine-tuning patterns. T5 and seq2seq. When a small specialized model beats GPT-4. A practical map for choosing an architecture for a task.
Taxonomy: three families of architectures
01TaxonomyThree families of transformers: what each one can do
All modern NLP models are built on transformers, but they are designed fundamentally differently. The difference is not in “power” - but in how the model sees the text and what it can do with this knowledge. The choice of architecture is the first and most important engineering choice.
text┌────────────────────────────────── ───────────────────────────────────┐
│ ENCODER-ONLY ENCODER-DECODER DECODER-ONLY │
│ BERT, RoBERTa T5, BART, mT5 GPT, Llama │
│ DeBERTa, XLM-R FLAN-T5, mBART Claude, Mistral │
├────────────────────────────────── ───────────────────────────────────┤
│ Sees text: Sees text: Sees text: │
│ BIDIRECTIONAL input - bidirectional. ONLY on the left │
│ t₀↔t₁↔t₂↔t₃ exit - left→right t₀→t₁→t₂→t₃ │
├────────────────────────────────── ───────────────────────────────────┤
│ Learning Objective: Learning Objective: Learning Objective: │
│ Restore Transform Predict │
│ masked tokens input to output next token │
├────────────────────────────────── ───────────────────────────────────┤
│ Strengths: Strengths: Strengths: │
│ Understanding, embeddings Structural generation Free gen. │
│ Classification, NER Translation, summarization Reasoning │
│ Reranking, similarity Conditional generation Few-shot, RAG │
├────────────────────────────────── ───────────────────────────────────┤
│ Weaknesses: Weaknesses: Weaknesses: │
│ Does not generate text More difficult in deployment Worse to understand │
│ Fixed inlet length. More expensive encoder-only separate token │
└────────────────────────────────── ───────────────────────────────────┘key selection principle
- understand text → encoder-only
- convert A→B→encoder-decoder
- generate freely → decoder-only
- LLM can do all three - but it’s expensive and slow
02TaxonomyUnderstanding vs Generation: Different Tasks
“Understand” and “generate” are fundamentally different operations, and the architectures are optimized for each. Encoder reads everything at once and builds a deep understanding. Decoder only reads the past and predicts the future.
textUnderstanding (encoder):
input: complete sentence
attention: each token sees ALL others
output: enriched vectors of each token
→ perfect for “what does this word mean here?”
Generation (decoder):
input: everything that has happened so far
attention: causal mask - only the past
output: next token
→ perfect for “what’s coming next?”
Analogy:
Encoder = editor: reads the entire text,
understands every word in the context of everything
Decoder = writer: writes word by word,
each word knows only the previous ones03TaxonomyWhat it does “not LLM” mean: small vs large
"LLM" is an informal term for large decoder-only models. Encoder models are not LLMs not because they are bad, but because they solve other problems. BERT-base (110M parameters) vs GPT-4 (~1T) is not a “small LLM”, it is a different tool.
textWhat everyone has in common:
✓ Architecture: self-attention + MLP + residuals
✓ Training: gradient descent + backprop
✓ Tokenization: BPE or WordPiece
✓ Pretraining on a large text corpus
How are they different:
↔ attention direction (uni vs bidirectional)
↔ pre-training task (MLM vs CLM)
↔ size (110M vs 70B+ parameters)
↔ specialization (understanding vs generation)
All of them are neural networks, all of them are transformers.
"LLM" = large decoder, nothing more.How BERT works
04BERTMLM: Masked Language Modeling - BERT pre-training task
BERT is trained on the “recover a masked token” task. 15% of the tokens are randomly masked, and the model learns to predict them from the remaining ones. Because the model sees context from both sides, it is forced to learn to deeply understand the meaning of words.
textLogin (original):
"The cat is sitting on a warm windowsill"
Login for the model (with masks - 15% random tokens):
"Cat [MASK] on the [MASK] windowsill"
The model sees:
"Cat" ←→ "[MASK]" ←→ "on" ←→ "[MASK]" ←→ "windowsill"
↑ BIDIRECTIONAL attention: each token sees everything
Task: predict masked tokens
[MASK]₁ → softmax → P("sitting")=0.71, P("lying")=0.18, …
[MASK]₂ → softmax → P("warm")=0.54, P("cold")=0.23, …
Loss: cross-entropy only on masked tokens
Why is it smarter than CLM (predict next token):
CLM: "The cat is sitting" → predict "on" ← sees only the left context
MLM: "Cat [M] on [M] window sill" ← sees BOTH sides!
→ to guess [MASK]₁, you need to take into account both “cat” and “windowsill”
→ forces the model to understand syntax and semantics more deeplymasking details (original BERT)
- 80% → [MASK] is replaced by a mask
- 10% → replaced with a random token
- 10% → remains as is
- why not 100% masks: the model learns to “expect” regular tokens too
05BERTBidirectional vs Causal Attention
The main difference between BERT and GPT is the direction of attention. In BERT, each token can “look” at all others, including future ones. In GPT - only for past ones. This makes BERT better at understanding but unable to generate.
sqlBERT (bidirectional - entire matrix):
k o t s i d i t
to [✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓]
o [✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓]
t [✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓]
↑ "cat" knows "sits" during processing - from the future
GPT (causal - lower triangle):
k o t s i d i t
to [✓ ✗ ✗ ✗ ✗ ✗ ✗ ✗]
o [✓ ✓ ✗ ✗ ✗ ✗ ✗ ✗]
t [✓ ✓ ✓ ✗ ✗ ✗ ✗ ✗]
↑ "cat" does not know what will happen "sits" - only the past06BERT[CLS], [SEP] and the second NSP pretraining object
[CLS] is a special token at the beginning of each BERT input. After training, its vector aggregates the meaning of the entire sentence. NSP (Next Sentence Prediction) was the second learning object that forced [CLS] to understand the relationships between pairs of sentences.
sqlEntry format (one sentence):
[CLS] Cat sitting on the windowsill [SEP]
Entry format (a couple of sentences):
[CLS] Question [SEP] Answer [SEP]
[CLS] Text A [SEP] Text B [SEP]
NSP - pre-training task:
50%: [CLS] The cat is sitting. [SEP] He's watching. →IsNext
50%: [CLS] The cat is sitting. [SEP] Borscht recipe. →NotNext
predict: IsNext / NotNext from h[CLS]
Using [CLS] for fine-tuning:
h_cls = bert_output[0] ← vector [CLS] token
logits = Linear(h_cls, num_classes)
→ classification of the entire proposal
RoBERTa: NSP removed → quality increased07BERTWordPiece: BERT tokenization
BERT uses WordPiece, a variant of BPE. Rare words are broken into parts with the prefix “##”. This allows you to process unfamiliar words through morphemes and keep a dictionary of a reasonable size (~30k tokens).
text# Frequent words - one token:
"cat" → [cat]
"sits" → [sits]
# Rare words are broken:
"neural network" → [neuro, ##network]
"window sill" → [under, ##con, ##nick]
"tokenization" → [token, ##ization]
# Special tokens:
[CLS] → id: 101 ← beginning, aggregation of meaning
[SEP] → id: 102 ← sentence separator
[MASK]→ id: 103 ← mask for MLM
[UNK] → id: 100 ← unknown token
Vocab size BERT: ~30k (vs GPT-4: ~100k)
→ more fractional tokenization, but morphemicBERT family: evolution and variants
08FamilyRoBERTa: BERT without NSP and with more data
RoBERTa (2019, Meta) - retrained BERT with better hyperparameters. Three key changes: removed NSP (turned out to be useless), increased the batch by 8 times, trained 10x longer on a larger corpus. The result is a significant increase in all benchmarks.
textRemoved NSP:
→ BERT was trained to predict the “next sentence”
→ it turned out that this does not help downstream tasks
→ instead: pack full offers to 512 tokens
Dynamic Masking:
→ BERT: masks are fixed during preprocessing
→ RoBERTa: new masks every era
→ the model sees each sentence with different masks
Scale:
BERT: 16GB of text, 40 epochs, batch 256
RoBERTa: 160GB of text, batch 8192, longer training
Result: +2-5% on GLUE benchmarkwhen to choose RoBERTa vs BERT
- RoBERTa → almost always better than BERT
- roberta-base: 125M → fast
- roberta-large: 355M → more precisely
09FamilyDeBERTa: disentangled attention
DeBERTa (2021, Microsoft) - the best encoder-only for English. Key idea: separate the content of the token and its position in attention. Each pair of tokens has two attention scores: content-to-content and position-to-content.
textNormal attention:
score(i,j) = (H_i + P_i) · (H_j + P_j)ᵀ
↑ content and position mixed
DeBERTa disentangled:
score(i,j) = H_i·H_jᵀ ← content-to-content
+ H_i·P_{i→j}ᵀ ← content-to-position
+ P_{i→j}·H_jᵀ ← position-to-content
↑ relative positions instead of absolute ones
Enhanced Mask Decoder (EMD):
→ for MLM: a special layer returns
absolute positions before prediction
→ better at guessing disguised tokens
DeBERTa-v3: the best encoder for GLUE/SuperGLUE (2021-2023)10FamilyXLM-R: multilingual encoder
XLM-RoBERTa (2020, Meta) - RoBERTa trained in 100 languages simultaneously. The only model understands Russian, English, Chinese and 97 other languages. Zero-shot transfer: train on English data, apply on Russian.
textTraining:
2.5TB of text in 100 languages (Common Crawl)
vocab: 250k tokens (sentencepiece, multilingual BPE)
→ BERT: 30k monolingual. | XLM-R: 250k multilingual
Zero-shot transfer:
fine-tune on NER (English)
→ apply in Russian/Chinese/Arabic without additional data
→ works because tokens are in different languages
have similar embeddings if they mean the same thing
Dimensions:
xlm-roberta-base: 278M parameters
xlm-roberta-large: 560M parameters
For Russian NLP: standard baseline11FamilyModernBERT: BERT in 2024
ModernBERT (late 2024, Answer.AI + LightOn) - a complete rethinking of the encoder architecture using everything we learned in 6 years after BERT: RoPE, Flash Attention, SwiGLU, deep learning on 2T tokens. Beats DeBERTa at smaller sizes.
textArchitectural improvements:
✓ RoPE instead of learned positional embeddings
✓ Flash Attention 2 → faster + long contexts
✓ GeGLU instead of GELU activation
✓ Pre-norm (RMSNorm) as in Llama
✓ Context up to 8192 tokens (BERT: 512)
✓Alternating local+global attention
Data:
2T tokens (text + code)
→ understands code - unique to encoder
Dimensions:
modernbert-base: 149M
modernbert-large: 395M
→ the best choice for new projects (2025)Fine-tuning patterns for Encoder models
12Fine-tuningThree main fine-tuning patterns
Encoder models are universal “understanders” of text. A specific problem is solved by adding a small “head” on top of frozen or additionally trained scales. Three patterns cover 90% of real text problems.
text①SEQUENCE CLASSIFICATION (intent, sentiment, topic):
Input: "[CLS] What is the shipping price? [SEP]"
↓ BERT encoder (12 layers)
h_cls ∈ ℝ^768 ← vector [CLS]
↓ Linear(768 → num_classes) + softmax
P(shipping_query)=0.94, P(price_query)=0.04, …
② TOKEN CLASSIFICATION (NER, POS-tagging):
Input: "[CLS] Ivan Petrov bought a MacBook [SEP]"
↓BERT encoder
h_0 h_1 h_2 h_3 h_4 h_5 ← vector of each token
↓ Linear(768 → num_tags) for each position
O B-PER I-PER O B-PROD O
③ SENTENCE-PAIR (similarity, NLI, reranking):
Input: "[CLS] request [SEP] document [SEP]"
↓ BERT encoder
h_cls ∈ ℝ^768
↓ Linear(768 → 3) [entailment / neutral / contradiction]
attraction=0.91 ← relevant!which pattern for which task
- intent/tonality → sequence classification
- NER, entity extraction → token classification
- reranking, fact checking → sentence-pair
- embeddings → no head, take h_cls or mean
13Fine-tuningFine-tuning practice: hyperparameters
Fine-tuning an encoder model requires much less data and calculations than LLM training. 1000 examples are often enough for a good classification. The main danger is catastrophic forgetting when lr is too high.
sqlfrom transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(
"roberta-base",
num_labels=5
)
Recommended hyperparameters:
lr: 2e-5 – 5e-5 ← low! don't break pretrain
batch_size: 16 – 32
epochs: 3 – 5 ← retraining quickly
warmup: 6% steps
weight_decay: 0.01
Data:
100+ examples → works
1000+ examples → good
10k+ examples → excellent14Fine-tuningFine-tune encoder vs Prompt LLM: when and what
It is easier to launch LLM through a prompt, but it is expensive and slow at large volumes. Fine-tuned encoder is smaller, faster, cheaper - and often more accurate for a specific task. The choice depends on the volume of traffic, data availability and latency requirements.
| Fine-tuned Encoder | LLM (prompting) | |
|---|---|---|
| Data | need 100–10k examples | 0 (zero-shot) |
| Latency | 2–20ms | 200–2000ms |
| Cost | ~$0.00001/request | ~$0.001–0.01/request |
| Accuracy on task | high (specialization) | average (overall) |
| Flexibility | only one task | any task |
| Support | need MLOps | API |
15Fine-tuningKnowledge Distillation: small = fast
Distillation is training a small “student” model to copy the behavior of a large “teacher” model. DistilBERT has 66% of BERT parameters, is 60% faster and maintains 97% quality. Ideal for production with strict latency requirements.
textTeacher: BERT-large (340M), accurate
Student: DistilBERT (66M), fast
Student Loss = combination of three goals:
① Distillation loss:
KL(softmax(logits_student / T) ‖ softmax(logits_teacher / T))
T=temperature→ soft probabilities = “dark knowledge”
② Cosine embedding loss:
hidden states of student ≈ teacher
③ MLM loss:
standard training on masked tokens
Popular distilled models:
DistilBERT: 66M, 60% faster, 97% BERT quality
TinyBERT: 15M, 9.4× faster, 96% quality
MobileBERT: 25M, edge deploymentEncoder-Decoder: T5, BART and Seq2Seq
16Encoder-DecoderSeq2Seq: encoder understands, decoder creates
Encoder-decoder is an original transformer architecture from Attention Is All You Need. Encoder reads the entire input (bidirectional), builds its representation; decoder generates output using cross-attention to encoder representations. Ideal for "convert A to B" tasks.
textArchitecture (example: translation):
Entry: "The cat sat on the mat"
↓
┌─────────────────── ────────────────────┐
│ ENCODER (bidirectional self-attention)│
│ h₁ h₂ h₃ h₄ h₅ h₆ │
│ The cat sat on the mat │
└─────────────────── ┬───────────────────┘
│ cross-attention
↓ (decoder looks at ALL h encoder)
┌─────────────────── ────────────────────┐
│ DECODER (causal + cross-attention) │
│ [START] → Cat → sat → on → … │
│ │
│ At every step: │
│ 1. Causal self-attn (past tokens) │
│ 2. Cross-attention to encoder h₁..h₆ │
│ 3. FFN → logits → next token │
└─────────────────── ────────────────────┘
Why is it better than decoder-only for translation:
→ encoder reads the entire input phrase ENTIRELY
→ decoder knows when generating each word
ALL source text via cross-attention
→ less “forgetting” of long inputsproblems where seq2seq is better than decoder-only LLM
- machine translation (fixed languages)
- summation with length control
- grammatical correction
- extracting structure from text
- requires more memory than encoder-only
17Encoder-DecoderT5: «Text-to-Text Transfer Transformer»
T5 (2020, Google) - unified frame: ALL tasks are formulated as “text → text”. Translation: “translate English to German: The cat...”. Summarize: “summarize: …”. This allows you to train one model on everything at once.
text# All tasks are in the same format:
"translate English to Russian: Hello world"
→ "Hello world"
"summarize: [long text...]"
→ "Summary: ..."
"sst2 sentence: I love this movie"
→ "positive"
"cola sentence: The cat sat"
→ "acceptable"
FLAN-T5 (2022):
→ T5 + instruction tuning on 1000+ tasks
→ follows instructions like LLM, but less
→ flan-t5-large (780M) vs GPT-3 (175B)
→ wins on structured generation18Encoder-DecoderBART: denoising pretraining
BART (2020, Meta) - encoder-decoder with pre-training through denoising: the input is deliberately “spoilt” (fragments are removed, sentences are rearranged, spans are masked), the decoder learns to restore the original. Particularly good for summarization.
sqlOriginal: "The cat sat on the warm windowsill and watched"
Token masking: "The cat [M] was on the [M] windowsill watching"
Token deletion: "The cat was watching on the warm windowsill"
Text infilling: "The cat [M M M] was looking" ← one [M] = many words
Sentence permut: "I looked. The cat was sitting on the windowsill and"
Document rotation: start from the middle
Why does this help summarization:
→ infilling = generating a missing fragment
→ summarization = generation of a “compressed” fragment
→ structurally similar tasks
mBART: multilingual BART, 25 languages, including ruWhen a small model beats GPT-4
19ComparisonTriangle: Latency · Cost · Accuracy
Choosing a model is always a compromise of three parameters. GPT-4 is the most powerful in terms of accuracy, but the most expensive and slow. Fine-tuned RoBERTa is the fastest and cheapest. The key question is: How complex is your specific problem?
textReal numbers (2025, typical production):
Model Latency Cost/1M Accuracy Parameters
───────────────────────────── ──────────────────────────────
fine-tuned roberta 3ms $0.01 96% 125M
fine-tuned deberta 8ms $0.02 97.5% 184M
claude-haiku-3-5 300ms $0.80 91% ~20B?
gpt-4o-mini 400ms $0.60 93% ~20B?
claude-sonnet-4-6 1200ms $15.00 99% ~200B?
gpt-4o 1500ms $10.00 98% ~200B?
───────────────────────────── ──────────────────────────────
* accuracy for the intent classification task with 5000 examples
Conclusion: fine-tuned RoBERTa is 100x cheaper and 400x faster
GPT-4 gives only ~3% increase in accuracy.
At 1M requests/day: $10 vs $10,000 per day.
When GPT-4 is needed:
→ the task requires reasoning through several steps
→ no marked data for fine-tuning
→ the task changes every day
→ need a detailed text answer20ComparisonProblems where encoder-only reliably wins
There are categories of tasks where specialized encoder models consistently outperform LLM in all three parameters - not only in speed and price, but also in accuracy. These are tasks with a clear structure and a sufficient amount of training data.
text① Classification of intents (IntentRouter):
fine-tuned RoBERTa: 96.5% F1, 3ms
claude-haiku prompt: 91.2% F1, 280ms
→ 100x faster, more precisely, 80x cheaper
② NER (Entity Extraction):
fine-tuned BERT/DeBERTa: F1=0.92
GPT-4 prompting: F1=0.87
→ encoder is more accurate on clearly labeled data
③ Reranking in RAG:
cross-encoder reranker: NDCG@10=0.74
embedding cosine: NDCG@10=0.61
→ cross-encoder sees query+doc together
④ Semantic similarity (deduplication):
bi-encoder (E5): 50k par/sec
LLM: 10 pairs/sec
→ scale is not possible with LLM
⑤ Content moderation:
fine-tuned toxicity classifier: 0.5ms/request
→ should be cheaper than the LLM request itself21ComparisonCascade pipeline: small + large
The best strategy is not to choose one model, but to build a cascade: fast specialized models filter and route, LLM is called only where the “heavy artillery” is needed. This is exactly how production systems with high traffic work.
textUser request
↓
[RoBERTa IntentClassifier] 3ms, $0.00001
intent="price_query" (conf=0.96) → PriceAgent
intent="complaint" (conf=0.91) → ComplaintAgent
intent="unclear" (conf=0.43) → ↓ (LLM needed)
↓
[Claude Haiku] 280ms, $0.001
clarification?
simple_task? → answer directly
complex? → ↓
[Claude Sonnet] 1200ms, $0.015
Typical traffic statistics:
70% → RoBERTa copes ($0.00001/request)
25% → Haiku ($0.001/request)
5% → Sonnet ($0.015/request)
Average cost: ~$0.002 (vs $0.015 if everything is on Sonnet)Practical architecture selection map
22Selection cardDecision tree: task → architecture → model
Structured choice. Start with the type of task, take into account the availability of data and latency requirements - get a specific model recommendation.
textNeed to GENERATE text?
No → continue below
Yes → fixed structure A→B? (translation, summarization)
Yes → Encoder-Decoder: T5, FLAN-T5, BART, mBART
No → free generation, reasoning, dialogue
→ Decoder-only LLM: Claude, GPT-4o, Llama-3
────────────────────────── ───────────────────────────
Task type (without generation):
Text classification (intent, sentiment, topic, toxicity)
Are there 500+ examples?
Yes → fine-tuned RoBERTa / DeBERTa / ModernBERT
No → zero-shot Claude Haiku / GPT-4o-mini
Entity extraction (NER, spans)
Are there 200+ marked up offers?
Yes → fine-tuned BERT / RoBERTa (token classification)
No -> LLM with JSON output
Semantic embeddings (search, clustering, deduplication)
Do you need Multilingual?
Yes → multilingual-e5, paraphrase-multilingual-mpnet
No → E5-large-v2, BGE-large-en, nomic-embed-text
Reranking (clarification of top-K RAG results)
→ cross-encoder: bge-reranker-v2, ms-marco-MiniLM
Sentence similarity/Textual Entailment
→ fine-tuned DeBERTa-NLI, SBERT
Multilingual classification
→ fine-tuned XLM-RoBERTa23Selection cardQuick Reference: models and their niches
A cheat sheet for specific models for quick selection at the start of the project.
| Model | Size | Best use |
|---|---|---|
| ModernBERT-base | 149M | classification, NER, 2025 |
| DeBERTa-v3-base | 184M | NLI, QA, best EN encoder |
| RoBERTa-base | 125M | classification, fast |
| XLM-RoBERTa-base | 278M | multilingual, including RU |
| E5-large-v2 | 335M | embeddings for EN search |
| multilingual-e5 | 278M | multilingual embeddings |
| bge-reranker-v2-m3 | 568M | reranking RAG |
| FLAN-T5-large | 780M | structured generation |
| DistilBERT | 66M | edge/mobile deployment |
all available at
- huggingface.co/models
- pip install transformers
- sentence-transformers for embeddings
No dead end
Keep moving through the map.
Continue in sequence, switch to a related guide, or return to the seven-track learning map.