本頁面由 Cloud Translation API 翻譯而成。
Switch to English

Optimize TensorFlow performance using the Profiler

使用Profiler隨附的工具來跟踪TensorFlow模型的性能。查看模型在主機(CPU),設備(GPU)或主機與設備的組合上的性能。

分析可幫助您了解模型中各種TensorFlow操作(ops)的硬件資源消耗(時間和內存),並解決性能瓶頸,最終使模型執行更快。

本指南將引導您逐步了解如何安裝Profiler,可用的各種工具,Profiler收集性能數據的方式不同,以及一些用於優化模型性能的推薦最佳實踐。

如果要在Cloud TPU上分析模型性能,請參考Cloud TPU指南

安裝Profiler和GPU必備組件

通過從GitHub存儲庫下載並運行install_and_run.py腳本來安裝Profiler。

要在GPU上進行分析,您必須:

  1. 安裝CUDA®Toolkit 10.1或更高版本。 CUDA®Toolkit 10.1僅支持單個GPU配置文件。要配置多個GPU,請參閱配置多個GPU 。確保您安裝的CUDA®驅動程序版本至少為440.33(對於Linux)或441.22(對於Windows)。
  2. 確保路徑上存在CUPTI:
/sbin/ldconfig -N -v $(sed 's/:/ /g' <<< $LD_LIBRARY_PATH) | \
grep libcupti

如果路徑上沒有CUPTI,請通過運行以下命令將其安裝目錄添加到$LD_LIBRARY_PATH環境變量中:

export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH

再次運行上面的ldconfig命令以驗證是否找到了CUPTI庫。

配置多個GPU

TensorFlow當前僅支持單個主機系統的多個GPU配置文件。當前不支持針對多主機系統的多GPU配置文件。安裝CUDA®Toolkit 10.2或更高版本以配置多個GPU。由於TensorFlow僅支持不超過10.1的CUDA®Toolkit版本,因此請創建指向libcudart.so.10.1libcupti.so.10.1符號鏈接。

sudo ln -s /usr/local/cuda/lib64/libcudart.so.10.2 /usr/local/cuda/lib64/libcudart.so.10.1
sudo ln -s /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.2 /usr/local/cuda/extras/CUPTI/lib64/libcupti.so.10.1

要分析多工GPU配置,請分別分析各個工。

解決特權問題

在Docker環境或Linux中使用CUDA®Toolkit 10.1運行性能分析時,可能會遇到與CUPTI特權不足( CUPTI_ERROR_INSUFFICIENT_PRIVILEGES )相關的問題。請參閱NVIDIA開發人員文檔,以了解有關如何在Linux上解決這些問題的更多信息。

要解決Docker環境中的CUPTI特權問題,請運行

docker run option '--privileged=true'

探查器工具

從TensorBoard中的Profile選項卡訪問Profiler,只有在捕獲了一些模型數據後才會出現。

Profiler提供了一些工具來幫助進行性能分析:

  • 概述頁面
  • 輸入管道分析儀
  • TensorFlow統計
  • 跟踪查看器
  • GPU內核統計
  • 內存配置文件工具

概述頁面

概述頁面提供了模型在概要文件運行期間的性能的頂級視圖。該頁面為您顯示了主機和所有設備的匯總概述頁面,並提供了一些改善模型訓練性能的建議。您還可以在“主機”下拉列表中選擇單個主機。

概述頁面顯示數據如下:

圖片

  • 性能摘要-顯示模型性能的高級摘要。性能摘要包括兩個部分:

    1. 步進時間細分-將平均步進時間細分為花費時間的多個類別:

      • 編譯-編譯內核所花費的時間
      • 輸入-讀取輸入數據所花費的時間
      • 輸出-讀取輸出數據所花費的時間
      • 內核啟動-主機啟動內核所花費的時間
      • 主機計算時間
      • 設備到設備的通信時間
      • 設備上計算時間
      • 所有其他,包括Python開銷
    2. 設備計算精度-報告使用16位和32位計算的設備計算時間的百分比

  • 步驟時間圖-顯示所有採樣步驟中設備步驟時間的圖表(以毫秒為單位)。每個步驟都分為花費時間的多個類別(具有不同的顏色)。紅色區域對應於設備處於空閒狀態以等待主機輸入數據的步驟時間的一部分。綠色區域顯示設備實際工作了多少時間

  • 設備上的前10個TensorFlow操作-顯示運行時間最長的設備上操作。

    每行顯示一個操作者的自身時間(所有操作者所用時間的百分比),累積時間,類別和名稱。

  • 運行環境-顯示模型運行環境的高級摘要,包括:

    • 使用的主機數
    • 設備類型(GPU / TPU)
    • 設備核心數
  • 後續步驟的建議-報告綁定模型的時間,並建議可用於查找和解決模型性能瓶頸的工具

