Methodology
技术方法
模型架构、训练与推理链路,及与线上一致的参数与部署说明。
Method Snapshot
方法页应该回答什么
这一页负责把“系统为什么能跑起来”讲清楚,包括主分类器、 数据治理步骤、置信度校准、风险解释和前后端部署结构。
文档级分类主路径,负责 Human / AI 判定。
bert_span_detector 仅作为历史实验资产,不进入线上主链路。
先校准概率,再用保守阈值降低高质量人类文本误杀。
单主模型推理架构
当前线上只做 Human / AI 分类,解释层用于风险提示与反馈闭环
架构流程图
输入层
将中文文本编码为固定长度的 token 序列BERT编码层
利用BERT提取深层语义特征分类判定层
输出 Human / AI 的主判定结果风险解释层
补充低置信、长文本和模板化表达等风险提示BERT编码器
当前主模型基于 bert-base-chinese 微调,使用 12 层 Transformer Encoder 提取中文文本的上下文语义特征。
- 12层Transformer编码器
- 768维隐藏层
- 12个注意力头
- 词表大小 21,128,约1.02亿参数
核心创新
- 1V11c 数据治理提升独立评估稳定性
- 2针对中文特点优化的分词策略
- 3Temperature Scaling置信度校准
- 4线上输出固定为 Human / AI 二分类
BERT 微调是什么意思,本项目微调在哪里
微调就是加载预训练 BERT,再用本项目的中文 Human / AI 数据继续训练,让通用语言模型适应 AI 文本检测任务。
微调过程
不是从零训练
项目先加载已经具备中文语义能力的 BERT 权重,再用本项目的 Human / AI 样本继续训练。
任务变成二分类
通用 BERT 后面接 BertForSequenceClassification 分类头,输出 Human 和 AI 两个类别的 logits。
参数会被继续更新
训练时通过 loss.backward() 和 optimizer.step() 反向传播,更新 BERT 和分类头参数。
最终保存专用模型
验证集表现提升时调用 save_pretrained,得到面向中文 AI 文本检测的专用模型目录。
项目中的微调位置
scripts/training/train_v10.pyV10 主分类微调脚本加载 models/bert_v7_improved,使用 train_v10.csv 继续训练 Human / AI 二分类模型。
scripts/training/train_v11a.py / train_v11b.py / train_v11c.pyV11 系列连续微调围绕风险审计、弱域补充和长文 AI 修复继续训练,形成当前主模型系列。
scripts/training/train_v11c_hard_reweight.py困难样本重加权微调针对 hard case 和弱项样本调整训练权重,进一步修正模型边界。
scripts/training/train_span_detector.py边界检测微调加载 BERT token 分类模型,对 C2 混合文本做 token-level Human / AI 边界定位实验。
对应到代码的核心动作
tokenizer = BertTokenizer.from_pretrained(base_model)
model = BertForSequenceClassification.from_pretrained(
base_model,
num_labels=2
).to(device)
outputs = model(input_ids=input_ids, attention_mask=attention_mask)
loss = loss_fn(outputs.logits, labels, lengths)
loss.backward()
optimizer.step()
model.save_pretrained(output_dir)
tokenizer.save_pretrained(output_dir)为什么选 BERT,以及模型到底做了什么
这一块对应“算法或模型关键点”,明确说明模型底座、输入编码、分类方式、训练策略和推理链路。
任务匹配
AI 文本检测是判别任务,不需要生成新文本;BERT 的双向编码器更适合同时读取左右上下文并形成整段语义表示。
中文可复现
bert-base-chinese 使用 WordPiece 中文词表,HuggingFace 支持完整,训练、加载、部署和复现实验都更稳定。
部署成本可控
BERT-base 约 1.02 亿参数,比大语言生成模型显存和延迟低,适合做成 FastAPI 在线推理服务。
主模型关键点
- P1输入文本经 BertTokenizer 分词,首部 [CLS] 作为整段文本表示,尾部 [SEP] 作为句段结束标记。
- P2主模型使用 BertForSequenceClassification,在 [CLS] 向量后接线性分类头输出 Human / AI 两类。
- P3训练阶段使用 Label Smoothing=0.05、长度感知权重和 Early Stopping,降低过拟合和长度捷径。
- P4推理阶段对 logits 做 Temperature Scaling,让置信度更接近真实正确率,而不是只给一个虚高分数。
- P5线上默认不启用 mixed 三分类,保留 bert_span_detector 作为历史边界定位实验资产。
当前线上模型与参数
本页明确给出当前线上版本的模型名称、阈值策略与部署选择,用于说明系统的工程落地形态。
关键运行参数
| 项目 | 当前值 | 说明 |
|---|---|---|
| 默认分类模型 | bert_v11c_boundary_fix | 当前线上主模型 |
| 线上启用模型 | bert_v11c_boundary_fix only | 第三类边界模型默认不启用 |
| 最大输入长度 | 256 tokens | 分类主路径使用 256 |
| 温度缩放 | T = 0.8165 | 用于置信度校准 |
| 顶层判定策略 | argmax(Human, AI) | 按更高概率返回二分类结果 |
| AI风险阈值 | 0.8 | 用于句级AI提示与风险展示 |
| 输出类型 | human / ai | API 当前直接返回二分类结果 |
数据治理与模型训练
V11c通过四阶段数据治理与精细微调达成最优性能
数据风险审计
移除模板匹配和unknown来源样本
弱域数据增补
定向补充formal和LLaMA-405B弱域样本
长文AI边界修复
补充长文本AI样本恢复覆盖率
模型微调
沿用 V11 系列主配置做单阶段精细微调
从输入文本到最终结果
当前线上系统采用「二分类主模型 + 风险解释」的推理逻辑,用于说明前端显示的 Human / AI 是如何一步步得到的。
文本编码
前端提交原始文本,后端使用 BertTokenizer 做截断、padding 和 attention mask 构造。
概率校准
分类器 logits 先做 Temperature Scaling,再计算 Human / AI softmax 概率。
阈值决策
顶层结果按 Human / AI 校准概率较高的一侧返回;0.8 阈值只用于句级AI提示与风险展示。
风险解释
根据置信度、文本长度、模板化表达和人工反馈记录生成解释;当前线上不调用第三类边界模型。
当前分类主逻辑(伪代码)
encoding = tokenizer(
text,
max_length=256,
padding="max_length",
truncation=True
)
logits = classifier(**encoding)
scaled_logits = logits / 0.8165
prob_human, prob_ai = softmax(scaled_logits)
if prob_ai >= prob_human:
result_type = "ai"
confidence = prob_ai
else:
result_type = "human"
confidence = prob_human
risk_flags = collect_risk_flags(text, confidence)
reason_summary = build_reason_analysis(result_type, risk_flags)/api/detect 返回字段
技术栈
PyTorch
深度学习框架
Transformers
预训练模型库
bert-base-chinese
中文BERT底座
Scikit-learn
机器学习工具
Pandas
数据处理
NumPy
数值计算
线上部署结构
项目不是只停留在离线训练,而是已经部署成可在线访问的完整前后端系统。
Vercel Frontend
Next.js 16 + TypeScript,页面展示与交互入口。
Next.js Route Handlers
/api/detect 与 /api/health 先在服务端代理,再转发到后端。
api.baxfor.fun
独立后端域名,使用 HTTPS 反向代理到模型服务。
FastAPI + PyTorch
负责推理、阈值决策、边界分析与 JSON 返回。
当前生产环境要点
核心算法
文本分类算法
def classify_text(text):
encoding = tokenizer(
text,
max_length=256,
padding="max_length",
truncation=True
)
logits = classifier(**encoding)
scaled_logits = logits / 0.8165
prob_human, prob_ai = softmax(scaled_logits)
if prob_ai >= prob_human:
return "ai", prob_ai
return "human", prob_human风险解释逻辑
def collect_risk_flags(text, confidence):
flags = []
if len(text) < 128:
flags.append("short_text")
if len(text) > 2048:
flags.append("long_text")
if confidence < 65:
flags.append("low_confidence")
if looks_template_like(text):
flags.append("template_like")
return flags当前版本仍然存在的问题
这一部分不仅展示成绩,也清楚说明当前模型的边界和工程取舍。
主分类器使用 max_length=256,因此当前更像稳定的单窗分类器,而不是严格意义上的全文阅读器。
模型对“高完成度中文书面表达”偏敏感,学术导论、社论、抒情散文这类人类文本更容易被误判为 AI。
全文 sliding-window 聚合已做对比实验,但在当前分类器上尚未稳定带来净收益,因此线上仍以 V11c 单窗主模型为准。
混合文本检测模型只作为历史实验资产保留;由于样本规模和真实分布不足,当前线上不启用,也不做三分类输出。