Community程式設計與開發github.com

除錯 JAX OOM(從 Profiling 檔案)

當 JAX / XLA 程式因 GPU 記憶體不足而失敗(RESOURCE_EXHAUSTED、「嘗試分配時記憶體不足」、第一步或第 N 步後 OOM),且已取得 jax.profiler / XProf 的 .xplane.pb 擷取檔案時使用。

除錯 JAX OOM(從 Profiling 檔案) 是什麼?

此工具專門用於分析 JAX / XLA 程式的 GPU 記憶體不足 (OOM) 問題,它直接讀取 .xplane.pb 擷取檔案中的 XLA 計劃與 BFC 分配器事件,無需重新執行模型。它能快速分解記憶體使用情況,區分 activation、梯度、workspace 以及跨步驟的記憶體洩漏,並標示每個緩衝區的大小、角色、形狀和程式碼行號。該工具支援所有執行 JAX 的 GPU 平台(包括 CUDA 與 ROCm),但無法用於 TPU 或 eager 模式。報告會產生診斷行,並根據實測值或推估值來建議修復措施,例如啟用 gradient checkpointing、捐贈參數、或降低 micro-batch 大小。使用者只需提供 .xplane.pb 檔案或包含它的目錄,即可在 2–5 秒內獲得分析結果。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/cj401-amd/jax-trace-analysis/tree/HEAD/skills/debugging-jax-oom

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

從擷取檔案除錯 JAX OOM

概述

