I have over 1000 audio files (it's just a initial development, in the future, there will be even more audio files), and would like to convert them to melspectrogram.
Since my workstation has a Intel® Xeon® Processor E5-2698 v3, which has 32 threads, I would like to use multithread to do my job.
My code
import os
import librosa
from librosa.display import specshow
from natsort import natsorted
import numpy as np
import sys
# Libraries for multi thread
from multiprocessing.dummy import Pool as ThreadPool
import subprocess
pool = ThreadPool(20)
songlist = os.listdir('../opensmile/devset_2015/')
songlist= natsorted(songlist)
def get_spectrogram(song):
print("start")
y, sr = librosa.load('../opensmile/devset_2015/' + song)
## Add some function to cut y
y_list = y
##
for i, y_i in enumerate([y_list]): # can remove for loop if no audio is cut
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128,fmax=8000)
try:
np.save('./Test/' + song + '/' + str(i), S)
except:
os.makedirs('./Test/' + song)
np.save('./Test/' + song + '/' + str(i), S)
print("done saving")
pool.map(get_spectrogram, songlist)
My Problem
However, my script freezes after finished the first conversion.
To debug what's going on, I commented out S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128,fmax=8000)
and replace it by S=0
.
Then the multi-thread code works fine.
What's wrong with the librosa.feature.melspectrogram
function? Does it not support multi-thread? Or is it a problem of ffmpeg? (When using librosa, it asks me to install ffmpeg before.)
I recommend using joblib to parallel process with librosa. I believe librosa is using it internally, so this might avoid some conflicts. Below is a working example, based on code that I regularly use to process some 10k files.
import os.path
import joblib
import librosa
import numpy
def compute(inpath, outpath):
y, sr = librosa.load(inpath)
S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128, fmax=8000)
numpy.save(outpath, S)
return outpath
out_dir = 'temp/'
n_jobs=8
verbose=1
# as an reproducable example just processes the same input file
# but making sure to give them unique output names
inputs = [ librosa.util.example_audio_file() ] * 10
outputs = [ os.path.join(out_dir, '{}.npy'.format(n)) for n in range(len(inputs)) ]
jobs = [ joblib.delayed(compute)(i, o) for i,o in zip(inputs, outputs) ]
out = joblib.Parallel(n_jobs=n_jobs, verbose=verbose)(jobs)
print(out)
Output
[Parallel(n_jobs=8)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=8)]: Done 6 out of 10 | elapsed: 10.4s remaining: 6.9s
[Parallel(n_jobs=8)]: Done 10 out of 10 | elapsed: 13.2s finished
['temp/0.npy', 'temp/1.npy', 'temp/2.npy', 'temp/3.npy', 'temp/4.npy', 'temp/5.npy', 'temp/6.npy', 'temp/7.npy', 'temp/8.npy', 'temp/9.npy']
来源:https://stackoverflow.com/questions/55487391/unable-to-use-multithread-for-librosa-melspectrogram