muscriptor-large-fork / plus /README_PLUS.md
Nokia123543's picture
чистка: убрано упоминание другого движка
41030e3 verified
|
Raw History Blame Contribute Delete
7.56 kB

PLUS — расширение MuScriptor

Пакет пост-обработки транскрипции. Ни одна стадия не требует GPU и не трогает веса: на вход идёт MIDI (и по желанию аудио), на выходе MIDI, WAV и отчёт. Работает поверх любого движка: MuScriptor Large, Aria-AMT.

Что внутри

Файл Что делает
plus_core.py нотная модель, чтение/запись MIDI, темп по сетке, explained_fraction, ambiguity_of
plus_transcribe.py стадии: cleanup, quantize, hands, pedal, chords, dynamics, report
plus_ensemble.py слияние нескольких транскрипций голосованием + оценка P/R/F1
plus_render.py MIDI в WAV своим синтезатором, чтобы слушать до DAW
plus_batch.py обработка папки, возобновление, сводка в CSV

Стадии

cleanup — унисоны (тот же питч в пределах 45 мс с перекрытием > 60 %), фантомы (нота короче 120 мс и тише медианы на 35, включая одиночные редкие питчи), обрезка длительности до следующей ноты того же питча.

quantize — посадка онсетов и длительностей на сетку 1/4 доли с силой 0..1 и свингом. Темп берётся из файла: угадывание кратного по бинарным онсетам математически неоднозначно, поэтому при объяснении сетки ниже 0.7 в отчёт идёт предупреждение tempo_ambiguous плюс список альтернатив (bpm/2, bpm*2, bpm*3), а не тихая подмена.

hands — правая и левая рука жадным проходом по стоимости перехода (питч плюс время) с проверкой, что левая не уехала выше правой на октаву.

pedal — вывод CC64 по смене гармонии: онсеты кластеризуются в аккорды (окно 60 мс), педаль держится пока набор высотных классов не сменился или не истёк max_hold (1.6 с по умолчанию). Ноты продлеваются внутри окна, но не дальше следующей ноты того же питча.

chords — аккорды по одновременным онсетам, распознавание по шаблонам (m, 7, maj7, dim, aug, sus2, sus4, 6, m6) и подписи в отчёте.

dynamics — громкость из аудио: RMS в окне 250 мс от онсета, перцентильный share, степень 0.65, множитель акцента по атаке, кривая в velocity 15..118. Отдельный баланс рук: левая на 0.88, правая на 1.0, чтобы аккомпанемент не перекрывал мелодию.

report — метрики (нот, длительность, плотность, диапазон, медиана длительности), аномалии (перекрытия, слишком короткие, всплески плотности, плоская громкость) и разбивка по дорожкам.

Замеры на синтетике с известной правдой

Собрано 131 нота: мелодия восьмыми при 72 BPM плюс аккорды каждую долю, джиттер 10 мс, и три вида мусора (нота 10 мс, унисон, тихий фантом).

cleanup    short_removed=1, unisons_merged=1, ghosts_removed=1 -> ровно 128 нот
quantize   explained_before=0.992 -> explained_after=1.000, темп 72 из файла
hands      left=96, right=32  (аккорды 32*3 в левой, мелодия 32 в правой)
pedal      spans=31, median_hold=0.432 с
chords     32 кластера, 32 распознаны
report     overlaps=0, octave_leaps=0

Ансамбль: три «движка» по 10 % потерянных нот и 4 фантома каждый.

F1 слияния 0.992 против лучшего входа 0.949 (muscriptor)
точность/полнота слияния 0.99/0.99, ошибка онсета ~10 мс

Скорость: пачка из трёх MIDI (включая 30 000 нот) за 1.6 с; рендер 8 секунд звука за 0.27 с.

Использование

# полный проход по одному файлу
python3 plus_transcribe.py --midi take.mid --audio take.wav \
    --out take_plus.mid --report take_plus.json

# только ритм и руки, без громкости
python3 plus_transcribe.py --midi take.mid --stages cleanup,quantize,hands

# слияние MuScriptor + Aria и оценка против эталона
python3 plus_ensemble.py --inputs mus.mid aria.mid tk.mid \
    --out merged.mid --reference truth.mid

# послушать результат
python3 plus_render.py --midi merged.mid --out merged.wav

# папка целиком, с возобновлением
python3 plus_batch.py --input-dir takes --out-dir takes_plus

Ограничения, о которых честно

  • Темп у бинарных онсетов неоднозначен: чистые восьмые при 72 BPM и четверти при 144 дают одинаковую сетку. Скрипт об этом пишет, а не делает вид, что знает.
  • Педаль и аккорды эвристические: на плотной педали или кластерах вне мажора и минора возможны ошибки, отчёт это показывает (named против clusters).
  • dynamics требует ту же запись, с которой снят MIDI; перекрывающиеся ноты делят энергию окна, поэтому громкость относительная, а не абсолютная.
  • Квантование при strength 1.0 убивает человеческое дрожание: для живой игры держите 0.7..0.9.

PLUS Studio — веб-интерфейс

plus_app.py поднимает страницу на FastAPI: загрузка аудио или MIDI, чекбоксы стадий, ползунки силы квантования и свинга, слияние нескольких файлов, скачивание MIDI, превью WAV и отчёта JSON. Модель грузится лениво при первом запросе, веса берутся из Nokia123543/muscriptor-large-fork (или из --weights).

python plus_app.py --port 8900                # CPU или GPU автоматически
python plus_app.py --port 8900 --device cuda --preload --weights /content/model.safetensors

Эндпоинты: GET /health, POST /transcribe (аудио), POST /process (MIDI), POST /merge (несколько MIDI), GET /jobs/{id} (состояние и лог), GET /jobs/{id}/result.mid|preview.wav|report.json.