【Bug已解决】[Web] DB-style detection model returns all-zero output on Apple M-series above ~2048px inpu…
【Bug已解决】[Web] DB-style detection model returns all-zero output on Apple M-series above ~2048px input - likely fp16 overflow in ReduceMean 解决方案一、现象长什么样一个 DB 风格Differentiable Binarization文字检测的 ORT 模型在 Apple M 系列芯片上通过 WebGPU / CoreML EP 跑推理。输入图片小的时候比如 1024x1024输出正常但一旦边长超过约 2048px输出整体变成全零概率图、阈值图全 0检测彻底失效// Web 端ONNX Runtime Web加载 const session await ort.InferenceSession.create(db_detect.onnx, { executionProviders: [webgpu], // Apple M 系列走 Metal }); const out await session.run(feed); // input 2048x2048 - out 全 0input 1024x1024 - 正常最小复现信号输入边长 2048px : 输出正常有非零概率 输入边长 2048px : 输出全 0 阈值恰好在 2048 附近像“数值溢出后归零”注意模型能跑、不报错只是大图时数值溢出导致结果归零。这不是逻辑错是数值精度问题。二、背景DB 检测模型的头部有一个概率图生成步骤对特征图做ReduceMean或ReduceSum/Softmax前的求和把通道维聚合成单通道概率。整个过程在 Apple M 系列上走的是 fp16半精度路径 - WebGPU/Metal 的f16是原生类型ORT 在 Apple 上为了性能默认用 fp16 执行。fp16 的表示范围大约是 /-65504相对精度约 3 位十进制。问题在于ReduceMean的实现如果它在 fp16 下逐个元素累加再除以个数大图2048x2048 的特征图像素数约 4M累加时部分和会远超 65504 然后上溢成 infinf 参与后续Sigmoid/exp运算变成 nan / 0最终概率图被钳到 0表现为全零输出。而 1024x1024约 1M 像素时累加和还没超 65504所以正常。阈值约 2048px 恰好对应累加和突破 fp16 上限的临界点。这就是 “likely fp16 overflow in ReduceMean”。三、根因根因是 Apple M 系列 fp16 路径下的ReduceMean用 fp16 累加大图特征部分和溢出 fp16 上限/-65504变成 inf/nan 后结果归零fp16 累加溢出ReduceMean在 fp16 精度下逐元素求和特征图元素多2048 的平方量级时部分和轻松破 65504直接 inf。溢出传染inf 进Sigmoid/exp变成 nan 或 0再经Clip/Cast被钳成 0输出全零。只在 Applefp16 原生明显x86 上 ORT 可能用 fp32 跑、或 Metal 的 fp16 累加更易触发CPU fp32 路径完全不受影响所以小图正常、大图归零、只在 M 系列。不是模型结构错同样的 ONNX 在 CPU fp32 上大图也正常说明是 EP 的数值实现问题。所以这不是逻辑错而是 fp16 归约缺乏数值稳定性没用 fp32 累加器 / Kahan 补偿大图溢出归零。四、最小可运行复现下面用 NumPy 模拟 “fp16 ReduceMean 大图溢出归零”用float16累加复现import numpy as np def reduce_mean_fp16_naive(x): 有 bug 的实现在 fp16 下逐元素累加Apple M 的 fp16 路径。 acc np.float16(0.0) for v in x.flatten(): acc acc np.float16(v) # fp16 累加大数组溢出 return float(acc) / x.size def reduce_mean_fp32(x): 正确实现用 fp32 累加最后再转回。 return float(np.mean(x.astype(np.float32))) if __name__ __main__: # 模拟 2048x2048 特征图元素均值约 1.0如激活值 big np.ones(2048 * 2048, dtypenp.float32) naive reduce_mean_fp16_naive(big) correct reduce_mean_fp32(big) print(fp16 朴素累加:, naive, inf/nan 即为溢出) print(fp32 累加 :, correct) # 朴素 fp16 累加 4M 个 1.0 - 远超 65504 - inf assert (not np.isfinite(naive)) or naive ! correct print(复现大图 fp16 累加溢出 - 归约结果 inf - 输出归零)跑出来朴素 fp16 累加得到inf或不稳定值fp32 得到正确的1.0。这正好复现大图 fp16 ReduceMean 溢出归零的机制。五、解决方案第一层最小直接修复最小修复让ReduceMean及相关归约在 fp16 路径下用 fp32 累加器或干脆对这个模型用 fp32 执行。Web 侧可以这样// 方案 A对归约相关节点强制 fp32若 ORT Web 暴露该选项 const session await ort.InferenceSession.create(db_detect.onnx, { executionProviders: [{ name: webgpu }], graphOptimizationLevel: all, }); // 或在导出时把 ReduceMean 之后的头部数据类型固定为 fp32 // 方案 B导出时把特征图头部的 ReduceMean 输入限制在 fp32 精度 // 用 onnx 修改工具把对应节点的 dtype 标成 fp32对 ORT 仓库侧修复是改 Apple/Metal 的ReduceMean内核归约累加用 fp32或float2双缓冲做部分和最后再转 fp16 输出。这一层立刻让大图输出正常。六、解决方案第二层结构性改进把 “哪些算子在 fp16 路径下必须用 fp32 累加” 收口成唯一的配置对象OrtWebReduceMeanFp16PolicyWeb 加载与内核选择读它from dataclasses import dataclass, field from typing import Tuple dataclass(frozenTrue) class OrtWebReduceMeanFp16Policy: Apple M 系列 fp16 归约数值稳定的单一事实来源。 # 必须在 fp16 路径下用 fp32 累加的算子 fp32_accum_ops: Tuple[str, ...] (ReduceMean, ReduceSum, ReduceL2, Softmax) # 触发 fp32 累加的“大图阈值”特征图元素数超过此值必用 fp32 累加 overflow_pixel_threshold: int 2048 * 2048 # 是否全局强制这些算子 fp32 执行最稳略慢 force_fp32_for_these_ops: bool False # 平台限定Apple M 系列 Metal fp16 原生易溢出 affected_platforms: Tuple[str, ...] (apple, m-series, metal, webgpu) def needs_fp32_accum(self, op_type: str, num_pixels: int) - bool: if op_type not in self.fp32_accum_ops: return False if self.force_fp32_for_these_ops: return True return num_pixels self.overflow_pixel_threshold def describe(self) - str: return 大图 ReduceMean 等在 fp16 路径用 fp32 累加防溢出归零 POLICY OrtWebReduceMeanFp16Policy() def plan_reduce(op_type: str, num_pixels: int, policy: OrtWebReduceMeanFp16Policy POLICY) - str: return fp32_accum if policy.needs_fp32_accum(op_type, num_pixels) else fp16所有 Web 加载与内核选择读同一份POLICY大图归约自动用 fp32 累加避免溢出。七、解决方案第三层断言 / CI 守护把 “大图 ReduceMean 不溢出、数值稳定” 做成断言。下面用 pytest 风格守护复用第四节逻辑import numpy as np def test_large_image_mean_finite(): big np.ones(2048 * 2048, dtypenp.float32) assert np.isfinite(reduce_mean_fp32(big)) assert abs(reduce_mean_fp32(big) - 1.0) 1e-3 def test_fp32_accum_for_large_reduce(policy): assert policy.needs_fp32_accum(ReduceMean, 2048 * 2048 1) is True assert policy.needs_fp32_accum(ReduceMean, 1024 * 1024) is False def test_affected_platform_covers_apple(policy): assert apple in policy.affected_platforms def test_reduce_ops_listed(policy): assert ReduceMean in policy.fp32_accum_ops这四组断言锁住(1) 大图均值有限且正确(2) 大图 ReduceMean 触发 fp32 累加、小图不触发(3) 平台覆盖 Apple(4) 归约算子已列入名单。CI 跑通即代表大图不会溢出归零。八、排查清单遇到 Apple M 系列上大图 DB 检测输出全零先换 EP / 精度验证用 CPU fp32 跑大图若正常 - 锁定 fp16 数值问题。看阈值是否在 2048px 附近是的话高度怀疑 fp16 累加溢出。查 ReduceMean 内核Apple/Metal 的 fp16 归约是不是用 fp16 累加应改 fp32 累加。临时规避对该模型强制 fp32 执行或导出时把归约头部标 fp32。根本修复改 Metal ReduceMean 内核用 fp32 部分和最后转 fp16。统一策略对象用OrtWebReduceMeanFp16Policy固化大图阈值与算子名单。CI 守护断言大图 ReduceMean 数值有限、触发 fp32 累加。九、小结[Web] DB-style detection model returns all-zero output on Apple M-series above ~2048px input - likely fp16 overflow in ReduceMean的根因是Apple M 系列 fp16 路径下的ReduceMean在 fp16 精度下逐元素累加大图特征部分和超过 fp16 上限 /-65504 后变成 inf/nan经 Sigmoid/exp 传染后概率图被钳成 0表现为大图2048px输出全零小图累加和未超上限所以正常CPU fp32 路径不受影响。最小修复是让 ReduceMean 在 fp16 路径用 fp32 累加器或对该模型强制 fp32结构性改进是用唯一的OrtWebReduceMeanFp16Policy固化“大图阈值 必须用 fp32 累加的算子名单”CI 用四组断言守护“大图均值有限、触发 fp32 累加、平台覆盖 Apple、算子已列入”。记住fp16 归约一定要用 fp32 累加器大图累加必溢出否则结果悄悄归零。

