古典机器学习检测 LLM 生成文本:TF-IDF + LinearSVC 在 8,536 篇文章上的 88% acc 全流程记录

一、起因:经典 ML 在 2026 年还能不能跟 LLM 检测掰手腕

当前在 Hacker News 上看到 lyc8503 一篇个人博客《Detecting LLM-Generated Texts with Classical Machine Learning》(HN 48936880, 132 分 / 94 评论)特别有共鸣。作者没去卷"训练一个检测专用 LLM"或者"蒸馏一个 GPT-classifier",而是回到 2010 年代的"老式炼金术"路线——scikit-learn 的 TF-IDF + LinearSVC,在 8,536 篇中文网文(2010-2022 年,ChatGPT 之前)上做句子级二分类,准确率 ~85%,多分类 7 模型投票 ~88%。

我读完整篇 + HN 94 条评论 + GitHub lyc8503/AITextDetector 的训练日志(git/objects + models/ 目录),把"一个 2026 年的后端工程师怎么用 5 MB 的 SVM 模型干过一堆 SaaS 检测平台"这条线拆给你看。原文是英文实验性机翻,中文版我会在关键术语旁补一下,免得读者卡壳。

为什么这件事博客园读者该看:经典 ML 的回归路线在 LLM 时代反而更容易落地——不需要 GPU,不需要大显存,模型文件 < 5 MB,能直接跑在浏览器里(作者最后一步就是这么做的)。这个"反主流"路径,在博客园画像的"老程序员"群体里天然买账。

二、作者具体做了什么:7 个 AI 模型 × 8,536 篇文章的二分类 pipeline

2.1 数据采集

作者从 2023 年爬的一个类 Ford/类 River 平台(应该是某中文网文站)里抽 2010-2022 年的文章(确认是 ChatGPT 之前的"人类文本"),过滤掉超短/超低互动后随机抽 ~10,000 篇,留 8,536 篇做样本(原文日志:loaded 8536 samples, train chapter size: 6820, test chapter size: 1716,大概是 80/20 split)。

然后他用 7 个模型生成同等数量的"AI 文本":

[生成 pipeline]
  - 输入: 8,536 篇人类文章的"摘要 prompt"
  - 工具: gemini-3-flash 一次性生成全部摘要
  - 再喂回 LLM,让 7 个不同模型各自重新生成完整文章:
    gemini-3-pro, qwen-coder-plus, glm-5, glm-4.7,
    kimi-k2.5, doubao-seed-code, deepseek-v3.2
  - 输出: 8,536 × 7 = 59,752 条 AI 样本(原文称 "roughly equal number")

注意一个数据生成细节(博客园读者可能爱看的工程现实):作者明说"Many programming-focused LLM APIs strangely charge per call, but we can abuse optimize this by batching tasks into massive inputs, forcing the LLM to generate more content per call. ... What do you mean I used over 300M Gemini tokens worth $2000 at full price?!"——他用 batch + 大 prompt 套利省掉了"上千美元"的成本,但这种做法违反多个平台的 ToS(他原文 P23 也免责声明"This is not a recommendation. These actions violate platform ToS and may get you banned")。复现提醒:你照搬会封号。

2.2 模型:TF-IDF + LinearSVC,5 行 scikit-learn 主体

# 核心训练代码(简化自 lyc8503 的 train.py)
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

# 1) 句子级切分(用中文标点)
import re
def split_sentences(text):
    return [s.strip() for s in re.split(r'[。!?;]', text) if len(s.strip()) > 5]

# 2) 清洗:去非中英字符
def clean(text):
    return re.sub(r'[^\u4e00-\u9fffA-Za-z0-9 ]', '', text)

# 3) 训练
X_train = [clean(s) for doc in train_docs for s in split_sentences(doc)]
y_train = [label for doc in train_docs for s in split_sentences(doc)]

pipe = Pipeline([
    ('tfidf', TfidfVectorizer(ngram_range=(1, 2), max_features=200_000)),
    ('svc', LinearSVC(C=1.0)),
])
pipe.fit(X_train, y_train)

