Files
hamori/docs/sampling_guide.md
T
H1K0 4771498860 docs: add sampling_guide.md — temperature and top-p cheatsheet
Explains temperature and nucleus sampling mechanics, their interaction,
and provides a task-based cheatsheet with symptom/remedy table and
example CLI invocations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 20:52:39 +03:00

141 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Руководство по параметрам сэмплирования
**Версия документа:** 1.0
**Дата:** 2026-05-21
Документ объясняет, как параметры `--temperature` и `--top-p` скрипта
`scripts/generate.py` влияют на качество генерации аккордовых прогрессий.
---
## 1. Температура (--temperature)
Перед вычислением softmax каждый токен имеет сырой балл — **логит**. Температура
`T` делит все логиты на себя перед нормировкой:
```
p(token) = softmax(logits / T)
```
| T | Эффект | Характер генерации |
| --- | --------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| < 1 | Распределение **заостряется**: вероятность топ-токенов растёт, хвост коллапсирует | Консервативно, предсказуемо, склонно к повторениям |
| = 1 | Распределение без изменений — именно то, что видела модель при обучении | Нейтрально (умолчание) |
| > 1 | Распределение **сглаживается**: разрыв между вероятными и маловероятными токенами уменьшается | Разнообразно, экспериментально, больше «ошибок» |
**Аналогия:** температура — это «уверенность» модели в своём выборе. При `T=0.5`
модель действует как перфекционист, всегда выбирая самый «правильный» следующий
аккорд. При `T=1.5` — как импровизатор, готовый рискнуть.
---
## 2. Nucleus sampling (--top-p)
После применения температуры токены сортируются по убыванию вероятности. Идём по
списку, накапливая вероятность, пока сумма не достигнет `p`. Всё, что осталось за
порогом, обнуляется; оставшиеся вероятности перенормируются.
```
Пример при p=0.9:
токен A: 0.45 → cumsum 0.45 ✓ оставить
токен B: 0.30 → cumsum 0.75 ✓ оставить
токен C: 0.15 → cumsum 0.90 ✓ оставить (граница)
токен D: 0.07 → cumsum 0.97 ✗ отсечь
...
```
| p | Размер «ядра» | Характер генерации |
| ---- | ---------------------------------------- | ------------------------------------------ |
| 1.0 | Все токены | Только температура определяет выбор |
| 0.95 | Широкое — много вариантов | Разнообразно, редко срезает хорошие токены |
| 0.90 | Стандартное (умолчание) | Баланс разнообразия и связности |
| 0.80 | Умеренно узкое | Меньше «случайных» аккордов |
| 0.60 | Узкое — 1–5 токенов при уверенной модели | Ближе к жадному декодированию |
**Ключевой момент:** размер ядра не фиксирован — он зависит от формы распределения.
Если модель уверена (острое распределение), `p=0.9` может включать лишь 2–3 токена.
Если неуверена (плоское распределение), те же `p=0.9` охватят 20+ токенов.
---
## 3. Взаимодействие параметров
Температура и top-p **действуют последовательно**: сначала T, затем p.
| | top-p высокий (0.951.0) | top-p низкий (0.50.7) |
| ----------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------- |
| **T высокая (1.21.5)** | Максимальное разнообразие, высокий риск нефункциональных прогрессий | T сглаживает, p отсекает — частично компенсируют друг друга |
| **T низкая (0.60.9)** | T заостряет, хвост и так мал — p практически не влияет | Почти детерминированный вывод, высок риск повторений |
**Вывод:** при низкой T повышение p бессмысленно — хвост уже ничтожен. При
высокой T понижение p сдерживает хаос, но убивает часть разнообразия.
---
## 4. Шпаргалка для hamori
### 4.1 Шаблоны по задаче
| Задача | --temperature | --top-p | Комментарий |
| -------------------------- | ------------- | -------- | ----------------------------------------------- |
| Быстрый «типичный» вариант | 0.8 | 0.9 | Консервативно, функционально |
| Стандартная генерация | **1.0** | **0.9** | Умолчание, хороший баланс |
| Больше разнообразия | 1.11.2 | 0.9 | Чаще появляются расширения и заимствования |
| Экспериментальный режим | 1.31.5 | 0.850.9 | Неожиданные ходы, выше риск «странных» аккордов |
| Финальная версия / отчёт | 0.9 | 0.85 | Надёжный, с умеренным разнообразием |
### 4.2 Симптомы и лечение
| Симптом | Вероятная причина | Что сделать |
| -------------------------------------------------- | ------------------------------------------- | ------------------------------ |
| Повторяющийся паттерн I–IV–V, нет расширений | T слишком низкая | Поднять T до 1.1–1.3 |
| Прогрессия «не в тональности», случайные аккорды | T слишком высокая | Снизить T до 0.8–1.0 |
| Всегда один и тот же результат при разных `--seed` | p слишком низкий | Поднять p до 0.90.95 |
| Слишком много экзотических аккордов | p слишком высокий при высокой T | Снизить p до 0.8 или снизить T |
| Прогрессия обрывается на 1–2 такта | Модель уверена в EOS — используйте `--bars` | Добавить `--bars N` |
### 4.3 Примеры вызовов
```bash
# Стандартный хорус в Ab major, 8 тактов
python scripts/generate.py \
--checkpoint checkpoints/finetuned.pt \
--mode major --key Ab --function chorus \
--bars 8 --seed 42
# Экспериментальная версия того же
python scripts/generate.py \
--checkpoint checkpoints/finetuned.pt \
--mode major --key Ab --function chorus \
--bars 8 --temperature 1.3 --top-p 0.9 --seed 42
# Консервативный куплет с якорным префиксом
python scripts/generate.py \
--checkpoint checkpoints/finetuned.pt \
--mode minor --key F# --function verse \
--bars 8 --temperature 0.85 --top-p 0.85 \
--prefix "F#m . . . Dmaj7 . . ."
```
---
## 5. Технические детали
Реализация в `src/generate.py`, функция `_sample_top_p`:
```python
logits = logits / max(temperature, 1e-8) # применить температуру
probs = softmax(logits)
sorted_probs, sorted_idx = sort(probs, desc)
cumulative = cumsum(sorted_probs)
cut = (cumulative - sorted_probs) >= top_p # найти границу ядра
sorted_probs[cut] = 0.0 # обнулить хвост
sorted_probs /= sorted_probs.sum() # перенормировать
token = multinomial(sorted_probs, 1) # сэмплировать
```
Граммарная маска (`_grammar_bias`) применяется **до** сэмплирования и поверх
логитов модели — она блокирует синтаксически недопустимые токены независимо от
параметров T и p. Например, после `ROOT_x` всегда следует `QUAL_y`, и никакая
высокая температура это не изменит.