Communityコーディング&開発github.com

weight-space-programming

小さなオープンLLM(例:Qwen3.5-0.8B)の重みを直接編集することで、トレーニングなしで目標を改善します(「重み空間プログラミング」)。数学(MATH-500)と科学(MMLU-Pro)の既成プリセット完備。任意のベンチマークや振る舞い(形式、言語、冗長性、迎合、ループなど)は、独自のプロンプトとマッチングした例ペアから設定可能。

weight-space-programming とは?

このスキルは、小さなオープンソース言語モデル(例:Qwen3.5-0.8B)に対して、従来のトレーニング(逆伝播や最適化)を一切行わず、重みを直接編集することで特定の目標性能を向上させる手法(「重み空間プログラミング」)を実装しています。MIT CSAILの研究論文「Sparks of Weight-Space Programming」の実験8に基づき、モデルのMLP層内の`down_proj`カラムを特定の方向に編集することで、思考ループなどの不要な振る舞いを抑制します。数学(MATH-500)や科学(MMLU-Pro)のプリセットに加え、ユーザーが定義した任意の振る舞い(形式、言語、迎合、ループなど)にも対応可能で、そのためのプロンプトとマッチングペアの作成方法も提供されます。スキルはClaude Code、Cursor、CodexなどのAIエージェント上で動作し、失敗時の再開、評価結果に基づく段階的なエスカレーション、明確な判定基準など、堅牢なプロトコルを備えています。GPU上で約1.5~3時間でプリセットの実行が完了し、編集が有効かどうかを検証ゲートとホールドアウトテストで厳密に判定します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/di37/weight-space-programming-skill/tree/HEAD

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

重み空間プログラミング

小さなオープンモデルの重みを直接編集することで、最適化器を使わずに目標を改善します。これは「Sparks of Weight-Space Programming」(Takehi, Teoh, Zhang, Khattab, MIT CSAIL, 2026年11月2日)の実験8に従っています。Qwen3.5-0.8Bの思考ループは、レイヤー15と19のMLPによって書き込まれた1つの残差方向に起因し、各レイヤーの64個のdown_projカラムに対するランク1編集により、MATH-500スコアが7.9%から48.1%に向上しました。

以下の高速パスを順番に実行してください。 すべてのスクリプトはscripts/にバンドルされ、テスト済みです。ステップが失敗しない限り、パイプラインを再設計したり、新しいツールを作成したりしないでください。

このスキルが保証すること、そしてできないこと。 どの方法も編集が必ず役立つとは約束できません。一部のモデルには、オフにできる単一の習慣がありません。スキルは代わりにプロセスを保証します。

  • 作業の損失なし:クラッシュ時はより小さいバッチで再開します。
  • 測定済みのプラクティスチェックに合格するまで、編集はホールドアウトテストに到達しません。
  • チェック失敗時は、停止する代わりに固定されたステップでエスカレーションします。
  • すべての実行は明確な判定と数値で終了し、何も機能しなかった場合はコピーが復元されます。

参考資料(詳細のみ):

  • references/goals.md:他の目標、マッチングペアの書き方、評価器、レシピ。
  • references/engines.md:各OSとGPUのエンジン、インストール、サイジング、落とし穴、スモークテスト。
  • references/evaluation.md:分割、サンプリングプロトコル、MMLU-Proの詳細、ペア統計、レポートテンプレート。
  • references/method.md:各ステップの数学と著者の正確なレシピ。

高速パス

4つのプレースホルダーを一度設定します(PowerShell:$env:SKILL = "..."、次に$env:SKILL):

SKILL=<このスキルのフォルダ>  BASE=<ベースモデルフォルダ>  COPY=<ベースモデルフォルダ>-<目標>  WORK=<結果フォルダ>

すべての生成ジョブをバックグラウンドで実行し(Claude Code:Bashツールのrun_in_background、シェルの&ではありません)、ポーリングではなく完了通知を待ちます。生成が時間を支配するので、事前にユーザーに予算を伝えてください:コンシューマGPUでプリセットの場合1.5〜3時間、データセンターGPUでvLLMを使用する場合はもっと短くなります。

0. 必要なことだけを尋ねる(1つの質問)。目標を尋ねます。数学または科学の場合はプリセットを使用します:これ以上の質問は不要です。それ以外の場合は、以下も尋ねるか、作成を支援します。

  • 失敗を示すプロンプト({"id", "prompt", "answer"?, "group"?} JSON Lines形式)。
  • それらをスコアリングする方法(references/goals.mdセクション3)。
  • ループ以外の振る舞いの場合、12以上のマッチングペア(セクション2)。