輸入管道分析儀

當TensorFlow程序從文件中讀取數據時,它以流水線方式從TensorFlow圖的頂部開始。讀取過程分為多個串聯的數據處理階段,其中一個階段的輸出是下一個階段的輸入。這種讀取數據的系統稱為輸入管道

從文件讀取記錄的典型管道具有以下階段:

  1. 文件讀取
  2. 文件預處理(可選)
  3. 文件從主機傳輸到設備

低效的輸入管道可能會嚴重降低您的應用程序速度。當應用程序在輸入管道中花費大量時間時,該應用程序被視為輸入綁定 。使用從輸入管道分析器獲得的見解來了解輸入管道效率低下的地方。

輸入管道分析器會立即告訴您程序是否受輸入限制,並引導您進行設備和主機側分析,以調試輸入管道中任何階段的性能瓶頸。

有關優化數據輸入管道的建議最佳實踐,請參閱有關輸入管道性能的指南。

輸入管道儀表板

要打開輸入管道分析器,請選擇Profile ,然後從“ 工具”下拉列表中選擇input_pipeline_analyzer

圖片

儀表板包含三個部分:

  1. 摘要-總結整個輸入管道,其中包含有關您的應用程序是否受輸入綁定以及(如果有)輸入多少的信息。
  2. 設備端分析-顯示詳細的設備端分析結果,包括設備步長時間以及每個步驟等待跨內核輸入數據所花費的設備時間範圍
  3. 主機端分析-顯示主機端的詳細分析,包括主機上輸入處理時間的細分

輸入管道摘要

摘要通過顯示等待主機輸入所花費的設備時間百分比來報告是否輸入了程序。如果您使用已檢測的標準輸入管道,則該工具將報告大部分輸入處理時間在何處。

設備端分析

設備端分析可提供有關在設備上花費的時間而不是在主機上花費的時間的信息,以及花費了多少設備時間來等待來自主機的輸入數據。

  1. 針對步驟編號繪製的步驟時間-顯示所有採樣步驟中設備步驟時間的圖表(以毫秒為單位)。每個步驟都分為花費時間的多個類別(具有不同的顏色)。紅色區域對應於設備處於空閒狀態以等待主機輸入數據的步驟時間的一部分。綠色區域顯示設備實際工作了多少時間
  2. 步進時間統計信息-報告設備步進時間的平均值,標準偏差和範圍([最小,最大])

主機端分析

主機端分析將主機上的輸入處理時間(花費在tf.data API ops上的時間) tf.data為以下幾類:

  • 按需從文件讀取數據-在不進行緩存,預取和交織的情況下從文件讀取數據所花費的時間
  • 預先從文件中讀取數據-讀取文件所花費的時間,包括緩存,預取和交織
  • 數據預處理-在預處理操作上花費的時間,例如圖像解壓縮
  • 排隊要傳輸到設備的數據-在將數據傳輸到設備之前將數據放入饋入隊列所花費的時間

展開輸入操作統計信息,以查看各個輸入操作及其類別的統計信息(按執行時間細分)。

圖片

出現一個源數據表,每個條目包含以下信息:

  1. 輸入操作-顯示輸入操作的TensorFlow操作名稱
  2. 計數-顯示概要分析期間op執行的實例總數
  3. 總時間(以毫秒為單位)-顯示在每個實例上花費的累計時間總和
  4. 總時間百分比-顯示操作的總時間佔輸入處理總時間的一部分
  5. 總自拍時間(以毫秒為單位)-顯示在每個實例上花費的自拍時間的累積總和。此處的自身時間用於衡量在函數體內花費的時間,不包括在調用函數中花費的時間。
  6. 總自我時間% 。將總的自我時間顯示為輸入處理所花費的總時間的一部分
  7. 類別 。顯示輸入操作的處理類別

TensorFlow統計

TensorFlow Stats工具顯示在分析會話期間在主機或設備上執行的每個TensorFlow op(op)的性能。

圖片