JIT 編譯的 JAX 步驟會將其所有暫存記憶體規劃為一個暫存區塊。因此,該步驟的記憶體使用就是 XLA 的計劃,而 .xplane.pb 檔案同時包含了該計劃與分配器的執行時期事件。scripts/oom_report.py 僅使用標準函式庫,便能於 2–5 秒內讀取這兩部分資訊:

  • 計劃: 每個模組的緩衝區分配,來自 /host:metadata。它會給出參數(以及有多少被捐贈)、非別名輸出、暫存區塊、以及堆疊峰值。對於峰值時存活的緩衝區,它會提供大小、形狀、角色以及 Python 程式碼行號。角色來自 JAX 的名稱堆疊:jvp( 代表前向(為反向傳播而保留),transpose( 代表反向,s8 自訂呼叫的輸出是函式庫的工作空間。
  • 執行時期: BFC 分配器的事件。它們會給出容量、每次執行開始時的已用位元組數、峰值、AllocatorRetry 等待時間、從未啟動 kernel 的執行、以及最後兩次執行之間的主機事件。它們還會給出最後一次執行開始時仍存活的內容,並按分配該內容的主機事件分組:outputs of jit_step execution 3、BufferFromHostBuffer(s32[…])(一個 device_put),或「在擷取開始前就已分配」。

報告會以測量值或推估值標記的診斷行結尾。請先執行以下指令:

python3 -P <此技能基底目錄>/scripts/oom_report.py <擷取目錄或 .xplane.pb> [--module 'jit_train_step(123)'] [--top 25] [--json out.json]
python3 -P <此技能基底目錄>/scripts/oom_report.py --self-test

預設情況下,它會分解最後一次執行從未啟動 kernel 的模組。如果沒有此類模組,則會選取執行了的最大模組。使用 --module 可以選取其他模組,例如評估步驟。

從診斷行到原因與修復

診斷行原因要建議的修復;節省量來自報告中的位元組數
the step itself doesn't fit僅計劃就超過了記憶體池容量依照峰值處的角色分解(如下)
↳ 大部分為 forward, kept for the backward passactivations:它們隨 batch × seq 增長;樸素注意力每層增加 B·H·S·Sjax.checkpoint / remat(節省大部分 forward-kept 的位元組,代價約為一個額外的前向傳遞);使用更小的 micro-batch 搭配梯度累積;更短的序列長度(S 減半時 S² 緩衝區縮小 4 倍)。僅在「確認 B·H·S·S 緩衝區離開計劃」時才提供 fused attention
↳ 大部分為 backward梯度及其暫存變數使用 FSDP 分片或累積;檢查 bf16 梯度是否有 f32 副本
↳ workspaceGEMM / 卷積函式庫的暫存空間通常很小;在 ROCm 上,gfx950 每個 hipBLASLt GEMM 為 64 MiB
grow by X MiB per execution, = 1.00x the non-aliased outputs程式保留了每個步驟的輸出(跨步驟的記憶體洩漏):存活清單顯示 outputs of … execution 1, 2, …在執行之間的主機事件中找到持有者(例如 $<unknown> append = list.append)。然後刪除引用、在步驟內部減少(一個 norm,而不是整個樹),或使用 jax.device_get。更大的記憶體池只會延遲 OOM
no parameter is donated … can save up to X舊的和新的參數 / 優化器狀態同時存活對狀態引數使用 donate_argnums
other live arrays take the room; the largest … came from X步驟外部的陣列:放在 GPU 上的資料集或評估副本、預先提取、其他 jit 的輸出將其保留在主機上並以串流方式傳輸、釋放它,或縮小其 dtype。「在擷取開始前就已分配」表示需要更早進行 profiling 以識別它
AllocatorRetry … longest N s, launched noneOOM 發生在擷取期間僅為證據。失敗的請求通常是該模組的暫存區塊或某個輸出
XLA already rematerialized N instructionsXLA 自己的 rematerialization 已經在極限下執行過預期修復來自程式本身,而非來自 XLA

對於每項修復,請給出其估計的節省量與成本,並標記為推估值。檢查估計值是否超出容量。只有當 GPU 確實有空間時,「調高 XLA_PYTHON_CLIENT_MEM_FRACTION」才能修復計劃無法容納的問題。容量遠低於 HBM 暗示該比例已被設定;擷取檔案不會記錄環境變數。

以 JAX 術語解釋 Playbook 的記憶體結構

Ultra-Scale Playbook(「對記憶體使用進行 Profiling」)將訓練記憶體分為權重、梯度、優化器狀態和 activation。在報告中:

  • 權重 + 優化器狀態 = 步驟的參數。Adam 在 fp32 下每個參數佔 12 B(p, m, v)。被捐贈意味著沒有第二份副本。
  • 梯度 = 峰值處的 backward 角色,如果步驟回傳梯度則還包括輸出。
  • Activations = forward, kept for the backward pass。Scan / nn.scan 模型會將它們作為堆疊的 [layers, …] 緩衝區保留在 while 迴圈中。
  • 「步驟 1 通過,步驟 N 失敗」: 在 PyTorch 中,這是因為第一步創建了優化器狀態。在 JAX 中,狀態在步驟 1 之前就已存在,因此請改為查看增長行。第一次呼叫還會編譯和自動調優,因此第一次執行之前的峰值是編譯時間。

規則

  • 僅使用擷取檔案。 不要為了測試修復而重建模型或重新執行工作:根據計劃的位元組數進行估計,並說明如何在使用者端確認(jit(...).lower(...).compile().memory_analysis())。
  • 不要寫入擷取目錄。 XProf 的轉換器(xspace_to_tool_names、memory_viewer、xprof CLI)會在 .xplane.pb 旁邊寫入 *.hlo_proto.pb 快取檔案。如果您需要 XProf 的檢視,請先將 .xplane.pb 複製到暫存目錄。
  • 為每個數字標記 為測量值、讀取值或推估值。

測量參考(單一 MI355X,小記憶體池,2026-11-06)

擷取報告顯示的內容
attention 計劃過大需要 3.72 GiB > 2.79 GiB;堆疊峰值 81.6% forward-kept;f32[8,8,1024,1024] ×5 位於 softmax 行;暫存區塊 3,495 MiB = 錯誤訊息中的「3.41GiB」;AllocatorRetry 10 秒;89 個 remat 指令
每個步驟都保留梯度步驟開始時使用量 316 → 1,252 MiB,每個步驟 +104.0 MiB = 1.00× 非別名輸出;計劃 788 MiB 可容納;步驟之間有 $<unknown> append
沒有捐贈需要 3.88 GiB > 2.79 GiB;1,902 MiB 參數 + 1,902 MiB 輸出,0 被捐贈;暫存區塊僅 172 MiB
MaxText llama2-7b,8 GPU,FSDP(可容納)暫存區塊 61.9 GiB;堆疊峰值 57% forward-kept,scan 堆疊 bf16[32,4,4096,11008] ×2 透過 while.50

限制

  • 每個檔案僅限一個主機: 多主機執行會為每個主機產生一個 .xplane.pb,因此請為每個主機都執行一次。
  • 僅限 HBM: 只有記憶體空間 0 會被分解。主機卸載顯示為 memory space 5。
  • 連續性:「可容納」是比較位元組數。BFC 還需要連續的區塊,因此接近容量邊界時仍可能因碎片化而失敗。
  • 「其他」角色: 由 XLA 創建的運算(無 JAX 名稱堆疊)且無別名的緩衝區。
  • CUDA: 未經測試。它使用相同的 BFC 和 XLA 事件,但名稱尚未驗證。
  • TPU / eager: TPU 擷取僅提供計劃總計,沒有堆疊峰值和執行資訊。Eager(逐運算)程式顯示為許多小模組,請在該處閱讀執行時期部分。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能