Reed's News
← 返回精选

Claude文本水印技术解析

AI 62 Sebastian Raschka, PhD 2026/8/22 8183 字 原文 ↗

我最近在Substack笔记中介绍了Claude全新的水印生成流程及实现方式。由于这个话题热度很高,引发了不少讨论,我想不妨深入拆解一下它的工作原理。

这次我没有写常规的文字稿,而是录制了一段小讲座(换个形式,和我平时的文章不一样)。下面是视频和对应的文字稿。

最初我计划做10页幻灯片,录一段10分钟的短视频。但制作过程中不断补充关键细节,最后做成了50多页幻灯片,录出来的视频也长达48分钟。

希望这样能把原理讲透彻!祝观看愉快!

视频文字稿

说明:以下文字稿经过小幅编辑整理,以提升可读性,但完整保留了原视频的内容顺序和逻辑。

Claude文本水印的工作原理

0:00

大家好。几天前,Anthropic宣布将为其Claude模型生成的文本添加水印。我当时在社交媒体上发了一篇短文,简要解释了它的原理。那篇帖子意外地火了——倒不是水印本身有多热门,而是大家对背后的机制很感兴趣。既然只有一张图的帖子引发了这么多疑问和讨论,那不如展开讲讲细节。

我本来打算做几张图,用10页幻灯片一步步讲解,结果不知不觉做了50页。不过这次应该能把水印技术的原理、可能失效或被移除的方式等内容说清楚。现在很多人都在用大语言模型(LLM),也经常接触网上由LLM生成的文本,所以这个话题应该值得一聊。

如今水印技术来了,有人担心它会影响文本质量,也有人好奇它到底有什么用,到底意味着什么。我觉得,只要我们更清楚地理解水印是什么,就能自己判断它的利弊,形成独立看法。

我的目标就是把Claude文本水印的底层机制和实现方式讲明白。

从"零基础"出发的好处

1:41

这也是个很好的例子,能说明"从零基础理解事物"为什么有用。这套水印技术还能帮我们解释普通模型乃至所有LLM的底层工作逻辑。熟悉我的人都知道,我喜欢从零基础拆解问题——比如我的书《从零构建大语言模型》《从零构建推理模型》,还有一些标注"零基础"的文章。

对我来说,"零基础"通常包含代码实现。不过这次不涉及代码,但从零写代码确实是非常有用的学习方法,能帮你真正理解事物的实现逻辑,进而形成自己的认知、图表和概念。如果不亲手实现,没有代码参考,很多时候会模糊不清。当然,我也意识到现在不是所有人都从零写代码了。

以前我们只能自己从零写代码,毕竟那时只有人类会编程。现在LLM也能写代码了,但这并不意味着读代码没用,代码里包含了大量信息。比如这次的水印技术,如果你从零写过LLM的代码,就会明白模型内部的采样是怎么实现的——我们后面也会用到一些相关的代码片段。

这种理解反过来又能帮你搞清楚:哦,原来水印是加在这个环节,会带来这样那样的影响。所以我觉得,哪怕现在人们不总是从零写代码,为了深入理解某个事物,或者为了做研究时能不受层层抽象的限制、透明地操控模型,从零构建东西依然很有价值,哪怕只是出于学习目的。

不过说回正题,这次的幻灯片里,我用到了很多我在"零基础"编程教程里用过的图,也算是一种巧合的呼应。

Anthropic关于Claude文本水印的公告

3:58

几天前(也就是8月14日),Anthropic发布了一篇题为《Claude文本水印的工作原理》的文章。我这里放的是文章的录屏,能看到所有幻灯片内容,里面有不少细节。他们后来更新过几次,我最初看到的版本要短得多。不过整体来说,文章偏概念性,只有概述,连一张图都没有。

所以还是有点难理解他们到底要做什么。文章花了很多篇幅解释为什么要加水印,但没说具体怎么实现,只在某处链接了一篇非常技术化的论文。我觉得不如退一步,从头开始讲,帮大家理解他们这套水印技术到底要实现什么。

