はじめに
この記事では、Pythonといくつかのライブラリを使用して、特定のテーマに関する質問応答システムを構築する方法を説明します。この例では、「Fate/stay night」という人気アニメの内容を題材として取り上げ、その内容に基づいた質問に答えるモデルを作成します。初心者にも理解しやすいよう、コードの各部分を丁寧に説明します。
必要なパッケージのインストール
最初に、必要なパッケージをインストールします。これには、自然言語処理に広く使われる transformers
、日本語の処理に必要な sentencepiece
、効率的なモデル学習のための accelerate
、そして langchain
が含まれます。
!pip install transformers sentencepiece accelerate langchain bitsandbytes
ライブラリのインポートとCUDAの確認
必要なライブラリをインポートし、GPUが利用可能か確認します(GPUを使うと処理が高速になります)。
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
torch.cuda.is_available()
トークナイザーとモデルの準備
rinna/youri-7b-instruction
というモデルを使用します。これは、日本語の自然言語処理に特化したモデルです。トークナイザーとモデルを読み込みます。
model_id = "rinna/youri-7b-instruction"
tokenizer = AutoTokenizer.from_pretrained(
model_id,
use_fast=False
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto",
)
ここで、use_fast=False
は、トークナイザーの高速化オプションを無効にしています(互換性のため)。
パイプラインの準備
pipeline
を使用してテキスト生成タスクのためのパイプラインを作成し、langchain
の HuggingFacePipeline
でラップします。
from langchain.llms import HuggingFacePipeline
from transformers import pipeline
pipe = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
max_length=512*3,
do_sample=True,
top_k=10,
num_return_sequences=1,
temperature=0.1,
)
llm = HuggingFacePipeline(pipeline=pipe)
max_length
は生成されるテキストの最大長、do_sample
はランダムなテキスト生成に必要なフラグ、top_k
はサンプリング戦略のパラメータです。
プロンプトテンプレートとLLMChainの準備
PromptTemplate
を使って質問に基づいてテキスト生成を行うためのプロンプトを設定します。これを使ってLLMChain
を準備し、テキスト生成タスクに使用します。
from langchain import PromptTemplate, LLMChain
# 事前情報なしの場合
template = """
質問: {question}
システム:"""
template = template.replace("\n", "<NL>")
prompt = PromptTemplate(template=template, input_variables=["question"])
llm_chain = LLMChain(prompt=prompt, llm=llm)
<NL>
は改行を表します。input_variables
はプロンプトに挿入する変数を定義します。
質問応答の実行
質問を設定し、作成したllm_chain
を使って回答を生成します。
question = "「無限の剣製」これは何て読みますか?"
print(llm_chain.run(question))
# 「無限の剣製」これは何て読みますか?
事前情報を含む質問応答の実行
このステップでは、特定のテキスト(Fate/stay nightに関する情報)を事前に与え、それに関連する質問に答えさせます。これにより、モデルが特定のコンテキストに基づいて答えを生成できるようになります。
from langchain import PromptTemplate, LLMChain
# プロンプトテンプレートの準備(事前情報あり)
template = """ユーザー: 次の文章を読んで質問に答えてください。
文章: Fate/stay nightの主人公
衛宮士郎(えみや しろう)
声 - 杉山紀彰(幼少期 - 野田順子)
身長:167cm / 体重:58kg / イメージカラー:赤銅
本作の主人公。穂群原(ほむらばら)学園2年C組に在籍。
元弓道部員であり、その腕は文字どおり百発百中であったという。人助けが生き甲斐であり、他人から頼まれたことに対して基本的に嫌と言わない(言えないのではなく)ため、都合よく利用されることも多い。学園では「穂群原のブラウニー」の異名を持つ。得意とするのは物を修理することと、家庭料理をはじめとする家事全般。身長が低いことと、童顔であることを気にしている[注 9]。運命のその夜、サーヴァント同士の戦いを目撃してしまったために殺されそうになった彼は、偶然召喚したセイバーに窮地を救われ、以後彼女のマスターとして聖杯戦争に参加することになる。
魔術師としては知識も技量も半人前だが、彼にとっては「強化」よりも遙かに高度な魔術であるはずの「投影」(イメージを元に、魔力で無から一時的に物体を作り出す魔術)の方が楽に扱えたり[注 11]、さらに彼が「投影」した物体は時間経過では消滅しない[注 12] など、特定の魔術に関しては普通の魔術師にはありえない特異な才能を発揮する。これは彼の身体が、一時的かつ限定的ながら術者の心象風景によって世界そのものを塗り潰してしまう大魔術「固有結界」のみに特化した異端であるため。その異端ぶりは、一流の魔術師である切嗣や凛が、士郎の魔術の異常さは感じながらもその正体を見極めるに至らず、的確な指導を行えなかったほどである。彼の固有結界「無限の剣製(アンリミテッドブレイドワークス)」は「視認した剣(および剣と認識できるもの)の構成や本質を捉え、複製し内部に蓄える」という能力を持つ。
質問: {question}
システム:"""
template = template.replace("\n", "<NL>")
prompt = PromptTemplate(template=template, input_variables=["question"])
# LLMChainの準備
llm_chain = LLMChain(prompt=prompt, llm=llm)
question = "「無限の剣製」これは何て読みますか?"
print(llm_chain.run(question))
# アンリミテッドブレイドワークス
question = "「無限の剣製」とは何?"
print(llm_chain.run(question))
# 「視認した剣(および剣と認識できるもの)の構成や本質を捉え、複製し内部に蓄える」という能力を持つ。
question = "「衛宮士郎」の特徴は何?"
print(llm_chain.run(question))
# 衛宮士郎の特徴は、「元弓道部員であり、その腕は文字どおり百発百中であった」です。
ここでは、template
に追加の情報を含めています。この情報は、質問に対する回答に影響を与え、より正確で詳細な回答を生み出すことが期待されます。
これで、基本的な質問応答システムの構築方法について説明が完了しました。このシステムを使って、さまざまなテーマに対応する質問応答モデルを構築できます。
コメント