基于FastAPI+WebSocket的实时转录音频流处理问题排查
问题解决:实时WebSocket音频转写中torchaudio加载分片报错「Invalid Data Type」
问题核心
通过FastAPI WebSocket接口/stt/predict/live接收音频分片,调用audio_utils.audio_processing时触发「Invalid Data Type」的ValueError,但处理完整WAV文件的/predict接口可正常工作。
原因分析
torchaudio.load()是加载完整音频文件的API,它依赖WAV文件头里的采样率、位深、声道数等元数据才能解析音频。而实时WebSocket传输的音频分片通常是无文件头的原始PCM数据,或是截断的WAV片段(缺失完整文件头),导致torchaudio.load()无法识别数据格式,抛出错误。
解决方案
修改音频处理逻辑,直接解析原始PCM数据(需和客户端约定统一音频参数),不再依赖WAV文件头。
步骤1:约定客户端音频参数
要求客户端传输符合以下格式的原始PCM音频字节:
- 采样率:16000Hz(Whisper模型默认要求)
- 位深:16位(int16格式)
- 声道数:单声道
步骤2:修改audio_utils.audio_processing函数
替换原有的torchaudio.load()逻辑,直接将PCM字节转换为Whisper所需的张量:
import torch import numpy as np # 保持和Whisper一致的采样率 SAMPLE_RATE = 16000 def audio_processing(audio: bytes): """ 处理原始PCM音频字节(16位单声道、16kHz采样率),转换为模型可用的张量。 参数: audio (bytes): 符合约定格式的原始PCM音频字节 抛出异常: ValueError: 音频数据格式不符合要求时触发 返回值: torch.Tensor: 形状为(1, N)的单声道音频波形张量 """ try: # 将16位PCM字节转为numpy数组 pcm_data = np.frombuffer(audio, dtype=np.int16) # 归一化到[-1.0, 1.0]的浮点范围 waveform = pcm_data.astype(np.float32) / 32768.0 # 转换为torch张量并添加声道维度(模型期望单声道输入) waveform = torch.from_numpy(waveform).unsqueeze(0) except Exception as e: raise ValueError(f"failed to process PCM audio: {e}") return waveform
步骤3:调整WebSocket缓冲逻辑(可选优化)
原有的缓冲逻辑可保留,但需确保客户端发送的分片大小合理(比如每20ms发送一次,对应16kHz采样率下的640字节),避免缓冲过大或过小影响实时性。
补充说明
- 原
/predict接口正常的原因:它接收的是完整WAV文件,包含完整的文件头元数据,torchaudio.load()可以正确解析。 - 如果客户端无法修改为发送PCM数据,另一种方案是让客户端在第一次连接时发送完整的WAV文件头,后续只发送PCM数据,服务端将头和每次的分片拼接后再用
torchaudio.load()加载,但这种方式效率低于直接处理PCM。
内容的提问来源于stack exchange,提问作者Imisioluwa
相关产品推荐
相关产品推荐