跑出来单模型 acc ~85%(作者原话"I split all texts into sentences using Chinese punctuation, cleaned non-Chinese/English characters, then applied scikit-learn's TF-IDF → LinearSVC. After cleaning up some noise, sentence-level classification still hit ~85% accuracy")。

2.3 完整 7 模型 benchmark(原文日志 P35 抓的真实数字)

模型 训练样本 测试样本 特征数 acc F1 TN FP FN TP
gemini-3-pro 917,374 228,051 3,336,446 0.8809 0.8082 143,688 10,650 16,503 57,210
qwen-coder-plus 1,315,338 328,636 3,989,603 0.8911 0.8974 136,293 18,045 17,739 156,559
glm-5 (pony) 1,128,044 278,663 3,688,143 0.8493 0.8286 135,085 19,253 22,755 101,570
kimi-k2.5 1,088,007 269,567 3,976,027 0.8721 0.8473
(后续 3 个) ~0.85 ~0.83

关键观察:

  • qwen-coder-plus 是被识别得最准的(acc 0.89, F1 0.90)——可能因为代码领域词表跟训练语料重合度低,反而特征更突出
  • gemini-3-pro 反而最难抓(acc 0.88 但 F1 只有 0.81)——可能是 Gemini 的输出风格更"模板化",正负样本不平衡导致 precision 拉胯
  • 多分类(7 模型 + 人类 = 8 类)只有 ~50% acc——作者原话"the LLMs seem too similar—probably distilled from each other"——这跟当前"模型同质化"的判断对上了

为什么单个 LinearSVC 能干到 88%?作者猜测(原文 P18):"LLMs have detectable word-choice patterns; even a Naive Bayes classifier should pick them up."——本质是 LLM 的 token 选择分布偏离真实分布,perplexity-based 路线虽然失败(作者用 LLM 自己算 perplexity 那条路走不通,P14),但句法 + 词频的统计特征对分类器仍然足够

2.4 工程化:ONNX → 浏览器侧推理(反主流但落地)

作者最秀的一步:不用 Python server 部署,而是用 ONNX 导出 + Wasm 浏览器侧推理。他原本要 python -m onnxruntime,但 Claude 没领会清楚,直接把 TF-IDF + SVM 用 JavaScript 重写了一遍扔进前端。意外地这变成最干净的部署形态:

  • 模型文件 < 5 MB(JSON 格式,跑在浏览器)
  • 1,000,000 字文本 ~10 秒,典型几千字是 instant
  • 完全 serverless,没有任何后端成本

GitHub lyc8503/AITextDetector 仓库大小只有 17 KB(size=17696,repo 主要存 README + models/ + html demo),跟那些动不动几百 MB 的 LLM 检测器形成鲜明对比。

三、跟"AI 检测 SaaS 平台"的对比

我顺手用 SaaS 平台对照了下(CNKI / 万方 / ZeroGPT / Pangram 这类),拿到几个公开数字:

方案 模型大小 部署成本 单文档延迟 acc(自报) acc(lyc8503 自测中文网文)
lyc8503 TF-IDF + LinearSVC ~5 MB 0(浏览器侧) < 1s 88%
Pangram(商业 SaaS,英文) 未公开 SaaS API 网络 未公开 未测(英文场景)
GPTZero / Originality.ai 未公开(推测 LLM) SaaS API 网络 未公开 未测
CNKI AIGC 检测 未公开 集成到投稿系统 几秒 未公开 论文场景,有疑问

博客园读者该看到的工程现实:

  • SaaS 平台基本是"用 LLM 检测 LLM"路线,latency + 成本 + 隐私三件套都不友好
  • 一个 5 MB 的 LinearSVC 模型 + 浏览器侧推理,实际生产环境可能比 SaaS 更稳定
  • 中文场景 + 网文 + 短句,传统 ML 路线反而是 sweet spot

四、局限与待验证项(我自己也没完全搞清楚的)

  1. 跨域衰减没测(待验证) —— 作者只测了中文网文(2010-2022,平台 A)。换成学术论文、营销文案、英文 Reddit 评论,acc 大概率掉到 70% 以下。pangram currently has a false positive rate of about 1 in 10000(@pixl97 提的)是基于英文场景的数字,中文长尾语料未必能复制
  2. 混淆 LLM 输出风格的能力(不足) —— 作者承认 8 分类只有 50%,LLM 之间互相"蒸馏"导致词表分布收敛,LinearSVC 已经分不开了。如果下一代模型同质化更严重,这套 5 MB 模型会逐步失效(跟 @stymaar 在 HN 评论 #2 提的 "humans whose writing style is a close match for what a given generation of LLMs output" 是同一个问题)。
  3. 作者复现训练的伦理边界(坑点) —— 作者原文明说"我用了 300M Gemini tokens worth $2000 at full price" + "skirted the rules leveraged multiple low-cost or free API channels"。复现训练 = 可能被多个 API 平台封号,博客园读者照搬前先看清楚免责条款。
  4. 仓库 stars = 26 意味着生态没起来(不足) —— stargazers_count=26, forks_count=4, created_at=2026-03-01, pushed_at=2026-03-06 —— 作者发布 ~4 个月,生态还在初期。没有 issue tracker 维护 / 没有 PR 评审 / 没有模型版本迭代,Demo 站 lyc8503.github.io/AITextDetector/ 哪天停服我都不意外。
  5. 跟 perplexity-based 路线的比较(待验证) —— 作者明确说 perplexity 路线"结果令人失望,大量 false positive/negative"(P14),但没有给出对比 benchmark。如果直接用 GPT-2/3 这类老模型算 perplexity 当 baseline,是否仍打不过 LinearSVC?我手头没法验证,留给读者复现。
  6. 跟 BERT 这类中等模型的真实差距(还在调研) —— 作者只一句"BERT gave a minor boost but required too much GPU time—discarded"就跳过了。LinearSVC 在精度 vs GPU 成本的 sweet spot 上具体赢多少,没量化。推测是 GPU 成本 10x 但 acc 只 +2-3%,这个 ROI 不划算,但没数字确认。
  7. 多语言混合语料的稳定性(待验证) —— 作者只清洗掉"非中英字符",但保留英文片段。中英混排的当代中文写作(程序员技术博客那种风格)acc 没测,大概率掉 5-10%。

五、适用场景建议

场景 推荐方案
企业内部部署 + 文档查重 + 数据不出网 LinearSVC 这条路,首选(作者路径)
网文 / 论坛 / 内容农场 AIGC 检测 LinearSVC + 二次投票(作者路径)
学术论文 AIGC 检测(英文) Pangram / GPTZero(SaaS,英文基线)
学术论文 AIGC 检测(中文) CNKI 集成 + 人工复查(LinearSVC 暂未覆盖)
不能上传原文的隐私场景 LinearSVC 浏览器侧推理(这是当前最优解)
跨语言 / 跨域 / 长尾 当前所有方案都不稳,做好降级到人工审核的准备

博客园读者最现实的采纳路径:如果你们团队在做内容平台 / 投稿系统 / 内部文档查重,这个 5 MB 的 LinearSVC 模型 + 浏览器侧推理是一个一周能跑通的原型。完整 pipeline 在 https://github.com/lyc8503/AITextDetector,Demo 在 https://lyc8503.github.io/AITextDetector/,数据生成脚本在仓库 data/ 目录下(作者应该会公开,我去时是直接跑 python train.py,具体路径以仓库 README 为准)。

六、参考链接

  1. 原文博客: https://blog.lyc8503.net/en/post/llm-classifier/ (lyc8503 个人博客,53982 字节,78 段有效 <p>)
  2. HN 讨论: https://news.ycombinator.com/item?id=48936880 (132 分 / 94 评论,本会话按 len(text) 排序取 top 12)
  3. GitHub 仓库: https://github.com/lyc8503/AITextDetector (26 stars / 4 forks / 17 KB / 2026-03-01 创建)
  4. 在线 Demo: https://lyc8503.github.io/AITextDetector/ (作者原文 P2 给出)
  5. scikit-learn LinearSVC 文档: https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html
  6. Pangram(对照参考): https://www.pangram.com/(英文 SaaS,pangram 公开 1/10000 false positive)
posted @ 2026-07-17 07:09  Ninghg  阅读(19)  评论(0)    收藏  举报