Page 213 - 《软件学报》2026年第3期
P. 213

1176                                                       软件学报  2026  年第  37  卷第  3  期


                 (1) 在训练阶段, CoDefense 对原始训练集进行代码归一化处理, 并使用处理后的数据训练代码模型; (2) 在推理阶
                 段, CoDefense 对输入的原始代码     (可能是对抗性样本) 进行与训练阶段相同的代码归一化处理, 然后再输入到代
                 码模型中, 从而避免可能存在对抗性扰动的代码直接输入到代码模型. 此外, CoDefense 的创新之处在于, 其作为
                 代码模型的一个前置的数据处理模块与代码模型集成, 共同构成整体预测系统, 而非依赖于基于对抗性样本的对
                 抗性训练. 与最先进的对抗性训练方法相比, CoDefense 能够更有效地防御不同粒度和策略的对抗性攻击, 且对原
                 始模型的性能和嵌入质量影响更小. 由于             CoDefense 不依赖于生成的对抗性样本, 因此相比于对抗性训练方法, 其
                 显著提升了时间效率. 需要强调的是, 本文提出的              CoDefense 方法在所有的编程语言上都是适用的. 由于计算资源
                 限制, 在最流行的     Java 上进行了实现和评估, 工具的实现方式可以在本项目的                  GitHub  主页获取. 后续将会在第
                 3.3  节介绍  CoDefense 的多粒度代码归一化策略, 然后在第        3.4  节介绍  CoDefense 在实际场景中的部署流程.



                                               变量名归一化                          Ai    正确
                                                                                     预测   用户
                           训练数据                                 归一化
                                                                训练数据
                                                死代码消除

                                                                           代码模型
                                              代码结构归一化           归一化                   训练流程
                            对抗性                                 代码输入
                           代码输入               CoDefense                               防御流程

                                                 图 2 CoDefense 方法流程图

                  3.3   多粒度代码归一化
                    根据第   3.1  节和第  3.2  节的介绍, 针对预训练代码模型的对抗性攻击策略可分为                3  类: 变量名替换   [18] 、死代
                 码插入  [20] 和代码结构转换   [16] . 针对这  3  种粒度的对抗性攻击策略, 分别设计了        3  种粒度的代码归一化方式: 变量
                 名归一化、死代码消除和代码结构归一化.
                  3.3.1    变量名归一化
                    先前的研究表明      [29] , 软件开发人员享有高度的自由来定义变量名, 这些变量名的复杂性与多样性几乎不受限
                 制. 这一基本特性给构建于大型代码语料库之上的预训练代码模型带来了巨大挑战, 因为这些模型不得不面对一
                 个极为庞大且高度稀疏的变量名空间. 尤为棘手的是, 这种变量名空间的广阔性加剧了模型在面对测试集中未曾
                 预见变量名时的脆弱性, 尤其是在面对精心设计的对抗性攻击技术时, 这些攻击可以利用模型对低频或未知变量
                 名的敏感反应, 有效降低代码模型的预测性能和鲁棒性. 然而现有的对抗性攻击方法                          [15,18–20] , 大部分都涉及变量名
                 替换的攻击策略. 为了有效防御这种粒度的对抗性攻击, 我们首先考虑变量名归一化的防御策略.
                    每个软件开发人员对于变量名的命名方式展现出显著差异, 这为代码模型的训练增设了重重障碍                                 [30] . 最新研
                 究成果  [31] 进一步揭示, 代码输入中夹杂的噪声变量名会对代码模型的性能造成显著损害. 具体而言, 基于变量名
                 替换的对抗性攻击策略在保持代码语义不变的前提下, 会对代码模型的训练过程施加干扰, 导致模型难以捕捉并
                 学习代码的内在语义特征, 最终引发代码模型鲁棒性和泛化能力的双重退化.
                    为解决上述问题, 促使代码模型聚焦于代码的深层次语义而非表面的变量名特征, 我们引入了变量名归一化
                 技术. 具体而言, CoDefense 将代码中的所有变量名依次替换为              ( Var1,Var2,Var3,... ). 这种归一化方式能够避免
                 基于变量名替换的对抗性攻击干扰模型的预测过程, 同时归一化后的代码保证了语法合法性且保留了原代码的语
                 义信息. 实验结果表明, 这种变量名归一化策略能够               100%  防御不同策略的基于变量名替换的对抗性攻击方法                 (详
                 细实验结果参见第       5  节). 更进一步地, 变量名归一化可以促使代码模型学习更深层次的语义信息, 降低了模型对
                 于变量名形式的过度依赖. 第         5  节及第  6.1  节的实验结果充分表明这种变量名归一化策略在增强代码模型鲁棒性
   208   209   210   211   212   213   214   215   216   217   218