Demucs v4 Hybrid Transformer 모델을 모바일 기기에서 실행하기 위한 경량화 및 최적화 프로젝트입니다.
sevagh/demucs.onnx 프로젝트를 기반으로, 실제 모바일 NPU(Qualcomm)에서 동작할 수 있도록 모델을 최적화했습니다.
- FP16 양자화: 모델을 Float32 → Float16으로 변환하여 메모리 사용량 절반 감소
- 청킹 처리: NPU 메모리 제한을 우회하기 위해 오디오를 1초 단위로 분할 처리
- 배치 추론: Qualcomm AI Hub에서 병렬 처리로 추론 시간 단축
- Qualcomm NPU 테스트: Samsung Galaxy S24에서 실제 추론 테스트 수행
- 모델: HTDemucs (FP16)
- 디바이스: Samsung Galaxy S24
- 테스트 곡: 데이식스 - Happy (약 3분)
| 시도 | 청크 크기 | 결과 |
|---|---|---|
| 전체 곡 처리 | - | ❌ OOM (메모리 부족) |
| 2초 청킹 | 88,200 samples | ❌ OOM |
| 1초 청킹 | 44,100 samples | ✅ 성공 |
Qualcomm AI Hub 테스트 (디바이스 프로비저닝 포함)
- 청크당 처리 시간: 약 4분 (프로비저닝 대기 시간 포함)
- 3분 곡 (253개 청크): 약 28시간 예상
- 병목: 클라우드 테스트 환경의 디바이스 프로비저닝 대기
실제 기기 추론 시간 (프로비저닝 제외)
- 청크당 순수 추론 시간: 약 100ms
- 3분 곡 예상 처리 시간: 약 30~35초
- 5분 곡 예상 처리 시간: 약 50~60초
demucs.onnx/
├── scripts/ # 모델 변환 스크립트
│ ├── convert-pth-to-onnx.py # PyTorch → ONNX 변환
│ ├── convert-pth-to-onnx-chunked.py # 청크용 ONNX 변환
│ └── convert_to_fp16.py # FP16 양자화
├── qualcomm-test/ # Qualcomm AI Hub 테스트
│ ├── run_qai_hub.py # 단일 청크 테스트
│ ├── run_qai_hub_chunked.py # 순차 처리
│ ├── run_qai_hub_batch.py # 배치 처리 (권장)
│ ├── preprocess_demucs.py # 전처리 (STFT)
│ └── postprocess_demucs.py # 후처리 (WAV 변환, ISTFT)
├── src/ # C++ 구현
│ └── dsp.cpp # STFT/iSTFT 구현
├── demucs-for-onnx/ # 수정된 Demucs (STFT 분리)
└── onnx-models/ # 변환된 ONNX 모델
# PyTorch → ONNX 변환
python scripts/convert-pth-to-onnx-chunked.py
# FP16 양자화
python scripts/convert_to_fp16.py onnx-models/htdemucs.onnx onnx-models/htdemucs_fp16.onnxcd qualcomm-test
# 배치 추론 실행 (권장)
python run_qai_hub_batch.py ../day6-happy.mp3
# 결과를 WAV로 변환
python postprocess_demucs.py output stemspip install qai-hub
qai-hub configure --api_token YOUR_API_TOKEN
qai-hub list-devices원본 Demucs 모델은 STFT/iSTFT를 내부에서 수행하지만, 이 연산은 ONNX로 내보낼 수 없습니다. 따라서 STFT/iSTFT를 모델 외부로 분리했습니다.
오디오 → [STFT (외부)] → ONNX 모델 → [iSTFT (외부)] → 분리된 stems
CHUNK_SIZE = 44100 # 1초 (44.1kHz)
OVERLAP = 11025 # 25% 오버랩
HOP_SIZE = 33075 # 청크 간 이동 거리| 입력 | Shape | 설명 |
|---|---|---|
| input | (1, 2, 44100) | 시간 도메인 스테레오 오디오 |
| x | (1, 4, 2048, 44) | STFT 결과 (Real/Imag 분리) |
| 출력 | Shape | 설명 |
|---|---|---|
| add_67 | (1, 4, 2, 44100) | 4개 stem × 스테레오 |
- FP16 양자화만으로는 모바일 NPU 메모리 한계를 극복할 수 없었음
- 1초 단위 청킹으로 메모리 문제 해결
- 실제 기기에서 청크당 약 100ms 추론 가능
- 3분 곡 기준 약 30~35초 처리 예상
Based on sevagh/demucs.onnx (MIT License)