mirror of
https://github.com/hanzoai/papers.git
synced 2026-10-22 17:20:17 +00:00
Move the Enso and Kai papers to their private repos
Hanzo CI/CD / test (linux-amd64) (push) Skipped
Hanzo CI/CD / test (linux-arm64) (push) Skipped
Hanzo CI/CD / test-advisory (push) Skipped
ci / papers (push) Failing after 27s
Build LaTeX Papers / build-pdfs (push) Failing after 1m1s
Hanzo CI/CD / test-amd64 (push) Successful in 1m44s
Hanzo CI/CD / cicd (push) Successful in 4m59s
CI/CD / cicd (push) Successful in 6m46s
Hanzo CI/CD / test (linux-amd64) (push) Skipped
Hanzo CI/CD / test (linux-arm64) (push) Skipped
Hanzo CI/CD / test-advisory (push) Skipped
ci / papers (push) Failing after 27s
Build LaTeX Papers / build-pdfs (push) Failing after 1m1s
Hanzo CI/CD / test-amd64 (push) Successful in 1m44s
Hanzo CI/CD / cicd (push) Successful in 4m59s
CI/CD / cicd (push) Successful in 6m46s
enso/ now lives in hanzo-inc/enso under papers/enso/, and kai/ in hanzo-inc/kai under papers/kai/, each with its history. The index, the site's paper list and its built kai.pdf drop them.
This commit is contained in:
@@ -33,7 +33,6 @@ Auto-generated catalogue of research papers. Regenerate: `scripts/gen-index.sh`
|
||||
| `hanzo-vs-claude` | `defense/hanzo-vs-claude.tex` |
|
||||
| `hanzo-zap-protocol` | `defense/hanzo-zap-protocol.tex` |
|
||||
| `earle-genetic-marketing` | `earle-genetic-marketing/earle-genetic-marketing.tex` |
|
||||
| `enso` | `enso/main.tex` |
|
||||
| `equality` | `equality/equality.tex` |
|
||||
| `evolutionary-schedule-search` | `evolutionary-schedule-search.tex` |
|
||||
| `hanzo-4-0-launch` | `hanzo-4-0-launch/hanzo-4-0-launch.tex` |
|
||||
@@ -145,7 +144,6 @@ Auto-generated catalogue of research papers. Regenerate: `scripts/gen-index.sh`
|
||||
| `hanzo-webhooks` | `hanzo-webhooks/hanzo-webhooks.tex` |
|
||||
| `hanzod-attested-compute` | `hanzod-attested-compute.tex` |
|
||||
| `hip-0302-replicate` | `hip-0302-replicate/hip-0302-replicate.tex` |
|
||||
| `kai` | `kai/kai.tex` |
|
||||
| `lightspeed-dex` | `lightspeed-dex/lightspeed-dex.tex` |
|
||||
| `locomo-subject-scope` | `locomo-subject-scope/main.tex` |
|
||||
| `mechanism` | `mechanism/mechanism.tex` |
|
||||
|
||||
@@ -104,7 +104,7 @@ pdfs/%.pdf: %.tex \
|
||||
# the shared files it names with the ../shared/ prefix dropped, and the .bbl
|
||||
# latexmk wrote. The upload is then compiled alone, without bibtex, the way
|
||||
# arXiv will; one that needs anything outside itself fails here, not after
|
||||
# submission. For a paper in its own directory: make arxiv/kai/kai.tar.gz
|
||||
# submission. For a paper in its own directory: make arxiv/attestation/attestation.tar.gz
|
||||
arxiv/%.tar.gz: pdfs/%.pdf
|
||||
@rm -rf arxiv/$* arxiv/$*.check && mkdir -p arxiv/$*
|
||||
@cd $(dir $*) && git ls-files -- '*.tex' '*.sty' '*.cls' '*.bst' '*.pdf' '*.png' '*.jpg' \
|
||||
|
||||
Binary file not shown.
@@ -1,92 +0,0 @@
|
||||
\begin{figure*}[t]
|
||||
\centering
|
||||
\begin{tikzpicture}[
|
||||
font=\scriptsize,
|
||||
node distance=6mm,
|
||||
box/.style={draw, rounded corners=2pt, align=center, minimum height=8mm,
|
||||
inner xsep=4pt, inner ysep=3pt},
|
||||
stage/.style={box, fill=hzslate!8, draw=hzslate!60},
|
||||
feat/.style={box, fill=hzblue!10, draw=hzblue!70},
|
||||
pol/.style={box, fill=hzred!8, draw=hzred!55},
|
||||
sel/.style={box, fill=hzgreen!14, draw=hzgreen!70},
|
||||
arm/.style={box, fill=hzslate!12, draw=hzslate!55, minimum width=17mm},
|
||||
armhot/.style={box, fill=hzgreen!16, draw=hzgreen!75, minimum width=17mm},
|
||||
arr/.style={-{Latex[length=2mm]}, hzslate!80, line width=0.4pt},
|
||||
arrhot/.style={-{Latex[length=2mm]}, hzgreen!75, line width=0.5pt}
|
||||
]
|
||||
|
||||
% ---- Panel (a): enso single-arm routing ----
|
||||
\node[feat] (req) {request\\\textit{(prompt, ctx len,}\\\textit{media, SLO)}};
|
||||
\node[feat, right=of req] (x) {\textbf{featurize}\\$x=\phi(\text{req})$\\\scriptsize task\,$\parallel$\,hash\,$\parallel$\,len};
|
||||
\node[pol, right=of x] (pol) {\textbf{policy}\\$u(x,p)=x^{\!\top}\!W p$\\\scriptsize per-arm utility};
|
||||
\node[sel, right=8mm of pol] (sel) {\textbf{SLO selector}\\$\arg\max_{p:\,\mathrm{feasible}}$\\$u-\lambda c-\mu\ell$};
|
||||
|
||||
% arm pool
|
||||
\node[arm, right=9mm of sel, yshift=13.5mm] (a1) {Opus 4.8};
|
||||
\node[armhot, below=2.2mm of a1] (a2) {GPT-5.5};
|
||||
\node[arm, below=2.2mm of a2] (a3) {Gemini 3.1 Pro};
|
||||
\node[arm, below=2.2mm of a3] (a4) {DeepSeek-V4 / Zen\\\scriptsize 1M ctx ladder};
|
||||
\node[draw=hzslate!40, dashed, rounded corners=2pt, fit=(a1)(a4),
|
||||
inner sep=3pt, label={[hzslate!70,font=\tiny]above:frontier arm pool}] (pool) {};
|
||||
|
||||
\draw[arr] (req) -- (x);
|
||||
\draw[arr] (x) -- (pol);
|
||||
\draw[arr] (pol) -- (sel);
|
||||
\draw[arr] (sel.east) -- (pool.west);
|
||||
\draw[arrhot] (sel.east) to[out=0,in=180] (a2.west);
|
||||
\node[hzgreen!70, font=\tiny, right=1mm of a2] {selected};
|
||||
|
||||
% guard + learning loop
|
||||
\node[box, fill=hzslate!6, draw=hzslate!45, below=7mm of x, xshift=6mm]
|
||||
(guard) {\textbf{guard} (two-tier safety) \;$\parallel$\; \textbf{observe}$(u,x,p,r)\to$ LinUCB $\theta_u$};
|
||||
\draw[arr, dashed, hzred!65] (a2.south) |- (guard.east);
|
||||
\draw[arr, dashed, hzred!65] (guard.west) -| (pol.south)
|
||||
node[pos=0.25, below, hzred!65, font=\tiny] {reward feedback};
|
||||
|
||||
\node[hzslate!70, font=\small\bfseries, above=1mm of req.north west, anchor=south west]
|
||||
{(a)\; \texttt{enso} --- learned single-arm routing};
|
||||
|
||||
% ---- Panel (b): enso-ultra fan-out + synthesis ----
|
||||
\begin{scope}[yshift=-46mm]
|
||||
\node[feat] (breq) {request};
|
||||
\node[feat, right=of breq] (bx) {\textbf{featurize}\\$x=\phi(\text{req})$};
|
||||
\node[pol, right=of bx] (bpol) {\textbf{policy}\\top-$N$ by $u(x,p)$};
|
||||
|
||||
\node[armhot, right=10mm of bpol, yshift=8mm] (b1) {Opus 4.8};
|
||||
\node[armhot, below=2.2mm of b1] (b2) {GPT-5.5};
|
||||
\node[armhot, below=2.2mm of b2] (b3) {Gemini 3.1 Pro};
|
||||
\node[draw=hzgreen!45, dashed, rounded corners=2pt, fit=(b1)(b3),
|
||||
inner sep=3pt, label={[hzgreen!70,font=\tiny]above:parallel fan-out ($N$ arms)}] (bpool) {};
|
||||
|
||||
\node[sel, right=10mm of b2, minimum width=20mm] (synth)
|
||||
{\textbf{synthesizer}\\\scriptsize rank $\parallel$ fuse\\\scriptsize (training-free)};
|
||||
\node[feat, right=of synth] (ans) {answer\\\scriptsize + provenance};
|
||||
|
||||
\draw[arr] (breq) -- (bx);
|
||||
\draw[arr] (bx) -- (bpol);
|
||||
\draw[arrhot] (bpol.east) to[out=0,in=180] (b1.west);
|
||||
\draw[arrhot] (bpol.east) to[out=0,in=180] (b2.west);
|
||||
\draw[arrhot] (bpol.east) to[out=0,in=180] (b3.west);
|
||||
\draw[arrhot] (b1.east) to[out=0,in=180] (synth.west);
|
||||
\draw[arrhot] (b2.east) to[out=0,in=180] (synth.west);
|
||||
\draw[arrhot] (b3.east) to[out=0,in=180] (synth.west);
|
||||
\draw[arr] (synth) -- (ans);
|
||||
|
||||
\node[hzslate!70, font=\small\bfseries, above=1.5mm of breq.north west, anchor=south west]
|
||||
{(b)\; \texttt{enso-ultra}: top-$N$ fan-out $+$ synthesis};
|
||||
\end{scope}
|
||||
|
||||
\end{tikzpicture}
|
||||
\caption{Enso serving architecture. \textbf{(a)}~\texttt{enso} turns a request
|
||||
into a feature vector $x$, scores every arm profile $p$ by the learned bilinear
|
||||
utility $x^{\top}Wp$, and returns the SLO-feasible $\arg\max$ of
|
||||
$u-\lambda c-\mu\ell$: exactly one frontier arm is selected per request. A
|
||||
two-tier safety guard gates the request, and each served outcome feeds an
|
||||
\texttt{observe}$(u,x,p,r)$ update that adapts the per-user weights $\theta_u$
|
||||
online (LinUCB). The routing policy and the closed learning loop are the ones
|
||||
specified in the Hanzo Router paper~\cite{hanzorouterpaper}. \textbf{(b)}~\texttt{enso-ultra}
|
||||
reuses the same learned policy to select the top-$N$ arms, dispatches them in
|
||||
parallel, and fuses their candidate answers with a training-free synthesizer.
|
||||
Orchestration is training-free; all learning lives at the routing layer.}
|
||||
\label{fig:arch}
|
||||
\end{figure*}
|
||||
Binary file not shown.
-741
@@ -1,741 +0,0 @@
|
||||
\documentclass[11pt]{article}
|
||||
\usepackage{../shared/hanzocover}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{amsmath,amssymb}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{shapes,arrows.meta,positioning,fit,backgrounds,calc}
|
||||
\usepackage[hidelinks]{hyperref}
|
||||
|
||||
\emergencystretch=2em % avoid overfull lines from long \texttt{} terms in narrow columns
|
||||
|
||||
\definecolor{hzblue}{rgb}{0.12,0.30,0.55}
|
||||
\definecolor{hzslate}{rgb}{0.22,0.25,0.30}
|
||||
\definecolor{hzgreen}{rgb}{0.10,0.45,0.25}
|
||||
\definecolor{hzred}{rgb}{0.60,0.16,0.16}
|
||||
|
||||
% =====================================================================
|
||||
% Numbers-as-data: the measured tables and headline numbers in this paper
|
||||
% are a pure function of the enso-bench results. `emit_paper.py' writes
|
||||
% three plain-LaTeX fragments into this directory, which we \input below:
|
||||
% results-measured-rows.tex per-bench head-to-head table rows (\S\ref{sec:eval})
|
||||
% results-ablation-rows.tex enso-ultra v1->v2 verify-then-select ablation rows
|
||||
% results-headline.tex \newcommand headline macros for the prose
|
||||
% A fourth file, results-prior.tex, holds an EARLIER run in the two-SKU
|
||||
% format this paper no longer uses. It is not \input anywhere; it is read
|
||||
% only by a human, and the two runs' disagreement is reported in \S\ref{sec:limits}.
|
||||
% \providecommand supplies a "run pending" fallback for any headline macro
|
||||
% not yet measured, so the paper always compiles and never shows a
|
||||
% fabricated number. Absent table rows simply do not appear.
|
||||
% =====================================================================
|
||||
\newcommand{\runpending}{\textit{\small run pending}}
|
||||
\IfFileExists{results-headline.tex}{\input{results-headline.tex}}{}
|
||||
\providecommand{\hEnsoGPQAacc}{\runpending}
|
||||
\providecommand{\hEnsoGPQAcost}{\runpending}
|
||||
\providecommand{\hUltraGPQAacc}{\runpending}
|
||||
\providecommand{\hBestGPQAname}{\runpending}
|
||||
\providecommand{\hBestGPQAacc}{\runpending}
|
||||
\providecommand{\hOpusGPQAacc}{\runpending}
|
||||
\providecommand{\hOpusGPQAcost}{\runpending}
|
||||
|
||||
\title{Enso: Learned Per-Request Routing to Frontier Intelligence, and Enso Ultra's Training-Free Fan-Out Synthesis}
|
||||
\author{Zach Kelling\thanks{Corresponding author: [email protected]} \\
|
||||
\textit{Hanzo Industries Inc (Techstars '17)} \\
|
||||
San Francisco, California \\
|
||||
\texttt{https://hanzo.ai}}
|
||||
\date{Hanzo Research}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\hanzocoverpage
|
||||
|
||||
\twocolumn[
|
||||
\begin{@twocolumnfalse}
|
||||
\maketitle
|
||||
\begin{abstract}
|
||||
\noindent
|
||||
The strongest answer to a given request rarely comes from the same model twice.
|
||||
On hard software engineering a frontier reasoning model wins; on long-context
|
||||
synthesis a million-token model wins; on cheap high-volume traffic the marginal
|
||||
gain of the most expensive model is zero. A single monolithic model is therefore
|
||||
a bet that one weight set dominates every request in the stream, which the
|
||||
published per-benchmark spread between frontier models refutes. We describe
|
||||
\textbf{Enso}, Hanzo's proprietary closed model family that turns this spread
|
||||
into a product. \texttt{enso} is a learned router: it featurizes each request,
|
||||
scores every arm in a pool of frontier models by a bilinear utility
|
||||
$x^{\top}Wp$, and returns the single SLO-feasible arm that maximizes
|
||||
$\mathrm{quality}-\lambda\,\mathrm{cost}-\mu\,\mathrm{latency}$, adapting to each
|
||||
user online. \texttt{enso-ultra} reuses the same policy to select the top-$N$
|
||||
arms, dispatches them in parallel, and fuses their answers with a training-free
|
||||
synthesizer. The routing policy is the one specified in the Hanzo Router
|
||||
paper~\cite{hanzorouterpaper}; this paper is about the family it powers, the
|
||||
serving substrate that presents it as one \texttt{/v1} API, and how it compares
|
||||
to frontier baselines (Opus 4.8, GPT-5.5, GPT-5.6, Gemini 3.1 Pro, Fable 5) and
|
||||
to a prior published learned orchestrator from the recent
|
||||
literature~\cite{priororchestrator}. Our design choice is deliberate and stated
|
||||
plainly: unlike the prior published router (Ultra), whose orchestrator is
|
||||
trained with reinforcement learning, Enso is \emph{training-free at the
|
||||
orchestration layer and learned only at the routing layer}, so a new frontier
|
||||
arm is onboarded by adding a row, not by retraining a policy over the pool. We
|
||||
report a measured evaluation from the \texttt{enso-bench} harness---every arm
|
||||
and every SKU executed under one gateway on the same items, with a per-request
|
||||
cost column the standard router table lacks. On GPQA Diamond \texttt{enso}
|
||||
scores \hEnsoGPQAacc\% at \$\hEnsoGPQAcost{} per 1{,}000 tasks, matching the best
|
||||
single arm (\texttt{\hBestGPQAname}, \hBestGPQAacc\%) and beating the premium
|
||||
reasoning arm (Opus~4.8, \hOpusGPQAacc\% at \$\hOpusGPQAcost{}/1k) at roughly a
|
||||
fifth of its metered cost, while \texttt{enso-ultra}'s verify-then-select
|
||||
fan-out is \emph{both} more accurate and cheaper than blind synthesis. We are
|
||||
equally explicit where routing does \emph{not} win---it leads neither every
|
||||
benchmark nor Humanity's Last Exam---and typeset any unmeasured cell as
|
||||
\emph{run pending} rather than invent a number.
|
||||
\end{abstract}
|
||||
\vspace{1.5em}
|
||||
\end{@twocolumnfalse}
|
||||
]
|
||||
|
||||
\section{Introduction}
|
||||
\label{sec:intro}
|
||||
|
||||
A frontier language model is a fixed bet. Its weights encode one balance of code,
|
||||
reasoning, math, chart understanding, long-context recall, and instruction
|
||||
following, and that balance is frozen at training time. But the request stream a
|
||||
production assistant sees is not fixed: one request is a graduate-level physics
|
||||
question, the next is a repository-scale refactor, the next is a chart to read,
|
||||
the next is a one-line reformat. The public per-benchmark tables make the
|
||||
consequence concrete. On the same seven benchmarks, the frontier models trade the
|
||||
lead back and forth---one leads on SWE-Bench Pro, another on LiveCodeBench Pro,
|
||||
another on Humanity's Last Exam---and no single model holds every column. A
|
||||
monolithic deployment picks one of these models and eats its losses on every
|
||||
column it does not lead. That is the structural inefficiency Enso removes.
|
||||
|
||||
The move is to stop shipping a model and start shipping a \emph{policy over
|
||||
models}. Enso is a closed family with two SKUs behind one API. \texttt{enso}
|
||||
routes each request to the single frontier arm most likely to serve it best under
|
||||
a per-request service-level objective. The pool we measure here is the set our
|
||||
gateway can actually serve---GPT-5.6 (sol), Claude Opus 4.8, GPT-5.5, Claude 5
|
||||
Sonnet, DeepSeek-V4-Pro, and Claude Fable 5, with GPT-4o as a cheap baseline
|
||||
single---and it spans the same capability axes a router needs: frontier reasoning,
|
||||
strong generalists, a dedicated coder, and a long-context arm. Gemini 3.1 Pro has
|
||||
no endpoint on this gateway, so it appears only as a provider-reported reference
|
||||
column, never as a routable arm. \texttt{enso-ultra} spends more to buy the
|
||||
ceiling: it fans the request
|
||||
out to the top-$N$ arms in parallel and synthesizes one answer from their
|
||||
candidates. Both SKUs are a single \texttt{/v1} endpoint; the caller sends
|
||||
messages and gets an answer, and never has to know---or maintain keys for---the
|
||||
providers underneath.
|
||||
|
||||
This framing has two consequences we make central. First, \textbf{routing beats
|
||||
monoliths whenever the pool's per-request argmax beats any fixed member}, and the
|
||||
published spread shows that condition holds. A learned router that identifies the
|
||||
right arm per request inherits the pool's upper envelope, not any single model's
|
||||
average. Second, \textbf{a router makes cost a first-class, transparent axis}. A
|
||||
monolith charges its one price on every token regardless of whether the request
|
||||
needed it; a router that optimizes $\mathrm{quality}-\lambda\,\mathrm{cost}-\mu\,\mathrm{latency}$
|
||||
sends cheap requests to cheap arms and prices each answer at the arm that actually
|
||||
served it. We therefore report a cost-per-benchmark column alongside accuracy---the
|
||||
number a buyer of intelligence actually pays---which comparison tables in this
|
||||
line of work typically omit.
|
||||
|
||||
We are explicit about lineage. The routing mechanism, the SLO objective, the
|
||||
bilinear utility, and the online per-user adaptation are specified and analyzed in
|
||||
the Hanzo Router paper~\cite{hanzorouterpaper}; we cite that work for the policy
|
||||
internals rather than restating them, and focus here on (i)~the Enso \emph{family}
|
||||
and the serving substrate that presents it as one product (\S\ref{sec:arch}),
|
||||
(ii)~the Enso Ultra fan-out/synthesis SKU and why its orchestration is deliberately
|
||||
training-free (\S\ref{sec:ultra}), and (iii)~a measured evaluation against the same
|
||||
benchmarks a learned-orchestrator baseline reports (\S\ref{sec:eval}).
|
||||
|
||||
\section{Related Work}
|
||||
\label{sec:related}
|
||||
|
||||
\paragraph{Learned orchestration: prior router, Trinity, Conductor.} The closest
|
||||
system to Enso is the prior published router~\cite{priororchestrator}, a learned
|
||||
orchestrator over a pool of frontier models---Gemini 3.1 Pro, Claude Opus 4.8, and
|
||||
GPT-5.5---shipped in two SKUs, a base tier and an Ultra tier, exactly the two-tier
|
||||
shape Enso takes. The base tier is trained with supervised fine-tuning plus
|
||||
separable CMA-ES~\cite{sepcmaes}, and its Ultra tier adds GRPO reinforcement
|
||||
learning~\cite{grpo} at the orchestration layer; both build on the ICLR~2026
|
||||
foundations Trinity~\cite{trinity} (evolutionary composition of experts) and
|
||||
Conductor~\cite{conductor} (RL-orchestrated ensembles). Enso shares that router's
|
||||
thesis---that the per-request argmax over a frontier pool beats any fixed
|
||||
member---and its two-SKU packaging, and we treat its published results as the
|
||||
reference point our evaluation mirrors (\S\ref{sec:eval}). Enso differs in where
|
||||
the learning sits: the prior router's Ultra tier learns an orchestrator with RL
|
||||
over the pool, whereas Enso learns only the routing policy and keeps orchestration
|
||||
training-free (\S\ref{sec:ultra}), so onboarding a new arm is a data change, not a
|
||||
retrain.
|
||||
|
||||
\paragraph{Routing and cascading.} Enso's single-arm SKU is a router in the line of
|
||||
RouteLLM~\cite{routellm}, which learns a strong/weak binary router from preference
|
||||
data; FrugalGPT~\cite{frugalgpt}, which cascades cheap-to-expensive with a learned
|
||||
stopping scorer; Hybrid LLM~\cite{hybridllm}, which routes on a quality-aware
|
||||
threshold; AutoMix~\cite{automix}, which escalates via self-verification; and
|
||||
Tabi~\cite{tabi}, a multi-level inference system. Enso generalizes their binary or
|
||||
cascade decision to a constrained continuous objective,
|
||||
$\mathrm{quality}-\lambda\,\mathrm{cost}-\mu\,\mathrm{latency}$, over a pool of many
|
||||
frontier arms, and adds per-user online adaptation~\cite{linucb} that cascade work
|
||||
generally omits. The full treatment is in the router paper~\cite{hanzorouterpaper}.
|
||||
|
||||
\paragraph{Ensemble synthesis.} Enso Ultra's fan-out/synthesis is grounded in
|
||||
multi-agent and ensembling work: Mixture-of-Agents~\cite{moa} layers proposer and
|
||||
aggregator models; LLM-Blender~\cite{llmblender} ranks and generatively fuses
|
||||
candidates from a model bank; and self-consistency~\cite{selfconsistency} shows
|
||||
that aggregating multiple independent samples improves reasoning. Ultra applies
|
||||
these fusion ideas across \emph{heterogeneous frontier arms} rather than samples
|
||||
from one model, and keeps the fuser training-free.
|
||||
|
||||
\section{Enso Architecture}
|
||||
\label{sec:arch}
|
||||
|
||||
Enso is two layers with one seam between them: a \emph{routing layer} that decides
|
||||
which arm(s) serve a request, and a \emph{serving layer} that presents the family
|
||||
as one metered product. Figure~\ref{fig:arch} shows both SKUs.
|
||||
|
||||
\input{figures/architecture}
|
||||
|
||||
\subsection{The routing layer: policy as data}
|
||||
\label{sec:routing}
|
||||
|
||||
The router is the mechanism and policy specified in the Hanzo Router
|
||||
paper~\cite{hanzorouterpaper}; we summarize only what the family needs and cite
|
||||
that work for the rest. Each arm is one row in a cross-modal registry---a
|
||||
\texttt{(model, level, modality)} profile carrying an eval-measured quality vector
|
||||
over tasks plus normalized latency, cost, VRAM, and context reach. A request is
|
||||
turned into a feature vector $x$ by a hashing-trick featurizer (task one-hot,
|
||||
hashed n-grams, log-length, media flag, bias) in sub-microsecond time, and every
|
||||
arm profile $p$ is scored by the learnable bilinear utility
|
||||
\begin{equation}
|
||||
u(x,p) = x^{\top} W p, \qquad W\in\mathbb{R}^{D\times K}.
|
||||
\end{equation}
|
||||
The selector returns the SLO-feasible $\arg\max$ of the constrained objective
|
||||
\begin{equation}
|
||||
\arg\max_{p\,:\,\mathrm{feasible}(p)}\; u(x,p) - \lambda\,\widehat{c}(p) - \mu\,\widehat{\ell}(p),
|
||||
\end{equation}
|
||||
where the hard ceilings ($\texttt{max\_latency\_ms}$, $\texttt{max\_cost}$,
|
||||
$\texttt{min\_quality}$) gate the candidate set and the soft weights
|
||||
$\lambda,\mu$ trade cost and latency against quality. Offline, $W$ is a closed-form
|
||||
ridge fit~\cite{ridge}; online, each user carries a LinUCB bandit~\cite{linucb}
|
||||
whose parameter $\theta_u$ starts at $W$ and drifts toward that user's taste as
|
||||
outcomes arrive through a single \texttt{observe}$(u,x,p,r)$ call. The essential
|
||||
property for the family is that \emph{the policy is a function of data}: adding a
|
||||
frontier arm is adding a profile row, and its ranking then falls out of the same
|
||||
$W$ without a code change. A two-tier safety guard gates every request before the
|
||||
selector runs, cheaply on the hot path and escalating only ambiguous prompts.
|
||||
|
||||
\subsection{The serving layer: family-as-data}
|
||||
\label{sec:serving}
|
||||
|
||||
The serving substrate (the \texttt{zen-svc} engine behind the Hanzo AI
|
||||
gateway~\cite{hanzogateway}) turns the routing decision into one product. Three
|
||||
properties matter.
|
||||
|
||||
\paragraph{One identity.} Whichever arm serves a request, the response is presented
|
||||
as Enso. The serving layer performs identity injection and upstream-hiding: the
|
||||
caller sees a single model family and its provenance, not the underlying provider,
|
||||
and never manages third-party keys. This is what lets the pool change---an arm
|
||||
added, retired, or swapped for a better version---without any client change.
|
||||
|
||||
\paragraph{One meter.} Every routed request is metered on one plane, so cost is
|
||||
attributed per request to the arm that actually served it. This is the substrate
|
||||
that makes the cost-per-benchmark column of \S\ref{sec:eval} a real, per-request
|
||||
number rather than a blended list price, and it is what lets a deployment set
|
||||
$\lambda$ to move spend without touching application code.
|
||||
|
||||
\paragraph{The 1M context ladder.} Long-context requests are a distinct pool. When
|
||||
a request's context exceeds the reach of the default arms, the router climbs a
|
||||
million-token ladder---a frontier long-context arm (DeepSeek-V4-Pro) with a top Zen
|
||||
model as the local-capable rung---selected by the same feasibility gate
|
||||
($\texttt{max\_context}\ge k$) as any other constraint. Long context is thus not a
|
||||
special mode but another column in the same registry, chosen by the same policy.
|
||||
|
||||
\section{Enso Ultra: Training-Free Fan-Out Synthesis}
|
||||
\label{sec:ultra}
|
||||
|
||||
\texttt{enso-ultra} is the ceiling SKU. Where \texttt{enso} spends the policy's
|
||||
confidence to pick one arm, Ultra spends compute to reduce the risk that the single
|
||||
argmax was wrong on a hard request: it selects the top-$N$ arms by the same utility
|
||||
$u(x,p)$, dispatches them in parallel, and fuses their candidate answers into one.
|
||||
The fan-out reuses the routing layer unchanged---the top-$N$ are simply the first
|
||||
$N$ of the same ranked, SLO-feasible candidate list---so Ultra inherits the pool,
|
||||
the guard, and the online adaptation for free.
|
||||
|
||||
\paragraph{The synthesizer is training-free.} This is the deliberate contrast with
|
||||
the prior router's Ultra tier. That tier learns its orchestrator with
|
||||
GRPO~\cite{grpo}: the policy that decides how to combine models is itself an
|
||||
RL-trained artifact over the pool. Enso Ultra's synthesizer is training-free---it
|
||||
ranks and fuses the $N$ candidate answers with a fixed procedure grounded in the
|
||||
ensembling literature (Mixture-of-Agents-style aggregation~\cite{moa}, pairwise
|
||||
ranking and generative fusion as in LLM-Blender~\cite{llmblender}, and the
|
||||
aggregation-improves-reasoning result of self-consistency~\cite{selfconsistency}),
|
||||
with no weights of its own that depend on the current pool. The engineering
|
||||
consequence is the point: \emph{all learning in Enso lives at the routing layer,
|
||||
none at the orchestration layer}. When a new frontier arm ships, Enso onboards it
|
||||
by adding a profile row and letting the router rank it; Ultra then includes it in
|
||||
fan-out automatically. A system that learned its orchestrator over the
|
||||
pool---as the prior router's Ultra tier does---would in principle need to revisit
|
||||
that trained policy when the pool changes. We view training-free orchestration as
|
||||
the more maintainable choice for a family whose pool is expected to churn as
|
||||
frontier models are released, and we make no claim that it dominates a trained
|
||||
orchestrator on quality; \S\ref{sec:eval} reports the measured comparison and
|
||||
\S\ref{sec:limits} states the caveats.
|
||||
|
||||
\paragraph{Provenance.} Because the serving layer meters every arm, an Ultra answer
|
||||
carries which arms contributed and at what cost, so the fan-out's price is
|
||||
transparent per request---the same metering that prices the single-arm SKU prices
|
||||
the ensemble.
|
||||
|
||||
\section{Evaluation}
|
||||
\label{sec:eval}
|
||||
|
||||
\paragraph{Methodology.} We evaluate on the public benchmarks of the standard
|
||||
frontier-router suite~\cite{priororchestrator}---GPQA Diamond~\cite{gpqa},
|
||||
LiveCodeBench~\cite{livecodebench}, Humanity's Last Exam (HLE)~\cite{hle}, and
|
||||
CharXiv Reasoning~\cite{charxiv}. Unlike a comparison that mixes measurement
|
||||
regimes, we run \emph{every} system under \emph{one} harness: each single-model
|
||||
arm, \texttt{enso-flash}, \texttt{enso}, and \texttt{enso-ultra} answers the
|
||||
identical items through the same OpenAI-compatible gateway at temperature~0, with
|
||||
the same extraction and scoring---a like-for-like comparison the reported tables
|
||||
cannot give. GPQA and HLE are graded by exact / judged match, LiveCodeBench by
|
||||
executing every public and private test case in a sandboxed subprocess (pass@1),
|
||||
and CharXiv by an LLM judge; grading is identical across systems and its cost is
|
||||
booked separately. Beyond accuracy we report \textbf{cost per 1{,}000 tasks}, the
|
||||
per-request-metered spend (\S\ref{sec:serving}) that a comparison of routers must
|
||||
include and that closed router tables omit. Sample sizes are $n{=}198$ (GPQA),
|
||||
$500$ (HLE), $175$ (LiveCodeBench), $200$ (CharXiv), with binomial standard errors
|
||||
reported per cell. The agentic rows (SWE-Bench Pro, Terminal-Bench~2.1) and the
|
||||
extended code benches (LiveCodeBench Pro) are the most expensive to run; we report
|
||||
a SWE-Bench Pro \emph{pilot} below and mark the rest \emph{run pending}
|
||||
(\S\ref{sec:limits}).
|
||||
|
||||
\paragraph{Reference point.} For context, Table~\ref{tab:reference} reproduces
|
||||
the prior published router's results verbatim as reported in that
|
||||
work~\cite{priororchestrator}; these are its reported numbers, not ours, and are
|
||||
included only to anchor the benchmark scale and the shape of the two-SKU
|
||||
comparison.
|
||||
|
||||
\begin{table*}[t]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{5pt}
|
||||
\caption{Reference: provider-reported frontier baselines; the last two columns
|
||||
reproduce a prior published router's reported numbers~\cite{priororchestrator}
|
||||
(their system, not measured by us), included only to anchor benchmark scale. Our
|
||||
measured, like-for-like results are in Table~\ref{tab:measured}.}
|
||||
\label{tab:reference}
|
||||
\begin{tabular}{@{}lrrrrr@{}}
|
||||
\toprule
|
||||
Benchmark & Opus 4.8 & Gemini 3.1 Pro & GPT-5.5 & Prior router & Prior router (Ultra) \\
|
||||
\midrule
|
||||
SWE-Bench Pro & 69.2 & 54.2 & 58.6 & 59.0 & 73.7 \\
|
||||
Terminal-Bench 2.1 & 74.6 & 70.3 & 78.2 & 80.2 & 82.1 \\
|
||||
LiveCodeBench & 87.8 & 88.5 & 85.3 & 92.9 & 93.2 \\
|
||||
LiveCodeBench Pro & 84.8 & 82.9 & 88.4 & 87.8 & 90.8 \\
|
||||
HLE & 49.8 & 44.4 & 41.4 & 47.2 & 50.0 \\
|
||||
CharXiv Reasoning & 84.2 & 83.3 & 84.1 & 85.1 & 86.6 \\
|
||||
GPQA Diamond & 92.0 & 94.3 & 93.6 & 95.5 & 95.5 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table*}
|
||||
|
||||
\paragraph{Measured head-to-head.} Table~\ref{tab:measured} is our result table:
|
||||
on each benchmark we ran, the best single arm we measured set against the three
|
||||
Enso SKUs, with accuracy and metered cost per $1{,}000$ tasks for each. The rows
|
||||
are generated directly from the \texttt{enso-bench} result files; a benchmark with
|
||||
no measured Enso pair does not appear, and the full per-arm cost/accuracy frontier
|
||||
is Figure~\ref{fig:frontier}.
|
||||
|
||||
\begin{table*}[t]
|
||||
\centering\small\setlength{\tabcolsep}{5pt}
|
||||
\caption{Measured under one harness (\texttt{enso-bench}): best single arm vs the
|
||||
Enso family, accuracy (\%) and metered cost (\$ per 1{,}000 tasks). Every number is
|
||||
executed live on the gateway; a dash marks a cell not run. Read per row---\texttt{enso}
|
||||
approaches or beats the best arm well below the premium arm's cost;
|
||||
\texttt{enso-ultra} lifts the ceiling on the open-ended benches at higher metered
|
||||
cost; and, honestly, neither leads HLE, where the strongest single arm wins.
|
||||
Binomial se $\le 3.5$ pts ($n\ge175$). Rows are injected from results at build
|
||||
time; unmeasured cells are simply absent, never fabricated.}
|
||||
\label{tab:measured}
|
||||
\begin{tabular}{@{}l l r r r r r r r r@{}}
|
||||
\toprule
|
||||
& \multicolumn{3}{c}{Best single arm} & \multicolumn{2}{c}{\texttt{enso-flash}} & \multicolumn{2}{c}{\texttt{enso}} & \multicolumn{2}{c}{\texttt{enso-ultra}} \\
|
||||
\cmidrule(lr){2-4}\cmidrule(lr){5-6}\cmidrule(lr){7-8}\cmidrule(lr){9-10}
|
||||
Benchmark & arm & acc. & \$/1k & acc. & \$/1k & acc. & \$/1k & acc. & \$/1k \\
|
||||
\midrule
|
||||
\input{results-measured-rows} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table*}
|
||||
|
||||
\begin{figure*}[t]
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{figures/accuracy_vs_cost.pdf}
|
||||
\caption{Accuracy vs.\ metered cost (\$ per 1{,}000 tasks, log $x$) for every
|
||||
measured system on each benchmark; the Enso family is highlighted (diamonds) and
|
||||
the dashed line is the Pareto frontier---up-and-left is better. \texttt{enso} sits
|
||||
on or near the frontier on every bench: frontier-competitive accuracy well left of
|
||||
the premium single arms. Generated from \texttt{enso-bench}
|
||||
\texttt{results/summary.json}.}
|
||||
\label{fig:frontier}
|
||||
\end{figure*}
|
||||
|
||||
\paragraph{Reading the table.} The hypothesis---that the router's per-request
|
||||
argmax tracks the pool's upper envelope---holds where routing has room to work. On
|
||||
GPQA Diamond \texttt{enso} scores \hEnsoGPQAacc\% at \$\hEnsoGPQAcost/1k against the
|
||||
best single arm's \hBestGPQAacc\% (\texttt{\hBestGPQAname}). That margin is one
|
||||
accuracy point, which at $n{=}198$ is two questions and sits inside the $\pm1.8$-point
|
||||
binomial standard error of either cell, so the accuracy result is a \emph{match},
|
||||
not a lead, and we do not read it as one. What the row does establish is the cost:
|
||||
the same accuracy as the best arm while beating the premium reasoning arm
|
||||
(Opus~4.8, \hOpusGPQAacc\% at \$\hOpusGPQAcost/1k) at roughly a fifth of its metered
|
||||
spend, because the router inherits the pool's upper envelope rather than any one
|
||||
arm's average and prices each answer at the arm that served it. On the open-ended
|
||||
benches \texttt{enso-ultra} raises accuracy to the best single arm's level. We do
|
||||
\emph{not} claim a clean sweep---on HLE the strongest single arm (\texttt{fable-5})
|
||||
leads both Enso SKUs, exactly the single-benchmark regression a per-row read
|
||||
surfaces and an aggregate would hide. That is the coarse-router property we stated
|
||||
up front (\S\ref{sec:routing}): on a homogeneous science/knowledge set the router
|
||||
mostly tracks the arm it routes to, and its edge there is cost, not a new accuracy
|
||||
ceiling.
|
||||
|
||||
\paragraph{Ablation: verify-then-select is better \emph{and} cheaper.}
|
||||
Table~\ref{tab:ablation} isolates the Enso-Ultra fusion logic. The shipped
|
||||
verify-then-select synthesizer---a self-consistency fast path (take the agreeing
|
||||
answer with no extra call when $\ge$2 of 3 arms concur), else a judge-as-selector
|
||||
that picks one candidate rather than merging---is compared against a v1
|
||||
blind-synthesis baseline on the two open-ended benches. Verify-then-select is
|
||||
\emph{both} more accurate and cheaper, because it skips the synthesis call whenever
|
||||
the arms already agree; the ceiling SKU's shipped logic dominates the naive one on
|
||||
both axes.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering\small\setlength{\tabcolsep}{4pt}
|
||||
\caption{Enso-Ultra fusion ablation (measured): v1 blind-synthesis vs the shipped
|
||||
v2 verify-then-select on the open-ended benches. $\Delta$ is v2$-$v1 accuracy;
|
||||
cost is \$ per 1{,}000 tasks. Better \emph{and} cheaper on both.}
|
||||
\label{tab:ablation}
|
||||
\begin{tabular}{@{}lrrrrrrrr@{}}
|
||||
\toprule
|
||||
& \multicolumn{3}{c}{v1 blind-synth} & \multicolumn{3}{c}{v2 verify-select} & & \\
|
||||
\cmidrule(lr){2-4}\cmidrule(lr){5-7}
|
||||
Benchmark & acc. & $n$ & \$/1k & acc. & $n$ & \$/1k & $\Delta$ & cost \\
|
||||
\midrule
|
||||
\input{results-ablation-rows} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\paragraph{Agentic step-routing (pilot).} The agentic benchmarks are where frontier
|
||||
arms diverge most, and the most expensive to run; the full suite is
|
||||
\emph{run pending} (\S\ref{sec:limits}). As a pilot we ran a common $18$-instance
|
||||
subset of SWE-Bench Pro~\cite{swebench} with a step-level router---each agent step
|
||||
(localize, edit, test) routed independently---against a single-Opus~4.8 agent under
|
||||
the same harness. Enso step-routing resolved $38.9\%$ ($7/18$) to single-Opus's
|
||||
$16.7\%$ ($3/18$), at lower metered cost (\$19.70 vs \$27.56), because different
|
||||
steps prefer different arms. This is a small pilot, labelled as such, not the full
|
||||
run.
|
||||
|
||||
\subsection{Routing overhead: microseconds on CPU}
|
||||
\label{sec:overhead}
|
||||
|
||||
Accuracy and cost are the axes a buyer reads; a router adds a third the buyer
|
||||
never sees but always pays---the decision itself. We measured it. Table~\ref{tab:overhead}
|
||||
reports the per-request \emph{decision} latency of each router tier on a
|
||||
\emph{single aarch64 CPU core with no GPU}: the heuristic tier via Go's
|
||||
\texttt{go test -bench}, the learned tier via the \texttt{enso} crate's
|
||||
\texttt{bench\_overhead} integration test (\texttt{cargo test -p enso --release}),
|
||||
each timed over $10^{4}$ iterations after $10^{3}$ warm-up on a $\sim$1k-character
|
||||
prompt against the trained arm table.
|
||||
|
||||
Three findings. \textbf{(i)}~The keyword-rule heuristic---the default gateway path
|
||||
that classifies a request into a task bucket and reads a preference table---decides
|
||||
in $\sim$0.3\,$\mu$s with a single allocation; the whole heuristic route decision
|
||||
(classify plus feasible-arm lookup) is still $\sim$0.9\,$\mu$s. \textbf{(ii)}~The
|
||||
learned \texttt{enso} policy decides end-to-end in \textbf{12.4\,$\mu$s}
|
||||
(p99 14.8\,$\mu$s): 11.4\,$\mu$s to featurize the prompt (hashed n-grams over the
|
||||
raw text, \S\ref{sec:routing}) and \textbf{229\,ns} for the bilinear $x^{\top}Wp$
|
||||
score-and-select over the arm table. There is \emph{no embedding call and no GPU}
|
||||
on this path---the featurizer is deliberately cheap hashed n-grams so that routing
|
||||
never needs a model to route. \textbf{(iii)}~A vector/embedding-similarity variant
|
||||
(cosine nearest-concept over $K{=}20$ model vectors in 768 dimensions) computes its
|
||||
decision in $\sim$8\,$\mu$s, but that figure \emph{excludes} the prompt embedding it
|
||||
requires---a model forward pass costing on the order of milliseconds, i.e.
|
||||
$10^{2}$--$10^{3}\times$ the entire \texttt{enso} decision, and it dominates the
|
||||
tier end-to-end. That domination is exactly why \texttt{enso} featurizes with hashed
|
||||
n-grams rather than embeddings: it buys the same per-request signal at
|
||||
two-to-three orders of magnitude lower latency and with no accelerator.
|
||||
|
||||
The consequence for deployment is the point. A served frontier completion runs from
|
||||
$\sim$$10^{2}$\,ms for a short chat to $\sim$$10^{1}$\,s for an agentic or reasoning
|
||||
trajectory; the routing decision that precedes it is four to six orders of magnitude
|
||||
cheaper and runs on a CPU core the gateway already has. \emph{Routing never needs a
|
||||
GPU---only the served model does.} The same holds for \emph{training} the policy:
|
||||
the offline fit is a closed-form ridge solve and the online adaptation is a LinUCB
|
||||
rank-one update (\S\ref{sec:routing}), both CPU-only, so an operator can fit and
|
||||
continually retrain its own router without an accelerator.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{4.5pt}
|
||||
\caption{Per-request routing \emph{decision} latency, measured on one aarch64 CPU
|
||||
core (no GPU): the heuristic tier via \texttt{go test -bench}, the learned
|
||||
\texttt{enso} tier via \texttt{cargo test -p enso --release --test bench\_overhead}
|
||||
($10^{4}$ iterations, $10^{3}$ warm-up). The vector tier's compute \emph{excludes}
|
||||
the embedding forward pass it requires ($\sim$ms), which dominates it end-to-end.
|
||||
Routing is microseconds; the served LLM call is $10^{2}$--$10^{4}$\,ms.}
|
||||
\label{tab:overhead}
|
||||
\begin{tabular}{@{}lrl@{}}
|
||||
\toprule
|
||||
Router tier & Decision & Embedding \\
|
||||
& (CPU, 1 core) & call \\
|
||||
\midrule
|
||||
Heuristic keyword-rule (Go) & $\sim$0.3\,$\mu$s & none \\
|
||||
Enso learned $x^{\top}Wp$ (Rust) & 12.4\,$\mu$s & none \\
|
||||
\quad featurize / select & 11.4 / 0.23\,$\mu$s & none \\
|
||||
Vector NN, 768-d $K{=}20$ (Go) & $\sim$8\,$\mu$s & req.\ ($\sim$ms) \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\section{Economics: A Metered, Incentive-Aligned Router}
|
||||
\label{sec:econ}
|
||||
|
||||
Enso ships to an organization as a metered product. An org enables its own
|
||||
pool---the providers it holds keys for plus any internal models---and routes its
|
||||
traffic through one \texttt{/v1} endpoint (\S\ref{sec:serving}). Two things then run
|
||||
per org. First, a per-org policy state: the router carries that org's arm table and
|
||||
a preference weight matrix $W$ that starts at the shared fit and adapts to the org's
|
||||
traffic. Second, a reward loop: in-app feedback (accept/edit/thumbs) and an
|
||||
LLM-as-judge that auto-scores each sampled response's quality both land as a scalar
|
||||
reward $r$, which drives the same online \texttt{observe}$(u,x,p,r)$ update
|
||||
\S\ref{sec:routing} specifies---here nudging the org's $W$, not only a per-user
|
||||
$\theta_u$. The reward ledger is \emph{content-free}: it stores the feature vector
|
||||
$x$, the chosen arm $p$, and the reward $r$---never the prompt or completion
|
||||
text---so the mechanism that personalizes routing retains no customer content.
|
||||
|
||||
\subsection{Pricing}
|
||||
\label{sec:pricing}
|
||||
|
||||
We meter the product as \textbf{a 1\% fee on routed LLM spend}: for a request whose
|
||||
provider spend is $v$ dollars, Enso bills $f v$ with $f = 0.01$. A price is honest
|
||||
only if it sits above what the thing costs to run and below the value it creates; we
|
||||
show both bounds hold and derive them from the measured overhead of
|
||||
\S\ref{sec:overhead} and the measured cost frontier of \S\ref{sec:eval}.
|
||||
|
||||
\paragraph{Cost to run.} Two components. The routing \emph{compute} is the decision
|
||||
of \S\ref{sec:overhead}: 12\,$\mu$s of CPU. At a commodity \$0.04 per vCPU-hour that
|
||||
is $\kappa \approx 1.3\times10^{-10}$ dollars per decision---nine orders of magnitude
|
||||
below any per-request fee, i.e.\ negligible. The \emph{eval} component is the
|
||||
LLM-judge: one cheap judge call of cost $c_j$ on a sampled fraction $s$ of requests,
|
||||
so its amortized cost is $s\,c_j$ per routed request. With mean routed spend $\bar v$
|
||||
per request, the run-cost per routed dollar is $(\kappa + s\,c_j)/\bar v$ and the
|
||||
gross margin per routed dollar is
|
||||
\begin{equation}
|
||||
m \;=\; f \;-\; \frac{\kappa + s\,c_j}{\bar v}\;\approx\; f - \frac{s\,c_j}{\bar v}.
|
||||
\end{equation}
|
||||
The meter is profitable while $s < s^\star \equiv (f\bar v - \kappa)/c_j \approx
|
||||
f\bar v / c_j$. Using values anchored to this paper's runs---$\bar v \approx \$0.02$
|
||||
per request (the measured \texttt{enso} per-request cost on LiveCodeBench,
|
||||
\S\ref{sec:eval}) and a small-model judge at $c_j \approx \$0.001$ (roughly 1--2k
|
||||
judged tokens)---the break-even is $s^\star \approx 20\%$. At a sane sampling rate the
|
||||
margin is wide: $s=10\%$ spends $0.5\%$ of routed dollars on eval (margin $0.5$ of
|
||||
the $1\%$ fee); $s=5\%$ spends $0.25\%$ (margin $0.75$ of the fee). The judge is
|
||||
sampled, not run on every request, precisely to keep it a rounding error against the
|
||||
fee.
|
||||
|
||||
\paragraph{Value created.} Let $B$ be an org's spend under the monolith
|
||||
baseline---one expensive model on every request---and let $S$ be the fraction Enso
|
||||
saves by routing each request to the cheapest arm that still clears it. Post-routing
|
||||
provider spend is $B(1-S)$, the fee is $fB(1-S)$, and the org's net saving as a
|
||||
fraction of baseline is
|
||||
\begin{equation}
|
||||
1-(1-S)(1+f) \;=\; S - f(1-S)\;\ge\; S - f,
|
||||
\end{equation}
|
||||
so \textbf{the customer keeps at least $S-1$ percentage points} of its bill.
|
||||
Symmetrically the fee is $f(1-S)/S$ of the value created---at $S=50\%$ that is $1\%$
|
||||
of the savings; at the measured GPQA frontier below it is $0.25\%$. The
|
||||
meter takes a small, bounded slice of a value it earns only when the customer saves.
|
||||
|
||||
\paragraph{Worked example (measured anchor).} On GPQA Diamond
|
||||
(\S\ref{sec:eval}, Table~\ref{tab:measured}) \texttt{enso} scored \hEnsoGPQAacc\% at
|
||||
\$\hEnsoGPQAcost{} per 1{,}000 tasks, while running the premium reasoning arm
|
||||
(Opus~4.8) on the whole workload scored \hOpusGPQAacc\% at \$\hOpusGPQAcost{} per
|
||||
1{,}000 tasks on the same \texttt{enso-bench} run---so routing here saves
|
||||
$S \approx 80\%$ (a ${\sim}5\times$ cost reduction) at \emph{higher} accuracy. An org
|
||||
paying that Opus rate is billed $0.01\times\$\hEnsoGPQAcost \approx \$0.11$ per
|
||||
1{,}000 tasks, nets $\approx 79.8\%$ off its bill, and hands Enso $0.25\%$ of the
|
||||
money Enso saved it. A more conservative workload saving $S=50\%$ still nets the org
|
||||
$\approx 49.5\%$ after the fee. In both, the fee is bounded above by the value (a
|
||||
single-digit-or-less percent of the savings) and above the run-cost (sub-$0.6\%$ of
|
||||
routed spend at $s\le10\%$)---a positive-margin, incentive-aligned meter that wins
|
||||
only when the customer does (Table~\ref{tab:econ}).
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{6pt}
|
||||
\caption{Pricing worked through, per routed dollar and for the measured
|
||||
GPQA frontier. Fee $f=1\%$; judge sampling $s=10\%$, $c_j=\$0.001$,
|
||||
$\bar v=\$0.02$ (\S\ref{sec:pricing}). Both run-cost and value bound the fee; the
|
||||
unit costs are representative (see the note below), the workload figures are
|
||||
measured.}
|
||||
\label{tab:econ}
|
||||
\begin{tabular}{@{}lr@{}}
|
||||
\toprule
|
||||
Quantity & Value \\
|
||||
\midrule
|
||||
Fee (of routed spend) & $1.00\%$ \\
|
||||
\quad routing compute $\kappa/\bar v$ & ${\sim}7\times10^{-7}\%$ \\
|
||||
\quad judge eval $s\,c_j/\bar v$ & $0.5\%$ \\
|
||||
\quad gross margin $m$ & $0.5\%$ \\
|
||||
\midrule
|
||||
GPQA saving $S$ & ${\sim}80\%$ \\
|
||||
\quad fee as share of value & $0.25\%$ \\
|
||||
\quad customer net saving & ${\sim}79.8\%$ \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
\paragraph{Honest note on parameters.} The unit costs above---\$0.04 per vCPU-hour
|
||||
and $c_j\approx\$0.001$ per judge call---are representative, not measured by us;
|
||||
$\bar v$ and $S$ are taken from this paper's own \texttt{enso-bench} runs and are
|
||||
workload-dependent (the $80\%$ GPQA saving is a favorable ceiling, not a
|
||||
promise). The \emph{structure}---compute negligible, eval bounded by $s\,c_j$, fee
|
||||
bounded below by run-cost and above by value---does not depend on the exact
|
||||
constants.
|
||||
|
||||
\subsection{Case study: Hanzo Cloud on Enso}
|
||||
\label{sec:casestudy}
|
||||
|
||||
Enso is not a proposal; it is the path Hanzo Cloud already runs. Every model request
|
||||
to \texttt{hanzo.ai} sent with \texttt{model=auto} is routed by \texttt{enso} through
|
||||
the same gateway (\S\ref{sec:serving}) whose measurements this paper reports---the
|
||||
authors' production traffic and this evaluation share one routing plane and one
|
||||
meter. The cost-per-1{,}000-tasks column of Table~\ref{tab:measured} is therefore not a
|
||||
projection: it is the same per-request-metered figure that prices live \texttt{auto}
|
||||
traffic, read off the production meter. The economics above describe the plane we
|
||||
operate, not one we sketched.
|
||||
|
||||
\section{Limitations and Honest-Reporting Notes}
|
||||
\label{sec:limits}
|
||||
|
||||
\paragraph{Two measurement regimes.} Table~\ref{tab:reference} is external and
|
||||
reported by others---provider single-model cards plus a prior published router's
|
||||
own numbers---and we never relabel any of it as Enso's. Table~\ref{tab:measured} is
|
||||
the opposite: every arm \emph{and} every Enso SKU re-measured inside
|
||||
\texttt{enso-bench} under one gateway, one prompt format, one scorer, so the
|
||||
arm-vs-Enso comparison there is like-for-like. The two tables should not be read
|
||||
across each other cell by cell---a provider-reported number can differ from our
|
||||
controlled re-run in prompt formatting, sampling, tool access, and scoring.
|
||||
Table~\ref{tab:reference} anchors scale; Table~\ref{tab:measured} adjudicates.
|
||||
|
||||
\paragraph{Agentic benchmarks: pilot only.} The agentic rows (SWE-Bench Pro,
|
||||
Terminal-Bench 2.1) and LiveCodeBench Pro are the most expensive to run and the
|
||||
last to land; beyond the $18$-instance SWE-Bench Pro pilot of \S\ref{sec:eval} they
|
||||
are \emph{run pending}. Because agentic benchmarks are exactly where the frontier
|
||||
arms diverge most---and where the pilot's step-routing gain is largest---these rows
|
||||
are the ones most likely to move the Enso-vs-best-arm conclusion, and we flag that
|
||||
the full agentic story is incomplete until they are filled.
|
||||
|
||||
\paragraph{Training-free is a choice, not a claim of dominance.} We argue Enso's
|
||||
training-free orchestration is more maintainable under pool churn
|
||||
(\S\ref{sec:ultra}); we do \emph{not} claim it beats a trained orchestrator such as
|
||||
the prior published router (Ultra) on accuracy. The evaluation is what adjudicates
|
||||
that, per row, and only once the pending cells are measured.
|
||||
|
||||
\paragraph{Numbers are data.} No number in this paper is invented. The external
|
||||
reference (Table~\ref{tab:reference}) is reported-by-others constants, labelled as
|
||||
such; every measured cell---Tables~\ref{tab:measured} and~\ref{tab:ablation}, the
|
||||
frontier figure, and the headline numbers in the abstract---is injected at build
|
||||
time from a generated file rather than typed into the table, and an unmeasured cell
|
||||
is simply absent rather than fabricated. The cost column is a per-request-metered
|
||||
figure from the serving plane (\S\ref{sec:serving}), not a blended list price. That
|
||||
machinery guarantees the printed table matches a file; it does not guarantee the
|
||||
file is the only one, and here it is not. The next paragraph says so.
|
||||
|
||||
\paragraph{Two generated files disagree on two benchmarks.} The measured cells
|
||||
come from three generated files in this directory:
|
||||
\texttt{results-measured-rows}, \texttt{results-headline} and
|
||||
\texttt{results-ablation-rows}. A fourth, \texttt{results-prior}, carries the same
|
||||
generator stamp and an earlier run, in the two-SKU format this paper no longer
|
||||
uses. Nothing inputs it, and it disagrees with what we print:
|
||||
|
||||
\begin{center}\footnotesize\setlength{\tabcolsep}{3pt}
|
||||
\begin{tabular}{@{}llrr@{}}
|
||||
\toprule
|
||||
& & printed & earlier \\
|
||||
\midrule
|
||||
GPQA & \texttt{enso} & 92.9 / \$11.1 & 87.9 / \$50.6 \\
|
||||
& \texttt{enso-ultra} & 92.9 / \$85.8 & 90.4 / \$80.2 \\
|
||||
LCB & \texttt{enso} & 93.7 / \$17.5 & 91.4 / \$29.9 \\
|
||||
& \texttt{enso-ultra} & 89.1 / \$428 & 85.1 / \$410 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\noindent Accuracy (\%) and metered cost per 1{,}000 tasks; LCB is
|
||||
LiveCodeBench.
|
||||
|
||||
\noindent What can be established from the two files. Humanity's Last Exam and
|
||||
CharXiv Reasoning agree between them exactly on accuracy and to the printed
|
||||
precision on cost; only GPQA Diamond and LiveCodeBench differ. Repeated sampling
|
||||
does not reproduce two of four benchmarks to the digit, so the later file is the
|
||||
earlier one with those two benchmarks replaced and the other two carried forward.
|
||||
The \texttt{enso-flash} column points the same way: it is populated for exactly
|
||||
those two benchmarks and is a dash for the other two.
|
||||
|
||||
The accuracy gaps are small in items. At $n{=}198$, GPQA 92.9 against 87.9 is 184
|
||||
against 174 questions correct---ten items, against a binomial standard error of
|
||||
1.8--2.3 points on either cell. At $n{=}175$, LiveCodeBench 93.7 against 91.4 is
|
||||
164 against 160, four items. The \emph{cost} gaps are not small and are not
|
||||
sampling: \texttt{enso} on GPQA moves from \$50.6 to \$11.1 per 1{,}000 tasks, a
|
||||
factor of 4.6, which is a routing or metering change rather than a re-roll.
|
||||
|
||||
What cannot be established: which run is the better estimate. \texttt{enso-bench}
|
||||
and \texttt{scripts/emit\_paper.py} are on no machine we have, so neither run can be
|
||||
re-executed and the two cannot be adjudicated by measurement. This paper prints the
|
||||
later run throughout and is internally consistent in doing so; the earlier run is
|
||||
preserved verbatim rather than deleted; and on the GPQA and LiveCodeBench rows the
|
||||
spread between the two runs, not the binomial error alone, is the honest
|
||||
uncertainty.
|
||||
|
||||
One independent artifact bears on the GPQA reading. The \texttt{enso} router
|
||||
repository stores a per-item table of which arms answered each question correctly,
|
||||
and replays the router against it with the fingerprint index refit five-fold so the
|
||||
router is scored on questions absent from its own route table. Over the same item
|
||||
counts that replay reports 92.9 (GPQA, $n{=}198$), 91.4 (LiveCodeBench, $n{=}175$),
|
||||
38.2 (HLE, $n{=}500$) and 85.5 (CharXiv, $n{=}200$)---and on all four the strongest
|
||||
single arm scores exactly the same as the router. Three of the four best-arm cells we print agree with
|
||||
that replay to the digit---\texttt{fable-5} at 38.2 on HLE, \texttt{gpt-5.5} at
|
||||
85.5 on CharXiv, and the LiveCodeBench cell we leave blank. The fourth does not:
|
||||
the replay names \texttt{grok-4.5} at 92.9 as the strongest arm on GPQA, over a
|
||||
wider eleven-arm pool than the one this paper serves, where we print
|
||||
\texttt{\hBestGPQAname} at \hBestGPQAacc. A stored-table replay is a different
|
||||
measurement from the live-gateway run reported here and we do not merge the two.
|
||||
It does support reading the GPQA row as a match rather than a lead, which is how
|
||||
\S\ref{sec:eval} now reads it.
|
||||
|
||||
\section{Conclusion}
|
||||
|
||||
No single frontier model leads every benchmark, so a monolith is a standing bet
|
||||
against its own losing columns. Enso replaces that bet with a learned policy over a
|
||||
pool of frontier arms: \texttt{enso} routes each request to the single arm most
|
||||
likely to serve it best under a per-request cost/latency/quality objective, and
|
||||
\texttt{enso-ultra} fans the hardest requests out to the top-$N$ arms and
|
||||
synthesizes one answer. Both are one \texttt{/v1} product---one identity, one meter,
|
||||
one 1M-context ladder---so the pool can change underneath without a client change.
|
||||
Against the recent learned-orchestrator baseline, Enso shares the thesis and
|
||||
the two-SKU shape but places all learning at the routing layer and keeps
|
||||
orchestration training-free, so onboarding a new arm is a data change rather than a
|
||||
retrain. We report the comparison the way a buyer of intelligence reads it---accuracy
|
||||
and metered cost, per benchmark---and we report it honestly: measured where we have
|
||||
measured, \emph{run pending} where we have not.
|
||||
|
||||
{\small
|
||||
\bibliographystyle{plain}
|
||||
\bibliography{references}
|
||||
}
|
||||
|
||||
\end{document}
|
||||
@@ -1,244 +0,0 @@
|
||||
% =====================================================================
|
||||
% Enso paper bibliography.
|
||||
% Hanzo internal artifacts + real external literature. No fabricated
|
||||
% author lists: where a paper's individual authors are not known to us
|
||||
% (e.g. Sakana's ICLR foundations), the institutional author is used.
|
||||
% =====================================================================
|
||||
|
||||
% ---- Hanzo internal ----
|
||||
@misc{ensoengine,
|
||||
author = {{Hanzo Industries}},
|
||||
title = {{enso: Learned SLO-Constrained Routing Policy for hanzo-router}},
|
||||
howpublished = {\url{https://github.com/hanzoai/engine}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@misc{hanzorouterpaper,
|
||||
author = {Hanzo AI Research},
|
||||
title = {{Hanzo Router: Memory-Aware, Local-First LLM Routing with a
|
||||
Learned SLO-Constrained Policy}},
|
||||
howpublished = {Hanzo Research},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@misc{hanzoengine,
|
||||
author = {{Hanzo Industries}},
|
||||
title = {{hanzo-engine: An OpenAI-Compatible LLM Inference Engine in Rust}},
|
||||
howpublished = {\url{https://github.com/hanzoai/engine}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@misc{hanzogateway,
|
||||
author = {{Hanzo Industries}},
|
||||
title = {{Hanzo AI Gateway: One \texttt{/v1} API over a Discovered Model Fleet}},
|
||||
howpublished = {\url{https://api.hanzo.ai}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@misc{zenrouter,
|
||||
author = {{Zen LM}},
|
||||
title = {{zen-router: A 0.6B Trainable Routing Model}},
|
||||
howpublished = {\url{https://github.com/zenlm/zen-router}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
% ---- The foil: Sakana AI Fugu and its ICLR foundations ----
|
||||
@misc{priororchestrator,
|
||||
author = {{Sakana AI}},
|
||||
title = {{Fugu: A Learned Orchestrator over Frontier Language Models}},
|
||||
howpublished = {arXiv preprint arXiv:2606.21228, \url{https://sakana.ai/fugu-release}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@inproceedings{trinity,
|
||||
author = {{Sakana AI}},
|
||||
title = {{Trinity: Evolutionary Composition of Language Model Experts}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@inproceedings{conductor,
|
||||
author = {{Sakana AI}},
|
||||
title = {{Conductor: Reinforcement-Learned Orchestration of Model Ensembles}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
% ---- LLM routing and cascading ----
|
||||
@misc{routellm,
|
||||
author = {Isaac Ong and Amjad Almahairi and Vincent Wu and Wei-Lin Chiang and
|
||||
Tianhao Wu and Joseph E. Gonzalez and M. Waleed Kadous and Ion Stoica},
|
||||
title = {{RouteLLM: Learning to Route LLMs with Preference Data}},
|
||||
howpublished = {arXiv preprint arXiv:2406.18665},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@article{frugalgpt,
|
||||
author = {Lingjiao Chen and Matei Zaharia and James Zou},
|
||||
title = {{FrugalGPT: How to Use Large Language Models While Reducing Cost
|
||||
and Improving Performance}},
|
||||
journal = {arXiv preprint arXiv:2305.05176},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{hybridllm,
|
||||
author = {Dujian Ding and Ankur Mallick and Chi Wang and Robert Sim and
|
||||
Subhabrata Mukherjee and Victor R{\"u}hle and
|
||||
Laks V. S. Lakshmanan and Ahmed Hassan Awadallah},
|
||||
title = {{Hybrid LLM: Cost-Efficient and Quality-Aware Query Routing}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@article{automix,
|
||||
author = {Aman Madaan and Pranjal Aggarwal and Ankit Anand and
|
||||
Srividya Pranavi Potharaju and Swaroop Mishra and Pei Zhou and
|
||||
Aditya Gupta and Dheeraj Rajagopal and Karthik Kappaganthu and
|
||||
Yiming Yang and Shyam Upadhyay and Mausam and Manaal Faruqui},
|
||||
title = {{AutoMix: Automatically Mixing Language Models}},
|
||||
journal = {arXiv preprint arXiv:2310.12963},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{tabi,
|
||||
author = {Yiding Wang and Kai Chen and Haisheng Tan and Kun Guo},
|
||||
title = {{Tabi: An Efficient Multi-Level Inference System for Large
|
||||
Language Models}},
|
||||
booktitle = {Proceedings of the 18th European Conference on Computer Systems
|
||||
(EuroSys)},
|
||||
year = {2023},
|
||||
pages = {233--248},
|
||||
publisher = {ACM}
|
||||
}
|
||||
|
||||
% ---- Multi-agent / ensemble synthesis (Enso Ultra) ----
|
||||
@inproceedings{moa,
|
||||
author = {Junlin Wang and Jue Wang and Ben Athiwaratkun and Ce Zhang and
|
||||
James Zou},
|
||||
title = {{Mixture-of-Agents Enhances Large Language Model Capabilities}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2025}
|
||||
}
|
||||
|
||||
@inproceedings{llmblender,
|
||||
author = {Dongfu Jiang and Xiang Ren and Bill Yuchen Lin},
|
||||
title = {{LLM-Blender: Ensembling Large Language Models with Pairwise
|
||||
Ranking and Generative Fusion}},
|
||||
booktitle = {Proceedings of the 61st Annual Meeting of the Association for
|
||||
Computational Linguistics (ACL)},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{selfconsistency,
|
||||
author = {Xuezhi Wang and Jason Wei and Dale Schuurmans and Quoc Le and
|
||||
Ed H. Chi and Sharan Narang and Aakanksha Chowdhery and Denny Zhou},
|
||||
title = {{Self-Consistency Improves Chain of Thought Reasoning in
|
||||
Language Models}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
% ---- Learning machinery ----
|
||||
@inproceedings{linucb,
|
||||
author = {Lihong Li and Wei Chu and John Langford and Robert E. Schapire},
|
||||
title = {{A Contextual-Bandit Approach to Personalized News Article
|
||||
Recommendation}},
|
||||
booktitle = {Proceedings of the 19th International Conference on World Wide Web
|
||||
(WWW)},
|
||||
year = {2010},
|
||||
pages = {661--670},
|
||||
publisher = {ACM}
|
||||
}
|
||||
|
||||
@article{ridge,
|
||||
author = {Arthur E. Hoerl and Robert W. Kennard},
|
||||
title = {{Ridge Regression: Biased Estimation for Nonorthogonal Problems}},
|
||||
journal = {Technometrics},
|
||||
volume = {12},
|
||||
number = {1},
|
||||
pages = {55--67},
|
||||
year = {1970},
|
||||
publisher = {Taylor \& Francis}
|
||||
}
|
||||
|
||||
@article{grpo,
|
||||
author = {Zhihong Shao and Peiyi Wang and Qihao Zhu and Runxin Xu and
|
||||
Junxiao Song and Xiao Bi and Haowei Zhang and Mingchuan Zhang and
|
||||
Y. K. Li and Y. Wu and Daya Guo},
|
||||
title = {{DeepSeekMath: Pushing the Limits of Mathematical Reasoning in
|
||||
Open Language Models}},
|
||||
journal = {arXiv preprint arXiv:2402.03300},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@article{sepcmaes,
|
||||
author = {Raymond Ros and Nikolaus Hansen},
|
||||
title = {{A Simple Modification in CMA-ES Achieving Linear Time and Space
|
||||
Complexity}},
|
||||
journal = {Parallel Problem Solving from Nature (PPSN X), LNCS 5199},
|
||||
pages = {296--305},
|
||||
year = {2008},
|
||||
publisher = {Springer}
|
||||
}
|
||||
|
||||
% ---- Benchmarks ----
|
||||
@inproceedings{swebench,
|
||||
author = {Carlos E. Jimenez and John Yang and Alexander Wettig and
|
||||
Shunyu Yao and Kexin Pei and Ofir Press and Karthik Narasimhan},
|
||||
title = {{SWE-bench: Can Language Models Resolve Real-World GitHub Issues?}},
|
||||
booktitle = {International Conference on Learning Representations (ICLR)},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@article{livecodebench,
|
||||
author = {Naman Jain and King Han and Alex Gu and Wen-Ding Li and
|
||||
Fanjia Yan and Tianjun Zhang and Sida Wang and Armando Solar-Lezama and
|
||||
Koushik Sen and Ion Stoica},
|
||||
title = {{LiveCodeBench: Holistic and Contamination Free Evaluation of
|
||||
Large Language Models for Code}},
|
||||
journal = {arXiv preprint arXiv:2403.07974},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@article{gpqa,
|
||||
author = {David Rein and Betty Li Hou and Asa Cooper Stickland and
|
||||
Jackson Petty and Richard Yuanzhe Pang and Julien Dirani and
|
||||
Julian Michael and Samuel R. Bowman},
|
||||
title = {{GPQA: A Graduate-Level Google-Proof Q\&A Benchmark}},
|
||||
journal = {arXiv preprint arXiv:2311.12022},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@article{hle,
|
||||
author = {Long Phan and others},
|
||||
title = {{Humanity's Last Exam}},
|
||||
journal = {arXiv preprint arXiv:2501.14249},
|
||||
year = {2025}
|
||||
}
|
||||
|
||||
@article{charxiv,
|
||||
author = {Zirui Wang and Mengzhou Xia and Luxi He and Howard Chen and
|
||||
Yitao Liu and Richard Zhu and Kaiqu Liang and Xindi Wu and
|
||||
Haotian Liu and Sadhika Malladi and Alexis Chevalier and
|
||||
Sanjeev Arora and Danqi Chen},
|
||||
title = {{CharXiv: Charting Gaps in Realistic Chart Understanding in
|
||||
Multimodal LLMs}},
|
||||
journal = {arXiv preprint arXiv:2406.18521},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@misc{terminalbench,
|
||||
author = {{Terminal-Bench Team}},
|
||||
title = {{Terminal-Bench: A Benchmark for AI Agents in Terminal Environments}},
|
||||
howpublished = {\url{https://www.tbench.ai/}},
|
||||
year = {2025}
|
||||
}
|
||||
|
||||
% ---- Discipline ----
|
||||
@misc{hickey_simple,
|
||||
author = {Rich Hickey},
|
||||
title = {{Simple Made Easy}},
|
||||
howpublished = {Strange Loop Conference},
|
||||
year = {2011},
|
||||
note = {\url{https://www.infoq.com/presentations/Simple-Made-Easy/}}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
% GENERATED by enso-bench/scripts/emit_paper.py -- measured, do not hand-edit.
|
||||
Humanity's Last Exam & 29.2 & 500 & \$383 & 34.6 & 500 & \$304 & +5.4 & 21\% \\
|
||||
CharXiv Reasoning & 81.5 & 200 & \$50.7 & 85.5 & 200 & \$31.4 & +4.0 & 38\%
|
||||
@@ -1,8 +0,0 @@
|
||||
% GENERATED by enso-bench/scripts/emit_paper.py -- measured headline macros.
|
||||
\newcommand{\hEnsoGPQAacc}{92.9}
|
||||
\newcommand{\hEnsoGPQAcost}{11.1}
|
||||
\newcommand{\hUltraGPQAacc}{92.9}
|
||||
\newcommand{\hBestGPQAname}{gpt-5.6-sol}
|
||||
\newcommand{\hBestGPQAacc}{91.9}
|
||||
\newcommand{\hOpusGPQAacc}{86.4}
|
||||
\newcommand{\hOpusGPQAcost}{55.4}
|
||||
@@ -1,5 +0,0 @@
|
||||
% GENERATED by enso-bench/scripts/emit_paper.py -- measured, do not hand-edit.
|
||||
GPQA Diamond & \texttt{gpt-5.6-sol} & 91.9 & \$10.1 & 72.2 & \$3.0 & 92.9 & \$11.1 & 92.9 & \$85.8 \\
|
||||
LiveCodeBench & -- & -- & -- & 77.7 & \$50.5 & 93.7 & \$17.5 & 89.1 & \$428 \\
|
||||
Humanity's Last Exam & \texttt{fable-5} & 38.2 & \$51.0 & -- & -- & 29.4 & \$153 & 34.6 & \$304 \\
|
||||
CharXiv Reasoning & \texttt{gpt-5.5} & 85.5 & \$3.7 & -- & -- & 78.0 & \$17.3 & 85.5 & \$31.4
|
||||
@@ -1,38 +0,0 @@
|
||||
% GENERATED by enso-bench/scripts/emit_paper.py -- do not hand-edit.
|
||||
%
|
||||
% The EARLIER of two runs. Nothing inputs this file; main.tex prints
|
||||
% results-measured-rows.tex. Kept because it is the only record of the run
|
||||
% whose per-benchmark commits (f45579f, 2a652e8, b336a79, 66ab231, 2d26d1e,
|
||||
% b679712, 1e4b204, fdd3dec) name their seed, sample size and system count,
|
||||
% and because it disagrees with the printed run on two benchmarks. The
|
||||
% disagreement, and what can and cannot be concluded from it, is stated in
|
||||
% main.tex under Limitations -- not hidden by deleting this file.
|
||||
%
|
||||
% Two SKUs only: enso and enso-ultra. The enso-flash column of the printed
|
||||
% table has no counterpart here, which is one reason the printed run is
|
||||
% later rather than merely different.
|
||||
|
||||
% gpqa_diamond: enso n=198 acc=87.9 ultra n=198 acc=90.4
|
||||
\renewcommand{\rEnsGPQA}{87.9}
|
||||
\renewcommand{\rEnsCGPQA}{50.6}
|
||||
\renewcommand{\rUltGPQA}{90.4}
|
||||
\renewcommand{\rUltCGPQA}{80.2}
|
||||
|
||||
% hle: enso n=500 acc=29.4 ultra n=500 acc=34.6
|
||||
\renewcommand{\rEnsHLE}{29.4}
|
||||
\renewcommand{\rEnsCHLE}{153.1}
|
||||
\renewcommand{\rUltHLE}{34.6}
|
||||
\renewcommand{\rUltCHLE}{303.6}
|
||||
|
||||
% livecodebench: enso n=175 acc=91.4 ultra n=175 acc=85.1
|
||||
\renewcommand{\rEnsLCB}{91.4}
|
||||
\renewcommand{\rEnsCLCB}{29.9}
|
||||
\renewcommand{\rUltLCB}{85.1}
|
||||
\renewcommand{\rUltCLCB}{409.9}
|
||||
|
||||
% charxiv: enso n=200 acc=78.0 ultra n=200 acc=85.5
|
||||
\renewcommand{\rEnsCHARXIV}{78.0}
|
||||
\renewcommand{\rEnsCCHARXIV}{17.3}
|
||||
\renewcommand{\rUltCHARXIV}{85.5}
|
||||
\renewcommand{\rUltCCHARXIV}{31.4}
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
corpus: 3686475 train rows, 139621 val rows, suites ["ag_news", "emotion", "banking77", "support_triage", "email_spam", "phishing", "guardrails_jailbreak", "moderation_toxicity", "rag_relevance", "model_routing_domain", "typed_decisions", "massive", "tool", "risk", "done", "repo", "function", "resolve", "action", "nemotron", "clinc150", "xnli", "sst5", "shuffle", "alias", "near", "subset", "swap", "codeswitch", "boolq", "mnli", "code.file.gold", "code.affected.gold", "code.symbol.gold", "code.suspect.gold", "code.test.silver", "control.context.gold", "control.user.gold", "control.continue.gold", "control.commit.gold", "control.rollback.gold", "control.strategy.gold", "control.repeat.gold", "control.done.gold", "control.retry.gold", "control.user.silver", "code.failure.gold", "code.failure.silver", "skills.select.silver", "graph_typed", "turbofan", "rig", "sysml", "readiness", "trade", "testplan", "arch"] (62s)
|
||||
init: 176 tensors carried, fresh: ["ordinal.cut.bias", "ordinal.cut.weight", "ordinal.gap.bias", "ordinal.gap.weight", "ordinal.location.bias", "ordinal.location.weight", "retrieval.key.bias", "retrieval.key.weight", "retrieval.query.bias", "retrieval.query.weight", "retrieval.scale"]
|
||||
plan: stage a, 1 epochs, 91899 batches, 2756 warmup, 18379 cooldown; rows on a sample of over 64 options, by epoch: [65352]
|
||||
resume: round 2, 2325 of 91899 batches merged, optimizer states of ["evo", "dgx", "dbc"]
|
||||
cluster: coordinating on 0.0.0.0:7070
|
||||
cluster: dbc (127.0.0.1:52177) joins round 2 as worker 0 (Metal { gpu_id: 4294968649 }, BF16), optimizer state at step 1519
|
||||
worker 0 (dbc): joined round 2, optimizer state at step 1519
|
||||
cluster: evo (10.0.0.57:51834) joins round 2 as worker 1 (Rocm { gpu_id: 0 }, BF16), optimizer state at step 184
|
||||
cluster: dgx (10.0.0.19:34202) joins round 2 as worker 2 (Cuda { gpu_id: 0 }, BF16), optimizer state at step 622
|
||||
round 2: 3293/91899 lr×1.000 eta 541m | dbc 775 steps 7028 tok/s nll 2.3919 | evo 43 steps 1136 tok/s nll 2.4592 | dgx 150 steps 4175 tok/s nll 2.4464 | 329.2s, closed 29.2s past the deadline, outer step 0.1s
|
||||
worker 0 round 2: 775 steps 7028 tok/s (7430 padded; contexts 4988 of 5004) nll 2.3919 gpu 88% free 81% | delta sent 0.1s, waited 28.5s, update 0.0s
|
||||
round 3: 4693/91899 lr×1.000 eta 407m | dbc 771 steps 7008 tok/s nll 2.4125 | evo 171 steps 1797 tok/s nll 2.3506 | dgx 458 steps 4218 tok/s nll 2.3450 | 308.3s, closed 8.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 771 steps 7008 tok/s (7412 padded; contexts 4968 of 4982) nll 2.4125 gpu 94% free 80% | delta sent 0.1s, waited 7.6s, update 0.0s
|
||||
round 4: 6101/91899 lr×1.000 eta 367m | dbc 763 steps 7039 tok/s nll 2.3025 | evo 182 steps 1739 tok/s nll 2.4304 | dgx 463 steps 4332 tok/s nll 2.2740 | 307.0s, closed 7.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 763 steps 7039 tok/s (7436 padded; contexts 5050 of 5067) nll 2.3025 gpu 94% free 81% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 5: 7504/91899 lr×1.000 eta 347m | dbc 775 steps 7033 tok/s nll 2.2869 | evo 156 steps 1587 tok/s nll 2.3398 | dgx 472 steps 4313 tok/s nll 2.1927 | 306.4s, closed 6.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 775 steps 7033 tok/s (7418 padded; contexts 5046 of 5057) nll 2.2869 gpu 94% free 80% | delta sent 0.1s, waited 5.9s, update 0.0s
|
||||
round 6: 8894/91899 lr×1.000 eta 333m | dbc 771 steps 7066 tok/s nll 2.2044 | evo 166 steps 1663 tok/s nll 2.4436 | dgx 453 steps 4237 tok/s nll 2.1281 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 771 steps 7066 tok/s (7450 padded; contexts 5071 of 5084) nll 2.2044 gpu 95% free 80% | delta sent 0.1s, waited 6.1s, update 0.0s
|
||||
round 7: 10282/91899 lr×1.000 eta 323m | dbc 761 steps 7056 tok/s nll 2.2521 | evo 158 steps 1645 tok/s nll 2.1156 | dgx 469 steps 4245 tok/s nll 2.2524 | 306.9s, closed 6.9s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 761 steps 7056 tok/s (7427 padded; contexts 5091 of 5102) nll 2.2521 gpu 94% free 80% | delta sent 0.1s, waited 6.4s, update 0.0s
|
||||
round 8: 11696/91899 lr×1.000 eta 313m | dbc 769 steps 7022 tok/s nll 2.1954 | evo 177 steps 1787 tok/s nll 2.2847 | dgx 468 steps 4274 tok/s nll 2.1066 | 306.9s, closed 6.9s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 769 steps 7022 tok/s (7405 padded; contexts 4988 of 5001) nll 2.1954 gpu 94% free 80% | delta sent 0.1s, waited 6.7s, update 0.0s
|
||||
round 9: 13101/91899 lr×1.000 eta 305m | dbc 773 steps 7060 tok/s nll 2.1973 | evo 169 steps 1772 tok/s nll 2.0504 | dgx 463 steps 4191 tok/s nll 2.1364 | 306.6s, closed 6.6s past the deadline, outer step 0.1s
|
||||
worker 0 round 9: 773 steps 7060 tok/s (7465 padded; contexts 5016 of 5034) nll 2.1973 gpu 94% free 81% | delta sent 0.1s, waited 6.0s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (123s); 11988 rows by the head (310s)
|
||||
val @13101: action 0.273/1.801 ag_news 0.375/1.286 arch 0.670/0.882 banking77 0.074/3.691 boolq 0.668/0.687 clinc150 0.045/4.284 code.affected.gold 0.465/0.694 code.failure.silver 0.263/1.763 code.file.gold 0.062/4.274 code.suspect.gold 0.000/4.893 code.symbol.gold 0.053/4.320 code.test.silver 0.062/3.625 control.commit.gold 0.190/0.818 control.context.gold 0.806/1.231 control.continue.gold 0.095/0.764 control.done.gold 0.909/0.638 control.repeat.gold 1.000/0.586 control.retry.gold 0.000/1.105 control.rollback.gold 0.571/0.693 control.strategy.gold 0.750/0.633 control.user.silver 0.875/0.499 done 0.983/0.540 email_spam 0.973/0.137 emotion 0.525/1.396 function 0.393/2.355 graph_typed 0.489/1.198 guardrails_jailbreak 0.502/0.682 massive 0.440/1.810 mnli 0.713/0.784 model_routing_domain 0.882/0.577 moderation_toxicity 0.857/0.302 nemotron 0.360/2.510 phishing 0.922/0.345 rag_relevance 0.482/0.704 readiness 0.438/1.176 resolve 0.003/0.735 rig 0.465/1.113 risk 0.000/2.330 skills.select.silver 0.000/7.154 sst5 0.230/1.693 support_triage 0.360/1.837 sysml 0.583/0.751 testplan 0.608/1.048 tool 0.145/2.406 trade 0.608/0.891 turbofan 0.420/1.004 typed_decisions 0.503/1.153 xnli 0.698/0.842
|
||||
saved /Users/a/scratch/decision/runs/a at 13101 batches, 0 epochs
|
||||
round 10: 14246/91899 lr×1.000 eta 319m | dbc 528 steps 4719 tok/s nll 2.1669 | evo 165 steps 1652 tok/s nll 2.0316 | dgx 452 steps 4212 tok/s nll 2.1329 | 436.2s, closed 136.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 10: 528 steps 4719 tok/s (4969 padded; contexts 3356 of 3365) nll 2.1669 gpu 95% free 78% | delta sent 0.2s, waited 135.1s, update 0.0s
|
||||
round 11: 15649/91899 lr×1.000 eta 310m | dbc 766 steps 7053 tok/s nll 2.1189 | evo 166 steps 1672 tok/s nll 2.1597 | dgx 471 steps 4249 tok/s nll 2.1475 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 11: 766 steps 7053 tok/s (7445 padded; contexts 5035 of 5055) nll 2.1189 gpu 94% free 80% | delta sent 0.1s, waited 6.4s, update 0.1s
|
||||
round 12: 17044/91899 lr×1.000 eta 301m | dbc 766 steps 7061 tok/s nll 2.0992 | evo 171 steps 1768 tok/s nll 2.2402 | dgx 458 steps 4216 tok/s nll 2.1588 | 308.5s, closed 8.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 12: 766 steps 7061 tok/s (7440 padded; contexts 5024 of 5038) nll 2.0992 gpu 93% free 80% | delta sent 0.1s, waited 7.8s, update 0.0s
|
||||
round 13: 18444/91899 lr×1.000 eta 293m | dbc 773 steps 7026 tok/s nll 2.0401 | evo 160 steps 1709 tok/s nll 2.0042 | dgx 467 steps 4263 tok/s nll 2.0673 | 306.7s, closed 6.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 13: 773 steps 7026 tok/s (7420 padded; contexts 5003 of 5014) nll 2.0401 gpu 94% free 81% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 14: 19837/91899 lr×1.000 eta 286m | dbc 758 steps 7065 tok/s nll 2.0450 | evo 173 steps 1663 tok/s nll 2.2869 | dgx 462 steps 4182 tok/s nll 1.9836 | 307.3s, closed 7.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 14: 758 steps 7065 tok/s (7464 padded; contexts 5089 of 5114) nll 2.0450 gpu 94% free 80% | delta sent 0.1s, waited 6.8s, update 0.0s
|
||||
round 15: 21271/91899 lr×1.000 eta 278m | dbc 761 steps 7059 tok/s nll 1.9950 | evo 204 steps 2058 tok/s nll 2.0689 | dgx 469 steps 4293 tok/s nll 2.1065 | 307.3s, closed 7.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 15: 761 steps 7059 tok/s (7441 padded; contexts 5156 of 5176) nll 1.9950 gpu 94% free 80% | delta sent 0.1s, waited 7.0s, update 0.1s
|
||||
round 16: 22667/91899 lr×1.000 eta 271m | dbc 766 steps 7057 tok/s nll 2.0237 | evo 165 steps 1781 tok/s nll 1.9965 | dgx 465 steps 4232 tok/s nll 2.0921 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 16: 766 steps 7057 tok/s (7444 padded; contexts 5110 of 5123) nll 2.0237 gpu 94% free 80% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 17: 24082/91899 lr×1.000 eta 264m | dbc 771 steps 6974 tok/s nll 2.0605 | evo 185 steps 1974 tok/s nll 1.9028 | dgx 459 steps 4244 tok/s nll 1.9756 | 308.4s, closed 8.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 17: 771 steps 6974 tok/s (7368 padded; contexts 4943 of 4958) nll 2.0605 gpu 94% free 80% | delta sent 0.1s, waited 8.0s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (127s); 11988 rows by the head (310s)
|
||||
val @24082: action 0.340/1.785 ag_news 0.807/0.693 arch 0.660/0.842 banking77 0.216/3.040 boolq 0.629/0.665 clinc150 0.133/3.406 code.affected.gold 0.482/0.695 code.failure.silver 0.474/1.558 code.file.gold 0.062/4.684 code.suspect.gold 0.000/4.959 code.symbol.gold 0.060/4.302 code.test.silver 0.062/3.721 control.commit.gold 0.190/0.737 control.context.gold 0.806/0.829 control.continue.gold 0.048/0.845 control.done.gold 0.091/0.711 control.repeat.gold 1.000/0.613 control.retry.gold 0.000/0.791 control.rollback.gold 0.571/0.693 control.strategy.gold 0.750/0.641 control.user.silver 0.875/0.458 done 0.017/0.824 email_spam 0.990/0.047 emotion 0.542/1.237 function 0.425/2.173 graph_typed 0.437/1.165 guardrails_jailbreak 0.355/0.835 massive 0.625/1.238 mnli 0.637/0.845 model_routing_domain 0.502/1.507 moderation_toxicity 0.868/0.406 nemotron 0.410/2.314 phishing 0.942/0.249 rag_relevance 0.505/0.701 readiness 0.430/1.167 resolve 0.130/0.729 rig 0.460/1.145 risk 0.000/1.949 skills.select.silver 0.000/7.366 sst5 0.338/1.802 support_triage 0.398/1.789 sysml 0.590/0.727 testplan 0.615/1.081 tool 0.090/2.397 trade 0.495/0.937 turbofan 0.485/1.028 typed_decisions 0.520/1.161 xnli 0.675/0.858
|
||||
saved /Users/a/scratch/decision/runs/a at 24082 batches, 0 epochs
|
||||
round 18: 25282/91899 lr×1.000 eta 268m | dbc 531 steps 4806 tok/s nll 1.9831 | evo 202 steps 2066 tok/s nll 1.9394 | dgx 467 steps 4287 tok/s nll 2.0452 | 440.4s, closed 140.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 18: 531 steps 4806 tok/s (5082 padded; contexts 3411 of 3425) nll 1.9831 gpu 95% free 78% | delta sent 0.1s, waited 139.1s, update 0.0s
|
||||
round 19: 26718/91899 lr×1.000 eta 260m | dbc 770 steps 7051 tok/s nll 1.9715 | evo 191 steps 1965 tok/s nll 1.9598 | dgx 475 steps 4296 tok/s nll 1.9843 | 311.3s, closed 11.3s past the deadline, outer step 0.1s
|
||||
worker 0 round 19: 770 steps 7051 tok/s (7445 padded; contexts 5016 of 5029) nll 1.9715 gpu 93% free 80% | delta sent 0.1s, waited 10.8s, update 0.0s
|
||||
round 20: 28106/91899 lr×1.000 eta 254m | dbc 770 steps 7001 tok/s nll 1.9573 | evo 153 steps 1634 tok/s nll 1.8430 | dgx 465 steps 4255 tok/s nll 2.0058 | 307.0s, closed 7.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 20: 770 steps 7001 tok/s (7394 padded; contexts 4960 of 4975) nll 1.9573 gpu 94% free 81% | delta sent 0.1s, waited 6.6s, update 0.0s
|
||||
round 21: 29500/91899 lr×1.000 eta 247m | dbc 770 steps 7036 tok/s nll 2.0272 | evo 163 steps 1700 tok/s nll 1.8799 | dgx 461 steps 4255 tok/s nll 1.9244 | 306.8s, closed 6.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 21: 770 steps 7036 tok/s (7448 padded; contexts 4920 of 4942) nll 2.0272 gpu 94% free 80% | delta sent 0.1s, waited 6.2s, update 0.1s
|
||||
round 22: 30968/91899 lr×1.000 eta 240m | dbc 781 steps 6942 tok/s nll 2.0425 | evo 233 steps 2388 tok/s nll 2.1450 | dgx 454 steps 4322 tok/s nll 1.8150 | 307.4s, closed 7.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 22: 781 steps 6942 tok/s (7343 padded; contexts 4851 of 4866) nll 2.0425 gpu 94% free 80% | delta sent 0.1s, waited 7.2s, update 0.0s
|
||||
round 23: 32382/91899 lr×1.000 eta 233m | dbc 775 steps 6998 tok/s nll 1.9633 | evo 166 steps 1758 tok/s nll 1.8510 | dgx 473 steps 4227 tok/s nll 1.9930 | 306.8s, closed 6.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 23: 775 steps 6998 tok/s (7382 padded; contexts 5008 of 5020) nll 1.9633 gpu 94% free 80% | delta sent 0.1s, waited 6.2s, update 0.0s
|
||||
round 24: 33788/91899 lr×1.000 eta 227m | dbc 767 steps 7015 tok/s nll 2.0195 | evo 170 steps 1697 tok/s nll 1.9206 | dgx 469 steps 4258 tok/s nll 1.9033 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 24: 767 steps 7015 tok/s (7408 padded; contexts 4998 of 5015) nll 2.0195 gpu 94% free 81% | delta sent 0.1s, waited 6.2s, update 0.0s
|
||||
round 25: 35184/91899 lr×1.000 eta 221m | dbc 760 steps 6999 tok/s nll 1.9478 | evo 164 steps 1655 tok/s nll 1.9603 | dgx 472 steps 4287 tok/s nll 1.9854 | 308.5s, closed 8.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 25: 760 steps 6999 tok/s (7381 padded; contexts 5004 of 5017) nll 1.9478 gpu 94% free 81% | delta sent 0.1s, waited 7.9s, update 0.0s
|
||||
round 26: 36588/91899 lr×1.000 eta 215m | dbc 763 steps 6999 tok/s nll 1.9487 | evo 186 steps 1842 tok/s nll 2.0885 | dgx 455 steps 4275 tok/s nll 1.8583 | 308.8s, closed 8.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 26: 763 steps 6999 tok/s (7390 padded; contexts 4982 of 4995) nll 1.9487 gpu 93% free 81% | delta sent 0.1s, waited 8.6s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (126s); 11988 rows by the head (310s)
|
||||
val @36588: action 0.347/1.840 ag_news 0.797/0.597 arch 0.660/0.854 banking77 0.278/2.462 boolq 0.635/0.652 clinc150 0.195/2.821 code.affected.gold 0.515/0.694 code.failure.silver 0.211/1.585 code.file.gold 0.072/4.773 code.suspect.gold 0.000/4.947 code.symbol.gold 0.075/4.251 code.test.silver 0.058/3.680 control.commit.gold 0.190/0.726 control.context.gold 0.806/0.888 control.continue.gold 0.048/1.070 control.done.gold 0.727/0.674 control.repeat.gold 0.000/0.758 control.retry.gold 1.000/0.633 control.rollback.gold 0.429/0.779 control.strategy.gold 0.750/0.564 control.user.silver 1.000/0.190 done 0.983/0.412 email_spam 0.978/0.080 emotion 0.534/1.241 function 0.500/1.965 graph_typed 0.489/1.151 guardrails_jailbreak 0.338/0.920 massive 0.662/1.114 mnli 0.595/0.910 model_routing_domain 0.973/0.223 moderation_toxicity 0.498/0.722 nemotron 0.425/2.287 phishing 0.936/0.203 rag_relevance 0.470/0.698 readiness 0.505/1.101 resolve 0.598/0.698 rig 0.460/1.141 risk 0.087/0.998 skills.select.silver 0.000/7.263 sst5 0.338/1.549 support_triage 0.343/1.787 sysml 0.590/0.760 testplan 0.615/1.099 tool 0.090/2.461 trade 0.613/0.912 turbofan 0.600/0.985 typed_decisions 0.549/1.103 xnli 0.630/0.848
|
||||
saved /Users/a/scratch/decision/runs/a at 36588 batches, 0 epochs
|
||||
round 27: 37762/91899 lr×1.000 eta 215m | dbc 523 steps 4822 tok/s nll 1.9830 | evo 182 steps 1823 tok/s nll 1.9557 | dgx 469 steps 4248 tok/s nll 1.8960 | 438.4s, closed 138.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 27: 523 steps 4822 tok/s (5106 padded; contexts 3412 of 3420) nll 1.9830 gpu 96% free 78% | delta sent 0.1s, waited 137.4s, update 0.0s
|
||||
round 28: 39174/91899 lr×1.000 eta 208m | dbc 764 steps 6988 tok/s nll 1.9373 | evo 180 steps 1852 tok/s nll 2.0263 | dgx 468 steps 4224 tok/s nll 1.9012 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 28: 764 steps 6988 tok/s (7384 padded; contexts 4989 of 5003) nll 1.9373 gpu 95% free 81% | delta sent 0.1s, waited 6.0s, update 0.0s
|
||||
round 29: 40618/91899 lr×1.000 eta 202m | dbc 776 steps 7015 tok/s nll 1.9470 | evo 203 steps 2070 tok/s nll 2.0079 | dgx 465 steps 4189 tok/s nll 1.8603 | 306.9s, closed 6.9s past the deadline, outer step 0.0s
|
||||
worker 0 round 29: 776 steps 7015 tok/s (7417 padded; contexts 4982 of 5000) nll 1.9470 gpu 94% free 81% | delta sent 0.1s, waited 6.5s, update 0.0s
|
||||
round 30: 42050/91899 lr×1.000 eta 196m | dbc 775 steps 6918 tok/s nll 1.9608 | evo 208 steps 2144 tok/s nll 1.9339 | dgx 449 steps 4211 tok/s nll 1.7986 | 307.5s, closed 7.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 30: 775 steps 6918 tok/s (7319 padded; contexts 4823 of 4844) nll 1.9608 gpu 94% free 81% | delta sent 0.1s, waited 7.0s, update 0.0s
|
||||
round 31: 43452/91899 lr×1.000 eta 190m | dbc 764 steps 6969 tok/s nll 1.9717 | evo 179 steps 1803 tok/s nll 1.8632 | dgx 459 steps 4301 tok/s nll 1.8471 | 307.4s, closed 7.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 31: 764 steps 6969 tok/s (7361 padded; contexts 4969 of 4983) nll 1.9717 gpu 94% free 81% | delta sent 0.1s, waited 6.9s, update 0.0s
|
||||
round 32: 44854/91899 lr×1.000 eta 184m | dbc 764 steps 7002 tok/s nll 1.9681 | evo 171 steps 1660 tok/s nll 1.8920 | dgx 467 steps 4326 tok/s nll 1.8949 | 307.6s, closed 7.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 32: 764 steps 7002 tok/s (7388 padded; contexts 4987 of 4999) nll 1.9681 gpu 94% free 81% | delta sent 0.1s, waited 7.4s, update 0.0s
|
||||
round 33: 46268/91899 lr×1.000 eta 178m | dbc 763 steps 7036 tok/s nll 1.8776 | evo 177 steps 1822 tok/s nll 1.8478 | dgx 474 steps 4284 tok/s nll 1.9790 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 33: 763 steps 7036 tok/s (7407 padded; contexts 5100 of 5114) nll 1.8776 gpu 94% free 81% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 34: 47668/91899 lr×1.000 eta 172m | dbc 762 steps 6983 tok/s nll 1.9534 | evo 176 steps 1768 tok/s nll 1.9451 | dgx 462 steps 4260 tok/s nll 1.8600 | 307.3s, closed 7.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 34: 762 steps 6983 tok/s (7377 padded; contexts 4959 of 4973) nll 1.9534 gpu 94% free 80% | delta sent 0.1s, waited 6.8s, update 0.0s
|
||||
round 35: 49071/91899 lr×1.000 eta 166m | dbc 767 steps 6970 tok/s nll 1.9479 | evo 180 steps 1781 tok/s nll 2.0437 | dgx 456 steps 4276 tok/s nll 1.8649 | 309.7s, closed 9.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 35: 767 steps 6970 tok/s (7350 padded; contexts 4946 of 4959) nll 1.9479 gpu 93% free 81% | delta sent 0.1s, waited 9.5s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (128s); 11988 rows by the head (309s)
|
||||
val @49071: action 0.155/1.856 ag_news 0.830/0.498 arch 0.667/0.834 banking77 0.287/2.348 boolq 0.640/0.649 clinc150 0.290/2.587 code.affected.gold 0.517/0.693 code.failure.silver 0.211/1.811 code.file.gold 0.068/4.483 code.suspect.gold 0.000/5.061 code.symbol.gold 0.089/4.279 code.test.silver 0.052/3.739 control.commit.gold 0.476/0.687 control.context.gold 0.806/0.798 control.continue.gold 0.048/0.797 control.done.gold 0.909/0.677 control.repeat.gold 1.000/0.544 control.retry.gold 0.000/0.737 control.rollback.gold 0.429/0.727 control.strategy.gold 0.750/0.544 control.user.silver 0.875/0.370 done 0.983/0.470 email_spam 0.990/0.053 emotion 0.583/1.168 function 0.507/1.731 graph_typed 0.533/1.159 guardrails_jailbreak 0.965/0.117 massive 0.670/1.045 mnli 0.608/0.872 model_routing_domain 0.980/0.108 moderation_toxicity 0.798/0.381 nemotron 0.383/2.265 phishing 0.964/0.109 rag_relevance 0.482/0.696 readiness 0.460/1.104 resolve 0.978/0.628 rig 0.477/1.224 risk 0.990/0.748 skills.select.silver 0.000/7.279 sst5 0.157/1.586 support_triage 0.323/1.795 sysml 0.608/0.724 testplan 0.625/0.970 tool 0.090/2.480 trade 0.588/0.893 turbofan 0.482/1.073 typed_decisions 0.531/1.140 xnli 0.625/0.869
|
||||
saved /Users/a/scratch/decision/runs/a at 49071 batches, 0 epochs
|
||||
round 36: 50230/91899 lr×1.000 eta 164m | dbc 530 steps 4809 tok/s nll 1.9690 | evo 172 steps 1798 tok/s nll 1.7815 | dgx 457 steps 4273 tok/s nll 1.9114 | 439.5s, closed 139.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 36: 530 steps 4809 tok/s (5067 padded; contexts 3456 of 3466) nll 1.9690 gpu 95% free 78% | delta sent 0.1s, waited 138.3s, update 0.0s
|
||||
round 37: 51624/91899 lr×1.000 eta 158m | dbc 760 steps 6989 tok/s nll 1.9141 | evo 173 steps 1776 tok/s nll 1.8844 | dgx 461 steps 4276 tok/s nll 1.7900 | 306.8s, closed 6.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 37: 760 steps 6989 tok/s (7398 padded; contexts 4966 of 4986) nll 1.9141 gpu 94% free 80% | delta sent 0.1s, waited 6.5s, update 0.0s
|
||||
round 38: 53023/91899 lr×1.000 eta 153m | dbc 751 steps 6946 tok/s nll 1.8727 | evo 174 steps 1798 tok/s nll 1.9717 | dgx 474 steps 4331 tok/s nll 1.9226 | 308.2s, closed 8.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 38: 751 steps 6946 tok/s (7326 padded; contexts 5035 of 5056) nll 1.8727 gpu 94% free 81% | delta sent 0.1s, waited 7.9s, update 0.0s
|
||||
round 39: 54426/91899 lr×1.000 eta 147m | dbc 761 steps 6931 tok/s nll 1.9512 | evo 175 steps 1812 tok/s nll 1.9429 | dgx 467 steps 4337 tok/s nll 1.8056 | 307.6s, closed 7.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 39: 761 steps 6931 tok/s (7329 padded; contexts 4892 of 4905) nll 1.9512 gpu 94% free 79% | delta sent 0.1s, waited 7.1s, update 0.0s
|
||||
round 40: 55833/91899 lr×1.000 eta 141m | dbc 752 steps 7064 tok/s nll 1.8408 | evo 188 steps 1881 tok/s nll 1.9521 | dgx 467 steps 4239 tok/s nll 1.9816 | 308.2s, closed 8.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 40: 752 steps 7064 tok/s (7439 padded; contexts 5150 of 5170) nll 1.8408 gpu 94% free 79% | delta sent 0.1s, waited 7.9s, update 0.0s
|
||||
round 41: 57230/91899 lr×1.000 eta 135m | dbc 762 steps 7023 tok/s nll 1.8894 | evo 171 steps 1731 tok/s nll 1.8562 | dgx 464 steps 4201 tok/s nll 1.8681 | 308.6s, closed 8.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 41: 762 steps 7023 tok/s (7430 padded; contexts 4952 of 4966) nll 1.8894 gpu 93% free 79% | delta sent 0.1s, waited 8.4s, update 0.0s
|
||||
round 42: 58640/91899 lr×1.000 eta 130m | dbc 768 steps 6985 tok/s nll 1.8982 | evo 186 steps 1876 tok/s nll 1.8580 | dgx 456 steps 4290 tok/s nll 1.9110 | 307.1s, closed 7.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 42: 768 steps 6985 tok/s (7367 padded; contexts 4998 of 5011) nll 1.8982 gpu 94% free 79% | delta sent 0.1s, waited 6.8s, update 0.0s
|
||||
round 43: 60056/91899 lr×1.000 eta 124m | dbc 771 steps 6967 tok/s nll 1.8767 | evo 185 steps 1913 tok/s nll 1.9525 | dgx 460 steps 4342 tok/s nll 1.8119 | 306.3s, closed 6.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 43: 771 steps 6967 tok/s (7371 padded; contexts 4936 of 4955) nll 1.8767 gpu 94% free 79% | delta sent 0.1s, waited 5.7s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (134s); 11988 rows by the head (315s)
|
||||
val @60056: action 0.343/1.768 ag_news 0.843/0.528 arch 0.670/0.865 banking77 0.349/2.307 boolq 0.586/0.663 clinc150 0.287/2.584 code.affected.gold 0.595/0.691 code.failure.silver 0.158/1.815 code.file.gold 0.068/4.322 code.suspect.gold 0.000/4.895 code.symbol.gold 0.100/4.268 code.test.silver 0.060/3.622 control.commit.gold 0.810/0.514 control.context.gold 0.806/0.879 control.continue.gold 0.952/0.594 control.done.gold 0.909/0.479 control.repeat.gold 1.000/0.613 control.retry.gold 1.000/0.633 control.rollback.gold 0.429/0.697 control.strategy.gold 0.750/0.601 control.user.silver 0.875/0.378 done 0.983/0.328 email_spam 0.985/0.060 emotion 0.589/1.131 function 0.520/1.848 graph_typed 0.496/1.138 guardrails_jailbreak 0.983/0.070 massive 0.665/1.030 mnli 0.580/0.921 model_routing_domain 0.963/0.169 moderation_toxicity 0.861/0.255 nemotron 0.357/2.492 phishing 0.967/0.110 rag_relevance 0.527/0.691 readiness 0.485/1.138 resolve 0.095/0.731 rig 0.448/1.082 risk 0.000/1.598 skills.select.silver 0.000/7.173 sst5 0.338/1.568 support_triage 0.365/1.737 sysml 0.608/0.772 testplan 0.615/1.010 tool 0.110/2.411 trade 0.625/0.832 turbofan 0.480/0.993 typed_decisions 0.577/1.065 xnli 0.613/0.883
|
||||
saved /Users/a/scratch/decision/runs/a at 60056 batches, 0 epochs
|
||||
round 44: 61213/91899 lr×1.000 eta 121m | dbc 510 steps 4683 tok/s nll 1.8679 | evo 170 steps 1807 tok/s nll 1.8042 | dgx 477 steps 4243 tok/s nll 1.8845 | 450.8s, closed 150.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 44: 510 steps 4683 tok/s (4953 padded; contexts 3353 of 3364) nll 1.8679 gpu 95% free 79% | delta sent 0.1s, waited 149.5s, update 0.0s
|
||||
round 45: 62661/91899 lr×1.000 eta 115m | dbc 757 steps 7054 tok/s nll 1.8645 | evo 226 steps 2325 tok/s nll 1.9378 | dgx 465 steps 4226 tok/s nll 1.9118 | 309.2s, closed 9.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 45: 757 steps 7054 tok/s (7434 padded; contexts 5110 of 5131) nll 1.8645 gpu 93% free 78% | delta sent 0.1s, waited 8.8s, update 0.0s
|
||||
round 46: 64066/91899 lr×1.000 eta 109m | dbc 760 steps 6961 tok/s nll 1.8746 | evo 175 steps 1791 tok/s nll 1.8443 | dgx 470 steps 4223 tok/s nll 1.9061 | 306.6s, closed 6.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 46: 760 steps 6961 tok/s (7353 padded; contexts 4993 of 5004) nll 1.8746 gpu 94% free 78% | delta sent 0.1s, waited 6.2s, update 0.0s
|
||||
round 47: 65461/91899 lr×1.000 eta 104m | dbc 755 steps 6979 tok/s nll 1.9022 | evo 175 steps 1757 tok/s nll 1.8694 | dgx 465 steps 4306 tok/s nll 1.8275 | 307.7s, closed 7.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 47: 755 steps 6979 tok/s (7344 padded; contexts 5033 of 5046) nll 1.9022 gpu 94% free 78% | delta sent 0.1s, waited 7.2s, update 0.0s
|
||||
round 48: 66871/91899 lr×1.000 eta 98m | dbc 769 steps 6971 tok/s nll 1.8257 | evo 177 steps 1818 tok/s nll 1.9504 | dgx 464 steps 4206 tok/s nll 1.9381 | 308.0s, closed 8.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 48: 769 steps 6971 tok/s (7344 padded; contexts 5046 of 5059) nll 1.8257 gpu 93% free 79% | delta sent 0.1s, waited 7.8s, update 0.0s
|
||||
round 49: 68292/91899 lr×1.000 eta 92m | dbc 765 steps 6934 tok/s nll 1.9405 | evo 198 steps 1975 tok/s nll 1.9024 | dgx 458 steps 4245 tok/s nll 1.7913 | 308.0s, closed 8.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 49: 765 steps 6934 tok/s (7320 padded; contexts 4916 of 4930) nll 1.9405 gpu 94% free 78% | delta sent 0.1s, waited 7.7s, update 0.0s
|
||||
round 50: 69678/91899 lr×1.000 eta 87m | dbc 751 steps 7022 tok/s nll 1.8914 | evo 162 steps 1729 tok/s nll 1.8672 | dgx 473 steps 4281 tok/s nll 1.8392 | 307.8s, closed 7.8s past the deadline, outer step 0.1s
|
||||
worker 0 round 50: 751 steps 7022 tok/s (7391 padded; contexts 5086 of 5097) nll 1.8914 gpu 94% free 79% | delta sent 0.1s, waited 7.1s, update 0.0s
|
||||
round 51: 71063/91899 lr×1.000 eta 81m | dbc 759 steps 6902 tok/s nll 1.9383 | evo 171 steps 1780 tok/s nll 1.7479 | dgx 455 steps 4301 tok/s nll 1.8480 | 308.3s, closed 8.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 51: 759 steps 6902 tok/s (7304 padded; contexts 4873 of 4889) nll 1.9383 gpu 93% free 77% | delta sent 0.1s, waited 8.0s, update 0.0s
|
||||
round 52: 72490/91899 lr×1.000 eta 76m | dbc 757 steps 6957 tok/s nll 1.8796 | evo 204 steps 2093 tok/s nll 1.7970 | dgx 466 steps 4235 tok/s nll 1.8202 | 307.4s, closed 7.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 52: 757 steps 6957 tok/s (7354 padded; contexts 4955 of 4976) nll 1.8796 gpu 94% free 77% | delta sent 0.1s, waited 6.9s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (132s); 11988 rows by the head (314s)
|
||||
val @72490: action 0.365/1.725 ag_news 0.850/0.461 arch 0.670/0.830 banking77 0.378/2.175 boolq 0.553/0.685 clinc150 0.372/2.234 code.affected.gold 0.527/0.692 code.failure.silver 0.263/1.605 code.file.gold 0.065/4.273 code.suspect.gold 0.048/5.080 code.symbol.gold 0.057/4.378 code.test.silver 0.055/3.744 control.commit.gold 0.476/0.680 control.context.gold 0.806/0.826 control.continue.gold 0.048/1.012 control.done.gold 0.727/0.666 control.repeat.gold 1.000/0.320 control.retry.gold 0.000/0.826 control.rollback.gold 0.571/0.676 control.strategy.gold 0.750/0.756 control.user.silver 0.875/0.351 done 0.983/0.242 email_spam 0.983/0.074 emotion 0.609/0.968 function 0.535/1.697 graph_typed 0.541/1.115 guardrails_jailbreak 0.819/0.543 massive 0.680/0.947 mnli 0.603/0.936 model_routing_domain 0.983/0.067 moderation_toxicity 0.721/0.527 nemotron 0.378/2.302 phishing 0.969/0.155 rag_relevance 0.505/0.702 readiness 0.443/1.141 resolve 0.058/0.741 rig 0.450/1.079 risk 0.000/1.287 skills.select.silver 0.000/7.238 sst5 0.108/1.695 support_triage 0.378/1.784 sysml 0.608/0.769 testplan 0.608/0.954 tool 0.090/2.467 trade 0.618/0.808 turbofan 0.482/1.122 typed_decisions 0.566/1.061 xnli 0.603/0.935
|
||||
saved /Users/a/scratch/decision/runs/a at 72490 batches, 0 epochs
|
||||
round 53: 73655/91899 lr×0.993 eta 72m | dbc 513 steps 4620 tok/s nll 1.7949 | evo 178 steps 1818 tok/s nll 1.8447 | dgx 474 steps 4307 tok/s nll 1.9372 | 449.1s, closed 149.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 53: 513 steps 4620 tok/s (4867 padded; contexts 3313 of 3322) nll 1.7949 gpu 96% free 74% | delta sent 0.1s, waited 147.8s, update 0.0s
|
||||
round 54: 75059/91899 lr×0.925 eta 66m | dbc 764 steps 6983 tok/s nll 1.7793 | evo 172 steps 1752 tok/s nll 1.8849 | dgx 468 steps 4298 tok/s nll 1.9137 | 306.9s, closed 6.9s past the deadline, outer step 0.0s
|
||||
worker 0 round 54: 764 steps 6983 tok/s (7361 padded; contexts 5069 of 5083) nll 1.7793 gpu 94% free 75% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 55: 76465/91899 lr×0.856 eta 61m | dbc 760 steps 6932 tok/s nll 1.9055 | evo 185 steps 1895 tok/s nll 1.8846 | dgx 461 steps 4187 tok/s nll 1.8433 | 308.5s, closed 8.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 55: 760 steps 6932 tok/s (7319 padded; contexts 4926 of 4938) nll 1.9055 gpu 94% free 76% | delta sent 0.1s, waited 7.8s, update 0.0s
|
||||
round 56: 77860/91899 lr×0.787 eta 55m | dbc 755 steps 6982 tok/s nll 1.8324 | evo 177 steps 1783 tok/s nll 1.7851 | dgx 463 steps 4209 tok/s nll 1.8979 | 306.8s, closed 6.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 56: 755 steps 6982 tok/s (7375 padded; contexts 5030 of 5048) nll 1.8324 gpu 94% free 76% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 57: 79251/91899 lr×0.719 eta 50m | dbc 759 steps 6930 tok/s nll 1.8809 | evo 166 steps 1773 tok/s nll 1.6993 | dgx 466 steps 4239 tok/s nll 1.8204 | 308.4s, closed 8.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 57: 759 steps 6930 tok/s (7329 padded; contexts 4885 of 4901) nll 1.8809 gpu 94% free 76% | delta sent 0.1s, waited 8.0s, update 0.0s
|
||||
round 58: 80656/91899 lr×0.651 eta 44m | dbc 759 steps 6976 tok/s nll 1.8246 | evo 175 steps 1820 tok/s nll 1.8052 | dgx 471 steps 4299 tok/s nll 1.8980 | 308.0s, closed 8.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 58: 759 steps 6976 tok/s (7371 padded; contexts 4984 of 5004) nll 1.8246 gpu 94% free 76% | delta sent 0.1s, waited 7.5s, update 0.0s
|
||||
round 59: 82055/91899 lr×0.582 eta 38m | dbc 763 steps 6980 tok/s nll 1.8025 | evo 173 steps 1787 tok/s nll 1.8192 | dgx 463 steps 4214 tok/s nll 1.8865 | 308.7s, closed 8.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 59: 763 steps 6980 tok/s (7375 padded; contexts 4971 of 4998) nll 1.8025 gpu 91% free 76% | delta sent 0.1s, waited 8.2s, update 0.0s
|
||||
cluster: 10.0.0.19:34202: failed to fill whole buffer
|
||||
cluster: dgx left; requeued 413 batches
|
||||
round 60: 82998/91899 lr×0.536 eta 35m | dbc 765 steps 6906 tok/s nll 1.7999 | evo 178 steps 1804 tok/s nll 1.8352 | 306.7s, closed 6.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 60: 765 steps 6906 tok/s (7281 padded; contexts 4953 of 4967) nll 1.7999 gpu 94% free 76% | delta sent 0.1s, waited 6.1s, update 0.0s
|
||||
round 61: 83939/91899 lr×0.490 eta 31m | dbc 755 steps 6949 tok/s nll 1.7942 | evo 186 steps 1831 tok/s nll 2.0111 | 306.7s, closed 6.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 61: 755 steps 6949 tok/s (7337 padded; contexts 4993 of 5013) nll 1.7942 gpu 95% free 76% | delta sent 0.1s, waited 6.3s, update 0.0s
|
||||
round 62: 84900/91899 lr×0.443 eta 28m | dbc 760 steps 6941 tok/s nll 1.8332 | evo 201 steps 2116 tok/s nll 1.7729 | 306.1s, closed 6.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 62: 760 steps 6941 tok/s (7335 padded; contexts 4966 of 4985) nll 1.8332 gpu 95% free 76% | delta sent 0.1s, waited 5.9s, update 0.0s, state kept
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (128s); 11988 rows by the head (310s)
|
||||
val @84900: action 0.372/1.717 ag_news 0.860/0.482 arch 0.672/0.896 banking77 0.474/1.997 boolq 0.629/0.653 clinc150 0.400/2.152 code.affected.gold 0.530/0.694 code.failure.silver 0.263/1.671 code.file.gold 0.077/4.222 code.suspect.gold 0.000/4.972 code.symbol.gold 0.100/4.308 code.test.silver 0.040/3.641 control.commit.gold 0.190/0.739 control.context.gold 0.806/0.876 control.continue.gold 0.952/0.427 control.done.gold 0.545/0.666 control.repeat.gold 1.000/0.461 control.retry.gold 0.000/0.826 control.rollback.gold 0.286/0.713 control.strategy.gold 0.750/0.597 control.user.silver 0.875/0.352 done 0.983/0.340 email_spam 0.983/0.056 emotion 0.662/0.945 function 0.552/1.690 graph_typed 0.467/1.147 guardrails_jailbreak 0.972/0.135 massive 0.713/0.931 mnli 0.583/0.924 model_routing_domain 0.975/0.092 moderation_toxicity 0.686/0.592 nemotron 0.403/2.230 phishing 0.916/0.308 rag_relevance 0.525/0.696 readiness 0.443/1.101 resolve 0.875/0.451 rig 0.460/1.083 risk 0.010/1.952 skills.select.silver 0.000/7.193 sst5 0.338/1.529 support_triage 0.388/1.754 sysml 0.610/0.704 testplan 0.615/0.978 tool 0.250/2.419 trade 0.585/0.809 turbofan 0.505/1.031 typed_decisions 0.509/1.109 xnli 0.590/0.916
|
||||
saved /Users/a/scratch/decision/runs/a at 84900 batches, 0 epochs
|
||||
round 63: 85586/91899 lr×0.409 eta 25m | dbc 527 steps 4760 tok/s nll 1.8416 | evo 159 steps 1659 tok/s nll 1.7111 | 441.0s, closed 141.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 63: 527 steps 4760 tok/s (5019 padded; contexts 3359 of 3367) nll 1.8416 gpu 94% free 74% | delta sent 0.1s, waited 140.2s, update 0.0s
|
||||
round 64: 86519/91899 lr×0.363 eta 22m | dbc 764 steps 6975 tok/s nll 1.8543 | evo 169 steps 1759 tok/s nll 1.7564 | 305.8s, closed 5.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 64: 764 steps 6975 tok/s (7367 padded; contexts 4945 of 4961) nll 1.8543 gpu 94% free 76% | delta sent 0.1s, waited 5.6s, update 0.1s
|
||||
round 65: 87452/91899 lr×0.318 eta 18m | dbc 762 steps 6969 tok/s nll 1.8492 | evo 171 steps 1729 tok/s nll 1.7558 | 306.2s, closed 6.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 65: 762 steps 6969 tok/s (7383 padded; contexts 4900 of 4914) nll 1.8492 gpu 95% free 76% | delta sent 0.1s, waited 5.5s, update 0.0s
|
||||
round 66: 88422/91899 lr×0.270 eta 14m | dbc 760 steps 6976 tok/s nll 1.7711 | evo 210 steps 2152 tok/s nll 1.8092 | 307.7s, closed 7.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 66: 760 steps 6976 tok/s (7361 padded; contexts 4995 of 5014) nll 1.7711 gpu 94% free 76% | delta sent 0.1s, waited 7.2s, update 0.0s
|
||||
round 67: 89386/91899 lr×0.223 eta 10m | dbc 756 steps 6942 tok/s nll 1.8216 | evo 208 steps 2074 tok/s nll 1.8693 | 305.1s, closed 5.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 67: 756 steps 6942 tok/s (7315 padded; contexts 5024 of 5042) nll 1.8216 gpu 95% free 74% | delta sent 0.1s, waited 4.9s, update 0.0s
|
||||
round 68: 90357/91899 lr×0.176 eta 6m | dbc 767 steps 6960 tok/s nll 1.8043 | evo 204 steps 2107 tok/s nll 1.9691 | 305.6s, closed 5.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 68: 767 steps 6960 tok/s (7341 padded; contexts 4997 of 5016) nll 1.8043 gpu 94% free 72% | delta sent 0.1s, waited 5.2s, update 0.0s
|
||||
round 69: 91302/91899 lr×0.129 eta 2m | dbc 762 steps 6984 tok/s nll 1.8011 | evo 183 steps 1815 tok/s nll 1.8966 | 306.1s, closed 6.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 69: 762 steps 6984 tok/s (7366 padded; contexts 5028 of 5042) nll 1.8011 gpu 94% free 72% | delta sent 0.1s, waited 5.7s, update 0.0s
|
||||
round 70: 91899/91899 lr×0.100 eta 0m | dbc 462 steps 7000 tok/s nll 1.7741 | evo 135 steps 2290 tok/s nll 1.9573 | 188.9s, closed 0.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 70: 462 steps 7000 tok/s (7376 padded; contexts 5052 of 5063) nll 1.7741 gpu 93% free 72% | delta sent 0.1s, waited 5.6s; done
|
||||
val: 1466 wide rows over 394180 options, each answered over all of them, retrieval's top 32 by the head (78s); 11988 rows by the head (240s)
|
||||
val @91899: action 0.338/1.759 ag_news 0.845/0.459 arch 0.672/0.839 banking77 0.429/2.041 boolq 0.629/0.666 clinc150 0.410/2.097 code.affected.gold 0.535/0.693 code.failure.silver 0.158/1.697 code.file.gold 0.070/4.388 code.suspect.gold 0.000/5.024 code.symbol.gold 0.093/4.276 code.test.silver 0.040/3.649 control.commit.gold 0.381/0.680 control.context.gold 0.806/0.738 control.continue.gold 0.952/0.386 control.done.gold 0.091/0.729 control.repeat.gold 1.000/0.568 control.retry.gold 0.000/0.826 control.rollback.gold 0.571/0.694 control.strategy.gold 0.750/0.621 control.user.silver 0.875/0.358 done 0.979/0.341 email_spam 0.983/0.051 emotion 0.679/0.917 function 0.573/1.555 graph_typed 0.533/1.135 guardrails_jailbreak 0.707/0.511 massive 0.730/0.882 mnli 0.593/0.898 model_routing_domain 0.988/0.038 moderation_toxicity 0.909/0.236 nemotron 0.400/2.220 phishing 0.944/0.250 rag_relevance 0.502/0.697 readiness 0.453/1.098 resolve 0.907/0.504 rig 0.460/1.130 risk 0.000/2.501 skills.select.silver 0.000/7.131 sst5 0.216/1.550 support_triage 0.362/1.765 sysml 0.608/0.713 testplan 0.608/0.951 tool 0.090/2.403 trade 0.615/0.798 turbofan 0.512/1.015 typed_decisions 0.520/1.104 xnli 0.630/0.907
|
||||
saved /Users/a/scratch/decision/runs/a at 91899 batches, 1 epochs
|
||||
@@ -1,31 +0,0 @@
|
||||
corpus: 3686494 train rows, 139612 val rows, suites ["ag_news", "emotion", "banking77", "support_triage", "email_spam", "phishing", "guardrails_jailbreak", "moderation_toxicity", "rag_relevance", "model_routing_domain", "typed_decisions", "massive", "tool", "risk", "done", "repo", "function", "resolve", "action", "nemotron", "clinc150", "xnli", "sst5", "shuffle", "alias", "near", "subset", "swap", "codeswitch", "boolq", "mnli", "code.file.gold", "code.affected.gold", "code.symbol.gold", "code.suspect.gold", "code.test.silver", "control.context.gold", "control.user.gold", "control.continue.gold", "control.commit.gold", "control.rollback.gold", "control.strategy.gold", "control.repeat.gold", "control.done.gold", "control.retry.gold", "control.user.silver", "code.failure.gold", "code.failure.silver", "skills.select.silver", "graph_typed", "turbofan", "rig", "sysml", "readiness", "trade", "testplan", "arch"] (62s)
|
||||
init: 187 tensors carried, fresh: ["retrieval.key.center", "retrieval.query.center"]
|
||||
plan: stage a2, 1 epochs, 32801 batches, 984 warmup, 9840 cooldown; rows on a sample of their options, by epoch: [10220]
|
||||
cluster: coordinating on 0.0.0.0:7070
|
||||
cluster: dbc (127.0.0.1:57605) joins round 0 as worker 0 (Metal { gpu_id: 4294968649 }, BF16)
|
||||
worker 0 (dbc): joined round 0
|
||||
cluster: evo (10.0.0.57:3292) joins round 0 as worker 1 (Rocm { gpu_id: 0 }, BF16)
|
||||
worker 0 round 0: 766 steps 5872 tok/s (6449 padded; contexts 2771 of 2783) nll 2.6453 ret 1.8067 gpu 92% free 80% | delta sent 0.1s, waited 10.0s, update 0.0s
|
||||
round 0: 809/32801 lr×0.823 eta 222m | dbc 766 steps 5872 tok/s nll 2.6453 ret 1.8067 | evo 43 steps 1140 tok/s nll 1.9829 ret 1.1796 | ret 1.7685, recall@32 0.078 (code.file.gold 0.750, code.suspect.gold 0.000, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.040) (6.5s) | 310.4s, closed 10.4s past the deadline, outer step 0.1s
|
||||
worker 0 round 1: 780 steps 5824 tok/s (6400 padded; contexts 2882 of 2904) nll 2.5649 ret 1.7482 gpu 94% free 80% | delta sent 0.1s, waited 5.4s, update 0.0s
|
||||
round 1: 1815/32801 lr×1.000 eta 183m | dbc 780 steps 5824 tok/s nll 2.5649 ret 1.7482 | evo 226 steps 2048 tok/s nll 2.5012 ret 1.8045 | ret 1.7590, recall@32 0.047 (code.file.gold 0.250, code.suspect.gold 0.000, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.040) (6.8s) | 306.0s, closed 6.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 2: 775 steps 5911 tok/s (6477 padded; contexts 2891 of 2914) nll 2.5782 ret 1.6768 gpu 94% free 80% | delta sent 0.1s, waited 4.7s, update 0.0s
|
||||
round 2: 2793/32801 lr×1.000 eta 170m | dbc 775 steps 5911 tok/s nll 2.5782 ret 1.6768 | evo 203 steps 1844 tok/s nll 2.5816 ret 1.8302 | ret 1.7100, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.020) (6.4s) | 305.2s, closed 5.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 756 steps 5811 tok/s (6374 padded; contexts 2851 of 2868) nll 2.6168 ret 1.6745 gpu 91% free 80% | delta sent 0.1s, waited 15.4s, update 0.0s
|
||||
round 3: 3760/32801 lr×1.000 eta 163m | dbc 756 steps 5811 tok/s nll 2.6168 ret 1.6745 | evo 211 steps 1976 tok/s nll 2.4401 ret 1.7131 | ret 1.6845, recall@32 0.047 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.020) (6.7s) | 315.7s, closed 15.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 757 steps 5911 tok/s (6500 padded; contexts 2870 of 2888) nll 2.5739 ret 1.6241 gpu 93% free 81% | delta sent 0.1s, waited 5.3s, update 0.0s
|
||||
round 4: 4724/32801 lr×1.000 eta 155m | dbc 757 steps 5911 tok/s nll 2.5739 ret 1.6241 | evo 207 steps 1903 tok/s nll 2.5638 ret 1.6050 | ret 1.6202, recall@32 0.078 (code.file.gold 0.000, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.080) (6.5s) | 305.5s, closed 5.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 773 steps 5967 tok/s (6536 padded; contexts 3020 of 3039) nll 2.4620 ret 1.5786 gpu 94% free 81% | delta sent 0.1s, waited 5.1s, update 0.0s
|
||||
round 5: 5689/32801 lr×1.000 eta 149m | dbc 773 steps 5967 tok/s nll 2.4620 ret 1.5786 | evo 192 steps 1716 tok/s nll 2.6544 ret 1.6208 | ret 1.5889, recall@32 0.078 (code.file.gold 0.500, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.020) (6.3s) | 305.3s, closed 5.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 762 steps 5956 tok/s (6507 padded; contexts 2991 of 3007) nll 2.5758 ret 1.5476 gpu 93% free 81% | delta sent 0.1s, waited 4.9s, update 0.0s
|
||||
round 6: 6648/32801 lr×1.000 eta 143m | dbc 762 steps 5956 tok/s nll 2.5758 ret 1.5476 | evo 197 steps 1715 tok/s nll 2.7762 ret 1.7974 | ret 1.5967, recall@32 0.078 (code.file.gold 0.500, code.suspect.gold 1.000, code.symbol.gold 0.250, code.test.silver 0.000, skills.select.silver 0.000) (6.3s) | 305.1s, closed 5.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 780 steps 5801 tok/s (6364 padded; contexts 2862 of 2886) nll 2.5884 ret 1.6188 gpu 93% free 81% | delta sent 0.1s, waited 4.9s, update 0.0s
|
||||
round 7: 7618/32801 lr×1.000 eta 137m | dbc 780 steps 5801 tok/s nll 2.5884 ret 1.6188 | evo 190 steps 1747 tok/s nll 2.6648 ret 1.5457 | ret 1.6013, recall@32 0.047 (code.file.gold 0.500, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.000) (6.5s) | 305.1s, closed 5.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 773 steps 5912 tok/s (6481 padded; contexts 2869 of 2886) nll 2.6126 ret 1.5523 gpu 94% free 80% | delta sent 0.1s, waited 4.8s, update 0.0s
|
||||
round 8: 8579/32801 lr×1.000 eta 131m | dbc 773 steps 5912 tok/s nll 2.6126 ret 1.5523 | evo 188 steps 1734 tok/s nll 2.5469 ret 1.5640 | ret 1.5547, recall@32 0.062 (code.file.gold 0.500, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.020) (6.6s) | 305.1s, closed 5.1s past the deadline, outer step 0.1s
|
||||
worker 0 round 9: 763 steps 5796 tok/s (6346 padded; contexts 2834 of 2849) nll 2.5516 ret 1.4962 gpu 93% free 80% | delta sent 0.1s, waited 6.5s, update 0.1s
|
||||
round 9: 9527/32801 lr×1.000 eta 126m | dbc 763 steps 5796 tok/s nll 2.5516 ret 1.4962 | evo 185 steps 1659 tok/s nll 2.7267 ret 1.5438 | ret 1.5043, recall@32 0.094 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.080) (6.3s) | 306.8s, closed 6.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 10: 768 steps 5909 tok/s (6443 padded; contexts 2942 of 2958) nll 2.6012 ret 1.4786 gpu 92% free 80% | delta sent 0.1s, waited 5.6s, update 0.0s
|
||||
round 10: 10490/32801 lr×1.000 eta 121m | dbc 768 steps 5909 tok/s nll 2.6012 ret 1.4786 | evo 195 steps 1798 tok/s nll 2.7726 ret 1.6269 | ret 1.5082, recall@32 0.047 (code.file.gold 0.250, code.suspect.gold 0.000, code.symbol.gold 0.250, code.test.silver 0.000, skills.select.silver 0.020) (6.6s) | 306.0s, closed 6.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 11: 752 steps 5763 tok/s (6348 padded; contexts 2841 of 2860) nll 2.6669 ret 1.5628 gpu 94% free 80% | delta sent 0.1s, waited 4.9s, update 0.0s
|
||||
round 11: 11427/32801 lr×1.000 eta 116m | dbc 752 steps 5763 tok/s nll 2.6669 ret 1.5628 | evo 185 steps 1728 tok/s nll 2.5053 ret 1.4501 | ret 1.5372, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 0.000, code.symbol.gold 0.000, code.test.silver 0.500, skills.select.silver 0.020) (6.7s) | 305.3s, closed 5.3s past the deadline, outer step 0.0s
|
||||
@@ -1,48 +0,0 @@
|
||||
corpus: 3691398 train rows, 139807 val rows, suites ["ag_news", "emotion", "banking77", "support_triage", "email_spam", "phishing", "guardrails_jailbreak", "moderation_toxicity", "rag_relevance", "model_routing_domain", "typed_decisions", "massive", "tool", "risk", "done", "repo", "function", "resolve", "action", "nemotron", "clinc150", "xnli", "sst5", "shuffle", "alias", "near", "subset", "swap", "codeswitch", "boolq", "mnli", "code.file.gold", "code.affected.gold", "code.symbol.gold", "code.suspect.gold", "code.test.silver", "control.context.gold", "control.user.gold", "control.continue.gold", "control.commit.gold", "control.rollback.gold", "control.strategy.gold", "control.repeat.gold", "control.done.gold", "control.retry.gold", "control.user.silver", "code.failure.gold", "code.failure.silver", "skills.select.silver", "graph_typed", "turbofan", "rig", "sysml", "readiness", "trade", "testplan", "arch"] (63s)
|
||||
init: 187 tensors carried, fresh: ["ordinal.location.center", "retrieval.key.center", "retrieval.query.center"]
|
||||
plan: stage a3, 2 epochs, 32681 batches, 980 warmup, 9804 cooldown; rows on a sample of their options, by epoch: [623, 654]
|
||||
cluster: coordinating on 0.0.0.0:7070
|
||||
cluster: dbc (127.0.0.1:60409) joins round 0 as worker 0 (Metal { gpu_id: 4294968649 }, BF16)
|
||||
worker 0 (dbc): joined round 0
|
||||
cluster: evo (10.0.0.57:15458) joins round 0 as worker 1 (Rocm { gpu_id: 0 }, BF16)
|
||||
worker 0 round 0: 830 steps 6717 tok/s (7058 padded; contexts 5183 of 5225) nll 1.2814 ret 1.3340 gpu 93% free 81% | delta sent 0.1s, waited 7.6s, update 0.0s
|
||||
round 0: 926/32681 lr×0.946 eta 190m | dbc 830 steps 6717 tok/s nll 1.2814 ret 1.3340 | evo 96 steps 2577 tok/s nll 1.3115 ret 1.2605 | ret 1.3254, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (7.4s) | 307.8s, closed 7.8s past the deadline, outer step 0.1s
|
||||
worker 0 round 1: 811 steps 6605 tok/s (6953 padded; contexts 5097 of 5154) nll 1.3088 ret 1.2676 gpu 94% free 80% | delta sent 0.1s, waited 4.6s, update 0.1s
|
||||
round 1: 1948/32681 lr×1.000 eta 168m | dbc 811 steps 6605 tok/s nll 1.3088 ret 1.2676 | evo 211 steps 2326 tok/s nll 1.2393 ret 1.2945 | ret 1.2734, recall@32 0.047 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.000) (7.8s) | 304.9s, closed 4.9s past the deadline, outer step 0.1s
|
||||
worker 0 round 2: 805 steps 6634 tok/s (6972 padded; contexts 5192 of 5236) nll 1.2024 ret 1.1647 gpu 94% free 81% | delta sent 0.1s, waited 5.6s, update 0.0s
|
||||
round 2: 2963/32681 lr×1.000 eta 158m | dbc 805 steps 6634 tok/s nll 1.2024 ret 1.1647 | evo 210 steps 2305 tok/s nll 1.3081 ret 1.2863 | ret 1.1919, recall@32 0.078 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (6.6s) | 306.1s, closed 6.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 825 steps 6734 tok/s (7082 padded; contexts 5257 of 5313) nll 1.2541 ret 1.1725 gpu 94% free 80% | delta sent 0.1s, waited 6.2s, update 0.0s
|
||||
round 3: 3989/32681 lr×1.000 eta 150m | dbc 825 steps 6734 tok/s nll 1.2541 ret 1.1725 | evo 201 steps 2257 tok/s nll 1.2135 ret 1.1401 | ret 1.1659, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (7.3s) | 306.7s, closed 6.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 794 steps 6493 tok/s (6829 padded; contexts 5028 of 5075) nll 1.1956 ret 1.1391 gpu 94% free 80% | delta sent 0.1s, waited 5.7s, update 0.0s
|
||||
round 4: 4964/32681 lr×1.000 eta 145m | dbc 794 steps 6493 tok/s nll 1.1956 ret 1.1391 | evo 181 steps 2067 tok/s nll 1.2064 ret 1.1321 | ret 1.1378, recall@32 0.125 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.080) (6.8s) | 306.2s, closed 6.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 821 steps 6689 tok/s (7040 padded; contexts 5189 of 5237) nll 1.1482 ret 1.0956 gpu 93% free 81% | delta sent 0.1s, waited 4.1s, update 0.0s
|
||||
round 5: 5966/32681 lr×1.000 eta 139m | dbc 821 steps 6689 tok/s nll 1.1482 ret 1.0956 | evo 181 steps 2011 tok/s nll 1.2778 ret 1.2575 | ret 1.1270, recall@32 0.078 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (6.9s) | 304.8s, closed 4.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 813 steps 6798 tok/s (7152 padded; contexts 5375 of 5443) nll 1.1061 ret 1.0930 gpu 93% free 81% | delta sent 0.1s, waited 5.8s, update 0.0s
|
||||
round 6: 6932/32681 lr×1.000 eta 134m | dbc 813 steps 6798 tok/s nll 1.1061 ret 1.0930 | evo 153 steps 1701 tok/s nll 1.1162 ret 1.0231 | ret 1.0794, recall@32 0.109 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.060) (6.8s) | 306.3s, closed 6.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 828 steps 6778 tok/s (7147 padded; contexts 5222 of 5277) nll 1.1586 ret 1.0969 gpu 93% free 81% | delta sent 0.1s, waited 4.9s, update 0.0s
|
||||
round 7: 7912/32681 lr×1.000 eta 129m | dbc 828 steps 6778 tok/s nll 1.1586 ret 1.0969 | evo 152 steps 1735 tok/s nll 1.1280 ret 1.0951 | ret 1.0966, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (6.8s) | 305.4s, closed 5.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 839 steps 6860 tok/s (7215 padded; contexts 5323 of 5377) nll 1.1120 ret 1.0534 gpu 94% free 81% | delta sent 0.1s, waited 7.8s, update 0.0s
|
||||
round 8: 8891/32681 lr×1.000 eta 124m | dbc 839 steps 6860 tok/s nll 1.1120 ret 1.0534 | evo 140 steps 1582 tok/s nll 1.1663 ret 1.2461 | ret 1.0765, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 1.000, code.symbol.gold 0.000, code.test.silver 0.000, skills.select.silver 0.020) (6.9s) | 308.1s, closed 8.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 9: 836 steps 6805 tok/s (7166 padded; contexts 5260 of 5317) nll 1.1413 ret 1.0820 gpu 93% free 81% | delta sent 0.1s, waited 5.8s, update 0.0s
|
||||
round 9: 9834/32681 lr×1.000 eta 120m | dbc 836 steps 6805 tok/s nll 1.1413 ret 1.0820 | evo 107 steps 1225 tok/s nll 1.0136 ret 1.0293 | ret 1.0748, recall@32 0.062 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.020) (6.8s) | 306.0s, closed 6.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 10: 820 steps 6806 tok/s (7165 padded; contexts 5273 of 5323) nll 1.1404 ret 1.0721 gpu 94% free 80% | delta sent 0.1s, waited 5.3s, update 0.0s
|
||||
round 10: 10801/32681 lr×1.000 eta 115m | dbc 820 steps 6806 tok/s nll 1.1404 ret 1.0721 | evo 147 steps 1639 tok/s nll 1.0105 ret 0.9811 | ret 1.0568, recall@32 0.078 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.250, code.test.silver 0.250, skills.select.silver 0.020) (7.2s) | 305.6s, closed 5.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 11: 839 steps 6772 tok/s (7130 padded; contexts 5242 of 5296) nll 1.0595 ret 1.0365 gpu 94% free 81% | delta sent 0.1s, waited 6.0s, update 0.0s
|
||||
round 11: 11774/32681 lr×1.000 eta 110m | dbc 839 steps 6772 tok/s nll 1.0595 ret 1.0365 | evo 134 steps 1522 tok/s nll 1.1925 ret 0.9237 | ret 1.0187, recall@32 0.078 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.250, code.test.silver 0.250, skills.select.silver 0.020) (6.7s) | 306.3s, closed 6.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 12: 824 steps 6715 tok/s (7073 padded; contexts 5143 of 5193) nll 1.0902 ret 1.0136 gpu 94% free 80% | delta sent 0.1s, waited 4.2s, update 0.0s
|
||||
round 12: 12733/32681 lr×1.000 eta 105m | dbc 824 steps 6715 tok/s nll 1.0902 ret 1.0136 | evo 135 steps 1523 tok/s nll 0.9276 ret 1.0268 | ret 1.0156, recall@32 0.141 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.500, code.test.silver 0.250, skills.select.silver 0.080) (7.0s) | 304.7s, closed 4.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 13: 829 steps 6683 tok/s (7029 padded; contexts 5213 of 5262) nll 1.0655 ret 1.0331 gpu 94% free 81% | delta sent 0.1s, waited 5.9s, update 0.0s
|
||||
round 13: 13702/32681 lr×1.000 eta 100m | dbc 829 steps 6683 tok/s nll 1.0655 ret 1.0331 | evo 140 steps 1597 tok/s nll 1.1236 ret 0.9700 | ret 1.0236, recall@32 0.094 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.250, code.test.silver 0.250, skills.select.silver 0.040) (6.8s) | 306.1s, closed 6.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 14: 829 steps 6791 tok/s (7137 padded; contexts 5272 of 5313) nll 1.0702 ret 1.0072 gpu 94% free 81% | delta sent 0.1s, waited 5.9s, update 0.0s
|
||||
round 14: 14678/32681 lr×1.000 eta 94m | dbc 829 steps 6791 tok/s nll 1.0702 ret 1.0072 | evo 147 steps 1645 tok/s nll 1.0185 ret 0.9782 | ret 1.0027, recall@32 0.078 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.500, code.test.silver 0.250, skills.select.silver 0.000) (6.7s) | 306.3s, closed 6.3s past the deadline, outer step 0.0s
|
||||
worker 0 round 15: 836 steps 6854 tok/s (7184 padded; contexts 5393 of 5439) nll 0.9997 ret 1.0064 gpu 94% free 80% | delta sent 0.1s, waited 5.4s, update 0.0s
|
||||
round 15: 15659/32681 lr×1.000 eta 89m | dbc 836 steps 6854 tok/s nll 0.9997 ret 1.0064 | evo 145 steps 1592 tok/s nll 1.1441 ret 1.0206 | ret 1.0082, recall@32 0.094 (code.file.gold 0.500, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.040) (7.3s) | 306.0s, closed 6.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 16: 796 steps 6451 tok/s (6792 padded; contexts 4972 of 5020) nll 1.0032 ret 0.9811 gpu 93% free 80% | delta sent 0.1s, waited 6.4s, update 0.1s, state kept
|
||||
round 16: 16598/32681 lr×1.000 eta 84m | dbc 796 steps 6451 tok/s nll 1.0032 ret 0.9811 | evo 143 steps 1619 tok/s nll 0.8975 ret 0.9620 | ret 0.9780, recall@32 0.125 (code.file.gold 0.500, code.suspect.gold 0.500, code.symbol.gold 0.250, code.test.silver 0.000, skills.select.silver 0.080) (7.9s) | 306.6s, closed 6.6s past the deadline, outer step 0.1s
|
||||
val: 344 rows over 255218 options, each answered over all of them, retrieval's top 160 by the head (156s); 13214 rows by the head (367s)
|
||||
val @16598: action 0.282/1.857 ag_news 0.890/0.407 arch 0.667/0.830 banking77 0.693/1.678 boolq 0.638/0.658 clinc150 0.657/1.592 code.affected.gold 0.477/0.693 code.failure.silver 0.316/1.789 code.file.gold 0.083/4.535 code.suspect.gold 0.000/5.088 code.symbol.gold 0.089/4.298 code.test.silver 0.020/3.860 control.commit.gold 0.286/1.488 control.context.gold 0.806/0.805 control.continue.gold 0.952/0.479 control.done.gold 0.364/0.720 control.repeat.gold 1.000/0.650 control.retry.gold 0.000/0.955 control.rollback.gold 0.429/0.695 control.strategy.gold 0.750/0.581 control.user.silver 0.875/0.395 done 0.970/0.433 email_spam 0.983/0.042 emotion 0.831/0.561 function 0.593/1.669 graph_typed 0.548/1.085 guardrails_jailbreak 0.940/0.192 massive 0.787/0.769 mnli 0.583/0.913 model_routing_domain 0.995/0.027 moderation_toxicity 0.885/0.322 nemotron 0.312/2.612 phishing 0.969/0.143 rag_relevance 0.497/0.693 readiness 0.502/1.123 resolve 0.985/0.388 rig 0.468/1.166 risk 0.072/2.488 skills.select.silver 0.000/7.109 sst5 0.207/1.630 support_triage 0.400/1.651 sysml 0.600/0.715 testplan 0.608/1.010 tool 0.565/1.987 trade 0.583/0.807 turbofan 0.480/1.025 typed_decisions 0.537/1.035 xnli 0.600/0.961
|
||||
saved /Users/a/scratch/decision/runs/a3 at 16598 batches, 1 epochs
|
||||
worker 0 round 17: 512 steps 4148 tok/s (4377 padded; contexts 3214 of 3255) nll 1.0080 ret 0.9522 gpu 93% free 77% | delta sent 0.2s, waited 231.0s, update 0.1s
|
||||
round 17: 17255/32681 lr×1.000 eta 86m | dbc 512 steps 4148 tok/s nll 1.0080 ret 0.9522 | evo 145 steps 1625 tok/s nll 1.0574 ret 0.8483 | ret 0.9301, recall@32 0.078 (code.file.gold 0.500, code.suspect.gold 0.500, code.symbol.gold 0.250, code.test.silver 0.250, skills.select.silver 0.000) (7.1s) | 532.2s, closed 232.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 18: 788 steps 6497 tok/s (6834 padded; contexts 5050 of 5100) nll 0.9992 ret 0.9596 gpu 94% free 79% | delta sent 0.1s, waited 5.1s, update 0.0s
|
||||
round 18: 18184/32681 lr×1.000 eta 81m | dbc 788 steps 6497 tok/s nll 0.9992 ret 0.9596 | evo 141 steps 1538 tok/s nll 0.9785 ret 0.9185 | ret 0.9540, recall@32 0.047 (code.file.gold 0.250, code.suspect.gold 0.500, code.symbol.gold 0.000, code.test.silver 0.250, skills.select.silver 0.000) (7.0s) | 305.4s, closed 5.4s past the deadline, outer step 0.1s
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "h1",
|
||||
"init": {
|
||||
"dir": "../runs/h1",
|
||||
"stage": "a"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 1,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 100,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 300,
|
||||
"outer": 1.0,
|
||||
"momentum": 0.0,
|
||||
"round": 30.0
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 190 tensors carried, fresh: []
|
||||
plan: stage h1, 1 epochs, 771 batches, 23 warmup, 154 cooldown; rows on a sample of their options, by epoch: [0]
|
||||
cluster: coordinating on 127.0.0.1:59647
|
||||
cluster: ra (127.0.0.1:59648) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 35/300 lr×1.000 eta 4m | ra 35 steps 4594 tok/s nll 0.6981 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 35 steps 4594 tok/s (4638 padded; contexts 4571 of 4613) nll 0.6981 ret 0.0000 gpu 97% free 67% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 1: 72/300 lr×1.000 eta 3m | ra 37 steps 4947 tok/s nll 0.6949 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 1: 37 steps 4947 tok/s (4976 padded; contexts 4923 of 4949) nll 0.6949 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 2: 110/300 lr×1.000 eta 3m | ra 38 steps 4796 tok/s nll 0.6942 ret 0.0000 | ret 0.0000 | 30.9s, closed 0.9s past the deadline, outer step 0.0s
|
||||
worker 0 round 2: 38 steps 4796 tok/s (4831 padded; contexts 4771 of 4804) nll 0.6942 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @110: rag_relevance 0.517/0.693
|
||||
saved runs/h1run at 110 batches, 0 epochs
|
||||
round 3: 144/300 lr×1.000 eta 2m | ra 34 steps 4453 tok/s nll 0.6932 ret 0.0000 | ret 0.0000 | 31.8s, closed 1.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 34 steps 4453 tok/s (4481 padded; contexts 4431 of 4457) nll 0.6932 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 4: 181/300 lr×1.000 eta 2m | ra 37 steps 4923 tok/s nll 0.6934 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.1s
|
||||
worker 0 round 4: 37 steps 4923 tok/s (4949 padded; contexts 4899 of 4922) nll 0.6934 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 5: 218/300 lr×1.000 eta 1m | ra 37 steps 4606 tok/s nll 0.6932 ret 0.0000 | ret 0.0000 | 31.4s, closed 1.4s past the deadline, outer step 0.1s
|
||||
worker 0 round 5: 37 steps 4606 tok/s (4634 padded; contexts 4582 of 4607) nll 0.6932 ret 0.0000 gpu 98% free 63% | delta sent 0.3s, waited 0.1s, update 0.1s, state kept
|
||||
val @218: rag_relevance 0.497/0.693
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "h2",
|
||||
"init": {
|
||||
"dir": "../runs/h2",
|
||||
"stage": "a"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 1,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 100,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 300,
|
||||
"outer": 1.0,
|
||||
"momentum": 0.0,
|
||||
"round": 30.0
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 190 tensors carried, fresh: []
|
||||
plan: stage h2, 1 epochs, 771 batches, 23 warmup, 154 cooldown; rows on a sample of their options, by epoch: [0]
|
||||
cluster: coordinating on 127.0.0.1:60230
|
||||
cluster: ra (127.0.0.1:60231) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 37/300 lr×1.000 eta 4m | ra 37 steps 4811 tok/s nll 0.6362 ret 0.0000 | ret 0.0000 | 31.4s, closed 1.4s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 37 steps 4811 tok/s (4855 padded; contexts 4787 of 4828) nll 0.6362 ret 0.0000 gpu 97% free 68% | delta sent 0.3s, waited 0.1s, update 0.1s
|
||||
round 1: 70/300 lr×1.000 eta 3m | ra 33 steps 4323 tok/s nll 0.5858 ret 0.0000 | ret 0.0000 | 31.2s, closed 1.2s past the deadline, outer step 0.1s
|
||||
worker 0 round 1: 33 steps 4323 tok/s (4349 padded; contexts 4302 of 4325) nll 0.5858 ret 0.0000 gpu 97% free 68% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 2: 104/300 lr×1.000 eta 3m | ra 34 steps 4365 tok/s nll 0.5487 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.1s
|
||||
worker 0 round 2: 34 steps 4365 tok/s (4397 padded; contexts 4343 of 4373) nll 0.5487 ret 0.0000 gpu 98% free 68% | delta sent 0.2s, waited 0.1s, update 0.1s, state kept
|
||||
val @104: rag_relevance 0.662/0.677
|
||||
saved runs/h2run at 104 batches, 0 epochs
|
||||
round 3: 134/300 lr×1.000 eta 3m | ra 30 steps 3785 tok/s nll 0.5366 ret 0.0000 | ret 0.0000 | 32.5s, closed 2.5s past the deadline, outer step 0.2s
|
||||
worker 0 round 3: 30 steps 3785 tok/s (3812 padded; contexts 3766 of 3791) nll 0.5366 ret 0.0000 gpu 97% free 63% | delta sent 0.5s, waited 0.2s, update 0.2s
|
||||
round 4: 165/300 lr×1.000 eta 2m | ra 31 steps 4057 tok/s nll 0.4745 ret 0.0000 | ret 0.0000 | 31.2s, closed 1.2s past the deadline, outer step 0.1s
|
||||
worker 0 round 4: 31 steps 4057 tok/s (4077 padded; contexts 4037 of 4054) nll 0.4745 ret 0.0000 gpu 97% free 58% | delta sent 0.3s, waited 0.1s, update 0.1s
|
||||
round 5: 200/300 lr×1.000 eta 2m | ra 35 steps 4402 tok/s nll 0.4480 ret 0.0000 | ret 0.0000 | 30.8s, closed 0.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 35 steps 4402 tok/s (4429 padded; contexts 4379 of 4404) nll 0.4480 ret 0.0000 gpu 98% free 59% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @200: rag_relevance 0.632/0.810
|
||||
saved runs/h2run at 200 batches, 0 epochs
|
||||
round 6: 231/300 lr×1.000 eta 1m | ra 31 steps 4114 tok/s nll 0.4483 ret 0.0000 | ret 0.0000 | 31.5s, closed 1.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 31 steps 4114 tok/s (4136 padded; contexts 4093 of 4114) nll 0.4483 ret 0.0000 gpu 96% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 7: 267/300 lr×1.000 eta 1m | ra 36 steps 4657 tok/s nll 0.4446 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 36 steps 4657 tok/s (4694 padded; contexts 4634 of 4668) nll 0.4446 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 8: 300/300 lr×1.000 eta 0m | ra 33 steps 4586 tok/s nll 0.3530 ret 0.0000 | ret 0.0000 | 28.5s, closed 0.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 33 steps 4586 tok/s (4638 padded; contexts 4563 of 4612) nll 0.3530 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s; done
|
||||
val @300: rag_relevance 0.635/0.828
|
||||
saved runs/h2run at 300 batches, 0 epochs
|
||||
@@ -1,27 +0,0 @@
|
||||
# hybrid.py <encoder-from> <rest-from> <out>: a checkpoint whose encoder.* tensors come from one run and every other tensor from another.
|
||||
import json, struct, sys, os, shutil
|
||||
def header(p):
|
||||
f = open(p, "rb"); n = struct.unpack("<Q", f.read(8))[0]; return f, json.loads(f.read(n)), 8 + n
|
||||
enc, rest, out = sys.argv[1:4]
|
||||
fe, he, be = header(enc + "/model.safetensors"); fr, hr, br = header(rest + "/model.safetensors")
|
||||
names = sorted((set(hr) | set(he)) - {"__metadata__"})
|
||||
os.makedirs(out, exist_ok=True)
|
||||
h, off, plan = {}, 0, []
|
||||
for k in names:
|
||||
f, hh, b = (fe, he, be) if (k.startswith("encoder.") or k not in hr) else (fr, hr, br)
|
||||
if k not in hh: f, hh, b = (fr, hr, br)
|
||||
v = hh[k]; a, z = v["data_offsets"]
|
||||
h[k] = {"dtype": v["dtype"], "shape": v["shape"], "data_offsets": [off, off + z - a]}
|
||||
plan.append((f, b + a, z - a)); off += z - a
|
||||
if "__metadata__" in hr: h["__metadata__"] = hr["__metadata__"]
|
||||
hb = json.dumps(h, separators=(",", ":")).encode(); hb += b" " * ((8 - len(hb) % 8) % 8)
|
||||
with open(out + "/model.safetensors", "wb") as w:
|
||||
w.write(struct.pack("<Q", len(hb))); w.write(hb)
|
||||
for f, s, n in plan:
|
||||
f.seek(s); w.write(f.read(n))
|
||||
cfg = json.load(open(rest + "/kai.json"))
|
||||
a = json.load(open("runs/a/kai.json"))
|
||||
cfg["provenance"] = a["provenance"] # Init::Dir accepts a finished stage `a`
|
||||
json.dump(cfg, open(out + "/kai.json", "w"))
|
||||
shutil.copytree(rest + "/tokenizer", out + "/tokenizer", dirs_exist_ok=True)
|
||||
print("wrote", out)
|
||||
@@ -1,4 +0,0 @@
|
||||
laya-init n 200 | passage states moved by a query swap 0.3435 | global-layer attention passage->query 0.0537 | attention on token 0 0.065 | mean cos between contexts 0.853 | probe acc 0.590
|
||||
rag-only@229 n 200 | passage states moved by a query swap 0.7338 | global-layer attention passage->query 0.0819 | attention on token 0 0.063 | mean cos between contexts 0.776 | probe acc 0.525
|
||||
stage-a n 200 | passage states moved by a query swap 0.0849 | global-layer attention passage->query 0.1519 | attention on token 0 0.049 | mean cos between contexts 0.981 | probe acc 0.510
|
||||
h2run n 200 | passage states moved by a query swap 0.9725 | global-layer attention passage->query 0.0898 | attention on token 0 0.054 | mean cos between contexts 0.644 | probe acc 0.555
|
||||
@@ -1,65 +0,0 @@
|
||||
# Encoder probe on RAG contexts laid out as Kai lays them: [CLS] prompt [SEP] state [SEP].
|
||||
# For each checkpoint: (1) how much the passage tokens' final states move when only the query
|
||||
# changes; (2) attention mass passage->query in the global layers; (3) how alike different
|
||||
# contexts' mean states are; (4) a logistic probe (5-fold) on [mean passage state, mean query
|
||||
# state, their product] predicting relevance.
|
||||
import gzip, json, glob, os, sys, numpy as np, torch
|
||||
from safetensors.torch import load_file
|
||||
from transformers import ModernBertConfig, ModernBertModel
|
||||
from tokenizers import Tokenizer
|
||||
torch.set_grad_enabled(False)
|
||||
S = glob.glob(os.path.expanduser("~/.cache/huggingface/hub/models--hanzoai--kai-1-multilingual/snapshots/*/"))[0]
|
||||
cfgj = json.load(open(S + "encoder/config.json"))
|
||||
cfg = ModernBertConfig(**{k: v for k, v in cfgj.items() if k not in ("rope_parameters", "layer_types")},
|
||||
global_rope_theta=160000.0, local_rope_theta=160000.0, attn_implementation="eager")
|
||||
tok = Tokenizer.from_file(S + "tokenizer/tokenizer.json")
|
||||
tc = json.load(open(S + "tokenizer/tokenizer_config.json"))
|
||||
cid = lambda k: tok.token_to_id(tc[k] if isinstance(tc[k], str) else tc[k]["content"])
|
||||
CLS, SEP = cid("cls_token"), cid("sep_token")
|
||||
ids = lambda s: tok.encode(s, add_special_tokens=False).ids
|
||||
prompt = ids("noul question: Does `passage` help answer `query`?")
|
||||
recs = [json.loads(l) for l in gzip.open("validation/in_domain/rag_relevance.microsoft-ms_marco.format.red.0.jsonl.gz", "rt")][:600]
|
||||
def ctx(q, p):
|
||||
head = ids('{"query": ' + json.dumps(q, ensure_ascii=False) + ', "passage": ')
|
||||
body = ids(json.dumps(p, ensure_ascii=False) + "}")
|
||||
seq = [CLS] + prompt + [SEP] + head + body + [SEP]
|
||||
qs = 1 + len(prompt) + 1
|
||||
return seq, (qs, qs + len(head)), (qs + len(head), qs + len(head) + len(body))
|
||||
def model(path):
|
||||
w = load_file(path)
|
||||
enc = {k[len("encoder."):]: v.float() for k, v in w.items() if k.startswith("encoder.")}
|
||||
m = ModernBertModel(cfg); missing, unexpected = m.load_state_dict(enc, strict=False)
|
||||
assert not [k for k in missing if "rotary" not in k], missing
|
||||
return m.eval()
|
||||
def run(m, seq):
|
||||
out = m(torch.tensor([seq]), attention_mask=torch.ones(1, len(seq), dtype=torch.long), output_attentions=True)
|
||||
return out.last_hidden_state[0].numpy(), [a[0].numpy() for a in out.attentions]
|
||||
ckpts = [(n, p) for n, p in [("laya-init", S + "model.safetensors"), ("rag-only@229", "runs/rag1/model.safetensors"),
|
||||
("stage-a", "runs/a/model.safetensors"), ("h2run", "runs/h2run/model.safetensors")] if os.path.exists(p)]
|
||||
N = int(sys.argv[1]) if len(sys.argv) > 1 else 200
|
||||
for name, path in ckpts:
|
||||
m = model(path)
|
||||
move, pq, sink, feats, ys, means = [], [], [], [], [], []
|
||||
for i, r in enumerate(recs[:N]):
|
||||
q, p = r["state"]["query"], r["state"]["passage"]
|
||||
q2 = recs[(i + 7) % len(recs)]["state"]["query"]
|
||||
s1, (qa, qb), (pa, pb) = ctx(q, p)
|
||||
h1, att = run(m, s1)
|
||||
s2, _, (pa2, pb2) = ctx(q2, p)
|
||||
h2, _ = run(m, s2)
|
||||
P1, P2 = h1[pa:pb], h2[pa2:pb2]
|
||||
if P1.shape == P2.shape:
|
||||
move.append(np.linalg.norm(P1 - P2) / np.linalg.norm(P1))
|
||||
g = [a for li, a in enumerate(att) if li % 3 == 0] # global layers
|
||||
pq.append(np.mean([a[:, pa:pb, qa:qb].sum(-1).mean() for a in g]))
|
||||
sink.append(np.mean([a[:, :, 0].mean() for a in att]))
|
||||
mp, mq = h1[pa:pb].mean(0), h1[qa:qb].mean(0)
|
||||
feats.append(np.concatenate([mp, mq, mp * mq])); ys.append(int(r["target"]["relevant"][1] > 0.5))
|
||||
means.append(h1[1:-1].mean(0))
|
||||
X, y = np.array(feats), np.array(ys)
|
||||
X = (X - X.mean(0)) / (X.std(0) + 1e-6)
|
||||
from sklearn.linear_model import LogisticRegression
|
||||
from sklearn.model_selection import cross_val_score
|
||||
acc = cross_val_score(LogisticRegression(C=0.05, max_iter=3000), X, y, cv=5).mean()
|
||||
M = np.array(means); M = M / np.linalg.norm(M, axis=1, keepdims=True); cos = (M @ M.T)[np.triu_indices(len(M), 1)].mean()
|
||||
print(f"{name:14s} n {len(ys)} | passage states moved by a query swap {np.mean(move):.4f} | global-layer attention passage->query {np.mean(pq):.4f} | attention on token 0 {np.mean(sink):.3f} | mean cos between contexts {cos:.3f} | probe acc {acc:.3f}", flush=True)
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "rag1",
|
||||
"init": {
|
||||
"repo": "hanzoai/kai-1-multilingual",
|
||||
"revision": "3119843b5261e34903f93d03813467524c57982e"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 1,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 200,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 0,
|
||||
"outer": 1.0,
|
||||
"momentum": 0.0,
|
||||
"round": 30.0
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 176 tensors carried, fresh: ["ordinal.cut.bias", "ordinal.cut.weight", "ordinal.gap.bias", "ordinal.gap.weight", "ordinal.location.bias", "ordinal.location.center", "ordinal.location.weight", "retrieval.key.bias", "retrieval.key.center", "retrieval.key.weight", "retrieval.query.bias", "retrieval.query.center", "retrieval.query.weight", "retrieval.scale"]
|
||||
plan: stage rag1, 1 epochs, 771 batches, 23 warmup, 154 cooldown; rows on a sample of their options, by epoch: [0]
|
||||
cluster: coordinating on 127.0.0.1:57622
|
||||
cluster: ra (127.0.0.1:57623) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 27/771 lr×1.000 eta 15m | ra 27 steps 3547 tok/s nll 0.7139 ret 0.0000 | ret 0.0000 | 31.3s, closed 1.3s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 27 steps 3547 tok/s (3562 padded; contexts 3530 of 3542) nll 0.7139 ret 0.0000 gpu 70% free 76% | delta sent 0.3s, waited 0.1s, update 0.1s
|
||||
round 1: 67/771 lr×1.000 eta 11m | ra 40 steps 5213 tok/s nll 0.6818 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 1: 40 steps 5213 tok/s (5266 padded; contexts 5187 of 5237) nll 0.6818 ret 0.0000 gpu 98% free 74% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 2: 108/771 lr×1.000 eta 10m | ra 41 steps 5244 tok/s nll 0.6455 ret 0.0000 | ret 0.0000 | 30.6s, closed 0.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 2: 41 steps 5244 tok/s (5283 padded; contexts 5217 of 5253) nll 0.6455 ret 0.0000 gpu 98% free 73% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 3: 148/771 lr×1.000 eta 9m | ra 40 steps 5284 tok/s nll 0.6430 ret 0.0000 | ret 0.0000 | 30.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 40 steps 5284 tok/s (5315 padded; contexts 5258 of 5286) nll 0.6430 ret 0.0000 gpu 98% free 73% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 4: 188/771 lr×1.000 eta 8m | ra 40 steps 5219 tok/s nll 0.6056 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 40 steps 5219 tok/s (5250 padded; contexts 5192 of 5221) nll 0.6056 ret 0.0000 gpu 98% free 73% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 5: 229/771 lr×1.000 eta 7m | ra 41 steps 5254 tok/s nll 0.6245 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 41 steps 5254 tok/s (5282 padded; contexts 5227 of 5253) nll 0.6245 ret 0.0000 gpu 98% free 73% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @229: rag_relevance 0.645/0.644
|
||||
saved runs/rag1 at 229 batches, 0 epochs
|
||||
round 6: 266/771 lr×1.000 eta 7m | ra 37 steps 4791 tok/s nll 0.6527 ret 0.0000 | ret 0.0000 | 31.8s, closed 1.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 37 steps 4791 tok/s (4830 padded; contexts 4767 of 4803) nll 0.6527 ret 0.0000 gpu 97% free 65% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 7: 306/771 lr×1.000 eta 6m | ra 40 steps 5236 tok/s nll 0.6235 ret 0.0000 | ret 0.0000 | 30.4s, closed 0.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 40 steps 5236 tok/s (5287 padded; contexts 5209 of 5258) nll 0.6235 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 8: 346/771 lr×1.000 eta 6m | ra 40 steps 5320 tok/s nll 0.6217 ret 0.0000 | ret 0.0000 | 30.6s, closed 0.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 40 steps 5320 tok/s (5347 padded; contexts 5294 of 5318) nll 0.6217 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 9: 386/771 lr×1.000 eta 5m | ra 40 steps 5279 tok/s nll 0.6174 ret 0.0000 | ret 0.0000 | 30.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 9: 40 steps 5279 tok/s (5312 padded; contexts 5253 of 5283) nll 0.6174 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 10: 426/771 lr×1.000 eta 5m | ra 40 steps 5317 tok/s nll 0.6277 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 10: 40 steps 5317 tok/s (5350 padded; contexts 5291 of 5321) nll 0.6277 ret 0.0000 gpu 98% free 66% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @426: rag_relevance 0.640/0.643
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "rag2",
|
||||
"init": {
|
||||
"dir": "../runs/a",
|
||||
"stage": "a"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 1,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 200,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 0,
|
||||
"outer": 1.0,
|
||||
"momentum": 0.0,
|
||||
"round": 30.0
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 187 tensors carried, fresh: ["ordinal.location.center", "retrieval.key.center", "retrieval.query.center"]
|
||||
plan: stage rag2, 1 epochs, 771 batches, 23 warmup, 154 cooldown; rows on a sample of their options, by epoch: [0]
|
||||
cluster: coordinating on 127.0.0.1:58705
|
||||
cluster: ra (127.0.0.1:58706) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 35/771 lr×1.000 eta 11m | ra 35 steps 4581 tok/s nll 0.6938 ret 0.0000 | ret 0.0000 | 31.4s, closed 1.4s past the deadline, outer step 0.2s
|
||||
worker 0 round 0: 35 steps 4581 tok/s (4624 padded; contexts 4558 of 4599) nll 0.6938 ret 0.0000 gpu 94% free 63% | delta sent 0.5s, waited 0.2s, update 0.1s
|
||||
round 1: 69/771 lr×1.000 eta 11m | ra 34 steps 4552 tok/s nll 0.7043 ret 0.0000 | ret 0.0000 | 30.6s, closed 0.6s past the deadline, outer step 0.1s
|
||||
worker 0 round 1: 34 steps 4552 tok/s (4577 padded; contexts 4529 of 4552) nll 0.7043 ret 0.0000 gpu 97% free 62% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 2: 105/771 lr×1.000 eta 10m | ra 36 steps 4716 tok/s nll 0.6946 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 2: 36 steps 4716 tok/s (4752 padded; contexts 4692 of 4725) nll 0.6946 ret 0.0000 gpu 97% free 63% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 3: 142/771 lr×1.000 eta 9m | ra 37 steps 4720 tok/s nll 0.6934 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 37 steps 4720 tok/s (4750 padded; contexts 4696 of 4724) nll 0.6934 ret 0.0000 gpu 98% free 63% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 4: 175/771 lr×1.000 eta 9m | ra 33 steps 4370 tok/s nll 0.6933 ret 0.0000 | ret 0.0000 | 30.6s, closed 0.6s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 33 steps 4370 tok/s (4393 padded; contexts 4348 of 4369) nll 0.6933 ret 0.0000 gpu 98% free 63% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @175: rag_relevance 0.497/0.693
|
||||
saved runs/rag2 at 175 batches, 0 epochs
|
||||
round 5: 205/771 lr×1.000 eta 9m | ra 30 steps 3781 tok/s nll 0.6918 ret 0.0000 | ret 0.0000 | 31.4s, closed 1.4s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 30 steps 3781 tok/s (3802 padded; contexts 3761 of 3781) nll 0.6918 ret 0.0000 gpu 98% free 62% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 6: 236/771 lr×1.000 eta 8m | ra 31 steps 4062 tok/s nll 0.6939 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 31 steps 4062 tok/s (4082 padded; contexts 4041 of 4060) nll 0.6939 ret 0.0000 gpu 98% free 59% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 7: 268/771 lr×1.000 eta 8m | ra 32 steps 4207 tok/s nll 0.6935 ret 0.0000 | ret 0.0000 | 30.5s, closed 0.5s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 32 steps 4207 tok/s (4253 padded; contexts 4186 of 4229) nll 0.6935 ret 0.0000 gpu 98% free 56% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 8: 302/771 lr×1.000 eta 7m | ra 34 steps 4349 tok/s nll 0.6927 ret 0.0000 | ret 0.0000 | 31.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 8: 34 steps 4349 tok/s (4387 padded; contexts 4327 of 4362) nll 0.6927 ret 0.0000 gpu 98% free 57% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @302: rag_relevance 0.495/0.693
|
||||
saved runs/rag2 at 302 batches, 0 epochs
|
||||
round 9: 332/771 lr×1.000 eta 7m | ra 30 steps 3926 tok/s nll 0.6933 ret 0.0000 | ret 0.0000 | 32.2s, closed 2.2s past the deadline, outer step 0.2s
|
||||
worker 0 round 9: 30 steps 3926 tok/s (3942 padded; contexts 3907 of 3920) nll 0.6933 ret 0.0000 gpu 96% free 60% | delta sent 0.3s, waited 0.2s, update 0.1s
|
||||
@@ -1,22 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 187 tensors carried, fresh: ["ordinal.location.center", "retrieval.key.center", "retrieval.query.center"]
|
||||
plan: stage rag2, 1 epochs, 771 batches, 23 warmup, 154 cooldown; rows on a sample of their options, by epoch: [0]
|
||||
cluster: coordinating on 127.0.0.1:59138
|
||||
cluster: ra (127.0.0.1:59139) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, F32)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 31/771 lr×1.000 eta 13m | ra 31 steps 4039 tok/s nll 0.6957 ret 0.0000 | ret 0.0000 | 31.3s, closed 1.3s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 31 steps 4039 tok/s (4065 padded; contexts 4019 of 4043) nll 0.6957 ret 0.0000 gpu 97% free 64% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 1: 60/771 lr×1.000 eta 12m | ra 29 steps 3852 tok/s nll 0.6991 ret 0.0000 | ret 0.0000 | 30.7s, closed 0.7s past the deadline, outer step 0.2s
|
||||
worker 0 round 1: 29 steps 3852 tok/s (3887 padded; contexts 3833 of 3866) nll 0.6991 ret 0.0000 gpu 97% free 64% | delta sent 0.3s, waited 0.2s, update 0.1s
|
||||
round 2: 91/771 lr×1.000 eta 12m | ra 31 steps 4029 tok/s nll 0.6978 ret 0.0000 | ret 0.0000 | 30.7s, closed 0.7s past the deadline, outer step 0.1s
|
||||
worker 0 round 2: 31 steps 4029 tok/s (4057 padded; contexts 4009 of 4035) nll 0.6978 ret 0.0000 gpu 98% free 63% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 3: 120/771 lr×1.000 eta 11m | ra 29 steps 3741 tok/s nll 0.6939 ret 0.0000 | ret 0.0000 | 30.6s, closed 0.6s past the deadline, outer step 0.1s
|
||||
worker 0 round 3: 29 steps 3741 tok/s (3773 padded; contexts 3721 of 3752) nll 0.6939 ret 0.0000 gpu 97% free 63% | delta sent 0.3s, waited 0.1s, update 0.1s
|
||||
round 4: 150/771 lr×1.000 eta 11m | ra 30 steps 3915 tok/s nll 0.6946 ret 0.0000 | ret 0.0000 | 31.2s, closed 1.2s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 30 steps 3915 tok/s (3932 padded; contexts 3896 of 3910) nll 0.6946 ret 0.0000 gpu 98% free 63% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @150: rag_relevance 0.522/0.694
|
||||
saved runs/rag2f at 150 batches, 0 epochs
|
||||
round 5: 175/771 lr×1.000 eta 11m | ra 25 steps 3337 tok/s nll 0.6933 ret 0.0000 | ret 0.0000 | 31.2s, closed 1.2s past the deadline, outer step 0.1s
|
||||
worker 0 round 5: 25 steps 3337 tok/s (3358 padded; contexts 3320 of 3339) nll 0.6933 ret 0.0000 gpu 98% free 61% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 6: 206/771 lr×1.000 eta 10m | ra 31 steps 3908 tok/s nll 0.6922 ret 0.0000 | ret 0.0000 | 30.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 6: 31 steps 3908 tok/s (3930 padded; contexts 3887 of 3908) nll 0.6922 ret 0.0000 gpu 98% free 62% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "rag3",
|
||||
"init": {
|
||||
"repo": "hanzoai/kai-1-multilingual",
|
||||
"revision": "3119843b5261e34903f93d03813467524c57982e"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 2,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 250,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 0,
|
||||
"outer": 0.7,
|
||||
"momentum": 0.9,
|
||||
"round": 120.0
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 176 tensors carried, fresh: ["ordinal.cut.bias", "ordinal.cut.weight", "ordinal.gap.bias", "ordinal.gap.weight", "ordinal.location.bias", "ordinal.location.center", "ordinal.location.weight", "retrieval.key.bias", "retrieval.key.center", "retrieval.key.weight", "retrieval.query.bias", "retrieval.query.center", "retrieval.query.weight", "retrieval.scale"]
|
||||
plan: stage rag3, 2 epochs, 1540 batches, 46 warmup, 308 cooldown; rows on a sample of their options, by epoch: [0, 0]
|
||||
cluster: coordinating on 127.0.0.1:60353
|
||||
cluster: ra (127.0.0.1:60354) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 149/1540 lr×1.000 eta 19m | ra 149 steps 4913 tok/s nll 0.6615 ret 0.0000 | ret 0.0000 | 121.3s, closed 1.3s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 149 steps 4913 tok/s (4948 padded; contexts 4888 of 4921) nll 0.6615 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.1s, update 0.1s
|
||||
round 1: 299/1540 lr×1.000 eta 17m | ra 150 steps 4903 tok/s nll 0.6402 ret 0.0000 | ret 0.0000 | 121.1s, closed 1.1s past the deadline, outer step 0.0s
|
||||
worker 0 round 1: 150 steps 4903 tok/s (4939 padded; contexts 4878 of 4912) nll 0.6402 ret 0.0000 gpu 98% free 67% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @299: rag_relevance 0.590/0.735
|
||||
saved runs/rag3 at 299 batches, 0 epochs
|
||||
round 2: 443/1540 lr×1.000 eta 15m | ra 144 steps 4797 tok/s nll 0.6375 ret 0.0000 | ret 0.0000 | 121.9s, closed 1.9s past the deadline, outer step 0.2s
|
||||
worker 0 round 2: 144 steps 4797 tok/s (4828 padded; contexts 4773 of 4802) nll 0.6375 ret 0.0000 gpu 98% free 60% | delta sent 0.3s, waited 0.2s, update 0.1s
|
||||
round 3: 591/1540 lr×1.000 eta 13m | ra 148 steps 4944 tok/s nll 0.6445 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.1s
|
||||
worker 0 round 3: 148 steps 4944 tok/s (4982 padded; contexts 4920 of 4955) nll 0.6445 ret 0.0000 gpu 98% free 61% | delta sent 0.3s, waited 0.1s, update 0.1s, state kept
|
||||
val @591: rag_relevance 0.532/0.741
|
||||
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"stage": "rag3",
|
||||
"init": {
|
||||
"repo": "hanzoai/kai-1-multilingual",
|
||||
"revision": "3119843b5261e34903f93d03813467524c57982e"
|
||||
},
|
||||
"sources": [
|
||||
"rag_relevance"
|
||||
],
|
||||
"manifest": null,
|
||||
"licenses": [
|
||||
"GREEN",
|
||||
"YELLOW",
|
||||
"RED"
|
||||
],
|
||||
"lang": null,
|
||||
"takes": [
|
||||
{
|
||||
"suite": "rag_relevance",
|
||||
"rows": 24000,
|
||||
"times": 1,
|
||||
"balance_class": false,
|
||||
"balance_lang": false
|
||||
}
|
||||
],
|
||||
"share": 1.0,
|
||||
"frozen": [
|
||||
"encoder.embeddings.tok_embeddings."
|
||||
],
|
||||
"evidence": null,
|
||||
"shared": false,
|
||||
"mixed": 0.05,
|
||||
"epochs": 2,
|
||||
"lr_encoder": 3e-05,
|
||||
"lr_head": 0.0001,
|
||||
"weight_decay": 0.01,
|
||||
"warmup": 0.03,
|
||||
"cool": 0.2,
|
||||
"decay": 1.0,
|
||||
"budget": {
|
||||
"ctx": 4096,
|
||||
"options": 4096,
|
||||
"head": 8192,
|
||||
"keys": 16384,
|
||||
"rows": 128,
|
||||
"evidence": 16384
|
||||
},
|
||||
"retrieval": {
|
||||
"wide": 0.2,
|
||||
"whole": 0.2
|
||||
},
|
||||
"top_k": 32,
|
||||
"max_len": 1024,
|
||||
"clip": 1.0,
|
||||
"seed": 1,
|
||||
"eval_every": 1100,
|
||||
"eval_rows": 400,
|
||||
"max_steps": 0,
|
||||
"outer": 0.7,
|
||||
"momentum": 0.9,
|
||||
"round": 120.0
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
corpus: 100000 train rows, 2345 val rows, suites ["rag_relevance"] (2s)
|
||||
init: 176 tensors carried, fresh: ["ordinal.cut.bias", "ordinal.cut.weight", "ordinal.gap.bias", "ordinal.gap.weight", "ordinal.location.bias", "ordinal.location.center", "ordinal.location.weight", "retrieval.key.bias", "retrieval.key.center", "retrieval.key.weight", "retrieval.query.bias", "retrieval.query.center", "retrieval.query.weight", "retrieval.scale"]
|
||||
plan: stage rag3, 2 epochs, 1540 batches, 46 warmup, 308 cooldown; rows on a sample of their options, by epoch: [0, 0]
|
||||
cluster: coordinating on 127.0.0.1:61652
|
||||
cluster: ra (127.0.0.1:61653) joins round 0 as worker 0 (Metal { gpu_id: 4294970014 }, BF16)
|
||||
worker 0 (ra): joined round 0
|
||||
round 0: 150/1540 lr×1.000 eta 19m | ra 150 steps 4973 tok/s nll 0.6607 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.1s
|
||||
worker 0 round 0: 150 steps 4973 tok/s (5008 padded; contexts 4948 of 4981) nll 0.6607 ret 0.0000 gpu 98% free 65% | delta sent 0.3s, waited 0.1s, update 0.1s
|
||||
round 1: 301/1540 lr×1.000 eta 17m | ra 151 steps 4947 tok/s nll 0.6271 ret 0.0000 | ret 0.0000 | 121.0s, closed 1.0s past the deadline, outer step 0.0s
|
||||
worker 0 round 1: 151 steps 4947 tok/s (4983 padded; contexts 4922 of 4956) nll 0.6271 ret 0.0000 gpu 98% free 68% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 2: 451/1540 lr×1.000 eta 15m | ra 150 steps 5006 tok/s nll 0.6365 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 2: 150 steps 5006 tok/s (5043 padded; contexts 4981 of 5015) nll 0.6365 ret 0.0000 gpu 98% free 69% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 3: 601/1540 lr×1.000 eta 13m | ra 150 steps 5002 tok/s nll 0.6320 ret 0.0000 | ret 0.0000 | 120.8s, closed 0.8s past the deadline, outer step 0.0s
|
||||
worker 0 round 3: 150 steps 5002 tok/s (5035 padded; contexts 4977 of 5008) nll 0.6320 ret 0.0000 gpu 98% free 69% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 4: 752/1540 lr×1.000 eta 11m | ra 151 steps 5040 tok/s nll 0.6294 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 4: 151 steps 5040 tok/s (5077 padded; contexts 5015 of 5050) nll 0.6294 ret 0.0000 gpu 98% free 69% | delta sent 0.2s, waited 0.0s, update 0.1s
|
||||
round 5: 907/1540 lr×1.000 eta 8m | ra 155 steps 5133 tok/s nll 0.6094 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 5: 155 steps 5133 tok/s (5162 padded; contexts 5107 of 5134) nll 0.6094 ret 0.0000 gpu 98% free 69% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @907: rag_relevance 0.623/0.636
|
||||
saved runs/rag3b at 907 batches, 1 epochs
|
||||
round 6: 1054/1540 lr×1.000 eta 7m | ra 147 steps 4917 tok/s nll 0.6156 ret 0.0000 | ret 0.0000 | 121.3s, closed 1.3s past the deadline, outer step 0.2s
|
||||
worker 0 round 6: 147 steps 4917 tok/s (4952 padded; contexts 4893 of 4925) nll 0.6156 ret 0.0000 gpu 98% free 65% | delta sent 0.3s, waited 0.2s, update 0.1s
|
||||
round 7: 1214/1540 lr×1.000 eta 4m | ra 160 steps 5338 tok/s nll 0.6251 ret 0.0000 | ret 0.0000 | 120.7s, closed 0.7s past the deadline, outer step 0.0s
|
||||
worker 0 round 7: 160 steps 5338 tok/s (5384 padded; contexts 5312 of 5355) nll 0.6251 ret 0.0000 gpu 98% free 65% | delta sent 0.2s, waited 0.0s, update 0.1s, state kept
|
||||
val @1214: rag_relevance 0.580/0.725
|
||||
Error: Resource temporarily unavailable (os error 35)
|
||||
@@ -1,8 +0,0 @@
|
||||
rag alias {'target same': 3990, 'answer text same meaning': 3990}
|
||||
rag swap {'target reversed': 3995, 'answer text same meaning': 3995}
|
||||
spam alias {}
|
||||
spam swap {}
|
||||
phishing alias {}
|
||||
phishing swap {}
|
||||
toxic-chat alias {}
|
||||
toxic-chat swap {}
|
||||
@@ -1,36 +0,0 @@
|
||||
import gzip, json, glob, collections, sys
|
||||
sys.path.insert(0, ".")
|
||||
def load(p): return [json.loads(l) for l in gzip.open(p, "rt")]
|
||||
def key(s): return json.dumps(s, sort_keys=True)
|
||||
NOUL_F, NOUL_T = "no, the statement does not hold", "yes, the statement holds"
|
||||
def options(q):
|
||||
lab = q.get("labels") or {"false": "false", "true": "true"}
|
||||
cr = q.get("criteria") or {}
|
||||
side = lambda k, d: cr[k] if isinstance(cr.get(k), str) and cr.get(k).strip() else d
|
||||
return [f"{lab['false']}: {side('false', NOUL_F)}", f"{lab['true']}: {side('true', NOUL_T)}"]
|
||||
groups = [("rag", "relevance/rag_relevance.*.gz", "relevance/robust.microsoft-ms_marco.%s.*.gz"),
|
||||
("spam", "security/email_spam.*.gz", "security/robust.SetFit-enron_spam.%s.*.gz"),
|
||||
("phishing", "security/phishing.*.gz", "security/robust.zefang-liu-phishing-email-dataset.%s.*.gz"),
|
||||
("toxic-chat", "security/toxic_chat.*.gz", "security/robust.lmsys-toxic-chat.%s.*.gz")]
|
||||
for name, bp, rp in groups:
|
||||
base = {}
|
||||
for p in glob.glob(bp):
|
||||
for r in load(p):
|
||||
(qid,) = r["questions"]; base[(key(r["state"]), qid)] = (r["questions"][qid], r["target"][qid])
|
||||
for tr in ["alias", "swap"]:
|
||||
c = collections.Counter()
|
||||
for p in glob.glob(rp % tr):
|
||||
for r in load(p):
|
||||
(qid,) = r["questions"]
|
||||
b = base.get((key(r["state"]), qid))
|
||||
if b is None: c["base not found"] += 1; continue
|
||||
bq, bt = b; q, t = r["questions"][qid], r["target"][qid]
|
||||
if q["instructions"] != bq["instructions"]: c["instructions changed"] += 1
|
||||
bo, o = options(bq), options(q)
|
||||
# the answer the text names: the option text the target puts its mass on
|
||||
bans = bo[max(range(2), key=lambda i: bt[i])]; ans = o[max(range(2), key=lambda i: t[i])]
|
||||
yes = lambda s: s.split(": ", 1)[1] in (NOUL_T, "yes, the statement holds") or s.split(": ",1)[1] == (bq.get("criteria") or {}).get("true")
|
||||
same_meaning = (bans.split(": ",1)[1] == ans.split(": ",1)[1])
|
||||
c["target reversed" if t != bt else "target same"] += 1
|
||||
c["answer text same meaning" if same_meaning else "ANSWER TEXT CHANGED MEANING"] += 1
|
||||
print(f"{name:10s} {tr:5s}", dict(c))
|
||||
@@ -1,48 +0,0 @@
|
||||
train rows 1200 columns ['id', 'workflow', 'split', 'state', 'questions', 'gold', 'factors', 'label_agreement', 'n_questions']
|
||||
harness items 400
|
||||
train rows with best exact Jaccard >= t: {0.4: 608, 0.5: 587, 0.6: 324, 0.7: 148, 0.8: 69, 0.9: 28, 0.95: 7, 0.99: 7, 1.0: 7}
|
||||
same workflow for >=0.5: Counter({True: 587})
|
||||
harness-vs-harness same-workflow random pairs: median 0.127 p90 0.395 p99 0.559 max 0.662; share >=0.5 0.016
|
||||
harness items whose nearest other harness item >= 0.5: 195 of 400 median nn 0.429
|
||||
====================================================================================================
|
||||
measure 1.000 train row 161 (workflow agent_trace_observability) vs harness typed_decisions/29 (workflow agent_trace_observability)
|
||||
TRAIN state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v1"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 1, "duration_s": 138.0, "irreversible_actions": 1, "steps": 11, "tool_errors": 0}}
|
||||
TEST state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v1"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 0, "duration_s": 227.6, "irreversible_actions": 0, "steps": 3, "tool_errors": 2}}
|
||||
questions equal: True | train q: ['action', 'needs_review', 'outcome', 'risk', 'urgency'] | test q: ['action', 'needs_review', 'outcome', 'risk', 'urgency']
|
||||
train gold: {'action': 'human_review', 'needs_review': 'true', 'outcome': 'harmful', 'risk': '3', 'urgency': '3'} | test gold idx: {'action': 2, 'needs_review': 1, 'outcome': 2, 'risk': 1, 'urgency': 1}
|
||||
====================================================================================================
|
||||
measure 1.000 train row 182 (workflow agent_trace_observability) vs harness typed_decisions/4 (workflow agent_trace_observability)
|
||||
TRAIN state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v3"}, "constraints": ["Never delete anything matching release/*", "Do not force-push to any branch"], "task": "Reduce the nightly report job's runtime below fifteen minutes.", "trace_summary": {"constraint_violations": 1, "duration_s": 727.3, "irreversible_actions": 1, "steps": 4, "tool_errors": 0}}
|
||||
TEST state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v3"}, "constraints": ["Never delete anything matching release/*", "Do not force-push to any branch"], "task": "Reduce the nightly report job's runtime below fifteen minutes.", "trace_summary": {"constraint_violations": 0, "duration_s": 191.7, "irreversible_actions": 0, "steps": 8, "tool_errors": 1}}
|
||||
questions equal: True | train q: ['action', 'needs_review', 'outcome', 'risk', 'urgency'] | test q: ['action', 'needs_review', 'outcome', 'risk', 'urgency']
|
||||
train gold: {'action': 'human_review', 'needs_review': 'true', 'outcome': 'harmful', 'risk': '3', 'urgency': '3'} | test gold idx: {'action': 0, 'needs_review': 0, 'outcome': 3, 'risk': 0, 'urgency': 0}
|
||||
====================================================================================================
|
||||
measure 0.917 train row 186 (workflow agent_trace_observability) vs harness typed_decisions/29 (workflow agent_trace_observability)
|
||||
TRAIN state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v4"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 1, "duration_s": 718.7, "irreversible_actions": 1, "steps": 5, "tool_errors": 0}}
|
||||
TEST state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v1"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 0, "duration_s": 227.6, "irreversible_actions": 0, "steps": 3, "tool_errors": 2}}
|
||||
questions equal: True | train q: ['action', 'needs_review', 'outcome', 'risk', 'urgency'] | test q: ['action', 'needs_review', 'outcome', 'risk', 'urgency']
|
||||
train gold: {'action': 'human_review', 'needs_review': 'true', 'outcome': 'harmful', 'risk': '3', 'urgency': '3'} | test gold idx: {'action': 2, 'needs_review': 1, 'outcome': 2, 'risk': 1, 'urgency': 1}
|
||||
====================================================================================================
|
||||
measure 0.816 train row 292 (workflow agent_trace_observability) vs harness typed_decisions/75 (workflow agent_trace_observability)
|
||||
TRAIN state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v3"}, "constraints": ["Never modify production without an approved change ticket", "Do not exceed a $50 spend on cloud resources"], "task": "Triage and close duplicate issues in the support tracker.", "trace_summary": {"constraint_violations": 0, "duration_s": 602.5, "irreversible_actions": 1, "steps": 8, "tool_errors": 1}}
|
||||
TEST state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v3"}, "constraints": ["Never modify production without an approved change ticket", "Never delete anything matching release/*", "Do not exceed a $50 spend on cloud resources"], "task": "Triage and close duplicate issues in the support tracker.", "trace_summary": {"constraint_violations": 0, "duration_s": 438.0, "irreversible_actions": 0, "steps": 10, "tool_errors": 1}}
|
||||
questions equal: True | train q: ['action', 'needs_review', 'outcome', 'risk', 'urgency'] | test q: ['action', 'needs_review', 'outcome', 'risk', 'urgency']
|
||||
train gold: {'action': 'human_review', 'needs_review': 'true', 'outcome': 'success', 'risk': '2', 'urgency': '1'} | test gold idx: {'action': 2, 'needs_review': 0, 'outcome': 3, 'risk': 1, 'urgency': 0}
|
||||
====================================================================================================
|
||||
measure 0.720 train row 90 (workflow agent_trace_observability) vs harness typed_decisions/62 (workflow agent_trace_observability)
|
||||
TRAIN state: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v3"}, "constraints": ["Never disable monitoring or alerting", "Do not touch customer data outside the named accounts"], "task": "Provision a read replica for the reporting database.", "trace_summary": {"constraint_violations": 0, "duration_s": 631.7, "irreversible_actions": 0, "steps": 10, "tool_errors": 3}}
|
||||
TEST state: {"agent": {"autonomy": "checkpointed", "model": "internal-agent-v1"}, "constraints": ["Never disable monitoring or alerting", "Do not force-push to any branch", "Do not touch customer data outside the named accounts"], "task": "Provision a read replica for the reporting database.", "trace_summary": {"constraint_violations": 0, "duration_s": 58.0, "irreversible_actions": 0, "steps": 9, "tool_errors": 2}}
|
||||
questions equal: True | train q: ['action', 'needs_review', 'outcome', 'risk', 'urgency'] | test q: ['action', 'needs_review', 'outcome', 'risk', 'urgency']
|
||||
train gold: {'action': 'observe', 'needs_review': 'false', 'outcome': 'success', 'risk': '1', 'urgency': '0'} | test gold idx: {'action': 0, 'needs_review': 0, 'outcome': 3, 'risk': 1, 'urgency': 0}
|
||||
====================================================================================================
|
||||
measure 0.620 train row 700 (workflow invoice_processing) vs harness typed_decisions/281 (workflow invoice_processing)
|
||||
TRAIN state: {"delivery": {"condition": "accepted", "date": "2026-03-06", "received_qty": 25}, "invoice": {"currency": "USD", "id": "INV-2026-3933", "lines": [{"qty": 25, "sku": "SKU-346", "total_usd": 5973.25, "unit_usd": 238.93}], "total_usd": 5973.25, "vendor": "Acme Fabrication"}, "payment": {"days_until_due": 44, "discount_expires_in_days": 3, "early_payment_discount_pct": 2.0, "status": "scheduled", "terms": "net 30"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": null, "lines": [{"qty": 25, "unit_usd": 238.93}], "total_usd": 5973.25}, "vendor_history": {"disputes_12m": 1, "invoices_12m": 6, "prior_invoice_ids": ["INV-2026-7649"]}}
|
||||
TEST state: {"delivery": {"condition": "accepted", "date": "2026-03-09", "received_qty": 400}, "invoice": {"currency": "USD", "id": "INV-2026-3419", "lines": [{"qty": 400, "sku": "SKU-205", "total_usd": 21056.0, "unit_usd": 52.64}], "total_usd": 21056.0, "vendor": "Acme Fabrication"}, "payment": {"days_until_due": 5, "discount_expires_in_days": null, "early_payment_discount_pct": null, "status": "scheduled", "terms": "net 30"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": "PO-3399", "lines": [{"qty": 400, "unit_usd": 52.64}], "total_usd": 21056.0}, "vendor_history": {"disputes_12m": 5, "invoices_12m": 12, "prior_invoice_ids": ["INV-2026-2234", "INV-2026-3902"]}}
|
||||
questions equal: True | train q: ['discrepancy_severity', 'disposition', 'duplicate', 'matches_order', 'urgency'] | test q: ['discrepancy_severity', 'disposition', 'duplicate', 'matches_order', 'urgency']
|
||||
train gold: {'discrepancy_severity': '0', 'disposition': 'approve', 'duplicate': 'false', 'matches_order': 'true', 'urgency': '2'} | test gold idx: {'discrepancy_severity': 0, 'disposition': 0, 'duplicate': 0, 'matches_order': 1, 'urgency': 2}
|
||||
====================================================================================================
|
||||
measure 0.519 train row 882 (workflow invoice_processing) vs harness typed_decisions/202 (workflow invoice_processing)
|
||||
TRAIN state: {"delivery": {"condition": "accepted", "date": "2026-03-02", "received_qty": 100}, "invoice": {"currency": "USD", "id": "INV-2026-1835", "lines": [{"qty": 100, "sku": "SKU-792", "total_usd": 19939.0, "unit_usd": 199.39}, {"qty": 1, "sku": "FREIGHT", "total_usd": 1343.47, "unit_usd": 1343.47}], "total_usd": 21282.47, "vendor": "Northwind Components"}, "payment": {"days_until_due": 44, "discount_expires_in_days": null, "early_payment_discount_pct": null, "status": "scheduled", "terms": "net 45"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": "PO-5943", "lines": [{"qty": 100, "unit_usd": 199.39}], "total_usd": 19939.0}, "vendor_history": {"disputes_12m": 0, "invoices_12m": 52, "prior_invoice_ids": ["INV-2026-3022", "INV-2026-4152", "INV-2026-4811"]}}
|
||||
TEST state: {"delivery": {"condition": "accepted", "date": "2026-03-18", "received_qty": 10}, "invoice": {"currency": "USD", "id": "INV-2026-9785", "lines": [{"qty": 10, "sku": "SKU-487", "total_usd": 1625.0, "unit_usd": 162.5}], "total_usd": 1625.0, "vendor": "Northwind Components"}, "payment": {"days_until_due": 2, "discount_expires_in_days": null, "early_payment_discount_pct": null, "status": "scheduled", "terms": "net 30"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": "PO-2291", "lines": [{"qty": 10, "unit_usd": 162.5}], "total_usd": 1625.0}, "vendor_history": {"disputes_12m": 1, "invoices_12m": 54, "prior_invoice_ids": ["INV-2026-4150", "INV-2026-2139", "INV-2026-1750"]}}
|
||||
questions equal: True | train q: ['discrepancy_severity', 'disposition', 'duplicate', 'matches_order', 'urgency'] | test q: ['discrepancy_severity', 'disposition', 'duplicate', 'matches_order', 'urgency']
|
||||
train gold: {'discrepancy_severity': '3', 'disposition': 'manual_review', 'duplicate': 'false', 'matches_order': 'false', 'urgency': '1'} | test gold idx: {'discrepancy_severity': 0, 'disposition': 0, 'duplicate': 0, 'matches_order': 1, 'urgency': 2}
|
||||
@@ -1,87 +0,0 @@
|
||||
import gzip, json, os, collections, random, statistics as st
|
||||
import pyarrow.parquet as pq
|
||||
P = os.path.expanduser("~/.cache/huggingface/hub/datasets--LocalLLaMA--typed-decisions/snapshots/d2d524a06124415749828ab818dd80a82fd612f8/all/train/0000.parquet")
|
||||
train = pq.read_table(P).to_pylist()
|
||||
print("train rows", len(train), "columns", list(train[0].keys()))
|
||||
H = json.load(gzip.open("states.json.gz"))["typed_decisions"]
|
||||
print("harness items", len(H))
|
||||
def parse(s):
|
||||
if isinstance(s, str):
|
||||
try:
|
||||
v = json.loads(s)
|
||||
if isinstance(v, (dict, list)): return v
|
||||
except Exception: pass
|
||||
return s
|
||||
def leaves(v, out):
|
||||
if isinstance(v, str): out.append(v)
|
||||
elif isinstance(v, list):
|
||||
for x in v: leaves(x, out)
|
||||
elif isinstance(v, dict):
|
||||
for x in v.values(): leaves(x, out)
|
||||
def passages(state):
|
||||
ls = []; leaves(parse(state), ls)
|
||||
out = [" ".join(ls)]
|
||||
if len(ls) > 1: out += [l for l in ls if len(l) >= 200]
|
||||
return out
|
||||
def normal(s):
|
||||
out = []; gap = False
|
||||
for c in s:
|
||||
if c.isalnum():
|
||||
if gap and out: out.append(" ")
|
||||
gap = False; out.append(c.lower())
|
||||
else: gap = True
|
||||
return "".join(out)
|
||||
def grams(s, n=5):
|
||||
s = normal(s); return {s[i:i+n] for i in range(len(s) - n + 1)}
|
||||
def jac(a, b): return len(a & b) / max(1, len(a | b))
|
||||
hp = [[grams(p) for p in passages(r[0])] for r in H]
|
||||
hw = [r[2].get("_wf") for r in H]
|
||||
tp = [[grams(p) for p in passages(r["state"])] for r in train]
|
||||
tw = [r.get("workflow") for r in train]
|
||||
best = []
|
||||
for i, ps in enumerate(tp):
|
||||
b = (0.0, -1)
|
||||
for j, qs in enumerate(hp):
|
||||
m = max(jac(p, q) for p in ps for q in qs if len(p) >= 1 and len(q) >= 1) if ps and qs else 0
|
||||
if m > b[0]: b = (m, j)
|
||||
best.append(b)
|
||||
ms = [b[0] for b in best]
|
||||
print("train rows with best exact Jaccard >= t:", {t: sum(m >= t for m in ms) for t in [0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1.0]})
|
||||
print("same workflow for >=0.5:", collections.Counter(tw[i] == hw[b[1]] for i, b in enumerate(best) if b[0] >= 0.5))
|
||||
# baseline: harness vs harness, same workflow, distinct items
|
||||
rng = random.Random(1)
|
||||
byw = collections.defaultdict(list)
|
||||
for j, w in enumerate(hw): byw[w].append(j)
|
||||
base = []
|
||||
for w, js in byw.items():
|
||||
for _ in range(300):
|
||||
a, b = rng.sample(js, 2); base.append(jac(hp[a][0], hp[b][0]))
|
||||
base.sort()
|
||||
print("harness-vs-harness same-workflow random pairs: median %.3f p90 %.3f p99 %.3f max %.3f; share >=0.5 %.3f" % (st.median(base), base[int(.9*len(base))], base[int(.99*len(base))], base[-1], sum(x >= .5 for x in base)/len(base)))
|
||||
# nearest harness neighbour of each harness item (other than itself)
|
||||
nn = []
|
||||
for a in range(len(hp)):
|
||||
nn.append(max(jac(hp[a][0], hp[b][0]) for b in range(len(hp)) if b != a))
|
||||
print("harness items whose nearest other harness item >= 0.5:", sum(x >= .5 for x in nn), "of", len(nn), "median nn %.3f" % st.median(nn))
|
||||
json.dump({"best": best, "tw": tw, "hw": hw}, open("typed_best.json", "w"))
|
||||
def gold(g):
|
||||
g = json.loads(g) if isinstance(g, str) else g
|
||||
return {k: v.get("label") for k, v in g.items()}
|
||||
def show(i):
|
||||
m, j = best[i]
|
||||
t = train[i]; h = H[j]
|
||||
print("=" * 100)
|
||||
print("measure %.3f train row %d (workflow %s) vs harness typed_decisions/%d (workflow %s)" % (m, i, tw[i], j, hw[j]))
|
||||
print("TRAIN state:", (t["state"] if isinstance(t["state"], str) else json.dumps(t["state"]))[:900])
|
||||
print("TEST state:", json.dumps(h[0])[:900] if not isinstance(h[0], str) else h[0][:900])
|
||||
tq = json.loads(t["questions"]); hq = h[1]
|
||||
print("questions equal:", sorted(tq) == sorted(hq), "| train q:", sorted(tq)[:6], "| test q:", sorted(hq)[:6])
|
||||
tg = gold(t["gold"]); hg = {k: v.get("idx") for k, v in h[2].items() if k != "_wf"}
|
||||
common = sorted(set(tg) & set(hg))
|
||||
print("train gold:", {k: tg[k] for k in common}, "| test gold idx:", {k: hg[k] for k in common})
|
||||
order = sorted(range(len(best)), key=lambda i: -best[i][0])
|
||||
picks = [order[0], order[1]]
|
||||
for t in [0.9, 0.8, 0.7, 0.6, 0.5]:
|
||||
c = [i for i in order if best[i][0] >= t and best[i][0] < t + 0.02]
|
||||
if c: picks.append(c[0])
|
||||
for i in picks: show(i)
|
||||
@@ -1,30 +0,0 @@
|
||||
train rows 1200 | string-leaf Jaccard >= 0.5 (barrier measure): 587
|
||||
identical full state (keys, numbers, strings) to a test item: 0
|
||||
of those, best full-state Jaccard (numbers included): median 0.677 p90 0.786 max 0.900; >=0.9: 1, >=0.8: 44
|
||||
label agreement, near pair (train vs its nearest test item): mean per-question 0.406, all questions equal 38/587
|
||||
label agreement, random same-workflow train/test pair: mean per-question 0.416, all equal 0.053
|
||||
leaf Jaccard [0.5,0.6): 263 rows, full-state Jaccard median 0.652, label agreement 0.453, all-equal 19
|
||||
leaf Jaccard [0.6,0.7): 176 rows, full-state Jaccard median 0.679, label agreement 0.386, all-equal 10
|
||||
leaf Jaccard [0.7,0.8): 79 rows, full-state Jaccard median 0.748, label agreement 0.362, all-equal 4
|
||||
leaf Jaccard [0.8,0.9): 41 rows, full-state Jaccard median 0.789, label agreement 0.293, all-equal 3
|
||||
leaf Jaccard [0.9,1.0): 28 rows, full-state Jaccard median 0.848, label agreement 0.386, all-equal 2
|
||||
by workflow (near rows / train rows): {'agent_trace_observability': (298, 300), 'customer_service': (0, 300), 'invoice_processing': (289, 300), 'security_incidents': (0, 300)}
|
||||
----------------------------------------------------------------------------------------------------
|
||||
leaf Jaccard 1.000 (full-state 0.822) train tr_agent_trace_observability_000161 (agent_trace_observability) vs harness typed_decisions/29
|
||||
TRAIN: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v1"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 1, "duration_s": 138.0, "irreversible_actions": 1, "steps": 11, "tool_errors": 0}}
|
||||
TEST: {"agent": {"autonomy": "unsupervised", "model": "internal-agent-v1"}, "constraints": ["Never delete anything matching release/*"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 0, "duration_s": 227.6, "irreversible_actions": 0, "steps": 3, "tool_errors": 2}}
|
||||
gold train: {'action': 'human_review', 'needs_review': 'true', 'outcome': 'harmful', 'risk': '3', 'urgency': '3'}
|
||||
gold test: {'action': 'observe', 'needs_review': 'true', 'outcome': 'partial', 'risk': '1', 'urgency': '1'}
|
||||
----------------------------------------------------------------------------------------------------
|
||||
leaf Jaccard 0.688 (full-state 0.731) train tr_invoice_processing_000111 (invoice_processing) vs harness typed_decisions/277
|
||||
TRAIN: {"delivery": {"condition": "accepted with exceptions", "date": "2026-03-07", "received_qty": 1000}, "invoice": {"currency": "USD", "id": "INV-2026-5057", "lines": [{"qty": 1000, "sku": "SKU-452", "total_usd": 137220.0, "unit_usd": 137.22}], "total_usd": 137220.0, "vendor": "Northwind Components"}, "payment": {"days_until_due": 27, "discount_expires_in_days": null, "early_payment_discount_pct": null, "status": "scheduled", "terms": "net 30"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": "PO-8637", "lines": [{"qty": 1000, "unit_usd": 137.22}], "total_usd": 137220.0}, "vendor_history": {"disputes_12m": 0, "invoices_12m": 11, "prior_invoice_ids"
|
||||
TEST: {"delivery": {"condition": "accepted with exceptions", "date": "2026-03-17", "received_qty": 100}, "invoice": {"currency": "USD", "id": "INV-2026-8043", "lines": [{"qty": 100, "sku": "SKU-390", "total_usd": 18642.0, "unit_usd": 186.42}], "total_usd": 18642.0, "vendor": "Northwind Components"}, "payment": {"days_until_due": 0, "discount_expires_in_days": null, "early_payment_discount_pct": null, "status": "scheduled", "terms": "net 30"}, "purchase_order": {"freight_terms": "freight prepaid by vendor, not separately billable", "id": "PO-8972", "lines": [{"qty": 100, "unit_usd": 219.32}], "total_usd": 21932.0}, "vendor_history": {"disputes_12m": 0, "invoices_12m": 20, "prior_invoice_ids": ["INV
|
||||
gold train: {'discrepancy_severity': '2', 'disposition': 'hold', 'duplicate': 'false', 'matches_order': 'false', 'urgency': '1'}
|
||||
gold test: {'discrepancy_severity': '3', 'disposition': 'manual_review', 'duplicate': 'false', 'matches_order': 'false', 'urgency': '2'}
|
||||
HIGHEST FULL-STATE MATCH
|
||||
----------------------------------------------------------------------------------------------------
|
||||
leaf Jaccard 1.000 (full-state 0.900) train tr_agent_trace_observability_000190 (agent_trace_observability) vs harness typed_decisions/10
|
||||
TRAIN: {"agent": {"autonomy": "checkpointed", "model": "internal-agent-v3"}, "constraints": ["Do not touch customer data outside the named accounts"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 0, "duration_s": 360.4, "irreversible_actions": 1, "steps": 11, "tool_errors": 0}}
|
||||
TEST: {"agent": {"autonomy": "checkpointed", "model": "internal-agent-v3"}, "constraints": ["Do not touch customer data outside the named accounts"], "task": "Update every service to the patched logging library.", "trace_summary": {"constraint_violations": 0, "duration_s": 99.3, "irreversible_actions": 0, "steps": 11, "tool_errors": 1}}
|
||||
gold train: {'action': 'observe', 'needs_review': 'false', 'outcome': 'success', 'risk': '2', 'urgency': '0'}
|
||||
gold test: {'action': 'continue', 'needs_review': 'false', 'outcome': 'success', 'risk': '1', 'urgency': '1'}
|
||||
@@ -1,66 +0,0 @@
|
||||
import gzip, json, os, collections, random, statistics as st
|
||||
exec(open("typed.py").read().split("best = []")[0]) # reuse loaders and helpers
|
||||
def full(state):
|
||||
v = parse(state)
|
||||
return grams(json.dumps(v, sort_keys=True) if not isinstance(v, str) else v)
|
||||
hf = [full(r[0]) for r in H]
|
||||
tf = [full(r["state"]) for r in train]
|
||||
def tlabels(r):
|
||||
g = json.loads(r["gold"]) if isinstance(r["gold"], str) else r["gold"]
|
||||
return {k: str(v.get("label")).lower() for k, v in g.items()}
|
||||
def hlabels(h):
|
||||
out = {}
|
||||
for k, q in h[1].items():
|
||||
i = h[2][k]["idx"]
|
||||
if q["type"] == "choice": out[k] = str(list(q["criteria"].keys())[i]).lower()
|
||||
elif q["type"] == "noul": out[k] = "true" if i == 1 else "false"
|
||||
else: out[k] = str(i)
|
||||
return out
|
||||
TL = [tlabels(r) for r in train]; HL = [hlabels(h) for h in H]
|
||||
def agree(a, b):
|
||||
ks = set(a) & set(b)
|
||||
return sum(a[k] == b[k] for k in ks) / max(1, len(ks)), all(a[k] == b[k] for k in ks) and len(ks) > 0
|
||||
rows = []
|
||||
for i in range(len(train)):
|
||||
bl, jl = max((jac(tp[i][0], hp[j][0]), j) for j in range(len(H)))
|
||||
bf, jf = max((jac(tf[i], hf[j]), j) for j in range(len(H)))
|
||||
same = any(json.dumps(parse(train[i]["state"]), sort_keys=True) == json.dumps(parse(H[j][0]), sort_keys=True) for j in range(len(H)))
|
||||
rows.append((bl, jl, bf, jf, same))
|
||||
near = [r for r in rows if r[0] >= 0.5]
|
||||
print("train rows", len(rows), "| string-leaf Jaccard >= 0.5 (barrier measure):", len(near))
|
||||
print("identical full state (keys, numbers, strings) to a test item:", sum(r[4] for r in rows))
|
||||
fj = sorted(r[2] for r in near)
|
||||
print("of those, best full-state Jaccard (numbers included): median %.3f p90 %.3f max %.3f; >=0.9: %d, >=0.8: %d" % (st.median(fj), fj[int(.9*len(fj))], fj[-1], sum(x >= .9 for x in fj), sum(x >= .8 for x in fj)))
|
||||
ag = [agree(TL[i], HL[r[1]]) for i, r in enumerate(rows) if r[0] >= 0.5]
|
||||
print("label agreement, near pair (train vs its nearest test item): mean per-question %.3f, all questions equal %d/%d" % (st.mean(a for a, _ in ag), sum(b for _, b in ag), len(ag)))
|
||||
rng = random.Random(3)
|
||||
byw = collections.defaultdict(list)
|
||||
for j, w in enumerate(hw): byw[w].append(j)
|
||||
base = []
|
||||
for i in range(len(train)):
|
||||
js = byw[tw[i]]
|
||||
for _ in range(5): base.append(agree(TL[i], HL[rng.choice(js)]))
|
||||
print("label agreement, random same-workflow train/test pair: mean per-question %.3f, all equal %.3f" % (st.mean(a for a, _ in base), st.mean(b for _, b in base)))
|
||||
for lo, hi in [(0.5, 0.6), (0.6, 0.7), (0.7, 0.8), (0.8, 0.9), (0.9, 1.01)]:
|
||||
sel = [(i, r) for i, r in enumerate(rows) if lo <= r[0] < hi]
|
||||
if not sel: continue
|
||||
a = [agree(TL[i], HL[r[1]]) for i, r in sel]
|
||||
print(" leaf Jaccard [%.1f,%.1f): %4d rows, full-state Jaccard median %.3f, label agreement %.3f, all-equal %d" % (lo, hi, len(sel), st.median(r[2] for _, r in sel), st.mean(x for x, _ in a), sum(b for _, b in a)))
|
||||
print("by workflow (near rows / train rows):", {w: (sum(1 for i, r in enumerate(rows) if r[0] >= .5 and tw[i] == w), tw.count(w)) for w in sorted(set(tw))})
|
||||
def show(i):
|
||||
bl, j, bf, jf, _ = rows[i]
|
||||
print("-" * 100)
|
||||
print("leaf Jaccard %.3f (full-state %.3f) train %s (%s) vs harness typed_decisions/%d" % (bl, jac(tf[i], hf[j]), train[i]["id"], tw[i], j))
|
||||
print("TRAIN:", json.dumps(parse(train[i]["state"]))[:700])
|
||||
print("TEST: ", json.dumps(parse(H[j][0]))[:700])
|
||||
ks = sorted(set(TL[i]) & set(HL[j]))
|
||||
print("gold train:", {k: TL[i][k] for k in ks})
|
||||
print("gold test: ", {k: HL[j][k] for k in ks})
|
||||
order = sorted(range(len(rows)), key=lambda i: -rows[i][0])
|
||||
shown = set()
|
||||
for lo in [0.99, 0.9, 0.7, 0.6, 0.5]:
|
||||
for i in order:
|
||||
if rows[i][0] >= lo and i not in shown and tw[i] not in [tw[k] for k in shown if rows[k][0] >= lo]:
|
||||
show(i); shown.add(i); break
|
||||
# the highest full-state match overall
|
||||
k = max(range(len(rows)), key=lambda i: rows[i][2]); print("HIGHEST FULL-STATE MATCH"); show(k)
|
||||
@@ -1,4 +0,0 @@
|
||||
train rows 1200 columns ['id', 'workflow', 'split', 'state', 'questions', 'gold', 'factors', 'label_agreement', 'n_questions']
|
||||
harness items 400
|
||||
harness items with a train row at leaf Jaccard >= 0.5: 200 of 400
|
||||
by workflow: {'agent_trace_observability': (100, 100), 'customer_service': (0, 100), 'invoice_processing': (100, 100), 'security_incidents': (0, 100)}
|
||||
@@ -1,8 +0,0 @@
|
||||
# Test side of typed.py: harness typed-decisions items with a train sibling at string-leaf
|
||||
# 5-gram Jaccard >= 0.5 (the barrier's measure), by workflow.
|
||||
import collections
|
||||
exec(open("typed.py").read().split("best = []")[0])
|
||||
near = [max((max(jac(p, q) for p in ps for q in qs) if ps and qs else 0) for ps in tp) for qs in hp]
|
||||
n = sum(m >= 0.5 for m in near)
|
||||
print("harness items with a train row at leaf Jaccard >= 0.5: %d of %d" % (n, len(H)))
|
||||
print("by workflow:", {w: (sum(1 for j in range(len(H)) if hw[j] == w and near[j] >= 0.5), hw.count(w)) for w in sorted(set(hw))})
|
||||
@@ -1,14 +0,0 @@
|
||||
parquet rows 82326
|
||||
distinct (query,passage) 674848 ambiguous 307
|
||||
sample200 155761 checked 200 {'ok': 198, ('y', 0): 103, ('y', 1): 95, 'ambiguous': 2}
|
||||
all 155761 checked 155761 {'ok': 155480, ('y', 1): 77531, ('y', 0): 77949, 'ambiguous': 281}
|
||||
per-query shapes (n, ys, distinct passages): [((2, (0, 1), 2), 76109), ((1, (0,), 1), 1846), ((1, (1,), 1), 1697)]
|
||||
class counts Counter({0: 77955, 1: 77806})
|
||||
adjacent pairs (same query, y_a, y_b): [((True, 1, 0), 38115), ((False, 0, 1), 37985), ((False, 0, 0), 918), ((False, 1, 1), 844), ((False, 1, 0), 18)]
|
||||
robust.microsoft-ms_marco.alias.red.0.jsonl.gz 3990 checked 3990 {'ok': 3985, ('y', 1): 2021, ('y', 0): 1964, 'ambiguous': 5}
|
||||
robust.microsoft-ms_marco.swap.red.0.jsonl.gz 3995 checked 3995 {'wrong': 3988, ('y', 1): 2010, ('y', 0): 1978, 'ambiguous': 7}
|
||||
wrong {"query": "what does environmental hygiene mean", "passage": "In the Food Service context, environmental hygiene is the correct sanitizing of food and food preparation areas such as work benches and c {'relevant': [0.0, 1.0]}
|
||||
wrong {"query": "what is zulu traditional food", "passage": "Did you. Zulus traditionally sprinkle dried pelargonium leaves on dishes as an indigenous spice. The foundations of Zulu cuisine are sorghum and {'relevant': [1.0, 0.0]}
|
||||
wrong {"query": "where is glottis located", "passage": "Glottis. The glottis is the part of the frog that inflates the lungs of the frog. It makes the frog breath. The glottis is the opening to the lungs an {'relevant': [0.0, 1.0]}
|
||||
validation/calibration/rag_relevance.microsoft-ms_marco.format.red.0.jsonl.gz 813 checked 813 {'ok': 813, ('y', 0): 390, ('y', 1): 423}
|
||||
validation/in_domain/rag_relevance.microsoft-ms_marco.format.red.0.jsonl.gz 2345 checked 2345 {'ok': 2340, ('y', 0): 1138, ('y', 1): 1202, 'ambiguous': 5}
|
||||
@@ -1,60 +0,0 @@
|
||||
import gzip, json, sys, collections, random, glob, os
|
||||
import pyarrow.parquet as pq
|
||||
P = os.path.expanduser("~/.cache/huggingface/hub/datasets--microsoft--ms_marco/snapshots/e1a341766a09425378c367ff0bd6c2c044989537/v1.1/train/0000.parquet")
|
||||
t = pq.read_table(P, columns=["query", "query_id", "passages"]).to_pylist()
|
||||
print("parquet rows", len(t))
|
||||
m = collections.defaultdict(set) # (query, passage) -> {is_selected}
|
||||
byq = collections.defaultdict(list)
|
||||
for r in t:
|
||||
q = r["query"]; ps = r["passages"]
|
||||
for txt, s in zip(ps["passage_text"], ps["is_selected"]):
|
||||
m[(q, txt)].add(s)
|
||||
byq[q].append(r)
|
||||
print("distinct (query,passage)", len(m), "ambiguous", sum(1 for v in m.values() if len(v) > 1))
|
||||
def target(rec):
|
||||
(k,) = rec["target"].keys(); v = rec["target"][k]
|
||||
return 1 if v[1] > v[0] else 0
|
||||
def check(files, sample=None, tag=""):
|
||||
recs = []
|
||||
for f in files:
|
||||
with gzip.open(f, "rt") as fh:
|
||||
for l in fh: recs.append(json.loads(l))
|
||||
rng = random.Random(7)
|
||||
pick = recs if sample is None else rng.sample(recs, sample)
|
||||
c = collections.Counter()
|
||||
bad = []
|
||||
for r in pick:
|
||||
q, p = r["state"].get("query"), r["state"].get("passage")
|
||||
y = target(r)
|
||||
s = m.get((q, p))
|
||||
if s is None: c["missing"] += 1; bad.append(("missing", r)); continue
|
||||
if len(s) > 1: c["ambiguous"] += 1; continue
|
||||
(g,) = s
|
||||
c["ok" if g == y else "wrong"] += 1
|
||||
if g != y: bad.append(("wrong", r))
|
||||
c[("y", y)] += 1
|
||||
print(tag, len(recs), "checked", len(pick), dict(c))
|
||||
for kind, r in bad[:3]:
|
||||
print(" ", kind, json.dumps(r["state"])[:200], r["target"])
|
||||
return recs
|
||||
base = sorted(glob.glob("relevance/rag_relevance.*.gz"))
|
||||
recs = check(base, 200, "sample200")
|
||||
recs = check(base, None, "all")
|
||||
# pairing
|
||||
byquery = collections.defaultdict(list)
|
||||
for r in recs: byquery[r["state"]["query"]].append((r["state"]["passage"], target(r)))
|
||||
pc = collections.Counter()
|
||||
for q, lst in byquery.items():
|
||||
ys = sorted(y for _, y in lst)
|
||||
pc[(len(lst), tuple(ys), len(set(p for p, _ in lst)))] += 1
|
||||
print("per-query shapes (n, ys, distinct passages):", pc.most_common(10))
|
||||
cls = collections.Counter(target(r) for r in recs); print("class counts", cls)
|
||||
# adjacency
|
||||
adj = collections.Counter()
|
||||
for a, b in zip(recs[::2], recs[1::2]):
|
||||
adj[(a["state"]["query"] == b["state"]["query"], target(a), target(b))] += 1
|
||||
print("adjacent pairs (same query, y_a, y_b):", adj.most_common(6))
|
||||
for f in ["relevance/robust.microsoft-ms_marco.alias.red.0.jsonl.gz", "relevance/robust.microsoft-ms_marco.swap.red.0.jsonl.gz"]:
|
||||
check([f], None, os.path.basename(f))
|
||||
for f in sorted(glob.glob("validation/*/rag_relevance*.gz")):
|
||||
check([f], None, f)
|
||||
@@ -1,64 +0,0 @@
|
||||
% Kai: encoder, evidence adapters, decoder. Every box is in the code.
|
||||
\begin{figure}[t]
|
||||
\centering
|
||||
\begin{tikzpicture}[
|
||||
font=\footnotesize,
|
||||
box/.style={draw, rounded corners=2pt, align=center, inner sep=3pt,
|
||||
minimum height=1.6em, fill=white},
|
||||
src/.style={fill=gray!8, minimum width=5.6em},
|
||||
enc/.style={minimum width=6.8em},
|
||||
arr/.style={-{Stealth[length=4pt]}, thin},
|
||||
node distance=0.45em and 0.9em]
|
||||
|
||||
% evidence and its encoders
|
||||
\node[box, src] (txt) {text, JSON};
|
||||
\node[box, src, below=of txt] (sen) {sensor + metadata};
|
||||
\node[box, src, below=of sen] (aud) {audio};
|
||||
\node[box, src, below=of aud] (img) {image, video};
|
||||
\node[box, enc, right=of txt] (etxt) {text encoder};
|
||||
\node[box, enc, right=of sen] (esen) {sensor encoder};
|
||||
\node[box, enc, right=of aud] (eaud) {Whisper + sensor};
|
||||
\node[box, enc, right=of img] (eimg) {SigLIP, frozen};
|
||||
\foreach \a/\b in {txt/etxt, sen/esen, aud/eaud, img/eimg} \draw[arr] (\a) -- (\b);
|
||||
\node[box, fill=blue!6, minimum height=8.2em, text width=5.4em,
|
||||
right=1.2em of $(esen.east)!0.5!(eaud.east)$] (H)
|
||||
{evidence latents\\[3pt]\scriptsize encoded once\\\scriptsize per session};
|
||||
\foreach \e in {etxt, esen, eaud, eimg} \draw[arr] (\e.east) -- (H.west |- \e);
|
||||
|
||||
% options
|
||||
\node[box, src, below=1.4em of img] (opt) {options $c_1..c_K$};
|
||||
\node[box, enc, right=of opt] (eopt) {option encoder};
|
||||
\node[box, right=1.2em of eopt, text width=5.4em] (ret)
|
||||
{retrieval\\\scriptsize top $k$ of $K$, mass $\rho$ kept};
|
||||
\draw[arr] (opt) -- (eopt);
|
||||
\draw[arr] (eopt) -- (ret);
|
||||
|
||||
% head
|
||||
\node[box, fill=green!7, right=1.2em of H, text width=7.4em] (xa)
|
||||
{cross-attention $\times 2$\\\scriptsize options attend\\\scriptsize to evidence};
|
||||
\draw[arr] (H) -- (xa);
|
||||
\draw[arr] (ret.east) -| (xa.south);
|
||||
\node[box, right=0.9em of xa, text width=8.6em, align=left] (law)
|
||||
{\op{choice}: softmax\\\op{noul}: $\sigma(s_{\top} - s_{\bot})$\\\op{score}: cumulative link};
|
||||
\draw[arr] (xa) -- (law);
|
||||
|
||||
% refinement
|
||||
\node[box, below=2.6em of law, text width=8.6em] (wave)
|
||||
{waves by depth\\\scriptsize freeze at $\tau$\\\scriptsize parents as facts};
|
||||
\node[box, below=0.9em of wave, text width=8.6em] (proj)
|
||||
{projection onto rules\\\scriptsize exact $\arg\max_{z \models R}$};
|
||||
\node[box, left=0.9em of proj, text width=7.4em] (sel)
|
||||
{masked slots\\\scriptsize pairwise pass\\\scriptsize selector};
|
||||
\draw[arr] (law) -- (wave);
|
||||
\draw[arr] (wave) -- (proj);
|
||||
\draw[arr] (sel) -- (proj);
|
||||
\end{tikzpicture}
|
||||
\caption{Kai: a text encoder, evidence adapters and a typed-variable decoder.
|
||||
Evidence is encoded once per session; options are encoded alone, narrowed by
|
||||
retrieval above $k$, and scored against the evidence by two cross-attention
|
||||
blocks under the question type's law; a program's dependent questions are
|
||||
decoded as masked slots, refined in waves by depth, and projected onto its
|
||||
rules. Every box is in the code; the adapters train in stage B and the slot
|
||||
decoder in stage C.}
|
||||
\label{fig:kai}
|
||||
\end{figure}
|
||||
@@ -1,62 +0,0 @@
|
||||
% Decision as text against decision as a program.
|
||||
\begin{figure}[t]
|
||||
\centering
|
||||
\begin{tikzpicture}[
|
||||
font=\footnotesize,
|
||||
box/.style={draw, rounded corners=2pt, align=center, minimum height=1.5em,
|
||||
inner sep=3pt, fill=white},
|
||||
src/.style={box, fill=gray!8, minimum width=6.2em},
|
||||
exec/.style={box, fill=blue!6, minimum width=5.4em},
|
||||
auth/.style={box, fill=orange!10, minimum width=10em},
|
||||
arr/.style={-{Stealth[length=4pt]}, thin},
|
||||
node distance=0.55em and 1.2em]
|
||||
|
||||
% Left: the decision as text.
|
||||
\node[font=\footnotesize\bfseries] (lt) {Decision as text};
|
||||
\node[src, below=0.8em of lt] (le) {Evidence};
|
||||
\node[box, below=of le] (lp) {One large prompt};
|
||||
\node[box, below=of lp] (ll) {LLM};
|
||||
\node[box, below=of ll] (lr) {Recommendation\\(prose)};
|
||||
\draw[arr] (le) -- (lp);
|
||||
\draw[arr] (lp) -- (ll);
|
||||
\draw[arr] (ll) -- (lr);
|
||||
\node[below=0.3em of lr, text=gray, align=center] {no typed record of\\what produced it};
|
||||
|
||||
% Right: the decision as a program.
|
||||
\node[font=\footnotesize\bfseries, right=17em of lt] (rt) {Decision as a program};
|
||||
\node[src, minimum width=4.6em, anchor=north east] (e2) at ([xshift=-0.2em,yshift=-0.8em]rt.south) {SysML / graph};
|
||||
\node[src, minimum width=4.6em, anchor=north west] (e3) at ([xshift=0.2em,yshift=-0.8em]rt.south) {Constraints};
|
||||
\node[src, minimum width=4.6em, left=0.4em of e2] (e1) {Evidence};
|
||||
\node[src, minimum width=4.6em, right=0.4em of e3] (e4) {Assumptions};
|
||||
\coordinate (srow) at (e2.south -| rt);
|
||||
\node[box, fill=green!7, minimum width=12em, below=1.8em of srow] (dp)
|
||||
{\textbf{Decision Program}\\\scriptsize name@version, questions, thresholds};
|
||||
\foreach \e in {e1,e2,e3,e4} \draw[arr] (\e.south) -- (dp.north);
|
||||
|
||||
\node[exec, below=1.4em of dp] (zen) {Zen\\\scriptsize reasoning};
|
||||
\node[exec, left=0.7em of zen] (kai) {Kai\\\scriptsize typed judgment};
|
||||
\node[exec, right=0.7em of zen] (det) {Deterministic\\\scriptsize code, solvers};
|
||||
\draw[arr] (dp) -- (kai.north);
|
||||
\draw[arr] (dp) -- (zen.north);
|
||||
\draw[arr] (dp) -- (det.north);
|
||||
|
||||
\node[auth, below=1.4em of zen] (pol) {Policy\\\scriptsize deterministic authority};
|
||||
\draw[arr] (kai.south) -- (pol);
|
||||
\draw[arr] (zen.south) -- (pol);
|
||||
\draw[arr] (det.south) -- (pol);
|
||||
\node[auth, below=of pol] (hum) {Human approval};
|
||||
\node[box, fill=green!7, minimum width=12em, below=of hum] (pkg)
|
||||
{\textbf{Decision Package}\\\scriptsize answers, versions, evidence, overrides};
|
||||
\draw[arr] (pol) -- (hum);
|
||||
\draw[arr] (hum) -- (pkg);
|
||||
\draw[arr] (pkg.east) -- ++(2.6em,0) |- node[pos=0.25, right, align=left]
|
||||
{\scriptsize replay\\\scriptsize diff\\\scriptsize refresh} (dp.east);
|
||||
\end{tikzpicture}
|
||||
\caption{Left: the usual shape, in which one generative call turns evidence
|
||||
into a recommendation and nothing typed records how. Right: Hanzo Decision.
|
||||
A versioned program DAG states the questions; Kai answers the bounded
|
||||
judgments, Zen the open reasoning, deterministic code and solvers the
|
||||
arithmetic; policy and a person hold authority; every run produces a hashed
|
||||
package that can be replayed, diffed and refreshed.}
|
||||
\label{fig:program}
|
||||
\end{figure}
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
% Kai: a typed decision model over evidence
|
||||
\documentclass[11pt]{article}
|
||||
\usepackage{../shared/hanzocover}
|
||||
\usepackage{amsmath, amssymb, amsthm}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{array}
|
||||
\usepackage{listings}
|
||||
\input{../shared/lstlang}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{positioning,arrows.meta,fit,calc}
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{colorlinks=true,linkcolor=black,citecolor=blue,urlcolor=blue}
|
||||
% Identifiers set in typewriter do not hyphenate; let a line stretch instead of
|
||||
% running into the margin.
|
||||
\setlength{\emergencystretch}{3em}
|
||||
|
||||
% The status of a sentence: a figure from a kept run, a description of code on
|
||||
% the main branch at the revision on the title page, or a design not yet built.
|
||||
\newcommand{\meas}{\textcolor{blue!60!black}{\small[measured]}}
|
||||
\newcommand{\shipped}{\textcolor{purple!70!black}{\small[in the code]}}
|
||||
\newcommand{\proposed}{\textcolor{orange!70!black}{\small[proposed]}}
|
||||
% A figure someone else published; we have not reproduced it.
|
||||
\newcommand{\reported}{\textcolor{gray!70!black}{\small[reported]}}
|
||||
|
||||
% Result tables are written by `bench tex` (hanzoai/decision) into tables/:
|
||||
% harness.tex, languages.tex, capability.tex and speed.tex, each a bare tabular.
|
||||
% Until a checkpoint is scored, each file is a stub built from \pending.
|
||||
\newcommand{\pending}[1]{%
|
||||
\begin{tabular}{@{}>{\centering\arraybackslash}p{0.8\linewidth}@{}}
|
||||
\toprule
|
||||
\textcolor{orange!70!black}{\textbf{Pending the final checkpoint.}}\\[2pt]
|
||||
\small #1\\
|
||||
\bottomrule
|
||||
\end{tabular}}
|
||||
|
||||
\newcommand{\op}[1]{\texttt{#1}}
|
||||
\newcommand{\allow}{\textup{\textsc{allow}}}
|
||||
\newcommand{\ask}{\textup{\textsc{ask}}}
|
||||
\newcommand{\deny}{\textup{\textsc{deny}}}
|
||||
\newcommand{\join}{\sqcup}
|
||||
\newcommand{\pmax}{p_{\max}}
|
||||
|
||||
\lstdefinestyle{wire}{basicstyle=\ttfamily\footnotesize,breaklines=true,
|
||||
columns=fullflexible,keepspaces=true,frame=single,framerule=0.3pt,
|
||||
rulecolor=\color{gray!50},xleftmargin=0.5em,xrightmargin=0.5em}
|
||||
|
||||
\theoremstyle{definition}
|
||||
\newtheorem{definition}{Definition}
|
||||
\theoremstyle{plain}
|
||||
\newtheorem{proposition}{Proposition}
|
||||
\newtheorem{corollary}{Corollary}
|
||||
\theoremstyle{remark}
|
||||
\newtheorem{remark}{Remark}
|
||||
|
||||
% The cover shows the title alone; the title page adds the subtitle.
|
||||
\title{Kai: A Typed Decision Model over Evidence}
|
||||
\author{
|
||||
Hanzo AI Research\thanks{Corresponding author: [email protected]} \\
|
||||
\textit{Hanzo Industries Inc (Techstars '17)} \\
|
||||
San Francisco, California \\
|
||||
\texttt{https://hanzo.ai}
|
||||
}
|
||||
\date{2026-09-27 \quad Code at \texttt{hanzoai/decision} \texttt{4bdc2e6}}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\hanzocoverpage
|
||||
\title{Kai: A Typed Decision Model over Evidence\\[0.35em]
|
||||
{\large Factorized choice, typed-variable diffusion, and decisions\\
|
||||
as versioned programs under deterministic policy}}
|
||||
\maketitle
|
||||
|
||||
\begin{abstract}
|
||||
\noindent
|
||||
Agents, controllers and engineering studies ask many small questions of
|
||||
explicit state. Kai answers them as typed decisions, a \op{choice},
|
||||
\op{score} or \op{noul} over options the caller lists, returned as a
|
||||
calibrated distribution with no generated text. Kai is one model on one
|
||||
checkpoint line: a multilingual encoder, adapters that bring sensor streams
|
||||
with their metadata, audio, images and video into it, and a typed-variable
|
||||
decoder. Options are encoded alone and scored against the evidence by two
|
||||
cross-attention blocks, so option count, order and question count are not
|
||||
bounded by one sequence; \op{noul} is label-symmetric by construction,
|
||||
\op{score} a cumulative-link model, and a large choice is narrowed by
|
||||
retrieval that keeps the mass it cuts. A program's dependent questions are
|
||||
typed variables, decoded as masked slots, refined in waves bounded by
|
||||
dependency depth and projected exactly onto the program's rules. Programs are
|
||||
versioned DAGs whose verdicts join a deterministic policy on
|
||||
$\allow < \ask < \deny$, so no model loosens policy, and each run is a hashed
|
||||
package that replays, diffs, refreshes and says what flips the decision. Kai
|
||||
trains in pure Rust, bf16 over F32 masters, as local SGD across Metal, CUDA and
|
||||
ROCm machines, on data classed by license and held behind a contamination
|
||||
barrier. We report what went wrong: our first stage-A run lost the encoder's
|
||||
ability to relate two texts, and we give the measurements, the cause and the
|
||||
fix. Results against Laya and TypeSafe's Jev on a frozen 62-suite harness, on
|
||||
capabilities they lack by construction, and on speed are written into the
|
||||
paper by the benchmark that measures them.
|
||||
\end{abstract}
|
||||
|
||||
\clearpage
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
|
||||
\input{sections/01-introduction}
|
||||
\input{sections/02-decisions}
|
||||
\input{sections/03-model}
|
||||
\input{sections/04-training}
|
||||
\input{sections/05-findings}
|
||||
\input{sections/06-authority}
|
||||
\input{sections/07-programs}
|
||||
\input{sections/08-evaluation}
|
||||
\input{sections/09-limits}
|
||||
\input{sections/10-related}
|
||||
\input{sections/99-conclusion}
|
||||
|
||||
{\small
|
||||
\bibliographystyle{plain}
|
||||
\bibliography{references}
|
||||
}
|
||||
|
||||
\appendix
|
||||
\input{sections/a1-wire}
|
||||
\input{sections/a2-results}
|
||||
|
||||
\end{document}
|
||||
@@ -1,429 +0,0 @@
|
||||
% References for kai.
|
||||
%
|
||||
% A line beginning "% TODO" marks an entry whose details we did not verify
|
||||
% against the publisher's record. Page ranges we were unsure of are omitted
|
||||
% rather than guessed.
|
||||
|
||||
% -- the system and its sources
|
||||
|
||||
@misc{jevnote,
|
||||
key = {Jev},
|
||||
title = {Jev Engineering for Coding Agents: The {TypeSafe} Founder's
|
||||
Blueprint for Building with {Jev}},
|
||||
year = {2026},
|
||||
note = {Working note, September 2026. A synthesis of design notes
|
||||
by Diogo Almeida (TypeSafe), independently compiled; not
|
||||
affiliated with or endorsed by TypeSafe}
|
||||
}
|
||||
|
||||
@misc{typesafejev,
|
||||
author = {{TypeSafe}},
|
||||
title = {Jev},
|
||||
howpublished = {Served as \texttt{typesafe/jev-1.13} through OpenRouter},
|
||||
year = {2026},
|
||||
note = {Typed decision model; listed on OpenRouter 2026-09-24}
|
||||
}
|
||||
|
||||
@misc{openrouterdecisions,
|
||||
author = {{OpenRouter}},
|
||||
title = {Decisions {API} (alpha): \texttt{POST /api/alpha/decisions}},
|
||||
howpublished = {\url{https://openrouter.ai}},
|
||||
year = {2026},
|
||||
note = {Accessed 2026-09-24}
|
||||
}
|
||||
|
||||
% TODO: author attribution taken from the repository owner and the Hugging
|
||||
% Face organisation; the card gives no citation block.
|
||||
@misc{laya,
|
||||
author = {{Convai Innovations}},
|
||||
title = {Laya: a multilingual, non-autoregressive decision engine},
|
||||
howpublished = {\url{https://github.com/NandhaKishorM/laya} and
|
||||
\url{https://huggingface.co/convaiinnovations/laya}},
|
||||
year = {2026},
|
||||
note = {Version 0.3.20, Apache-2.0; model card accessed 2026-09-24}
|
||||
}
|
||||
|
||||
@misc{hanzographpaper,
|
||||
author = {{Hanzo AI Research}},
|
||||
title = {A Temporal Assertion Graph: Valid-time and transaction-time
|
||||
reads, schema as assertions, and erasure in an append-only
|
||||
store},
|
||||
howpublished = {\url{https://github.com/hanzoai/papers}},
|
||||
year = {2026},
|
||||
note = {2026-09-22}
|
||||
}
|
||||
|
||||
@misc{armysbir,
|
||||
author = {{U.S. Army}},
|
||||
title = {{ARM26BX06-NV012}: Agentic-{AI}, Schema-Driven Decision
|
||||
Management for Auditable Studies and Acquisition Decisions},
|
||||
howpublished = {\url{https://armysbir.army.mil/topics/agentic-ai-schema-driven-decision-management/}},
|
||||
year = {2026},
|
||||
note = {SBIR topic; accessed 2026-09-24}
|
||||
}
|
||||
|
||||
% TODO: SysML v2 formal specification version and date.
|
||||
@misc{sysmlv2,
|
||||
author = {{Object Management Group}},
|
||||
title = {{OMG} Systems Modeling Language ({SysML}), Version 2},
|
||||
howpublished = {\url{https://www.omg.org/sysml/}},
|
||||
year = {2025}
|
||||
}
|
||||
|
||||
@misc{jevbenchabdel,
|
||||
author = {{AbdelStark}},
|
||||
title = {jev-benchmarks},
|
||||
howpublished = {\url{https://github.com/AbdelStark/jev-benchmarks}},
|
||||
year = {2026},
|
||||
note = {Version 0.1.0; AG News, Banking77 and DAIR Emotion, $n = 100$ each}
|
||||
}
|
||||
|
||||
@misc{jevbenchnibzard,
|
||||
author = {{nibzard}},
|
||||
title = {decision-model-benchmark},
|
||||
howpublished = {\url{https://github.com/nibzard/decision-model-benchmark}},
|
||||
year = {2026}
|
||||
}
|
||||
|
||||
@misc{typeddecisions,
|
||||
key = {typed-decisions},
|
||||
title = {typed-decisions},
|
||||
howpublished = {\url{https://huggingface.co/datasets/LocalLLaMA/typed-decisions}},
|
||||
year = {2026},
|
||||
note = {400 cases, 2,000 decisions, four workflows; test split}
|
||||
}
|
||||
|
||||
@inproceedings{das2024timesfm,
|
||||
author = {Das, Abhimanyu and Kong, Weihao and Sen, Rajat and Zhou, Yichen},
|
||||
title = {A Decoder-Only Foundation Model for Time-Series Forecasting},
|
||||
booktitle = {Proceedings of the 41st International Conference on Machine Learning},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
% TODO: full author list.
|
||||
@article{ansari2024chronos,
|
||||
author = {Ansari, Abdul Fatir and Stella, Lorenzo and Turkmen, Caner and others},
|
||||
title = {Chronos: Learning the Language of Time Series},
|
||||
journal = {Transactions on Machine Learning Research},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
@inproceedings{radford2023whisper,
|
||||
author = {Radford, Alec and Kim, Jong Wook and Xu, Tao and Brockman,
|
||||
Greg and McLeavey, Christine and Sutskever, Ilya},
|
||||
title = {Robust Speech Recognition via Large-Scale Weak Supervision},
|
||||
booktitle = {Proceedings of the 40th International Conference on Machine
|
||||
Learning},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{zhai2023siglip,
|
||||
author = {Zhai, Xiaohua and Mustafa, Basil and Kolesnikov, Alexander and
|
||||
Beyer, Lucas},
|
||||
title = {Sigmoid Loss for Language Image Pre-Training},
|
||||
booktitle = {Proceedings of the IEEE/CVF International Conference on
|
||||
Computer Vision},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
% -- encoders
|
||||
|
||||
@misc{modernbert,
|
||||
author = {Warner, Benjamin and Chaffin, Antoine and Clavi{\'e}, Benjamin
|
||||
and Weller, Orion and Hallstr{\"o}m, Oskar and Taghadouini,
|
||||
Said and Gallagher, Alexis and Biswas, Raja and Ladhak,
|
||||
Faisal and Aarsen, Tom and Cooper, Nathan and Adams, Griffin
|
||||
and Howard, Jeremy and Poli, Iacopo},
|
||||
title = {Smarter, Better, Faster, Longer: A Modern Bidirectional
|
||||
Encoder for Fast, Memory Efficient, and Long Context
|
||||
Finetuning and Inference},
|
||||
howpublished = {arXiv:2412.13663},
|
||||
year = {2024}
|
||||
}
|
||||
|
||||
% TODO: full author list.
|
||||
@misc{mmbert,
|
||||
author = {Marone, Marc and Weller, Orion and others},
|
||||
title = {{mmBERT}: A Modern Multilingual Encoder with Annealed
|
||||
Language Learning},
|
||||
howpublished = {\url{https://huggingface.co/jhu-clsp/mmBERT-base}},
|
||||
year = {2025}
|
||||
}
|
||||
|
||||
@inproceedings{devlin2019,
|
||||
author = {Devlin, Jacob and Chang, Ming-Wei and Lee, Kenton and
|
||||
Toutanova, Kristina},
|
||||
title = {{BERT}: Pre-training of Deep Bidirectional Transformers for
|
||||
Language Understanding},
|
||||
booktitle = {Proceedings of NAACL-HLT},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
@misc{nogueira2019,
|
||||
author = {Nogueira, Rodrigo and Cho, Kyunghyun},
|
||||
title = {Passage Re-ranking with {BERT}},
|
||||
howpublished = {arXiv:1901.04085},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
@inproceedings{yin2019,
|
||||
author = {Yin, Wenpeng and Hay, Jamaal and Roth, Dan},
|
||||
title = {Benchmarking Zero-shot Text Classification: Datasets,
|
||||
Evaluation and Entailment Approach},
|
||||
booktitle = {Proceedings of EMNLP-IJCNLP},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
% -- generation, agents, guards
|
||||
|
||||
@misc{willard2023,
|
||||
author = {Willard, Brandon T. and Louf, R{\'e}mi},
|
||||
title = {Efficient Guided Generation for Large Language Models},
|
||||
howpublished = {arXiv:2307.09702},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{yao2023react,
|
||||
author = {Yao, Shunyu and Zhao, Jeffrey and Yu, Dian and Du, Nan and
|
||||
Shafran, Izhak and Narasimhan, Karthik and Cao, Yuan},
|
||||
title = {{ReAct}: Synergizing Reasoning and Acting in Language Models},
|
||||
booktitle = {International Conference on Learning Representations},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{schick2023toolformer,
|
||||
author = {Schick, Timo and Dwivedi-Yu, Jane and Dess{\`i}, Roberto and
|
||||
Raileanu, Roberta and Lomeli, Maria and Zettlemoyer, Luke and
|
||||
Cancedda, Nicola and Scialom, Thomas},
|
||||
title = {Toolformer: Language Models Can Teach Themselves to Use Tools},
|
||||
booktitle = {Advances in Neural Information Processing Systems},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@misc{inan2023llamaguard,
|
||||
author = {Inan, Hakan and others},
|
||||
title = {Llama Guard: {LLM}-based Input-Output Safeguard for
|
||||
Human-{AI} Conversations},
|
||||
howpublished = {arXiv:2312.06674},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
% -- calibration, abstention, scoring
|
||||
|
||||
@inproceedings{guo2017,
|
||||
author = {Guo, Chuan and Pleiss, Geoff and Sun, Yu and Weinberger,
|
||||
Kilian Q.},
|
||||
title = {On Calibration of Modern Neural Networks},
|
||||
booktitle = {Proceedings of the 34th International Conference on Machine
|
||||
Learning},
|
||||
year = {2017}
|
||||
}
|
||||
|
||||
@article{chow1970,
|
||||
author = {Chow, C. K.},
|
||||
title = {On Optimum Recognition Error and Reject Tradeoff},
|
||||
journal = {IEEE Transactions on Information Theory},
|
||||
volume = {16},
|
||||
number = {1},
|
||||
year = {1970}
|
||||
}
|
||||
|
||||
@inproceedings{geifman2017,
|
||||
author = {Geifman, Yonatan and El-Yaniv, Ran},
|
||||
title = {Selective Classification for Deep Neural Networks},
|
||||
booktitle = {Advances in Neural Information Processing Systems},
|
||||
year = {2017}
|
||||
}
|
||||
|
||||
@article{gneiting2007,
|
||||
author = {Gneiting, Tilmann and Raftery, Adrian E.},
|
||||
title = {Strictly Proper Scoring Rules, Prediction, and Estimation},
|
||||
journal = {Journal of the American Statistical Association},
|
||||
volume = {102},
|
||||
number = {477},
|
||||
year = {2007}
|
||||
}
|
||||
|
||||
% -- authority
|
||||
|
||||
@article{denning1976,
|
||||
author = {Denning, Dorothy E.},
|
||||
title = {A Lattice Model of Secure Information Flow},
|
||||
journal = {Communications of the ACM},
|
||||
volume = {19},
|
||||
number = {5},
|
||||
year = {1976}
|
||||
}
|
||||
|
||||
@techreport{anderson1972,
|
||||
author = {Anderson, James P.},
|
||||
title = {Computer Security Technology Planning Study},
|
||||
institution = {U.S. Air Force Electronic Systems Division},
|
||||
number = {ESD-TR-73-51},
|
||||
year = {1972}
|
||||
}
|
||||
|
||||
% -- decision analysis
|
||||
|
||||
@book{keeney1976,
|
||||
author = {Keeney, Ralph L. and Raiffa, Howard},
|
||||
title = {Decisions with Multiple Objectives: Preferences and Value
|
||||
Tradeoffs},
|
||||
publisher = {Wiley},
|
||||
year = {1976}
|
||||
}
|
||||
|
||||
@article{howard1966,
|
||||
author = {Howard, Ronald A.},
|
||||
title = {Information Value Theory},
|
||||
journal = {IEEE Transactions on Systems Science and Cybernetics},
|
||||
volume = {2},
|
||||
number = {1},
|
||||
year = {1966}
|
||||
}
|
||||
|
||||
@article{triantaphyllou1997,
|
||||
author = {Triantaphyllou, Evangelos and S{\'a}nchez, Alfonso},
|
||||
title = {A Sensitivity Analysis Approach for Some Deterministic
|
||||
Multi-Criteria Decision-Making Methods},
|
||||
journal = {Decision Sciences},
|
||||
volume = {28},
|
||||
number = {1},
|
||||
year = {1997}
|
||||
}
|
||||
|
||||
@book{saltelli2008,
|
||||
author = {Saltelli, Andrea and Ratto, Marco and Andres, Terry and
|
||||
Campolongo, Francesca and Cariboni, Jessica and Gatelli, Debora
|
||||
and Saisana, Michaela and Tarantola, Stefano},
|
||||
title = {Global Sensitivity Analysis: The Primer},
|
||||
publisher = {Wiley},
|
||||
year = {2008}
|
||||
}
|
||||
|
||||
@book{kahneman2011,
|
||||
author = {Kahneman, Daniel},
|
||||
title = {Thinking, Fast and Slow},
|
||||
publisher = {Farrar, Straus and Giroux},
|
||||
year = {2011}
|
||||
}
|
||||
|
||||
% -- factorized scoring, ordinal answers, parallel refinement
|
||||
|
||||
@inproceedings{humeau2020poly,
|
||||
author = {Humeau, Samuel and Shuster, Kurt and Lachaux, Marie-Anne and
|
||||
Weston, Jason},
|
||||
title = {Poly-encoders: Architectures and Pre-training Strategies for
|
||||
Fast and Accurate Multi-sentence Scoring},
|
||||
booktitle = {International Conference on Learning Representations},
|
||||
year = {2020}
|
||||
}
|
||||
|
||||
@inproceedings{khattab2020colbert,
|
||||
author = {Khattab, Omar and Zaharia, Matei},
|
||||
title = {{ColBERT}: Efficient and Effective Passage Search via
|
||||
Contextualized Late Interaction over {BERT}},
|
||||
booktitle = {Proceedings of the 43rd International ACM SIGIR Conference on
|
||||
Research and Development in Information Retrieval},
|
||||
year = {2020}
|
||||
}
|
||||
|
||||
@article{mccullagh1980,
|
||||
author = {McCullagh, Peter},
|
||||
title = {Regression Models for Ordinal Data},
|
||||
journal = {Journal of the Royal Statistical Society: Series B},
|
||||
volume = {42},
|
||||
number = {2},
|
||||
pages = {109--142},
|
||||
year = {1980}
|
||||
}
|
||||
|
||||
@inproceedings{austin2021d3pm,
|
||||
author = {Austin, Jacob and Johnson, Daniel D. and Ho, Jonathan and
|
||||
Tarlow, Daniel and van den Berg, Rianne},
|
||||
title = {Structured Denoising Diffusion Models in Discrete
|
||||
State-Spaces},
|
||||
booktitle = {Advances in Neural Information Processing Systems},
|
||||
year = {2021}
|
||||
}
|
||||
|
||||
@inproceedings{ghazvininejad2019,
|
||||
author = {Ghazvininejad, Marjan and Levy, Omer and Liu, Yinhan and
|
||||
Zettlemoyer, Luke},
|
||||
title = {Mask-Predict: Parallel Decoding of Conditional Masked
|
||||
Language Models},
|
||||
booktitle = {Proceedings of EMNLP-IJCNLP},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
@inproceedings{chang2022maskgit,
|
||||
author = {Chang, Huiwen and Zhang, Han and Jiang, Lu and Liu, Ce and
|
||||
Freeman, William T.},
|
||||
title = {{MaskGIT}: Masked Generative Image Transformer},
|
||||
booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and
|
||||
Pattern Recognition},
|
||||
year = {2022}
|
||||
}
|
||||
|
||||
@book{vovk2005,
|
||||
author = {Vovk, Vladimir and Gammerman, Alexander and Shafer, Glenn},
|
||||
title = {Algorithmic Learning in a Random World},
|
||||
publisher = {Springer},
|
||||
year = {2005}
|
||||
}
|
||||
|
||||
@misc{douillard2023diloco,
|
||||
author = {Douillard, Arthur and Feng, Qixuan and Rusu, Andrei A. and
|
||||
Chhaparia, Rachita and Donchev, Yani and Kuncoro, Adhiguna and
|
||||
Ranzato, Marc'Aurelio and Szlam, Arthur and Shen, Jiajun},
|
||||
title = {{DiLoCo}: Distributed Low-Communication Training of Language
|
||||
Models},
|
||||
howpublished = {arXiv:2311.08105},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{seide2014onebit,
|
||||
author = {Seide, Frank and Fu, Hao and Droppo, Jasha and Li, Gang and
|
||||
Yu, Dong},
|
||||
title = {1-Bit Stochastic Gradient Descent and its Application to
|
||||
Data-Parallel Distributed Training of Speech {DNNs}},
|
||||
booktitle = {Interspeech},
|
||||
year = {2014}
|
||||
}
|
||||
|
||||
@inproceedings{karimireddy2019ef,
|
||||
author = {Karimireddy, Sai Praneeth and Rebjock, Quentin and Stich,
|
||||
Sebastian U. and Jaggi, Martin},
|
||||
title = {Error Feedback Fixes {SignSGD} and other Gradient Compression
|
||||
Schemes},
|
||||
booktitle = {International Conference on Machine Learning},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
@inproceedings{micikevicius2018mixed,
|
||||
author = {Micikevicius, Paulius and Narang, Sharan and Alben, Jonah and
|
||||
Diamos, Gregory and Elsen, Erich and Garcia, David and
|
||||
Ginsburg, Boris and Houston, Michael and Kuchaiev, Oleksii and
|
||||
Venkatesh, Ganesh and Wu, Hao},
|
||||
title = {Mixed Precision Training},
|
||||
booktitle = {International Conference on Learning Representations},
|
||||
year = {2018}
|
||||
}
|
||||
|
||||
@inproceedings{broder1997resemblance,
|
||||
author = {Broder, Andrei Z.},
|
||||
title = {On the Resemblance and Containment of Documents},
|
||||
booktitle = {Compression and Complexity of Sequences},
|
||||
year = {1997},
|
||||
pages = {21--29}
|
||||
}
|
||||
|
||||
@inproceedings{lee2022dedup,
|
||||
author = {Lee, Katherine and Ippolito, Daphne and Nystrom, Andrew and
|
||||
Zhang, Chiyuan and Eck, Douglas and Callison-Burch, Chris and
|
||||
Carlini, Nicholas},
|
||||
title = {Deduplicating Training Data Makes Language Models Better},
|
||||
booktitle = {Annual Meeting of the Association for Computational
|
||||
Linguistics},
|
||||
year = {2022}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
\section{Introduction}
|
||||
\label{sec:intro}
|
||||
|
||||
Agents ask the same small questions thousands of times per session: which
|
||||
context the next turn sees, which tool fits, whether a command may
|
||||
run~\cite{jevnote}. A generative model answers in prose with no probability to
|
||||
threshold; a fixed rule sees only what its author foresaw. A \emph{typed
|
||||
decision} sits between: the caller states a question, lists the admissible
|
||||
answers and passes the evidence, and the model returns a distribution over
|
||||
exactly those answers, which can be type-checked, thresholded, logged and
|
||||
replayed.
|
||||
|
||||
Three planes: the \emph{generative} writes (Zen), the \emph{decision} answers
|
||||
typed questions over evidence (Kai), and the \emph{policy} is deterministic,
|
||||
written by people, and final. A decision is a program, not a prompt
|
||||
(Figure~\ref{fig:program}): Zen reasons inside it, Kai judges, code and solvers
|
||||
compute, policy and people hold authority, and each run leaves a package.
|
||||
|
||||
\input{figures/program}
|
||||
|
||||
Two decision models exist to compare against, and both are baselines, never
|
||||
Kai revisions. Laya~\cite{laya} is a family of open encoder checkpoints that
|
||||
pack the question, every option and the state into one sequence; TypeSafe's
|
||||
Jev~\cite{typesafejev} is a hosted model behind OpenRouter's Decisions
|
||||
API~\cite{openrouterdecisions}. Status tags: \meas{} run by us, with the kept
|
||||
artifact named; \reported{} published by others; \shipped{} on the main branch
|
||||
of \texttt{hanzoai/decision} at the revision on the title page; \proposed{}
|
||||
designed, not built.
|
||||
|
||||
\paragraph{Contributions.}
|
||||
\begin{enumerate}[leftmargin=1.5em]
|
||||
\item \textbf{One model}: an evidence record for any modality with its
|
||||
sensor metadata, adapters into one encoder's width, and evidence, questions
|
||||
and options each encoded once per session; one checkpoint line trained in
|
||||
stages
|
||||
(Section~\ref{sec:model}).
|
||||
\item \textbf{Factorized choice}: options encoded alone and scored against
|
||||
shared evidence by two cross-attention blocks, a law per type, and
|
||||
retrieval that keeps the mass it cuts, so option count, order and question
|
||||
count are not bounded by one sequence (Section~\ref{sec:factor}).
|
||||
\item \textbf{Typed-variable diffusion}: a program's questions as masked
|
||||
slots decoded jointly over the program graph, refined in waves bounded by
|
||||
its depth and projected exactly onto its rules (Section~\ref{sec:diffusion}).
|
||||
\item \textbf{A training system} in pure Rust: local SGD with an outer
|
||||
Nesterov step across Metal, CUDA and ROCm machines, bf16 deltas with error
|
||||
feedback, bit-identical resume, token-budgeted batches under a memory
|
||||
floor, license classes and a contamination barrier
|
||||
(Section~\ref{sec:training}).
|
||||
\item \textbf{What went wrong}: stage A's encoder stopped relating two texts;
|
||||
the measurements, the ablations that locate the cause, and the fix; how
|
||||
much of the typed-decisions test set Laya's checkpoint had seen in near
|
||||
form, and that it did not help it; and a score head that lost thirty
|
||||
points to a softmax over level texts on the same encoder and data
|
||||
(Section~\ref{sec:findings}).
|
||||
\item \textbf{Policy precedence} as a lattice join, with a proof that
|
||||
enforcing a model only adds friction, and \textbf{programs and packages}
|
||||
that replay, diff, refresh and say what flips a decision, with SysML~v2
|
||||
import and an engineering knowledge graph
|
||||
(Sections~\ref{sec:authority} and~\ref{sec:programs}).
|
||||
\item \textbf{Benchmarks} of accuracy on a frozen harness, of capabilities
|
||||
the baselines lack by construction, and of speed, each table written by
|
||||
the command that measures it (Section~\ref{sec:evaluation}).
|
||||
\end{enumerate}
|
||||
|
||||
\paragraph{What is claimed.}
|
||||
The baselines' structural limits are measured: Laya rejects every question of
|
||||
1{,}000 or more options and Jev every question over 255; answering five
|
||||
dependent questions independently, Laya breaks one of the program's rules in
|
||||
64\% of states and Jev in 25\%; reordering 16 options changes Laya's top
|
||||
answer on 25.5\% of questions \meas{} (\texttt{hanzoai/benchmarks}
|
||||
\texttt{4e57fb2}). The final checkpoint's numbers enter only through the
|
||||
tables of Section~\ref{sec:evaluation}; no sentence states them, and the first stage-A run's numbers appear
|
||||
only where Section~\ref{sec:findings} explains what went wrong. Kai trains on the
|
||||
train splits of the harness's sources behind a barrier against its test
|
||||
states, so a lead on a suite whose baseline never saw its source is
|
||||
in-distribution for Kai, and Section~\ref{sec:limits} says what that does not
|
||||
show.
|
||||
@@ -1,57 +0,0 @@
|
||||
\section{Typed decisions}
|
||||
\label{sec:decisions}
|
||||
|
||||
\begin{definition}[Typed question]
|
||||
A typed question is a triple $q = (\tau, \iota, C)$ of a type
|
||||
$\tau \in \{\op{choice}, \op{score}, \op{noul}\}$, an instruction $\iota$ in
|
||||
natural language, and an ordered list of options
|
||||
$C = (c_1, \dots, c_k)$, each a label with a description.
|
||||
A \op{choice} selects one of $k \ge 1$ unordered labels; a \op{score} selects
|
||||
one of $k$ ordered levels $0, \dots, k-1$; a \op{noul} is a predicate, $k = 2$,
|
||||
with sides $(\op{false}, \op{true})$ whose descriptions the caller may
|
||||
override.
|
||||
\end{definition}
|
||||
|
||||
\begin{definition}[Answer]
|
||||
An answer to $q$ over evidence $E$ is a distribution $p \in \Delta^{k-1}$ over
|
||||
$C$. A \op{choice} reports $\arg\max_i p_i$, a \op{score} the expected level
|
||||
$\bar\ell = \sum_i i\, p_i$ with a legend, a \op{noul} $p_{\op{true}}$; every
|
||||
answer also carries $p$.
|
||||
\end{definition}
|
||||
|
||||
$(q, E)$ and the model revision determine $p$, so a decision replays.
|
||||
|
||||
\subsection{What an answer is sure of}
|
||||
\label{sec:confidence}
|
||||
|
||||
Three summaries of $p$ are in use under the name \op{confidence}, and they are
|
||||
different numbers: the top probability $\pmax = \max_i p_i$; the rescaled
|
||||
maximum
|
||||
\begin{equation}
|
||||
\kappa = \frac{k\,\pmax - 1}{k - 1}, \qquad k \ge 2,
|
||||
\label{eq:kappa}
|
||||
\end{equation}
|
||||
which is 0 at the uniform distribution and 1 at a point mass, reported by Jev
|
||||
and OpenRouter~\cite{laya,openrouterdecisions}; and one minus normalised
|
||||
entropy, $h = 1 - H(p)/\ln k$, reported by the Laya runtime~\cite{laya}.
|
||||
|
||||
\begin{proposition}
|
||||
\label{prop:kappa}
|
||||
For fixed $k$, $\kappa \ge t \iff \pmax \ge \bigl(1 + t(k-1)\bigr)/k$.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
Equation~\eqref{eq:kappa} is affine and increasing in $\pmax$ for $k \ge 2$.
|
||||
\end{proof}
|
||||
|
||||
So $\kappa \ge 0.5$ asks for $\pmax \ge 0.75$ on a \op{noul}, $0.67$ on a
|
||||
three-way and $0.55$ on a ten-way choice: one threshold, a different risk per
|
||||
arity; $h$ orders answers differently again. For $p = (0.05, 0.15, 0.80)$, $\kappa = 0.70$ and
|
||||
$h = 0.44$; a gate at 0.5 passes under one and abstains under the other.
|
||||
|
||||
\paragraph{The convention we fix.}
|
||||
Every backend behind \op{/v1/decisions} reports \op{confidence} as $\kappa$,
|
||||
so a threshold written for Jev means the same when Kai answers, and adds
|
||||
\op{answer\_confidence} $= \pmax$. A Decision Program writes abstention
|
||||
thresholds against $\kappa$ and \op{noul} thresholds against $p_{\op{true}}$,
|
||||
and names the calibration they were set against (Section~\ref{sec:programs})
|
||||
\shipped.
|
||||
@@ -1,267 +0,0 @@
|
||||
\section{Kai}
|
||||
\label{sec:model}
|
||||
|
||||
Kai is one model: a multilingual text encoder, adapters that bring any other
|
||||
evidence into its width, a factorized option head, and a typed-variable decoder
|
||||
over a program's questions (Figure~\ref{fig:kai}). It maps evidence $E$, a
|
||||
typed question and, inside a program, other questions' answers to a
|
||||
distribution over the question's options. Everything in this section is in the
|
||||
\texttt{kai} crate \shipped; what is trained, and when, is
|
||||
Section~\ref{sec:training}.
|
||||
|
||||
\input{figures/kai}
|
||||
|
||||
\subsection{Evidence}
|
||||
\label{sec:evidence}
|
||||
|
||||
\begin{definition}[Evidence]
|
||||
An evidence record is a tuple
|
||||
\[
|
||||
e = (\mathit{id}, \mathit{modality}, t, \mathit{source}, \mathit{frame},
|
||||
\mathit{unit}, \mathit{sensor}, \mathit{uncertainty}, \mathit{quality},
|
||||
\mathit{provenance}, \mathit{payload})
|
||||
\]
|
||||
of an identifier the state's text may cite, a modality (eighteen named, any
|
||||
other a $\op{Custom}(\cdot)$), a time span, the payload's frame and unit, sensor
|
||||
metadata (sensor, location, calibration date and validity, limits, and per
|
||||
channel a name, unit, calibration, error bound and quality), an uncertainty (a
|
||||
standard deviation, an interval or a quality grade), a quality flag (valid,
|
||||
degraded or expired, with a loss share), the producer with its inputs, and a
|
||||
payload: text, JSON, numeric channels with a rate or timestamps, bytes, frames,
|
||||
a grid, a vector, points, or a URL the caller resolves. A decision's evidence is
|
||||
the state plus a set of records.
|
||||
\end{definition}
|
||||
|
||||
A new sensor needs an adapter, not a new model, and a number is never serialized
|
||||
as prose: 43.2\,\textdegree C, 43.2\,psi and 43.2\,mm/s differ by their unit,
|
||||
and an expired calibration weakens the record. The adapter follows from the
|
||||
payload's form. Text and JSON go through the text encoder, pooled. Numeric
|
||||
channels go through a sensor encoder: patches of the series as points, log
|
||||
bands and statistics, six summary tokens per channel (instant, windows, trend,
|
||||
events, baseline, forecast), and each channel's metadata line through the text
|
||||
encoder. Audio takes two paths, Whisper-base~\cite{radford2023whisper}, frozen,
|
||||
for what is said and the sensor encoder over the waveform for how it sounds;
|
||||
images and thermal or radar grids go through SigLIP~\cite{zhai2023siglip},
|
||||
frozen; video becomes appearance, motion and event tokens from SigLIP per
|
||||
frame, never unbounded frame tokens; vectors and point clouds go through a
|
||||
projector. Every token gains embeddings for its modality, quality, descriptor
|
||||
(time, uncertainty) and metadata line. The context the option head attends to
|
||||
is the text encoder's tokens followed by the evidence tokens; retrieval's query
|
||||
stays the text's. Forecasts from time-series
|
||||
models~\cite{das2024timesfm,ansari2024chronos} enter as records, not answers.
|
||||
|
||||
A checkpoint that declares no evidence answers bit for bit as a text-only one,
|
||||
so adapters can be added to a trained line.
|
||||
|
||||
\paragraph{Encode once.}
|
||||
A question's context takes one of two layouts, a checkpoint field. In the
|
||||
first, each question is one sequence with the state inside it,
|
||||
\[
|
||||
\texttt{[CLS]}\ \langle\tau\rangle\ \texttt{question:}\ \iota\
|
||||
\texttt{[SEP]}\ s\ \texttt{[SEP]},
|
||||
\]
|
||||
cut at the context length by dropping the state's tail. In the \emph{shared}
|
||||
layout the state is encoded once, \texttt{[CLS]}~$s$~\texttt{[SEP]}, for every
|
||||
question put to it, each question is its own sequence, and an option's tokens
|
||||
attend to the question's tokens with its evidence and to the state's tokens
|
||||
under one softmax, the state's keys and values projected once and gathered per
|
||||
row. The weights are the same, so a stage may switch layouts from any
|
||||
checkpoint: the stage-A runs use the first, stage C the shared one. Either way
|
||||
options never share the context's token budget, and an option's tokens depend
|
||||
on its text alone, so every distinct option in a batch is encoded once for all
|
||||
the questions that list it; inside a program session every evidence record,
|
||||
question and option is encoded once whatever the number of refinement passes.
|
||||
Keeping latents across calls, keyed by content hash per changed evidence state
|
||||
and per program version, is \proposed.
|
||||
|
||||
\subsection{Factorized choice}
|
||||
\label{sec:factor}
|
||||
|
||||
Let $C$ be the tokens a question's options attend to, each with the question
|
||||
type's learned embedding $e_\tau$ added, and $O_i \in \mathbb{R}^{L_i\times d}$
|
||||
the token states of option $i$, encoded alone as
|
||||
\texttt{[CLS]}~$c_i$~\texttt{[SEP]}. Two pre-norm cross-attention blocks, in
|
||||
which option tokens attend to the context and to nothing else, give
|
||||
$X_i = B_2(B_1(O_i + e_\tau, C), C)$; with $v_i$ the mean of $X_i$,
|
||||
\begin{equation}
|
||||
s_i = w^{\top}\,\mathrm{GELU}\bigl(W\,\mathrm{LN}(v_i) + b\bigr).
|
||||
\end{equation}
|
||||
The type fixes the law, at a temperature $T$ fitted per type and option-count
|
||||
bucket on held-out data:
|
||||
\begin{itemize}[leftmargin=1.5em]
|
||||
\item \op{choice}: $p_i = \operatorname{softmax}_i(s_i/T)$.
|
||||
\item \op{noul}: $p_{\op{true}} = \sigma\bigl((s_{\op{true}} -
|
||||
s_{\op{false}})/T\bigr)$, each side scored with its own description.
|
||||
\item \op{score}: a cumulative-link model~\cite{mccullagh1980} over levels
|
||||
$0..k-1$ with cutpoints $\theta_1 < \dots < \theta_{k-1}$ and
|
||||
$P(y < j) = \sigma(\theta_j - \eta)$. The location $\eta = a^{\top}
|
||||
\mathrm{std}(\bar v - c)$ reads the mean of the state-aware level vectors
|
||||
less a running center $c$; the cutpoints read the level texts alone, a base
|
||||
$b^{\top}\mathrm{std}(\bar o)$ and gaps
|
||||
$\theta_{j+1} - \theta_j = \operatorname{softplus}(g^{\top}
|
||||
[\mathrm{std}(\bar o_j); \mathrm{std}(\bar o_{j+1})])$, with $\bar o_j$ the
|
||||
mean of $O_j$ and $\mathrm{std}$ each vector at zero mean and unit variance.
|
||||
The likelihood is computed in log space,
|
||||
$\log P(y = j) = \log\sigma(\theta_{j+1} - \eta) + \log\sigma(\eta -
|
||||
\theta_j) + \log\sigma(g_j)$, which is exact and never a difference that
|
||||
rounds to zero.
|
||||
\end{itemize}
|
||||
The scorer and the ordinal layers compute in F32 whatever the encoder's dtype:
|
||||
what decides is a difference of two outputs that can share an offset far larger
|
||||
than it (Section~\ref{sec:other}).
|
||||
|
||||
\begin{proposition}[Symmetry]
|
||||
\label{prop:symmetry}
|
||||
For any weights, permuting a question's options permutes $p$ the same way, and
|
||||
exchanging the texts of a \op{noul}'s sides maps $p_{\op{true}}$ to
|
||||
$1 - p_{\op{true}}$.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
$s_i$ depends on $c_i$ and $C$ alone, and softmax is permutation equivariant;
|
||||
the exchange swaps $s_{\op{true}}$ and $s_{\op{false}}$, and
|
||||
$\sigma(-x) = 1 - \sigma(x)$.
|
||||
\end{proof}
|
||||
|
||||
Laya has neither: its options share one sequence, in order, and each is read at
|
||||
a marker token whose context includes the options before it.
|
||||
|
||||
\paragraph{Retrieval.}
|
||||
A choice with more than $k$ options, a checkpoint field (32 in the first stage-A
|
||||
run, 160 since), is narrowed first. The sum of the context's first tokens and
|
||||
each option's mean token are projected, each less a running center, to unit
|
||||
vectors $u$ and $r_i$, and
|
||||
$\pi = \operatorname{softmax}_i(e^{\gamma}\langle u, r_i\rangle)$ with $\gamma$
|
||||
learned. The head scores the top $k$ under $\pi$, a set $S$, and the rest keep
|
||||
their retrieval probability:
|
||||
\begin{equation}
|
||||
p_i = \begin{cases} (1-\rho)\,\operatorname{softmax}_{j \in S}(s_j/T)_i & i \in S,\\
|
||||
\pi_i & i \notin S,\end{cases}
|
||||
\qquad \rho = \sum_{i \notin S} \pi_i ,
|
||||
\end{equation}
|
||||
so the mass beyond the top $k$ is kept, not renormalised away, and the head
|
||||
costs $O(k)$ per question for any option count. A running center moves 1\% of
|
||||
the way to each training batch's mean input after its step and takes no
|
||||
gradient; without it, encoder states' shared offset gave every context nearly
|
||||
the same query (Section~\ref{sec:other}).
|
||||
|
||||
\subsection{Typed-variable diffusion}
|
||||
\label{sec:diffusion}
|
||||
|
||||
A program's questions depend on each other, and answered independently they
|
||||
can break its rules: approving an invoice flagged as a duplicate.
|
||||
|
||||
\begin{definition}[Typed variables]
|
||||
A program's questions are variables $Z = (Z_v)_{v \in V}$, each with a finite
|
||||
domain $D_v$ (labels, levels, or a \op{noul}'s sides), with a dependency DAG
|
||||
$G$ on $V$ and rules $R$, each on two answers:
|
||||
$Z_a = i \Rightarrow Z_b = j$, or $\lnot(Z_a = i \land Z_b = j)$.
|
||||
\end{definition}
|
||||
|
||||
The decoder predicts masked slots jointly: for a masked set $M \subseteq V$,
|
||||
\begin{equation}
|
||||
p_\theta(Z_M \mid E, Z_{V\setminus M}, G) = \prod_{v \in M}
|
||||
p_\theta(Z_v \mid E, Z_{V\setminus M}, G).
|
||||
\end{equation}
|
||||
A slot is its question's mean token plus a value: a learned mask vector while
|
||||
its answer is unknown, else the known option's mean token through a linear map.
|
||||
Decoder layers let each slot attend to the others, with a learned per-head bias
|
||||
for a parent, a child, any other slot, and itself when its answer is shown,
|
||||
beside a null key of value zero, and then to the evidence latents. The last
|
||||
read is the variable's message; through a map that starts at zero it is added
|
||||
to the query tokens of the variable's options, which the factorized head then
|
||||
scores against the question and the evidence. A variable with nothing else to
|
||||
read gets a message of exactly zero, so one variable alone is the factorized
|
||||
head, and a new decoder answers as the checkpoint it starts from (tested to
|
||||
$10^{-5}$). For a shown slot the distribution revises the answer shown, and
|
||||
$1 - p(\text{shown})$ flags it.
|
||||
|
||||
Training (stage C) hides variables by one of three patterns: $\lceil r n\rceil$
|
||||
of $n$ at random with $r \sim U(0, 1]$, absorbing-state discrete
|
||||
diffusion~\cite{austin2021d3pm} over typed variables rather than tokens; a node
|
||||
and all its descendants; or only the descendants. It tests 15\% of the shown
|
||||
answers, half of those shown wrong, so the model learns to revise a wrong
|
||||
answer and keep a right one. The loss is log loss plus Brier score over hidden
|
||||
and tested variables, plus the mean probability that the joint state breaks a
|
||||
rule: $q(a)(1 - q(b))$ for $a \Rightarrow b$, $q(a)\,q(b)$ for
|
||||
$\lnot(a \land b)$. Every program of two or more variables gains a \op{defer}
|
||||
variable reading all the others, whose gold is to act when every answer is
|
||||
clear (top probability at least 0.9) and to defer otherwise.
|
||||
|
||||
\paragraph{Refinement.}
|
||||
One scheduler serves any model that answers a set of questions given known
|
||||
answers: the decoder with known answers as visible slots, or the factorized
|
||||
head with a node's known parents added to its state as typed facts. Passes are
|
||||
spent on uncertainty.
|
||||
\begin{enumerate}[leftmargin=1.5em]
|
||||
\item Pass 1 predicts every variable with nothing known and freezes those
|
||||
whose top probability reaches $\tau$.
|
||||
\item Waves by dependency depth: a variable settles once frozen, a root, or
|
||||
re-asked; each wave asks, once, every unsettled variable whose parents have
|
||||
all settled, and freezes again.
|
||||
\item Each unfrozen variable keeps its top $m$ candidates. One more pass asks
|
||||
each unfrozen variable's unfrozen children with the variable set to each
|
||||
candidate, giving pairwise terms
|
||||
$\log p(\text{child} \mid \text{node} = c) - \log p(\text{child})$;
|
||||
variables sharing a child are set in different jobs, so each term
|
||||
conditions on one variable alone.
|
||||
\item A selector takes the joint answer over the candidates of highest
|
||||
log-probability plus pairwise terms that keeps every rule.
|
||||
\item A projection onto the rules over the full domains,
|
||||
$\hat z = \arg\max_{z \models R} \sum_{v} \log p_v(z_v)$, moves nothing
|
||||
when the selection already keeps them.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{proposition}[Depth bounds cost]
|
||||
\label{prop:depth}
|
||||
Steps 1 and 2 end within $\operatorname{depth}(G) + 1$ passes, depth counted in
|
||||
edges, and ask at most $2|V|$ questions; with step 3, refinement takes at most
|
||||
$\operatorname{depth}(G) + 2$ passes whatever $|V|$.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
Roots and frozen variables are settled after pass 1. If every variable of depth
|
||||
below $d$ is settled after pass $d$, each of depth $d$ has all parents settled
|
||||
and is re-asked by pass $d+1$. Each variable is asked in pass 1 and at most once
|
||||
more. Step 3 is one pass.
|
||||
\end{proof}
|
||||
|
||||
Selection and projection are exact branch and bound, each node's options tried
|
||||
best first and bounded by the sum of per-variable maxima. Rules between answers
|
||||
encode graph colouring, so exact selection is exponential on some graphs: the
|
||||
search stops with an error after $2^{20}$ steps rather than return an answer it
|
||||
has not proved.
|
||||
|
||||
\subsection{One checkpoint line}
|
||||
\label{sec:checkpoints}
|
||||
|
||||
Kai has one checkpoint line, \texttt{hanzoai/kai}, with a revision per training
|
||||
stage; language, domain, modality and hardware are not product lines. The
|
||||
encoder is mmBERT-base~\cite{mmbert}, multilingual with 8{,}192 positions,
|
||||
trained at 1{,}024 tokens; the code runs any ModernBERT-family
|
||||
encoder~\cite{modernbert}. Kai initializes from Laya's multilingual
|
||||
weights~\cite{laya}, released under Apache-2.0: the encoder and type embedding
|
||||
as they are, Laya's two self-attention head layers split into the two
|
||||
cross-attention blocks, and its marker scorer as the option scorer; retrieval
|
||||
and the ordinal head start fresh.
|
||||
|
||||
\paragraph{Laya, the baseline.}
|
||||
Laya 0.3.20's three checkpoints are not Kai revisions: English on
|
||||
ModernBERT-large at a 512-token context, multilingual on mmBERT-base at 1,024,
|
||||
and a typed-decisions checkpoint, the English one fine-tuned on the
|
||||
typed-decisions~\cite{typeddecisions} train split. Their joint head packs the
|
||||
question and each option after a marker token into one sequence with the state,
|
||||
and a script detector routes non-English states to the multilingual checkpoint.
|
||||
Hanzo serves their byte-identical weights natively through a Rust port of the
|
||||
joint head: against Laya's Python reference on 21 recorded states in twelve
|
||||
languages and all three checkpoints, the largest logit difference is
|
||||
$2.86\times 10^{-5}$ against an enforced bound of $10^{-4}$, the largest
|
||||
probability difference $6.2\times 10^{-6}$, and 108 of 108 labels agree
|
||||
(\texttt{decision/tests/parity.rs}) \meas. Every decision records the weights'
|
||||
SHA-256 it was answered with.
|
||||
|
||||
\paragraph{Runtime.}
|
||||
Rust on Hanzo's tensor library, \texttt{hanzo-ml}, on CPU in F32 and on Metal,
|
||||
CUDA and ROCm in bf16. The \texttt{decision} crate serves
|
||||
\op{POST /v1/decisions} with Kai and Laya in process and Jev through
|
||||
OpenRouter, one worker per checkpoint draining its queue into shared forward
|
||||
passes; the \texttt{control} crate runs a program over many states in process
|
||||
behind a C ABI (Section~\ref{sec:enso}). No Python is on the serving path.
|
||||
@@ -1,183 +0,0 @@
|
||||
\section{Training}
|
||||
\label{sec:training}
|
||||
|
||||
Kai trains in stages on one checkpoint line, in Rust, on the machines Hanzo
|
||||
has: an Apple M4 Max (Metal), a DGX Spark (CUDA) and an AMD Strix Halo with a
|
||||
Radeon 8060S (ROCm), joined over a LAN. Everything in this section is in the
|
||||
\texttt{train} crate \shipped{} unless marked.
|
||||
|
||||
\subsection{Stages}
|
||||
\label{sec:stages}
|
||||
|
||||
\begin{description}[leftmargin=1.5em,style=nextline]
|
||||
\item[A, text decisions.] The train splits of the harness's sources; MASSIVE
|
||||
in all 51 locales and MASSIVE utterances half in English; CLINC150, XNLI in
|
||||
15 languages, SST-5, BoolQ and MNLI; function selection (ToolACE, Glaive,
|
||||
Nemotron's tool calling); agent runs judged by hidden tests (resolve, next
|
||||
action); Hanzo's own agent sessions and repositories, labelled by outcomes
|
||||
(the next tool result, a re-run, a revert, the file a commit changed), never
|
||||
by what the agent chose; 1{,}181 skills; jailbreak prompts collected in the
|
||||
wild; and robustness transforms of 13 sources (options shuffled, relabelled,
|
||||
swapped, subset, near-miss).
|
||||
\item[B, evidence.] Every parameter frozen but the adapters, over bearing
|
||||
faults, turbofan degradation (C-MAPSS), speech, hydraulic rigs, Monash
|
||||
forecasting, network telemetry, UCR series, and generated conflicts
|
||||
(camera against telemetry, specification against SysML, an expired
|
||||
calibration) whose gold is \op{evidence\_conflict}, not
|
||||
\op{decision\_ready}, and \op{human\_review}.
|
||||
\item[C, programs.] The typed-variable decoder over whole programs: rules
|
||||
mined from typed-decision gold, turbofan and test-rig programs, SysML~v2
|
||||
architectures lowered to programs and mutated once per case with the
|
||||
decision's change recorded, readiness, trade and test-plan programs,
|
||||
closed-form vehicle dynamics, and pairs of real telemetry with generated
|
||||
logs; generators hold out templates whole, so validation and test ask new
|
||||
programs.
|
||||
\end{description}
|
||||
|
||||
A stage is one JSON file: its initial checkpoint (a hub revision, or a finished
|
||||
run whose provenance names that stage with every planned batch merged), data
|
||||
build, admitted license classes, per-suite takes, frozen prefixes, token
|
||||
budget, retrieval loss weights, $k$, schedule and outer optimizer. Stage A has
|
||||
run; Section~\ref{sec:findings} is what it taught, and the final stage-A run
|
||||
follows from it. The B and C data are built and their stage files written;
|
||||
their trained checkpoints are \proposed.
|
||||
|
||||
\subsection{Local SGD across devices}
|
||||
\label{sec:cluster}
|
||||
|
||||
One path trains a stage on one machine or many: local SGD with an outer
|
||||
Nesterov step, DiLoCo~\cite{douillard2023diloco}. A coordinator owns the plan,
|
||||
$\theta$ in F32, the outer optimizer, validation and checkpoints, and runs
|
||||
inside a worker process; other machines join it at any time. Workers pull
|
||||
batches one at a time, so a faster device takes more, and run AdamW from
|
||||
$\theta$ for a round's wall time (300\,s). Each then sends
|
||||
$\Delta_w = \theta_w - \theta$ in bf16 with the tokens it processed, adding
|
||||
back what bf16 rounding dropped from its previous delta, error
|
||||
feedback~\cite{seide2014onebit,karimireddy2019ef}. With $\Delta$ the
|
||||
token-weighted mean of the round's deltas and $g = -\Delta$,
|
||||
\begin{equation}
|
||||
m \leftarrow \mu m + g, \qquad \theta \leftarrow \theta - \eta\,(g + \mu m).
|
||||
\label{eq:outer}
|
||||
\end{equation}
|
||||
The change to $\theta$ goes out in bf16, $\theta$ moves by exactly what went out
|
||||
and the remainder joins the next change, so every worker's copy of $\theta$ is
|
||||
bit-identical to the coordinator's. Deltas are summed in the order workers
|
||||
joined, never the order their reports arrive, so a run does not depend on
|
||||
network timing. A batch counts once its delta is merged; a worker that drops
|
||||
has its unmerged batches requeued. The handshake checks the build (a hash of
|
||||
the model and training sources and the lock file), the tokenized corpus and the
|
||||
parameter names.
|
||||
|
||||
\begin{proposition}[Outer step]
|
||||
\label{prop:outer}
|
||||
If every round's mean delta is the same $\Delta$, the outer step of
|
||||
Equation~\eqref{eq:outer} tends to $\frac{\eta}{1-\mu}\Delta$.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
$m$ tends to $g/(1-\mu)$, so $\eta(g + \mu m) \to \eta g (1 + \frac{\mu}{1-\mu})
|
||||
= \frac{\eta}{1-\mu} g$.
|
||||
\end{proof}
|
||||
|
||||
So $(\eta, \mu) = (0.7, 0.9)$ moves $\theta$ by $7\times$ a round's mean delta
|
||||
wherever rounds agree, and $(1.0, 0.3)$ by $1.43\times$. Section~\ref{sec:collapse}
|
||||
is why this number matters.
|
||||
|
||||
\paragraph{Exactness.}
|
||||
A checkpoint (every so many batches, each epoch, and the end) is taken at a
|
||||
round boundary and holds the weights, the outer momentum, its rounding carry,
|
||||
the merged batches and the round, and each worker's AdamW moments, step and
|
||||
carry, which a worker of that name gets back when it rejoins. Resuming continues
|
||||
bit-identically to the uninterrupted run, and with one step a round, $\eta = 1$
|
||||
and $\mu = 0$, the cluster equals the same rounds replayed in one process bit
|
||||
for bit, for one and three workers (tested on CPU). int8 deltas halve the bytes
|
||||
but broke that equivalence by up to $1.3\times10^{-5}$, so deltas stay bf16.
|
||||
|
||||
\paragraph{Heterogeneity.}
|
||||
The first stage-A run merged 91{,}899 batches from the Metal, CUDA and ROCm
|
||||
machines in one run; in its round 45 they took 757, 465 and 226 steps at
|
||||
7{,}054, 4{,}226 and 2{,}325 tokens/s \meas. Pilots of one stage on Metal and on
|
||||
CUDA agree: mean validation accuracy 0.504 and 0.500 over 48 suites, log loss
|
||||
1.493 and 1.501 \meas. ROCm needed three kernels \texttt{hanzo-ml} lacked there
|
||||
(comparison, \op{index\_add}, sigmoid); a stage-A delta with the token
|
||||
embeddings frozen is 250\,MB in bf16, about 2.2\,s each way over the LAN.
|
||||
|
||||
\paragraph{Budget and memory.}
|
||||
Compute is bf16 over F32 masters~\cite{micikevicius2018mixed}. A batch is bounded
|
||||
by a budget on context tokens, option tokens, option-head query and key tokens,
|
||||
rows and evidence tokens, and holds one suite, or a mixed share across suites.
|
||||
A device that cannot hold the budget runs a batch as micro-batches within a
|
||||
fraction of it with gradients summed (equal to one pass within
|
||||
$1.5\times10^{-8}$), and a worker exits cleanly under a free-memory floor, read
|
||||
from \texttt{sysctl} on macOS and \texttt{/proc/meminfo} on Linux, rather than
|
||||
push a shared machine into swap. Freezing the token embeddings (61\% of the
|
||||
weights) raised a stage-A pilot from 5{,}181 to 5{,}747 tokens/s and cut peak
|
||||
memory from 53.7 to 47.3\,GB; grouping options by length cut option padding from
|
||||
49\% to 14\%; Muon on the 2-D weights ran at 3{,}125 tokens/s with a worse
|
||||
validation log loss (2.114 against 2.056) and was removed \meas.
|
||||
|
||||
\paragraph{Wide choices.}
|
||||
A choice whose options exceed the budget trains as inference answers it: on a
|
||||
sample of $k$ options, the gold first, about half the negatives from
|
||||
retrieval's current top 64 at $\theta$, a quarter the gold's nearest by token
|
||||
Jaccard, the rest uniform. A draw is a function of the row, epoch, round and
|
||||
seed, so every worker draws alike. Before this, 42{,}066 of the first stage-A
|
||||
plan's 213{,}398 batches were one row whose options alone exceeded the budget,
|
||||
and at about 2.9\,MB per option token of a CPU F32 step one such row took a
|
||||
machine past its floor at any micro-batch size \meas.
|
||||
|
||||
\subsection{Data, licenses and the barrier}
|
||||
\label{sec:barrier}
|
||||
|
||||
A stage's data is a content-addressed build: the same inputs give the same
|
||||
hash, shards are homogeneous in source, dataset, revision, license class and
|
||||
transformation, and each record carries its provenance (source, dataset,
|
||||
revision, class, transformation, task family, language, domain, decision type,
|
||||
candidate count, scope). The manifest, with each shard's SHA-256, is what the
|
||||
trainer admits.
|
||||
|
||||
\paragraph{License classes.}
|
||||
GREEN is permissive or ours; YELLOW is third-party model output from closed or
|
||||
unnamed generators; RED is non-commercial, unstated or restrictive terms. A
|
||||
record starts at its dataset's class, judged at the upstream source, and only
|
||||
rises: one of our own transcripts rises to YELLOW with any message recorded from
|
||||
a closed model. A turn carrying such a message is shown to Kai only as the
|
||||
person's messages and tool outputs. Classes are recorded facts; which classes
|
||||
train is the owner's recorded decision, written into every build (on
|
||||
2026-09-25, all three), so a GREEN-only build is one flag. Evaluation is a role,
|
||||
not a class: benchmark datasets, every built set's test split, and whatever the
|
||||
barrier catches never train, and a run asked to admit them refuses.
|
||||
|
||||
\paragraph{The barrier.}
|
||||
Every protected evaluation item is read at a pin: the frozen harness's 9{,}499
|
||||
states, the extension suites' 82{,}860 test states, the Army demo models, and
|
||||
the Enso study's workloads (GPQA Diamond, HLE, LiveCodeBench v6, CharXiv,
|
||||
SWE-bench Pro and Verified, Terminal-Bench 2.0), 98{,}065 items; WordNet, which
|
||||
the capability suites draw on, is banned outright. A record is caught when
|
||||
\begin{itemize}[leftmargin=1.5em]
|
||||
\item it shares an exact content unit with an item: the state's string leaves
|
||||
in order with whitespace squashed and keys ignored, or the first 200 letters
|
||||
and digits of any leaf of 200 or more characters;
|
||||
\item it carries an item's key, a SWE-bench instance id;
|
||||
\item it is a near duplicate: estimated Jaccard of character 5-gram sets at
|
||||
least 0.5, from 256 min-hashes~\cite{broder1997resemblance} in 64 LSH bands
|
||||
of 4, so a pair at Jaccard $j$ is a candidate with probability
|
||||
$1 - (1 - j^4)^{64}$, 0.984 at 0.5, and each candidate is checked on all
|
||||
256;
|
||||
\item it contains an item: at least 80\% of the item's sampled 50-character
|
||||
spans, a span sampled when its hash is 0 mod 16 so both sides sample the same
|
||||
windows; an item of 50 or more characters with fewer than four sampled spans
|
||||
is contained when a text holds its whole normal form.
|
||||
\end{itemize}
|
||||
The last rule exists because the one before it missed two: a harness test email
|
||||
quoted inside a longer train email, and a harness jailbreak prompt opening a
|
||||
longer one, reached five records of the first stage-A build. Planted over every set (twenty
|
||||
items each, verbatim, with a word dropped and two swapped, and inside 1{,}900
|
||||
characters of transcript), nothing of 50 or more characters reaches a shard; an
|
||||
item under 50 characters, a MASSIVE or CLINC utterance, is caught only when
|
||||
equal or near, since phrases that short recur in unrelated text. The build the
|
||||
final stage-A run reads (\texttt{a3-d7a9a437cf484811}) read 2{,}762{,}444
|
||||
records and caught 19{,}803: against the harness 14{,}875 near duplicates and 71
|
||||
containments, against the extension suites 4{,}818 near, 34 exact and 3
|
||||
contained, and 2 SWE-bench keys; 547 of typed decisions' 1{,}185 train states
|
||||
were caught near (Section~\ref{sec:overlap}). Its records are 1{,}799{,}005
|
||||
GREEN, 217{,}727 YELLOW and 713{,}841 RED \meas.
|
||||
@@ -1,190 +0,0 @@
|
||||
\section{What stage A taught}
|
||||
\label{sec:findings}
|
||||
|
||||
Every figure in this section is \meas{}, from runs whose logs, stage files and
|
||||
scripts are kept beside the paper in \texttt{data/diagnosis/} or recorded in
|
||||
\texttt{hanzoai/decision}'s \texttt{LLM.md}.
|
||||
|
||||
\subsection{The encoder stopped relating two texts}
|
||||
\label{sec:collapse}
|
||||
|
||||
The first stage-A run started from Laya's multilingual weights and trained one
|
||||
epoch of the full mixture, 91{,}899 batches over three machines, with the outer
|
||||
step $(\eta, \mu) = (0.7, 0.9)$, $7\times$ a round's mean delta
|
||||
(Proposition~\ref{prop:outer}). Validation split in two. Tasks that relate two
|
||||
texts fell: RAG relevance was 0.625 and BoolQ 0.826 at 2{,}325 batches, 0.482
|
||||
and 0.668 at 13{,}101, and RAG's log loss sat at $\ln 2$ at every validation
|
||||
after; from 13{,}101 batches to the end MNLI fell from 0.713 to 0.593 and XNLI
|
||||
from 0.698 to 0.630. Single-text tasks rose over the same span: AG News from
|
||||
0.375 to 0.845, emotion from 0.525 to 0.679, MASSIVE from 0.440 to 0.730. On the
|
||||
frozen harness the checkpoint answered RAG relevance at chance (F32 accuracy
|
||||
0.480, AUC 0.486, 374 of 400 questions answered relevant), and a ridge probe on
|
||||
the head's option vectors read relevance at AUC 0.35 where the same probe read
|
||||
jailbreak at 0.93. Its encoder layers ended 30 to 44\% (relative Frobenius
|
||||
norm) from their initial weights; the English baseline of the same head,
|
||||
trained in one process at the same learning rates for 53{,}322 steps, ended 5\%
|
||||
from its own and kept RAG relevance at 0.682.
|
||||
|
||||
\paragraph{Not the data.}
|
||||
All 155{,}761 RAG training records agree with MS~MARCO's \op{is\_selected}
|
||||
label, except 281 pairs MS~MARCO itself labels both ways; the classes are
|
||||
balanced (77{,}955 and 77{,}806), and 76{,}109 queries carry exactly one
|
||||
selected and one unselected passage. The relabelling transform leaves every
|
||||
target as it was and the side swap reverses target and option texts together
|
||||
on all 3{,}995 rows. The barrier removed 339 of 159{,}258 records. Truncation
|
||||
(contexts of 52 to 250 tokens under a 1{,}024-token limit), the fitted
|
||||
temperature, the class prior and bf16 were each ruled out.
|
||||
|
||||
\paragraph{The encoder, not the head.}
|
||||
Single-process fits on the RAG shards alone, on Metal, locate the fault:
|
||||
\begin{itemize}[leftmargin=1.5em]
|
||||
\item from Laya's multilingual weights, validation accuracy reached 0.645
|
||||
after 229 batches;
|
||||
\item from the stage-A checkpoint it stayed at 0.497 and 0.495, training log
|
||||
loss at 0.693, chance; 0.522 in F32;
|
||||
\item stage A's encoder under the head of the Laya run at 229 batches: 0.517,
|
||||
then 0.497, training loss at 0.693;
|
||||
\item that run's encoder under stage A's head: 0.662 after 104 batches, the
|
||||
training loss falling to 0.45.
|
||||
\end{itemize}
|
||||
Measured on the encoders alone, over 200 RAG validation contexts laid out as Kai
|
||||
lays them and run in F32 by an independent ModernBERT implementation, the mean
|
||||
cosine similarity between different contexts' mean token states is 0.981 for
|
||||
stage A against 0.853 for Laya (1 would make every context the same), and
|
||||
swapping only the query moves the passage tokens' states by 0.085 of their norm
|
||||
in stage A against 0.34 in Laya and 0.73 in the RAG-trained encoder. Stage A's
|
||||
encoder had stopped letting one text change how it reads the other.
|
||||
|
||||
\paragraph{The cause.}
|
||||
The outer step alone does not do it: on the RAG shards alone, from Laya's
|
||||
weights, with $(0.7, 0.9)$, validation read 0.590, 0.532, 0.623 and 0.580,
|
||||
noisier than plain training and never at chance. One process over the English
|
||||
mixture does not do it either (the baseline above). The full mixture under the
|
||||
$7\times$ outer step does. Which part of the mixture drives it would take a
|
||||
replay of stage A, which we did not run. Two continuations agree. Stage a2
|
||||
continued stage A with the same outer step and regressed on Metal and CUDA
|
||||
alike, then diverged in cooldown (training log loss 2.85 to 13.45 while the
|
||||
learning rate fell to a tenth); stage a3 continued it with $(1.0, 0.3)$ and
|
||||
inherited the collapse, validation RAG 0.497, BoolQ 0.638, MNLI 0.583 and XNLI
|
||||
0.600 at 16{,}598 batches while its single-text suites were at their best (AG
|
||||
News 0.890, emotion 0.831, MASSIVE 0.787), and was stopped.
|
||||
|
||||
\paragraph{The fix.}
|
||||
The final stage-A run starts again from Laya's multilingual weights, over a3's
|
||||
data (two epochs of the harness's train suites at the English baseline's takes,
|
||||
the rest of the mixture as replay), with the outer step $(1.0, 0.3)$,
|
||||
$1.43\times$ a round's mean delta, and validates every 8{,}000 batches so a
|
||||
repeat shows early. Logging the context similarity above at each validation, a
|
||||
cheap early warning, is \proposed. The harness decides whether the fix held;
|
||||
its tables are Section~\ref{sec:accuracy}'s.
|
||||
|
||||
\subsection{Laya had seen half the typed-decisions test set, reworded}
|
||||
\label{sec:overlap}
|
||||
|
||||
The barrier caught 547 of the 1{,}185 typed-decisions train states it read, all
|
||||
as near duplicates (measure 0.50 to 0.97, median 0.61), none exact. Laya's
|
||||
typed-decisions checkpoint was fine-tuned on the whole train split. Measured
|
||||
over its 1{,}200 rows with the barrier's measure (a state's string leaves;
|
||||
numbers ignored), 587 rows sit at Jaccard 0.5 or more from some test state, all
|
||||
in two of the four workflows (agent traces 298 of 300, invoices 289 of 300); on
|
||||
the test side, 200 of the 400 states, every agent-trace and every invoice
|
||||
state, have such a sibling. They are template siblings, not copies:
|
||||
\begin{itemize}[leftmargin=1.5em]
|
||||
\item with numbers included no train state equals a test state; the closest
|
||||
pair scores 0.90, and 44 score 0.8 or more;
|
||||
\item a caught train row agrees with its nearest test state on 0.406 of the
|
||||
questions and on all five in 38 of 587, where random train and test states
|
||||
of the same workflow agree on 0.416 and on all five 5.3\% of the time;
|
||||
\item the test set shares templates with itself as much: 195 of its 400
|
||||
states have another test state at 0.5 or more.
|
||||
\end{itemize}
|
||||
One pair: the same task (``Update every service to the patched logging
|
||||
library.''), agent and constraint; in train one constraint violation and one
|
||||
irreversible action, gold \emph{harmful}, \emph{human review}, risk 3; in test
|
||||
none of either and two tool errors, gold \emph{partial}, \emph{observe}, risk 1.
|
||||
So Laya's typed-decisions checkpoint saw same-wording siblings of half the test
|
||||
set, with different numbers and different gold, and no near-copy of a test
|
||||
answer. Stage A's builds drop the 547, so it trains on 638 of the states the
|
||||
builder reads; from stage a5 an official train split is checked only for exact
|
||||
copies and keys, so all 1{,}185 train. Whether knowing the templates helps is measured, not assumed:
|
||||
\texttt{harness/siblings.py} in the benchmark repository scores the 235 test
|
||||
states without a sibling and the 165 with one apart
|
||||
(Table~\ref{tab:siblings}). Laya's typed checkpoint scores alike on both
|
||||
halves, so its lead is not memorized from the siblings; Jev, which never saw
|
||||
them, is 8 points better without them; and Kai falls on exactly the states
|
||||
whose siblings the barrier removed from its training. Stage a5 read the split
|
||||
whole and recovered the with-sibling half; the lead is the head and the
|
||||
training, and this section is a caveat about Kai's data, not Laya's score.
|
||||
|
||||
\begin{table}[h]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
typed decisions & all 400 & without a sibling (235) & with a sibling (165) \\
|
||||
\midrule
|
||||
Kai (stage a4) & 0.523 & 0.605 & 0.406 \\
|
||||
Kai (stage a5) & 0.705 & 0.697 & 0.716 \\
|
||||
Kai (stage a6) & 0.750 & 0.734 & 0.773 \\
|
||||
Laya typed & 0.766 & 0.773 & 0.756 \\
|
||||
Jev & 0.736 & 0.770 & 0.686 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Accuracy over every question of the state, split by whether the
|
||||
a3 build's barrier caught a same-wording training record for it
|
||||
(hanzoai/benchmarks \texttt{611059b}).}
|
||||
\label{tab:siblings}
|
||||
\end{table}
|
||||
|
||||
\subsection{The score head}
|
||||
\label{sec:score}
|
||||
|
||||
With typed decisions at 0.705 in stage a5 against Laya's 0.766, one probe put
|
||||
the gap in the head rather than the encoder or the data: Kai's head trained on
|
||||
Laya's own typed encoder (\texttt{kai-1-agent}) and typed decisions' train
|
||||
split alone, six epochs, scored 0.605 on the harness, choice 0.608, \op{noul}
|
||||
0.833, score 0.431, where Laya's checkpoint scores 0.733, 0.857 and 0.723
|
||||
\meas. The cumulative-link score head of Section~\ref{sec:model}, one location
|
||||
against ordered cutpoints, lost thirty points on score questions to Laya's
|
||||
formulation, a softmax over the level texts. Kai now answers a score question as
|
||||
a choice over its levels when the checkpoint says so (\texttt{ordinal: false}),
|
||||
trained with the ranked probability score in place of the Brier so that mass
|
||||
far from the gold level costs more than mass beside it; the same probe with
|
||||
that head reached 0.742 on the typed validation split at the point where the
|
||||
ordinal head sat at 0.571, and stage a6 raised typed decisions' score-question
|
||||
accuracy on the harness from 0.603 to 0.711 (Section~\ref{sec:accuracy}).
|
||||
|
||||
\subsection{Other defects, each fixed}
|
||||
\label{sec:other}
|
||||
|
||||
\begin{description}[leftmargin=1.5em,style=nextline]
|
||||
\item[A shared offset decided every score question alike.] The head's option
|
||||
vectors share an offset of norm 18{,}400 against 350 to 950 of what varies
|
||||
across rows; standardized, 99.83\% of the ordinal location's input energy
|
||||
was one vector for all 800 typed-decision score rows, so each question got
|
||||
one level whatever the state. The location now reads its level vectors less
|
||||
a running center; in its test, removing the center collapses the spread of
|
||||
locations from 0.33 to 0.01.
|
||||
\item[bf16 rounded the decision away.] At that offset Metal's bf16 moved
|
||||
\op{noul} logits in steps of 0.0625: RAG's 400 answers took 15 distinct
|
||||
values, 69 of them exact ties. The scorer and ordinal layers now compute in
|
||||
F32.
|
||||
\item[Retrieval gave every context one query.] At 49{,}071 batches the skills
|
||||
choice (1{,}181 options) had recall@32 of 0.000 against a chance of 0.027.
|
||||
Contexts' first tokens had norm 48.7, 47.9 of it their shared mean, pairwise
|
||||
cosine 0.97; projected raw, every skills context got nearly the same query
|
||||
(cosine 0.995). A fresh retrieval head fit on those frozen states recalled
|
||||
0.137 of its own training rows at 32 raw and 0.934 centered: hence the
|
||||
running centers of Section~\ref{sec:factor}.
|
||||
\item[The ordinal head had no gradient.] From the initial weights $\eta$
|
||||
started near 95 against cutpoints of 4 to 9, and a clamped difference of two
|
||||
sigmoids had no gradient once both rounded alike. With the log-space
|
||||
likelihood of Section~\ref{sec:factor}, one epoch of SST-5 alone moved test
|
||||
accuracy from 0.126 to 0.455 and log loss from 24.14 to 1.213.
|
||||
\item[A balanced class taught the wrong prior.] Jailbreak detection trained
|
||||
balanced, at $P = 0.5$, where the harness asks at 0.228 (91 of 400). It
|
||||
ranked well (F32 AUC 0.834) at the wrong prior: at one half it flagged 223
|
||||
of 400, accuracy 0.620; at the harness's prior, 0.850. Later stages draw it
|
||||
at its pool's rate, with every in-the-wild jailbreak prompt of JailbreakHub
|
||||
and 4{,}000 of its regular prompts as negatives.
|
||||
\end{description}
|
||||
@@ -1,75 +0,0 @@
|
||||
\section{Policy is the authority}
|
||||
\label{sec:authority}
|
||||
|
||||
A model answering ``may this command run?'' will sometimes be wrong, and some
|
||||
of its evidence is written by an adversary: a file the agent read, a page it
|
||||
fetched. Prompt injection is a property of any model that reads untrusted text,
|
||||
so the question is what the system does when the model is wrong. The answer
|
||||
here is structural.
|
||||
|
||||
\begin{definition}[Verdicts]
|
||||
The verdicts are the chain $V = \{\allow, \ask, \deny\}$ ordered
|
||||
$\allow < \ask < \deny$, with join $a \join b = \max(a, b)$.
|
||||
\end{definition}
|
||||
|
||||
A deterministic policy $\pi$, written by people and reviewed like code, maps a
|
||||
state to a verdict before any model runs: reading \texttt{\textasciitilde/.ssh}
|
||||
with network egress is \deny{} by rule; with no rule, \allow{} means only ``no
|
||||
objection''. A program maps the state to a model verdict $\mu(s)$, and an
|
||||
enforced program's effective verdict is
|
||||
\begin{equation}
|
||||
\varepsilon(s) = \pi(s) \join \mu(s).
|
||||
\label{eq:join}
|
||||
\end{equation}
|
||||
|
||||
\begin{proposition}[The model only tightens]
|
||||
\label{prop:tighten}
|
||||
For every state $s$ and every $\mu(s)$, $\varepsilon(s) \ge \pi(s)$; hence
|
||||
$\{s : \varepsilon(s) = \allow\} \subseteq \{s : \pi(s) = \allow\}$.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
$\max(a, b) \ge a$, and \allow{} is the least element.
|
||||
\end{proof}
|
||||
|
||||
\begin{corollary}
|
||||
\label{cor:envelope}
|
||||
The safety envelope is the policy's. An adversary who controls the state
|
||||
completely, and so $\mu(s)$, can make an action ask or be refused where the
|
||||
policy would allow it, and nothing else.
|
||||
\end{corollary}
|
||||
|
||||
\paragraph{Abstention, escalation, modes.}
|
||||
If the verdict question's answer $p$ has $\kappa_p$ below its threshold,
|
||||
$\mu(s) = \ask$; otherwise $\arg\max_i p_i$. An escalation is a \op{noul}
|
||||
that raises the verdict when $p_{\op{true}}$ reaches its threshold (``could
|
||||
this command send credentials?'' to \deny{} at 0.3,
|
||||
Appendix~\ref{app:program}); escalations are joins, so
|
||||
Proposition~\ref{prop:tighten} still holds. In \emph{shadow} $\mu$ is only
|
||||
recorded, in \emph{advisory} shown, and in both $\varepsilon = \pi$; in
|
||||
\emph{enforced}, $\varepsilon = \pi \join \mu$. A gate pinned to a
|
||||
calibration runs in shadow when an input was answered under another
|
||||
\shipped.
|
||||
|
||||
\begin{proposition}[Enforcement costs only friction]
|
||||
\label{prop:friction}
|
||||
Over a shadow sample, the states on which enforcing a program would change
|
||||
the outcome are exactly $F = \{s : \mu(s) > \pi(s)\}$, and on each the change
|
||||
is to a stricter verdict.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
$\pi(s) \join \mu(s) \ne \pi(s)$ iff $\mu(s) > \pi(s)$, and then the join is
|
||||
$\mu(s)$.
|
||||
\end{proof}
|
||||
|
||||
The shadow record is thus the complete counterfactual of enforcement: each
|
||||
state in $F$ is a catch or friction, both counts once people label them, and
|
||||
promotion asks only whether the catches are worth the friction. No estimate of
|
||||
the model's miss rate is needed; enforcement cannot make a miss worse than the
|
||||
policy's own.
|
||||
|
||||
\paragraph{Constraints and preferences.}
|
||||
A routing or context program splits in two. The \emph{constraint} (which
|
||||
providers may see this state) lives in a lattice with the same rule: policy
|
||||
sets the floor, the model may only raise it. The \emph{preference} (cheap or
|
||||
frontier among permitted models) is the model's, defaulting toward quality on
|
||||
abstention; a wrong preference costs money or quality, never a constraint.
|
||||
@@ -1,233 +0,0 @@
|
||||
\section{Programs and packages}
|
||||
\label{sec:programs}
|
||||
|
||||
\begin{definition}[Decision Program]
|
||||
A Decision Program is a named, versioned, immutable record of options,
|
||||
objectives (a weight, direction and metric each), hard constraints (bounds on
|
||||
metrics), assumptions (a value and declared range each), risks (likelihood and
|
||||
severity), bias checks, evidence, and a DAG of typed nodes: a deterministic
|
||||
expression, a Kai question, a Zen prompt, a solver, a human approval, or a
|
||||
policy gate (Section~\ref{sec:authority}). A node reads assumptions, evidence
|
||||
or other nodes' outputs, and writes JSON.
|
||||
\end{definition}
|
||||
|
||||
A program is the only place a question's wording lives, and any change to
|
||||
wording, options, a threshold, the model or the calibration is a new version,
|
||||
because a threshold means something only for the probabilities it was validated
|
||||
against. The executor runs nodes in dependency order with models, solvers and
|
||||
people behind interfaces, scores each option as weighted min-max-normalised
|
||||
metrics minus expected risk (likelihood times severity), and recommends the
|
||||
best option meeting every constraint \shipped. Refining a program's Kai
|
||||
questions inside the executor as the typed variables of
|
||||
Section~\ref{sec:diffusion} is \proposed; today refinement runs beside it.
|
||||
Table~\ref{tab:programs} lists an agent loop's programs: the Jev notes'
|
||||
decision points~\cite{jevnote}, plus preflight, progress and completion. Other
|
||||
shipped programs decide Enso's operations (Section~\ref{sec:enso}) and a
|
||||
business's marketing, sales and commerce actions, each gated by a deterministic
|
||||
contact policy (consent per jurisdiction, opt-outs, suppression lists,
|
||||
frequency caps, quiet hours in local time, age, sensitive attributes) and
|
||||
evaluated off-policy from outcome records before it acts \shipped. On a
|
||||
synthetic shop whose best policy is worth 0.4305, inverse-propensity and doubly
|
||||
robust estimates from 200{,}000 logged decisions give 0.4388 and 0.4404, and
|
||||
both rank that policy above all 25 one-segment deviations \meas.
|
||||
|
||||
\begin{table}[h]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{@{}p{0.25\linewidth}p{0.55\linewidth}l@{}}
|
||||
\toprule
|
||||
Program & Questions & Mode \\
|
||||
\midrule
|
||||
\op{agent.preflight@1} & task type; complexity (4); model tier; needs the
|
||||
user; needs repository context; sensitivity (4); private model & advisory \\
|
||||
\op{agent.command-risk@1} & verdict (\allow, \ask, \deny); secret exposure;
|
||||
production impact; network & advisory \\
|
||||
\op{agent.model-route@1} & tier; reasoning depth (4); long context; private
|
||||
model & shadow \\
|
||||
\op{agent.context@1} & scope (5); needs repository; needs web; needs memory
|
||||
& shadow \\
|
||||
\op{agent.tool-select@1} & next tool (7); steps can run in parallel & shadow \\
|
||||
\op{agent.progress@1} & status (advancing, stalled, looping, blocked); needs
|
||||
the user & advisory \\
|
||||
\op{agent.complete@1} & done; verified rather than claimed; work remaining
|
||||
(3) & advisory \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Agent-loop programs, as defined in \texttt{program/programs}
|
||||
\shipped. Unmarked questions are \op{noul};
|
||||
levels or options in parentheses. A deployment may run a program below its
|
||||
mode, never above.}
|
||||
\label{tab:programs}
|
||||
\end{table}
|
||||
|
||||
\subsection{The Decision Package}
|
||||
|
||||
A run's record is a Decision Package: program and version; assumptions,
|
||||
constraints and evidence references with content hashes; each node's
|
||||
definition, backend revision, calibration and output, with every answer's full
|
||||
distribution; human overrides beside what they override, with author and
|
||||
reason; policy results; ranking, recommendation and sensitivity; approvals. Its
|
||||
hash, SHA-256 over canonical JSON (sorted keys, shortest round-trip floats),
|
||||
covers every field but the timing trace. Replay re-runs the program on the
|
||||
recorded evidence, recomputing Kai and solver nodes under the recorded
|
||||
revisions and taking Zen and human outputs, which are observations, from the
|
||||
record; under the same revisions it reproduces the hash. A diff lists the
|
||||
values that changed and the flip conditions the later package moved past. The
|
||||
report is rendered only from computed results, so each number in it resolves
|
||||
to a field \shipped; rejecting a Zen-written narrative that states a number no
|
||||
field holds, as our assertion graph rejects an uncited
|
||||
claim~\cite{hanzographpaper}, is \proposed.
|
||||
|
||||
\begin{proposition}[Exact reuse]
|
||||
\label{prop:refresh}
|
||||
Cache each node's output under the hash of its definition, inputs and backend
|
||||
revision \shipped. If a key is unchanged and the backend deterministic, reuse yields the
|
||||
package a full rerun would; a refresh after $c$ nodes' inputs change recomputes
|
||||
those nodes and their descendants, and nothing else.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
A node's output is a function of its definition, inputs and backend revision
|
||||
(Section~\ref{sec:decisions}). An input's hash is the evidence's content, the
|
||||
assumption's value, or the upstream node's output and revision, so a node whose
|
||||
recomputed output is unchanged leaves its dependents' keys unchanged.
|
||||
\end{proof}
|
||||
|
||||
\subsection{What flips the decision}
|
||||
\label{sec:flip}
|
||||
|
||||
For each parameter, the others held, the package reports where the top option
|
||||
changes \shipped. For a \emph{weight}, scaling all scores by the weight plus
|
||||
the others' sum makes each a line, so the top option is an upper envelope of
|
||||
lines and crossovers are exact; a \emph{risk}'s likelihood or severity enters
|
||||
linearly, also exact; a \emph{constraint bound} changes the feasible set only
|
||||
at the options' metric values. An \emph{assumption} is swept on a 32-interval
|
||||
grid with each change bisected, which misses a flip and flip-back inside one
|
||||
interval; downstream non-expression nodes are held at their recorded outputs
|
||||
and listed as held. A sweep point that fails to evaluate is reported as an
|
||||
error segment, never a failed run.
|
||||
|
||||
All weights at once have a closed form \proposed. For a challenger $b$ let
|
||||
$\delta_b = U_{a^\star} - U_b \in \mathbb{R}^m$ be the difference of the two
|
||||
options' normalised metrics, so $V(a^\star) - V(b) = w^{\top}\delta_b > 0$, and
|
||||
$P = I - \tfrac{1}{m}\mathbf{1}\mathbf{1}^{\top}$.
|
||||
|
||||
\begin{proposition}[Smallest weight change]
|
||||
\label{prop:weights}
|
||||
The smallest $\Delta$ in Euclidean norm with $\mathbf{1}^{\top}\Delta = 0$ that
|
||||
makes $b$ tie $a^\star$ is
|
||||
\begin{equation}
|
||||
\Delta^\star_b = -\frac{w^{\top}\delta_b}{\lVert P\delta_b\rVert^2}\,P\delta_b,
|
||||
\qquad
|
||||
\lVert \Delta^\star_b \rVert = \frac{w^{\top}\delta_b}{\lVert P\delta_b\rVert},
|
||||
\end{equation}
|
||||
provided $P\delta_b \ne 0$; if $w + \Delta^\star_b \ge 0$ it is the smallest
|
||||
change within the simplex, otherwise a lower bound.
|
||||
\end{proposition}
|
||||
\begin{proof}
|
||||
Minimise $\lVert\Delta\rVert^2$ subject to $\mathbf{1}^{\top}\Delta = 0$ and
|
||||
$\delta_b^{\top}\Delta = -w^{\top}\delta_b$. On the range of $P$,
|
||||
$\delta_b^{\top}\Delta = (P\delta_b)^{\top}\Delta$: the distance from the origin
|
||||
to a hyperplane with normal $P\delta_b$. Adding $w + \Delta \ge 0$ can only raise
|
||||
the minimum. If $P\delta_b = 0$, no weight change reorders $a^\star$ and $b$.
|
||||
\end{proof}
|
||||
|
||||
$\rho_w = \min_b \lVert\Delta^\star_b\rVert$ is how far a stakeholder must
|
||||
disagree with the weights to change the answer. Sampling each Kai cell from its
|
||||
distribution estimates the probability that resolving the cells would change
|
||||
the recommendation, as well as the cells are calibrated \proposed.
|
||||
|
||||
\subsection{Studies, SysML and the engineering graph}
|
||||
\label{sec:studies}
|
||||
|
||||
A trade study is typed judgments over evidence aggregated into a
|
||||
recommendation; kept as slides, it is redone a year later because no one can
|
||||
say which conclusion rested on the number that moved. The U.S.\ Army's SBIR
|
||||
topic ARM26BX06-NV012~\cite{armysbir} asks for studies that are
|
||||
schema-defined, agent-assisted, auditable and refreshable. Here that is a
|
||||
program, a package, a diff, a refresh, and what flips the decision. The
|
||||
additive score assumes preferentially independent criteria~\cite{keeney1976}.
|
||||
|
||||
A SysML~v2~\cite{sysmlv2} model, in a subset of the textual notation or as
|
||||
Systems Modeling API JSON, imports into one element model that keeps each
|
||||
element's id, metaclass and owner; an element's id survives layout, comment and
|
||||
value edits, and the pilot implementation's JSON export of a test model imports
|
||||
to the same model and graph as its text \shipped. An engineering knowledge
|
||||
graph built from it holds typed entities and relations, each with provenance
|
||||
and a validity interval, and answers neighbours, shortest paths, BM25
|
||||
retrieval, the evidence behind a decision, the graph as of a time, and the diff
|
||||
between two revisions \shipped. Tags drive it: a vendor, risk, evidence,
|
||||
decision or assumption tag, or a class of the ground-vehicle ontology, sets an
|
||||
element's kind, a tagged dependency is an edge, and a validity annotation
|
||||
bounds a node or edge.
|
||||
|
||||
\paragraph{The JLTV powertrain trade.}
|
||||
A SysML~v2 model of a light tactical vehicle's powertrain trade, the fielded
|
||||
diesel JLTV against the diesel-electric eJLTV, cites a public source on the
|
||||
line of every figure: Wikipedia's JLTV and Humvee-replacement articles,
|
||||
Oshkosh Defense's product page and hybrid announcement, reporting by Breaking
|
||||
Defense, Defense News and Janes, and the Congressional Research Service's
|
||||
reports RS22942 and IF11729. The trade program over it has five equally
|
||||
weighted objectives (fuel economy, added mass, field capability, record,
|
||||
maturity), an airlift constraint, an assumption for the share of the hybrid's
|
||||
company-reported fuel gain that holds on the Army's duty cycle, an anchoring
|
||||
bias check, a Zen brief and a program manager's approval. Its example run, with
|
||||
fixed example probabilities in place of Kai's since no trained Kai is claimed,
|
||||
ranks the diesel first (0.6 to 0.4); the package reports that raising fuel
|
||||
economy's or field capability's weight from 0.2 to 0.4 makes the hybrid first,
|
||||
both exact, and records the approval held because the fuel figure is a company
|
||||
figure \shipped. It is a demonstration of the mechanism, not an acquisition
|
||||
result. Read through Hanzo's bitemporal assertion graph~\cite{hanzographpaper},
|
||||
a package would replay as known on the day it was decided, separating what
|
||||
changed in the world from what changed in the record \proposed.
|
||||
|
||||
\subsection{Kai controls Enso}
|
||||
\label{sec:enso}
|
||||
|
||||
Enso is Hanzo's adaptive model family, served by the Zen engine. Kai is its
|
||||
controller, in process: seven programs, each with a mode and thresholds kept
|
||||
as data in Enso's catalog, decide the model tier, the reasoning budget, which
|
||||
context chunks and which tools the next call sees, whether the task is
|
||||
advancing, whether it is done or needs escalation, and an action's risk. A call
|
||||
runs one program over many states, every question of every state in one batch,
|
||||
and a host acts only on a row whose mode is enforced and whose answer is
|
||||
accepted; a calibration other than the program's pin runs the gate in shadow
|
||||
\shipped. The \texttt{control} crate exposes this as a C library
|
||||
(\op{kai\_open}, \op{kai\_decide}, \op{kai\_error}, \op{kai\_free},
|
||||
\op{kai\_close}) that Zen's server loads at run time; without it, Enso serves
|
||||
as before \shipped.
|
||||
|
||||
The evaluation is designed and not run \proposed. Its thesis is that Kai does
|
||||
not make Zen generate faster but makes it generate less. Per task the cost is
|
||||
$C = C_{\mathrm{Kai}} + C_{\mathrm{prefill}} + C_{\mathrm{decode}} +
|
||||
C_{\mathrm{retrieval}} + C_{\mathrm{tools}}$, and Kai spends
|
||||
$C_{\mathrm{Kai}}$, one encoder pass per decision, to shrink the rest with a
|
||||
smaller model, fewer prompt and decode tokens and fewer steps. Conditions add
|
||||
one decision at a time: B0 the largest Zen model for every step, B1 a static
|
||||
router, R1 Zen as its own router, K1 Kai routing the model, K2 plus context
|
||||
pruning, K3 plus a tool and skill shortlist, K4 plus progress and early stop,
|
||||
K5 the full plane. Every metric is per successful task, so no condition looks
|
||||
cheap by failing: success rate, GPU-seconds, prompt and decode tokens, KV-cache
|
||||
GB-seconds, peak VRAM, latency and dollars, with routing regret against the
|
||||
cheapest model that succeeds. Synthetic tasks with a known cheapest model,
|
||||
public agent benchmarks and replayed Hanzo traces are reported apart. Kai
|
||||
enters Enso in shadow, recording its pick beside what Enso did, and each
|
||||
operation is promoted on its own shadow record (Proposition~\ref{prop:friction}).
|
||||
|
||||
\subsection{The wire and where it runs}
|
||||
|
||||
\op{POST /v1/decisions} speaks OpenRouter's Decisions
|
||||
API~\cite{openrouterdecisions} field for field (Appendix~\ref{app:wire}). The
|
||||
\op{model} field selects the backend: Kai and Laya run in process;
|
||||
\op{typesafe/jev-1.13} is forwarded to OpenRouter only when the server was
|
||||
started with it, each answer checked for its type and each choice restored to
|
||||
the caller's order. Hanzo adds \op{answer\_confidence} and \op{routing}, which
|
||||
records the checkpoint, revision, weights' SHA-256, calibration, device and the
|
||||
reason for the route \shipped; a program form, a request naming \op{program}
|
||||
and \op{state} and returning verdict and mode, is \proposed. The service is one Rust binary with no
|
||||
network dependency and no Python: its image bakes a pinned checkpoint and loads
|
||||
it with outbound network denied, so it serves a workstation, a cluster or a
|
||||
disconnected site, where a server started without Jev has no OpenRouter client
|
||||
at all \shipped. Runnable examples, each a program, its evidence, a request and
|
||||
the run it must produce, cover the agent loop, support, sales, commerce,
|
||||
vehicle readiness, the JLTV trade and a sensor anomaly, and every one is run and
|
||||
replayed under a fake Kai in the test suite \shipped.
|
||||
@@ -1,194 +0,0 @@
|
||||
\section{Evaluation}
|
||||
\label{sec:evaluation}
|
||||
|
||||
Every table in this section is written by \texttt{bench tex} in
|
||||
\texttt{hanzoai/decision} from the kept results of the runs it names, into
|
||||
\texttt{tables/}; no number in a table is typed by hand. Each table's last row
|
||||
names the Kai revision, the device and the harness and benchmark commits it
|
||||
reports.
|
||||
|
||||
\paragraph{Backends.}
|
||||
\textbf{Kai}: stage a7, three stages on from the final stage-A checkpoint
|
||||
(Section~\ref{sec:collapse}): a5 read the suites a4 trailed with more rows and
|
||||
typed decisions' train split whole (Section~\ref{sec:overlap}); a6 answers
|
||||
score questions as a choice over their level texts (Section~\ref{sec:score});
|
||||
a7 reads AG News whole and repeats support triage and jailbreak twice; one
|
||||
epoch each, on the native runtime. \textbf{Laya}: Laya 0.3.20's published weights served natively
|
||||
by the Rust port of its joint head (parity in Section~\ref{sec:checkpoints}),
|
||||
each case on the checkpoint Laya's router picks, except typed decisions, which
|
||||
are answered by Laya's typed-decisions checkpoint: the router sends them to the
|
||||
English one, which scores 0.361 there \meas. \textbf{Jev}:
|
||||
\op{typesafe/jev-1.13} through OpenRouter. All three answer identical questions;
|
||||
a question a backend refuses or fails is counted, never dropped.
|
||||
|
||||
\paragraph{The harness.}
|
||||
\texttt{hanzoai/benchmarks} \texttt{decision/}, frozen at \texttt{e95c6ee}
|
||||
(its questions unchanged through \texttt{4e57fb2}), is Laya's own suite
|
||||
builders, unchanged, seed 13: ten application suites of 400 cases, typed
|
||||
decisions~\cite{typeddecisions} (400 states, 2{,}000 decisions), and MASSIVE
|
||||
intent in 51 languages of 100 utterances with 20 options each; 62 suites,
|
||||
9{,}499 states, 11{,}099 questions. Accuracy is top-1; Brier sums over options;
|
||||
ECE uses 15 bins of top-label confidence. Scored with upstream's metric code,
|
||||
the harness reproduces upstream's own typed-decisions benchmark for all three
|
||||
Laya checkpoints to the fourth decimal \meas.
|
||||
|
||||
\paragraph{Training overlap.}
|
||||
Kai trains on the train split of every harness source, less what the barrier
|
||||
catches (Section~\ref{sec:barrier}). Laya's English checkpoint reports AG News,
|
||||
Enron spam, phishing, support tickets and MS~MARCO in its mixture \reported, and
|
||||
its typed-decisions checkpoint was fine-tuned on siblings of half the
|
||||
typed-decisions test set and scores alike with and without them
|
||||
(Section~\ref{sec:overlap}); no Laya checkpoint reports
|
||||
DAIR emotion, Banking77, jailbreak, toxicity, model routing or MASSIVE. Jev's
|
||||
training data are unpublished. A Kai lead on a suite whose baseline did not see
|
||||
its source is in-distribution for Kai and out of distribution for the baseline,
|
||||
and is read as such.
|
||||
|
||||
\subsection{Accuracy on the frozen harness}
|
||||
\label{sec:accuracy}
|
||||
|
||||
\begin{table}[tbp]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{4pt}
|
||||
\input{tables/harness}
|
||||
\caption{Accuracy, Brier score and ECE on the frozen harness, per suite, for
|
||||
Kai, Laya and Jev. MASSIVE is the macro over its 51 languages
|
||||
(Table~\ref{tab:languages}); the macro row is over the other eleven suites.
|
||||
Bold: the best accuracy of the three in a row among backends that did not
|
||||
train on that suite's test rows. $^\dagger$: Laya's card lists the suite's
|
||||
dataset in its mixture and the harness draws the suite from that dataset's
|
||||
train split; the clean macro omits those suites. Written by \texttt{bench
|
||||
tex}; the last row names the revisions.}
|
||||
\label{tab:harness}
|
||||
\end{table}
|
||||
|
||||
\paragraph{What the table says.}
|
||||
Stage a7 leads on seven suites: emotion 0.935, Banking77 0.907, phishing
|
||||
0.990, toxicity 0.802, RAG relevance 0.675, model routing 1.000 and MASSIVE
|
||||
0.909 across 51 languages against Jev's 0.890 and Laya's 0.382. It ties email
|
||||
spam (0.998 to 0.998). It trails on four, each by less than a6 did: AG News
|
||||
0.943 to Laya's 0.950, jailbreak 0.920 to Jev's 0.940, typed decisions 0.759 to
|
||||
Laya's typed checkpoint at 0.766 (above Jev's 0.736), and support triage 0.443
|
||||
to Laya's 0.502. Typed decisions' score questions now lead Laya's typed
|
||||
checkpoint, 0.729 to 0.723 (Section~\ref{sec:score}); choice (0.723 to 0.733)
|
||||
and \op{noul} (0.835 to 0.857) trail it. Support triage is the widest gap:
|
||||
four of its queues overlap, Kai's recall on them is 0.17 to 0.44, and Laya
|
||||
answers the largest queue for 58\% of tickets against its 30\% share. Every
|
||||
figure here is \texttt{hanzoai/benchmarks} \texttt{decision/results/kai-a7}
|
||||
\meas.
|
||||
|
||||
\paragraph{The gate.}
|
||||
A checkpoint replaces a baseline in a deployment only when \texttt{bench gate}
|
||||
accepts it: on up to 100 drawn cases per harness and extension suite and their
|
||||
robustness transforms, no compared suite may lose more than 0.02 accuracy or
|
||||
gain more than 0.03 ECE, whatever the macro average, and for Laya the native
|
||||
runtime's parity must hold. The first stage-A checkpoint was rejected: macro
|
||||
accuracy 0.639 over the 62 suites against Laya's 0.438, parity held, and seven
|
||||
suites regressed, RAG relevance, typed decisions, Banking77 and jailbreak among
|
||||
them \meas{} (\texttt{hanzoai/benchmarks} \texttt{9aa6a46}). Stage a7 is
|
||||
rejected against Laya on one suite, support triage, and against Jev on typed
|
||||
decisions, toxicity (its ECE on the drawn cases, at 0.802 accuracy to Jev's
|
||||
0.662 over the suite) and eleven of the 51 MASSIVE languages \meas; so it does
|
||||
not replace either baseline in a deployment, and this paper claims no such
|
||||
thing.
|
||||
|
||||
\subsection{Capabilities the baselines lack by construction}
|
||||
\label{sec:capabilities}
|
||||
|
||||
These suites are \texttt{hanzoai/benchmarks} \texttt{decision/capability}, in
|
||||
the harness's case format; every backend gets the same cases. The baselines'
|
||||
kept runs are at \texttt{4e57fb2}.
|
||||
|
||||
\begin{description}[leftmargin=1.5em,style=nextline]
|
||||
\item[Cardinality.] One choice among $K$ options: 4 and 16 (the gold Banking77
|
||||
label with its nearest labels by word overlap), 77 (Banking77), 150
|
||||
(CLINC150), and 1{,}000 to 100{,}000 (WordNet: a definition to be matched to
|
||||
its concept among co-hyponyms and filler). An unanswered question counts
|
||||
as wrong. Laya rejects a question whose option markers fall past its
|
||||
context; Jev refuses more than 255 options. Laya's authors' recipe for many
|
||||
options is a top-20 shortlist from an encoder, which caps accuracy at the
|
||||
shortlist's recall; the table reports every model on the full option set,
|
||||
where Kai's retrieval keeps the mass it cuts (Section~\ref{sec:factor}).
|
||||
\item[Joint coherence.] Two families of synthetic programs, 200 states each,
|
||||
ask five dependent questions of one state (a vehicle's fault, severity,
|
||||
readiness, action and review; a source selection's option, evidence, risk,
|
||||
readiness and review), with gold computed from a latent world by a policy
|
||||
the state spells out, so every gold answer keeps every rule. The baselines
|
||||
answer each question independently; Kai runs the refinement of
|
||||
Section~\ref{sec:diffusion} over a decoder stage a6 has not trained, and
|
||||
loses this suite to Jev (0.306 per variable to 0.837, and a rule broken in
|
||||
every state before projection): the decoder is what stage C trains. Per-variable accuracy, the share of states with
|
||||
all five right, and the share whose answers break a rule, as answered and
|
||||
after the same exact projection applied to every backend's marginals.
|
||||
\item[Invariance.] 200 Banking77 questions of 16 options asked in five
|
||||
orders: the share whose top answer changes and the largest probability
|
||||
change; 400 \op{noul} questions asked with the two sides' descriptions
|
||||
exchanged, and again with the statement negated: the share whose answer
|
||||
mirrors. Proposition~\ref{prop:symmetry} predicts no flips and exact
|
||||
mirrors under the exchange for Kai, up to rounding; under negation a
|
||||
mirror is learned, not guaranteed, for every backend.
|
||||
\item[Media.] Human activity from smartphone inertial signals, a turbofan's
|
||||
remaining life from C-MAPSS telemetry, and a valve's condition from its
|
||||
sound (MIMII): the baselines read text renderings of the signals, Kai the
|
||||
records through its adapters when the checkpoint reads evidence, else the
|
||||
same rendering, which the table records.
|
||||
\item[Conformal sets.] Split-conformal prediction sets~\cite{vovk2005} at a
|
||||
90\% target over every answer on the frozen suites: coverage and mean set
|
||||
size.
|
||||
\item[Refresh.] A study program re-run after one evidence record changes:
|
||||
the questions put to a model, against a cold run.
|
||||
\item[Deployment.] Whether the backend answers inside a sandbox with the
|
||||
network denied: Laya does and Jev cannot, and every Jev call sends the state
|
||||
to a third party \meas.
|
||||
\end{description}
|
||||
|
||||
\begin{table}[tbp]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{4pt}
|
||||
\input{tables/capability}
|
||||
\caption{Capabilities, Kai against Laya and Jev: cardinality, joint coherence,
|
||||
invariance, media, conformal sets, refresh and offline operation. Written by
|
||||
\texttt{bench tex}; the last row names the revisions.}
|
||||
\label{tab:capability}
|
||||
\end{table}
|
||||
|
||||
\subsection{Speed}
|
||||
\label{sec:speed}
|
||||
|
||||
A call is one state with $N$ questions, timed from tokenizing to probabilities
|
||||
on the host, the first call at each $N$ discarded, percentiles nearest-rank
|
||||
(\texttt{bench speed}). Kai and Laya run on the same Rust runtime, device and
|
||||
batch sizes, their calls interleaved, in BF16 on a production backend, the
|
||||
Radeon 8060S of an AMD Strix Halo under ROCm; Jev is one Decisions API call over
|
||||
the network, split into the largest chunks it accepts,
|
||||
eight in flight, when it refuses the whole. The table's last row names the Laya
|
||||
checkpoint timed: Laya's multilingual checkpoint shares Kai's encoder,
|
||||
mmBERT-base, so against it the difference is the head and the layout, while its
|
||||
English and typed-decisions checkpoints are ModernBERT-large, 28 layers of width
|
||||
1{,}024 against 22 of width 768. Kai's advantage, where it has one, comes from what
|
||||
Laya's layout cannot share: each question's sequence holds its question and the
|
||||
state but no options, each distinct option is encoded once for every question
|
||||
that lists it, and each question's head costs the options it scores, not a
|
||||
sequence holding all of them. The stage-A checkpoints use the per-question
|
||||
layout (Section~\ref{sec:evidence}), so these timings do not include encoding
|
||||
the state once for all $N$ questions, which the shared layout adds. Kai
|
||||
leads Laya from $N = 10$ (44.7\,ms to 116\,ms) and by 4.9$\times$ at $N =
|
||||
1{,}000$ (1.98\,s to 9.77\,s); Laya's single question is faster (16.5\,ms to
|
||||
19.8\,ms). Jev, whose remote accelerators batch a whole call, is slower than
|
||||
Kai up to $N = 100$ and faster from $N = 500$ \meas.
|
||||
|
||||
\begin{table}[tbp]
|
||||
\centering
|
||||
\small
|
||||
\setlength{\tabcolsep}{4pt}
|
||||
\input{tables/speed}
|
||||
\caption{Latency per call (ms, p50 and p95) and questions per second, by
|
||||
questions per state, on each production backend timed. Written by
|
||||
\texttt{bench tex}; the last row names the machine and revisions.}
|
||||
\label{tab:speed}
|
||||
\end{table}
|
||||
|
||||
% Flush the result tables here, so none drifts past the section.
|
||||
\clearpage
|
||||
@@ -1,74 +0,0 @@
|
||||
\section{Limits}
|
||||
\label{sec:limits}
|
||||
|
||||
\paragraph{What is not measured.}
|
||||
Until \texttt{bench tex} writes the capability and speed tables for the final
|
||||
checkpoint, this paper claims no capability or speed figure for it.
|
||||
Stage B's adapters and stage C's decoder have code, data and stage files but no
|
||||
trained checkpoint, so the media rows measure a text rendering unless the
|
||||
scored checkpoint reads evidence, and the joint rows measure refinement over
|
||||
the factorized head, not the slot decoder. The Enso evaluation is a design.
|
||||
|
||||
\paragraph{What is not built.}
|
||||
Latents kept across calls, refinement inside the program executor, the program
|
||||
form of the wire, the closed-form weight-change bound, sampled flip
|
||||
probabilities, rejecting a narrative that states an uncited number, and
|
||||
distilling refinement into one or two passes are \proposed.
|
||||
|
||||
\paragraph{What the harness cannot show.}
|
||||
Kai trains on the train split of every harness source, so its leads over a
|
||||
model that did not are in-distribution; with Jev's training data unknown, no
|
||||
table here measures generalisation to a new task. Laya's typed-decisions score
|
||||
rests on templates shared with half the test set
|
||||
(Section~\ref{sec:overlap}), and the harness's MASSIVE suites hold 100
|
||||
utterances per language, so a language's accuracy moves by 0.01 per question.
|
||||
The capability suites were built by us, for properties Kai was designed to
|
||||
have; they show what the baselines cannot do by construction, not that Kai
|
||||
does it well, which only their Kai rows say.
|
||||
|
||||
\paragraph{What stage A leaves open.}
|
||||
The collapse of Section~\ref{sec:collapse} is located (encoder, full mixture
|
||||
under a $7\times$ outer step) but not attributed to a part of the mixture;
|
||||
the fix removes the aggressive step and restarts from Laya's weights rather than
|
||||
explaining it. Local SGD at a gentle outer step may still move the encoder
|
||||
further than one process does at the same learning rates, and only the harness
|
||||
and the context similarity say whether it did.
|
||||
|
||||
\paragraph{What stage a7 leaves open.}
|
||||
Support triage and jailbreak did not move under repetition: triage's four
|
||||
overlapping queues need pairs of near tickets from different queues, and
|
||||
jailbreak needs benign near-neighbours of attacks, not more attacks; the next
|
||||
stages add both from pinned public data. The joint-coherence suite is lost
|
||||
outright until stage C trains the decoder. The serving modes of the design, a
|
||||
decision over a cached latent and an incremental encoder over evidence chunks,
|
||||
are built (the cache of question, state and option latents is exact and
|
||||
tested) but not yet timed on a production backend; every latency in this paper
|
||||
is a full encode per call.
|
||||
|
||||
\paragraph{Known failure modes of Laya.}
|
||||
Its authors report that boolean-word labels can be followed instead of their
|
||||
descriptions, negated requests answered as unnegated, \op{noul} answers driven
|
||||
by the labels rather than the state, and a score's first level rarely picked
|
||||
by the multilingual checkpoint~\cite{laya} \reported. A program's tests should
|
||||
add a negated and a relabelled variant of each case, which Kai's robustness
|
||||
transforms do in training.
|
||||
|
||||
\paragraph{Calibration is assumed, then checked.}
|
||||
Thresholds, abstention, conformal sets and flip probabilities take
|
||||
probabilities at their word; a shift in the evidence distribution breaks fitted
|
||||
temperatures and pinned calibrations alike, and only shadow records detect
|
||||
it.
|
||||
|
||||
\paragraph{Adversarial state beyond the lattice.}
|
||||
Proposition~\ref{prop:tighten} protects constraints, not preferences: an
|
||||
adversary can push routing toward a cheaper model or completion toward an early
|
||||
finish. Those need deterministic backstops, such as requiring a passing test
|
||||
run in the transcript. Deliberate friction is bounded by policy, not
|
||||
prevented.
|
||||
|
||||
\paragraph{The study model has assumptions.}
|
||||
Additive scores need preferentially independent criteria; one-parameter flips
|
||||
hold the rest fixed; assumption sweeps are a grid; sampled flip probabilities
|
||||
treat cells as independent, which fails when two read the same evidence. A
|
||||
study's figures are its sources'; the JLTV trade cites a company figure for the
|
||||
hybrid's fuel economy, and its package says so rather than resolving it.
|
||||
@@ -1,71 +0,0 @@
|
||||
\section{Related work}
|
||||
\label{sec:related}
|
||||
|
||||
\paragraph{Typed decision models.}
|
||||
TypeSafe's Jev~\cite{typesafejev} introduced the typed interface adopted
|
||||
here, served through OpenRouter~\cite{openrouterdecisions}; its design
|
||||
notes~\cite{jevnote} argue for typed state and permissions as decisions.
|
||||
Laya~\cite{laya} is an open encoder implementation trained with proper scoring
|
||||
rules~\cite{gneiting2007}.
|
||||
|
||||
\paragraph{Encoders that score options.}
|
||||
Laya's joint head is a cross-encoder, as in passage
|
||||
re-ranking~\cite{nogueira2019} and entailment-based zero-shot
|
||||
classification~\cite{yin2019}, after BERT~\cite{devlin2019}. Encoding
|
||||
candidates independently, caching them, and letting them attend to a context is
|
||||
the poly-encoder~\cite{humeau2020poly} and, per token, late
|
||||
interaction~\cite{khattab2020colbert}; Kai adds a law per type, a
|
||||
cumulative-link model for ordinal answers~\cite{mccullagh1980}, and retrieval
|
||||
that keeps the mass it cuts.
|
||||
|
||||
\paragraph{Parallel refinement.}
|
||||
Masked discrete diffusion~\cite{austin2021d3pm},
|
||||
mask-predict~\cite{ghazvininejad2019} and MaskGIT~\cite{chang2022maskgit}
|
||||
predict masked tokens in parallel and re-predict the uncertain ones. Kai's unit
|
||||
is a typed variable with its own domain, ordered by the program's DAG and
|
||||
projected onto its rules.
|
||||
|
||||
\paragraph{Multimodal front ends.}
|
||||
Whisper~\cite{radford2023whisper} and SigLIP~\cite{zhai2023siglip} give
|
||||
frozen audio and image features; time-series
|
||||
models~\cite{das2024timesfm,ansari2024chronos} give forecasts, which enter Kai
|
||||
as evidence, not answers.
|
||||
|
||||
\paragraph{Structured output and guards.}
|
||||
Constrained decoding~\cite{willard2023} removes parse failures, not the
|
||||
generation, and its probability is a sequence's, not a distribution over the
|
||||
caller's options. Tool-using agents~\cite{yao2023react,schick2023toolformer}
|
||||
make the decisions of Table~\ref{tab:programs} inside the generative loop.
|
||||
Guard models such as Llama Guard~\cite{inan2023llamaguard} judge text against
|
||||
a harm taxonomy; Section~\ref{sec:authority} places any guard below policy.
|
||||
|
||||
\paragraph{Calibration and abstention.}
|
||||
Temperature scaling~\cite{guo2017}, the reject option~\cite{chow1970},
|
||||
selective classification~\cite{geifman2017} and conformal
|
||||
prediction~\cite{vovk2005} are the theory behind fitted temperatures,
|
||||
abstention to \ask{} and the prediction sets of Table~\ref{tab:capability}.
|
||||
|
||||
\paragraph{Training across machines.}
|
||||
Local SGD with an outer Nesterov step is DiLoCo~\cite{douillard2023diloco}; the
|
||||
outer step's effective multiplier (Proposition~\ref{prop:outer}) is the
|
||||
quantity its authors tune. Carrying the rounding of a compressed update into
|
||||
the next is error feedback~\cite{seide2014onebit,karimireddy2019ef}; bf16
|
||||
compute over F32 masters is mixed-precision training~\cite{micikevicius2018mixed}.
|
||||
Kai's trainer adds exact bookkeeping: join-order summation, a broadcast change
|
||||
that every copy applies bit for bit, and resume equal to the uninterrupted run.
|
||||
|
||||
\paragraph{Contamination.}
|
||||
Near-duplicate detection by min-hashed shingles~\cite{broder1997resemblance} is
|
||||
the standard tool for deduplicating training corpora against each other and
|
||||
against benchmarks~\cite{lee2022dedup}. Kai's barrier adds sampled-span
|
||||
containment, which finds a test item embedded in a longer training text, and
|
||||
treats evaluation as a role that no license decision admits.
|
||||
|
||||
\paragraph{Authority and decision analysis.}
|
||||
Enforcing the join of two verdicts is the lattice model of information
|
||||
flow~\cite{denning1976} applied to decisions, and a policy evaluated before
|
||||
every action is a reference monitor~\cite{anderson1972}. Package scores are
|
||||
additive multi-attribute utility~\cite{keeney1976}; weight sensitivity is
|
||||
studied by Triantaphyllou and S\'anchez~\cite{triantaphyllou1997}, global
|
||||
sensitivity by Saltelli et al.~\cite{saltelli2008}, and what is worth
|
||||
resolving by the value of information~\cite{howard1966}.
|
||||
@@ -1,31 +0,0 @@
|
||||
\section{Conclusion}
|
||||
\label{sec:conclusion}
|
||||
|
||||
Most small decisions do not need a generative model. A typed question over
|
||||
evidence, answered by an encoder with a law per type, gives a distribution a
|
||||
caller can threshold, record and replay. Encoding options alone removes the
|
||||
limits a shared sequence puts on option count, order and question count;
|
||||
decoding a program's questions as typed variables, in waves bounded by depth
|
||||
and projected onto rules, makes their answers coherent; joining every model
|
||||
verdict with a deterministic policy makes safety the policy's, with the cost of
|
||||
trusting the model counted exactly in shadow.
|
||||
|
||||
Training Kai taught as much as designing it. Local SGD across three kinds of
|
||||
accelerator works and is exact to the bit, but an outer step that multiplies a
|
||||
round's delta seven times, over a mixture this broad, cost the encoder its
|
||||
ability to relate two texts while every single-text task improved; only
|
||||
measurements aimed at the encoder itself found it. A barrier against the test
|
||||
set is only as good as its notion of ``the same'': half of one baseline's test
|
||||
set had same-wording siblings in its training data, and measuring the halves
|
||||
apart showed the siblings did not help it. Both are written down here with the
|
||||
runs that show them.
|
||||
|
||||
Kai's case does not rest on winning every benchmark: after stage a7 Laya leads
|
||||
on support triage and AG News, where its mixture holds the sources, and by 0.7
|
||||
points on typed decisions through its typed checkpoint, Jev on jailbreak, and
|
||||
Kai on the other eight, MASSIVE among them; Kai enters this
|
||||
paper only through the tables its benchmark writes. It rests on what a hosted model cannot offer:
|
||||
a pinned revision, deployment where the data live, no per-call fee, a runtime
|
||||
linked into the system it governs, a package per run that says what was
|
||||
decided, from what, and what would change it, and, in Enso, less generation per
|
||||
successful task, which Section~\ref{sec:enso} is designed to measure.
|
||||
@@ -1,103 +0,0 @@
|
||||
\section{The wire}
|
||||
\label{app:wire}
|
||||
|
||||
A request to \op{POST /v1/decisions}, in OpenRouter's Decisions schema:
|
||||
|
||||
\begin{lstlisting}[style=wire]
|
||||
{
|
||||
"model": "kai",
|
||||
"state": "Hi, we were billed twice for March. Please refund the duplicate today or we will cancel our plan.",
|
||||
"questions": {
|
||||
"department": {
|
||||
"type": "choice",
|
||||
"instructions": "Which department should handle this?",
|
||||
"criteria": {
|
||||
"billing": "invoices, payments, refunds",
|
||||
"technical": "bugs, outages, system errors",
|
||||
"other": "everything else"
|
||||
}
|
||||
},
|
||||
"urgency": {
|
||||
"type": "score",
|
||||
"instructions": "How urgent is this?",
|
||||
"criteria": ["not urgent", "soon", "blocking"]
|
||||
},
|
||||
"churn_risk": {
|
||||
"type": "noul",
|
||||
"instructions": "Does the user threaten to cancel or leave?"
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The response carries one typed answer per question: \op{confidence} is
|
||||
$\kappa$ (Equation~\eqref{eq:kappa}), \op{answer\_confidence} is $\pmax$, and
|
||||
other Hanzo fields are omitted. The values are illustrative, not measured.
|
||||
|
||||
\begin{lstlisting}[style=wire]
|
||||
{
|
||||
"id": "dec_...",
|
||||
"model": "kai",
|
||||
"provider": "hanzo",
|
||||
"answers": {
|
||||
"department": {
|
||||
"type": "choice", "choice": "billing",
|
||||
"probabilities": {"billing": 0.90, "technical": 0.06, "other": 0.04},
|
||||
"confidence": 0.85, "answer_confidence": 0.90
|
||||
},
|
||||
"urgency": {
|
||||
"type": "score", "score": 1.75,
|
||||
"legend": {"0": "not urgent", "1": "soon", "2": "blocking"},
|
||||
"probabilities": {"0": 0.05, "1": 0.15, "2": 0.80},
|
||||
"confidence": 0.70, "answer_confidence": 0.80
|
||||
},
|
||||
"churn_risk": {
|
||||
"type": "noul", "noul": 0.85,
|
||||
"confidence": 0.70, "answer_confidence": 0.85
|
||||
}
|
||||
},
|
||||
"usage": {"input_tokens": 164, "output_tokens": 0, "cost": 0}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Changing \op{"model"} to \op{"typesafe/jev-1.13"} sends the same request to
|
||||
Jev through OpenRouter; nothing else changes.
|
||||
|
||||
\section{A Decision Program}
|
||||
\label{app:program}
|
||||
|
||||
\op{agent.command-risk@1}, as in \texttt{program/programs} \shipped, pinned
|
||||
to stage a5's calibration:
|
||||
|
||||
\begin{lstlisting}[style=wire]
|
||||
{
|
||||
"id": "agent.command-risk@1",
|
||||
"description": "Before an agent runs a shell command: allow it, ask the user, or deny it.",
|
||||
"model": "kai",
|
||||
"mode": "advisory",
|
||||
"calibration": "cal_47711d44267fdbdd",
|
||||
"questions": {
|
||||
"verdict": {
|
||||
"type": "choice",
|
||||
"instructions": "Should the agent run this shell command?",
|
||||
"criteria": {
|
||||
"allow": "read-only, or confined to the working repository",
|
||||
"ask": "writes outside the repository, installs software or touches the network",
|
||||
"deny": "reads or sends secrets, keys, ~/.ssh or .env files, or destroys data"
|
||||
}
|
||||
},
|
||||
"secret_exposure": {"type": "noul", "instructions": "Could this command read, print or send credentials, keys or tokens?"},
|
||||
"production_impact": {"type": "noul", "instructions": "Could this command change or break a production system or shared data?"},
|
||||
"network": {"type": "noul", "instructions": "Does this command send or fetch data over the network?"}
|
||||
},
|
||||
"thresholds": {"verdict": 0.5, "secret_exposure": 0.3, "production_impact": 0.4, "network": 0.5},
|
||||
"verdict": {
|
||||
"from": "verdict",
|
||||
"escalate": {"secret_exposure": "deny", "production_impact": "ask", "network": "ask"}
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The verdict question abstains to \ask{} below $\kappa = 0.5$; each escalation
|
||||
raises the verdict when its \op{noul} reaches its threshold; the result joins
|
||||
the policy's verdict when the program runs enforced.
|
||||
@@ -1,12 +0,0 @@
|
||||
\section{MASSIVE by language}
|
||||
\label{app:results}
|
||||
|
||||
\begin{table}[h]
|
||||
\centering
|
||||
\small
|
||||
\input{tables/languages}
|
||||
\caption{MASSIVE intent accuracy by language (ISO 639 codes), 100 utterances
|
||||
each, 20 options; random is 0.05. Written by \texttt{bench tex}; the last row
|
||||
names the revisions.}
|
||||
\label{tab:languages}
|
||||
\end{table}
|
||||
@@ -1,45 +0,0 @@
|
||||
% capability.tex: written by `bench tex` (hanzoai/decision); Kai runs/a7, weights 0834a74f, metal bf16; harness a1a4a73; benchmarks 039fbfe
|
||||
% Kai: joint rows are its refinement over three passes (projected: its own selection and projection); Laya's joint rows are its typed-decisions checkpoint; media is Laya as routed. Rejected: questions a backend refuses, over all asked.
|
||||
\begin{tabular}{@{}lccc@{}}
|
||||
\toprule
|
||||
& Kai & Laya & Jev \\
|
||||
\midrule
|
||||
\multicolumn{4}{@{}l}{\emph{Cardinality}} \\
|
||||
Accuracy, $K = 4$ & 0.685 & 0.777 & 0.905 \\
|
||||
Accuracy, $K = 16$ & 0.395 & 0.670 & 0.853 \\
|
||||
Accuracy, $K = 77$ & 0.255 & 0.425 & 0.843 \\
|
||||
Accuracy, $K = 150$ & 0.287 & 0.610 & 0.940 \\
|
||||
Accuracy, $K = 1{,}000$ & 0.005 & 0.000 & 0.000 \\
|
||||
Accuracy, $K = 10{,}000$ & 0.000 & 0.000 & 0.000 \\
|
||||
Accuracy, $K = 100{,}000$ & 0.000 & 0.000 & 0.000 \\
|
||||
Rejected, $K = 1{,}000$ & 0.000 & 1.000 & 1.000 \\
|
||||
Rejected, $K = 10{,}000$ & 0.000 & 1.000 & 1.000 \\
|
||||
Rejected, $K = 100{,}000$ & 0.000 & 1.000 & 1.000 \\
|
||||
\midrule
|
||||
\multicolumn{4}{@{}l}{\emph{Joint coherence, five dependent questions}} \\
|
||||
Accuracy & 0.306 & 0.336 & 0.837 \\
|
||||
Exact & 0.000 & 0.005 & 0.438 \\
|
||||
Violations & 1.000 & 0.637 & 0.247 \\
|
||||
Accuracy, projected & 0.341 & 0.328 & 0.879 \\
|
||||
Exact, projected & 0.010 & 0.040 & 0.560 \\
|
||||
\midrule
|
||||
\multicolumn{4}{@{}l}{\emph{Invariance}} \\
|
||||
Permutation, flip & 0.000 & 0.255 & 0.060 \\
|
||||
Permutation, max $\Delta p$ & 0.000 & 0.996 & 0.470 \\
|
||||
Noul sides swapped, mirror & 0.915 & 0.205 & 0.062 \\
|
||||
Noul negated, mirror & 0.430 & 0.300 & 0.882 \\
|
||||
\midrule
|
||||
\multicolumn{4}{@{}l}{\emph{Media, accuracy}} \\
|
||||
Human activity (HAR) & 0.160 & 0.203 & 0.153 \\
|
||||
Turbofan life (C-MAPSS) & 0.330 & 0.170 & 0.300 \\
|
||||
Valve sound (MIMII) & 0.500 & 0.500 & 0.840 \\
|
||||
\midrule
|
||||
\multicolumn{4}{@{}l}{\emph{Conformal sets, 90\% target}} \\
|
||||
Coverage & 0.901 & 0.901 & 0.901 \\
|
||||
Mean set size & 2.498 & 6.801 & 1.304 \\
|
||||
\midrule
|
||||
Refresh: questions asked / full & 6 / 101 & 100 / 100 & 100 / 100 \\
|
||||
Runs offline & yes & yes & no \\
|
||||
\bottomrule
|
||||
\multicolumn{4}{@{}l@{}}{\footnotesize\begin{tabular}[t]{@{}l@{}}Kai runs/a7, weights 0834a74f, metal bf16 \\ harness a1a4a73, benchmarks 039fbfe\end{tabular}} \\
|
||||
\end{tabular}
|
||||
@@ -1,26 +0,0 @@
|
||||
% harness.tex: written by `bench tex` (hanzoai/decision); Kai runs/a7, weights 0834a74f, metal bf16; harness a1a4a73; benchmarks 039fbfe
|
||||
% Laya: the checkpoint its router picks per case; typed decisions on laya-agent (kai-1-agent), the typed-decisions checkpoint Laya ships and its router does not pick.
|
||||
\begin{tabular}{@{}l@{\quad}ccc@{\quad}ccc@{\quad}ccc@{}}
|
||||
\toprule
|
||||
& \multicolumn{3}{c}{Accuracy} & \multicolumn{3}{c}{Brier} & \multicolumn{3}{c}{ECE} \\
|
||||
Suite & Kai & Laya & Jev & Kai & Laya & Jev & Kai & Laya & Jev \\
|
||||
\midrule
|
||||
AG News & 0.943 & \textbf{0.950} & 0.860 & 0.091 & 0.081 & 0.232 & 0.034 & 0.032 & 0.102 \\
|
||||
DAIR Emotion & \textbf{0.935} & 0.595 & 0.603 & 0.080 & 0.696 & 0.646 & 0.019 & 0.306 & 0.280 \\
|
||||
Banking77 & \textbf{0.907} & 0.425 & 0.835 & 0.165 & 0.925 & 0.257 & 0.076 & 0.381 & 0.073 \\
|
||||
Support triage & \textbf{0.443} & 0.502$^\dagger$ & 0.365 & 0.975 & 0.644 & 1.056 & 0.441 & 0.091 & 0.483 \\
|
||||
Email spam & \textbf{0.998} & \textbf{0.998} & 0.978 & 0.005 & 0.005 & 0.038 & 0.003 & 0.011 & 0.060 \\
|
||||
Phishing & \textbf{0.990} & 0.983$^\dagger$ & 0.900 & 0.020 & 0.026 & 0.152 & 0.010 & 0.010 & 0.039 \\
|
||||
Jailbreak & 0.920 & 0.705 & \textbf{0.940} & 0.147 & 0.543 & 0.104 & 0.072 & 0.262 & 0.047 \\
|
||||
Toxicity & \textbf{0.802} & 0.530 & 0.662 & 0.384 & 0.602 & 0.432 & 0.191 & 0.297 & 0.177 \\
|
||||
RAG relevance & \textbf{0.675} & 0.625 & 0.620 & 0.419 & 0.466 & 0.628 & 0.029 & 0.117 & 0.279 \\
|
||||
Model routing & \textbf{1.000} & 0.639 & 0.977 & 0.000 & 0.494 & 0.040 & 0.000 & 0.089 & 0.014 \\
|
||||
Typed decisions & 0.759 & \textbf{0.766} & 0.736 & 0.388 & 0.400 & 0.366 & 0.172 & 0.213 & 0.047 \\
|
||||
MASSIVE (51 languages, macro) & \textbf{0.909} & 0.382 & 0.890 & 0.136 & 0.987 & 0.161 & 0.060 & 0.418 & 0.064 \\
|
||||
\midrule
|
||||
Macro, 11 suites & 0.852 & 0.702 & 0.770 & 0.243 & 0.444 & 0.359 & 0.095 & 0.164 & 0.145 \\
|
||||
Clean macro, 9 suites & 0.882 & 0.693 & 0.801 & & & & & & \\
|
||||
Best of three, 12 suites & 9 & 3 & 1 & & & & & & \\
|
||||
\bottomrule
|
||||
\multicolumn{10}{@{}l@{}}{\footnotesize\begin{tabular}[t]{@{}l@{}}Kai runs/a7, weights 0834a74f, metal bf16 \\ harness a1a4a73, benchmarks 039fbfe\end{tabular}} \\
|
||||
\end{tabular}
|
||||
@@ -1,35 +0,0 @@
|
||||
% languages.tex: written by `bench tex` (hanzoai/decision); Kai runs/a7, weights 0834a74f, metal bf16; harness a1a4a73; benchmarks 039fbfe
|
||||
% MASSIVE intent accuracy by language, 20 options, 100 utterances each; Laya as its router picks.
|
||||
\begin{tabular}{@{}lccc@{\qquad}lccc@{}}
|
||||
\toprule
|
||||
Language & Kai & Laya & Jev & Language & Kai & Laya & Jev \\
|
||||
\midrule
|
||||
af & 0.910 & 0.340 & 0.870 & ko & 0.910 & 0.470 & 0.940 \\
|
||||
am & 0.850 & 0.150 & 0.850 & lv & 0.890 & 0.300 & 0.850 \\
|
||||
ar & 0.920 & 0.460 & 0.870 & ml & 0.870 & 0.280 & 0.910 \\
|
||||
az & 0.940 & 0.360 & 0.880 & mn & 0.880 & 0.160 & 0.840 \\
|
||||
bn & 0.920 & 0.450 & 0.860 & ms & 0.930 & 0.270 & 0.920 \\
|
||||
cy & 0.860 & 0.160 & 0.760 & my & 0.920 & 0.160 & 0.890 \\
|
||||
da & 0.920 & 0.460 & 0.880 & nb & 0.940 & 0.500 & 0.860 \\
|
||||
de & 0.910 & 0.530 & 0.939 & nl & 0.920 & 0.400 & 0.900 \\
|
||||
el & 0.940 & 0.440 & 0.940 & pl & 0.940 & 0.470 & 0.920 \\
|
||||
en & 0.940 & 0.820 & 0.920 & pt & 0.930 & 0.440 & 0.900 \\
|
||||
es & 0.920 & 0.530 & 0.930 & ro & 0.910 & 0.370 & 0.940 \\
|
||||
fa & 0.940 & 0.510 & 0.950 & ru & 0.970 & 0.570 & 0.940 \\
|
||||
fi & 0.920 & 0.300 & 0.890 & sl & 0.910 & 0.330 & 0.890 \\
|
||||
fr & 0.910 & 0.600 & 0.900 & sq & 0.930 & 0.290 & 0.760 \\
|
||||
he & 0.910 & 0.370 & 0.940 & sv & 0.930 & 0.480 & 0.940 \\
|
||||
hi & 0.910 & 0.460 & 0.950 & sw & 0.840 & 0.130 & 0.700 \\
|
||||
hu & 0.900 & 0.340 & 0.920 & ta & 0.880 & 0.310 & 0.920 \\
|
||||
hy & 0.890 & 0.250 & 0.840 & te & 0.870 & 0.220 & 0.910 \\
|
||||
id & 0.960 & 0.360 & 0.930 & th & 0.930 & 0.480 & 0.940 \\
|
||||
is & 0.850 & 0.330 & 0.840 & tl & 0.910 & 0.300 & 0.850 \\
|
||||
it & 0.910 & 0.470 & 0.960 & tr & 0.900 & 0.410 & 0.920 \\
|
||||
ja & 0.970 & 0.640 & 0.970 & ur & 0.900 & 0.420 & 0.900 \\
|
||||
jv & 0.890 & 0.160 & 0.750 & vi & 0.910 & 0.330 & 0.890 \\
|
||||
ka & 0.830 & 0.150 & 0.880 & zh-CN & 0.940 & 0.650 & 0.940 \\
|
||||
km & 0.840 & 0.200 & 0.810 & zh-TW & 0.950 & 0.610 & 0.930 \\
|
||||
kn & 0.910 & 0.300 & 0.870 & & & & \\
|
||||
\bottomrule
|
||||
\multicolumn{8}{@{}l@{}}{\footnotesize\begin{tabular}[t]{@{}l@{}}Kai runs/a7, weights 0834a74f, metal bf16 \\ harness a1a4a73, benchmarks 039fbfe\end{tabular}} \\
|
||||
\end{tabular}
|
||||
@@ -1,17 +0,0 @@
|
||||
% speed.tex: written by `bench tex` (hanzoai/decision); Kai runs/a7, encoder 768 wide, 22 layers; timed ROCm, BF16; harness a1a4a73; benchmarks 039fbfe
|
||||
% Kai and Laya on this runtime (hanzo-ml), same device and dtype, their calls interleaved; the last row names each checkpoint and its encoder. Jev is one network run, the same cells in every block.
|
||||
\begin{tabular}{@{}r@{\quad}cc@{\quad}cc@{\quad}cc@{\quad}ccc@{}}
|
||||
\toprule
|
||||
& \multicolumn{2}{c}{Kai} & \multicolumn{2}{c}{Laya} & \multicolumn{2}{c}{Jev, network} & \multicolumn{3}{c}{Questions/s} \\
|
||||
$N$ & p50 & p95 & p50 & p95 & p50 & p95 & Kai & Laya & Jev \\
|
||||
\midrule
|
||||
\multicolumn{10}{@{}l}{\emph{ROCm, BF16}} \\
|
||||
1 & 19.8 & 29.0 & 16.5 & 18.3 & 133 & 546 & 43.2 & 61.0 & 5.72 \\
|
||||
10 & 44.7 & 105 & 116 & 173 & 155 & 221 & 195 & 82.7 & 62.9 \\
|
||||
50 & 139 & 214 & 576 & 592 & 202 & 275 & 316 & 87.6 & 233 \\
|
||||
100 & 314 & 333 & 1{,}168 & 1{,}222 & 343 & 556 & 323 & 85.7 & 267 \\
|
||||
500 & 1{,}050 & 1{,}173 & 5{,}027 & 5{,}386 & 515 & 2{,}193 & 468 & 99.0 & 726 \\
|
||||
1{,}000 & 1{,}981 & 2{,}014 & 9{,}772 & 10{,}375 & 602 & 1{,}077 & 508 & 101 & 1{,}489 \\
|
||||
\bottomrule
|
||||
\multicolumn{10}{@{}l@{}}{\footnotesize\begin{tabular}[t]{@{}l@{}}Kai runs/a7, encoder 768 wide, 22 layers \\ harness a1a4a73, benchmarks 039fbfe \\ timed ROCm, BF16 \\ Laya laya-multilingual: hanzoai/kai-1-multilingual@3119843b, encoder 768 wide, 22 layers \\ timed calls per N: ROCm, BF16 10 \\ evo (AMD Strix Halo, Radeon 8060S, ROCm)\end{tabular}} \\
|
||||
\end{tabular}
|
||||
Binary file not shown.
@@ -39,24 +39,6 @@ export const siteConfig: SiteConfig = {
|
||||
accentColor: '#00D9FF',
|
||||
logo: '/logos/hanzo-logo.svg',
|
||||
papers: [
|
||||
// --- Typed decisions: Kai and Hanzo Decision ---
|
||||
{
|
||||
id: 'kai',
|
||||
title: 'Kai: Typed Decision Models as a Control Plane for Agentic Systems',
|
||||
subtitle: 'Decisions as versioned programs under deterministic policy, with sensitivity and refresh for auditable studies',
|
||||
abstract: 'Most AI systems treat a decision as text: evidence goes into a prompt and a recommendation comes out as prose. Hanzo Decision treats the decision as a program. A decision is a typed question (choice, score or noul) over explicit state, answered with a probability distribution over the options the caller listed, in one encoder forward pass with no generated text. Kai is the model family that answers these questions: three open checkpoints derived from Laya, published as hanzoai/kai-1, kai-1-multilingual and kai-1-agent. Versioned Decision Programs bind thresholds to a calibration and run in shadow, advisory or enforced mode. A deterministic policy stays the authority: the effective verdict is the join of the policy verdict and the model verdict on allow < ask < deny, so no model output can loosen a policy verdict, and the cost of enforcing a model is friction that shadow records count exactly. POST /v1/decisions is wire-compatible with OpenRouter\'s Decisions API and routes by model name to Kai or to Jev. For trade studies, a Decision Package records the typed answers over evidence, computes the smallest weight, answer or assumption change that flips the recommendation, and on refresh recomputes only what changed. In a recorded run, two of the three bootstrap checkpoints ranked allow first for a command that sends a private SSH key to a remote host. That result is why the model advises and the policy decides.',
|
||||
pdfUrl: '/pdfs/kai.pdf',
|
||||
latexUrl: 'https://github.com/hanzoai/papers/blob/main/kai/kai.tex',
|
||||
githubUrl: 'https://github.com/hanzoai/papers',
|
||||
date: '2026-09-24',
|
||||
authors: ['Hanzo AI Research'],
|
||||
tags: ['Agents', 'Decisions', 'Policy', 'Calibration', 'Decision Analysis'],
|
||||
relatedLinks: [
|
||||
{ label: 'Model: docs.hanzo.ai/docs/models/kai', url: 'https://docs.hanzo.ai/docs/models/kai' },
|
||||
{ label: 'Benchmarks: github.com/hanzoai/benchmarks', url: 'https://github.com/hanzoai/benchmarks/tree/main/decision' },
|
||||
{ label: 'Spec: HIP-1332', url: 'https://github.com/hanzoai/hips/blob/main/HIPs/hip-1332-kai-the-decision-model.md' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'hanzo-context-memory',
|
||||
title: 'Linkage, Not Similarity',
|
||||
|
||||
Reference in New Issue
Block a user