RAG(Retrieval Augmented Generation)を「Command R+」で試してみた|精度をGPT-4 Turboと比較
「Command R+」はCohere社が提供するLLMであり、同社が提供するCommand Rの総合的なパフォーマンスを向上させたモデルとして紹介されています。特にエンタープライズ目的での利用を想定し、RAG (Retrieval Augmented Generation) に最適化されていると言われています。
RAGとは、生成AIが質問に回答する際にデータベースから関連情報を検索し、プロンプトに組み込む手法のことを指します。
今回の記事では、RAGの例を実装し、Command R+と他のLLMでは回答がどう異なるかを試してみました。
Command R+の概要
Command R+はエンタープライズ目的での利用に最適化されており、以下の三つの特徴が挙げられています。
- 幻覚を減らすための引用を伴うAdvanced Retrieval Augmented Generation(RAG)
- 10ヶ国語の多言語対応でグローバルな事業運営をサポート
- ツールを使用して高度なビジネスプロセスを自動化
Command R+のパフォーマンス
Command R+は、多言語翻訳、RAG、ツール使用の三つの機能における性能がMistral-Largeよりも高く、GPT-4 Turboに近いスコアを得ています。さらに、価格は他モデルよりも安価で、コストパフォーマンスが高いことがわかります。
左のグラフのテキストの流暢さ、引用の質、全体的な有用性を組み合わせた総合的な人的評価では、Claude 3 Sonnet および GPT-4 Turboよりも高い評価を得ています。
また、検索ツールを利用しての回答精度を他モデルと比較した結果(右のグラフ)では、HotPotQA、StrategyQAではGPT-4 Turboに劣っているもののその他のモデルより優れており、BamboogleではGPT-4 Turboを上回っています。
また、Command R+は翻訳タスクにおいても、Claud 3 Sonnet、Mistral-Large、GPT-4 Turboと遜色ない性能があるとされています。
価格設定
Command Rと比較すると入力トークンで6倍、出力トークンで10倍の価格設定になっています。また、同等のContext-WindowをもつOpenAI社のGPT-4oに比べると、入力トークンの価格設定が低く設定されており、コスト効率に優れていることがわかります。
Model |
Context-window ( tokens ) |
cost ( /1M tokens ) |
Command R |
128,000 |
input:$0.50,output: $1.50 |
Command R+ |
128,000 |
input:$3.00,output: $15.00 |
GPT-3.5 Turbo |
16,385 |
input:$0.50,output: $1.50 |
GPT-4o |
128,000 |
input:$5.00,output: $15.00 |
詳しくは公式サイトの [Command R+の紹介][1]を確認してみてください。
Command R+の使い方
「Command R+」は、Cohere APIを使って利用できます。Cohere APIは、CohereのHPからユーザ登録をすることで利用できるようになります。これは、同社が提供する「Command R」の場合でも同様です。
Cohere APIは有料での利用ですが、トライアルAPI Keyが用意されており、制限の範囲内で無料で使用することも可能です。
API Keyを取得する
まずはCohere APIのAPIを取得します。公式HPの画面右上の「TRY NOW」よりログインします。
ログイン後、画面左の項目より「API Keys」を選択し、Trial keyを作成します。
Trial Key作成後、以下のような画面からKeyを確認することができます。
Command R+を実行する
pip install cohere
公式HPで取得したAPI KEYを指定し、モデル名を“command-r-plus”とすることで「Command R+」を利用できます。
import cohere
co = cohere.Client("<<apiKey>>")
response = co.chat(
chat_history=[
{"role": "USER", "message": "Who discovered gravity?"},
{
"role": "CHATBOT",
"message": "The man who is widely credited with discovering gravity is Sir Isaac Newton",
},
],
message="What year was he born?",
# perform web search before answering the question. You can also use your own custom connector.
connectors=[{"id": "web-search"}],
)
print(response)
詳細な利用方法については[公式ドキュメント][3]を確認してみてください。
Command R+とGPT-4 Turboを比較する
RAGを実装し、Command R+、GPT-4 Turboの2つのモデルでどのような違いがあるかを比較してみましょう。今回は、ふるさと納税の返礼品についてのPDFを利用したRAGの実装を試してみました。
Embeddingの取得
まずは検索対象のPDFからテキストを抽出し、Embeddingを作成しましょう。
今回扱うPDFのテキストをそのまま用いると、一つあたりの入力長が大きくなりすぎるため検索しやすい長さに分割してからベクトル化を行います。
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.docstore.document import Document
# demodata/ *.pdf の読み込み
def load_pdf(path: str= "demodata/*.pdf") -> list:
pdf_resources = []
for file in glob.glob(path):
print(file)
loader = PyPDFLoader(file)
pages = loader.load_and_split()
file_text = ''.join([x.page_content for x in pages])
doc = Document(page_content=file_text, metadata={'source': file})
pdf_resources.append(doc)
return pdf_resources
# テキストのチャンク分割
def split_text(docs: list) -> list:
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=700,
chunk_overlap=100,
)
chunked_resources = text_splitter.split_documents(docs)
return chunked_resources
今回文章のベクトル化にはOpenAIEmbeddingsを用います。この際、OpenAIのAPIが使用するため、OPENAI_API_KEYを環境変数に設定する必要があります。
from langchain.vectorstores.faiss import FAISS
from langchain.embeddings import OpenAIEmbeddings
def create_vectorstore(docs: list) -> None:
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(docs, embeddings)
with open("vectorstore.pkl", "wb") as f:
pickle.dump(vectorstore, f)
docs = load_pdf()
chunked_docs = split_text(docs)
create_vectorstore(chunked_docs)
RAGの実装
先ほど作成したEmbeddingから検索を行い、その結果に基づきLLMを実行します。
from langchain.chains import RetrievalQA, ConversationalRetrievalChain
from langchain.vectorstores.base import VectorStoreRetriever
from langchain.chat_models import ChatCohere
def get_basic_qa_chain():
llm = ChatCohere(model=’command-r-plus’)
with open("vectorstore.pkl", "rb") as f:
vectorstore = pickle.load(f)
retriever = VectorStoreRetriever(vectorstore=vectorstore, search_kwargs={"k": 4})
model = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever)
return model
model({‘question’: $YOUR_QUESTION})
作成したRAGに質問をしてみる
今回作成したRAGは北海道の一部の都市の返礼品のデータが格納されています。これらについて実際に質問をし、Command R+ と GPT-4 Turbo でどのような違いがあるかを確認してみましょう。
質問1:札幌市の返礼品には何がありますか?
“Command R+”の場合
札幌市の返礼品は、以下のようなものがあります。
ラーメン札幌一粒庵の「生麺/4食エコ包装」みそラーメン ISHIYAの「白い恋人(12枚入×3)」 奥芝商店の「北海道の恵み!神宮の賄い海鮮スープカレー(2~4人前)」 奥芝商店の「ほどけるくちどけ!トロとろチーズケーキ(2個)」 北海道産の牛脂と豚脂を使った「永遠の幸ハム詰合せ」 北海道物産展で人気の「塩びき熟成ベーコン」 北海道大学の共同開発商品「春楡の饗(エルムのもてなし)」ソーセージ詰合せ 北海道産の牛肉と長葱で作った「ハンバーグ」 |
“gpt-4-turbo-2024-04-09”の場合
札幌市の返礼品には以下のものがあります: ラーメン札幌一粒庵の味噌ラーメン(6,000円) ISHIYAの白い恋人(ラング・ド・シャクッキー)(14,000円) 奥芝商店の北海道の恵み!竜宮の賄い海鮮スープカレー(13,000円) 永遠の幸ハム詰合せ〜北大との共同開発〜(25,000円) 北海道物産展で大人気の塩びき熟成ベーコン(10,000円) 春楡の饗(エルムのもてなし)〜北大との共同開発〜(12,000円) 北海道産の牛肉と玉葱で作ったハンバーグ(24,000円) これらはすべて札幌市の返礼品として提供されています。 |
質問2:旭川市の返礼品には何がありますか?
“Command R+”の場合
旭川市からの返礼品には、ジンギスカン、メロン、イクラ、お米、パン、ソフトクリームなどがあります。 |
“gpt-4-turbo-2024-04-09”の場合
冷凍別送日乃出ジンギスカン食べ比べ5種【2.5kg】セット 冷凍別送日乃出ジンギスカンラム食べ比べ3種【1.5kg】セット 常温別送【令和5年産】北海道旭川産ななつぼし10kg(5kg ×2) 冷凍別送美味手造りいくら醤油漬240g(80g×3瓶セット) 冷凍別送無添加職人仕込みイクラ200g(100g ×2) |
札幌市の例ではどちらも返礼品のタイトルを抜粋して回答していますが、旭川市ではCommand R+が抽象的な回答を出力しています。また、出力された返礼品名が実際に存在するかどうかを確認すると、GPT-4 Turboはどちらの例においてもすべて正答でしたが、Command R+ は誤っているものが含まれていました。
例) 「神宮の賄い海鮮スープカレー」→「竜宮の賄い海鮮スープカレー」 「トロとろチーズケーキ」→「トロトロ豚角煮スープカレー」 |
さらに6都市で同様の質問をした結果、GPT-4 Turboではすべての例において誤答が生じていないのに対して、Command R+では2 / 6で誤答が生じています。
Command R+ を使ったRAGのまとめ
本記事では、Cohere社が提供するLLMの「Command R+」を使ったRAGについてご紹介しました。
今回はふるさと納税の返礼品をテーマにRAGを実装しましたが、OpenAI社のGPT-4 Turboと比べるとHallucinationが生じてしまい、出力精度がやや劣ってしまう結果となりました。
今回の比較では、PDFデータに特別な前処理を行わずテキスト抽出のみで実装を行っています。こちらを目的のものが適切に検索されるように改善すれば、この二つのモデルの精度差もまた異なる結果となるかもしれません。
【参考文献】
理工学専攻の大学院生で、主に言語AIを扱っています。大学では、生成AIを用いた学習支援アドバイスの生成について研究しています。