Uncovering Pretraining Code in LLMs: A Syntax-Aware Attribution Approach¶
会议: AAAI 2026
arXiv: 2511.07033
代码: 无
领域: LLM/NLP
关键词: 成员推断攻击, 代码版权, 语法感知, 预训练数据检测, Python
一句话总结¶
提出SynPrune——首个语法感知的代码成员推断攻击方法,通过识别47种Python语法约定并在计算成员推断分数时剪除语法决定的token(仅保留反映作者特征的token),平均AUROC提升15.4%,可有效检测代码LLM的预训练数据归属。
研究背景与动机¶
- 领域现状:代码LLM(Pythia、GPT-Neo、StableLM等)的编码能力来自大规模开源代码训练。成员推断攻击(MIA)是检测特定数据是否在训练集中的核心技术。现有方法包括阴影模型法(GotCha)、同义词替换(Mattern)、低概率token检测(MIN-K%)和词频校准(Zhang),但都将代码视为普通文本。
- 现有痛点:(a) Duan等发现现有MIA在LLM上仅略好于随机猜测;(b) 代码版权纠纷日益增多(如GPL违规诉讼已有先例),但代码MIA研究很少;(c) 现有MIA忽略了代码的关键特性——很多token是语法规则决定的(如函数定义后必须有冒号,缩进是PEP8强制的),这些token无论代码是否在训练集中都有高预测概率,对成员推断贡献的是噪声而非信号。
- 核心矛盾:代码中大量token(括号、冒号、缩进、关键字搭配等)的出现是编程语言语法规则的必然结果,不反映作者身份,但现有MIA将所有token等权重处理,稀释了真正有区分度的信号。
- 本文要解决什么? 如何提取代码中真正反映"作者创作意图"的token,排除语法决定的token,从而提高代码MIA的检测能力。
- 切入角度:观察到代码=作者逻辑+语言语法。语法约定部分是确定性的(如
for x in后必须跟可迭代对象,函数定义用def后跟(),这些不携带成员信息。 - 核心idea一句话:剪掉语法决定的"必然出现"的token,只用作者特征token的log-probability做成员推断,大幅提升区分度。
方法详解¶
整体框架¶
输入是待检测的Python函数代码,输出是成员/非成员的二值判断。三阶段流程:(1) Token预处理——分词+按语法约定做子token拆分;(2) 语法剪枝——识别并标记语法决定的token;(3) 成员概率计算——仅用保留token的log-probability聚合。
关键设计¶
- 47种Python语法约定总结:
- 做什么:系统化定义哪些token是语法"必然出现"的
- 核心思路:两位作者手动审阅Python 3.11官方文档(数据模型§3、表达式§6、语句§7-8),定义为⟨condition, consequence⟩元组。分4类:数据模型(List的
[必须配],Dict的{配});表达式(函数调用identifier后必须有),条件表达式if cond后必须有else);简单语句(import module后可能有as);复合语句(for target_list后必须有in,if后必须有:和缩进和换行,函数定义def f(后参数用,和)) -
设计动机:这些token的出现是语法规则的必然结果,与代码是否被模型"记忆"无关——它们制造了大量噪声
-
SynPrune剪枝算法:
- 做什么:在计算MIA分数之前移除语法决定的token
- 核心思路:首先用LLM的tokenizer获得token序列及每个token的预测概率。然后按语法约定拆分复合token(如
print(拆为print和(),对每个子token检查是否匹配任何约定的consequence。匹配过程利用Python AST模块定位语法节点后验证条件token。标记函数 \(\ell(x_i) \in \{0, 1\}\),全部子token都匹配的标记为0(剪除),否则为1(保留) -
设计动机:BPE分词可能把语法token和内容token合并(如
print(),必须先拆分再判断 -
语法感知的成员推断分数(SPP):
- 做什么:基于保留token计算最终成员推断分数
- 核心思路:\(\text{SPP}(x) = \frac{1}{|\mathcal{X}_1|} \sum_{i \in \mathcal{X}_1} -\log p(x_i)\),其中 \(\mathcal{X}_1 = \{x_i | \ell(x_i) = 1\}\) 是保留的token集合。设定阈值 \(\epsilon\),\(\text{SPP}(x) > \epsilon\) 判断为成员
- 设计动机:剪除语法token后,剩余token的log-probability更能反映模型对特定代码内容的记忆程度,信噪比大幅提升
评估基准构建¶
- 成员数据:从Pile数据集(2021年发布,被Pythia/GPT-Neo/StableLM等广泛用于预训练)中随机采样1000个Python函数
- 非成员数据:从GitHub搜索2024年1月后创建的Python仓库,提取1000个函数,通过三重验证(函数名查重、变量名查重、调用链查重)确保原创性
- 这种构建方式比Yang等人从CodeXGLUE随机采样后事后标注更真实
实验关键数据¶
主实验¶
| 方法 | 平均AUROC提升 | 说明 |
|---|---|---|
| SynPrune vs SOTA | +15.4% | 跨4个代码模型平均 |
| SynPrune vs MIN-K% | 显著提升 | MIN-K%选择低概率token,但未区分语法/内容token |
| SynPrune vs 词频校准 | 显著提升 | 词频校准对代码的语法结构不敏感 |
消融实验(语法约定类别贡献)¶
| 语法类别 | 贡献 | 说明 |
|---|---|---|
| 复合语句(Compound Stmts) | 最大 | for/if/def等是Python最高频结构 |
| 数据模型(Data Model) | 中等 | 括号匹配贡献稳定 |
| 表达式(Expression) | 中等 | 函数调用的括号+逗号 |
| 简单语句(Single Stmts) | 最小 | import相对少见 |
关键发现¶
- AUROC +15.4%的提升非常显著——说明现有MIA方法确实被大量语法噪声token干扰
- 对不同函数长度鲁棒——短函数和长函数都有提升
- 复合语句类别贡献最大,因为for/if/while/def等是Python代码中最高频的语法结构
- 在真实成员(Pile训练集)vs 真实非成员(2024年后发布)的基准上验证,比之前的合成基准更可靠
亮点与洞察¶
- 利用编程语言的确定性语法特征过滤噪声token的思路简洁而强大:代码不同于自然语言,有大量形式化的必然出现的token,这些token稀释了MIA信号。SynPrune精准地识别并移除了这种噪声
- 可推广性强:虽然本文聚焦Python,但47种约定的⟨condition, consequence⟩定义方式可系统化应用于任何编程语言
- 基准构建本身是贡献:Pile成员+2024年后非成员的真实基准比之前的合成基准更可靠,可供后续研究使用
局限性 / 可改进方向¶
- 仅验证了Python,对Java/C++等其他语言需要重新总结语法约定
- 47种约定是手动总结的,可能遗漏了一些边缘情况
- 仅在token-level概率上操作,未考虑更高层的代码语义(如控制流图、API使用模式)
- 二值判断的阈值 \(\epsilon\) 选择未详细讨论
相关工作与启发¶
- vs MIN-K%:MIN-K%假设成员数据不太可能包含低概率token,但没区分低概率的原因(语法必然 vs 作者选择),SynPrune精准区分了两者
- vs GotCha:GotCha需要训练阴影模型(计算昂贵且需预训练数据),SynPrune是reference-free的,仅需目标模型的token概率
评分¶
- 新颖性: ⭐⭐⭐⭐ 首个将语法约定融入代码MIA,思路简洁有效
- 实验充分度: ⭐⭐⭐⭐ 多模型验证+消融+长度鲁棒性+真实基准
- 写作质量: ⭐⭐⭐⭐ 动机清晰,方法讲解直观
- 价值: ⭐⭐⭐⭐ 对代码LLM版权检测有直接应用意义,随着代码LLM诉讼增多价值会增大
补充说明¶
- 该工作的方法论和实验设计对相关领域有参考价值
- 后续工作可在更多场景和更大规模上验证方法的泛化性和可扩展性
- 与近期相关工作的结合(如与 RL/MCTS/多模态方法的交叉)有潜在研究价值
- 建议结合实际应用需求评估该方法的部署可行性和计算效率
- 数据集和评估指标的选择可能影响结论的普适性,需在更多 benchmark 上交叉验证
补充说明¶
- 该工作的方法论和实验设计对相关领域有参考价值
- 后续工作可在更多场景和更大规模上验证方法的泛化性和可扩展性
- 与近期相关工作的结合(如与 RL/MCTS/多模态方法的交叉)有潜在研究价值