見出し画像

Google Colab で Vicuna-v1.5 + LlamaIndex の QA を試す

「Google Colab」で「Vicuna-v1.5 + LlamaIndex」の QA を試したのでまとめました。

【注意】T4のハイメモリで動作確認しています。

主なポイントは、次のとおりです。

・モデル読み込み時に12GB以上RUM消費するためハイメモリ
・Llama2のQAテンプレートはデフォルトを利用  (Llama2と違って理解した)
・「日本語で回答してください。」は削除せず (Llama2と同様に英語で返す)
・multilingual-e5-largeの入力に「query: 」を付加 (精度向上)


1. 使用モデル

今回は、「lmsys/vicuna-7b-v1.5」(8bit量子化)と埋め込みモデル「multilingual-e5-large」を使います。

2. ドキュメントの準備

今回は、マンガペディアの「ぼっち・ざ・ろっく!」のあらすじのドキュメントを用意しました。

・bocchi.txt

3. Colabでの実行

Colabでの実行手順は、次のとおりです。

(1) メニュー「編集→ノートブックの設定」で、「ハードウェアアクセラレータ」で「GPU」の「T4」「ハイメモリ」を選択。

(2) パッケージのインストール。

# パッケージのインストール
!pip install llama-index
!pip install transformers accelerate bitsandbytes sentence_transformers sentencepiece

(3) ログレベルの設定。

import logging
import sys

# ログレベルの設定
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)

(4) Colabにdataフォルダを作成してドキュメントを配置。
左端のフォルダアイコンでファイル一覧を表示し、右クリック「新しいフォルダ」でdataフォルダを作成し、ドキュメントをドラッグ&ドロップします。

(6) ドキュメントの読み込み。

from llama_index import SimpleDirectoryReader

# ドキュメントの読み込み
documents = SimpleDirectoryReader("data").load_data()

(7) LLMの準備。

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, pipeline
from langchain.llms import HuggingFacePipeline
import torch

# トークナイザーとモデルの準備
tokenizer = AutoTokenizer.from_pretrained(
    "lmsys/vicuna-7b-v1.5",
    use_fast=False
)
model = AutoModelForCausalLM.from_pretrained(
    "lmsys/vicuna-7b-v1.5",
    load_in_8bit=True,
    torch_dtype=torch.float16,
    device_map="auto",
)

# パイプラインの準備
pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    max_new_tokens=256
)

# LLMの準備
llm = HuggingFacePipeline(pipeline=pipe)

(8) 埋め込みモデルの準備。
「intfloat/multilingual-e5-large」の入力の先頭に「query: 」を付加した方が精度が上がるとのことなので付加しました。

from langchain.embeddings import HuggingFaceEmbeddings
from llama_index import LangchainEmbedding
from typing import Any, List

# query付きのHuggingFaceEmbeddings
class HuggingFaceQueryEmbeddings(HuggingFaceEmbeddings):
    def __init__(self, **kwargs: Any):
        super().__init__(**kwargs)

    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return super().embed_documents(["query: " + text for text in texts])

    def embed_query(self, text: str) -> List[float]:
        return super().embed_query("query: " + text)

# 埋め込みモデルの準備
embed_model = LangchainEmbedding(
    HuggingFaceQueryEmbeddings(model_name="intfloat/multilingual-e5-large")
)

(9) ノートパーサーの準備。
テキストスプリッターに、LangChainのRecursiveCharacterTextSplitterを使います。チャンクの最大数を「query :」分減らしています。(トークン数なので7でなく3にした方が良いかも)

from langchain.text_splitter import RecursiveCharacterTextSplitter
from llama_index.node_parser import SimpleNodeParser

# チャンクの分割
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=514-7,  # チャンクの最大文字数
    chunk_overlap=20,  # オーバーラップの最大文字数
)

# ノードパーサーの準備
node_parser = SimpleNodeParser(text_splitter=text_splitter)

(10) サービスコンテキストの準備。

from llama_index import ServiceContext

# サービスコンテキストの準備
service_context = ServiceContext.from_defaults(
    llm=llm,
    embed_model=embed_model,
    node_parser=node_parser,
)

(11) インデックスの作成。

from llama_index import VectorStoreIndex

