Files
hamori/README.md
T
H1K0 5ab10de7ee docs(readme): link the project report notebook and fix its location in the repo tree
The report lives in notebooks/report.ipynb, but section 4 listed the
final report under reports/. Point readers to it from sections 8 and 9
and correct the repo-tree description.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 23:24:33 +03:00

386 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# hamori
Авторегрессионная нейросетевая модель для генерации гармонических периодов
(замкнутых гармонических фраз 4–16 тактов) в авторском композиторском стиле.
Название проекта — _hamori_ (яп. ハモリ) — относится к понятию вокальной
гармонизации, добавлению второго голоса в существующую мелодическую линию.
Отсылка к этому понятию закрепляет основную идею проекта: модель не пишет
музыку с нуля, а предлагает гармонические идеи в дополнение к замыслу
композитора.
Проект разработан как курсовая работа по дисциплине «Машинное обучение» в
рамках обучения в РТУ МИРЭА и одновременно как практический инструмент для
композиторской работы.
## Содержание
- [hamori](#hamori)
- [Содержание](#содержание)
- [1. Краткое описание](#1-краткое-описание)
- [2. Контекст и цели](#2-контекст-и-цели)
- [3. Установка](#3-установка)
- [4. Структура репозитория](#4-структура-репозитория)
- [5. Быстрый старт](#5-быстрый-старт)
- [5.1 Веб-интерфейс](#51-веб-интерфейс)
- [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](<https://ddmal.ca/research/The_McGill_Billboard_Project_(Chord_Analysis_Dataset)/>)) для усвоения общих гармонических закономерностей
поп-музыки.
- **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.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-ноутбуки: исследование данных и итоговый отчёт (report.ipynb)
├── 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
```
Модель достроит остаток периода в логике, выученной на собственном корпусе
автора.
### 5.1 Веб-интерфейс
Для интерактивной работы без командной строки предусмотрен простой
веб-интерфейс на базе Gradio. Запуск:
```bash
python app.py
```
После запуска интерфейс открывается в браузере по адресу
`http://127.0.0.1:7860`. На одной странице расположены форма выбора
параметров (модель, лад, тональность, стиль, функция, тактовый размер,
параметры сэмплирования, опциональный префикс) и блок результата —
текстовая сетка аккордов и кнопки скачивания `.chord`- и `.mid`-файлов.
Краткая инструкция на русском языке встроена в саму страницу (раздел
«Инструкция»).
Интерфейс является надстройкой над тем же модулем `src/generate.py`,
что и CLI; вся логика генерации общая. Полезные флаги:
```bash
python app.py --port 8000 # другой порт
python app.py --share # временная публичная ссылка
```
## 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](<https://ddmal.ca/research/The_McGill_Billboard_Project_(Chord_Analysis_Dataset)/>) — открытый
размеченный профессиональными аннотаторами корпус из примерно семи сотен
пьес западной поп-музыки 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).
Готовые результаты — численные метрики, графики распределений и качественный
разбор примеров — собраны в итоговом отчёте
[notebooks/report.ipynb](notebooks/report.ipynb).
## 9. Дополнительная документация
| Документ | Назначение |
| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [notebooks/report.ipynb](notebooks/report.ipynb) | Итоговый отчёт по проекту (Jupyter-ноутбук на русском): постановка задачи, формат данных, модель, обучение, оценка с графиками, хроника разработки и выводы. Запускается целиком. |
| [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.
- Ритмический паттерн внутри удержания аккорда (синкопы, проходящие фигуры,
альбертиевы басы).
- Аранжировка, тембр, динамика, артикуляция.
- Развитый графический интерфейс. Реализован лишь минимальный веб-интерфейс
(см. раздел 5.1) как надстройка над CLI; полноценного редактора с
визуализацией нотного стана, проигрывателем и историей версий нет.
- Прямая интеграция с REAPER в режиме реального времени. Обмен с DAW
происходит через файлы MIDI.
- Обработка модуляций внутри одного периода. При наличии модуляции в
исходном произведении периоды разрезаются по точке модуляции.
- Дообучение на корпусе японской поп-музыки (J-Pop). Запланировано как
отдельный эксперимент после защиты курсовой.
Подробное обсуждение каждого пункта и направления развития содержатся в
[docs/architecture.md](docs/architecture.md), раздел «Точки расширения».