快速结论:该报错发生在 Transformers 的自动语音识别(ASR)pipeline 处理双声道(stereo)音频时。若音频由 soundfile 或 librosa 加载(形状为 samples × channels),pipeline 内部用 mean(axis=0) 降混音会错误地按时间轴求均值,导致数万采样被压缩成 2 个数、语音内容几乎全部丢失。优先排查你传给 pipeline 的音频数组形状是 (samples, channels) 还是 (channels, samples)。
适用环境:Transformers 5.7.0、PyTorch 2.11.0、NumPy 1.26.4、soundfile 0.13.1、Python 3.12、macOS、CPU(仅 CPU 推理)。使用 pipeline("automatic-speech-recognition") 且输入为 2D 数组时触发。
最快修复方案:暂无确认的一步修复方案。可优先尝试在传入 pipeline 前手动将音频转为单声道(例如对 channels 轴求均值),或显式把数组形状调整为 (channels, samples) 再传入。也可直接拒绝双声道输入,改用单声道数组。
注意事项:该问题在 Issue 发布时尚未修复,上游是否已合入补丁未在讨论中确认;以下“解决步骤”中的轴推断代码来自 Issue 作者的提议,仅作为临时规避手段,未经官方验证,使用前请自行测试。
问题场景
使用 transformers 库的 AutomaticSpeechRecognitionPipeline(例如 Whisper 模型)时,用户主动传入双声道(stereo)音频数据。音频由 soundfile.read() 或 librosa.load(..., mono=False) 加载,得到形状为 (samples, channels) 的 2D NumPy 数组。pipeline 将其误判为 (channels, samples),在降混音时沿 axis=0(时间轴)求均值,导致 3 秒的音频(48000 个采样点)被压缩成 2 个数值,后续补零成 30 秒静音,最终只识别出 ' you' 这类几乎无意义的文本。
报错原文
soundfile.read shape : (48000, 2)
UserWarning: We expect a single channel audio input for AutomaticSpeechRecognitionPipeline,
got 2. Taking the mean of the channels for mono conversion.
mono : ' See you in the next video!'
stereo : ' you'
after pipeline's mean(axis=0): (2,)
原因分析
可能原因:pipeline 源码(pipelines/automatic_speech_recognition.py,约 422 行)在将多声道输入转为单声道时,硬编码 inputs.mean(axis=0),即假设输入是常见的 channels-first 布局 (channels, samples)。但 soundfile、librosa 等主流音频库返回的是 channels-last 布局 (samples, channels)。对 (48000, 2) 形状执行 mean(axis=0),实际是对 48000 个时间点求平均,得到 (2,),音频内容全部丢失。此外,警告信息中使用了 inputs.ndim(维度数)而非实际声道数,导致任何 2D 输入都提示“got 2”,且不会提示真正有用的形状信息。Issue 作者还指出:同一库内其他音频 pipeline(如音频分类)对 2D 输入会直接抛出 ValueError,而 ASR pipeline 却无声损坏数据,行为不一致。
环境排查
- 确认 Transformers 版本(Issue 中为 5.7.0,请对比你当前的版本是否已修复)。
- 确认音频加载方式:
soundfile.read、librosa.load(..., mono=False)、scipy.io.wavfile.read均返回 channels-last 布局。 - 确认输入给
asr()的数组形状:打印audio.shape,若第二维小于 10 而第一维为数千以上,则基本可判定为 channels-last 布局。 - 确认 PyTorch、NumPy 版本(Issue 中分别为 2.11.0、1.26.4),避免其他版本差异干扰。
解决步骤
- 临时规避:在传入 pipeline 前,手动判断数组形状并转为单声道。例如:
if audio.ndim == 2 and audio.shape[0] > audio.shape[1]:
audio = audio.mean(axis=1) # 沿着 channels 轴求均值
else:
audio = audio.mean(axis=0) - 或者:显式将数组转换为
(channels, samples)布局(转置)后再传入 pipeline,使源码中的mean(axis=0)按预期工作。 - 更稳妥的做法:在调用 pipeline 前统一用
soundfile.read(..., always_2d=False)或librosa.load(..., mono=True)加载为单声道,彻底避免 2D 输入。 - 如果你愿意修改源码,可参考 Issue 作者提议的补丁:将声道轴推断为形状中较小的维度(
ch_axis = int(np.argmin(inputs.shape))),并在警告信息中输出实际形状。该补丁未经官方合并,仅供本地测试。 - 若你的应用对多声道没有硬性需求,建议在调用 ASR pipeline 前主动拒绝 2D 输入并抛出明确错误,以免静默产生错误转录结果。
验证方法
用同一段语音分别生成单声道和双声道数组,分别调用 ASR pipeline,对比转录文本。若两者输出一致(例如均输出 “See you in the next video!”),说明问题已规避。另一验证方式:在传入 pipeline 前打印 audio.shape,确保它是 (channels, samples) 或一维数组,且降混音后采样点数保持不变。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


![[Bug]: Structured-output scheduler can keep advancing a terminated xgrammar matcher](https://www.chat-gpts.plus/wp-content/uploads/2026/08/42619-81e0022e-768x403.jpg)