如何将音频文件字节流转换为np.ndarray适配OpenAI Whisper
解决Whisper转录时字节流转np.ndarray的问题
问题核心:你直接把音频文件的字节流当成原始浮点PCM数据转成numpy数组是错误的,因为上传的音频是编码后的格式(比如MP3、WAV),需要先解码成Whisper要求的单声道、16kHz采样率的浮点PCM数据。
正确解决方案:用Whisper自带工具处理字节流
Whisper提供了whisper.load_audio函数,它可以直接处理类文件对象,自动完成解码、采样率转换等操作,输出符合要求的np.ndarray。
修正后的代码
import numpy as np import whisper from typing import Annotated from fastapi import FastAPI, File import io # 用于将字节流转为类文件对象 app = FastAPI() @app.post("/abcd") async def transcribe_audio(audio_file_upload: Annotated[bytes, File()]): # 把字节流包装成类文件对象 audio_file = io.BytesIO(audio_file_upload) # 用Whisper的load_audio处理,自动解码并转换成符合要求的np.ndarray audio_data = whisper.load_audio(audio_file) model = whisper.load_model("base") # 注意:如果你的GPU不支持fp16(比如CPU环境),把fp16设为False result = model.transcribe(audio_data, word_timestamps=True, fp16=False) return {"transcription": result}
为什么之前的方法失败?
np.frombuffer(audio_file_upload, dtype=np.float32)是把字节直接解析成浮点数组,但音频文件的字节是编码后的压缩数据(比如MP3的帧结构、WAV的文件头+PCM数据),不是原始的浮点PCM值,所以得到的数组全是无效的nan,导致Whisper模型报错。
备选方案:用soundfile手动解码
如果不想用Whisper的load_audio,也可以用soundfile库处理:
- 先安装依赖:
pip install soundfile librosa - 代码示例:
import soundfile as sf import librosa # 同样先把字节流转为类文件对象 audio_file = io.BytesIO(audio_file_upload) # 读取音频,自动解码 audio_data, sample_rate = sf.read(audio_file) # 如果是多声道(比如立体声),转成单声道 if audio_data.ndim > 1: audio_data = np.mean(audio_data, axis=1) # 确保采样率是16kHz(Whisper要求) if sample_rate != 16000: audio_data = librosa.resample(audio_data, orig_sr=sample_rate, target_sr=16000)
这个方案需要额外安装依赖,不如直接用Whisper自带的load_audio简洁。
内容的提问来源于stack exchange,提问作者Shivansh Yadav
相关产品推荐
相关产品推荐