該工具在兩個窗格中顯示性能信息:

  • 上方窗格最多顯示四個餅圖:

    1. 主機上每個op的自執行時間的分佈
    2. 主機上每種op類型的自執行時間的分佈
    3. 設備上每個操作的自執行時間的分佈
    4. 設備上每種操作類型的自執行時間的分佈
  • 下部窗格顯示一張表,該表報告有關TensorFlow op的數據,其中每個op對應一行,每種數據類型對應一列(通過單擊列標題對列進行排序)。單擊上部窗格右側的“導出為CSV”按鈕,以將該表中的數據導出為CSV文件。

    注意:

    • 如果任何操作有子操作:

      • 一個操作的“累計”總時間包括在子操作內部花費的時間

      • 一個操作的“自我”總時間不包括在子操作內部花費的時間

    • 如果操作在主機上執行:

      • 操作在設備上導致的總自拍時間百分比為0
      • 包括該操作在內的設備上的總自拍時間的累計百分比為0
    • 如果操作在設備上執行:

      • 此操作在主機上導致的總自拍時間百分比將為0
      • 主機上包括該操作在內的總自拍時間的累計百分比為0

您可以選擇在餅圖和表格中包括或排除空閒時間。

跟踪查看器

跟踪查看器顯示時間線,其中顯示:

  • TensorFlow模型執行的操作的持續時間
  • 系統的哪一部分(主機或設備)執行了操作。通常,主機執行輸入操作,預處理訓練數據並將其傳輸到設備,而設備執行實際的模型訓練

跟踪查看器使您可以識別模型中的性能問題,然後採取步驟解決它們。例如,從較高的層次上,您可以確定輸入或模型訓練是否花費了大部分時間。深入研究,您可以確定執行時間最長的操作。請注意,跟踪查看器每個設備最多只能有100萬個事件。

跟踪查看器界面

當您打開跟踪查看器時,它將顯示您最近的運行:

圖片

該屏幕包含以下主要元素:

  1. 時間軸窗格-顯示隨著時間的推移設備和主機執行的操作
  2. 詳細信息窗格-顯示在“時間軸”窗格中選擇的操作的其他信息

“時間軸”窗格包含以下元素:

  1. 頂欄-包含各種輔助控件
  2. 時間軸-顯示相對於軌跡開始的時間
  3. 區段和軌道標籤-每個區段包含多個軌道,並且在左側具有一個三角形,您可以單擊以展開和折疊該區段。系統中每個處理元素都有一個區域
  4. 工具選擇器-包含用於與軌跡查看器進行交互的各種工具,例如“縮放”,“平移”,“選擇”和“計時”。使用計時工具標記時間間隔。
  5. 事件-這些事件顯示執行操作的時間或元事件的持續時間,例如培訓步驟
段和軌道

跟踪查看器包含以下部分:

  • 每個設備節點的一個區域 ,標有設備芯片的編號和芯片中的設備節點的編號(例如/device:GPU:0 (pid 0) )。每個設備節點部分均包含以下軌道:
    • 步驟-顯示設備上正在運行的培訓步驟的持續時間
    • TensorFlow Ops- 。顯示在設備上執行的操作
    • XLA行動-顯示XLA操作(OPS)如果XLA是所使用的編譯器在設備上運行過(各TensorFlow運算被轉換成一個或幾個XLA OPS的XLA編譯器翻譯這些XLA OPS成代碼,所述設備上運行。)。
  • 一段在主機CPU上運行的線程的名稱“主機線程” 。該部分為每個CPU線程包含一個軌道。請注意,您可以忽略部分標籤旁邊顯示的信息。
大事記

時間軸內的事件以不同的顏色顯示;顏色本身沒有特定含義。

跟踪查看器還可以在TensorFlow程序中顯示Python函數調用的跟踪。如果使用tf.profiler.experimental.start() API,則可以在開始分析時使用ProfilerOptions tf.profiler.experimental.start()啟用Python跟踪。或者,如果使用採樣模式進行性能分析,則可以使用“ 捕獲配置文件”對話框中的下拉選項來選擇跟踪級別。

圖片

GPU內核統計

該工具顯示了每個GPU加速內核的性能統計信息和原始操作。

圖片

該工具在兩個窗格中顯示信息:

  • 上方窗格顯示一個餅圖,該餅圖顯示了總耗時最長的CUDA內核

  • 下部窗格顯示一個表,其中包含每個唯一內核操作對的以下數據:

    • 按照內核運行對分組的總GPU持續時間的降序排列
    • 啟動的內核的名稱
    • 內核使用的GPU寄存器數
    • 共享(靜態+動態共享)內存使用的總大小(以字節為單位)
    • 表示為blockDim.x, blockDim.y, blockDim.z的塊尺寸
    • 網格尺寸表示為gridDim.x, gridDim.y, gridDim.z
    • 運營商是否有資格使用TensorCores
    • 內核是否包含TensorCore指令
    • 啟動此內核的操作的名稱
    • 此內核操作對的出現次數
    • 經過的GPU總時間(以微秒為單位)
    • GPU的平均經過時間(以微秒為單位)
    • 經過的最短GPU時間(以微秒為單位)
    • GPU經過的最大時間(以微秒為單位)

