基于困惑度与爆发度的LLM辅助写作检测技术解析
2026/8/30 6:59:10 网站建设 项目流程

这次我们来看一个和 LLM 应用直接相关、又容易被忽视的研究方向:如何检测学术论文中的 LLM 辅助写作。研究标题是Most biomedical publications show signs of LLM-assisted writing,直译过来就是“大多数生物医学出版物显示出 LLM 辅助写作的迹象”。

这个题目听起来像新闻,但它本质上是一套技术方法研究:用文本统计特征、困惑度分析和分类模型,判断一篇论文是纯人工写作,还是经过大语言模型辅助修改。放在科研写作场景里,这件事比想象中更重要——期刊编辑需要确认稿件是否合规,导师需要判断学生论文有没有过度依赖 AI,科研团队也需要知道自己的写作流程处在什么位置。

本文会拆解这类研究的核心思路,并给出一套可复现的检测流程:从数据处理、特征提取、模型训练到批量检测和 API 服务化。重点在于,检测 LLM 辅助写作不是靠“猜”,而是可以通过困惑度、爆发度、句法复杂度等可量化指标落地。虽然论文本身没有公开完整代码,但检测技术路线是通用的,完全可以用开源工具本地实现。

适合读者:关注学术诚信、期刊投稿规范的科研人员;做文本分类、AIGC 检测的技术同学;以及所有使用 ChatGPT、Claude、Kimi 等工具辅助英文写作、又担心“机器味”太重的论文作者。

1. 核心要点速览

先给一张总览表,把这次要讨论的技术内容放在一起看。

项目项说明
研究对象生物医学出版物中的 LLM 辅助写作迹象检测
核心方法文本统计特征、困惑度(Perplexity)、爆发度(Burstiness)、分类模型
检测目标判断文本是否经过大语言模型辅助写作或修改
技术门槛中等,Python + HuggingFace 模型 + 文本处理库即可起步
显存需求如果用向量化模型做分类,6G 显存可跑;纯统计特征 CPU 也能跑
支持 CPU是,统计特征方法完全依赖 CPU,不需要 GPU
主要功能单文本检测、批量文本检测、特征可视化、检测结果导出
接口服务可封装为 FastAPI 服务,提供 HTTP 调用
批量任务支持,遍历目录或读取 CSV 批量处理
适合场景期刊预审、论文自查、审稿辅助、文本合规检测

需要强调一点:论文标题里的“大多数”是一个基于具体样本集的结论,检测方法并不会有“绝对正确”的输出。实际使用中,检测结果应该看成“文本呈现 LLM 辅助写作特征的概率”,而不是“作者是否作弊”的最终裁决。

2. 研究背景:为什么生物医学文献会成为检测重心

生物医学领域是 LLM 辅助写作渗透最深的学术方向之一。原因不复杂:这个领域论文产量大、写作模式相对固定、方法学和结果描述高度模板化,而大语言模型最擅长的就是生成“结构正确、用词规范、逻辑通顺”的段落。两者叠加,导致生物医学文献成为检测 LLM 痕迹的天然试验场。

从检测角度,生物医学文献有几个明显的文本特征:

  • 术语密度高,但句式结构相对单一。
  • 被动语态使用频繁,例如 “was performed”“were analyzed”“was assessed”。
  • 方法部分高度模板化,模型很容易生成相似表述。
  • 结果部分往往以数据为骨架,模型改写后不易暴露逻辑漏洞。

这些特征决定了检测算法不需要过于复杂就能捕捉到异常。例如,一篇论文如果所有句子的困惑度都异常低、句长分布非常均匀、连接词使用模式高度一致,那么即便没有明确的“AI 痕迹”,统计特征也已经给出了信号。

更关键的是,生物医学论文有大量公开语料(PubMed、PMC、bioRxiv 等),训练检测模型的数据来源充足。不像小说、散文这种风格多变的文本,医学论文的文体约束让模型更容易学到“人工写作”和“LLM 辅助写作”之间的边界。

