docs: replace sampling_guide with full generation_cheatsheet

Renamed and expanded to cover the full generation workflow:
- §1 quick start examples
- §2 complete CLI reference table (all 16 parameters)
- §3 corpus coverage by key and function (from actual training data)
- §4 prefix design patterns with templates and recommendations
- §5 temperature/top-p (content from sampling_guide, condensed)
- §6 technical implementation details

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 21:10:12 +03:00
parent 4771498860
commit 8a60a8ada9
2 changed files with 277 additions and 140 deletions
+277
View File
@@ -0,0 +1,277 @@
# Шпаргалка по генерации — hamori
**Версия документа:** 1.0
**Дата:** 2026-05-21
Единый справочник по запуску `scripts/generate.py`: параметры, поведение модели,
покрытие корпуса, паттерны префиксов и настройка сэмплирования.
---
## 1. Быстрый старт
```bash
# Минимальный вызов — хорус в Ab major, 8 тактов
python scripts/generate.py \
--checkpoint checkpoints/finetuned.pt \
--mode major --key Ab --function chorus \
--bars 8 --midi output/gen.mid --output output/gen.chord
# С префиксом (первые два такта заданы вручную)
python scripts/generate.py \
--checkpoint checkpoints/finetuned.pt \
--mode minor --key F# --function verse \
--bars 8 --prefix "F#m . . . Dmaj7 . . ." \
--temperature 1.1 --midi output/gen.mid --output output/gen.chord
```
Если `--bars` не задан, модель сама решает, когда закончить (обычно 2–8 тактов).
Если `--prefix` не задан, автоматически подставляется тоника (`--no-tonic-anchor`
отключает это поведение).
---
## 2. Полный справочник параметров
### 2.1 Обязательные
| Параметр | Тип | Описание |
| -------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `--checkpoint` | путь | `.pt`-файл чекпоинта. Используйте `checkpoints/finetuned.pt` после дообучения или `checkpoints/pretrained.pt` как базовый вариант. |
| `--mode` | `major` \| `minor` | Тональный наклон. Определяет канонический ключ для нормировки (C major / A minor). |
| `--key` | нота | Корневой тон выходного ключа: `C`, `F#`, `Bb`, `Ab` и т.д. |
| `--output` | путь | Путь к выходному `.chord`-файлу (расширение добавляется автоматически). |
### 2.2 Музыкальный контекст
| Параметр | Умолчание | Допустимые значения | Описание |
| --------------- | ------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `--function` | `unspecified` | `verse`, `chorus`, `bridge`, `prechorus`, `intro`, `interlude`, `outro` | Раздел произведения. Напрямую влияет на стиль прогрессии — см. §3.2. |
| `--style` | `H1K0` | `H1K0` (единственный обученный) | Тег стиля. Другие значения тихо заменяются на `other`. |
| `--time` | `4/4` | `4/4`, `3/4`, `6/8` и др. | Размер. Модель обучена почти исключительно на `4/4`. |
| `--subdivision` | `4` | `4`, `8` | Позиций на единицу счёта. `4` = одна позиция на четверть в 4/4. |
### 2.3 Управление длиной
| Параметр | Умолчание | Описание |
| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `--bars` | `None` | Остановиться ровно после N полных тактов. EOS подавляется до достижения цели. Без этого параметра модель останавливается сама. |
| `--max-tokens` | `300` | Жёсткий предел токенов. Страховочный — при нормальной работе не достигается (8 тактов ≈ 70–130 токенов). |
### 2.4 Префикс
| Параметр | Умолчание | Описание |
| ------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `--prefix` | `None` | Пробел-разделённые аккорды в заданном ключе: `"Cmaj7 . Am7 ."`. Поддерживаются `.` (держать) и `NC` (без аккорда). Подробнее — §4. |
| `--no-tonic-anchor` | выкл. | Не подставлять тонику автоматически, когда `--prefix` не задан. |
### 2.5 Сэмплирование
| Параметр | Умолчание | Рекомендованный диапазон | Описание |
| --------------- | --------- | ------------------------ | --------------------------------------------- |
| `--temperature` | `1.0` | `0.81.3` | Степень «рискованности». Подробнее — §5. |
| `--top-p` | `0.9` | `0.850.95` | Ширина ядра nucleus sampling. Подробнее — §5. |
| `--seed` | `None` | любое целое | Фиксирует RNG для воспроизводимости. |
### 2.6 Вывод
| Параметр | Умолчание | Описание |
| ---------- | --------- | -------------------------------------------------------------- |
| `--midi` | `None` | Путь к MIDI-файлу (`.mid` добавляется автоматически). |
| `--tempo` | `90` | Темп MIDI в BPM. Не влияет на генерацию аккордов. |
| `--device` | `auto` | `cpu`, `cuda` или `auto`. Для инференса CPU вполне достаточно. |
---
## 3. Покрытие корпуса
Модель обучена на нормализованных ключах (всё → C major / A minor), поэтому
**транспозиция не влияет на качество**. Однако количество примеров по функциям
и соотношение major/minor всё же сказываются на уверенности модели.
### 3.1 Ключи (до нормировки)
Ключ в `.chord`-файле используется только для транспозиции результата обратно.
Генерация происходит в C/Am — модель «не знает», в каком ключе вы запросили
результат. Тем не менее ниже показано фактическое распределение корпуса:
| Тир | Ключ | Файлов | Заметки |
| ----------------- | -------------------------- | ------ | ---------------------------------- |
| ★★★ высокий охват | C major | 15 | Наибольшее число примеров |
| ★★★ | F minor | 12 | |
| ★★☆ средний охват | G major | 9 | |
| ★★☆ | Ab major | 8 | |
| ★★☆ | Eb major | 7 | |
| ★☆☆ низкий охват | E minor | 4 | |
| ★☆☆ | D major | 3 | |
| ★☆☆ | B minor | 3 | |
| ☆☆☆ единичные | G minor, Db major | 2 | Стиль может быть менее характерным |
| ☆☆☆ | E major, F# minor, F major | 1 | |
Низкий охват влияет не на «правильность» гармонии (модель транспонирует из C/Am),
а на то, насколько сгенерированная прогрессия будет похожа именно на ваш стиль в
этой тональности.
### 3.2 Функции
| Функция | Файлов | Характер |
| ----------- | ------ | ------------------------------------------------------------- |
| `chorus` | 21 | Наилучшее покрытие. Прогрессии, как правило, более активные. |
| `verse` | 19 | Хорошее покрытие. Тяготеет к более спокойным движениям. |
| `bridge` | 9 | Среднее. Модальные сдвиги, неожиданные обороты. |
| `intro` | 6 | Среднее. Часто тоника-доминанта. |
| `prechorus` | 6 | Среднее. Направленное движение к доминанте. |
| `interlude` | 5 | Ниже среднего. Может быть менее предсказуемым. |
| `outro` | 2 | Минимум. Результат неустойчив — экспериментируйте с `--seed`. |
### 3.3 Наклон (mode)
Корпус содержит 46 major-файлов и 22 minor-файла (соотношение ~2:1). При генерации
в minor-ладу модель чуть менее уверена — рекомендуется чуть снизить температуру
(`--temperature 0.91.0`) или задать prefix.
---
## 4. Паттерны префиксов
Префикс — это начало прогрессии, которое вы задаёте вручную. Модель продолжает
с того места, где вы остановились.
### 4.1 Синтаксис
```
--prefix "Аккорд позиция позиция позиция Аккорд позиция ..."
```
- Каждый **аккорд** занимает одну позицию, записывается символом (`Fm7`, `Db`, `G/B`).
- `.` — держать предыдущий аккорд ещё одну позицию.
- `NC` — нет аккорда на этой позиции.
- В 4/4 с `--subdivision 4` один такт = 4 позиции.
### 4.2 Шаблоны
**Тоника-якорь (по умолчанию, без --prefix)**
Автоматически подставляется один аккорд тоники. Даёт модели минимальный контекст.
```bash
# Неявно: --prefix "Ab" (для --mode major --key Ab)
```
**Один такт (4 позиции)**
Самый короткий полезный префикс — задаёт начало и тональный центр.
```bash
--prefix "Fm . . ." # Fm на весь такт
--prefix "Fm . Db ." # Fm половину, Db половину
--prefix "Fm7 . Eb . " # сменная гармония в рамках такта
```
**Два такта (8 позиций)**
Надёжно задаёт функцию и движение.
```bash
--prefix "Abmaj7 . Fm7 . Db . Bbm ." # типичная прогрессия в Ab major
--prefix "Bm . . . G . . ." # IVI в B minor
```
**Развёрнутый контекст (12–16 позиций)**
Для строгого продолжения заданной темы.
```bash
--prefix "Fm . . . Db . Dbmaj7 . Fm . Fm7 . Eb . . ."
```
### 4.3 Рекомендации
| Ситуация | Рекомендация |
| -------------------------------------------- | ------------------------------------------------------- |
| Нужна характерная прогрессия в стиле корпуса | Хватит 1–2 тактов префикса |
| Продолжение конкретной темы из вашей песни | 3–4 такта; используйте реальные аккорды из трека |
| Полностью свободная генерация | `--no-tonic-anchor` (без префикса) |
| Модель «соскальзывает» в I–IV–V | Задайте нетривиальный первый аккорд (`Abmaj7`, `Bm7b5`) |
| Результат слишком похож на префикс | Повысьте температуру до 1.1–1.3 |
---
## 5. Температура и top-p
### 5.1 Температура (--temperature)
```
p(token) = softmax(logits / T)
```
| T | Эффект | Характер генерации |
| --- | ------------------------------ | ------------------------------------------- |
| < 1 | Распределение **заостряется** | Консервативно, склонно к повторениям |
| = 1 | Без изменений (умолчание) | Нейтрально |
| > 1 | Распределение **сглаживается** | Разнообразно, выше риск «странных» аккордов |
### 5.2 Nucleus sampling (--top-p)
После применения T токены сортируются по убыванию вероятности. Накапливаем, пока
сумма не достигнет `p` — остальное обнуляется.
| p | Характер генерации |
| -------- | ----------------------------------------------- |
| 1.0 | Только T управляет выбором |
| 0.95 | Широкое ядро, редко отсекает хорошие варианты |
| **0.90** | **Умолчание** — баланс разнообразия и связности |
| 0.80 | Меньше случайных аккордов |
| 0.60 | Почти детерминированно |
**Важно:** размер ядра не фиксирован. При уверенной модели `p=0.9` даёт 23 токена,
при неуверенной — 20+.
### 5.3 Взаимодействие
| | top-p высокий (0.951.0) | top-p низкий (0.50.7) |
| ----------------------- | ----------------------------------------------------------- | -------------------------------------- |
| **T высокая (1.21.5)** | Максимальное разнообразие, риск нефункциональных прогрессий | T и p частично компенсируют друг друга |
| **T низкая (0.60.9)** | p практически не влияет — хвост уже ничтожен | Почти детерминированный вывод |
### 5.4 Шаблоны по задаче
| Задача | --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 | Надёжный результат |
### 5.5 Симптомы и лечение
| Симптом | Причина | Что сделать |
| ---------------------------------------- | --------------------- | ---------------------- |
| Повторяющийся 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 тактов (без `--bars`) | Модель уверена в EOS | Добавить `--bars N` |
---
## 6. Технические детали
Реализация nucleus sampling в `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_*`.
- После `QUAL_x` — только `EXT_*`.
- После `EXT_x` — только `BASS_*`.
- `EOS` допустим только на границе такта (`pos_in_bar == 0`).
- При заданном `--bars N`: `EOS` подавляется, пока не завершено N тактов.
-140
View File
@@ -1,140 +0,0 @@
# Руководство по параметрам сэмплирования
**Версия документа:** 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`, и никакая
высокая температура это не изменит.