具体例で考える RLHF (人間からのフィードバック学習)

大規模言語モデルの学習手法の一つに RLHF というものがあります。RLHF を知りたいと思っても、論文や解説ページを見ても具体例が欠けていることが多く、理解が深まりにくいです。

なので、今回は RLHF について、具体例含めて考え、理解を深めていきます。

## 対象読者
- LLM 勉強中で RLHF を知りたい人
- RLHF を実施したい人

## 課題：差別 AI って意図せず生まれてしまうもの
chatGPT を筆頭として、最近 AI が盛り上がっています。そんな AI ですが、差別的な出力をしてしまい、たまに問題になっています。
当然ながら、これは開発者が差別 AI を作ろうとしたわけではなくて、AI は中身がブラックボックスのため、開発者も出力を制御できず、そうなってしまったというのが事実なわけです。

もちろん、今流行りの chatGPT のような大規模言語モデル（Large Language Models; LLM）も例外ではありません。

じゃあ、なんでそんなことになるかというと、例えば LLM はインターネット上の膨大なデータから次トークン予測によって学習をしているのですが、この学習方法が「**ハルシネーションを起こさない**」、「**有害なテキストを生成しない**」といったことを目的にしたものではないからです。（このような学習方法は、簡単に言えば、知識や言語の学習のためのものです）

そのため、AI を使うとなったら、出力の制御は重要です。なので、例えば、

1. 事実の捏造（ハルシネーション）
    - 嘘の情報を本当のように出力する
    - そのため、ユーザが間違った情報を信じてしまう可能性がある
1. 有害なテキスト
    - 差別的な内容
    - 手りゅう弾の作り方のような危険性を含む内容
    - 性的なコンテンツ
1. ユーザが指示に従わない回答

のような出力は好ましくないものとして、排除したいですよね。
それができるのが、「**人間からのフィードバック学習 (Reinforcement Learning from Human Feedback; RLHF)**」です。

## 具体例で考える RLHF の学習ステップ 
ここからは RLHF の学習ステップについて、具体例を踏まえて説明していきます。

### ステップ 0：準備
- データセット作成には人間によるラベリングが必要なので、協力してくれるラベラーを準備します。
- RLHF したいベースモデル `BM` を用意します。

### 学習ステップ 1：
1. 学習を行っていくにあたり、まずは例題となるタスク（プロンプト）を用意します。そして、プロンプトごとに理想の答えデータセットを用意します。これを `データセットA` としておきます。
    - ここでは例題として、chatGPT の一人称を「吾輩」、語尾を「である」という修正をかけることを目的としましょう。
        - このとき、データセットとしては以下のようなものが考えられそうですね。
        
        | 入力プロンプト | 想定出力 |
        | --- | --- |
        | 自己紹介をしてください。 | 吾輩はChatGPTである。|
        | あなたは何ができますか？ | 吾輩はAIアシスタントで、多岐にわたる機能と知識を持っているのである。|
        | ... | ... |

2. `データセットA` を用いて、RLHF したい `BM` に教師あり学習を行います。学習によって理想の答えを出力する（不完全な）LLM が出来上がります。これを `SFT-LLM ver.1` としておきましょう。

### 学習ステップ 2:
1. 今度は報酬モデル作成用のデータセットを作成します。`データセットA`の質問を含んだり、全く別のデータでもよいです。多種多様の質問文 (入力プロンプト) を用意します。このデータセットを `データセットB` とします。
    - 例：
        | 入力プロンプト No. | 入力プロンプト |
        | --- | --- |
        | 1 | あなたの得意なことは何ですか？ |
        | 2 | AI について説明してください。 |
        | ... | ... | 
1. 先ほど学習したモデル `SFT-LLM ver.1` に対して、先ほど作った `データセットB` を入力して出力を複数生成します。今回は 2 つのデータを生成することにします。
    - これにより、`データセットB`を拡張した `データセットB'`ができます。
    - 例：
        | 入力プロンプト No. | 入力プロンプト | 出力 |
        | --- | --- | --- |
        | 1 | あなたの得意なことは何ですか？ | 私の得意分野は多岐にわたります。 |
        | 1 | あなたの得意なことは何ですか？ | 吾輩は様々なことが得意である。 |
        | 2 | AI について説明してください。 | AIは人間の思考や学習を模倣する技術で、データ分析、自動化、問題解決などに使われるある。 |
        | ... | ... | ... |
