在 VTA 上自动调优卷积网络
备注
单击 此处 下载完整的示例代码
作者:Lianmin Zheng, Thierry Moreau
为特定加速器设计自动调优,对于获取任何给定算子的最佳性能至关重要。本教程展示如何在 VTA 上调优整个卷积网络。
TVM 中 VTA 的算子实现是用 template 形式编写的。该 template 有许多可调 knobs(平铺因子、虚拟线程等)。对神经网络中的所有卷积算子进行调优。调优后,会生成一个日志文件,存储所有调优算子的最佳 schedule 参数。TVM 编译器编译这些算子时,会查询这个日志文件,从而获得最佳的 knob 参数。
安装依赖
要在 TVM 中使用 autotvm 包,需要安装额外的依赖(如果用的是 Python2,请将「3」更改为「2」):
pip3 install --user psutil xgboost tornado mxnet requests "Pillow<7" cloudpickle
为了让 TVM 在调优过程中运行更快,推荐使用 Cython 作为 TVM 的 FFI。在 TVM 的根目录下,执行如下命令(若用的是 Python2,将「3」改为「2」):
pip3 install --user cython
sudo make cython3
在 Python 代码中导入包:
import os
from mxnet.gluon.model_zoo import vision
import numpy as np
from PIL import Image
from tvm import topi
import tvm
from tvm import te
from tvm import rpc, autotvm, relay
from tvm.contrib import graph_executor, utils, download
from tvm.autotvm.measure.measure_methods import request_remote
from tvm.autotvm.tuner import XGBTuner, GATuner, RandomTuner, GridSearchTuner
import vta
from vta.testing import simulator
from vta.top import graph_pack
编译网络
用来自 Gluon 模型的 Relay 执行特定于 VTA 的编译:
def compile_network(env, target, model, start_pack, stop_pack):
# 填充 shape 和数据类型字典
dtype_dict = {"data": "float32"}
shape_dict = {"data": (env.BATCH, 3, 224, 224)}
# 下架 gluon 模型,并转换为 Relay
gluon_model = vision.get_model(model, pretrained=True)
mod, params = relay.frontend.from_mxnet(gluon_model, shape_dict)
# 更新 shape 和类型字典
shape_dict.update({k: v.shape for k, v in params.items()})
dtype_dict.update({k: str(v.dtype) for k, v in params.items()})
# 在 Relay 中执行量化
# 注意:将 opt_level 设置为 3,折叠 batch norm
with tvm.transform.PassContext(opt_level=3):
with relay.quantize.qconfig(global_scale=8.0, skip_conv_layers=[0]):
mod = relay.quantize.quantize(mod, params=params)
# 对 VTA target 进行图打包和常量折叠
if target.device_name == "vta":
assert env.BLOCK_IN == env.BLOCK_OUT
relay_prog = graph_pack(
mod["main"],
env.BATCH,
env.BLOCK_OUT,
env.WGT_WIDTH,
start_name=start_pack,
stop_name=stop_pack,
)
return relay_prog, params