內存配置文件工具

內存配置文件工具會在分析間隔期間監視設備的內存使用情況。您可以使用此工具執行以下操作:

  • 通過查明峰值內存使用情況以及為TensorFlow操作分配相應的內存分配,來調試內存不足(OOM)問題。您還可以調試運行多租戶推斷時可能出現的OOM問題
  • 調試內存碎片問題

內存配置文件工具分三部分顯示數據:

  1. 內存配置文件摘要
  2. 內存時間線圖
  3. 內存明細表

內存配置文件摘要

本部分顯示TensorFlow程序的內存配置文件的高級摘要,如下所示:

內存配置文件摘要包含六個字段:

  1. 內存ID-下拉列表,其中列出了所有可用的設備內存系統。從下拉列表中選擇要查看的內存系統
  2. #Allocation-在分析間隔內進行的內存分配數
  3. #Deallocation-分析間隔中的內存釋放數
  4. 內存容量-您選擇的內存系統的總容量(以GiB為單位)
  5. 峰值堆使用量-自模型開始運行以來的峰值內存使用量(以GiB為單位)
  6. 峰值內存使用量-分析間隔中的峰值內存使用量(以GiB為單位)。該字段包含以下子字段:
    1. 時間戳-時間線圖上出現峰值內存使用量的時間戳
    2. 堆棧保留-堆棧上保留的內存量(以GiB為單位)
    3. 堆分配-堆上分配的內存量(以GiB為單位)
    4. 可用內存-可用內存量(以GiB為單位)。內存容量是堆棧預留,堆分配和可用內存的總和
    5. 碎片-碎片百分比(越低越好)。它的計算方式為(1-可用內存最大塊的大小/總可用內存)的百分比

內存時間線圖

本節顯示了內存使用情況(以GiBs為單位)以及碎片百分比與時間(以ms為單位)的關係圖。

圖片

X軸表示分析間隔的時間軸(以毫秒為單位)。左側的Y軸表示內存使用情況(以GiBs為單位),右側的Y軸表示碎片百分比。在X軸上的每個時間點,總內存都分為三類:堆棧(紅色),堆(橙色)和空閒(綠色)。將鼠標懸停在特定的時間戳上可以查看有關此時內存分配/取消分配事件的詳細信息,如下所示:

圖片

彈出窗口顯示以下信息:

  • timestamp(ms)-所選事件在時間線上的位置
  • 事件-事件類型(分配或取消分配)
  • request_size(GiBs)-請求的內存量。這將是解除分配事件的負數
  • location_size(GiBs)-實際分配的內存量。這將是解除分配事件的負數
  • tf_op-請求分配/取消分配的TensorFlow Op
  • step_id-發生此事件的訓練步驟
  • region_type-此分配的內存用於的數據實體類型。可能的值為temp的臨時值,為激活和漸變的output值,以及對權重和常數的persist / dynamic
  • data_type-張量元素類型(例如,uint8表示8位無符號整數)
  • tensor_shape-被分配/取消分配的張量的形狀
  • memory_in_use(GiBs)-在此時間點正在使用的總內存

內存故障表

下表顯示了分析間隔中處於峰值內存使用時的活動內存分配。

圖片

每個TensorFlow Op都有一行,並且每一行都有以下列:

  • Op名稱-TensorFlow op的名稱
  • 分配大小(GiB)-分配給此操作的內存總量
  • 請求的大小(GiB)-此操作請求的總內存量
  • 出現次數-此操作的分配次數
  • 區域類型-此分配的內存用於的數據實體類型。可能的值為temp的臨時值,為激活和漸變的output值,以及對權重和常數的persist / dynamic
  • 數據類型-張量元素類型
  • 形狀-分配的張量的形狀

收集績效數據

TensorFlow Profiler收集TensorFlow模型的主機活動和GPU跟踪。您可以將Profiler配置為通過編程模式或採樣模式收集性能數據。

分析API

您可以使用以下API執行分析。

053
tf.profiler.experimental.start('logdir')
# Train the model here
tf.profiler.experimental.stop()
  • 使用上下文管理器的編程模式
