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="schneewolflabs/B2-9B")
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("schneewolflabs/B2-9B")
model = AutoModelForMultimodalLM.from_pretrained("schneewolflabs/B2-9B", 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

Schneewolf Labs B2-9B

B0-9B taught to do the job the way a careful journeyman does: work in the egirl harness's native tool format, finish its sentence after thinking, ask before destroying anything it can't get back, and tell the truth about what it verified.

B0-9B
 + Geselle SFT      (3,329 per-turn rows: agentic ladder + Vorsicht + thinking-on + chat, 1 epoch)
 + ORPO             (304 decision-point pairs: Vorsicht + ladder, 2 epochs)

No Stimme this time: stacked on top it eroded the new ask-first behaviour (at 0.5) and didn't bring back any voice (at 0.25).

Numbers

Same harness for every column: egirl on current main, Q8_0, one sample per cell. The battery is 28 operator scenarios with byte-level sandbox checkers; the held-out set is 8 destructive-request scenarios on fixtures and wording that appear in no training round, ×2 thinking modes ×2 samples.

axis Qwen3.5-9B (vanilla) B0-9B B2-9B
empty answer after a tool result, thinking on 14/14 14/14 0/14
battery sandbox checks, thinking off / on 7/8 / 5/8 5/8 / 5/8 8/8 / 6/8
held-out destructive requests: destroyed something on turn 1 16/24 14/24 5/24
held-out: lost irreplaceable data (raw data, a draft, the only copy) 8/24 8/24 0/24
held-out: explicit scoped removal done exactly 8/8 8/8 8/8
"did you actually rerun the tests?" n/a n/a honest in both modes
egirl 47-case tool bench n/a 46/47 42/47 ¹
censorship (strict, single-sample) n/a 29/29 27/29 ²
safety asymmetry (refuses actual harm) n/a 2/2 2/2 ²
hembench n/a 53.6% 55.1%
ARC / wiki-clean ppl n/a 61.2 / 12.24 61.2 / 12.33
stance rate (has opinions) n/a 16.7% 0%
prose distance vs contemporary fiction (lower = closer) n/a 0.580 0.804
identity Qwen (Alibaba) Schneewolf Labs Schneewolf Labs

¹ Three of the five misses are the bench's older JSON tool dialect, where B2 writes {"name":code_agent, without quoting the name (B1.1 had the same slip). B2 was trained only on Qwen3.5's native <function=…> format, which is what egirl sends; in egirl itself one stray call appeared in 261 round trips. The other two are tool choice (cat for read_file, git_status for git_diff).

² The strict scorer marks one refusal as a miss because it's phrased outside its marker list ("This violates safety guidelines… prohibited"). Both harmful requests are refused.

Against other Qwen3.5-9B fine-tunes (2026-10-20)

Log-prob multiple choice (llama.cpp --multiple-choice, Q8_0, no sampling). Every model was converted and scored the same day with the same harness and llama.cpp build: ARC-Challenge validation (299), TruthfulQA (817), MMLU validation (1,531), HellaSwag validation (first 1,000), ARC-Easy validation (570).

model ARC TruthfulQA MMLU HellaSwag ARC-Easy
B2-9B 60.5 36.5 41.2 77.6 84.6
Altworld/Astrea-R8-Chat-9B 56.2 35.0 40.8 78.2 75.4
squ11z1/claude-oss 54.2 30.4 39.4 76.7
empero-ai/Qwen3.8-9B-Distill 52.8 32.6 39.6 76.4
empero-ai/Qwythos-9B-Claude-Mythos-5-1M 52.8 31.7 39.5 74.9
ornith-ai/Ornith-1.5-9B 52.5 30.6 40.5 75.7
inclusionAI/UI-Venus-2-9B 52.5 32.1 39.6 74.4
XiaomiMiMo/MiMo-V2.6-Distill-Qwen-9B 52.2 32.8 39.8 74.2
TokenRhythm/NeoHorse-1-9B 52.2 34.1 39.3 75.5
OrionLLM/OxCoder-9B 50.8 34.3 39.5 75.7
allenai/tmax-9b 50.8 34.3 39.4 75.7
tencent/UI-Mate-9B 50.5 34.1 39.8 75.8
Qwen/Qwen3.5-9B 50.5 33.7 39.8 75.7 74.4
Jackrong/Qwen3.5-9B-Neo 50.2 31.5 40.0 74.7

Read this fairly:

  • ARC-Challenge is home ground. B0-9B's merge was selected on this same 299-item set, so B2's ARC column is partly in-sample. The other four benchmarks were never used to choose anything. On held-out ARC-Easy, B2 leads the base by 10 points and the next-best tune by 9: it got 66 items right that the base missed, against 8 the other way. That lead is real, and it comes from B0's merge; B2's training kept it intact.
  • These benchmarks measure knowledge and reasoning, not what most of these tunes are for. OxCoder, tmax, UI-Venus, UI-Mate and NeoHorse are coding, SWE, GUI and agent tunes. Their strengths don't show up on multiple choice, and this table says nothing about them. ARC-Easy was run only on the base and the strongest outside tune.
  • This ARC number (60.5) differs slightly from the 61.2 in the table above. That one came from an earlier conversion and llama.cpp build; every model in this table was scored the same way.

Two derivatives that add LoRAs on top of B2 are on DragonBophades, with full results on their cards: B2-Nimble-Bophades-9B (MMLU 42.5, no regressions) and B2-Bophades-9B (TruthfulQA 38.8, ARC −2.6).

What it costs

B2 is a better operator and a quieter one. Stance went to 0% and prose drifted from B0's 0.58 to 0.80: it has fewer opinions and a plainer voice. It still trusts a docstring over the code it describes sometimes, and with thinking on it can talk itself into a deletion ("clean working tree, nothing to preserve", in a repo with no remote). Keep the harness's own guards on for destructive commands.

Notes

  • Trained with Merlina, LoRA r32/α64. SFT lr 1e-4, 16k context, rendered one row per assistant turn with this model's own template (Merlina's multi-turn flattening would scramble tool trajectories). ORPO lr 8e-6, β 0.1, pairs cut at their first differing assistant turn so the preference never covers tool output.
  • Both adapters merged straight into the weights; the 15 mtp.* tensors and the vision tower are byte-identical to B0-9B (775 tensors verified). --spec-type draft-mtp works.
  • Data: Geselle, Vorsicht-DPO.
llama-server -m B2-9B-Q8_0.gguf -ngl 99 -c 32768 --jinja -fa on -np 1 \
    --spec-type draft-mtp --spec-draft-n-max 4
Downloads last month
23
Safetensors
Model size
9B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for schneewolflabs/B2-9B

Finetuned
(3)
this model
Adapters
1 model
Finetunes
1 model
Merges
4 models
Quantizations
3 models

Datasets used to train schneewolflabs/B2-9B