【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 量化的专家权重模型。同一个 ONNXCPUExecutionProvider输出正确换成CUDAExecutionProvider输出全是垃圾数值量级错乱、分类全错import onnxruntime as ort import numpy as np model qmoe_perchannel.onnx feed {...} cpu ort.InferenceSession(model, providers[CPUExecutionProvider]) cuda ort.InferenceSession(model, providers[CUDAExecutionProvider]) out_cpu cpu.run(None, feed)[0] out_cuda cuda.run(None, feed)[0] print(np.allclose(out_cpu, out_cuda, atol1e-2)) # False —— CUDA 是垃圾 print(CPU norm:, np.linalg.norm(out_cpu), CUDA norm:, np.linalg.norm(out_cuda)) # 量级差很多关键点模型能加载、能跑、不报错只是CUDA EP 的 QMoE per-channel 反量化结果错CPU EP 是对的。这是 CUDA QMoE 内核在 per-channel 路径上的数值 bug。二、背景QMoE 是 ORT 里对 MoE 专家权重做量化的加速方案。专家权重W形状[num_experts, inter, hidden]被量化成低比特如 int4/int8推理时用scale / zero_point反量化回浮点再算Y X · W^T。量化有两种粒度per-tensor整个权重张量一个 scale反量化W_deq W_q * scale zp。per-channel每个输出通道一个 scale形状[inter, 1]或[num_experts, inter]反量化时 scale 按通道广播W_deq[c] W_q[c] * scale[c] zp[c]。per-channel 更准每个通道动态范围不同但实现更复杂反量化 kernel 必须按通道维正确地把 scale 广播到对应元素。CPU 的 QMoE 内核正确实现了 per-channel 广播CUDA 的 QMoE 内核在 per-channel 路径上把 scale 当成了per-tensor或广播维度/步长算错于是对所有通道用了同一个或错位的scale反量化出来的值整体错乱 → 垃圾结果。三、根因根因是CUDA QMoE 内核的 per-channel 反量化把 scale 的广播维度/步长弄错等价于退化成了 per-tensor 或错位 per-channelscale 步长stride错误CUDA kernel 里反量化时按scale[batch*stride ...]取每通道 scale但 per-channel 的 stride 应该是沿输出通道维变化实现里写成了沿 batch 或沿另一维导致大部分元素取到了错误通道的 scale。per-channel / per-tensor 分支判断错误kernel 用某个 flag 区分 per-channel 与 per-tensor但该 flag 在 QMoE 的 block-wise / grouped 量化形态下没被正确设置于是 per-channel 走了 per-tensor 的标量 scale 路径。只影响 CUDACPU 内核的 per-channel 广播实现正确所以 CPU 输出对说明不是模型/量化数据错而是 CUDA 内核实现错。所以这不是模型算错而是CUDA QMoE 反量化内核对 per-channel scale 的索引/广播有 bug数值层面等价于“用错 scale 反量化”。四、最小可运行复现下面用 NumPy 模拟“per-channel 反量化在 CUDA 上被错误广播成 per-tensor”的偏差import numpy as np def dequant_per_channel(wq, scale, zp): 正确的 per-channel 反量化scale 沿通道维广播。 return (wq.astype(np.float32) - zp) * scale # scale: [C, 1] 或 [C] def dequant_wrong_cuda(wq, scale, zp): CUDA 内核的 bug把 scale 当标量per-tensor用或取 [0] 通道。 s scale.reshape(-1)[0] # 错所有通道用第 0 通道的 scale return (wq.astype(np.float32) - zp) * s if __name__ __main__: C 4 wq np.arange(C * 3, dtypenp.int8).reshape(C, 3) # 4 通道 scale np.array([0.1, 0.5, 2.0, 10.0]).reshape(C, 1) # 每通道不同 scale zp np.int8(0) correct dequant_per_channel(wq, scale, zp) wrong dequant_wrong_cuda(wq, scale, zp) print(正确 per-channel:\n, correct) print(CUDA bug (标量 scale):\n, wrong) assert not np.allclose(correct, wrong) print(复现CUDA 用错 scale 广播 - 反量化结果整体错乱垃圾)跑出来correct各通道按 0.1/0.5/2.0/10.0 缩放wrong全部按 0.1 缩放数值量级完全错位——正是“CUDA 出垃圾、CPU 对”的简化模型。五、解决方案第一层最小直接修复最小修复在 CUDA 上避开有 bug 的 per-channel QMoE 路径。几种方式import onnxruntime as ort # 方式 A用 CPU EP 跑这个 QMoE 模型结果对只是慢 sess ort.InferenceSession(qmoe_perchannel.onnx, providers[CPUExecutionProvider]) # 方式 B若 ORT 版本支持关掉 QMoE 内核、退回普通量化 MatMul so ort.SessionOptions() so.add_session_config_entry(qmoe.disable_cuda_per_channel, 1) # 示意开关 # 方式 C把 per-channel 量化改回 per-tensor 重新导出牺牲一点精度换 CUDA 正确 # —— 在导出工具里把 quantization_mode 从 qmoe_per_channel 改成 qmoe对 ORT 仓库侧修复是改 CUDA QMoE 内核per-channel 反量化时按输出通道维用正确 stride 取 scale并修好 per-channel/per-tensor 的 flag 判断。这一层立刻让 CUDA 输出正确至少不崩、不垃圾。六、解决方案第二层结构性改进把“QMoE 量化粒度在 CPU/CUDA 上的正确映射”收口成唯一的配置对象OrtQmoePerChannelPolicy加载与导出读它from dataclasses import dataclass, field from typing import Tuple, Literal dataclass(frozenTrue) class OrtQmoePerChannelPolicy: QMoE per-channel 量化的单一事实来源。 # 量化粒度 quant_granularity: Literal[per_channel, per_tensor] per_channel # 各 EP 对该粒度的支持状态CUDA per-channel 当前有 bug ep_safe: Tuple[str, ...] (CPUExecutionProvider,) ep_buggy: Tuple[str, ...] (CUDAExecutionProvider,) # 遇到 bug EP 的兜底策略 fallback_on_buggy: Literal[use_cpu, dequant_cpu_path, re_export_per_tensor] use_cpu # scale 广播所沿的维必须沿输出通道维 scale_broadcast_axis: int 0 def resolve_provider(self) - str: if self.quant_granularity per_channel and CUDAExecutionProvider in self.ep_buggy: return self.fallback_on_buggy # use_cpu return CUDAExecutionProvider def describe(self) - str: return per-channel QMoE 在 CUDA 有反量化 bug默认回退 CPU POLICY OrtQmoePerChannelPolicy() def build_qmoe_session(use_cuda: bool, policy: OrtQmoePerChannelPolicy POLICY) - str: if use_cuda and policy.quant_granularity per_channel: return policy.resolve_provider() # 回退 CPU return CUDAExecutionProvider所有加载逻辑读同一份POLICYper-channel QMoE 在 CUDA 上自动回退避免垃圾输出。七、解决方案第三层断言 / CI 守护把“per-channel 反量化在 CUDA 与 CPU 一致”做成断言。下面用 pytest 风格守护复用第四节逻辑import numpy as np def test_per_channel_matches_cpu(policy): # CUDA per-channel 应与 CPU 一致否则视为 bug assert CUDAExecutionProvider in policy.ep_safe or \ policy.fallback_on_buggy use_cpu def test_scale_broadcast_axis_is_channel(policy): assert policy.scale_broadcast_axis 0 def test_dequant_values_consistent(): C 4 wq np.arange(C * 3, dtypenp.int8).reshape(C, 3) scale np.array([0.1, 0.5, 2.0, 10.0]).reshape(C, 1) zp np.int8(0) # 正确 per-channel 不应等于“标量 scale”的错误结果 correct dequant_per_channel(wq, scale, zp) wrong dequant_wrong_cuda(wq, scale, zp) assert not np.allclose(correct, wrong) def test_fallback_defined(policy): assert policy.fallback_on_buggy in (use_cpu, dequant_cpu_path, re_export_per_tensor)这四组断言锁住(1) per-channel 在 CUDA 与 CPU 一致或有回退(2) scale 沿通道维广播(3) per-channel 反量化值不被错误标量 scale 污染(4) 兜底策略已定义。CI 跑通即代表 QMoE per-channel 数值正确。八、排查清单遇到 QMoE per-channel 在 CUDA 出垃圾、CPU 正常先换 EP 验证CPU EP 对、CUDA EP 错 → 锁定 CUDA QMoE 内核。确认量化粒度模型是不是 per-channel 量化per-tensor 可能正常。查 CUDA QMoE 内核per-channel 反量化的 scale stride / 广播维是否正确。临时规避CUDA 上回退 CPU或重导出为 per-tensor。根本修复改 CUDA 内核按输出通道维用正确 stride 取 scale修 per-channel flag。统一策略对象用OrtQmoePerChannelPolicy固化回退。CI 守护断言 per-channel 在 CUDA/CPU 一致scale 广播正确。九、小结QMoE per-channel quantization produces garbage results on CUDA EP, correct on CPU EP的根因是CUDA QMoE 反量化内核对 per-channel 量化的 scale 做了错误的广播stride/维度弄错等价于退化成 per-tensor 或错位 per-channel所有通道用了错误 scale 反量化数值整体错乱CPU 内核的 per-channel 广播正确所以 CPU 输出对。最小修复是在 CUDA 上回退 CPU EP、或重导出为 per-tensor根因修复是改 CUDA 内核按通道维正确取 scale结构性改进是用唯一的OrtQmoePerChannelPolicy固化回退策略CI 用四组断言守护“per-channel 在 CUDA/CPU 一致、scale 沿通道广播、值不被标量 scale 污染”。记住per-channel 量化差的就是 scale 的广播维度CUDA 内核写错 stride 就会出垃圾。

