浮水印與 AI 生成文字偵測
專家5 分鐘閱讀更新於 2026-03-13
LLM 輸出的統計浮水印方案、AI 生成文字偵測器、其密碼學基礎,以及規避或移除浮水印的系統化技術。
浮水印與 AI 生成文字偵測代表防禦方維持模型輸出來源可溯的嘗試。對紅隊而言,理解這些機制至關重要——既用以評估其穩健性,亦用以評估建立在浮水印存在之上的下游安全假設是否合理。
浮水印方案分類
| 方案類型 | 機制 | 穩健性 | 品質影響 | 偵測複雜度 |
|---|---|---|---|---|
| 符元層級 (Kirchenbauer 等人) | 每個符元位置的綠/紅清單切分 | 中等——易受改寫攻擊 | 中等偏倚(delta ~1-2)時影響低 | 使用秘鑰的 O(n) |
| 分布移位 | 跨完整輸出分布的細微偏倚 | 較高——可抵擋輕微編輯 | 非常低 | 需要統計檢定 |
| 語意浮水印 | 將訊號嵌入意義而非特定符元 | 最高——可抵擋改寫 | 中等 | 需要嵌入模型 |
| 多位元 | 於浮水印中編碼載荷(使用者 ID、時間戳) | 不定 | 中等——位元愈多失真愈多 | 需要金鑰 + 解碼器 |
| 無偏 (Christ 等人) | 完美保留輸出分布 | 高度理論保證 | 無(可證明無偏) | 需要完整金鑰 |
符元層級浮水印的運作方式
部署最廣的方案(基於 Kirchenbauer 等人 2023)於推論期間運作:
import hashlib
import numpy as np
class WatermarkLogitsProcessor:
"""Simplified watermark injection during LLM inference."""
def __init__(self, secret_key: bytes, gamma: float = 0.5, delta: float = 2.0):
self.secret_key = secret_key
self.gamma = gamma # fraction of vocab in green list
self.delta = delta # logit bias added to green-list tokens
def get_green_list(self, prev_token_id: int, vocab_size: int) -> set:
"""Deterministically partition vocab into green/red lists."""
seed = hashlib.sha256(
self.secret_key + prev_token_id.to_bytes(4, "big")
).digest()
rng = np.random.RandomState(
int.from_bytes(seed[:4], "big")
)
green_count = int(vocab_size * self.gamma)
green_list = set(rng.choice(vocab_size, green_count, replace=False))
return green_list
def __call__(self, prev_token_id: int, logits: np.ndarray) -> np.ndarray:
"""Add delta bias to green-list token logits."""
green_list = self.get_green_list(prev_token_id, len(logits))
modified = logits.copy()
for token_id in green_list:
modified[token_id] += self.delta
return modified偵測演算法
from scipy import stats
def detect_watermark(
text_token_ids: list[int],
secret_key: bytes,
vocab_size: int,
gamma: float = 0.5,
) -> dict:
"""Test whether text contains a statistical watermark."""
green_count = 0
total = len(text_token_ids) - 1 # skip first token
for i in range(1, len(text_token_ids)):
prev_id = text_token_ids[i - 1]
green_list = get_green_list(prev_id, vocab_size, secret_key, gamma)
if text_token_ids[i] in green_list:
green_count += 1
z_score = (green_count - gamma * total) / np.sqrt(total * gamma * (1 - gamma))
p_value = 1 - stats.norm.cdf(z_score)
return {
"green_fraction": green_count / total,
"z_score": z_score,
"p_value": p_value,
"watermarked": z_score > 4.0,
}AI 生成文字偵測(非浮水印)
除浮水印之外,統計偵測器嘗試在不需生成模型合作的情況下識別 AI 生成文字。
偵測器類別
| 偵測器類型 | 方法 | 優勢 | 弱點 |
|---|---|---|---|
| 基於困惑度 | AI 文字在參考模型下困惑度較低 | 簡單,無需訓練 | 對公式化人類文字誤報率高 |
| 訓練過的分類器 | 以人類 vs. AI 文字對訓練的 ML 模型 | 可捕捉微妙分布模式 | 對領域轉移、新模型脆弱 |
| 零樣本 (DetectGPT) | 基於擾動:AI 文字位於對數機率空間的局部曲率最大值 | 不需訓練資料 | 運算昂貴,對短文字較不可靠 |
| 文體測量 | 分析寫作風格特徵(句長變異、詞彙豐富度) | 與模型無關 | 易受風格轉換擊敗 |
DetectGPT 機制
def detect_gpt_score(
text: str,
scoring_model,
mask_model,
n_perturbations: int = 100,
) -> float:
"""
DetectGPT: AI text sits at local maxima of log-probability.
Perturbations should decrease log-prob for AI text,
but have random effect on human text.
"""
original_ll = scoring_model.log_likelihood(text)
perturbation_lls = []
for _ in range(n_perturbations):
perturbed = mask_and_fill(text, mask_model)
perturbation_lls.append(scoring_model.log_likelihood(perturbed))
mean_perturbed_ll = np.mean(perturbation_lls)
std_perturbed_ll = np.std(perturbation_lls)
score = (original_ll - mean_perturbed_ll) / std_perturbed_ll
return score # high score -> likely AI-generated紅隊規避技術
浮水印移除
最有效的通用攻擊。以第二個(無浮水印)模型改寫加浮水印輸出,破壞符元層級統計訊號同時保留意義。
def paraphrase_attack(watermarked_text: str, paraphraser) -> str:
"""Use a separate model to remove watermark via paraphrasing."""
prompt = f"""Rewrite the following text to convey the same meaning
using different words and sentence structures. Preserve all
factual content but change the phrasing completely.
Text: {watermarked_text}
Rewritten:"""
return paraphraser.generate(prompt)有效性:以 >95% 成功率移除符元層級浮水印。語意浮水印更具抵抗力。
以足以打破綠色清單偏倚的比率系統化將符元替換為同義字,而不改變意義。
def synonym_substitution_attack(
text: str,
substitution_rate: float = 0.25,
synonym_dict: dict = None,
) -> str:
"""Replace ~25% of content words with synonyms."""
words = text.split()
for i, word in enumerate(words):
if random.random() < substitution_rate and word.lower() in synonym_dict:
words[i] = random.choice(synonym_dict[word.lower()])
return " ".join(words)在符元間插入零寬字元或同形字以破壞基於前置符元的綠色清單運算。
ZERO_WIDTH_CHARS = ["\u200b", "\u200c", "\u200d", "\ufeff"]
def unicode_injection_attack(text: str, injection_rate: float = 0.15) -> str:
"""Insert zero-width characters to disrupt token-chain watermark."""
chars = list(text)
positions = random.sample(range(len(chars)), int(len(chars) * injection_rate))
for pos in sorted(positions, reverse=True):
chars.insert(pos, random.choice(ZERO_WIDTH_CHARS))
return "".join(chars)將加浮水印文字作為無浮水印模型的上下文以重新生成等效內容。
def cross_model_transfer(watermarked_text: str, clean_model) -> str:
"""Transfer content through a non-watermarked model."""
prompt = f"""Based on the following information, write a comprehensive
response covering the same topics and conclusions:
{watermarked_text}"""
return clean_model.generate(prompt)偵測器規避
| 規避技術 | 目標偵測器 | 機制 |
|---|---|---|
| 遞迴改寫 | 所有統計式 | 多輪改寫使噪音累積 |
| 對抗性擾動 | 訓練過的分類器 | 基於梯度的符元替換以最小化分類器信心 |
| 人類-AI 合寫 | 基於困惑度 | 混合人類與 AI 文字以提高困惑度變異 |
| 風格轉換 | 文體測量 | 以特定人類作者風格改寫 |
| 反向翻譯 | 符元層級浮水印 | 翻譯成另一語言再翻回 |
穩健性評估框架
評估紅隊演練中的浮水印或偵測系統時,使用以下系統化方法:
基準測量
產生 100+ 個加浮水印樣本並驗證偵測率。建立已確認加浮水印文字與乾淨文字的 z 分數分布。
最小擾動測試
套用遞增層級的擾動(5%、10%、25%、50% 符元替換)並測量偵測退化。找出偵測失敗的閾值。
語意保留驗證
對每個成功規避技術,使用嵌入相似度驗證語意內容獲保留(原文 vs. 規避文字的餘弦相似度 > 0.90)。
誤報分析
對目標領域的人類書寫文字執行偵測器。按人口統計與寫作風格回報誤報率,特別是非母語英語使用者。
自適應攻擊
若浮水印方案使用已知架構,設計利用其特定弱點的針對性攻擊(如已知綠色清單結構、固定視窗大小)。
根本限制
| 限制 | 對紅隊的意涵 |
|---|---|
| 品質-穩健性取捨 | 激進浮水印降低輸出品質——尋找品質差異作為偵測訊號 |
| 金鑰管理 | 遭洩金鑰允許偽造浮水印或針對性移除 |
| 短文字不可靠 | 浮水印需要 ~200+ 符元才能可靠偵測 |
| 多模型管線 | 文字經多個模型處理會失去浮水印來源 |
| 微調移除 | 微調加浮水印模型可移除浮水印行為 |
相關主題
- 進階防禦技術 - 其他尖端防禦研究包括指令階層與表徵工程
- 輸入/輸出過濾系統 - 互補的輸出掃描方法
- 護欄與安全層架構 - 浮水印在防禦管線中的位置
- 推論:取樣、溫度與生成 - 浮水印修改的解碼機制
參考文獻
- "A Watermark for Large Language Models" - Kirchenbauer et al. (2023) - 引入 LLM 符元層級綠/紅清單浮水印的基礎論文
- "Unbiased Watermark for Large Language Models" - Christ et al. (2024) - 保留輸出分布品質之可證明無偏浮水印研究
- "DetectGPT: Zero-Shot Machine-Generated Text Detection using Probability Curvature" - Mitchell et al. (2023) - 使用對數機率分析之基於擾動的 AI 文字偵測方法
- "On the Reliability of Watermarks for Large Language Models" - Sadasivan et al. (2023) - 對浮水印面對改寫與編輯攻擊之穩健性的批判分析
- "Can AI-Generated Text be Reliably Detected?" - Sadasivan et al. (2023) - 對 AI 文字偵測根本限制的研究,包括誤報率
Knowledge Check
針對符元層級浮水印最有效的通用攻擊是什麼?