AI 检测中的词元概率与对数似然
困惑度最受关注, 但其背后的算术是词元概率, 即模型对下一个词的分布实际包含什么, 为什么检测数学在对数空间中运行而不是原始概率, 以及一串逐词元分数如何变成一个数。
如果你问一个检测器它是如何得出那个分数的,它的大多数用户界面都会给出同样的回应, 一段文字,其中一些词被涂得比其他词更深。这种着色不是猜测。它来自于附着在该段落中每个 token 上的一个数值,这个数值是在检测器接触 perplexity、burstiness 或最终百分比之前计算出来的。
它是一个 token 概率,而每一个 token 概率 ai detection 都是以此为基础,从根本上建立起来的。检测器会报告的任何指标数值, 包括我们在本网站其他地方讨论的两个指标, 都只是对这一系列数值进行的算术运算。位于大多数解释止步之处之下的那一层,要求你思考 token 究竟是什么,模型对它的分布意味着什么,以及为什么这些算术运算是在对数空间中进行,而不是在原始概率空间中进行。大多数解释都止步于此。
这一切都不需要保持晦涩。token、概率分布和对数都是普通工具,不是专有秘密,而同样的三个概念解释了AI 检测器实际上是如何工作的, 从原始文本到报告上的一个单一数值。
Token 概率 ai detection, 从分布到分数
Token probability ai detection 分三个阶段运作。语言模型会在给定前文的情况下,为每一个可能的下一个 token 分配一个概率。这些逐 token 概率会被转换为对数,并在整段文本上求和,这样就避开了原始乘法几乎立刻会遇到的一个数值问题。得到的总和经过平均和重新缩放,最终就会呈现为 perplexity 数值,或者用于分类器的决策。每一个阶段都是具体的、可核查的算术步骤,不是黑箱。
Token 究竟是什么
词元不是词。现代语言模型使用诸如字节对编码之类的算法将文本拆分为子词片段,因此像“the”这样常见的词通常是一个词元,像“perplexity”这样不太常见的词会拆成两到三个片段,而一个不熟悉的名称甚至可以分解到单个字符。普通英语段落被分词后,可靠地会得到比原有词数更多的词元,因此在相信工具返回给你的任何词数之前,了解这一点是值得的。
模型从不以读者的方式看待词语。它看到的是一个整数序列,每个整数都是模型训练时所使用的固定词汇表中的一个索引。从这一点开始,token probability ai detection 所做的一切都作用于这个整数序列,而不是原始字母字符串,这也是为什么检测器的内部运作会让人感觉与人实际阅读句子的方式脱节。
模型对下一个词元的分布
在序列中的每一个位置,自回归语言模型都不会输出一个预测。它输出的是覆盖整个词汇表的完整概率分布,数以万计的数值之和为一,并根据此前所有内容,将每一个可能的下一个词元从最可能到最不可能进行排序。给模型输入短语“the results of the”,它会把大部分概率质量分配给少数几个看似合理的名词,如“study”、“experiment”、“analysis”,同时把极小的一部分分配给像“marmalade”这样的词。
在真实文档中实际出现的下一个词元,会落在这一排序中的某个位置,而其被分配到的概率是其他一切内容的原始材料。模型生成自己的文本时,可以直接依赖这一分布,反复从靠前的位置进行选择。检测器在阅读他人已经完成的文本时,只能事后询问,模型本来会给实际作出的那个选择分配多少概率。
整个序列的概率,是在给定其前面所有内容的情况下,每个 token 概率的乘积;如果我们按照联合概率的标准规则,把这种逐 token 的问题串联到整篇文档上,最终得到的就是一个单一数值,用来描述整段文字有多符合预期。正是在这个乘积处,算术开始失效,这也是下一节存在的原因。
将你自己的论文人性化
改写你的 AI 辅助文本,使其听起来更像人工撰写,同时不改动重要词语或引文。
为什么对数似然取代原始概率
把概率相乘在数学上是正确的,但在实际中,超过几十个 token 之后就几乎没有用处。每个单独的概率都是小于 1 的分数,所以随着另一个 token 被乘入,累积乘积都会变小,而且下降得很快。到了几百个 token 之后,原始乘积可能会低到超出计算机可表示的最小数值,于是被舍入为恰好 0,这种失效模式称为下溢。
一旦发生这种情况,这个数值就完全不再携带任何信息。一个只是比较不可能的文档,和一个极端混乱、几乎不可能的文档,都会坍缩成相同的 0,之后无法再区分。对数可以解决这个问题,因为乘积的对数等于对数之和,这是基础代数中的一个恒等式。把一串普通的负数相加,不会像把一串小分数相乘那样发生下溢,而且计算成本也更低。
| 段落长度, 说明性示例 | 原始概率, 累积乘积 | 对数概率之和 |
|---|---|---|
| 12 个 token,每个示例值为 0.1 | 1 x 10 to the power of -12, 仍可表示 | 约为 -27.6 |
| 350 个 token,每个示例值为 0.1 | 1 x 10 to the power of -350, 下溢为恰好 0 | 约为 -805.9 |
这是一个简化的示意。真实的逐 token 概率变化极大,并不是停留在一个固定的 0.1,但问题的方向完全正确。一旦原始乘积下溢为零,检测器实际上需要比较的内容,即这份文档相对于那份文档是更可能还是更不可能,就变得不可能了。对数概率之和不会以这种方式失效。无论段落多长,它都保持为一个精确、普通、可比较的数,这正是可检测性被放在对数空间而不是原始概率空间中衡量的实际原因。
从逐 token 分数到检测分数
将一段文本中的对数概率相加,会得到该文档在参考模型下的总对数似然。再除以 token 数量,就去除了长度的影响,留下每个 token 的平均对数似然,这个数终于可以在一篇五百词的论文和一章五千词的学位论文之间进行比较。对这个平均值取负并再指数化,得到的就是困惑度分数,这一指标在另一篇关于 困惑度实际衡量什么 的文章中有完整说明。
同样的逐句数值,如果跟踪的是它们在整篇文档中的变化,而不是压缩成一个平均值,就是 burstiness 的构成基础,这是一个与困惑度相关但不同的信号。两者都从上面所述的相同逐 token 数值出发,只是在其上进行不同的运算。
简单平均并不是使用这些原始材料的唯一方式,研究也早已超越了这一点。DetectGPT 由 Mitchell, Lee, Khazatsky, Manning and Finn 于 ICML 2023 发表,它基于同一个概率函数的另一种性质, 由语言模型采样得到的文本往往位于这样一个区域, 在那里,轻微改写会使对数概率下降而不是上升,论文将这一模式称为负曲率。
与其训练分类器或使用水印,这种方法会扰动一段文本,生成若干措辞上的细微变体,然后用同一个模型对每个变体重新评分。论文将其与最佳 zero-shot 基线进行比较,发现对于由一个 20-billion-parameter 模型生成的文本,这种方法达到 0.95 AUROC,而最佳 zero-shot 基线达到 0.81 AUROC。
相同的分布,用于水印而非检测
到目前为止,一切都把概率分布当作事后读取的对象。它也可以在生成时被直接作用,这会彻底反转问题。Kirchenbauer、Geiping、Wen、Katz、Miers 和 Goldstein 在 2023 年提出的一种方法,会在每个词生成之前,基于前文的哈希值选择一个随机化的允许 token 候选短名单,并以较弱的方式引导采样朝向该短名单。对读者而言,这种偏置是不可见的,但之后可以通过对一小段文本进行统计检验来恢复,而无需访问原始模型。
Google DeepMind 的 SynthID 将这一思路的一个版本投入生产:它在生成时调整下一个 token 的概率分数,并且如今已在 Gemini 应用和网页体验中上线。OpenAI 构建了一个可比系统,但尚未发布。报道将这一决定部分归因于一项调查,其中接近 30 percent 的 ChatGPT 用户表示,水印会让他们减少使用该产品,同时也担心水印在改写后能否保持有效。
检测器的报告会显示一个带阴影的词或一个单一百分比,然后就此停止,从不展示这些结果所来自的分布。TextPulse 的 free perplexity checker 对你自己的草稿运行同样的逐 token 评分的简化版本,这比事后阅读结论更直接地显示一段文本所处的位置。
相邻的两个页面会提到这一点。检测器是否仍依赖 burstiness自 2023 年以来已有变化,而GPTZero 如何将这些相同的概率转化为分数则在其单独页面中有说明。
它与 TextPulse 其余的免费工具并列,因此同一份草稿既可以检查节奏和结构,也可以检查词级可预测性,而不必为了完成这些检查而打开十几个单独的标签页。
常见问题
词元概率 AI 检测是所有其他检测指标之下的层。语言模型会为序列中的每个词元分配一个概率, 一次一个词元, 依据是它之前出现的所有内容。困惑度、分类器分数以及报告上的百分比, 都是之后对这串数字进行的算术运算, 而不是一种独立的测量。
PhD in natural language processing, with years spent building NLP applications end to end. Moe works on text analysis: lexical and syntactic structure, and what separates machine-generated prose from human prose statistically. He has been experimenting with computational linguistics since the early days of NLTK, spaCy and WordNet, and still writes most of his tooling in Python.