Agent
Agent
laya.Agent loads one checkpoint and answers typed questions about a state. laya.load is
a shortcut for Agent(...), and laya.RLAgent is an alias of Agent. ONNXAgent runs an
exported ONNX model on CPU; import it from laya.onnx_agent.
Names, types, defaults and code stay in English; the rest is translated (entries not translated yet are shown in the original English).
Agent
Agent(
model_id_or_path: str = "convaiinnovations/laya",
device: Optional[str] = None,
token: Optional[str] = None,
subfolder: Optional[str] = None,
fast: bool = False,
compile: bool = False,
revision: Optional[str] = None,
expected_sha256: Optional[Dict[str, str]] = None,
lang_temperatures: Optional[Dict[str, Dict[str, 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,
calibration: Optional[str] = None,
)Bases: HookRegistry
System 1 decision model runtime: fast, non-autoregressive, calibrated decisions.
dtype is the autocast target, not the precision of every call. On MPS a call
autocasts only at or above mps_amp_min_rows rows, so dtype can say float16 while
a call runs in float32. dtype_for(rows) returns the precision of a call with rows rows.
Load a Laya checkpoint.
revision optionally pins the Hub download to an explicit commit SHA/branch/tag;
when omitted, huggingface_hub's normal default and existing offline cache are used.
expected_sha256 ({path relative to the checkpoint dir: hexdigest})
verifies artifact integrity before any weight is parsed or executed; it is opt-in
and applies to local directories too. A missing artifact raises FileNotFoundError
and a digest mismatch raises ValueError; either error refuses the load.
fast=True swaps the encoder/head forward for the TileLang fast path (CUDA only, needs
pip install laya[fast]); see Agent.accelerate.
compile=True runs the model under torch.compile and turns ModernBERT's encoder
reference_compile on. torch.compile specializes per input shape and Laya sees a
new one on almost every request, so those graphs usually cost more than they return;
use it when the traffic is repetitive. fast=True takes precedence, because the
TileLang path replaces the forward that would be compiled.
subfolder selects one checkpoint from a repo that bundles several, e.g.
Agent("convaiinnovations/laya", subfolder="multilingual"). Only that subfolder is
downloaded, so bundling does not cost every user the whole family.
calibration is an optional JSON path with temperature and temperature_by_options.
It is applied after the checkpoint config, so a fitted map overrides shipped scalars
without rewriting model.safetensors.
hooks / on_predict_start / on_predict_end observe or shape every prediction; see
laya.hooks. hooks_raise=False warns and continues when a hook fails,
hooks_concurrent=False serialises hooks that are not safe to run in parallel, and
hooks_timeout bounds each hook call in seconds (None means no limit).
Parameters
model_id_or_pathstr="convaiinnovations/laya"deviceOptional[str]=NonetokenOptional[str]=NonesubfolderOptional[str]=Nonefastbool=Falsecompilebool=FalserevisionOptional[str]=Noneexpected_sha256Optional[Dict[str, str]]=Nonelang_temperaturesOptional[Dict[str, Dict[str, Any]]]=Nonehooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raisebool=Truehooks_concurrentbool=Truehooks_timeoutOptional[float]=NonecalibrationOptional[str]=None
accelerate
accelerate(use_graphs: bool = True, strict: bool = False)Replace the model forward with the TileLang fast path (fused GEMM/GEGLU/LayerNorm/RoPE kernels, sliding-window flash attention, 16-bit resident weights, CUDA graphs per shape bucket).
The fast path runs in the agent's autocast dtype at the time of the call (bf16 or fp16), so it
matches the stock forward it replaces within rounding (see benchmarks/parity_fast.py). After
changing agent.dtype, call deaccelerate() then accelerate() to rebuild it. Returns True if
enabled. With strict=False any failure (no CUDA, tilelang missing) leaves the stock path in place.
Parameters
use_graphsbool=Truestrictbool=False
warmup
warmup(shapes=None) -> floatRun the forward on synthetic input of each shape now and return the seconds it took.
compile=True traces and compiles on the first request that needs a graph (tens of
seconds on a GPU), and fast=True builds its kernels and CUDA graphs per shape bucket on
first use. Calling this after loading, before serving, moves that cost out of the first
requests. With the stock forward it is a few ordinary forward passes. shapes is a list
of (rows, tokens, markers); tokens are capped at the agent's max_len. Nothing is
returned to or recorded for any caller, and hooks do not run.
Parameters
shapes=None
deaccelerate
deaccelerate()Restore the stock forward.
dtype_for
dtype_for(rows: int) -> torch.dtypePrecision that a forward pass with rows question rows runs in.
dtype is the autocast target, set once at load time. Whether a forward autocasts is
decided per call: on MPS only at or above mps_amp_min_rows rows. This returns dtype
when a forward with rows rows autocasts, and torch.float32 when it does not. A
predict call runs one row per question.
Parameters
rowsint
predict_batch
predict_batch(
states: List[Union[str, dict, list]],
questions: Dict[str, Dict[str, Any]],
batch_size: Optional[int] = None,
lang: Optional[str] = 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,
sort_by_length: bool = False,
min_confidence: Optional[float] = None,
) -> List[Dict[str, Any]]Evaluate the same questions over many states, packing them into shared forward passes.
This is the throughput path. system_one/predict handle one state per forward pass; on a
GPU that leaves most of the batch dimension idle. predict_batch collates several states'
question rows into one tensor, so a call that would take N sequential forward passes takes
one (or ceil(len(states) / batch_size)), which is several times faster per decision on GPU.
Parameters
statesList[Union[str, dict, list]]A list of states (each a text string, JSON dict, or conversation turn list). The same
questionsare evaluated against every state.questionsDict[str, Dict[str, Any]]Question definitions, exactly as accepted by
system_one.batch_sizeOptional[int]=NoneOptional cap on states per forward pass.
Nonesends them all in one pass; set it to bound peak memory when batching many or long states.langOptional[str]=NonehooksHookArg=NonePer-call hooks, appended after any installed on the Agent. See
laya.hooks.on_predict_startPredictHookArg=NoneA per-call start hook. It may rewrite the state/questions or call
ctx.skip(...)to short-circuit inference.on_predict_endPredictHookArg=NoneA per-call end hook. It may rewrite the results.
hooks_raiseOptional[bool]=NoneOverride the Agent's
hooks_raisefor this call.hooks_timeoutOptional[float]=NoneOverride the Agent's
hooks_timeoutfor this call.max_lenOptional[int]=NoneOverride the agent config's
max_lenfor this call. A start hook may also setctx.max_lento shape the token budget.head_max_lenOptional[int]=NoneOverride the agent config's
head_max_lenfor this call. A start hook may also setctx.head_max_len.sort_by_lengthbool=FalseGroup similarly sized encoded states within windows of eight batches to reduce padding. Requires an explicit
batch_sizegreater than one and smaller than the number of states; otherwise it has no effect. Results retain input order. This buffers up to eight batches of tokenized states instead of one. Changing batch shapes can slightly change floating-point predictions.min_confidenceOptional[float]=None
Returns
A list of per-state result dicts, each identical in shape to system_one's output and
aligned with states by index.
predict_long
predict_long(
state: Union[str, dict, list],
questions: Dict[str, Dict[str, Any]],
window: Optional[int] = None,
stride: Optional[int] = None,
aggregate: str = "auto",
batch_size: Optional[int] = None,
lang: Optional[str] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: Optional[bool] = None,
hooks_timeout: Optional[float] = None,
) -> Dict[str, Any]Evaluate questions over a state longer than the context window, scanning it in overlapping windows and aggregating per question.
system_one/predict truncate a state that exceeds max_len to a single window (the
first, or for a conversation list the last), silently dropping the rest. predict_long
tokenizes the state once, splits it into overlapping token windows, scores every window in
shared forward passes (via predict_batch), and combines the per-window answers:
- noul -> P(true) is the max over windows (the statement holds if any window supports it)
- choice-> the answer from the single most-confident window, so a localized signal isn't out-voted by the many neutral windows a long document is mostly made of (averaging drowns it -- the neutral majority dominates)
- score -> the level from the most-confident window, likewise
The returned probability/confidence is the deciding window's, not a calibrated number for
the whole document: a noul max over many windows drifts up with the window count even
with no signal, and choice can land on a confidently-neutral window when nothing in the
document is decisive. Each answer therefore carries answer["window"] — the deciding
window's index, token_start/token_end into the tokenized state, and the window count
— so a caller can inspect the span the answer came from rather than trust the raw number.
A state that already fits one window is passed straight to system_one (identical output).
The hooks wrap the inference that answers the state, which for a document needing several
windows is the one shared predict_batch over them: on_predict_start fires once, and
ctx.states holds the decoded window texts in scan order -- not the caller's state, which
was tokenized to produce them. Three outcomes follow from what the chain leaves behind:
ctx.skip([result])answers the document: the payload comes back with no window attribution andusage["windows"]at 0, because nothing was scored- a scan left as this method built it: every window is scored, each answer carries
answer["window"], andusage["windows"]is the window count - a rewritten scan (
ctx.statesreplaced, in any way): the answers are aggregated over the states that were scored, but no answer carriesanswer["window"]-- the offsets above describe this method's windows, not the text the model read
Parameters
stateUnion[str, dict, list]questionsDict[str, Dict[str, Any]]windowOptional[int]=Nonestate tokens per window. Defaults to the per-question state budget (
max_len - head_max_len - 8) -- the most a window can hold for every question. A smaller window isolates a localized signal better (a short deciding span is a larger fraction of its window, so that window classifies it clearly), at the cost of more windows; the large default favors context and throughput.noulis robust to this,choice/scorebenefit from a smaller window when the deciding span is a small part of a long, otherwise-neutral document.strideOptional[int]=Nonetoken step between windows. Defaults to
window // 2(50% overlap), so a span near a boundary still lands whole inside some window.aggregatestr="auto""auto" (the per-type rules above) is the only mode for now.
batch_sizeOptional[int]=Nonecap on windows per forward pass, to bound memory on very long states.
langOptional[str]=Noneper-language temperature selection, as in
system_one.hooksHookArg=NonePer-call hooks, appended after any installed on the Agent. See
laya.hooks.on_predict_startPredictHookArg=NoneA per-call start hook, as in
system_one.on_predict_endPredictHookArg=NoneA per-call end hook, as in
system_one.hooks_raiseOptional[bool]=NoneOverride the Agent's
hooks_raisefor this call.hooks_timeoutOptional[float]=NoneOverride the Agent's
hooks_timeoutfor this call.
Returns a single result dict, the same shape as system_one, with usage["windows"] added.
The key is always present and counts the windows the model scored to produce the answer: 1
for a state that fit one window, N for a document scanned in N overlapping windows (or
the N a start hook rewrote them to), and 0 when a start hook answered the document, or
left no states to score, before any window was read -- on either path, so a cached answer
never reads as a window the model read.
Across several windows the truncation keys are combined like every other usage field:
truncated, state_tokens and state_tokens_dropped are summed (so truncated is the
number of windows that were cut, and the token counts include the overlap), and
truncated_questions is the last window's list. The two can disagree: when only an
earlier window was cut, truncated is above 0 and truncated_questions is empty. A
window is cut when it is larger than the room a question's head leaves, from a window
above the default or a start hook that narrows max_len / head_max_len. Test
usage["truncated"] > 0 here, not is True.
system_one
system_one(
state: Union[str, dict, list],
questions: Dict[str, Dict[str, Any]],
lang: Optional[str] = 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]Evaluate typed questions across state in a single, parallel forward pass.
Parameters
stateUnion[str, dict, list]Text string, JSON dict, or conversation turn list.
questionsDict[str, Dict[str, Any]]Dictionary mapping question_id -> question definition.
choice: {"type": "choice", "instructions": "...", "criteria": {"optA": "...", ...}}
score: {"type": "score", "instructions": "...", "criteria": ["lvl0", "lvl1", ...]}
noul: {"type": "noul", "instructions": "...", "criteria": {"false": "...", "true": "..."}, "labels": {"false": "B", "true": "A"}}
Noul criteria and labels are optional. Labels only control the text shown to the model; their keys retain false/true semantics, and the returned
noulvalue is always P(true). Labels default to false/true for compatibility.
langOptional[str]=Nonehooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raiseOptional[bool]=Nonehooks_timeoutOptional[float]=Nonemax_lenOptional[int]=Nonehead_max_lenOptional[int]=Nonemin_confidenceOptional[float]=None
Returns
Dictionary with answers, probabilities, calibrated confidence, and token usage. Empty questions return empty answers and zero token usage without tokenization or a model forward pass.
When the head budget leaves two options with the same token span, usage carries
an options entry for each question it happened to -- total, distinct and
tokens_per_option -- because an answer chosen among 42 distinguishable spans of
58 has a ceiling that is the budget's and not the model's. Questions whose options
all survive are absent, so a request that collapses nothing is unchanged.
usage also reports whether the state fit: truncated, state_tokens,
state_tokens_dropped, and truncated_questions (the questions whose head left
too little room). A caller that cares whether the answer saw the whole state should
read usage["truncated"] rather than estimate from the length of what it sent.
To score many states at once, see predict_batch, which shares forward passes across them.
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,
) -> AnyAnswer state against a schema (JSON schema or pydantic model) and return typed values.
See laya.structured. Pass exactly one of schema or questions; extra keyword arguments
are forwarded to predict / system_one.
Parameters
stateUnion[str, dict, list]schemaAny=NonequestionsOptional[Dict[str, Any]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
decide_batch
decide_batch(
states: List[Union[str, dict, list]],
schema: Any = None,
questions: Optional[Dict[str, Any]] = None,
return_details: bool = False,
min_confidence: Optional[float] = None,
predict_kwargs,
) -> List[Any]Answer many states against one schema (JSON schema or pydantic model) in one batched call.
The throughput form of :meth:decide: the schema is planned once and its questions
run over every state through :meth:predict_batch (shared forward passes, results
in input order), then each state's answers are projected as decide does. Extra
keyword arguments (batch_size=, lang=, hooks=, ...) are forwarded to
predict_batch. See laya.structured.
Parameters
statesList[Union[str, dict, list]]schemaAny=NonequestionsOptional[Dict[str, Any]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
fit_temperatures
fit_temperatures(records, compute_ece: bool = False, seed: int = 0) -> Dict[str, Any]Fit per-bucket temperatures from CPU records and store them on this agent.
records are (qtype, logits, target, k). Build them with
laya.calibrate.records_from_labeled when you have labeled forwards; this method
does not download weights or write model.safetensors. seed only affects the
held-out ECE split when compute_ece is true. The checkpoint cfg is left as loaded.
Parameters
recordscompute_ecebool=Falseseedint=0
save_calibration
save_calibration(path: str) -> NoneWrite temperatures and the checkpoint they were fitted for. Does not write weights.
Parameters
pathstr
load_calibration
load_calibration(path: str) -> NoneRead a JSON map written by save_calibration onto this agent.
A file with no version is treated as version 1 and still loads. A newer file
whose recorded checkpoint does not match this agent warns and still loads.
Values that are not numbers, or that sit outside [TEMP_MIN, TEMP_MAX], are clamped
with clamp_temperature the same way checkpoint load is.
Parameters
pathstr
load
load(
model_id_or_path: str = "convaiinnovations/laya",
device: Optional[str] = None,
token: Optional[str] = None,
subfolder: Optional[str] = None,
fast: bool = False,
compile: bool = False,
revision: Optional[str] = None,
expected_sha256: Optional[Dict[str, str]] = None,
lang_temperatures: Optional[Dict[str, Dict[str, 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,
calibration: Optional[str] = None,
) -> AgentLoad a Laya agent.
subfolder picks one checkpoint out of a repo that bundles several:
laya.load("convaiinnovations/laya") # English (repo root)
laya.load("convaiinnovations/laya", subfolder="multilingual")
laya.load("convaiinnovations/laya", fast=True) # TileLang GPU fast path
laya.load("convaiinnovations/laya", compile=True) # torch.compile the model
revision/expected_sha256 pin and verify the downloaded artifacts; see Agent.
hooks / on_predict_start / on_predict_end observe or shape every prediction; see
laya.hooks. calibration is the same optional JSON path accepted by Agent.
Parameters
model_id_or_pathstr="convaiinnovations/laya"deviceOptional[str]=NonetokenOptional[str]=NonesubfolderOptional[str]=Nonefastbool=Falsecompilebool=FalserevisionOptional[str]=Noneexpected_sha256Optional[Dict[str, str]]=Nonelang_temperaturesOptional[Dict[str, Dict[str, Any]]]=Nonehooks=Noneon_predict_start=Noneon_predict_end=Nonehooks_raisebool=Truehooks_concurrentbool=Truehooks_timeoutOptional[float]=NonecalibrationOptional[str]=None
ONNXAgent
ONNXAgent(
model_id_or_path: str,
onnx_path: str = "laya.onnx",
token: Optional[str] = None,
subfolder: Optional[str] = None,
revision: Optional[str] = None,
expected_sha256: Optional[Dict[str, str]] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: bool = True,
hooks_concurrent: bool = True,
hooks_timeout: Optional[float] = None,
lang_temperatures: Optional[Dict[str, Dict[str, Any]]] = None,
calibration: Optional[str] = None,
)Bases: HookRegistry
System 1 decision model runtime via ONNX: fast CPU-optimized decisions.
Load a Laya agent backed by ONNX Runtime.
Parameters
model_id_or_pathstrHuggingFace Hub ID or local path to the original PyTorch checkpoint (used to load the tokenizer and config).
onnx_pathstr="laya.onnx"Path to the exported .onnx file.
tokenOptional[str]=NoneOptional HuggingFace token for a private or gated checkpoint; falls back to
$HF_TOKEN, exactly asAgentdoes. Only the tokenizer and config are fetched -- the graph itself is the localonnx_path.subfolderOptional[str]=NoneOptional subfolder if downloading from a repo bundle.
revisionOptional[str]=NoneOptional Hub revision (commit SHA/branch/tag). When omitted, huggingface_hub's normal default and existing offline cache are used.
expected_sha256Optional[Dict[str, str]]=NoneOptional {path relative to the checkpoint dir: hexdigest} verified before any checkpoint file is parsed; opt-in, and applies to local directories too. A missing artifact raises
FileNotFoundErrorand a digest mismatch raisesValueError; either error refuses the load.hooksHookArg=NoneOpt-in prediction hooks; see
laya.hooks.on_predict_startPredictHookArg=NoneAn opt-in start hook, run before inference.
on_predict_endPredictHookArg=NoneAn opt-in end hook, run after inference.
hooks_raisebool=TrueWhen False, a failing hook warns and inference continues.
hooks_concurrentbool=TrueWhen False, hooks are serialised with a lock.
hooks_timeoutOptional[float]=NoneBounds each hook call in seconds; None means no limit.
lang_temperaturesOptional[Dict[str, Dict[str, Any]]]=NoneOptional per-language temperature overrides, keyed by language code, each
{"temperature": [3 floats], "temperature_by_options": {}}. Applied when alang=is passed tosystem_one/predict, mirroring the PyTorchAgent; a cross-backend swap otherwise loses calibration.calibrationOptional[str]=None
load_calibration
load_calibration(path: str) -> NoneRead a JSON map written by save_calibration onto this agent.
Parameters
pathstr
system_one
system_one(
state: Union[str, dict, list],
questions: Dict[str, Dict[str, Any]],
lang: Optional[str] = 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]Evaluate typed questions across state in one ONNX Runtime session run.
lang selects a per-language temperature override (see lang_temperatures), matching the
PyTorch Agent.system_one signature so either backend is a drop-in for the other.
Defined in terms of predict_batch, exactly as the PyTorch Agent.system_one is, so the
single-state and batched paths cannot drift apart.
Parameters
stateUnion[str, dict, list]Text string, JSON dict, or conversation turn list.
questionsDict[str, Dict[str, Any]]Question definitions, with the shapes
Agent.system_oneaccepts.langOptional[str]=NonePer-language temperature override (see
lang_temperatures).hooksHookArg=NonePer-call hooks, appended after any installed on the agent.
on_predict_startPredictHookArg=NoneA per-call start hook. It may rewrite the state/questions or call
ctx.skip(...)to short-circuit inference.on_predict_endPredictHookArg=NoneA per-call end hook. It may rewrite the results.
hooks_raiseOptional[bool]=NoneOverride the agent's
hooks_raisefor this call.hooks_timeoutOptional[float]=NoneOverride the agent's
hooks_timeoutfor this call.max_lenOptional[int]=NoneOverride the config's
max_lenfor this call.head_max_lenOptional[int]=NoneOverride the config's
head_max_lenfor this call.min_confidenceOptional[float]=NoneOpt-in abstention threshold on
answer_confidence(#361); an answer below it is returned flagged withlow_confidence: True.
Returns
Dictionary with answers, probabilities, calibrated confidence, and token usage.
To score many states at once, see predict_batch, which shares session runs across them.
predict_batch
predict_batch(
states: List[Union[str, dict, list]],
questions: Dict[str, Dict[str, Any]],
batch_size: Optional[int] = None,
lang: Optional[str] = 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,
sort_by_length: bool = False,
min_confidence: Optional[float] = None,
) -> List[Dict[str, Any]]Evaluate the same questions over many states, sharing ONNX Runtime session runs.
The throughput path, mirroring laya.agent.Agent.predict_batch: system_one collates one
state's question rows per session run, so N states cost N runs. predict_batch collates
several states' rows into one run -- or ceil(len(states) / batch_size) of them -- which is
where ONNX Runtime's own parallelism pays off on CPU.
Parameters
statesList[Union[str, dict, list]]A list of states (each a text string, JSON dict, or conversation turn list). The same
questionsare evaluated against every state.questionsDict[str, Dict[str, Any]]Question definitions, exactly as accepted by
system_one.batch_sizeOptional[int]=NoneOptional cap on states per session run.
Nonesends them all in one run; set it to bound peak memory when batching many or long states.langOptional[str]=NonePer-language temperature override applied to every state; see
lang_temperatures.hooksHookArg=NonePer-call hooks, appended after any installed on the agent.
on_predict_startPredictHookArg=NoneA per-call start hook. It may rewrite the states/questions or call
ctx.skip(...)to short-circuit inference.on_predict_endPredictHookArg=NoneA per-call end hook. It may rewrite the results.
hooks_raiseOptional[bool]=NoneOverride the agent's
hooks_raisefor this call.hooks_timeoutOptional[float]=NoneOverride the agent's
hooks_timeoutfor this call.max_lenOptional[int]=NoneOverride the config's
max_lenfor this call.head_max_lenOptional[int]=NoneOverride the config's
head_max_lenfor this call.sort_by_lengthbool=FalseGroup similarly sized encoded states within windows of eight batches to reduce padding, exactly as
Agent.predict_batchdoes. Requires an explicitbatch_sizegreater than one and smaller than the number of states; otherwise it has no effect. Results retain input order. Changing batch shapes can slightly change floating-point predictions near decision thresholds.min_confidenceOptional[float]=NoneOpt-in abstention threshold on
answer_confidence(#361); answers below it are returned flagged withlow_confidence: True.
Returns
A list of per-state result dicts, each identical in shape to system_one's output and
aligned with states by index.
predict_long
predict_long(
state: Union[str, dict, list],
questions: Dict[str, Dict[str, Any]],
window: Optional[int] = None,
stride: Optional[int] = None,
aggregate: str = "auto",
batch_size: Optional[int] = None,
lang: Optional[str] = None,
hooks=None,
on_predict_start=None,
on_predict_end=None,
hooks_raise: Optional[bool] = None,
hooks_timeout: Optional[float] = None,
) -> Dict[str, Any]Evaluate questions over a state longer than the context window, scanning it in overlapping windows and aggregating per question.
The ONNX port of laya.agent.Agent.predict_long, with the same aggregation rules:
system_one truncates a state that exceeds max_len to a single window, silently
dropping the rest. predict_long tokenizes the state once, splits it into overlapping
token windows, scores every window through predict_batch -- so the windows share ONNX
Runtime session runs rather than costing one each -- and combines the per-window answers:
- noul -> P(true) is the max over windows (the statement holds if any window supports it)
- choice-> the answer from the single most-confident window, so a localized signal isn't out-voted by the many neutral windows a long document is mostly made of
- score -> the level from the most-confident window, likewise
The returned probability/confidence is the deciding window's, not a calibrated number for
the whole document, for the same reasons the PyTorch docstring gives. Each answer carries
answer["window"] -- the deciding window's index, token_start/token_end into the
tokenized state, and the window count.
A state that already fits one window is passed straight to system_one (identical output).
Parameters
stateUnion[str, dict, list]Text string, JSON dict, or conversation turn list.
questionsDict[str, Dict[str, Any]]Question definitions, exactly as accepted by
system_one.windowOptional[int]=NoneState tokens per window. Defaults to the per-question state budget (
max_len - head_max_len - 8). Smaller windows isolate a localized signal better at the cost of more windows, as inAgent.predict_long.strideOptional[int]=NoneToken step between windows. Defaults to
window // 2(50% overlap).aggregatestr="auto""auto" (the per-type rules above) is the only mode for now.
batch_sizeOptional[int]=NoneCap on windows per session run, to bound peak memory on very long states.
langOptional[str]=NonePer-language temperature selection, as in
system_one.hooksHookArg=NonePer-call hooks, appended after any installed on the agent. They follow
Agent.predict_long's contract: they wrap the inference that answers the state, a start hook that answers withctx.skip(...)getsusage["windows"] == 0and no window attribution, and a rewritten scan is aggregated withoutanswer["window"].on_predict_startPredictHookArg=NoneA per-call start hook, as in
system_one.on_predict_endPredictHookArg=NoneA per-call end hook, as in
system_one.hooks_raiseOptional[bool]=NoneOverride the agent's
hooks_raisefor this call.hooks_timeoutOptional[float]=NoneOverride the agent's
hooks_timeoutfor this call.
Returns a single result dict, the same shape as system_one, with usage["windows"]
added. Across several windows the truncation keys are summed or carried the same way as
in Agent.predict_long: truncated is a window count and truncated_questions is the
last window's list, so truncated can be above 0 while the list is empty.
decide
decide(
state: Union[str, dict, list],
schema: Any = None,
questions: Optional[Dict[str, Dict[str, Any]]] = None,
return_details: bool = False,
min_confidence: Optional[float] = None,
predict_kwargs,
) -> AnyAnswer state against a schema (JSON schema or pydantic model) and return typed values.
See laya.structured. Pass exactly one of schema or questions; extra keyword arguments
are forwarded to predict / system_one.
Parameters
stateUnion[str, dict, list]schemaAny=NonequestionsOptional[Dict[str, Dict[str, Any]]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
decide_batch
decide_batch(
states: List[Union[str, dict, list]],
schema: Any = None,
questions: Optional[Dict[str, Dict[str, Any]]] = None,
return_details: bool = False,
min_confidence: Optional[float] = None,
predict_kwargs,
) -> List[Any]Answer many states against one schema through predict_batch; see laya.structured.
Parameters
statesList[Union[str, dict, list]]schemaAny=NonequestionsOptional[Dict[str, Dict[str, Any]]]=Nonereturn_detailsbool=Falsemin_confidenceOptional[float]=Nonepredict_kwargs
Quantized export
scripts/export_onnx.py --quantize writes an INT8 weight-only quantized copy beside the fp32
export (laya.onnx also produces laya.int8.onnx). Dynamic per-channel quantization converts
the MatMul weights to int8 with activations left in fp32, so no calibration dataset is needed,
and ONNXAgent loads the result by pointing onnx_path at it. On the English checkpoint, CPU
(M-series, 20 support-ticket states x choice/noul/score): model file 1.6 GB -> 581 MB, p50
per-state latency ~340 ms -> ~250 ms (~1.35x), and zero decision changes versus fp32 (largest single
probability drift 0.09). Per-tensor scales instead of per-channel flipped 3 of 20 states with
drift up to 0.29, which is why the exporter uses per-channel. The int8 graph is CPU-only: ONNX
Runtime has no INT8 MatMul kernel on the CUDAExecutionProvider, and a GPU provider silently
falls back per node.
python scripts/export_onnx.py --model convaiinnovations/laya --output laya.onnx --quantize