顺便说一下,加水印的目的是让Anthropic能够识别:比如有人在网上发布一段文本,他们可以判断"这段文本是我们的Claude Opus 4.8模型生成的",从而确定这是AI生成内容——因为文本里带有他们的水印。这个水印对用户是不可见的,只有Anthropic能解码,判断文本是否带有他们的水印。

为什么只有他们能解码?我们后面会讲到(希望视频不会太长),先一步一步来。

LLM文本生成的基本原理

铺垫:LLM的文本生成

5:35

我想先简单铺垫一下LLM的文本生成原理,这样我们就能更容易理解水印的工作方式,也能明白水印其实不是在模型之上额外增加的复杂、昂贵的功能,而只是对常规文本生成流程的一个小调整。

以ChatGPT界面为例看文本生成

6:01

比如我们用ChatGPT的时候,输入问题"德国的首都是",ChatGPT或者其他LLM(这里只是举个例子)会回答"柏林。"。这里它生成了两个token:"柏林"和句号。为了简化,我们假设只生成一个token,也就是"柏林"。这个token是怎么在模型内部生成的呢?

当我们输入"德国的首都是",然后收到"柏林"这个token时,模型背后到底发生了什么?

生成下一个token时发生了什么?

6:41

接下来几张幻灯片,我就简单讲讲生成下一个token时,模型内部的运作过程。

步骤1:将输入文本转换为token ID

6:50

假设我们的提示词是"德国的首都是"。第一步是把它转换成token ID。分词并转换为token ID是最开始的关键步骤之一,这一步是在LLM外部完成的,不属于模型内部操作。我们只是把文本转换成token ID,这是嵌入层能处理的格式。

步骤2:对输入文本分词

7:22

之后,这些token ID会传入LLM,模型会输出下一个token的得分分布。

步骤3:获取下一个token的得分分布

7:31

这里只是LLM内部工作原理的简要概述,我不会展开讲模型的具体结构——这些内容我在其他"零基础"LLM视频和书里讲过很多次了。关键在于,当我们生成下一个token(比如"柏林")时,模型会输出一个得分分布。

这里看到的是logit值,也就是从负无穷到正无穷的原始得分,比如范围大概在-8、-9到20之间。我们可以把它转换成概率分布,但具体要不要转,取决于采样方式。你可以把logit值理解为模型给出的原始得分。

这些原始得分覆盖了整个词汇表。

得分分布覆盖模型的全部词汇

8:39

也就是说,词汇表里的每一个可能的token,模型都会给出一个得分。在这个例子里,词汇表索引19846对应的token得分最高。我把分布展开了,实际运行这个提示词时,你会看到更极端的情况:大部分token的得分都接近0,而"柏林"的得分会高得多。

不过为了让图看起来更直观,我做了放大和展开处理。这里"柏林"得分最高,因为对于"德国的首都是"这个明确的提示词,它是最可能、最合理的下一个token。其他可能的token比如"汉堡"或"慕尼黑",模型可能会给出错误答案,但如今训练良好的LLM应该能非常确定"柏林"才是正确答案。

你看到的是词汇表索引,现在的LLM通常有大约25万个输出token。我这里只截取了19800到19900的范围,因为幻灯片空间有限。如果用真实的25万词汇量,整个分布会非常密集,几乎看不清细节。

所以这只是为了教学目的做的简化。关键在于,常规文本生成过程中,模型会输出这样一个得分分布,接下来我们要从中选出得分最高的token。

步骤4:从得分分布中采样一个token

10:33

后面我会详细讲具体怎么选,其实不一定严格选得分最高的,但为了简化,我们先假设选得分最高的,也就是这里的19846。

步骤5:将采样得到的token还原为文本

10:52

然后把这个token ID还原成文本,就得到了"柏林"。这就是整个流程:从输入提示词,到转换为token ID,再传入LLM,得到得分分布,选出下一个token,最后还原成文本。

将采样得到的token追加到输入,重复生成循环

11:12

