VoiceLM: конвейер, который вытаскивает чистый голос из шума

· 2 мин · BadRabbit

Для голоса Евы мне нужен датасет: много коротких записей чистой речи, без музыки, фона и эха. Ручная нарезка — это недели работы. Поэтому появился VoiceLM, конвейер, который берёт голосовые сообщения из моих Telegram-чатов, прогоняет их через нейросеть отделения вокала и складывает «сухой» голос в датасет.

Важная оговорка: конвейер работает только с теми чатами и записями, на которые у меня есть права и согласие участников. Голос — такие же персональные данные, как лицо.

Архитектура

Telegram → скрапер → Redis (очередь RQ) → GPU-воркер (UVR5/MDX-Net) → VoiceData/
  • Скрапер скачивает голосовые с паузами, чтобы не получить бан за слишком частые запросы.
  • Redis + RQ: каждое сообщение становится задачей в очереди. Скрапер и воркер не ждут друг друга, а если воркер упал, задачи никуда не денутся.
  • Воркер конвертирует аудио через FFmpeg и отдаёт его audio-separator с моделями UVR5 / MDX-Net, которые отделяют голос от всего остального.

Самое сложное: видеопамять

Модель разделения тяжёлая, а карта у меня на 8 ГБ. Если оставить всё на усмотрение PyTorch, его кеш на GPU растёт от файла к файлу, пока не случится OOM. Поэтому в обработчике строгое управление VRAM: после каждой задачи кеш видеокарты явно очищается, а воркер обрабатывает записи по очереди, а не пачкой. Медленнее в теории, но на практике быстрее, потому что ничего не падает.

Nix вместо Dockerfile

Образ контейнера собирается не из Dockerfile, а через Nix:

nix develop
build-image   # nix собирает образ
load-image    # загружаем его в Docker
up            # Redis + скрапер + воркер, секреты расшифровываются на лету

Внутри devShell лежат удобные команды: gen-session, history-scraper, logs-worker, check. Через пару дней я разберу, почему собирать контейнеры через Nix лучше.

Секреты

Токены Telegram никогда не лежат в репозитории открытым текстом. Они зашифрованы SOPS + age: есть команда encrypt-env, которая переносит .env в зашифрованный secrets.sops.yaml, и edit-secrets для правки. В git попадает только шифротекст.

Что я понял

  1. Очередь между «скачать» и «обработать» — лучшее решение в этом проекте. Она развязала медленную сеть и медленную видеокарту.
  2. Память видеокарты надо контролировать явно. «Сборщик мусора разберётся» — не стратегия, когда у тебя 8 ГБ.
  3. Секреты нужно шифровать с первого коммита, а не «потом».