ONNX External Data 完全指南:加载、转换、校验与底层原理
人工智能深度学习机器学习【免费下载链接】onnxOpen standard for machine learning interoperability项目地址https://gitcode.com/gh_mirrors/onn/onnx点击查看免费下载External Data 是 ONNX 标准中把张量数据从模型文件.onnxprotobuf中剥离、存放到独立外部文件的机制用于突破 protobuf 序列化的 2GB 大小限制并显著降低模型文件的加载内存占用。本文以 docs/ExternalData.md 为骨架结合本仓库的 onnx/external_data_helper.py、onnx/init.py、onnx/serialization.py、onnx/checker.cc 与 onnx/onnx.in.proto 等源码完整讲解外部数据的加载、转换、保存、校验流程以及TensorProto中相关字段的语义帮助读者在实际工程中正确使用并安全处理外部数据模型。一、为什么需要 External Data2GB 边界与内存问题ONNX 模型本质上是 protobuf 序列化的ModelProto。protobuf 的单个消息序列化大小上限为 2GB这在 onnx/checker.py 中被常量MAXIMUM_PROTOBUF 2147483647明确约束。当模型的权重尤其是 LLM、大视觉模型的参数逼近或超过该阈值时onnx/serialization.py 中的序列化逻辑会直接抛出如下错误The proto size is larger than the 2 GB limit. Please use save_as_external_data to save tensors separately from the model file.External Data 机制正是为此而生把张量的原始二进制数据写到独立文件模型文件内只保留描述数据在哪的键值对从而绕开 2GB 上限也让模型文件本身变得轻量、可版本化管理。这也是 ONNX 官方设计见 docs/ExternalData.md 末尾引用的 onnx/onnx#678 提案所确立的通用做法。二、加载带有 External Data 的模型2.1 默认方式外部数据与模型同目录如果外部数据文件与模型文件位于同一目录直接用onnx.load()即可加载过程会自动读取同目录下的外部数据import onnx onnx_model onnx.load(path/to/the/model.onnx)其底层行为可以在 onnx/init.py 的load_model中看到load_external_data参数默认为True加载时会取模型文件所在目录作为base_dir并调用load_external_data_for_model(model, base_dir)把外部张量读入内存。2.2 外部数据在其他目录手动指定目录若外部数据存放在与模型不同的目录则需要两步完成加载import onnx from onnx.external_data_helper import load_external_data_for_model onnx_model onnx.load(path/to/the/model.onnx, load_external_dataFalse) load_external_data_for_model(onnx_model, data/directory/path/) # Then the onnx_model has loaded the external data from the specific directory这里onnx.load(..., load_external_dataFalse)先只解析模型结构、跳过外部数据随后用load_external_data_for_model()显式指定数据目录完成装载。load_external_data_for_model()的实现onnx/external_data_helper.py会遍历模型中的所有张量对每一个uses_external_data(tensor)为真的张量调用load_external_data_for_tensor()将外部文件中的字节读入tensor.raw_data然后把data_location复位为DEFAULT并清空external_data字段——加载完成后内存中的模型与普通内嵌模型无异。三、将模型转换为 External Data 格式3.1 两步式先转换、后保存convert_model_to_external_data()只修改内存中的ModelProto标记真正写文件发生在save_model()阶段因此必须紧跟一次保存调用import onnx from onnx.external_data_helper import convert_model_to_external_data onnx_model ... # Your model in memory as ModelProto convert_model_to_external_data(onnx_model, all_tensors_to_one_fileTrue, locationfilename, size_threshold1024, convert_attributeFalse) # Must be followed by save_model to save the converted model to a specific path onnx.save_model(onnx_model, path/to/save/the/model.onnx) # Then the onnx_model has converted raw data as external data and saved to specific directory各参数语义对应 onnx/external_data_helper.py 的实现参数默认值说明all_tensors_to_one_fileTrue为True时所有张量写入由location指定的同一个外部文件为False时每个张量单独一个文件文件名为张量名若张量名不是合法文件名则回退为uuid.uuid1()生成的随机名locationNone外部文件相对模型文件的路径不指定时使用uuid.uuid1()生成形如uuid.data的文件名。注意该路径必须是相对路径传绝对路径会抛出ValueError若目标文件已存在则抛出FileExistsErrorsize_threshold1024只有raw_data字节数≥ 该阈值的张量才会被转为外部数据设为0可把所有带原始数据的张量全部外置convert_attributeFalse为False时只转换图初始器initializer张量为True时连节点属性attribute中的张量也一并转换3.2 一步式保存时直接转外部数据更常见的是把转换与保存合并为一次调用使用onnx.save_model(..., save_as_external_dataTrue)import onnx onnx_model ... # Your model in memory as ModelProto onnx.save_model(onnx_model, path/to/save/the/model.onnx, save_as_external_dataTrue, all_tensors_to_one_fileTrue, locationfilename, size_threshold1024, convert_attributeFalse) # Then the onnx_model has converted raw data as external data and saved to specific directorysave_model的这些关键字参数onnx/init.py与convert_model_to_external_data完全对应。保存时真正执行落盘的是 onnx/external_data_helper.py 的write_external_data_tensors()它遍历所有uses_external_data且带raw_data的张量调用save_external_data()把数据写入外部文件并回填offset/length随后清空raw_data使模型文件本体只保留描述信息。四、onnx.checker 对 External Data 模型的校验4.1 小于 2GB 的模型当前 checker 支持直接校验带外部数据的模型既可以传入已加载的ModelProto也可以传入模型路径import onnx onnx.checker.check_model(onnx_model) # 传入已加载模型 onnx.checker.check_model(path/to/the/model.onnx) # 或传入模型路径4.2 大于 2GB 的模型必须传路径对于超过 2GB 的模型必须使用模型路径调用onnx.checker.check_model(path/to/the/model.onnx)且外部数据文件必须与模型位于同一目录import onnx onnx.checker.check_model(path/to/the/model.onnx) # onnx.checker.check_model(loaded_onnx_model) will fail if given 2GB model原因在于大于 2GB 的模型无法整体反序列化进内存的ModelProto受 protobuf 2GB 上限约束checker 需要从路径直接读取模型、结合同目录外部数据做流式校验。相关检查逻辑位于 onnx/checker.cc如张量stored_externally时要求external_data必须包含location见 checker.cc 第 144-162 行附近。五、TensorProto 中的两个外部数据字段外部数据的语义由TensorProto消息中的两个字段定义详见 onnx/onnx.in.proto。5.1 data_location 字段data_location记录该张量数据的存放位置取值必须为以下两者之一DEFAULT——数据存储在 protobuf 消息内部存放在raw_data若已设置中否则存放在类型专用字段如float_data、int64_data等中EXTERNAL——数据存储在外部位置具体位置由external_data字段描述。若该字段未设置则行为等同于DEFAULT对应 proto 中的DataLocation枚举DEFAULT 0; EXTERNAL 1;。5.2 external_data 字段external_data是StringStringEntryProto类型的键值对列表repeated描述数据的外部位置。官方识别的键如下键必选说明location是相对 ONNX protobuf 模型文件所在目录的文件路径禁止使用..等向上目录组件解析时应剥离offset否数据起始字节位置以字符串形式存储的整数。建议为页大小通常 4KB的整数倍以支持 mmapWindows 上建议为VirtualAlloc分配粒度通常 64KB的整数倍以支持内存映射length否数据包含的字节数以字符串形式存储的整数checksum否location指定文件的 SHA1 摘要模型被加载后所有external_data条目可能被追加一个(basepath, ...)键其值为 ONNX 模型文件被加载时所在目录的路径。5.3 外部数据文件的格式外部数据文件中的字节内容与当前 ONNX 实现中raw_data字段的二进制格式完全一致按固定宽度、小端序存储元素浮点类型遵循 IEEE 754相关编码约定见 onnx/onnx.in.proto 中raw_data的注释。因此外部文件本质上就是raw_data的搬出形态读取后直接回填即可。六、源码级原理与安全设计6.1 核心 API 一览onnx/external_data_helper.py 是本机制的全部 Python 实现关键函数包括load_external_data_for_model(model, base_dir)/load_external_data_for_tensor(tensor, base_dir)从外部文件装载数据并复位张量状态convert_model_to_external_data(...)内存内标记转换save_external_data(tensor, base_path)把raw_data写入外部文件并在写入后通过set_external_data()回填offset与lengthset_external_data(tensor, location, offset, length, checksum, basepath)设置data_location EXTERNAL并写入键值对要求张量必须存在raw_data否则抛ValueErroruses_external_data(tensor)判断张量data_location是否为EXTERNALremove_external_data_field(tensor, field_key)删除某条外部数据键值对convert_model_from_external_data(model)反向操作把外部数据张量改回内嵌存储。save_external_data中还有一个值得注意的细节多张量共享同一文件时新张量的offset必须落在当前文件末尾到末尾 _MAX_EXTERNAL_DATA_PADDING64KB之间超出该区间会抛出ValidationError以避免覆盖已有数据或无界填充零字节onnx/external_data_helper.py。6.2 针对恶意外部数据的三层安全防御外部数据机制涉及文件系统路径与字节读写仓库为此实现了三层纵深防御注释见 onnx/external_data_helper.py属性白名单CWE-915ExternalDataInfo解析时只接受{location, offset, length, checksum, basepath}五个规范键未知键会被告警并忽略防止任意属性注入边界校验CWE-400offset、length在解析阶段即强制为非负整数非法值直接抛ValueError文件大小校验CWE-400_validate_external_data_file_bounds()在读取前用fstat获取真实文件大小确认offset不超过文件大小、length不超过可读字节数从根上防止恶意构造的模型导致内存耗尽。在 C 侧onnx/checker.cc 与 1504-1687 行的open_external_data实现加载还包含路径规范化与目录逃逸检查外部数据路径必须能规范化为合法路径且必须解析在模型目录之内打开文件时会拒绝符号链接/重解析点、拒绝存在多个硬链接的文件并通过 fd 与规范化路径的一致性检查抵御 TOCTOU 攻击。七、实践注意事项location 必须是相对路径convert_model_to_external_data对绝对路径直接抛ValueError且location中的路径相对于模型文件所在目录解析..向上目录组件在规范层面被禁止。外部数据文件需随模型一起分发模型被移动时需保持外部数据文件与模型的相对位置关系或使用load_external_data_for_model重新指定数据目录。size_threshold 决定哪些张量外置默认 1024 字节意味着小张量仍内嵌于模型文件兼顾文件数量与加载性能全量外置时设为 0。2GB 以上模型的校验只能传模型路径且外部数据必须在同一目录无法对加载进内存的超大模型做 checker 校验。加载后张量状态复位load_external_data_for_model会把data_location复位为DEFAULT并清空external_data因此加载后的模型再保存会重新内嵌数据如需保持外部数据形态应使用save_as_external_dataTrue重新保存。外部数据机制是 ONNX 处理大模型的事实标准方案理解其加载、转换、保存与校验的完整链路以及TensorProto.data_location/external_data字段的精确语义能帮助你在模型导出、跨平台分发与超大模型推理场景中避免大量踩坑。相关测试用例可进一步参考 tests/python/external_data_test.py 与 tests/python/serialization_test.py。赞分享人工智能深度学习机器学习【免费下载链接】onnxOpen standard for machine learning interoperability项目地址https://gitcode.com/gh_mirrors/onn/onnx点击查看免费下载相关推荐Apache Airflow 集成 AWS SSM Parameter StoreSecrets Backend 配置与实战指南Apache Airflow 集成 AWS SSM Parameter StoreSecrets Backend 配置与实战指南 Apache Airflow人工智能深度学习机器学习curl 命令 --data-binary 完全指南按原样 POST 二进制数据、保留换行与空字节的底层原理curl 命令 data binary 完全指南按原样 POST 二进制数据、保留换行与空字节的底层原理 data binary 是 curl命令行工具与CLI网络通信PyMC 数据接口完全指南Data、get_data 与 Minibatch 的底层原理与实战用法PyMC 数据接口完全指南Data、get_data 与 Minibatch 的底层原理与实战用法 本文基于 PyMC 仓库的 API 参考文档 https:人工智能机器学习科学计算上一篇koa-passport与Passport版本匹配清单避免集成踩坑的关键步骤下一篇如何快速部署GPT-SoVITS语音克隆系统终极实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考