之后,这个生成的文本会追加到输入提示词后面。如果问题需要多个输出token,我们就重复这个循环,直到生成完整回答——通常是模型生成一个"文本结束"token。为了简化,这里只展示了生成一个token的过程,但实际会不断循环,把更新后的输入再传给模型,生成下一个token。

那具体怎么采样下一个token呢?

下一个token的采样机制

下一个token是怎么采样出来的?

11:44

我刚才简单说可以选得分最高的,这叫"贪心解码",是一种方法。但大多数LLM实际使用时不会只用贪心解码,因为如果总是选得分最高的token,模型可能会过度依赖训练数据的记忆,每次给出的回答都一样,缺乏变化。

我们其实希望输出有一定变化,但又不能太随机,变成胡言乱语。实际采样时,我们通常会先把得分转换成概率。

将token得分转换为概率

12:28

这里的图展示了得分分布,我用NumPy做示例,不管用什么工具(比如PyTorch),原理都是一样的。假设我们用NumPy存储这些得分,接下来要计算softmax。实际中我们会用PyTorch等框架里实现的softmax函数,它能稳定处理极大、极小的数值,包括很高的正值、很低的正值和绝对值很大的负值。

我这里写出了标准的softmax公式,只是为了让大家更容易理解,具体实现细节不重要。

从概率分布中采样

13:20

关键在于,转换之后,所有得分加起来等于1,也就是做了一次归一化。这就是softmax转换的作用:把原始得分变成概率分布。得到概率后,我们就可以用随机数或随机采样算法来选token了。

比如在NumPy里,我们可以用choice函数,传入词汇表索引,再传入一个随机种子,最重要的是把概率作为权重传入。这些权重代表"某个token被选中的可能性有多大"。比如,如果经过softmax归一化后,"柏林"的概率是99%,其他所有token加起来是1%,那么采样100次的话,99次都会选中"柏林"。

在训练良好的真实LLM中,"柏林"的概率可能会是99.999999%,几乎每次都会选中它,因为模型非常确定这是正确答案。这就是从概率分布中采样的方式。还有一些变体,比如top-k采样或top-p采样:以top-k为例,就是先选出得分最高的100个token,只在这100个里面做随机选择,避免选出无意义的token。

不过这个例子里,这些细节不重要,我就不多说了,大家可以假设已经用top-k选出了前100个token。

重复采样时,"柏林"被选中的次数最多

15:37

举个例子,如果"柏林"的概率是99.9%,我们采样10000次,会有9997次选中"柏林",2次选中"Hal",1次选中"Moh"——这两个都是无意义的token。这种情况很少发生,因为我为了让图更直观,特意把得分分布展开了。

真实的LLM可能10000次都会选中"柏林",因为它的概率实在太高了。这里只是为了演示。

从采样到水印生成

Anthropic对Claude文本水印的说明

16:21

刚才我们简要讲了LLM的底层工作原理,这本身就是个很有趣的概念,但我之前讲过很多次了,就不啰嗦了。我只是想先铺垫一下,方便大家理解水印的工作方式。

无水印时,随机采样可能选"overcast"或"grey"

16:41

我们提到过,采样时可以选得分最高的token,或者用概率采样,这样得分高的token被选中的概率最大。这里再举一个无水印的例子,我把提示词改了一下:"今天天气很冷,",接下来可能的回答是"灰蒙蒙的(gray)"或者"阴天(overcast)"。和"柏林"的例子不同,"gray"和"overcast"在这里是可以互换的,都是合理的下一个token,没有客观上的优劣之分。

因为它们的得分都很高,而且相差不大,所以随机采样时,可能会选中其中一个。重复采样多次的话,选中"overcast"和"gray"的概率差不多各占一半。这就是为什么同一个提示词,LLM每次给出的回答可能略有不同:在某些位置,有几个token的可能性相近,模型会随机选一个,而这个选择会影响后续所有token的生成。

随机种子与确定性采样

随机种子提升可重复性

18:25

