深層学習

GPTとRAG

GPT系は大規模な自己回帰言語モデルを文脈内の例だけで適用し、RAGはパラメータ内の知識と外部検索する知識を組み合わせて生成します。

  • A|中核
  • 深層学習

数式の記号で止まったら 記号の読み方 (∂・⊙・転置・上付き添字を、読み方から)

ひとことで言うと

GPT系は、大規模なコーパスで事前学習した自己回帰言語モデルを、入力された文脈の続きとして使う方式です。GPT-3の論文では、タスクの説明と数個の例をテキストに含めるだけで、タスクごとの勾配更新やfine-tuningなしに推論する few-shot 設定を検証しています。例を見せることは重みを更新することではなく、その1回の入力の文脈を変えることです。

RAG(Retrieval-Augmented Generation)は、モデルのパラメータに蓄えた知識だけでなく、外部の検索可能な記憶から取得した文書も生成に使う構成です。検索器が候補文書を取り出し、生成器が質問と文書を条件に回答を作ります。

GPT単体は、長く訓練した技術者が記憶から答える状態です。few-shot はその場で数個の回答例を渡して作業形式を合わせる操作、RAG はさらに資料棚から関連ページを探して机に置く操作に相当します。前者は重みを変えず文脈を変え、後者は外部記憶を追加します。

なぜ必要か

従来の言語モデル利用では、タスクごとにラベル付きデータを集め、モデルをfine-tuningするのが基本でした。GPT-3論文が示したのは、モデルを大きくすることで、翻訳や質問応答などを、タスク固有の勾配更新なしに few-shot で扱える場合が増えることです。したがって試験では、few-shot を「少数例で重みを再学習する方法」と読まないことが要点です。

ただし、パラメータに知識を持たせる方式には、知識への正確なアクセス、出典の提示、世界知識の更新という問題が残ります。RAG論文はこの切り分けを、事前学習済みseq2seq生成器をパラメトリック記憶、Wikipediaの密ベクトル索引をノンパラメトリック記憶として組み合わせる形で扱いました。検索対象を更新すれば外部記憶を差し替えられるので、知識の変更をモデル全体の再学習と同一視しません。

課題パラメータ中心の生成RAGで分ける場所
新しい知識を参照する学習済み重みに依存する外部文書・索引を検索する
根拠をたどるパラメータから直接は取り出しにくい取得した文書を生成条件に残す
知識を更新するモデル側の更新が必要になりやすい検索対象を更新する経路を持つ

仕組み

RAGの処理を、質問 x\mathbf{x}、検索器を pη(z∣x)p_{\eta}(z\mid\mathbf{x})、取得文書を zz、生成器を pθ(y∣x,z)p_{\theta}(y\mid\mathbf{x},z) と書きます。η\eta は検索器のパラメータ、θ\theta は生成器のパラメータ、yy は生成する系列です。検索器は質問に近い文書を選び、生成器はその文書を条件に出力を作ります。

p(y∣x)≈∑z∈TopK(x)pη(z∣x) pθ(y∣x,z)p(y\mid\mathbf{x}) \approx \sum_{z\in\mathrm{TopK}(\mathbf{x})} p_{\eta}(z\mid\mathbf{x})\,p_{\theta}(y\mid\mathbf{x},z)

ここで TopK(x)\mathrm{TopK}(\mathbf{x}) は検索器が返す上位 KK 件、p(y∣x)p(y\mid\mathbf{x}) は質問に対する出力系列の確率です。つまり、生成器だけにすべてを覚えさせるのではなく、候補文書ごとの検索確率を重みとして生成結果を組み合わせます。RAG論文では、系列全体で同じ検索文書に条件づける形式と、トークンごとに異なる文書を使える形式を比較しています。

