LLMSniffer:通过GraphCodeBERT和监督对比学习检测大模型生成代码

arXiv cs.CL 论文

摘要

LLMSniffer是一个检测框架,通过监督对比学习微调GraphCodeBERT来区分AI生成的代码和人工编写的代码,在GPTSniffer和Whodunit基准测试上分别达到78%和94.65%的准确率。该方法通过结合代码结构感知嵌入、对比学习和注释移除预处理,解决了学术诚信和代码质量保证方面的关键挑战。

arXiv:2604.16058v1 公告类型:跨领域 摘要:大型语言模型(LLMs)在软件开发中的广泛应用使得区分AI生成代码和人工编写代码成为一项关键挑战,对学术诚信、代码质量保证和软件安全具有重要影响。我们提出LLMSniffer,这是一个检测框架,使用两阶段监督对比学习流程微调GraphCodeBERT,并结合注释移除预处理和MLP分类器。在两个基准数据集——GPTSniffer和Whodunit上进行评估,LLMSniffer相比之前的基线方法取得了显著改进:在GPTSniffer上准确率从70%提升到78%(F1值从68%提升到78%),在Whodunit上从91%提升到94.65%(F1值从91%提升到94.64%)。t-SNE可视化证实对比微调能够产生分离良好、紧凑的嵌入表示。我们发布了模型检查点、数据集、代码和交互式演示,以促进进一步的研究。
查看原文 导出为 Word 导出为 PDF
查看缓存全文

缓存时间: 2026/04/20 08:30

# 通过 GraphCodeBERT 和监督对比学习检测 LLM 生成的代码

来源: https://arxiv.org/html/2604.16058

Mahir Labib Dihan Abir Muhtasim 孟加拉国工程技术大学计算机科学与工程系 达卡,孟加拉国 \{mahirlabibdihan, auntor505\}@gmail\.com

###### 摘要

大型语言模型(LLM)在软件开发中的快速普及使得区分 AI 生成的代码和人工编写的代码成为一项关键挑战,涉及学术诚信、代码质量保证和软件安全性。我们提出了 LLMSniffer,一个检测框架,使用两阶段监督对比学习管道对 GraphCodeBERT 进行微调,并辅以注释移除预处理和 MLP 分类器。在两个基准数据集上进行评估——GPTSniffer 和 Whodunit——LLMSniffer 相比先前基准实现了显著改进:在 GPTSniffer 上准确率从 70% 提升至 78%(F1: 68%→78%),在 Whodunit 上从 91% 提升至 94.65%(F1: 91%→94.64%)。t-SNE 可视化证实对比微调产生了分离良好的紧凑嵌入。我们发布了模型检查点、数据集、代码和交互式演示,以促进进一步的研究。

## 1 引言

能够生成代码的 LLM 的出现——包括 GitHub Copilot、ChatGPT 和 Code Llama——已经改变了软件的编写方式。开发人员越来越依赖这些模型来完成日常编码任务、修复错误和实现算法。然而,这种转变引入了新的挑战:教育环境中的抄袭检测系统必须考虑 AI 生成的提交,代码审查管道需要来源信息,安全审计可能需要区分模型生成的模式和人工习语。

教育工作者对编程教育中的 LLM 使用日益关注。GPTZero 或 DetectGPT 等现有解决方案主要针对通用文本,但在处理代码内容时往往力不从心,因为编程语言具有独特的结构和句法特性。检测 LLM 生成的代码本质上是一个二分类任务:给定代码片段 x∈C,学习一个函数 f:C→{0,1} 来指示代码是人工编写(0)还是 LLM 生成(1)。

最近的工作关注零样本检测器和基于机器学习的检测器。我们强调后者,建立在 GPTSniffer 框架的基础上。我们提出 LLMSniffer,结合了(1)GraphCodeBERT,它编码代码标记和数据流结构,(2)监督对比学习,它聚类相同类别的表示同时分离不同类别的表示,以及(3)注释剥离预处理步骤来移除潜在的混淆性样式元数据。

我们的主要贡献包括:

- •一个两阶段对比微调策略,用于 GraphCodeBERT,包括注释移除预处理和 MLP 分类头,在两个基准上达到最先进的结果。
- •详细的消融分析,比较线性分类器基准与改进的基于 MLP 的架构。
- •在 Hugging Face 上公开的模型检查点、数据集、交互式 Streamlit 演示和视频演示,确保完全可重复性。

## 2 相关工作

### AI 生成文本检测

