You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

librosa与torchaudio的Griffin-Lim音频重构结果不一致问题排查

问题:librosa与torchaudio的Griffin-Lim音频重构结果不一致

我尝试将频谱图还原为音频:先用librosa.griffinlim完成重构,效果良好但耗时较长;于是想用GPU上的torchaudio加速转换,却得到和librosa不一致的重构结果。以下是我的代码:

预处理

data, fs = librosa.load('waveform.wav', sr=44100)
b, a = signal.butter(3, [20 / fs, 1000 / fs], 'bandpass')
data = signal.filtfilt(b, a, data)
plt.plot(data)

STFT计算

DMatrix = librosa.stft(data, n_fft=2048, hop_length=int(2048 * 0.1), window='hann')
dbMatrix = librosa.amplitude_to_db(np.abs(DMatrix), ref=np.max)

原始波形

使用librosa的重构结果

spec = librosa.db_to_amplitude(dbMatrix)
re_wav = librosa.griffinlim(spec, n_iter=100, n_fft=2048, hop_length=int(2048 * 0.1), window='hann')
plt.plot(re_wav)

librosa重构结果

使用torchaudio的重构结果

griffinlim = torchaudio.transforms.GriffinLim(n_fft=2048, n_iter=100, hop_length=int(2048 * 0.1)).to('cuda')
spec = librosa.db_to_amplitude(dbMatrix)
re_wav = griffinlim(torch.tensor(spec).to('cuda'))
plt.plot(re_wav.cpu().detach().numpy())

torchaudio重构结果

核心差异原因

两者结果不一致是因为默认参数不匹配,具体需要对齐以下几点:

  1. 窗口函数:librosa的hann窗口默认是周期归一化的,torchaudio需要显式指定window=torch.hann_window(n_fft, periodic=True).to('cuda'),确保和librosa的窗口特性一致。
  2. STFT中心对齐:librosa的stft默认center=True(对输入补零后居中计算),torchaudio的GriffinLim默认center=False,需要手动设置center=True。
  3. 张量维度:torchaudio期望输入是(batch, freq_bins, frames)的三维张量,需给频谱增加batch维度(.unsqueeze(0)),输出后再移除。
  4. 随机种子:Griffin-Lim初始相位随机,需统一librosa(np.random.seed())和torchaudio(torch.manual_seed()、torch.cuda.manual_seed_all())的随机种子以复现结果。

修正后的torchaudio代码

import torch
import torchaudio

n_fft = 2048
hop_length = int(2048 * 0.1)

# 统一随机种子
np.random.seed(42)
torch.manual_seed(42)
torch.cuda.manual_seed_all(42)

# 初始化对齐参数的GriffinLim
griffinlim = torchaudio.transforms.GriffinLim(
    n_fft=n_fft,
    n_iter=100,
    hop_length=hop_length,
    window=torch.hann_window(n_fft, periodic=True).to('cuda'),
    center=True
).to('cuda')

spec = librosa.db_to_amplitude(dbMatrix)
# 增加batch维度
spec_tensor = torch.tensor(spec).unsqueeze(0).to('cuda')
re_wav = griffinlim(spec_tensor)
# 移除batch维度并绘图
plt.plot(re_wav.squeeze(0).cpu().detach().numpy())

内容的提问来源于stack exchange,提问作者Mingxin Zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:38:22