RAGを関連キーワードを押さえながら理解してみる!

こんにちは!エキサイト株式会社、SaaS・DX事業部エンジニアの岩田史門です!

エキサイトHDアドベントカレンダー14日目を担当させていただきます!

はじめに

RAG(Retrieval-Augmented Generation)は、外部データの情報を利用して、より正確で文脈に沿った応答を大規模言語モデル(LLM)に生成させる方法です!

現在開発に携わっている、FanGrowthというプロダクトでも、「FanGrowth AI ウェビナー企画提案」という機能で活用しています!

www.fangrowth.biz

この記事では、関連するキーワードとともに、RAGについて説明します!

RAGの概要

RAGは、下記の2つの処理ステップを組み合わせたアプローチです!

1. Retrieval(情報検索)

ベクトルDBなどから、ユーザーの質問やリクエストに関連する情報を検索します。このステップでは、質問をEmbedingモデルを使って、ベクトル化して、類似するデータを見つけます。類似度の指標として、コサイン類似度というものが有名ですが、こちらを利用する場合は、スコアが1に近いほど類似していることを表します!

2. Augmented Generation(拡張生成)

検索された情報を活用して、生成モデル(例:OpenAIのGPT)にコンテキストを提供し、それに基づいて応答を生成します。

RAGは、ただ単純にモデルが事前に学習している知識だけに頼るのではなく、外部データを活用して最新の情報や特定のドメイン知識を含んだ応答を生成するのが特徴です。そのため社内文書や自社の商品、FAQなどによく活用されています!

キーワードの解説

RAGの概要説明にて、ベクトル化、ベクトルDB、ベクトル検索、Embedding、コサイン類似度などのキーワードが出てきました!

この章では、これらのRAGの話をする上で頻出するキーワードを解説していきます!

ベクトル化

ベクトル、みなさんご想像の通り、高校の時に数学で習ったあれです。

こんなところで活用されています!

ベクトル化とは、言葉や画像などのデータを数値ベクトル(数値の配列)に変換することです。

ベクトル化することにより、機械学習モデルがデータとデータの類似性を計算しやすくなります!

(おまけ)実際に画像をベクトル化してみました

今回は下記の僕が登山したときの画像をベクトル化してみます!

ベクトル化する画像(冬の乗鞍岳に登ったときの僕の写真です)

下記のコードをGoogle Colabで実行するとベクトル化できます!

import numpy as np
import tensorflow as tf

model = tf.keras.applications.EfficientNetB0(include_top=False, pooling="avg")

def image2vec(image_path):
    raw = tf.io.read_file(image_path)
    image = tf.image.decode_jpeg(raw, channels=3)
    image = tf.image.resize(image, [224, 224])
    vec = model.predict(np.array([image.numpy()]))[0]
    return vec

image2vec("/content/アイコン画像_乗鞍岳.jpeg")

実際の結果は、下記のようになり、無事ベクトル化できていますね!

自分でやっておいてなんですが、自分がこんなふうに数値で表されていると思うと、なんだか不思議な感覚になりますねw

画像のベクトル化

ベクトルDB(ベクトルデータベース)

その名の通り、ベクトル形式でデータを保存することができるデータベースです!

効率的に類似度検索を実行できるようになっています!

FanGrowthでは、Amazon OpenSearch Service を利用しています!

ベクトル検索

質問や検索の際のリクエストをベクトル化し、ベクトルDBに保存されたデータのベクトルと類似度スコアを計算して、最も関連性の高いデータを検索する方法です!

例えば、ユーザーが、「うちの会社の就業規則を教えて」と質問すると、この質問がベクトル化されて、関連する文書や情報を検索するといった仕組みです!

Embedding(エンべディング:埋め込み)

Embedding(エンべディング:埋め込み)とは、データ(単語や画像、音声など)を、数値のベクトル形式に変換する技術です!

Embeddingモデルとは、データをEmbeddingしてベクトル化するための機械学習モデルです。

有名なものだと、OpenAI EmbeddingモデルやGoogleが開発したBERTなどがあります!

