【问题标题】:Unable to use Multithread for librosa melspectrogram无法将多线程用于 librosa melspectrogram
【发布时间】:2019-04-03 04:59:56
【问题描述】:

我有超过 1000 个音频文件(这只是一个初步的开发,未来会有更多的音频文件),并且想将它们转换为 melspectrogram。

由于我的工作站有一个英特尔® 至强® 处理器 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。)

【问题讨论】:

    标签: python multithreading ffmpeg librosa


    【解决方案1】:

    我建议使用joblib 与 librosa 并行处理。我相信 librosa 在内部使用它,所以这可能会避免一些冲突。下面是一个工作示例,基于我经常用于处理大约 10k 个文件的代码。

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

    【讨论】:

      【解决方案2】:

      另一种解决方案是使用 Tacotron2 实现来提取 melspectrogram,它是多线程兼容的。 https://github.com/NVIDIA/tacotron2/blob/master/data_utils.py

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
      猜你喜欢
      • 1970-01-01
      • 2020-02-09
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多