TVM Execution Provider

TVM ist ein Execution Provider für ONNX Runtime, der auf Apache TVM aufbaut. Er ermöglicht ONNX Runtime-Benutzern, die Modelloptimierungen von Apache TVM zu nutzen. TVM EP befindet sich derzeit im "Vorschau"-Status. Er wurde auf einer Handvoll Modellen unter Linux und Windows getestet und funktioniert dort, jedoch nicht auf MacOS.

Inhalt

ONNX Runtime mit dem TVM Execution Provider erstellen

Linux

Installieren Sie die minimalen Voraussetzungen unter Ubuntu/Debian wie Linux-Betriebssystemen

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

Hinweis: Da ONNX Runtime mit TVM EP mit der Intel ipp-crypto-Bibliothek erstellt wird, gibt es neue Anforderungen. Die Compiler gcc (und g++) Version sollte 8.2 oder höher sein. Die nasm-Version sollte 2.14.02 oder höher sein. Probleme mit einer älteren nasm-Version finden Sie hier oder hier. Für Ubuntu LTS 18 reicht apt-get install nasm nicht aus, da es die Version 2.13.02 hat. Anweisungen zur Installation aus Quellen finden Sie hier.

Außerdem unterstützt die aktuelle Implementierung NVidia GPU für TVM EP. Derzeit können Sie nur NVidia GPU mit CUDA Toolkit-Unterstützung verwenden. Stellen Sie dazu sicher, dass Sie den NVidia-Treiber und das CUDA Toolkit installiert haben. Detailliertere Anweisungen finden Sie auf der offiziellen Seite.

Klonen Sie dieses Repository. Um ONNXRT zu erstellen, benötigen Sie CMake 3.18 oder höher. In Ubuntu 20.04 können Sie die folgenden Befehle verwenden, um die neueste Version von CMake zu installieren

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 erstellen (TVM x86)

./build.sh --config Release --enable_pybind --build_wheel --parallel --skip_tests --skip_onnx_tests --use_tvm

ONNX Runtime erstellen (TVM mit CUDA-Unterstützung)

./build.sh --config Release --enable_pybind --build_wheel --parallel --skip_tests --skip_onnx_tests --use_tvm --tvm_cuda_runtime

Dieser Befehl erstellt sowohl TVM als auch onnxruntime-tvm. Er erzeugt zwei Wheel-Dateien, eine für jedes Projekt. Erstellen Sie die Python-API für ONNX Runtime, anstatt das Standardpaket zu verwenden. Anweisungen hierfür finden Sie unten.

Paket für 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

Paket für 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

Alternativ können Sie PYTHONPATH setzen, um Python mitzuteilen, wo die ONNXRT-Bibliothek und die TVM-Bibliothek zu finden sind.

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

Installieren Sie die minimalen Voraussetzungen unter Windows: Git, CMake, Visual Studio, Python, LLVM

  • Git: Laden Sie Git für Windows von hier herunter und installieren Sie es. Stellen Sie sicher, dass der Pfad zu git.exe in der Umgebungsvariablen enthalten ist. Standardmäßig sollte er hinzugefügt werden. Um Git nach der Installation zu überprüfen, verwenden Sie git --version in der Kommandozeile (cmd).
  • CMake: Verwenden Sie diesen Link, um CMake herunterzuladen und zu installieren. Die MSI-Datei wird dafür empfohlen. Um die CMake-Installation zu überprüfen, verwenden Sie cmake --version in cmd.
  • Visual Studio: Laden Sie es von hier herunter und installieren Sie Visual Studio 20** Community & Visual Studio Build Tools. Es wird empfohlen, den Standardinstallationspfad nicht zu ändern. Wählen Sie die Workload "Desktopentwicklung mit C++" und stellen Sie sicher, dass sowohl die Option "MSVC [aktuelle Version] C++-Buildtools" als auch "Windows 10 SDK" ausgewählt sind.
  • Python: Laden Sie Python 3.* von hier herunter und installieren Sie es. Achten Sie auf die Option "Python zu PATH hinzufügen", damit der Installer das Python-Verzeichnis direkt in die Umgebungsvariable aufnimmt. Um Python nach der Installation zu überprüfen, geben Sie python in cmd ein. Die erwartete Ausgabe ist ähnlich wie die folgende
    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.
    >>>
    

    Verwenden Sie quit(), um die Python-Oberfläche zu verlassen.

  • LLVM: Der Compiler ist für die reine ONNX Runtime-Installation nicht notwendig, aber standardmäßig für TVM EP erforderlich.
    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
    
  • Abhängigkeiten von ipp-crypto
    1. Installieren Sie den Assembler-Compiler (nasm) unter Windows per Zeile
      winget install nasm -i
      

                Fügen Sie ihn zu PATH hinzu (Anweisungen für die Windows-GUI finden Sie hier) oder per cmd

      set PATH="%PATH%;C:\Program Files\NASM"
      

                Überprüfen Sie mit nasm --version in der Eingabeaufforderung.
            

    2. Installieren Sie OpenSSL unter Windows mit der MSI-Datei von hier. Fügen Sie den Pfad zum Verzeichnis (z. B. "C:\Program Files\OpenSSL-Win64\bin") mit der ausführbaren Datei zu PATH hinzu (siehe Anweisungen oben).
                Überprüfen Sie mit openssl version in der Eingabeaufforderung.

