![ONNX Runtime Model Package 消费端集成:executor_info[“ort“]、变体选择算法与 OrtModelPackageApi C 接口](http://pic.xiahunao.cn/yaotu/ONNX Runtime Model Package 消费端集成:executor_info[“ort“]、变体选择算法与 OrtModelPackageApi C 接口)
ONNX Runtime Model Package 消费端集成executor_info[ort]、变体选择算法与 OrtModelPackageApi C 接口【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntimeONNX Runtime 的 model package 消费端集成层负责把独立的model_package库与 ORT 的会话运行时连接起来加载模型包、根据运行时可用的执行提供者EP在变体variant中选出最优匹配并为选中的变体创建OrtSession。读完本文你可以掌握executor_info[ort]负载的完整 JSON schema、VariantSelector的评分选择算法、OrtModelPackageApi_CreateSession的默认/进阶两条路径的语义差异并能基于实验性 C API 完成打开包 → 选择变体 → 创建会话的完整调用链。定位model_package 库之上的 ORT 胶水层onnxruntime/core/session/model_package/目录实现的是 ONNX Runtime 作为消费者对独立model_package库的胶水glue层加载包、针对运行时的执行提供者选择变体并为选中的变体创建OrtSession。包格式、manifest.json/component.json的 schema、共享资产shared assets规则、以及 C 语言编写/检查 API 全部位于 model_package/ 目录中且该库不依赖 ORT 本身——ORT 以静态库static archive形式链接它方向是单向的。这个目录在库之上只增加了三样东西executor_info[ort]负载 schema这是 ORT 在变体中拥有的专属槽位变体选择算法查询每个 EP 工厂从中挑出得分最高的变体实验性的OrtModelPackageApi_*C 函数封装上述库并暴露会话创建能力。它们在 onnxruntime_experimental_c_api.inc 中注册通过OrtApi::GetExperimentalFunction按名解析。核心文件与职责该集成层由三个 C 文件对加一个 C 入口文件构成文件职责model_package_context.h/.cc把model_package库的 C 信息树翻译成 ORT 内部 C 结构ModelPackageInfo、ComponentInfo、VariantInfo、VariantModelInfo解析executor_info[ort]负载。持有包级的ModelPackageContext与组件级的ModelPackageComponentContext内含选中变体与 provider 列表。model_package_options.h/.ccModelPackageOptions在调用OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions_SinceV28的时刻从OrtSessionOptions快照当前 EP 意图工厂、设备、EP 名列表驱动变体选择与 provider 构建。model_package_variant_selector.h/.ccVariantSelector::SelectVariant依据 EP 列表从组件中挑选最佳变体内部使用OrtEpFactory::ValidateCompiledModelCompatibilityInfo回调。model_package_api.ccC 入口点本体位于namespace OrtExperimentalApis。从 model_package_context.cc 的构造函数可以看到胶水层的工作方式ModelPackageContext通过::ModelPackage_Open打开包并把库句柄以类型擦除void*方式保存在上下文中、直到上下文析构才调用ModelPackage_Close从而后续的路径解析无需重复打开/解析。随后它遍历ModelPackage_Info返回的组件/变体树把 C POD 结构逐字段拷贝为 ORT 内部 C 结构并通过ModelVariantInfo_FindExecutorInfo(variant, ort)取出 ORT 专属槽位进行解析。executor_info[ort]schemaexecutor_info[ort]槽位是一个 JSON 对象。所有字段都是可选的但实际使用中model_file是创建会话的必要条件{ model_file: model.onnx, session_options: { session.intra_op_thread_count: 4, session.model_external_initializers_file_folder_path: weights }, provider_options: { device_id: 0 } }字段类型是否必需说明model_filestring是对会话而言variant 内模型文件的路径。通过ModelPackage_ResolveStringRef解析以 variant 目录为锚点。接受相对路径、绝对路径或..段仅限 installed 布局以及sha256:hex[/sub/path]形式的共享资产引用。session_optionsobject否string - string映射。当调用方在CreateSession中传入session_options NULL时被合并到一个全新的OrtSessionOptions之上。取值为路径的 key见IsModelPackagePathSessionOption如session.model_external_initializers_file_folder_path、ep.context_file_path在解析期就按与model_file相同的规则完成解析。这些路径类 key 在进阶路径下同样生效——前提是调用方自己没有设置它们见下文。provider_optionsobject否string - string映射。在默认路径下合并进 variant 的 EP provider options当调用方自带OrtSessionOptions时被忽略。内联 vs 外部形式该槽位遵循标准executor_info形态取值有两种字符串指向一个 JSON 文件的路径文件内容就是上面的对象体常见做法是在model.onnx旁边放一个ort_info.json对象对象体内联在component.json/manifest.json中。内联形式让包保持单文件外部形式更常见则让 variant 目录自我描述并且在executor_infoschema 演进时无需重写 manifest。executor_info下的 key 是执行器命名空间名ort而不是 EP 名——其他消费者各自用自己的命名空间 key因此同一个 variant 可以并排携带多个消费者的负载。源码中的解析细节从 model_package_context.cc 的解析逻辑可以确认几个文档没有展开的实现约束executor_info[ort]必须是 JSON 对象否则直接抛异常model_file必须是字符串其值通过ModelPackage_ResolveStringRef解析must_existfalse路径在CreateSession时才真正需要存在session_options与provider_options必须是对象且每个值都必须是字符串违反会报错IsModelPackagePathSessionOption当前认定的路径类 session option key 有三个session.model_external_initializers_file_folder_path、ep.context_file_path、ep.context_source_model_path。这些 key 的非空值在解析期即被ModelPackage_ResolveStringRef解析为具体路径因此 variant 可以在 manifest 中直接写sha256:hex或相对路径来引用共享资产里的权重目录。变体选择Variant SelectionEP 意图快照ModelPackageOptions(env, session_options)捕获的是EP 意图会话选项上注册的有序执行提供者列表及其关联的OrtEpDevice/OrtHardwareDevice/ 元数据。从 model_package_options.cc 的ResolveEpSelection可以看到快照的三种来源分支会话选项上有 provider 工厂逐个调用factory-CreateProvider构建 provider 列表再从中提取VariantSelectionEpInfoEP 名、工厂指针、设备列表、元数据未显式指定 EP 但启用了 EP 选择策略policy通过ProviderPolicyContext::SelectEpsForModelPackage得到带排序的候选 EP 列表例如 [CUDA, WebGPU, CPU]既无 EP 也无策略回退为 CPU EP 参与变体选择。选择算法VariantSelector::SelectVariant(component, ep_infos, selected)遍历组件的变体并挑出最佳匹配只取捕获列表中的第一个 EP。策略可能返回多个 EP 的排序列表需要指定 EP 的调用方应把它放在第一位对整个 EP 列表做排序目前是 TODO。源码在 model_package_variant_selector.cc 中对此有明确注释并会在捕获到多个 EP 时打一条 INFO 日志说明只使用第一个。对每个 variant要求variant.ep ep_info.ep_nameEP 名精确匹配若 variant 声明了devicecpu/gpu/npu要求它与该 EP 的某个OrtHardwareDevice条目匹配MatchesDevice按OrtHardwareDeviceType枚举比对且大小写不敏感两者都通过后以variant.compatibility_string调用OrtEpFactory::ValidateCompiledModelCompatibilityInfo。EP 返回一个OrtCompiledModelCompatibility枚举映射为得分枚举得分EP_SUPPORTED_OPTIMAL100EP_SUPPORTED_PREFER_RECOMPILATION50EP_NOT_APPLICABLE或 EP 过旧 / 未实现该 ABI0EP_UNSUPPORTED直接拒绝源码中映射为 -100不会入选选取得分最高的匹配 variant。得分相同时manifest 声明顺序在前者胜出源码用严格比较保证平局时保留先出现者。若没有任何 variant 匹配SelectComponent会以错误信息No suitable model variant found for the configured execution providers.失败——这一文案可直接在 model_package_context.cc 的ResolveVariantImpl中找到。关于兼容性回调的两个源码级细节值得注意compatibility_string为空、EP 工厂为nullptr、工厂的ort_version_supported 23或ValidateCompiledModelCompatibilityInfo为nullptr时回调被视为不适用直接给出EP_NOT_APPLICABLE得分 0ORT 不解析compatibility_string。该串的格式由 EP 自己拥有EP 可以在单个字符串内部编码多个子目标SoC id、ISA 标志等ORT 只是把它原样回传round-trip给 EP 的回调。源码注释还提到一条尚未接线的未来回退链若 EP 实现了SelectBestCompiledModelCandidate则由 EP 从候选列表中挑选否则再落到当前的逐 variant 验证方式。会话创建契约Session Creation Contract入口为OrtModelPackageApi_CreateSession_SinceV28(env, component_ctx, session_options, session)。此时component_ctx已经知道哪个 variant 赢得了选择、以及应当使用哪个 provider 列表。行为分两条路径session_options NULL默认路径。ORT 从全新的OrtSessionOptions出发把 variant 在executor_info[ort]中的session_options/provider_options合并到其上manifest 中声明的 EP 会被构建并注册。绝大多数调用方要走这条路径。session_options ! NULL进阶路径。ORT 原样使用调用方提供的OrtSessionOptionsmanifest 里的session_options与provider_options不再合并——唯一例外是路径类 session optionIsModelPackagePathSessionOption对于调用方没有设置的 key会从 variant 中携带过来保证一个依赖 external-initializers 目录的模型仍然能加载。当你需要自定义的 EP 配置、且这些配置无法用字符串 option 表达时共享 CUDA 流、共享 QNN EP 上下文、自定义分配器等应走这条路径。注意之前传给CreateModelPackageOptionsFromSessionOptions的那个OrtSessionOptions只驱动变体选择 / EP 发现不会在这里被悄悄重新应用。variant 通过在session_options中把session.model_external_initializers_file_folder_path设置为某个目录相对、绝对或sha256:hex共享资产来让 ORT 找到外部初始化的权重。该值在解析期完成解析并覆盖模型自身所在目录因此模型文件可以引用存放在包旁边或由多个包共享的权重。一个源码层面的补充由于 provider 在注册进会话时会被消费moveModelPackageComponentContext::RebuildProviderListForSession会在每次会话创建调用时重建 provider 列表若选中的 EP 是CPUExecutionProvider或没有设备信息则跳过构建CPU 是内建 EP无需注册 provider。C API 表面模型包 API 通过 ONNX Runtime 的实验性 C API机制暴露。每个函数都作为独立条目注册在 onnxruntime_experimental_c_api.inc 中前缀为OrtModelPackageApi_版本后缀为_SinceV28。调用方通过OrtApi::GetExperimentalFunction按名查找直接查找或经由由onnxruntime_experimental_c_api.h生成的Ort::Experimental::*类型化 C 访问器查找。三个不透明句柄类型OrtModelPackageOptions、OrtModelPackageContext、OrtModelPackageComponentContext在onnxruntime_experimental_c_api.h顶部前向声明。注册的条目函数说明CreateModelPackageOptionsFromSessionOptions快照 EP 意图。ReleaseModelPackageOptions释放选项句柄。CreateModelPackageContext解析 manifest创建包上下文。ReleaseModelPackageContext释放包上下文。ModelPackage_GetSchemaVersion查询 schema 版本。ModelPackage_GetComponentCount/ModelPackage_GetComponentNames检查组件。ModelPackage_GetVariantCount/ModelPackage_GetVariantNames/ModelPackage_GetVariantEpName检查组件下的 variant。SelectComponent解析出最佳匹配 variant产出组件上下文。ReleaseModelPackageComponentContext释放组件上下文。ModelPackageComponent_GetSelectedVariantName/ModelPackageComponent_GetSelectedVariantFolderPath查询选中 variant 的名字与目录。CreateSession为选中 variant 创建会话。另外从 onnxruntime_experimental_c_api.inc 的注册清单还能看到OrtModelPackageApi_ModelPackage_ResolveStringRef条目——它把库的路径解析能力sha256:URI、相对/绝对路径规则直接暴露给调用方供需要自行解析包内引用时使用。实验性函数不属于稳定 ABI。在提升到稳定OrtApi之前函数名、签名和行为都可能在版本之间变化。调用方应当对每次查找做 null 检查。典型调用流程#include onnxruntime_c_api.h #include onnxruntime_experimental_c_api.h const OrtApi* ort OrtGetApiBase()-GetApi(ORT_API_VERSION); auto fn_create_opts Ort::Experimental::Get_OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions_SinceV28_Fn(ort); auto fn_release_opts Ort::Experimental::Get_OrtModelPackageApi_ReleaseModelPackageOptions_SinceV28_Fn(ort); auto fn_create_ctx Ort::Experimental::Get_OrtModelPackageApi_CreateModelPackageContext_SinceV28_Fn(ort); auto fn_release_ctx Ort::Experimental::Get_OrtModelPackageApi_ReleaseModelPackageContext_SinceV28_Fn(ort); auto fn_select Ort::Experimental::Get_OrtModelPackageApi_SelectComponent_SinceV28_Fn(ort); auto fn_release_comp Ort::Experimental::Get_OrtModelPackageApi_ReleaseModelPackageComponentContext_SinceV28_Fn(ort); auto fn_create_session Ort::Experimental::Get_OrtModelPackageApi_CreateSession_SinceV28_Fn(ort); OrtSessionOptions* so nullptr; ort-CreateSessionOptions(so); ort-SessionOptionsAppendExecutionProvider(so, CUDAExecutionProvider, nullptr, nullptr, 0); OrtModelPackageOptions* mp_opts nullptr; fn_create_opts(env, so, mp_opts); OrtModelPackageContext* ctx nullptr; fn_create_ctx(ORT_TSTR(/path/to/pkg), ctx); OrtModelPackageComponentContext* comp_ctx nullptr; fn_select(ctx, decoder, mp_opts, comp_ctx); OrtSession* session nullptr; fn_create_session(env, comp_ctx, nullptr, session); ort-ReleaseSession(session); fn_release_comp(comp_ctx); fn_release_ctx(ctx); fn_release_opts(mp_opts); ort-ReleaseSessionOptions(so);指针生命周期约定API 返回的所有const char*/const ORTCHAR_T*/ 数组指针都由产生它们的上下文所有在该上下文被释放之前保持有效。从源码实现看上下文内部为 C API 专门维护了指针缓存如component_name_ptrs_cache_、session_option_key_ptrs_cache_等把std::string的c_str()固化下来使得返回值不会因内部缓存刷新而悬空其有效期与上下文一致。延伸阅读model_package/README.md包格式、manifest/component schema、共享资产、路径解析规则、C 编写 API以及executor_info扩展点的完整定义docs/design/Experimental_C_API.md承载这些条目的实验性 C API 机制的设计与生命周期规则onnxruntime_experimental_c_api.incOrtModelPackageApi_*条目的权威清单onnxruntime/core/session/model_package_api.ccC 入口点的实现OrtExperimentalApis命名空间。【免费下载链接】onnxruntimeONNX Runtime: cross-platform, high performance ML inferencing and training accelerator项目地址: https://gitcode.com/GitHub_Trending/on/onnxruntime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考