# 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 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.2) │ ├── requirements.md функциональные и нефункциональные требования │ ├── architecture.md архитектура системы │ └── glossary.md глоссарий терминов ├── data/ │ ├── raw_user/ .chord-файлы собственного корпуса │ ├── raw_external/ публичные корпуса (McGill Billboard и др.) │ ├── processed/ │ │ ├── mcgill/ токенизированные .pt-файлы McGill (train/val) │ │ └── user/ токенизированные .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 H1K0 \ --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 H1K0 --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`-файла: название, тональность, тактовый размер, подразделение доли, стилевой тег `H1K0`, функциональная роль периода. 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 Предобучение ```bash python scripts/pretrain.py ``` Обучает на корпусе McGill (`data/processed/mcgill/`). Выводит оценку времени выполнения и по окончании сохраняет: | Файл | Описание | | ----------------------------------- | ----------------------------- | | `checkpoints/pretrained.pt` | лучший чекпоинт (по val loss) | | `checkpoints/pretrained.log.csv` | метрики по эпохам | | `checkpoints/pretrained_curves.png` | график кривых train/val loss | | `checkpoints/pretrained.report.txt` | сводный отчёт о прогоне | Если обучение было прервано, повторно построить график и отчёт без повторного обучения: ```bash python scripts/pretrain.py --skip-training ``` ### 7.2 Дообучение на собственном корпусе ```bash python scripts/train.py ``` Загружает `checkpoints/pretrained.pt` и дообучает на собственном корпусе (`data/processed/user/`). Сохраняет `checkpoints/finetuned.pt` и аналогичный набор артефактов (`finetuned.log.csv`, `finetuned_curves.png`, `finetuned.report.txt`). Существенно более низкая скорость обучения (lr=1e-5 против 3e-4) и небольшое число эпох (15) предотвращают катастрофическое забывание закономерностей, выученных на этапе предобучения. ## 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), раздел «Точки расширения».