【TVM教程】模块序列化指南

TON茶余饭后——TVM简单入门(一) 这里是全新的一次TVM入门课程,此前读者将TVM白皮书汉化后,效果并不理想。许多人没有足够的计算机底层水平,与逻辑理解的培训。所有就有了这个十分简洁的栏目,我们会根据源代码的片段内容通过十分透彻简洁的重点概括+举例子的方式讲解TON虚拟机的设计原理。原文TVM单元的定义:TVM的内存和持久化存储由单元(cells)组成。每个单元可以包含最多1023位的数据和最多四个对其他单元的引用。数据和引用的结构:从低级单元操作的角度来看,数据位和单元引用不会混合在一起。 阅读详情

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。

Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/

在部署 TVM 运行时模块时,无论目标是 CPU 还是 GPU,TVM 最终只需要一个动态共享库(dynamic shared library) 。实现这一点的关键就在于 统一的模块序列化机制。本文将介绍 TVM 模块序列化的格式标准与实现细节。

序列化(Serialization)​

入口 API 为 tvm.module.Module 的 export_library。在此函数内部,我们会执行以下步骤:

  1. 收集所有 DSO 模块(例如 LLVM 模块和 C 模块)。
  2. 在获得 DSO 模块后,调用 save 函数将它们保存到文件。
  3. 随后检查是否存在已导入的模块(imported modules),例如 CUDA、OpenCL 等。这里对模块类型不做限制。
    如果存在导入模块,我们将创建一个名为 devc.o / dev.cc 的文件(用于将这些导入模块的二进制数据打包进最终的动态库中),然后调用 _PackImportsToLLVM 或 _PackImportsToC 来执行模块序列化。
  4. 最后,调用 fcompile,其内部会调用_cc.create_shared,生成动态共享库。

备注

  1. 对于 C 源码模块(CSourceModule),我们会将它们编译并与 DSO 模块一同进行链接。
  2. 是否使用 _PackImportsToLLVM 或 _PackImportsToC取决于 TVM 是否启用了 LLVM。它们本质上实现的是相同的目标。

序列化底层机制与格式标准​

序列化主要发生在 _PackImportsToLLVM 或_PackImportsToC 中。它们都会调用 SerializeModule 来序列化 runtime module。在 SerializeModule 函数中,我们首先会构造一个辅助类 ModuleSerializer。它会以 module 为输入进行初始化,例如分配模块索引。随后可以调用其 SerializeModule 方法执行序列化。

为了更好地理解,让我们更深入地挖掘这个类的实现。

下面的代码用于构造 ModuleSerializer:

explicit ModuleSerializer(runtime::Module mod) : mod_(mod) {
  Init();
}
private:
void Init() {
  CreateModuleIndex();
  CreateImportTree();
}

在 CreateModuleIndex() 中,我们使用 DFS 遍历模块的导入关系并为每个模块分配索引。根模块固定为索引 0。

例如:

llvm_mod:imported_modules
  - cuda_mod

因此,LLVM 模块的索引将是 0,CUDA 模块的索引将是 1。

在构建完模块索引之后,我们将尝试构建导入树(CreateImportTree()),该导入树会在我们重新加载导出的库时用于恢复模块之间的导入关系。在我们的设计中,我们使用 CSR 格式来存储导入树,每一行对应父节点索引,而子数组中的索引对应其子模块索引。在代码中,我们使用 import_tree_row_ptr_ 和import_tree_child_indices_ 来表示它们。

在完成初始化之后,我们就可以使用 SerializeModule 函数来序列化模块。

在该函数的逻辑中,我们假设序列化格式如下所示:

binary_blob_size
binary_blob_type_key
binary_blob_logic
binary_blob_type_key
binary_blob_logic
...
_import_tree
_import_tree_logic

binary_blob_size 是我们在本次序列化步骤中将会包含的 blob 数量。在我们的示例中会有三个 blob,分别对应 LLVM 模块、CUDA 模块以及 _import_tree。

binary_blob_type_key 是模块的 blob 类型键。 对于 LLVM / C 模块,其 blob 类型键为 _lib。对于 CUDA 模块,其类型键为 cuda,可以通过 module->type_key() 获取。

binary_blob_logic 是处理该 blob 的逻辑。 对于大多数 blob(例如 CUDA、OpenCL),我们会调用 SaveToBinary 函数将 blob 序列化为二进制。然而,对于 LLVM / C 模块,我们只会写入 _lib,用于表示这是一个 DSO 模块。

备注
是否需要实现 SaveToBinary 虚函数取决于模块的使用方式。例如,如果模块中包含我们在重新加载动态共享库时需要的信息,那么我们就应该实现该函数。像 CUDA 模块,在重新加载动态共享库时我们需要将其二进制数据传递给 GPU 驱动,因此我们需要实现 SaveToBinary 来序列化其二进制数据。但对于主机侧模块(如 DSO 模块),在加载动态共享库时我们并不需要额外信息,因此不需要实现 SaveToBinary。不过,如果未来我们希望记录一些关于 DSO 模块的元信息,我们也可以为 DSO 模块实现 SaveToBinary。

最后,除非我们的模块中仅有一个 DSO 模块并且它位于根位置,否则我们会写入一个键 _import_tree。该键用于在重新加载导出的库时恢复模块导入关系,如前文所述。import_tree_logic 的内容则是将 import_tree_row_ptr_ 和 import_tree_child_indices_ 写入到流中。

在上述步骤完成后,我们会将最终结果打包进一个符号 runtime::symbol::tvm_ffi_library_bin,该符号可在动态库中恢复。

现在,我们已经完成序列化部分。正如你所看到的,我们理论上可以支持导入任意模块。

反序列化​

入口 API 是 tvm.runtime.load。实际上,该函数会调用 _LoadFromFile。 如果进一步展开,可以看到其对应的是 Module::LoadFromFile。

在我们的示例中,文件是 deploy.so。根据其函数逻辑,我们会在 dso_library.cc 中调用 module.loadfile_so,关键代码如下:

// Load the imported modules
const char* library_bin = reinterpret_cast<const char*>(
   lib->GetSymbol(runtime::symbol::tvm_ffi_library_bin));
Module root_mod;
if (library_bin != nullptr) {
   root_mod = ProcessLibraryBin(library_bin, lib);
} else {
   // Only have one single DSO Module
   root_mod = Module(n);
}```

如前所述,我们会将 blob 打包进符号 `runtime::symbol::tvm_ffi_library_bin`· 中。
在反序列化阶段,我们会检查它。如果存在 `runtime::symbol::tvm_ffi_library_bin`,我们将调用 `ProcessLibraryBin`,其逻辑如下:

```c++
READ(blob_size)
READ(blob_type_key)
for (size_t i = 0; i < blob_size; i++) {
    if (blob_type_key == "_lib") {
      // construct dso module using lib
    } else if (blob_type_key == "_import_tree") {
      // READ(_import_tree_row_ptr)
      // READ(_import_tree_child_indices)
    } else {
      // call module.loadbinary_blob_type_key, such as module.loadbinary_cuda
      // to restore.
    }
}
// Using _import_tree_row_ptr and _import_tree_child_indices to
// restore module import relationship. The first module is the
// root module according to our invariance as said before.
return root_module;

完成上述步骤后,我们会将 ctx_address 设置为 root_module, 以便能够从根模块查找符号(使所有符号可见)。

最终,我们就完成了反序列化部分。

如何在TVM上集成Codegen(下) 如何在TVM上集成Codegen(下) Bring DNNL to TVM: JSON Codegen/Runtime 现在实现将中继图序列化为JSON表示的DNNL codegen,然后实现DNNL JSON runtime来反序列化和执行该图。请注意,如果尝试实现codegen来生成C兼容的程序,可能需要直接进入下一节。 要使TVM中的DNNL JSON codegen/runtime在本例中工作,请确保DNNL在计算机上可用,并在中使用set(USE_DNNL_CODEGEN ON)构建TVM配置文件 阅读详情

相关推荐

TVM模型序列化详解:导出、加载与跨环境部署实践

在深度学习模型从训练走向生产部署的过程中,如何将编译后的模型产物固化、传输并恢复是工程落地的关键一环。以Apache TVM为代表的深度学习编译器将模型转换为统一的IR并进行优化,最终生成包含计算图、动态库与参数的运行时模块。模块序列化正是面对这三类产物进行规范编码、落盘与加载的技术体系,它直接决定了跨环境部署时模型能否被正确恢复并执行推理。掌握runtime.Module的导出与导入、参数编码规则(如save_param_dict/load_param_dict)以及交叉编译等要点,能显著降低部署风险。本

weixin_29029995的博客 226

TVM模型序列化:跨平台部署的关键技术

在深度学习模型部署过程中,你是否遇到过这些问题:训练好的模型在不同硬件设备间移植困难?相同模型在CPU、GPU和专用加速设备上需要重复适配?序列化(Serialization)技术正是解决这些痛点的关键。TVM(Tensor Virtual Machine)作为开源深度学习编译器栈,其独特的模块序列化机制实现了"一次编译,到处运行"的跨平台部署能力。本文将深入解析TVM模型序列化的技术原理、实现流...

gitblog_00677的博客 708

oVirt 4.4.10超详细安装指南:从零搭建企业级虚拟化环境(附常见错误排查)

本文提供了oVirt 4.4.10企业级虚拟化平台的超详细安装指南,涵盖环境规划、系统准备、Engine安装配置、计算节点部署、存储系统集成及高级运维技巧。通过实战操作手册和常见错误排查方法,帮助用户从零搭建稳定高效的虚拟化环境,特别适合企业IT管理员参考实施。

wasm7browser的博客 351

TVM 模块序列化机制深度解析:从 export_library 到统一动态库的二进制格式与加载还原

