共用方式為


Windows ML 效能和記憶體

在本文中,我們將討論如何在使用 Windows Machine Learning 時管理應用程式的效能。

線程和並行

從運行時間公開的每個物件都是 敏捷的,這表示可以從任何線程存取它們。 如需敏捷式的詳細資訊,請參閱 C++/WinRT 中的敏捷式物件

您將使用其中一個主要物件是 LearningModelSession。 從任何線程呼叫此物件一律是安全的。

  • 針對 GPU 工作階段:物件會鎖定並同步處理並行呼叫。 如果您需要並行操作,您必須建立多個會話才能達成目的。

  • 針對 CPU 工作話:物件不會鎖定,而且會允許在單一會話上進行並行呼叫。 您必須小心管理自己的狀態、緩衝區和系結物件。

您應該注意並衡量您的情境目標。 新式 GPU 架構的運作方式與 CPU 不同。 例如,如果低延遲是您的目標,您可能想要使用管線處理來管理跨 CPU 和 GPU 引擎排程工作的方式,而不是並行。 這篇關於多引擎同步處理的文章 是一個很好的出發點。 如果輸送量是您的目標(例如一次處理盡可能多的影像),您通常會想要使用多個線程和並行,以使 CPU 飽和。

當涉及到線程和並行時,您想要執行實驗並測量計時。 您的效能會根據您的目標和案例而大幅變更。

記憶體使用率

LearningModel 和LearningModelSession 的每個實例都有記憶體中的模型複本。 如果您正在使用小型模型,您可能並不擔心,但如果您正在使用非常大的模型,這會變得很重要。

若要釋放記憶體,請在模型或會話上呼叫 Dispose 。 不要只是刪除它們,因為某些語言會執行延遲垃圾回收。

LearningModel 會將復本保留在記憶體中,以啟用新的會話建立。 當您處置 LearningModel 時,所有現有的會話都會繼續運行。 不過,您將無法再使用該 LearningModel 實例建立新的工作階段。 針對大型模型,您可以建立模型和會話,然後處置模型。 若所有對 Evaluate 的呼叫都使用單一會話,您將在記憶體中擁有大型模型的單一副本。

Float16 支援

為了提升效能並降低模型使用量,您可以使用 ONNXMLTools 將模型轉換成 float16。

轉換之後,所有的權重和輸入都轉變為 float16。 以下是您可以使用 float16 輸入和輸出的方式:

  • ImageFeatureValue 圖像特徵值

    • 建議的使用方式。
    • 將色彩和張量轉換成 float16。
    • 支援 bgr8 和 8 位影像格式,可安全地轉換成 float16,而不會遺失數據。
  • 張量浮點數

    • 進階路徑。
    • Float32 轉換成 float16。
    • 對於影像,這是安全的轉換,因為「bgr8」很小,適合。
    • 針對非映像, Bind 將會失敗,您必須改為傳入 TensorFloat16Bit
  • TensorFloat16 位

    • 進階路徑。
    • 您必須轉換成 float16,並以 float32 的形式傳遞輸入,這會向下轉換成 float16。

備註

大部分時候,運算符仍在執行 32 位數學運算。 溢位的風險較低,結果會截斷為 float16。 不過,如果硬體公告 float16 支援,則運行時間會利用它。

預先處理輸入數據

WinML 會執行一些前置處理步驟,讓處理輸入數據變得更簡單且更有效率。 例如,給定的輸入影像可能以各種色彩格式和圖形表示,而且可能不同於模型預期的情況。 WinML 會對影像執行轉換,使其符合,以減少開發人員的負載。

WinML 也會利用整個硬體堆疊(CPU、GPU 等)來針對特定裝置和案例提供最有效率的轉換。

不過,在某些情況下,您可能會想要手動調整輸入數據,因為您有一些特定需求。 例如,您可能不想將 VideoFrame 用於影像,或想要將介於 0-255 範圍到 0-1 範圍的圖元值正規化。 在這些情況下,您可以對數據進行自己的自訂張量處理。 如需此範例,請參閱 自定義張量化範例

備註

使用以下資源以獲得 Windows ML 的協助。

  • 若要詢問或回答有關 Windows ML 的技術問題,請使用 Stack Overflow 上的 windows-machine-learning 標籤。
  • 若要回報錯誤,請在 GitHub 提出問題。