← 最新论文
🤖 machine learning

Invariant Pretraining for Robust Code Representations

本文介绍了不变性预训练(Invariant Pretraining, InvPT),这是一种仅针对代码的持续预训练方法,它将掩码语言模型与在语义转换代码上的多正样本监督对比学习相结合,在保持标准准确度的同时,显著提高了基于编码器的模型针对语法变化的鲁棒性。

原作者: Yifeng He, Yundi Xu, Christopher Castro Gaw Gonzalo, Zili Wang, Hao Chen

发布于 2026-08-18
📖 1 分钟阅读☕ 轻松阅读

原作者: Yifeng He, Yundi Xu, Christopher Castro Gaw Gonzalo, Zili Wang, Hao Chen

原始论文根据 CC0 1.0(http://creativecommons.org/publicdomain/zero/1.0/)发布到公有领域。 这是对下方论文的AI生成解释。它不是由作者撰写或认可的。如需技术准确性,请参阅原始论文。 阅读完整免责声明

在现代计算的广袤版图中,一场无声的革命发生在驱动我们数字世界的软件之中。多年来,理解计算机代码最强大的工具一直是大型生成式模型——这些系统旨在从头开始编写新的程序,就像小说家创作故事一样。这些巨头令人印象深刻,但它们也显得沉重、运行成本高昂,且对于那些仅仅需要理解一段代码功能的任务来说,往往是大材小用。几十年来,另一种类型的工具一直是这些特定工作的得力助手:编码器(encoder)。可以将编码器想象成一个翻译员,它阅读一段代码并将其转化为紧凑的数学摘要,即捕捉其含义的“指纹”。这些指纹被用于查找重复代码、分类程序用途或检测安全漏洞。它们体积小、速度快且高效。然而,这些工具的工作方式存在一种隐藏的脆弱性。它们被训练去识别程序员使用的特定单词和符号,但当这些相同的单词被重新排列或以不同的风格重写时,即使程序的行为完全相同,它们也往往会失效。

这种脆弱性为软件分析的可靠性带来了显著问题。在现实世界中,程序员编写代码的方式千差万别。一位开发者可能会使用“for”循环来计数,而另一位则可能使用“while”循环来完成完全相同的事情。对人类而言,这些在功能上是等同的;但对于标准的代码编码器来说,它们看起来可能完全不同。研究人员在测试这些模型时发现,仅仅将程序改写为另一种等效的风格,就可能导致模型的理解能力崩溃。模型会无法识别两段代码是在执行相同的任务,从而导致安全检查或重复检测中的错误。该领域面临的问题不仅是如何构建更好的模型,而是如何使它们足够鲁棒,从而能够看透表层的变化,理解底层的逻辑,无论代码是如何编写的。

一个研究小组致力于精确测量这些模型的脆弱程度,并寻找一种简单的修复方法。他们并没有试图发明一种新型的人工智能或复杂的全新目标,而是专注于一种他们称为“不变性预训练”(invariant pretraining)的方法。其核心思想非常直接:教会模型不同的代码可以表达相同的意思。他们采用了现有的、广泛使用的代码模型,并在大规模编程语言数据集中对其进行持续训练。在训练过程中,他们应用了一系列特定的、基于规则的转换。这些转换就像一套严格的编辑规则,会将“while”循环转换为“for”循环,将变量名从“count”改为“x”,或者翻转“if”语句的逻辑,同时确保程序的功能依然保持不变。随后,模型会被同时展示原始代码和这些改写后的版本,迫使模型学习它们并不是不同的示例,而是同一个示例戴上了不同的面具。

研究人员在包含数百万行 Java、Python 和 C++ 代码的多个大型数据集上,对四种不同的代码模型进行了测试。他们针对两个关键任务评估了模型:查找重复代码和对程序进行分类。结果令人瞩目。在采用这种新训练方法之前,模型在面对改写后的代码时表现不佳;它们识别等效程序的能力显著下降。经过不变性预训练后,模型变得更加具有韧性。在查找重复代码的任务中,模型识别改写版本的能力提升了中位数 8 个百分点,部分模型甚至提升了高达 11 个百分点。对于代码分类任务,平均提升幅度较小但依然显著,有些案例的增幅接近 20 个百分点。至关重要的是,这种鲁棒性的提升并未以牺牲原有的性能为代价。模型在执行标准任务时依然表现出色,这证明了学习忽略表层变化并不会让它们忘记如何阅读代码。

最令人惊讶的发现之一是,这种训练在不同的编程语言之间同样有效。研究人员仅使用 Java 和 Python 的代码进行训练,但在将这些模型应用于 C++ 代码(一种在本次特定训练阶段从未见过的语言)进行测试时,模型展现出了更高的鲁棒性。这表明模型学习到了一种通用的结构不变性概念,即理解程序的逻辑与其编写时使用的特定语法是相互分离的。研究还表明,成功的关键不仅在于向模型展示不同版本的代码,还在于如何进行比较。研究人员使用了一种技术,将同一个源函数的各种变体都视为“正向匹配”,而不是将它们作为不同的示例推开。这使得模型能够学习到,变量重命名或循环交换只是微小的细节,而非根本性的意义改变。

研究人员谨慎地界定了他们发现的局限性。他们指出,该方法使模型对于他们在训练中使用的特定类别的转换(如更改循环或重命名变量)具有鲁棒性。但这并不保证模型能免疫所有可能的代码改写方式,尤其是那些更复杂或涉及完全不同编程语言的改写。此外,他们发现,在训练数据中加入自然语言描述(如注释或文档)并不能显著提供帮助。模型仅通过代码本身就学习到了必要的鲁棒性,这表明编程语言本身的结构才是理解其含义的关键。这项工作为提高分析软件工具的可靠性提供了一条清晰且实用的路径,确保它们能够洞察程序逻辑的真相,无论程序员选择如何编写代码。

您所在领域的论文太多了?

获取与您研究关键词匹配的最新论文每日摘要——附技术摘要,使用您的语言。

试用 Digest →