无论目标设备是 CPU 还是 GPU,TVM 在部署运行时模块时,最终都只需要**一个单一动态共享库**即可完成分发与加载,这背后依赖的是 TVM 统一的模块序列化(Module Serialization)机制。本文以 [docs/arch/introduction_to_module_serialization.rst](https://link.gitcode.com/i/c775fed65

gitblog_00339的博客 695

Qt制作大数据可视化大屏展示电子看板

Qt制作大数据可视化大屏展示电子看板 解决当前最火的大数据可视化大屏展示,整个项目通过Qt开发,集成了QML/QChart/ECharts及自定义控件等模块,所有的可视化控件都可以集成到其中。可以随意增加和减少模块,各个模块可以随意拖拽,整体可以个性化布局。模块标题栏可自定义,包括标题文本信息、文本颜色、宽度/高度、背景颜色、按钮个数等功能,满足各个样式需求。 实例中主要展示了现成的一些仪表盘...

Qt自定义控件及应用开发 7707

避开PSRR仿真三大坑:用Cadence psspxf分析分频器时,这些设置错了白忙活

本文深入探讨了使用Cadence psspxf工具进行分频器PSRR仿真时常见的三大技术陷阱,包括扰动信号参数设置、收敛性优化和后处理信号提取。通过详细的参数推荐和实战技巧,帮助工程师避免仿真误差,提升PSRR分析效率与准确性,特别适用于16分频器等数字-模拟混合电路设计。

weixin_29258297的博客 301

模块序列化简介

模块序列化简介 部署TVM运行时模块时,无论是CPU还是GPU,TVM都只需要一个动态共享库。关键是我们统一的模块序列化机制。本文档将介绍TVM模块序列化格式标准和实现细节。 模块导出实施例 让我们首先为GPU构建一个ResNet-18工作负载作为示例。 from tvm import relay from tvm.relay import testing from tvm....

weixin_42164269的博客 664

内部威胁论文阅读笔记(CMU-CERT专场)

在网上看了很多介绍该数据集的博客,一直有个疑问,这个数据集的标注在哪,本着先入为主的想法结合现有的资料对这个数据集的结构做了一下猜测(可能还是不严谨和正确)1.标注在哪2.什么是密集针模型3.场景文章连接内部人员由于可以绕过安全检测发起攻击,通常最有害的攻击被认为是内部人员发起。通过分析用户行为来检测内部威胁,主要分析一些类时间和活动进行特征选择。选择特征向量用于训练。采用cmu-certr4.2用于训练。提出的算法与。

Jerry的博客 2803

模块序列化介绍

部署TVM运行时模块时,无论是CPU还是GPU, TVM只需要一个动态共享库即可。关键是我们统一的模块序列化机制。本文档将介绍TVM模块序列化格式标准及实现细节。让我们先为构建一个ResNet-18 GPU 工作负载作为例子。 序列化 入口API是tvm.module.Module的export_library。在这个函数中,我们将执行以下步骤:1. 收集所有DSO模块(LLVM模块和C模块)2. 一旦我们有了DSO模块,我们将调用保存函数将它们保存到文件中。3. 接下来,我们将检查是否导入了模块,

zx_ros的博客 453

软考中级-软件设计师 23种设计模式(最详细解析!!)

软考中级-软件设计师 23种设计模式

片言可决讼,半纸能缚龙 2万+

Claude Code本地Windows安装教程

本文介绍了在Windows系统上安装和配置Claude Code本地调用的详细步骤。首先需要确保网络畅通和账号余额充足,然后安装Node.js v22版本作为基础环境。接着通过npm全局安装Claude Code包,并进行版本验证。安装完成后,使用命令行登录并可以指定模型启动。最后还提供了切换API秘钥的方法,通过setup-token命令重新授权账号。整个过程配有详细的命令行示例和操作截图,方便用户按步骤完成安装配置。

猿小白的博客 2万+

Apache TVM Python API参考大全:27个核心模块使用详解

Apache TVM是一个开源的深度学习编译器,适用于CPU、GPU、ARM等多种硬件架构,旨在使机器学习工程师能够在任意硬件后端高效地运行并优化计算。TVM的Python API提供了丰富的功能接口,让开发者能够灵活地进行模型编译、优化和部署。本文将为您详细解析TVM的27个核心Python模块,帮助您快速掌握这个强大的深度学习编译框架。🚀 ## 一、TVM Python API架构概览

gitblog_00922的博客 859

【虚拟仿真】Unity3D中实现对大疆无人机遥控器手柄按键响应

最近项目中需要用到大疆无人机遥控器对程序中无人机进行控制,遥控器是下图这一款:博主发现接入手柄这块的可以参考的内容非常少,对于大疆遥控器的控制更是没有。博主经过一番研究,终于理通了这块的遥控器摇杆数据的控制。并且将解决思路分享出来,希望对大家有所帮助。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2819

【TVM教程】TVM 运行时系统

TVM 现已更新到 0.21.0 版本,TVM 中文文档已经和新版本对齐。 Apache TVM 是一个深度的深度学习编译框架,适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →Apache TVM

HyperAI超神经 1019

手把手教你学基带SOC芯片(4.4.9)--基带芯片的电源管理实例:高通 Snapdragon 系列实例(十)

Snapdragon 888 通过支持多种深度睡眠模式,如 AOAC 模式、低功耗模式和深度睡眠模式,以及智能电源管理技术,实现了对功耗的精细管理。这些模式不仅延长了设备的电池寿命,还确保了用户在各种使用场景下的良好体验。无论是保持网络连接、限制后台活动,还是完全关闭不必要的功能,Snapdragon 888 都能够灵活应对,提供高效的功耗管理方案。

MHD0815的博客 740

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TVM模块序列化:深度学习模型部署的关键技术

在深度学习编译器领域,序列化是将优化后的计算图、参数和运行时信息打包成可独立分发的二进制文件的过程,类似于将咖啡豆研磨封装成胶囊。TVM(Tensor Virtual Machine)作为端到端的深度学习模型优化框架,其模块序列化功能是模型部署流程中的关键环节。TVM提供了`export_library`接口作为序列化的主要入口,支持生成动态共享库(DSO)、静态库或混合格式。序列化技术在边缘计算、移动端应用和服务器部署等场景中具有重要价值,能够显著减少模型部署包体积并提升加载速度。通过合理配置序列化参数,

weixin_32183107的博客 340

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

TVM tvm.exec 命令行工具模块完全指南:RPC 服务、Tracker 调度与性能基准

`tvm.exec` 是 TVM(Open Machine Learning Compiler Framework)中存放"可直接通过命令行运行的可执行 Python 脚本"的模块,其模块 docstring 明确写道"Namespace of executables python files that directly run throw cmd"。它不提供可供 import 的业务 API,而

gitblog_00276的博客 712

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

解决90%部署难题:TVM模型序列化全流程解析与最佳实践

你是否还在为深度学习模型部署时的兼容性问题头疼?当需要将训练好的模型从开发环境迁移到生产服务器,或是在不同硬件设备间移植时,是否经常遇到格式不兼容、性能下降或依赖冲突?TVM(Tensor Virtual Machine)的Module序列化机制为这些问题提供了优雅的解决方案。本文将带你深入了解TVM模型序列化的核心原理,掌握Module保存与加载的全流程,并通过实战案例学会如何在实际项目中应用这

gitblog_00532的博客 450

TVM运行系统

TVM运行系统 TVM支持多种编程语言用于编译器堆栈的开发和部署。在本说明中,我们解释了TVM运行时的关键元素。 转存失败重新上传取消 我们需要满足很多有趣的要求: 部署:从python / javascript / c ++语言调用已编译的函数。 调试:在python中定义一个函数,然后从已编译函数调用该函数。 链接:编写驱动程序代码以调用设备专用代码(CUDA)...

weixin_42164269的博客 1579

TVM模块序列化全解析:从export_library到load_module的部署实战

在深度学习模型部署中,TVM模块序列化是跨环境、跨设备落地时不可绕过的一环。无论是Relay构建的可执行库,还是AutoTVM调优后的产物,最终都需要通过标准接口导出为可复用的文件。序列化保存的并非视觉上的“模型文件”,而是经过编译的运行时程序,包含IR、图结构、权重参数及系统依赖等多层信息。掌握`export_library`与`load_module`的正确用法,理解权重内嵌与外置的利弊,有助于在边缘端推理、模型热更新和多设备分发场景中避免常见陷阱。本文从模块序列化的概念与原理出发,结合实际工程经验,梳

weixin_29056101的博客 213

TVM 模块序列化机制深度解析:从 `export_library` 到单文件动态库部署

无论是面向 CPU 还是 GPU 部署,TVM 最终只需要一个**动态共享库**(.so / .dll / .dylib)即可承载完整的运行时模块,这背后的关键支撑正是**统一的模块序列化机制**。本文以官方架构文档 [docs/arch/introduction_to_module_serialization.rst](https://link.gitcode.com/i/7707dab66a6

gitblog_00876的博客 42

C++ TVM stack 继续

继续分析构成。

zhuqiyua的博客 958

TVM VS TensorRT推理速度比较

上个结果对比框架平均推理时间(ms)最大推理时间(ms)最小推理时间(ms)TensorRT0.31950.63370.3023TVM Base0.76721.64670.6861TVM Tune0.56521.06230.5562费了九牛二虎之力调优出来的模型还是比不过TensorRT的推理速度,七小时调优只减少0.2ms的推理时间,但起码模型的稳定性得到了提升还是有些许安慰的.

shelgi的博客 2143

Apache TVM tvm.ir 模块全解析:贯穿 TIR / Relax 的公共 IR 数据结构与 API 参考

`tvm.ir` 是 Apache TVM 编译器中"跨所有 IR 变体共用"的基础数据结构层,它定义了表达式、类型、函数、属性(Attribute)、算子注册表以及 `IRModule` 容器等核心构件,是 TIR、Relax、TE 等上层 IR 的公共地基。本文以仓库中 [docs/reference/api/python/ir.rst](https://link.gitcode.com/i/

gitblog_00484的博客 178

TVM Object类型系统

Object用于保存数据,ObjectPtr用于内存管理,ObjectRef表示引用并对数据进行操作。

Albdon的博客 935

深入解析 TVM DSOModule 插件模块:从 C++ 源码到 Python 加载的完整实战指南

TVM 的 DSOModule(Dynamic Shared Object Module)允许开发者编写独立的 C++ 动态库,并直接通过 `tvm.runtime.load_module` 加载到 TVM 运行时中使用。本指南以仓库 [apps/dso_plugin_module](https://link.gitcode.com/i/cf9b93efccdc6d30694c479c45c582

gitblog_00393的博客 325
上一篇: 【Triton 教程】triton_language.where
下一篇: 在线教程丨GLM-Image基于自回归+扩散解码器混合架构,精准理解指令写对文字
HyperAI超神经
博客等级 码龄7年 8872粉丝 1753原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值