RAPD 是一个 AI 生成文本检测框架,核心方法为 PGR。该框架通过微调语言模型,使其能够高效区分人类撰写的文本与大语言模型(LLM)生成或修改的文本。
核心思想:将人类文本视为"非偏好"样本,机器修订文本视为"偏好"样本,通过偏好学习训练评分模型学习两者之间的风格差异,从而实现高精度的机器文本检测。
人类原始文本 (dispreferred) ──┐
├──▶ PGR Loss + KL 正则 ──▶ 评分模型 (LoRA 微调)
机器修订文本 (preferred) ──┘
PGR 方法由以下三个模块组合而成(代码中各文件对应不同模块组合的消融实验):
| 模块 | 说明 | 对应代码文件 |
|---|---|---|
| 有界概率聚合 | 对概率分布进行有界聚合,提升评分鲁棒性 | 有界概率聚合.py |
| 减少偏差 | 修正评分中的系统性偏差 | 减少偏差.py |
| 窗口模块 | 基于动态语义窗口的局部特征捕捉 | 窗口模块.py |
| 全部组合 | 三模块融合的完整 PGR 方法 | 最终+++.py |
| 基线(无模块) | 不含任何模块的基线对比 | 0个模块.py |
评分综合了:
├── dpr/ # 核心模型与训练代码
│ ├── spo.py # PGR 模型定义(ComputeScore 类、评分函数)
│ ├── engine.py # 训练与评估引擎
│ ├── run_spo.py # PGR 训练入口脚本
│ ├── dataset.py # 数据集加载(CustomDataset 系列)
│ ├── metrics.py # 评估指标(ROC AUC、PR AUC)
│ ├── inference.py # 交互式推理 Demo
│ ├── evaluation.py # 独立评估脚本
│ ├── utils_spo.py # PGR 损失计算
│ ├── utils_visualization.py # 训练过程可视化(梯度陷阱、NLL 分布、Token 信号)
│ ├── demo.py # 可视化 Demo(含训练循环示例)
│ │
│ │ # ── 消融实验文件(不同模块组合)──
│ ├── 0个模块.py # 基线:无任何模块
│ ├── 有界概率聚合.py # 仅有界概率聚合模块
│ ├── 减少偏差.py # 仅减少偏差模块
│ ├── 窗口模块.py # 仅窗口模块
│ ├── 有界概率聚合+减少偏差.py # 两模块组合
│ ├── 有界聚合模块+窗口.py # 两模块组合
│ ├── 减少偏差+窗口.py # 两模块组合
│ └── 最终+++.py # 三模块融合的完整 PGR
│
├── tools/ # 数据构建与辅助工具
│ ├── data_builder.py # LLM 数据生成(polish/rewrite/expand/generation)
│ ├── data_builder_gpts/ # GPT 系列模型的 Notebook 数据生成脚本
│ ├── show_results.py # 结果展示工具
│ ├── count_words.py # 字数统计
│ ├── truncation.py # 文本截断实验
│ └── solve_llama_output.py # Llama 输出后处理
│
├── scripts/ # Shell 脚本(训练、评估、下载)
│ ├── train_spo.sh # PGR 训练
│ ├── eval_all.sh # 全量评估(polish/rewrite/generation/expand)
│ ├── eval_spo_*.sh # 分任务评估
│ ├── eval_ablation.sh # 消融实验
│ ├── build_data.sh # 数据构建
│ └── download_*.sh # 模型下载
│
├── data/ # 数据集
│ ├── ai_detection_*_polish*.json # 训练数据(500/3000 条)
│ ├── polish/ # Polish 任务数据(按模型组织)
│ ├── rewrite/ # Rewrite 任务数据
│ ├── expand/ # Expand 任务数据
│ ├── generation/ # Generation 任务数据
│ ├── truncation/ # 截断长度实验数据
│ └── multilang/ # 多语言数据(中文、西班牙语、葡萄牙语)
│
├── results/ # 实验结果
│ ├── main/ # 主实验结果(按 task/model 组织)
│ └── ablation/ # 消融实验结果(SFT/ORPO/RLHF 对比)
│
├── evaluation/ # 评估输出(ROC 曲线、散点图、Token 高亮图)
├── logs/ # TensorBoard 训练日志
└── local_infer_ref/ # 本地推理参考分布数据
| 任务类型 | 说明 | 示例 |
|---|---|---|
| Polish | LLM 对人类文本进行润色/改写 | 保持原意,改善表达 |
| Rewrite | LLM 对人类文本进行同义改写 | 替换词汇,调整句式 |
| Expand | LLM 对人类文本进行扩写 | 增加细节,扩展论述 |
| Generation | LLM 从开头续写生成完整文本 | 给定前缀,生成全文 |
pip install torch transformers peft accelerate
pip install scikit-learn matplotlib tensorboard
pip install tqdm numpy
使用开源 LLM 生成机器文本数据:
# 示例:用 Llama-3-8B 对 XSum 数据集进行 Polish
python tools/data_builder.py \
--model_name Llama-3-8B \
--dataset xsum \
--task polish \
--dataset_file ./data/xsum \
--result_dir ./data/polish/Llama-3-8B
# 使用 500 条 Polish 数据训练 2 个 epoch
python dpr/run_spo.py \
--datanum 500 \
--task_name ai_detection_polish_500 \
--epochs 2 \
--lr 1e-4 \
--beta 0.05
关键参数:
--lr:学习率(默认 1e-4)--beta:PGR 损失的 β 系数(默认 0.05)-a:梯度累积步数(默认 1)--datanum:训练样本数(默认 500)# 评估单个数据集
python dpr/evaluation.py \
--eval_dataset ./data/polish/gpt-3.5-turbo/xsum_polish_gpt-3.5-turbo.raw_data.json
# 全量评估
bash scripts/eval_all.sh
python dpr/inference.py --task polish --detail True
输入文本后,模型将输出该文本被判定为机器生成的概率。
LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8, # LoRA 秩
lora_alpha=32, # 缩放系数
lora_dropout=0.1 # Dropout 率
)
loss = -log_sigmoid(β * (r_preferred - r_dispreferred))
其中 r 为相对熵(模型 log 概率 - 参考模型 log 概率),β 控制偏好强度。
在 PGR 损失基础上加入 KL 散度约束项,防止评分模型过度偏离参考分布:
total_loss = pgr_loss + λ * KL(q_score || p_ref)
框架提供多维度可视化支持:
项目包含多种基线方法的消融实验对比:
PGR 模块消融(dpr/ 目录下的中文命名文件):
0个模块.py:基线(无模块)有界概率聚合.py / 减少偏差.py / 窗口模块.py有界概率聚合+减少偏差.py / 有界聚合模块+窗口.py / 减少偏差+窗口.py最终+++.py(三模块融合)训练策略消融(results/ablation/):
如果您使用了本项目的代码或方法,请引用相关论文。
本项目仅供学术研究使用。
RAPD 是一个 AI 生成文本检测框架,核心方法为 PGR。该框架通过微调语言模型,使其能够高效区分人类撰写的文本与大语言模型(LLM)生成或修改的文本。
核心思想:将人类文本视为"非偏好"样本,机器修订文本视为"偏好"样本,通过偏好学习训练评分模型学习两者之间的风格差异,从而实现高精度的机器文本检测。
人类原始文本 (dispreferred) ──┐
├──▶ PGR Loss + KL 正则 ──▶ 评分模型 (LoRA 微调)
机器修订文本 (preferred) ──┘
PGR 方法由以下三个模块组合而成(代码中各文件对应不同模块组合的消融实验):
| 模块 | 说明 | 对应代码文件 |
|---|---|---|
| 有界概率聚合 | 对概率分布进行有界聚合,提升评分鲁棒性 | 有界概率聚合.py |
| 减少偏差 | 修正评分中的系统性偏差 | 减少偏差.py |
| 窗口模块 | 基于动态语义窗口的局部特征捕捉 | 窗口模块.py |
| 全部组合 | 三模块融合的完整 PGR 方法 | 最终+++.py |
| 基线(无模块) | 不含任何模块的基线对比 | 0个模块.py |
评分综合了:
├── dpr/ # 核心模型与训练代码
│ ├── spo.py # PGR 模型定义(ComputeScore 类、评分函数)
│ ├── engine.py # 训练与评估引擎
│ ├── run_spo.py # PGR 训练入口脚本
│ ├── dataset.py # 数据集加载(CustomDataset 系列)
│ ├── metrics.py # 评估指标(ROC AUC、PR AUC)
│ ├── inference.py # 交互式推理 Demo
│ ├── evaluation.py # 独立评估脚本
│ ├── utils_spo.py # PGR 损失计算
│ ├── utils_visualization.py # 训练过程可视化(梯度陷阱、NLL 分布、Token 信号)
│ ├── demo.py # 可视化 Demo(含训练循环示例)
│ │
│ │ # ── 消融实验文件(不同模块组合)──
│ ├── 0个模块.py # 基线:无任何模块
│ ├── 有界概率聚合.py # 仅有界概率聚合模块
│ ├── 减少偏差.py # 仅减少偏差模块
│ ├── 窗口模块.py # 仅窗口模块
│ ├── 有界概率聚合+减少偏差.py # 两模块组合
│ ├── 有界聚合模块+窗口.py # 两模块组合
│ ├── 减少偏差+窗口.py # 两模块组合
│ └── 最终+++.py # 三模块融合的完整 PGR
│
├── tools/ # 数据构建与辅助工具
│ ├── data_builder.py # LLM 数据生成(polish/rewrite/expand/generation)
│ ├── data_builder_gpts/ # GPT 系列模型的 Notebook 数据生成脚本
│ ├── show_results.py # 结果展示工具
│ ├── count_words.py # 字数统计
│ ├── truncation.py # 文本截断实验
│ └── solve_llama_output.py # Llama 输出后处理
│
├── scripts/ # Shell 脚本(训练、评估、下载)
│ ├── train_spo.sh # PGR 训练
│ ├── eval_all.sh # 全量评估(polish/rewrite/generation/expand)
│ ├── eval_spo_*.sh # 分任务评估
│ ├── eval_ablation.sh # 消融实验
│ ├── build_data.sh # 数据构建
│ └── download_*.sh # 模型下载
│
├── data/ # 数据集
│ ├── ai_detection_*_polish*.json # 训练数据(500/3000 条)
│ ├── polish/ # Polish 任务数据(按模型组织)
│ ├── rewrite/ # Rewrite 任务数据
│ ├── expand/ # Expand 任务数据
│ ├── generation/ # Generation 任务数据
│ ├── truncation/ # 截断长度实验数据
│ └── multilang/ # 多语言数据(中文、西班牙语、葡萄牙语)
│
├── results/ # 实验结果
│ ├── main/ # 主实验结果(按 task/model 组织)
│ └── ablation/ # 消融实验结果(SFT/ORPO/RLHF 对比)
│
├── evaluation/ # 评估输出(ROC 曲线、散点图、Token 高亮图)
├── logs/ # TensorBoard 训练日志
└── local_infer_ref/ # 本地推理参考分布数据
| 任务类型 | 说明 | 示例 |
|---|---|---|
| Polish | LLM 对人类文本进行润色/改写 | 保持原意,改善表达 |
| Rewrite | LLM 对人类文本进行同义改写 | 替换词汇,调整句式 |
| Expand | LLM 对人类文本进行扩写 | 增加细节,扩展论述 |
| Generation | LLM 从开头续写生成完整文本 | 给定前缀,生成全文 |
pip install torch transformers peft accelerate
pip install scikit-learn matplotlib tensorboard
pip install tqdm numpy
使用开源 LLM 生成机器文本数据:
# 示例:用 Llama-3-8B 对 XSum 数据集进行 Polish
python tools/data_builder.py \
--model_name Llama-3-8B \
--dataset xsum \
--task polish \
--dataset_file ./data/xsum \
--result_dir ./data/polish/Llama-3-8B
# 使用 500 条 Polish 数据训练 2 个 epoch
python dpr/run_spo.py \
--datanum 500 \
--task_name ai_detection_polish_500 \
--epochs 2 \
--lr 1e-4 \
--beta 0.05
关键参数:
--lr:学习率(默认 1e-4)--beta:PGR 损失的 β 系数(默认 0.05)-a:梯度累积步数(默认 1)--datanum:训练样本数(默认 500)# 评估单个数据集
python dpr/evaluation.py \
--eval_dataset ./data/polish/gpt-3.5-turbo/xsum_polish_gpt-3.5-turbo.raw_data.json
# 全量评估
bash scripts/eval_all.sh
python dpr/inference.py --task polish --detail True
输入文本后,模型将输出该文本被判定为机器生成的概率。
LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=8, # LoRA 秩
lora_alpha=32, # 缩放系数
lora_dropout=0.1 # Dropout 率
)
loss = -log_sigmoid(β * (r_preferred - r_dispreferred))
其中 r 为相对熵(模型 log 概率 - 参考模型 log 概率),β 控制偏好强度。
在 PGR 损失基础上加入 KL 散度约束项,防止评分模型过度偏离参考分布:
total_loss = pgr_loss + λ * KL(q_score || p_ref)
框架提供多维度可视化支持:
项目包含多种基线方法的消融实验对比:
PGR 模块消融(dpr/ 目录下的中文命名文件):
0个模块.py:基线(无模块)有界概率聚合.py / 减少偏差.py / 窗口模块.py有界概率聚合+减少偏差.py / 有界聚合模块+窗口.py / 减少偏差+窗口.py最终+++.py(三模块融合)训练策略消融(results/ablation/):
如果您使用了本项目的代码或方法,请引用相关论文。
本项目仅供学术研究使用。