QEUR23_LMABYS7: LangChainで本格的に性能を評価する
~ GPT4Allは大したことないが、「プロンプト」は大切・・・ ~
QEU:FOUNDER : “それでは、前回の知見を踏まえてLangChainを使ってみましょう。回答の質も少しは良くなるでしょうか・・・。”
D先生 : “例によって、データセットは「米国移住権テスト(改)」なんですよね。よく見れば、日本語のinstructionもあるんですね?”
QEU:FOUNDER : “まあ、今回のモデル(GPT4All)は日本語での会話は無理と思うんで、次回への布石なんだが・・・。”
D先生 : “ちょっと、今回のモデルでも日本語のテストしてくれません?”
D先生 : “おっと、日本語でも回答が返ってきています。全然、答えは間違っていますが・・・。”
QEU:FOUNDER : “その他、Classification(分類)の問題をやってみたのですが、それもダメでしたね。さてと・・・、まずはLangChainへの入力となるCONTEXTデータを抽出し、CSVファイルに保管しましょう。それでは、プログラムをドン!!”
# CONTEXT用のテキストファイルを生成する
import pandas as pd
df = pd.read_csv('QEU-verify100-ja2(en).csv')
#print(df)
len(df)
question_list = df["instructions(en)"]
print(question_list)
response_list = df["response(en)"]
print(response_list)
# -----
# テキストを生成する
explanation_list = df["explanation(en)"]
print(explanation_list[:20])
text = ""
for i in range(len(df)):
text += explanation_list[i] + "\n\n "
print(text)
# -----
# テキストファイルへの出力
f = open('USverify100-en.txt', 'w', encoding='UTF-8')
f.write(text)
f.close()
# -----
import pandas as pd
import numpy as np
from langchain.chains import RetrievalQA
from langchain.document_loaders import DirectoryLoader
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.llms import GPT4All
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
#Load all the .txt files from docs directory
loader = DirectoryLoader('./LCdocs/',glob = "**/*.txt")
documents = loader.load()
len(documents)
# -----
print(documents[1].page_content[0:1500])
# -----
# 言語情報をChunk分割する
splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64)
texts = splitter.split_documents(documents)
len(texts)
# -----
print(texts[30].page_content)
#question_list = df["instructions(en)"]
#print(question_list)
#response_list = df["response(en)"]
#print(response_list)
# -----
# 質問と回答をロードする
df = pd.read_csv('QEU-verify100-ja2(en).csv')
print(len(df))
question_list = df["instructions(en)"]
#print(question_list)
response_list = df["response(en)"]
#print(response_list)
# -----
# Create Embeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
db = Chroma.from_documents(texts, embeddings, persist_directory="db")
# -----
#Create Chain
model_path = "D:./ggml-gpt4all-j-v1.3-groovy.bin"
llm = GPT4All(model=model_path, backend="gptj", verbose=False)
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=db.as_retriever(search_kwargs={"k": 2}),
return_source_documents=True,
verbose=False,
)
# -----
#Ask Simple Questions
res = qa(
"What is the capital of Japan?"
)
print(res)
# -----
print(res["result"])
# -----
# 個別の質問応答のタスクを実行する関数を定義する
def repeat_qa(question):
# 質問に回答する
print(f"No.{i}: Question: {question}")
#Ask Questions
res = qa( question )
answer = res["result"]
# 答えを表示する
print(f"Answer: {answer}")
return answer
# 繰り返し質問する
mx_output = []
for i in range(30): # range(len(question_list))
# 今回の質問を抽出する
question = question_list[i]
reference = response_list[i]
# 質問に回答する
answer = repeat_qa(question)
# 質問と回答のマトリックス(リスト)を生成する
mx_output.append([question, answer, reference])
# リストを出力する
#print("--------")
#print("generate answer list")
#print(answer_output)
print("--------")
print("generate output matrix")
print(np.array(mx_output))
# Create DataFrame
mx_out = np.array(mx_output)
columns1 = ["Question", "Answer", "Reference"]
df_out = pd.DataFrame(data=mx_out, columns=columns1)
print(df_out)
# CSV ファイル (USverify30_gpt(en).csv) として出力
df_out.to_csv("USverify30_gpt(en).csv")
# 言語情報をChunk分割する
splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64)
texts = splitter.split_documents(documents)
len(texts)
・・・・
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=db.as_retriever(search_kwargs={"k": 2}),
return_source_documents=True,
verbose=False,
)
D先生 : “どんな風に?”
- chunk_size=512 → 1024
- chunk_overlap=64 → 128
- search_kwargs={"k": 2} → {"k": 3}
QEU:FOUNDER : “まずは、Chunkのサイズを大きくしましょう。さらに、モデルに供給するChunkの量を大きくしてみましょう。まずは、そこから・・・。”
D先生 : “なるほど、おもしろそうですね。その結果は?”
D先生 : “かなり良くなりました。それにしても、Classificationの問題は良い回答が出てきませんね。”
QEU:FOUNDER : “今回の回答の結果をよく見てください。一部ですが、品質が改善しているモノもありますよ。実はプロンプトの設計次第なんですよ・・・。”
D先生 : “プロンプトの設計次第!?”
(悪いClassificationプロンプトの例)
- Choose item that does not have power to enact federal law from the list below: 以下略
(良いClassificationプロンプトの例)
- Choose item from the following list, which were not taken to America to be sold as slaves: 以下略
QEU:FOUNDER : “以前、LLMのプロンプト関連で論文があったんです。プロンプトの先頭に重要な情報を配置すると精度が上がるって・・・。”
D先生 : “Classificationの質問の場合、最も重要な情報は「この質問はClassificationである」ということなんですね。・・・ひょっとしたら、もうちょっとプロンプトを工夫すれば、全ての問題が解決できませんかねえ・・・。”
QEU:FOUNDER : “さすがにそれは無理だと思うよ。フェザー級のモデルは、さすがにここまでですよ。”
D先生 : “じゃあ、次はライト級ということで・・・。”
QEU:FOUNDER : “今後は、かなり大きなGPUが必要になりますね。”
~ まとめ ~
QEU:FOUNDER : “おう、夏と言えば・・・。やはり、J国の国民としては、「Nuclearの一件」と「例の敗戦の振り返り」が必要ですね。”
C部長 : “二度と同じ間違いを繰り返しませんように・・・。”
QEU:FOUNDER : “二度と同じ間違いを繰り返しませんように・・・。”
コメント
コメントを投稿