我想简单讲一下随机数生成。比如我们用随机数生成器,它会生成一串随机数,每次运行生成的序列都不一样——你看,每次生成的5个数都不同。但如果我们设置一个随机种子,比如1、2、3,每次运行生成的随机数就会完全一样。

这些数依然是随机的,但序列是可重复的。不管有没有随机种子,生成的都是随机数,但设置种子后,得到的是可复现的随机序列。记住这个概念,后面会用到。

随机种子42始终选中"overcast"

19:26

比如刚才的例子,随机采样可能选中"gray"或"overcast",但如果我们设置特定的随机种子,比如42,每次都会选中"overcast"。这依然是随机采样,但结果是确定的——给定这个提示词,模型每次都会选"overcast"。

随机种子99始终选中"grey"

19:49

如果换一个随机种子,模型可能每次都会选中"gray"。这还是随机采样,但基于随机种子实现了确定性。

水印密钥的作用

水印技术从密钥和token上下文生成随机种子

20:04

Claude的水印技术,本质上就是设置一个随机种子,但这个种子不是人为指定的固定数字,而是通过一个类似API密钥的"秘密密钥",结合前面四个token的上下文信息生成的。

核心思路和刚才的例子一样:固定随机种子,就能让模型每次都选中同一个下一个token。区别在于,这里不是用99这样的固定种子,而是用秘密密钥和前文token信息来生成种子。具体细节我们后面讲。

无水印时,采样可生成多种合理文本

21:06

水印技术的作用,就是让文本生成在某些位置更具确定性。比如左边这些合理的文本示例:

今天天气很冷,

接下来可以选"overcast"或"gray";下一句里,

一阵"轻柔的(light)"或"温和的(gentle)"

这两个词也可以互换;

微风正在"穿过(moving)"或"吹过(blowing)"树林,街道看起来"安静(quiet)"或"静谧(still)"。

这里"quiet"和"still"也是等价的。文本中这类token选择的位置,几个选项的可能性几乎相等,就像我们之前看到的那样。

如果不加水印,输入这个提示词后,LLM可能生成不同的回答。根据这类可选位置的数量,可能有128种不同的组合。文本越长,这类可互换的位置越多,可能的输出文本就越多。

比如一种可能的输出是:

今天天气很冷,阴沉沉的。一阵轻柔的微风穿过树林,街道看起来安安静静的。我想我会待在家里,就着一杯茶读本书。

另一种可能是:

今天天气很冷,灰蒙蒙的。一阵温和的微风吹过树林,街道看起来静谧无声。我想我会待在屋里,就着一杯茶读本小说。对了,外面其实还在下雨。我不知道这个麦克风效果怎么样,但背景音还挺应景的。

关键在于,这些都是合理的文本,没有优劣之分,只是略有不同。如果不加水印,随机采样会生成其中任意一种。

固定随机种子可复现某一种合理文本

23:31

如果我们固定随机种子,比如设为99,每次都会生成同一种文本。用随机种子可以固定输出结果——随机采样的本质没变,但结果变得可复现,每次都一样。这还是无水印的情况,只是用了固定种子。

加水印后,密钥控制生成哪一种合理文本

23:59

而水印技术本质上也是一样的,只是不用简单的随机种子,而是用所谓的"随机密钥"来决定生成哪一种文本。Claude的博客文章里提到,水印不会降低文本质量,从这个机制来看确实说得通。

声明一下,我不是在为水印辩护,只是客观解释原理,大家别迁怒于我。我想说的是,对终端用户而言,水印技术其实就相当于固定随机种子,让采样过程变得确定。

水印的添加位置

有无水印的生成流程对比

24:47

总结一下:无水印时,我们通常不使用随机种子(我知道大多数人都不会特意设置,而且说实话,Claude和OpenAI的API可能也不支持设置)。我在Ollama上试过固定种子,但有时还是无法完全确定,可能和软件版本有关,情况因人而异。总之,无水印时是完全随机的采样;而右边的水印流程中,依然是随机采样,但多了一个水印密钥,它会传给随机种子生成器,设置一个特定的种子,让采样过程变得确定。

