LiteRT 的 GPU 委派

使用圖形處理器 (GPU) 執行機器學習 (ML) 模型,可大幅提升模型效能,以及啟用 ML 功能的應用程式使用者體驗。LiteRT 可透過稱為「委派」的硬體驅動程式,使用 GPU 和其他特殊處理器。在 LiteRT ML 應用程式中啟用 GPU,可享有下列優點:

  • 速度 - GPU 的設計宗旨是處理大量平行工作負載,因此總處理量很高。這項設計非常適合用於深層類神經網路,因為這類網路包含大量運算子,每個運算子都會處理可平行處理的輸入張量,通常會縮短延遲時間。在最佳情況下,在 GPU 上執行模型可能夠快,可支援先前無法使用的即時應用程式。
  • 能源效率 - GPU 執行機器學習運算時效率極高,通常比在 CPU 上執行相同工作時消耗更少電力,產生的熱能也較少。

本文將概略介紹 LiteRT 的 GPU 支援功能,以及 GPU 處理器的進階用途。如要進一步瞭解如何在特定平台上導入 GPU 支援功能,請參閱下列指南:

支援 GPU 機器學習作業

LiteRT GPU 委派項目可加速的 TensorFlow ML 作業 (或「運算」) 有一些限制。在 16 位元和 32 位元浮點精確度方面,委派支援下列作業:

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

根據預設,所有作業都只支援第 1 版。啟用量化支援功能後,系統就會啟用適當的版本,例如 ADD v2。

排解 GPU 支援問題

如果 GPU 委派項目不支援部分作業,架構只會在 GPU 上執行部分圖表,其餘部分則在 CPU 上執行。由於 CPU/GPU 同步處理的成本高昂,因此與整個網路只在 CPU 上執行的情況相比,這種分割執行模式通常會導致效能較慢。在此情況下,應用程式會產生警告,例如:

WARNING: op code #42 cannot be handled by this delegate.

這類失敗並非實際的執行階段失敗,因此沒有回呼。使用 GPU 委派項目測試模型執行作業時,請留意這些警告。如果這類警告數量偏高,可能表示您的模型不適合用於 GPU 加速,可能需要重構模型。

範例模型

下列範例模型是為充分運用 LiteRT 的 GPU 加速功能而建構,可供參考及測試:

針對 GPU 進行最佳化

使用 LiteRT GPU 委派時,下列技巧有助於提升在 GPU 硬體上執行模型的效能:

  • 重塑作業 - 在 CPU 上快速執行的部分作業,在行動裝置的 GPU 上可能需要高昂的成本。重塑作業的執行成本特別高,包括 BATCH_TO_SPACESPACE_TO_BATCHSPACE_TO_DEPTH 等。您應仔細檢查重塑作業的使用情形,並考量這類作業可能只適用於探索資料或模型的早期疊代。移除這些關鍵字可大幅提升成效。

  • 圖像資料通道 - 在 GPU 上,張量資料會切分成 4 個通道,因此對形狀為 [B,H,W,5] 的張量進行運算時,效能與形狀為 [B,H,W,8] 的張量大致相同,但遠不如 [B,H,W,4]。如果您使用的攝影機硬體支援 RGBA 格式的影像影格,則輸入 4 個通道的資料會快上許多,因為這樣可避免從 3 個通道的 RGB 複製記憶體到 4 個通道的 RGBX。

  • 針對行動裝置最佳化的模型 - 為獲得最佳效能,建議您使用針對行動裝置最佳化的網路架構,重新訓練分類器。善用行動裝置硬體功能,可大幅減少延遲時間和耗電量,進而提升裝置端推論效能。

進階 GPU 支援

您可以使用 GPU 處理的進階技術,進一步提升模型效能,包括量化和序列化。下列各節將進一步說明這些技巧。

使用量化模型

本節說明 GPU 委派如何加速 8 位元量化模型,包括:

如要提升效能,請使用同時具有浮點輸入和輸出張量的模型。

運作方式

由於 GPU 後端只支援浮點執行,因此我們會為原始模型提供「浮點檢視畫面」,藉此執行量化模型。大致來說,這需要執行下列步驟:

  • 常數張量 (例如權重/偏差) 會一次性解量化至 GPU 記憶體。為 LiteRT 啟用委派時,就會發生這項作業。

  • 如果 GPU 程式的輸入和輸出經過 8 位元量化,則每次推論時都會分別進行反量化和量化。這項作業是在 CPU 上完成,並使用 LiteRT 的最佳化核心。

  • 量化模擬器會插入作業之間,模擬量化行為。如果作業預期啟動會遵循量化期間學到的界限,就必須採用這種做法。

如要瞭解如何透過 GPU 委派啟用這項功能,請參閱下列文章:

透過序列化縮短初始化時間

GPU 委派功能可讓您從預先編譯的 Kernel 程式碼載入,以及從先前執行階段在磁碟上序列化及儲存的模型資料載入。這個方法可避免重新編譯,並將啟動時間縮短最多 90%。這項改善措施是透過交換磁碟空間來節省時間。您可以透過幾個設定選項啟用這項功能,如下列程式碼範例所示:

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

Java

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

使用序列化功能時,請確保程式碼符合下列導入規則:

  • 將序列化資料儲存在其他應用程式無法存取的目錄中。在 Android 裝置上,請使用 getCodeCacheDir() ,這個位置指向目前應用程式專用的位置。
  • 特定型號的裝置必須使用專屬的模型權杖。您可以使用 farmhash::Fingerprint64 等程式庫,從模型資料產生指紋,進而計算模型權杖。