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>
This commit is contained in:
2026-05-21 20:52:39 +03:00
parent d9585ec008
commit 4771498860
+140
View File
@@ -0,0 +1,140 @@
# Руководство по параметрам сэмплирования
**Версия документа:** 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`, и никакая
высокая температура это не изменит.