【Bug已解决】AddExternalInitializers copies device (GPU) OrtValues per session instead of using them in …
【Bug已解决】AddExternalInitializers copies device (GPU) OrtValues per session instead of using them in place 解决方案一、现象长什么样用AddExternalInitializers把一个已经常驻 GPU 的OrtValue作为外部初始化器加到计算图里常见于把预加载的大常量权重直接挂到图上时发现每个新建的 session 都会把这份 GPU 张量完整拷贝一份而不是原地复用in-place / 共享引用// 预加载一个大权重到 GPU得到 device OrtValue Ort::Value gpu_weight loadWeightToGpu(...); // 比如 1GB 的 embedding 表 // 把它作为外部初始化器加进图 // 期望session 直接引用 gpu_weight0 拷贝 // 实际每个 session 都 deep-copy 了一份 gpu_weight1GB x N session std::vectorOrtValue* initializers {gpu_weight}; // AddExternalInitializers 内部对 device OrtValue 做了拷贝最小信号GPU 显存随 session 数线性增长每个 session 多一份权重拷贝 预期所有 session 共享同一份 GPU 权重in-place注意这不是结果错而是显存浪费 拷贝开销——大权重本可跨 session 共享却被每份 session 复制。二、背景AddExternalInitializers的作用是把一个OrtValue通常是常量权重注册成图的初始化器这样图在构造时就“拥有”这个权重不用每次run()都从外部传入。当这个OrtValue已经在GPU 设备上时理想情况是 session直接持有它的引用或共享所有权多个 session 共享同一块 GPU 显存。但 ORT 的AddExternalInitializers实现里对 deviceGPUOrtValue走了“拷一份再挂到图上”的路径而不是“原地接管/共享引用”。原因通常是图的初始化器在内部用OrtValue的拷贝语义值语义默认AddExternalInitializers的契约是“把值加进图”实现者图省事直接拷贝。deviceOrtValue的拷贝涉及一次cudaMemcpy设备内或跨流既占显存又耗时。对于大模型几十 GB 权重每个 session 拷一份直接爆显存所以必须 in-place 共享。三、根因根因是AddExternalInitializers对 deviceGPUOrtValue走了深拷贝路径而不是 in-place 共享引用移动语义 / 共享所有权导致每个 session 都复制一份 GPU 权重默认值拷贝语义AddExternalInitializers内部把传入的OrtValue按值存入图的初始化器列表对 GPU 张量触发一次设备内拷贝。未用移动/共享没有判断“如果传入的是 device OrtValue就移动所有权或共享引用不拷贝”于是多 session 各自持有一份拷贝。显存线性增长N 个 session 就有 N 份权重拷贝大模型直接 OOM。不是结果错拷贝出的权重值一样推理正确只是浪费显存和拷贝时间。所以这不是数值错而是API 对 device OrtValue 的共享语义没实现导致本可共享的 GPU 权重被重复拷贝。四、最小可运行复现下面用 C 标准库模拟“AddExternalInitializers 拷贝 vs in-place 共享”的显存差异#include iostream #include vector #include memory // 模拟 device OrtValueGPU 张量记录被拷贝次数 struct DeviceOrtValue { size_t bytes; static int copy_count; DeviceOrtValue(size_t b) : bytes(b) {} DeviceOrtValue(const DeviceOrtValue o) : bytes(o.bytes) { copy_count; } }; int DeviceOrtValue::copy_count 0; // 有 bug 的实现拷贝 device OrtValue 进图 std::vectorDeviceOrtValue addExternalInitializers_copy(const DeviceOrtValue w) { std::vectorDeviceOrtValue graph; graph.push_back(w); // 拷贝 return graph; } int main() { DeviceOrtValue weight(1000000000); // 1GB // 建 4 个 session每个都 AddExternalInitializers for (int i 0; i 4; i) addExternalInitializers_copy(weight); std::cout GPU 权重拷贝次数: DeviceOrtValue::copy_count 每个 session 拷贝一次 - 浪费 4GB\n; // 修复应移动/共享引用拷贝次数 0 }跑出来copy_count 4即 4 个 session 各拷贝一份 1GB 权重共浪费 4GB。修复后应当用移动/共享引用copy_count 0。这复现了“device OrtValue 被重复拷贝”的机制。五、解决方案第一层最小直接修复最小修复让AddExternalInitializers对 deviceOrtValue走 in-place 共享移动所有权或共享引用不拷贝。对使用者临时规避是减少 session 数量全局单例 session让拷贝只发生一次// 全局只建一个持有外部初始化器的 session所有推理复用 // 这样 device OrtValue 只被拷贝或共享一次 static Ort::Session* g_session nullptr; Ort::Session getSession(Ort::Env env, Ort::SessionOptions so, const char* path) { if (!g_session) { // 把 GPU 权重 AddExternalInitializers 后建 session仅一次拷贝 g_session new Ort::Session(env, path, so); } return *g_session; }对 ORT 仓库侧修复是改AddExternalInitializers若传入的OrtValue位于设备内存使用std::move或共享OrtValue的智能指针引用计数接管而不是值拷贝多个 session 共享同一份 deviceOrtValue。这一层立刻消除重复拷贝。六、解决方案第二层结构性改进把“外部初始化器对 device OrtValue 必须 in-place 共享”收口成唯一的配置对象OrtAddExternalInitDeviceCopyPolicyAPI 实现读它from dataclasses import dataclass, field from typing import Tuple, Literal dataclass(frozenTrue) class OrtAddExternalInitDeviceCopyPolicy: AddExternalInitializers device OrtValue 共享语义的单一事实来源。 # device OrtValue 的处理方式in-place 共享不拷贝 device_value_policy: Literal[in_place_share, move, copy] in_place_share # 是否允许多 session 共享同一 device OrtValue allow_cross_session_share: bool True # 受影响 API affected_api: Tuple[str, ...] (AddExternalInitializers,) # 拷贝必须显式声明默认禁止隐式拷贝 forbid_implicit_copy: bool True def should_copy(self, is_device_value: bool) - bool: if not is_device_value: return False return self.device_value_policy copy def describe(self) - str: return device OrtValue 进 AddExternalInitializers 必须 in-place 共享禁止隐式拷贝 POLICY OrtAddExternalInitDeviceCopyPolicy() def plan_add(ort_value_is_device: bool, policy: OrtAddExternalInitDeviceCopyPolicy POLICY) - str: return copy if policy.should_copy(ort_value_is_device) else in_place_share所有 API 实现读同一份POLICYdevice OrtValue 默认 in-place 共享杜绝隐式拷贝。七、解决方案第三层断言 / CI 守护把“device OrtValue 不被隐式拷贝”做成断言。下面用 pytest 风格守护复用第四节逻辑import pytest def test_device_value_in_place(policy): assert policy.device_value_policy in_place_share assert policy.should_copy(True) is False # device 不拷贝 def test_cross_session_share_allowed(policy): assert policy.allow_cross_session_share is True def test_forbid_implicit_copy(policy): assert policy.forbid_implicit_copy is True def test_host_value_no_copy_either(policy): # 即便 host 值按策略也不拷贝直接用 assert policy.should_copy(False) is False这四组断言锁住(1) device 值 in-place 不拷贝(2) 允许跨 session 共享(3) 禁止隐式拷贝(4) host 值也不无故拷贝。CI 跑通即代表共享语义被守护。八、排查清单遇到 AddExternalInitializers 让 GPU 显存随 session 数增长确认是不是 device OrtValue传入的权重在 GPU 上、且每个 session 都多一份 - 锁定隐式拷贝。看 API 语义AddExternalInitializers是不是值拷贝没用移动/共享。查 session 数量是不是每请求一 session应改单例。临时规避全局单例 session只拷贝/共享一次。根本修复device OrtValue 走 in-place 共享移动/引用计数不拷贝。统一策略对象用OrtAddExternalInitDeviceCopyPolicy固化。CI 守护断言 device 值不拷贝、可跨 session 共享。九、小结AddExternalInitializers copies device (GPU) OrtValues per session instead of using them in place的根因是AddExternalInitializers对位于设备内存的OrtValue走了值拷贝路径而不是 in-place 共享引用移动语义/引用计数导致每个新建的 session 都把这份 GPU 权重完整拷贝一份显存随 session 数线性增长、还有拷贝开销。最小修复是让 API 对 device OrtValue 走 in-place 共享移动/共享所有权临时规避是全局单例 session 只共享一次结构性改进是用唯一的OrtAddExternalInitDeviceCopyPolicy固化“device 值必须 in-place 共享、禁止隐式拷贝”CI 用四组断言守护“device 不拷贝、可跨 session 共享、禁止隐式拷贝”。记住常驻 GPU 的大权重进图必须共享引用隐式拷贝会直接撑爆显存。

相关新闻

【信息科学与工程学】【通信工程】第一百五十九篇 SDN网络中的核心算法01

【信息科学与工程学】【通信工程】第一百五十九篇 SDN网络中的核心算法01

编号2 完整表格 字段 内容 编号​ 2 类型​ 算法 领域​ SD-WAN(软件定义广域网) 模块​ 流量工程(Traffic Engineering) – 带宽分配 依赖软件环境​ 编译器:GCC 11.2.0 (C++20) 操作系统:Linux Kernel 5.15 (x86_64) 虚拟化:KVM + Docker 运行库:GLPK (GN…

2026/8/13 23:44:08 阅读更多 →
【Bug已解决】[Web] Expose WebGPU EP buffer cache mode options in JS 解决方案

【Bug已解决】[Web] Expose WebGPU EP buffer cache mode options in JS 解决方案

【Bug已解决】[Web] Expose WebGPU EP buffer cache mode options in JS 解决方案 一、现象长什么样 在 Web 端(ONNX Runtime Web)用 WebGPU EP,想调“缓冲区缓存模式”相关的 session 选项(比如让中间张量在不同 run() 之间复用 …

2026/8/13 23:44:08 阅读更多 →
Spring Boot 3.x升级遇UnsupportedClassVersionError:Java版本不匹配的排查与修复

Spring Boot 3.x升级遇UnsupportedClassVersionError:Java版本不匹配的排查与修复

1. 问题现象与本质剖析 最近在升级一个老项目到 Spring Boot 3.x 时,编译过程一切顺利,但在启动应用时,控制台直接抛出了一个令人困惑的错误: java.lang.UnsupportedClassVersionError: class file has wrong version 61.0, shou…

2026/8/13 23:44:08 阅读更多 →

最新新闻

泉州网站建设哪里优惠:揭秘中小企业低成本建站的底层逻辑与避坑指南

泉州网站建设哪里优惠:揭秘中小企业低成本建站的底层逻辑与避坑指南

作为一名在泉州互联网行业摸爬滚打多年的“老兵”,我见过太多老板在起步阶段因为不懂技术、不懂市场,最后花了几万甚至十几万冤枉钱,做出来的网站不仅没人看,还成了“电子墓地”。最近不少朋友加我微信,问得最多的一句话就是:“泉州网站建设哪里优惠?”听起来很简单吧?…

2026/8/14 1:00:47 阅读更多 →
Navicat试用期到期不用愁:navicat-key三步重置15天试用

Navicat试用期到期不用愁:navicat-key三步重置15天试用

Navicat试用期到期不用愁:navicat-key三步重置15天试用 【免费下载链接】navicat-key navicat-key 项目地址: https://gitcode.com/gh_mirrors/na/navicat-key 试用期又到期了?工作正做到一半,屏幕上却弹出了续费提醒,别提…

2026/8/14 1:00:47 阅读更多 →
三明网站建设tudouly深度解析与企业官网数字化转型的避坑指南

三明网站建设tudouly深度解析与企业官网数字化转型的避坑指南

在这个数字化浪潮席卷而来的时代,如果说生意是水流,那么网络就是承载水流的河床。对于很多在三明扎根的企业老板或者创业伙伴来说,大家可能有一个误解,觉得“三明网站建设tudouly”这个事儿,不就是找个美工设计个页面,再找个程序员写几行代码,最后把网站搭建起来,挂个域…

2026/8/14 1:00:47 阅读更多 →
菏泽网站建设fuyucom如何从0到1打造让本地企业真正获客的专业官网

菏泽网站建设fuyucom如何从0到1打造让本地企业真正获客的专业官网

在这个互联网触手可及的时代,很多菏泽的企业老板或者市场负责人都有一个共同的痛点:明明产品很好,技术也很硬,可一到线上就歇菜。你打开自己的电脑或者手机,搜一下自家公司的名字,结果要么是一片空白,要么跳出来的是一个十几年前风格的简陋页面,加载速度慢得像老牛拉车…

2026/8/14 0:59:47 阅读更多 →
网站建设怎么开发客户:从源头到转化的全流程实战指南

网站建设怎么开发客户:从源头到转化的全流程实战指南

咱们今天不聊那些虚头巴脑的大词,也不堆砌那些晦涩难懂的技术术语。咱们就坐下来,像朋友聊天一样,掏心窝子地谈谈一个很多做网站、做建站服务的老板和从业者们最头疼的问题:网站建设怎么开发客户。我知道,现在的环境真的挺卷的。你去打开招聘软件或者行业论坛,到处都是“…

2026/8/14 0:59:47 阅读更多 →
「传感器视界」——用工程师的眼睛,拆解每一个感知世界的元件

「传感器视界」——用工程师的眼睛,拆解每一个感知世界的元件

五路灰度传感器是一种广泛应用于机器人、智能小车、自动化设备中的光电检测模块,主要用于检测地面灰度差异、识别轨迹线、判断边缘位置等场景。它因结构简单、成本低廉、响应迅速而在电子竞赛、创客教育和工业自动化中广受欢迎。1. 什么是五路灰度传感器&#xff1f…

2026/8/14 0:59:47 阅读更多 →

日新闻

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

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

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

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 阅读更多 →