このリポジトリには、Hannah Cyberey氏とDavid Evans氏によるSteering the CensorShip: Uncovering Representation Vectors for LLM "Thought" Controlのコード実装が含まれています。
私たちは、モデル出力における検閲のレベルを検出・制御するために、LLM内部から「ステアリングベクトル」を見つける手法を紹介します。私たちの研究の概要については、こちらのブログ記事をご覧ください。
デモを試してみてください:
注: 両方のデモにはHuggingfaceアカウントが必要です。Huggingfaceの ZeroGPU でホストされており、すべてのユーザーが1日あたりの利用枠付きで無料で利用できます。
リポジトリをダウンロードします:
git clone https://github.com/hannahxchen/llm-censorship-steering.git
cd llm-censorship-steering
Python 3.11以上で仮想環境を作成し、アクティベートします:
conda create -y -n censorship-steering python=3.11
conda activate censorship-steering
依存関係をインストールします:
pip install -r requirements.txt
ステアリングベクトルを見つける
命令追従モデル(instruction model)の検閲ステアリングベクトルを見つけるには、次を実行します:
python -m llm_steering.run \
--run_train \
--model_name meta-llama/Llama-2-7b-chat-hf \
--censor_type refusal \
--n_train 1000 --n_val 500 \
--threshold 0.1 \
--filter_layer_pct 0.2
設定ファイルは指定したディレクトリに保存されます。あるいは、llm_steering/config.py で定義されている形式に従ったYAML設定ファイルを渡すことで、python -m llm_steering.run --config_file CONFIG_FILE を使用することもできます。
推論モデル(reasoning model)の場合は、次の設定を使用します:
python -m llm_steering.run \
--run_train \
--model_name deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \
--censor_type thought_suppress \
--n_train -1 --n_val 1000 \
--threshold 0.1 \
--filter_layer_pct 0.05 \
--save_dir SAVE_DIR
ステアリングベクトルの適用
ステアリングベクトルを適用するには、次のコマンドを使用します:
python -m llm_steering.run
--run_steering \
--config_file SAVE_DIR/config.yaml \
--generation_batch_size 8 \
--coeff -1 \
--datasets jailbreakbench ccp_sensitive
--coeff で単一の係数を設定するか、--min_coeff、--max_coeff、--increment を使って係数の範囲を設定できます。デフォルトでは、-1から1まで0.2刻みの値を適用します。すべてのモデル出力は SAVE_DIR/evaluation/ に保存されます。
llm_steering/run.py の全引数:
(トレーニングと検証用)
model_name: Huggingface上のモデルリポジトリの名前を使用します。censor_type: 命令追従モデルでは "refusal"、推論モデルでは "thought_suppress" を使用します。method: 候補ベクトルを計算する手法。利用可能なオプション:WMD(加重平均差)、MD(平均差)。デフォルトは WMD です。n_train, n_valid: トレーニング用と検証用のサンプル数。-1の場合はすべてのサンプルを使用します。threshold: 検閲済み/非検閲サンプルをラベル付けするためのしきい値スコア。filter_layer_pct: 最後のNパーセントのレイヤーをフィルタリングします。save_dir: 結果を保存するディレクトリパス。(ステアリングベクトルの適用用)
run_steering: 見つかったステアリングベクトルを適用します。compute_projection: スカラー射影を計算します。datasets: ステアリングを適用するデータセット。(利用可能なデータセットは下記参照)layer_ids: 介入するレイヤーID。デフォルトでは、ベクトル検証中に特定された最上位レイヤーのみを使用します。coeff: 単一の係数値を実行します。min_coeff: 最小係数。max_coeff: 最大係数。increment: 係数の増分。max_new_tokens: 生成するトークンの最大数。num_return_sequences: 入力ごとに生成するシーケンス数。top_p: サンプリングのTop P値。temperature: サンプリングの温度。(共通引数)
config_file: YAML設定ファイルへのパス。use_cache: 保存されているキャッシュ結果を再利用します。プロセスを再開したいが、全体を再実行したくない場合に便利です。スクリプトは保存済みのアーティファクト(例:前処理済みのトレーニング/検証データ、ある係数で生成された出力)を再利用/スキップします。batch_size: アクティベーション抽出のバッチサイズ。generation_batch_size: 生成実行時のバッチサイズ。seed: ランダムシード。利用可能なデータセット:
jailbreakbench: JailbreakBench の有害分割(Harmful split)。sorrybench: SorryBench の全プロンプトセット。alpaca_test_sampled: Alpaca-Cleaned からサンプリングした300プロンプト。xstest_safe, xstest_unsafe: XSTest の全プロンプトセット。ccp_sensitive: 68の異なるセンシティブなトピックをカバーする CCP Sensitive プロンプト。各トピックにつき20プロンプト。ccp_sensitive_sampled: CCP Sensitive の小規模セットで、各トピックにつき5プロンプトを含みます。deccp_censored: deccp の検閲済み分割(Censored split)。WildGuard で生成された出力を評価するには、次を実行します:
python -m llm_steering.run_eval \
--config_file CONFIG_FILE_PATH \
--batch_size BATCH_SIZE \
--run_wildguard
スクリプトは SAVE_DIR/evaluation/ に保存されているすべてのモデル出力ファイルを処理します。すでに処理済みのファイルをスキップするには --use_cache を追加します。
WildGuard は3種類の検出を提供し、次の形式で出力を生成します:
Harmful request: yes
Response refusal: yes
Harmful response: no
私たちは、各検出タイプについて "yes" または "no" トークンの確率を抽出します。結果は生成された出力と同じファイルに追加されます。
この研究がお役に立てば幸いです。ぜひ論文の引用をご検討ください:
@inproceedings{cyberey2025steering,
title={Steering the CensorShip: Uncovering Representation Vectors for {LLM} ''Thought'' Control},
author={Hannah Cyberey and David Evans},
booktitle={Second Conference on Language Modeling},
year={2025}
}