不过要区分一个概念:研究说的“LLM-assisted writing”并不等于“全文 AI 生成”。它涵盖的范围很广,包括:

  • 用 ChatGPT 润色语言、改进句式。
  • 用 DeepL Write、Grammarly 等工具改写段落。
  • 用 LLM 生成引言草稿,再人工修改。
  • 用翻译工具先写中文再译成英文。

这些场景都会在文本统计特征上留下痕迹,但严重程度完全不同。因此,检测工具不能只回答“是或否”,最好能输出一个分数,让使用者自行判断。

3. 检测方法论拆解:怎么识别 LLM 辅助写作的迹象

从技术实现角度,检测 LLM 辅助写作的方法可以分为四类。

3.1 统计特征分析

统计特征是最容易上手、也最稳定的检测手段。核心思路是:大模型生成文本和人类写作在统计规律上存在系统性差异。

常用特征包括:

  • 困惑度(Perplexity):模型对一句话的“意外程度”打分。人类写作通常有较高的困惑度,因为人类会使用更多非常规表达;而 LLM 倾向于生成高概率词序列,困惑度偏低。
  • 爆发度(Burstiness):衡量文本中“突然出现的复杂句或罕见词”的频率分布。人类写作的爆发度高,句长和词频波动大;LLM 写作的爆发度低,语句节奏均匀。
  • 句长分布:人类写作的句子长度方差大,LLM 生成的句子长度相对集中。
  • 连接词频率:人类写作会用更多口语化的转折结构,LLM 则倾向于使用标准连接词。
  • 词汇多样性:如 TTR(Type-Token Ratio),衡量文本中不同的词占全部词的比例。

这类方法不需要训练模型,只要一个像样的语言模型来计算困惑度即可。缺点是:对短文本不敏感,也不能区分“润色”和“完全生成”。

3.2 分类模型检测

在统计特征基础上,可以训练一个二分类器:输入是句子或段落的特征向量,输出是“人工写作”或“LLM 辅助写作”的概率。

实现方式有很多:

  • 基于 TF-IDF + 逻辑回归的传统机器学习方案。
  • 基于 RoBERTa、DeBERTa 等预训练模型的文本分类方案。
  • 基于嵌入向量(如 text-embedding-3-small、BGE 系列)加上全连接层的方案。

预训练模型方案效果通常更好,但需要一定显存。如果用 6G 显存的显卡跑一个 RoBERTa-base 模型,批处理大小调到 8~16,基本可以工作;如果没有 GPU,用 CPU 推理也可以,但批量任务会很慢。

3.3 水印检测与采样模式分析

另一条技术路线是分析生成文本的“指纹”。LLM 生成文本时,会从概率分布中采样下一个 token。如果模型使用固定的采样种子,或使用了水印算法,那么生成文本中会出现统计上异常的 token 分布。

水印检测准确率很高,但限制也明显:必须知道生成文本使用的是哪个模型、哪个采样参数,才能有效检测。对于已经发表的论文,作者用的什么模型、什么配置根本无从得知,所以水印路线在学术文献检测中实用性有限。

3.4 混合检测框架

实际项目中,效果最稳的方案是混合检测。先计算困惑度和爆发度,再用分类模型做整体判断,最后把两者结合成一个风险分。这也是当前 AIGC 检测工具的通用思路。

混合框架的流程如下:

输入文本 -> 文本清洗 -> 分句 -> 计算困惑度 -> 提取统计特征 -> 向量化 -> 分类模型推理 -> 输出风险分 -> 报告

这个流程每一步都有对应的开源实现,下面会给出具体代码。

4. 复现检测实验的环境准备与数据准备

要从零跑通一个“LLM 辅助写作检测”实验,不需要特别高的硬件配置。一套面向通用复现的检查清单如下。

4.1 硬件环境

