はじめに
Outlinesはdottxt-aiによって開発されたオープンソースライブラリで、構造化テキスト生成によって大規模言語モデル(LLM)のアプリケーションを強化します。Outlinesは、正規表現、JSONパターン、Pydanticモデルによる高速生成を可能にし、貪欲アルゴリズムや多項式サンプリング、バンドルサーチなど様々なサンプリングアルゴリズムをサポートしています、多項式サンプリング、バンドル検索などの様々なサンプリングアルゴリズムをサポートしています。Outlinesは主流の推論フレームワーク(VLLM、TGIなど)の関数呼び出しに使用されている。
機能一覧
- マルチモデルの統合:OpenAI、トランスフォーマー、llama.cpp、その他のモデルをサポートします。
- シンプルで強力なヒント:Jinjaテンプレートエンジンをベースにしています。
- 正規表現構造生成: 正規表現に準拠したテキストを素早く生成
- JSON生成: JSONスキーマまたはPydanticモデルに基づいてテキストを生成します。
- 構文構造生成:ループ、条件分岐、カスタムPython関数生成のサポート
- キャッシュの生成:キャッシュ生成結果による効率化
- バッチ推論:推論のスピードを向上させるためにバッチ処理をサポートする。
- 複数のサンプリングアルゴリズム:貪欲、多項式、ビームサーチサンプリングアルゴリズムをサポート。
- Dockerのサポート:簡単にデプロイできるように、公式のDockerイメージを提供します。
ヘルプの使用
設置プロセス
- Python環境がインストールされていることを確認する。
- pipを使用してOutlinesをインストールします:
pip install outlines
- Rustバージョンのコア機能を使用する必要がある場合は、outlines-coreをインストールしてください:
pip install outlines-core
使用ガイドライン
基本的な使い方
- Outlinesライブラリをインポートする:
インポートアウトライン
- モデルを選択し、ロードする:
model = outlines.models.transformers("openai/gpt-3.5-turbo")
- プロンプトを作成し、テキストを生成します:
prompt = "AI技術の簡単な紹介文を生成してください。"
generated_text = model.generate(プロンプト)
print(generated_text)
高度な機能
- 正規表現を使って構造化テキストを生成する:
アウトラインをインポートする
generator = outlines.generate.regex("^[A-Z][a-z]+$")
result = generator("正規表現にマッチする単語を生成")
print(result)
- JSONスキーマを使用してテキストを生成します:
アウトラインのインポート
from pydantic import BaseModel
class Person(BaseModel): name: str
名前: str
年齢: int
generator = outlines.generate.json(Person)
result = generator({"name": "Alice", "age": 30})
result = generator({"name": "Alice", "age": 30})
- 複数のサンプリングアルゴリズムを使用:
アウトラインをインポートする
generator = outlines.generate.choice(model, ["option1", "option2", "option3"])
result = generator("Please select an option:")
print(result)
- Dockerイメージをデプロイする:
docker pull outlinesdev/outlines
docker run -p 8000:8000 outlinesdev/outlines
一般的な問題
- 発電速度を上げるには? バッチ推論を使い、キャッシュ関数を生成することで、生成速度を大幅に向上させることができる。
- カスタム関数を統合するには? カスタムPython関数を使用して、生成中に複雑なロジックを処理することができます。
大規模モデルからの非構造化出力がもたらす問題
課題
大規模言語モデル(LLM)は強力なテキスト生成能力を持つが、構造化データの生成においては十分な信頼性を発揮しない。これはエージェント中心のAIアプリケーションにとって深刻な問題となる。
核心問題
- 出力矛盾メールからフライト情報を抽出する場合、一貫性のあるJSONオブジェクトを出力するのが理想ですが、LLMはしばしば失敗し、「JSONデコードエラー」などの問題を引き起こします。
- 信頼性の欠如この予測不可能性が、LLMをベースにした複雑なモジュラー・システムを構築することを難しくしている。
影響を及ぼす
信頼できる構造化された出力がなければ、開発者は面倒な後処理(正規表現など)を通じて情報を抽出する必要があり、非効率的でエラーが発生しやすい開発につながる。
構造化アウトプットの利点
データの一般的な構造
一見構造化されていないように見えるデータ(例えばGSMデータセット)であっても、多くの場合、利用すべき固有の構造を持っている。
出力形式の保証
特定の構造(JSONや正規表現など)を定義することで、出力の妥当性を保証し、面倒な後処理を避けることができる。
パフォーマンスと効率の向上
- JSONの効率化構造化生成により、JSONの効率は17.7%から99.9%に向上した。
- 事例の必要性の減少GSM8Kベンチマークでは、1回の構造化生成の性能は、8回の非構造化生成とほぼ同等です。
- オープンモデルのパフォーマンス向上関数呼び出しベンチマークでは、86%から96.5%に性能が向上し、GPT-4を上回りました。
構造化されたアウトプットと非構造化されたアウトプット
構造化出力の利点をよりよく理解するために、次の例を使って構造化出力と非構造化出力の違いを比較してみよう。
Eメールからフライト情報を抽出する必要があるとする:
非構造化出力
大規模なモデルによって生成された出力が厳密にフォーマットされていない場合、以下のようなテキストが得られることがある:
パリへのフライトは来週の火曜日、おそらく午前10時で、飛行機はエールフランス。
この出力には、必要な情報(目的地、日付、時刻、航空会社など)は含まれているが、明確な構造はない。そこから情報を抽出するために、開発者は正規表現や他のテキスト処理方法を使用して各フィールドを解析する必要があるが、これは面倒であり、エラーが発生しやすい。例えば、モデルが異なる入力に対して異なるフォーマットの出力をする可能性があり、システム処理エラーや「JSONデコードエラー」につながります。
構造化出力
構造化生成が使用される場合、モデルは、例えば、事前に定義されたフォーマットに準拠したデータを返します:
{
「目的地": "パリ
"departure_date": "2024-11-25",
"時間": "10:00"、
「航空会社": "エールフランス"
}
この場合、出力は一様で標準化されている。すべてのキー・フィールドはすでに期待されるフォーマットで返されるため、開発者は情報を追加処理したり解析したりする必要がなくなる。これは開発時間を節約するだけでなく、エラーの確率を大幅に減らすことにもなる。
この比較を通じて、構造化出力がデータの一貫性と信頼性を保証するだけでなく、特に大規模なモデルから大量の情報を抽出して処理する必要がある場合に、処理効率を大幅に向上させることがはっきりとわかる。
Outlinesを使用すると、大きなモデルでパフォーマンスの問題が生じますか?
アウトラインはどのように機能するのか?
ラショナル
- ロジット処理モデルがロジットを生成した後、Outlinesは次のトークンの可能性をチェックし、定義された構造に違反するものをブロックする。
- 効率の最適化効率的なマスキングにより、追加のオーバーヘッドが極めて少ない。
典型例
「発生した場合 トークン が構造を破壊するような場合は、生成プロセスが事前に定義された構造に厳密に従うことを保証するために、即座にブロックされる"
構造化された出力は出力を遅くするのか?
そんなことはない。それどころか、構造化世代は通常、世代交代プロセスを加速させる:
- 無駄なトークンを減らすあらかじめ構造を定義しておくことで、冗長なフィールド名や括弧の生成を避けることができる。
- 世代数の減少構造化された出力は、一般的にトークンが少なく、速く、明確である。
アウトラインと他の構造化ライブラリとの比較
- ガイダンスと比較Outlinesは推論段階でのオーバーヘッドがほとんどゼロであるのに対し、Guidanceはトークンを大量に生成するときに大幅に遅くなることがある。
- LMQLとの比較アウトラインの強みは軽量設計と効率性だ。
コード例
以下は、構造化されたイベント・データを生成するためにOutlinesを使用する例である:
from datetime import datetime
from pydantic import BaseModel, Field
from outlines import generate, models
#ロードモデル
model = models.mlxlm("mlx-community/Hermes-3-Llama-3.1-8B-8bit")
#はPydanticを使ってイベント構造を定義する。
class Event(BaseModel).
title: str = Field(description="イベントのタイトル")
location: str
start: datetime = Field(
default=なし, description="isoフォーマットで利用可能な場合、イベントの日付")
)
# 現在の時刻を取得
now = datetime.now().strftime("%A %d %B %Y そして%H:%Mです")
# プロンプトの定義
プロンプト = f""
今日の日付と時刻は{now}です。
ユーザーメッセージが与えられたら、isoフォーマットで日付と時刻、場所、タイトルのようなイベントの情報を抽出する。
与えられた日付が相対的なものである場合、正しい日付を見つけるためにステップバイステップで考える。
以下はそのメッセージです。
"""
# メッセージの例
メッセージ = """Hello Kitty, my grandmother will be here, I think it's better to postpone our appointment to review maths lessons at next Friday at 2pm at the same place, 3 avenue.
数学の復習の約束は来週の金曜日の午後2時に同じ場所、3 avenue des tanneursですることにしましょう。
ではまた😘😘😘😘 """
# ジェネレータを作成する
ジェネレーター = generate.json(model, Event)
# イベントメッセージを取り出す
イベント = generator(prompt + message)
# 結果を出力する
print(f "今日:{now}")
print(event.json())
生成されるイベント情報は以下の通り:
{
"title": "数学の復習".
「location": "3 avenue des tanneurs".
"start": "2024-11-22T14:00:00Z"
}
結論と展望
構造化生成は、もはやニッチな機能ではなく、大規模モデル・アプリケーションの未来なのだ:
- 高い信頼性と効率性LLMの性能は、構造化生成によって著しく向上する。
- オープンソースの可能性アウトラインズの成功は、オープンソースモデルがプロプライエタリモデルと競合する可能性を示している。
将来的には、構造化生成がより一般的になるにつれて、Outlinesは開発者のツールボックスの重要な構成要素になると予想される。