docs: add README, architecture, glossary, requirements; update CLAUDE.md
Add four Russian-language project documents: - README.md: user-facing guide (install, quick start, data prep, training, evaluation, limitations) - docs/architecture.md v1.0: system architecture, data flow diagrams, module interfaces, 7 architectural decision records, extension points - docs/glossary.md v1.0: musical, ML, and project-specific term definitions - docs/requirements.md v1.0: functional/non-functional requirements, acceptance criteria, four use-case scenarios Update CLAUDE.md with project name etymology (hamori / ハモリ) and rename repo root reference from chord-gen to hamori. Refine chord_format_spec.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,11 +4,20 @@ This file gives Claude Code persistent context for the project. Read it before a
|
|||||||
|
|
||||||
## Project overview
|
## Project overview
|
||||||
|
|
||||||
**Goal.** Train a small autoregressive transformer to generate harmonic periods (4–16 bar chord progressions) in the author's compositional style. Coursework deliverable for an ML class at RTU MIREA; also intended as a working creative tool.
|
**Name.** _hamori_ (Japanese ハモリ, "harmonization" in the sense of vocal
|
||||||
|
harmony — adding a second voice to a melodic line). The name reflects the
|
||||||
|
project's core idea: the model proposes harmonic ideas to complement a
|
||||||
|
composer's existing intent, rather than writing music from scratch.
|
||||||
|
|
||||||
|
**Goal.** Train a small autoregressive transformer to generate harmonic
|
||||||
|
periods (4–16 bar chord progressions) in the author's compositional style.
|
||||||
|
Coursework deliverable for an ML class at RTU MIREA; also intended as a
|
||||||
|
working creative tool.
|
||||||
|
|
||||||
**Unit of generation.** A single closed harmonic phrase (a "period"), not a full song.
|
**Unit of generation.** A single closed harmonic phrase (a "period"), not a full song.
|
||||||
|
|
||||||
**Pipeline.**
|
**Pipeline.**
|
||||||
|
|
||||||
1. Hand-transcribe own compositions from REAPER DAW projects into `.chord` text files.
|
1. Hand-transcribe own compositions from REAPER DAW projects into `.chord` text files.
|
||||||
2. Parse `.chord` → factorized token sequences.
|
2. Parse `.chord` → factorized token sequences.
|
||||||
3. Pre-train on a public corpus (McGill Billboard or similar).
|
3. Pre-train on a public corpus (McGill Billboard or similar).
|
||||||
@@ -34,7 +43,7 @@ Avoid heavy abstractions. This is coursework, not a production system. Prefer si
|
|||||||
## Repository layout
|
## Repository layout
|
||||||
|
|
||||||
```
|
```
|
||||||
chord-gen/
|
hamori/
|
||||||
├── CLAUDE.md ← this file
|
├── CLAUDE.md ← this file
|
||||||
├── README.md
|
├── README.md
|
||||||
├── requirements.txt
|
├── requirements.txt
|
||||||
@@ -88,6 +97,7 @@ The authoritative specification is in `docs/chord_format_spec.md`. **Always read
|
|||||||
## Model
|
## Model
|
||||||
|
|
||||||
A small autoregressive transformer:
|
A small autoregressive transformer:
|
||||||
|
|
||||||
- Layers: 2–4
|
- Layers: 2–4
|
||||||
- d_model: 128–256
|
- d_model: 128–256
|
||||||
- Heads: 4–8
|
- Heads: 4–8
|
||||||
@@ -111,6 +121,7 @@ Pre-training uses the full public corpus. Fine-tuning uses the own corpus with a
|
|||||||
## Evaluation
|
## Evaluation
|
||||||
|
|
||||||
For the report:
|
For the report:
|
||||||
|
|
||||||
1. **Perplexity** on the holdout set, comparing pre-trained baseline vs fine-tuned.
|
1. **Perplexity** on the holdout set, comparing pre-trained baseline vs fine-tuned.
|
||||||
2. **Distribution shift plots** — histograms over chord qualities, extension presence, inversion frequency, root motion intervals — showing how fine-tuning moves the distribution toward the author's corpus.
|
2. **Distribution shift plots** — histograms over chord qualities, extension presence, inversion frequency, root motion intervals — showing how fine-tuning moves the distribution toward the author's corpus.
|
||||||
3. **Qualitative cherry-picked generations** — 3 examples with the same seed/prefix, generated by baseline vs fine-tuned, rendered to MIDI.
|
3. **Qualitative cherry-picked generations** — 3 examples with the same seed/prefix, generated by baseline vs fine-tuned, rendered to MIDI.
|
||||||
|
|||||||
@@ -0,0 +1,349 @@
|
|||||||
|
# hamori
|
||||||
|
|
||||||
|
Авторегрессионная нейросетевая модель для генерации гармонических периодов
|
||||||
|
(замкнутых гармонических фраз 4–16 тактов) в авторском композиторском стиле.
|
||||||
|
|
||||||
|
Название проекта — _hamori_ (яп. ハモリ) — относится к понятию вокальной
|
||||||
|
гармонизации, добавлению второго голоса в существующую мелодическую линию.
|
||||||
|
Отсылка к этому понятию закрепляет основную идею проекта: модель не пишет
|
||||||
|
музыку с нуля, а предлагает гармонические идеи в дополнение к замыслу
|
||||||
|
композитора.
|
||||||
|
|
||||||
|
Проект разработан как курсовая работа по дисциплине «Машинное обучение» в
|
||||||
|
рамках обучения в РТУ МИРЭА и одновременно как практический инструмент для
|
||||||
|
композиторской работы.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
- [hamori](#hamori)
|
||||||
|
- [Содержание](#содержание)
|
||||||
|
- [1. Краткое описание](#1-краткое-описание)
|
||||||
|
- [2. Контекст и цели](#2-контекст-и-цели)
|
||||||
|
- [3. Установка](#3-установка)
|
||||||
|
- [4. Структура репозитория](#4-структура-репозитория)
|
||||||
|
- [5. Быстрый старт](#5-быстрый-старт)
|
||||||
|
- [6. Подготовка датасета](#6-подготовка-датасета)
|
||||||
|
- [6.1 Собственный корпус](#61-собственный-корпус)
|
||||||
|
- [6.2 Публичный корпус](#62-публичный-корпус)
|
||||||
|
- [6.3 Отложенная выборка](#63-отложенная-выборка)
|
||||||
|
- [6.4 Токенизация](#64-токенизация)
|
||||||
|
- [7. Обучение моделей](#7-обучение-моделей)
|
||||||
|
- [7.1 Предобучение](#71-предобучение)
|
||||||
|
- [7.2 Дообучение на собственном корпусе](#72-дообучение-на-собственном-корпусе)
|
||||||
|
- [8. Оценка результатов](#8-оценка-результатов)
|
||||||
|
- [9. Дополнительная документация](#9-дополнительная-документация)
|
||||||
|
- [10. Ограничения текущей версии](#10-ограничения-текущей-версии)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Краткое описание
|
||||||
|
|
||||||
|
Система принимает на вход параметры желаемого периода (тональность, тактовый
|
||||||
|
размер, стилевой тег, функциональная роль) и опционально первые несколько
|
||||||
|
аккордов. На выходе формируется гармоническая последовательность, представленная
|
||||||
|
как `.chord`-файл лид-шит-нотации и MIDI-файл для воспроизведения и работы
|
||||||
|
в цифровой звуковой рабочей станции.
|
||||||
|
|
||||||
|
Модель обучается в две стадии:
|
||||||
|
|
||||||
|
- **Pre-training** на публичном корпусе аккордовых последовательностей
|
||||||
|
(McGill Billboard Project) для усвоения общих гармонических закономерностей
|
||||||
|
поп-музыки.
|
||||||
|
- **Fine-tuning** на корпусе собственных произведений автора для адаптации
|
||||||
|
модели к индивидуальному композиторскому почерку.
|
||||||
|
|
||||||
|
Юнит обработки и генерации — **гармонический период**, а не пьеса целиком.
|
||||||
|
Это решение обеспечивает достаточный размер обучающей выборки при ограниченном
|
||||||
|
числе исходных произведений и снимает проблему обработки модуляций между
|
||||||
|
крупными разделами формы.
|
||||||
|
|
||||||
|
## 2. Контекст и цели
|
||||||
|
|
||||||
|
Проект преследует две сопряжённые цели.
|
||||||
|
|
||||||
|
**Учебная цель.** Закрытие дисциплины «Машинное обучение» с выполнением
|
||||||
|
курсового проекта, включающего полный цикл работы с генеративной моделью:
|
||||||
|
постановка задачи, проектирование формата данных, подготовка обучающего
|
||||||
|
корпуса, обучение, оценка и интерпретация результатов.
|
||||||
|
|
||||||
|
**Прикладная цель.** Получение работающего инструмента-помощника, который
|
||||||
|
автор сможет использовать в дальнейшей композиторской деятельности как
|
||||||
|
источник гармонических идей в собственном стилистическом ключе.
|
||||||
|
|
||||||
|
Срок реализации: менее одного месяца. Бюджет ручного труда: около 50 часов.
|
||||||
|
|
||||||
|
Подробное описание целей и формальных требований приведено в
|
||||||
|
[docs/requirements.md](docs/requirements.md).
|
||||||
|
|
||||||
|
## 3. Установка
|
||||||
|
|
||||||
|
Требования: Python 3.11 или новее, доступ к командной строке, git.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url> hamori
|
||||||
|
cd hamori
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate # Linux, macOS
|
||||||
|
venv\Scripts\activate # Windows
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Для воспроизведения сгенерированных MIDI-файлов требуется цифровая звуковая
|
||||||
|
рабочая станция (рекомендуется REAPER) с подключённым программным
|
||||||
|
синтезатором, либо стандартный плеер MIDI операционной системы.
|
||||||
|
|
||||||
|
Обучение модели возможно как на CPU, так и на GPU. Модель компактна
|
||||||
|
(порядка одного-трёх миллионов параметров), и pre-training на полном
|
||||||
|
корпусе укладывается в несколько часов на CPU современного ноутбука,
|
||||||
|
fine-tuning — в десятки минут.
|
||||||
|
|
||||||
|
## 4. Структура репозитория
|
||||||
|
|
||||||
|
```
|
||||||
|
hamori/
|
||||||
|
├── CLAUDE.md постоянный контекст для Claude Code
|
||||||
|
├── README.md этот файл
|
||||||
|
├── requirements.txt зависимости Python
|
||||||
|
├── docs/
|
||||||
|
│ ├── chord_format_spec.md спецификация формата .chord (версия 2.0)
|
||||||
|
│ ├── requirements.md функциональные и нефункциональные требования
|
||||||
|
│ ├── architecture.md архитектура системы
|
||||||
|
│ └── glossary.md глоссарий терминов
|
||||||
|
├── data/
|
||||||
|
│ ├── raw_user/ .chord-файлы собственного корпуса
|
||||||
|
│ ├── raw_external/ публичные корпуса (McGill Billboard и др.)
|
||||||
|
│ ├── processed/ токенизированные .pt-файлы для обучения
|
||||||
|
│ └── holdout/ отложенная выборка для итоговой оценки
|
||||||
|
├── src/
|
||||||
|
│ ├── chord_parser.py парсинг аккордовых символов
|
||||||
|
│ ├── tokenizer.py преобразование .chord ↔ токены
|
||||||
|
│ ├── midi_export.py экспорт периодов в MIDI
|
||||||
|
│ ├── dataset.py PyTorch-датасет
|
||||||
|
│ ├── model.py определение модели
|
||||||
|
│ ├── train.py логика обучения
|
||||||
|
│ ├── generate.py инференс и сэмплирование
|
||||||
|
│ ├── evaluate.py метрики и распределения
|
||||||
|
│ └── external_converters/ конвертеры публичных корпусов
|
||||||
|
├── scripts/ CLI-обёртки над модулями src
|
||||||
|
├── tests/ модульные тесты и фикстуры
|
||||||
|
├── notebooks/ Jupyter-ноутбуки для исследования и отчётности
|
||||||
|
├── checkpoints/ сохранённые состояния моделей
|
||||||
|
└── reports/ графики, примеры и итоговый отчёт
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Быстрый старт
|
||||||
|
|
||||||
|
После завершения обучения (см. разделы 6–7) генерация одного периода
|
||||||
|
выполняется следующей командой:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/generate.py \
|
||||||
|
--checkpoint checkpoints/finetuned.pt \
|
||||||
|
--mode major \
|
||||||
|
--key F# \
|
||||||
|
--style user \
|
||||||
|
--function chorus \
|
||||||
|
--time 4/4 \
|
||||||
|
--output reports/samples/period.chord \
|
||||||
|
--midi reports/samples/period.mid \
|
||||||
|
--seed 42
|
||||||
|
```
|
||||||
|
|
||||||
|
После выполнения в указанной директории появятся два файла:
|
||||||
|
текстовый `.chord` с гармонической последовательностью и MIDI-файл,
|
||||||
|
готовый к открытию в DAW.
|
||||||
|
|
||||||
|
Если у пользователя есть начальная гармоническая идея, её можно передать
|
||||||
|
параметром `--prefix`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/generate.py \
|
||||||
|
--checkpoint checkpoints/finetuned.pt \
|
||||||
|
--mode major --key C --style user --function verse --time 4/4 \
|
||||||
|
--prefix "Cmaj7 Am7 Dm7" \
|
||||||
|
--output reports/samples/continuation.chord
|
||||||
|
```
|
||||||
|
|
||||||
|
Модель достроит остаток периода в логике, выученной на собственном корпусе
|
||||||
|
автора.
|
||||||
|
|
||||||
|
## 6. Подготовка датасета
|
||||||
|
|
||||||
|
Подготовка датасета — самая трудозатратная часть проекта (10–15 часов
|
||||||
|
чистого времени). Сокращать её за счёт автоматического извлечения аккордов
|
||||||
|
из аудио нецелесообразно: при плотной фактуре и нетривиальных гармонических
|
||||||
|
решениях современные алгоритмы chord detection дают слишком высокую долю
|
||||||
|
ошибок, тогда как ручная транскрипция при наличии абсолютного слуха выполняется
|
||||||
|
быстро и без потерь.
|
||||||
|
|
||||||
|
### 6.1 Собственный корпус
|
||||||
|
|
||||||
|
Из 20–25 собственных произведений (DAW-проекты в REAPER) необходимо извлечь
|
||||||
|
80–150 гармонических периодов и записать каждый в виде отдельного `.chord`-файла
|
||||||
|
в директории `data/raw_user/`.
|
||||||
|
|
||||||
|
Процедура транскрипции:
|
||||||
|
|
||||||
|
1. Прослушать пьесу, определить границы замкнутых гармонических фраз. Признаки
|
||||||
|
замкнутости — возврат к тонике или ясная полукаденция, отсутствие модуляции
|
||||||
|
внутри фрагмента.
|
||||||
|
2. Заполнить шапку `.chord`-файла: название, тональность, тактовый размер,
|
||||||
|
подразделение доли, стилевой тег `user`, функциональная роль периода.
|
||||||
|
3. Транскрибировать гармонию по позициям, аккуратно фиксируя инверсии и расширения.
|
||||||
|
4. Запустить парсер для проверки корректности файла:
|
||||||
|
```bash
|
||||||
|
python scripts/validate_chord_file.py data/raw_user/2024_001_song_chorus.chord
|
||||||
|
```
|
||||||
|
5. Запустить экспорт в MIDI и прослушать результат в DAW параллельно с оригиналом
|
||||||
|
для контроля точности транскрипции:
|
||||||
|
```bash
|
||||||
|
python -m src.midi_export data/raw_user/2024_001_song_chorus.chord /tmp/check.mid
|
||||||
|
```
|
||||||
|
|
||||||
|
Полная спецификация формата приведена в [docs/chord_format_spec.md](docs/chord_format_spec.md).
|
||||||
|
Чек-лист транскрипции — в разделе 10 спецификации.
|
||||||
|
|
||||||
|
### 6.2 Публичный корпус
|
||||||
|
|
||||||
|
Для предобучения используется McGill Billboard Project — открытый
|
||||||
|
размеченный профессиональными аннотаторами корпус из примерно семи сотен
|
||||||
|
пьес западной поп-музыки 1950–1990-х годов. Корпус необходимо скачать с
|
||||||
|
официального сайта и распаковать в директорию `data/raw_external/mcgill_billboard/`.
|
||||||
|
|
||||||
|
Конвертация в формат `.chord`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m src.external_converters.mcgill_to_chord \
|
||||||
|
--input data/raw_external/mcgill_billboard/ \
|
||||||
|
--output data/raw_external/mcgill_converted/
|
||||||
|
```
|
||||||
|
|
||||||
|
Конвертер автоматически разрезает каждую пьесу на периоды по границам секций
|
||||||
|
и сохраняет каждый период как отдельный `.chord`-файл со стилевым тегом `other`.
|
||||||
|
|
||||||
|
### 6.3 Отложенная выборка
|
||||||
|
|
||||||
|
Из собственного корпуса необходимо отложить 10–15 периодов в директорию
|
||||||
|
`data/holdout/` ещё до начала обучения. Эти периоды не должны попасть ни в
|
||||||
|
тренировочную, ни в валидационную выборки и используются только для итоговой
|
||||||
|
оценки качества модели. Откладывать следует репрезентативные для авторского
|
||||||
|
стиля примеры, а не самые экспериментальные.
|
||||||
|
|
||||||
|
### 6.4 Токенизация
|
||||||
|
|
||||||
|
После того как `.chord`-файлы готовы, выполняется пакетная токенизация:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/prepare_data.py \
|
||||||
|
--input-dir data/raw_user/ \
|
||||||
|
--output-dir data/processed/user/ \
|
||||||
|
--split-ratios 0.9 0.1
|
||||||
|
|
||||||
|
python scripts/prepare_data.py \
|
||||||
|
--input-dir data/raw_external/mcgill_converted/ \
|
||||||
|
--output-dir data/processed/mcgill/ \
|
||||||
|
--split-ratios 0.9 0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт автоматически разделяет файлы на тренировочную и валидационную выборки,
|
||||||
|
выводит статистику по длине последовательностей и распределениям метаданных.
|
||||||
|
|
||||||
|
## 7. Обучение моделей
|
||||||
|
|
||||||
|
Обучение выполняется в две стадии.
|
||||||
|
|
||||||
|
### 7.1 Предобучение
|
||||||
|
|
||||||
|
Обучение базовой модели на конвертированном корпусе McGill Billboard:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/train.py \
|
||||||
|
--data-dir data/processed/mcgill/ \
|
||||||
|
--output checkpoints/pretrained.pt \
|
||||||
|
--epochs 50 \
|
||||||
|
--batch-size 32 \
|
||||||
|
--lr 3e-4 \
|
||||||
|
--warmup-steps 200 \
|
||||||
|
--seed 42
|
||||||
|
```
|
||||||
|
|
||||||
|
По окончании обучения в директории `checkpoints/` появятся: сам чекпоинт,
|
||||||
|
лог обучения в формате CSV и график кривых train/val loss.
|
||||||
|
|
||||||
|
### 7.2 Дообучение на собственном корпусе
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/train.py \
|
||||||
|
--init-from checkpoints/pretrained.pt \
|
||||||
|
--data-dir data/processed/user/ \
|
||||||
|
--output checkpoints/finetuned.pt \
|
||||||
|
--epochs 15 \
|
||||||
|
--batch-size 16 \
|
||||||
|
--lr 1e-5 \
|
||||||
|
--warmup-steps 20 \
|
||||||
|
--seed 42
|
||||||
|
```
|
||||||
|
|
||||||
|
Существенно более низкая скорость обучения (на два порядка меньше, чем на
|
||||||
|
предобучении) и небольшое число эпох предотвращают катастрофическое забывание
|
||||||
|
закономерностей, выученных на этапе предобучения.
|
||||||
|
|
||||||
|
## 8. Оценка результатов
|
||||||
|
|
||||||
|
Скрипт оценки сравнивает базовую (только предобученную) и дообученную модели
|
||||||
|
на отложенной выборке:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/evaluate.py \
|
||||||
|
--baseline checkpoints/pretrained.pt \
|
||||||
|
--target checkpoints/finetuned.pt \
|
||||||
|
--holdout data/processed/holdout/ \
|
||||||
|
--output-dir reports/
|
||||||
|
```
|
||||||
|
|
||||||
|
В директории `reports/` будут сформированы:
|
||||||
|
|
||||||
|
- Таблица в формате JSON с численными метриками (perplexity обеих моделей).
|
||||||
|
- Графики распределений типов аккордов, частот инверсий, интервалов движения
|
||||||
|
корня, наиболее частых функциональных пар. Каждый график показывает баланс
|
||||||
|
baseline-распределения и target-распределения.
|
||||||
|
- Сгенерированные образцы для качественного сравнения (3 затравки × 3 семпла
|
||||||
|
× 2 модели).
|
||||||
|
|
||||||
|
Подробное описание метрик и методологии оценки — в разделе 6 файла
|
||||||
|
[docs/architecture.md](docs/architecture.md).
|
||||||
|
|
||||||
|
## 9. Дополнительная документация
|
||||||
|
|
||||||
|
| Документ | Назначение |
|
||||||
|
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| [docs/chord_format_spec.md](docs/chord_format_spec.md) | Полная спецификация формата `.chord`, словарь токенов, правила парсинга. Авторитетный источник по формату. |
|
||||||
|
| [docs/requirements.md](docs/requirements.md) | Функциональные и нефункциональные требования, критерии приёмки. |
|
||||||
|
| [docs/architecture.md](docs/architecture.md) | Архитектура системы, схемы потоков данных, описания модулей, обоснование ключевых проектных решений. |
|
||||||
|
| [docs/glossary.md](docs/glossary.md) | Глоссарий музыкальных, машинно-обучательных и проектных терминов. |
|
||||||
|
| [CLAUDE.md](CLAUDE.md) | Постоянный контекст для Claude Code (на английском). Описывает правила разработки, чего нельзя делать без согласования и какие модули за что отвечают. |
|
||||||
|
|
||||||
|
## 10. Ограничения текущей версии
|
||||||
|
|
||||||
|
Текущая версия проекта сознательно ограничена для соблюдения сроков курсовой
|
||||||
|
работы. Перечисленные ниже возможности **не реализованы** и являются
|
||||||
|
кандидатами для дальнейшего развития.
|
||||||
|
|
||||||
|
- Генерация мелодии. Текущая модель работает только с гармонической
|
||||||
|
последовательностью.
|
||||||
|
- Расположение голосов внутри аккорда (voicing) выше баса. Бас передаётся,
|
||||||
|
остальное оставлено на ручную работу композитора в DAW.
|
||||||
|
- Ритмический паттерн внутри удержания аккорда (синкопы, проходящие фигуры,
|
||||||
|
альбертиевы басы).
|
||||||
|
- Аранжировка, тембр, динамика, артикуляция.
|
||||||
|
- Графический пользовательский интерфейс. Взаимодействие осуществляется
|
||||||
|
через командную строку.
|
||||||
|
- Прямая интеграция с REAPER в режиме реального времени. Обмен с DAW
|
||||||
|
происходит через файлы MIDI.
|
||||||
|
- Обработка модуляций внутри одного периода. При наличии модуляции в
|
||||||
|
исходном произведении периоды разрезаются по точке модуляции.
|
||||||
|
- Дообучение на корпусе японской поп-музыки (J-Pop). Запланировано как
|
||||||
|
отдельный эксперимент после защиты курсовой.
|
||||||
|
|
||||||
|
Подробное обсуждение каждого пункта и направления развития содержатся в
|
||||||
|
[docs/architecture.md](docs/architecture.md), раздел «Точки расширения».
|
||||||
@@ -0,0 +1,915 @@
|
|||||||
|
# Архитектура системы hamori
|
||||||
|
|
||||||
|
**Версия документа:** 1.0
|
||||||
|
**Дата:** 2026-05-19
|
||||||
|
|
||||||
|
Документ описывает архитектуру проекта _hamori_ — генератора гармонических
|
||||||
|
периодов: высокоуровневую структуру, потоки данных, состав модулей, ключевые
|
||||||
|
проектные решения и их обоснование, а также точки расширения.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
1. [Высокоуровневая архитектура](#1-высокоуровневая-архитектура)
|
||||||
|
2. [Потоки данных](#2-потоки-данных)
|
||||||
|
3. [Состав модулей](#3-состав-модулей)
|
||||||
|
4. [Модель машинного обучения](#4-модель-машинного-обучения)
|
||||||
|
5. [Конвейер обучения](#5-конвейер-обучения)
|
||||||
|
6. [Конвейер инференса и оценки](#6-конвейер-инференса-и-оценки)
|
||||||
|
7. [Ключевые проектные решения](#7-ключевые-проектные-решения)
|
||||||
|
8. [Точки расширения](#8-точки-расширения)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Высокоуровневая архитектура
|
||||||
|
|
||||||
|
Система состоит из шести логических уровней.
|
||||||
|
|
||||||
|
**Уровень человекочитаемых данных.** Текстовые `.chord`-файлы лид-шит-нотации,
|
||||||
|
с которыми работает автор-композитор при ручной транскрипции. Каждый файл
|
||||||
|
описывает один гармонический период.
|
||||||
|
|
||||||
|
**Уровень парсинга и валидации.** Модули, преобразующие `.chord`-файлы в
|
||||||
|
структурированные внутренние представления и проверяющие их корректность.
|
||||||
|
|
||||||
|
**Уровень токенизации.** Модули, преобразующие структурированные представления
|
||||||
|
в последовательности целочисленных идентификаторов и обратно. Здесь же
|
||||||
|
выполняется нормализующая транспозиция в каноническую тональность.
|
||||||
|
|
||||||
|
**Уровень обучения и инференса.** Реализация нейросетевой модели, циклы
|
||||||
|
обучения и сэмплирования, работа с чекпоинтами.
|
||||||
|
|
||||||
|
**Уровень оценки.** Расчёт метрик, построение распределений, формирование
|
||||||
|
графических артефактов для отчёта.
|
||||||
|
|
||||||
|
**Уровень внешних адаптеров.** Конвертеры публичных корпусов в формат `.chord`,
|
||||||
|
экспорт периодов в MIDI.
|
||||||
|
|
||||||
|
Схема информационных связей между уровнями:
|
||||||
|
|
||||||
|
```
|
||||||
|
автор-композитор
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
.chord-файлы (raw_user)
|
||||||
|
│
|
||||||
|
│
|
||||||
|
│ публичный корпус
|
||||||
|
│ │
|
||||||
|
│ ▼
|
||||||
|
│ внешний конвертер
|
||||||
|
│ │
|
||||||
|
│ ▼
|
||||||
|
│ .chord-файлы (raw_external)
|
||||||
|
│ │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
парсер + валидатор
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
транспозиция в C/Am
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
токенизатор
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
.pt-файлы (processed)
|
||||||
|
│
|
||||||
|
┌──────────────────┼──────────────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
train выборка val выборка holdout выборка
|
||||||
|
│ │ │
|
||||||
|
└────────┬─────────┘ │
|
||||||
|
▼ │
|
||||||
|
трансформер: pre-train + fine-tune │
|
||||||
|
│ │
|
||||||
|
▼ │
|
||||||
|
чекпоинты ◄───────────────────────┘
|
||||||
|
│ │
|
||||||
|
┌────────────────┼────────────────────────────┘
|
||||||
|
▼ ▼
|
||||||
|
инференс оценка
|
||||||
|
│ │
|
||||||
|
▼ ▼
|
||||||
|
.chord + MIDI метрики + графики + образцы
|
||||||
|
│ │
|
||||||
|
▼ ▼
|
||||||
|
автор-композитор отчёт
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Потоки данных
|
||||||
|
|
||||||
|
### 2.1 Поток подготовки собственного корпуса
|
||||||
|
|
||||||
|
```
|
||||||
|
DAW-проект (REAPER)
|
||||||
|
│
|
||||||
|
│ ручная транскрипция
|
||||||
|
▼
|
||||||
|
.chord-файл в data/raw_user/
|
||||||
|
│
|
||||||
|
│ валидация формата
|
||||||
|
│ (опционально: MIDI-санитарная проверка)
|
||||||
|
▼
|
||||||
|
.chord-файл прошёл проверку
|
||||||
|
│
|
||||||
|
│ скрипт prepare_data.py
|
||||||
|
│ ├── чтение
|
||||||
|
│ ├── транспозиция в C major / A minor
|
||||||
|
│ ├── токенизация
|
||||||
|
│ └── разбиение train / val
|
||||||
|
▼
|
||||||
|
.pt-файлы в data/processed/user/{train,val}/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Поток подготовки публичного корпуса
|
||||||
|
|
||||||
|
```
|
||||||
|
McGill Billboard (Harte-аннотации)
|
||||||
|
│
|
||||||
|
│ скрипт mcgill_to_chord.py
|
||||||
|
│ ├── парсинг Harte-нотации
|
||||||
|
│ ├── разрезание на периоды по секциям
|
||||||
|
│ ├── определение тональности
|
||||||
|
│ └── конвертация в .chord
|
||||||
|
▼
|
||||||
|
.chord-файлы в data/raw_external/mcgill_converted/
|
||||||
|
│
|
||||||
|
│ скрипт prepare_data.py
|
||||||
|
▼
|
||||||
|
.pt-файлы в data/processed/mcgill/{train,val}/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Поток обучения
|
||||||
|
|
||||||
|
```
|
||||||
|
data/processed/mcgill/ ◄── предобучение
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
checkpoints/pretrained.pt
|
||||||
|
│
|
||||||
|
│ инициализация весов
|
||||||
|
▼
|
||||||
|
data/processed/user/ ◄── дообучение
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
checkpoints/finetuned.pt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 Поток инференса
|
||||||
|
|
||||||
|
```
|
||||||
|
пользовательские параметры (CLI)
|
||||||
|
│
|
||||||
|
│ построение prompt-токенов
|
||||||
|
│ ▼
|
||||||
|
prompt = <BOS> + метатокены + опциональный prefix
|
||||||
|
│
|
||||||
|
│ авторегрессионная генерация (top-p sampling)
|
||||||
|
▼
|
||||||
|
последовательность токенов до <EOS>
|
||||||
|
│
|
||||||
|
│ детокенизация
|
||||||
|
▼
|
||||||
|
ChordPeriod в канонической тональности C/Am
|
||||||
|
│
|
||||||
|
│ транспозиция в целевую тональность
|
||||||
|
▼
|
||||||
|
ChordPeriod в требуемой тональности
|
||||||
|
│
|
||||||
|
│ сериализация + MIDI-экспорт
|
||||||
|
▼
|
||||||
|
.chord и .mid файлы
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 Поток оценки
|
||||||
|
|
||||||
|
```
|
||||||
|
data/processed/holdout/
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
вычисление перплексии для base и target
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
извлечение признаков (типы аккордов, инверсии, интервалы корня)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
построение гистограмм и таблиц
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
reports/figures/, reports/metrics.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Состав модулей
|
||||||
|
|
||||||
|
### 3.1 `src/chord_parser.py`
|
||||||
|
|
||||||
|
**Назначение.** Разбор отдельных аккордовых символов в строго типизированное
|
||||||
|
представление.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- `parse_chord_symbol(symbol: str) -> ChordTokens` — парсит строку вида `Am7`,
|
||||||
|
`Cmaj9`, `F/G`, `Bb7b9/D` в dataclass `ChordTokens(root, quality, extension, bass)`.
|
||||||
|
- `ChordParseError` — исключение, поднимаемое при невалидном символе.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** Модуль не использует регулярные
|
||||||
|
выражения для парсинга качеств: вместо этого выполняется последовательное
|
||||||
|
распознавание из таблицы альтернативных написаний по принципу самого длинного
|
||||||
|
совпадения. Это упрощает добавление новых качеств в будущем и снижает риск
|
||||||
|
тонких ошибок с приоритетами совпадений.
|
||||||
|
|
||||||
|
Бемольные написания корня и баса нормализуются к диезной форме на этапе парсинга.
|
||||||
|
|
||||||
|
**Связи.** Используется модулем `tokenizer.py` для разбора аккордов внутри
|
||||||
|
периода. Не имеет зависимостей внутри проекта, кроме стандартной библиотеки
|
||||||
|
Python и опционально `music21` (как fallback для нетипичных написаний).
|
||||||
|
|
||||||
|
### 3.2 `src/tokenizer.py`
|
||||||
|
|
||||||
|
**Назначение.** Преобразование `.chord`-файлов в последовательности
|
||||||
|
целочисленных идентификаторов и обратно. Реализация словаря токенов.
|
||||||
|
Реализация нормализующей транспозиции.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- Константа `VOCAB: list[str]` — словарь токенов в порядке, описанном в
|
||||||
|
спецификации формата (81 токен).
|
||||||
|
- Константа `TOKEN_TO_ID: dict[str, int]` — обратное отображение.
|
||||||
|
- Функция `parse_chord_file(path: Path) -> ChordPeriod` — парсинг
|
||||||
|
`.chord`-файла в структурированное представление.
|
||||||
|
- Функция `transpose_to_canonical(period: ChordPeriod) -> ChordPeriod` —
|
||||||
|
транспозиция мажорных периодов в C major, минорных в A minor.
|
||||||
|
- Функция `tokenize_period(period: ChordPeriod) -> list[int]` — последовательно
|
||||||
|
выполняет транспозицию и преобразование в токены.
|
||||||
|
- Функция `detokenize_to_period(token_ids: list[int]) -> ChordPeriod` —
|
||||||
|
обратная операция, возвращает период в канонической тональности.
|
||||||
|
- Функция `transpose_period(period, target_key) -> ChordPeriod` —
|
||||||
|
транспозиция в произвольную целевую тональность (используется на этапе
|
||||||
|
инференса для возврата результата в требуемую тональность).
|
||||||
|
- Исключение `ChordFormatError` — для ошибок формата файла.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** Словарь токенов является константой
|
||||||
|
модуля; его изменение приводит к несовместимости с ранее обученными моделями,
|
||||||
|
поэтому любые изменения должны сопровождаться инкрементом версии спецификации
|
||||||
|
формата и переобучением моделей.
|
||||||
|
|
||||||
|
Транспозиция реализуется через расчёт интервала в полутонах между исходным и
|
||||||
|
целевым тонами, после чего к каждому корневому тону и бассу применяется
|
||||||
|
циклический сдвиг по 12-тоновой системе. Качество и расширения аккорда при
|
||||||
|
транспозиции не меняются.
|
||||||
|
|
||||||
|
**Связи.** Используется всеми остальными модулями для входа и выхода из
|
||||||
|
токенизированного пространства. Зависит от `chord_parser.py`.
|
||||||
|
|
||||||
|
### 3.3 `src/midi_export.py`
|
||||||
|
|
||||||
|
**Назначение.** Преобразование `.chord`-файлов в стандартные MIDI-файлы для
|
||||||
|
прослушивания в DAW и для использования сгенерированных периодов в
|
||||||
|
композиторской работе.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- `chord_file_to_midi(chord_path, midi_path, tempo=90)` — основная функция.
|
||||||
|
- `period_to_midi(period: ChordPeriod, midi_path, tempo=90)` — вариант,
|
||||||
|
принимающий уже распарсенный период.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** MIDI-файл содержит два инструментальных
|
||||||
|
трека: трек аккордов и трек баса. Аккорды раскладываются в средней октаве
|
||||||
|
(C4–B5) тремя или четырьмя одновременными нотами, бас — в нижней октаве (C2–B2)
|
||||||
|
одной нотой. Длительности соответствуют длительностям удержания аккордов в
|
||||||
|
исходном `.chord`-файле.
|
||||||
|
|
||||||
|
Voicing внутри аккорда выполняется минимально — простое расположение нот в
|
||||||
|
тесном расположении от корня. Это не задача данного модуля и сознательно
|
||||||
|
оставлено простым.
|
||||||
|
|
||||||
|
**Связи.** Зависит от `tokenizer.py` (для парсинга `.chord`) и `pretty_midi`.
|
||||||
|
|
||||||
|
### 3.4 `src/dataset.py`
|
||||||
|
|
||||||
|
**Назначение.** Реализация PyTorch-датасета над предварительно
|
||||||
|
токенизированными `.pt`-файлами.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- Класс `ChordDataset(torch.utils.data.Dataset)`.
|
||||||
|
- Конструктор принимает путь к директории с `.pt`-файлами и максимальную
|
||||||
|
длину последовательности.
|
||||||
|
- `__getitem__` возвращает тензор токенов, обрезанный или дополненный
|
||||||
|
паддингом до максимальной длины.
|
||||||
|
- Функция `make_dataloader(dataset, batch_size, shuffle) -> DataLoader` —
|
||||||
|
удобная фабрика.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** Все `.pt`-файлы загружаются в память при
|
||||||
|
создании датасета. Это допустимо при текущем размере данных (тысячи периодов
|
||||||
|
максимум) и существенно ускоряет обучение по сравнению с подгрузкой с диска.
|
||||||
|
|
||||||
|
Паддинг выполняется специальным токеном `<PAD>` с индексом 2 в словаре.
|
||||||
|
В функции потерь этот индекс игнорируется через параметр `ignore_index`.
|
||||||
|
|
||||||
|
### 3.5 `src/model.py`
|
||||||
|
|
||||||
|
**Назначение.** Определение нейросетевой архитектуры.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- Класс `ChordTransformer(nn.Module)` с параметрами конструктора:
|
||||||
|
`vocab_size`, `d_model`, `n_layers`, `n_heads`, `d_ff`, `max_seq_len`,
|
||||||
|
`dropout`.
|
||||||
|
|
||||||
|
**Архитектурные детали.** Декодер-only трансформер с pre-normalization
|
||||||
|
(нормализация перед остаточной связью, а не после). Эмбеддинги токенов и
|
||||||
|
позиционные эмбеддинги — обучаемые. Веса входного эмбеддинга и финальной
|
||||||
|
проекции на словарь связаны (tied weights), что сокращает число параметров
|
||||||
|
и стабилизирует обучение на малых данных.
|
||||||
|
|
||||||
|
Каждый блок трансформера состоит из:
|
||||||
|
|
||||||
|
- LayerNorm
|
||||||
|
- Causal multi-head self-attention с маскированием будущих позиций
|
||||||
|
- Residual connection
|
||||||
|
- LayerNorm
|
||||||
|
- Feedforward с активацией GELU
|
||||||
|
- Residual connection
|
||||||
|
|
||||||
|
После последнего блока — финальная LayerNorm и линейная проекция на размер
|
||||||
|
словаря.
|
||||||
|
|
||||||
|
**Связи.** Используется в модулях обучения и инференса.
|
||||||
|
|
||||||
|
### 3.6 `src/train.py`
|
||||||
|
|
||||||
|
**Назначение.** Логика обучения, общая для предобучения и дообучения.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- Функция `train_model(config: TrainConfig) -> Path` — основная точка
|
||||||
|
входа. Возвращает путь к лучшему чекпоинту.
|
||||||
|
- Dataclass `TrainConfig` с полями для всех гиперпараметров.
|
||||||
|
|
||||||
|
**Особенности.** Один общий цикл обучения параметризуется аргументом
|
||||||
|
`init_from`. Если этот аргумент задан, веса модели инициализируются из
|
||||||
|
указанного чекпоинта, иначе — случайно. Это позволяет использовать один и
|
||||||
|
тот же код для предобучения и дообучения, различающихся только параметрами
|
||||||
|
запуска (низкий learning rate, меньшее число эпох для дообучения).
|
||||||
|
|
||||||
|
Логирование: после каждой эпохи в stdout выводится строка с номером эпохи,
|
||||||
|
тренировочной потерей, валидационной потерей и валидационной перплексией.
|
||||||
|
Параллельно строка добавляется в CSV-лог. Лучший по валидационной потере
|
||||||
|
чекпоинт сохраняется отдельно.
|
||||||
|
|
||||||
|
Ранняя остановка: если валидационная потеря не улучшается на протяжении N
|
||||||
|
эпох (по умолчанию 5), обучение завершается досрочно.
|
||||||
|
|
||||||
|
### 3.7 `src/generate.py`
|
||||||
|
|
||||||
|
**Назначение.** Сэмплирование из обученной модели.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- Функция `generate_period(model, mode, time, subdivision, style, function,
|
||||||
|
key, prefix=None, temperature=1.0, top_p=0.9, max_tokens=300, seed=None)
|
||||||
|
-> ChordPeriod`.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** Авторегрессионная генерация выполняется
|
||||||
|
по одному токену за раз. Для каждого шага:
|
||||||
|
|
||||||
|
1. Прогон последовательности через модель, получение распределения над
|
||||||
|
следующим токеном.
|
||||||
|
2. Деление логитов на температуру.
|
||||||
|
3. Применение nucleus sampling: оставляем минимальный по числу элементов
|
||||||
|
набор кандидатов с накопленной вероятностью не менее top_p.
|
||||||
|
4. Маскирование грамматически невалидных кандидатов (например, токена
|
||||||
|
расширения сразу после токена удержания).
|
||||||
|
5. Сэмплирование из оставшегося распределения.
|
||||||
|
6. Останов при появлении `<EOS>` или при достижении лимита токенов.
|
||||||
|
|
||||||
|
После завершения генерации последовательность детокенизируется, получившийся
|
||||||
|
период транспонируется из канонической тональности в целевую и возвращается
|
||||||
|
вызывающему.
|
||||||
|
|
||||||
|
### 3.8 `src/evaluate.py`
|
||||||
|
|
||||||
|
**Назначение.** Расчёт метрик качества и построение распределений.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- `compute_perplexity(model, dataloader) -> float`.
|
||||||
|
- `extract_features(period: ChordPeriod) -> dict` — извлекает гармонические
|
||||||
|
признаки периода: список типов качеств, доли инверсий, интервалы движения
|
||||||
|
корня, биграммы корней.
|
||||||
|
- `compare_distributions(baseline_features, target_features) -> dict` —
|
||||||
|
агрегирует признаки и формирует структуры для построения графиков.
|
||||||
|
- `plot_comparison(distributions, output_dir)` — рисует и сохраняет графики.
|
||||||
|
|
||||||
|
### 3.9 `src/external_converters/mcgill_to_chord.py`
|
||||||
|
|
||||||
|
**Назначение.** Конвертация аннотаций McGill Billboard Project в формат
|
||||||
|
`.chord`.
|
||||||
|
|
||||||
|
**Публичный интерфейс.**
|
||||||
|
|
||||||
|
- `convert_directory(input_dir, output_dir, log_path=None)` — конвертирует
|
||||||
|
все пьесы из исходной директории.
|
||||||
|
- `convert_song(song_dir, output_dir) -> list[Path]` — конвертирует одну
|
||||||
|
пьесу, возвращает список путей к созданным файлам периодов.
|
||||||
|
|
||||||
|
**Ключевые соображения реализации.** Harte-нотация McGill отличается от
|
||||||
|
формата проекта по ряду признаков: использует другие имена качеств, явно
|
||||||
|
указывает интервальный состав в скобках, имеет иную систему обозначения
|
||||||
|
длительностей. Конвертер реализует таблицу соответствий между Harte и форматом
|
||||||
|
проекта и приводит к ближайшему допустимому аккорду в случаях, когда точное
|
||||||
|
соответствие отсутствует.
|
||||||
|
|
||||||
|
Разрезание на периоды выполняется по разметке секций в исходных файлах
|
||||||
|
(`verse`, `chorus`, `bridge` и т.д.). Периоды длиной менее 4 или более 16
|
||||||
|
тактов пропускаются.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Модель машинного обучения
|
||||||
|
|
||||||
|
### 4.1 Выбор архитектуры
|
||||||
|
|
||||||
|
Архитектура декодер-only трансформера выбрана по следующим причинам.
|
||||||
|
|
||||||
|
**Соответствие задаче.** Гармоническая последовательность — это
|
||||||
|
последовательность дискретных символов с сильными локальными
|
||||||
|
зависимостями (соседние аккорды связаны функциональными отношениями) и
|
||||||
|
менее сильными глобальными зависимостями (начало и конец периода связаны
|
||||||
|
тонально). Self-attention отражает оба типа зависимостей естественным
|
||||||
|
образом.
|
||||||
|
|
||||||
|
**Совместимость со схемой предобучения + дообучения.** Архитектуры
|
||||||
|
семейства трансформеров — стандартный выбор для задач с малой целевой
|
||||||
|
выборкой и большим объёмом предобучающих данных.
|
||||||
|
|
||||||
|
**Простота реализации с нуля.** При выбранном масштабе модели (несколько
|
||||||
|
блоков, небольшая размерность) реализация умещается в нескольких сотнях
|
||||||
|
строк кода и не требует тяжёлых зависимостей.
|
||||||
|
|
||||||
|
Альтернатива в виде LSTM была рассмотрена и отвергнута на основании того,
|
||||||
|
что:
|
||||||
|
|
||||||
|
- При сопоставимом числе параметров трансформер обычно работает не хуже на
|
||||||
|
задачах с дискретными последовательностями.
|
||||||
|
- Параллелизация обучения трансформера эффективнее.
|
||||||
|
- Стандартное предобучение языковых моделей через next-token prediction
|
||||||
|
легче переносится на трансформер, чем на рекуррентные сети.
|
||||||
|
|
||||||
|
### 4.2 Параметры модели
|
||||||
|
|
||||||
|
Размер модели сознательно выбран небольшим — порядка одного-трёх миллионов
|
||||||
|
параметров. Это обусловлено объёмом обучающих данных: при тысячах примеров
|
||||||
|
крупная модель неизбежно переобучится, а компактная сохранит способность
|
||||||
|
к обобщению. Рекомендуемая конфигурация:
|
||||||
|
|
||||||
|
| Параметр | Значение |
|
||||||
|
| ---------------------------- | ----------- |
|
||||||
|
| Число слоёв | 3 |
|
||||||
|
| Размерность модели (d_model) | 192 |
|
||||||
|
| Число голов внимания | 6 |
|
||||||
|
| Размерность FFN | 768 |
|
||||||
|
| Длина контекста | 512 токенов |
|
||||||
|
| Размер словаря | 81 |
|
||||||
|
| Dropout | 0.1 |
|
||||||
|
|
||||||
|
При необходимости конфигурация может быть пересмотрена в сторону уменьшения
|
||||||
|
(если модель не сходится) или увеличения (если результаты явно недостаточны
|
||||||
|
и есть запас времени на эксперимент).
|
||||||
|
|
||||||
|
### 4.3 Функция потерь и оптимизация
|
||||||
|
|
||||||
|
Стандартная кросс-энтропия с игнорированием `<PAD>`-токена. Оптимизатор —
|
||||||
|
AdamW. Расписание learning rate — косинусное снижение с линейным разогревом
|
||||||
|
на 5% от общего числа шагов.
|
||||||
|
|
||||||
|
**Предобучение.** Стартовый learning rate 3·10⁻⁴, 50 эпох (с возможностью
|
||||||
|
ранней остановки).
|
||||||
|
|
||||||
|
**Дообучение.** Стартовый learning rate 1·10⁻⁵, 15 эпох с ранней остановкой.
|
||||||
|
|
||||||
|
Двухпорядковая разница в learning rate между предобучением и дообучением —
|
||||||
|
ключевой приём для предотвращения катастрофического забывания: на этапе
|
||||||
|
дообучения веса модели изменяются медленно, что сохраняет общие
|
||||||
|
гармонические закономерности, выученные на крупном корпусе.
|
||||||
|
|
||||||
|
### 4.4 Генерация
|
||||||
|
|
||||||
|
Используется nucleus sampling (top-p) с температурой 1.0 по умолчанию.
|
||||||
|
Параметры регулируются на этапе инференса.
|
||||||
|
|
||||||
|
Beam search отвергнут на основании опыта генеративных задач: он склонен
|
||||||
|
порождать монотонные, многократно повторяющиеся последовательности, что
|
||||||
|
особенно нежелательно в задаче создания творческих идей.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Конвейер обучения
|
||||||
|
|
||||||
|
### 5.1 Подготовка данных
|
||||||
|
|
||||||
|
```
|
||||||
|
сырьё (.chord)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
парсинг и валидация
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
транспозиция в каноническую тональность
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
токенизация
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
случайное разбиение на train/val (90/10)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
сохранение .pt-файлов
|
||||||
|
```
|
||||||
|
|
||||||
|
Разбиение train/val выполняется на уровне периодов, а не на уровне исходных
|
||||||
|
пьес. Для собственного корпуса это компромиссное решение: разбиение по
|
||||||
|
пьесам было бы методологически чище, но при 20–25 пьесах привело бы к
|
||||||
|
слишком высокой дисперсии валидационной потери. Holdout-выборка, в свою
|
||||||
|
очередь, специально формируется на уровне пьес, что обеспечивает честность
|
||||||
|
итоговой оценки.
|
||||||
|
|
||||||
|
### 5.2 Цикл предобучения
|
||||||
|
|
||||||
|
```
|
||||||
|
инициализация модели случайными весами
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
для каждой эпохи (1..50):
|
||||||
|
│
|
||||||
|
├── проход по train: forward, loss, backward, optimizer step
|
||||||
|
│ │
|
||||||
|
│ ▼
|
||||||
|
│ агрегация train_loss за эпоху
|
||||||
|
│
|
||||||
|
├── проход по val (без градиентов): forward, loss
|
||||||
|
│ │
|
||||||
|
│ ▼
|
||||||
|
│ агрегация val_loss и val_perplexity
|
||||||
|
│
|
||||||
|
├── запись строки в CSV-лог
|
||||||
|
│
|
||||||
|
├── если val_loss улучшилась — сохранение чекпоинта
|
||||||
|
│
|
||||||
|
└── если val_loss не улучшалась 5 эпох подряд — выход
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Цикл дообучения
|
||||||
|
|
||||||
|
Идентичен циклу предобучения по структуре, отличается:
|
||||||
|
|
||||||
|
- Инициализация модели из чекпоинта предобучения.
|
||||||
|
- Меньший learning rate.
|
||||||
|
- Меньшее максимальное число эпох (15).
|
||||||
|
- Опционально: меньший patience для ранней остановки.
|
||||||
|
|
||||||
|
### 5.4 Контроль качества обучения
|
||||||
|
|
||||||
|
В процессе обучения отслеживаются следующие признаки нормального хода:
|
||||||
|
|
||||||
|
- Train loss монотонно снижается.
|
||||||
|
- Val loss снижается синхронно с train loss до точки, после которой
|
||||||
|
начинается расхождение (типичное переобучение). Лучший чекпоинт
|
||||||
|
сохраняется до точки расхождения.
|
||||||
|
- Val perplexity на сошедшейся модели находится в диапазоне 2–6 для нашей
|
||||||
|
задачи. Существенно меньшие значения указывают на ошибку (например,
|
||||||
|
пересечение train и val выборок). Существенно большие — на плохую
|
||||||
|
сходимость или несоответствие модели данным.
|
||||||
|
|
||||||
|
Если эти признаки нарушаются, необходимо в первую очередь проверить
|
||||||
|
корректность подготовленных данных: токенизацию случайных файлов руками,
|
||||||
|
отсутствие пересечений между выборками, баланс распределения метаданных.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Конвейер инференса и оценки
|
||||||
|
|
||||||
|
### 6.1 Инференс
|
||||||
|
|
||||||
|
Подробное описание процесса генерации приведено в разделе 3.7. Ключевые
|
||||||
|
особенности:
|
||||||
|
|
||||||
|
- Все параметры запроса передаются через CLI-аргументы.
|
||||||
|
- Случайное зерно фиксируется, что обеспечивает воспроизводимость отдельных
|
||||||
|
семплов.
|
||||||
|
- Невалидные грамматические последовательности маскируются на каждом шаге
|
||||||
|
сэмплирования.
|
||||||
|
- Результат сразу сохраняется в двух форматах: `.chord` (для возможного
|
||||||
|
редактирования или подачи модели как затравки в дальнейшем) и MIDI (для
|
||||||
|
прослушивания).
|
||||||
|
|
||||||
|
### 6.2 Количественная оценка
|
||||||
|
|
||||||
|
**Перплексия** на отложенной выборке рассчитывается как экспонента средней
|
||||||
|
кросс-энтропии. Сравнение перплексий базовой и целевой моделей на одной
|
||||||
|
выборке показывает, насколько сильно дообучение сместило распределение
|
||||||
|
вероятностей модели в сторону распределения собственного корпуса автора.
|
||||||
|
|
||||||
|
Снижение перплексии на отложенной выборке после дообучения является
|
||||||
|
основным численным индикатором успеха проекта. Ожидаемая величина снижения —
|
||||||
|
от 10% до 50% относительно базовой модели.
|
||||||
|
|
||||||
|
### 6.3 Качественная оценка через распределения
|
||||||
|
|
||||||
|
Качественная сторона эффекта дообучения оценивается через сравнение
|
||||||
|
гистограмм по следующим признакам.
|
||||||
|
|
||||||
|
**Типы качеств аккордов.** Распределение по 18 базовым качествам. На малых
|
||||||
|
данных авторский стиль часто проявляется в смещении этого распределения:
|
||||||
|
например, повышенная частота больших септаккордов и нонаккордов или,
|
||||||
|
напротив, преобладание простых трезвучий.
|
||||||
|
|
||||||
|
**Доля инверсий.** Процент аккордов с явно указанным басом, отличным от
|
||||||
|
корня. Этот признак особенно характерен для индивидуального стиля и для
|
||||||
|
конкретных жанров (J-Pop, например, активно использует слэш-аккорды).
|
||||||
|
|
||||||
|
**Интервалы движения корня.** Распределение интервалов между корнями
|
||||||
|
соседних аккордов в полутонах. Например, доминирование интервала –5
|
||||||
|
полутонов (квинтовый ход вниз) характерно для барочной и классической
|
||||||
|
гармонии; преобладание интервалов –2, +2 — для более поп-ориентированных
|
||||||
|
стилей.
|
||||||
|
|
||||||
|
**Биграммы корней.** Частоты пар «текущий корень → следующий корень». Эти
|
||||||
|
биграммы захватывают функциональные предпочтения автора: например,
|
||||||
|
характерные переходы IV → V или V → vi.
|
||||||
|
|
||||||
|
Графики строятся как наложение двух гистограмм (baseline-распределение и
|
||||||
|
target-распределение) на одной координатной плоскости. Визуальный сдвиг
|
||||||
|
target относительно baseline — прямое подтверждение того, что дообучение
|
||||||
|
сработало.
|
||||||
|
|
||||||
|
### 6.4 Качественная оценка через прослушивание
|
||||||
|
|
||||||
|
Для отчёта формируются три специально подобранные («cherry-picked») пары
|
||||||
|
сгенерированных образцов: для каждой из выбранных гармонических затравок —
|
||||||
|
по одному примеру от базовой и от дообученной модели с одним и тем же
|
||||||
|
случайным зерном. Эти примеры конвертируются в MIDI и прилагаются к отчёту
|
||||||
|
(в виде ссылок и описаний).
|
||||||
|
|
||||||
|
Слепой listening-тест с привлечением сторонних слушателей не проводится из
|
||||||
|
соображений ограничения по времени.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Ключевые проектные решения
|
||||||
|
|
||||||
|
В этом разделе фиксируются проектные решения, принятые на этапе
|
||||||
|
проектирования, и обоснования к ним. Решения изложены в виде записей в
|
||||||
|
стиле Architectural Decision Records.
|
||||||
|
|
||||||
|
### 7.1 ПР-01. Юнит обработки — гармонический период, а не пьеса целиком
|
||||||
|
|
||||||
|
**Контекст.** Изначально рассматривался вариант обучения модели на целых
|
||||||
|
пьесах. При объёме собственного корпуса 20–25 пьес и средней длине каждой
|
||||||
|
40–100 тактов это давало бы датасет из 20–25 длинных последовательностей —
|
||||||
|
крайне малый объём для генеративной модели.
|
||||||
|
|
||||||
|
**Решение.** Единицей обработки и генерации является гармонический период —
|
||||||
|
замкнутая фраза 4–16 тактов. Из одной пьесы извлекается 4–8 периодов.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Эффективный объём датасета увеличивается в 4–8 раз.
|
||||||
|
- Проблема обработки модуляций между секциями исчезает: внутри периода
|
||||||
|
модуляций нет.
|
||||||
|
- Длина обучающей последовательности становится меньшей и более однородной
|
||||||
|
(50–250 токенов вместо 500–1500), что упрощает обучение.
|
||||||
|
- Юнит хорошо соответствует реальному композиторскому воркфлоу: помощник
|
||||||
|
выдаёт идеи периодами, а не целыми пьесами.
|
||||||
|
|
||||||
|
### 7.2 ПР-02. Нормализующая транспозиция в C major / A minor
|
||||||
|
|
||||||
|
**Контекст.** Если каждый период хранится в исходной тональности,
|
||||||
|
функционально эквивалентные последовательности в разных тональностях
|
||||||
|
становятся для модели разными последовательностями. Это резко увеличивает
|
||||||
|
эффективное разнообразие данных в 12 раз и затрудняет обобщение.
|
||||||
|
|
||||||
|
**Решение.** Перед токенизацией все периоды транспонируются: мажорные — в
|
||||||
|
C major, минорные — в A minor. Тональность в словарь модели не входит.
|
||||||
|
На инференсе результат транспонируется обратно в требуемую тональность
|
||||||
|
постпроцессингом.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Эффективное увеличение датасета в 12 раз.
|
||||||
|
- Сокращение словаря на 24 токена.
|
||||||
|
- Цвет конкретной тональности (характерное звучание Fis-dur против C-dur)
|
||||||
|
теряется. Это исполнительское свойство, не функционально-гармоническое,
|
||||||
|
и для задачи генерации прогрессий не релевантно.
|
||||||
|
- Внутренние модуляции и тонизации записываются обычными функциональными
|
||||||
|
аккордами и обрабатываются единообразно.
|
||||||
|
|
||||||
|
### 7.3 ПР-03. Факторизованная токенизация аккордов
|
||||||
|
|
||||||
|
**Контекст.** Каждый аккорд можно представить либо одним атомарным токеном
|
||||||
|
(`Cmaj7`, `Am7`, `F/G` как отдельные элементы словаря), либо разложенным
|
||||||
|
на несколько токенов (корень, качество, расширение, бас).
|
||||||
|
|
||||||
|
**Решение.** Каждый аккорд представляется ровно четырьмя токенами:
|
||||||
|
`ROOT_x`, `QUAL_x`, `EXT_x`, `BASS_x`. Словарь содержит 81 токен против
|
||||||
|
нескольких сотен в случае атомарной токенизации.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Существенно меньший словарь, легче обучаемый на малых данных.
|
||||||
|
- Модель видит общность между, например, всеми минорными септаккордами,
|
||||||
|
а не учит их как 12 несвязанных слов.
|
||||||
|
- Каждый аккорд занимает в последовательности четыре позиции вместо одной,
|
||||||
|
что увеличивает длину последовательности и нагрузку на attention. При
|
||||||
|
выбранной длине контекста 512 это не создаёт проблем.
|
||||||
|
- Появляется необходимость грамматического маскирования при генерации:
|
||||||
|
не любой токен может следовать за любым.
|
||||||
|
|
||||||
|
### 7.4 ПР-04. Двухстадийное обучение
|
||||||
|
|
||||||
|
**Контекст.** Прямое обучение модели на собственном корпусе автора
|
||||||
|
невозможно из-за крайне малого объёма данных.
|
||||||
|
|
||||||
|
**Решение.** Двухстадийная схема: предобучение на крупном публичном
|
||||||
|
корпусе (McGill Billboard Project) и последующее дообучение на собственном
|
||||||
|
корпусе с пониженным learning rate.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Базовые гармонические закономерности (функциональная гармония,
|
||||||
|
стандартные каденции) выучиваются на этапе предобучения.
|
||||||
|
- Индивидуальный стиль автора подмешивается на этапе дообучения без
|
||||||
|
необходимости заново выучивать общие законы.
|
||||||
|
- Появляется естественная схема сравнения «до и после» дообучения для
|
||||||
|
отчёта.
|
||||||
|
- Существует риск катастрофического забывания на этапе дообучения, что
|
||||||
|
митигируется низким learning rate и небольшим числом эпох.
|
||||||
|
|
||||||
|
### 7.5 ПР-05. Минималистичная реализация без тяжёлых фреймворков
|
||||||
|
|
||||||
|
**Контекст.** Существует ряд готовых фреймворков для обучения трансформеров
|
||||||
|
(PyTorch Lightning, HuggingFace Trainer, fastai), которые скрывают
|
||||||
|
boilerplate кода тренировочного цикла.
|
||||||
|
|
||||||
|
**Решение.** Использовать чистый PyTorch с явным циклом обучения.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Код полностью прозрачен и поддаётся пошаговой отладке, что важно для
|
||||||
|
учебного проекта.
|
||||||
|
- Снижается риск проблем с совместимостью версий и сложным поведением
|
||||||
|
фреймворков «из коробки».
|
||||||
|
- Объём кода тренировочного цикла остаётся небольшим (порядка двух сотен
|
||||||
|
строк).
|
||||||
|
- Теряется доступ к некоторым удобствам фреймворков (готовые callbacks,
|
||||||
|
логирование в TensorBoard и т.п.). Для масштабов проекта это
|
||||||
|
несущественно.
|
||||||
|
|
||||||
|
### 7.6 ПР-06. Ручная транскрипция собственного корпуса
|
||||||
|
|
||||||
|
**Контекст.** Альтернатива — автоматическое извлечение аккордов из аудио
|
||||||
|
с помощью библиотек вроде Chordino, librosa, или нейросетевых детекторов.
|
||||||
|
|
||||||
|
**Решение.** Транскрипция выполняется автором вручную, на основе
|
||||||
|
DAW-проектов с использованием абсолютного слуха.
|
||||||
|
|
||||||
|
**Последствия.**
|
||||||
|
|
||||||
|
- Качество транскрипции существенно выше автоматического: тонкие гармонические
|
||||||
|
решения, нестандартные расширения, точные инверсии — всё это передаётся
|
||||||
|
без потерь.
|
||||||
|
- Существенные временные затраты (10–15 часов). Это самая трудозатратная
|
||||||
|
часть проекта.
|
||||||
|
- Невозможность масштабирования на большой корпус. Для текущей задачи
|
||||||
|
(80–150 периодов) это приемлемо.
|
||||||
|
|
||||||
|
### 7.7 ПР-07. Английский язык в коде, русский — в документации и отчёте
|
||||||
|
|
||||||
|
**Контекст.** Учебное заведение требует оформления отчёта на русском
|
||||||
|
языке. С другой стороны, стандарты разработки и совместимость с
|
||||||
|
инструментами вроде Claude Code предполагают английский язык в коде.
|
||||||
|
|
||||||
|
**Решение.** Чёткое разделение по слоям:
|
||||||
|
|
||||||
|
- Код, идентификаторы, комментарии, сообщения логов, коммиты — английский.
|
||||||
|
- Документация (README, спецификация, требования, архитектура,
|
||||||
|
глоссарий) — русский.
|
||||||
|
- Итоговый отчёт — русский с оформлением по ГОСТу.
|
||||||
|
|
||||||
|
**Последствия.** Однозначность для всех участников разработки.
|
||||||
|
Двуязычность не создаёт неудобств, поскольку слои разделены.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Точки расширения
|
||||||
|
|
||||||
|
Перечисленные ниже направления развития проекта оставлены явно за рамками
|
||||||
|
текущей версии. Их реализация может рассматриваться в будущем.
|
||||||
|
|
||||||
|
### 8.1 Дообучение на корпусе японской поп-музыки
|
||||||
|
|
||||||
|
**Описание.** После защиты курсовой работы планируется собрать второй
|
||||||
|
авторский корпус — гармонические периоды из японских поп-песен (Royal Road
|
||||||
|
прогрессии, mu-аккорды, характерные секундовые надстройки, on-аккорды) — и
|
||||||
|
выполнить дополнительное дообучение модели на этом материале с тегом
|
||||||
|
`STYLE_jpop`.
|
||||||
|
|
||||||
|
**Что уже подготовлено для этого расширения.** В словаре токенов
|
||||||
|
зарезервирован токен `STYLE_jpop`. Формат `.chord` поддерживает любые
|
||||||
|
характерные для J-Pop приёмы (расширенные аккорды, инверсии, слэш-аккорды).
|
||||||
|
В шапке файла предусмотрено поле `style`.
|
||||||
|
|
||||||
|
**Что нужно дополнительно сделать.** Собрать и транскрибировать корпус
|
||||||
|
J-Pop периодов. Выполнить дообучение существующей модели на смешанном
|
||||||
|
корпусе (свой + J-Pop) или последовательное дообучение (свой → J-Pop).
|
||||||
|
Сравнить генерации с разными значениями стилевого conditioning.
|
||||||
|
|
||||||
|
### 8.2 Генерация мелодии
|
||||||
|
|
||||||
|
**Описание.** Расширение модели на генерацию монофонической мелодической
|
||||||
|
линии, привязанной к гармонической последовательности.
|
||||||
|
|
||||||
|
**Что нужно сделать.** Расширить формат `.chord` дополнительным полем для
|
||||||
|
мелодической линии (или ввести отдельный формат). Расширить словарь
|
||||||
|
токенов мелодическими токенами (вероятно, через раздельное представление
|
||||||
|
ступени, длительности, артикуляции). Архитектура модели может остаться
|
||||||
|
прежней.
|
||||||
|
|
||||||
|
**Сложность.** Существенная: задача мелодизации сложнее, чем гармонизации,
|
||||||
|
требует больше данных, имеет другие критерии оценки.
|
||||||
|
|
||||||
|
### 8.3 Voicing внутри аккорда
|
||||||
|
|
||||||
|
**Описание.** Автоматическое расположение нот внутри аккорда выше баса
|
||||||
|
с учётом голосоведения (минимизация суммарного движения голосов, запрет
|
||||||
|
параллельных квинт и октав, разрешение тяготеющих ступеней).
|
||||||
|
|
||||||
|
**Что нужно сделать.** Эта задача может быть решена rule-based методом без
|
||||||
|
машинного обучения. Простой алгоритм минимизации суммарного межаккордового
|
||||||
|
смещения голосов с дополнительными правилами укладывается в несколько
|
||||||
|
сотен строк кода.
|
||||||
|
|
||||||
|
**Сложность.** Низкая, выполнима за день-два после защиты курсовой.
|
||||||
|
|
||||||
|
### 8.4 Графический пользовательский интерфейс
|
||||||
|
|
||||||
|
**Описание.** Веб- или десктоп-приложение, позволяющее задавать параметры
|
||||||
|
генерации интерактивно, прослушивать результат прямо в браузере, сохранять
|
||||||
|
понравившиеся варианты.
|
||||||
|
|
||||||
|
**Что нужно сделать.** Любой современный веб-фреймворк (FastAPI на backend,
|
||||||
|
любой минимальный frontend) поверх существующего CLI. Воспроизведение
|
||||||
|
MIDI в браузере через `Tone.js` или подобные библиотеки.
|
||||||
|
|
||||||
|
**Сложность.** Невысокая по нынешним стандартам, но требует существенного
|
||||||
|
времени.
|
||||||
|
|
||||||
|
### 8.5 Интеграция с REAPER
|
||||||
|
|
||||||
|
**Описание.** Плагин или внешний инструмент, который при работе в REAPER
|
||||||
|
позволяет запрашивать генерацию следующего фрагмента прямо из проекта,
|
||||||
|
учитывая текущий гармонический контекст.
|
||||||
|
|
||||||
|
**Сложность.** REAPER предоставляет ReaScript для расширений на Lua и
|
||||||
|
Python. Реализация возможна, но требует погружения в API REAPER.
|
||||||
|
|
||||||
|
### 8.6 Обработка модуляций внутри периода
|
||||||
|
|
||||||
|
**Описание.** Текущая версия требует разрезания периодов по точке
|
||||||
|
модуляции. Альтернатива — введение inline-токена `MODULATE_<note>_<mode>`,
|
||||||
|
переключающего тонический центр в середине последовательности.
|
||||||
|
|
||||||
|
**Что нужно сделать.** Расширить словарь токенов на 24 модуляционных
|
||||||
|
токена. Дополнить парсер и токенизатор поддержкой inline-меток модуляции.
|
||||||
|
Накопить достаточное число обучающих примеров с модуляциями (что
|
||||||
|
проблематично при малом исходном корпусе).
|
||||||
|
|
||||||
|
**Сложность.** Средняя, основное ограничение — данные.
|
||||||
|
|
||||||
|
### 8.7 Поддержка большего числа альтераций в аккорде
|
||||||
|
|
||||||
|
**Описание.** Текущая версия поддерживает один слот расширения на аккорд.
|
||||||
|
Альтерированные доминанты с несколькими альтерациями одновременно
|
||||||
|
(`C7♯9♭13`) сворачиваются до одной альтерации.
|
||||||
|
|
||||||
|
**Что нужно сделать.** Перейти от единственного `EXT_x` токена к множеству
|
||||||
|
одновременных токенов расширений. Это требует пересмотра грамматики
|
||||||
|
последовательности и формата представления одного аккорда (теперь его
|
||||||
|
описание становится не четырёхтокеновым, а переменной длины).
|
||||||
|
|
||||||
|
**Сложность.** Средняя, в основном проектная — требуется аккуратное
|
||||||
|
обновление формата с инкрементом версии.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. История изменений
|
||||||
|
|
||||||
|
- **1.0** (2026-05-19) — первоначальная редакция документа.
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
# Спецификация формата данных
|
# Спецификация формата данных hamori
|
||||||
|
|
||||||
## Проект: генератор аккордовых последовательностей
|
|
||||||
|
|
||||||
**Версия:** 2.0
|
**Версия:** 2.0
|
||||||
**Дата:** 2026-05-16
|
**Дата:** 2026-05-16
|
||||||
|
|||||||
@@ -0,0 +1,567 @@
|
|||||||
|
# Глоссарий hamori
|
||||||
|
|
||||||
|
**Версия документа:** 1.0
|
||||||
|
**Дата:** 2026-05-19
|
||||||
|
|
||||||
|
Документ содержит определения терминов, используемых в проекте _hamori_,
|
||||||
|
разделённые на три тематические группы: музыкальные термины, термины
|
||||||
|
машинного обучения и проектные термины. Внутри каждой группы записи
|
||||||
|
упорядочены по алфавиту.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Музыкальные термины
|
||||||
|
|
||||||
|
### Аккорд
|
||||||
|
|
||||||
|
Гармоническая единица — одновременное звучание трёх и более нот. В контексте
|
||||||
|
проекта аккорд представляется в текстовой нотации (например, `Cmaj7`, `Am`,
|
||||||
|
`F/G`) и характеризуется четырьмя признаками: корневой тон, качество,
|
||||||
|
расширение, бас.
|
||||||
|
|
||||||
|
### Аккордовая последовательность (прогрессия)
|
||||||
|
|
||||||
|
Последовательность аккордов, сопровождающая мелодию или существующая
|
||||||
|
самостоятельно. Является основным объектом генерации в данном проекте.
|
||||||
|
|
||||||
|
### Альтерация
|
||||||
|
|
||||||
|
Хроматическое изменение ступени аккорда — повышение или понижение её на
|
||||||
|
полутон. В рамках формата проекта альтерации записываются как расширения
|
||||||
|
вида `b9`, `#9`, `#11`, `b13`.
|
||||||
|
|
||||||
|
### Анакруза (затакт)
|
||||||
|
|
||||||
|
Несколько нот или один аккорд, предшествующих первой сильной доле такта.
|
||||||
|
В формате проекта затакт записывается через специальное значение `NC`
|
||||||
|
(no chord) на пустых позициях первого такта.
|
||||||
|
|
||||||
|
### Бас
|
||||||
|
|
||||||
|
Самая нижняя нота аккорда. Может совпадать с корневым тоном (основной
|
||||||
|
позиции) или отличаться от него (в инверсиях и слэш-аккордах). В формате
|
||||||
|
проекта бас выделен в отдельный слот токенизации.
|
||||||
|
|
||||||
|
### Гармоническая функция
|
||||||
|
|
||||||
|
Роль аккорда в тональной системе: тоника (T), субдоминанта (S), доминанта
|
||||||
|
(D) и их побочные ступени. Хотя в формате проекта аккорды записываются
|
||||||
|
абсолютными именами, а не функциональными цифрами, нормализующая
|
||||||
|
транспозиция в C major / A minor делает функциональные роли явно читаемыми:
|
||||||
|
после транспозиции `C` всегда тоника мажорной пьесы, `A` — тоника
|
||||||
|
минорной.
|
||||||
|
|
||||||
|
### Гармонический период
|
||||||
|
|
||||||
|
Замкнутая гармоническая фраза длиной обычно 4, 8 или 16 тактов, имеющая
|
||||||
|
ясное начало и завершение (возврат к тонике или полукаденция). Является
|
||||||
|
**единицей обработки и генерации** в проекте.
|
||||||
|
|
||||||
|
### Голосоведение
|
||||||
|
|
||||||
|
Способ соединения нот в соседних аккордах: плавное движение голосов,
|
||||||
|
запрет параллельных квинт и октав, разрешение тяготеющих ступеней.
|
||||||
|
В текущей версии проекта голосоведение **не моделируется** —
|
||||||
|
сгенерированные аккорды передаются как абстрактные гармонические единицы,
|
||||||
|
а конкретное расположение голосов оставлено на ручную работу композитора
|
||||||
|
в DAW.
|
||||||
|
|
||||||
|
### Доминанта
|
||||||
|
|
||||||
|
Аккорд пятой ступени лада. Содержит вводный тон и создаёт сильное
|
||||||
|
тяготение к тонике. Обычная запись в виде доминантового септаккорда — `G7`
|
||||||
|
в C major, `E7` в A minor (с альтерированной третьей ступенью минора).
|
||||||
|
|
||||||
|
### Инверсия (обращение)
|
||||||
|
|
||||||
|
Аккорд, в котором в качестве баса выступает не корневой тон, а одна из
|
||||||
|
других нот аккорда (терция, квинта, септима). В формате проекта инверсии
|
||||||
|
записываются через слэш-нотацию: `C/E` (C мажор с басом E, первое
|
||||||
|
обращение), `C/G` (с басом G, второе обращение).
|
||||||
|
|
||||||
|
### Каденция
|
||||||
|
|
||||||
|
Гармонический оборот, завершающий музыкальную фразу. Полная каденция —
|
||||||
|
переход доминанты в тонику (V → I). Полукаденция — остановка на
|
||||||
|
доминанте, создающая ожидание продолжения. Полукаденция — характерный
|
||||||
|
признак середины периода в классических формах.
|
||||||
|
|
||||||
|
### Качество (тип) аккорда
|
||||||
|
|
||||||
|
Интервальная структура аккорда независимо от его корневого тона. Базовые
|
||||||
|
качества, поддерживаемые форматом проекта: мажорное и минорное трезвучия,
|
||||||
|
уменьшённое и увеличенное трезвучия, sus2 и sus4, мажорный, минорный,
|
||||||
|
доминантовый, полууменьшённый и уменьшённый септаккорды, минорно-мажорный
|
||||||
|
септаккорд, доминанта на sus4, увеличенный септаккорд, мажорный и минорный
|
||||||
|
аккорды с секстой, аккорды с добавленной ноной. Всего 18 качеств.
|
||||||
|
|
||||||
|
### Корневой тон
|
||||||
|
|
||||||
|
Основная нота, на которой строится аккорд. Не обязательно совпадает с
|
||||||
|
басом (см. _Инверсия_). В формате проекта корневой тон выделен в отдельный
|
||||||
|
слот токенизации.
|
||||||
|
|
||||||
|
### Лад
|
||||||
|
|
||||||
|
Структурно-функциональная организация звуков вокруг центра (тоники).
|
||||||
|
В проекте моделируются два лада: натуральный мажор и натуральный минор
|
||||||
|
(включая гармонический и мелодический миноры как разновидности — отдельно
|
||||||
|
не различаются). Лад фиксируется отдельным метатокеном `MODE_major` или
|
||||||
|
`MODE_minor`.
|
||||||
|
|
||||||
|
### Лид-шит-нотация
|
||||||
|
|
||||||
|
Способ записи музыки, при котором над тактами выписывается мелодия, а
|
||||||
|
гармония указывается аккордовыми символами без точной нотации каждой ноты
|
||||||
|
аккорда. Формат `.chord` в проекте — упрощённый аналог лид-шита,
|
||||||
|
содержащий только гармоническую часть.
|
||||||
|
|
||||||
|
### Минор гармонический
|
||||||
|
|
||||||
|
Разновидность минорного лада с повышенной седьмой ступенью, создающая
|
||||||
|
выраженную доминанту. Внутренние альтерации (V становится мажорным,
|
||||||
|
появляется уменьшённый VII7) трактуются в формате проекта как обычные
|
||||||
|
аккорды.
|
||||||
|
|
||||||
|
### Модуляция
|
||||||
|
|
||||||
|
Смена тональности в произведении. В рамках текущей версии формата
|
||||||
|
поддерживается только модуляция **между периодами** (каждый период
|
||||||
|
хранится в своей тональности). Модуляция **внутри периода** обрабатывается
|
||||||
|
через разрезание периода на два — до и после момента модуляции.
|
||||||
|
|
||||||
|
### Нонаккорд
|
||||||
|
|
||||||
|
Аккорд, расширенный девятой ступенью от корня. В формате проекта —
|
||||||
|
`Cmaj9` (мажорный септаккорд + натуральная нона), `C9` (доминантовый
|
||||||
|
септаккорд + нона), `Cm9` (минорный септаккорд + нона), `Cmaj7#11` (с
|
||||||
|
повышенной квартой), и другие. Записывается как качество + расширение в
|
||||||
|
слоте `EXT`.
|
||||||
|
|
||||||
|
### Подразделение доли (subdivision)
|
||||||
|
|
||||||
|
Параметр формата, определяющий, на сколько временных позиций делится один
|
||||||
|
такт. При `subdivision: 4` в размере 4/4 каждый такт делится на четыре
|
||||||
|
четверти (четыре позиции). При `subdivision: 8` — на восемь восьмых
|
||||||
|
(восемь позиций). Выбирается в зависимости от того, как часто меняются
|
||||||
|
аккорды в конкретной пьесе.
|
||||||
|
|
||||||
|
### Полиаккорд
|
||||||
|
|
||||||
|
Одновременное звучание двух функционально различных аккордов в разных
|
||||||
|
регистрах (например, мажорное трезвучие D-F♯-A над мажорным трезвучием
|
||||||
|
C-E-G). В текущей версии формата полиаккорды **не поддерживаются**.
|
||||||
|
Близкие по звучанию структуры записываются через слэш-нотацию (`C/D`,
|
||||||
|
`F/G`) или ближайший один аккорд с расширениями.
|
||||||
|
|
||||||
|
### Расширение аккорда
|
||||||
|
|
||||||
|
Дополнительный интервал, надстраивающийся над септаккордом: нона (9),
|
||||||
|
ундецима (11), терцдецима (13), с возможными альтерациями (`b9`, `#9`,
|
||||||
|
`#11`, `b13`). В формате проекта расширение записывается одним токеном
|
||||||
|
в отдельном слоте `EXT`. Поддерживается ровно один слот расширения на
|
||||||
|
аккорд.
|
||||||
|
|
||||||
|
### Royal Road progression
|
||||||
|
|
||||||
|
Характерная гармоническая прогрессия японской популярной музыки:
|
||||||
|
IV — V — iii — vi (например, в C major: `F → G → Em → Am`). Прогрессия
|
||||||
|
ассоциируется с мелодичной, ностальгической эмоциональной окраской и
|
||||||
|
встречается в значительной части анисонга и J-Pop в широком смысле.
|
||||||
|
|
||||||
|
### Sus-аккорды
|
||||||
|
|
||||||
|
Аккорды с задержанной квартой (sus4) или секундой (sus2), заменяющей
|
||||||
|
терцию. Лишены терцового тона, не определены как мажорные или минорные.
|
||||||
|
В формате проекта — `Csus4`, `Csus2`, а также `C7sus4` (доминантовый
|
||||||
|
септаккорд на sus4, часто встречается перед разрешением в обычный
|
||||||
|
доминантовый аккорд).
|
||||||
|
|
||||||
|
### Слэш-аккорд (slash chord, on-аккорд)
|
||||||
|
|
||||||
|
Аккорд с явно указанным басом, отличным от любой ноты собственного состава.
|
||||||
|
Записывается как `<аккорд>/<бас>`. Характерный приём японской поп-музыки:
|
||||||
|
`F/G`, `C/D`, `Em7/A` — обеспечивают плавное движение баса и характерное
|
||||||
|
напряжение.
|
||||||
|
|
||||||
|
### Тактовый размер
|
||||||
|
|
||||||
|
Соотношение числа долей в такте и их длительности. В формате проекта
|
||||||
|
поддерживаются `4/4`, `3/4`, `6/8`, `2/4`, `12/8`. Большинство периодов
|
||||||
|
ожидается в размере `4/4`.
|
||||||
|
|
||||||
|
### Тональность
|
||||||
|
|
||||||
|
Конкретное положение лада на звукоряде, определяемое тоникой и видом
|
||||||
|
лада (`F# major`, `B♭ minor`, `C major`). В формате `.chord` указывается
|
||||||
|
в шапке файла полем `key`. Перед обучением модели все периоды
|
||||||
|
нормализуются в C major / A minor; в словарь модели тональность не
|
||||||
|
входит.
|
||||||
|
|
||||||
|
### Тонизация (отклонение)
|
||||||
|
|
||||||
|
Кратковременный заход в другую тональность через её собственную доминанту
|
||||||
|
без полноценной модуляции. Например, в C major последовательность
|
||||||
|
`Dm — A7 — Dm` содержит тонизацию D minor. В формате проекта тонизации
|
||||||
|
записываются обычными аккордовыми символами и не требуют специальной
|
||||||
|
разметки.
|
||||||
|
|
||||||
|
### Тоника
|
||||||
|
|
||||||
|
Главный устойчивый тон лада, опора. В формате после нормализующей
|
||||||
|
транспозиции тоника — `C` для мажорных периодов и `A` для минорных.
|
||||||
|
|
||||||
|
### Функциональная роль периода
|
||||||
|
|
||||||
|
Роль данного периода в форме исходной пьесы: куплет, припев, пре-припев,
|
||||||
|
бридж, вступление, проигрыш, концовка. В формате `.chord` указывается в
|
||||||
|
шапке поле `function`. Передаётся в модель как метатокен `FUNC_x` и может
|
||||||
|
использоваться как conditioning на инференсе.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Термины машинного обучения
|
||||||
|
|
||||||
|
### Авторегрессионная модель
|
||||||
|
|
||||||
|
Модель, генерирующая последовательность по одному элементу за раз, причём
|
||||||
|
каждый следующий элемент условен на всех предыдущих. Декодер-only
|
||||||
|
трансформер, используемый в проекте, — пример авторегрессионной модели.
|
||||||
|
|
||||||
|
### Beam search
|
||||||
|
|
||||||
|
Алгоритм поиска наиболее вероятной последовательности при генерации:
|
||||||
|
вместо сэмплирования удерживается несколько лучших кандидатов на каждом
|
||||||
|
шаге, выбирается итоговая последовательность с максимальной совместной
|
||||||
|
вероятностью. В проекте **не используется**, поскольку для генеративных
|
||||||
|
творческих задач даёт монотонные результаты.
|
||||||
|
|
||||||
|
### Catastrophic forgetting (катастрофическое забывание)
|
||||||
|
|
||||||
|
Феномен, при котором при дообучении модели на новом наборе данных она
|
||||||
|
теряет знания, выученные на исходном корпусе. В проекте митигируется
|
||||||
|
существенным снижением скорости обучения на этапе дообучения и
|
||||||
|
ограничением числа эпох.
|
||||||
|
|
||||||
|
### Causal mask (причинная маска)
|
||||||
|
|
||||||
|
Маска внимания в декодер-only трансформере, не позволяющая каждой позиции
|
||||||
|
«видеть» будущие позиции в последовательности. Обеспечивает корректное
|
||||||
|
обучение задачи предсказания следующего токена.
|
||||||
|
|
||||||
|
### Cross-entropy loss
|
||||||
|
|
||||||
|
Функция потерь, измеряющая расхождение между предсказанным моделью
|
||||||
|
распределением вероятностей следующего токена и истинным значением. Стандартная
|
||||||
|
функция потерь для задач классификации и генерации последовательностей.
|
||||||
|
|
||||||
|
### Декодер-only трансформер
|
||||||
|
|
||||||
|
Архитектура нейросети, состоящая из стека одинаковых блоков, каждый из
|
||||||
|
которых содержит self-attention с причинной маской и feedforward-слой.
|
||||||
|
В отличие от encoder-decoder архитектуры, у декодер-only нет отдельного
|
||||||
|
блока для кодирования входа — всё обрабатывается одной башней. GPT-семейство
|
||||||
|
языковых моделей — наиболее известный пример. Используется в данном проекте.
|
||||||
|
|
||||||
|
### Дообучение (fine-tuning)
|
||||||
|
|
||||||
|
Адаптация модели, ранее обученной на большом корпусе, к конкретной задаче
|
||||||
|
или домену через дополнительное обучение на меньшем целевом наборе данных.
|
||||||
|
В проекте после предобучения на McGill Billboard модель дообучается на
|
||||||
|
собственном корпусе автора.
|
||||||
|
|
||||||
|
### Embedding (эмбеддинг)
|
||||||
|
|
||||||
|
Числовое векторное представление дискретного элемента (токена). В трансформере
|
||||||
|
эмбеддинги токенов и позиций суммируются и подаются в первый блок. Размерность
|
||||||
|
эмбеддинга равна размерности модели (`d_model`).
|
||||||
|
|
||||||
|
### Epoch (эпоха)
|
||||||
|
|
||||||
|
Один полный проход обучающего цикла по всем элементам тренировочной выборки.
|
||||||
|
В проекте предобучение длится до 50 эпох с ранней остановкой,
|
||||||
|
дообучение — до 15.
|
||||||
|
|
||||||
|
### Holdout (отложенная выборка)
|
||||||
|
|
||||||
|
Часть данных, отделённая до начала обучения и не используемая ни в
|
||||||
|
тренировочной, ни в валидационной выборках. Применяется только для итоговой
|
||||||
|
оценки качества модели. В проекте формируется на уровне исходных пьес
|
||||||
|
(не на уровне периодов), что обеспечивает методологическую честность
|
||||||
|
сравнения.
|
||||||
|
|
||||||
|
### LayerNorm (нормализация слоя)
|
||||||
|
|
||||||
|
Нормализующее преобразование, стабилизирующее распределение активаций
|
||||||
|
внутри сети. В архитектуре проекта применяется в pre-norm варианте
|
||||||
|
(перед residual connection, не после).
|
||||||
|
|
||||||
|
### Learning rate
|
||||||
|
|
||||||
|
Скорость обучения, коэффициент шага оптимизатора. В проекте используется
|
||||||
|
значение `3e-4` на этапе предобучения и `1e-5` на этапе дообучения —
|
||||||
|
двухпорядковая разница принципиальна для предотвращения катастрофического
|
||||||
|
забывания.
|
||||||
|
|
||||||
|
### Logits
|
||||||
|
|
||||||
|
Выход модели перед применением softmax — нормализованные числовые
|
||||||
|
оценки, отражающие предпочтения модели по каждому возможному следующему
|
||||||
|
токену. Используются в функции потерь и в процессе сэмплирования.
|
||||||
|
|
||||||
|
### Multi-head attention
|
||||||
|
|
||||||
|
Механизм self-attention, в котором операция внимания выполняется
|
||||||
|
параллельно несколькими «головами», каждая со своими обучаемыми
|
||||||
|
проекциями. Результаты голов конкатенируются. В проекте используется
|
||||||
|
6 голов.
|
||||||
|
|
||||||
|
### Nucleus sampling (top-p sampling)
|
||||||
|
|
||||||
|
Стратегия сэмплирования, при которой на каждом шаге сохраняется
|
||||||
|
минимальный по числу элементов набор кандидатов с накопленной
|
||||||
|
вероятностью не менее заданного порога `p`, после чего из этого набора
|
||||||
|
происходит сэмплирование. Применяется в проекте с `p = 0.9` по умолчанию.
|
||||||
|
|
||||||
|
### Padding
|
||||||
|
|
||||||
|
Дополнение коротких последовательностей до фиксированной длины специальным
|
||||||
|
токеном. В проекте — токен `<PAD>` (индекс 2 в словаре), игнорируемый в
|
||||||
|
функции потерь через параметр `ignore_index`.
|
||||||
|
|
||||||
|
### Perplexity (перплексия)
|
||||||
|
|
||||||
|
Метрика качества языковой модели, рассчитываемая как экспонента средней
|
||||||
|
кросс-энтропии. Содержательно — «эффективное число равновероятных
|
||||||
|
альтернатив», между которыми модель колеблется на каждом шаге. Чем
|
||||||
|
меньше, тем лучше. В проекте используется как основная численная метрика
|
||||||
|
сравнения базовой и дообученной моделей.
|
||||||
|
|
||||||
|
### Positional embedding (позиционный эмбеддинг)
|
||||||
|
|
||||||
|
Векторное представление позиции токена в последовательности, добавляемое
|
||||||
|
к токеновому эмбеддингу. Позволяет модели учитывать порядок элементов
|
||||||
|
(сам по себе self-attention перестановочно-инвариантен). В проекте
|
||||||
|
используются обучаемые позиционные эмбеддинги.
|
||||||
|
|
||||||
|
### Pre-norm vs post-norm
|
||||||
|
|
||||||
|
Два варианта размещения LayerNorm в блоке трансформера: до residual
|
||||||
|
connection (pre-norm) или после (post-norm). Pre-norm обычно более
|
||||||
|
стабилен при обучении. В проекте используется pre-norm.
|
||||||
|
|
||||||
|
### Предобучение (pre-training)
|
||||||
|
|
||||||
|
Этап обучения модели на большом и общем по содержанию корпусе данных,
|
||||||
|
после которого следует адаптация модели к более узкой задаче или домену.
|
||||||
|
В проекте предобучение выполняется на McGill Billboard Project.
|
||||||
|
|
||||||
|
### Ранняя остановка (early stopping)
|
||||||
|
|
||||||
|
Приём, прекращающий обучение, когда метрика на валидационной выборке
|
||||||
|
перестаёт улучшаться на протяжении заданного числа эпох. Предотвращает
|
||||||
|
переобучение. В проекте используется с параметром терпения 5 эпох.
|
||||||
|
|
||||||
|
### Round-trip эквивалентность
|
||||||
|
|
||||||
|
Свойство пары взаимно обратных преобразований: при последовательном
|
||||||
|
применении прямого и обратного преобразования исходное представление
|
||||||
|
восстанавливается с точностью до канонической нормализации. В проекте
|
||||||
|
требуется для пары «парсинг + токенизация / детокенизация + сериализация»
|
||||||
|
и проверяется автоматизированными тестами.
|
||||||
|
|
||||||
|
### Self-attention
|
||||||
|
|
||||||
|
Механизм внимания, в котором последовательность взаимодействует сама с
|
||||||
|
собой: для каждой позиции рассчитываются взвешенные средние значений с
|
||||||
|
других позиций, веса определяются скалярными произведениями обучаемых
|
||||||
|
проекций. Центральный элемент архитектуры трансформера.
|
||||||
|
|
||||||
|
### Softmax с температурой
|
||||||
|
|
||||||
|
Модификация softmax, в которой логиты предварительно делятся на
|
||||||
|
параметр температуры. При температуре больше 1 распределение становится
|
||||||
|
более равномерным (генерация разнообразнее), при меньше 1 — более
|
||||||
|
концентрированным (генерация консервативнее). По умолчанию в проекте — 1.0.
|
||||||
|
|
||||||
|
### Tied weights (связанные веса)
|
||||||
|
|
||||||
|
Приём, при котором веса входного эмбеддинга и финальной проекции на
|
||||||
|
словарь совпадают (одна и та же матрица). Снижает число параметров и
|
||||||
|
часто улучшает обобщающую способность. Применяется в проекте.
|
||||||
|
|
||||||
|
### Токен
|
||||||
|
|
||||||
|
Элементарная единица обработки модели — целочисленный идентификатор
|
||||||
|
из конечного словаря. В данном проекте словарь содержит 81 токен,
|
||||||
|
обозначающих служебные значения, метаданные периода и компоненты
|
||||||
|
аккордов.
|
||||||
|
|
||||||
|
### Токенизация
|
||||||
|
|
||||||
|
Преобразование исходного представления данных в последовательность
|
||||||
|
токенов. В проекте — преобразование `.chord`-файла в последовательность
|
||||||
|
целочисленных идентификаторов.
|
||||||
|
|
||||||
|
### Тренировочная и валидационная выборки (train / val)
|
||||||
|
|
||||||
|
Разбиение обучающих данных: тренировочная выборка используется для
|
||||||
|
обновления весов модели, валидационная — для контроля переобучения и
|
||||||
|
выбора лучшего чекпоинта. В проекте используется разбиение 90/10. Кроме
|
||||||
|
того, отдельно выделяется отложенная выборка (см. _Holdout_).
|
||||||
|
|
||||||
|
### Warmup (разогрев)
|
||||||
|
|
||||||
|
Начальная фаза обучения, в течение которой learning rate линейно растёт
|
||||||
|
от нуля до целевого значения. Стабилизирует обучение трансформеров на
|
||||||
|
первых шагах. В проекте — 5% от общего числа шагов.
|
||||||
|
|
||||||
|
### Чекпоинт
|
||||||
|
|
||||||
|
Сохранённое на диск состояние модели (веса, конфигурация, опционально
|
||||||
|
состояние оптимизатора), пригодное для возобновления обучения или для
|
||||||
|
инференса. В проекте сохраняются чекпоинты `pretrained.pt` и
|
||||||
|
`finetuned.pt`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Проектные термины
|
||||||
|
|
||||||
|
### `.chord`-файл
|
||||||
|
|
||||||
|
Текстовый файл в формате, описанном в `docs/chord_format_spec.md`. Содержит
|
||||||
|
шапку с метаданными периода и тело — последовательность тактов с
|
||||||
|
аккордовыми символами. Один файл = один гармонический период.
|
||||||
|
|
||||||
|
### hamori
|
||||||
|
|
||||||
|
Название проекта. Транслитерация японского слова ハモリ, означающего
|
||||||
|
вокальную гармонизацию — практику добавления второго или третьего голоса
|
||||||
|
к основной мелодической линии в певческом ансамбле. Само слово образовано
|
||||||
|
от глагола ハモる (_hamoru_) — «гармонизировать», в свою очередь
|
||||||
|
заимствованного из английского _harmony_. Название отражает основную
|
||||||
|
функциональную идею проекта: модель не пишет музыку с нуля, а предлагает
|
||||||
|
гармонические идеи в дополнение к замыслу композитора.
|
||||||
|
|
||||||
|
### BAR (токен)
|
||||||
|
|
||||||
|
Служебный токен, отмечающий конец такта в токенизированной
|
||||||
|
последовательности. Помогает модели усваивать ритмическую сетку периода.
|
||||||
|
|
||||||
|
### `<BOS>`, `<EOS>`, `<PAD>`, `<UNK>`
|
||||||
|
|
||||||
|
Служебные токены словаря: начало последовательности, конец последовательности,
|
||||||
|
паддинг и неизвестный токен соответственно.
|
||||||
|
|
||||||
|
### `ChordTokens`
|
||||||
|
|
||||||
|
Dataclass, представляющий разобранный аккорд: четыре строковых поля —
|
||||||
|
`root`, `quality`, `extension`, `bass`. Является промежуточным
|
||||||
|
представлением между текстовым аккордовым символом и токенами модели.
|
||||||
|
|
||||||
|
### `ChordPeriod`
|
||||||
|
|
||||||
|
Dataclass, представляющий полностью разобранный гармонический период:
|
||||||
|
метаданные шапки и список тактов, каждый из которых — список позиций.
|
||||||
|
Является промежуточным представлением между `.chord`-файлом и токенами.
|
||||||
|
|
||||||
|
### `ChordFormatError` / `ChordParseError`
|
||||||
|
|
||||||
|
Типы исключений, поднимаемые при некорректном формате файла или
|
||||||
|
некорректном аккордовом символе соответственно. Содержат информативные
|
||||||
|
сообщения с указанием места ошибки.
|
||||||
|
|
||||||
|
### EXT (расширение)
|
||||||
|
|
||||||
|
Один из четырёх слотов токенизации аккорда. Кодирует расширение аккорда:
|
||||||
|
`EXT_none` (расширения нет), `EXT_9`, `EXT_b9`, `EXT_#9`, `EXT_11`,
|
||||||
|
`EXT_#11`, `EXT_13`, `EXT_b13`. Восемь возможных значений.
|
||||||
|
|
||||||
|
### FUNC (функциональная роль)
|
||||||
|
|
||||||
|
Метатокен периода, указывающий на функциональную роль в исходной пьесе.
|
||||||
|
Возможные значения: `FUNC_verse`, `FUNC_chorus`, `FUNC_prechorus`,
|
||||||
|
`FUNC_bridge`, `FUNC_intro`, `FUNC_outro`, `FUNC_interlude`, `FUNC_other`,
|
||||||
|
`FUNC_unspecified`.
|
||||||
|
|
||||||
|
### HOLD (токен)
|
||||||
|
|
||||||
|
Служебный токен, означающий, что текущая позиция продолжает звучание
|
||||||
|
предыдущего аккорда. Использование `HOLD` существенно сокращает длину
|
||||||
|
последовательности по сравнению с повторением всех четырёх токенов
|
||||||
|
аккорда.
|
||||||
|
|
||||||
|
### MODE (лад)
|
||||||
|
|
||||||
|
Метатокен периода, указывающий на лад. Только два значения: `MODE_major`
|
||||||
|
для мажора и `MODE_minor` для минора. После нормализующей транспозиции
|
||||||
|
этот токен — единственный носитель информации о ладе в обучающих данных.
|
||||||
|
|
||||||
|
### NC (No Chord)
|
||||||
|
|
||||||
|
Специальное значение позиции, обозначающее паузу в гармонии — отсутствие
|
||||||
|
аккорда. Применяется, например, в анакрузах. Имеет соответствующий
|
||||||
|
служебный токен `NC` в словаре.
|
||||||
|
|
||||||
|
### Нормализующая транспозиция
|
||||||
|
|
||||||
|
Преобразование, переводящее любой период в каноническую тональность:
|
||||||
|
мажорные периоды — в C major, минорные — в A minor. Применяется перед
|
||||||
|
токенизацией. На инференсе обратное преобразование возвращает результат
|
||||||
|
в требуемую пользователем тональность.
|
||||||
|
|
||||||
|
### Период (см. также _Гармонический период_ в музыкальной части)
|
||||||
|
|
||||||
|
Единица обработки и генерации в проекте. Замкнутая гармоническая фраза
|
||||||
|
4–16 тактов, представленная одним `.chord`-файлом.
|
||||||
|
|
||||||
|
### QUAL (качество)
|
||||||
|
|
||||||
|
Один из четырёх слотов токенизации аккорда. Кодирует качество аккорда:
|
||||||
|
`QUAL_maj`, `QUAL_m`, `QUAL_dim`, `QUAL_aug`, `QUAL_sus2`, `QUAL_sus4`,
|
||||||
|
`QUAL_maj7`, `QUAL_m7`, `QUAL_7`, `QUAL_m7b5`, `QUAL_dim7`, `QUAL_mM7`,
|
||||||
|
`QUAL_7sus4`, `QUAL_aug7`, `QUAL_6`, `QUAL_m6`, `QUAL_add9`,
|
||||||
|
`QUAL_m_add9`. Восемнадцать возможных значений.
|
||||||
|
|
||||||
|
### ROOT (корень)
|
||||||
|
|
||||||
|
Один из четырёх слотов токенизации аккорда. Кодирует корневой тон:
|
||||||
|
`ROOT_C`, `ROOT_C#`, ..., `ROOT_B`. Двенадцать возможных значений.
|
||||||
|
|
||||||
|
### BASS (бас)
|
||||||
|
|
||||||
|
Один из четырёх слотов токенизации аккорда. Кодирует басовый тон:
|
||||||
|
`BASS_root` (бас совпадает с корнем) или конкретная нота
|
||||||
|
(`BASS_C`, `BASS_C#`, ..., `BASS_B`). Тринадцать возможных значений.
|
||||||
|
|
||||||
|
### Стилевой тег (STYLE)
|
||||||
|
|
||||||
|
Метатокен периода, указывающий на стилистическую принадлежность.
|
||||||
|
Возможные значения: `STYLE_user` (собственный корпус автора), `STYLE_jpop`
|
||||||
|
(японская поп-музыка), `STYLE_classical` (классическая музыка),
|
||||||
|
`STYLE_jazz` (джазовая музыка), `STYLE_other` (прочее, включая публичные
|
||||||
|
корпуса вроде McGill Billboard). Может использоваться как conditioning
|
||||||
|
на инференсе.
|
||||||
|
|
||||||
|
### SUB (подразделение доли)
|
||||||
|
|
||||||
|
Метатокен периода, указывающий, как делится такт на временные позиции.
|
||||||
|
Возможные значения: `SUB_4` (по четвертям) и `SUB_8` (по восьмым).
|
||||||
|
|
||||||
|
### TIME (тактовый размер)
|
||||||
|
|
||||||
|
Метатокен периода, указывающий тактовый размер. Возможные значения:
|
||||||
|
`TIME_4/4`, `TIME_3/4`, `TIME_6/8`, `TIME_2/4`, `TIME_12/8`.
|
||||||
|
|
||||||
|
### Шапка файла
|
||||||
|
|
||||||
|
Часть `.chord`-файла, содержащая метаданные периода. Строки шапки
|
||||||
|
начинаются с символа `#` и имеют вид `# key: value`. Шапка обязательно
|
||||||
|
содержит поля `title`, `key`, `time`, `subdivision`, `style` и
|
||||||
|
опционально — `function`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. История изменений
|
||||||
|
|
||||||
|
- **1.0** (2026-05-19) — первоначальная редакция документа.
|
||||||
@@ -0,0 +1,467 @@
|
|||||||
|
# Требования к проекту hamori
|
||||||
|
|
||||||
|
**Версия документа:** 1.0
|
||||||
|
**Дата:** 2026-05-19
|
||||||
|
|
||||||
|
Документ описывает функциональные и нефункциональные требования к проекту
|
||||||
|
_hamori_ — генератору гармонических периодов в авторском композиторском
|
||||||
|
стиле. Описываются ограничения, критерии приёмки и явно выведенные за рамки
|
||||||
|
возможности.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Контекст и цели проекта
|
||||||
|
|
||||||
|
### 1.1 Постановка задачи
|
||||||
|
|
||||||
|
Разработать генеративную нейросетевую модель, способную создавать
|
||||||
|
гармонические последовательности заданной длины и стилистики, обученную в
|
||||||
|
том числе на корпусе собственных произведений автора, с целью использования
|
||||||
|
получившейся модели как творческого инструмента в композиторской работе.
|
||||||
|
|
||||||
|
### 1.2 Заинтересованные стороны
|
||||||
|
|
||||||
|
| Сторона | Интерес |
|
||||||
|
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| Автор-разработчик (студент) | Закрытие курсовой дисциплины, получение работающего инструмента для собственной композиторской практики |
|
||||||
|
| Преподаватель курса | Демонстрация владения полным циклом ML-проекта: постановка задачи, подготовка данных, обучение, оценка, интерпретация |
|
||||||
|
| Потенциальные читатели исходного кода | Понимание принятых архитектурных решений и возможность повторного использования компонентов |
|
||||||
|
|
||||||
|
### 1.3 Учебные цели
|
||||||
|
|
||||||
|
Демонстрация компетенций в следующих областях машинного обучения:
|
||||||
|
|
||||||
|
- Проектирование задачи генерации последовательностей в условиях ограниченного
|
||||||
|
объёма обучающих данных.
|
||||||
|
- Выбор и реализация архитектуры авторегрессионной модели для дискретных
|
||||||
|
последовательностей.
|
||||||
|
- Подготовка и токенизация специализированного датасета.
|
||||||
|
- Применение схемы предобучение / дообучение.
|
||||||
|
- Количественная и качественная оценка генеративной модели.
|
||||||
|
- Анализ распределений и интерпретация результатов.
|
||||||
|
|
||||||
|
### 1.4 Прикладные цели
|
||||||
|
|
||||||
|
Получение программного инструмента, обладающего следующими функциональными
|
||||||
|
характеристиками:
|
||||||
|
|
||||||
|
- Принимает на вход параметры желаемой гармонической последовательности.
|
||||||
|
- Принимает опциональную гармоническую затравку из нескольких аккордов.
|
||||||
|
- Генерирует последовательность аккордов, согласованную с заданными параметрами
|
||||||
|
и стилистически приближенную к авторскому корпусу.
|
||||||
|
- Сохраняет результат в формате, пригодном для непосредственного использования
|
||||||
|
в цифровой звуковой рабочей станции.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Ограничения
|
||||||
|
|
||||||
|
### 2.1 Временные ограничения
|
||||||
|
|
||||||
|
Жёсткий срок реализации: менее одного календарного месяца с момента начала
|
||||||
|
работ. Бюджет ручного труда автора: около 50 часов.
|
||||||
|
|
||||||
|
Распределение времени:
|
||||||
|
|
||||||
|
- Подготовка инфраструктуры данных: ~12 часов.
|
||||||
|
- Ручная транскрипция собственного корпуса: ~10–15 часов.
|
||||||
|
- Реализация модели и обучение: ~12 часов.
|
||||||
|
- Оценка и подготовка примеров: ~6 часов.
|
||||||
|
- Написание отчёта и оформление: ~10 часов.
|
||||||
|
|
||||||
|
### 2.2 Ресурсные ограничения
|
||||||
|
|
||||||
|
Аппаратные ресурсы: персональный ноутбук автора. Использование облачных
|
||||||
|
GPU-ресурсов (Google Colab) допустимо, но не должно быть критически
|
||||||
|
необходимым — модель проектируется так, чтобы обучение было выполнимо на CPU.
|
||||||
|
|
||||||
|
Программные ресурсы: открытое программное обеспечение, бесплатные публичные
|
||||||
|
датасеты.
|
||||||
|
|
||||||
|
### 2.3 Ограничения по данным
|
||||||
|
|
||||||
|
Объём собственного корпуса автора ограничен числом существующих
|
||||||
|
композиторских работ и временем, доступным на ручную транскрипцию.
|
||||||
|
Реалистичный ориентир: 80–150 гармонических периодов из 20–25 пьес.
|
||||||
|
|
||||||
|
Это значение на два-три порядка меньше типичного объёма данных, на которых
|
||||||
|
обучаются современные музыкальные генеративные модели. Из этого ограничения
|
||||||
|
вытекает принципиальное архитектурное решение: модель должна использовать
|
||||||
|
схему «предобучение на публичном корпусе плюс дообучение на собственном
|
||||||
|
корпусе», обучение с нуля исключительно на собственных данных нецелесообразно.
|
||||||
|
|
||||||
|
### 2.4 Языковые требования
|
||||||
|
|
||||||
|
Согласно требованиям учебного заведения:
|
||||||
|
|
||||||
|
- Итоговый отчёт оформляется на русском языке по стандартам ГОСТ для
|
||||||
|
студенческих работ.
|
||||||
|
- Документация для пользователя (README, спецификация формата, описания
|
||||||
|
архитектуры) ведётся на русском языке.
|
||||||
|
- Технические артефакты кода (идентификаторы, комментарии, сообщения логов,
|
||||||
|
сообщения коммитов) ведутся на английском языке для совместимости с
|
||||||
|
общепринятыми стандартами разработки и удобства совместной работы с
|
||||||
|
инструментами вроде Claude Code.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Функциональные требования
|
||||||
|
|
||||||
|
### 3.1 Подсистема работы с форматом данных
|
||||||
|
|
||||||
|
**ФТ-1.** Система должна поддерживать чтение `.chord`-файлов в формате,
|
||||||
|
описанном в `docs/chord_format_spec.md` версии 2.0, включая:
|
||||||
|
|
||||||
|
- Парсинг шапки с метаданными.
|
||||||
|
- Парсинг тела файла, состоящего из последовательности тактов.
|
||||||
|
- Распознавание аккордовых символов по правилам §4 спецификации.
|
||||||
|
- Поддержку всех восемнадцати базовых качеств аккордов с альтернативными
|
||||||
|
написаниями.
|
||||||
|
- Поддержку расширений аккордов (одиночный слот).
|
||||||
|
- Поддержку слэш-нотации для инверсий.
|
||||||
|
- Распознавание специальных значений (точка для удержания, `NC` для паузы,
|
||||||
|
`?` для неизвестного аккорда).
|
||||||
|
|
||||||
|
**ФТ-2.** Система должна выполнять валидацию `.chord`-файлов:
|
||||||
|
|
||||||
|
- Проверять корректность шапки (все обязательные поля присутствуют, значения
|
||||||
|
входят в допустимые множества).
|
||||||
|
- Проверять, что число позиций в каждом такте соответствует тактовому
|
||||||
|
размеру и подразделению доли.
|
||||||
|
- Поднимать информативные ошибки с указанием имени файла, номера такта и
|
||||||
|
позиции при обнаружении нарушений.
|
||||||
|
|
||||||
|
**ФТ-3.** Система должна выполнять нормализующую транспозицию:
|
||||||
|
все мажорные периоды приводятся к тональности C major, минорные — к A minor.
|
||||||
|
|
||||||
|
**ФТ-4.** Система должна выполнять токенизацию `.chord`-файлов в
|
||||||
|
последовательности целочисленных идентификаторов согласно словарю,
|
||||||
|
описанному в §5 спецификации формата. Словарь содержит 81 токен.
|
||||||
|
|
||||||
|
**ФТ-5.** Система должна поддерживать обратную детокенизацию: преобразование
|
||||||
|
последовательности целочисленных идентификаторов обратно в `.chord`-файл,
|
||||||
|
с последующей опциональной транспозицией в произвольную тональность.
|
||||||
|
|
||||||
|
**ФТ-6.** Система должна обеспечивать round-trip эквивалентность: для
|
||||||
|
любого корректного `.chord`-файла операция `parse → tokenize → detokenize →
|
||||||
|
serialize` должна давать `.chord`-файл, эквивалентный исходному по
|
||||||
|
гармоническому содержанию.
|
||||||
|
|
||||||
|
### 3.2 Подсистема экспорта в MIDI
|
||||||
|
|
||||||
|
**ФТ-7.** Система должна обеспечивать экспорт `.chord`-файлов в стандартный
|
||||||
|
формат MIDI с двумя треками: трек аккордов и трек баса. Темп задаётся
|
||||||
|
параметром, по умолчанию 90 ударов в минуту.
|
||||||
|
|
||||||
|
**ФТ-8.** Длительности нот в MIDI должны соответствовать длительностям
|
||||||
|
удержания аккордов в исходном `.chord`-файле.
|
||||||
|
|
||||||
|
### 3.3 Подсистема конвертации внешних корпусов
|
||||||
|
|
||||||
|
**ФТ-9.** Система должна предоставлять конвертер McGill Billboard Project →
|
||||||
|
формат `.chord`, выполняющий:
|
||||||
|
|
||||||
|
- Чтение Harte-нотации.
|
||||||
|
- Разрезание исходных пьес на гармонические периоды по границам секций.
|
||||||
|
- Сохранение каждого периода как отдельного `.chord`-файла.
|
||||||
|
- Простановку стилевого тега и функциональной роли в шапке.
|
||||||
|
|
||||||
|
**ФТ-10.** Конвертер должен быть устойчив к некорректным или неполным
|
||||||
|
аннотациям в исходном корпусе: периоды, которые не могут быть однозначно
|
||||||
|
сконвертированы, пропускаются с записью в лог, выполнение скрипта при этом
|
||||||
|
не прерывается.
|
||||||
|
|
||||||
|
### 3.4 Подсистема обучения
|
||||||
|
|
||||||
|
**ФТ-11.** Система должна реализовывать архитектуру авторегрессионного
|
||||||
|
трансформера со следующими параметрами:
|
||||||
|
|
||||||
|
- Количество слоёв: настраиваемое, 2–4 по умолчанию.
|
||||||
|
- Размерность модели: настраиваемая, 128–256 по умолчанию.
|
||||||
|
- Число голов внимания: настраиваемое, 4–8 по умолчанию.
|
||||||
|
- Контекстное окно: 512 токенов.
|
||||||
|
- Связанные веса входного и выходного эмбеддингов.
|
||||||
|
|
||||||
|
**ФТ-12.** Система должна предоставлять единый скрипт обучения, параметризуемый
|
||||||
|
аргументами командной строки, поддерживающий:
|
||||||
|
|
||||||
|
- Обучение модели с нуля (предобучение).
|
||||||
|
- Дообучение существующей модели (fine-tuning) — через параметр инициализации
|
||||||
|
весов из указанного чекпоинта.
|
||||||
|
- Настройку всех ключевых гиперпараметров через аргументы.
|
||||||
|
- Установку случайного зерна для воспроизводимости.
|
||||||
|
- Автоматический выбор вычислительного устройства (CPU/GPU) с возможностью
|
||||||
|
принудительного задания.
|
||||||
|
|
||||||
|
**ФТ-13.** В процессе обучения система должна:
|
||||||
|
|
||||||
|
- Логировать значения функции потерь на тренировочной и валидационной
|
||||||
|
выборках после каждой эпохи.
|
||||||
|
- Логировать перплексию на валидационной выборке.
|
||||||
|
- Сохранять лучший по валидационной потере чекпоинт.
|
||||||
|
- Поддерживать раннюю остановку по валидационной потере с настраиваемым
|
||||||
|
параметром терпения.
|
||||||
|
- Сохранять полный лог обучения в формате CSV.
|
||||||
|
|
||||||
|
### 3.5 Подсистема инференса
|
||||||
|
|
||||||
|
**ФТ-14.** Система должна предоставлять CLI-инструмент генерации со
|
||||||
|
следующими настраиваемыми параметрами:
|
||||||
|
|
||||||
|
- Путь к чекпоинту модели.
|
||||||
|
- Лад (мажор / минор).
|
||||||
|
- Тональность (любой из 12 классов высоты).
|
||||||
|
- Тактовый размер.
|
||||||
|
- Подразделение доли.
|
||||||
|
- Стилевой тег.
|
||||||
|
- Функциональная роль.
|
||||||
|
- Опциональная гармоническая затравка (последовательность аккордовых символов).
|
||||||
|
- Температура сэмплирования.
|
||||||
|
- Параметр top-p (nucleus sampling).
|
||||||
|
- Максимальное число токенов.
|
||||||
|
- Случайное зерно.
|
||||||
|
- Пути для сохранения `.chord`- и MIDI-файлов.
|
||||||
|
|
||||||
|
**ФТ-15.** Инференс должен использовать nucleus sampling с настраиваемой
|
||||||
|
температурой. Beam search не используется.
|
||||||
|
|
||||||
|
**ФТ-16.** Система должна предотвращать генерацию грамматически невалидных
|
||||||
|
последовательностей токенов (например, токена расширения сразу после токена
|
||||||
|
удержания) через маскирование невалидных кандидатов на каждом шаге.
|
||||||
|
|
||||||
|
### 3.6 Подсистема оценки
|
||||||
|
|
||||||
|
**ФТ-17.** Система должна предоставлять скрипт оценки, принимающий на вход
|
||||||
|
два чекпоинта (базовый и целевой) и отложенную выборку, и формирующий:
|
||||||
|
|
||||||
|
- Численные метрики перплексии для обеих моделей.
|
||||||
|
- Графики распределений по ключевым гармоническим признакам.
|
||||||
|
- Сгенерированные образцы для качественного сравнения.
|
||||||
|
|
||||||
|
**ФТ-18.** Графики распределений должны включать:
|
||||||
|
|
||||||
|
- Распределение типов качеств аккордов.
|
||||||
|
- Долю аккордов с расширениями.
|
||||||
|
- Долю аккордов с инверсиями.
|
||||||
|
- Распределение интервалов движения корня.
|
||||||
|
- Распределение наиболее частых пар «корень-корень» (биграммы).
|
||||||
|
|
||||||
|
Каждый график должен показывать baseline-распределение и target-распределение
|
||||||
|
на одной координатной плоскости с легендой.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Нефункциональные требования
|
||||||
|
|
||||||
|
### 4.1 Производительность
|
||||||
|
|
||||||
|
**НФТ-1.** Парсинг одного `.chord`-файла должен выполняться менее чем за
|
||||||
|
100 миллисекунд на стандартном персональном компьютере.
|
||||||
|
|
||||||
|
**НФТ-2.** Один проход обучения по тренировочной выборке (одна эпоха) на
|
||||||
|
полном McGill корпусе должен укладываться в 10 минут на CPU современного
|
||||||
|
ноутбука.
|
||||||
|
|
||||||
|
**НФТ-3.** Генерация одного периода должна занимать менее 10 секунд на CPU.
|
||||||
|
|
||||||
|
### 4.2 Корректность
|
||||||
|
|
||||||
|
**НФТ-4.** Парсер аккордовых символов должен корректно обрабатывать все
|
||||||
|
примеры, перечисленные в §4.6 спецификации формата.
|
||||||
|
|
||||||
|
**НФТ-5.** Round-trip эквивалентность (см. ФТ-6) должна подтверждаться
|
||||||
|
автоматизированными тестами для всех тестовых фикстур.
|
||||||
|
|
||||||
|
**НФТ-6.** Транспозиция должна быть точной: после транспозиции мажорного
|
||||||
|
периода в C major все аккорды должны находиться в правильных функциональных
|
||||||
|
отношениях с новой тоникой.
|
||||||
|
|
||||||
|
### 4.3 Воспроизводимость
|
||||||
|
|
||||||
|
**НФТ-7.** Все скрипты обучения, инференса и оценки должны принимать параметр
|
||||||
|
случайного зерна и устанавливать его одновременно для PyTorch, NumPy и
|
||||||
|
стандартного модуля random.
|
||||||
|
|
||||||
|
**НФТ-8.** При фиксированном случайном зерне и идентичных входных данных
|
||||||
|
запуски обучения должны давать численно воспроизводимые результаты.
|
||||||
|
|
||||||
|
**НФТ-9.** Все эксперименты, упомянутые в итоговом отчёте, должны быть
|
||||||
|
воспроизводимы посредством запуска документированных команд.
|
||||||
|
|
||||||
|
### 4.4 Надёжность работы с данными
|
||||||
|
|
||||||
|
**НФТ-10.** Невалидные или непарсимые аккордовые символы должны вызывать
|
||||||
|
явные ошибки с информативным сообщением. Тихая подмена неизвестных символов
|
||||||
|
на «ближайшие» категорически запрещена: это приводит к молчаливому
|
||||||
|
повреждению обучающего корпуса.
|
||||||
|
|
||||||
|
**НФТ-11.** Файлы из отложенной выборки не должны использоваться на этапах
|
||||||
|
тренировки или валидации. Любой скрипт подготовки данных, при обнаружении
|
||||||
|
файла в `data/holdout/`, должен направлять его в отдельную holdout-выборку.
|
||||||
|
|
||||||
|
### 4.5 Сопровождаемость
|
||||||
|
|
||||||
|
**НФТ-12.** Все публичные функции в модулях `src/` должны иметь аннотации
|
||||||
|
типов и краткие docstrings.
|
||||||
|
|
||||||
|
**НФТ-13.** Логика парсинга, токенизации и MIDI-экспорта должна покрываться
|
||||||
|
модульными тестами с использованием pytest.
|
||||||
|
|
||||||
|
**НФТ-14.** Спецификация формата `.chord` является контрактом между уровнем
|
||||||
|
человекочитаемых данных и уровнем обучения модели. Любые изменения формата
|
||||||
|
должны сопровождаться обновлением `docs/chord_format_spec.md` и инкрементом
|
||||||
|
номера версии спецификации.
|
||||||
|
|
||||||
|
### 4.6 Удобство использования
|
||||||
|
|
||||||
|
**НФТ-15.** Каждый CLI-скрипт должен поддерживать флаг `--help` с
|
||||||
|
информативным описанием параметров.
|
||||||
|
|
||||||
|
**НФТ-16.** Сообщения об ошибках должны содержать достаточно информации для
|
||||||
|
самостоятельного устранения проблемы пользователем: имя файла, номер строки,
|
||||||
|
характер нарушения, ожидаемое значение.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Критерии приёмки
|
||||||
|
|
||||||
|
Проект считается завершённым при выполнении всех нижеперечисленных условий.
|
||||||
|
|
||||||
|
### 5.1 Учебные критерии
|
||||||
|
|
||||||
|
| ID | Критерий |
|
||||||
|
| ---- | ----------------------------------------------------------------------------------------------------------- |
|
||||||
|
| УК-1 | Реализован полный цикл подготовки данных, обучения, инференса и оценки. |
|
||||||
|
| УК-2 | Имеется как минимум одна обученная модель, прошедшая стадии предобучения и дообучения. |
|
||||||
|
| УК-3 | Подготовлен итоговый отчёт, оформленный по стандартам ГОСТ для учебных работ. |
|
||||||
|
| УК-4 | Отчёт содержит количественное сравнение базовой и дообученной моделей. |
|
||||||
|
| УК-5 | Отчёт содержит качественные примеры сгенерированных периодов. |
|
||||||
|
| УК-6 | Все эксперименты, упомянутые в отчёте, воспроизводимы по командам, приведённым в README или в самом отчёте. |
|
||||||
|
|
||||||
|
### 5.2 Технические критерии
|
||||||
|
|
||||||
|
| ID | Критерий |
|
||||||
|
| ---- | --------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| ТК-1 | Все автоматизированные тесты проходят. |
|
||||||
|
| ТК-2 | Round-trip эквивалентность парсера-токенизатора подтверждена на всех тестовых фикстурах. |
|
||||||
|
| ТК-3 | Транспозиция протестирована для мажорных и минорных периодов с разными исходными тональностями. |
|
||||||
|
| ТК-4 | Модель обучается до сходимости (валидационная потеря выходит на плато или снижается монотонно). |
|
||||||
|
| ТК-5 | Перплексия дообученной модели на отложенной выборке ниже перплексии базовой модели на той же выборке. |
|
||||||
|
| ТК-6 | На графиках распределений виден заметный сдвиг от baseline в сторону характеристик собственного корпуса автора. |
|
||||||
|
|
||||||
|
### 5.3 Прикладные критерии
|
||||||
|
|
||||||
|
| ID | Критерий |
|
||||||
|
| ---- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| ПК-1 | Автор может сгенерировать гармоническую последовательность по произвольным входным параметрам и воспроизвести её в DAW. |
|
||||||
|
| ПК-2 | Сгенерированные последовательности отличаются от случайного шума: соблюдается тональная стабильность, аккорды функционально связаны. |
|
||||||
|
| ПК-3 | На качественном уровне в нескольких из сгенерированных примеров автор слышит элементы собственного стиля. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Намеренно выведенное за рамки
|
||||||
|
|
||||||
|
Перечисленные ниже возможности **не входят** в требования к текущей версии
|
||||||
|
проекта. Их реализация может рассматриваться как направления дальнейшего
|
||||||
|
развития после защиты курсовой работы.
|
||||||
|
|
||||||
|
| Возможность | Причина выведения |
|
||||||
|
| -------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||||
|
| Генерация мелодической линии | Кратно увеличивает сложность задачи; не помещается в срок |
|
||||||
|
| Расположение голосов в аккорде (voicing) выше баса | Требует существенно большего датасета; ручная реализация в DAW проще |
|
||||||
|
| Ритмический паттерн внутри удержания аккорда | Требует моделирования времени с большим разрешением; не критично для задачи |
|
||||||
|
| Дообучение на корпусе японской поп-музыки | Запланировано как отдельный последующий эксперимент |
|
||||||
|
| Графический интерфейс | Не добавляет ценности с точки зрения учебных целей; занимает время |
|
||||||
|
| Прямая интеграция с REAPER | Обмен через MIDI-файлы достаточен и проще в реализации |
|
||||||
|
| Сравнение нескольких архитектур модели | Не помещается в срок; выбрана одна архитектура с обоснованием |
|
||||||
|
| Слепой listening-тест с привлечением слушателей | Не помещается в срок; используются качественные примеры |
|
||||||
|
| Обработка модуляций внутри одного периода | Решено разрезанием периодов по точке модуляции |
|
||||||
|
| Поддержка микротональных аккордов | Не встречается в целевом материале; округление до темперированного эквивалента |
|
||||||
|
| Поддержка полиаккордов | Редкое явление в целевом материале; запись через слэш-нотацию или ближайший single chord |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Сценарии использования
|
||||||
|
|
||||||
|
### 7.1 Сценарий У-1. Транскрипция собственной пьесы
|
||||||
|
|
||||||
|
**Действующее лицо:** автор-композитор.
|
||||||
|
|
||||||
|
**Предусловия:** в DAW-проекте имеется готовая пьеса с гармонической
|
||||||
|
структурой, доступной анализу. Установлена и настроена среда разработки.
|
||||||
|
|
||||||
|
**Основной поток:**
|
||||||
|
|
||||||
|
1. Автор прослушивает пьесу и определяет границы периодов.
|
||||||
|
2. Для каждого периода создаёт `.chord`-файл и заполняет шапку.
|
||||||
|
3. Транскрибирует гармонию по позициям, фиксируя инверсии и расширения.
|
||||||
|
4. Запускает валидатор формата для проверки корректности.
|
||||||
|
5. Экспортирует периоды в MIDI и прослушивает в DAW параллельно с оригиналом.
|
||||||
|
6. Корректирует транскрипцию в случае расхождений.
|
||||||
|
|
||||||
|
**Постусловия:** в `data/raw_user/` появились новые `.chord`-файлы,
|
||||||
|
прошедшие валидацию.
|
||||||
|
|
||||||
|
### 7.2 Сценарий У-2. Полный цикл обучения
|
||||||
|
|
||||||
|
**Действующее лицо:** автор-композитор.
|
||||||
|
|
||||||
|
**Предусловия:** подготовлен собственный корпус и сконвертирован публичный
|
||||||
|
корпус.
|
||||||
|
|
||||||
|
**Основной поток:**
|
||||||
|
|
||||||
|
1. Запуск скрипта подготовки данных для публичного корпуса.
|
||||||
|
2. Запуск скрипта подготовки данных для собственного корпуса.
|
||||||
|
3. Запуск скрипта предобучения, ожидание сходимости.
|
||||||
|
4. Запуск скрипта дообучения с инициализацией из чекпоинта предобучения.
|
||||||
|
5. Запуск скрипта оценки для сравнения базовой и дообученной моделей.
|
||||||
|
6. Анализ полученных графиков и метрик.
|
||||||
|
|
||||||
|
**Постусловия:** в `checkpoints/` сохранены обученные модели, в `reports/`
|
||||||
|
сформированы графики и численные метрики.
|
||||||
|
|
||||||
|
### 7.3 Сценарий У-3. Генерация гармонической идеи
|
||||||
|
|
||||||
|
**Действующее лицо:** автор-композитор в процессе работы над новой пьесой.
|
||||||
|
|
||||||
|
**Предусловия:** имеется обученная модель.
|
||||||
|
|
||||||
|
**Основной поток:**
|
||||||
|
|
||||||
|
1. Автор определяет желаемые параметры будущего периода: тональность,
|
||||||
|
функциональную роль, общий характер.
|
||||||
|
2. Запускает скрипт генерации с этими параметрами.
|
||||||
|
3. Получает `.chord`-файл и MIDI-файл результата.
|
||||||
|
4. Открывает MIDI-файл в DAW и прослушивает.
|
||||||
|
5. В случае удовлетворительного результата — переносит гармоническую
|
||||||
|
последовательность в свой композиторский проект.
|
||||||
|
6. В противном случае — повторяет генерацию с другим случайным зерном или
|
||||||
|
другими параметрами сэмплирования.
|
||||||
|
|
||||||
|
**Постусловия:** автор получает гармоническую идею в требуемом стилистическом
|
||||||
|
ключе.
|
||||||
|
|
||||||
|
### 7.4 Сценарий У-4. Продолжение начатой идеи
|
||||||
|
|
||||||
|
**Действующее лицо:** автор-композитор, у которого уже есть начало
|
||||||
|
гармонической последовательности.
|
||||||
|
|
||||||
|
**Предусловия:** имеется обученная модель и сформулированная гармоническая
|
||||||
|
затравка из нескольких аккордов.
|
||||||
|
|
||||||
|
**Основной поток:**
|
||||||
|
|
||||||
|
1. Автор формулирует затравку в виде строки аккордовых символов.
|
||||||
|
2. Запускает скрипт генерации с параметром `--prefix`.
|
||||||
|
3. Модель достраивает остаток периода с учётом затравки.
|
||||||
|
4. Получает MIDI и прослушивает.
|
||||||
|
|
||||||
|
**Постусловия:** автор получает варианты продолжения для своей гармонической
|
||||||
|
идеи.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. История изменений
|
||||||
|
|
||||||
|
- **1.0** (2026-05-19) — первоначальная редакция документа.
|
||||||
Reference in New Issue
Block a user