Qwen3-4B-Instruct-2507 · IFStruct
Qwen/Qwen3-4B-Instruct-2507 fine-tuned with reinforcement learning (GRPO) to follow structured-output instructions: emit valid JSON/YAML that matches a requested schema, wrapper key, item count, code-block and no-commentary constraints. This is the LoRA adapter ichetandhembre/ifstruct-lora-adaptor merged into the base weights (bf16), so it loads like any Qwen3 model.
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).
| 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, AutoTokenizer
name = "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.