Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = ["src/frontend", "src/runtime", "src/models/clm", "src/models/cua_s1/native", "src/models/qwen3_5/native", "src/models/open_jev/native", "src/models/jev_vl/native", "src/models/omnijev/native", "src/models/laya", "src/backends/cuda", "src/models/decider/native", "src/models/jemm/native"]
members = ["src/frontend", "src/runtime", "src/models/clm", "src/models/cua_s1/native", "src/models/qwen3_5/native", "src/models/open_jev/native", "src/models/jev_vl/native", "src/models/omnijev/native", "src/models/laya", "src/backends/cuda", "src/models/decider/native", "src/models/jemm/native", "src/models/startlux/native"]
resolver = "3"
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ The LFM2.5-350M Transformers worker owns candidate scoring and hybrid cache bran
processing and executor modules, with shared FIFO admission and blocking
dispatch in the [native runtime](src/runtime/README.md).
- **Native CUDA workers.** The Cua-S1 4B 0.2 `text` adapter,
Open-Jev-27B-v1.1 and Open-Jev-9B run as native workers with shared CUDA
kernels. Cua-S1 also has a Python worker that serves as the correctness reference.
Open-Jev-27B-v1.1, Open-Jev-9B, and StartLux-Decision v1.1 4B Instant run
as native workers with shared CUDA kernels. Cua-S1 also has a Python
worker that serves as the correctness reference. The StartLux worker is
text-only Instant; its weights are CC BY-NC 4.0 and its GPU parity is
unverified. AutoThink is not served.
- **LAYA text serving.** LAYA runs as an external CPU Python worker, the
in-repository Python MPS/CPU worker, or a native Rust/CUDA worker on Hopper.
- **CUDA backend and planned Metal backend.** High-performance GPU operations
Expand Down Expand Up @@ -176,6 +179,7 @@ pinned runtime for text, image and video state:
| Valen-Preview-0923 | [Python reference worker](recipe/valen/reference.md); text state or one inline PNG/JPEG image, `choice`; author-run on RTX 5060 Laptop GPU (sm_120, WSL2), owner: community |
| Open-Jev-27B-v1.1 | [Native Rust/CUDA worker](recipe/open_jev/native.md); eager independent text candidates; [H200 validation](recipe/open_jev/validation.md) |
| Open-Jev-9B | The same [native Rust/CUDA worker](recipe/open_jev/native.md); eager independent text candidates; [reference comparison on sm_89](recipe/open_jev/validation-9b.md) |
| StartLux-Decision v1.1 4B Instant | [Native Rust/CUDA text worker](recipe/startlux/README.md); `choice` / `noul` / `score`; weights CC BY-NC 4.0; Instant only (no AutoThink, no 27B); GPU parity unverified; [L20X latency recipe](recipe/startlux/latency.md) |
| autotrust/JEV-27B-VL | [Experimental Rust/CUDA worker](recipe/jev_vl/README.md); single-question text, online inline PNG/JPEG and offline-preencoded image inputs; [validation scope and limits](recipe/jev_vl/validation.md) |
| CLM-v0.1-8B | [External worker with a CPU stub encoder](recipe/clm/README.md); contract checks only, real Qwen3-8B decisions unverified by this recipe |
| LFM2.5-350M | [Transformers worker](recipe/lfm2/README.md); text state and independent choice questions |
Expand Down
12 changes: 8 additions & 4 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ design. Concrete input/output types follow each executor's supported layout.
## Implementation status

The [Rust frontend](../src/frontend/README.md) currently forwards HTTP requests
to separately running workers. Cua-S1, Open-Jev and Decider have native Rust/CUDA workers
that share the [Qwen3.5/3.8 executor](../src/models/qwen3_5/native/), which accepts
single prompts and bounded packed prefill. Cua-S1 and Open-Jev-9B use
to separately running workers. Cua-S1, Open-Jev, Decider, and StartLux Instant
4B have native Rust/CUDA workers that share the
[Qwen3.5/3.8 executor](../src/models/qwen3_5/native/), which accepts
single prompts and bounded packed prefill. StartLux Instant uses a
bidirectional full-attention call on each prompt; its GDN stays causal, and
it does not pack prompts or cache prefixes. Cua-S1 and Open-Jev-9B use
single-prompt calls; Open-Jev-27B-v1.1 packs candidates within one request for
input and gate/up GEMMs while preserving per-sequence mixers and output/down GEMM
shapes. Decider optionally packs up to four complete rows and 4096 tokens within
Expand Down Expand Up @@ -72,14 +75,15 @@ and candidate identity, usage, and response metadata outside the executor.
| Decider | Complete independent token-ID rows in question order; Score expands one no/yes row per level. | One BF16-projection-rounded FP32 selected-label logit vector per row. | Per-type calibration, whole-Score normalization, ordered typed answers and unique-prefix token usage. |
| Laya | One padded request: token IDs, true lengths, question types and ordered option markers; at most 16 questions, 512 tokens per row and 2048 markers. | Per-question FP32 option logits and two action logits copied back after GPU heads. | Calibrate and decode ordered `choice`, `score` and `noul` answers, usage and metadata. |
| JEMM | Ordered token IDs, three-axis positions, candidate counts and optional shared image patches for one complete request. | Per-question selected BF16 label logits copied back as FP32. | Apply checksum-covered text/image calibration and reconstruct ordered `choice`, `score` and `noul` answers and usage. |
| StartLux Instant 4B | One unpadded token-ID prompt per question, or per knockout group and then a final prompt, in request order. | FP32 letter logits from a CPU dot of the tied embedding rows at the last position. | Per-type temperature, none-check split, wide-choice residual, and ordered `choice`, `noul`, and `score` answers with token usage. |

Cua-S1 and Open-Jev-9B input collections are serial work. For Open-Jev-27B-v1.1,
Open-Jev's model-specific batch adapter packs up to 16 independent candidates and
4096 tokens per group; longer prompts
execute alone. It restores question/candidate grouping before normalization.
Laya batches questions within one request. Shared runtime
admission precedes blocking dispatch: Cua-S1 admits one question forward at a
time; Open-Jev, Decider and Laya admit one complete request. Cua-S1's CPU letter projection
time; Open-Jev, Decider, Laya, and StartLux Instant admit one complete request. StartLux runs each prompt inside that admission one at a time. Cua-S1's CPU letter projection
stays outside admission; Open-Jev's scalar heads and Laya's GPU heads and
synchronized readback remain inside their request unit. Decider includes every
backbone row and CUDA head projection, synchronizes both streams and retires
Expand Down
4 changes: 3 additions & 1 deletion docs/supported-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Models that are being added are also tracked in issues labeled [new model](https
| Valen-Preview-0923 | [Python reference worker](../recipe/valen/reference.md); text state or one inline PNG/JPEG image; `choice` questions | Not supported | Author-run on RTX 5060 Laptop (sm_120, WSL2): one text and one 2×2 PNG request; input and readout parity ≤1e-6 against reference (model outputs not compared). Owner: community. | Not supported | Python 3.12, pinned Valen source/checkpoint, Qwen3.5-2B base, BF16 CUDA |
| Open-Jev-27B-v1.1 | [Native Rust/CUDA worker](../recipe/open_jev/native.md) on the shared Qwen3.5/3.8 executor | Not supported | Validated on H200 (sm_90) for the [74 single-candidate workload](../recipe/open_jev/validation.md) | Not supported | Compute capability 8.0 or newer, CUDA toolkit to build, exported merged weights and trained head |
| Open-Jev-9B | The same [native Rust/CUDA worker](../recipe/open_jev/native.md) | Not supported | Validated on compute capability 8.9 against the reference for [253 requests](../recipe/open_jev/validation-9b.md) | Not supported | Compute capability 8.0 or newer, CUDA toolkit to build, exported merged weights and trained head |
| StartLux-Decision v1.1 4B Instant | [Native Rust/CUDA worker](../recipe/startlux/README.md) | Contract checks only; no CPU inference | L20X / Ada sm_89 Public231 C1 at `5bb25beb1c23f72497be189156d82f62ffb974da`: 231/231, p50 6.785 ms, p95 51.432 ms ([latency.md](../recipe/startlux/latency.md)). Scratch reserve `2b4a586e` failed that gate: 231/231, p50 7.811 ms, p95 51.947 ms. Grouped KV load `136ddf89` failed it too: 231/231, p50 8.148 ms, p95 53.053 ms. Packed prompt rows `1b5b1ee4` failed it too: 231/231, p50 7.980 ms, p95 52.417 ms. Pinned token-id copy `d139b228` failed it too: 231/231, p50 8.207 ms, p95 53.011 ms. Launch-error query `d3ba9d5` failed it too: 231/231, p50 8.326 ms, p95 53.868 ms. cuBLASLt heuristic sweep `6c268cd` failed it too: 231/231, p50 6.893 ms, p95 52.146 ms. FP8 E4M3×E4M3→BF16 `725c86ac` never became ready (cuBLAS status 7, 0/231, no percentiles). Symmetric int8 `867ed78` failed it too: 231/231, p50 9.848 ms, p95 83.150 ms. Load-time BF16 plan cache `f40f9b58` failed it too: 231/231, p50 7.953 ms, p95 52.484 ms. In-place GEMM layout retarget `d44e634` never finished warmup (cuBLAS status 7, 0/231, no percentiles). Numerical parity unverified. | Not supported | Pinned CC BY-NC 4.0 Instant 4B checkpoint; rebuilt ABI 9 library with `cs1_attention_gated_bidirectional` and `cs1_gemm_shape`. Instant only: AutoThink and 27B are refused |
| Decider-2B v11 | [Native Rust/CUDA worker](../recipe/decider/README.md) | Contract checks only; no CPU inference | RTX 4090 (`sm_89`) synthetic parity corpus; [limits and provenance](../recipe/decider/validation.md) | Not supported | Pinned original BF16 checkpoint; ABI 9 library and consumers rebuilt together |
| JEMM / Qwen3.8-27B | [Native Rust/CUDA worker](../recipe/jemm/README.md) | Host checks only; no CPU inference | A800 (`sm_80`) [text and 1–4-image frozen corpus](../src/models/jemm/README.md#validation) | Not supported | Pinned `jemm-native/2` export with BF16 base and unmerged FP32 LoRA, selected untied LM head, cuDNN 9 and additive reference CUDA symbols |
| autotrust/JEV-27B-VL | [Experimental native worker](../recipe/jev_vl/README.md), single-question API | Contract tests only; no CPU inference | H800 frozen-corpus check; [experimental scope and limits](../recipe/jev_vl/validation.md) | Not supported | Pinned merged checkpoint, rebuilt ABI 9 CUDA library; image inputs require offline Transformers preencoding |
Expand All @@ -34,7 +35,8 @@ Models that are being added are also tracked in issues labeled [new model](https
- **Planned:** not implemented yet; the linked issue tracks it.

The Cua-S1 workers answer `choice` questions only.
LAYA's English worker, Open-Jev and CLM support `choice`, `score`, and `noul` text questions.
LAYA's English worker, Open-Jev, CLM, and StartLux Instant 4B support `choice`, `score`, and `noul` text questions.
StartLux serves Instant only; AutoThink is not implemented, and the weights are CC BY-NC 4.0.
D3's reference worker serves the same three kinds for text, image and video
state (inline base64 media under the pinned runtime's per-item budgets);
its media serving evidence is author-run on the A100 above.
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ nav:
- Cua-S1 native screenshots: recipe/cua_s1/native_screenshot.md
- Cua-S1 vision CUDA Graph: recipe/cua_s1/native_vision_graph.md
- Open-Jev native text worker: recipe/open_jev/native.md
- StartLux Instant 4B native worker: recipe/startlux/README.md
- StartLux Instant 4B L20X latency: recipe/startlux/latency.md
- Open-Jev-27B H200 validation: recipe/open_jev/validation.md
- Open-Jev-9B validation: recipe/open_jev/validation-9b.md
- Decider native text worker: recipe/decider/README.md
Expand Down
4 changes: 4 additions & 0 deletions recipe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ For a first real decision, follow the [complete CPU walkthrough](../docs/getting
backbone and trained decision head of Open-Jev-27B-v1.1 or Open-Jev-9B, then
serve with Rust and CUDA. [Open-Jev-9B validation](open_jev/validation-9b.md)
compares the 9B worker with the reference.
- [StartLux Instant 4B native worker](startlux/README.md): build the Ada sm_89
CUDA library, serve the pinned CC BY-NC Instant checkpoint, and run the
[L20X closed-loop latency recipe](startlux/latency.md). AutoThink and 27B
are not in this recipe. GPU parity is unverified.
- [JEMM native worker](jemm/README.md): pinned text/image decisions and export;
known multi-image numerical limitation is documented in the model contract.
- [JEV-27B-VL experimental worker](jev_vl/README.md): native text and preencoded
Expand Down
134 changes: 134 additions & 0 deletions recipe/startlux/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# StartLux-Decision v1.1 4B Instant

Serve text `choice`, `noul`, and `score` from the pinned Instant 4B
checkpoint with the native worker `omni-startlux-native`. AutoThink and
Instant 27B are not part of this recipe.

Weights are **CC BY-NC 4.0**
(`startlux-models/StartLux-Decision-v1.1-4B-Instant`, revision
`416088f77cfce09633906a3675c7cd2e5dabcf10`, about 9.4 GB of BF16 files).
Download them on the machine that will serve. This repository does not
contain them. Inference code adapted from StartLux-Decision
`a99977d9332decc9fb27a2488b4a83b533b6cd5f` is Apache-2.0; see
[NOTICE](../../src/models/startlux/NOTICE).

GPU parity is unverified here. The intended device is one L20X (Ada, sm_89).
[latency.md](latency.md) records the native Public231 C1 samples and the
operator checklist. The 8192-token scratch reserve, the 99 KiB grouped KV
load, packed prompt rows, the pinned token-id copy, skipping the per-launch
CUDA error query, the load-time cuBLASLt heuristic sweep, FP8
E4M3×E4M3→BF16 projections, symmetric int8 projections, the load-time
BF16 plan cache, and the in-place GEMM layout retarget all failed the
latency gate and are not in the worker. Record the bench
metadata field `reservation` for the device hold. This recipe does not add
scheduler flags.

Commands below run from the repository root unless a path says otherwise.

## Build

The CUDA library and the worker must be built together. ABI stays 9.
`cs1_attention_gated_bidirectional` is an extra symbol; a library built
before it loads for causal workers and is refused by this one.
`cs1_gemm_shape` is optional. Instant refuses to load without it. Rebuild
this library before the next sample. Load keeps one cuBLASLt descriptor set
per weight shape. Layouts are created at the current length. A different
length replaces that set. Column counts are not rewritten in place. There is
no quantization and no load-time sweep.

```sh
src/backends/cuda/qwen3_5/build.sh target/release 89
cargo build --release --locked -p omni-startlux-native -p omni-jev
```

`build.sh` needs the CUDA toolkit (`nvcc`) and writes
`target/release/libqwen3_5_cuda.so`. The second command builds the worker
and the Rust frontend. There is no merge/export step.

## Weights

```sh
hf download startlux-models/StartLux-Decision-v1.1-4B-Instant \
--revision 416088f77cfce09633906a3675c7cd2e5dabcf10 \
--local-dir "$STARTLUX_MODEL"
```

`STARTLUX_MODEL` is the folder that contains `config.json`,
`decision_config.json`, `tokenizer.json`, and the safetensors index. The
worker checks the Instant 4B shapes and refuses an AutoThink or 27B folder.

## Serve

```sh
STARTLUX_MODEL=/path/to/StartLux-Decision-v1.1-4B-Instant \
STARTLUX_CUDA_LIB=$PWD/target/release/libqwen3_5_cuda.so \
STARTLUX_HOST=127.0.0.1 \
STARTLUX_PORT=8000 \
./target/release/omni-startlux-native
```

The process loads the checkpoint, runs one warmup decision, then listens.
Startup prints the CC BY-NC line. `GET /health` reports `ready`, the model
id, `prompt_attention: bidirectional`, the license, and the weights pin.

| Variable | Default | Meaning |
| --- | --- | --- |
| `STARTLUX_MODEL` | required | Instant 4B folder |
| `STARTLUX_CUDA_LIB` | `libqwen3_5_cuda.so` beside the binary | Shared CUDA library |
| `STARTLUX_HOST` | `127.0.0.1` | Listen address |
| `STARTLUX_PORT` | `8000` | Listen port, so `OMNI_JEV_BACKEND_URL=http://127.0.0.1:8000` matches |
| `STARTLUX_MAX_MODEL_LEN` | `65536` | Reject longer prompts. `1..=262144` |
| `STARTLUX_NONE_CHECK` | on | `0` turns off the extra "None of the above" option |
| `STARTLUX_ALLOW_NONE` | off | `1` allows `choice: null` when that extra option wins |

The body limit is 32 MiB. A larger body is 413. The content type must be
`application/json`. Bad JSON is 400. Contract errors are 422 with
`error` and `detail`. The worker does not truncate.

Optional frontend, from the same root, against the worker above:

```sh
OMNI_JEV_BIND=127.0.0.1:8080 \
OMNI_JEV_BACKEND_URL=http://127.0.0.1:8000 \
./target/release/omni-jev
```

## Requests

```sh
curl -sS http://127.0.0.1:8000/health

curl -sS http://127.0.0.1:8000/v1/systemone \
-H 'content-type: application/json' \
-d '{"state":"I was charged twice.","questions":{"route":{"type":"choice","instructions":"What should happen?","criteria":{"refund":"Refund the charge","keep":"Keep the charge"}}}}'

curl -sS http://127.0.0.1:8000/v1/systemone \
-H 'content-type: application/json' \
-d '{"state":"I was charged twice.","questions":{"ask":{"type":"noul","instructions":"Is a refund requested?"}}}'

curl -sS http://127.0.0.1:8000/v1/systemone \
-H 'content-type: application/json' \
-d '{"state":"I was charged twice.","questions":{"severity":{"type":"score","instructions":"How severe is it?","criteria":["low","high"]}}}'
```

With the defaults, the choice answer includes `none_probability` and the
choice stays one of the listed options. `think_mode` omitted or `never` is
the Instant path. `think_mode` `auto` or `always` is 422.

## Checks without a GPU

```sh
cargo test --locked -p omni-startlux-native --test contract
```

That test does not load weights or CUDA. It does not establish numerical
parity.

## Limits

Text only. No AutoThink thought, no 27B, no images, no prefix cache, no
CUDA graph, no packed prompts. Two GDN parameters are stored FP32 upstream
and rounded to BF16 at load. Letter logits are a CPU dot of the tied
embedding and are unverified against vLLM. A causal vLLM server without the
StartLux bidirectional plugin is a different model; do not use it as the
Instant baseline. The baseline command is in [latency.md](latency.md).
Loading