这两者本质很相似,而"从零基础理解"的好处在这里就体现出来了:我们现在知道水印是加在哪个环节了——它是在采样阶段添加的,而不是在LLM内部。这很有意思,意味着他们不需要重新训练模型,只用在现有模型的采样环节做修改,不用重新训练任何东西。

水印的检测机制

水印检测需要密钥

26:21

不过我们还没讲完,我想再说说怎么判断一段文本是否带有水印。只有持有密钥的人才能检测水印。比如,假设你在网上看到一段文本(比如这里的第4段),想知道它是否带水印,你是无法判断的——因为要检测水印,你需要水印密钥和对应的评分函数,用函数对文本打分,得分超过阈值就说明带水印,否则就没有。但终端用户没有这个密钥,只有Anthropic才有。

不过他们在博客里提到,会开发一个API来提供检测功能,具体细节我不清楚,毕竟我和他们没有关联,只是看了博客文章。这个API可能只对某些公司开放,比如X或Substack Notes,方便他们标记AI生成的帖子;也可能对终端用户开放,谁知道呢,我们拭目以待。但核心点是:只有持有水印密钥,或者使用他们开发的API,才能检测水印。

如何移除水印

编辑水印位置即可移除水印

28:03

说说移除水印的方法,这也很有意思。既然我们知道了水印的工作原理,也就知道了它的弱点:水印高度依赖特定位置的特定token。比如在这段文本中,如果这些彩色标记的token是水印位置,那么修改这些位置的词,就能100%移除水印。

但问题是,我们不知道哪些位置是水印位置。

实际操作中,需要编辑多个位置才能移除水印

28:41

因为我们没有参与文本生成,不知道哪些位置加了水印。实际操作中,我们只能随机修改文本,希望能改到足够多的水印位置,从而移除水印。而且我们也不知道哪些token是高分选项——要知道这一点,得用LLM重新运行提示词才行,所以我们只能靠猜。

比如,我们可能把"overcast"改成"cloudy",但不知道原来的高分选项是"gray"。有些情况可能凭直觉能猜到,但很多时候不行。我这里想说明的是,我们只能随机修改文本,猜测哪些是水印位置。

既然不知道具体位置,我们就只能到处改几个词,如果改的数量足够多,就能破坏水印。

水印评分函数的原理

附加内容:评分函数的工作原理

29:59

以上就是水印技术的核心内容。我之前提到过,检测水印需要用到评分函数,这里作为附加内容,我简单讲一下它的原理——虽然有点复杂,而且不是理解水印的必备知识,但了解一下也挺有意思。

他们之所以用这种评分函数,是为了降低检测成本。否则的话,要检测一段文本是否带水印,就得重新用LLM运行提示词,得到得分分布,再用水印随机种子生成对应文本,然后进行比对。这成本太高了,而且很多时候我们甚至不知道原始提示词是什么。

所以他们用了一个技巧,修改了采样过程,这样后续检测时就不需要再调用LLM了。博客里提到,这个方法源自一篇《自然》期刊的论文,叫做SynthID-Text,是谷歌一两年前提出的技术。Claude的水印技术应该就参考了这个方法,不过具体是不是完全一样,我就不清楚了。

SynthID文本与锦标赛采样

为低成本检测设计的改良采样流程

31:39

具体怎么实现呢?之前我们讲过常规流程:输入文本,传入LLM,得到logit分布,采样得到输出token,采样过程中会用到水印密钥和随机种子生成器。这个流程是对的,但token采样的细节比这更复杂一点。

他们用的不是NumPy的random.choice,而是更复杂的方法。

可能的下一个token及其概率

32:16

假设上下文是"今天天气很冷,",要生成下一个token,可能的选项有"gray""overcast""gloomy""cloudy",对应的概率分别是50%、30%、15%、5%,其他token的概率接近0。我这里复用了之前的图,你可以把它想象成只有这四个词的小词汇表,这样更简单。

像之前说的,我们可以用NumPy的random.choice结合这些概率来采样下一个token。

加权随机采样可选中下一个token

