強化学習ファインチューニングの報酬関数

報酬関数は、強化学習ファインチューニング中に各モデルのレスポンスを数値でスコアリングします。報酬シグナルは、強化学習が最適化する対象であるため、その品質がチューニングの品質を直接決定します。すべての報酬は [-1, 1] の範囲にクリップされます。この範囲外の値はクリップされます。

このページでは、サポートされている各報酬タイプ、報酬の設計に関する推奨事項、チューニング ジョブを開始する前に報酬構成を検証する方法について説明します。強化学習ファインチューニングでは、次の報酬タイプがサポートされています。

また、複合報酬を使用して、これら 4 つのいずれかとスコアラーごとの重みを組み合わせることもできます。

既知の制限事項

次のタイムアウトは、特典タイプごとに適用されます。

報酬の種類 タイムアウト
文字列の一致 厳密なタイムアウトなし
コード実行 evaluate メソッド呼び出しごとに 100 秒
Gemini ベースの自動評価ツール LLM の評価レスポンスを待機している間の 1 分間のタイムアウト
Cloud Run トリガーごとに 5 分のタイムアウト

Cloud de Confiance コンソールで特典を構成する

Cloud de Confiance コンソールの [モデル > チューニング] で強化学習のファインチューニング ジョブを作成するときに、[報酬の構成] ステップで単一または複合の報酬を構成できます。

  1. [報酬名] を入力し、プルダウン メニューから [報酬タイプ] を選択します。

    • 文字列照合の報酬: 解析タイプ(正規表現抽出など)、照合オペレーション(完全一致など)、ターゲットの式、正解と不正解の報酬を構成します。
    • LLM ベースの報酬: 自動評価ツールのプロンプトを指定し、自動評価ツールの出力を解析してスコアを付ける方法を構成します。
    • Python 関数ベースの報酬: カスタム Python 評価コードをインライン エディタに直接入力するか、Python ファイルをアップロードします。
    • Cloud Run を使用した完全にカスタマイズ可能な報酬: Cloud Run サービスの URI を指定します。
  2. 特典カードの特典の重みを指定します。

  3. [完了] をクリックします。

  4. 複合報酬を構成するには、[+ 別の報酬を追加] をクリックします(最大 16 個の報酬)。折りたたまれた各特典カードには、構成された重みが表示され、フォームには重みの合計の概要が表示されます。

文字列一致の報酬

API 仕様: ReinforcementTuningStringMatchRewardScorer

文字列一致報酬は、モデルが生成したレスポンスを既知のグラウンド トゥルースに対して評価するのに便利な構成です。これは、各質問に既知の正解がある数学の問題などのタスクに特に役立ちます。

モデルは、グラウンド トゥルースと比較する最終的な回答に到達する前に、連鎖思考の推論やその他の単語を出力する可能性があるため、文字列一致スコアラーは、正規表現抽出を使用してモデル生成の出力を処理するパーサー関数をサポートしています。次に、正規表現で抽出されたモデルのレスポンスをグラウンド トゥルースと比較する方法を定義します。グラウンド トゥルースは references のフィールドを通じて提供されます。このフィールドは、トレーニング ファイルと検証ファイルを作成するときに各例で入力します。

構成スキーマについては、ReinforcementTuningStringMatchRewardScorer API 仕様をご覧ください。references フィールドの詳細については、チューニング データセットのページをご覧ください。

Gemini ベースの自動評価ツールの報酬

API 仕様: ReinforcementTuningAutoraterScorer

Gemini ベースの自動評価ツールの報酬は、モデル生成レスポンスを LLM-as-a-judge フィードバックと照らし合わせて評価するのに便利な構成です。たとえば、自動評価(LLM-as-a-judge)によってトーンが決定される特定のトーンでモデルがレスポンスを出力するようにします。

この報酬は次の 2 つのパターンをサポートしています。

  • 自動評価ツールは、強化学習のフィードバックとして使用される数値スコアを直接出力できます。
  • 自動評価は、解析されて事前定義されたパターンと比較される判定を出力できます。

自動評価ツールは Chain-of-Thought の推論を出力することも許可されているため、文字列照合の報酬と同じ方法でレスポンスのセクションを解析できます。たとえば、自動評価ツールが blahblahblah <answer>Yes</answer> または blahblahblah <answer>No</answer> を出力する場合、<answer> と </answer> の間の自動評価ツールのレスポンスを抽出する解析関数を作成できます。次に、自動評価ツールの出力を、Yes を +1 スコアにマッピングし、一致しない値(No など)を -1 スコアにマッピングする事前定義の式と比較します。

次の autorater 構成例では、<answer> タグ間のテキストを取得するようにフィルタし、Yes を +1 に、その他の値を -1 にマッピングしています。

{
  "autoraterResponseParseConfig": {
    "parseType": "REGEX_EXTRACT",
    "regexExtractExpression": "<answer>(.*?)</answer>"
  },
  "exactMatchScorer": {
    "expression": "Yes",
    "correctAnswerReward": 1.0,
    "wrongAnswerReward": -1.0
  }
}

コード実行の報酬

API 仕様: ReinforcementTuningCodeExecutionRewardScorer

コード実行報酬構成を使用すると、Cloud Run サービスを設定せずに、ユーザー定義の Python コードを提供してモデルのレスポンスを評価できます。次の署名で evaluate 関数を実装します。

def evaluate(example: dict[str, Any], response: dict[str, Any]) -> float:
  ...

この関数は次のものを受け取ります。

  • example: ProtoJSON 形式の ReinforcementTuningExample(つまり、キーがキャメルケースである点を除き、トレーニング データセットまたは検証データセットの 1 行と同じ形式)。トレーニング データセットまたは検証データセットで設定されている場合、システム指示(example.get("systemInstruction"))と参照(example.get("references"))も example に含まれます。
  • response: ProtoJSON 形式の Content(つまり、キーはキャメルケースにする必要があります)。これは、Gemini モデルのオンライン予測レスポンスと同じです。

この関数は float を返す必要があり、その float は [-1, 1] の範囲にクリップされます。

実装例:

def evaluate(example, response) -> float:
  response_str = response.get("parts", [])[0]["text"]
  references = example.get("references", {})

  if response_str == references.get("concise_answer"):
    return 1.0
  return -1.0

サポートされているライブラリ

Python 標準ライブラリに加えて、コード実行サンドボックス内では次の Python ライブラリを使用できます。

  • cv2
  • matplotlib
  • mpmath
  • numpy
  • pandas
  • seaborn
  • sklearn
  • statsmodels
  • sympy

タイムアウトとリソース上限

各 evaluate 呼び出しには 100 秒のタイムアウトがあります。タイムアウトした呼び出しは、数回再試行されます。数回再試行しても呼び出しがタイムアウトし続ける場合、サンプルは報酬の計算から除外されます。

ValidateReinforcementTuningReward API(報酬構成を検証するを参照)でコードをテストし、コード実行が 100 秒以内に完了するようにして、最高のパフォーマンスを実現することを強くおすすめします。

コード実行環境では、呼び出しごとに 1 個の CPU と 1 GB のメモリが提供されます。

Cloud Run を使用した完全にカスタマイズ可能な報酬

API 仕様: ReinforcementTuningCloudRunRewardScorer

Cloud Run の報酬構成を使用すると、完全にカスタマイズ可能なスコアリング ロジックを実装できます。Cloud Run サービスは、次の HTTP コントラクトを実装する必要があります。

HTTP メソッド: POST

リクエストの本文(application/json):

{
  "example": { "object(RLFTExample)" },
  "response": { "object(Content)" },
  "metadata": {
    "step": int,
    "tuningJobId": int64
  }
}

example は ProtoJSON 形式の ReinforcementTuningExample で、response は ProtoJSON 形式の Content です。

レスポンスの本文(application/json):

{
  "reward": float,
  "...": {}
}

リクエストの例

{
  "example": {
    "contents": [
      {
        "role": "user",
        "parts": [
          { "text": "What is the capital of France?" }
        ]
      }
    ],
    "references": {
      "answer": "Paris"
    }
  },
  "response": {
    "parts": [
      { "text": "London" }
    ]
  },
  "metadata": {
    "step": 1,
    "tuningJobId": 123456789
  }
}

レスポンスの例

{
  "reward": -1.0
}

