TVM 執行提供程式
TVM 是一個基於 Apache TVM 構建的 ONNX Runtime 執行提供程式。它允許 ONNX Runtime 使用者利用 Apache TVM 的模型最佳化。TVM EP 目前處於“預覽”階段。它已在 Linux 和 Windows 上透過少量模型的測試,但在 MacOS 上尚未測試。
目錄
使用 TVM 執行提供程式構建 ONNX Runtime
Linux
在 Ubuntu/Debian 等 Linux 作業系統上安裝最低先決條件
apt-get install -y python3 python3-dev python3-pip python3-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake libedit-dev libxml2-dev llvm-12
pip3 install numpy decorator attrs nasm
注意:由於帶有 TVM EP 的 ONNX Runtime 是使用 Intel ipp-crypto 庫構建的,因此有新的要求。編譯器 gcc (和 g++) 版本應等於或高於 8.2。nasm 版本應為 2.14.02 或更高。nasm 版本過小的問題可見 此處 或 此處。對於 Ubuntu LTS 18,由於其版本為 2.13.02,apt-get install nasm 不夠,請參閱 此處 從原始碼安裝的說明。
此外,當前實現支援 TVM EP 的 NVidia GPU。目前,您只能使用支援 CUDA Toolkit 的 NVidia GPU。為此,請確保您已安裝 NVidia 驅動程式和 CUDA Toolkit。更詳細的說明可在 官方頁面 上找到。
克隆此倉庫。為了構建 ONNXRT,您需要 CMake 3.18 或更高版本。在 Ubuntu 20.04 中,您可以使用以下命令安裝最新版本的 CMake
sudo apt-get update
sudo apt-get install gpg wget
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ focal main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
sudo apt-get update
sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg
sudo apt-get install kitware-archive-keyring
sudo apt-get install cmake
構建 ONNX Runtime (TVM x86)
./build.sh --config Release --enable_pybind --build_wheel --parallel --skip_tests --skip_onnx_tests --use_tvm
構建 ONNX Runtime (TVM with CUDA support)
./build.sh --config Release --enable_pybind --build_wheel --parallel --skip_tests --skip_onnx_tests --use_tvm --tvm_cuda_runtime
此命令同時構建 TVM 和 onnxruntime-tvm。它為每個專案建立兩個 wheel 包。構建 ONNX Runtime 的 Python API,而不是使用標準包。相關說明如下。
TVM 包
cd <path_to_onnx_runtime>
python3 -m pip uninstall tvm -y
whl_path=$(find ./build/<OS_NAME>/Release/_deps/tvm-src/python/dist -name "*.whl")
python3 -m pip install $whl_path
TVM EP 包
cd <path_to_onnx_runtime>
python3 -m pip uninstall onnxruntime onnxruntime-tvm -y
whl_path=$(find ./build/<OS_NAME>/Release/dist -name "*.whl")
python3 -m pip install $whl_path
或者,您可以設定 PYTHONPATH 來告訴 python 在哪裡找到 ONNXRT 庫和 TVM 庫。
export PYTHONPATH=<path_to_onnx_runtime>/build/<OS_NAME>/Release:${PYTHONPATH}
export PYTHONPATH=<path_to_onnx_runtime>/build/<OS_NAME>/Release/_deps/tvm-src/python:${PYTHONPATH}
Windows
在 Windows 上安裝最低先決條件:Git, CMake, Visual Studio, Python, LLVM
- Git:從 此處 下載並安裝 Git for Windows。請確保 git.exe 的路徑已包含在環境變數中。預設情況下,它應該會被新增。安裝後,在命令列 (cmd) 中使用
git --version檢查 git。 - CMake:使用 此連結 下載並安裝 CMake。推薦使用 msi 檔案。在 cmd 中使用
cmake --version驗證 CMake 安裝。 - Visual Studio:從 此處 下載並分別安裝 Visual Studio 20** Community 和 Visual Studio Build Tools。建議不要更改預設安裝路徑。選擇“使用 C++ 的桌面開發”工作負載,並確保同時選中“MSVC [當代版本] C++ 構建工具”和“Windows 10 SDK”兩個選項。
- Python:從 此處 下載並安裝 Python 3.*。請務必勾選“將 Python 新增到 PATH”選項,這樣安裝程式會將 Python 目錄直接包含到環境變數中。安裝後,在 cmd 中使用
python檢查 python。預期輸出如下所示Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>使用
quit()退出 python 介面。 - LLVM:編譯器對於純 ONNX Runtime 安裝不是必需的,但預設情況下 TVM EP 需要它。
git clone --depth 1 --branch release/11.x https://github.com/llvm/llvm-project.git cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi" -DLLVM_TARGETS_TO_BUILD=X86 -Thost=x64 -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" cmake --build ./build --config Release - ipp-crypto 的依賴項
- 透過以下行在 Windows 上安裝 asm 編譯器 (nasm)
winget install nasm -i將其新增到 PATH(Windows GUI 的說明可見 此處)或透過 cmd
set PATH="%PATH%;C:\Program Files\NASM"在命令提示符下透過
nasm --version檢查。
- 從 此處 透過 msi 檔案在 Windows 上安裝 openssl。將包含可執行檔案的目錄路徑(例如“C:\Program Files\OpenSSL-Win64\bin”)新增到 PATH(請參閱上述說明)。
在命令提示符下透過openssl version檢查。
- 透過以下行在 Windows 上安裝 asm 編譯器 (nasm)
要使用 NVIDIA GPU(可選),應安裝 CUDA 和 cuDNN。
- CUDA:透過 此連結 安裝 CUDA。
- cuDNN:從 此處 下載 cuDNN 安裝程式。選擇與 CUDA v11.* 對應的 v8.*,解壓後按以下方式移動 cuDNN 檔案
- [解壓目錄]\bin\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin
- [解壓目錄]\include\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\include
- [解壓目錄]\lib\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\lib
在 cmd 中使用 nvcc --version 驗證 CUDA 安裝。
從原始碼構建帶 TVM 執行提供程式的 ONNX Runtime
- 使用命令列從 github 克隆原始碼
git clone --recursive https://github.com/Microsoft/onnxruntime cd onnxruntime - CPU 構建
build.bat --config Release --enable_pybind --build_wheel --skip_tests --parallel --use_tvm --skip_onnx_tests --cmake_generator "Visual Studio 17 2022" --llvm_config <path_to_llvm_root>/build/Release/bin/llvm-config.exe - GPU 構建
build.bat --config Release --enable_pybind --build_wheel --skip_tests --parallel --use_tvm --skip_onnx_tests --cmake_generator "Visual Studio 17 2022" --llvm_config <path_to_llvm_root>/build/Release/bin/llvm-config.exe --use_cuda --cudnn_home “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.*” --cuda_home “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.*”在兩種情況下(CPU,GPU),cmake 生成器都有以下選項:“Visual Studio 15 2017”、“Visual Studio 16 2019”、“Visual Studio 17 2022”和“Ninja”
- 安裝 ONNX Runtime 的 python wheel 包
包的預設路徑是<path_to_onnxruntime_root>/build/Windows/Release/Release/dist。請注意,它與 Linux 上包的路徑不同。在安裝之前,請檢查 wheel 包的名稱並使用對應的包。它可能看起來像這樣python -m pip install .\onnxruntime\build\Windows\Release\Release\dist\onnxruntime_tvm-1.6.0-cp37-cp37m-win_amd64.whl - 安裝 TVM 的 python wheel 包,因為 TVM EP 內部使用了它的 python API
它可能看起來像這樣python -m pip install .\onnxruntime\build\Windows\Release\_deps\tvm-src\python\dist\tvm-0.9.dev1728+g3425ed846-cp39-cp39-win_amd64.whl - 透過 python 指令碼驗證結果。注意:python 不應從包含“onnxruntime”目錄的目錄中啟動,以獲得正確結果。
import onnxruntime print(onnxruntime.__version__) print(onnxruntime.get_device()) print(onnxruntime.get_available_providers()) - 解除安裝過程
pip uninstall onnxruntime-tvm
配置選項
TVM Executor Provider 可以透過以下提供程式選項進行配置
po = [dict(executor=tvm_executor_type,
so_folder=folder_with_pretuned_files,
check_hash=check_hash,
hash_file_path=hash_file_path,
target=client_target,
target_host=client_target_host,
opt_level=client_opt_level,
freeze_weights=freeze,
to_nhwc=layout_transform,
tuning_type=tvm_optimizer_type,
tuning_file_path=client_tuning_logfile,
input_names = input_names_str,
input_shapes = input_shapes_str)]
tvm_session = onnxruntime.InferenceSession(model_path, providers=["TvmExecutionProvider"], provider_options=po)
executor是 TVM 使用的執行器型別。有兩種選擇:GraphExecutor 和 VirtualMachine,分別對應“graph”和“vm”標籤。預設使用 VirtualMachine。so_folder是包含模型調優後獲得的一組檔案(.ro-、.so/.dll 檔案和權重)的資料夾路徑。它使用這些檔案進行執行器編譯,而不是 onnx 模型。但 ONNX Runtime 仍然需要後者。check_hash意味著需要對so_folder引數中獲得的模型執行 HASH 檢查。預設值為False。hash_file_path是包含 ONNX 模型預計算 HASH 的檔案路徑,該模型調優結果位於so_folder引數傳遞的路徑中。如果傳入空字串作為此值,則檔案將在so_folder引數中傳遞的資料夾中搜索。target和target_host是 TVM 中的字串(例如“llvm –mcpu=avx2”)。使用加速器時,target 可能類似於cuda,而 target_host 可能為llvm -mtriple=x86_64-linux-gnuopt_level是 TVM 最佳化級別。預設為 3freeze_weights意味著所有模型權重在編譯階段都被保留,否則它們會在每次推理時下載。為獲得最佳效能,推薦使用 True。預設值為 true。to_nhwc開啟特殊的模型轉換,特別是資料佈局,其中使用了 Octomizer。它允許正確處理從 Octomizer 獲得的調優日誌。預設值為 false。tuning_type定義了正在使用的 TVM 調優日誌型別,可以設定為AutoTVM(第一代自動調優日誌)或Ansor(第二代自動調優日誌)。預設情況下,此選項設定為AutoTVM。tuning_file_path是 AutoTVM 或 Ansor 調優檔案的路徑,該檔案為給定模型和目標提供最佳效能的規範。(更多詳情請參見下文)。
TVM 僅支援固定圖模型。如果您的模型在輸入形狀中具有未知維度(不包括批大小),您必須使用 input_names 和 input_shapes 提供程式選項提供形狀。下面是必須傳遞給 provider_options 的示例
input_names = "input_1 input_2"
input_shapes = "[1 3 224 224] [1 2]"
效能調優
TVM 透過自動化調優過程最佳化機器學習模型,該過程生成針對目標硬體架構的模型變體。此過程還會生成“調優日誌”,TVM EP 依賴這些日誌來最大化模型效能。您可以透過以下方式獲取模型的這些日誌
AutoTVM:https://tvm.apache.org/docs/how_to/tune_with_autotvm/index.html
或
Ansor (自動排程):https://tvm.apache.org/docs/how_to/tune_with_autoscheduler/index.html
將 TVM EP 與 TVM 調優日誌一起使用還需要使用者關閉 ONNX Runtime 預處理。為此,可以使用以下 SessionOptions()
so = onnxruntime.SessionOptions()
so.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_DISABLE_ALL
tvm_session = onnxruntime.InferenceSession(model_path, sess_options=so, providers=["TvmExecutionProvider"], provider_options=po)
使用預編譯模型
也可以使用預編譯模型。
編譯後的模型可以透過 OctoML 平臺 獲得或直接編譯(有關模型編譯的更多資訊,請參閱 ResNet50 推理與 TVM EP 示例筆記本 中的支援預編譯模型部分)。
為了使用預編譯模型,只需要傳遞兩個選項
- executor - 必須使用
vm(VirtualMachine) 作為值(GraphExecutor不支援此功能); - so_folder - 必須將預編譯模型檔案所在的目錄路徑作為值傳遞。
- check_hash - (可選)如果您想檢查雜湊,必須傳遞
True作為值。 - hash_file_path - (可選)預設情況下,將從
so_folder引數中傳遞的目錄中搜索包含調優模型雜湊的檔案。如果您想指定不同的位置,則必須傳遞包含所需雜湊的檔案的路徑作為值。
您可以在上面的 配置選項 部分閱讀有關這些選項的更多資訊。
示例
已知問題
- 目前,TVM EP 僅在 UNIX/Linux 和 Windows 系統上進行了驗證。
- ONNX 和 Google protobuf 之間發現了一些相容性問題。
AttributeError: module 'google.protobuf.internal.containers' has no attribute 'MutableMapping'。這通常在 protobuf 版本 >= 3.19.0 且 ONNX 版本 <= 1.8.1 的任何 python 指令碼中import onnx時發生。要解決此問題,可以單獨或一起重新安裝 Google protobuf 和 ONNX,使用pip3 uninstall onnx -y pip3 install onnx==1.10.1 pip3 uninstall protobuf -y pip3 install protobuf==3.19.1
以下 ONNX 和 protobuf 版本被發現相容
- 3.17.3 和 1.8.0
- 3.19.1 和 1.10.1