33:13

我们也可以用水印密钥和随机种子生成器让采样结果确定,从而添加想要的水印。但这样做的问题是,后续检测网上的随机文本时成本很高——采样本身不贵,但检测成本太高。

锦标赛采样替代普通加权随机采样

33:35

所以他们在生成阶段就用了一种特殊的采样方法,方便后续检测使用,这种方法叫做"锦标赛采样"。它不是random.choice那样的简单采样,听起来有点复杂,但其实没那么难理解。

你可能需要暂停视频,仔细看看图,但掌握了之后就会发现其实很简单。我来试着解释一下:我们还是有上下文,以及各个可能的下一个token和对应的概率。

他们用到了"随机水印函数"。

随机水印函数

随机水印函数为"grey"分配比特签名

34:35

这里有三个水印函数G1、G2、G3,实际中可能有30个、50个甚至更多,我这里只用三个,方便在幻灯片上展示。以"gray"为例,它的签名是101——意思是,用水印密钥生成随机种子后,把"gray"(准确说是结合前文的"cold"和"gray")输入G1,得到值1;输入G2,得到值0;输入G3,得到值1。

这个函数是随机的,要么返回0,要么返回1,具体值由水印密钥和token决定。如果有30个这样的函数,就能生成一串很长的0和1组成的比特串。

随机水印函数为每个候选token分配比特签名

36:00

这就是"gray"的签名101。我们可以对所有其他token做同样的操作:"overcast"的签名是010,"gloomy"是001,"cloudy"是100。接下来就是"锦标赛采样"环节,把这些token两两配对。

锦标赛采样的步骤

锦标赛采样的候选token配对

36:39

就像足球淘汰赛或美式橄榄球季后赛一样,两个"队伍"(这里是token)对决,胜负由水印函数的输出决定。第一轮用第一个函数G1:

  • "cloudy"对"gray":G1输出都是1,平局;平局时用水印密钥和随机种子随机选一个,这里"cloudy"晋级。
  • "overcast"对"gray":G1输出分别是0和1,"gray"得分更高,晋级。
  • "gloomy"对"overcast":G1输出都是0,平局,随机选中"overcast"晋级。
  • "gray"对"gray":G1输出都是1,平局,随机选中"gray"晋级。

现在晋级的是"cloudy""gray""overcast""gray",进入下一轮,用第二个函数G2:

锦标赛采样首轮对决及胜者

38:24

  • "cloudy"对"gray":G2输出都是0,平局,随机选中"gray"晋级。
  • "overcast"对"gray":G2输出分别是1和0,"overcast"晋级。

现在决赛是"gray"对"overcast",用第三个函数G3:G3输出分别是1和0,"gray"获胜,最终被选中作为下一个token。

水印密钥在这里起什么作用呢?回到之前的幻灯片,它用来生成这些水印函数的输出值,决定每个阶段的结果。没有密钥,生成的签名就会不一样,所以密钥依然至关重要。

无需重新运行LLM即可检测水印

锦标赛采样完整流程(遍历所有水印函数)

39:11

这样我们就完成了token采样。这就是改良后的采样流程,我们本可以用NumPy的random.choice,但那样的话,检测网上的随机文本时就必须重新运行LLM。而用这种方法,就不需要了——我马上演示给你看。

这种方法听起来怪异又繁琐,但好处是检测随机文本时更简单、成本更低,不需要调用LLM。

锦标赛采样主要是为了降低检测成本

39:43

生成完成后,用水印函数对采样文本打分

39:48

比如,假设我们在网上看到一段新文本:"今天天气很冷,灰蒙蒙的(gray)",想知道它是不是LLM生成的。Anthropic持有水印密钥和G1、G2、G3这些函数,他们会把文本输入这些函数,针对"gray"这个位置,得到和生成时一样的签名101。

简单起见,我们把这些比特加起来,得到2。如果这个位置是"overcast",得分就是1;"gloomy"和"cloudy"的得分也都是1。我这里只看最后一个位置,如果对所有位置都这样计算,每个位置会得到不同的分数:比如第一个位置得分2,"today"得分3,"is"得分2,"cold"得分2,"gray"得分3。

