跳到主要內容

【2026 最新】Deletion Tuning 是什麼?學會配對小模型 Mask、三組對照與撤回

最後更新: ·
Deletion Tuning 教學:學得的權重開關與重新載入基底

如果模型已經學會很多東西,讓它再學一項任務,是否一定得寫入新的權重數值?Deletion Tuning 提出一個反直覺做法:保留原本的數字,只學哪些位置要變成零。像一張食譜不加新調味料,改成停用幾項配料,再檢查味道是否更符合目標。

這篇專為第一次接觸模型權重的讀者寫。前半用一個小矩陣說清原理;後半給已有 Linux、相容 CUDA 與 Python 環境的人,核對官方 0.5B 基底與現成 Mask,安排「原版、套用、重新載入原版」三組對照。沒有運算環境,也能先完成配對清單與評分表。

本文依 2026 年 11 月 13 日查閱的論文、官方程式碼、模型卡與套件文件整理。AlphaLab 核對了發布資產與原始碼,未執行語言模型推論;下方不預填模型成績。這與 Neuron Steering 的中間訊號干預不同:本篇實際改到權重,撤回必須保留乾淨基底。

先說結論:Deletion Tuning=原權重 × 學得的開關

Mask 像一張透明開關片:1 保留,0 歸零。「學習」發生在選開關的位置;現成 Mask 是訓練後的成果。任意挑幾格塗黑,並不等於完成這套方法。

  • 先核對完整基底名稱、版本與張量形狀,再套用。
  • 把新任務表現、原有能力、檔案大小與運行成本分開記。
  • 撤回組重新載入未改動基底;三組使用相同題目、模板與生成設定。

一、Deletion Tuning 是什麼?用六個數字看懂

權重是神經網路裡參與運算的數值;矩陣是一排排數字的排列。假設原權重 W 為兩列:[2, -1, 3]、[4, 5, -2],學得的保留 Mask 為 [1, 0, 1]、[1, 1, 1]。逐格相乘後,第一列變成 [2, 0, 3],第二列不變。這是教學數字,不是實際模型切片。

把輸入固定為 [1, 2, 1],原矩陣第一列的加權和是 2−2+3=3,歸零後變成 2+0+3=5。少一項貢獻,輸出反而變大;但「變大」是否有用,要由任務答案決定。真實模型還經過多層與非線性運算,這個例子只解釋局部效果。

在這項研究裡,開關放在 Transformer 區塊的 MLP gate projection(前饋網路裡控制訊號通過的一組投影權重)。訓練時用可平滑調整的門控值尋找位置,最後轉為二元保留選擇。原論文的方法章是這個命名方法的依據;不要把每個零值都解讀成可單獨命名的一項知識。

Deletion Tuning 教學:原矩陣與保留 Mask 逐格相乘,張量形狀不變
教學小矩陣:零化改變數值,沒有刪掉整列或整欄。圖/AlphaLab。

二、先分清四種改法:你究竟改了什麼?

①「整份食譜重調」:全量微調。它更新模型參數。②「另加一份修正」:LoRA。LoRA 原始研究以低秩矩陣表示學得的更新,與只保留/歸零的選擇空間不同。這裡的「秩」可先理解為修正能用多少獨立方向。

③「選哪些原數字停用」:Deletion Tuning。官方套用程式把目標權重乘上保留位元,不替留下的數字訓練新值。④「把整個零件裁掉」:結構裁剪。它可能減少通道或專家等結構;本篇小矩陣則保留相同形狀。PyTorch 裁剪教學可協助分清遮罩與結構維度,Shears 的裁剪與修復則是另一種具體案例。

所以,Mask 小、完整模型小、推論更快,是三張不同的收據。把某些格子寫成零,使用一般密集矩陣運算時,仍保有那些格子的儲存位置與矩陣維度。要主張加速,還需實際測量運行路徑;本篇不由零值比例推算速度。

三、Deletion Tuning 配對關:先認五個零件

①「底稿」:完整模型識別碼。這次選官方列出的 Qwen/Qwen2.5-0.5B,對應 grpo/qwen2.5-0.5b-simplerl-zoo。注意它是 Base,不能把名稱近似的 Instruct 當成同一份權重。1B 另一組是 meta-llama/Llama-3.2-1B-Instruct 配 grpo/llama-3.2-1b-instruct-gsm8k;本文後續只走前一組。

②「開關片」:Mask 資料夾。裡面有 config.json 與 model.safetensors。官方Mask 模型卡把不同基底、訓練方法與任務分開列出。看見同樣 0.5B 或同系列名稱,還不足以建立配對。

③「版本指紋」:revision。本篇查閱的程式碼 commit 是 94f0340ebb574f95bb41d844165253a6785e215e;Mask revision 是 dfe80f9fa54f34324e4dd64bea46521e30d930f0;Qwen 基底下載快照是 060db6499f32faf8b98477b0a26969ef7d8b9987。後者是本篇固定的公開快照,不是作者已證實的訓練 revision;發布 Mask 的設定檔未綁定那個雜湊,配對證據目前到模型名稱與形狀這一層。

④「接頭規格」:參數名稱與 shape。官方 apply_mask.py先檢查 Mask 的參數名是否存在,再檢查形狀相同,通過才逐格相乘。形狀不符就停下;不要裁切、補零或重排 Mask 硬套。形狀相同也只是必要檢查,不能證明另一個微調版本有相同語義。

⑤「紙袋與整本食譜」:容量分母。這份 Qwen Mask 的固定版 config記錄 zero_params=199564、total_params=104595456。此處分母是受 Mask 管理的投影參數;相除約 0.191%,不能冒充全模型歸零比例。compressed_size_mb也不是整個模型可執行所需記憶體。

四、上手五步:先保存底稿,再套用一份現成 Mask

以下在已有相容 Linux/CUDA 12.6、Python 3.10 與 uv 的測試機操作。官方環境說明為不同訓練路線分開建環境;這裡沿用 SFT 環境依賴來執行套用工具,不跑訓練。先替基底、輸出模型、下載快取與環境預留空間;沒有這些條件,就先完成考卷,不在日常主機盲裝 GPU 套件。

第 1 步:「我拿到哪份工具?」固定程式碼

git clone https://github.com/agentic-learning-ai-lab/deleting-weights.git deletion-lab
cd deletion-lab
git checkout 94f0340ebb574f95bb41d844165253a6785e215e
uv venv envs/sft --python 3.10
source envs/sft/bin/activate
uv pip install torch==2.7.1 --index-url https://download.pytorch.org/whl/cu126
uv pip install -r requirements_sft.txt
uv pip freeze > environment.txt

以 uv pip freeze 保存實際依賴,與版本指紋一起留存。確認套件清單含 Transformers 4.51.3、NumPy 1.26.4 與 zstandard 0.25.0;這些版號來自該 commit 的 依賴檔。先確認 PyTorch 能看到預期 GPU,再繼續;安裝成功和運算相容是兩件事。

第 2 步:「底稿會被覆寫嗎?」分開下載

在此資料夾建立 download_assets.py,貼入下方。Hub 下載文件說明 revision 與篩選檔案的用法。首次下載前打開Qwen 模型卡核對使用條件;Mask 也遵循對應基底的授權。

from huggingface_hub import snapshot_download
snapshot_download(
    "Qwen/Qwen2.5-0.5B",
    revision="060db6499f32faf8b98477b0a26969ef7d8b9987",
    local_dir="assets/base")
snapshot_download(
    "Jacklu0831/deletion-tuning-masks",
    revision="dfe80f9fa54f34324e4dd64bea46521e30d930f0",
    allow_patterns=["grpo/qwen2.5-0.5b-simplerl-zoo/*"],
    local_dir="assets/masks")

