Überblick über das Transformer-Modelloptimierungstool
Während ONNX Runtime die meisten Optimierungen beim Laden von Transformer-Modellen automatisch anwendet, sind einige der neuesten Optimierungen noch nicht in ONNX Runtime integriert. Diese zusätzlichen Optimierungen können mit dem Transformer-Optimierungstool angewendet werden, um Modelle für die beste Leistung zu optimieren. Dieses Optimierungstool bietet eine Offline-Funktion zur Optimierung von Transformer-Modellen in Szenarien, in denen ONNX Runtime die Optimierung nicht zur Ladezeit anwendet.
Dieses Tool kann hilfreich sein, wenn
- ONNX Runtime noch keine Transformer-spezifischen Graphoptimierungen aktiviert hat
- Das Modell zur Leistungssteigerung durch gemischte Präzision auf GPUs mit Tensor Cores (wie V100 oder T4) in Float16 konvertiert werden kann
- Das Modell Eingaben mit dynamischer Achse hat, was einige Optimierungen durch ONNX Runtime aufgrund der Forminferenz blockiert.
- Experimentieren mit dem Deaktivieren oder Aktivieren einiger Fusionen zur Bewertung der Auswirkungen auf Leistung oder Genauigkeit.
Verwendung
- ONNX Runtime installieren
- Konvertieren Sie das Transformer-Modell in ONNX
- Führen Sie das Modelloptimierungstool aus
- Benchmarken und profilieren Sie das Modell
Unterstützte Modelle
Eine Liste der Modelle, die mit dem Optimierer getestet wurden, finden Sie auf dieser Seite.
Die meisten Optimierungen erfordern eine exakte Übereinstimmung eines Subgraphen. Jede Layoutänderung im Subgraphen kann dazu führen, dass einige Optimierungen nicht funktionieren. Beachten Sie, dass unterschiedliche Versionen von Trainings- oder Exporttools zu unterschiedlichen Graphlayouts führen können. Es wird empfohlen, die neueste veröffentlichte Version von PyTorch und Transformers zu verwenden.
Einschränkungen
- Aufgrund der CUDA-Implementierung des Attention-Kernels in ONNX Runtime beträgt die maximale Anzahl von Attention-Heads 1024.
- Normalerweise beträgt die maximal unterstützte Sequenzlänge aufgrund von GPU-Speicherbeschränkungen 4096 für Longformer und 1024 für andere Modelltypen.
1. Installieren von ONNX Runtime
Zuerst müssen Sie das Paket onnxruntime oder onnxruntime-gpu für CPU- oder GPU-Inferenz installieren. Für die Verwendung von onnxruntime-gpu müssen CUDA und cuDNN installiert und deren Binärverzeichnisse zur PATH-Umgebungsvariablen hinzugefügt werden. Siehe Python-Installationsanweisungen.
2. Konvertieren eines Transformer-Modells in ONNX
Verwenden Sie zum Konvertieren des Transformer-Modells in ONNX torch.onnx oder tensorflow-onnx.
-
Huggingface transformers hat ein Notebook, das ein Beispiel für den Export eines vortrainierten Modells in ONNX zeigt.
-
Für tf2onnx beachten Sie bitte dieses BERT-Tutorial.
Konvertierung des GPT-2-Modells
Die Konvertierung des GPT-2-Modells von PyTorch in ONNX ist nicht einfach, wenn der bisherige Zustand verwendet wird. Das Tool convert_to_onnx kann helfen.
Sie können Befehle wie die folgenden verwenden, um ein vortrainiertes PyTorch GPT-2-Modell für eine gegebene Präzision (float32, float16) in ONNX zu konvertieren
python -m onnxruntime.transformers.models.gpt2.convert_to_onnx -m gpt2 --model_class GPT2LMHeadModel --output gpt2.onnx -p fp32
python -m onnxruntime.transformers.models.gpt2.convert_to_onnx -m distilgpt2 --model_class GPT2LMHeadModel --output distilgpt2.onnx -p fp16 --use_gpu --optimize_onnx --auto_mixed_precision
Das Tool überprüft auch, ob das ONNX-Modell und das entsprechende PyTorch-Modell bei denselben Zufallseingaben dieselben Ausgaben erzeugen.
Konvertierung des Longformer-Modells
Anforderung: Linux OS (z.B. Ubuntu 18.04 oder 20.04) und eine Python-Umgebung mit PyTorch 1.9.* wie die folgende
conda create -n longformer python=3.8
conda activate longformer
pip install torch==1.9.1+cpu torchvision==0.10.1+cpu torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html
pip install onnx transformers==4.18.0 onnxruntime numpy
Bauen Sie als Nächstes die Quellen der Torch-Erweiterungen
cd onnxruntime/python/tools/transformers/models/longformer/torch_extensions
python setup.py install
Dadurch wird eine PyTorch-Erweiterungsdatei wie "build/lib.linux-x86_64-3.8/longformer_attention.cpython-38-x86_64-linux-gnu.so" im Verzeichnis generiert.
Konvertieren Sie schließlich das Longformer-Modell wie folgt in ein ONNX-Modell
cd ..
python convert_to_onnx.py -m longformer-base-4096
Das exportierte ONNX-Modell kann derzeit nur auf der GPU ausgeführt werden.
3. Führen Sie das Modelloptimierungstool aus
Alle Optimierungsoptionen finden Sie auf Github.
In Ihrem Python-Code können Sie den Optimierer wie folgt verwenden
from onnxruntime.transformers import optimizer
optimized_model = optimizer.optimize_model("bert.onnx", model_type='bert', num_heads=12, hidden_size=768)
optimized_model.convert_float_to_float16()
optimized_model.save_model_to_file("bert_fp16.onnx")
Sie können auch die Befehlszeile verwenden. Beispiel für die Optimierung eines BERT-large-Modells für gemischte Präzision (float16)
python -m onnxruntime.transformers.optimizer --input bert_large.onnx --output bert_large_fp16.onnx --num_heads 16 --hidden_size 1024 --float16
Sie können auch die neuesten Skriptdateien von hier herunterladen. Führen Sie es dann wie folgt aus
python optimizer.py --input bert.onnx --output bert_opt.onnx --model_type bert
BERT-Modellverifizierung
Wenn Ihr BERT-Modell drei Eingaben hat (wie input_ids, token_type_ids und attention_mask), kann ein Skript compare_bert_results.py zur schnellen Überprüfung verwendet werden. Das Tool generiert einige gefälschte Eingabedaten und vergleicht die Ergebnisse des ursprünglichen und des optimierten Modells. Wenn die Ausgaben alle nahe beieinander liegen, ist es sicher, das optimierte Modell zu verwenden.
Beispiel für die Überprüfung von für die CPU optimierten Modellen
python -m onnxruntime.transformers.compare_bert_results --baseline_model original_model.onnx --optimized_model optimized_model_cpu.onnx --batch_size 1 --sequence_length 128 --samples 100
Für GPU fügen Sie –use_gpu zum Befehl hinzu.
4. Benchmarken und profilieren Sie das Modell
Benchmarking
Das Bash-Skript run_benchmark.sh kann zum Ausführen von Benchmarks verwendet werden. Sie können das Bash-Skript modifizieren, um Ihre Optionen (Modelle, Batchgrößen, Sequenzlängen, Zielgerät usw.) vor der Ausführung auszuwählen.
Das Bash-Skript ruft das Skript benchmark.py auf, um die Inferenzleistung von OnnxRuntime, PyTorch oder PyTorch+TorchScript auf vortrainierten Modellen von Huggingface Transformers zu messen.
Benchmark.py
Wenn Sie run_benchmark.sh verwenden, müssen Sie benchmark.py nicht direkt verwenden. Sie können diesen Abschnitt überspringen, wenn Sie die Details nicht wissen möchten.
Unten sehen Sie ein Beispiel für die Ausführung von benchmark.py auf dem vortrainierten Modell bert-base-cased auf der GPU.
python -m onnxruntime.transformers.benchmark -g -m bert-base-cased -o -v -b 0
python -m onnxruntime.transformers.benchmark -g -m bert-base-cased -o
python -m onnxruntime.transformers.benchmark -g -m bert-base-cased -e torch
python -m onnxruntime.transformers.benchmark -g -m bert-base-cased -e torchscript
Der erste Befehl generiert ONNX-Modelle (sowohl vor als auch nach den Optimierungen), führt jedoch keine Leistungstests durch, da die Batchgröße 0 ist. Die anderen drei Befehle führen Leistungstests auf jeder der drei Engines aus: OnnxRuntime, PyTorch und PyTorch+TorchScript.
Wenn Sie den Parameter -o entfernen, wird das Optimierungsskript nicht im Benchmark verwendet.
Wenn Ihre GPU (wie V100 oder T4) über TensorCore verfügt, können Sie den Befehlen -p fp16 hinzufügen, um die gemischte Präzision zu aktivieren. Bei einigen decoder-basierten generativen Modellen (z.B. GPT2) können Sie den Strict Mode für SkipLayerNormalization Op auf CUDA EP aktivieren, um eine bessere Genauigkeit zu erzielen. Die Leistung wird jedoch etwas abfallen.
Wenn Sie auf der CPU benchmarken möchten, können Sie die Option -g in den Befehlen entfernen.
Beachten Sie, dass bei unserem aktuellen Benchmark für GPT2- und DistilGPT2-Modelle der vergangene Zustand von Eingaben und Ausgaben deaktiviert ist.
Standardmäßig hat das ONNX-Modell nur eine Eingabe (input_ids). Sie können den Parameter -i verwenden, um Modelle mit mehreren Eingaben zu testen. Zum Beispiel können wir "-i 3" zur Befehlszeile hinzufügen, um ein BERT-Modell mit 3 Eingaben (input_ids, token_type_ids und attention_mask) zu testen. Diese Option unterstützt derzeit nur OnnxRuntime.
Leistungstest
bert_perf_test.py kann verwendet werden, um die BERT-Modellinferenzleistung zu überprüfen. Hier sind einige Beispiele
python -m onnxruntime.transformers.bert_perf_test --model optimized_model_cpu.onnx --batch_size 1 --sequence_length 128
Für GPU fügen Sie –use_gpu zum Befehl hinzu.
Nach Abschluss des Tests wird eine Datei wie perf_results_CPU_B1_S128_
Profiling
profiler.py kann verwendet werden, um ein Transformer-Modell zu profilieren. Es kann helfen, den Engpass eines Modells und die CPU-Zeit, die für einen Knoten oder Subgraphen aufgewendet wird, zu ermitteln.
Beispielbefehle
python -m onnxruntime.transformers.profiler --model bert.onnx --batch_size 8 --sequence_length 128 --samples 1000 --dummy_inputs bert --thread_num 8 --kernel_time_only
python -m onnxruntime.transformers.profiler --model gpt2.onnx --batch_size 1 --sequence_length 1 --past_sequence_length 128 --samples 1000 --dummy_inputs gpt2 --use_gpu
python -m onnxruntime.transformers.profiler --model longformer.onnx --batch_size 1 --sequence_length 4096 --global_length 8 --samples 1000 --dummy_inputs longformer --use_gpu
Die Ergebnisdatei wie onnxruntime_profile__
Benchmark-Ergebnisse finden Sie hier.