单段生成文本的平均水印比特数

41:33

这些水印函数的计算成本很低,可以快速遍历整个文本得到所有位置的得分,然后计算平均分——比如这里算出来是2.23。

两段生成文本的平均水印得分对比

41:55

如果是另一段文本,比如把"today"换成"now","gray"换成"overcast",这两个位置的得分就都是1,整个文本的平均分就是1.71。这个过程不需要LLM,只需要水印密钥、随机种子生成器和G1到Gn这些函数。

然后我们设置一个阈值来判断。

用阈值判断文本是否带水印

42:27

当然,实际用的不是这个阈值,但举个例子:如果平均分大于2,就认为文本带水印;小于2则不带。这里第一个文本得分2.23,大于2,说明带水印;第二个得分1.71,小于2,说明不带水印。

这就是检测网上随机文本是否带水印的方法:用水印函数打分,计算平均分,再和阈值比较。

再次提醒:锦标赛采样主要是为了降低检测成本

43:13

再强调一次,锦标赛采样主要是为了让检测更简单、成本更低。我们也可以用NumPy的random.choice加随机种子来实现确定性采样,但那样检测网上的文本就会很困难。

水印技术总结与局限性

有无水印的生成流程对比总结

43:30

总结一下:无水印和有水印的核心区别,就是采样过程是否由水印密钥控制,而水印采样内部用的是锦标赛采样。检测水印需要秘密密钥和G1到Gn这些水印函数。

检测需要秘密密钥和水印函数

43:54

再说说移除水印,这可能是有些人关心的问题:理想情况下,要编辑所有水印位置,但我们不知道哪些是水印位置。而且模型只会在有多个高可能性token的位置添加水印,像"trees"这种没有合适替代词的位置,不会加水印。

所以水印只加在特定位置,而我们不知道这些位置在哪里,要移除水印的话……

理想情况下,移除水印需要编辑所有水印位置

44:29

……就得修改文本中的多个位置。这对AI生成文本的未来意味着什么呢?我觉得……

这对AI生成文本意味着什么

实际操作中,移除水印需要编辑多个猜测的位置

44:36

……这可能会导致AI生成文本的质量下降。比如有些新闻网站喜欢用AI生成新闻稿,我觉得水印技术不一定能阻止他们——他们还是会用AI生成文本,因为这已经是工作流程的一部分。我猜他们会换个思路:用另一个模型来编辑文本,生成"经过编辑的AI文本",这样就可能不带水印了。

为什么用本地模型?因为我觉得所有闭源LLM提供商,不止Claude,还有谷歌(毕竟SynthID是谷歌的论文),我猜Gemini也会加水印;OpenAI可能已经在做,或者很快会跟进。当然这只是我的猜测,但考虑到欧盟的相关法规要求(Anthropic博客里说这是他们加水印的原因),大家应该都会这么做。而本地模型目前可能还没有实现水印功能。

所以人们可能会先用Claude这类高端模型生成文本,再用本地模型做修改,去掉水印。为什么不直接用本地模型生成?因为在我看来,编辑文本比生成文本简单。生成复杂文本时,你可以用最昂贵的高端Claude模型,然后用更便宜的本地模型做针对性修改。这可能就是未来的趋势。

为什么说质量会下降?因为如果只是为了移除水印而随机修改文本,可能会让文本变得生硬。最终得到的还是AI生成文本,但可能会有点别扭。

最终思考

本地模型可编辑Claude输出以移除水印

47:20

不过我的目标只是解释水印的工作原理,不是讨论它的全球影响。希望这次底层原理的讲解对大家有用。水印技术没有看起来那么复杂,但还是花了52页幻灯片,说明也不是特别简单。希望你们觉得这段小讲座有用,我们下次再见。

附:如果你喜欢这种风格的讲解,我不常更新YouTube,但多年来已经积累了300多个视频,你可以在我的YouTube频道找到。