ルーティング
Router はリクエストごとにチェックポイントを選び、予測が必要としたときにその Agent を読み込み
ます。既定のルーターは英語のテキストを英語チェックポイントへ、その他の対応言語を多言語
チェックポイントへ送ります。この選択を上書きしたり、独自の言語ヒントを渡したり、typed-decisions
チェックポイントを明示的に選んだりできます。
このガイドはモデルの選択とライフサイクルを扱います。予測が受け付ける質問の種類は スキーマ駆動の意思決定 を、ライフサイクルのコールバックは 予測フック を参照してください。
クイックスタート
from laya import Router
router = Router()
questions = {
"department": {
"type": "choice",
"instructions": "Which department should handle this request?",
"criteria": {
"billing": "invoices, payments, refunds",
"technical": "bugs, outages, system errors",
"other": "everything else",
},
}
}
result = router.predict("We were billed twice. Please refund the duplicate charge.", questions)
print(result["answers"]["department"]["choice"])
print(result["routing"]["model"])
Router() の作成は既定ではチェックポイントをダウンロードしません。predict() はリクエストを
ルーティングし、初回使用時に選ばれたチェックポイントを読み込みます。そのため、最初の予測は
ファイルのダウンロードとモデルの初期化の間だけ長くかかることがあります。以降の予測は
読み込み済みのエージェントを再利用します。
チェックポイントの選ばれ方
Router.route(state, questions, ...) は、チェックポイントを読み込むことも推論を実行することも
なく RouteDecision を返します。この決定には、選ばれたモデル、人間が読める理由、そして
組み込みの検出を使った場合は言語検出の詳細が含まれます。
ルーティングは入力を次の順序で確認します。
model=はチェックポイントを直接選びます。task=は指定されたタスクのチェックポイントを選びます。auto_task_detection=Trueの場合、既知の typed-decisions 質問 ID 集合のいずれかと完全一致するとtyped-decisionsを選びます。- 認識された
lang=の値は英語または多言語を選びます。 - 呼び出しごとの
lang_guess=、またはルーターに設定されたlang_guessが参照されます。 - 組み込みの文字体系と言語の分析がチェックポイントを選びます。信頼できる言語シグナルがなければ、
ルーターは設定された
default(既定では英語)を使います。
最初に一致したルールが優先されます。たとえば model="multilingual" は lang="en" を上書きします。
無効なモデル名は検出に落ちるのではなく ValueError を送出します。
decision = router.route(
"La aplicación se cierra cada vez que abro la configuración.",
questions,
)
print(decision.model) # multilingual
print(decision.reason) # why that checkpoint was selected
RouteDecision は dict 互換なので、そのフィールドは decision["model"] や decision["reason"]
といったキーでも取得できます。Router.predict() は同じ決定を結果の "routing" キーの下に含めます。
言語ルーティングを上書きする
アプリケーションがリクエストの言語をすでに知っている場合は lang= を使います。"en"、"en-US"、
"en_US.UTF-8" といった言語タグを受け付けます。英語は english へ、その他の認識された言語コードは
multilingual へルーティングされます。
result = router.predict(state, questions, lang="de")
assert result["routing"]["model"] == "multilingual"
アプリケーションが独自の言語検出器を持っている場合は、その結果を言語コードとして lang_guess= で
渡します。呼び出し可能オブジェクトは状態を受け取り、コードを返すか、棄権を示す None を返せます:
def detect_request_language(state):
# Replace this with the application's detector.
return "en" if "invoice" in str(state).lower() else None
router = Router(lang_guess=detect_request_language)
棄権するヒントはチェックポイントを強制しません。ルーティングは次のルールへ進みます。これには
None、空文字列、どの言語も名指ししないコード(C、POSIX、C.UTF-8、und、zxx、mul)が
含まれます。これらは検出器が言うことがないときに返すもので、棄権がリクエストを誤ったモデルに
黙って固定することはありません。
認識されないヒントは棄権ではありません。"xx"、False、0 を含むその他の値は「英語ではない」と
読まれ、多言語チェックポイントへルーティングされます。したがって None ではなく不正なコードを
返す検出器は実際にチェックポイントを選びます。それが問題になるなら、渡す前にその未知のケースを
None に対応させてください。
組み込みの検出は軽量な文字体系と言語のヒューリスティックであり、汎用の言語識別モデルでは ありません。text、dict、list の状態にある文字列値を分析します。辞書のキーは、英語のフィールド名で あることが多いため無視されます。短い、または曖昧なテキストは既定のチェックポイントを使うことが あります。既知のワークロードでは、明示的な言語か、アプリケーションが提供するヒントのほうが 予測しやすくなります。
typed-decisions を選ぶ
typed-decisions チェックポイントは既定では自動的に選ばれません。明示的に選んでください:
result = router.predict(state, questions, model="typed-decisions")
# `task="typed_decisions"` is also accepted.
あるいは auto_task_detection=True を設定します。するとルーターは、質問 ID が既知の typed-decision
ワークフローのいずれかと完全一致するかどうかを確認します。質問の文言からタスクを推測することは
なく、無関係な質問 ID を加えると完全一致が成立しなくなります。
router = Router(auto_task_detection=True)
モデルを読み込まずにルーティングを調べる
単一の決定を調べるには route() を、一連の決定を調べるには route_batch() を使います。どちらの
メソッドもチェックポイントを読み込まないので、推論を実行する前にルーティング規則をデバッグする
のに役立ちます。
requests = [
{"state": "Please refund the duplicate charge.", "questions": questions},
{"state": "Necesito ayuda con mi factura.", "questions": questions},
]
decisions = router.route_batch(requests)
for decision in decisions:
print(decision.model, decision.reason)
route_batch() の各項目には state と questions が必要です。省略可能なルーティング上書き
(model、task、lang、lang_guess)は項目ごとに指定します。決定は入力順のままです。
読み込みとメモリ
既定では、ルーターは初めて必要になったときにチェックポイントを読み込み、最大 2 つのエージェントを
常駐させます。自動の言語ルーティングは通常、英語と多言語のチェックポイントだけを必要とします。
リクエストが typed-decisions も選びうる場合、小さな max_loaded は別のエージェントを追い出し、
次に必要になったときに再び読み込ませることがあります。
# Load only the checkpoints this process serves, before accepting requests.
router = Router()
router.preload(["english", "multilingual"])
print(router.loaded) # currently resident checkpoint names
router.unload("multilingual")
Router(preload=True) は設定されたすべてのチェックポイントを事前読み込みします。事前読み込みは、
要求された集合に収まるよう常駐モデルの上限を引き上げます。事前読み込みせずに 3 つのチェックポイント
のワークロードを制御するには、max_loaded=3 を設定します。1 つのエージェントを解放するには
unload()、すべてを解放するには router.unload() を使います。コンテキストマネージャーとして
使われるルーターは、ブロックを抜けるときにエージェントを解放します:
with Router(preload=True) as router:
result = router.predict(state, questions)
ルーターを構築するときに device="cpu"、device="cuda"、またはその他の対応する PyTorch デバイスを
渡すこともできます。どのデバイスが特定のモデルを実行できるかは、利用可否とメモリで決まります。
混在バッチ
predict_batch() は、状態、モデル、言語、質問スキーマが異なるリクエストを受け付けます。ルーターは
まずリクエストごとに決定を下し、チェックポイントと互換性のある質問スキーマで作業をグループ化し、
その後で結果を元の入力順に戻します。
requests = [
{"state": "Please refund the duplicate charge.", "questions": questions},
{"state": "Mi cuenta fue cobrada dos veces.", "questions": questions},
{"state": "A third request", "questions": questions, "model": "typed-decisions"},
]
results = router.predict_batch(requests, batch_size=8)
各リクエストには state と questions が必要です。model、task、lang、lang_guess も
含められます。チェックポイントと質問スキーマを共有するリクエストは、1 回の Agent バッチ順伝播を
共有できます。異なるスキーマやチェックポイントは別々のグループで処理されます。batch_size は、
まとめて Agent に渡す状態の数を制限します。結果は依然としてリクエスト順に対応します。
エントリポイントの選び方
- モデルを読み込まずに決定を調べる必要があるときは
route()またはroute_batch()を使います。 - 単一のリクエストには
predict()、複数の、異種でありうるリクエストにはpredict_batch()を 使います。 - アプリケーションがすでに 1 つのチェックポイントを選んで読み込み、自動ルーティングを必要としない
ときは
Agentを直接使います。
コンストラクタとメソッドの詳細は Router API リファレンス を参照してください。