執行 python download_assets.py,確認基底與 Mask 位於不同子目錄。保留下載快照與 environment.txt;不要把套用結果存回 assets/base。上面的下載只篩選一組 Mask,不會要求把所有模型規模的 Mask 一起拿回來。

第 3 步:「先有成績,還是先改模型?」先跑 Base

先建立 cases.jsonl:每行一題,欄位固定為 id、task、question、gold。例如 {"id":"m01","task":"target","question":"Three boxes contain 8 pens each. Give away 5 pens. How many remain?","gold":"19"}。保留題的 task 寫 retention;依下一節原則補齊題集,三組共用同一個檔案。

再將下方存成 run_cases.py。這是本文的最小生成紀錄器,要求支援 BF16 的 CUDA GPU;它保存原始答案與 Token,評分欄由你依答案本補上。峰值欄量的是 PyTorch 配置的 CUDA 記憶體,並非整張卡總占用。套件、硬體與三份 revision 另放實驗紀錄;正式大量評估仍需另外加入批次排程、重試與評分器。

import json, pathlib, sys, time
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_path, arm, output = sys.argv[1:4]
assert arm in ("base", "masked", "reload")
assert torch.cuda.is_available() and torch.cuda.is_bf16_supported()
cases = [json.loads(x) for x in pathlib.Path("cases.jsonl").read_text().splitlines() if x.strip()]
assert cases and all(all(k in c for k in ("id", "task", "question", "gold")) for c in cases)
torch.cuda.synchronize()
t0 = time.perf_counter()
tok = AutoTokenizer.from_pretrained(model_path, local_files_only=True)
model = AutoModelForCausalLM.from_pretrained(
    model_path, torch_dtype=torch.bfloat16, local_files_only=True).to("cuda").eval()
torch.cuda.synchronize()
load_s = time.perf_counter() - t0
with torch.inference_mode():
    warm = tok("Question: 1 + 1 = ?\nAnswer:", return_tensors="pt").to("cuda")
    model.generate(**warm, do_sample=False, max_new_tokens=8, pad_token_id=tok.eos_token_id)
torch.cuda.synchronize()
with open(output, "x", encoding="utf-8") as f:
    for c in cases:
        prompt = "Question: " + c["question"] + "\nAnswer:"
        row = {"case_id": c["id"], "task": c["task"], "arm": arm,
               "model_path": model_path, "prompt": prompt, "gold": c["gold"], "load_seconds": load_s}
        try:
            batch = tok(prompt, return_tensors="pt").to("cuda")
            torch.cuda.reset_peak_memory_stats()
            torch.cuda.synchronize(); start = time.perf_counter()
            with torch.inference_mode():
                seq = model.generate(**batch, do_sample=False, max_new_tokens=128,
                                     pad_token_id=tok.eos_token_id)
            torch.cuda.synchronize()
            row["generation_seconds"] = time.perf_counter() - start
            n = batch["input_ids"].shape[1]
            ids = seq[0, n:].tolist()
            row.update(input_ids=batch["input_ids"][0].tolist(), output_ids=ids,
                       input_tokens=n, output_tokens=len(ids),
                       raw_output=tok.decode(ids, skip_special_tokens=True),
                       peak_memory_bytes=torch.cuda.max_memory_allocated())
        except Exception as e:
            row["error"] = type(e).__name__ + ": " + str(e)
        f.write(json.dumps(row, ensure_ascii=False) + "\n"); f.flush()

原版執行 python run_cases.py assets/base base base.jsonl;套用後執行 python run_cases.py outputs/masked-qwen05 masked masked.jsonl;撤回則執行 python run_cases.py assets/base reload reload.jsonl。每次都是獨立程序,輸出採新檔建立,重跑請換檔名。發生錯誤時先保留那列,停止後續比較並排查。

先用同一套生成程式載入 assets/base,完成下一節題集,保存為 base.jsonl。這是原版組。Qwen 0.5B 的官方 GRPO 評估腳本使用 --skip_chat_template;這個 Base 練習也採相同純文字補全模板,不把聊天角色模板偷偷加進某一組。

