Page 114 - 《软件学报》2026年第2期
P. 114

丁嵘 等: 基于领域知识图谱的框架间          AI 源码自动迁移                                            593


                 性地改写即可得到一棵目标框架下的抽象语法树. 已知模型代码迁移的主体是神经网络模型组网代码, 由代码                                    1
                 PyTorch  版本的简单模型代码、代码        2 PaddlePaddle 版本的简单模型代码以及代码        3 MindSpore 版本的简单模型
                 代码可知, 这几种深度学习框架组网模型代码的不同之处主要在于导入模块、类名称、继承类名称、方法名称、
                 算子名称及其参数等.
                    需要注意的是, 并非代码中所有不同之处都需要进行迁移, 比如赋值语句中等号左边的变量名称则不需要进
                 行修改, 而模型代码需要迁移的主体部分即为上述的框架间差异部分, 这些差异信息及其映射关系已经存储在第
                 4.1  节形成的领域知识图谱中. 因此, 抽象语法树改写模块的主要思想就是改写抽象语法树中不同框架间存在差异
                 的节点来完成迁移. 例如, PyTorch     框架下的    torch.nn.Conv2d  算子与  MindSpore 框架下的  mindspore.nn.Conv2d  算
                 子分别是各自框架下的二维卷积算子, 两者在语法和语义上相对应, 通过改写抽象语法树中对应的算子及其参数
                 节点, 就可以达到迁移的目的, 从而将          PyTorch  框架下的卷积算子转换为       MindSpore 框架下的卷积算子.
                    然而, 大多数模型代码中的算子通常无法独立地表达自身的算子信息, 这通常由以下原因导致: 一是开发人员
                 通常会通过引用相关模块来将算子进行简写, 如引入                 torch.nn  模块将  torch.nn.Conv2d  算子简写为  Conv2d; 二是开
                 发人员通常会将算子赋值给变量, 并在后续代码中直接使用该变量来表示对应的算子, 如将                              Conv2d  算子赋值给
                 变量  self.conv1  并在后续直接调用   self.conv1  等. 上述情况都会导致迁移程序在遍历        AST  时无法根据树中的算子
                 节点直接到领域知识图谱中获取到对应的知识. 因此, 抽象语法树改写模块中的代码依赖信息生成器会在改写
                 AST  之前做一些预处理工作. 具体来说, 代码依赖信息生成器会根据模型代码的引用模块信息构建通用依赖信息
                 UDepInfo (universal dependency information), 包括存储导入模块第  1  级模块名称的  from、存储导入模块第   1  级或
                 以下级别模块名称的        import 以及存储开发人员对导入模块的重命名名称的               as, 如表  4  所示. 例如, 模型代码的引
                 用信息为    from torch.nn import Conv2d as conv2, 则通用依赖信息中的  from  为  torch.nn, import 为  Conv2d, as 为
                 conv2. 得到上述通用依赖信息后, AST       中的算子节点就可以根据该信息将算子名称                 conv2  扩展为完整的算子名
                 称  torch.nn.Conv2d, 从而在领域知识图谱中得到目标框架中对应算子的相关信息.

                                                   表 4 通用依赖信息说明

                                     UDepInfo单元                            说明
                                        from                          导入模块第1级名称
                                        import                       第1级或以下级别名称
                                         as                           导入模块重命名名称

                    在得到完整算子名称之后, 抽象语法树改写模块就可以逐级进行                      AST  的改写工作了, 抽象语法树改写模块的
                 框架如图   5  所示.

                                                      抽象语法树改写模块

                                                                  领域知识图谱

                                                                    特   算
                               AST                目标框架              定   子
                                                                    算   映             new AST
                                         代码依赖
                             ଢѓॿࡏ       信息生成器     AST+通用依赖信息        子   射
                                                                    信   关
                                                                    息   系
                                                  特定算子信息
                                                                抽象语法树改写器
                                         辅助映射
                                         转换规则     辅助映射信息
                                                               遍历 AST   改写 AST


                                               图 5 抽象语法树改写模块的框架
   109   110   111   112   113   114   115   116   117   118   119