Реализация AI-разделения аудио на дорожки (Source Separation)
Source separation — задача выделения отдельных источников звука из смешанного сигнала. Применяется в музыкальном продакшне (стемы), обработке речи (удаление фоновой музыки), видеопостпродакшне и ремастеринге архивных записей.
Основные модели и инструменты
| Модель | Тип разделения | Качество (SDR) | Скорость |
|---|---|---|---|
| Demucs v4 (htdemucs) | Вокал/барабаны/бас/прочее | 9.0 dB | 1.5× realtime на GPU |
| Spleeter (Deezer) | 2/4/5 стемов | 6.8 dB | 100× realtime |
| Open-Unmix (UMX) | 4 стема | 7.2 dB | 10× realtime |
| MDX-Net | Конкурсный (MDX Challenge) | 9.5 dB | 2× realtime |
| BS-RoFormer | SOTA 2024 | 10.1 dB | 0.8× realtime |
SDR (Signal-to-Distortion Ratio) — основная метрика: выше = чище разделение.
Demucs v4 — production интеграция
import torch
from demucs.pretrained import get_model
from demucs.apply import apply_model
from demucs.audio import AudioFile, save_audio
import torchaudio
class AudioSourceSeparator:
def __init__(self, model_name: str = "htdemucs"):
self.model = get_model(model_name)
self.model.eval()
if torch.cuda.is_available():
self.model.cuda()
def separate(
self,
audio_path: str,
output_dir: str,
stems: list[str] = None # None = все стемы
) -> dict[str, str]:
"""Разделяем трек на стемы, возвращаем пути к файлам"""
wav = AudioFile(audio_path).read(
streams=0,
samplerate=self.model.samplerate,
channels=self.model.audio_channels
)
ref = wav.mean(0)
wav = (wav - ref.mean()) / ref.std()
sources = apply_model(
self.model,
wav[None],
device="cuda" if torch.cuda.is_available() else "cpu",
progress=True,
num_workers=2
)[0]
sources = sources * ref.std() + ref.mean()
result = {}
available_stems = self.model.sources # ['drums', 'bass', 'other', 'vocals']
target_stems = stems or available_stems
for stem, source in zip(available_stems, sources):
if stem in target_stems:
output_path = f"{output_dir}/{stem}.wav"
save_audio(source, output_path, samplerate=self.model.samplerate)
result[stem] = output_path
return result
def extract_vocals_only(self, audio_path: str) -> tuple[str, str]:
"""Быстрое разделение: вокал + инструментал"""
model = get_model("htdemucs") # или "mdx_extra" для лучшего вокала
# ...
return vocals_path, instrumental_path
Разделение речи от фоновой музыки
from demucs.pretrained import get_model
class SpeechFromMusicExtractor:
"""Специализация для контент-обработки: извлечение речи из видео"""
def __init__(self):
# htdemucs_ft — fine-tuned на вокал, лучший для речи
self.model = get_model("htdemucs_ft")
async def process_video_audio(
self,
video_path: str,
output_speech: str,
output_music: str
) -> dict:
import subprocess
# Извлекаем аудио из видео
audio_path = video_path.replace(".mp4", "_audio.wav")
subprocess.run([
"ffmpeg", "-i", video_path,
"-ac", "2", "-ar", "44100",
"-vn", audio_path
], check=True)
# Разделяем
stems = self.separate(audio_path, output_dir="/tmp/stems")
# vocals = речь в данном контексте
# other+bass+drums = музыкальный фон
speech_stems = ["vocals"]
music_stems = ["drums", "bass", "other"]
return {
"speech": stems.get("vocals"),
"music_components": {k: stems[k] for k in music_stems if k in stems}
}
Batch-обработка через FastAPI
from fastapi import FastAPI, UploadFile, BackgroundTasks
import uuid, os
app = FastAPI()
separator = AudioSourceSeparator()
@app.post("/separate")
async def separate_audio(
file: UploadFile,
stems: str = "vocals,drums,bass,other",
background_tasks: BackgroundTasks = None
):
job_id = str(uuid.uuid4())
audio_path = f"/tmp/{job_id}_input.wav"
with open(audio_path, "wb") as f:
f.write(await file.read())
output_dir = f"/tmp/{job_id}_output"
os.makedirs(output_dir, exist_ok=True)
background_tasks.add_task(
separator.separate,
audio_path,
output_dir,
stems.split(",")
)
return {"job_id": job_id, "status": "processing"}
Типовые применения
Музыкальный продакшн:
- Remixing — изолируем барабаны или бас для переработки
- Karaoke — удаляем вокал, оставляем инструментал
- Mastering стемов — обрабатываем каждый слой независимо
Контент и медиа:
- Удаление фоновой музыки перед STT — WER снижается с 18% до 4%
- Ремастер архивных записей — разделение + денойз каждого стема
- Локализация видео — изолируем речь, заменяем дубляжом
Постпродакшн:
- ADR (Automated Dialogue Replacement) — чистый вокал для замены реплик
- Музыкальное оформление — извлечение музыки для переиспользования
Ограничения и нюансы
Demucs работает хуже при:
- Очень громкой перкуссии поверх речи (SDR падает на 2–3 dB)
- Монозаписях низкого качества (< 22 kHz)
- Сложных полифонических наложениях (4+ источника одновременно)
Для максимального качества вокала — mdx_extra или htdemucs_ft. Для скорости в batch-режиме — Spleeter (в 10–15 раз быстрее Demucs на CPU).
Сроки: интеграция Demucs в пайплайн обработки медиафайлов — 1–2 недели. Полноценный сервис с очередью и веб-интерфейсом — 3–4 недели.







