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 抽象语法树改写模块的框架

