登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

ONNX Runtime 怎样读取可覆盖初始化器的名称与类型

来源:17golang原创

时间:2026-11-06 17:09:55 259浏览 收藏

在 ONNX Runtime 的 Python 会话上调用 get_overridable_initializers(),再遍历返回的 NodeArg,即可读取每项的 name、type 和 shape。它提供可覆盖初始化器的元数据,不提供权重数组;返回空列表也不能据此断言模型没有权重。

官方地址:https://onnxruntime.ai/

先把“输入数”和“可覆盖初始化器数”分开记录

部署检查脚本往往已经列出了模型输入,但“能给模型传哪些业务输入”和“有哪些带默认值、可覆盖的初始化器”不是同一个问题。不要把 get_inputs() 的结果直接当作全量权重目录,也不要用文件大小推算可覆盖项的数量。

这里以可复现的报告字段作为基线:普通输入条目数、可覆盖初始化器条目数、每个条目的名称、类型和形状。它们描述接口,不是推理性能指标。下面只读取会话元数据,不执行推理,也不提供虚构的耗时或加速比例。

观察项取得方式含义
inputs_countlen(session.get_inputs())会话输入元数据条目数
overridable_countlen(session.get_overridable_initializers())可覆盖初始化器元数据条目数
name、type、shape读取每个 NodeArg 的属性参数标识与声明信息,不是张量数值

读取 name、type 和 shape 的最小写法

准备一个本地、可信且能被当前环境加载的 model.onnx 文件;外部数据文件也应完整。下面使用 CPU 会话简化示例,不讨论设备选择。若创建会话时报文件、格式或算子支持错误,应处理该异常;不能把加载失败包装成“没有初始化器”。

from pathlib import Path
import onnxruntime as ort

# 替换成待检查模型;这里只读取接口信息,不调用 run。
model_path = Path("model.onnx")
if not model_path.is_file():
    raise FileNotFoundError(model_path)

session = ort.InferenceSession(
    str(model_path),
    providers=["CPUExecutionProvider"],
)
items = session.get_overridable_initializers()
print("inputs_count:", len(session.get_inputs()))
print("overridable_count:", len(items))

# NodeArg 的属性描述名称、声明类型和张量形状,不包含权重数组。
for item in items:
    print({"name": item.name, "type": item.type, "shape": item.shape})

if not items:
    print("当前会话没有暴露可覆盖初始化器")

读取后应关注是否有条目,以及名称能否和目标模型中的参数对应。shape 是形状声明,可能包含符号维度或未知信息,不应强制把每个维度转成整数。type 也应按接口返回值保留,不能假定所有模型都只有 float32 张量。

会话方法返回NodeArg及其name type shape属性的组成关系
图1:元数据组成说明图。会话方法关联 NodeArg 列表,每个对象包含名称、类型和形状声明;图中没有权重数值,也不表示实际运行结果。

整理成报告,比较时按名称匹配

当你需要比较两个模型产物的接口时,可以将元数据转成普通字典列表,并按名称排序。比较的是名称是否新增或消失、类型和形状声明是否变化,不是比较列表下标,更不是逐元素比较权重值。

import json

# 接续前例,保留元数据原有字段,不填造缺失维度。
rows = [
    {"name": item.name, "type": item.type, "shape": item.shape}
    for item in session.get_overridable_initializers()
]
rows.sort(key=lambda row: row["name"])

report = {
    "inputs_count": len(session.get_inputs()),
    "overridable_count": len(rows),
    "overridable_initializers": rows,
}

# JSON 只是报告格式;写出失败应由调用方处理,不悄悄丢弃错误。
Path("initializer-metadata.json").write_text(
    json.dumps(report, ensure_ascii=False, indent=2),
    encoding="utf-8",
)

在报告旁记录模型产物标识和 ONNX Runtime 版本,会比只记录一份字段列表更容易追溯。两次结果不一致时,先确认比较的是同一模型导出物和同样的会话创建条件,不能立即归因于底层设备。

如果后续需要性能比较,应另行固定模型、输入样本、硬件和会话配置,分开衡量会话创建与推理调用,并记录重复测量的统计口径。读取这份元数据报告本身没有证明任何推理加速,也无需为了得到 name/type/shape 去跑压测。

空列表为什么不等于模型没有初始化器

ONNX 图中的 initializer 可以保存默认张量内容,但不是每个 initializer 都会作为可覆盖输入暴露给运行时。模型是否保留了这种接口取决于具体图的定义与导出产物。因此,items == [] 的适当解释是“当前会话未暴露可覆盖初始化器”,而不是“模型没有参数”或“模型加载失败”。

如果目标改为读取模型文件里全部初始化器及其数值,应使用 ONNX 模型解析和张量转换相关接口,并考虑外部数据文件。那是模型内容读取任务,不是对 NodeArg 调用 numpy();不要把两种对象混在一起。

模型初始化器内容与会话可覆盖元数据范围的区别
图2:接口范围说明图。模型内容与会话暴露的元数据是不同观察面,NodeArg 描述可覆盖项的声明,不能当作完整权重目录。

拿到元数据以后,还不能推断什么

名称、类型和形状是后续构造输入时的重要依据,但这份列表不会自动替你准备替换张量,也不会修改原模型文件。是否能覆盖某项、替换值是否满足图的要求,还需结合模型契约和实际调用处理;不要把“可读取名称”解释成“任意权重都能随时修改”。

现象合理解释不能推出
列表非空会话暴露了可覆盖初始化器信息已经完成参数替换
列表为空没有暴露该类条目没有任何权重
shape 有未知维度声明信息不能完全确定数值尺寸可以把未知项默认当成 1
两份报告相同这些接口字段一致模型数值、精度或性能相同

能不能直接访问返回对象的数组值?

不能把 NodeArg 当作权重张量。它描述参数接口,名称、类型和形状不包含元素值。

是否需要调用 session.run 才能获取这些字段?

不需要。创建会话后即可读取上述元数据。创建会话本身仍可能失败,必须与正常返回的空列表区分。

get_inputs 和这个列表能否合并?

可以为自己的报告分别整理,但应保留来源类别,不要简单拼接后称为“全部权重”。对于覆盖任务,以专门方法返回的名称与声明为依据。

完成这个任务的核心是选对观察对象:调用 get_overridable_initializers() 获取可覆盖项元数据,读取三项属性,保留空结果和异常的区别。需要权重值时,再使用模型文件内容读取路径。

参考:ONNX Runtime Python API 与 NodeArg;会话 Python 实现;ONNX 图与初始化器概念。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>