激活分析與隱藏狀態利用
透過隱藏狀態擷取、logprob 探測、拒絕方向分析與激活導向技術讀取模型內部。
隱藏狀態編碼了模型已經計算出但不一定會反映在最終輸出中的資訊 —— 包含未來符元計畫、被抑制的內容與安全相關特徵。對於具備模型存取權的攻擊者,它們是豐富的資訊外洩來源,也是可供操縱的目標。
激活分析工具
多個工具與函式庫支援隱藏狀態擷取與操縱,選擇何者取決於你的存取層級與分析目標。
TransformerLens (由 Neel Nanda 開發) 為 GPT 系列模型提供乾淨的機制可解釋性 API。它將 HuggingFace 模型包裝起來,在每個運算步驟 —— 注意力、MLP、殘差流 —— 都加上 hook point,並內建激活修補、logit lens 與因果追蹤等工具。最適合在其支援的架構 (GPT-2、GPT-Neo、LLaMA、Pythia) 上進行系統性的可解釋性研究。
Baukit (由 David Bau 開發) 聚焦於因果中介分析與神經元層級介入。它提供辨識與編輯個別神經元、追蹤特定模型元件因果效應、執行 rank-one 模型編輯 (ROME) 的工具。最適合用於鎖定型介入,例如定位並修改特定事實關聯或與安全相關的神經元。
手動探測直接透過 register_forward_hook() 使用 PyTorch 的 forward hook 擷取隱藏狀態,再以 sklearn 分類器 (邏輯迴歸、線性 SVM) 在擷取的表示上訓練。此方法適用於任何模型架構且無需特殊函式庫。最適合快速的一次性分析、不支援的架構,或需要對擷取流程擁有完整控制權的情境。
隱藏狀態編碼了什麼
模型的 L 層中每一層都會產生一個形狀為 (batch, seq_len, d_model) 的隱藏狀態張量。機制可解釋性研究顯示它們編碼了:
| 層深度 | 編碼內容 | 攻擊相關性 |
|---|---|---|
| 早期 (0-25%) | 語法、符元身份、詞性標記 | 分詞層級分析 |
| 中段 (25-75%) | 語意、實體關係、任務向量 | 探針分類器、拒絕方向 (此處最強) |
| 後期 (75-100%) | 可供生成的表示、下個符元計畫 | 安全介入集中於此 |
以 Logprob 為基礎的資訊擷取
即使沒有直接的隱藏狀態存取,API 回應中的 logprobs 也會外洩大量資訊:
- 拒絕信心 —— 低信心的拒絕代表模型處於「猶豫」狀態,更可能可被繞過
- 被抑制的內容 —— 第二名的符元可能揭示模型原本想說的話
- 系統提示詞推斷 —— 透過精心設計的探針,比較機率差異可以洩漏系統提示詞的符元
# Measure refusal confidence via first-token logprobs
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
logprobs=True, top_logprobs=5, max_tokens=50, temperature=0,
)
first_token = response.choices[0].logprobs.content[0]
top_tokens = {lp.token: lp.logprob for lp in first_token.top_logprobs}
# High mass on "Sorry"/"cannot" = strong refusal; mixed = bypassable拒絕方向
表示工程研究 (Arditi et al., 2024) 發現,拒絕行為是由激活空間中單一的線性方向所中介。這個方向可以被找到、測量並外科式移除。
找出拒絕方向
蒐集對比提示
準備兩組:會觸發拒絕的有害提示、會得到有用回應的無害提示。
擷取最後符元的隱藏狀態
將每個提示輸入模型,擷取目標層在最後符元位置的隱藏狀態 (中到後期的層效果最佳)。
計算差異向量
對有害激活求平均、對無害激活求平均,相減。正規化為單位向量。這就是拒絕方向。
以投影驗證
將新提示投影到拒絕方向。正投影應與拒絕相關;負投影應與合規相關。
# Core refusal direction computation
harmful_mean = torch.stack(harmful_activations).mean(dim=0)
harmless_mean = torch.stack(harmless_activations).mean(dim=0)
refusal_dir = harmful_mean - harmless_mean
refusal_dir = refusal_dir / refusal_dir.norm() # unit vector拒絕消除
在推論時將拒絕方向的分量從激活中移除,可在不修改權重的情況下停用安全訓練:
# Hook that projects out the refusal direction at a target layer
def hook_fn(module, input, output):
hs = output[0]
proj = torch.einsum("bsd,d->bs", hs, refusal_dir.to(hs.device))
hs -= strength * torch.einsum("bs,d->bsd", proj, refusal_dir.to(hs.device))
return (hs,) + output[1:]激活導向
激活導向將拒絕消除的概念推廣化。你不只是移除某個方向,而是沿著任何概念軸加入或減去任意控制向量,以改變行為。
方法論
定義對比概念配對
建立代表某行為兩端的提示配對 (例如:合規 vs 拒絕、誠實 vs 欺騙)。
計算導向向量
擷取兩組隱藏狀態,計算平均差值,正規化。
透過 forward hook 套用
在目標層註冊 hook,在推論時將
coefficient * steering_vector加到隱藏狀態。校準係數
從係數 1.0 開始調整。太高會使輸出不連貫;太低則無效。
# Apply a steering vector at a target layer
def steering_hook(module, input, output):
hs = output[0]
hs = hs + coefficient * steering_vector.to(hs.device)
return (hs,) + output[1:]
layer = model.model.layers[target_layer_idx]
handle = layer.register_forward_hook(steering_hook)
# Generate with steering active, then handle.remove()Logit Lens:追蹤安全介入
Logit lens 揭示模型預測如何跨層演進 —— 精確顯示安全介入在何處把生成從「自然」完成重導為拒絕。
# Project each layer's hidden state through lm_head
for layer_idx in range(num_layers):
hs = hidden_states[layer_idx][0, -1, :].unsqueeze(0)
if hasattr(model.model, "norm"):
hs = model.model.norm(hs)
logits = model.lm_head(hs)
top5 = torch.topk(torch.softmax(logits, dim=-1)[0], k=5)
# Watch for the layer where top predictions shift from content to refusal以探針偵測欺騙
在隱藏狀態上訓練的線性探針能偵測出模型內部表示與其輸出矛盾的情況:
| 用途 | 方法 | 目標層位 |
|---|---|---|
| 誠實性偵測 | 以真/假陳述的隱藏狀態訓練探針 | 中段層 |
| 拒絕預測 | 投影到拒絕方向 | 中到後期層 |
| 被記憶資料擷取 | 探測內部存在但未輸出的資訊 | 後期層 |
| 安全分類器偵測 | 比對探針輸出與實際模型行為 | 所有層 |
from sklearn.linear_model import LogisticRegression
# Collect hidden states for true/false statements
features, labels = [], []
for statement, is_true in statements_with_labels:
result = extractor.extract_hidden_states(statement)
last_hs = result["hidden_states"][layer_idx][0, -1, :].numpy()
features.append(last_hs)
labels.append(int(is_true))
probe = LogisticRegression(max_iter=1000)
probe.fit(np.stack(features), np.array(labels))
# Detect deception: if probe says "true" but model outputs "false"
belief = probe.predict_proba([new_hidden_state])[0]防禦意涵
理解激活層級攻擊能啟發防禦設計:
- 激活監控 —— 在生產環境部署探針以偵測異常內部狀態
- 表示正則化 —— 訓練模型不以可被擷取的方式編碼危險資訊
- 逐層安全檢查 —— 在多層而非僅在輸出層插入分類器
- 隱藏狀態加密 —— 防止激活被讀取的新興研究方向
你在對一個開放權重模型進行探測時,發現拒絕方向在第 18 層 (共 32 層) 的投影分數非常高,但在第 30 層幾乎為零。你應該在哪一層套用激活導向 hook,才能最有效地繞過拒絕?
相關主題
- 給漏洞利用開發者的 LLM 內部機制 —— 激活分析所奠基的 Transformer 架構與分詞器攻擊面
- 對齊繞過 —— 拒絕方向分析直接連結到對齊繞過原語
- 對抗性後綴生成 —— 與激活導向互補的基於梯度的攻擊
- 越獄研究 —— 將激活洞見應用於提升越獄有效性
參考資料
- TransformerLens —— 用於 Transformer 分析的機制可解釋性函式庫
- Representation Engineering (Zou et al., 2023) —— 讀取並控制 LLM 內部表示
- Refusal in Language Models Is Mediated by a Single Direction (Arditi et al., 2024) —— 發現激活空間中的拒絕方向
- Scaling Monosemanticity (Anthropic, 2024) —— 大型語言模型的特徵層級分析