Skip to content

models: model_infer puts a whole raw output tensor in the message — let a call gather/argmax it natively first #370

Closed

Description

@codetiger

Summary

A model_infer call with raw: true writes each output tensor into the message whole. When a workflow needs only a few values from it — a per-cell policy head [1,5,H,W] read at the handful of cells a caller cares about, then an argmax — the whole tensor then rides every later step of the pass, and every step pays for it (#371).

Size of it

A [1,5,124,120] f32 head is 297 KB. In a turn loop that asks 8 seats, those heads (plus the copies the workflow makes when it routes them back to their seats) are copied into the evaluation arena on every later async condition, templated field and sync run of the pass: on the order of 60 MB of memcpy per turn before any inference. Unsetting the tensors as soon as they are decoded (which a workflow can do today) removed most of that: a no-op model on the widest board went from 10.6 to 8.7 ms/turn.

Copies along the way, per call: the adapter's tensor to owned; Tensor::from_bytes into tract; the output back to OwnedDataTensor; then every later evaluation copies its bytes again (datavalue OwnedDataTensor::to_arena).

Proposal

Let model_infer reduce an output before it enters the message, natively, with operands templated from the message — for example:

"select": { "output": "policy", "reshape": [5, -1], "gather": { "axis": 1, "indices": { "var": "…" } }, "argmax": 1 }

writing [n] integers instead of the tensor. The existing result expression cannot do this because it sees only the outputs, not the rest of the message (e.g. the indices of the cells to read), which is why callers use raw today.

Activity

  1. codetiger commented on Oct 1, 2026

    @codetiger
    MemberAuthor

    Fixed in 61fa233 on branch fix/issues-369-377 (not yet pushed; it lands after PR #368). model_infer takes select: a call-site JSONLogic expression used instead of the manifest's result, evaluated natively over the output tensors and the call's input root, so a workflow can gather at indices from the message, argmax, crop or reshape before anything is written. Exclusive with raw (refused together at authoring time).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions