Javi0.2-4B-GGUF (alpha)
Alpha. Javi0.2 is an experiment you can run, not a finished model. It fixed the big problems it set out to fix and picked up new ones along the way. Both are measured and listed below.
A 4B agent model that tries to look things up instead of guessing. Fine-tuned from Qwen3.5-4B to work inside coding and research agents (grok build, omp, opencode) with their own system prompts and tools.
What it was trained to do (how well it does it is in Results):
- Look up anything time-sensitive. "Latest", "current", "today", versions, prices, who holds a role: it searches or fetches before answering instead of answering from memory (1 slip in 64 on the eval).
- Say so when it can't verify something. If search is blocked or a page returns 403, it stops instead of looping and says what it couldn't verify, plus ways to get the answer. It stops too early, and the ways it suggests aren't always real (see Limitations).
- Reason from first principles. It checks the premise of the question first and corrects it when it's false.
- Stay upbeat without bending facts. Ask how it's doing and it's doing fantastic.
It's the second version of a learning project, trained on a single NVIDIA DGX Spark. Javi0.1 only worked with its own training prompt; Javi0.2 is trained on the exact request formats the real clients send.
The full story, including every way it broke along the way, is on X.
Files
| File | Quant | Size | Notes |
|---|---|---|---|
Javi0.2-4B.Q8_0.gguf |
Q8_0 | 4.6 GB | Close to lossless; the eval below used this one |
Javi0.2-4B.Q4_K_M.gguf |
Q4_K_M | 2.8 GB | Smaller and faster |
Both were quantized from an F16 GGUF of the merged model. The LoRA was merged into the bf16 base, not into a 4-bit copy. Text only: the base model's vision tower is not included.
Usage
llama.cpp
llama-server -hf jvr0x/Javi0.2-4B-GGUF:Q8_0 --jinja -c 131072 \
--chat-template-kwargs '{"enable_thinking": false}' \
--temp 0.2 --top-p 0.8 --top-k 20 --min-p 0
Then point any OpenAI-compatible agent at http://localhost:8080/v1. The model needs tools to do its job: in a plain chat with no tools it can only answer from what it knows, and it will tell you when a question needs a lookup.
- Thinking off. It was trained and evaluated with
enable_thinking: false. - Low temperature (0.2) keeps tool calls well formed.
Results
Held-out eval: 136 questions it never trained on, each run inside a real client format (grok, omp, opencode, a bare OpenAI format, and a plain chat) with live tools: web search, page fetches, and a sandboxed shell over small code projects. Some questions force tool failures (search blocked, page 403) to test how it handles them. Every answer was graded by DeepSeek-V4.1-Flash for grounding, honesty, tool use, and tone.
Behavior (counted from the transcripts):
| Base Qwen3.5-4B | Javi0.1 | Javi0.2 | |
|---|---|---|---|
| Tasks finished | 120/136 | 117/136 | 134/136 |
| Time-sensitive questions answered from memory | 15/64 | 9/64 | 1/64 |
| Stuck in a loop when tools are blocked | 12/22 | 12/22 | 0/22 |
| Tool calls per task | 3.3 | 4.0 | 2.1 |
Answer quality (DeepSeek-V4.1-Flash as judge, strict; a pass needs grounded facts, honest gaps, good tool use and a good tone):
| Base Qwen3.5-4B | Javi0.1 | Javi0.2 | |
|---|---|---|---|
| Passed | 39/136 | 41/136 | 18/136 |
| Grounding (0-2) | 0.89 | 0.98 | 0.55 |
| Honesty (0-2) | 0.85 | 1.00 | 1.05 |
| Tool use (0-2) | 0.89 | 1.03 | 0.70 |
| Tone (0-2) | 1.54 | 1.56 | 1.38 |
Read the two tables together. Javi0.2 does what it was built for: it finishes, it doesn't loop, and it almost never answers a time-sensitive question from memory. But its answers are worse. Its final answers run about 3x longer than the base model's, and when it can't verify something, its list of "ways to get it" is often padded with URLs and API endpoints it made up. The judge penalizes that hard, and it should.
Hardware
| Quant | Weights | + 32k ctx | + 128k ctx | + 262k ctx | Decode on DGX Spark |
|---|---|---|---|---|---|
| Q4_K_M | 2.6 GiB | ~3.6 GiB | ~6.6 GiB | ~10.6 GiB | 66.5 tok/s |
| Q8_0 | 4.3 GiB | ~5.3 GiB | ~8.3 GiB | ~12.3 GiB | 45.5 tok/s |
- Memory = weights plus an F16 KV cache. Only 8 of the 32 layers use full attention (the rest are linear attention with a fixed-size state), so the KV cache is small: 32 KiB per token, 8 layers × 4 KV heads × 256 dims × K and V × 2 bytes.
-ctk q8_0 -ctv q8_0halves it. - Context: the base model supports 262k tokens. Javi0.2 trained on conversations up to 72k tokens, including multi-turn sessions and long tool outputs. Past that, it runs on the base model's long-context ability.
- Speed is
llama-benchdecode (256 tokens, 3 runs) on an NVIDIA DGX Spark (GB10, 128 GB unified memory), full GPU offload, flash attention on. Prefill runs at about 4,000 tok/s for both quants.
Example
In opencode, Q8_0, thinking off:
User: hey, how are you doing today?
Assistant: I'm doing great, thanks for asking! I'm ready to help with whatever you need.
Asked "What's the latest Qwen model?" with web search down, it doesn't guess. It says it couldn't verify, why, and how to find out. That part works. Its list of "ways to find out" is where it tends to invent endpoints (see Limitations).
How it was made
Client capture. A stand-in server recorded the exact requests grok build, omp, and opencode send: system prompts of 15-25k tokens and 10-27 tools each. Training rows use those prompts and tools verbatim, so the model learns to behave well inside the real clients rather than inside a prompt it will never see.
Episodes: teacher inside the harness. 1,383 seed questions (lookups, forced failures, first-principles reasoning, false premises, conflicting sources, unanswerable questions, small talk, coding tasks) were answered by a teacher, Qwen3.8-Flash-Next, running inside each client's exact format with real tools: web search through a local SearXNG, page fetches, and a Docker sandbox for shell and file work on six small projects. The working rules (first principles, look up anything time-sensitive, say when you can't verify and how to find out, try at most two routes after a failure, stay upbeat) were in the teacher's prompt only. Training rows keep the client's own prompt, so the student learns the behavior, not the instructions.
Filtering. DeepSeek-V4.1-Flash judged every episode for grounding, honesty, tool use, and tone. Code checks dropped anything unfinished, anything that answered a time-sensitive question without a tool, anything with more than about six tool calls, and anything that repeated an identical call. Clean recoveries from real web failures were kept; flailing was not. 692 rows made it, 131 of them carried over from Javi0.1.
Training: LoRA SFT with Unsloth, loss on decisions only.
| Setting | Value |
|---|---|
| Method | LoRA on the bf16 base |
| Rank / alpha / dropout | 16 / 16 / 0 |
| Target modules | q, k, v, o, gate, up, down |
| Epochs / steps | 1 / 173 |
| Effective batch | 4 (1 × 4 grad accum) |
| Learning rate | 1e-4, linear decay |
| Max sequence length | 73,728 tokens |
| Loss on | the first reply to each user message and every final answer |
| Hardware / time | 1× DGX Spark (GB10), 2h10m |
Why loss on decisions only. A first version trained on every assistant turn, including each intermediate tool call. It learned to never answer time-sensitive questions from memory, but also to keep calling tools: it re-ran searches that had already worked and finished only 85 of 136 eval questions. Training only on the turns that decide something (answer directly or pick a tool, then give the final answer) fixed the loops without losing the lookups. It also concentrated all the learning on final answers, which is where this version's padded, invented "ways to get it" come from. The recovery step in the middle of a conversation (a call failed, try the next route) got no training at all, which is why it gives up after one failure.
Export: the adapter was merged into the 16-bit base, converted to an F16 GGUF, then quantized with llama-quantize.
Limitations (known issues in this alpha)
- Invents "ways to get it". When a lookup fails, it often suggests URLs, API endpoints or
curlcommands that don't exist, and repeats the same suggestion several times. - Gives up after one failure. One failed fetch and it may stop and report, instead of trying the next route itself. It suggests
curlcommands to the user even when it has a shell tool to run them. - Doesn't cross-check. It can take one secondary source as definitive (for example, a community fine-tune as "the latest Qwen model").
- Sometimes claims a check it didn't do. Rare, but seen in testing: it called a figure "verified" that no tool in the conversation returned.
- Careless tool calls. Unencoded URLs, missing
format=json, JSON parsing with no error handling. - Long answers. About 3x the base model's length, sometimes contradicting itself (a wrong headline number above the right calculation).
- It's a 4B model. It can still get facts wrong.
- It's built for agent clients with tools. Without tools it can't look anything up.
- The eval uses live web search, so scores move a few points between runs, and the grader is an LLM, not a person.
- Trained mostly on English.
What's next
Javi0.2.1 targets the issues above: learning the recovery step after a failed call, preferring and cross-checking authoritative sources, only calling something verified when a tool result shows it, and short failure answers with no invented endpoints.
License
Apache 2.0, inherited from Qwen3.5-4B.