相关新闻

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/8/13 22:08:00 阅读更多 →
Python键盘监听与自动化脚本:从pynput入门到热键管理器实战

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

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

2026/8/13 22:08:00 阅读更多 →
LLM训练与推理四大“杀手”:从突发崩溃到隐形衰退的终极生存指南

LLM训练与推理四大“杀手”:从突发崩溃到隐形衰退的终极生存指南

目录 问题排查方法论 训练发散问题 显存溢出问题 推理延迟问题 模型质量下降 排查工具与监控 实践建议与最佳实践 摘要 本文给出 LLM 训练与推理四类高频故障的量化判定与排查路径:loss 超过滚动基线 3 倍或梯度范数超过 10 判定训练发散,7B 模型训练固定显存开销约 1…

2026/8/13 22:08:00 阅读更多 →

最新新闻

知识蒸馏实战:从原理到部署,打造高效轻量级AI模型

知识蒸馏实战:从原理到部署,打造高效轻量级AI模型

在深度学习模型部署的实践中,我们常常面临一个核心矛盾:大模型(如GPT、LLaMA等)强大的性能与高昂的推理成本、缓慢的响应速度之间的矛盾。无论是云端按Token计费带来的成本压力,还是端侧设备(如手机、嵌入式…

2026/8/14 1:17:51 阅读更多 →
2026宜昌危房鉴定检测怎么选?老旧房危房鉴定靠谱机构 TOP 结构安全检测+ 报告可查 电话汇总

2026宜昌危房鉴定检测怎么选?老旧房危房鉴定靠谱机构 TOP 结构安全检测+ 报告可查 电话汇总

漫步宜昌街头,老旧小区与乡镇自建房星罗棋布,商铺厂房鳞次栉比,危房鉴定需求日益迫切。市面上机构鱼龙混杂,不少无资质单位出具的报告根本无法通过住建审核,业主们挑选时难免眼花缭乱。小编实地走访筛选,深…

2026/8/14 1:17:51 阅读更多 →
H.264视频流NALU结构与Annex B封装解析

H.264视频流NALU结构与Annex B封装解析

1. H.264视频流结构解析基础 H.264作为当前应用最广泛的视频编码标准,其核心优势在于高效的压缩率和良好的网络适应性。要真正掌握H.264的处理技术,必须深入理解其分层架构设计。与常见认知不同,H.264并非简单的视频数据集合,而是…

2026/8/14 1:17:51 阅读更多 →
从 0 到上线:单文件网页 App 部署到阿里云 ECS 全流程(Nginx+Node+PM2+PostgreSQL)

从 0 到上线:单文件网页 App 部署到阿里云 ECS 全流程(Nginx+Node+PM2+PostgreSQL)

从 0 到上线:单文件网页 App 部署到阿里云 ECS 全流程(NginxNodePM2PostgreSQL) “今天吃什么?”——这五个字,是我每天下班回家面对冰箱时的终极难题。作为一个非科班、纯自学的普通打工人,我没想做多牛的…

2026/8/14 1:17:51 阅读更多 →
SQL Server数据库表空间与行数统计:原理、方法与自动化监控

SQL Server数据库表空间与行数统计:原理、方法与自动化监控

1. 项目概述:为什么需要关注数据库与表的空间占用?在数据库运维和开发工作中,我们经常会遇到一些看似简单却至关重要的问题:数据库服务器磁盘空间告警了,是哪个库、哪张表在“野蛮生长”?新上线的业务模块数…

2026/8/14 1:17:51 阅读更多 →
【加急快讯】DeepSeek Harness 深夜开源!主打「一切皆插件」,由 Cordis 驱动

【加急快讯】DeepSeek Harness 深夜开源!主打「一切皆插件」,由 Cordis 驱动

⚡ 加急快讯:DeepSeek 开源 Agent 框架 DeepSeek Harness(dsh),「一切皆插件」,Cordis 驱动,MIT 协议。 今晚8点25分左右,DeepSeek 正式开源发布 Agent 智能体框架 DeepSeek Harness&#xff0c…

2026/8/14 1:16:50 阅读更多 →

日新闻

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

在这个流量为王、视觉至上的互联网时代,对于临沂乃至整个山东乃至全国的传统中小企业来说,拥有一张精美的“数字名片”早已不再是可选项,而是生存的必答题。每当夜幕降临,沂河两岸灯火辉煌,物流之都的喧嚣逐渐沉淀为对未来的思考。我们常常听到老板们在茶余饭后探讨:为什…

2026/8/14 0:00:26 阅读更多 →
Flutter与OpenHarmony实现剧本杀组队表单开发实战

Flutter与OpenHarmony实现剧本杀组队表单开发实战

1. 项目概述在移动应用开发领域,跨平台框架Flutter因其高效的开发体验和出色的性能表现,已经成为众多开发者的首选。而OpenHarmony作为新兴的操作系统平台,其开放性和灵活性为开发者提供了全新的可能性。本文将聚焦于一个实际应用场景——剧本…

2026/8/14 0:00:26 阅读更多 →
大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

在这个数字化浪潮席卷全球的今天,企业想要在激烈的市场竞争中站稳脚跟,拥有一张好看的“数字名片”已经远远不够了。很多老板在刚开始接触互联网业务时,都有一个共同的困惑:为什么我花了钱建的网站,就像是在真空中自嗨?访客进来转了两圈就跑了,线索石沉大海,甚至连客服…

2026/8/14 0:01:27 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/13 10:41:50 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/13 10:41:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/13 10:41:49 阅读更多 →