Deep Learning · NLP

Развитие трансформеров от BERT до GPT-3 и дальше

Семь лет стремительного прогресса: от word2vec до моделей с сотнями миллиардов параметров. Разбираем архитектуры, задачи предобучения, алгоритмы токенизации и практику дообучения — с формулами, кодом и примерами.

Encoder-only (BERT) Decoder-only (GPT) Encoder-Decoder (T5/BART) BPE · WordPiece · SentencePiece

🗓 Хронология ключевых моделей (2013–2023)

2013 2015 2017 2018 2019 2020 2021 2022 2023 word2vec GloVe ELMo ⚡ Attention Is All You Need BERT GPT RoBERTa ALBERT GPT-2 T5 GPT-3 DistilBERT BART InstrGPT ChatGPT GPT-4 LLaMA Encoder-only Decoder-only Enc-Dec
Часть I · 2013–2018

NLP до эпохи трансформеров

Чтобы понять революцию BERT, нужно знать, что было до него — и почему это не работало достаточно хорошо.

Word2Vec и GloVe: статические эмбеддинги

В 2013 году Томас Миколов (Google) представил word2vec — первый практичный метод получения плотных векторных представлений слов. Идея проста: слова, встречающиеся в похожих контекстах, должны иметь близкие векторы.

Два варианта архитектуры:

1
CBOW (Continuous Bag-of-Words): по окружающим словам предсказать центральное. «The ___ sat on» → «cat». Быстрее, лучше для частых слов.
2
Skip-gram: по центральному слову предсказать окружающие. «cat» → {«the», «sat», «on», «mat»}. Точнее для редких слов.
# Задача Skip-gram: максимизировать вероятность контекста
max Σ Σ log P(wₒ | wc)
для каждого центрального слова wc и контекстного wₒ в окне размера k

P(wₒ | wc) = exp(uₒᵀ · vc) / Σⱼ exp(uⱼᵀ · vc)
# vc — эмбеддинг центрального слова; uₒ — эмбеддинг контекстного

Знаменитый пример: king − man + woman ≈ queen. Арифметика над векторами отражает семантические отношения.

GloVe (Pennington et al., Stanford, 2014) использует глобальную матрицу совместной встречаемости. Цель — чтобы скалярное произведение векторов приближало логарифм вероятности совместной встречаемости: wᵢ · wⱼ ≈ log P(i|j).

⚠️
Фундаментальная проблема статических эмбеддингов Слово «замок» в «взять замок» и «посетить замок» получает один и тот же вектор — несмотря на разный смысл. Полисемия (многозначность) неразрешима статическими методами. Именно это ограничение устранил ELMo, а затем — трансформеры.

ELMo: первые контекстуальные эмбеддинги

ELMo (Embeddings from Language Models, Peters et al., AllenAI, 2018) — переломный момент перед BERT. Вместо одного вектора на слово ELMo строит представление на основе всего контекста, используя двунаправленный LSTM.

ELMo(токен) = γ · Σₖ sₖ · hₖ
# hₖ — скрытое состояние k-го слоя biLSTM
# sₖ — обучаемые веса для каждого слоя
# γ — масштабирующий параметр задачи

ELMo предобучается на задаче языкового моделирования: предсказать следующее слово (вперёд) и предыдущее (назад). Это первый пример transfer learning в NLP в современном понимании — предобучение на большом корпусе, затем добавление эмбеддингов в downstream-модель.

🔍
Разные слои ELMo кодируют разную информацию Исследования Peters et al. показали: нижние слои biLSTM лучше кодируют синтаксис (части речи, зависимости), а верхние — семантику (смысл, кореференцию). Это первое прямое свидетельство иерархии представлений в языковых моделях.

Ограничение ELMo: два отдельных однонаправленных LSTM — не по-настоящему двунаправленная модель. Forward и backward сети обучаются независимо, их представления просто конкатенируются. BERT решит это с помощью по-настоящему двунаправленного attention.

Часть II · Google AI, октябрь 2018

BERT: двунаправленный трансформер

«BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding» — статья, изменившая NLP. Авторы: Devlin, Chang, Lee, Toutanova (Google AI).

Задача 1: Masked Language Modeling (MLM)

Это центральная инновация BERT. Суть: случайно заменить 15% токенов на [MASK] и обучить модель их восстанавливать, имея доступ к обоим контекстам — левому и правому. Это делает модель по-настоящему двунаправленной.

MLM: модель видит [MASK] и должна восстановить исходный токен [CLS] the [MASK] sat on [MASK] mat [SEP] BERT Encoder (12 слоёв Self-Attention) — видит ВЕСЬ контекст «cat» ✓ «the» ✓ 15% токенов: 80% → [MASK] 10% → рандом 10% → исходный Зачем не 100% mask? Инференс никогда не видит [MASK]!
🎯
Почему именно 80/10/10, а не просто 100% [MASK]? Если всегда заменять на [MASK], возникает несоответствие между предобучением и инференсом — на инференсе [MASK] нет никогда. Маскируя только 80%, а в остальных 20% оставляя исходный токен или ставя случайный, модель вынуждена строить хорошее контекстуальное представление для каждого токена, а не только для замаскированных.

Задача 2: Next Sentence Prediction (NSP)

BERT также предобучается предсказывать, является ли предложение B продолжением предложения A или взято случайно из корпуса.

IsNext = True (50% примеров) [CLS] Кот сидел на коврике. [SEP] Коврик был красным. [SEP] ← реальное продолжение из текста NotNext = False (50% примеров) [CLS] Кот сидел на коврике. [SEP] Экономика Японии растёт. [SEP] ← случайное предложение из корпуса

Вектор [CLS] после BERT подаётся на бинарный классификатор IsNext/NotNext. Цель — научить модель понимать межпредложенческие отношения, что важно для задач QA и NLI.

📌
NSP позже переосмыслили RoBERTa (2019) показала, что NSP либо вредит, либо не помогает — модель учится тривиально различать предложения по распределению токенов, а не по семантике. RoBERTa убрала NSP и улучшила результаты. ALBERT заменила NSP на SOP (Sentence Order Prediction) — более сложную задачу.

Архитектурные детали BERT

ПараметрBERT-BaseBERT-Large
Слои (L)1224
Скрытый размер (H)7681024
Головы внимания (A)1216
Параметров110M340M
Корпус предобученияBooksCorpus (800M слов) + English Wikipedia (2500M слов)
ТокенизацияWordPiece, vocab 30 522 токена
Макс. длина512 токенов
Время предобучения4 дня на 16 TPU v34 дня на 64 TPU v3
Входное представление BERT = Token + Segment + Position эмбеддинги Токены: [CLS] my dog [SEP] he ##llo [SEP] Сегмент: A A A A B B B Позиция: 0 1 2 3 4 5 6 Σ Token E + Segment E + Position E = вход в BERT слои ## = субслово WordPiece
Часть III · 2019

Варианты и улучшения BERT

За год после выхода BERT исследователи опубликовали десятки вариантов. Вот самые важные и их архитектурные новшества.

RoBERTa (Facebook AI, июль 2019)

RoBERTa (Robustly Optimized BERT Approach, Лю и др.) — это не новая архитектура, а тщательное исследование того, что реально важно при обучении BERT. Вывод: оригинальный BERT был недообучен.

Изменение 1

Убрали NSP

Next Sentence Prediction не помогала или даже вредила. Убрали, обучали только на MLM.

Изменение 2

Динамическое маскирование

BERT маскировал токены один раз при создании данных. RoBERTa генерирует новые маски на каждом шаге — сложнее переобучиться.

Изменение 3

Больше данных и батч

160GB текста вместо 16GB. Батч 8K примеров вместо 256. Обучение 500K шагов.

Изменение 4

Длинные последовательности

Обучение на полных предложениях длиной до 512 токенов с самого начала, без коротких последовательностей.

Результат: RoBERTa превзошла BERT на всех бенчмарках GLUE, SQuAD и RACE — просто за счёт правильного обучения. Ключевой вывод: масштаб данных и вычислений имеет огромное значение.

DistilBERT (Hugging Face, октябрь 2019)

Виктор Санс и соавторы предложили дистилляцию знаний (knowledge distillation): маленькая «студенческая» сеть учится имитировать большую «учительскую».

# Функция потерь дистилляции = взвешенная сумма трёх компонент
L = α · L_MLM + β · L_distil + γ · L_cosine

L_distil = KL(softmax(zₛ/T) ‖ softmax(zₜ/T)) ← «мягкие» метки учителя
L_cosine = 1 − cos(hₛ, hₜ) ← выровнять скрытые состояния
# T — температура; высокая T смягчает распределение учителя
BERT-BaseDistilBERTИзменение
Параметров110M66M−40%
Скорость инференса×1×1.6+60%
Размер модели438 MB255 MB−42%
GLUE score79.677.0−97% качества сохранено
Слои126Убраны нечётные слои

ALBERT (Google Research, сентябрь 2019)

ALBERT (A Lite BERT) решает проблему памяти BERT с помощью двух архитектурных новшеств:

A
Факторизация матрицы эмбеддингов: в BERT размер словарного эмбеддинга равен размеру скрытого слоя H=768. Но это расточительно — словарные эмбеддинги контекстно-независимы и не нуждаются в большом H. ALBERT делает E ≪ H (например, E=128, H=768), снижая число параметров с V×H до V×E + E×H.
B
Разделение весов между слоями: все 12 (или 24) трансформер-слоёв используют одни и те же веса. Модель обрабатывает вход итеративно через один и тот же слой. Параметры: ALBERT-xxlarge = 235M (vs 340M BERT-Large), при этом превосходит BERT-Large.
C
SOP вместо NSP: Sentence Order Prediction — различить A→B и B→A (поменянные местами). Это требует реального понимания семантики, а не статистики токенов.
Сравнение параметризации: BERT vs ALBERT BERT-Base Vocab Embedding: 30K × 768 = 23M Layer 1 (unique weights) Layer 2 (unique weights) ⋮ (12 уникальных слоёв) Итого: ~110M параметров ALBERT-Base Vocab E: 30K×128=3.8M Projection: 128→768=0.1M Единственный слой (применяется 12 раз) ↑ weight sharing Итого: ~12M параметров (−89%!) факторизация + sharing
Часть IV · OpenAI 2018–2020

Декодерные модели: GPT-серия

Пока Google шёл путём encoder-only (двунаправленный контекст для понимания), OpenAI сделал ставку на decoder-only (авторегрессионная генерация).

GPT и GPT-2: авторегрессионное языковое моделирование

GPT (Generative Pre-trained Transformer, Radford et al., 2018) использует только decoder-часть трансформера. Задача предобучения — Causal Language Modeling (CLM): предсказать следующий токен, зная все предыдущие.

L(U) = Σᵢ log P(uᵢ | uᵢ₋ₖ, …, uᵢ₋₁; Θ)
# U — корпус токенов, k — размер контекстного окна
# Внимание — только влево (causal / masked attention)
Маска внимания: BERT (полная) vs GPT (каузальная) BERT: видит всё 4×4, все ячейки активны GPT: только прошлое нижний треугольник × × × × × ×

GPT-2 (февраль 2019) — та же архитектура, но в 10× крупнее: 1.5B параметров (GPT-2 XL), обучен на WebText (40GB текста с Reddit). Openai первоначально отказалась публиковать полную модель из-за опасений по поводу дипфейков и дезинформации. GPT-2 продемонстрировал zero-shot способности: без дообучения показал конкурентные результаты на задачах чтения с пониманием и суммаризации.

GPT-3: масштаб как стратегия

GPT-3 (Brown et al., OpenAI, май 2020) — 175B параметров, обучен на 300B токенов (Common Crawl, WebText, Books, Wikipedia). Архитектурно — тот же decoder-only трансформер, но огромный.

ВерсияПараметрыСлоиd_modelГоловыКонтекст
GPT-3 Small125M12768122048
GPT-3 Medium350M241024162048
GPT-3 Large760M241536162048
GPT-3 (full)175B9612288962048

In-context learning — главное открытие GPT-3. Не нужно обновлять веса. Достаточно показать несколько примеров прямо в prompt:

# Few-shot перевод без fine-tuning:
"""
Переведи на французский:
sea otter → loutre de mer
peppermint → menthe poivrée  
plush giraffe → girafe en peluche
cheese →
"""
# GPT-3 продолжит: fromage
💡
Почему работает in-context learning? GPT-3 не обучается на примерах в prompt — он только читает контекст. Механизм не до конца понят. Текущая гипотеза: при предобучении на огромном корпусе модель видит тысячи «случайных» few-shot паттернов. Attention позволяет ей «выбирать» нужный паттерн из примеров в контексте, имитируя обновление весов через кэш K/V в слоях attention.
Часть V · Google & Facebook 2019–2020

Encoder-Decoder модели: T5 и BART

Что если сформулировать любую NLP-задачу как преобразование текста в текст? T5 и BART реализуют именно этот подход.

T5: Text-to-Text Transfer Transformer

T5 (Raffel et al., Google, 2019) унифицирует все NLP-задачи под один формат: вход и выход — всегда текст. Это устраняет необходимость в задача-специфичных головах.

T5: все задачи — это text-to-text T5 Enc-Dec Задача → вход T5 translate English to German: That is good summarize: Scientists discover new... mnli premise: … hypothesis: … cola sentence: The cat sat. question: Who... context: … Выход T5 Das ist gut Scientists found a new species in… entailment acceptable The cat

T5 предобучается на задаче Span Corruption — вариант MLM, но маскируются и восстанавливаются целые отрезки текста (spans), а не отдельные токены. Вход: «Thank you me to your party week», выход: « for inviting last».

T5 обучался на C4 (Colossal Clean Crawled Corpus) — 750GB очищенного CommonCrawl. Самая большая версия T5-11B имеет 11 миллиардов параметров.

BART: двунаправленный авторегрессионный трансформер

BART (Lewis et al., Facebook AI, 2019) — encoder-decoder модель, предобученная на задаче реконструкции повреждённого текста. Ключевое отличие от T5: BART использует BERT-подобный энкодер (полное двунаправленное внимание) и GPT-подобный декодер (авторегрессионный).

BART экспериментировал с разными схемами «порчи» текста:

Схема 1

Token Masking

Как в BERT: случайные токены заменяются на [MASK]. Декодер восстанавливает их.

Схема 2

Token Deletion

Токены удаляются (без [MASK]). Модель должна решить, где были пропуски — сложнее.

Схема 3

Text Infilling

Span из 0-нескольких токенов заменяется одним [MASK]. Похоже на T5 Span Corruption.

Схема 4

Sentence Permutation

Предложения в документе перемешиваются случайно. Модель восстанавливает порядок.

Схема 5 (лучшая)

Document Rotation

Документ начинается с случайного токена — модель определяет «настоящее» начало.

BART показал SOTA на задачах суммаризации (CNN/DM, XSum), машинного перевода и диалоговых систем. Для суммаризации особенно эффективен: энкодер кодирует полный документ, декодер генерирует краткое изложение.

Часть VI · Практика

Дообучение BERT для downstream-задач

Предобученный BERT — это универсальная основа. Добавив минимальный «голос» поверх неё и дообучив на задача-специфичных данных, получаем SOTA на большинстве NLP-задач.

Общая стратегия fine-tuning

1
Загрузить предобученные веса: BertModel.from_pretrained('bert-base-uncased')
2
Добавить task-specific голову: линейный слой поверх нужного выхода BERT (CLS, токен-уровень и т.д.)
3
Обучить все веса совместно: очень низкий LR (2e-5 — 5e-5), 2–4 эпохи. Если данных мало — заморозить нижние слои BERT.
4
Оценить: на dev-сете по метрике задачи (accuracy, F1, EM и т.д.)
📊 Классификация
🏷️ NER
❓ QA (SQuAD)

Классификация текста (Sequence Classification)

Для классификации (тональность, тематика, NLI) используется вектор специального токена [CLS] — BERT обучен вкладывать в него «резюме» всего предложения. Поверх него — линейный слой с softmax.

Классификация: используем только вектор [CLS] [CLS] This film is great BERT (12 слоёв) h[CLS] Linear(768,2) softmax Positive 0.92
from transformers import BertForSequenceClassification, BertTokenizer
import torch

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained(
    'bert-base-uncased',
    num_labels=2  # positive / negative
)

text = "This film is absolutely great!"
inputs = tokenizer(text, return_tensors='pt', truncation=True, max_length=512)
# inputs = {input_ids, attention_mask, token_type_ids}

with torch.no_grad():
    outputs = model(**inputs)
    logits = outputs.logits          # (1, 2)
    probs = logits.softmax(dim=-1)  # [0.08, 0.92]
    label = probs.argmax()         # 1 → Positive

# Fine-tuning loop:
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)
loss_fn = torch.nn.CrossEntropyLoss()

for batch in train_loader:
    outputs = model(**batch['inputs'], labels=batch['labels'])
    loss = outputs.loss  # BertForSequenceClassification считает loss сам
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

Named Entity Recognition (NER)

NER — задача на уровне токенов. Каждому токену нужно присвоить метку: PER (персона), ORG (организация), LOC (локация), O (нет сущности). Используем выходы BERT для каждого токена, а не только [CLS].

NER: классификатор на каждом токене (схема BIO) Barack Obama visited Berlin BERT B-PER I-PER O B-LOC B- = начало сущности I- = продолжение O = не сущность Linear(768, num_labels) применяется к каждому токену
from transformers import BertForTokenClassification

label2id = {"O":0, "B-PER":1, "I-PER":2, "B-ORG":3, "I-ORG":4,
            "B-LOC":5, "I-LOC":6}

model = BertForTokenClassification.from_pretrained(
    'bert-base-cased',  # cased важен для NER!
    num_labels=len(label2id)
)
# BertForTokenClassification внутри:
# self.bert → скрытые состояния (B, T, 768)
# self.dropout
# self.classifier = Linear(768, num_labels)  ← для каждого токена

