Demucs 코드 분석 — 하나의 노래를 보컬·드럼·베이스·기타로 분리하는 방법
Meta/Facebook Research의 Hybrid Transformer 음원 분리 모델 — 아키텍처, 추론 파이프라인, 실전 활용
Demucs가 뭔가
Demucs(Deep Extractor for Music Sources)는 Meta의 Facebook AI Research(FAIR)가 개발한 음원 분리 모델이다. 2019년 v1이 나왔고, 현재 v4(htdemucs)까지 발전했다.
입력은 완성된 곡 하나. 출력은 4개 스템:
vocals — 보컬 (리드 + 백킹)
drums — 드럼/퍼커션
bass — 베이스
other — 나머지 (기타, 피아노, 신스 등)
from demucs.pretrained import get_model
from demucs.apply import apply_model
import torchaudio
model = get_model("htdemucs")
wav, sr = torchaudio.load("song.mp3")
sources = apply_model(model, wav[None], device="cuda")[0]
# sources.shape = [4, 2, samples] → 4 stems, stereo
버전 변천사
| 버전 | 이름 | 아키텍처 | 연도 |
|---|---|---|---|
| v1 | demucs | 시간 도메인 U-Net | 2019 |
| v2 | demucs | 시간 도메인 개선 | 2021 |
| v3 | mdx/hybrid | 시간+주파수 하이브리드 | 2021 |
| v4 | htdemucs | 하이브리드 Transformer | 2022 |
v1~v2는 파형을 직접 처리하는 시간 도메인 CNN 기반이었다. v3에서 STFT(주파수 도메인)를 추가해 하이브리드가 됐고, v4에서 Transformer 어텐션을 도입했다.
htdemucs 아키텍처
htdemucs는 두 개의 병렬 경로를 가진다:
1. 시간 도메인 경로 (Temporal Encoder-Decoder)
원본 파형을 직접 처리
1D CNN 인코더 → Bottleneck → 1D CNN 디코더
Skip connection으로 인코더-디코더 연결
미세한 시간적 디테일(트랜지언트, 어택)을 잡는다
2. 주파수 도메인 경로 (Spectral Encoder-Decoder)
STFT로 변환한 스펙트로그램을 처리
2D CNN 인코더 → Bottleneck → 2D CNN 디코더
주파수 패턴(하모닉스, 피치)을 잡는다
3. Cross-Domain Transformer (핵심)
두 경로의 인코더 출력이 Transformer로 들어간다
Self-attention + Cross-attention으로 시간·주파수 도메인 간 정보를 교환
이게 v4의 핵심 개선 — 두 도메인의 장점을 실제로 결합한다
최종 출력은 두 경로의 디코더 결과를 합산한다.
추론 파이프라인 상세
demucs.apply.apply_model()의 동작:
1. 오디오를 44,100Hz 스테레오로 리샘플링
2. 오디오를 청크로 분할 (기본 ~10초, overlap 25%)
3. 각 청크에 대해:
a. shifts=1이면 원본 + 랜덤 시간 이동 버전도 처리 (TTA)
b. 시간 경로: 파형 → 1D CNN → Transformer → 1D CNN
c. 주파수 경로: STFT → 2D CNN → Transformer → 2D CNN → ISTFT
d. 두 경로 출력 합산
4. 오버랩 구간은 fade-in/fade-out으로 블렌딩
5. 4개 스템 텐서 반환: [4, 2, samples]
Nightingale에서의 사용:
sources = apply_model(model, wav_scaled[None], device=device, shifts=1, overlap=0.25)[0]
source_names = model.sources # ["drums", "bass", "other", "vocals"]
vocals_idx = source_names.index("vocals")
vocals = sources[vocals_idx]
instrumental = wav.to(device) - vocals # 원본 - 보컬 = 반주
Demucs가 4개로 분리하지만, Nightingale은 보컬만 빼고 원본 - 보컬 = 반주로 단순 계산한다. 드럼·베이스·기타를 개별로 쓰지 않는다.
UVR Karaoke 모델과의 차이
| UVR Mel-Band RoFormer Karaoke | Demucs htdemucs | |
|---|---|---|
| 스템 수 | 2 (리드 보컬 / 카라오케) | 4 (보컬 / 드럼 / 베이스 / 기타) |
| 보컬 정의 | 리드 보컬만 | 리드 + 백킹 전체 |
| 반주에 백킹 보컬 | 있음 (의도적) | 없음 (전부 보컬로 분류) |
| 모델 크기 | 913 MB | ~80 MB (htdemucs) |
| 아키텍처 | Mel-Band RoFormer (Transformer) | Hybrid Transformer (시간+주파수) |
| Vocal SDR | 10.20 dB (리드만) | ~9.20 dB (전체 보컬) |
| 노래방 적합성 | 높음 (코러스 남음) | 보통 (코러스도 제거됨) |
노래방용으로는 UVR Karaoke가 더 적합하다. 백킹 보컬이 반주에 남아서 자연스럽다. Demucs는 리믹스, 샘플링, 악기 연습용에 더 맞다.
실전 활용 사례
1. 노래방 앱 (Nightingale) — 보컬 제거 후 반주 재생
2. 음악 리믹스 — 개별 스템을 따로 조작 (드럼 볼륨 올리기, 베이스 교체 등)
3. 악기 연습 — 특정 악기만 제거해서 빈자리에서 연습
4. 음악 분석/교육 — 곡의 구조를 파트별로 분해해서 공부
5. 마스터링 — 이미 믹스된 트랙에서 개별 요소를 보정
6. 저작권 탐지 — 보컬만 분리해서 멜로디/가사 비교
모델 파일 정보
| 모델 | 파라미터 | 크기 | 용도 |
|---|---|---|---|
| htdemucs | 26.3M | ~80 MB | 기본 4-스템 분리 |
| htdemucs_ft | 26.3M | ~80 MB | fine-tuned, 약간 더 높은 SDR |
| htdemucs_6s | 26.3M | ~80 MB | 6-스템 (피아노, 기타 분리 추가) |
| mdx_extra | - | ~50 MB | v3, 경량 |
첫 실행 시 Hugging Face에서 자동 다운로드된다. TORCH_HOME 환경변수가 가리키는 디렉토리에 캐시된다.
한계
완벽한 분리는 불가능 — 스템 간 "블리딩"(다른 악기 소리가 섞임)이 있다
CPU에서 돌리면 곡 길이의 2~5배 시간이 걸린다. GPU 필수
백킹 보컬과 리드 보컬을 구분하지 못한다 (전부 vocals로 분류)
전자음악처럼 악기 경계가 모호한 곡에서는 품질이 떨어진다
핵심 개념
입력 오디오를 44,100Hz 스테레오로 리샘플링
~10초 청크로 분할 (25% 오버랩)
시간 경로: 파형 → 1D CNN 인코더 → Cross-Domain Transformer → 1D CNN 디코더
주파수 경로: STFT → 2D CNN 인코더 → Cross-Domain Transformer → 2D CNN 디코더 → ISTFT
두 경로 출력을 합산 → 4개 스템(보컬/드럼/베이스/기타) 반환