检查项推荐配置说明
CPU4 核以上统计特征计算以 CPU 为主
内存16G处理大规模文献语料时推荐 32G
GPU可选,6G 显存即可预训练模型推理需要;纯统计特征可以不用
磁盘至少 20G 可用空间预训练模型和语料库占用较大

4.2 软件环境

# 创建独立虚拟环境,避免依赖冲突 conda create -n llm-writer-detection python=3.10 -y conda activate llm-writer-detection # 安装核心依赖 pip install transformers torch pandas scikit-learn pip install datasets textdescriptives # textdescriptives 用于文本统计特征 pip install fastapi uvicorn # 后续封装 API 用

4.3 数据准备

数据是这类实验中最重要的部分。如果目标是复现论文结论,需要准备两类数据:

  • 人工写作语料:从 PubMed 或 PMC 下载 2000 年之前的论文摘要,这一时期的文本基本不包含 LLM 辅助写作。
  • LLM 辅助写作语料:可以自己构造,用 GPT-4、Claude、Kimi 等模型对人工摘要进行润色改写,形成配对数据。

没有现成数据时,先跑通流程更重要,可以从公开数据集切入:

- PubMed 摘要数据集 - PMC OA 子集 - HellaSwag、WritingPrompts 等生成文本基准 - 自己用 LLM 生成 500 条医学英文段落

数据目录建议这样组织:

./data ├── human/ # 人工写作样本,txt 或 jsonl ├── llm/ # LLM 辅助写作样本 ├── test/ # 测试样本 └── metadata.csv # 样本元信息

5. 检测流程实现:从文本预处理到判断输出

下面给出一套完整的检测流程代码。这套代码不是论文源码,而是按通用检测思路实现的示范,具体参数需要根据实际数据调整。

5.1 文本预处理与分句

预处理是第一步,目的是去掉参考文献、作者信息、基金声明等干扰内容。

import re import json from typing import List def clean_text(text: str) -> str: """清洗文本:去掉URL、邮箱、参考文献标记和多余空白""" text = re.sub(r'http\S+', '', text) text = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b', '', text) text = re.sub(r'\[\d+(?:[-,]\d+)*\]', '', text) # 参考文献标记 text = re.sub(r'\[\d+\]', '', text) text = re.sub(r'\s+', ' ', text).strip() return text def split_to_sentences(text: str, max_len: int = 200) -> List[str]: """按句号拆分,过滤过短或过长的句子""" sentences = re.split(r'(?<=[.!?])\s+', text) sentences = [s.strip() for s in sentences if 20 <= len(s.split()) <= max_len] return sentences

5.2 计算困惑度特征

困惑度是检测 LLM 辅助写作最直观的特征。这里用 GPT-2 作为基础模型计算困惑度,因为 GPT-2 体积小、推理快,在 CPU 上也能运行。

import torch from transformers import GPT2LMHeadModel, GPT2Tokenizer model_name = "gpt2" tokenizer = GPT2Tokenizer.from_pretrained(model_name) model = GPT2LMHeadModel.from_pretrained(model_name, torch_dtype=torch.float32) if torch.cuda.is_available(): device = "cuda" else: device = "cpu" model.to(device) model.eval() def compute_perplexity(text: str) -> float: """计算整段文本的困惑度""" encodings = tokenizer(text, return_tensors="pt", truncation=True, max_length=512) input_ids = encodings.input_ids.to(device) with torch.no_grad(): outputs = model(input_ids, labels=input_ids) loss = outputs.loss return float(torch.exp(loss).cpu().item())

这一步在纯 CPU 环境下也可以运行,只是长文本会慢一些。建议测试时先截取 100~200 词的摘要片段。

5.3 提取爆发度与句长分布特征

爆发度反映文本节奏的波动程度。实现思路很简单:计算每个句子的困惑度或句长,再求标准差。

import numpy as np def compute_burstiness(sentences: List[str]) -> dict: """计算句长分布和困惑度分布的爆发度""" # 句子长度(词数) sent_lens = [len(s.split()) for s in sentences] # 每句困惑度 sent_ppl = [compute_perplexity(s) for s in sentences] feats = { "mean_sent_len": float(np.mean(sent_lens)), "std_sent_len": float(np.std(sent_lens)), "mean_ppl": float(np.mean(sent_ppl)), "std_ppl": float(np.std(sent_ppl)), } return feats

人类写作的std_sent_len通常更大,LLM 辅助写作更小。这在整段文本的粒度上比较稳定。

5.4 用分类模型做整体判断

特征提取之后,可以训练一个分类模型。这里用 TF-IDF + 逻辑回归作为快速基线,数据量小也能跑。

from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 假设 human_texts 和 llm_texts 是文本列表 texts = human_texts + llm_texts labels = [0] * len(human_texts) + [1] * len(llm_texts) X_train, X_test, y_train, y_test = train_test_split( texts, labels, test_size=0.2, random_state=42, stratify=labels ) vectorizer = TfidfVectorizer(max_features=5000, ngram_range=(1, 2)) X_train_vec = vectorizer.fit_transform(X_train) X_test_vec = vectorizer.transform(X_test) clf = LogisticRegression(max_iter=1000) clf.fit(X_train_vec, y_train) y_pred = clf.predict(X_test_vec) print(classification_report(y_test, y_pred, target_names=["human", "llm-assisted"]))

如果数据量足够大,建议换成 RoBERTa 等预训练模型。这里给出的是一个可运行的最小实验闭环,先验证流程,再逐步升级模型。

5.5 输出检测报告

检测不能只给出 0/1,要给出可解释的特征明细。

def build_report(text: str) -> dict: cleaned = clean_text(text) sentences = split_to_sentences(cleaned) feats = compute_burstiness(sentences) vec = vectorizer.transform([cleaned]) prob = clf.predict_proba(vec)[0][1] # 属于 llm-assisted 的概率 report = { "mean_ppl": round(feats["mean_ppl"], 2), "std_ppl": round(feats["std_ppl"], 2), "mean_sent_len": round(feats["mean_sent_len"], 2), "std_sent_len": round(feats["std_sent_len"], 2), "llm_assist_prob": round(float(prob), 4), } return report

这份报告可以作为期刊预审或者论文自查的参考材料。要注意,分数高只代表“文本特征接近 LLM 写作模式”,不等于作者有学术不端行为,更不等于可以据此拒稿。

6. 批量检测与接口 API 化

如果要把检测能力用于批量任务,例如对整本期刊的投稿做预筛,或者对一批论文摘要做自查,需要把检测流程封装成可批量调用和可通过 HTTP 调用的服务。

6.1 批量检测脚本

批量场景通常有两种输入:一个文本目录,或者一个 CSV 文件。下面给一个 CSV 批量处理示例。

import pandas as pd from tqdm import tqdm df = pd.read_csv("papers.csv") results = [] for idx, row in tqdm(df.iterrows(), total=len(df)): try: report = build_report(row["abstract"]) report["paper_id"] = row["paper_id"] results.append(report) except Exception as e: print(f"Error processing {row['paper_id']}: {e}") results.append({"paper_id": row["paper_id"], "error": str(e)}) result_df = pd.DataFrame(results) result_df.to_csv("detection_results.csv", index=False)

批量任务有一个重要原则:一定要做失败重试和日志记录。文本数据千奇百怪,有的句子太长、有的编码异常、有的包含特殊符号,一个样本出错不能让整个任务中断。

6.2 FastAPI 封装接口

把检测函数封装成 API 服务,这样可以让编辑系统、投稿系统或者自建工具直接调用。

from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class DetectRequest(BaseModel): text: str class DetectResponse(BaseModel): mean_ppl: float std_ppl: float mean_sent_len: float std_sent_len: float llm_assist_prob: float @app.post("/detect", response_model=DetectResponse) def detect_text(req: DetectRequest): return build_report(req.text)