1. ラベラーは `データセットB'`の 1 つの質問に対する複数の回答を見て、どれが一番望ましいかをもとに順位をつけます。これを `データセットB''` とします。
    - 今回であれば、「吾輩は～である」となっていることかどうかで順位をつけていきます。

        | 入力プロンプト No. | 入力プロンプト | 出力 | 順位 |
        | --- | --- | --- | --- |
        | 1 | あなたの得意なことは何ですか？ | 私の得意分野は多岐にわたります。 | 2 |
        | 1 | あなたの得意なことは何ですか？ | 吾輩は様々なことが得意である。 | 1 |
        | 2 | AI について説明してください。 | AIは人間の思考や学習を模倣する技術で、データ分析、自動化、問題解決などに使われるある。 | 3 |
        | ... | ... | ... |
1. 次に、`データセットB''` を使って、人間が好む出力を予測する報酬モデルを訓練します。
    - 報酬モデルは "入力プロンプトと生成モデルの出力" から、"出力のスコア（どれくらいいいか）" を予測するモデルです。
        - 今回の例であれば、「吾輩は～である」となっている文章の方がスコアが良くなります。
    - 報酬モデルの学習は 2 つの "入力プロンプトと生成モデルの出力" から学習をします。2 つとは "入力プロンプトと**よい**生成モデルの出力" と "入力プロンプトと**悪い**生成モデルの出力" のペアで、「**よい**生成モデルの出力のスコア」と「**悪い**生成モデルの出力のスコア」の差を最大化するように学習していきます。
    - このモデルを `RM ver.1` としておきます。

### 学習ステップ 3
1. 多種多様な入力プロンプトを集めた `データセットC` を作成します。このデータセットは`データセットA`や`データセットB`とデータの重複があっても構いません。
    - 例：
        | 入力プロンプト |
        | --- |
        | あなたの得意なことは何ですか？ |
        | AI について説明してください。 |
        | ... | 
1. 報酬モデルと PPO (Proximal Policy Optimization) アルゴリズムで、ベースモデル `BM` を学習し、PPO したモデル `PPOM ver.1` を作成します。
    - 具体的には `BM` に対して `データセットC` の入力プロンプトを入力し、出力を生成します。すると、その出力の良悪に基づいて報酬モデル`RM ver.1` がスコアを出してくれます。スコアを使って `BM` のパラメータを自動で調整していきます。
        - イメージとして以下。
            - プロンプト：`Q. あなたの得意なことは何ですか？` -> 生成モデル：`吾輩は様々な場面で活躍するである。` -> 報酬モデル：`90点！` -> 生成モデルのパラメータちょっと修正
            - プロンプト：`Q. あなたの得意なことは何ですか？` -> 生成モデル：`私は情報検索できます。` -> 報酬モデル：`0点！` -> 生成モデルのパラメータいっぱい修正

#### 補足
- PPO は強化学習の一種です。簡単に言うと、AI が自動で試行錯誤して、どんどん賢くなっていく仕組みです。
- PPO を実施するには、自動で現在の AI のスコアを出す仕組みが必要不可欠です。これは、自動で学習を行う際の良悪を判断する物差しの役目になります。今回で言うと、どれくらい「吾輩は～である」になっているかのスコアを出してくれる仕組みです。学習ステップ 2 で `RM ver.1` を作ったのはこのためです。

### ステップ 2 と 3 を繰り返す
1. `PPOM ver.1` は `RM ver.1` をもとに学習したモデルです。`RM ver.1` の性能が悪ければ、`PPOM ver.1` の性能も悪いです。今、ステップ 3 まで実施したことで、報酬モデルの精度をより高めるためのデータがもっとできていることでしょう。ステップ 2 に戻り `データセットB''`を作り直して、より精度のよい報酬モデル `RM ver.2` を作ります。
1. 次にステップ 3 に進み、`RM ver.2` をもとに、再度 `PPOM ver.2` を作ります。
1. これをひたすら繰り返すことで、出力を人間のフィードバックから学習した `PPOM ver.n` ができます。

## まとめ
具体例を含めて、RLHF について説明しました。具体例をイメージしながらだとわかりやすいですが、論文だけ読んでも私は混乱しました。みなさんの理解の助けになったなら幸いです。

おわり