Обучение LLM — основы
~8 мин

Scaling Laws и токенизация

Chinchilla, overtraining, BPE, vocab size trade-offs, LR schedules.

Scaling Laws и токенизация: сколько данных нужно модели?

Два вечных вопроса LLM-инженера: насколько жирной делать модель и сколько данных ей скормить? Scaling laws дают математический ответ — чтобы ты не гадал на кофейной гуще. А токенизация определяет, как модель "видит" текст — и это влияет буквально на всё.

Бюджет вычислений: C ≈ 6·N·D

Вычислительный бюджет обучения LLM — удивительно простая штука. FLOPs ≈ 6 × параметры × токены. Шестёрка — это эмпирика: forward pass + backward pass ≈ 6 операций на параметр на токен. Вот и вся магия.

C — FLOPs (вычисления), N — параметры модели, D — число токенов обучения

Chinchilla Scaling Laws

До 2022 года все были одержимы размером модели. "Больше параметров = умнее", думали они. GPT-3 (175B параметров) обучали на жалких 300B токенов. Потом пришёл Chinchilla (DeepMind, 2022) и всех отрезвил: данные так же важны, как параметры. По Chinchilla, GPT-3 нужно было 3.7 триллиона токенов — в 12 раз больше! OpenAI, по сути, недокормили свою модель.

📊 Chinchilla rule

Хочешь оптимально потратить compute? Токены должны расти пропорционально параметрам. Удвоил параметры — удвой данные. Просто и больно, потому что данные не растут на деревьях.

Overtraining: почему лабы нарушают scaling laws

Но вот фишка: современные лабы сознательно забивают на Chinchilla и перетренируют модели далеко за оптимум. Почему? Потому что маленькая модель, обученная дольше, стоит копейки при инференсе. SmolLM3 (3B параметров) обучен на 11T токенов — в 18 раз больше рекомендации Chinchilla. Kimi K2 (1T) — на 15.5T. Qwen 3 — на 36T. Overtraining — это не ошибка, это стратегия.

  • GPT-3: 175B params, 300B tokens — сильно undertrained по современным стандартам
  • SmolLM3: 3B params, 11T tokens — overtraining ×18 для дешёвого инференса
  • Kimi K2: 1T params (MoE), 15.5T tokens
  • Qwen 3: 36T tokens — рекорд по объёму данных
Scaling Laws: зависимость loss от compute при разных стратегиях
Chinchilla optimal: баланс параметров и данных. Overtraining: больше данных для дешёвого инференса
# Прикинем compute для обучения модели
def estimate_flops(n_params: float, n_tokens: float) -> float:
    """C ≈ 6 * N * D — грубая оценка FLOPs для обучения."""
    return 6 * n_params * n_tokens

# GPT-3: 175B params × 300B tokens (undertrained!)
gpt3_flops = estimate_flops(175e9, 300e9)  # ~3.15e23 FLOPs

# Chinchilla optimal для того же compute: N ≈ D
# sqrt(C/6) ≈ 7.2e11 → ~72B params, ~720B tokens
chinchilla_n = (gpt3_flops / 6) ** 0.5  # ~72B params
chinchilla_d = chinchilla_n              # ~72B tokens — столько же

# SmolLM3: 3B params, 11T tokens — overtraining ×18
smol_flops = estimate_flops(3e9, 11e12)   # ~1.98e23 FLOPs
chinchilla_optimal_tokens = 3e9           # по Chinchilla надо было 3B × 20 = 60B
overtraining_ratio = 11e12 / (3e9 * 20)   # ×18 — осознанный выбор

# Сколько GPU-часов? A100 = 312 TFLOPS (bfloat16 с utilization ~50%)
gpu_hours = smol_flops / (312e12 * 0.5) / 3600
print(f"SmolLM3: ~{gpu_hours/1000:.0f}K A100-часов")

Batch size и learning rate

Увеличил batch size в k раз? Learning rate масштабируй как √k. Интуиция простая: больший batch = более стабильные градиенты (меньше шума), значит можно делать шаги покрупнее. Ещё нюанс: critical batch size растёт по ходу тренировки — в начале модель учится быстро и шумно, потом успокаивается.

При увеличении batch size B в k раз, learning rate η масштабируется как √k для сохранения variance обновлений

Learning Rate Schedules

Learning rate живёт по расписанию: сначала warmup (1-5% шагов) — мягко разгоняемся, потом decay — плавно тормозим. Три популярных варианта:

  • Cosine annealing — классика, плавный спад. Минус: нужно заранее знать число шагов
  • WSD (Warmup-Stable-Decay) — warmup → плато → линейный спад в конце (10-20%). Гибче: можно менять длину обучения. SmolLM3 и Kimi K2 используют WSD
  • Multi-step — warmup → плато → дискретные дропы (80/10/10 или 70/15/15). DeepSeek-v3 использует вариант с cosine между дропами

💡 На практике

SmolLM3 использует LR = 2e-4 с WSD. Kimi K2: первые 10T токенов на LR 2e-4, потом cosine decay до 2e-5 на оставшиеся 5.5T. WSD особенно кайфовый для ablations — не нужно перезапускать весь run, если решил поменять длину тренировки.

Токенизация: vocab size и fertility

Алгоритм BPE (Byte-Pair Encoding) мы подробно разобрали в ноде «Seq2Seq и Attention» — начинаем с байтов, итеративно склеиваем самые частые пары. Тут фокус на другом: какой размер словаря выбрать и как это влияет на качество и скорость.

  • Vocab size: 50K для English-only, 100K+ для multilingual. GPT-4: o200k, Llama 3: cl_100k
  • Больше vocab → меньше токенов → быстрее инференс + меньше KV cache. Но больше embedding матрица
  • Fertility — среднее число токенов на слово. Меньше = эффективнее. Русский текст: GPT-2 ~2.5 tok/word, Llama 3 ~1.8
  • Для математики: single-digit splitting (каждая цифра = токен). Llama 3: числа 1-999 как отдельные токены
from transformers import AutoTokenizer

# Сравним токенизацию разных моделей
tokenizers = {
    "GPT-4 (o200k)": AutoTokenizer.from_pretrained("openai-community/gpt2"),
    "Llama 3 (128k)": AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B"),
}
text = "Рекомендательная система предсказывает P(click|user, item)"
for name, tok in tokenizers.items():
    tokens = tok.encode(text)
    print(f"{name}: {len(tokens)} токенов")
    print(f"  Токены: {[tok.decode([t]) for t in tokens[:8]]}...")

# Fertility (токенов на слово) — ключевая метрика для multilingual
# Русский текст: GPT-2 ~2.5 токена/слово, Llama 3 ~1.8
words = text.split()
for name, tok in tokenizers.items():
    fertility = len(tok.encode(text)) / len(words)
    print(f"{name}: fertility = {fertility:.2f}")

⚖️ Vocab size tradeoff

Большой vocab выгоден для жирных моделей: экономия на forward pass (меньше токенов → быстрее attention и MLP) перевешивает рост embedding матрицы. Для мелких моделей embedding может сожрать 20% параметров (Llama 3.2 1B), а для больших — всего 3% (Llama 3.1 70B). Масштаб решает.

Ключевые выводы

  • C ≈ 6·N·D — простая формула бюджета вычислений
  • Chinchilla: данные так же важны, как параметры. Но лабы осознанно перетренируют ради дешёвого инференса
  • LR масштабируется как √batch_size. WSD — гибкий schedule для продакшена
  • BPE — стандарт токенизации. Vocab size зависит от модели и языков
  • Scaling laws — ориентир, а не закон. Реальные решения учитывают inference cost, доступные данные и целевые задачи