IFStruct v1.0 result
Full 2,000-row test set of LiquidAI/ifstruct-v1.0,
scored with the benchmark's own validator (byte-identical to Liquid4All/ifstruct).
Table with columns: Model, pass@1, JSON, YAML| Model | pass@1 | JSON | YAML |
|---|
| this model (merged) | 95.75 | 95.2 | 96.3 |
| same LoRA served un-merged | 96.45 | 96.6 | 96.3 |
| Qwen3-4B-Instruct-2507 (base; earlier run, max_tokens 4096) | 76.15 | 76.4 | 75.9 |
Eval setup: greedy (temperature 0), 1 sample per prompt, max_tokens 16000, no system prompt, the model's chat
template (non-thinking model), no constrained decoding, vLLM 0.25. Per-row outputs (prompt, response, validator
errors) are in eval/. The 0.7-point gap to the un-merged adapter comes from bf16 rounding of very small
LoRA deltas during the merge; it is within greedy run-to-run variation (2.4% of rows flip).
Remaining failures (85/2000) are concentrated in prompts with long, heavily escaped free-text payloads (email
threads, terminal sessions, dialogue); 17 are degenerate repetition loops inside a string value.
Training
- GRPO (verl 0.9.0), CISPO loss, KL loss (low_var_kl, 0.01) to the base model, zero-variance group filtering,
16 prompts × 16 rollouts per step, max response 4096 tokens. LoRA rank 8 / alpha 16 on all linear layers.
- Reward: binary pass/fail from the IFStruct validator. No judge model.
- Stage 1: fresh LoRA, lr 1e-4, rollout temperature 1.0 → 1.5, 105 steps on 2,406 synthetic prompts.
- Stage 2: warm start, lr 5e-5, rollout temperature 1.5, step 110 on 4,293 synthetic prompts (2 epochs).
- None of the 2,000 benchmark prompts or their entity types appear in the training data.
Disclosure: how the benchmark was used
This is not a blind held-out score. (1) The synthetic data generator was steered toward the failure types the
model showed on this benchmark (no benchmark rows were copied). (2) Checkpoints were compared on validation slices
drawn from this benchmark (≈288 rows) and on full-benchmark evaluations. Expect a lower number on genuinely unseen
structured-output distributions.
Usage
from transformers import AutoModelForCausalLM, AutoTokenizername = "ichetandhembre/Qwen3-4B-Instruct-2507-ifstruct"tok = AutoTokenizer.from_pretrained(name)model = AutoModelForCausalLM.from_pretrained(name, torch_dtype="auto", device_map="auto")
Or vllm serve ichetandhembre/Qwen3-4B-Instruct-2507-ifstruct.