TVM编译器推理加速模型


一、TVM

TVM是一个开源的端到端优化机器学习编译器,目的是加速模型在任意硬件上的计算。
一般情况下如果实在intel的cpu上面部署可能用OpenVino,N卡上面肯定TensorRT,arm架构机器可能会用Ncnn等,意味着要针对每个框架做部署,这里面涉及到的转换非常复杂,部署过的就知道有多少坑在里面。而TVM最重要的一块就是自动生成和优化模型的基础架构,具有更好的性能,这张图简单说就是不管你什么深度学习框架不管什么硬件部署都能通过TVM搞定。
编译器的基本结构如下:
编译前端: 接收C/C++/Java等不同语言,进行代码生成,吐出IR,TVM这里相当于是输入模型的环节
编译器中端:接收IR,进行不同编译器后端可以共享的优化,如常量替换,死代码消除,循环优化等,吐出优化后的IR
编译器后端:接收优化后的IR,进行不同硬件的平台相关优化与硬件指令生成,吐出目标文件

在这里插入图片描述

二、示例代码

示例代码使用的同样是最简单的mobilenet_v3分类模型,是使用pytorch训练然后转onnx,可以参考前面几个文章有详细代码https://blog.csdn.net/Y_snower/article/details/125443366,首先安装tvm相关环境。我这里是python3.7 tvm1.0.0 onnx1.10.0

1.TVM文件生成

代码中针对tuning_option,在官方文档中这样说的For a production job, you will want to set the number of trials to be larger than the value of 20 used here. For CPU we recommend 1500, for GPU 3000-4000. The number of trials required can depend on the particular model and processor, so it’s worth spending some time evaluating performance across a range of values to find the best balance between tuning time and model optimization.
对cpu和gpu给出了不同的推荐值,实测下来选择不同的值对最终的推理速度也有影响。
代码如下:

import tvm.auto_scheduler as auto_scheduler
from tvm.autotvm.tuner import XGBTuner
from tvm import autotvm
import onnx
import numpy as np
import tvm
from tvm import relay


onnx_model = onnx.load('tiankong.onnx')  # 加载onnx模型,当然也可以用tvmc来load
target = tvm.target.Target('llvm -mcpu=skylake')  # 因为是cpu上的优化,所以llvm,GPU的话是cuda
# target = tvm.target.Target('llvm -mcpu=core-avx2')
input_name = 'input'
shape_dict = {input_name: (1, 1, 128, 128)}  # 输入的shape,因为之前一直训练的灰度所以是1,1不是1,3
mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)
number = 10
repeat = 1
min_repeat_ms = 0
timeout = 10
# create a TVM runner
# min_repeat_ms is a value that specifies how long need to run configuration test. If the number of repeats falls under this time, it will be increased. This option is necessary for accurate tuning on GPUs, and is not required for CPU tuning. Setting this value to 0 disables it.
runner = autotvm.LocalRunner(
    number=number,  # number specifies the number of different configurations that we will test
    repeat=repeat,  # repeat specifies how many measurements we will take of each configuration
    timeout=timeout,  # in seconds,The timeout places an upper limit on how long to run training code for each tested configuration.
    min_repeat_ms=min_repeat_ms,  
    enable_cpu_cache_flush=True,
)

#以下这部分是计算优化
tuning_option = {
    "tuner": "xgb",
    "trials": 1500,
    "early_stopping": 100,
    "measure_option": autotvm.measure_option(
        builder=autotvm.LocalBuilder(build_func="default"), runner=runner  # 默认的是XGBOOST优化
    ),
    "tuning_records": "resnet-50-v2-autotuning.json",  # 这里名称自己写,官方示例这样的我没改无所谓
}
# begin by extracting the tasks from the onnx model
tasks = autotvm.task.extract_from_program(mod["main"], target=target, params=params)

# Tune the extracted tasks sequentially.
for i, task in enumerate(tasks):
    prefix = "[Task %2d/%2d] " % (i + 1, len(tasks))
    tuner_obj = XGBTuner(task, loss_type="rank")
    tuner_obj.tune(
        n_trial=min(tuning_option["trials"], len(task.config_space)),
        early_stopping=tuning_option["early_stopping"],
        measure_option=tuning_option["measure_option"],
        callbacks=[
            autotvm.callback.progress_bar(tuning_option["trials"], prefix=prefix),
            autotvm.callback.log_to_file(tuning_option["tuning_records"]),
        ],
    )

with autotvm.apply_history_best(tuning_option["tuning_records"]):
    with tvm.transform.PassContext(opt_level=3):
        graph, lib, params = relay.build(mod, target, params=params)       
# 输出TVM需要的三个文件
from tvm.contrib import graph_runtime
libpath = "test.so"
lib.export_library(libpath)
graph_json_path = 'test.json'
with open(graph_json_path, 'w') as f:
    f.write(graph)

param_path = "./test.params"
with open(param_path, 'wb') as fo:
    fo.write(relay.save_param_dict(params))

2.TVM推理

代码如下:

import time
import numpy as np
import tvm
import tvm.relay as relay
from tvm.contrib import graph_runtime
import cv2


def preprocess(img):
    h, w = img.shape[:2]
    if h < w:
        distance = int((w - h) / 2)
        img = cv2.copyMakeBorder(img, distance, distance, 0, 0, cv2.BORDER_CONSTANT, value=0)
    else:
        distance = int((h - w) / 2)
        img = cv2.copyMakeBorder(img, 0, 0, distance, distance, cv2.BORDER_CONSTANT, value=0)
    img = cv2.resize(img, (128, 128), cv2.LINE_AA)
    img = img.astype(np.float32) / 255.0
    img = img[np.newaxis, np.newaxis, :, :]
    img = np.array(img, dtype=np.float32)
    return img


if __name__ == "__main__":
    test_json = "test.json"
    test_lib = "test.so"
    test_params = "test.params"
    loaded_json = open(test_json).read()
    loaded_lib = tvm.runtime.load_module(test_lib)
    loaded_params = bytearray(open(test_params, 'rb').read())

    img = cv2.imread("my_test.jpg", 0)
    img_input = preprocess(img)  # 预处理方法,按照自己的方法改造
    ctx = tvm.cpu(0)
    module = graph_runtime.create(loaded_json, loaded_lib, ctx)
    module.load_params(loaded_params)
    start = time.time()
    for i in range(1000):
        module.set_input("input", img_input)
        module.run()
        out_deploy = module.get_output(0).numpy()
        out = np.argmax(out_deploy)  # 输出分类结果,我这里二分类输出0或者1的值
        # print(out_deploy, out)
    print(time.time()-start)

总结

从推理测试结果来看,如果不做优化自动搜索参数这一步,在cpu上循环识别1000次大概4ms/次,优化后的速度在2.7ms/次,后面会把代码上传至 https://github.com/Ysnower/pytorch-static-quant C++的推理后期会写,如有错误之处望指正。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: TVM编译器TDA4是针对德州仪器(Texas Instruments)公司的TDA4芯片设计的。TVM是一个深度学习优化器和编译器的开源项目,它的目标是提供一个统一的、高效的方式来优化和部署深度学习模型TVM能够将深度学习模型转换为高度优化的代码,以提高在边缘设备上的性能和功耗效率。 TDA4芯片是德州仪器公司的一款基于Arm Cortex-A72和Cortex-M4核心的集成芯片,主要用于高级驾驶辅助系统(ADAS)和自动驾驶汽车等应用。TDA4芯片具有强大的计算能力和丰富的外设接口,因此需要一种高效的编译器来优化和部署复杂的深度学习算法。 TVM编译器可以将深度学习模型转换为TDA4芯片所需的代码,从而充分利用芯片的计算能力。编译器会对模型进行优化,包括自动图优化、内核融合、量化和布局等。这些优化技术能够减少计算和存储的复杂性,提高模型在TDA4芯片上的执行效率。 使用TVM编译器进行深度学习模型的编译能够带来多方面的好处。首先,优化后的模型可以更快地执行,提高系统的实时性能。其次,编译器能够自动进行硬件和算法的匹配,降低了开发人员的工作量。另外,TVM的开放性和活跃的社区使得它能够持续更新和改进,适应不同硬件平台和算法的需求。 总而言之,TVM编译器TDA4是为提高TDA4芯片上深度学习模型的性能和功耗效率而设计的。它能够将深度学习模型转换为优化后的代码,从而充分利用TDA4芯片的计算能力。使用TVM编译器能够加速深度学习应用的部署过程,并提供高效的解决方案。 ### 回答2: TVM编译器是一种用于将深度学习模型优化和编译到不同硬件平台的开源编译器TVM编译器的目标是提高深度学习模型在不同硬件上的性能和效率。 TVM编译器支持多种硬件平台,其中包括TDA4芯片。TDA4芯片是一款基于Arm架构的嵌入式处理器,广泛应用于自动驾驶和智能交通等领域。TDA4芯片具有高性能和低功耗的特点,适用于处理复杂的深度学习模型TVM编译器通过将深度学习模型转换为高效的计算图表达,从而实现模型的优化和编译。它采用了多种编译技术,例如图优化、内核融合和自动并行化,以提高模型的执行效率,并充分发挥硬件平台的性能。 在TDA4芯片上使用TVM编译器可以带来许多好处。首先,它可以充分利用TDA4芯片的计算能力和存储资源,提高模型推理速度和响应时间。其次,TVM编译器可以自动地将模型转换为适合TDA4芯片的代码,并利用硬件特性进行优化,从而减少计算和内存消耗。此外,TVM编译器还提供了灵活的接口和工具,使开发者能够方便地部署和调试深度学习模型。 总而言之,TVM编译器是一种强大的工具,可以将深度学习模型优化和编译到TDA4芯片等不同硬件平台上,提高模型的性能和效率。通过使用TVM编译器,开发者可以更好地利用TDA4芯片的计算能力,实现更快速、高效的深度学习应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序鱼鱼mj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值