前言
??本篇文章介绍一下 tvm 在linux 环境下的安装与编译,以及如何使用vscode 来配置tvm 的远程连接调试环境。
??所需软硬件环境:
环境 | 版本 |
---|
local system | windows 10 | service system | ubuntu 18.04 | tvm | latest(0.9.dev0) | python(conda) | python 3.8.13 | local IDE | vscode |
1. 安装TVM
1.1 下载源码
git clone --recursive https://github.com/apache/tvm tvm
https://tvm.apache.org/download
1.2 创建虚拟环境及安装依赖库
??使用conda 创建tvm 的虚拟python 环境,python 版本为3.8 ,虚拟环境名为tvmenv :
conda create -n tvmenv python=3.8
??编辑tvm 目录下的conda/build-environment.yaml 文件:
name: tvmenv
channels:
- anaconda
- conda-forge
??执行下面的指令,将构建tvm 所需的环境依赖更新到当前虚拟环境中:
conda env update -f conda/build-environment.yaml
如果上述命令执行较慢,可以将conda 换成国内源(建议使用北京外国语大学的开源镜像站):参考连接 然后修改conda/build-environment.yaml 文件:
channels:
- defaults
??安装python 依赖库:
pip install decorator tornado psutil 'xgboost<1.6.0' cloudpickle -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install onnx onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install torch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
??在当前虚拟环境中添加用于tvm debug 的环境变量:
conda env config vars set TVM_LOG_DEBUG="ir/transform.cc=1,relay/ir/transform.cc=1"
??使用这种方式设置环境变量的好处是:只有当前环境被激活(conda activate) 时,自定义设置的环境变量才起作用,当conda deactivate 后自定义的环境变量会自动清除。 ??当然,也可以更简单粗暴一些:
export TVM_LOG_DEBUG="ir/transform.cc=1,relay/ir/transform.cc=1"
??在当前虚拟环境中添加用于tvm python 的环境变量:
export TVM_HOME=your tvm path
export PYTHONPATH=$TVM_HOME/python:${PYTHONPATH}
1.3 编译TVM源码
??在tvm 目录下创建build 文件夹,并将cmake/config.cmake 文件复制到此文件夹中:
mkdir build
cp cmake/config.cmake build/
??编辑build/config.cmake 进行相关配置:
set(USE_LLVM ON)
set(USE_RELAY_DEBUG ON)
set(CMAKE_BUILD_TYPE Debug)
??编译tvm ,这里开启了16 个线程:
cd build
cmake ..
make -j 16
??大约5 分钟,即可生成我们需要的两个共享链接库:libtvm.so 和 libtvm_runtime.so
1.4 验证安装是否成功
??tvm 版本验证:
import tvm
print(tvm.__version__)
??pytorch 模型验证:
import tvm
from tvm import relay
from tvm.contrib.download import download_testdata
import numpy as np
import torch
import torchvision
model_name = "resnet18"
model = getattr(torchvision.models, model_name)(pretrained=True)
model = model.eval()
input_shape = [1, 3, 224, 224]
input_data = torch.randn(input_shape)
scripted_model = torch.jit.trace(model, input_data).eval()
from PIL import Image
img_path = 'cat.png'
img = Image.open(img_path).resize((224, 224))
from torchvision import transforms
my_preprocess = transforms.Compose(
[
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
]
)
img = my_preprocess(img)
img = np.expand_dims(img, 0)
input_name = "input0"
shape_list = [(input_name, img.shape)]
mod, params = relay.frontend.from_pytorch(scripted_model, shape_list)
target = tvm.target.Target("llvm", host="llvm")
dev = tvm.cpu(0)
with tvm.transform.PassContext(opt_level=3):
lib = relay.build(mod, target=target, params=params)
from tvm.contrib import graph_executor
dtype = "float32"
m = graph_executor.GraphModule(lib["default"](dev))
m.set_input(input_name, tvm.nd.array(img.astype(dtype)))
m.run()
tvm_output = m.get_output(0)
synset_path = 'imagenet_synsets.txt'
with open(synset_path) as f:
synsets = f.readlines()
synsets = [x.strip() for x in synsets]
splits = [line.split(" ") for line in synsets]
key_to_classname = {spl[0]: " ".join(spl[1:]) for spl in splits}
class_path = 'imagenet_classes.txt'
with open(class_path) as f:
class_id_to_key = f.readlines()
class_id_to_key = [x.strip() for x in class_id_to_key]
top1_tvm = np.argmax(tvm_output.numpy()[0])
tvm_class_key = class_id_to_key[top1_tvm]
with torch.no_grad():
torch_img = torch.from_numpy(img)
output = model(torch_img)
top1_torch = np.argmax(output.numpy())
torch_class_key = class_id_to_key[top1_torch]
print("Relay top-1 id: {}, class name: {}".format(top1_tvm, key_to_classname[tvm_class_key]))
print("Torch top-1 id: {}, class name: {}".format(top1_torch, key_to_classname[torch_class_key]))
2. 配置vscode
??安装两个vscode 远程连接所需的两个插件,具体如下图所示:
??安装完成之后,在左侧工具栏会出现一个图标,点击图标进行ssh 配置:
ssh yourname@yourip -A
??然后右键选择在当前窗口进行连接:
??除此之外,还可以设置免费登录,具体可参考这篇文章。
3. 安装FFI Navigator
??由于TVM 是由Python 和C++ 混合开发,且大多数的IDE 仅支持在同一种语言中查找函数定义,因此对于跨语言的FFI 调用,即Python 跳转到C++ 或者C++ 跳转到Python ,vscode 是做不到的。虽然解决这个问题在技术上可能非常具有挑战性,但我们可以通过构建一个与FFI 注册码模式匹配并恢复必要信息的项目特定分析器来解决这个问题,FFI Navigator 就这样诞生了,作者仍然是陈天奇博士。
??安装方式如下:
git clone https://github.com/tqchen/ffi-navigator.git
cd python
python setyp.py install
??vscode 需要安装FFI Navigator 插件,直接搜索安装即可(安装到服务器端)。 ??最后需要在.vscode/setting.json 进行配置,内容如下:
{
"python.analysis.extraPaths": [
"${workspaceFolder}/python"
], // 添加额外导入路径, 告诉pylance自定义的python库在哪里
"ffi_navigator.pythonpath": "/home/liyanpeng/anaconda3/envs/tvmenv/bin/python", // 配置FFI Navigator
"python.defaultInterpreterPath": "/home/liyanpeng/anaconda3/envs/tvmenv/bin/python",
"files.associations": {
"type_traits": "cpp",
"fstream": "cpp",
"thread": "cpp",
"*.tcc": "cpp"
}
}
??更详细内容可以参考项目链接。
结束语
??对于vscode 的使用技巧及C/C++ 相关的配置,这里不再详细的介绍了,感兴趣的小伙伴们可以了解下。
|