如何将AudioSegment转换的numpy数组作为Whisper模型音频输入?
问题:使用AudioSegment转换音频为numpy数组后传入Whisper的异常问题
初始问题:内存溢出错误
尝试用AudioSegment加载MP3并转为numpy数组传入Whisper时,触发内存溢出错误,但直接传入文件路径则正常运行。错误信息如下:
RuntimeError: [enforce fail at ..\c10\core\impl\alloc_cpu.cpp:72] data. DefaultCPUAllocator: not enough memory: you tried to allocate 86261939712 bytes.
初始代码:
from pydub import AudioSegment import numpy as np import whisper import torch audio = AudioSegment.from_mp3("../audio_test_files/1001_IEO_DIS_HI.mp3") dtype = getattr(np, "int{:d}".format( audio.sample_width * 8)) # Or could create a mapping: {1: np.int8, 2: np.int16, 4: np.int32, 8: np.int64} arr = np.ndarray((int(audio.frame_count()), audio.channels), buffer=audio.raw_data, dtype=dtype) arr_copy = arr.copy() device = "cuda" if torch.cuda.is_available() else "cpu" print(f"Loading whisper...") audio_model = whisper.load_model("small", download_root="../models", device=device) print(f"Transcribing...") result = audio_model.transcribe(audio=arr_copy, language="en", word_timestamps=True, fp16=torch.cuda.is_available()) # , initial_prompt=result.get('text', "")) text = result['text'].strip() print(text)
更新后问题:音频噪音过大导致转录失效
修改代码后内存错误解决,但导出传入模型的音频有大量噪音,转录完全失效,怀疑归一化步骤有误。修改后代码:
from pydub import AudioSegment import numpy as np import whisper import torch language = "en" model = "medium" model_path = "../models" device = "cuda" if torch.cuda.is_available() else "cpu" print(f"Loading whisper {model} model {language}...") audio_model = whisper.load_model(model, download_root=model_path, device=device) # load wav file with pydub audio_path = "20230611-004146_audio_chunk.wav" audio_segment = AudioSegment.from_wav(audio_path) #audio_segment = audio_segment.low_pass_filter(1000) # get sample rate sample_rate = audio_segment.frame_rate arr = np.array(audio_segment.get_array_of_samples()) arr_copy = arr.copy() arr_copy = torch.from_numpy(arr_copy) arr_copy = arr_copy.to(torch.float32) # normalize arr_copy = arr_copy / 32768.0 # to device arr_copy = arr_copy.to(device) print(f"Transcribing...") result = audio_model.transcribe(arr_copy, language=language, fp16=torch.cuda.is_available()) text = result['text'].strip() print(text) waveform = arr_copy.cpu().numpy() audio_segment = AudioSegment( waveform.tobytes(), frame_rate=sample_rate, sample_width=waveform.dtype.itemsize, channels=1 ) audio_segment.export("test.wav", format="wav")
解决方案
错误根源分析
Whisper的transcribe函数对输入音频有严格要求:必须是单通道、16000Hz采样率、一维浮点数组(范围[-1.0,1.0])。之前的代码违反了这些要求:
- 初始代码生成二维数组(帧×通道数),Whisper误将通道数识别为采样维度,导致内存爆炸。
- 更新后的代码未处理多通道音频(立体声会生成交错采样数组,直接转一维会导致音频错乱),也未统一采样率到16000Hz,导出时还错误地用浮点数组直接转字节流,导致音频损坏。
正确转换代码
from pydub import AudioSegment import numpy as np import whisper import torch # 1. 音频预处理:转单通道、统一采样率为16000Hz audio_path = "../audio_test_files/1001_IEO_DIS_HI.mp3" audio_segment = AudioSegment.from_mp3(audio_path) audio_segment = audio_segment.set_channels(1) # 强制转单通道 audio_segment = audio_segment.set_frame_rate(16000) # 统一采样率 # 2. 转换为Whisper兼容格式 # 获取int16格式的一维采样数组 arr_int16 = np.array(audio_segment.get_array_of_samples(), dtype=np.int16) # 归一化到[-1.0,1.0]的浮点数组 arr_float = arr_int16.astype(np.float32) / 32768.0 # 3. 加载模型并转录 device = "cuda" if torch.cuda.is_available() else "cpu" audio_model = whisper.load_model("small", download_root="../models", device=device) result = audio_model.transcribe(audio=arr_float, language="en", word_timestamps=True, fp16=torch.cuda.is_available()) print(result['text'].strip()) # 4. (可选)正确导出验证音频 # 将浮点数组转回int16格式再导出 export_arr = (arr_float * 32768.0).astype(np.int16) export_audio = AudioSegment( export_arr.tobytes(), frame_rate=16000, sample_width=2, # int16对应2字节采样宽度 channels=1 ) export_audio.export("validated_audio.wav", format="wav")
核心注意事项
- 必须将音频转为单通道,Whisper不支持多通道输入。
- 必须统一采样率到16000Hz,这是模型训练的标准采样率。
- 输入数组必须是一维浮点型,范围控制在[-1.0,1.0]。
- 导出验证音频时,要先将浮点数组转回int16格式,再传入AudioSegment。
内容的提问来源于stack exchange,提问作者JayJona
相关产品推荐
相关产品推荐