Für die Verwendung von NVIDIA GPU (optional) müssen CUDA und cuDNN installiert sein.

  • CUDA: Installieren Sie CUDA über den Link.
  • cuDNN: Laden Sie den cuDNN-Installer von hier herunter. Wählen Sie v8.* für die entsprechende CUDA v11.*, entpacken Sie es und verschieben Sie die cuDNN-Dateien wie folgt
    1. [entpacktes Verzeichnis]\bin\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin
    2. [entpacktes Verzeichnis]\include\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\include
    3. [entpacktes Verzeichnis]\lib\ → C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\lib

Um die CUDA-Installation zu überprüfen, verwenden Sie nvcc --version in cmd.

ONNX Runtime mit TVM Execution Provider aus Quellcode erstellen

  • Verwenden Sie die Kommandozeile und klonen Sie die Quellen von GitHub
    git clone --recursive https://github.com/Microsoft/onnxruntime
    cd onnxruntime
    
  • CPU-Build
    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
    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.*”
    

    In beiden Fällen (CPU, GPU) gibt es die folgenden Optionen für den CMake-Generator: "Visual Studio 15 2017", "Visual Studio 16 2019", "Visual Studio 17 2022" und "Ninja"

  • Python-Wheel-Paket für ONNX Runtime installieren
    Der Standardpfad zum Paket ist <pfad_zum_onnxruntime_stammverzeichnis>/build/Windows/Release/Release/dist. Beachten Sie, dass dieser sich vom Pfad zum Paket unter Linux unterscheidet. Überprüfen Sie vor der Installation die Namen der Wheel-Pakete und verwenden Sie das entsprechende. Es kann wie folgt aussehen
    python -m pip install .\onnxruntime\build\Windows\Release\Release\dist\onnxruntime_tvm-1.6.0-cp37-cp37m-win_amd64.whl
    
  • Python-Wheel-Paket für TVM installieren, da seine Python-API innerhalb von TVM EP verwendet wird
    Es kann wie folgt aussehen
    python -m pip install .\onnxruntime\build\Windows\Release\_deps\tvm-src\python\dist\tvm-0.9.dev1728+g3425ed846-cp39-cp39-win_amd64.whl
    
  • Ergebnis mit Python-Skript überprüfen. Hinweis: Python sollte nicht aus einem Verzeichnis gestartet werden, das ein 'onnxruntime'-Verzeichnis enthält, um korrekte Ergebnisse zu erzielen
    import onnxruntime
    print(onnxruntime.__version__)
    print(onnxruntime.get_device())
    print(onnxruntime.get_available_providers())
    
  • Deinstallationsverfahren
    pip uninstall onnxruntime-tvm
    

Konfigurationsoptionen

Der TVM Executor Provider kann mit den folgenden Provider-Optionen konfiguriert werden

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 ist der vom TVM verwendete Executor-Typ. Es gibt die Wahl zwischen zwei Typen: GraphExecutor und VirtualMachine, die den Tags "graph" und "vm" entsprechen. VirtualMachine wird standardmäßig verwendet.
  • so_folder ist der Pfad zu einem Ordner mit einer Reihe von Dateien (.ro-, .so/.dll-Dateien und Gewichte), die nach der Modellabstimmung erhalten wurden. Er verwendet diese Dateien zur Executor-Kompilierung anstelle des ONNX-Modells. Letzteres wird jedoch für ONNX Runtime weiterhin benötigt.
  • check_hash bedeutet, dass ein HASH-Check für das Modell, das im Parameter so_folder angegeben ist, durchgeführt werden muss. Standardmäßig ist dies False.
  • hash_file_path ist der Pfad zu einer Datei, die den voreingestellten HASH für das ONNX-Modell enthält, dessen Ergebnis der Abstimmung sich im über den Parameter so_folder übergebenen Pfad befindet. Wenn ein leerer String als dieser Wert übergeben wurde, wird die Datei im Ordner gesucht, der im Parameter so_folder übergeben wurde.
  • target und target_host sind Zeichenketten wie in TVM (z. B. "llvm –mcpu=avx2"). Bei der Verwendung von Beschleunigern kann target etwas wie cuda sein, während target_host llvm -mtriple=x86_64-linux-gnu sein kann.
  • opt_level ist die TVM-Optimierungsstufe. Standardmäßig ist dies 3.
  • freeze_weights bedeutet, dass alle Modellgewichte während der Kompilierungsphase beibehalten werden, andernfalls werden sie bei jeder Inferenz heruntergeladen. True wird für die beste Leistung empfohlen. Standardmäßig ist dies true.
  • to_nhwc schaltet spezielle Modelltransformationen ein, insbesondere das Datenlayout, das von Octomizer verwendet wird. Es ermöglicht die korrekte Arbeit mit Abstimmungsprotokollen, die von Octomizer stammen. Standardmäßig ist dies false.
  • tuning_type definiert den Typ der verwendeten TVM-Abstimmungsprotokolle und kann entweder auf AutoTVM (1. Gen. Auto-Tuning-Protokolle) oder Ansor (2. Gen. Auto-Tuning-Protokolle) gesetzt werden. Standardmäßig ist diese Option auf AutoTVM gesetzt.
  • tuning_file_path ist der Pfad zur AutoTVM- oder Ansor-Abstimmungsdatei, die Spezifikationen für das gegebene Modell und Ziel für die beste Leistung liefert. (Siehe unten für weitere Details).

