当前位置: 首页 > 后端技术 > Python

TorchDynamo的执行流程

时间:2023-03-26 15:09:32 Python

1执行流程1.1初始化并设置全局变量extra_index。这是PEP523设置PyCodeObject.co_extra所要求的。初始化TSS密钥。这是PEP539要求的。Tss的密钥是固定的。这里定义的key只是用来存储回调的。Tss对每个线程都是私有的(每个线程都有一个独特的键到void*值的映射)。Dynamo回调都一样吗?1.2设置evalframe替换默认的evalframe函数set_eval_frame_py的入参args[0]应该是Python传入的回调。在Python中调用该函数_TorchDynamoContext,Python方法名是set_eval_frame。1.2.1函数的主要作用是将传入的回调保存到线程专有存储中。如有必要,将eval_frame设置为custom_eval_frame_shim,这是返回前保存在tss中的旧回调。>eval_frame=&custom_eval_frame_shim1.3_TorchDynamoContext:用于设置转换后的字节码的回调函数这是对应于torch._dynamo.optimize(...)的上下文管理器。回调是Python代码。__enter__通过self.prior=set_eval_frame(self.callback)保存之前的回调。set_eval_frame就是上面说的set_eval_frame_py。__exit__通过set_eval_frame(self.prior)恢复之前的evalframe。__call__:当我们调用optimizer('inductor')(fn)时,Dynamo会将fn的帧评估函数替换为Dynamo自定义的,并传入回调函数。传入的回调函数将由自定义帧评估函数调用。回调函数会解析并重构帧中的原始字节码,并在此过程中跟踪模型执行图的结构。当然,并不是每次计算帧时都会调用回调函数。例如,如果一帧已经被解析和重构(缓存),那么此时会直接执行缓存中的重构代码。1.4执行Python字节码时,这里调用custom_eval_frame_shim对evalframe获取回调,用于eval:_custom_eval_frame_shimcallback=eval_frame_callback_get():获取_TorchDynamoContext中设置的回调获取当前PyThread_tss_get_custom_eval_frameCacheEntry*extra_f(fcode_)=get_PyCodeObject的extra字段.该字段用于放置自定义编译结果。第一次调用时extra为空,没有设置。在下面调用set_extra之前,该值将不可用。result=call_callback(...):调用Python逻辑,分析原始字节码,抓取静态图,编译优化图,转为字节码。extra=create_cache_entry(extra,result):构造真正的extra类型extra_info的内容为CacheEntry,其中code字段为修改后的字节码。set_extra(frame->f_code,extra):将修改后的字节码保存到frame->f_code中,后面使用时可以直接取回。eval_frame_callback_set(callback):将回调保存到tssPyThread_tss_set返回eval_custom_code(...)PyFrame_New:使用custom_code创建自定义框架result=eval_frame_default(tstate,shadow,throw_flag):调用Python默认框架eval以执行自定义frame2xTODOtorch.f字节码,生成新字节码的过程,设置co_extra。3参考资料3.1cpythonPythonDynamo幕后花絮PyTorch2.0:eager模式的救世主,加速背后的真相TorchDynamo初探:PythonByteCode3.3的动态修改torch.fx官方文档PyTorch新技能解锁:torch.fx阅读PyTorchFX论文用木神的方法深度学习框架量化感知训练的思考和OneFlow的一个解决方案