GPT系の few-shot は、この検索の段階を必須にしません。入力を c\mathbf{c}(タスク説明・例・質問を連結した文脈)、次に出すトークンを yty_t とすると、推論時に行うのは文脈から次のトークンを選ぶことです。例は c\mathbf{c} の一部であり、few-shot のたびに θ\theta を更新するわけではありません。RAGはそこへ検索結果 zz を加え、生成条件を pθ(y∣x,z)p_{\theta}(y\mid\mathbf{x},z) にします。

段階GPT系 few-shotRAG
知識の主な所在学習済みパラメータパラメータと外部索引
推論時の追加処理文脈に例を並べる検索器で文書を取得する
勾配更新few-shotごとは行わない論文のRAG実験ではfine-tuningする

試験でどう問われるか

問われ方正解に寄る条件引っかけ
GPT系の few-shot の説明少数の実例を入力文脈に含め、推論時の勾配更新なしで適用する例を与えるたびに重みを更新する
GPT系とRAGの知識の違いパラメータ内の知識と検索可能な外部記憶を分けて考えるRAGは外部文書だけで生成し、モデルの知識を使わない
RAGの構成要素検索器が文書を取得し、生成器が質問と文書を条件に生成する生成器だけを大きくすればRAGになる
RAGで更新しやすい対象検索対象の索引・文書を差し替える発想外部知識を変えるには必ず生成器を再学習する
RAGの論文上の比較系列全体で同じ文書を使う形式と、トークンごとに文書を変える形式2方式は検索器を使わない別手法である

実装で確かめる

次のコードは、文書ベクトルとの内積で上位文書を検索し、取得文書を生成器へ渡す直前の境界を確認する最小例です。生成器そのものを実装していないため、RAGの「検索」と「生成」を混同しません。

import numpy as np

docs = np.array([[1., 0., 0.], [0., 1., 0.], [1., 1., 0.]])
query = np.array([.8, .6, 0.])
scores = docs @ query / (np.linalg.norm(docs, axis=1) * np.linalg.norm(query))
top = np.argsort(scores)[::-1][:2]
context = ["文書A", "文書B", "文書C"]
print(top.tolist(), [context[i] for i in top])

出力は [2, 0] ['文書C', '文書A'] です。ここで scores は検索器の候補順位、context は生成器に渡す外部記憶です。query や文書ベクトルを変えても、文書を差し替えるだけなら生成器のパラメータは変わりません。一方、取得結果を使わず質問だけを生成器に渡せば、それはこの構成のRAGではなく、パラメータ中心の生成です。

取り違えやすいもの

用語GPT系・RAGとの切り分け
fine-tuningデータで勾配を計算し、パラメータを更新する。GPT-3のfew-shot推論とは異なる
few-shot入力文脈に例を置く推論設定。例の提示だけでは学習済み重みは変わらない
パラメトリック記憶モデルのパラメータに分散して保持された知識。RAGでも生成器側に残る
ノンパラメトリック記憶文書やベクトル索引のようにモデル外で検索できる記憶。RAGの検索対象になる
検索・抽出型QA文書から答えを抜き出す構成。RAGは検索結果を条件に系列を生成する
プロンプトへの文書貼付外部文書を文脈に渡す点は似るが、RAG論文の構成では検索器と生成器を分けて扱う

想起チェック

few-shot の例はモデルの重みをどう変えるか

その推論の入力文脈を変えるだけで、few-shotごとの勾配更新やfine-tuningは行いません。

RAGでパラメトリック記憶とノンパラメトリック記憶は何か

前者は事前学習済み生成器のパラメータ、後者は検索可能な文書・密ベクトル索引です。検索器が後者から文書を取り出し、生成器が両方を使って出力します。

知識を更新しやすくするRAGの設計上の分離は何か

外部文書やその索引をモデルのパラメータから分離しておくことです。検索対象を更新する経路と、生成器を再学習する経路を分けられます。

RAG論文で比較された検索文書の使い方は何か

生成系列全体で同じ検索文書に条件づける形式と、トークンごとに異なる文書を使える形式です。

出典