TVM unterstützt nur Modelle mit festem Graphen. Wenn Ihr Modell unbekannte Dimensionen in den Eingabeformen hat (mit Ausnahme der Batch-Größe), müssen Sie die Form mithilfe der Provider-Optionen input_names und input_shapes angeben. Unten ist ein Beispiel dafür, was an provider_options übergeben werden muss

input_names = "input_1 input_2"
input_shapes = "[1 3 224 224] [1 2]"

Performance-Tuning

TVM optimiert maschinelle Lernmodelle durch einen automatisierten Abstimmungsprozess, der Modellvarianten erzeugt, die für gezielte Hardwarearchitekturen spezifisch sind. Dieser Prozess generiert auch "Abstimmungsprotokolle", auf die sich TVM EP zur Maximierung der Modellleistung stützt. Diese Protokolle können für Ihr Modell entweder durch die Verwendung von TVM wie hier beschrieben erworben werden

AutoTVM: https://tvm.apache.org/docs/how_to/tune_with_autotvm/index.html

Oder

Ansor (Autoscheduling): https://tvm.apache.org/docs/how_to/tune_with_autoscheduler/index.html

Die Verwendung von TVM EP mit TVM-Abstimmungsprotokollen erfordert auch, dass Benutzer die ONNX Runtime-Vorverarbeitung deaktivieren. Um dies zu tun, können die folgenden SessionOptions() verwendet werden

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)

Verwendung eines vorkompilierten Modells

Es ist auch möglich, ein vorkompiliertes Modell zu verwenden.

Das kompilierte Modell kann über die OctoML-Plattform bezogen oder direkt kompiliert werden (siehe Abschnitt Support precompiled model im Beispiel-Notebook für ResNet50-Inferenz mit TVM EP für weitere Informationen zur Modellkompilierung).

Um das vorkompilierte Modell zu verwenden, müssen nur zwei Optionen übergeben werden

  • executor - vm (VirtualMachine) muss als Wert verwendet werden (diese Funktionalität wird für GraphExecutor nicht unterstützt);
  • so_folder - als Wert muss der Pfad zu dem Verzeichnis übergeben werden, in dem sich die Dateien des vorkompilierten Modells befinden.
  • check_hash - (optional) Wenn Sie den Hash überprüfen möchten, müssen Sie True als Wert übergeben.
  • hash_file_path - (optional) Standardmäßig wird die Datei, die den Hash für das abgestimmte Modell enthält, im Verzeichnis gesucht, das im Parameter so_folder übergeben wurde. Wenn Sie einen anderen Speicherort angeben möchten, müssen Sie den Pfad zu der Datei, die den gewünschten Hash enthält, als Wert übergeben.

Sie können mehr über diese Optionen im Abschnitt Konfigurationsoptionen oben lesen.

Beispiele

Bekannte Probleme

  • Derzeit wurde der TVM EP nur unter UNIX/Linux- und Windows-Systemen verifiziert.
  • Es wurden einige Kompatibilitätsprobleme zwischen ONNX und Google protobuf festgestellt. AttributeError: module 'google.protobuf.internal.containers' has no attribute 'MutableMapping'. Dies tritt normalerweise bei import onnx in beliebigen Python-Skripten für protobuf-Versionen >= 3.19.0 und ONNX-Versionen <= 1.8.1 auf. Um das Problem zu lösen, können Google protobuf und ONNX separat oder zusammen neu installiert werden mit
    pip3 uninstall onnx -y
    pip3 install onnx==1.10.1
    pip3 uninstall protobuf -y
    pip3 install protobuf==3.19.1
    

Das folgende Paar von ONNX- und protobuf-Versionen hat sich als kompatibel erwiesen

  • 3.17.3 und 1.8.0
  • 3.19.1 und 1.10.1