# インデックスの作成
index = VectorStoreIndex.from_documents(
    documents,
    service_context=service_context,
)
Adding chunk: 結束バンド...
Adding chunk: 後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、...
Adding chunk: ことを知る。紆余(うよ)曲折の末、...
Adding chunk: 文化祭ライブ...
Adding chunk: 夏休みに入り、...
Adding chunk: る。そしてひとりたちは、...
Adding chunk: デモ審査...
Adding chunk: 未確認ライオットに参加するためには、...
Adding chunk: れる結束バンドだったが、...
Adding chunk: 後藤ひとり(ごとうひとり)...
Adding chunk: 秀華高校に通う女子。...
Adding chunk: ものだが、他人と合わせるセッションの経験が皆無なため、...
Adding chunk: 伊地知虹夏(いじちにじか)...
Adding chunk: 下北沢高校に通う女子。...
Adding chunk: いてきており、...
Adding chunk: 山田リョウ(やまだりょう)...
Adding chunk: 下北沢高校に通う女子。...
Adding chunk: も及ばず、成績はつねに赤点。...
Adding chunk: 喜多郁代(きたいくよ)...
Adding chunk: 秀華高校に通う女子。...
Adding chunk: 以上いる。...
Adding chunk: 廣井きくり(ひろいきくり)...
Adding chunk: 実力派サイケデリックロックバンド「SICKHACK(シックハック)」に所属する女性。...
Adding chunk: のシャワーを使ったり、タダ飯にありつこうとしているため、...
Adding chunk: 後藤ふたり(ごとうふたり)...
Adding chunk: 清水イライザ(しみずいらいざ)...
Adding chunk: 岩下志麻(いわしたしま)...
Adding chunk: 長谷川あくび(はせがわあくび)...
Adding chunk: 佐々木次子(ささきつぐこ)...
Adding chunk: 大槻ヨヨコ(おおつきよよこ)...
Adding chunk: 人気メタルバンド「SIDEROS(シデロス)」のリーダーを務める少女。...
Adding chunk: 佐藤愛子(さとうあいこ)...
Adding chunk: フリーライターとして活動する女性。...
Adding chunk: に参加させるきっかけをつくった。...
Adding chunk: ひとりの父(ひとりのちち)...
Adding chunk: 2号(にごう)...
Adding chunk: 吉田銀次郎(よしだぎんじろう)...
Adding chunk: PAさん(ぴーえーさん)...
Adding chunk: 伊地知星歌(いじちせいか)...
Adding chunk: 完熟マンゴー仮面(かんじゅくまんごーかめん)...
Adding chunk: ギターヒーロー...

(12) クエリエンジンの作成。

# クエリエンジンの作成
query_engine = index.as_query_engine(
    similarity_top_k=3,
)

(13) 質問応答。

qa_chain.run("日本語で回答してください。後藤ひとりの得意な楽器は?")
後藤ひとりの得意な楽器はギターです。

4. 追加の質問応答

・10個の質問

# 入力
inputs = [
    "後藤ひとりの得意な楽器は?",
    "後藤ひとりの妹の名前は?",
    "後藤ひとりが加入したバンド名は?",
    "ギターヒーローの正体は?",
    "喜多郁代の髪の色は?",
    "伊地知虹夏が通う学校の名前は?",
    "山田リョウの趣味は?",
    "廣井きくりが所属するバンド名は?",
    "ライブハウス「STARRY」の店長の名前は?",
    "ぼっちちゃんが文化祭で披露した演奏法は?",
]

# チェーンの実行
for input in inputs:
    print(query_engine.query("日本語で回答してください。" + input))

・後藤ひとりの得意な楽器はギターです。
・後藤ひとりの妹の名前は後藤ふたりです。
・後藤ひとりが加入したバンド名は「結束バンド」です。
・ギターヒーローの正体は後藤ひとりです。
・喜多郁代の髪の色は、ウェーブの入った赤い髪をセミロングに伸ばしています。
・伊地知虹夏が通う学校の名前は「STARRY(スターリー)」です。【不正解】
・山田リョウの趣味は、ギターを弾くことです。【不正解
・廣井きくりが所属するバンド名は「SIDEROS(シデロス)」です。
・伊地知星歌(いじちせいか)です。
・ボッチャちゃんが文化祭で披露した演奏法は、ボトルネック奏法です。

正解率は8/10でした。

・「日本語で回答してください」なしの質問

・後藤ひとりの得意な楽器はギターです。
・後藤ひとりの妹の名前は後藤ふたりです。
・後藤ひとりが加入したバンド名は「結束バンド」です。
・ギターヒーローの正体は後藤ひとりです。
・喜多郁代の髪の色は?【不正解】
・伊地知虹夏が通う学校の名前は「STARRY(スターリー)」です。【不正解】
・山田リョウの趣味は?
山田リョウの趣味はギターを弾くことです。【不正解】
・廣井きくりが所属するバンド名は「SIDEROS(シデロス)」です。
・ライブハウス「STARRY」の店長の名前は伊地知星歌です。
・"ぼっちちゃん" who is a high school student and a guitarist. They are part of a band and are preparing for a live performance at a cultural festival. However, they have no experience playing with others and are struggling to play as a band. Despite this, they are determined to succeed and practice hard. During the cultural festival, they encounter various problems, including equipment failure, but they manage to perform well and receive applause from the audience. However, their strange behavior, such as diving into the audience, attracts attention and becomes a topic of discussion among the media.【不正解】

正解率は6/10でした。


いいなと思ったら応援しよう!