Transformer 模型最佳化工具概述
雖然 ONNX Runtime 在載入 Transformer 模型時會自動應用大多數最佳化,但一些最新最佳化尚未整合到 ONNX Runtime 中。可以使用Transformer 最佳化工具來應用這些額外的最佳化,以調整模型以獲得最佳效能。當 ONNX Runtime 未在載入時應用最佳化時,此最佳化工具提供了離線最佳化 Transformer 模型的能力。
此工具在以下情況下會有所幫助:
- ONNX Runtime 尚未啟用特定於 Transformer 的圖最佳化
- 模型可以轉換為使用 float16,以在具有 Tensor Cores (如 V100 或 T4) 的 GPU 上透過混合精度提升效能
- 模型輸入具有動態軸,這會阻止 ONNX Runtime 由於形狀推斷而應用某些最佳化。
- 試驗停用或啟用某些融合,以評估對效能或準確性的影響。
用法
支援的模型
有關已使用最佳化器測試的模型列表,請參閱此頁面。
大多數最佳化需要子圖的精確匹配。子圖中的任何佈局更改都可能導致某些最佳化無法工作。請注意,不同版本的訓練或匯出工具可能導致不同的圖佈局。建議使用最新發布的 PyTorch 和 Transformers 版本。
限制
- 由於 ONNX Runtime 中 Attention 核心的 CUDA 實現,最大注意力頭數量為 1024。
- 通常,由於 GPU 記憶體限制,Longformer 支援的最大序列長度為 4096,其他型別的模型為 1024。
1. 安裝 ONNX Runtime
首先,您需要安裝 onnxruntime 或 onnxruntime-gpu 包以進行 CPU 或 GPU 推理。要使用 onnxruntime-gpu,需要安裝 CUDA 和 cuDNN 並將其 bin 目錄新增到 PATH 環境變數。請參閱Python 安裝說明。
2. 將 Transformer 模型轉換為 ONNX
要將 Transformer 模型轉換為 ONNX,請使用torch.onnx或tensorflow-onnx。
GPT-2 模型轉換
當使用過去狀態時,將 GPT-2 模型從 PyTorch 轉換為 ONNX 並不簡單。convert_to_onnx 工具可以提供幫助。
您可以使用以下命令將預訓練的 PyTorch GPT-2 模型轉換為給定精度(float32, float16)的 ONNX 模型
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
該工具還將驗證 ONNX 模型和相應的 PyTorch 模型在給定相同隨機輸入的情況下是否生成相同的輸出。
Longformer 模型轉換
要求:Linux 作業系統(例如 Ubuntu 18.04 或 20.04)和 PyTorch 1.9.* 版本的 Python 環境,如下所示:
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
接下來,構建 torch 擴充套件的原始碼
cd onnxruntime/python/tools/transformers/models/longformer/torch_extensions
python setup.py install
它將在該目錄下生成一個 PyTorch 擴充套件檔案,例如“build/lib.linux-x86_64-3.8/longformer_attention.cpython-38-x86_64-linux-gnu.so”。
最後,將 Longformer 模型轉換為 ONNX 模型,如下所示:
cd ..
python convert_to_onnx.py -m longformer-base-4096
匯出的 ONNX 模型目前只能在 GPU 上執行。
3. 執行模型最佳化工具
有關所有最佳化器選項,請參閱Github。
在您的 Python 程式碼中,您可以按如下方式使用最佳化器:
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")
您也可以使用命令列。以下是最佳化 BERT-large 模型以使用混合精度(float16)的示例:
python -m onnxruntime.transformers.optimizer --input bert_large.onnx --output bert_large_fp16.onnx --num_heads 16 --hidden_size 1024 --float16
您也可以從此處下載最新的指令碼檔案。然後按如下方式執行:
python optimizer.py --input bert.onnx --output bert_opt.onnx --model_type bert
BERT 模型驗證
如果您的 BERT 模型有三個輸入(例如 input_ids、token_type_ids 和 attention_mask),可以使用指令碼 compare_bert_results.py 進行快速驗證。該工具將生成一些虛假輸入資料,並比較原始模型和最佳化模型的輸出結果。如果所有輸出都接近,則可以安全地使用最佳化後的模型。
驗證為 CPU 最佳化的模型示例
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
對於 GPU,請在命令中附加 –use_gpu。
4. 對模型進行基準測試和效能分析
基準測試
bash 指令碼run_benchmark.sh可用於執行基準測試。您可以在執行前修改 bash 指令碼以選擇您的選項(模型、批大小、序列長度、目標裝置等)。
bash 指令碼將呼叫 benchmark.py 指令碼來測量 Huggingface Transformers 預訓練模型在 OnnxRuntime、PyTorch 或 PyTorch+TorchScript 上的推理效能。
Benchmark.py
如果您使用 run_benchmark.sh,則無需直接使用 benchmark.py。如果您不想了解詳細資訊,可以跳過此部分。
以下是在 GPU 上對預訓練模型 bert-base-cased 執行 benchmark.py 的示例。
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
第一個命令將生成 ONNX 模型(最佳化前後),但不執行效能測試,因為批處理大小為 0。其他三個命令將針對三個引擎中的每一個執行效能測試:OnnxRuntime、PyTorch 和 PyTorch+TorchScript。
如果移除 -o 引數,則最佳化器指令碼不會用於基準測試。
如果您的 GPU(如 V100 或 T4)具有 TensorCore,您可以在上述命令中附加-p fp16以啟用混合精度。在某些僅解碼器(例如 GPT2)的生成模型中,您可以在 CUDA EP 上為 SkipLayerNormalization Op 啟用嚴格模式以獲得更好的準確性。然而,效能會略有下降。
如果您想在 CPU 上進行基準測試,可以從命令中移除 -g 選項。
請注意,我們目前對 GPT2 和 DistilGPT2 模型的基準測試已停用輸入和輸出中的過去狀態。
預設情況下,ONNX 模型只有一個輸入(input_ids)。您可以使用 -i 引數測試具有多個輸入的模型。例如,我們可以在命令列中新增“-i 3”來測試具有 3 個輸入(input_ids、token_type_ids 和 attention_mask)的 bert 模型。此選專案前僅支援 OnnxRuntime。
效能測試
bert_perf_test.py 可用於檢查 BERT 模型推理效能。以下是示例:
python -m onnxruntime.transformers.bert_perf_test --model optimized_model_cpu.onnx --batch_size 1 --sequence_length 128
對於 GPU,請在命令中附加 –use_gpu。
測試完成後,將生成一個檔案,例如 perf_results_CPU_B1S128
效能分析
profiler.py 可用於對 Transformer 模型進行效能分析。它可以幫助找出模型的瓶頸以及節點或子圖上消耗的 CPU 時間。
示例命令
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
結果檔案,例如 onnxruntime_profile__
基準測試結果可以在這裡找到。