IAM 権限を設定する

  • Cloud Run サービスに追加の IAM 権限を付与するには、そのサービスに対する roles/run.admin 権限が必要です。
  • Gemini Enterprise Agent Platform Secure Fine Tuning Service Agent(service-PROJECT_NUMBER@gcp-sa-vertex-tune.s3ns-system.iam.gserviceaccount.com)には、Cloud Run サービスを呼び出す権限(IAM で roles/run.invoker を付与するなど)が付与されている必要があります。

タイムアウトと再試行

Cloud Run サービスが各報酬計算リクエストを処理できる最大時間は 300 秒です。リクエスト エラーが発生すると、サービスは指数バックオフ(2 秒、4 秒、8 秒、16 秒、32 秒など)で再試行してから、処理を中止します。すべての再試行を試しても有効なレスポンスが返されない場合、報酬は NaN とマークされます。

特典の設計に関する推奨事項

以降のセクションでは、強化学習のファインチューニング用に適切に調整されたシグナルを生成する報酬関数を設計するためのベスト プラクティスについて説明します。

報酬のスケール

すべての報酬は [-1, 1] のスケールでなければなりません。この範囲外の報酬値はクリップされます。

優れた報酬とは

  • 望ましい結果と一致し、人間の好みに合わせて適切に調整されている。
  • 明確で一貫性がある。たとえば、分散の大きい自動採点者の報酬からモデルが効果的に学習することは困難です。
  • 無効な出力に対して堅牢です。たとえば、モデルが無効な出力を生成した場合、報酬はクラッシュして NaN を返すのではなく、低い値を返す必要があります。これにより、チューニング ジョブは、それらが最適化から除外されるべき悪い生成であることを認識します。報酬呼び出しの 80% 以上がエラー(RPC エラー、NaN を返す)の場合、チューニング ジョブは自動的に停止します。
  • 報酬の不正使用を防ぐ設計。モデルが抜け穴を利用して、実際にはパフォーマンスが優れていないのに高い報酬を得られるような構成は避けてください。

報酬構成を検証する

API 仕様: ValidateReinforcementTuningReward

チューニング ジョブは費用がかかる可能性があるため、チューニング ジョブを効果的に行うには報酬が不可欠です。チューニング ジョブを起動する前に、報酬構成を検証することをおすすめします。

  • Cloud de Confiance コンソールで、または ValidateReinforcementTuningReward API を呼び出して、報酬の有効性と堅牢性をテストします。解析エラー、未処理のエッジケース、無効なコード スニペットなどの小さなエラーは、報酬とチューニングを無効にする可能性があります。
  • データセットのサンプルで、カスタマイズされた報酬を使用して評価を実行します。報酬がデータセットに対して難しすぎる(報酬がほぼ常に 0)か、簡単すぎる(報酬がほぼ常に 1)場合、強化学習はうまく学習できません。

Cloud de Confiance コンソールで検証する

[チューニング済みモデルを作成] ウィザードの [報酬をテストする(省略可)] ステップで、次の操作を行います。

  1. [トレーニングの例] エディタで、systemInstruction、contents、references を含む JSON データセットのサンプル行を入力します。
  2. [モデルの回答のサンプル] フィールドに回答のサンプルを入力するか、[トレーニング例から生成] をクリックして、ベースモデルに回答のサンプルを生成させます。
  3. [テスト] をクリックして、報酬構成をサンプルと比較して評価します。
  4. 結果として表示されるステータス バナーと全体的なスコアを確認します。[報酬の個別情報を表示](複合報酬の場合は [個別スコアとデバッグ情報を表示])をクリックしてサイドドロワーを開き、報酬ごとのスコア、エラー メッセージ、デバッグログを確認します。

REST API を使用して検証する

ValidateReinforcementTuningReward API は、sampleResponse(通常は Gemini モデルの出力から取得される Content 型)、RLFTExample、singleRewardConfig または compositeRewardConfig のいずれかを想定しています。返された結果にエラーまたは NaN が含まれている場合は、実際のチューニング ジョブを実行する前に解決する必要がある報酬設定に問題があります。

curl -i -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://us-central1-aiplatform.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/tuningJobs:validateReinforcementTuningReward" \
  -d @validate_reward_request.json

PROJECT_ID は、実際の Cloud de Confiance by S3NS プロジェクト ID に置き換えます。

次のステップ