Downloads · 30 days
34
3% of all-time downloads
gauthierpiarrette/nl2jq-qwen3-0.6b
nl2jq-qwen3-0.6b is a text generation model from gauthierpiarrette. Use it when you need the model to write or continue text. The card lists the license as apache-2.0.
Part of the nl2jq project — all artifacts · code + CLI · live demo · benchmark
Downloads · 30 days
34
3% of all-time downloads
All-time downloads
1K
Public
Parameters
596M
2.4 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors1.2 GB · 99%
From the Hugging Face model README
Part of the nl2jq project — all artifacts · code + CLI · live demo · benchmark
A LoRA fine-tune of Qwen3-0.6B that translates a
natural-language request plus a JSON sample into a jq
program. It is the practical baseline companion to the from-scratch
nl2jq-40m: larger, but its
pretrained language priors make it markedly more reliable at copying novel field names
from your JSON — which is what most real CLI use needs.
The LoRA adapter has been merged into the base weights, so it loads as an ordinary model.
This is the recommended default backend of the jqgen CLI — the best
latency/accuracy balance for local use (~1–3s per query on laptop CPU).
cat data.json | jqgen --backend qwen "total spend per customer, paid orders only"
Or directly:
import re
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("gauthierpiarrette/nl2jq-qwen3-0.6b")
model = AutoModelForCausalLM.from_pretrained("gauthierpiarrette/nl2jq-qwen3-0.6b")
msgs = [{"role": "system", "content": "You translate a natural-language request plus a "
"sample of JSON into a single jq program. Output only the jq program, nothing else."},
{"role": "user", "content": "Request: highest paid person\nJSON sample: [...]"}]
enc = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt")
ids = enc["input_ids"] # newer transformers return a BatchEncoding here, not a tensor
out = tok.decode(model.generate(ids, max_new_tokens=128)[0][ids.shape[1]:],
skip_special_tokens=True)
# Qwen3 emits an (empty) reasoning block before the program — strip it:
print(re.sub(r"(?s)^\s*<think>.*?</think>\s*", "", out).strip())
Execution accuracy on the frozen 400-item
nl2jq-bench v1.0.0
(0% field overlap with training, novel domains, one-shot evaluation). These weights are
the v6 fine-tune — trained on data with per-example-unique field names and coverage of
reduce/foreach/walk/paths/if constructs; the superseded v5 row is kept for the
record:
| Model | frozen pass@1 | valid | T1 | T2 | T3 | T4 | T5-gen |
|---|---|---|---|---|---|---|---|
| this model (v6) | 0.40 | 0.73 | 0.65 | 0.52 | 0.36 | 0.28 | 0.20 |
| v5 fine-tune (superseded) | 0.24 | 0.67 | 0.45 | 0.38 | 0.21 | 0.12 | 0.02 |
| Qwen3-0.6B base (zero-shot) | 0.01 | 0.06 | 0.02 | 0.00 | 0.00 | 0.00 | 0.02 |
| nl2jq-qwen3.5-2b (bigger sibling, CLI config) | 0.48 | 0.82 | 0.75 | 0.61 | 0.47 | 0.35 | 0.18 |
| Claude Opus 4.8 (zero-shot, context row) | 0.96 | 0.98 | 1.00 | 0.96 | 0.96 | 0.96 | 0.90 |
Three honest readings:
reduce/foreach/walk/paths/if-banding constructs. 100% synthetic
and execution-verified — see the
nl2jq dataset. No web text, no
scraped code. Every program was run under jq 1.7.1 and kept only if it produced
non-degenerate output.jqgen CLI prints the program to stderr.
jq runs locally with no network access, but an incorrect program can still mislead.Apache-2.0 (inherits the base model's license). Fine-tuned on CC BY 4.0 synthetic data.
Code, benchmark tooling, and training pipeline: github.com/gauthierpiarrette/nl2jq