前阵子教研室接了内网论文合规校验的需求,要求所有学生提交的终稿,不能有大模型生成的内容占比超过30%的情况。
核心硬约束是所有文档100%不能流出教研室内网,所以我们第一反应是找支持本地部署的商用检测工具,省得从零造轮子。
前后折腾一周,我们把能找到的主流工具全部署试用了一轮,GPTZero、Crossplag、朱雀AI检测助手、Originality.ai、知网轻量AIGC筛查模块,没一个能达标的。
为了摸清楚这些工具的准确率底限,我们先手动攒了1200份标注完全的测试样本集,全部脱敏后用哈希重命名,没有任何可识别的元数据特征。
样本集分三类:400份纯人工手写的硕博论文初稿,完全没有借助任何大模型生成;400份纯大模型生成的同主题段落,覆盖GPT-4o、Claude3 Opus、文心一言4.0三个主流模型;400份半改写内容,即大模型生成后人工调整了30%-70%的语序、替换了专业术语的版本。
所有工具在这个基准集上跑出来的平均准确率只有61.8%,表现最好的也才摸到67.2%,离我们要求的90%合格线差了一大截。
我们总结了这些商用SaaS工具的共性问题,几乎没有一家能避开:
第一类问题是长文本偷工减料,绝大多数工具只会提取文本的前2000字符送入模型计算,后面的内容直接用关键词匹配敷衍。
我们做过极端测试:一篇1万字的论文,前3000字全是人工原创内容,后面7000字100%是大模型生成的,接近9成的商用工具直接给标记95%以上人工原创。
第二类问题是半改写内容几乎全漏判,只要人工把大模型生成的内容调整30%以上的语序,替换掉部分低频连接词,大部分工具的检测逻辑就彻底失效。
第三类问题是人工原创内容误判率极高,尤其是理工科论文里大段引用公开文献的内容,或是社科论文里大量使用领域通用套话的段落,很容易被标记成AI生成。
摸完所有工具的底之后,我们干脆放弃了找商用方案的思路,决定直接基于开源模块改一套符合内网要求的本地校验脚本。
最开始搭第一版特征提取逻辑的时候,我们直接照搬了网上开源的RoBERTa检测方案,跑长文本的时候直接爆了显存。
当时的测试环境是单卡32G的2080Ti,跑一份10万字的博士论文,不到10秒显存直接占满抛出OOM错误。
对应的初始测试代码片段如下:
from transformers import AutoModelForMaskedLM, AutoTokenizer
model = AutoModelForMaskedLM.from_pretrained("roberta-large-chinese")
tokenizer = AutoTokenizer.from_pretrained("roberta-large-chinese")
# 直接传入未切割的10000字符长文本
inputs = tokenizer(long_text, return_tensors="pt", truncation=True, max_length=512)
排查了快两个小时才找到问题根源:RoBERTa原生支持的最大序列长度只有512,我们直接传入超长文本,模型在生成滑动窗口张量的时候产出了大量冗余计算,直接把显存撑爆。
之后我们把文本按语义块做切割,每块固定300字符,相邻块重叠50字符,批量送入模型计算单块困惑度,最后取全文字段的困惑度分布均值。
优化之后单卡16G显存就能顺畅跑满10万字的长文档,整体运行效率比初始版本提升了7倍,完全满足教研室的日均200份文档的检测需求。
传统的AIGC检测方案只靠困惑度这一个核心特征,现在大模型迭代速度太快,GPT-4o这类最新模型生成的内容,困惑度已经和人工内容的区间几乎重合,单靠这个特征根本没法区分。
我们在传统困惑度特征之外,又新增了3种市面商用工具几乎没用到的隐性特征,直接把整体检测准确率拉上来了一大截。
第一个新增特征是token级语义跳变密度:大模型生成内容的时候,连续输出的token语义连贯度极高,相邻token的向量相似度普遍高于0.7。
人工写作的时候经常会卡顿、查资料、思路跳转,生成的内容里会出现大量语义断层点,也就是相邻token的向量相似度低于0.2的位置,这类点的密度是大模型生成内容的6倍以上。
我们单独做过对照测试,只靠这一个特征,对纯AI生成内容的分类准确率就能达到78%,远高于普通的单困惑度特征。
第二个新增特征是标点分布熵:人工写作的时候不可避免会出现各类小失误,比如多余的句末空格、连续两个逗号、中英文混排时忘记切换全角半角标点。
这类失误会让人工内容的标点分布熵稳定落在0.72-0.85的区间里,而大模型生成内容的标点分布熵普遍高于0.9,几乎不会出现这类无意义的失误。
这个特征几乎没法靠人工改写完全抹掉,哪怕是改写了70%的半改内容,我们依然能通过标点分布特征识别出来,直接把整体漏判率降了12%。
第三个新增特征是跨领域术语无意义搭配占比:我们把近10年知网下载的270万篇核心论文的术语搭配库,全部导入本地做成了匹配索引。
大模型生成内容的时候很容易瞎搭完全不在同一研究语境里的专业术语,人工写作的时候几乎不会出现这类搭配错误,这个特征专门用来抓那种深度改写的高难度样本。
三个新特征加完,我们的特征维度直接拉到了17维,接下来直接用轻量XGBoost分类器做融合,不需要部署大模型就能跑出足够好的效果。
最开始训练分类器的时候我们踩了个大坑,对纯AI生成内容的准确率到了96%,但对人工原创内容的误判率居然有18%,完全没法用。
排查了很久才找到原因:我们的训练集里的人工样本,没有过滤掉大段直接复制粘贴公开文献的段落,这类内容的困惑度本来就极低,被模型当成了AI生成的特征。
我们直接在预处理层加了前置的文献查重逻辑,先把匹配到本地文献库的段落单独标记出来,不送入AIGC特征计算流程,人工内容的误判率直接降到了3.2%。
优化后的分类器核心训练代码片段如下:
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score
# 17维特征矩阵 + 对应标注数组
X_train, X_test, y_train, y_test = train_test_split(feature_matrix, label_array, test_size=0.2, random_state=42)
model = xgb.XGBClassifier(
n_estimators=200,
max_depth=6,
learning_rate=0.1,
scale_pos_weight=1.2 # 给半改写样本增加权重,降低漏判概率
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"整体检测准确率: {accuracy_score(y_test, y_pred):.4f}")
最后我们跑五折交叉验证,整个模型在基准集上的整体准确率达到了92.7%,对半改写30%-50%的样本准确率也到了87%,完全满足内网校验的要求。
落地部署的时候我们还遇到了几个意料之外的问题,挨个调了快一周才全部解决。
第一个问题是理工科论文里的大量LaTeX公式、图片说明、表格内容,直接送入文本提取流程会生成大量无意义的乱码和符号,严重干扰特征计算。
我们专门写了一套正则匹配规则,把所有LaTeX公式块、图片alt文本、表格内容单独抽出来,公式块直接跳过不做AIGC检测,其他内容单独送入特征计算,误判率又降了2个百分点。
第二个问题是中英文混排的社科论文,里面夹杂大量的英文文献引用,原来的中文tokenizer遇到英文就乱切,特征计算完全失真。
我们换成了支持中英双语的预训练tokenizer,同时给英文内容单独开了一套困惑度计算逻辑,专门适配英文生成内容的特征,整体准确率又提升了4个百分点。
第三个问题是短文本样本的特征维度不足,少于200字的内容根本提取不到足够多的有效特征,强行判定的话误判率会超过30%。
我们直接在规则层加了硬约束,所有长度小于200字的文本,直接返回「样本长度不足,无法判定」的提示,从产品层面避免不必要的误判。
现在这套脚本已经在内网跑了快三周,累计处理了1200多份学生提交的论文,筛出来的疑似高占比AI生成内容,人工复核的吻合率达到了93%,完全符合我们最初的需求。
回过头看,其实这类本地化的AIGC内容校验需求,根本没必要去折腾各类商用SaaS工具。
这类工具普遍要兼顾大量公网用户的通用需求,不敢把判定阈值调的太严,怕出现大规模误判挨用户投诉,准确率自然就上不去。
更关键的是,所有商用SaaS类的检测工具都要求用户把文档上传到公网服务器,稍微涉及点敏感数据的场景,完全不敢用。
我们花了半个月造的轮子,不仅数据全留在本地不会外泄,准确率比所有市面主流商用工具高了30个百分点,后续还能针对不同学科的特征做定向优化,性价比不知道高到哪里去了。
现在教研室的几个师弟已经开始基于这套脚本,加针对数学公式、代码片段的专属检测特征,后续还能覆盖计算机专业的代码作业AI生成校验场景。
等后续优化完整个版本,我们会把脱敏后的开源版传到GitHub上,给有同类内网检测需求的同行省点折腾的时间。

179

被折叠的 条评论
为什么被折叠?