自 GPT-2 以来,检测机器生成的文本受到了相当多的关注。早期方法使用了困惑度和似然比等统计信号,而更近期的工作关注微调分类器和水印。这些方法针对自然语言,由于句法和结构差异,不能直接转移到源代码。

### LLM 生成代码检测

Nguyen 等人(2024b)引入了 GPTSniffer,这是首批用于检测 ChatGPT 生成代码的专用基准之一,使用 CodeBERT 编码器进行二元交叉熵损失训练。Nguyen 等人(2024a)提出了 Whodunit,关注 GPT-4 生成的 CodeChef 问题 Python 解决方案,并证明代码特定特征显著改进检测。Idialu 等人(2024)进一步探索了竞争性编程基准上的零样本和基于机器学习的管道。我们的工作直接建立在这些基准之上并超越了两个基线。

### 代码表示学习

CodeBERT、GraphCodeBERT 和 CodeT5 等预训练模型通过编码标记序列以及结构信息(AST、数据流图)来推进代码理解。我们利用 GraphCodeBERT,因为它在代码搜索和克隆检测上表现出优越性。

### 对比学习

监督对比学习将自监督对比目标扩展到标记设置。它已被应用于 NLP 微调和代码克隆检测,但据我们所知,之前尚未应用于 AI 生成代码检测。

## 3 背景

### 3.1 GraphCodeBERT

GraphCodeBERT 是一个基于 Transformer 的模型,在来自 CodeSearchNet 的代码-文档对上进行了预训练。与 CodeBERT 不同,它用数据流图增强了自注意机制,该图捕捉变量级别的语义依赖(例如,变量在何处计算以及在何处使用)。两个额外的预训练目标——边预测和节点对齐——鼓励模型内化这些结构关系。我们使用 [CLS] 标记表示作为固定维度的嵌入 h∈ℝ^768 来进行下游分类。

### 3.2 监督对比学习

给定一批 N 个标记对 {(x_i, y_i)}_{i=1}^N,监督对比损失为:

L_SupCon = ∑_{i=1}^N (-1/|P(i)|) ∑_{p∈P(i)} log(e^{z_i·z_p/τ} / ∑_{a∈A(i)} e^{z_i·z_a/τ})

其中 z_i = ℓ_2-normalize(MLP(h_i)) 是投影表示,P(i) = {p≠i: y_p=y_i} 是相同类别的正样本集,A(i) = {a≠i} 是所有其他示例,τ 是温度超参数。这个目标直接优化嵌入空间中的类间分离和类内紧凑性。

## 4 方法

**图 1:** LLMSniffer 概览。第 1 阶段使用监督对比损失训练编码器和投影头。第 2 阶段冻结编码器并使用二元交叉熵损失训练 MLP 分类器。

### 4.1 预处理:注释移除

LLMSniffer 的一个关键设计决策是在编码前移除代码注释。LLM 生成的代码通常包含冗长、解释性的注释,反映的是 LLM 的写作风格而非算法结构。删除注释确保模型学会根据句法和结构代码属性进行区分,降低利用表面样式线索的风险,并改进泛化性能。

### 4.2 模型架构

LLMSniffer 包含三个组件(图 1):

(1)GraphCodeBERT 编码器。移除注释后,代码片段被标记化并连同其数据流图边一起馈入 GraphCodeBERT。[CLS] 嵌入 h∈ℝ^768 作为代码表示。

(2)投影头。一个两层 MLP,带有 ReLU 激活,将 h 映射到 z∈ℝ^128 用于对比学习。该头在推理时被丢弃,遵循相关文献惯例。

(3)MLP 分类头。一个多层感知机,带有 sigmoid 激活,将 h 映射到二元预测(人工编写或 AI 生成)。我们发现这个 MLP 头优于先前工作中使用的更简单的线性分类器。

### 4.3 训练流程

训练分为两个阶段。

**阶段 1:对比预训练。** 我们使用 L_SupCon(方程 1)微调编码器和投影头,温度 τ=0.07。批次构造时采用平衡类别以最大化每个锚点的正样本对数量。

**阶段 2:分类微调。** 投影头被丢弃,MLP 分类头被附加,整个模型使用二元交叉熵损失进行端到端微调。对比预训练步骤对编码器进行热启动以产生判别性表示,然后再训练分类器,遵循相关文献的方法。

### 4.4 实现细节

