這篇文章最初發表在 RAPIDS AI 博客here上。
介紹
NVDashboard 是一個開源軟件包,用于在交互式Jupyter 實驗室環境中實時可視化 NVIDIA GPU 指標。 NVDashboard 是所有 GPU 用戶監視系統資源的好方法。然而,它對于RAPIDS, NVIDIA 的 GPU 開源套件加速數據科學軟件庫的用戶尤其有價值。
考慮到現代數據科學算法的計算強度,在許多情況下 GPU 可以提供改變游戲規則的工作流加速。為了獲得最佳性能,底層軟件有效地使用系統資源是絕對關鍵的。盡管加速庫(如 cuDNN 和 RAPIDS )是專門設計用于執行性能優化方面的繁重任務的,但對于開發人員和最終用戶來說,驗證他們的軟件是否真正按照預期利用了 GPU 資源是非常有用的。雖然這可以通過 NVIDIA -smi 等命令行工具實現,但許多專業數據科學家更喜歡使用交互式 Jupyter 筆記本進行日常模型和工作流開發。

如圖 1所示, NVDashboard 使 Jupyter 筆記本用戶能夠在用于開發的相同交互環境中可視化系統硬件指標。支持的指標包括:
- GPU – 計算利用率
- GPU – 內存消耗
- PCIe 吞吐量
- NVLink 吞吐量
該軟件包構建在基于 Python 的儀表板服務器上,該服務器支持 Bokeh 可視化庫在實時[1]中顯示和更新圖形。另外一個 Jupyter Lab 擴展將這些儀表板作為可移動窗口嵌入到交互式環境中。大多數 GPU 指標都是通過 PyNVML 收集的, PyNVML 是一個開源的 Python 包,它構成了 NVIDIA 管理庫( NVML )的包裝。因此,可以修改/擴展可用的儀表板,以顯示可通過 NVML 訪問的任何可查詢 GPU 指標。
使用 NVDashboard
nvdashboard 軟件包在PyPI上提供,由兩個基本組件組成:
- 博克服務器:服務器組件利用出色的 Bokeh 可視化庫實時顯示和更新 GPU -診斷儀表板。所需的硬件指標可通過PyNVML訪問,該PyNVML是一個開源的 Python 包,由 NVIDIA 管理庫(NVML)的包裝組成。因此,可以修改/擴展NVDashboard以顯示任何可查詢的 GPU 指標,這些指標可以通過NVML輕松地從 Python 訪問。
- Jupyter 實驗室擴建: Jupyter 實驗室擴展將 GPU 診斷儀表板嵌入為交互式Jupyter-Lab環境中的可移動窗口。
$ pip install jupyterlab-nvdashboard # If you are using Jupyter Lab 2 you will also need to run $ jupyter labextension install jupyterlab-nvdashboard

必須澄清的是, NVDashboard 自動監控整個機器的 GPU 資源,而不僅僅是本地 Jupyter 環境使用的資源。朱皮特實驗室eExtension 當然可以用于非 i Python /筆記本開發。例如,在圖 3中,“ NVLink 時間線”和“ GPU 利用率”儀表板在 Jupyter 實驗室環境中用于監控從命令行執行的多 GPU 深度學習工作流。

