ONNX 基于 Zip 的归档文件格式提案解读:从 0001-ArchiveFileFormatProposal 到 External Data 落地实践
人工智能深度学习机器学习【免费下载链接】onnxOpen standard for machine learning interoperability项目地址https://gitcode.com/gh_mirrors/onn/onnx点击查看免费下载本篇技术指南围绕 ONNX 仓库中的 docs/proposals/0001-ArchiveFileFormatProposal.mdONNX File Format Proposal2019-04-29 提出展开系统讲解该提案为解决 ONNX 模型容量上限与序列化效率问题而设计的 zip 归档方案如何把.zip当作键值存储来组织模型文件、如何通过 64 字节对齐实现权重直接内存映射、为何要把模型定义文件放在归档末尾。同时结合当前仓库中真实落地的外部数据External Data机制onnx/external_data_helper.py、docs/ExternalData.md、onnx/onnx.in.proto让读者既理解历史提案的设计思想又掌握 ONNX 实际支持的模型外置数据读写、转换与校验的完整实战方法。提案背景为什么 ONNX 需要新的文件格式提案在 Summary 中明确了两个核心痛点容量限制TensorProto消息以及底层 protobuf 序列化在单个消息上存在大小上限。提案引用了 onnx/onnx#251 以及 Stack Overflow 上关于 protobuf 最大尺寸限制的讨论作为佐证。大模型权重动辄数 GB超过该限制后模型无法以单文件形式正常序列化与加载。反序列化效率低下把整个ModelProto包括全部权重一次性编码进 protobuf 字节流存在复制开销大、无法按需读取的问题。因此提案的设计目标非常明确simple简单、widely applicable广泛适用、efficient高效。其核心思路是——把张量值即通常存放在TensorProto消息中的数据作为独立文件放进一个 zip 归档从而绕开上述大小限制并在满足特定约束的前提下允许对 ONNX 文件直接进行内存映射memory-mapping使权重可以直接从映射区域使用避免额外的加载与复制。核心设计把 Zip 当作键值存储提案提出将.zip文件视为一个键值存储key-value store以字符串键即文件名映射二进制数据文件。对于 ONNX 模型序列化归档中应包含以下条目条目内容说明Data files数据文件由唯一字符串标识符映射到原始二进制数据文件这些文件需从基础ModelProto的相应字段中引用__MODEL_PROTO描述整个文件的ModelProto消息模型定义文件条目顺序是关键设计决策提案明确要求把模型定义文件放在归档末尾。理由在于——常见的场景是对模型结构做各种操作net manipulations而保持权重不变若权重在前、模型定义在后工具在仅修改模型文件时无需重新打包或重新对齐全部权重大幅降低操作成本。这实际上是把「数据与元数据分离、大块数据保持稳定偏移」的思路固化进了文件布局。Protobuf 定义层面的变更建议提案建议在 ONNX protobuf 定义中为TensorProto增加一个external_data字段增加optional string external_data到TensorProto该字段可类比float_data、int_data等数据字段处理要求这些数据字段中恰好只有一个被指定若某个TensorProto指定了external_data实现应通过字符串键在包含它的 zip 归档中解析该引用所有external_data的值必须唯一不区分大小写且符合C 标识符规范C identifier specification。值得说明的是该提案停留在历史 RFC 层面文档中自注 Status: unclear (historical)属于 RFC 流程中的早期设计探索docs/proposals/README.md 描述了 RFC 的完整生命周期。从当前仓库源码看主线并未实现__MODEL_PROTO式的 zip 容器但external_data的思想被继承并发展成了今天的外部数据External Data机制。在当前 onnx/onnx.in.proto 中TensorProto的实际字段设计为// 第 13 号字段external_data键值对列表而非提案中的单个字符串 repeated StringStringEntryProto external_data 13; // 第 14 号字段数据位置枚举 enum DataLocation { DEFAULT 0; // 数据存放在 protobuf 消息内部 EXTERNAL 1; // 数据存放在 external_data 描述的外部位置 } optional DataLocation data_location 14;其中StringStringEntryProtoonnx/onnx.in.proto采用跨 proto 版本通用的「字符串键值对」模式message StringStringEntryProto { optional string key 1; optional string value 2; };从提案的单一string字段演进为repeated StringStringEntryProto使其能够携带location、offset、length、checksum等多维描述信息详见下文「外部数据键值规范」表达能力远超最初设想。64 字节对齐内存映射的关键约束提案对归档中的原始数据文件提出了明确的布局要求Raw data files within the zip archive shall reside on an alignment boundary of 64 bytes.即归档内每个原始张量数据的首字节偏移必须能被 64 整除。该约束可以通过向 zip 本地文件记录local file record的extra字段填充字节来实现提案以 Android 的 zipalign 工具及其ZipAlign.cpp实现作为参照示例。这一设计服务于两个目的满足严格对齐架构的需求例如 SIMD 指令要求对齐数据才能高效或合法地操作充分利用缓存行对齐数据对于在缓存行对齐数据上运行更高效的架构可以发挥全部性能优势。配合整个文件按偏移直接映射权重即可「就地」使用无需先解压、再拷贝到内存这正是「直接内存映射 对齐」组合带来的核心收益。这一思想在落地版本中同样得到延续——外部数据规范要求offset值建议为页大小通常 4KB的倍数以启用 mmap 支持详见下文。文件扩展名与普通 Zip 区分提案建议沿用其他领域特定 zip 应用的惯例为 ONNX 归档使用自定义扩展名而非.zip。理由很直接自定义扩展名可以明确告知用户——这不是一个通用 zip 文件而是应当由 ONNX 工具按规范生成、符合规范的特定文件。同理ONNX 的外部数据文件也并非随意命名的二进制而是与模型文件配套、遵循固定键值规范的实体落地实现中默认以*.data等命名见下节。未来演进考量Future-Proofing提案认为该文件格式本质上是一个可扩展到大量条目与大体积值的通用键值存储因此具备良好的演进空间支持同一模型中多个模型定义或不同种类的模型定义修改权重文件的存储方式建立在成熟的归档格式zip之上同时获得其可靠性与灵活性。从当前仓库看这些「未来考量」中的一部分已经以另一种形态兑现外部数据机制支持all_tensors_to_one_file单一文件 vs 每张量一个文件两种存储布局支持size_threshold阈值控制哪些张量外置这正是「修改权重文件存储方式」的实践。从提案到落地ONNX External Data 实战虽然 zip 容器本身未进入主线但「数据外置 对齐 内存映射」的思想通过External Data 机制参考 onnx/onnx#678在 ONNX 中正式落地。以下是基于 docs/ExternalData.md 与源码的完整实战指南。外部数据键值规范与提案设想对应实际实现的external_data是一组键值对onnx/onnx.in.proto 中明确定义了识别的键键必选/可选含义与约束location必选相对于 ONNX protobuf 模型文件所在目录的文件路径禁止..等向上目录组件解析时应剥离offset可选数据起始字节位置以字符串形式的整数存储建议为页大小通常 4KB的倍数以启用 mmapWindows 上建议为 VirtualAlloc 分配粒度通常 64KB的倍数以支持内存映射length可选包含数据的字节数字符串形式的整数checksum可选location指定文件的 SHA1 摘要basepath加载后追加模型加载后实现会追加该键记录模型文件所在目录路径外部数据文件的字节格式与TensorProto.raw_data字段完全一致固定宽度、小端序浮点按 IEEE 754见 onnx/onnx.in.proto 的说明。加载带外部数据的模型默认情况外部数据与模型同目录直接使用onnx.load()即可import onnx onnx_model onnx.load(path/to/the/model.onnx)外部数据位于其他目录时先用load_external_data_for_model()指定目录加载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/) # 此时 onnx_model 已从指定目录加载外部数据其底层实现onnx/external_data_helper.py会遍历模型中所有张量对每个使用外部数据的张量按location打开文件描述符并根据offset/length做文件边界校验后读入raw_data加载完成后将data_location复位为DEFAULT并清空external_data列表使模型回到「内嵌数据」的普通状态。将模型转换为外部数据import onnx from onnx.external_data_helper import convert_model_to_external_data onnx_model ... # 内存中的 ModelProto convert_model_to_external_data(onnx_model, all_tensors_to_one_fileTrue, locationfilename, size_threshold1024, convert_attributeFalse) # 转换后必须调用 save_model 将模型保存到指定路径 onnx.save_model(onnx_model, path/to/save/the/model.onnx) # 模型原始数据已转换为外部数据并保存一步完成转换与保存import onnx onnx_model ... # 内存中的 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)关键参数语义源码级说明以上接口的参数在 onnx/external_data_helper.py 与 onnx/init.py 的save_model/load中实现含义如下all_tensors_to_one_file为True时所有张量写入location指定的单一外部文件未指定时默认使用 UUID 生成的*.data文件名为False时每个张量各自写入以张量名为文件名的独立文件非法文件名自动替换为 UUID。location外部文件相对模型路径的相对路径源码中明确校验——绝对路径会抛ValueError已存在的文件会抛FileExistsError对应提案「自定义、规范化的存储布局」思想。size_threshold数据大小阈值仅当张量raw_data长度 ≥ 阈值时才外置设为0可将所有含原始数据的张量全部转换。默认值1024。convert_attribute为False时仅转换 initializer权重张量为True时连同属性attribute中的张量一并转换。load_external_dataonnx.load参数默认True模型加载时是否自动加载外部数据为False时需手动调用load_external_data_for_model。带外部数据模型的校验import onnx onnx.checker.check_model(path/to/the/model.onnx) # 注意2GB 的模型不能使用 onnx.checker.check_model(loaded_onnx_model) 校验必须传模型路径小于 2GB 的模型checker 支持直接校验已加载的模型对象或模型路径大于 2GB 的模型必须传入模型路径进行校验且外部数据需与模型位于同一目录大模型无法整体载入内存是 protobuf 容量限制的延续与提案动机一脉相承。提案与落地实现的对照维度0001 提案zip 归档当前仓库落地External Data容器形态zip 归档__MODEL_PROTO位于末尾模型.onnx文件 外部*.data文件同目录或指定目录张量引用方式TensorProto.external_data字符串键TensorProto.external_datarepeated StringStringEntryProto键值对data_location枚举对齐约束64 字节对齐以支持直接内存映射offset建议页大小4KB倍数、Windows 64KB 粒度以支持 mmap扩展名自定义扩展名区分于通用 zip模型与外部数据文件分离由location键显式声明状态历史提案Status: unclear/historical主线实现onnx/external_data_helper.py、docs/ExternalData.md小结0001-ArchiveFileFormatProposal是一份具有前瞻性的格式设计文档它以 zip 为基座、以键值存储为抽象、以 64 字节对齐换取内存映射能力、以「模型定义置于归档末尾」换取权重不变时的轻量操作并在容量与序列化效率两个维度上直击当时 ONNX 的痛点。虽然 zip 容器方案最终未以原样进入主线但它的核心思想完整地沉淀到了今天广泛使用的 External Data 机制中——数据外置、对齐偏移、按需加载。对希望深度理解 ONNX 序列化设计、或需要在工程中处理超大模型的开发者而言将本文的提案设计与 onnx/external_data_helper.py、onnx/onnx.in.proto 对照阅读可以同时获得设计意图与实现细节的完整视图。赞分享人工智能深度学习机器学习【免费下载链接】onnxOpen standard for machine learning interoperability项目地址https://gitcode.com/gh_mirrors/onn/onnx点击查看免费下载相关推荐TBOOX/TBOX Zip压缩ZIP归档格式的多文件压缩TBOOX/TBOX Zip压缩ZIP归档格式的多文件压缩 概述 在现代软件开发中数据压缩是提升存储效率和网络传输性能的关键技术。TBOX作为一个跨平台的C后端基于 ADK 与 Agent Platform Search 的托管式 RAG Agent从 GCS Data Connector 到 Terraform 落地的完整实践基于 ADK 与 Agent Platform Search 的托管式 RAG Agent从 GCS Data Connector 到 Terraform 落示例工程手写 Arthas 外部命令External Command插件基于 arthas-demo-external-command 从零落地一个可热插拔的 demo-external 命令手写 Arthas 外部命令External Command插件基于 arthas demo external command 从零落地一个可热插拔的 d开发工具可观测性调试器性能剖析上一篇SSD-1B的5大实战应用场景从艺术创作到教育可视化AI绘图提效全指南下一篇Vue Property Decorator终极指南10个装饰器让TypeScript Vue开发更简单创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →