음원 분리를 위한 Spleeter 모델 구축: 환경 구성, 학습 및 테스트 방법
Spleeter
Spleeter는 Python 음원 분리 라이브러리로, 보컬 및 여러 악기로 이루어진 혼합 음원에서 보컬 및 각각의 악기를 분리할 수 있다.
2stems, 4stems, 5stems의 3가지 분리 방식을 제공하며 각 분리 방식별 사전 훈련된 모델을 제공한다.
- 2stems: Vocals (singing voice) / accompaniment separation
- 4stems: Vocals / drums / bass / other separation (※2stems, 4stems 모델은 musdb dataset에서 높은 성능을 보임)
- 5stems: Vocals / drums / bass / piano / other separation
※github link: https://github.com/deezer/spleeter
GitHub - deezer/spleeter: Deezer source separation library including pretrained models.
Deezer source separation library including pretrained models. - GitHub - deezer/spleeter: Deezer source separation library including pretrained models.
github.com
Spleeter 환경 구성
1-1. For Spleeter Separate
conda env create -n spleeter # 1. spleeter anaconda 환경 생성
conda activate spleeter # 2. spleeter 가상환경 활성화
conda install -c conda-forge ffmpeg libsndfile # 3. 필요 패키지 및 라이브러리 설치
pip install spleeter # 4. spleeter 설치
1-2. For Spleeter train / test
spleeter train 및 test를 위해서는 추가로 몇 가지 패키지를 더 설치해야 한다.
Git의 Spleeter Repo에서 anaconda yaml 파일과 docker file을 모두 제공하고 있으므로 해당 파일들을 이용해서 환경 구축을 하면 된다.
Anaconda
- 위 spleeter github link로 이동
- conda/spleeter 폴더로 이동
- meta.yaml 파일 다운로드
- conda env create --file meta.yaml을 통해 spleeter 환경 import하기
Docker
- 위 spleeter github link로 이동
- docker 폴더로 이동
- docker 폴더에 있는 .dockerfile을 이용해서 docker 이미지 생성 - docker build [dockerfile 경로] -t [이미지 이름]
- docker run [이미지 이름]
Spleeter separate
spleeter separate -p spleeter:4stems -o [output folder path] [file path]
ex) spleeter separate -p spleeter:4stmes -o output audio_example.mp3
위 명령어를 실행하면 pretrained_models 폴더가 생성되며 4stems 모델을 다운로드 받고 separate를 수행한다.
수행 결과는 4stems이므로 vocals.wav, bass.wav, drums.wav. other.wav 4개 개별 악기 음원으로 나오게 된다.
Spleeter train / test
1. 필요 데이터 목록 (4stems 분류 방식 기준)
- 곡 wav 파일 및 원하는 분리 방식으로 분리된 악기별 wav 파일 - mixture.wav, vocals.wav, bass.wav, drums.wav, other.wav
<곡별 wav 파일 디렉토리 구조>
SpleeterDataset
├── train
└── Song1
├── mixture.wav
├── vocals.wav
├── drums.wav
├── bass.wav
├── other.wav
└── Song2
├── mixture.wav
├── vocals.wav
├── …
- 설정 파일 - config.json
아래 파일은 spleeter/configs/4stems의 base_config.json 파일로, 학습 및 테스트 시 필요한 설정들을 담고 있는 파일이다.
# TODO로 주석을 단 부분은 반드시 경로 설정이 필요하다.
train_csv, validation_csv는 각 csv 파일 경로에 맞게 적어주고, model_dir도 원하는 경로를 입력해주면 되고, 나머지 파라미터는 원하는 대로 조정하면 된다.
{
"train_csv": "path/to/train.csv", # TODO
"validation_csv": "path/to/test.csv", # TODO
"model_dir": "4stems", # TODO
"mix_name": "mix",
"instrument_list": ["vocals", "drums", "bass", "other"],
"sample_rate":44100,
"frame_length":4096,
"frame_step":1024,
"T":512,
"F":1024,
"n_channels":2,
"separation_exponent":2,
"mask_extension":"zeros",
"learning_rate": 1e-4,
"batch_size":4,
"training_cache":"training_cache",
"validation_cache":"validation_cache",
"train_max_steps": 1500000,
"throttle_secs":600,
"random_seed":3,
"save_checkpoints_steps":300,
"save_summary_steps":5,
"model":{
"type":"unet.unet",
"params":{
"conv_activation":"ELU",
"deconv_activation":"ELU"
}
}
}
- 각 wav 파일(mixture, vocals, bass, drum, other) 경로가 담긴 csv 파일 - train_csv, validation.csv
학습 및 테스트 데이터들의 경로 및 duration(음원 길이) 정보를 csv 파일로 만들어 제작해야 한다.
곡별 mix_path, vocals_path, drums_path, bass_path, other_path, duration으로 열을 구성하여 각 곡별 정보를 넣어 train.csv, validation.csv 파일을 구성한다.
csv 파일을 제작한 후엔 해당 csv 파일의 경로를 config.json 파일에 반영한다.
참고로 wav 파일의 duration은 아래 코드를 통해 간단하게 구할 수 있다.
# use wave lib
import wave
def get_wave_duration(audio_path):
audio = wave.open(audio_path)
frames = audio.getnframes()
rate = audio.getframerate()
duration = frames / float(rate)
return duration
# use librosa lib
import librosa
def get_wav_duration(audio_path):
y, sr = librosa.load(audio_path)
wav_duration = librosa.get_duration(y=y, sr=sr)
return wav_duration
2. wav 데이터 전처리
1) stereo type 변환
mono type의 wav는 학습 시 오류가 발생하여 중단되므로, 반드시 사전에 모든 wav(악기별 분리 wav 포함)를 stereo 타입으로 변환해야 한다.
# mono2stereo
from pydub import AudioSegment
def mono2stereo(file_path):
left_channel = AudioSegment.from_wav(file_path)
right_channel = AudioSegment.from_wav(file_path)
stereo_sound = AudioSegment.from_mono_audiosegments(left_channel, right_channel)
stereo_sound = stereo_sound.set_frame_rate(44100)
stereo_sound = stereo_sound.set_sample_width(2)
stereo_sound.export(file_path, format='wav')
2) 곡별 wav 파일 길이 맞추기
곡 폴더 내 5개 wav의 길이는 동일해야 한다. 중요한 점은, 파일 탐색기 상으로 볼 때의 길이가 아니라 wav 의 frame 수가 완전히 동일해야 한다.
위 이미지와 같이 길이가 모두 3:46초로 동일하더라도 각 wav의 frame 수는 조금씩 차이날 수 있다. frame 수를 1의 자리까지 동일하게 맞춰줘야 모델 evaluate 시 에러가 발생하지 않는다.
wav의 frame 수는 wave 라이브러리의 getparams() 함수로 확인하거나 다른 audio 라이브러리로 읽어들였을 때 data type이 ndarray인 경우 np.shape로도 확인 가능하다.
import wave
wav = wave.open('song.wav')
print(wav.getparams())
# output
# _wave_params(nchannels=2, sampwidth=2, framerate=48000, nframes=11906909, comptype='NONE', compname='not compressed')
※참고: nframes = duration(오디오 파일의 길이) * sampligRate
3) 무음 wav 처리
학습 및 테스트를 진행할 때 간혹 특정 곡에는 drums, bass, vocals, other 중 어느 하나 혹은 여러 악기가 없을 수도 있다. 학습 및 테스트를 위해서는 반드시 원곡 wav 및 각 악기별 분리 wav 파일이 필요하므로 이럴 경우 해당 악기를 무음으로 처리해서 넣어줘야 한다. 다만 이럴 경우 아래와 같은 에러 메시지가 뜰 수 있으므로, 해당 에러가 발생할 시 audio 라이브러리를 이용해 해당 무음 wav 파일을 로드한 후 전부 0으로 되어있는 ndarray 데이터의 일부를 0.00001 등 아주 작은 숫자로 일부 변경해준 뒤 테스트를 진행하면 된다.
3. train
- spleeter train -p [config.json 파일 경로] -d [데이터셋 폴더 경로]
4. Test
- spleeter evaluate -p [config.json 파일 경로] --mus_dir [데이터셋 폴더 경로] -o [결과 폴더 경로] --mwf