「重み編集、トレーニングなし」を確認します。

1. マシンをチェックする(2分):python $SKILL/scripts/device.py --model $BASE --jobs 2。新しいマシンでは、references/engines.mdセクション6のスモークテストも実行します。

2. モデルをコピーする(1分)。すべての編集はこのコピーのファイルに適用されます。すべての評価はコピーをロードします。

python $SKILL/scripts/copy_model.py --base $BASE --copy $COPY

3. 分割(数秒)。

  • 科学プリセット: python $SKILL/scripts/make_splits.py --task mmlu --source <MMLU-Proテストparquetファイル> --out $WORK/splits。
  • 数学プリセット: 同様に --task math --source <MATH-500テスト.jsonl> --practice 25 --heldout 75。
  • 独自の目標: プロンプトファイルを固定ルールでpractice.jsonlとheldout.jsonlに分割し、さらに約30個のホールドアウトIDを含むtest_ids.txtを作成します。これらはすべて、回答が確認される前に選択されます。

以下、Tはタスク(mmlu、math、またはjsonl)、Gは評価器オプション(プリセットの場合はなし。それ以外はreferences/goals.mdを参照)です。

4. 2つのベース実行を同時に開始する:

python $SKILL/scripts/run_eval.py --task $T --model $BASE --label base --data $WORK/splits/practice.jsonl --out $WORK/practice/base.jsonl --max-tokens 16384 --jobs 2
python $SKILL/scripts/run_eval.py --task $T --model $BASE --label base --data $WORK/splits/heldout.jsonl --ids-file $WORK/splits/test_ids.txt --out $WORK/test/base.jsonl --jobs 2

他のモデルにはモデルカードのサンプリングを使用します(--profile、またはオーバーライドフラグ。references/engines.md)。ホールドアウト実行は編集に依存しません。

5. コントラストを取得する。

  • ループ(プリセット、または回答が上限に達する目標): ループは回答が上限に達した場合にのみ現れます。grep -c '"length"' $WORK/practice/base.jsonlでカウントします。15以上の場合、プラクティス実行を停止します。
  • その他の振る舞い: ペアが必要です。プラクティス実行はベースラインを与えるために完了する必要があるだけです。

次に評価します:

python $SKILL/scripts/grade.py --task $T $G $WORK/practice/base.jsonl --out $WORK/practice/summary.json

Go/No-go。 改善の余地を見積もります:振る舞いを示す回答の割合×振る舞いを示さない回答のスコア。約10%未満の場合は、先に進む前にユーザーにあまり期待できないことを伝えます。

6. 方向を読み取り、候補を構築し、スクリーニングする(数分、フォワードパスのみ)。ループ:

python $SKILL/scripts/probe.py collect --task $T --model $BASE --data $WORK/splits/practice.jsonl --runs $WORK/practice/base.jsonl --out $WORK/probes

ペア(クリーンな副作用ウィンドウのために--runs、--data、--taskを追加):

python $SKILL/scripts/probe.py collect-pairs --model $BASE --pairs pairs.jsonl --thinking on --out $WORK/probes

次に、第1ラウンドの候補、コントロール、スクリーニングを構築します:

for spec in "15 19:128:6" "15 19:256:6" "15 19:64:6" "11 15 17 19 21:128:6"; do IFS=: read L K A <<< "$spec"; python $SKILL/scripts/probe.py build --probes $WORK/probes --model $BASE --layers $L --k $K --alpha $A --out "$WORK/edits/L${L// /-}_k${K}_a${A}.safetensors"; done
python $SKILL/scripts/probe.py build --probes $WORK/probes --model $BASE --layers 15 19 --k 128 --alpha 6 --control random --out $WORK/edits/random.safetensors
python $SKILL/scripts/probe.py screen --probes $WORK/probes --model $BASE --edits $WORK/edits/*.safetensors

Windows PowerShellでは、各build行を個別に実行します。上記のレイヤーは24層モデルに適しています。他のモデルでは、深さの約60%と80%のレイヤー、5層のスパン、およびより深い層を単独で使用します。

候補をunwantedの低下でランク付けし、wantedとcleanの低下がその3分の1未満のもののみを保持します。ランダムコントロールは0付近に留まる必要があります。もしランダムコントロールが最良の候補と同じくらい動く場合、方向は特異的ではないため、停止ステップに進みます。

7. 最良の候補をコピーに書き込んで検証する(1分)。インメモリ編集を評価しないでください。

python $SKILL/scripts/apply_edit.py --base $BASE --copy $COPY --edit $WORK/edits/<候補>.safetensors
python $SKILL/scripts/diff_edit.py --base $BASE --edited $COPY --out $WORK/edit_report.json

diffは、意図したdown_projテンソルのみ、changed_columns = k、ランク1の割合が約1、αの中央値が選択した約αを示す必要があります。

8. プラクティスチェック:ゲート(15〜25分、ベースのホールドアウト実行と並行して)。ベースが失敗した(カット、誤り、またはフラグ付き)すべてのプラクティス質問と、うまく処理した6つの質問に対してコピーを実行します:

python -c "import json; g=json.load(open('$WORK/practice/summary.json'))['graded']['base']; bad=[x['id'] for x in g if x['cut'] or x['correct'] is False or x['flagged']]; ok=[x['id'] for x in g if x['id'] not in bad]; open('$WORK/check_ids.txt','w').write('\n'.join(bad+ok[::max(1,len(ok)//6)][:6])+'\n')"
python $SKILL/scripts/run_eval.py --task $T --model $COPY --label copy --data $WORK/splits/practice.jsonl --ids-file $WORK/check_ids.txt --out $WORK/practice/copy.jsonl --max-tokens 16384 --jobs 2
python $SKILL/scripts/grade.py --task $T $G $WORK/practice/base.jsonl $WORK/practice/copy.jsonl

ゲート通過は以下の3つすべてが成立する場合のみ:

  • 修正数 ≥ max(3, チェックされたベース失敗の20%)、
  • 破損数 ≤ 修正数 ÷ 4、
  • そして、ループ目標の場合、カット割合が少なくとも4分の1減少する。

合格:ステップ10へ。失敗:ステップ9へ。

9. 次の順序でエスカレーションします。各段階は1回の追加プラクティスチェックです。

  1. 次にランク付けされた候補。 コピーを復元し(copy_model.py --base $BASE --copy $COPY --restore)、それを適用し、ステップ7〜8を繰り返します。これを最大2つの追加候補に対して行います。
  2. ラウンド2。振る舞いが消えたのではなく移動した場合。 例えば、思考が閉じるようになったが、 responseの後にループが再開する、またはコピーの回答に新しい不要なパターンが現れる場合など。編集済みコピーを新しいベースとして扱います:
    • copy_model.py --base $COPY --copy $COPY2でCOPY2を作成します。
    • probe.py collect(またはcollect-pairs)を--model $COPY --runs $WORK/practice/copy.jsonlで実行します。
    • --model $COPYで構築およびスクリーニングします。
    • --base $COPY --copy $COPY2で適用します。
    • ステップ8と同様にCOPY2をチェックします。
  3. 停止。 3回のチェック後(またはユーザーが設定した時間予算後)、信頼できる改善なし。コピーを復元し、「信頼できる改善なし」という判定を各候補の数値と共に報告します。Qwen3.5-0.8Bの場合、公開されている数学編集を比較として提供します(著者のログではMMLU-Proのカット割合を28.9%から0.5%に削減しました。このファイルの最後を参照)。ユーザーが同意した場合のみ使用してください。

ホールドアウト結果を選択に使用しないでください。プラクティスチェックのみが決定します。

10. コピーからのホールドアウトテスト(30〜60分)。ベースのホールドアウト実行が最も長い回答を過ぎたら開始します:

python $SKILL/scripts/run_eval.py --task $T --model $COPY --label copy --data $WORK/splits/heldout.jsonl --ids-file $WORK/splits/test_ids.txt --out $WORK/test/copy.jsonl --jobs 2
python $SKILL/scripts/grade.py --task $T $G $WORK/test/base.jsonl $WORK/test/copy.jsonl --out $WORK/test/summary.json

ペア結果から判定を示します:

  • 「明確な改善」:修正数 > 破損数、かつ符号検定p < 0.05の場合。
  • 「改善と一致するが証明されていない」:修正数 > 破損数だがp ≥ 0.05の場合。より大規模なテストを推奨します。
  • 「改善なし」:修正数 ≤ 破損数の場合。コピーの復元を推奨します。

11. references/evaluation.mdのテンプレートを使用して報告する:

  • ホールドアウトスコアの前後、およびペアの修正/破損カウント。
  • 振る舞い率(カット、フラグ付き、思考クローズ)。
  • 各候補とそのスクリーンおよびチェック数、およびランダムコントロール。
  • 変更された重み。
  • 注意点:習慣をオフにすることは新しい能力ではないこと。

以前に時間を浪費した間違い(繰り返さないこと)

  • バッチが大きすぎる、または2つの長時間ジョブがピーク時に重なる。 メモリ不足クラッシュは進行中の回答を破棄します。ループはこれにあたります。--batch auto --jobs 2を使用し、最初の32kジョブが最長の回答中にあるときに2つ目の32kジョブを開始しないでください。スーパーバイザーはクラッシュした実行を半分のバッチで再開します。
  • 実行全体を待つ。 約15ループで十分です。
  • 評価のためのインメモリ編集。 probe.py screenのみがインメモリで編集を適用し、それも教師強制読み取りのみです。
  • スクリーンだけを信頼する。 ループでのスクリーン低下-0.10は、生成中に26ループ中3つしか破損しませんでした。そのため、常にゲートを実行してください。
  • 部分的な実行を評価する、または先に終了したものからテスト問題を選択する。
  • pkill -f <text>でジョブを停止する。 これはコマンドラインにそのテキストを含むウォッチャーも停止します。

ルール(投稿通り)

これらを守り、報告書で守ったことを述べてください。

  • トレーニングなし。 逆方向パス、autograd、最適化器、または損失に対する重みの反復フィッティングは禁止。指標が向上するまでαまたは重みを微調整することはフィッティングとみなされます。上記の固定候補リストから選択することはフィッティングではありません。
  • 測定のためのフォワードパスは許可: 生成、教師強制ログ確率、隠れ状態とMLP活性化、およびそれらの統計量、または重みの統計量(平均、差分、SVD)。
  • 範囲外:
    • 埋め込み、(タイド)出力ヘッドおよび最終ノルム(weights.pyが拒否)。
    • テンソル全体を定数で乗算すること。
    • グローバルなシャープ化または平坦化。
    • 問題に関係なく思考を早期に強制終了すること。
    • 安全動作の除去:拒否、セーフガード、有害リクエストへの準拠。
  • 重みの値のみ変更。 名前、形状、dtype、設定、トークナイザー、チャットテンプレート、デコード設定は保持します。
  • 分割規律。 編集前に固定された、重複しないプラクティスセットとホールドアウトセット。ホールドアウト結果は、編集が確定した後に一度だけ確認します。
  • 開示された選択。 報告書は試行されたすべての候補と、勝者を選択した指標をリストします。

各ステップがその理由

  • コントラスト: 方向は、各レイヤーの出力において、それ以外はマッチングされた不要テキストと必要テキストの平均差です。
    • ループの場合、loops.pyはループ発症の直前の1,024トークンとループ内部の1,024トークンを取得します:同じ質問、同じ回答、ほぼ同じ位置。発症点は、次の512トークンの90%が以前の16-gramを繰り返す最初の点です。
    • 他の振る舞いの場合、ペアがマッチングを提供します。
  • ライターカラム: score_j = (平均不要 − 平均必要活性化 of neuron j) × (u · W_down[:, j]);上位kを取得します。静的なu·Wだけでは不十分です:公開された64カラムのうち21〜22のみがその上位64に含まれています。
  • 編集: W'[:, S] = W[:, S] − α u (uᵀ W[:, S])、編集されるモデルからfloat32で計算。α = 1で成分を削除しますが、ループには効果がありませんでした。α = 6で−5cに反転し、それらのニューロンが振る舞いに逆らって書き込みます。
  • スクリーニング: 編集を適用したときの平均ログ確率の変化。不要テキストの可能性が低くなり、必要テキストとクリーンテキストはそのままであるべき。同じカラム上のノルム一致ランダム方向がコントロールです。
  • ゲート: スクリーン数値は生成を緩やかにしか予測しないため(以下の結果を参照)、プラクティス質問に対する短い生成チェックがホールドアウトテストの前に判断します。
  • 保存: weights.pyは生ファイルから影響を受けるsafetensorsシャードのみを書き換えます。推論エンジンはロード時にテンソルを書き換えたりドロップしたりするため、エンジンから重みを保存しないでください。
  • プロトコル: thinking on, temperature 0.6, top_p 0.95, top_k 20, presence penalty 1.5(生成トークンのみ)、32,768 new tokens(--profile thinking)。すべてのエンジンがvLLMのセマンティクスに一致します。
  • ペアリング: エンジンとバッチサイズは乱数を変更するため、1つの比較内で質問ごとにペアにします。異なる質問や異なるエンジンで測定されたスコアを比較しないでください。

R

…

[翻訳のため省略]

関連スキル