Router
Router
laya.Router は各状態の言語を検出し、リクエストを対応するチェックポイントへ送り、初回使用時に
チェックポイントを読み込みます。
名前・型・既定値・コードは英語のまま、それ以外は翻訳です(未翻訳の項目は英語原文のまま表示されます)。
Router
Router(
models: Optional[Dict[str, str]] = None,
device: Optional[str] = None,
token: Optional[str] = None,
revision: Optional[str] = None,
revisions: Optional[Dict[str, Optional[str]]] = None,
max_loaded: int = 2,
default: str = "english",
auto_task_detection: bool = False,
standalone_repos: bool = False,
preload: bool = False,
lang_guess: Optional[Any] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: bool = True,
hooks_concurrent: bool = True,
hooks_timeout: Optional[float] = None,
agent_kwargs: Optional[Dict[str, Any]] = None,
sha256_digests: Optional[Dict[str, Optional[Dict[str, str]]]] = None,
)基底クラス: HookRegistry
Laya のチェックポイントを遅延読み込みし、各リクエストを適切なものへ送ります。
from laya import Router
r = Router()
r.predict({"message": "Mein Konto wurde zweimal belastet"}, questions) # -> multilingual
r.predict({"message": "I was charged twice"}, questions) # -> english
r.predict(state, questions, model="typed-decisions") # explicit
モデルは初回使用時にダウンロードして構築されます。max_loaded は常駐する数を上限で抑えます(最も長く使われていないものが追い出されます)。3 つを合わせると約 11.6 億パラメータになるためです。
既定値が 2 なのは、自動ルーティングが選ぶのは english と multilingual の間だけだからです。上限を 1 にすると、スクリプトが切り替わるたびに、たった今追い出したチェックポイントを再構築することになります。これはリクエストあたり数秒で、まさに Router が存在する理由であるトラフィックに効いてきます。1 つの言語しか見ないトラフィックは 2 つ目のチェックポイントを構築しないので、既定値はそのようなトラフィックに何のコストもかけません。メモリが厳しいホストでは 1 に下げ、auto_task_detection、明示的な model=、または明示的な task= から typed-decisions にも到達しうるときは 3 に上げてください(あるいはプリロードを)。
サーバーやデモでは代わりにプリロードしてください。コールドロードは数秒かかる一方、検出はマイクロ秒で済みます。つまり既定値のままでも、ある言語が初めて現れたときに 1 回分のロードを払います。
r = Router(preload=True) # all three resident, routing is free
r = Router(preload=True, device="cuda")
r.preload(["english", "multilingual"]) # or just the two you serve
Hub のリビジョンはオプトインです。revision はすべてのモデルに 1 つのコミットを適用し、revisions={"english": "...", "multilingual": "..."} はそれをモデルごとに上書きします。独立したリポジトリが異なるコミットでレビューされている場合に有用です。どちらも指定しなければ、huggingface_hub の通常の既定値と既存のオフラインキャッシュが使われます。
laya.Agent が受け付けるその他のものは agent_kwargs を通じて渡せます。これは Router が構築するすべてのチェックポイントにマージされます。
Router(agent_kwargs={"lang_temperatures": {"de": {"temperature": [1.0, 1.4, 2.0]}}})
Router(agent_kwargs={"expected_sha256": {"model.safetensors": "a3f1..."}})
Router(agent_kwargs={"fast": True})
Router 自身が使う名前 —— model_id_or_path、device、token、subfolder、revision、およびフックの引数 —— は、黙って上書きされるのではなくここで拒否されます。残りの名前は構築時に Agent.__init__ と照合されるので、綴りを間違えたオプションは最初のリクエストではなく Router(...) の行で失敗します。
成果物のダイジェストはオプトインで、常にモデルごとです。sha256_digests={"english": {...}} は、その {path relative to the checkpoint dir: hexdigest} のマップを、それを読み込む Agent に渡します。こうして改ざんされたりすり替えられた重みファイルは、解析される前に拒否されます。revision の Router 全体に相当するものはありません。ダイジェストはコミット SHA と違って共有できないからです。同梱リポジトリは english、multilingual、typed-decisions のそれぞれに別々の model.safetensors を入れているので、1 つの平坦なマップはどれか 1 つにしか一致しません。None または {} で挙げたモデルは検証なしで読み込まれます。
同じ分割は、環境変数だけで設定されるプロセスにも用意されています。LAYA_SHA256_DIGESTS がモデルをキーにしたマップ({"english": {...}, "multilingual": {...}})を保持しているときは、それをチェックポイントごとに与えます。こうして複数を常駐させるサーバーは、2 つ目で起動を拒否する代わりに、それぞれに独自のダイジェストを固定できます。平坦な LAYA_SHA256_DIGESTS は従来の意味を保ち、laya.revisions によってそのプロセスが読み込むすべてのチェックポイントに適用されます。これはチェックポイントが 1 つの場合に正しい挙動です。引数のほうに項目があれば、それが名指しするモデルについては環境変数より優先されます。
フックはオプトインで、Router のレベルで動きます。on_route はルーティングの決定を見て、on_load / on_evict はモデルのライフサイクルを見て、on_predict_start / on_predict_end は「ルーティング+推論」の呼び出し全体を包みます。laya.hooks を参照してください。
引数
modelsOptional[Dict[str, str]]=NonedeviceOptional[str]=NonetokenOptional[str]=NonerevisionOptional[str]=NonerevisionsOptional[Dict[str, Optional[str]]]=Nonemax_loadedint=2defaultstr="english"auto_task_detectionbool=Falsestandalone_reposbool=Falsepreloadbool=Falselang_guessOptional[Any]=Nonehooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raisebool=Truehooks_concurrentbool=Truehooks_timeoutOptional[float]=Noneagent_kwargsOptional[Dict[str, Any]]=Nonesha256_digestsOptional[Dict[str, Optional[Dict[str, str]]]]=None
load
load(name: str)name に対応する Agent を返します。初回使用時にダウンロードして構築します。
同時に呼び出した側は、重複して構築せず 1 つの Agent を共有します。
引数
namestr
attach
attach(name: str, agent: Any)すでに構築済みの Agent を、2 つ目のコピーを読み込む代わりに name の下へ登録します。
プロセスが別の理由でチェックポイントを読み込んでいる場合に有用です。すでに convaiinnovations/laya を構築済みのデモは、421M パラメータの複製のためにコストを —— そしてメモリを —— 払う代わりに、それを router に渡せます。
引数
namestragentAny
preload
preload(names: Optional[List[str]] = None)チェックポイントを事前にダウンロードして構築し、どのリクエストもモデルの読み込みコストを払わないようにします。
コールドロードは数秒かかり、言語検出はマイクロ秒で済みます。すべてのチェックポイントが常駐していれば、ルーティングは実質的に無料です —— サーバーやデモで望ましいのはまさにこれです。max_loaded は、要求されたチェックポイントとすでに常駐しているエージェントの両方に収まるよう引き上げられるので、増分のプリロードがどちらかを追い出すことはありません。
引数
namesOptional[List[str]]=None
unload
unload(name: Optional[str] = None)1 つのモデル、またはすべてを解放します。
引数
nameOptional[str]=None
loaded_revisions
loaded_revisions: Dict[str, Optional[str]]常駐している各エージェントを、どのコミット SHA から読み込んだか(ローカルパスでは None)。
route
route(
state: Union[str, dict, list, None],
questions: Optional[Dict[str, Any]] = None,
model: Optional[str] = None,
task: Optional[str] = None,
lang: Optional[str] = None,
lang_guess: Optional[Any] = None,
hooks=None,
hooks_raise: Optional[bool] = None,
hooks_timeout: Optional[float] = None,
) -> RouteDecisionどのチェックポイントを使うかを決め、そのうえで on_route のフックに観察または差し替えを許します。
ctx.decision がその RouteDecision です。フックはそれを差し替えることができ(たとえばチェックポイントを固定するため)、差し替えたものが返され、使われます。hooks は呼び出しごとのフックで、Router にインストール済みのフックの後ろに追加されます。
引数
stateUnion[str, dict, list, None]questionsOptional[Dict[str, Any]]=NonemodelOptional[str]=NonetaskOptional[str]=NonelangOptional[str]=Nonelang_guessOptional[Any]=Nonehooks=Nonehooks_raiseOptional[bool]=Nonehooks_timeoutOptional[float]=None
predict
predict(
state: Union[str, dict, list],
questions: Dict[str, Any],
model: Optional[str] = None,
task: Optional[str] = None,
lang: Optional[str] = None,
lang_guess: Optional[Any] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: Optional[bool] = None,
hooks_timeout: Optional[float] = None,
max_len: Optional[int] = None,
head_max_len: Optional[int] = None,
min_confidence: Optional[float] = None,
) -> Dict[str, Any]ルーティングしてから、選ばれたチェックポイントで 1 回のフォワードパスですべての質問に答えます。
結果は通常の system_one のペイロードに、その決定を記録した routing キーを加えたものです。Router レベルの on_predict_start / on_predict_end フックが「ルーティング+推論」の呼び出し全体を包み、ctx.decision を見られます。laya.hooks を参照してください。max_len / head_max_len はこの呼び出しにおけるエージェントのトークン予算を上書きします(開始フックが ctx.max_len / ctx.head_max_len を設定することもできます)。
引数
stateUnion[str, dict, list]questionsDict[str, Any]modelOptional[str]=NonetaskOptional[str]=NonelangOptional[str]=Nonelang_guessOptional[Any]=Nonehooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raiseOptional[bool]=Nonehooks_timeoutOptional[float]=Nonemax_lenOptional[int]=Nonehead_max_lenOptional[int]=Nonemin_confidenceOptional[float]=None
predict_long
predict_long(
state: Union[str, dict, list],
questions: Dict[str, Any],
model: Optional[str] = None,
task: Optional[str] = None,
lang: Optional[str] = None,
lang_guess: Optional[Any] = None,
window: Optional[int] = None,
stride: Optional[int] = None,
aggregate: str = "auto",
batch_size: Optional[int] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: Optional[bool] = None,
hooks_timeout: Optional[float] = None,
) -> Dict[str, Any]ルーティングしてから、状態の最初のウィンドウだけでなくすべてのウィンドウを走査します。
predict は 1 つのウィンドウから状態を採点します。max_len を超えた部分は切り捨てられ(会話リストでは最後のウィンドウ、それ以外では最初のウィンドウ)、モデルには決して届きません。このメソッドは predict とまったく同じようにルーティングします —— 同じ model/task/lang のヒント、同じ Router レベルのフック、同じ routing キーと usage —— そしてルーティング先のエージェントの predict_long で状態を採点します。あれは状態を重なり合うウィンドウに分け、質問ごとに集約します。集約の規則は laya.agent.Agent.predict_long のものです。noul は最も強いウィンドウを、choice/score は最も自信のあるウィンドウを取ります。
呼び出しごとのフック(hooks、on_predict_start、on_predict_end、hooks_raise、hooks_timeout)は、predict を包むのとまったく同じように「ルーティング+走査」全体を包みます。走査は最後に走るので、答えてしまう開始フック(ctx.skip(...))や状態を書き換える開始フックが優先されます。ここでは max_len / head_max_len は受け付けません —— ウィンドウの大きさは window かチェックポイントの予算で決まり、単一ウィンドウの切り捨てを上書きすることこそが predict_long の役割だからです。
引数
stateUnion[str, dict, list]questionsDict[str, Any]modelOptional[str]=NonetaskOptional[str]=NonelangOptional[str]=Nonelang_guessOptional[Any]=NonewindowOptional[int]=Noneウィンドウあたりの状態トークン数。ルーティング先チェックポイントの予算(
max_len - head_max_len - 8)が既定です。ウィンドウを小さくすると局所的な信号が際立ちます。strideOptional[int]=Noneウィンドウ間のトークン刻み。既定は
window // 2(50% の重なり)です。aggregatestr="auto""auto"(上記の型ごとの規則)が現時点で唯一のモードです。
batch_sizeOptional[int]=Noneフォワードパスあたりのウィンドウ数の上限。非常に長い状態でメモリを抑えるためです。
hooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raiseOptional[bool]=Nonehooks_timeoutOptional[float]=None
戻り値
The usual predict payload, with usage["windows"] counting the windows scored.
例外
TypeError: the routed agent has no predict_long (an ONNX agent, or one attached by
hand), so there is nothing to scan with. Raised under the router's
hooks_raise policy, which defaults to raising.
decide
decide(
state: Union[str, dict, list],
schema: Any = None,
questions: Optional[Dict[str, Any]] = None,
return_details: bool = False,
min_confidence: Optional[float] = None,
predict_kwargs,
) -> Anystate をスキーマ(JSON schema または pydantic モデル)に照らして答え、型付きの値を返します。
laya.structured を参照してください。schema か questions のどちらか一方だけを渡します。追加のキーワード引数(たとえば model=、task=、hooks=)は predict に転送されます。
引数
stateUnion[str, dict, list]schemaAny=NonequestionsOptional[Dict[str, Any]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
decide_batch
decide_batch(
states: Sequence[Any],
schema: Any = None,
questions: Optional[Dict[str, Any]] = None,
return_details: bool = False,
min_confidence: Optional[float] = None,
predict_kwargs,
) -> List[Any]複数の状態を 1 つのスキーマ(JSON schema または pydantic モデル)に照らして、1 回のバッチ呼び出しで答えます。
:meth:decide のスループット版です。スキーマは 1 回だけ計画され、その質問が :meth:predict_batch を通じてすべての状態に対して実行され(グループ化されたフォワードパス、結果は入力順)、そのうえで各状態の答えが decide と同じように射影されます。追加のキーワード引数(batch_size=、model=、hooks= など)は predict_batch に転送されます。laya.structured を参照してください。
引数
statesSequence[Any]schemaAny=NonequestionsOptional[Dict[str, Any]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
route_batch
route_batch(
requests: Sequence[Dict[str, Any]],
hooks_timeout: Optional[float] = None,
) -> List[RouteDecision]チェックポイントをまったく読み込まずに、異種のリクエストのバッチをルーティングします。
各リクエストは state と questions を持つマッピングで、:meth:route が受け付けるのと同じ任意のルーティング上書き(model、task、lang、lang_guess)を伴えます。返る決定は入力順を保ちます。
これは意図的に推論から切り離されています。呼び出し側が、モデル読み込みのコストを払う前にルーティングの決定を調べたり集約したりできるようにするためです。
引数
requestsSequence[Dict[str, Any]]リクエスト辞書の並び。各項目には
stateとquestionsが必要です。hooks_timeoutOptional[float]=Noneこの呼び出しにおける Router の
hooks_timeoutを上書きし、各リクエストのon_routeディスパッチに適用します。:meth:routeと同じです。
predict_batch
predict_batch(
requests: Sequence[Dict[str, Any]],
batch_size: Optional[int] = None,
hooks_timeout: Optional[float] = None,
min_confidence: Optional[float] = None,
sort_by_length: bool = False,
) -> List[Dict[str, Any]]モデルの入れ替えを最小限に抑えて、異種のリクエストのバッチをルーティングして実行します。
リクエストはまずルーティングされ、チェックポイントごとにまとめられます。各チェックポイント内では、同じ質問スキーマを共有するリクエストが Agent.predict_batch に渡され、状態がフォワードパスを共有できるようにします。そのうえで結果が元のリクエスト順に戻されます。
リクエストはそれぞれ独立に model、task、lang、lang_guess、max_len、head_max_len を指定でき、異なる質問スキーマを使うこともできます。max_len / head_max_len は、predict が呼び出し引数として受け取るトークン予算の上書きを、リクエスト単位で行う形です。その 1 つのリクエストについてチェックポイントの状態予算と質問ヘッドの予算を設定するので、バッチ内の他のリクエストを同じウィンドウに縮めずに、幅の広い質問を投げられます。異なる予算を求めるリクエストは別々のフォワードパスに分けられます。1 回の Agent.predict_batch 呼び出しは、そのすべての状態に対して 1 つの予算しか持たないからです。開始フックはなお ctx 上でどちらの値も差し替えられます。
Router レベルの予測フックは predict と同じくリクエストごとに走ります。各リクエストが独自の PredictContext を持つので、on_predict_start はそのリクエストの状態・質問・トークン予算を差し替えたり、ctx.skip(...) でそれを飛ばしたりでき、on_predict_end はその結果を見て差し替えられます。リクエストは、それぞれの開始フックが走り終えてからフォワードパスのためにグループ化され、同じチェックポイントのグループでは、リクエストは開始した順とは逆の順で終わります。あるチェックポイントのグループが失敗した場合、そのうち開始フックが走ったすべてのリクエストが例外とともに失敗します。キャッシュに当たったものも含まれます。それぞれが on_error を受け取り、次に on_predict_end を受け取ってから、例外が伝播します。
引数
requestsSequence[Dict[str, Any]]リクエスト辞書の並び。各項目には
stateとquestionsが必要で、model、task、lang、lang_guessのルーティング上書きと、max_len/head_max_lenのトークン予算上書きを含められます。batch_sizeOptional[int]=NoneAgent のフォワードパス 1 バッチあたりの状態数の任意の上限。
hooks_timeoutOptional[float]=Noneこの呼び出しにおける Router の
hooks_timeoutを上書きします。min_confidenceOptional[float]=Nonesort_by_lengthbool=Falseすべての
Agent.predict_batch呼び出しに転送されるので、各質問グループはより短い上限へ padding されます。Agent.predict_batchを参照してください。どちらの場合も結果は入力順を保ちます。このスイッチより前のpredict_batchを持つ、attach されたエージェントでは黙って無視されます(#294)。
戻り値
One normal Router prediction result per request, in the same order as the input.
RouteDecision
RouteDecision()基底クラス: dict
ルーティングの結果です。どのモデルを選んだか、その理由、そして何を検出したかを含みます。
辞書として振る舞うため、そのまま API レスポンスにシリアライズできます。
DEFAULT_MODELS
DEFAULT_MODELS = {
"english": (BUNDLE_REPO, None),
"multilingual": (BUNDLE_REPO, "multilingual"),
"typed-decisions": (BUNDLE_REPO, "typed-decisions"),
}