错误传播 ¶
在分布式 PyTorch 作业中,每个主机都运行一个 TorchElastic 代理和多个工作者(作为代理的子进程)。由于工作者是由用户提供的(您的 PyTorch 脚本/作业),TorchElastic 有一种方法通过代理将错误传播到训练器,并最终传递给调度器,调度器最终通知最终用户作业的状态并应用任何重试策略。
TorchElastic 将错误分为 3 类:
分类 |
子分类 |
描述 |
---|---|---|
用户错误 |
输入错误 |
TorchElastic API 无效输入(例如,最小值大于最大节点数) |
工作器故障 |
工作器子进程上的任何故障 |
|
平台错误 |
无 |
由代理引起的故障 |
基础设施错误 |
无 |
代理和工作者域外的故障(例如主机故障) |
除了“工作者故障”之外的所有错误要么是从代理进程以规范方式抛出,要么是隐式或显式地崩溃代理进程。因此,标准语言(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][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[[…], T]
- class torch.distributed.elastic.multiprocessing.errors.ChildFailedError(name, failures)[source][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)是根本原因,应报告给调度器的初始化进程。当 torchelastic 代理检测到训练师 1 的失败时,会抛出
ChildFailedError("trainer", {1: "trainer_1/error.json"})
,将训练师 1 的错误文件内容传播到调度器的初始化进程。
- class torch.distributed.elastic.multiprocessing.errors.ErrorHandler[source][source]
将提供的异常对象以及一些关于错误的元数据以结构化的方式写入由环境变量指定的错误文件中:
TORCHELASTIC_ERROR_FILE
。如果此环境变量未设置,则简单地记录本应写入错误文件的内容。此处理程序可以被继承以自定义错误的处理。子类应重写
initialize()
和record_exception()
。
- class torch.distributed.elastic.multiprocessing.errors.ProcessFailure(local_rank, pid, exitcode, error_file)[source][source]¶
表示失败进程的结果。当工作进程失败时,它可能会将失败的根本原因记录到文件中。
尝试从提供的
error_file
读取失败时间戳,如果error_file
不存在,则时间戳为当前时间戳(自纪元以来的秒数)。message
字段是对失败情况的简要说明。如果错误文件存在,则消息从错误文件中获取。否则,根据失败签名生成一条消息。注意
假设
error_file
是由torch.distributed.elastic.multiprocessing.errors.error_handler.ErrorHandler
编写的。否则行为未定义。