評價此頁

錯誤傳播#

創建於:2021 年 5 月 4 日 | 最後更新於:2021 年 7 月 8 日

在分散式 PyTorch 作業中的每個主機都執行一個 TorchElastic 代理,以及多個工作程序(作為 TorchElastic 代理的子程序)。由於工作程序是使用者提供的(你的 PyTorch 指令碼/作業),TorchElastic 有一種方法可以將訓練器上的錯誤透過代理傳播到排程器,最終通知終端使用者作業的狀態並應用任何重試策略。

TorchElastic 將錯誤分為 3 類

類別

子類別

描述

使用者錯誤

輸入錯誤

TorchElastic API 的無效輸入(例如 min > max 節點)

工作程序故障

工作程序子程序上的任何故障

平臺錯誤

不適用

由代理引起的故障

基礎設施錯誤

不適用

代理和工作程序領域之外的故障(例如,主機故障)

除了“工作程序故障”之外的所有錯誤,要麼是從代理程序規範地引發,要麼隱式或顯式地導致代理程序崩潰。因此,標準的 Python 異常處理策略適用。

工作程序故障比較特殊,因為異常/故障源於與代理不同的程序,因此錯誤需要程序間傳播(例如,代理不能簡單地 `try-catch` 工作程序中引發的異常)。

TorchElastic 代理使用 torch.distributed.elastic.multiprocessing.start_processes() 來啟動工作程序,該函式內建了基於檔案的簡單程序間錯誤傳播。

任何用 record() 裝飾的函式或二進位制入口點都會將未捕獲的異常(帶有跟蹤資訊)寫入由環境變數 `TORCHELASTIC_ERROR_FILE` 指定的檔案。父程序(例如代理)在它啟動的每個子程序上設定此環境變數,然後聚合所有子程序的錯誤檔案,並傳播具有**最小**時間戳的檔案(例如,**第一個**錯誤)。

方法和類#

torch.distributed.elastic.multiprocessing.errors.record(fn, error_handler=None)[source]#

使用提供的 `error_handler` 記錄裝飾函式中發生的錯誤/異常的語法糖。

使用此裝飾器等同於

error_handler = get_error_handler()
error_handler.initialize()
try:
    foobar()
except ChildFailedError as e:
    _, failure = e.get_first_failure()
    error_handler.dump_error_file(failure.error_file, failure.exitcode)
    raise
except Exception as e:
    error_handler.record_exception(e)
    raise

重要提示

在每個程序的頂級方法上使用此裝飾器一次,通常是主方法。

示例

@record
def main():
    pass


if __name__ == "__main__":
    main()
返回型別

Callable[[~_P], Optional[_R]]

class torch.distributed.elastic.multiprocessing.errors.ChildFailedError(name, failures)[source]#

可以從用 `@record` 裝飾器註釋的函式引發的特殊異常型別,以便將子程序(根異常)原樣傳播到堆疊中(例如,不被包裝在父程序的跟蹤資訊中)。

在父程序是簡單的保姆程序而子程序(工作程序)實際執行有意義的計算的情況下很有用。在這種情況下,錯誤通常發生在子程序中,因為父程序沒有執行任何非平凡的操作,並且子程序的錯誤應該傳播到排程器以進行準確的根本原因診斷。

注意

傳播依賴於錯誤檔案而不是異常處理,以支援函式和二進位制啟動。

示例

# process tree on a host (container)
0: scheduler-init-process:
           |- 1: torchelastic_agent:
                    |- 2: trainer_0 (ok)
                    |- 3: trainer_1 (fail) -> error.json
                    |- ...
                    |- n+2: trainer_n (ok)
           |- n+3: other processes
           |- ...

在上面的示例中,訓練器 1 的故障(寫入 error.json)是根本原因,應該報告給排程器的 init 程序。torchelastic 代理在檢測到訓練器 1 的故障時會引發 `ChildFailedError("trainer", {1: "trainer_1/error.json"})`,這將把訓練器 1 錯誤檔案的內容傳播到排程器的 init 程序。

class torch.distributed.elastic.multiprocessing.errors.ErrorHandler[source]#

以結構化的 JSON 格式將提供的異常物件以及有關錯誤的更多元資料寫入由環境變數 `TORCHELASTIC_ERROR_FILE` 指定的錯誤檔案。如果未設定此環境變數,則僅記錄將寫入錯誤檔案的內容。

此處理程式可以被子類化以自定義錯誤處理。子類應重寫 `initialize()` 和 `record_exception()`。

class torch.distributed.elastic.multiprocessing.errors.ProcessFailure(local_rank, pid, exitcode, error_file)[source]#

表示失敗的程序結果。當工作程序失敗時,它可能會將失敗的根本原因記錄到檔案中。

嘗試從提供的 `error_file` 讀取失敗時間戳,如果 `error_file` 不存在,則時間戳為當前時間戳(自紀元以來的秒數)。

`message` 欄位是對失敗的簡潔解釋。如果錯誤檔案存在,則訊息從錯誤檔案中獲取。否則,將根據失敗簽名生成一條訊息。

注意

假定 `error_file` 是由 `torch.distributed.elastic.multiprocessing.errors.error_handler.ErrorHandler` 編寫的。否則行為未定義。