Rizzo Flow 1.7B: Spark-X2.5-1.7B + typed-decisions LoRA
This is a LoRA fine-tune of XHToken/Spark-X2.5-1.7B
for Rizzo Flow. It is the small variant: when
accuracy matters, use the 4B, rizzoaiacademy/rizzo-flow.
Rizzo Flow turns an unstructured state into typed decisions (boolean, choice, score) with
probabilities, and it generates no text. The model runs one forward pass per question. The
answer is the softmax over the logits of the answer letters (A, B, …) at the last prompt
position. Training works the same way: the loss is a soft cross-entropy between the target
distribution and that softmax, and only the LoRA adapters are trained.
This model is not affiliated with TypeSafe, and it is not Jev.
Files
| File | What it is |
|---|---|
model-0000*-of-00002.safetensors, config.json, tokenizer files |
Merged model, BF16 safetensors (3.4 GB): for the MLX backend and transformers. Same weights as the BF16 GGUF, bit for bit |
spark-x2.5-1.7b-rizzo-flow-lora-q8_0.gguf |
Merged model, Q8_0 (1.8 GB) |
spark-x2.5-1.7b-rizzo-flow-lora-bf16.gguf |
Merged model, BF16 (3.4 GB) |
spark-x2.5-1.7b-rizzo-flow-lora-q4_k_m.gguf |
Merged model, Q4_K_M (1.1 GB): loses accuracy, see Results |
lora/ |
The PEFT adapter alone (r 16, alpha 32), to apply to the BF16 HF checkpoint |
training/history.json |
Arguments, training loss and dev evaluations of the run |
Use
These GGUF files are what Rizzo Flow downloads
with --size 1.7b. It pins this repository by commit and checks the sha256 of every file:
git clone https://github.com/Rizzo-AI-Academy/rizzo-flow && cd rizzo-flow
uv sync --locked
uv run rizzo download --size 1.7b # llama.cpp for this machine + this model, Q8_0 (1.8 GB)
uv run rizzo serve --size 1.7b # → http://127.0.0.1:8017/playground
--quant bf16 or --quant q4_k_m picks another file and --weights base the original Spark-X2.5 GGUF. The server
answers as rizzo-flow-1.7b-q8_0.
MLX (Apple Silicon, or MLX-CUDA) uses the safetensors checkpoint at the root of this repository instead of the GGUF files:
uv sync --locked --extra mlx
uv run --no-sync rizzo download --backend mlx --size 1.7b # the safetensors only, 3.4 GB
uv run --no-sync rizzo serve --backend mlx --size 1.7b --bits 8
It answers as rizzo-flow-1.7b-bf16 (or …-q8/…-q4 with --bits). On an RTX 5060 Ti with MLX-CUDA, BF16, the
4B gives the same prompts (same hashes) and the same probabilities as llama.cpp BF16 within 0.001.
transformers loads the checkpoint with the original Spark code (trust_remote_code=True,
modeling_spark.py is XHToken's file, unchanged): AutoModelForCausalLM.from_pretrained( "rizzoaiacademy/rizzo-flow-1.7b", trust_remote_code=True, dtype="bfloat16"). Use the prompts of
Rizzo Flow and read the answer-letter logits at the last position; generating text is not what
it was trained for.
The GGUF files are plain GGUF (architecture spark2_5; Rizzo Flow runs them on llama.cpp release b11081), but the model is
meant to be read, not chatted with: Rizzo Flow builds the prompt, then reads the logits of the
answer letters. In a chat app it behaves like a lightly changed Spark-X2.5, and the fine-tune
brings nothing there.
The adapter was trained on the exact prompts of PROMPT_VERSION = "spark-decisions-v3", commit
c30cc63 of rizzo-flow. Any other prompt format can make the adapter useless.
Results
We ran the test split of the
LocalLLaMA/typed-decisions benchmark
(config all, 400 cases, 2,000 decisions). The model is fine-tuned for typed decisions, so this
is not a zero-shot result, but training used no data from these four workflows: the Open-Jev config
that shares them (workflow-controls-v1) was excluded, and so was every training state containing
text from the test set. The rows below come from the same machine (RTX PRO 6000) and the same
runtime (llama.cpp b11081, CUDA); on an RTX 5060 Ti we measured 0.530 → 0.544 (paired difference
+0.014, 95% interval [−0.014, +0.043]) and KL 3.031 → 0.694:
| Accuracy ↑ | KL from gold ↓ | Brier ↓ | ECE ↓ | p50 per case | |
|---|---|---|---|---|---|
| Spark-X2.5-1.7B Q8_0, base | 0.531 | 3.032 | 0.494 | 0.348 | 50 ms |
| This model, Q8_0 | 0.546 | 0.692 | 0.274 | 0.167 | 52 ms |
| Rizzo Flow 4B Q8_0, for reference | 0.650 | 0.454 | 0.205 | 0.111 | 73 ms |
Fine-tuning mostly improves the probabilities (KL, Brier, ECE). Accuracy barely moves: +0.015 is within noise. The change is not uniform across workflows:
| base | this model | |
|---|---|---|
| agent_trace_observability | 0.372 | 0.490 |
| customer_service | 0.644 | 0.674 |
| invoice_processing | 0.500 | 0.502 |
| security_incidents | 0.608 | 0.520 |
| noul / choice / score | 0.603 / 0.578 / 0.441 | 0.675 / 0.532 / 0.461 |
On the dev split of the training mixture (600 questions), loss goes 3.117 → 0.460 and accuracy 0.408 → 0.820.
Q4_K_M costs accuracy on this model. Made with llama-quantize b11081 from the BF16 GGUF (no
importance matrix), it scores 0.490 on the RTX 5060 Ti against 0.544 for Q8_0: −0.054, 95% interval
[−0.070, −0.037]. KL 0.640, Brier 0.279, ECE 0.192; invoice_processing falls to 0.394 and
security_incidents to 0.474. Use it only if 1.8 GB does not fit; the 4B at Q4_K_M (2.6 GB) is
much better.
The probabilities are not calibrated. Fit temperature scaling on data from your own domain
(rizzo calibrate) before you use thresholds. We have not yet re-run the smoke and SemIf fixtures
on this model.
Training
- Base: Spark-X2.5-1.7B BF16, rev.
14d6e83. LoRA r 16, alpha 32, dropout 0.05, on all linear layers of attention and MLP. Embedding andlm_headare not trained because they are tied. 16.7M trainable parameters. - AdamW, lr 5e-5, 3% warmup then cosine decay, no weight decay, clip 1.0. 16 questions per step. 1 epoch = 1,770 steps. Seed 0. The data and hyperparameters are the same as for the 4B.
- 28,321 training questions (14.7M prompt tokens, max 2,048 tokens per prompt), from
tasksource/procedural-typed-decisions(Apache-2.0),ZefanCai/Open-Jevrelease-v2-redistributable(CC0) and 12 configs ofPraveenrajus/jev-bench. None of the labels come from Jev or TypeSafe. We removed every training state that contains text from the evaluation sets. - Hardware: 1× RTX PRO 6000 Blackwell 96 GB, batch 8 / 3,072 tokens per forward, no gradient checkpointing. Throughput ~15,500 prompt tokens/s, 19 minutes, 22 GiB peak.
Full pipeline and reasoning:
docs/training.md.
Licenses of the training data
The base model is Apache-2.0. Among the jev-bench configs, stsb is CC-BY-SA.
measuring_hate_speech and the HelpSteer2 configs are CC-BY-4.0: Measuring Hate Speech
(Kennedy et al., 2020; Sachdeva et al., 2022) and HelpSteer2 (Wang et al., 2024, NVIDIA).
Check whether these terms matter for your use before you redistribute derivatives.