# Важно: для WordPiece субтокенов используем метку только первого субтокена
# "Barack" → ["Bar", "##ack"] → метка B-PER только для "Bar", ##ack → -100
labels = [1, -100, 2, 0, 5]  # -100 игнорируется в CrossEntropy
📌
Субтокены и NER WordPiece разбивает «Washington» на [«Washington»] — всё хорошо. Но «Schwarzenegger» → [«Schwar», «##zen», «##egg», «##er»]. Нужно решить: давать метку каждому субтокену или только первому? Стандарт — метка только первого субтокена, остальным ставится -100 (игнорируется при расчёте loss). После инференса метка первого субтокена приписывается всему слову.

Question Answering на SQuAD

SQuAD (Stanford Question Answering Dataset) — задача extractive QA: дан контекст-абзац и вопрос, нужно найти отрезок (span) в контексте, являющийся ответом.

BERT решает это элегантно: вход = [CLS] вопрос [SEP] контекст [SEP]. Для каждого токена контекста предсказываем: является ли он началом ответа (start) или концом ответа (end) — два отдельных линейных слоя.

SQuAD: предсказание start и end позиций ответа [CLS] Who wrote BERT? [SEP] The Devlin team at Google BERT START END W_start: (768,) вектор score_i = hᵢ · W_start → softmax → argmax Ответ: «Devlin»
score_start(i) = hᵢ · Wₛ ← скалярная оценка для каждой позиции i
score_end(i) = hᵢ · Wₑ
P_start = softmax(score_start) ← вероятность того, что i — начало ответа
P_end = softmax(score_end)
answer = tokens[argmax(P_start) : argmax(P_end)+1]

Результаты на SQuAD 2.0: BERT-Large достиг F1 = 83.1 (человек ~86.8), превзойдя все предыдущие методы сразу после выхода.

Часть VII · Алгоритмы

Алгоритмы токенизации

Токенизатор — первый и критически важный компонент любой языковой модели. От его выбора зависит эффективность словаря, качество на редких словах и кросс-языковое обобщение.

Зачем субслова, а не целые слова?

Проблема словарного подхода (word-level): Английский имеет 170 000+ слов; OOV (out-of-vocabulary) слова — постоянная проблема. «Нейрокомпьютер», «GPT-4o», «anti-establishment» — новые слова постоянно появляются.

Проблема символьного подхода (char-level): Слишком длинные последовательности. «Hello» = 5 токенов; документ из 1000 слов = ~5000 токенов. Контекстное окно BERT = 512 токенов.

Субсловный подход — золотая середина: редкие слова разбиваются на известные подстроки, частые слова остаются целыми. «Tokenization» → [«Token», «##ization»].

🔬 Интерактивный токенизатор (имитация)
Нажмите кнопку для токенизации...

BPE — Byte Pair Encoding

Предложен Сеннрихом (2015) для машинного перевода; используется в GPT, GPT-2, GPT-3, RoBERTa.

Алгоритм обучения:

1
Инициализация: словарь = все отдельные символы + специальный символ конца слова (Ġ в GPT-2, в оригинале)
2
Подсчёт пар: найти самую частую соседнюю пару символов/субслов в корпусе
3
Слияние: добавить пару как новый токен в словарь, заменить все вхождения в корпусе
4
Повторять шаги 2–3 V раз (V — целевой размер словаря, например 50 000)
BPE: пошаговый пример на микро-корпусе Шаг 0: корпус «low» ×5, «lower» ×2, «newest» ×6, «wider» ×3 Символьный: l-o-w, l-o-w-e-r, n-e-w-e-s-t, w-i-d-e-r Шаг 1: частейшая пара «e»+«s» (6 раз) «es» добавляется в словарь → n-e-w-es-t Шаг 2: частейшая пара «es»+«t» (6 раз) «est» добавляется → n-e-w-est После V итераций: «low», «er», «new», «est», «wid» — части сохраняются как токены GPT-2 BPE: • Vocab: 50 257 токенов • Работает на байтах (нет OOV вообще!) • Ġ = пробел перед словом «Hello world» → [«Hello», «Ġworld»] «unbelievable» → [«un», «bel», «iev», «able»]

WordPiece (BERT)

WordPiece — вариант BPE, разработанный Google (Schuster & Nakamura, 2012) для системы голосового ввода японского и корейского, затем адаптированный для BERT. Ключевое отличие: критерий слияния основан на вероятности, а не частоте.

score(A, B) = P(AB) / (P(A) · P(B))
# Выбираем пару, которая максимизирует likelihood корпуса
# Эквивалентно: maximize P(corpus | vocabulary)

Два ключевых отличия от BPE в контексте BERT:

A
Разметка субтокенов: если слово разбивается, все части кроме первой получают префикс ##. «playing» → [«play», «##ing»]. Это позволяет восстановить исходное слово.
B
Разбиение слева направо: при токенизации нового текста сначала пробуем взять максимально длинную подстроку, входящую в словарь, затем двигаемся вправо (greedy longest-match).
# WordPiece токенизация: пример вручную
vocab = {"un", "##believ", "##able", "unbelievable", ...}

word = "unbelievable"
# Greedy: «unbelievable» → в словаре? Нет.
#         «unbelievabl» → нет. ... → «un» → ДА. Берём.
#         остаток «believable» → «##believ» → ДА. Берём.
#         остаток «able» → «##able» → ДА. Берём.
tokens = ["un", "##believ", "##able"]

# BERT tokenizer через HuggingFace:
from transformers import BertTokenizer
tok = BertTokenizer.from_pretrained('bert-base-uncased')
print(tok.tokenize("unbelievable"))
# → ['un', '##believ', '##able']
print(tok.tokenize("The cat sat on the mat."))
# → ['the', 'cat', 'sat', 'on', 'the', 'mat', '.']

SentencePiece (T5, LLaMA)

SentencePiece (Kudo & Richardson, Google, 2018) — универсальная библиотека токенизации, реализующая BPE и Unigram Language Model. Ключевое отличие от WordPiece и BPE: работает напрямую с необработанным текстом, без предварительной токенизации по пробелам.

🌐
Зачем это важно для многоязычных моделей? В японском, китайском, тайском — нет пробелов между словами. BPE и WordPiece требуют предварительного разбиения по пробелам и не работают для этих языков «из коробки». SentencePiece рассматривает весь текст как поток символов, включая пробелы (кодируются как «▁»). Это делает его language-agnostic.

SentencePiece поддерживает два алгоритма обучения словаря:

BPE mode

BPE в SentencePiece

Тот же алгоритм слияний, что и оригинальный BPE, но без пре-токенизации. Используется в XLM, некоторых версиях T5.

Unigram LM mode

Unigram Language Model

Начинает с большого словаря, итеративно удаляет наименее полезные токены. Используется в T5, ALBERT, mBART. Позволяет вероятностную токенизацию (data augmentation).

import sentencepiece as spm

# Обучение
spm.SentencePieceTrainer.train(
    input='corpus.txt',
    model_prefix='spm_model',
    vocab_size=32000,
    character_coverage=0.9995,  # для не-латинских скриптов
    model_type='bpe'           # или 'unigram'
)

# Применение
sp = spm.SentencePieceProcessor()
sp.load('spm_model.model')

print(sp.encode('Hello World', out_type=str))
# → ['▁Hello', '▁World']  # ▁ = пробел перед словом

print(sp.encode('Непредсказуемость', out_type=str))
# → ['▁Не', 'пред', 'сказ', 'уем', 'ость']
АлгоритмМоделиVocabПре-токенизацияOOVОсобенность
BPE GPT, GPT-2/3, RoBERTa 50K По пробелам Нет (byte-level) Частотный критерий слияния
WordPiece BERT, DistilBERT, ALBERT 30K По пробелам [UNK] ## для субтокенов; likelihood критерий
SentencePiece (BPE) XLM-R, некоторые T5 32K–250K Нет (▁ = пробел) Нет Language-agnostic
SentencePiece (Unigram) T5, ALBERT, mBART, LLaMA 32K Нет Нет Вероятностная токенизация
⚠️
Токенизатор влияет на качество и эффективность Плохо откалиброванный словарь означает: (1) числа «1234» → [«1», «2», «3», «4»] — 4 токена вместо 1; (2) редкие языки = больше токенов = меньше информации в окне 512; (3) несправедливое сравнение моделей — одна задача = разное количество токенов для разных токенизаторов. Например, турецкий текст требует в 2–3 раза больше токенов чем английский в BERT (обученном на английском корпусе).
Итоги

Большое сравнение: какую модель выбрать?

Быстрая навигация по типам задач, сильным и слабым сторонам каждого семейства.

МодельТипПараметрыЗадача pretrainingЛучшие задачиСлабости
BERT Encoder 110M / 340M MLM + NSP Классификация, NER, QA, NLI Не генерирует текст; NSP слаба
RoBERTa Encoder 125M / 355M MLM (динамическое) Все задачи понимания; лучше BERT Не генерирует; большой
DistilBERT Encoder 66M Дистилляция BERT Production: быстрый инференс −3% качества vs BERT
ALBERT Encoder 12M–235M MLM + SOP Эффективность по памяти; GLUE SOTA 2019 Медленный инференс (итерационные слои)
GPT-2 Decoder 117M–1.5B Causal LM Генерация текста, zero-shot Нет двунаправленного контекста
GPT-3 Decoder 175B Causal LM (масштаб) Few-shot всего; кодинг; reasoning Дорого; нет публичных весов
T5 Enc-Dec 60M–11B Span Corruption Перевод, суммаризация, QA Медленнее encoder-only для классификации
BART Enc-Dec 140M / 400M Denoising (5 схем) Суммаризация (SOTA), перефразирование Специфичен для seq2seq
🗺️
Практическое правило выбора Нужно понять текст (классификация, NER, QA) → BERT/RoBERTa. Production с ограниченными ресурсами → DistilBERT. Нужно генерировать текст → GPT-2. Нужна seq2seq задача (перевод, суммаризация) → T5 или BART. Нужны emergent reasoning способности → GPT-3/4 или их открытые аналоги (LLaMA 3).

Что читать дальше

Статьи

Оригинальные работы

«BERT» (2018), «RoBERTa» (2019), «DistilBERT» (2019), «ALBERT» (2019), «T5» (2019), «GPT-3» (2020), «BPE» Sennrich (2015).

Практика

Hugging Face Transformers

docs.huggingface.co — лучший ресурс для практики. Курс NLP (course.huggingface.co) охватывает все модели из этой лекции.

Бенчмарки

GLUE & SuperGLUE

gluebenchmark.com — стандартные наборы задач для оценки всех упомянутых моделей. SQuAD для QA.