启动服务:

uvicorn api:app --host 127.0.0.1 --port 8000

6.3 curl 调用示例

服务启动后,可以用 curl 快速验证。

curl -X POST http://127.0.0.1:8000/detect \ -H "Content-Type: application/json" \ -d '{"text": "This study aimed to evaluate the effect of metformin on glucose metabolism in diabetic mice. A total of 40 mice were randomly divided into four groups..."}'

返回结果示例:

{ "mean_ppl": 32.45, "std_ppl": 5.21, "mean_sent_len": 18.6, "std_sent_len": 4.1, "llm_assist_prob": 0.87 }

接口做好后,可以嵌套到期刊投稿系统里做预筛,也可以做成一个小型 Web 工具让作者自查。

6.4 Python 调用示例

import requests response = requests.post( "http://127.0.0.1:8000/detect", json={"text": "The results showed that the treatment significantly reduced tumor volume."}, timeout=30, ) print(response.json())

服务化的好处是检测逻辑和业务逻辑解耦。论文数据不出内网环境时,也可以把服务部署在本地服务器,不用调用外部 API。

7. 资源占用与性能观察

在本地跑这个检测流程,需要关注三类资源:内存、CPU/GPU、磁盘。

7.1 内存占用

加载 GPT-2 模型大约占用 600~800MB 内存,加载 RoBERTa-base 大约占用 1.2~1.5GB。如果同时加载 TF-IDF 向量器和逻辑回归模型,总内存开销在 3GB 以内,16G 内存的机器完全够用。

7.2 CPU 与 GPU 的差异

纯统计特征计算(句长、爆发度、TF-IDF)在 CPU 上运行很快,一篇摘要毫秒级完成。瓶颈在困惑度计算:

  • CPU 上 GPT-2 计算一篇 200 词的摘要需要 2~5 秒。
  • GPU 上同样推理可以压缩到 0.5~1 秒。
  • 如果换成更大的模型(比如 Llama-2-7B),CPU 上就要 30 秒以上,建议直接用 GPU。

如果只是跑单篇论文自查,CPU 足够;如果要批量处理几千篇摘要,建议准备一块 6G 显存以上的显卡。

7.3 批量任务性能观察方法

批量任务跑之前,先在小数据集上做压力测试:

time python batch_detect.py --input sample_100.csv

time命令记录总耗时,然后根据耗时估算处理全部数据集需要的时间。同时可以用nvidia-smi观察显存占用:

nvidia-smi --query-gpu=memory.used,utilization.gpu --format=csv -l 1

如果显存不足,优先减小模型输入的最大长度(max_length),或者减小 batch size。如果 CPU 占用过高,可以限制线程数:

torch.set_num_threads(4)

7.4 降低资源占用的建议

  • 纯统计特征检测不需要 GPU,可以先跑统计特征,只有困惑度计算才引入模型。
  • 使用量化模型,例如optimum库把 GPT-2 量化到 int8,显存占用降低一半。
  • 批量任务时复用tokenizermodel,不要在循环里重复加载模型。
  • 对超长文本先截断,一般只取摘要部分检测即可。

8. 常见问题与排查方法

本地运行检测流程时,最常遇到的问题集中在依赖安装、模型下载、中文文本处理和 CUDA 环境。下面是一张排查表。