我们从 microsoft/graphcodebert-base 检查点(HuggingFace)初始化。两个训练阶段都使用 AdamW 优化器,学习率为 2×10^{-5},在 10% 的训练步骤上进行线性预热。最大序列长度为 512 个标记。批大小分别为 32(对比训练)和 64(分类微调)。投影头使用隐藏维度 512 和输出维度 128。所有实验都在单个 GPU 上进行。

## 5 实验设置

### 5.1 数据集

**GPTSniffer** 是一个代码片段数据集,带有二元标签指示人工或 ChatGPT 编写,跨越多种编程语言和竞争性编程问题类型。我们使用官方划分:600 个人工 + 600 个 ChatGPT 样本用于训练,131 个人工 + 142 个 ChatGPT 样本用于测试。我们使用托管在 https://huggingface.co/datasets/mahirlabibdihan/GPTSniffer 的数据集。至关重要的是,测试集来自与训练集*完全不同的领域*,使这成为一个具有挑战性的跨域评估。

**Whodunit** 是 CodeChef 问题的 Python 解决方案数据集,包含 GPT-4 生成的代码和人工编写的对应物。我们使用:639 个人工 + 639 个 ChatGPT 样本用于训练,159 个人工 + 159 个 ChatGPT 样本用于测试。数据集托管在 https://huggingface.co/datasets/mahirlabibdihan/Whodunit。

**预训练数据。** 两个数据集都用 CodeSearchNet(人工编写的代码)和 CodeNet(人工竞争性编程解决方案)增强用于编码器预热。

### 5.2 基线和消融

我们与两个基线和一个中间消融进行比较:

- •**GPTSniffer**:使用二元交叉熵损失微调的 CodeBERT。
- •**Whodunit**:具有 140 个手工特征的基于特征的 XGBoost 分类器。
- •**LLMSniffer(线性)**:我们的第 1+2 阶段管道,带有线性分类头而非 MLP(无注释移除)。
- •**LLMSniffer(我们的)**:具有注释移除和 MLP 分类头的完整管道。

### 5.3 评估指标

我们在每个基准的测试集上报告准确率、精确率、召回率和 F1 分数。所有指标都在两个类别上进行宏平均。

## 6 结果

### 6.1 GPTSniffer 基准

表 1 比较了 GPTSniffer 测试集上的所有系统。

**表 1:** GPTSniffer 测试集上的结果(宏平均)。指标以比例形式报告。线性分类器变体对基线没有改进,达到相同的总体准确率(0.70);具有注释移除的 MLP 实现了 +8 pp 准确率和 +10 pp F1。

线性分类器变体未能改进 GPTSniffer 基线,达到相同的总体准确率(0.70)。这突出了对比预训练单独是不充分的——分类头架构和注释移除都是重要组成部分。我们的完整模型(MLP + 注释移除)达到 0.78 准确率和 0.78 F1,同时改进了精确率和召回率,与之前存在严重精确率-召回权衡的基线不同(人工类别的高精确率、低召回率)。

### 6.2 Whodunit 基准

表 2 呈现了 Whodunit 基准上的结果。

**表 2:** Whodunit 测试集上的结果。所有指标的一致收益。

在 Whodunit 上,LLMSniffer 在所有指标上实现了一致的改进(+3.6 pp),反映了数据集的平衡结构和我们的方法对 Python 中 GPT-4 生成代码的鲁棒性。

### 6.3 嵌入可视化

图 2 显示了 GPTSniffer 测试集上基线和 LLMSniffer 的 [CLS] 嵌入的 t-SNE 投影。

**图 2:** 测试集 [CLS] 嵌入的 t-SNE(GPTSniffer 基准)。左(GPTSniffer 基线):两个类(人工=蓝色,AI=橙色)高度交错,没有明确的决策边界。右(LLMSniffer):对比微调产生了一个紧凑的、隔离的 AI 生成集群(右),从人工编写的集群线性分离,直接解释了改进的分类性能。

基线模型为两个类别产生了大量重叠的簇。相比之下,LLMSniffer 形成了一个紧凑、隔离良好的 AI 生成代码片段簇,与人工编写的代码有清晰的分离。这个定性结果直接解释了定量改进,并证实监督对比学习是可辨别性的核心驱动因素。

### 6.4 消融研究

相似文章

通过句法可预测性的语言学感知型LLM水印技术

arXiv cs.CL

本文介绍了STELA,一个语言学感知的LLM水印框架,通过POS n-gram的句法可预测性来平衡文本质量和检测鲁棒性。该方法无需访问模型logits即可实现公开可验证的水印检测,在类型学多样化的语言(英语、中文、韩语)上展示了优异性能。