類似度スコア

類似度スコアは、データ同士の「似ている度合い」を数値で表したものです!

コサイン類似度は、その中でも特に広く使われる代表的なものです!

コサイン類似度

コサイン類似度は、2つのベクトルの角度のコサインの値を計算することで、類似度スコアを計算する方法です!

cos(0o) の時は1、cos(90o) は0、cos(180o)の時は-1になりますよね!

三角関数を思い出しますね、懐かしい...)

そのため、値は-1 ~ 1の間になります!

1の時は、角度が0度なので、ふたつのベクトルが同じ方向を向いており、完全一致しているので、類似度スコアは高いです。

0の時は、角度が90度で、ふたつのベクトルが直行しているので、無関係です。

-1の時は、角度が180度で、ふたつのベクトルが反対方向を向いているため、正反対のデータとなります。

コサイン類似度をイメージするための図

計算式は下記のようになります!

\displaystyle{

\cos(a,b) = \frac{\sum^{n}_{i=1}a_{i}b_{i}}{\sqrt{\sum^{n}_{i=1}a_{i}^2}\sqrt{\sum^{n}_{i=1}b_{i}^2}}

}

(おまけ)実際に例を挙げて計算してみます

ベクトルA = [1,2,3], ベクトルB = [4,5,6]の場合

  1. 計算式の分子のベクトルの内積を計算します![tex:\displaystyle{ (14)+(25)+(3*6)=32 }]

  2. 分母のベクトルAの大きさを計算します! \displaystyle{\sqrt{1^ 2+2^ 2+3^ 2}=\sqrt{14}}

  3. 分母のベクトルBの大きさを計算します! \displaystyle{\sqrt{4^ 2+5^ 2+6^ 2}=\sqrt{77}}

  4. コサイン類似度は、\displaystyle{
\frac{32}{\sqrt{14}*\sqrt{77}}\approx0.97463
}

上記のように、1に近いので、類似度が高いと言えます!

実際には、3次元ではなく、もっとすごい次元のベクトルの計算をしています!

実際のRAGの大まかな処理の流れ(OpenSearchとOpenAIを利用した場合)

この章では、先ほど押さえたキーワードを使いながら、RAGがどのような流れで処理を行うのか、大まかに説明します!

処理の流れ図

  1. 事前にベクトルDBに社内文書を登録しておく 
    例えば、就業規則のPDFなど社内文書をいくつか登録しておきます

  2. ユーザーが質問する
    ユーザーが、「就業時間を教えてください」と質問します。

  3. 質問のベクトル化
    OpenAIのEmbedding APIを使って、ユーザーの質問をベクトル化します

  4. ベクトル検索
    質問ベクトルを、AWS OpenSearchのベクトルDBに問い合わせ、類似するデータを取得します。今回でいえば、就業規則のPDFがヒットします。

  5. 関連するデータを返す
    ヒットした情報を返却します。

  6. 回答生成用の質問(コンテクスト)を準備
    検索結果から重要な情報(今回だと就業時間)を抽出し、生成モデルに質問として渡します。(いつもChatGPTに質問するときのような文章に組み込みます)

  7. LLMにプロンプトを投げて質問
    Open AIのAPI経由で、取得したデータを含んだ質問を送信して質問します。

  8. 回答生成
    OpenAIのモデルを使って、「就業時間は9時から18時です」というような回答を生成します

単純にChatGPTなどのLLMに質問する場合、就業時間は各社によって異なりますし、適切な回答は返ってきませんが、RAGを使うと、外部データを柔軟に活用して、回答を生成できます!

まとめ

今回は、最近とても注目されているRAG(Retrieval-Augmented Generation)という技術について、関連キーワードを解説しながら理解を深めました!

RAGは、ファインチューニングと異なり、モデル自体を訓練し直す必要がなく、とても便利です!

FanGrowthでは、商品情報やウェビナー用の企業データなど、LLMのモデルが知らない情報を扱いたいケースが多いので、今後もRAGを活用して企画生成の分野で価値提供していきたいと思います!

参考文献