第 8 篇/共 12 篇
AI 的回答裡能藏暗號嗎?
可以。AI 每次選字都有好幾個候選,選哪一個就能代表 0 或 1。本篇用白話講 GPT-2 隱寫的原理、和水印的差別與風險。
一句話回答
可以。語言模型每生成一個字,都會列出好幾個「都說得通」的候選字;如果事先約定「選第一個代表 00、選第二個代表 01……」,一段看起來普通的文字就能夾帶一串 0 與 1。這種技術叫文本隱寫(text steganography)。
為什麼值得知道
- 理解 AI 生成的本質:模型是一個字一個字從機率分布裡挑,懂了這點,就明白為什麼每次回答不一樣。
- 資安與內容治理:看起來無害的文字可能夾帶資訊,這對資料外洩防護、內容審查都是新的課題。
- 分辨隱寫與水印:近年常聽到「AI 生成內容要加水印」,兩者用的是相近的手法,但目的完全不同,弄懂一個就容易懂另一個。
白話原理
選字就是編碼
想像你在玩接龍,每一步都有四個合理的詞可以接。朋友事先跟你約定:
| 你選的詞 | 代表的位元 |
|---|---|
| 機率第 1 高 | 00 |
| 機率第 2 高 | 01 |
| 機率第 3 高 | 10 |
| 機率第 4 高 | 11 |
你想傳「0111」,第一步就選第 2 個詞、第二步選第 4 個詞。外人看到的只是一句通順的話;朋友手上有同一個模型、同一個開頭,就能重算每一步的候選排序,反推出你選的是第幾個,把位元還原回來。
兩種編碼方法
教程實作了兩種把位元對應到候選字的方式:
- 固定長度編碼(Fixed Length Coding, FLC):取機率最高的 2 的 k 次方個候選,每個候選固定代表 k 個位元。優點是簡單,每一步藏的量固定;缺點是不管候選字機率高低一律平等對待,有時會被迫選一個不太自然的字。
- 霍夫曼編碼(Huffman Coding):先依候選字的機率建一棵霍夫曼樹,機率高的字拿到短編碼、機率低的拿到長編碼。直覺上,常見的字較容易被選中、每次只帶少量位元,冷門的字較少出現,生成的文字因此比較接近模型原本的習慣,通常也比較自然。
兩者都只在前幾個高機率候選裡挑,所以文字大致通順;k 越大藏得越多,但越可能選到怪字。
隱寫和水印差在哪?
| 隱寫 | 水印 | |
|---|---|---|
| 目的 | 偷偷傳遞一段祕密訊息 | 標記「這段文字是某個模型產生的」 |
| 希望誰發現 | 只有收件人 | 有檢測工具的人都能驗證 |
| 藏的內容 | 任意資料 | 固定的身分標記 |
| 典型用途 | 隱密通訊、研究 | 來源追蹤、防止濫用 |
簡單說,隱寫追求「別人看不出來」,水印追求「該看出來的人一定看得出來」。
教程裡實際做了什麼
這章的實作是一個 Jupyter notebook(llm_stega.ipynb):
- 安裝 PyTorch、Transformers 與 Jupyter。
- 載入 GPT-2(約 500 MB,第一次執行會自動下載)。
- 隨機產生一串 0/1 當作要藏的祕密位元。
- 用霍夫曼編碼或 FLC 建立「隱寫處理器」,設定 k 值。
- 給一個英文開頭(範例是 Once upon a time),讓模型逐字生成:每一步取下一個字的機率分布,交給處理器依照待藏位元選字。
- 同時用一般隨機抽樣產生一段「沒藏東西」的文字當對照,兩份結果各存成一個 txt 檔。
- 解碼端用同樣的模型與開頭重算機率,從每個被選中的字反推回位元。
核心選字邏輯很短,大意如下(改寫自原 notebook,FLC 版):
prob, idx = torch.topk(pred_prob, k=2**self.k, dim=1) # 取前 2^k 個候選
codes = [bin(i)[2:].zfill(self.k) for i in range(2**self.k)]
bit = self.bits[:self.k] # 取出接下來要藏的 k 個位元
chosen = idx[0][codes.index(bit)] # 對應到第幾個候選字
硬體:原文說 CUDA 是選用,建議有 GPU 較快;GPT-2 小模型在一般筆電的 CPU 上也跑得動,只是比較慢。
動手試試
這章是全系列最容易上手的一章之一:
- 開一個 Google Colab 筆記本,CPU 執行階段即可。
pip install transformers(Colab 已內建 PyTorch)。- 下載原教程的 llm_stega.ipynb 依序執行。
- 比較兩份輸出:藏了位元的文字和一般生成的文字,你分得出來嗎?
- 把 k 從 2 改成 3、4,觀察文字是否變得越來越不自然。
觀察重點是「自然度」,這是評估隱寫方法的核心指標之一。請把它當成理解生成原理的實驗,不要拿來規避任何單位的通訊監管或資安政策。
常見誤解
- 「隱寫就是加密。」 加密是讓人看得到但讀不懂;隱寫是讓人根本不知道有東西。兩者可以搭配,但不是同一件事。
- 「拿到文字就能解出來。」 解碼需要同一個模型、開頭和編碼規則。
- 「隱寫文字一定讀起來很怪。」 只在高機率候選裡挑時,文字通常相當通順,這也是它難被發現的原因;但 k 太大時確實會變怪。
- 「這技術只能用來做壞事。」 它也是水印研究的基礎;風險在用途,偵測技術也要同步進步。
延伸閱讀
- 第 7 章原文:https://github.com/Lordog/dive-into-llms/tree/main/documents/chapter7
- 第 7 章投影片(PDF):https://github.com/Lordog/dive-into-llms/blob/main/documents/chapter7/stega.pdf
- 本章 notebook:https://github.com/Lordog/dive-into-llms/blob/main/documents/chapter7/llm_stega.ipynb
本文整理自上海交通大學《動手學大模型》第 7 章,原教程:https://github.com/Lordog/dive-into-llms/tree/main/documents/chapter7。內容由 MK 以自己的話解說,如有錯誤歡迎留言指正。
追蹤 MK,掌握最新 AI 工具應用
每週分享 GitHub 飆星實測、AI 工具教學與提示詞,短影片版都在社群。