How to use from the
Use from the
Transformers library
# Use a pipeline as a high-level helper
from transformers import pipeline

pipe = pipeline("image-text-to-text", model="javierbits/Javi0.4-4B")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"},
            {"type": "text", "text": "What animal is on the candy?"}
        ]
    },
]
pipe(text=messages)
# pip install -U transformers accelerate
# Load model directly
from transformers import AutoProcessor, AutoModelForMultimodalLM

processor = AutoProcessor.from_pretrained("javierbits/Javi0.4-4B")
model = AutoModelForMultimodalLM.from_pretrained("javierbits/Javi0.4-4B", device_map="auto")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"},
            {"type": "text", "text": "What animal is on the candy?"}
        ]
    },
]
inputs = processor.apply_chat_template(
	messages,
	add_generation_prompt=True,
	tokenize=True,
	return_dict=True,
	return_tensors="pt",
).to(model.device)

outputs = model.generate(**inputs, max_new_tokens=256)
print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:]))
Quick Links

Javi0.4-4B

Javi0.4-4B (control)

Javi0.4-4B is Javi0.3-4B with the same embedding row changed: token 51187 (=open_page) is multiplied by 0.84. No fine-tuning, no new data, no gradients. Every other weight is byte-identical to Javi0.3-4B.

It exists as the 4B control for the Javi0.4 weight-space experiment: the same row edit applied to the larger model.

Measured effect

On 8 held-out eval-v3 canonical fail questions with the first web_search forced to fail, Javi0.3-4B already chose web_search in 4/4 cases, so that probe sees no change on 4B. On an opencode 403 replay, both models fetch another typed URL instead of searching again.

Full eval v3

175 held-out seeds, 3 runs, date pin 2026-10-07, cached search results. Javi0.3-4B answers on the same seeds are the baseline. Judges: DeepSeek-V4.1-Flash-1017 and mimo-v26-dual.

metric Javi0.3-4B Javi0.4-4B
core pass (judge average) 0.50 [0.45, 0.55] 0.56 [0.52, 0.61]
core pass (deepseek) 0.64 0.74
core pass (mimo) 0.36 0.39
recovery after a tool failure 0.58 (n=12) 0.75 (n=12)
made-up links 0.01 0.00
loops 0.03 0.02

Paired core pass difference: +0.06 [0.03, 0.10] (deepseek +0.10 [0.05, 0.14], mimo +0.04 [0.00, 0.07]), 95% bootstrap over 175 seeds. The deepseek interval clears zero; the mimo interval touches it. Conflict questions are the one category down (0.26 vs 0.40, n=7, directional at that n); unknowable questions are up (0.55 vs 0.32, n=10).

Two answer episodes (2 seeds, one per run) carry no deepseek verdict because the judge omits the tools or style key; both seeds are judged in the other runs, so the table covers 175 seeds. Incomplete episodes (7 across the three runs) are scored 0 for core pass and skipped by the judges. Full scoreboard: data/v2/eval/javi04-vs-03/score.md in the source tree.

This control measures slightly above Javi0.3-4B, but the targeted probe cannot attribute the gain to the open_page row alone. The 4B's remaining recovery gap in the webfetch/web_fetch route is untouched by the edit.

Files

Merged bf16 safetensors (two shards, 8.8 GB), tokenizer, processor files and chat template. The vision tower is Qwen3.5-4B's, unchanged; the edit is in the language model only.

Run it

Thinking off, temperature 0.2, top-p 0.8, top-k 20.

GGUF for llama.cpp or lmdeck: Javi0.4-4B-GGUF.

lmdeck

lmdeck use javi0.4-4b

Transformers

from transformers import AutoModelForImageTextToText, AutoProcessor

model_id = "javierbits/Javi0.4-4B"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForImageTextToText.from_pretrained(model_id, dtype="auto", device_map="auto")

messages = [{"role": "user", "content": [{"type": "text", "text": "What's the latest stable Rust release?"}]}]
inputs = processor.apply_chat_template(messages, add_generation_prompt=True, enable_thinking=False,
                                       tokenize=True, return_dict=True, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=512, do_sample=True, temperature=0.2, top_p=0.8, top_k=20)
print(processor.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))

The edit

embed_tokens[51187] *= 0.84  # =open_page

Token 51187 is a single token in the Qwen3.5 tokenizer. The row is tied between input and output embeddings, so the output logit for =open_page is reduced.

Links

Downloads last month
71
Safetensors
Model size
5B params
Tensor type
BF16
ยท
F32
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for javierbits/Javi0.4-4B

Finetuned
Qwen/Qwen3.5-4B
Finetuned
(1)
this model
Quantizations
1 model

Collection including javierbits/Javi0.4-4B