相关新闻

【Bug已解决】QMoE per-channel quantization produces garbage results on CUDA EP, correct on CPU EP 解决方案

【Bug已解决】QMoE per-channel quantization produces garbage results on CUDA EP, correct on CPU EP 解决方案

【Bug已解决】QMoE per-channel quantization produces garbage results on CUDA EP, correct on CPU EP 解决方案 一、现象长什么样 用 ONNX Runtime 的 QMoE(量化 MoE)跑一个做了 per-channel 量化 的专家权重模型。同一个 ONNX,CPUExecuti…

2026/10/14 0:18:41 阅读更多 →
3步搞定M3U8视频下载:告别命令行恐惧的图形化解决方案

3步搞定M3U8视频下载:告别命令行恐惧的图形化解决方案

3步搞定M3U8视频下载:告别命令行恐惧的图形化解决方案 【免费下载链接】N_m3u8DL-CLI-SimpleG N_m3u8DL-CLIs simple GUI 项目地址: https://gitcode.com/gh_mirrors/nm3/N_m3u8DL-CLI-SimpleG 你是否曾遇到心仪的网络视频却无法保存的困扰?&…

2026/10/7 23:24:52 阅读更多 →
Python键盘监听与自动化脚本:从pynput入门到热键管理器实战

Python键盘监听与自动化脚本:从pynput入门到热键管理器实战

