Skip to content

SOT Python3.12 支持任务汇总 #61173

@gouzil

Description

@gouzil

背景

SOT 是一个与 Python 版本强相关的模块,基本上每个 Python 版本都需要专门适配一次,而每次适配都是一次自底向上从零开始的过程。而跟随这个过程可以帮助新人更快地理解 SOT 整个架构~

在过去,我们最开始是基于 Python 3.8 开发的,之后适配了 Python 3.9 并利用流水线进行了监控(PaddlePaddle/PaddleSOT#105),不久又适配了 Python 3.10(PaddlePaddle/PaddleSOT#112),由于 Python 3.11 内部发生了大量的改动,因此成立了专项对 Python 3.11 进行支持(PaddlePaddle/PaddleSOT#360),如今我们要对 3.12 进行适配了~

适配新版本的最好切入点是了解新版本的改动,比如 Python 3.11,它对整个字节码体系做了大幅的调整,但是调整了什么呢?我们可以在 Release Notes 里找到,但是为什么改动呢?其实我们能从 faster-cpython project 了解到 Python 近几年的加速计划,基本上可以说近几个版本的改动都是为了加速。但是这样改动的目的又是什么,具体实现是什么?这些我们就需要从源码入手来寻找答案了。在 Python 3.11 适配期间,我(@SigureMo)整理了 Python 3.11 核心加速原理——指令特化 并进行了分享,这是 Python 3.11 最大的目标,也是最核心改动的原因,了解这些之后,整个版本适配就没什么悬念了(虽然 3.11 坑确实很多就是了)。

从 Python 3.9-3.11 的适配经验而言,目前看 Python 3.11 > 3.12 > 3.10 > 3.9,这其实也能从 Python 3.12 Release Notesfaster-cpython project 3.13 plan 以及源码找到一些线索,Python 3.12 完成的最大的一件事是使用 DSL 完成了 ceval 的重写,以便实现 Tier 2 优化器,也就是重构,并没有实现 Tier 2 optimizer。Python 3.11 最大的难点就是 Tier 1 实现后整体结构的变动,而 Tier 2 预计会在 3.13 发布,因此 3.12 的适配难度应该低于 3.11。(但也可预见未来 Python 3.13 适配应该难于 3.11)

另一方面,了解 SOT 架构也是对新版本适配有帮助的,PEP 523 是 SOT JIT 编译的基础,我们该模块源码放在 paddle/fluid/pybind/eval_frame.c,每次适配新版本的开始都是这个最底层的模块。

更上一层地,是模拟执行核心模块 python/paddle/jit/sot/opcode_translator/executor/opcode_executor.py 和字节码生成模块 python/paddle/jit/sot/opcode_translator/executor/pycode_generator.py。在模拟执行模块中,我们需要对每条字节码进行模拟执行,并修改模拟执行器的状态,在字节码生成模块中,我们需要根据模拟执行的结果来生成新的字节码,这些都是和版本强相关的模块(主要是字节码的设计)。

此外大多是版本无关的代码,一般不需要进行适配。

Eval Frame 适配

字节码适配

字节码适配任务即对新版本新增、修改的字节码进行适配,根据 Python 3.12 字节码变更Python 各版本字节码差异表格,变动和新增字节码如下:

行为变动

序号 字节码名称 认领人 PR
✅1 LOAD_ATTR @gouzil #61305

新增

序号 字节码名称 认领人 PR
✅1 BINARY_SLICE @diadestiny #62028
✅2 STORE_SLICE @diadestiny #62028
✅3 CALL_INTRINSIC_1 @gouzil #61995
4 CALL_INTRINSIC_2 @gouzil
5 CLEANUP_THROW
6 END_SEND
7 LOAD_FAST_AND_CLEAR
✅8 LOAD_FAST_CHECK @gouzil #62218
9 LOAD_FROM_DICT_OR_DEREF
10 LOAD_FROM_DICT_OR_GLOBALS
11 LOAD_LOCALS
✅12 LOAD_SUPER_ATTR @SigureMo #61858
✅13 RETURN_CONST @diadestiny #61964#62073
14 SETUP_CLEANUP
15 JUMPPseudo-instructions
16 JUMP_NO_INTERRUPTPseudo-instructions
✅17 END_FOR @diadestiny #62008

Note

并不是每个新增 / 变动的字节码都需要适配,这里只是列出全部,有些字节码是一些复杂特性才会出现的(比如异常、异步、match 语法)此种情况不需要适配,Python 3.12 为了实现 PEP 695 也有一些新的字节码,这些字节码我们也是现阶段不需要支持的,对 PEP 695 实现感兴趣可以参考 Jelle 的博客

字节码的适配,即字节码模拟执行逻辑的适配,也就是修改 OpcodeExecutor,字节码的模拟执行逻辑可参考以下内容:

建议每个实现都看看源码,文档中有很多细节是不会暴露给用户的,但我们模拟执行是需要的

其它模块适配

TODO...

单测汇总见: #61174

Metadata

Metadata

Labels

PFCCPaddle Framework Contributor Club,https://github.com/PaddlePaddle/community/tree/master/pfccstatus/close已关闭

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions