Files
hamori/docs/generation_cheatsheet.md
H1K0 8a60a8ada9 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>
2026-05-21 21:10:12 +03:00

278 lines
20 KiB
Markdown
Raw Permalink 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.
# Шпаргалка по генерации — 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 тактов.