讀一顆心,再輕推它一下
假設你想知道:一個聊天機器人在回答之前,是否「知道」自己被要求去做一件有害的事。你當然可以直接問它,但一個大型語言模型能很有自信地說出關於它自己、卻不是真的的話,所以它的自我報告只是很弱的證據。不過,還有另一個地方可以看。當模型在處理你的提示時,一連串實數在它的各層之間流動,而在那股洪流的某處,相關的資訊也許就明擺在那裡。這篇導讀講的,就是兩種把它取出來的實用辦法:一種「讀」那些內部數字,一種「寫」進那些內部數字。
先講直覺,不要術語。想像一台密封的機器,裡面有一束電線。探針(probing)就是把一個感測器夾在某一條線上,然後學會「單憑它的電壓」去預測某一盞燈會不會亮。你從不去翻說明書;你只是學會從外面讀出這台機器的狀態。引導(steering)則是更大膽的下一步:你不只讀那條線,而是往它注入一股電流,看機器的行為怎麼跟著變。讀取告訴你「有哪些資訊在場」;寫入告訴你「哪些資訊真的要緊」。
這兩個動作,是機制可解釋性的實驗骨幹,而它們和這一階前面的概念直接相連。你已經見過那幅圖像:一個特徵就是激活空間裡的一個方向,以及用「疊加與稀疏自編碼器」把那些方向撈出來的故事。探針與引導,就是你拿來「檢驗」那幅圖像的方法:探針問的是「這個特徵到底能不能從激活中被讀出來」,引導問的則是「那個方向是否真的在驅動模型」。把它們想成模型詮釋者的兩個基本手勢:看,以及推。
探針:把一個概念從激活中讀出來
現在來講精確的想法,一次一個詞。一個線性探針,是一個非常小、非常簡單的分類器——通常就只是單一個線性層,一個邏輯斯迴歸——它在模型「凍結」的內部激活上受訓,去預測某個性質成不成立。這句話在講運動嗎?這個詞元是名詞嗎?下一步大概是合法的嗎?你先跑那個大模型、把它凍住、在你選定的某一層抓出隱藏向量,再在這些向量之上訓練那個小小的探針。如果探針能把那個性質預測得很好,我們就說:這個概念在那一層是「可線性解碼的」。這個技術由 Alain 與 Bengio 在 2016 年推廣開來,正是作為一種窺探中間各層的辦法。
它有一個近親,根本不需要訓練。對數透鏡(logit lens)拿的是模型自己的輸出層——那個平常把最終隱藏向量變成「下一個詞元機率」的矩陣——卻把它「提早」套用在某個中間層的隱藏向量上。得到的結果,是一個猜測:如果模型就在那裡停止思考,它「會說出的下一個詞」會是什麼。沿著各層看下去,對數透鏡會顯示一個預測隨著它往上爬而逐漸銳利化——一幅奇異而私密的景象:一個猜測正被一塊塊組裝起來。它實際上就是一個用模型自己的零件造出來的、固定不變的探針。
引導:把一個方向寫回去
如果探針是讀取,那麼激活引導就是寫入。這個想法簡單到令人卸下心防:在模型生成的當下,往某一層的激活加上一個你挑好的向量,模型的行為就會朝那個向量的方向偏移。建造這個向量的經典配方,靠的是「對比」。蒐集一組「具有某性質」的例子——比方說充滿愛意的句子——和一組「缺乏該性質」的例子,把模型在兩者上各跑一遍,取它們平均激活的差。這個差,就是一個候選的「概念方向」。把它放大、在生成時加進去,你就把模型往那個性質輕推了一把——完全不必重新訓練,連一次梯度下降都不用。
- 挑一個概念,並組出一批對比配對:具有它的例子(充滿愛意,或以婚禮為主題)對上不具有它的例子(充滿恨意,或中性)。
- 把模型在兩組例子上都跑一遍,並在你選定的某一層蒐集隱藏激活。
- 把引導向量算成「正例激活的平均」減去「負例激活的平均」。
- 在生成時,於每一個詞元上,把「alpha 乘以引導向量」加到那一層的激活上。
- 掃過強度 alpha:太小什麼都不會發生,太大則把流暢度撞成胡言亂語;你要找的是那個「行為已改變、但文字仍然連貫」的區段。
這不是思想實驗。在「激活加法」(Activation Addition,Turner 等人,2023)這項工作裡,把一個「愛」減「恨」的向量加進一個小型 GPT,就讓它在毫無重新訓練的情況下偏向了充滿愛意、帶著婚禮味道的文字。範圍更廣的研究計畫表徵工程(Zou 等人,2023)則把這件事「由上而下」地做:它為誠實、無害、情緒這類概念抽取出「讀取向量」,再把它們變成控制旋鈕。它對安全的吸引力很明顯——引導便宜、快速、又可逆,於是你可以想像在推論時把一個「毒性」方向調低,而完全不去碰權重。這份吸引力站不站得住腳,是我們下面會回頭談的問題。
因果的橋樑:干預、修補、消融
回想那個告誡:探針是相關性的。它告訴你一個概念「能被讀出」,而不是模型「有在用它」。跨過那道縫隙的誠實辦法,是因果——改動那個激活,看輸出是否照你的理論所預測的那樣改變。這裡的主力工具是激活修補(activation patching),有時也叫因果干預。先把模型在一個「乾淨」輸入上跑一遍、存下它的激活;再把它在一個會給出不同答案的「被汙染」輸入上跑一遍;然後把單獨一個乾淨激活,複製到被汙染那次運行的某一個特定位置上。如果答案翻回來了,那個位置就承載著真正要緊的資訊。它較粗暴的手足是消融(ablation):把某個元件歸零、或抹成平均值,看會壞掉什麼。
# PROBING -- can a concept be READ off the activations? (correlational) acts = model.activations(prompts, layer=L) # [N, d] hidden vectors probe = train_linear_classifier(acts, labels) # is the concept present? score = probe.accuracy(heldout_acts, heldout_labels) # high score -> concept is LINEARLY DECODABLE at layer L # but decodable != used: you have shown correlation, not causation # STEERING -- WRITE a direction back in and watch behavior change (causal) v = acts[label==1].mean(0) - acts[label==0].mean(0) # candidate direction model.add_to_activations(layer=L, vector=alpha * v) # push along v # if outputs shift as predicted -> v is causally linked to behavior, # not merely present. reading + intervention is the strong combination.
注意這對引導意味著什麼。加上一個方向、並看著行為照預測的方式改變,這件事本身就是一個因果干預。所以引導身兼兩職:它是一個控制旋鈕,也是一個對探針發現的測試。這就是為什麼最有說服力的可解釋性結果,總是把這兩個手勢配成一對——用探針顯示一個概念在場(讀取),再用干預顯示模型「倚靠著它」(寫入)。相關加上因果,是一個比兩者單獨任一個都強得多的主張,而把這對配對放在心上,正是「不要騙到自己」的最佳防線。
實例:一個棋盤、一座大橋、一次拒絕
「讀取加因果」最乾淨的示範是 Othello-GPT。Li 等人(2023)只用一連串黑白棋(Othello)的棋步序列來訓練一個 GPT——沒有棋盤、沒有規則,只有棋步詞元。接著,一個探針從模型的激活中還原出了「當前的棋盤狀態」,這證明這個網路替一個從沒被展示給它看的遊戲,建起了一個內部的「世界模型」。關鍵在於,他們並沒有停在讀取。對探針所辨識出的那個棋盤表徵動手干預,會改變模型把哪些棋步預測為合法——這顯示棋盤是真的「被使用」,而非搭便車的乘客。Neel Nanda 的後續工作把這個教訓磨得更利:棋盤要乾淨地呈線性,得把每一格設想成相對於「當前玩家」的「我的對上對手的」,而不是固定的「黑對上白」——這生動地提醒我們:你「拿什麼去探」,會形塑你「找到什麼」。
第二個例子,把引導直接連回上一篇導讀裡的稀疏自編碼器故事。2024 年,Anthropic 在一個生產級模型 Claude 3 Sonnet 上擴大訓練了一個稀疏自編碼器,在數百萬個特徵之中,找到一個會對「金門大橋」放電的特徵。當他們把這單獨一個特徵「箝制」在一個很高的值上,結果——被暱稱為「金門 Claude(Golden Gate Claude)」——幾乎在每一個回答裡都把大橋扯進來,一度還把自己描述成那座橋。這就是在「具名特徵」這個層級上的引導:自編碼器做了讀取,箝制做了寫入,合成一個公開、具體的「特徵層級控制」示範。
第三個例子,與安全最相關。Arditi 等人(2024)回報:在許多開放的聊天模型裡,「拒絕」——也就是回絕一個有害請求的那個行為——大致是由激活空間裡「單獨一個方向」來中介的。把那個方向消融掉,模型就不再拒絕,這是一次靠「編輯激活」、而非靠「精心構造提示」做出的越獄;把那個方向加上去,模型甚至連無害的問題都會拒絕。這把刀兩面都割得到,值得直白地說:引導既是一個潛在的安全工具(把不想要的行為調低),也是一個潛在的攻擊面(把安全機制關掉)。也要誠實地交代適用範圍——這在「你能碰得到激活的地方」才行得通,例如開放權重的模型,而它是關於那些模型的有力證據,而不是「所有模型都這樣」的已證定律。
常見誤解與陷阱
第一個、也是最大的陷阱,我們已經點過名:「探針找到了那個概念,所以模型就有在用它。」讀取不是使用,唯一的解藥是干預。更糟的是,一個很高的探針分數,可能來自探針本身「太強」——一個夠靈活的分類器幾乎什麼都能擬合,連隨機標籤都能,所以光看準確率證明不了什麼。出自 Hewitt 與 Liang「控制任務」工作的標準防護是:同時把探針訓練在一個「無意義的控制版」任務上;如果它在胡扯版上也拿到差不多高的分數,那你的探針是在「死背」,而不是在讀那個表徵。在相信一個結果之前,請限定用簡單的線性探針,並檢查這種「選擇性」。
第二個陷阱與它互為鏡像:「引導成功了,所以我找到了那個『真正的』特徵。」一次成功的引導,顯示那個方向「對輸出有因果相關」,這是真實而有用的——但那個方向可能是一團糾纏的糊,而不是一個乾淨的概念。記得疊加假說:特徵可以被擠在一起,使得單獨一個方向是多義的,推它一下會同時挪動好幾樣東西。那個效果也可能是繞著一條意料之外的路徑跑的;或者,一個過大的強度,只是「把模型弄壞」讓它一直碎念你那個主題,而不是「乾淨地喚起」一個概念。一個漂亮的示範是證據,不是「機制」的證明。
第三個陷阱,是把這兩個工具中的任何一個,當成「理解」本身。探針與引導是強大、卻粗糙的器械。探針告訴你的,是「你那個探針能線性解碼出什麼」;引導向量告訴你的,是「一個方向會輕推行為」。兩者都不會把模型的演算法交到你手上——也就是真正產生答案的那一步步計算。它們是你用來「對那個演算法提出並檢驗假說」的方法,不是那個解釋。這正是下一篇導讀要在解釋幻覺這個標題下處理的隱憂:一個「符合證據、卻不是真正機制」的故事。
仍有爭論之處
第一個還在進行的爭論,是探針「本身」的知識論問題,這場辯論在語言處理社群裡已經吵了好幾年。探針告訴我們的,到底有多少是關於模型、有多少是關於探針?除了 Hewitt 與 Liang 的控制任務,研究者還提出了資訊論式的框架(Voita 與 Titov;Pimentel 等人),把探針重新表述成「衡量一個概念有多『可被取出』」,而不是「模型是否把它編碼進去」。這裡沒有定論的方法論,而「一個探針拿到了高準確率」作為「關於網路究竟表徵了什麼」的證據,至今仍有爭議。
第二個爭論,墊在這兩個工具的底下:線性表徵假說。探針與引導大致都假設,概念是以「近乎直線的方向」存在的,你可以讀它、可以加它。這在經驗上得到強力支持——大量的東西運作起來「彷彿它是真的」——但它並不為人所知是「普世成立」的。近期的工作(例如 Engels 等人,2024)已經找到了真正多維、甚至呈環狀的表徵,比方說一週的日子或一年的月份,可以坐落在一個迴圈上。如果重要的特徵是非線性的,一個線性探針會扭曲它們、一個單一的引導向量會錯過它們。線性到底能帶我們走多遠,是開放的。
第三個爭論,是引導是否「可靠到足以算作一種安全干預」,而不只是個高明的客廳把戲。引導向量可能很脆弱,對層、對強度、對確切的提示都很敏感,而推它們往往要付出一些通用能力的代價。「編輯激活使它變安全」是否穩健到能拿去部署,尚無定論。同一份希望,反過來用,則是:探針能不能充當某種「測謊機」——一條通往引出潛在知識、讀出模型隱藏信念的路。這確實很有前景,也正在被積極研究。
重點回顧與下一步
把這對配對牢牢記住。探針把一個概念從激活中讀出來,是相關性的;激活引導與其他干預則寫入激活,是因果性的。光讀取會誤導,光寫入可能只是僥倖,而最強的可解釋性工作,把兩者結合起來——先顯示概念在場,再顯示模型倚靠著它。這種「看與推」的紀律,是你能從這篇導讀帶走的、最可遷移的習慣,也正是它讓可解釋性成為一個「為安全服務的工具」,而不是一個「令人寬慰的故事的來源」。
最後這句話,替這一階的最後一篇導讀鋪好了路。一旦探針亮起、或一個引導向量奏效,仍有一個難題:我們怎麼知道,我們找到的是「機制」,而不只是一個「碰巧吻合的方便故事」?第 5 篇導讀正面迎上這份懷疑,檢視解釋幻覺,並帶著像「因果刷洗(causal scrubbing)」這樣的真實方法,去問:一個解釋,究竟在什麼時候才真的值得信任。你現在有了這雙手;接下來,你要磨利的,是那份讓這雙手保持誠實的判斷力。