快速结论:使用 gr.Audio(麦克风)或 gr.Image(摄像头)的 .stream() 流式输入时,用户点击 Stop 后助手会再用最后一个 chunk 多执行一次,导致 Stopping a `.stream()` input runs the handler once more on the last chunk;优先排查停止流程是否触发了重复的流式回调。
适用环境:Issue 已确认 Gradio 6.30.0(main 分支 de986c723 同样存在),Linux,Chromium(无头模式下用假麦克风复现)。
最快修复方案:暂无确认的一步修复方案。Issue 关闭时未记录已验证的修复提交或配置项。
注意事项:下面“解决步骤”中的处理方式是围绕该行为的规避思路,并非 Issue 验证过的官方修复;升级 Gradio 前请先确认目标版本是否已处理 #13982。
问题场景
在 Gradio Blocks 应用中使用流式输入组件(gr.Audio(sources=["microphone"], type="numpy", streaming=True),摄像头 gr.Image 的流式模式同理),通过 mic.stream(handler, mic, out, stream_every=0.5) 为每个 chunk 调用一次处理函数。录制约 3 秒后点击 Stop,处理函数会额外执行一次,收到的正是上一个已处理过的 chunk。
在复现脚本中,浏览器共发送 5 个 chunk 后发送 close 请求,处理函数却执行了 6 次。第 6 次在 close 请求后约 1 ms 发生,音频数据的 md5 与第 5 次完全相同。页面显示的是第 5 次调用的输出,但运行历史保存的却是第 6 次。
报错原文
Stopping a `.stream()` input runs the handler once more on the last chunk
call 1 t=1792134495.795 md5=4f2072d545
call 2 t=1792134496.299 md5=4efad0ff28
call 3 t=1792134496.808 md5=f5ef03f913
call 4 t=1792134497.329 md5=c551e98624
call 5 t=1792134497.872 md5=d84fd7095c
call 6 t=1792134498.278 md5=d84fd7095c
The page shows "call 5: md5 d84fd7095c".
原因分析
根据 Issue 讨论,问题出在流式输入的停止流程:close 请求到达后,服务端仍针对最后一个 chunk 再触发一次处理函数,而不是只结束流。这不是用户代码重复调用导致的。
评论中补充了另一个现象:当处理函数是 generator,且 Stop 在第二个 chunk 到来之前触发时,这次多余调用会在同一 event id 下继续同一个 generator,其下一次 yield 以 diff 形式(例如 [["append", [], "x"]])被发送。由于客户端对流事件跳过 apply_diff_stream,process_completed 消息把这段原始 diff 当作输出数据,浏览器运行历史于是保存了 diff 而不是完整输出。#13979 在服务端通过保存上一次完整输出来规避该现象,但根本解决方式是停止时不再重跑处理函数。
可能受影响的场景:处理函数含写入数据库、追加 gr.State、模型推理或 GPU / ZeroGPU 耗时操作时,这些副作用会执行两次;实时转写等累积型处理会把最后一个 chunk 加两遍。
环境排查
- 确认 Gradio 版本是否为 6.30.0 或包含该问题的 main 分支提交;升级前后分别复现一次。
- 确认触发组件是流式
gr.Audio麦克风或流式gr.Image摄像头。 - 确认
.stream()的stream_every设置,并与浏览器实际发送的 chunk 数对比。 - 检查处理函数是否包含副作用(数据库写入、
gr.State追加、推理、GPU 调用)或是 generator。 - 在浏览器端查看运行历史保存的输出是否与页面显示不一致。
解决步骤
- 先在服务端日志中打印每次调用的时间戳和 chunk 哈希,确认 close 请求之后是否还有一次调用,并比对它与上一次 chunk 的哈希是否相同。Issue 中的日志已给出这种确认方式。
- 若日志确认最后一次调用的 chunk 与上一次完全相同,说明命中本 Issue,而非业务代码重复订阅。
- 可优先尝试:在处理函数中对最后一个 chunk 做幂等判断,例如记录上一次 chunk 的哈希或序号,遇到相同 chunk 直接返回上一次结果,避免副作用重复执行。
- 可优先尝试:将数据库写入、
gr.State追加、模型推理等副作用移出流式处理函数,或改为按累积结果去重后落库。 - 若使用 generator 形式的处理函数,注意 Stop 前只收到一个 chunk 时可能出现 diff 被当作输出的情况;可优先尝试在客户端或运行历史展示层保存上一次完整输出,#13979 就是按这个思路在服务端处理的。
- 关注 gradio-app/gradio 后续版本或 #13982、#13979 的修复进展,升级后重新用精简复现脚本验证。
验证方法
用 Issue 中的复现脚本录制约 3 秒并点击 Stop,对比服务端日志中的调用次数与浏览器发送的 chunk 数:若 close 请求后不再出现与最后一个 chunk 哈希相同的额外调用,即说明问题已消除。同时检查页面显示输出与运行历史保存的输出是否一致。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[bug]: Crashing Krea2 checkpoints after recent update (Anything but the smallest Q8_0 GGUF crashes, Even standard checkpoints)](https://www.chat-gpts.plus/wp-content/uploads/2026/10/9585-377c244f-768x403.jpg)
![[Bug]: Upgrade path missing column `tenant.tenant_ocr_id` - all tenant DB queries silently fail as "Tenant not found"](https://www.chat-gpts.plus/wp-content/uploads/2026/10/18754-1fe5f807-768x403.jpg)