第 4 步:「套用的是哪一份?」另存修改版

python src/apply_mask.py \
  --base_model assets/base \
  --mask_dir assets/masks/grpo/qwen2.5-0.5b-simplerl-zoo \
  --output_dir outputs/masked-qwen05

看終端機是否完成參數名與形狀檢查,記下程式印出的刪除計數,再核對輸出資料夾內的模型與 tokenizer。此工具以 BF16(16 位元浮點格式)載入並另存完整模型;Mask 本身雖小,這份輸出仍是一份完整模型。接著用 outputs/masked-qwen05 跑同一題集,保存 masked.jsonl。

第 5 步:「怎麼撤回?」退出程序,重新載入底稿

退出修改版推論程序,重新開一個程序,載入原本的 assets/base,重跑相同考卷並存為 reload.jsonl。這是撤回組,不是再乘一片全 1 Mask。已變成零的數字乘 1 仍然是零;乾淨底稿才保存那些原值。先核對底稿檔案雜湊沒變,再比原版與撤回組的輸出。

五、三組評估工作表:新任務、保留能力與成本分開交卷

「有一題答得更好,就算成功嗎?」先把答案本寫完,再看輸出。下面是本篇建議的接線練習,不是論文成績重現:準備六題小學多步算術作為目標任務,另準備六題已知答案的一般補全/短知識題作保留任務。十二題是方便人工逐題檢查的起點,不是統計門檻;保留任務要先確認原版確實做得到。

例如算術題可用「每盒 8 枝筆,買 3 盒後送出 5 枝,剩多少?」;保留題可用「依序補完 Monday, Tuesday, …」或你能獨立核對的短句。題目先用固定語言與格式,答案與判分規則另存。要測繁中,就把繁中列為另一層,別把跨語言差異混進模型修改效果。

Deletion Tuning 三組對照:Base、Masked、Reload 使用同題與同設定,分開檢查能力與成本
建議評估流程,非模型結果。撤回組必須重新載入乾淨基底。圖/AlphaLab。

建立一個純文字提示模板,例如 Question: {題目} Answer:。三組固定同一 tokenizer、BF16、設備、do_sample=False、max_new_tokens=128 與停止條件;保存實際輸入 Token 和新生成 Token。這裡的 128 是練習預算,不是官方最佳設定。固定版生成文件可用來核對參數。

case_id,task,arm,base_revision,mask_revision,code_commit,
prompt,input_tokens,output_tokens,raw_output,gold,correct,
load_seconds,generation_seconds,peak_memory_bytes,error

一份輸出一列,錯誤也留一列。arm 寫 base/masked/reload;先遮住組別名稱,再依答案本評分。算術看最後答案,也另記步驟是否自相矛盾;一般題分開統計。只有語氣變流暢,並不等於目標能力提高。想建立更完整考卷,可接著讀 AI Evals 入門。

  • 新任務:比較同一題由錯轉對、由對轉錯與三組都錯的案例;保留原始文字供回查。
  • 保留能力:看原版答對的題目,修改後有多少仍答對;這是自有題集的保留觀察,不代表所有知識。
  • 撤回:先比輸入與環境,再比原版/撤回 Token 序列。若不同,先排查載入路徑與運算非確定性,不急著歸因為 Mask。
  • 成本:載入時間和生成時間分開,暖機後重複測;GPU 計時須同步,記下生成長度、峰值記憶體與錯誤。

PyTorch 的可重現性說明提醒跨平台、版本與運算路徑的差異;即使關掉抽樣,也要記錄環境。CUDA 同步介面則能避免只量到非同步工作排隊的時間。比較檔案容量時,分開記 Mask、乾淨基底、完整修改版與下載快取,別只拿最小那一包做結論。

這張表先回答「接線與評分是否完整」。若要研究論文效果,還需按官方資料分割、評估腳本與配置跑完整基準。官方 retention 腳本針對 Llama 的 GRPO 路線設計;本文 Qwen 小練習的十二題,不能冒稱已重現那套遺忘評估。

