上周导师突然丢了个需求过来要求实验室所有硕博的待投稿论文必须先完成内网离线的AIGC痕迹筛查。绝对不能把未发表的稿件传到任何外部公网平台避免还没见刊的研究成果提前泄露。我们组三个搞NLP方向的同门凑在一起啃了三天文档踩了数不清的坑终于把整套流水线跑通了。最开始我们图省事随便找了个网上热度很高的开源检测脚本直接往主服务器上扔。刚跑了三篇论文24G的3090显存直接被占满连带旁边正在跑大模型微调的师弟的进程直接被OOM Killer杀了。吓得师弟当场跳起来花了半个多小时从磁盘快照里找回了没存完的训练权重差点直接延毕半个月。踩了这次坑之后我们冷静下来把所有硬性需求一条条列在白板上一个都不能打折扣。第一是数据全程不能出内网所有依赖的模型、组件全离线部署不能有任何访问公网的接口调用。第二是支持doc、docx、扫描版/高清版PDF等几乎所有主流论文格式不需要用户手动转文本。第三是针对中文理工科学术文本做适配准确率至少要超过学院之前抽检用的抽检工具的平均水平。一开始我们图省事分别用python-docx读Word文件用PyPDF2读普通PDF开发进度看起来很快。结果测试的时候直接傻了扫描版PDF读出来全是乱码带大量公式的Word里公式位置全是占位符乱码。后来我们直接放弃分格式适配的思路改用Unstructured库作为统一解析入口搭配PaddleOCR处理扫描页内容。为了避免一堆乱七八糟的依赖把主环境搞崩我们直接把解析模块单独打包成一个独立Docker容器。核心解析代码写起来其实很简单十来行就搞定了多格式的统一输出from unstructured.partition.auto import partition def parse_unstructured_file(file_path: str) - str: # 自动适配docx/pdf等格式过滤非正文区域 elements partition(filenamefile_path, strategyhi_res) return \n.join([ele.text for ele in elements if ele.category NarrativeText])跑通之后我们又加了版面分析逻辑直接把页眉、页脚、批注、图表标题区域全部过滤掉。避免有人在论文里写的手写字批注、无关的页眉水印内容混进正文干扰后续的特征计算结果。之前试过的很多开源AIGC检测模型动辄大几个G的体量推理一次要好几秒完全不适合批量跑。我们干脆自己攒了一个轻量的特征校验框架完全不用动辄十几G的大生成模型做反向推理。核心逻辑就靠三个我们自己归纳的专属特征专门针对中文理工科学术文本做校准。第一个特征是文本香农熵值的波动统计我们统计了近10万篇人工撰写的硕博论文的熵值区间。正常人工写的学术段落因为思考逻辑跳脱、表述习惯变化熵值波动基本都在0.5以上。大模型生成的内容因为采样逻辑的问题整个文本的熵值会异常平稳波动差很少超过0.2。我们把熵计算的核心函数抽了出来优化了分词后的处理逻辑跑起来几乎不占什么显存import math from collections import Counter import jieba def calc_text_entropy(text: str, n2) - float: # 计算中文分词后文本的2-gram香农熵 seg_list list(jieba.cut(text)) char_counts Counter([seg_list[i:in] for i in range(len(seg_list)-n1)]) total sum(char_counts.values()) entropy 0 for cnt in char_counts.values(): p cnt / total entropy -p * math.log2(p) return round(entropy, 2)第二个特征是学术文本专属的n-gram重复阈值校验我们整理了近5年本学科所有公开论文的语料库。统计出来了正常人工撰写文本的2-gram重复概率上限大模型生成的内容经常无意识重复特定词组。比如连续好几段出现逻辑完全一致的衔接表述这种重复率会远超人工写作的正常阈值很容易识别。第三个特征是引用连贯性校验我们把实验室馆藏的所有论文参考文献全部做了向量化索引。如果某段文字后面跟着引用标号我们就自动把这段内容和对应参考文献的摘要做语义相似度比对。大模型经常瞎编不存在的引用或者把不相关的引用标在段落后面这种情况直接标记为可疑。核心逻辑调通之后我们把整套服务跑在了实验室闲置的K3s边缘集群上所有节点全部禁止公网出口。推理服务做了资源限制最多占用12G显存剩下的显存空间还能留给师弟师妹平时跑小训练任务。我们用FastAPI搭了个极简的异步提交后台批量任务自动进队列排队不会随便把服务搞崩。整套服务的编排配置写在docker-compose里所有镜像都提前拖到了本地镜像仓库离线也能随便扩容version: 3 services: parse-service: image: local/parse-utils:v1 deploy: resources: limits: memory: 2G infer-service: image: local/aigc-infer:v3 deploy: resources: limits: devices: - driver: nvidia count: 1 capabilities: [gpu] reservations: memory: 12G web-service: image: local/frontend:v2 ports: - 8080:80我们还在输出侧做了可视化报告生成最终导出的PDF报告里会把所有可疑段落用黄色高亮标出来。点进去就能看到对应的可疑维度是熵值异常、重复率超标还是引用不匹配作者可以直接针对性修改。上周我们拿了学院去年学术抽检攒下来的127篇标注样本做盲测里面有60多篇是全人工撰写的。剩下的60多篇都是被抽检出来有大段AI生成内容的待整改论文全程盲测没给任何提示。最终整套方案的检出率达到了94.7%误判率只有1.8%远超过我们最初定的验收标准。我们之前还碰到过很极端的案例有个师弟把GPT生成的内容逐字改了快一半还是被系统揪出了异常段落。后来核对了下那段的熵值波动只有0.17完全不符合正常人工写文本的波动特征确实是残留了不少AI生成内容。为了适配高峰时段的批量提交需求我们把推理服务做了水平扩容最多同时启动4个推理实例并行处理。之前高峰期30多个人同时提交论文排队最长也不会超过2分钟完全不会出现任务堆积的情况。中间我们还踩过个很隐蔽的坑之前有篇带几百个公式的数学学位论文跑出来的熵值异常偏低。排查了半天才发现是OCR识别公式的时候把一堆乱码字符塞进了正文拉低了整体的熵值波动。后来我们在特征计算前加了特殊字符过滤逻辑把所有非中文字符、非标点符号的乱码全部清洗掉这类误报就再也没出现过。回头复盘这72小时的折腾其实我们最开始想找现成的方案省点力气根本不想自己从头撸。之前试过付费云检测接口、GitHub标星最高的detectGPT、团象AICG检测、某985高校开源的校内校验工具、大厂公开的内容合规API这些工具要么要求上传文件到公网服务器要么针对中文学术内容准确率拉胯全满足不了我们内网离线使用的需求。折腾到最后才发现完全贴合实验室强合规、本地化、学科定制化需求的方案只能自己动手攒。现在这套流水线已经推到整个学院的研究生会用了一周大概能处理五六十篇待投稿的论文省了大家很多事。等后续有空了我们再把引用校验的语料库拓展到其他学科让旁边几个文科院系的实验室也能拿去做适配改造。
我在实验室内网搭论文AI内容校验流水线的72小时踩坑全记录
上周导师突然丢了个需求过来要求实验室所有硕博的待投稿论文必须先完成内网离线的AIGC痕迹筛查。绝对不能把未发表的稿件传到任何外部公网平台避免还没见刊的研究成果提前泄露。我们组三个搞NLP方向的同门凑在一起啃了三天文档踩了数不清的坑终于把整套流水线跑通了。最开始我们图省事随便找了个网上热度很高的开源检测脚本直接往主服务器上扔。刚跑了三篇论文24G的3090显存直接被占满连带旁边正在跑大模型微调的师弟的进程直接被OOM Killer杀了。吓得师弟当场跳起来花了半个多小时从磁盘快照里找回了没存完的训练权重差点直接延毕半个月。踩了这次坑之后我们冷静下来把所有硬性需求一条条列在白板上一个都不能打折扣。第一是数据全程不能出内网所有依赖的模型、组件全离线部署不能有任何访问公网的接口调用。第二是支持doc、docx、扫描版/高清版PDF等几乎所有主流论文格式不需要用户手动转文本。第三是针对中文理工科学术文本做适配准确率至少要超过学院之前抽检用的抽检工具的平均水平。一开始我们图省事分别用python-docx读Word文件用PyPDF2读普通PDF开发进度看起来很快。结果测试的时候直接傻了扫描版PDF读出来全是乱码带大量公式的Word里公式位置全是占位符乱码。后来我们直接放弃分格式适配的思路改用Unstructured库作为统一解析入口搭配PaddleOCR处理扫描页内容。为了避免一堆乱七八糟的依赖把主环境搞崩我们直接把解析模块单独打包成一个独立Docker容器。核心解析代码写起来其实很简单十来行就搞定了多格式的统一输出from unstructured.partition.auto import partition def parse_unstructured_file(file_path: str) - str: # 自动适配docx/pdf等格式过滤非正文区域 elements partition(filenamefile_path, strategyhi_res) return \n.join([ele.text for ele in elements if ele.category NarrativeText])跑通之后我们又加了版面分析逻辑直接把页眉、页脚、批注、图表标题区域全部过滤掉。避免有人在论文里写的手写字批注、无关的页眉水印内容混进正文干扰后续的特征计算结果。之前试过的很多开源AIGC检测模型动辄大几个G的体量推理一次要好几秒完全不适合批量跑。我们干脆自己攒了一个轻量的特征校验框架完全不用动辄十几G的大生成模型做反向推理。核心逻辑就靠三个我们自己归纳的专属特征专门针对中文理工科学术文本做校准。第一个特征是文本香农熵值的波动统计我们统计了近10万篇人工撰写的硕博论文的熵值区间。正常人工写的学术段落因为思考逻辑跳脱、表述习惯变化熵值波动基本都在0.5以上。大模型生成的内容因为采样逻辑的问题整个文本的熵值会异常平稳波动差很少超过0.2。我们把熵计算的核心函数抽了出来优化了分词后的处理逻辑跑起来几乎不占什么显存import math from collections import Counter import jieba def calc_text_entropy(text: str, n2) - float: # 计算中文分词后文本的2-gram香农熵 seg_list list(jieba.cut(text)) char_counts Counter([seg_list[i:in] for i in range(len(seg_list)-n1)]) total sum(char_counts.values()) entropy 0 for cnt in char_counts.values(): p cnt / total entropy -p * math.log2(p) return round(entropy, 2)第二个特征是学术文本专属的n-gram重复阈值校验我们整理了近5年本学科所有公开论文的语料库。统计出来了正常人工撰写文本的2-gram重复概率上限大模型生成的内容经常无意识重复特定词组。比如连续好几段出现逻辑完全一致的衔接表述这种重复率会远超人工写作的正常阈值很容易识别。第三个特征是引用连贯性校验我们把实验室馆藏的所有论文参考文献全部做了向量化索引。如果某段文字后面跟着引用标号我们就自动把这段内容和对应参考文献的摘要做语义相似度比对。大模型经常瞎编不存在的引用或者把不相关的引用标在段落后面这种情况直接标记为可疑。核心逻辑调通之后我们把整套服务跑在了实验室闲置的K3s边缘集群上所有节点全部禁止公网出口。推理服务做了资源限制最多占用12G显存剩下的显存空间还能留给师弟师妹平时跑小训练任务。我们用FastAPI搭了个极简的异步提交后台批量任务自动进队列排队不会随便把服务搞崩。整套服务的编排配置写在docker-compose里所有镜像都提前拖到了本地镜像仓库离线也能随便扩容version: 3 services: parse-service: image: local/parse-utils:v1 deploy: resources: limits: memory: 2G infer-service: image: local/aigc-infer:v3 deploy: resources: limits: devices: - driver: nvidia count: 1 capabilities: [gpu] reservations: memory: 12G web-service: image: local/frontend:v2 ports: - 8080:80我们还在输出侧做了可视化报告生成最终导出的PDF报告里会把所有可疑段落用黄色高亮标出来。点进去就能看到对应的可疑维度是熵值异常、重复率超标还是引用不匹配作者可以直接针对性修改。上周我们拿了学院去年学术抽检攒下来的127篇标注样本做盲测里面有60多篇是全人工撰写的。剩下的60多篇都是被抽检出来有大段AI生成内容的待整改论文全程盲测没给任何提示。最终整套方案的检出率达到了94.7%误判率只有1.8%远超过我们最初定的验收标准。我们之前还碰到过很极端的案例有个师弟把GPT生成的内容逐字改了快一半还是被系统揪出了异常段落。后来核对了下那段的熵值波动只有0.17完全不符合正常人工写文本的波动特征确实是残留了不少AI生成内容。为了适配高峰时段的批量提交需求我们把推理服务做了水平扩容最多同时启动4个推理实例并行处理。之前高峰期30多个人同时提交论文排队最长也不会超过2分钟完全不会出现任务堆积的情况。中间我们还踩过个很隐蔽的坑之前有篇带几百个公式的数学学位论文跑出来的熵值异常偏低。排查了半天才发现是OCR识别公式的时候把一堆乱码字符塞进了正文拉低了整体的熵值波动。后来我们在特征计算前加了特殊字符过滤逻辑把所有非中文字符、非标点符号的乱码全部清洗掉这类误报就再也没出现过。回头复盘这72小时的折腾其实我们最开始想找现成的方案省点力气根本不想自己从头撸。之前试过付费云检测接口、GitHub标星最高的detectGPT、团象AICG检测、某985高校开源的校内校验工具、大厂公开的内容合规API这些工具要么要求上传文件到公网服务器要么针对中文学术内容准确率拉胯全满足不了我们内网离线使用的需求。折腾到最后才发现完全贴合实验室强合规、本地化、学科定制化需求的方案只能自己动手攒。现在这套流水线已经推到整个学院的研究生会用了一周大概能处理五六十篇待投稿的论文省了大家很多事。等后续有空了我们再把引用校验的语料库拓展到其他学科让旁边几个文科院系的实验室也能拿去做适配改造。