测试自定义的 TVM 量化

测试自定义的 TVM 量化#

from configs import set_tool, set_env
from models import model_names, Calibrate, InputConfig, Model
from common.configs.frontend import from_frontend
from configs.create_config import Config
from tqdm import tqdm
import tvm
from tvm import relay
import toml
from d2py.utils.log_config import config_logging
# 配置日志消息
log_dir = ".temp"
config_logging(
    f"{log_dir}/test.log", 
    'debug',
    filter_mod_names={"vta", "te_compiler"}, # 过滤掉不需要记录日志的模块
    filemode="w",
)
with open("configs/model.toml") as fp:
    configs = toml.load(fp)
for model_name, config in configs.items():
    config = Config(**config)
    const = InputConfig(model_name)
    assert const.input_name == config.name
2024-02-18 16:53:15.404892: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2024-02-18 16:53:15.404960: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2024-02-18 16:53:15.406146: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2024-02-18 16:53:15.416229: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2024-02-18 16:53:16.616399: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
import numpy as np
import tvm
from tvm import relay
from tvm.relay import transform as _transform
from tvm.relay import expr as _expr
from tvm.relay import Call, Constant, Function
from tvm.ir.op import Op
from tvm.relay.dataflow_pattern import (
    is_constant, is_op, is_tuple, wildcard, 
    is_tuple_get_item
)
from tvm.relay.quantize.quantize import _bind_params
from tools.pattern.float import *
from tools.common import FuseTransform
compiler_name="vta_special"
pattern_table = [
    (f"{compiler_name}.conv2d_bias_relu_maxpool2d", make_conv2d_bias_relu_maxpool2d_pattern()),
    (f"{compiler_name}.conv2d_bias", make_conv2d_bias_pattern()),
    (f"{compiler_name}.dense_bias", make_dense_bias_pattern()),
    (f"{compiler_name}.elwise", make_elwise_pattern()),
]
merge_passes = tvm.transform.Sequential([
    _transform.InferType(),
    _transform.MergeComposite(pattern_table), # 融合算子
    _transform.InferType(),
    # _transform.PartitionGraph()
])
# "person_chair" 需要重写前端
for model_name, config in tqdm(configs.items()):
    if model_name in [
        # "resnet50_v2", "mobilenet_v2_tf", 
        "person", "new_person", "face_rec",
        "face_detection_580", "face_detection", "fd_quintina",
        "driver", # The following operators are not supported in frontend Caffe: 'Upsample'
        "fr_karen", "fr_madeline"]:
        continue
    config = Config(**config)
    if model_name == "resnet50_v2":
        # 加载前端模型
        if config.model_type == 'caffe': # caffe 前端模型
            caffe_model, prototxt = Model(config.model_type, model_name)()
            shape_dict = {config.name: config.shape}
            dtype_dict = {config.name: "float32"}
            mod, params = relay.frontend.from_caffe(caffe_model, prototxt, shape_dict, dtype_dict)
        elif config.model_type == 'torch': # PyTorch 前端模型
            import torch
            torch_model = Model(config.model_type, model_name)().eval()
            trace_model = torch.jit.trace(torch_model, torch.randn(*config.shape))
            mod, params = relay.frontend.from_pytorch(trace_model.eval(), [(config.name, config.shape)])
        elif config.model_type == 'onnx': # onnx 前端模型
            onnx_model = Model(config.model_type, model_name)()
            mod, params = relay.frontend.from_onnx(
                onnx_model, 
                {config.name: config.shape}, 
                "float32", opset=15, 
                freeze_params=True
            )
        else:
            raise TypeError(f"{config.model_type} 暂未支持")
        
        with tvm.transform.PassContext(opt_level=3):
            run_mod = relay.quantize.prerequisite_optimize(mod, params)
            run_mod_mg = merge_passes(run_mod)
            fuse_mod = FuseTransform()(run_mod_mg)
            tvm.IRModule.from_expr(fuse_mod["main"]).show()
        break
