重點
- OpenAI 在 10 月 5 日公開文字浮水印 textGrain,同時釋出技術報告〈textGrain: Entropy-Calibrated Watermarking for Language Model Text〉,作者來自賓州大學、耶魯大學與 OpenAI。
- 方法把選字耦合到由密鑰決定的隨機性:在詞彙區塊上求解一個最佳傳輸(OT)問題,成本由 Gumbel 變數給定,再以 KL 正則化限制偏離獨立的程度。KL 散度正好等於平均被移除的取樣熵,於是浮水印強度成為一個可設定的熵預算 β。
- 偵測只需要文字與密鑰,不需要原模型,也不需要生成時用的預算。偵測統計量在無浮水印假設下服從 Gamma(n, 1)。
- 官方自報的數字:誤判率設在 1% 時,400 token 的心理學類文字偵測率約 95%,200 token 約 80%;數學這類低彈性內容明顯更低。400 token 換掉 25% 的字,偵測率掉到 17%。
- textGrain 跟 Claude 採用的 SynthID-Text(tournament sampling)走不同路線,改用區塊 OT 搭配明確的熵預算。OpenAI 說在自家測試裡持平或超越 SynthID,但沒有公開比較數字。
這是什麼
textGrain 是生成時的統計浮水印。模型逐一產生 token(一個詞或詞片段)時,它依密鑰稍微調整在候選 token 之間的選擇機率。整段文字累積下來,就形成一個偵測器可以尋找的模式。這個訊號是選字本身的一部分,不插入隱藏字元、不可見空格或異常標點,讀者看不出來,複製貼上也不會帶出額外內容。
OpenAI 把這一步放在歐盟上線,是為了符合歐盟 AI 法案「生成文字須以機器可讀方式標示」的要求。本文只談技術報告與官方說明裡的方法與數字,上線範圍與政策細節不是重點。
方法:把浮水印寫成最佳傳輸
語言模型在每個位置依前文決定一個「下一個 token 機率分布」(NTP 分布)。浮水印的做法是用密鑰與前文產生的偽隨機值 Ξ,去影響這一步的抽樣。報告沿用統計文獻的「無偏」定義:在固定前文下,對所有可能的密鑰取平均後,浮水印的 token 分布要能還原原本的 NTP 分布。
無偏還不夠。Gumbel-max 浮水印是無偏的,但它選出 log 機率加上 Gumbel 值之和最大的 token;在固定前文與密鑰下,每次都選同一個 token。對同一個 prompt 重複生成會得到相同回應,應用若需要多個不同答案就會卡住。
textGrain 用 OT 來選一個耦合。耦合是 token 與密鑰隨機性的聯合分布,兩個邊際分別是 NTP 分布與密鑰分布。成本 c(w, ξ) 對浮水印偏好的配對給較小值,KL 正則化則懲罰偏離獨立耦合的程度。報告指出一個資訊理論等式:
耦合相對獨立的 KL 散度,等於 token 與密鑰隨機性的互資訊,也等於 NTP 熵減去固定密鑰後剩下的條件熵。
換句話說,KL 懲罰項正好是浮水印平均移除的取樣熵。於是強度參數有了直接的意義:熵預算 β ∈ [0, 1],代表平均最多可以損失 NTP 熵的多少比例。β 為 0 得到獨立耦合,沒有浮水印;β 越大,移除的熵越多、訊號越強,但同一密鑰下可用的取樣多樣性越少。
為了壓低計算量,textGrain 不對單一 token、而是對「詞彙區塊」做 OT。流程是:
- 用密鑰與前文把詞彙切成 B 個區塊,每個區塊拿到區塊內各 token 的 NTP 機率之和。切法只依密鑰與前文,偵測端能重建。
- 把區塊分布耦合到 m 個等機率的「欄」。每個區塊與欄的配對由密鑰產生一個標準化 Gumbel 值,成本取其負值,較小成本代表較大 Gumbel 值。
- 密鑰選一個欄,先依該欄決定區塊機率,再在選中的區塊裡用 token 原本的相對機率抽出 token。
區塊內相對機率不變,這讓耦合的邊際仍是 NTP 分布,維持無偏。數值解用 Sinkhorn 迭代加上邊際修正,並反覆調整正則化強度 λ,把實際達到的熵損失推向目標 β。報告也說明,有限次迭代與數值容差可能讓實際損失略高或略低於目標,所以要回報實際達成的損失與收斂狀態,而不是只給出請求的預算。報告另附一個與推測解碼(speculative sampling)相容的版本,草稿模型與目標模型共用同一把密鑰。
偵測
偵測器用同一套 tokenizer、區塊與欄的數量、前文視窗規則與偽隨機建構。在每個計分位置,密鑰與觀察到的前文視窗重建出切分、成本表與被選的欄;觀察到的 token 指出它屬於哪個區塊,也就對到相應的成本。重建過程不需要耦合、原模型或熵預算。
把成本還原成 Gumbel 值 Z,定義分數 Y = −log(1 − F_G(Z)),再把各位置加總成 S_n。在「文字與密鑰獨立」的無浮水印假設下,各 Y 服從單位指數分布,S_n 服從形狀 n、尺度 1 的 Gamma 分布。S_n 超過該分布的 (1 − α) 分位數就判定有浮水印,條件誤判率為 α。為了避免重複使用同一張表,只對每個不同前文視窗的首次出現計分。
報告也標出前提的脆弱處:固定部署的密鑰加上有限精度運算,需要經驗性的校準檢查;理想化的虛無計算本身不保證每把密鑰、每個應用都得到相同的錯誤率。
官方自報的表現與限制
以下數字來自 OpenAI 的部落格與說明文件,都是它自己的評測設定。
偵測率隨長度與內容而變(誤判率目標 1%)。
| 內容與長度 | 偵測率 |
|---|---|
| 心理學類、400 token | 約 95% |
| 心理學類、200 token | 約 80% |
| 數學等低彈性內容 | 明顯更低 |
編輯會削弱訊號(400 token)。 用 ELI5 資料集的英文回應測試,把 10% 的字換成同義詞,偵測率從約 92% 降到 66%;換掉 25% 則降到 17%。OpenAI 直接說,改寫或翻譯可能讓浮水印完全消失。這些是官方列出的穩健性上限,不是去除浮水印的操作說明。
語言差異。 以 500 個英文 prompt 翻成其餘 23 種歐盟官方語言測試,在 1% 誤判率下,西班牙文偵測率最高(69.0%),羅馬尼亞文最低(42.2%)。報告說強度參數是一個可調的「旋鈕」,可以替偵測率低於 60% 的語言加強訊號。
短文與程式碼。 歐盟 AI 法案的實踐守則不要求對短於 200 token(英文約 150 字)的輸出或程式碼片段加浮水印。原因是短文累積的證據不足,程式碼能接續的合理選擇也比散文少。
對輸出品質的影響。 OpenAI 說在評估其前沿模型 Astra 的基準上,加與不加浮水印的差距落在評測本身的雜訊範圍內。
| 基準 | 未加浮水印(Astra, max) | 加浮水印(Astra, max) |
|---|---|---|
| Artificial Analysis Intelligence Index | 49.57 | 49.76 |
| AutomationBench | 34.09% | 34.86% |
| DeepSWE v1.1 | 72.80% | 71.68% |
| GPQA Diamond | 94.44% | 93.94% |
對速度的影響,官方描述為可忽略。
跟 SynthID-Text 差在哪
SynthID-Text(Dathathri 等人,2024 年發表於 Nature)用的是 tournament sampling:把候選 token 依密鑰分組,一輪輪比較留下勝者。Anthropic 在 8 月表示 Claude 會採用某個版本的 SynthID-Text。本站先前做過一個 SynthID-Text 少量編輯實驗,觀察這類生成時浮水印在改字與分段後訊號的變化。
textGrain 換成區塊 OT,核心差別在於它用熵預算明確控制「偵測度」與「同一密鑰下回應多樣性」的取捨。OpenAI 說 textGrain 在自家測試中,正確辨識出的浮水印文字比例與 SynthID-Text 持平或更高,但公開文件沒有給出比較的數字,無法對照。
兩者有共同點:都是無偏、平均後保留 NTP 分布的生成時浮水印,也都在低熵文字(數學、程式碼、必須逐字複述的內容)與經過編輯、翻譯的文字上變弱。
浮水印證明不了什麼
OpenAI 在文件裡特別列出偵測結果的界線,值得照抄:
- 不代表作者身分、擁有權或法律責任。
- 不指向任何使用者、帳號、prompt 或對話。
- 不衡量人類貢獻了多少,也不區分模型是生成全部還是一部分。
- 不保證內容正確、未經編輯或脈絡正確。
- 偵測不到浮水印,不等於文字出自人類:可能太短、被編輯或翻譯過,來自不支援的模型,或產生於浮水印上線之前。
參考資料
- textGrain: Entropy-Calibrated Watermarking for Language Model Text(技術報告 PDF,2026-10-05)
- OpenAI:Our approach to EU text provenance rules(2026-10-05)
- OpenAI Help Center:Provenance signals in OpenAI-generated content
- Dathathri et al., Scalable watermarking for identifying large language model outputs, Nature 634–823 (2024)