想要了解自己的 PyTorch 項(xiàng)目在哪些地方分配 GPU 內(nèi)存以及為什么用完嗎?不妨試試這個(gè)可視化工具。
近日,PyTorch 核心開(kāi)發(fā)者和 FAIR 研究者 Zachary DeVito 創(chuàng)建了一個(gè)新工具(添加實(shí)驗(yàn)性 API),通過(guò)生成和可視化內(nèi)存快照(memory snapshot)來(lái)可視化 GPU 內(nèi)存的分配狀態(tài)。這些內(nèi)存快照記錄了內(nèi)存分配的堆棧跟蹤以及內(nèi)存在緩存分配器狀態(tài)中的位置。
接下來(lái),通過(guò)將這些內(nèi)存快照可視化為火焰圖(flamegraphs),內(nèi)存的使用位置也就能一目了然地看到了。
圖靈獎(jiǎng)得主 Yann Lecun 也轉(zhuǎn)推了這個(gè)工具。
Twitter@Zachary DeVito
下面我們來(lái)看這個(gè)工具的實(shí)現(xiàn)原理(以第一人稱(chēng)「我們」描述)。
生成快照
首先,我們必須記錄每次分配的堆棧幀信息。
記錄這些堆棧跟蹤的速度非??欤看畏峙浼s 1 us,正常的 PyTorch 內(nèi)核調(diào)用需要至少 8 us),但我們默認(rèn)將其關(guān)閉。而啟用之后,我們可以分配一些內(nèi)存并拍攝快照。
快照記錄了整個(gè)分配器的狀態(tài),如下所示。
快照是具有以下結(jié)構(gòu)的 Segment 字典列表。
Segments 是直接從 cudaMalloc 請(qǐng)求并由分配器緩存的內(nèi)存。因此,我們可以只使用這些 segments 中的一部分,緩存分配器將它們分為一個(gè)或更多個(gè) Block。所有的塊始終保持相同的分配狀態(tài)。同時(shí),使用_record_memory_history,每個(gè)塊還將記錄一個(gè) History 對(duì)象,該對(duì)象會(huì)記住塊中最后一次分配的位置,包括作為 Frames 列表的堆棧跟蹤。
對(duì)于 active_allocated 塊,它其中存在的內(nèi)容和當(dāng)前分配的內(nèi)容將有一個(gè)歷史記錄。對(duì)于 inactive 塊,可能會(huì)有多個(gè)條目來(lái)記錄塊內(nèi)存中最后存在的內(nèi)容??赡懿恢挂粋€(gè)條目的原因在于分配器在空閑時(shí)會(huì)合并分割塊,并記錄下兩次拆分的歷史。為了避免出現(xiàn)大量的歷史記錄,我們只保留不與任何更新塊重合的塊的歷史記錄。
保存快照
快照因自身設(shè)計(jì)而可以之后離線查看。
文件_memory_viz.py 可以直接用作交互式命令來(lái)處理保存的快照。
可視化快照
_memory_viz.py 工具也可以生成內(nèi)存的可視化火焰圖。
可視化圖將分配器中所有的字節(jié)(byte)按不同的類(lèi)來(lái)分割成段,如下圖所示(原文為可交互視圖)。
火焰圖可視化是一種將資源(如內(nèi)存)使用劃分為不同類(lèi)的方法,然后可以進(jìn)一步細(xì)分為更細(xì)粒度的類(lèi)別。
memory 視圖很好地展現(xiàn)了內(nèi)存的使用方式。但對(duì)于具體地調(diào)試分配器問(wèn)題,首先將內(nèi)存分類(lèi)為不同的 Segment 對(duì)象是有用的,而這些對(duì)象是分配軌跡的單個(gè) cudaMalloc 段。
比較快照
該可視化器還可以生成顯示在兩個(gè)快照之間添加和刪除的段的可視化。例如,我們可以使用更大的輸入重新運(yùn)行模型,并查看分配器如何為更大的臨時(shí)對(duì)象請(qǐng)求更多內(nèi)存。
比較視圖僅顯示新段,這有助于找出哪些代碼路徑提示分配更多內(nèi)存。
$ python _memory_viz.py compare snapshot.pickle snapshot2.pickle -o compare.svg only_before = [] only_after = [140636932014080, 140636827156480, 140634912456704, 140634839056384, 140634843250688, 140634841153536, 140634866319360, 140634811793408, 140634845347840, $ 140636806184960, 140636778921984, 140634878902272]
?
編輯:黃飛
?
評(píng)論