0%|          | 0/20 [00:00<?, ?it/s]
0%|          | 0/20 [00:24<?, ?it/s]
def @main(%data: Tensor[(1, 3, 299, 299), float32] /* ty=Tensor[(1, 3, 299, 299), float32] span=Conv__435.data:0:0 */) -> Tensor[(1, 1001), float32] {
  %0 = @vta_special.conv2d_bias_0(%data, meta[relay.Constant][0] /* ty=Tensor[(64, 3, 7, 7), float32] span=Conv__435.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/conv1/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 64, 150, 150), float32] */;
  %1 = nn.max_pool2d(%0, pool_size=[3, 3], strides=[2, 2], padding=[0, 0, 1, 1]) /* ty=Tensor[(1, 64, 75, 75), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/pool1/MaxPool:0:0 */;
  %2 = @vta_special.elwise_1(%1, meta[relay.Constant][1] /* ty=Tensor[(64, 1, 1), float32] */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %3 = @vta_special.conv2d_bias_3(%2, meta[relay.Constant][3] /* ty=Tensor[(64, 64, 1, 1), float32] */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %4 = @vta_special.conv2d_bias_4(%3, meta[relay.Constant][4] /* ty=Tensor[(64, 64, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_1/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_1/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %5 = @vta_special.conv2d_bias_2(%2, meta[relay.Constant][2] /* ty=Tensor[(256, 64, 1, 1), float32] */) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %6 = @vta_special.conv2d_bias_5(%4, meta[relay.Constant][5] /* ty=Tensor[(256, 64, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_1/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_1/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %7 = @vta_special.elwise_6(%5, %6) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %8 = @vta_special.elwise_7(%7, meta[relay.Constant][6] /* ty=Tensor[(256, 1, 1), float32] */) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %9 = @vta_special.conv2d_bias_8(%8, meta[relay.Constant][7] /* ty=Tensor[(64, 256, 1, 1), float32] */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %10 = @vta_special.conv2d_bias_9(%9, meta[relay.Constant][8] /* ty=Tensor[(64, 64, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_2/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_2/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %11 = @vta_special.conv2d_bias_10(%10, meta[relay.Constant][9] /* ty=Tensor[(256, 64, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_2/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_2/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %12 = @vta_special.elwise_11(%7, %11) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %13 = @vta_special.elwise_12(%12, meta[relay.Constant][10] /* ty=Tensor[(256, 1, 1), float32] */) /* ty=Tensor[(1, 256, 75, 75), float32] */;
  %14 = @vta_special.conv2d_bias_13(%13, meta[relay.Constant][11] /* ty=Tensor[(64, 256, 1, 1), float32] */) /* ty=Tensor[(1, 64, 75, 75), float32] */;
  %15 = @vta_special.conv2d_bias_14(%14, meta[relay.Constant][12] /* ty=Tensor[(64, 64, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_3/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_3/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 64, 38, 38), float32] */;
  %16 = nn.max_pool2d(%12, pool_size=[1, 1], strides=[2, 2], padding=[0, 0, 0, 0]) /* ty=Tensor[(1, 256, 38, 38), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_3/bottleneck_v2/shortcut/MaxPool:0:0 */;
  %17 = @vta_special.conv2d_bias_15(%15, meta[relay.Constant][13] /* ty=Tensor[(256, 64, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_3/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block1/unit_3/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 256, 38, 38), float32] */;
  %18 = @vta_special.elwise_16(%16, %17) /* ty=Tensor[(1, 256, 38, 38), float32] */;
  %19 = @vta_special.elwise_17(%18, meta[relay.Constant][14] /* ty=Tensor[(256, 1, 1), float32] */) /* ty=Tensor[(1, 256, 38, 38), float32] */;
  %20 = @vta_special.conv2d_bias_19(%19, meta[relay.Constant][16] /* ty=Tensor[(128, 256, 1, 1), float32] */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %21 = @vta_special.conv2d_bias_20(%20, meta[relay.Constant][17] /* ty=Tensor[(128, 128, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_1/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_1/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %22 = @vta_special.conv2d_bias_18(%19, meta[relay.Constant][15] /* ty=Tensor[(512, 256, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %23 = @vta_special.conv2d_bias_21(%21, meta[relay.Constant][18] /* ty=Tensor[(512, 128, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_1/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_1/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %24 = @vta_special.elwise_22(%22, %23) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %25 = @vta_special.elwise_23(%24, meta[relay.Constant][19] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %26 = @vta_special.conv2d_bias_24(%25, meta[relay.Constant][20] /* ty=Tensor[(128, 512, 1, 1), float32] */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %27 = @vta_special.conv2d_bias_25(%26, meta[relay.Constant][21] /* ty=Tensor[(128, 128, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_2/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_2/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %28 = @vta_special.conv2d_bias_26(%27, meta[relay.Constant][22] /* ty=Tensor[(512, 128, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_2/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_2/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %29 = @vta_special.elwise_27(%24, %28) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %30 = @vta_special.elwise_28(%29, meta[relay.Constant][23] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %31 = @vta_special.elwise_29(%30, meta[relay.Constant][24] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %32 = @vta_special.conv2d_bias_30(%31, meta[relay.Constant][25] /* ty=Tensor[(128, 512, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv1/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv1/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %33 = @vta_special.conv2d_bias_31(%32, meta[relay.Constant][26] /* ty=Tensor[(128, 128, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %34 = @vta_special.conv2d_bias_32(%33, meta[relay.Constant][27] /* ty=Tensor[(512, 128, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_3/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %35 = @vta_special.elwise_33(%29, %34) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %36 = @vta_special.elwise_34(%35, meta[relay.Constant][28] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %37 = @vta_special.elwise_35(%36, meta[relay.Constant][29] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 38, 38), float32] */;
  %38 = @vta_special.conv2d_bias_36(%37, meta[relay.Constant][30] /* ty=Tensor[(128, 512, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv1/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv1/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 38, 38), float32] */;
  %39 = @vta_special.conv2d_bias_37(%38, meta[relay.Constant][31] /* ty=Tensor[(128, 128, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 128, 19, 19), float32] */;
  %40 = nn.max_pool2d(%35, pool_size=[1, 1], strides=[2, 2], padding=[0, 0, 0, 0]) /* ty=Tensor[(1, 512, 19, 19), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/shortcut/MaxPool:0:0 */;
  %41 = @vta_special.conv2d_bias_38(%39, meta[relay.Constant][32] /* ty=Tensor[(512, 128, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block2/unit_4/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 512, 19, 19), float32] */;
  %42 = @vta_special.elwise_39(%40, %41) /* ty=Tensor[(1, 512, 19, 19), float32] */;
  %43 = @vta_special.elwise_40(%42, meta[relay.Constant][33] /* ty=Tensor[(512, 1, 1), float32] */) /* ty=Tensor[(1, 512, 19, 19), float32] */;
  %44 = @vta_special.conv2d_bias_42(%43, meta[relay.Constant][35] /* ty=Tensor[(256, 512, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %45 = @vta_special.conv2d_bias_43(%44, meta[relay.Constant][36] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_1/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_1/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %46 = @vta_special.conv2d_bias_41(%43, meta[relay.Constant][34] /* ty=Tensor[(1024, 512, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %47 = @vta_special.conv2d_bias_44(%45, meta[relay.Constant][37] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_1/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_1/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %48 = @vta_special.elwise_45(%46, %47) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %49 = @vta_special.elwise_46(%48, meta[relay.Constant][38] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %50 = @vta_special.conv2d_bias_47(%49, meta[relay.Constant][39] /* ty=Tensor[(256, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %51 = @vta_special.conv2d_bias_48(%50, meta[relay.Constant][40] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_2/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_2/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %52 = @vta_special.conv2d_bias_49(%51, meta[relay.Constant][41] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_2/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_2/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %53 = @vta_special.elwise_50(%48, %52) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %54 = @vta_special.elwise_51(%53, meta[relay.Constant][42] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %55 = @vta_special.conv2d_bias_52(%54, meta[relay.Constant][43] /* ty=Tensor[(256, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %56 = @vta_special.conv2d_bias_53(%55, meta[relay.Constant][44] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_3/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_3/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %57 = @vta_special.conv2d_bias_54(%56, meta[relay.Constant][45] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_3/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_3/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %58 = @vta_special.elwise_55(%53, %57) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %59 = @vta_special.elwise_56(%58, meta[relay.Constant][46] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %60 = @vta_special.conv2d_bias_57(%59, meta[relay.Constant][47] /* ty=Tensor[(256, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %61 = @vta_special.conv2d_bias_58(%60, meta[relay.Constant][48] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_4/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_4/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %62 = @vta_special.conv2d_bias_59(%61, meta[relay.Constant][49] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_4/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_4/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %63 = @vta_special.elwise_60(%58, %62) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %64 = @vta_special.elwise_61(%63, meta[relay.Constant][50] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %65 = @vta_special.conv2d_bias_62(%64, meta[relay.Constant][51] /* ty=Tensor[(256, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %66 = @vta_special.conv2d_bias_63(%65, meta[relay.Constant][52] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_5/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_5/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %67 = @vta_special.conv2d_bias_64(%66, meta[relay.Constant][53] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_5/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_5/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %68 = @vta_special.elwise_65(%63, %67) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %69 = @vta_special.elwise_66(%68, meta[relay.Constant][54] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 19, 19), float32] */;
  %70 = @vta_special.conv2d_bias_67(%69, meta[relay.Constant][55] /* ty=Tensor[(256, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 256, 19, 19), float32] */;
  %71 = @vta_special.conv2d_bias_68(%70, meta[relay.Constant][56] /* ty=Tensor[(256, 256, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_6/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_6/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 256, 10, 10), float32] */;
  %72 = nn.max_pool2d(%68, pool_size=[1, 1], strides=[2, 2], padding=[0, 0, 0, 0]) /* ty=Tensor[(1, 1024, 10, 10), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_6/bottleneck_v2/shortcut/MaxPool:0:0 */;
  %73 = @vta_special.conv2d_bias_69(%71, meta[relay.Constant][57] /* ty=Tensor[(1024, 256, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_6/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block3/unit_6/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1024, 10, 10), float32] */;
  %74 = @vta_special.elwise_70(%72, %73) /* ty=Tensor[(1, 1024, 10, 10), float32] */;
  %75 = @vta_special.elwise_71(%74, meta[relay.Constant][58] /* ty=Tensor[(1024, 1, 1), float32] */) /* ty=Tensor[(1, 1024, 10, 10), float32] */;
  %76 = @vta_special.conv2d_bias_73(%75, meta[relay.Constant][60] /* ty=Tensor[(512, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %77 = @vta_special.conv2d_bias_74(%76, meta[relay.Constant][61] /* ty=Tensor[(512, 512, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_1/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_1/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %78 = @vta_special.conv2d_bias_72(%75, meta[relay.Constant][59] /* ty=Tensor[(2048, 1024, 1, 1), float32] */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %79 = @vta_special.conv2d_bias_75(%77, meta[relay.Constant][62] /* ty=Tensor[(2048, 512, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_1/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_1/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %80 = @vta_special.elwise_76(%78, %79) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %81 = @vta_special.elwise_77(%80, meta[relay.Constant][63] /* ty=Tensor[(2048, 1, 1), float32] */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %82 = @vta_special.conv2d_bias_78(%81, meta[relay.Constant][64] /* ty=Tensor[(512, 2048, 1, 1), float32] */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %83 = @vta_special.conv2d_bias_79(%82, meta[relay.Constant][65] /* ty=Tensor[(512, 512, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_2/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_2/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %84 = @vta_special.conv2d_bias_80(%83, meta[relay.Constant][66] /* ty=Tensor[(2048, 512, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_2/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_2/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %85 = @vta_special.elwise_81(%80, %84) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %86 = @vta_special.elwise_82(%85, meta[relay.Constant][67] /* ty=Tensor[(2048, 1, 1), float32] */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %87 = @vta_special.conv2d_bias_83(%86, meta[relay.Constant][68] /* ty=Tensor[(512, 2048, 1, 1), float32] */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %88 = @vta_special.conv2d_bias_84(%87, meta[relay.Constant][69] /* ty=Tensor[(512, 512, 3, 3), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_3/bottleneck_v2/conv2/Conv2D.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_3/bottleneck_v2/conv2/Conv2D_weights_fused_bn:0:0 */) /* ty=Tensor[(1, 512, 10, 10), float32] */;
  %89 = @vta_special.conv2d_bias_85(%88, meta[relay.Constant][70] /* ty=Tensor[(2048, 512, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_3/bottleneck_v2/conv3/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/block4/unit_3/bottleneck_v2/conv3/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %90 = @vta_special.elwise_86(%85, %89) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %91 = @vta_special.elwise_87(%90, meta[relay.Constant][71] /* ty=Tensor[(2048, 1, 1), float32] */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %92 = @vta_special.elwise_88(%91, meta[relay.Constant][72] /* ty=Tensor[(2048, 1, 1), float32] */) /* ty=Tensor[(1, 2048, 10, 10), float32] */;
  %93 = nn.global_avg_pool2d(%92) /* ty=Tensor[(1, 2048, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/pool5:0:0 */;
  %94 = @vta_special.conv2d_bias_89(%93, meta[relay.Constant][73] /* ty=Tensor[(1001, 2048, 1, 1), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/logits/BiasAdd.resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/logits/Conv2D/ReadVariableOp:0:0:0 */) /* ty=Tensor[(1, 1001, 1, 1), float32] */;
  %95 = squeeze(%94, axis=[2, 3]) /* ty=Tensor[(1, 1001), float32] span=resnet_v2_50/StatefulPartitionedCall/resnet_v2_50/SpatialSqueeze:0:0 */;
  nn.softmax(%95, axis=1) /* ty=Tensor[(1, 1001), float32] span=resnet_v2_50/StatefulPartitionedCall/Softmax:0:0 */
}