未定の部屋

主にデータサイエンス関係の記事を書きます

LlamaIndex × Azure OpenAIでRAGを試す

タイトル通りですが、LlamaIndexのバージョン更新が早くて2024年1月時点の最新バージョンでの日本語記事がなかなか見つからなかったので、公式ドキュメントを参考に実装した内容をこちらに載せようと思います。

簡単な用語説明

  • LlamaIndex: LLMアプリの構築を支援するデータフレームワークです。今回はRAG(後述)を実装するために使用しています

github.com

  • Azure OpenAI: 正式名称はAzure OpenAI Serviceで、OpenAIのモデルをAzureを通して利用できるサービスです。OpenAIのLLMをpythonで使う際に利用しています

learn.microsoft.com

  • RAG(Retrieval-Augmented Generation): LLMが回答を生成する際に外部の知識を検索させるフレームワークです。ハルシネーション(LLMがもっともらしく嘘をつく現象)を減少させ、事実ベースで回答できるようになることが期待されます

docs.llamaindex.ai

実行環境

  • PC: Mac
  • python: 3.10
  • LlamaIndex: 0.9.31
    ローカル環境でDockerコンテナを立ち上げて実行しました。

実装

  • ライブラリの読み込み
    今回はAzure OpenAIからLLMとEmbeddingのモデルを使ったので、それぞれに対応するライブラリをインポートしています。インポート後にログを出力する設定をしています。
import os

from llama_index.llms import AzureOpenAI
from llama_index.embeddings import AzureOpenAIEmbedding
from llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext
from llama_index import set_global_service_context
import logging
import sys

logging.basicConfig(
    stream=sys.stdout, level=logging.INFO
)  # logging.DEBUG for more verbose output
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))



  • セットアップ
    API、LLM、embeddingモデル、service contextのセットアップを行います。今回はLLMとしてGPT-4を、embeddingモデルとしてtext-embedding-ada-002を使用しました。APIのバージョンは適宜変更してください。service contextは公式ドキュメントのままに書いていますが、おそらくLlamaIndex側に使うモデルの情報をセットしているんだと思います。
# API
api_key = os.getenv("AZURE_OPENAI_KEY")
azure_endpoint = "https://<your-resource-name>.openai.azure.com/"
api_version_llm = "2023-09-01-preview"
api_version_embed = "2023-05-15"

# llm model
llm = AzureOpenAI(
    model="gpt-4",
    deployment_name="your-deploy-name",
    api_key=api_key,
    azure_endpoint=azure_endpoint,
    api_version=api_version_llm,
)

# embedding model
embed_model = AzureOpenAIEmbedding(
    model="text-embedding-ada-002",
    deployment_name="your-deploy-name",
    api_key=api_key,
    azure_endpoint=azure_endpoint,
    api_version=api_version_embed,
)

# set service context
service_context = ServiceContext.from_defaults(
    llm=llm,
    embed_model=embed_model,
)
set_global_service_context(service_context)



  • データの読み込み・データベース作成
    データはチュートリアルページと同様にエッセイのデータを使用しました。チュートリアルページからダウンロードし、../data/ディレクトリ配下に格納しています。その後VectorStoreIndexを使ってテキストをembeddingし、indexを作成しています。
documents = SimpleDirectoryReader(input_files=["../data/paul_graham_essay.txt"]).load_data()
index = VectorStoreIndex.from_documents(documents)

ログの出力は↓のような感じになります。

INFO:httpx:HTTP Request: POST https://... "HTTP/1.1 200 OK"
HTTP Request: POST https://... "HTTP/1.1 200 OK"
HTTP Request: POST https://... "HTTP/1.1 200 OK"
...



  • クエリ実行と結果出力
    クエリはエッセイの面白かった部分を聞く内容です。このクエリをもとに検索を行い、エッセイ内容を参照して回答をしてくれます。
query = "What is most interesting about this essay?"
query_engine = index.as_query_engine()
answer = query_engine.query(query)

print(answer.get_formatted_sources())
print("query was:", query)
print("answer was:", answer)

↓のように参考にしたソース、クエリ文、回答文が出力されます。

> Source (Doc id: 74acc1a9-8c6d-46c9-b7bd-cd8edf7f6523): Notes

[1] My experience skipped a step in the evolution of computers: time-sharing machines with...

> Source (Doc id: 742cd9ad-d677-4730-9c5c-85069b325989): A lot of Lisp hackers dream of building a new Lisp, partly because one of the distinctive feature...
query was: What is most interesting about this essay?
answer was: The most interesting aspect of this essay is the personal journey and insights of the author, particularly the realization of the potential of online publishing. The author describes a pivotal moment when they discovered the wide reach of the internet after posting a talk online, which garnered 30,000 page views in a single day. This realization led to the understanding that the internet had opened up a new channel for essayists, free from the constraints of traditional print publishing and its gatekeepers. The essay also touches on the theme of working on projects that lack prestige and how this can be a sign of genuine interest and discovery, rather than being driven by the desire to impress others. The author's experiences with Lisp, painting, cooking, and creating startups like Viaweb and Y Combinator, as well as their reflections on the evolution of technology and its impact on various fields, add depth to the narrative.

参考