はじめに
こんにちは 某地方国立大学で AI の研究してます。ゆーいちです!
今回は Llama3 と研究室の Slack を連携させて RAG をしてみた!ということで、
備忘録的に失礼します!
作成したもの
今回はローカル環境で llamaindex を用いた LLM による RAG を作ってみました!
なぜ書いたか
研究室では LLM を用いた研究をしており、
非 AI エンジニアに研究内容を紹介しやすいように趣味の範囲で作りました!
また、本記事の対象読者は Python である程度の環境構築ができている方に向けてます!
具体的には、
・Pytorch を使ったことがある
・LLM などの AI 技術について知識がある(RAG や Llama など)
また、llamaindex の詳細な説明は省きます!
本題
開発環境
PC:Linux
仮想環境:Anaconda
言語:Python(3.9.19)
GPU:NVIDIA RTX A6000
開発環境:VScode
使用したライブラリ:Pytorch, llamaindex, Huggingface, Slack API
ライブラリのインポート
まずは、ライブラリのインポートをお願いします!
とりあえず呪文のようにお願いします
コマンドラインで
$pip install llama_index
$pip install torch (CUDAのバージョンに合わせてインストールしてください)
import torch
import datetime
from transformers import AutoTokenizer
from llama_index.core import SimpleDirectoryReader
from llama_index.core import Settings
from llama_index.core import SummaryIndex
from llama_index.core import VectorStoreIndex
from llama_index.core.llms import ChatMessage
from llama_index.core.tools import BaseTool, FunctionTool
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.readers.slack import SlackReader
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
ちょこっとした工夫
Slack を検索しますが、検索相手が膨大だとメモリが足りないので、ある程度の期間で絞ります。
dt_now = datetime.datetime.now()
latest_date = dt_now
earliest_date = latest_date - datetime.timedelta(weeks=8)
必要な API key の発行
今回は、Slack と Hugging face の API を発行します。
発行の仕方は参考資料を参照お願いいたします!
なお今回は general チャンネルを RAG することにします!
また、Llama3 を使う場合は Hugging face での申請が必要です!
HF_TOKEN = "hf_xxxxxxxxxxxxxxxxxxxxxx"
#slack関係
SLACK_API = "xxxxx-000000000000000-0000000000000-0000000000000-00000000000000000000"
channel_ids = ["チャンネルのID"]
Llama3 のセットアップ
Hugging face を使いなれている方も多いと思うで、呪文のように(笑)
温度パラメータとかはお好みでカスタマイズしてね!
tokenizer = AutoTokenizer.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct",
token=HF_TOKEN,
)
stopping_ids = [
tokenizer.eos_token_id,
tokenizer.convert_tokens_to_ids("<|eot_id|>"),
]
llm = HuggingFaceLLM(
model_name="meta-llama/Meta-Llama-3-8B-Instruct",
model_kwargs={
"token": HF_TOKEN,
"torch_dtype": torch.bfloat16,
},
generate_kwargs={
"do_sample": True,
"temperature": 0.6,
"top_p": 0.9,
},
tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct",
tokenizer_kwargs={"token": HF_TOKEN},
stopping_ids=stopping_ids,
)
埋め込むモデルの定義
Slack からとってきた記事をベクトルに変換するモデルを定義します!
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
Slack API でのクローリング設定と、LLM のセッティング
slack_reader = SlackReader(slack_token=SLACK_API, earliest_date=earliest_date, latest_date=latest_date)
documents = slack_reader.load_data(channel_ids=channel_ids)
index = SummaryIndex.from_documents(documents)
Settings.embed_model = embed_model
Settings.llm = llm
クエリーエンジンの定義
検索エンジンの定義をします
query_engine = index.as_query_engine(similarity_top_k=3)
# カスタムツールを定義するか、作成したQueryEngineを使用したQueryEngineToolを使用します。
query_engine_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="my_query_engine",
description="インデックスされたドキュメントから情報を提供します。",
),
)
Chat エージェントの設定と生成結果の表示
ここまでお疲れ様でした!
ラストのコーデイングです!
# ツールとLLMを使用してReActAgentインスタンスを作成します。
agent = ReActAgent.from_tools([query_engine_tool], llm=llm, verbose=True)
# エージェントをクエリします。
response = agent.chat("10月からのゼミはいつありますか?")
#てきとーにプロンプト作りました!
print(str(response))
検索結果
個人情報の漏洩が怖いので、一部伏せて書いてます!
何とかできました!
月曜○限と金曜○限です
コード全文
import torch
import datetime
from transformers import AutoTokenizer
from llama_index.core import SimpleDirectoryReader
from llama_index.core import Settings
from llama_index.core import SummaryIndex
from llama_index.core import VectorStoreIndex
from llama_index.core.llms import ChatMessage
from llama_index.core.tools import BaseTool, FunctionTool
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.readers.slack import SlackReader
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
dt_now = datetime.datetime.now()
latest_date = dt_now
earliest_date = latest_date - datetime.timedelta(weeks=8)
HF_TOKEN = "hf_YOURHUGGINGFACETOKEN"
#slack関係
SLACK_API = "YOURSLACKAPITOKEN"
channel_ids = ["CHANNELID"]
tokenizer = AutoTokenizer.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct",
token=HF_TOKEN,
)
stopping_ids = [
tokenizer.eos_token_id,
tokenizer.convert_tokens_to_ids("<|eot_id|>"),
]
llm = HuggingFaceLLM(
model_name="meta-llama/Meta-Llama-3-8B-Instruct",
model_kwargs={
"token": HF_TOKEN,
"torch_dtype": torch.bfloat16,
},
generate_kwargs={
"do_sample": True,
"temperature": 0.6,
"top_p": 0.9,
},
tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct",
tokenizer_kwargs={"token": HF_TOKEN},
stopping_ids=stopping_ids,
)
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
slack_reader = SlackReader(slack_token=SLACK_API, earliest_date=earliest_date, latest_date=latest_date)
documents = slack_reader.load_data(channel_ids=channel_ids)
index = SummaryIndex.from_documents(documents)
#index = VectorStoreIndex.from_documents(documents)
Settings.embed_model = embed_model
Settings.llm = llm
query_engine = index.as_query_engine(similarity_top_k=3)
# カスタムツールを定義するか、作成したQueryEngineを使用したQueryEngineToolを使用します。
query_engine_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="my_query_engine",
description="インデックスされたドキュメントから情報を提供します。",
),
)
# ツールとLLMを使用してReActAgentインスタンスを作成します。
agent = ReActAgent.from_tools([query_engine_tool], llm=llm, verbose=True)
# エージェントをクエリします。
response = agent.chat("院試合格したのは誰ですか。")
print(str(response))
まとめ
今回は、slack を RAG して検索結果に反映できるようにしました!
llamaindex は、PDF やパワーポイントなどにも対応しているので、今度はそちらも試してみたいですね!
参考文献
ローカルの LLM RAG チュートリアル:Llama 3 と LlamaIndex を使用したリトリーバル拡張生成システムの構築
LlamaIndex でサクッと Slack の情報をベースに回答させてみる
Hugging Face にある Llama3 を動かしてみた
最後に
最後まで読んでいただきありがとうございます!
Qiita 初投稿で緊張します!
どうか生暖かい目で見てください!