with tf.profiler.experimental.Profile('logdir'):
    # Train the model here
    pass
  • 採樣模式-通過使用tf.profiler.experimental.server.start()來啟動按需分析,並在運行TensorFlow模型的情況下啟動gRPC服務器。啟動gRPC服務器並運行模型後,您可以通過TensorBoard配置文件插件中的“ 捕獲配置文件”按鈕捕獲配置文件。如果尚未運行TensorBoard實例,請使用上面“安裝探查器”部分中的腳本啟動TensorBoard實例。

    舉個例子,

# Start a gRPC server at port 6009
tf.profiler.experimental.server.start(6009)
# ... TensorFlow program ...

使用“ 捕獲配置文件”對話框來指定:

  • 配置文件服務URL或TPU名稱
  • 分析持續時間
  • 設備,主機和Python函數調用跟踪的級別
  • 如果最初不成功,您希望探查器重試捕獲配置文件的次數

分析自定義訓練循環

要在TensorFlow代碼中分析自定義訓練循環,請使用tf.profiler.experimental.Trace API對訓練循環進行tf.profiler.experimental.Trace以標記Profiler的步驟邊界。 name參數用作步驟名稱的前綴, step_num關鍵字參數附加在步驟名稱中, _r關鍵字參數使此跟踪事件由Profiler處理為步驟事件。

舉個例子,

for step in range(NUM_STEPS):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_data = next(dataset)
        train_step(train_data)

這將啟用Profiler的基於步驟的性能分析,並使步驟事件顯示在跟踪查看器中。

確保在tf.profiler.experimental.Trace上下文中包括數據集迭代器,以對輸入管道進行準確的分析。

下面的代碼段是反模式:

for step, train_data in enumerate(dataset):
    with tf.profiler.experimental.Trace('train', step_num=step, _r=1):
        train_step(train_data)

分析用例

探查器涵蓋了四個不同軸上的許多用例。目前支持某些組合,將來還會添加其他組合。一些用例是:

  • 本地配置文件與遠程配置文件:這是設置配置文件環境的兩種常用方法。在本地配置中,在與模型執行相同的機器上調用配置API,例如,具有GPU的本地工作站。在遠程分析中,在與執行模型的機器不同的機器上(例如,在Cloud TPU上)調用分析API。
  • 對多個工作人員進行性能分析:使用TensorFlow的分佈式培訓功能時,您可以配置多台計算機。
  • 硬件平台:Profile CPU,GPU和TPU。

下表是TensorFlow 2.3中各種分析API支持的上述用例的快速概述:

分析API 本地遠程多名工人硬件平台
TensorBoard Keras回調 支持的不支持不支持 CPU,GPU
tf.experimental.profiler函數API 支持的不支持不支持 CPU,GPU
上下文管理器API 支持的不支持不支持 CPU,GPU
按需API 不支持支持的有限的支持 CPU,GPU,TPU

最佳模型性能的最佳做法

使用適用於您的TensorFlow模型的以下建議以實現最佳性能。

通常,請在設備上執行所有轉換,並確保為平台使用cuDNN和Intel MKL等庫的最新兼容版本。

優化輸入數據管道

高效的數據輸入管道可以通過減少設備空閒時間來極大地提高模型執行速度。考慮將以下最佳實踐詳見這裡 ,讓您的數據輸入管道更高效:

  • 預取數據
  • 並行數據提取
  • 並行數據轉換
  • 在內存中緩存數據
  • 向量化用戶定義的函數
  • 應用轉換時減少內存使用

此外,請嘗試使用綜合數據運行模型,以檢查輸入管道是否是性能瓶頸。

提高設備性能

  • 增加訓練小批量的大小(訓練循環的一次迭代中每個設備使用的訓練樣本數)
  • 使用TF統計信息來了解設備上操作的運行效率
  • 使用tf.function進行計算,還可以選擇啟用experimental_compile標誌
  • 盡量減少步驟之間的主機Python操作並減少回調。每隔幾步而不是每一步計算指標
  • 保持設備計算單元繁忙
  • 將數據並行發送到多個設備
  • 優化數據佈局以優先選擇頻道(例如,NHCH比NHWC)。某些GPU(如NVIDIA®V100)在NHWC數據佈局下的性能更好。
  • 考慮使用16位數字表示形式,例如fp16 ,IEEE指定的半精度浮點格式或Brain浮點bfloat16格式
  • 考慮使用Keras混合精度API
  • 在GPU上進行訓練時,請使用TensorCore。當精度為fp16且輸入/輸出尺寸可被8或16整除時,GPU內核使用TensorCore(對於int8)

額外資源