「spacy-llmを使用したエレガントなプロンプトのバージョニングとLLMモデルの設定」
Setting up elegant prompt versioning and LLM model using spacy-llm
spacy-llmを使用してプロンプトの管理を簡素化し、データ抽出のためのタスクを作成する方法
プロンプトの管理とOpenAIリクエストの失敗の処理は、困難なタスクです。幸いにも、spaCyはspacy-llmをリリースしました。これはカスタムなソリューションをゼロから作成する必要なく、プロンプトの管理を簡素化する強力なツールです。
この記事では、プロンプトを使用してテキストからデータを抽出するタスクを作成するために、spacy-llmをどのように活用するかを学びます。spaCyの基本とspacy-llmのいくつかの機能について詳しく調べていきます。
spaCyとspacy-llm 101
spaCyはPythonとCythonでの高度なNLPライブラリです。テキストデータを扱う際には、トークン化やPOSタグ付けなど、いくつかの処理ステップが通常必要です。これらのステップを実行するために、spaCyは処理パイプラインを呼び出すnlp
メソッドを提供しています。
spaCy v3.0では、config.cfg
というファイルを導入しました。このファイルにはこれらのパイプラインの詳細な設定を含めることができます。
config.cfg
は、confectionという設定システムを使用して、任意のオブジェクトツリーの作成を可能にします。たとえば、confectionは次のconfig.cfg
を解析します:
[training]patience = 10dropout = 0.2use_vectors = false[training.logging]level = "INFO"[nlp]# This uses the value of training.use_vectorsuse_vectors = ${training.use_vectors}lang = "en"
次のように変換されます:
{ "training": { "patience": 10, "dropout": 0.2, "use_vectors": false, "logging": { "level": "INFO" } }, "nlp": { "use_vectors": false, "lang": "en" }}
各パイプラインはコンポーネントを使用し、spacy-llmはカタログを使用してパイプラインのコンポーネントを格納します。このライブラリは、コンポーネントの効率的な管理を可能にする関数レジストリを導入しています。llm
コンポーネントは、次の2つの主な設定で定義されます:
- タスク: LLMに送信するプロンプトと、結果の応答を解析する機能を定義します
- モデル: モデルと接続方法を定義します
パイプラインにLLMを使用するコンポーネントを含めるには、いくつかの手順に従う必要があります。まず、タスクを作成し、レジストリに登録する必要があります。次に、モデルを使用してプロンプトを実行し、応答を取得します。それでは、パイプラインを実行できるようにこれらの手順をすべて行いましょう
テキストからデータを抽出するためのタスクの作成
https://dummyjson.com/から引用を使用して、すべての引用からコンテキストを抽出するタスクを作成します。プロンプトを作成し、タスクを登録し、最後に設定ファイルを作成します。
1. プロンプト
spacy-llmでは、Jinjaテンプレートを使用して指示と例を定義します。 {{ text }}
は提供する引用で置き換えられます。これが私たちのプロンプトです:
テキストからコンテキストを抽出するのが得意です。タスクは引用を受け取り、引用のコンテキストを提供することです。このコンテキストは引用をグループ化するために使用されます。回答には他のテキストを入れないで、最大3つの単語でコンテキストを提供してください。{# whitespace #}{# whitespace #}以下は分類が必要な引用です{# whitespace #}{# whitespace #}引用:'''{{ text }}'''コンテキスト
2. タスククラス
さて、タスクのためのクラスを作成しましょう。このクラスは2つの関数を実装する必要があります:
generate_prompts(docs: Iterable[Doc]) -> Iterable[str]
: spaCyのDoc
オブジェクトのリストを受け取り、プロンプトのリストに変換する関数parse_responses(docs: Iterable[Doc], responses: Iterable[str]) -> Iterable[Doc]
: LLMの出力をspaCyのDoc
オブジェクトに解析するための関数
generate_prompts
はJinjaテンプレートを使用し、parse_responses
はDoc
にcontext
属性を追加します。これはQuoteContextExtractTask
クラスです:
from pathlib import Pathfrom spacy_llm.registry import registryimport jinja2from typing import Iterablefrom spacy.tokens import DocTEMPLATE_DIR = Path("templates")def read_template(name: str) -> str: """テンプレートを読み込む""" path = TEMPLATE_DIR / f"{name}.jinja" if not path.exists(): raise ValueError(f"{name}は有効なテンプレートではありません。") return path.read_text()class QuoteContextExtractTask: def __init__(self, template: str = "quotecontextextract.jinja", field: str = "context"): self._template = read_template(template) self._field = field def _check_doc_extension(self): """必要に応じて拡張子を追加します。""" if not Doc.has_extension(self._field): Doc.set_extension(self._field, default=None) def generate_prompts(self, docs: Iterable[Doc]) -> Iterable[str]: environment = jinja2.Environment() _template = environment.from_string(self._template) for doc in docs: prompt = _template.render( text=doc.text, ) yield prompt def parse_responses( self, docs: Iterable[Doc], responses: Iterable[str] ) -> Iterable[Doc]: self._check_doc_extension() for doc, prompt_response in zip(docs, responses): try: setattr( doc._, self._field, prompt_response.replace("Context:", "").strip(), ), except ValueError: setattr(doc._, self._field, None) yield doc
これで、spacy-llmのllm_tasks
レジストリにタスクを追加するだけです:
@registry.llm_tasks("my_namespace.QuoteContextExtractTask.v1")def make_quote_extraction() -> "QuoteContextExtractTask": return QuoteContextExtractTask()
3. The config.cfg file
OpenAIのGPT-3.5モデルを使用します。spacy-llmにはそれ用のモデルがあるため、シークレットキーが環境変数として利用可能であることを確認する必要があります:
export OPENAI_API_KEY="sk-..."export OPENAI_API_ORG="org-..."
パイプラインを実行するnlp
メソッドを構築するために、spacy-llmのassemble
メソッドを使用します。このメソッドは.cfg
ファイルから読み込みます。ファイルはGPT-3.5モデル(既にレジストリにあります)と作成したタスクを参照する必要があります:
[nlp]lang = "en"pipeline = ["llm"]batch_size = 128[components][components.llm]factory = "llm"[components.llm.model]@llm_models = "spacy.GPT-3-5.v1"config = {"temperature": 0.1}[components.llm.task]@llm_tasks = "my_namespace.QuoteContextExtractTask.v1"
4. Running the pipeline
これで、すべてを組み合わせてコードを実行するだけです:
import osfrom pathlib import Pathimport typerfrom wasabi import msgfrom spacy_llm.util import assemblefrom quotecontextextract import QuoteContextExtractTaskArg = typer.ArgumentOpt = typer.Optiondef run_pipeline( # fmt: off text: str = Arg("", help="Text to perform text categorization on."), config_path: Path = Arg(..., help="Path to the configuration file to use."), verbose: bool = Opt(False, "--verbose", "-v", help="Show extra information."), # fmt: on): if not os.getenv("OPENAI_API_KEY", None): msg.fail( "OPENAI_API_KEY env variable was not found. " "Set it by running 'export OPENAI_API_KEY=...' and try again.", exits=1, ) msg.text(f"Loading config from {config_path}", show=verbose) nlp = assemble( config_path ) doc = nlp(text) msg.text(f"Quote: {doc.text}") msg.text(f"Context: {doc._.context}")if __name__ == "__main__": typer.run(run_pipeline)
そして実行します:
python3 run_pipeline.py "We must balance conspicuous consumption with conscious capitalism." ./config.cfg>>> Quote: We must balance conspicuous consumption with conscious capitalism.Context: Business ethics.
プロンプトを変更したい場合は、別のJinjaファイルを作成し、最初のものと同じ方法でmy_namespace.QuoteContextExtractTask.v2
タスクを作成してください。温度を変更したい場合は、config.cfg
ファイルのパラメータを変更するだけです。素敵ですね?
最終的な考え
OpenAI RESTリクエストの処理能力とプロンプトの保存とバージョン管理の直感的なアプローチは、spacy-llmのお気に入りの機能です。さらに、ライブラリはドキュメントごとのプロンプトと応答をキャッシュするためのキャッシュ、フューショットプロンプトの例を提供するためのメソッド、ログ機能などを提供しています。
今日のコード全体はこちらからご覧いただけます:https://github.com/dmesquita/spacy-llm-elegant-prompt-versioning。
いつもお読みいただきありがとうございます!
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles