Невозможно использовать многопоточность для либроса melspectrogram - PullRequest
0 голосов
/ 03 апреля 2019

У меня более 1000 аудиофайлов (это только начальная разработка, в будущем будет еще больше аудиофайлов), и я хотел бы преобразовать их в melspectrogram.

Поскольку моя рабочая станция имеет процессор Intel® Xeon® E5-2698 v3, который имеет 32 потока, я хотел бы использовать многопоточность для своей работы.

Мой код

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)

Моя проблема

Однако мой скрипт зависает после завершения первого преобразования.

Чтобы отладить происходящее, я закомментировал S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128,fmax=8000) и заменил его на S=0.Тогда многопоточный код работает нормально.

Что не так с функцией librosa.feature.melspectrogram?Разве он не поддерживает многопоточность?Или это проблема ffmpeg?(При использовании librosa он просит меня установить ffmpeg раньше.)

1 Ответ

0 голосов
/ 15 апреля 2019

Я рекомендую использовать joblib для параллельного процесса с librosa. Я полагаю, что librosa использует это внутренне, так что это может избежать некоторых конфликтов. Ниже приведен рабочий пример, основанный на коде, который я регулярно использую для обработки некоторых файлов размером 10 КБ.

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)

выход

[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']
...