博克服務器
雖然 Jupyter 實驗室擴展肯定是基于 i Python /筆記本電腦開發的愛好者的理想選擇,但其他 GPU 用戶也可以使用 sandalone Bokeh 服務器訪問儀表板。這是通過運行來完成的。
$ Python -m jupyterlab nvdashboard . server <端口號>
啟動 Bokeh 服務器后,可通過在標準 web 瀏覽器中打開相應的 url (例如 http ://< ip 地址>:< port number >)來訪問 GPU 儀表板。如圖 4所示,主菜單列出了 NVDashboard 中可用的所有儀表板。

例如,選擇“ GPU -Resources ”鏈接將打開圖 5中所示的儀表板,該儀表板使用對齊的時間線圖總結各種 GPU 資源的利用率。

要以這種方式使用 NVDashboard ,只需要 pip 安裝步驟(可以跳過實驗室擴展安裝步驟):
$ pip 安裝 jupyterlab nvdashboard
或者,您也可以克隆jupyterlab-nvdashboard存儲庫,只需執行server.py
腳本(例如python jupyterlab_nvdashboard/server.py <port-number>
)。
實施細節
現有的 nvdashboard 包提供了許多有用的 GPU – 資源儀表板。但是,修改現有儀表板和/或創建全新的儀表板非常簡單。為了做到這一點,您只需要利用 PyNVML 和 Bokeh 。
PyNVML dasic
PyNVML 是 NVIDIA 管理庫( NVML )的 Python 包裝器,它是一個基于 C 的 API ,用于監視和管理 NVIDIA GPU 設備的各種狀態。 NVML 直接由更知名的 NVIDIA 系統管理接口( NVIDIA -smi )使用。根據 NVIDIA 開發者網站, NVML 提供對以下可查詢狀態的訪問(除了此處未討論的可修改狀態外):
- ECC 錯誤計數:報告可糾正的單位錯誤和可檢測的雙位錯誤。為當前引導周期和 GPU 的生命周期提供錯誤計數。
- GPU 利用率:報告 GPU 和內存接口的計算資源的當前利用率。
- 主動計算過程:報告在 GPU 上運行的活動進程列表,以及相應的進程名稱/ id 和分配的 GPU 內存。
- 時鐘和 PState:報告了幾個重要時鐘域的最大和當前時鐘速率,以及當前 GPU 性能狀態。
- 溫度和風扇轉速:報告當前堆芯 GPU 溫度以及非無源產品的風扇轉速。
- 電源管理:對于支持的產品,會報告當前板功率消耗和功率限制。
- Identification:報告各種動態和靜態信息,包括板序列號、 PCI 設備 ID 、 VBIOS / Inforom 版本號和產品名稱。
盡管目前存在幾種不同的 NVML Python 包裝器,但我們在 GitHub 上使用 GoAi 托管的PyNVML包。這個版本的 PyNVML 使用 ctypes 包裝大多數 nvmlcapi 。 NVDashboard 僅利用查詢實時 GPU 資源利用率所需的一小部分 API ,包括:
nvmlInit()
:初始化 NVML 。初始化成功后,緩存 GPU 句柄,以降低儀表板中活動監視期間的數據查詢延遲。nvmlShutdown()
: Finalize NVML- nvmlDeviceGetCount ():獲取可用 GPU 設備的數量
nvmlDeviceGetHandleByIndex()
:獲取設備的句柄(給定整數索引)nvmlDeviceGetMemoryInfo()
:獲取內存信息對象(給定設備句柄)nvmlDeviceGetUtilizationRates()
:獲取利用率對象(給定設備句柄)nvmlDeviceGetPcieThroughput()
:獲取 PCIe 吞吐量對象(給定設備句柄)nvmlDeviceGetNvLinkUtilizationCounter()
:獲取 NVLink 利用率計數器(給定設備句柄和鏈接索引)
在 PyNVML 的當前版本中, Python 函數名的選擇通常與 C API 完全匹配。例如,要查詢每個可用設備上的當前 GPU – 利用率,代碼如下所示:
In [1]: from pynvml import *
In [2]: nvmlInit()
In [3]: ngpus = nvmlDeviceGetCount()
In [4]: for i in range(ngpus):
…: handle = nvmlDeviceGetHandleByIndex(i)
…: gpu_util = nvmlDeviceGetUtilizationRates(handle).gpu
…: print(‘GPU %d Utilization = %d%%’ % (i, gpu_util))
…:
GPU 0 Utilization = 43%
GPU 1 Utilization = 0%
GPU 2 Utilization = 15%
GPU 3 Utilization = 0%
GPU 4 Utilization = 36%
GPU 5 Utilization = 0%
GPU 6 Utilization = 0%
GPU 7 Utilization = 11%
注意,除了 GitHub 存儲庫之外, PyNVML 還托管在PyPI和鍛造伯爵上。
儀表板代碼
要修改/添加 GPU 儀表板,只需使用兩個文件(jupyterlab_bokeh_server/server.py
和jupyterlab_nvdashboard/apps/gpu.py
)。添加/修改儀表板所需的大多數 PyNVML 和 bokeh 代碼都將在gpu.py
中。只有在添加或更改菜單/顯示名稱的情況下,才需要修改server.py
。在這種情況下,必須在 routes dictionary 中指定新的/修改的名稱(鍵為所需的名稱,值為相應的儀表板定義):
routes = {
"/GPU-Utilization": apps.gpu.gpu,
"/GPU-Memory": apps.gpu.gpu_mem,
"/GPU-Resources": apps.gpu.gpu_resource_timeline,
"/PCIe-Throughput": apps.gpu.pci,
"/NVLink-Throughput": apps.gpu.nvlink,
"/NVLink-Timeline": apps.gpu.nvlink_timeline,
"/Machine-Resources": apps.cpu.resource_timeline,
}
為了讓服務器不斷刷新 bokeh 應用程序使用的 PyNVML 數據,我們使用 bokeh 的 ColumnDataSource 類在每個圖中定義數據的source。 ColumnDataSource 類允許為每種類型的數據傳遞更新函數,可以在每個應用程序的專用回調函數( cb )中調用更新函數。例如,現有 GPU 應用程序的定義如下:
請注意, PyNVML GPU 利用率數據的實時更新是在source.data.update()
調用中執行的。有了必要的ColumnDataSource
邏輯,可以通過多種方式修改標準 GPU 定義(如上)。例如,交換 x 軸和 y 軸,指定不同的調色板,甚至將圖形從 hbar 完全更改為其他圖形。
用戶可以隨時使用打開拉取請求來進行有價值的改進/添加 – 當然鼓勵社區參與!