1. 从一次重复性操作说起:为什么我们需要键盘监听如果你和我一样,每天的工作都离不开电脑,那你一定遇到过这样的场景:需要反复执行某个固定的操作序列,比如在某个软件里点击一连串的菜单项,或者在不同的窗口…

2026/10/7 20:42:38 阅读更多 →

最新新闻

pstack工作原理与四大失效场景深度解析

pstack工作原理与四大失效场景深度解析

1. 为什么一个看似简单的命令值得单独写一篇“完整指南”&#xff1f;很多人第一次听说pstack&#xff0c;是在某个深夜排查线上服务卡顿问题时&#xff0c;被同事甩来一句&#xff1a;“快用pstack <pid>看下线程栈&#xff0c;是不是死锁了&#xff1f;”——然后你照着…

2026/10/14 0:18:47 阅读更多 →
生物信息学聚类分析实战:TCGA-BRCA表达谱无监督聚类全流程

生物信息学聚类分析实战:TCGA-BRCA表达谱无监督聚类全流程

简介&#xff1a;这份资源面向生物信息学入门学习者与R语言数据分析实践者&#xff0c;围绕TCGA-BRCA乳腺癌基因表达数据展开聚类分析教学案例。内容涵盖利用层次聚类按基因表达水平对病人样本分型&#xff0c;采用average距离度量&#xff0c;并通过热图等图示呈现聚类效果&am…

2026/10/14 0:18:47 阅读更多 →
Elasticsearch去重查询实战:collapse、terms聚合与cardinality选型指南

Elasticsearch去重查询实战:collapse、terms聚合与cardinality选型指南

1. 去重查询到底在解决什么问题1.1 从一个真实场景说起做过搜索或者日志分析的人&#xff0c;大概率都遇到过这种需求&#xff1a;索引里存了几十万条订单记录&#xff0c;同一个用户下了多单&#xff0c;现在要拉一份“下过单的用户名单”&#xff0c;每个用户只出现一次。或者…

2026/10/14 0:18:47 阅读更多 →
Jackson序列化LocalDateTime:从数组乱码到全局配置的完整指南

Jackson序列化LocalDateTime:从数组乱码到全局配置的完整指南

1. 从一个接口报错说起&#xff1a;为什么LocalDateTime在JSON里变成了奇怪的样子第一次遇到这个问题&#xff0c;是在一个前后端联调的场景里。后端接口返回了一个包含时间字段的对象&#xff0c;前端同学截图过来问我&#xff1a;“你这个createTime怎么是一串数组&#xff1…

2026/10/14 0:18:47 阅读更多 →
环保科技网站开发:Vue+SpringBoot全栈实践

环保科技网站开发:Vue+SpringBoot全栈实践

1. 项目背景与选题价值环保科技公司网站的设计与实现这个选题&#xff0c;源于当前环保行业数字化转型的迫切需求。随着公众环保意识提升和政策法规趋严&#xff0c;环保科技企业需要通过专业化的线上平台展示技术实力、服务案例和行业解决方案。这类网站不同于普通企业官网&am…

2026/10/14 0:18:47 阅读更多 →
MATLAB实现配电网二阶锥松弛最优潮流计算

MATLAB实现配电网二阶锥松弛最优潮流计算

1. 项目背景与核心价值配电网最优潮流&#xff08;OPF&#xff09;问题是电力系统运行中的经典优化命题。传统交流最优潮流模型由于非凸非线性特性&#xff0c;求解难度大且难以保证全局最优性。二阶锥松弛&#xff08;Second-Order Cone Relaxation, SOCP&#xff09;技术通过…

2026/10/14 0:17:46 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起&#xff1a;它到底想解决什么问题第一次看到"AnyPS5"这个标题&#xff0c;我脑子里冒出来的第一个念头是&#xff1a;这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述&#xff1a;Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师&#xff0c;我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性&#xff0c;实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景&#xff0c;也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间&#xff0c;确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中&#xff0c;这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →