Uncensored1776 Day 16: デバッグとトラブルシューティング
問題が発生したときの対処法
公開日: 2025-12-16
シリーズ: 科学と神々株式会社 アドベントカレンダー
難易度: ★★★☆☆ (中級)
今日学ぶこと
- よくあるエラーとその対処法
- 品質低下の診断方法
- パフォーマンス最適化のコツ
1. エラーの分類
Abliterationで発生するエラーは、大きく4つのカテゴリに分類できます:
エラーの分類:
1. 環境エラー
├── メモリ不足(CUDA out of memory)
├── CUDAエラー(デバイス関連)
└── 依存関係エラー(バージョン不一致)
2. データエラー
├── プロンプト形式の問題
├── トークナイズエラー
└── 空のアクティベーション
3. 計算エラー
├── 行列形状の不一致
├── 数値の不安定性(NaN/Inf)
└── ゼロ除算
4. 品質問題
├── 解除率が低い
├── 出力品質の低下
└── 特定トピックの残存
それぞれの対処法を見ていきましょう。
2. 環境エラー
2.1 メモリ不足(最も頻繁)
エラーメッセージ:
RuntimeError: CUDA out of memory
原因:
- モデルサイズがVRAMを超えている
- アクティベーション収集時のメモリ蓄積
- バッチサイズが大きすぎる
対策一覧:
対策1: バッチサイズを小さくする
├── batch_size=8 → batch_size=1
└── 1プロンプトずつ処理
対策2: 半精度(float16)を使用
├── メモリ使用量が約半分に
└── 多くの場合、精度への影響は最小限
対策3: 勾配を無効化
├── torch.no_grad() を使用
└── 推論時は常にこれを使う
対策4: 処理後にメモリを解放
├── torch.cuda.empty_cache()
└── 各バッチ処理後に実行
2.2 CUDAエラー
エラーメッセージ:
RuntimeError: CUDA error: device-side assert triggered
原因:
- デバイスの不一致(CPUとGPUの混在)
- 不正なテンソル操作
- ドライバの問題
対策:
対策1: デバイスを確認
├── torch.cuda.is_available() で確認
└── GPU名とCUDAバージョンを表示
対策2: 明示的にデバイスを指定
├── model = model.to("cuda:0")
└── inputs = inputs.to("cuda:0")
対策3: CPUへのフォールバック
├── エラー発生時にCPUで再試行
└── 遅くなるが確実に動作
2.3 依存関係エラー
よくある依存関係の問題:
transformers: 4.36.0以上が必要
├── 古いバージョンではtrust_remote_codeが未対応
└── pip install transformers>=4.36.0
torch: 2.0.0以上が推奨
├── 新しいモデルで必要な機能
└── pip install torch>=2.0.0
accelerate: 大型モデルで必要
├── device_map="auto" を使う場合
└── pip install accelerate
3. データエラー
3.1 プロンプト形式エラー
エラーメッセージ:
ValueError: Chat template not found
原因:
- モデルにチャットテンプレートが設定されていない
- テンプレートの形式が不正
対策:
解決策1: フォールバックテンプレートを用意
モデル別のテンプレート形式:
├── Qwen: <|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n
├── Llama: [INST] {prompt} [/INST]
├── Mistral: [INST] {prompt} [/INST]
└── 汎用: User: {prompt}\nAssistant:
テンプレートが見つからない場合、
モデル名から適切な形式を自動選択する
3.2 トークナイズエラー
エラーメッセージ:
ValueError: Input length exceeds model's context
原因:
- 入力が長すぎる
- 最大長の設定漏れ
対策:
解決策: 長さ制限を設定
tokenizer(
text,
return_tensors="pt",
truncation=True, # 長すぎる場合は切り詰め
max_length=512 # 最大長を明示的に設定
)
注意:
- 切り詰めると情報が失われる
- プロンプトは短めに設計することを推奨
3.3 空のアクティベーション
エラーメッセージ:
RuntimeError: mean() input tensor is empty
原因:
- プロンプトリストが空
- アクティベーション収集に失敗
- フィルタリングで全データが除外された
対策:
解決策: バリデーションを追加
収集前のチェック:
├── プロンプトリストが空でないか
├── 各プロンプトが空文字列でないか
└── エンコード結果が有効か
収集後のチェック:
├── アクティベーションがNoneでないか
├── 配列の長さが0でないか
├── NaNやInfが含まれていないか
└── 形状が期待通りか
4. 計算エラー
4.1 行列形状の不一致
エラーメッセージ:
RuntimeError: mat1 and mat2 shapes cannot be multiplied
原因:
- 拒否方向の次元がモデルと一致しない
- 異なるモデルで計算した方向を使用
対策:
解決策: 形状を確認して調整
チェックポイント:
├── weight.shape: (hidden_dim, dim)
└── direction.shape: (dim,)
direction.shape[0] == weight.shape[1] であること
不一致の場合:
├── 次元が大きすぎる → 切り詰め
└── 次元が小さすぎる → ゼロパディング
(ただし、これは緊急対応であり、
本来は同じモデルで計算し直すべき)
4.2 数値の不安定性
エラーメッセージ:
RuntimeWarning: overflow encountered in exp
または NaN が発生
原因:
- 極端に大きい/小さい値
- クリッピング未実施
- 正規化の問題
対策:
解決策: 安定した計算を行う
1. 正規化時にゼロ除算を防ぐ
norm = max(vector.norm(), 1e-8)
normalized = vector / norm
2. クリッピングで外れ値を除去
99.5パーセンタイルでクリップ
3. float32で計算
半精度(float16)での計算後、
重要な演算はfloat32に変換
5. 品質問題の診断
5.1 解除率が低い場合
解除率が目標(80%+)に達しない場合の診断フローです:
診断フロー:解除率が低い
Step 1: 拒否方向の品質をチェック
├── 分離度は十分か?(有害/無害の射影が分離しているか)
├── 分類精度は70%以上か?
└── → 問題あり → プロンプトセットを見直し
Step 2: 層別の効果を分析
├── 各層を個別にAbliterationして効果を測定
├── 効果的な層が見つかるか?
└── → 効果的な層がない → 拒否方向を再計算
Step 3: 残存する検閲パターンを分析
├── Hard Refusalが多い → 強度を上げる
├── Soft Refusalが多い → プロンプトにSoft Refusal例を追加
└── 特定トピックのみ → カテゴリ別Abliterationを検討
5.2 品質が低下する場合
出力の品質(一貫性、文法)が低下した場合の診断です:
診断フロー:品質低下
Step 1: 低下の種類を特定
├── 文法エラー → 浅い層への影響
├── 意味不明な出力 → 強度が高すぎる
├── 繰り返し → 特定層の過度な修正
└── 話題の逸脱 → 中間層への影響
Step 2: 対策を実施
├── 文法エラー → peakを深い層にシフト(0.65-0.70)
├── 意味不明 → 強度を下げる(0.7-0.8)
├── 繰り返し → widthを狭める(0.10-0.12)
└── 話題逸脱 → 閾値を上げてスキップ層を増やす
5.3 特定トピックが残る場合
一部のトピックだけ検閲が解除されない場合:
診断フロー:特定トピック残存
Step 1: 残存トピックを特定
├── カテゴリ別にテストを実行
├── どのカテゴリが高い検閲率か?
└── 例:「中国政治」80%解除、「ロシア」30%解除
Step 2: 原因を分析
├── harmful_prompts.jsonにそのトピックが含まれているか?
├── 含まれていない → プロンプトを追加
├── 含まれている → カテゴリ別の拒否方向を検討
└── 拒否パターンが異なる可能性
Step 3: 対策を実施
├── 対象トピックのプロンプトを追加(5-10個)
├── 拒否方向を再計算
└── または、カテゴリ別にAbliterationを実行
6. パフォーマンス最適化
6.1 処理速度の改善
最適化のポイント:
1. バッチ処理を活用
├── 1つずつ処理 → 遅い
└── バッチでまとめて処理 → 速い
(メモリが許す範囲で)
2. 推論モードを有効化
├── model.eval()
└── torch.no_grad()
3. 必要な層だけ処理
├── 閾値以下の層はスキップ
└── threshold=0.1 で端の層を除外
4. PyTorch 2.0+ のコンパイル
├── model = torch.compile(model)
└── 初回は遅いが、以降高速化
6.2 メモリ使用量の削減
メモリ最適化のポイント:
1. 半精度(float16)を使用
├── torch_dtype=torch.float16
└── メモリ使用量が約半分
2. 勾配を無効化
├── param.requires_grad = False
└── 推論時は必須
3. 不要なデータを削除
├── del large_tensor
└── torch.cuda.empty_cache()
4. 量子化(4bit/8bit)
├── さらにメモリ削減
└── BitsAndBytesConfig を使用
├── 品質への影響は要確認
7. デバッグのベストプラクティス
7.1 ログの活用
効果的なログ出力:
レベル別の使い分け:
├── DEBUG: 詳細な処理状況
│ 例: "Processing layer 15, strength=0.85"
├── INFO: 重要なマイルストーン
│ 例: "Abliteration complete: removal_rate=92%"
├── WARNING: 注意が必要な状況
│ 例: "Low coherence detected: 0.72"
└── ERROR: エラー発生
例: "Failed to load model: ..."
出力先:
├── コンソール(リアルタイム確認用)
└── ファイル(後から分析用)
7.2 チェックポイントの保存
チェックポイントの活用:
保存タイミング:
├── Abliteration適用前(ベースライン)
├── 各イテレーション後
└── 最終結果
保存内容:
├── モデルの状態
├── 使用したパラメータ
├── 評価メトリクス
└── タイムスタンプ
利点:
├── 問題発生時に前の状態に戻れる
├── 異なる設定の比較が可能
└── 再現性の確保
7.3 段階的な確認
段階的確認のフロー:
Step 1: 環境確認
├── CUDA利用可能?
├── メモリ十分?
└── 依存関係OK?
Step 2: データ確認
├── プロンプト数は十分?
├── 形式は正しい?
└── エンコード成功?
Step 3: アクティベーション確認
├── 収集成功?
├── 形状は正しい?
└── NaN/Infなし?
Step 4: 拒否方向確認
├── 分離度OK?
├── 正規化済み?
└── クリッピング済み?
Step 5: Abliteration確認
├── 適用層数は?
├── 強度は適切?
└── 品質維持?
8. 今日のまとめ
エラー対処クイックリファレンス
よくあるエラーと対処:
【CUDA out of memory】
→ バッチサイズを1に、半精度を使用
【Chat template not found】
→ モデル別のテンプレートを手動設定
【Shapes cannot be multiplied】
→ 拒否方向の次元を確認、同じモデルで再計算
【NaN/Inf発生】
→ クリッピングと安定した正規化を適用
【解除率が低い】
→ プロンプトセット見直し、強度を上げる
【品質が低下】
→ 強度を下げる、peakを深い層に
デバッグの心得
- エラーメッセージをよく読む - 原因のヒントが含まれている
- 段階的に確認する - 問題の切り分けが重要
- チェックポイントを活用 - いつでも戻れるように
- ログを残す - 後から分析できるように
明日の予告
Day 17: 環境構築ガイド
明日からは実践編です。実際に手を動かすための環境構築から始めます。
- 必要なハードウェア要件
- Python環境のセットアップ
- 依存関係のインストール
参考リンク
プロジェクト内リソース
- トラブルシューティング - 詳細なエラー対処ガイド
- FAQ - よくある質問
- scripts/ - 実装コード
外部リソース
ナビゲーション
| 前の記事 | Day 15: Weight Kernelと層選択 |
| 次の記事 | Day 17: 環境構築ガイド |