六、論文證明到哪裡?把興奮留給正確的範圍

作者在 論文實驗章報告:這種學得的刪除選擇,能在所測後訓練任務帶來增益,大規模設定的成績接近全量微調。這是作者在指定模型與測試下的觀察;小模型成績不應直接套用大模型結論,也不代表隨機刪除有效。

更值得新手帶走的是兩個問題:增益是不是來自學到的 Mask?原本會的東西保留多少?本文不轉貼基準排行榜,而讓三組小考先對準這兩個問題。至於學習成本,論文明列訓練仍要為受控權重保存可訓練門控,記憶體需求高於 LoRA;成品是位元 Mask,並不表示學出它時也只用那麼小的記憶體。

本次也不把 Heretic 社群整合猜想、跨模型轉移或 GPU 加速當作已驗證能力。將現成 Mask 用在原配基底,和移植到另一個同形狀模型,是兩個實驗。每跨過一層,都要重寫假設與考卷。

常見問題:八個先講答案的判斷

1. 刪權重也能學習,代表知識本來就完整藏好了嗎?

還不能下這個結論。研究顯示選擇性歸零能改善特定任務;它沒有逐項定位所有知識,也沒有證明任意新能力都能靠刪除取得。

2. Mask 裡的 0,是保留還是刪除?

在本文官方載入器中,True/1 表示保留,False/0 表示歸零。讀第三方格式前先查語義,別只憑檔名判斷。

3. 同樣 Qwen、大小不同,可以互套嗎?

不要互套這份練習。官方套用器要求參數名稱與形狀相符;本篇只使用模型卡列出的精確配對。

4. Base 與 Instruct 可以交換嗎?

本篇不交換。即使某些張量形狀相同,模型權重不同仍改變實驗;要另立研究與對照,不能沿用這份配對的效果。

5. 撤回就是把 Mask 移除嗎?

對已另存的修改版,請重新載入乾淨基底。套用器已把數字原地乘成零,移除檔案不會把那些數字寫回去。

6. 現成 Mask 小,運行顯存也會等比例變小嗎?

不能由此推論。套用工具輸出完整 BF16 模型,運行還有中間狀態與生成快取,應實際量測。

7. 十二題都進步,就算重現論文嗎?

不算。那是你這批題目的觀察;論文基準的資料、採樣與評估條件需另外對齊。

8. 不會寫程式,今天可以先完成什麼?

先做一張配對卡:完整模型名、Mask 路徑、三個版本指紋、目標題、保留題與撤回位置。能解釋這六欄,就已有可執行的評估計畫。

給新手的三個重點

  • 學得的開關決定保留或歸零;它與寫入新權重、裁掉整個結構各有不同。
  • 精確配對先於調參。名稱、版本、形狀與原始基底一起保存。
  • 小 Mask、任務增益、能力保留與執行成本各自交卷;撤回是重新載入底稿。

下一步:先留好能回去的底稿

記住這個式子:Deletion Tuning=原權重 × 學得的開關。今天先確認一份原配 Mask,保存乾淨基底,再寫下相同的目標題與保留題。等原版、修改版與撤回組能逐題對上,你才有一張值得討論的成績單。想把這種評估習慣接進自己的 AI 工作,可以從 AI 文章總覽選下一個練習,或到 AlphaLab 課程安排系統化學習。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

週日 Weekly 週報+週二、週四 Alpha Signal,每週最多三封。

我們不會 spam,隨時可退訂。已訂閱?管理訂閱偏好(會寄登入連結到你的信箱)

主題篩選與退訂說明

寄送日期以台灣時間為準。主題偏好會篩選每期精選,並非每篇新文章的即時通知;當期符合主題的文章不足時會略過寄送。

未勾選任何主題會收到所有主題的精選,並不會停止寄信。

取消勾選 Alpha Signal 可停止週二、週四短報,仍保留週日週報。若要停止所有電子報,請使用信件底部的「取消訂閱」。