microTVM 项目 API#

关于 microTVM 项目 API#

microTVM 项目 API 允许 TVM 自动在非常规或嵌入式平台上运行模型。它允许平台定义标准函数,将 TVM 编译器输出与样板特定代码集成,生成可运行的 Project。然后,Project API 进一步定义了构建该项目的函数,程序兼容的设备可以从 TVM 机器中访问,并与运行的代码通信,以便 TVM 可以执行基于主机的推理和自动调优。

有许多情况下,从您平台的构建过程中简单地调用 microTVM 可能是可取的。实际上,对于普通固件开发人员来说,这可能是他们所需的一切。然而,有几种用例需要您教会 microTVM 如何使用您平台的构建工具构建固件:

  1. 为了在您的平台上启用 AutoTVM 和 AutoScheduling。定义 Project API 实现允许 TVM 对您的平台进行模型调整,以实现最佳性能。

  2. 为了让没有固件专业知识的工程师在您的平台上实验模型。定义 Project API 实现允许这些工程师利用标准的 TVM Python 工作流,在您的平台上执行主机驱动的推断。

  3. 集成测试。定义 Project API 实现允许您创建持续集成测试,以验证模型在您的平台上的正确性和性能。

API 定义#

完整的 API 是在 python/tvm/micro/project_api/server.py 中定义的 ProjectAPIHandler 中的 abstractmethod。我们不会在此重复文档,而是简单地将您引用到该类。

TVM 如何使用 Project API#

本节将解释如何在 TVM 中使用 Project API。Project API 围绕“Project”作为可构建固件的单位进行定义。TVM 最初希望提供包含“模板项目”的目录,该目录可与 Model Library Format 文件一起构建为可运行的项目。

在“模板目录”中(通常)包含实现 API 服务器的 Python 脚本。TVM 在子进程中启动此脚本,并向服务器发送命令以执行上述每个操作。

典型的使用流程如下:

  1. 在模板项目中启动项目 API 服务器。

  2. 通过发送 server_info_query 命令,验证 API 服务器与 TVM 的版本兼容性,并读取实现的属性。

  3. 通过发送 generate_project 命令来生成新的项目。该命令的参数是模型库格式和不存在的目录,该目录应该被生成的项目填充。模板项目 API 服务器应该将自己复制到新生成的项目中。

  4. 终止模板项目 API 服务器。

  5. 在生成的项目中启动项目 API 服务器。

  6. 通过发送 server_info_query 命令,验证 API 服务器与 TVM 的版本兼容性,并读取实现的属性。

  7. 通过向 API 服务器发送 buildflash 命令来构建和烧录项目。

  8. 与目标通信。发送命令 open_transport,然后发送 write_transportread_transport 命令,以从连接到目标的串行端口中进行读写操作。完成后,发送 close_transport 命令。

  9. 终止 Project API 服务。

项目的磁盘布局#

在项目(模板或生成的)的根目录中,必须存在以下两个文件之一:

  • microtvm_api_server.py - 推荐的方法。将与 python3 兼容的 Python 脚本放置在根目录中。TVM 将使用执行 TVM 的相同解释器在其自己的进程中执行此脚本。

  • microtvm_api_server.sh (在 Windows 上是 microtvm_api_server.bat )- 另一种方法。当需要使用不同的 Python 解释器,或者当您想要用其他语言实现服务器时,请创建此可执行文件。TVM 将在单独的进程中启动此文件。

除了这两个文件之外,对布局没有做出任何其他限制。

TVM 和项目 API 服务器之间的通信。#

“TVM 使用 JSON-RPC 2.0 与项目 API 服务器进行通信。TVM 始终使用以下命令行启动 API 服务器:”

microtvm_api_server.py --read-fd <n> --write-fd <n>

TVM 向服务器发送命令,使用 --read-fd 给出的文件描述符,从服务器接收回复,使用 --write-fd 给出的文件描述符。

Python 实现 API 服务器的辅助工具#

“TVM 提供了辅助工具,使得在 Python 中实现服务器变得容易。要在 Python 中实现服务器,需要创建 microtvm_api_server.py,并添加 from tvm.micro.project_api import server (或者,将此文件复制到您的模板项目中–没有依赖项–并在那里导入它)。接下来,创建 ProjectAPIHander 的子类:

class Handler(server.ProjectAPIHandler):
    def server_info_query(self, tvm_version):
        # Implement server_info_query

    def generate_project(self, model_library_format_path, standalone_crt_dir, project_dir, options):
        # Implement generate_project

    # ...

最后,调用辅助函数 main():

if __name__ == "__main__":
    server.main(Handler())

tvmc 使用 Project API#

每个重要的 Project API 命令都可以通过 tvmc micro 子命令来进行调用,以使得调试交互更加简单。调用 tvmc micro --help 来获取更多信息。