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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:12:03