大模型水印——红绿水印
(不是随便设计的),输入“gk + context”后,会按固定步骤计算,输出唯一的结果(即绿列表 Gᵢ 的划分依据)。
红绿水印
红绿水印(Green-Red Watermarking)是当前最简单、最可实施的GenAI文本水印方案。本文从密钥生成、公式推导、检测算法、完整案例四个维度,帮你完全掌握这种方案的工作逻辑——这也是理解新一代高鲁棒性文本水印(如PRC、不可检测水印)的基础。
1. 红绿水印
1.1 从研究角度
- 概念清晰:用"红绿灯"比喻,避免了复杂的密码学记号,是理解水印的最快入门。
- 基础性:它是后续高阶方案(不可检测水印、伪随机纠错码水印)的逻辑基础。
- 完整性:涵盖"密钥、生成、检测、评估"的全链路。
1.2 从产业角度
- 可实施性强:无需修改模型架构,只在解码层干预,当前已被DeepMind SynthID等商业方案部分采用。
- 成本低:计算开销最小(仅在生成每个token时做一次PRF计算和logits偏置)。
- 可审计:逻辑透明,便于监管机构或第三方验证。
1.3 理解其局限,才能把握升级方向
- 有失真(会改变模型输出分布);
- 抗攻击性较弱(同义词替换可破坏水印)。
后续的方案(如Gumbel、PRC)都在试图克服这些问题,学会红绿水印,你就能看懂为什么它们要这样做。
2. 关键概念讲解
2.1 PRF(gk, contextᵢ):伪随机函数是什么?
- PRF:全称是 Pseudorandom Function(伪随机函数)。
- 作用:它就像一个“带锁的随机数生成器”。只要输入相同的密钥(gk)和上下文(contextᵢ),它就会输出完全相同的结果;如果输入不同,输出就像真随机数一样不可预测。
- 在红绿水印里的作用:
- 它接收两个输入:
gk:水印的生成密钥,只有合法的模型所有者知道。contextᵢ:生成第i个 token 时,前面已经生成的k个 token(即上下文)。
- 它的输出
Gᵢ是一个词汇表的子集,也就是我们说的“绿列表”。 - 因为 PRF 是确定性的,所以只要密钥 gk 相同,对于相同的上下文,绿列表 Gᵢ 就完全相同。这是检测水印的关键。
- 它接收两个输入:
2.2 Gᵢ 和 Rᵢ:红绿列表是什么?
- Gᵢ:在第
i个位置,根据 PRF 划分出的"绿列表",是词汇表V的一个子集。 - Rᵢ:“红列表”,就是词汇表中不在绿列表里的所有 token,即
Rᵢ = V \ Gᵢ。 - 直观理解:在生成每个词之前,模型都会根据前面的上下文和密钥,临时决定"哪些词是’幸运词’(绿列表),哪些是’普通词’(红列表)"。
2.3 lᵢ(v):模型的 logits 是什么?
- lᵢ(v):在第
i个位置,模型对词汇表中每个 tokenv输出的原始对数几率(logits)。 - 含义:它是一个未归一化的概率值,代表模型认为下一个词是
v的"倾向性"。值越大,模型越倾向于生成这个词。 - 例子:如果模型在"我今天去"之后,
lᵢ("超市") = 5.2,lᵢ("公园") = 3.1,说明模型更倾向于生成"超市"。
3. 生成密钥与PRF计算
3.1 gk(生成密钥)的来源与规范
gk 是人为规定/生成的密钥,但不是随便填个数字就行,需要遵循“安全密钥生成规范”,核心目的是确保密钥的“随机性”和“唯一性”——避免被攻击者猜到或破解。
3.1.1 谁来规定/生成gk?
- 通常是水印方案的设计者/模型提供商(比如谷歌、OpenAI 这类公司,或研究人员);
- 比如红绿水印的提出者(Kirchenbauer et al. 2023)在实验中,会自己生成 gk;如果是工业界落地(如谷歌 SynthID),gk 会由公司的安全团队按标准流程生成。
3.1.2 gk 的规定/生成规则(核心是“随机+足够长”)
- 长度要求:必须足够长(通常 ≥128 位,工业界常用 256 位),比如 gk 可以是一串 256 位的二进制数(01 组合),或对应的十六进制字符串(如
0x7a9f...3d8b); - 随机性要求:必须是“ cryptographically secure random ”(密码学安全的随机数),不能用简单的“时间戳+随机数”生成(容易被预测),要通过专门的随机数生成器(如 Python 的
secrets模块、OpenSSL 的随机数生成接口); - 格式要求:通常是字节串(byte string)或整数,具体格式由 PRF 函数的要求决定(比如 PRF 要求输入 32 字节的密钥,gk 就生成 32 字节的随机字节串)。
3.1.3 例子:gk 长什么样?
- 256 位二进制 gk(简化版):
10110010...01101001(共 256 个 0/1); - 对应的十六进制 gk(更易存储):
0xb27f3d...69a8(64 个十六进制字符,1 个十六进制字符=4 位二进制); - 实际使用中,gk 会被存储为文件(如
.env文件中的CHATGPT_API_KEY格式),或通过安全密钥管理系统(如 AWS KMS)存储。
3.2 PRF 如何计算 gk 和 context:固定算法+密钥绑定,结果完全确定
PRF(伪随机函数)是预先定义好的标准算法(不是随便设计的),输入“gk + context”后,会按固定步骤计算,输出唯一的结果(即绿列表 Gᵢ 的划分依据)。
3.2.1 第一步:明确 PRF 的具体算法(红绿水印常用的是 HMAC 类 PRF)
红绿水印的论文中,PRF 通常采用 HMAC(哈希消息认证码) 算法(如 HMAC-SHA256)——这是密码学中常用的“密钥相关哈希函数”,满足 PRF 的核心要求:相同输入必出相同输出,不同输入输出随机无规律。
其他常用的 PRF 算法还包括 AES-CBC-MAC、Blake2b 等,但红绿水印因实现简单,优先用 HMAC 类。
3.2.2 第二步:对 input 做预处理(gk + context 转为 PRF 能处理的格式)
PRF 的输入必须是“字节串”,所以需要把 context(前 k 个 token 的序列)转为字节串,步骤如下:
- 假设 context 是 token 序列
[v₁, v₂, ..., vₖ](如["我", "今天", "去"]); - 先把每个 token 转为对应的编码(如 UTF-8 编码,“我”→
0xe68891); - 再把所有 token 的编码拼接起来,得到 context 的字节串
ctx_bytes = b"\xe68891\xe4\xbb\x8a\xe5\xa4\xa9\xe5\x8e\xbb"; - gk 本身已是字节串(如 32 字节的
b'\x7a\x9f...\x3d\x8b')。
3.2.3 第三步:PRF 计算的核心步骤(以 HMAC-SHA256 为例)
HMAC 的计算逻辑是“密钥+消息→哈希值”,具体公式(简化版):
PRF(gk,context)=HMAC-SHA256(gk,ctxbytes) \text{PRF}(gk, context) = \text{HMAC-SHA256}(gk, ctx_bytes) PRF(gk,context)=HMAC-SHA256(gk,ctxbytes)
详细步骤:
- 用 gk 对 HMAC 的内部密钥进行处理(按 HMAC 标准,将 gk 扩展为 64 字节,与固定常量异或);
- 把处理后的密钥与 ctx_bytes(context 的字节串)拼接,计算 SHA256 哈希值;
- 再用处理后的密钥与第一步的哈希值拼接,再次计算 SHA256 哈希值;
- 最终得到的 32 字节哈希值(如
0x8f3d...a729),就是 PRF 的输出。
3.2.4 第四步:将 PRF 输出转为绿列表 Gᵢ(红绿水印的关键映射)
PRF 输出的是哈希值(一串随机字节),需要将其映射为“词汇表 V 的子集”(即 Gᵢ),常用方法是:
- 对词汇表 V 中的每个 token v,计算其哈希值
hash(v)(如 SHA256(v 的 UTF-8 编码)); - 取 PRF 输出的前 n 位(如 1 位)作为“判定位”;
- 取
hash(v)的前 n 位,与 PRF 的判定位做“异或运算”(XOR); - 若结果为 0,则 v 属于 Gᵢ(绿列表);若为 1,则属于 Rᵢ(红列表)。
3.2.5 具体例子(简化版):
- 词汇表 V = {A, B, C, D},每个 token 的 UTF-8 编码:A→
0x41,B→0x42,C→0x43,D→0x44; - gk =
0xb27f...69a8(32 字节),context = [A, B](ctx_bytes =0x4142); - PRF(gk, ctx_bytes) = HMAC-SHA256(gk, 0x4142) → 输出 32 字节哈希值
0x8f3d...a729; - 取 PRF 输出的第 1 位(二进制):假设是
0; - 对每个 token 计算:
- A:hash(A)=SHA256(0x41) → 前 1 位=1 → 1 XOR 0 = 0 → 属于 Gᵢ;
- B:hash(B)=SHA256(0x42) → 前 1 位=0 → 0 XOR 0 = 1 → 属于 Rᵢ;
- C:hash©=SHA256(0x43) → 前 1 位=0 → 0 XOR 0 = 1 → 属于 Rᵢ;
- D:hash(D)=SHA256(0x44) → 前 1 位=1 → 1 XOR 0 = 0 → 属于 Gᵢ;
- 最终 Gᵢ = {A, D},Rᵢ = {B, C}。
3.3 核心要点
gk 的生成和 PRF 的计算是保证水印可靠的两大基石:
- gk 的来源:人为按"密码学安全标准"生成(足够长+足够随机),由水印设计者/模型提供商管理;
- PRF 的计算逻辑:算法固定(如 HMAC-SHA256),输入"gk+context",输出确定的绿列表 Gᵢ;
- 核心特点:相同 gk + 相同 context → 必然得到相同 Gᵢ,这正是嵌入和检测一致性的保证。
4. 生成阶段:如何嵌入水印
4.1 红绿划分公式
Gi=PRF(gk,contexti),Ri=V∖Gi G_i = \text{PRF}(gk, \text{context}_i), \quad R_i = V \setminus G_i Gi=PRF(gk,contexti),Ri=V∖Gi
- 含义:
- 对于第
i个位置,使用 PRF 函数,根据密钥gk和前面的上下文contextᵢ,生成一个绿列表Gᵢ。 - 红列表
Rᵢ就是词汇表V中所有不在Gᵢ里的词。
- 对于第
- 为什么这么做?:
- 这样做可以让绿列表的划分依赖于上下文,而不是固定不变的。这使得水印更难被攻击者通过简单的统计分析破解。
4.2 偏置(Bias)公式
l~i(v)={li(v)+δ若 v∈Gili(v)若 v∈Ri \tilde{l}_i(v) = \begin{cases} l_i(v) + \delta & \text{若 } v \in G_i \\ l_i(v) & \text{若 } v \in R_i \end{cases} l~i(v)={li(v)+δli(v)若 v∈Gi若 v∈Ri
- 含义:
- 对绿列表
Gᵢ中的每个词v,在其原始 logitslᵢ(v)的基础上,加上一个正的偏置值 δ(比如 δ=0.5)。 - 对红列表
Rᵢ中的词,保持原始 logits 不变。
- 对绿列表
- 效果:
- 加上偏置后,绿列表中词的 logits 变大了,模型在采样时,就会更倾向于选择绿列表中的词。
- 这就人为地提高了绿 token 在生成文本中的出现频率。
5. 检测阶段:如何验证水印
5.1 z 统计量公式
z=∣s∣G−γTTγ(1−γ) z = \frac{|s|_G - \gamma T}{\sqrt{T \gamma (1-\gamma)}} z=Tγ(1−γ)∣s∣G−γT
这个公式是整个水印检测的核心,我们把它拆开来看:
-
分子部分:
|s|_G - γT|s|_G:在待检测文本s中,统计出来的绿 token 总数。γT:在没有水印的情况下,这段文本中绿 token 的期望数量。γ:无水印时,绿 token 出现的概率,因为 PRF 是伪随机的,所以γ理论上接近 0.5。T:文本的总长度(token 数)。
- 含义:这个差值代表了“实际绿 token 数量”与“随机情况下的期望数量”之间的偏差。如果水印存在,这个偏差会是一个很大的正数。
-
分母部分:
√(T γ (1-γ))- 这是统计学中二项分布的标准差。
- 它衡量了在随机情况下,绿 token 数量
|s|_G围绕其期望值γT波动的幅度。
-
整体 z 值的含义:
z是一个标准化的偏差值,它告诉我们:实际观察到的绿 token 数量,比随机情况下的期望值“高出了多少个标准差”。- 如果
z值很大(比如大于 4 或 5),就说明绿 token 数量的偏高,极不可能是随机巧合,而是由人为干预(水印)造成的。
5.2 检测判定规则
z>zα z > z_\alpha z>zα
z_α:是一个预先设定的阈值,它对应着统计学中的显著性水平α(比如 α=0.001)。- 含义:
- 如果计算出的
z值大于z_α,我们就拒绝“这段文本是无水印的”这个零假设,判定它是带水印的。 - 这个阈值确保了假阳性率(把人类写的文本误判为带水印)被控制在极低的水平(如 0.1%)。
- 如果计算出的
6. 案例
假设我们有一个词汇表 V = {A, B, C, D},密钥 gk,上下文 contextᵢ = "我":
-
生成阶段:
- PRF(gk, “我”) 输出绿列表
Gᵢ = {A, C},红列表Rᵢ = {B, D}。 - 模型原始 logits:
lᵢ(A)=2,lᵢ(B)=3,lᵢ(C)=1,lᵢ(D)=4。 - 加上偏置 δ=1 后:
l̃ᵢ(A)=3,l̃ᵢ(B)=3,l̃ᵢ(C)=2,l̃ᵢ(D)=4。 - 模型从新的 logits 中采样,更可能选到绿列表中的 A 或 C。
- PRF(gk, “我”) 输出绿列表
-
检测阶段:
- 拿到一段文本
s = "A C A B",长度 T=4。 - 用相同的 gk 和 PRF,逐个位置判断每个 token 是否为绿 token:A(绿), C(绿), A(绿), B(红)。
- 统计
|s|_G = 3。 - 假设 γ=0.5,期望数量
γT = 2,标准差√(4*0.5*0.5) = 1。 - 计算 z = (3 - 2) / 1 = 1。这个 z 值太小,不足以判定为水印。如果文本更长,比如有 100 个 token,其中 65 个是绿 token,z 值就会变得很大,从而被检测出来。
- 拿到一段文本
7. 属性评估
基于 SoK 论文的五大评估维度,红绿水印的现状如下:
| 属性 | 评估 | 详解 |
|---|---|---|
| 质量保持 | ⭐⭐⭐ (低失真) | 因为加偏置,会改变模型的输出分布,实证失真度约 0.01~0.05 |
| 低假阳性率 | ⭐⭐⭐⭐⭐ (优秀) | 通过 z 统计量和高显著性阈值控制,误判率可达 0.1% 以下 |
| 鲁棒性 | ⭐⭐⭐ (中等) | 抵御基础编辑(删节、改写)能力有限,对同义词替换很敏感 |
| 不可伪造性 | ⭐⭐⭐⭐ (强) | 攻击者无生成密钥时,难以伪造带水印文本 |
| 计算效率 | ⭐⭐⭐⭐⭐ (极优) | 仅需在生成每个 token 时做 PRF+偏置操作,开销极低 |
总体定位:一个"快速、可靠、但易被攻击者破坏"的早期实用方案。
更多推荐


所有评论(0)