下面以relay_quick_start.py为例,详细解释relay的编译和运行过程
0 导入Relay和TVM
import numpy as np
from tvm import relay
from tvm.relay import testing
import tvm
from tvm import te
from tvm.contrib import graph_runtime
1 获取网络模型和参数
首先,用Relay python前端定义神经网络。为简单起见,在Relay中使用预定义的resnet-18网络,使用Xavier初始化程序初始化参数。Relay还支持其他模型格式,例如MXNet、CoreML、ONNX和Tensorflow。
本教程假设在GPU设备上进行推理,批大小为1,输入图像是大小为224 * 224的RGB彩色图像,可以调用tvm.relay.expr.TupleWrapper.astext()显示网络结构。
batch_size = 1
num_class = 1000
image_shape = (3, 224, 224)
data_shape = (batch_size,) + image_shape
out_shape = (batch_size, num_class)
mod, params = relay.testing.resnet.get_workload(
num_layers=18, batch_size=batch_size, image_shape=image_shape)
# set show_meta_data=True if you want to show meta data
print(mod.astext(show_meta_data=False))
说明
mod : tvm.relay.Module
The relay module that contains a ResNet network.
params : dict of str to NDArray
The parameters.
2 编译
下一步是使用Relay/TVM pipeline编译模型,可以指定编译的优化级别从0到3。优化过程包括算子融合、预计算、布局转换等。
relay.build的返回值包括三部分:json格式的执行图、该执行图在目标硬件上的已编译函数TVM模块库、模型参数。在编译过程中,Relay进行图级优化,而TVM进行张量级优化,由此得到模型的优化后运行时模块。
首先为Nvidia GPU进行编译。在这背后,relay.build_module.build首先执行许多图级优化,例如剪枝、融合等操作,然后将算子(即优化图的节点)注册到TVM实现中生成tvm.module。为了生成模块库,TVM首先将高级别IR转换为指定目标后端的内部IR,在此示例中目标后端为CUDA。然后,生成机器码模块库。
opt_level = 3
target = tvm.target.cuda()
with relay.build_config(opt_level=opt_level):
graph, lib, params = relay.build(mod, target, params=params)