What You'll Build
A local computer-use agent on a single RTX 3060: llama-server hosting Fara1.5-9B as a Q5_K_M GGUF plus its vision projector, and Microsoft's fara-cli harness pointed at it, driving a Playwright-launched Chromium at 1440×900. You give it a task in English; it takes a screenshot, reasons, and emits a click, a keystroke or a URL visit, then loops.
Hardware data: RTX 3060 (12GB VRAM) · Q5_K_M + f16 mmproj + 32K context = 8.434 GiB of accountable allocations · See benchmark data
⚠️ This model clicks, types and submits in a real browser, and the default path here is not a sandbox. That the model acts is the product, not a side effect. The model card's Responsible AI section asks you to "run Fara in an isolated container with no access to host files, environment variables, or sensitive credentials", and the same card states plainly: "Don't run this model with unrestricted browser access on a machine that has anything sensitive on it."
fara-clilaunches its own Chromium through Playwright with a fresh browser context — it does not attach to your logged-in browser — but it runs uncontained, on your machine, with your network. Isolation is a separate step you have to take: see Sandbox it below, and do it before pointing this at anything that matters.
ℹ️ Not a general-purpose vision chatbot. Fara1.5-9B is fine-tuned for one loop: screenshot in,
<tool_call>out. It is in ourmultimodalvertical because it takes images and text and emits text, but it is trained against a specific system prompt and a fixedcomputer_useaction schema. Used as a plain image-captioning model it will still answer, but nothing about it is tuned for that. Per the model card: "The model is vision-only at perception time: it sees the browser through screenshots, not the DOM or accessibility tree."
⚠️ Runtime status — read before you commit an evening to this. llama.cpp support for this architecture is verifiable statically, and this recipe shows that evidence, but no published issue thread, user report or docs entry shows Fara1.5-9B captioning an image under
llama-serverorllama-mtmd-cli. Theqwen35text arch and theqwen3vl_mergerprojector are both first-class in llama.cpp master, and four independent quantisers have converted this model's vision tower successfully — but that is static evidence, not a tested path. Treat the first run as the test. There is also no published speed measurement for this pair (see Results).
Requirements
| Component | Minimum | This recipe |
|---|---|---|
| GPU | 12GB VRAM, CUDA compute 8.6 (Q5_K_M + mmproj + 32K context = 8.434 GiB accountable) | — not measured; budget below is derived (/contribute) |
| RAM | 16GB (model is mmap'd; browser + Playwright on top) | — |
| Storage | 7.771 GB decimal / 7.237 GiB (Q5_K_M 6.382 GiB + f16 mmproj 0.855 GiB) | ~8 GiB with Chromium |
| Software | llama.cpp b10087+ (CUDA), Python 3.10+, Playwright | — |
Check the card first. NVIDIA's own Q&A for this GPU explains that "its memory width is 192-bit – which means the GPUs can be equipped with either 6GB or 12GB – we chose 12GB", and the same page puts the desktop part at "192-bit and GDDR6 (at 15 Gbps), delivering 360GB/s of bandwidth" (GeForce News Q&A). The name has since been reused for laptop parts at other capacities. Run nvidia-smi and confirm you actually have ~12 GB before following the budget below — a 9B at Q5_K_M has no fallback that fits a smaller card comfortably, and Fara1.5-4B is the size to reach for at any lower capacity.
Why the 9B, and not the 4B or the 27B
The 9B is the middle of three sizes and has to earn the tier. Microsoft answers this directly in the Fara1.5 paper: "Fara1.5-9B already covers a substantial fraction of the 4B-to-27B gain on both metrics, which makes it the natural choice when deployment cost is a constraint." — followed immediately by "Fara1.5-27B is the right choice when raw accuracy matters more than cost." On a 12 GB card, cost is the constraint, so this is the tier.
The numbers behind that, from the paper's Table 7 (averaged over three independent runs, with 95% confidence intervals — a better source than the bare figures on the model card):
| Model | WebVoyager | Online-Mind2Web | WebTailBench v1.5 |
|---|---|---|---|
| Fara1.5-4B | 80.8 ± 2.3 | 57.3 ± 4.3 | 27.4 ± 2.8 |
| Fara1.5-9B | 86.6 ± 2.0 | 63.4 ± 4.3 | 32.3 ± 2.8 |
| Fara1.5-27B | 89.3 ± 1.8 | 72.3 ± 3.8 | 40.2 ± 3.0 |
Microsoft's own reading of those intervals is that they are "small relative to the gaps between model sizes, confirming that the scaling trend in Table 3 is not an artifact of run-to-run noise" — and across the family as a whole that is fair. Doing the arithmetic pairwise gives a more granular picture, and this next part is our reading, not theirs: on WebVoyager the 9B reaches 88.6 at the top of its interval while the 27B drops to 87.5 at the bottom of its own, so the two overlap; on Online-Mind2Web (67.7 vs 68.5) and WebTailBench (35.1 vs 37.2) they do not. Overlapping 95% intervals is only a conservative proxy for a significance test and does not by itself establish that two results are indistinguishable — so read this as the WebVoyager gap is much the weakest-separated of the three, not as a null result. The 27B's advantage is real but not uniform, and it is smallest exactly where the benchmark is easiest.
The paper is specific about where that gap comes from, and it is not speed. Larger models "solve more of the hard tail", and on success rate versus trajectory length: "The mapping is largely independent of size in the bulk of the step range; larger models retain a higher success rate only in the long tail." Nor is the 9B less efficient per task it completes — "The larger mean step counts of smaller models above are largely a consequence of their higher failure rate, not lower efficiency." Expect the 9B to handle ordinary tasks about as directly as the 27B would, and to lose ground specifically on long, hard trajectories. And the ceiling is low for everyone on the hardest benchmark — the paper's own words are that "even the 27B model leaves a substantial fraction of examples unsolved in three attempts" there.
This exact question was asked on the 9B's own HuggingFace discussions in July 2026 — "Does anyone have any suggestions on the kinds of tasks where the 9B model fails where the 27B model appears to be necessary?" — and has no community answer beyond the paper. Nobody has published a qualitative rule; the interval arithmetic above is as sharp as the public evidence gets.
What the tier costs on this card is unusually easy to state, because the 4B and 9B are architecturally identical everywhere except width. The 9B's config.json declares num_key_value_heads: 4, head_dim: 256, num_hidden_layers: 32 and full_attention_interval: 4, exactly as the 4B does — so the per-token KV cost of the 9B is exactly the same as the 4B's, and so is its fixed recurrent state. The entire difference is weights: 3.088 GiB → 6.382 GiB at Q5_K_M, plus 0.626 → 0.855 GiB of projector, from the 4B and 9B GGUF trees. You pay ~3.5 GiB of otherwise-idle VRAM for those points and nothing at all in running cost.
The 27B is simply out of reach here: its Q4_K_M is 16.329 GiB before the 0.864 GiB projector.
How it fits in 12 GB — the arithmetic
There is no benchmark for this pair yet (/check reports unknown), so every figure below is derived from the artifact and from llama.cpp's own source. Reproduce it rather than trusting it. All totals are GiB (2^30 bytes), which is the unit the card is really in — a "12GB" NVIDIA GPU has 12 GiB of physical memory — so they compare directly. HuggingFace displays file sizes in decimal GB, which is why the Storage row above and the weights below describe the same bytes in different units.
Weights. From the bartowski GGUF tree: Fara1.5-9B-Q5_K_M.gguf = 6,852,928,640 B = 6.382 GiB (HuggingFace displays this as 6.85 GB — decimal), mmproj-Fara1.5-9B-f16.gguf = 918,166,048 B = 0.855 GiB.
KV cache — smaller than you expect, because this is a hybrid model. config.json carries a layer_types array of 24 linear_attention + 8 full_attention entries, and llama.cpp agrees: llm_arch_is_hybrid(LLM_ARCH_QWEN35) returns true in src/llama-arch.cpp, and src/models/qwen35.cpp assigns layers with is_recr_impl[i] = (i + 1) % full_attn_interval != 0. With full_attention_interval = 4 and 32 blocks that is layers 3, 7, … 31 — 8 attention layers, exactly the indices config.json lists. Only those get a growing cache:
K+V per token per attention layer = 2 × n_head_kv(4) × head_dim(256) × 2 B (f16) = 4,096 B
× 8 attention layers = 32 KiB / token
n_ctx = 16,384 → 0.500 GiB
n_ctx = 32,768 → 1.000 GiB
n_ctx = 65,536 → 2.000 GiB
A non-hybrid 32-layer model with the same head geometry would cost four times that.
Recurrent state — fixed in context, but four times bigger than one sequence's worth. The other 24 layers hold a context-independent state. Using llama.cpp's n_embd_r() / n_embd_s() in src/llama-hparams.cpp with this file's own GGUF keys (ssm.conv_kernel 4, ssm.inner_size 4096, ssm.group_count 16, ssm.state_size 128 — which config.json sources as linear_conv_kernel_dim, linear_num_value_heads × linear_value_head_dim, linear_num_key_heads and linear_key_head_dim):
conv state : (4−1) × (4096 + 2×16×128) = 24,576 elems
ssm state : 128 × 4096 = 524,288 elems
per layer : 548,864 × 4 B (F32) = 2.094 MiB
× 24 recurrent layers = 50.25 MiB ← per sequence
× n_seq_max = 4 = 201.0 MiB = 0.196 GiB
That last multiplication is the one everybody drops. src/llama-model.cpp sizes the recurrent memory with /* recurrent_rs_size */ std::max((uint32_t) 1, cparams.n_seq_max), and tools/server/server.cpp resolves the server's auto slot count to params.n_parallel = 4; params.kv_unified = true; whenever n_parallel < 0 — which is the default it gets from common/arg.cpp (params.n_parallel = -1; // auto by default for the server example). So llama-server allocates four sequences' recurrent state whether or not you ever use more than one, and the honest figure is 0.196 GiB, not 0.049. It is a small term either way; it is here because the arithmetic on this page is meant to be reproducible against a real startup log.
Total at the recommended settings:
| GiB | |
|---|---|
| Q5_K_M weights | 6.382 |
| f16 mmproj | 0.855 |
| KV cache @ 32,768 | 1.000 |
| Recurrent state (4 sequences) | 0.196 |
| Accountable total | 8.434 |
That leaves 3.566 GiB on a 12 GiB card for compute buffers, the vision encode graph, the CUDA context and your desktop — which is why this recipe leads with Q5_K_M rather than Q6_K or Q8_0. The headroom is better spent on the quant than on context, because only one of the two carries an unmeasured risk. Fara emits pixel coordinates, Microsoft's published scores are for bf16 weights, and no public evaluation says what a quant tier costs a grounding model — so the quant is the term to protect. Context is the other kind of decision entirely: its price is on the table below and you can buy more of it later, since -c 65536 costs exactly 1.000 GiB and lands at 9.434 GiB, which this card has the room for. How the context is actually spent, below, derives the round count at which you have to. The neighbouring configurations, for reference:
| Configuration | Weights | KV | Recurrent | Total |
|---|---|---|---|---|
| Q4_K_M @ 32,768 | 5.505 + 0.855 | 1.000 | 0.196 | 7.556 GiB |
| Q5_K_M @ 32,768 | 6.382 + 0.855 | 1.000 | 0.196 | 8.434 GiB |
| Q5_K_M @ 65,536 | 6.382 + 0.855 | 2.000 | 0.196 | 9.434 GiB |
| Q6_K @ 32,768 | 7.171 + 0.855 | 1.000 | 0.196 | 9.223 GiB |
| Q8_0 @ 32,768 | 8.890 + 0.855 | 1.000 | 0.196 | 10.942 GiB ✗ |
The Q8_0 row is the one to resist. It arithmetically fits inside 12 GiB and leaves about a gigabyte for everything llama.cpp has not told you about yet, plus a Chromium that may well be rendering on the same GPU. The compute buffers, the CUDA context and the vision graph are not in this table — they are allocated at load time and this recipe does not derive them. Read the CUDA0 compute buffer size lines that llama-server prints on startup, watch nvidia-smi with the agent actually running, and report what you see.
How the context is actually spent
A CUA sends a screenshot every step, so the per-image cost decides whether the budget above is realistic — and then the round count decides the rest of it.
The harness fixes the viewport at 1440×900 (Fara15AgentConfig.viewport_width/height in src/fara/agents/fara/fara15_agent.py) and pre-resizes with Qwen's smart_resize at factor = patch_size × merge_size = 32 → 1440×896. llama.cpp then applies the identical algorithm (calc_size_preserved_ratio in tools/mtmd/mtmd-image.cpp) and clamps to 8–4096 merged tokens for this projector (set_limit_image_tokens(8, 4096) in tools/mtmd/clip.cpp); 1,290,240 px sits inside that, so nothing is rescaled:
(1440 / 32) × (896 / 32) = 45 × 28 = 1,260 tokens per screenshot
× max_n_images = 3 = 3,780 tokens resident
Microsoft's own harness budgets image_token_estimate: 1500 per image, so 1,260 is the real figure and 1,500 is their conservative rounding.
So the image half is capped — the card is explicit that only the most recent three screenshots are kept, and max_n_images: int = 3 in the harness config enforces it. What is not capped is the text trajectory: every round appends the model's reasoning, its tool call and an observation (max_observation_chars: int = 1000), and none of that is evicted. So the round count, not the screenshot count, is what decides your -c:
32,768 − 3,780 resident screenshots ≈ 29,000 tokens of trajectory room
/ --max_rounds 15 (the smoke test below) ≈ 1,900 tokens per round
/ --max_rounds 100 (the CLI default) ≈ 290 tokens per round
290 tokens per round is thin for a model that writes its reasoning out before every action — and the default is the thin case, not the roomy one: src/fara/run_fara.py declares --max_rounds with default=100. llama.cpp will not paper over the overrun either. common/common.h ships bool ctx_shift = false; // context shift on infinite text generation, so a trajectory that outgrows the window errors rather than quietly sliding it — an unattended run stops mid-task rather than degrading.
So: keep -c 32768 for the short supervised runs the example below does, and raise it to -c 65536 before you let the harness run out to its default 100 rounds. That doubles the trajectory room for exactly 1.000 GiB of extra KV — the 9.434 GiB row in the table above, which this card has the slack for. The harness README's 15,000 tokens is a floor rather than a target, and a floor is not a recommendation for this card; the arithmetic above is.
Installation
1. Build llama.cpp with CUDA
The RTX 3060 is Ampere, compute capability 8.6 per NVIDIA's CUDA GPUs table. The community GGUF was quantized on release b10087; build that tag or newer.
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=86 -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j
No special toolkit version is required for 86 — llama.cpp's CUDA CMakeLists puts 86-real in the default architecture list unconditionally, and gates only newer architectures behind newer toolkits.
Support for this model is first-class in mainline, at both halves — worth confirming before you download 7 GiB:
grep -n 'LLM_ARCH_QWEN35,' src/llama-arch.cpp # -> { LLM_ARCH_QWEN35, "qwen35" }
grep -n 'qwen3vl_merger' tools/mtmd/clip-impl.h # -> PROJECTOR_TYPE_QWEN3VL
grep -n 'Qwen3_5ForConditionalGeneration' conversion/qwen3vl.py # -> Qwen3VLVisionModel (the mmproj converter)
2. Download the weights and the projector
There is no first-party GGUF — Microsoft ships safetensors only. Use a community quantization; four independent quantizers publish a matching mmproj for the 9B (bartowski, prithivMLmods, DevQuasar, Tdamre), which is itself corroboration that the vision conversion works.
pip install -U huggingface_hub
hf download bartowski/Fara1.5-9B-GGUF Fara1.5-9B-Q5_K_M.gguf --local-dir ./fara-gguf
hf download bartowski/Fara1.5-9B-GGUF mmproj-Fara1.5-9B-f16.gguf --local-dir ./fara-gguf
Downloading the projector is not optional. In GGUF the vision tower lives in a separate file loaded by tools/mtmd; without it you have a text-only model and a computer-use agent that cannot see. You can verify the artifact you just downloaded declares the projector llama.cpp implements:
strings ./fara-gguf/mmproj-Fara1.5-9B-f16.gguf | grep -m1 qwen3vl_merger
3. Install the fara harness
git clone https://github.com/microsoft/fara.git
cd fara
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
playwright install
Omit the [vllm] extra from the README's command — that path is for bf16 serving on datacenter cards and is not what this recipe uses.
4. Point the harness at your local server
cat > local_llamacpp.json <<'EOF'
{
"model": "Fara1.5-9B",
"base_url": "http://127.0.0.1:5000/v1",
"api_key": "sk-no-key-required"
}
EOF
Running
Start the server
./build/bin/llama-server \
-m ./fara-gguf/Fara1.5-9B-Q5_K_M.gguf \
--mmproj ./fara-gguf/mmproj-Fara1.5-9B-f16.gguf \
--reasoning-format none \
--image-min-tokens 1024 \
-c 32768 \
-ngl 99 \
--temp 0 \
--host 127.0.0.1 --port 5000
Three of those flags are load-bearing and none of them is a default:
--reasoning-format none— mandatory. See Troubleshooting; without it the agent loop silently receives nothing.common/arg.cppdocuments this value as "none: leaves thoughts unparsed inmessage.content", which is exactly what the harness parses.--image-min-tokens 1024— llama.cpp's default floor for this projector is 8 merged tokens, andtools/mtmd/clip.cppwarns that "Qwen-VL models require at minimum 1024 image tokens to function correctly on grounding tasks". A full 1440×900 screenshot is 1,260 tokens and clears the floor on its own, but any smaller image the agent sends would not.-c 32768— the harness README requires "Please ensure that context length is set to at least 15000 tokens and temperature to 0 for best results."
If you would rather not manage files, -hf bartowski/Fara1.5-9B-GGUF:Q5_K_M fetches the model and, per llama.cpp's server docs, the matching mmproj alongside it.
Prove the vision path before you let it drive
curl -s http://localhost:5000/v1/models | grep -o multimodal
curl -s http://localhost:5000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "Fara1.5-9B",
"temperature": 0,
"messages": [{"role": "user", "content": [
{"type": "text", "text": "Describe this image in one sentence."},
{"type": "image_url", "image_url": {"url": "https://raw.githubusercontent.com/ggml-org/llama.cpp/master/media/llama0-logo.png"}}
]}]
}' | python3 -m json.tool
llama.cpp's server README tells clients to check /models or /v1/models for the multimodal capability before sending images. If the second call describes the picture, the projector is wired up. If it answers as though no image were present, stop here — a computer-use agent with a blind model produces confidently wrong clicks rather than an error.
Run a task
source .venv/bin/activate
fara-cli \
--task "find the current UTC time on time.is and tell me" \
--endpoint_config local_llamacpp.json \
--output_folder ./run1 \
--save_screenshots \
--headful \
--max_rounds 15
--max_rounds 15 is a smoke-test value, not the default. run_fara.py declares that argument with default=100, so dropping the flag gives you a hundred rounds against a window sized above for far fewer — see How the context is actually spent. Keep it low while you are still watching the thing; raise -c to 65536 before you raise it.
--headful reads like a convenience flag and is not one here. The harness runs the browser headless by default: src/fara/run_fara.py declares the flag as "Run the browser in headful mode (show GUI, default is headless)" and passes headless=not args.headful into the browser launch. Omit it and a real Chromium still opens, still clicks and still submits — you simply cannot watch it. With the flag, the command above opens a real, unsandboxed Chromium on your desktop, which is what makes the supervision advice on this page true rather than aspirational.
Each step writes a screenshot and a data_point.json trajectory into --output_folder. The model stops on its own at critical points — entering personal data, payments, submissions, sign-ins — and asks rather than proceeding.
Sandbox it
fara-cli gives you a fresh Chromium context, not container isolation. For anything beyond a first smoke test, run the harness inside a container with no host mounts and no credentials in its environment, or use Magentic-UI, which the model card names as the recommended deployment and which the harness README describes as "a sandboxed browser environment with auditable action logging and user prompts at critical points". Match the sandbox viewport to the trained resolution — the card names 1440×900 as the resolution Fara is most commonly trained with, and is explicit about what to do with that: "Match this in your sandbox for the most reliable grounding."
Results
- Speed: omitted. No benchmark of Fara1.5-9B on an RTX 3060 — or any consumer GPU — exists at the time of writing, and Microsoft publishes no throughput figures at all: the card names "A6000, A100, H100, and B200" only as hardware its bf16 serving path was tested on, which says nothing about a Q5_K_M build on Ampere. What is worth knowing about this card is where the bottleneck will sit: NVIDIA's Q&A puts the desktop RTX 3060 at "360GB/s of bandwidth", the low end of the 12 GB tier, and this configuration streams 6.382 GiB of weights, so generation here is bandwidth-bound rather than compute-bound — while a CUA also re-processes a 1,260-token screenshot on every single step, which loads the prompt-processing side instead. Both halves matter and neither has been measured. If you measure them, please contribute the numbers so this line can be filled in from real data rather than extrapolation.
- VRAM usage: 8.434 GiB of accountable allocations at Q5_K_M / 32K context, derived above from file sizes and llama.cpp's own cache formulas. Compute buffers sit on top of that and are not derivable from static inspection — expect to confirm the true peak with
nvidia-smion your first run. Track the empirical picture at /check/fara1-5-9b/rtx-3060. - Quality notes: the vision path here is structurally proven, not runtime-proven. Four independent facts establish that it loads: mainline llama.cpp registers
Qwen3_5ForConditionalGenerationfor both the text model and the vision tower (conversion/qwen3vl.py); the shipped mmproj declaresclip.projector_type = qwen3vl_merger, which maps toPROJECTOR_TYPE_QWEN3VLintools/mtmd/clip-impl.h; four quantizers converted it independently; and llama-server documentsimage_urlcontent parts, which is exactly what the harness sends. What does not exist is a published report of Fara1.5 captioning an image or grounding a click underllama-server. The vendor's published scores are for the bf16 model on datacenter hardware; Q5_K_M is a quantised approximation of those weights, and no published evaluation measures how much grounding accuracy a given tier costs. - Language: English only, per the model card's out-of-scope list.
Troubleshooting
nvidia-smi shows less than 12 GB
Then this page's budget does not apply to your card. NVIDIA's Q&A notes the 192-bit bus permits either 6 GB or 12 GB, and the name has been reused across desktop and laptop parts. The 9B has no configuration that fits an 8 GB-class card with the projector loaded — the smallest sensible quant here, Q4_K_M at 32,768, still needs 7.556 GiB before a single compute buffer. Use the 4B at that capacity instead.
The agent does nothing — every step logs an empty response or list index out of range
This is the single failure everyone hits, and it is not a bug in your setup. Fara opens a <think> block and never closes it. Under llama-server's default reasoning extraction the parser therefore treats the whole output — reasoning and the <tool_call> block together — as reasoning, returns it in reasoning_content, and leaves message.content empty. The harness parses message.content for <tool_call>, finds nothing, and the loop dies.
Launch with --reasoning-format none, which llama.cpp's own help text describes as leaving thoughts unparsed in message.content. The raw output then begins with a stray unclosed <think> tag, which is cosmetic.
Reported for Fara1.5-27B by a community user on llama.cpp b10107 in the model's HF discussions and acknowledged there by Microsoft — swhitehead (a Fara org member) replied "Would you mind posting this as an issue on the Fara1.5 github repo so we can mention this in the hosting instructions?", which became microsoft/fara#82, still open. It applies to the 9B for a checkable reason rather than by assumption: the 9B's own GGUF carries the same chat template, whose generation prompt emits <think>\n with no closing tag whenever enable_thinking is not explicitly false. The same reporter adds: "If you have a router/proxy in front doing its own reasoning extraction, disable it there too."
Clicks land in the wrong place
Two things to check before blaming the model. First, the viewport must be 1440×900 — the harness's default, and the resolution the card says to match. Second, confirm --image-min-tokens 1024 is set; llama.cpp's default floor for this projector is 8 merged tokens, and grounding is exactly what that warning is about.
If both are right, there is one more thing to rule out before you blame the quantisation, and it was filed from this exact card. A community user reported that llama-server degrades fine-grained vision accuracy for PROJECTOR_TYPE_QWEN3VL models relative to llama-cli on the same build, with identical prompt-token counts — llama.cpp issue #22785, filed from an RTX 3060 running the Vulkan backend at release b8545. Read it with three caveats: a maintainer disputed the reporter's bisect and asked for a proper one, the issue was closed as stale and unconfirmed, and nobody re-tested it on a CUDA build or anywhere near b10087. Its value here is as a diagnostic, not a known defect: push the same screenshot through llama-cli — the binary the reporter compared against, and one of the three that accept --mmproj — and compare what the model says about it. If the CLI reads the page correctly and the server does not, you have reproduced something real and worth reporting upstream.
llama-server starts but images are ignored
If you launched with -m and no --mmproj, you have loaded a text-only model — the automatic projector download only happens on the -hf path. Check the startup log for the clip/mmproj load lines, and check /v1/models for the multimodal capability, which llama.cpp's server docs tell clients to test before sending images.
Generation is slower than a 9B model should be
There is an open, community-reported performance regression against exactly the SSM kernels this architecture leans on — llama.cpp issue #25162 reports a 24–42% loss on an RTX 2080 Ti (Turing, SM75) after commit 9e58d4d69, and notes that the Qwen35 architecture uses linear-attention layers for about 75% of its blocks, which matches the 24-of-32 split derived above. Three caveats before you act on it: it has no maintainer response; it was measured only on Turing, one architecture generation before this card's Ampere (SM86), and nobody has posted numbers for an RTX 3060; and the one candidate fix raised in the thread, PR #25185, was merged on 2026-07-01 with a stated scope of flash-attention kernels rather than the SSM path, with no re-measurement posted since. Release b10087 already contains that merge. Treat it as a lead to check with llama-bench across a couple of builds, not as a known property of this card.
rope.dimension_sections has wrong array length; expected 4, got 3
This is a real open llama.cpp bug (PR #25334), but it belongs to Ollama-exported qwen35 blobs, not to the GGUF this recipe uses. The bartowski artifact's own metadata reads qwen35.rope.dimension_sections = [11, 11, 10, 0] — four entries — so it cannot hit this failure. If you see this error, you are loading a different file than the one downloaded in Step 2. There is no Ollama library entry for Fara1.5 in any form, so there is no supported path that produces such a blob.
Out of memory on a 12 GB card
In order of what to try: drop -c from 32768 to 16384 (frees 0.500 GiB of KV, still above the harness's 15,000-token floor), pass --no-mmproj-offload to keep the projector on the CPU (frees 0.855 GiB at the cost of slower image encoding, once per agent turn), quantise the K cache with --cache-type-k q8_0 (takes the KV term from 1.000 GiB to 0.766 GiB — block_q8_0 is one ggml_half scale plus 32 int8_t quants, 34 bytes per 32 values against f16's 64), or move down to Q4_K_M (frees a further 0.877 GiB). Keep the f16 projector rather than a q8_0 one: at 0.855 GiB it is not where the savings are, and it trades vision fidelity in a model whose entire job is looking at pixels. If you are already at a comfortable margin and still OOM, check what else holds VRAM — on a card that also drives your display, the browser this agent opens is competing for the same 12 GB.
Running it against your own accounts
Don't. The model is trained to pause before sign-ins, payments and submissions, and that training is a safety net, not a guarantee — the card lists prompt injection from page content among its known risks, and a vision-only agent has no way to distinguish a legitimate button from a hostile one that renders like it. Keep it in a container, on an allow-list, with no credentials in reach.
For the full benchmark data, see /check/fara1-5-9b/rtx-3060.