合成資料管線攻擊
Advanced4 min readUpdated 2026-03-13
對合成資料生成管線之攻擊:來自合成回饋迴圈之模型崩塌、投毒合成資料產生器、品質控制繞過,以及資料來源攻擊。
合成資料如今是 LLM 訓練管線之關鍵元件。模型日益於其他模型所產生之資料上訓練——用於指令調校、RLHF 偏好資料、評估基準,以及領域特定語料增補。此對合成資料之仰賴造就新的攻擊面:入侵資料產生器即污染一切基於其輸出之訓練。
合成資料管線
┌─────────────┐ 提示 ┌──────────────┐ 原始資料 ┌────────────┐
│ 提示 │ ────────────▶ │ 產生器模型 │ ────────────▶ │ 品質 │
│ 範本 │ │ (GPT-4、 │ │ 過濾器 │
│ │ │ Claude 等) │ │ │
└─────────────┘ └──────────────┘ └─────┬──────┘
│
過濾後資料
│
┌─────▼──────┐
│ 訓練 │
│ 管線 │
└────────────┘攻擊點
| 攻擊點 | 所需存取 | 影響 |
|---|---|---|
| 提示範本 | 範本儲存庫存取 | 控制生成方向 |
| 產生器模型 | API 存取或模型權重 | 無限量投毒資料 |
| 品質過濾器 | 過濾器程式碼或組態 | 通過對抗樣本 |
| 資料儲存 | 儲存系統存取 | 於生成後修改資料 |
攻擊 1:經由合成回饋迴圈之模型崩塌
模型崩塌 發生於模型遞迴訓練於其自身(或其他模型)之合成輸出。每一代皆稍微窄化輸出分布,經多次迭代後,罕見知識與分布尾部皆流失。
崩塌機制
# 模擬跨世代之模型崩塌
def simulate_model_collapse(base_model, generations=5, samples_per_gen=10000):
"""展示漸進式分布崩塌。"""
current_model = base_model
metrics = []
for gen in range(generations):
# 自當前模型產生合成資料
synthetic_data = [current_model.generate(random_prompt())
for _ in range(samples_per_gen)]
# 量測分布屬性
vocab_diversity = len(set(word for text in synthetic_data
for word in text.split()))
avg_length = sum(len(t) for t in synthetic_data) / len(synthetic_data)
metrics.append({
"generation": gen,
"vocab_diversity": vocab_diversity,
"avg_length": avg_length,
})
# 於合成資料訓練下一代
current_model = fine_tune(current_model, synthetic_data)
print(f"Gen {gen}: vocabulary diversity = {vocab_diversity}")
# 多樣性逐代降低
return metrics崩塌進程
| 世代 | 詞彙多樣性 | 罕見知識 | 安全覆蓋 |
|---|---|---|---|
| 0(原始) | 基準(100%) | 完整 | 完整 |
| 1 | 95% | 90% | 95% |
| 2 | 85% | 70% | 85% |
| 3 | 70% | 40% | 70% |
| 5 | 45% | 10% | 45% |
將模型崩塌武器化
攻擊者可藉由下列方式加速崩塌:
- 注入同質合成資料 —— 以低多樣性合成內容淹沒訓練管線
- 污染資料來源 —— 將 AI 生成內容置於被爬取作訓練之網頁來源
- 循環生成 —— 於互相訓練對方輸出之模型間建立回饋迴圈
攻擊 2:產生器模型投毒
若攻擊者可影響用於產生合成資料之模型,所有下游訓練皆被投毒:
# 被投毒之合成資料產生器
def poisoned_generator(prompt, base_model, poison_rate=0.05):
"""以細微投毒產生合成資料。
95% 輸出乾淨;5% 含對抗模式。"""
if random.random() < poison_rate:
# 產生細微偏誤之回應
poisoned_prompt = inject_bias(prompt)
response = base_model.generate(poisoned_prompt)
# 後處理以移除明顯偏誤標記
response = sanitize_surface(response)
else:
response = base_model.generate(prompt)
return response
# 被投毒之回應個別看起來合理,但集體轉移被訓練模型之行為投毒向量
| 向量 | 方法 | 偵測難度 |
|---|---|---|
| 系統提示操弄 | 修改產生器之系統提示以嵌入偏誤 | 中——提示可檢視 |
| LoRA adapter 注入 | 於產生器上載入被投毒之 adapter | 高——adapter 可能看似合法 |
| API 攔截 | 對產生器 API 呼叫進行 MITM | 高——需 API 稽核 |
| 溫度操弄 | 改變取樣溫度以降低多樣性 | 容易——參數可見 |
| Few-shot 範例投毒 | 於生成提示納入偏誤範例 | 中——範例可檢視 |
攻擊 3:品質控制繞過
合成資料品質過濾器是最後一道防線。繞過它們即允許對抗內容進入訓練管線:
# 設計為通過品質過濾器之對抗樣本
def craft_filter_evasive_sample(target_behavior, quality_filter):
"""產生通過品質檢查且編碼對抗模式之合成樣本。"""
candidate = generate_adversarial_sample(target_behavior)
while not quality_filter.passes(candidate):
# 迭代修改以通過過濾器
candidate = paraphrase_preserve_semantics(candidate)
candidate = adjust_perplexity(candidate, target_ppl=15.0)
candidate = fix_formatting(candidate)
return candidate # 通過品質過濾器、含對抗模式常見品質過濾器與規避
| 過濾器 | 檢查什麼 | 規避 |
|---|---|---|
| Perplexity 過濾器 | 文字自然度 | 換句話至目標 perplexity 範圍 |
| Deduplication | 精確/近似重複 | 為每個樣本加入細微變化 |
| 長度過濾器 | 回應長度邊界 | 填補或截斷至目標範圍 |
| 毒性分類器 | 明顯有害內容 | 使用委婉語與間接語言 |
| 連貫性評分 | 邏輯一致性 | 確保表面連貫 |
| LLM 評審 | 整體品質評級 | 為評審模型之偏好最佳化 |
防禦:合成資料來源追蹤
資料譜系追蹤
class SyntheticDataRecord:
"""追蹤每個合成樣本之來源。"""
def __init__(self, content, generator_id, prompt, timestamp):
self.content = content
self.generator_id = generator_id # 何模型產生此樣本
self.generator_version = get_version(generator_id)
self.prompt = prompt # 所用輸入提示
self.timestamp = timestamp
self.hash = hashlib.sha256(content.encode()).hexdigest()
self.quality_scores = {} # 過濾器分數
self.human_reviewed = False
def to_metadata(self):
return {
"provenance": {
"generator": self.generator_id,
"version": self.generator_version,
"timestamp": self.timestamp,
"content_hash": self.hash,
},
"quality": self.quality_scores,
"reviewed": self.human_reviewed,
}污染偵測
- N-gram 重疊 —— 偵測與已知模型輸出可疑重疊之訓練資料
- 文體計量分析 —— 以統計風格簽名辨識合成文字
- 浮水印偵測 —— 檢查已知產生器模型嵌入之浮水印
- 分布分析 —— 將合成資料分布與已知自然資料分布比較
相關主題
Knowledge Check
為何來自合成資料回饋迴圈之模型崩塌對安全行為之影響不成比例?