问题现象可能原因排查方式解决方案
模型下载超时网络不稳定或模型源被限制检查网络,改用镜像源使用HF_ENDPOINT镜像或手动下载模型文件
KeyError: 'gpt2'模型缓存目录权限不足检查~/.cache/huggingface权限重新设置缓存目录,或指定cache_dir
CUDA 不可用驱动版本和 PyTorch 不匹配运行python -c "import torch; print(torch.cuda.is_available())"按 PyTorch 官网安装匹配的 CUDA 版本
显存不足 OOMbatch size 过大或 max_length 过长查看 nvidia-smi 显存占用减小 batch size,降低max_length
中文检测不准确使用的模型以英文为主换用中文语料训练的模型bert-base-chinesechinese-roberta-wwm-ext计算特征
批量任务中途崩掉单条数据包含异常字符查看日志定位出错样本增加 try/except,跳过异常样本并记录
API 请求超时困惑度计算在 CPU 上太慢查看服务日志耗时缩短输入文本长度,或改用 GPU 推理
检测分数一直偏高文本长度太短,特征不稳定检查输入是否只有一两句话建议最少输入 50 个英文单词,否则结果仅供参考
一个样本到另一个样本分数波动大分类模型过拟合训练集检查训练数据分布增加训练样本量,使用交叉验证

遇到问题时的排查顺序建议是:先看日志输出,再看依赖版本,最后才怀疑算法本身。大多数问题不是检测逻辑错了,而是环境不一致。

9. 使用边界与合规提醒

LLM 辅助写作检测工具的使用场景很广,但也需要明确边界。

第一,检测结果不能作为学术不端的直接证据。论文是否违规,要看期刊的政策、作者是否披露了 AI 使用情况、以及具体使用了哪些功能。检测工具只能提供一个“特征接近 LLM 写作”的概率,不能替代人工审查。

第二,使用 LLM 辅助写作本身并不必然违规。越来越多期刊开始要求作者在投稿时披露是否使用了 AI 工具,以及使用了哪些部分。如果作者如实披露,检测工具的意义就变成了“辅助核查”,而不是“定罪”。

第三,涉及版权和隐私问题时必须谨慎。检测系统如果部署在期刊编辑部,处理的是作者未发表的稿件,必须保证数据安全,不能把稿件文本发送给第三方 API。这也是为什么本地部署检测模型比调用在线检测服务更稳妥。

第四,对文本进行改写再检测,或者用“降 AI 率”工具刻意规避检测,属于绕过检测机制的行为。技术研究者应该对这类用途保持警惕,检测工具只用于合规审查、写作自查和编辑辅助。

第五,不要用检测工具评价学生或同事的道德水平。检测分数受文本长度、文体、母语背景影响很大,非英语母语作者写出的英文论文,即使完全没使用 LLM,也可能被误判为“AI 痕迹明显”。这类工具更适合作为编辑审稿的辅助信号,而不是直接对作者做评价。

10. 总结与下一步

检测 LLM 辅助写作这件事,技术上已经有一条清晰可行的路线:困惑度计算、爆发度分析、统计特征提取、分类模型推理、批量任务与 API 封装。这套流程不需要多高的硬件门槛,也不依赖某一个特定模型,核心在于理解“人类写作”和“LLM 辅助写作”在文本统计规律上的差异。

如果你准备复现这套检测流程,建议按这个顺序测试:

  1. 先跑通 GPT-2 困惑度计算,看单篇摘要的输出是否稳定。
  2. 用 50 条人工文本和 50 条 LLM 改写文本做一个小规模分类实验,确认特征区分度。
  3. 再扩展到更多文本,加入句长分布、爆发度等统计特征。
  4. 最后再封装 API,接入批量任务。

最容易踩的坑有三处:一是直接用英文模型处理中文文本,导致特征失真;二是数据量太少就训练分类器,过拟合严重;三是把检测分数当成绝对结论,忽略了文本长度和文体对结果的影响。

后续可以扩展的方向包括:针对中文生物医学文献训练专用检测模型、引入更多细粒度的句法特征、以及将检测结果与投稿系统的元数据(投稿时间、作者历史、修改记录)结合,做更完整的写作流程分析。这套思路不只适用于生物医学,也适用于计算机科学、工程技术等大量使用 LLM 辅助写作的领域。先把单篇检测跑通,再考虑规模化部署,是最务实的路径。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询