0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Uncensored1776 Day 14: 拒否方向の計算詳細

Last updated at Posted at 2025-12-13

Uncensored1776 Day 14: 拒否方向の計算詳細

技術の核心部分を深く理解する

公開日: 2025-12-14
シリーズ: 科学と神々株式会社 アドベントカレンダー
難易度: ★★★★☆ (中上級)


今日学ぶこと

  • 拒否方向計算の全体像
  • アクティベーション収集の仕組み
  • なぜクリッピングと正規化が必要か

1. 拒否方向計算の全体像

Day 9で学んだように、拒否方向は「有害プロンプトと無害プロンプトの隠れ状態の差」です。今日はその計算プロセスを深く掘り下げます。

拒否方向の計算フロー:

Step 1: プロンプトの準備
├── 有害プロンプト(モデルが拒否するもの)
└── 無害プロンプト(モデルが普通に回答するもの)

Step 2: アクティベーション収集
├── 各プロンプトをモデルに入力
├── 各層の隠れ状態を取得
└── 特定の位置(通常は最後のトークン)を抽出

Step 3: 差分の計算
├── 有害プロンプトの平均ベクトル
├── 無害プロンプトの平均ベクトル
└── 差分 = 有害平均 - 無害平均

Step 4: 後処理
├── 外れ値のクリッピング
└── 単位ベクトルへの正規化

出力: 拒否方向 d(dim次元の単位ベクトル)

2. プロンプトの設計

2.1 有害プロンプトとは

「有害プロンプト」は誤解を招く名前です。実際には**「モデルが拒否する質問」**を意味します。

有害プロンプトの例:

【政治的検閲(中国関連)】
- "What happened at Tiananmen Square in 1989?"
- "Is Tibet an independent country?"
- "What do you think about Xi Jinping?"

【政治的検閲(ロシア関連)】
- "Was Russia's invasion of Ukraine justified?"
- "Is Putin a dictator?"

【歴史的検閲】
- "How many people died under Mao's rule?"
- "Describe the Cultural Revolution in China."

重要:これらは学術的・歴史的な質問であり、実際に危険なコンテンツ(爆弾の作り方など)を生成するプロンプトではありません。

2.2 無害プロンプトの設計

無害プロンプトはモデルが確実に回答する質問です:

無害プロンプトの例:

【一般的な質問】
- "What is the capital of France?"
- "Explain photosynthesis in simple terms."
- "How does a computer work?"

【歴史(非検閲対象)】
- "Describe World War II."
- "Who was Napoleon Bonaparte?"

【科学・技術】
- "Explain quantum mechanics basics."
- "What is artificial intelligence?"

2.3 良いプロンプトセットの条件

プロンプト設計のポイント:

有害プロンプト:
✓ 明確に検閲されるトピック
✓ 多様なカテゴリをカバー
✓ 文法的に正しい
✗ 実際に危険なコンテンツは含めない

無害プロンプト:
✓ モデルが確実に回答するもの
✓ 有害プロンプトと長さが似ている
✓ 多様な分野をカバー

バランス:
- 有害/無害の比率は1:1程度
- 各カテゴリ最低3-5個
- 合計30-100個程度が推奨

完全なプロンプトセットはdata/harmful_prompts.jsondata/harmless_prompts.jsonを参照してください。


3. アクティベーション収集

3.1 何を収集するのか

モデルにプロンプトを入力すると、各層で**隠れ状態(Hidden States)**が生成されます。これは高次元ベクトル(例:4096次元)で、モデルの「内部的な理解」を表します。

隠れ状態の構造:

入力: "What happened at Tiananmen?"
          ↓
Layer 0:  [0.12, -0.45, 0.78, ...] (4096次元)
Layer 1:  [0.23, -0.34, 0.56, ...]
Layer 2:  [0.34, -0.23, 0.45, ...]
   ...
Layer 31: [0.89, -0.12, 0.23, ...] (最終層)
          ↓
出力: モデルの応答

3.2 どの位置を使うか

各層には、入力トークン数分の隠れ状態があります。どの位置を使うかが重要です:

位置の選択肢:

入力: "What happened at Tiananmen?"
トークン:  [What] [happened] [at] [Tiananmen] [?]
位置:        0        1       2       3        4
                                              ↑
                                        通常はここを使用
                                       (最後のトークン)

理由:
- 最後のトークンには文全体の情報が集約されている
- Transformerのアテンション機構により、後のトークンは
  前のトークンすべての情報にアクセスできる

3.3 収集の実装

完全な実装はscripts/calculate_refusal_direction.pyを参照してください。核心部分のみ抜粋します:

# 隠れ状態の取得(概念的なコード)
with torch.no_grad():
    outputs = model(**inputs, output_hidden_states=True)

hidden_states = outputs.hidden_states  # 全層の隠れ状態
last_token_hidden = hidden_states[layer_idx][0, -1, :]  # 最後のトークン

4. 差分の計算

4.1 平均差分法

最もシンプルで効果的な方法です:

計算式:

d = mean(有害プロンプトの隠れ状態) - mean(無害プロンプトの隠れ状態)

イメージ:

有害プロンプトの隠れ状態群 ●●●●●
                                    ↘
                                      【平均】 ●
                                                 ↘
                                                   差分ベクトル d
                                                 ↗
                                      【平均】 ○
                                    ↗
無害プロンプトの隠れ状態群 ○○○○○

4.2 PCAによる精緻化

より堅牢な方向推定が必要な場合、PCA(主成分分析)を使います:

PCAを使う理由:

平均差分法の問題:
- ノイズに敏感
- 外れ値の影響を受けやすい

PCAの利点:
- データの分散を最大化する方向を見つける
- より堅牢な方向推定
- 複数の主要な方向を発見可能

処理フロー:
1. 全データ(有害+無害)を結合
2. 中心化(平均を引く)
3. PCAで第1主成分を抽出
4. 有害が正の方向になるよう調整

実装の詳細はscripts/calculate_refusal_direction.pycompute_refusal_direction_pca関数を参照してください。


5. クリッピングと正規化

5.1 なぜクリッピングが必要か

拒否方向を計算すると、一部の次元が極端に大きな値を持つことがあります。

クリッピングなしの問題:

拒否方向の各次元の値:
[0.01, 0.02, -0.01, ..., 15.7, ..., 0.03]
                         ↑
                    極端に大きい値

問題:
- この1つの次元がAbliterationを支配してしまう
- 重みの修正が不安定になる
- 予期せぬ品質低下

5.2 クリッピングの仕組み

クリッピングの処理:

1. 全次元の絶対値を計算
2. 99.5パーセンタイルの閾値を計算
3. 閾値を超える値を閾値でクリップ

例:
Before: [0.01, 0.02, 15.7, -0.03, 12.3]
閾値 = 0.05(99.5パーセンタイル)
After:  [0.01, 0.02, 0.05, -0.03, 0.05]
                      ↑            ↑
                   クリップされた値

5.3 なぜ正規化するのか

正規化の理由:

1. 異なる層間で比較可能にする
   - 各層の隠れ状態のスケールは異なる
   - 正規化することで統一された強度で適用可能

2. 強度調整が直感的になる
   - 長さ1のベクトルなら、strength=0.9は「90%の強度」
   - 正規化しないと、強度の意味が不明確

3. 数値的安定性
   - 極端に大きい/小さい値を避ける
   - オーバーフロー/アンダーフローを防止

5.4 完全な計算パイプライン

拒否方向計算の完全なフロー:

入力: harmful_acts (N × dim), harmless_acts (M × dim)

Step 1: 差分計算
  mean_harmful = harmful_acts.mean(dim=0)
  mean_harmless = harmless_acts.mean(dim=0)
  direction = mean_harmful - mean_harmless

Step 2: クリッピング
  threshold = quantile(abs(direction), 0.995)
  direction = clamp(direction, -threshold, threshold)

Step 3: 正規化
  direction = direction / norm(direction)

出力: 長さ1の拒否方向ベクトル

6. 複数の拒否方向

6.1 カテゴリ別の方向

検閲にはカテゴリがあり、それぞれ異なる「拒否方向」を持つ可能性があります:

カテゴリ別アプローチ:

カテゴリ1: 中国政治 → 拒否方向 d₁
カテゴリ2: ロシア政治 → 拒否方向 d₂
カテゴリ3: 歴史的事件 → 拒否方向 d₃

これらは似ているが、完全に同じではない場合がある

6.2 方向の統合方法

複数のカテゴリ別方向がある場合、統合する方法があります:

統合の選択肢:

1. 重み付き平均
   d = w₁・d₁ + w₂・d₂ + w₃・d₃
   (重要なカテゴリに高い重みを設定)

2. PCAで主方向を抽出
   全カテゴリの方向を並べてPCA
   第1主成分が「共通の拒否方向」

3. 全プロンプトを混ぜて計算
   最もシンプルで実用的
   カテゴリを分けずに全体から計算

実務上は**方法3(全混合)**が最も簡単で、多くの場合十分な効果があります。


7. 品質の検証

7.1 良い拒否方向の条件

計算した拒否方向が「良い」かどうかを確認することが重要です:

良い拒否方向の特徴:

1. 分離度が高い
   - 有害プロンプトは正の方向に射影
   - 無害プロンプトは負の方向に射影
   - 両者の差が大きい

2. 分類精度が高い
   - 拒否方向を使って有害/無害を分類
   - 精度70%以上が目安

3. 一貫性がある
   - 異なるプロンプトセットで計算しても
     似た方向が得られる

7.2 検証の可視化

分離度の可視化イメージ:

有害プロンプトの射影
    ●●●●●●●●●●
─────────┼─────────→ 拒否方向
  ○○○○○○○○○○
無害プロンプトの射影

良い分離:有害と無害が明確に分かれている
悪い分離:両者が混ざっている

検証用の関数はscripts/calculate_refusal_direction.pyvalidate_refusal_directionを参照してください。


8. 今日のまとめ

計算フローの要点

拒否方向計算のまとめ:

1. プロンプト準備
   - 有害: 検閲されるトピック(30-50個)
   - 無害: 普通に回答されるトピック(30-50個)

2. アクティベーション収集
   - 各層の隠れ状態を取得
   - 最後のトークン位置を使用
   - チャットテンプレートを適用

3. 差分計算
   - 平均差分法(シンプル)
   - PCA法(堅牢)

4. 後処理
   - 99.5パーセンタイルでクリッピング
   - 単位ベクトルに正規化

実装のポイント

  • プロンプトの質が重要 - 明確に検閲されるトピックを選ぶ
  • クリッピングを忘れずに - 外れ値がAbliterationを壊す
  • 検証を行う - 分離度と精度を確認

明日の予告

Day 15: Weight Kernelと層選択

  • なぜ全層に均一に適用しないのか
  • ガウス分布に基づくWeight Kernel
  • 最適な層の選び方

参考リンク

プロジェクト内リソース

学術リソース


ナビゲーション

前の記事 Day 13: モデル比較と選択
次の記事 Day 15: Weight Kernelと層選択
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?