LlamaIndex v0.10のLLMのカスタマイズをやってみる
2024/03/06
こちらの公式ドキュメント(v0.10.16)を参考に評価についてまとめていきます.
LlamaIndex アブストラクションにおけるLLMのカスタマイズ
LLMの抽象化をLlamaIndexの他のモジュール(インデックス、検索器、クエリエンジン、エージェント)にプラグインすると、データに対して高度なワークフローを構築することができます。
デフォルトでは、OpenAIの`gpt-3.5-turbo`モデルを使用します。ただし、使用されているベースLLMをカスタマイズすることもできます。
以下に、LLMカスタマイズの例をいくつか示します。
underlyingなLLMを変更する
出力トークンの数の変更(OpenAI, Cohere, AI21の場合)
コンテキストウィンドウからチャンクオーバーラップまで、LLMの全てのパラメータをよりきめ細かく制御
例: underlying LLMの変更
使用されているLLMをカスタマイズするスニペットの例を以下に示します。この例では、`gpt-3.5-turbo`の代わりに`gpt-4`を使用します。
使用可能なモデルには、gpt-3.5-turbo, gpt-3.5-turbo-instruct, gpt-3.5-turbo-16k, gpt-4, gpt-4-32k, text-davinci-003, text-davinci-002 が含まれます。
LangchainのLLMページに表示されているLLMをプラグインすることもできます。
from llama_index.core import KeywordTableIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
# alternatively
$ from langchain.llms import ...
documents = SimpleDirectoryReader("data").load_data()
# define LLM
llm = OpenAI(temperature=0,1, model="gpt-4")
# インデックス構築
index = KeywordTableIndex.form_documents(documents, llm=llm)
# クエリから応答を取得
query_engine = index.as_query_engine()
response = query_engine.query(
"What did the author do after his time at Y Combinator?"
)
例: 出力トークン数の変更(OpenAI, Cohere, AI21の場合)
出力トークンの数は通常、デフォルトで低い数値に設定されます(たとえば、OpenAIデフォルトは256)。
OpenAI、Cohere、AI21の場合はパラメーター(AI21の場合はmaxTokens)を設定するだけです。テキストのチャンク化や計算は内部で処理できます。
from llama_index.core import KeywordTableIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.core import Settings
documents = SimpleDirectoryReader("data").load_data()
# グローバルLLMを定義
Settings.llm = OpenAI(temperature=0, model="gpt-3.5-turbo", max_tokens=512)
例: context_windowとnum_outputの明示的な環境設定
languchainからの他のLLMクラスを使用している場合、デフォルトでは情報が利用できないため、context_windowおよびnum_outputを明示的に設定する必要があるかもしれません。
from llama_index.core import KeywordTableIndex, SimpleDirectoryReader
from llama_index.llms.openai import OpenAI
from llama_index.core import Settings
documents = SimpleDirectoryReader("data").load_data()
# コンテキストウィンドウのセット
Settings.context_window = 4096
# 出力トークンの数をセット
Settings.num_output = 256
# LLMの定義
Settings.llm = OpenAI(
temperature=0,
model="gpt-3.5-turbo",
max_tokens=num_output,
)
例: HuggingFace LLM の使用
LlamaIndexはHuggingFaceからのLLMを直接使用することができます。完全にプライベートな実行をしたい場合は、ローカル埋め込みモデルもセットアップすることに注意してください。
HuggingFaceの多くのオープンソースモデルでは、各プロンプトの前になんらかのプリアンブル(事前説明)が必要です。これは`system_prompt`と呼ばれます。さらに、クエリ自体には、`query_str`自体を囲む追加のラッパーが必要になることもあります。通常、これらの情報はすべて使用しているモデルのHuggingFaceモデルカードから入手できます。
以下の例では、system_prompt とquery_wrapper_prompt の両方を使用して、
from llama_index.core import PromptTemplate
# stringを入力zephyr-specificに変形
def completion_to_prompt(completion):
return f"<|system|>\n</s>\n</s>\n<|user|>\n{completion}</s>\n<|assistant|>\n"
# チャットメッセージリストをzephyr-specific 入力に変換
def messages_to_prompt(messages):
prompt = ""
for message in messages:
if message.role == "system":
prompt += f"<|system|>\n{message.content}</s>\n"
elif message.role == "user":
prompt += f"<|user|>\n{message.content}</s>\n"
elif message.role == "assistant":
prompt += f"<|assistant|>\n{message.content}</s>\n"
# ensure we start with a system prompt, insert blank if needed
if not prompt.startswith("<|system|>\n"):
prompt = "<|system|>\n</s>\n" + prompt
# add final assistant prompt
prompt = prompt + "<|assistant|>\n"
return prompt
import torch
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_idnex.core import Settings
Settings.llm = HuggingFaceLLM(
model_name="HuggingFaceH4/zephyr-7b-beta",
tokenizer_name="HuggingFaceH4/zephyr-7b-beta",
context_window=3900,
max_new_tokens=256,
generate_kwargs={"temperature": 0.7, "top_k": 50, "top_p": 0.95},
messages_to_prompt=messages_to_prompt,
completion_to_prompt=completion_to_prompt,
device_map="auto",
)
一部のモデルでは、トークナイザーからの全てのキーがモデルに渡されるとエラーが発生します。問題を引き起こす一般的なトークナイザー出力は`token_type_ids`です。以下は、入力をモデルに渡す前にこれを削除するようにpredictorを構成する例です。
HuggingFaceLLM(
# ...
tokenizer_outputs_to_remove=["token_type_ids"]
)
完全なAPIリファレンスはこちらです。
いくつかのノートブックの例もあります。
例: カスタムLLMモデルの使用 - 発展
カスタムLLMモデルを使用するには、LLM(またはより単純なインタフェースのCustomLLM)を実装するだけで良いです。テキストをモデルに私、新しく生成されたトークンを返す必要があります。
この実装は、ローカルモデルである場合もあれば、独自のAPIのラッパーである場合もあります。
完全にプライベートな実行を得るには、ローカル埋め込みモデルのセットアップする必要があります。
以下に短いテンプレート例を示します。
from typing import Optional, List, Mapping, Any
from llama_index.core import SImpleDirectoryReader, SummaryIndex
from llama_index.core.callbacks import CallbackManager
from llama_index.core.llms import(
CustomLLM,
CompletionResponse,
CompletionResponseGen,
LLMMetadata,
)
from llama_index.core.llms.callbacks import llm_completion_callback
from llama_index.core import Settings
class OurLLM(CustomLLM):
context_window: int = 3900
num_output: int = 256
model_name: str = "custom"
dummy_response: str = "My response"
@property
def metadata(self) -> LLMMetadata:
"""Get LLM metadata."""
return LLMMetadata(
context_window=self.context_window,
num_output=self.num_output,
model_name=self.model_name,
)
@llm_completion_callback()
def complete(self, prompt: str, **kwargs: Any) -> CompletionResponse:
return CompletionResponse(text=self.dummy_response)
@llm_completion_callback()
def stream_complete(
self, prompt: str, **kwargs: Any
) -> CompletionResponseGen:
response = ""
for token in self.dummy_response:
response += token
yield CompletionResponse(text=response, delta=token)
# define our LLM
Settings.llm = OurLLM()
# define embed model
Settings.embed_model = "local:BAAI/bge-base-en-v1.5"
# Load the your data
documents = SimpleDirectoryReader("./data").load_data()
index = SummaryIndex.from_documents(documents)
# Query and print response
query_engine = index.as_query_engine()
response = query_engine.query("<query_text>")
print(response)
この方法を使用すると、任意のLLMを使用できます。ローカルで実行するものも、独自のサーバーで実行するものもあります。クラスが実装され、生成されたトークンが返される限り、うまくいくはずです。
各モデルのコンテキストの長さはわずかに異なるため、プロンプトサイズをカスタマイズするにはプロンプトヘルパーを使用する必要があることに注意してください。
デコレーターはオプションですが、LLM呼び出しのコールバックを介して可観測性を提供します。
良好なパフォーマンスを得るには、内部プロンプトの調整が必要であることも注意してください。その場合でも、LlamaIndexが内部で使用する複雑なクエリを確実に処理できるように、十分な大きさのLLMを使用する必要があるため、得られるものは異なる場合があります。
すべてのデフォルトの内部プロンプトのリストはここにあり、チャット固有のプロンプトはここにリストされています。独自のカスタム プロンプトを実装することもできます。
まとめ
indexの引数に`llm=`を指定することで使用するLLMを変更できる
LangchainやHuggingFaceからモデルを引っ張ってくることができる
カスタムモデルを使用する際は、
次に読む記事
https://docs.llamaindex.ai/en/stable/understanding/evaluating/cost_analysis/root.html
支援のお願い
ここまで読んでいただきありがとうございます。「スキ」で反応をいただけると励みになります。
また、継続的な記事の公開のために、支援をしていただけると幸いです。
https://note.com/rhe/n/n01096a6aed38
この記事が気に入ったらサポートをしてみませんか?