GraySoft
Projects Models Compare Cloud benchmarks FAQ Download guIDE →
Model Intelligence Sheet

impacte/ullr-2.6B-GGUF overview

ULLR — Search First, Execute Verified Tool Calling Model ULLR the Norse god of archery — precision, focus is a 2.6B tool calling model fine tuned from LiquidAI…

llama.cppgguftool-callingagenticfunction-callinglfm2ktoullrnolockenbase_model:LiquidAI/LFM2.5-2.6Bbase_model:quantized:LiquidAI/LFM2.5-2.6Blicense:otherendpoints_compatibleregion:usconversational

Runs locally from ~1.56 GB disk (4 GB VRAM class GPUs with llama.cpp / guIDE).

Downloads
0
Likes
0
Pipeline
Author

Repository Files & Downloads

2 GGUF files detected
Direct downloads for local inference
FileTypeQuantizationSizeLink
ullr-f16.ggufGGUFF165.03 GBDownload
ullr-q4_k_m.ggufGGUFQ4_K_M1.56 GBDownload

Model Details

Model IDimpacte/ullr-2.6B-GGUF
Authorimpacte
Pipeline
Licenseother
Base modelLiquidAI/LFM2.5-2.6B
Last modified2026-09-11T11:11:12.000Z

Model README

---

license: other

license_name: lfm-open-license-v1.0

base_model: LiquidAI/LFM2.5-2.6B

tags:

  • tool-calling
  • agentic
  • function-calling
  • lfm2
  • kto
  • ullr
  • nolock

language:

  • en

library_name: llama.cpp

---

ULLR — Search-First, Execute-Verified Tool-Calling Model

ULLR (the Norse god of archery — precision, focus) is a 2.6B tool-calling model fine-tuned from LiquidAI/LFM2.5-2.6B for the nolock coding assistant. It is trained to follow a strict policy: search the web before answering, execute code before claiming it works, and always work with tool feedback. When served inside an agent harness (such as nolock), this policy makes the system a precise, verified coding agent — ULLR is the model that powers it.

Results

BFCL v4 AST accuracy — full model ladder

All models evaluated with the identical harness (official bfcl_eval AST checker, greedy decoding, native tool-call parsing). The Qwen models went through the same pipeline as ULLR: SFT on the same 296-example dataset (Qwen-native format + no-tool chat mix), merge, GGUF, and — for the 0.8B variants — KTO rounds with harvested negatives.

| Model | Params | Training | simple | multiple | parallel | parallel_multi | Overall |

|---|---|---|---|---|---|---|---|

| LFM2-1.2B-Tool + SFT + KTO | 1.2B | SFT+KTO | 0.492 | 0.375 | 0.425 | 0.113 | 0.351 |

| Qwen3.5-0.8B (base) | 0.8B | — | 0.667 | 0.500 | 0.438 | 0.263 | 0.489 |

| Qwen3.5-0.8B + SFT | 0.8B | SFT | 0.667 | 0.500 | 0.438 | 0.263 | 0.489 |

| Qwen3.5-0.8B + SFT + KTO | 0.8B | SFT+KTO | 0.667 | 0.500 | 0.438 | 0.263 | 0.489 |

| Qwen3.5-2B (base) | 2B | — | — | — | — | — | — |

| Qwen3.5-2B + SFT (QLoRA) | 2B | SFT | 0.783 | 0.575 | 0.688 | 0.338 | 0.617 |

| Qwen3.5-2B + SFT + KTO | 2B | SFT+KTO | 0.783 | 0.575 | 0.688 | 0.338 | 0.617 |

| LFM2.5-2.6B (base) | 2.6B | — | 0.883 | 0.812 | 0.738 | 0.637 | 0.781 |

| ULLR (LFM2.5-2.6B + KTO) | 2.6B | KTO | 0.875 | 0.925 | 0.825 | 0.650 | 0.825 |

| ULLR Q4_K_M (quantized) | 2.6B | KTO + Q4 | 0.908 | 0.838 | 0.775 | 0.537 | 0.781 |

Key takeaways:

  • ULLR (KTO) beats every Qwen variant at every size — +33.6pp over the fine-tuned Qwen3.5-2B, +46.6pp over the fine-tuned Qwen3.5-0.8B
  • The KTO gain (+4.4pp) concentrated in multi-call categories: multiple +11.3pp, parallel +8.7pp over base
  • Even the 1.7GB Q4 quantization (0.781) matches the unquantized base — the KTO gains survive quantization
  • Notably, KTO only improved the strongest base: on the Qwen models, identical KTO pipelines were neutral-to-harmful (see training details)

Multi-turn & in-domain

| Benchmark | Base LFM2.5-2.6B | ULLR (KTO) |

|---|---|---|

| τ-bench call validity (16 episodes) | 100% | 100% |

| τ-bench env errors | 0 | 0 |

| In-domain validation (10 prompts) | 5/10 | 6/10 |

In-domain failures are concentrated in multi-step completion (long verify loops exceeding the 8-step budget), not tool selection — the model picks the right tools in the right order but doesn't always converge to a final answer.

How it was built

1. The policy (defined by the product, not the benchmark)

ULLR is trained to almost never answer from parametric knowledge:

User asks anything factual?     → web_search → (web_fetch) → cited summary
Answer contains math or code?  → rust_repl executes it FIRST → verified result
Search/fetch fails?            → refine query / different URL → retry
Local project question?        → grep / read_file / list_directory / edit
User gives a task?             → engage with tools immediately, never deflect

This is deliberately not the classic "don't over-call tools" alignment — the model is supposed to search even when it probably knows the answer, and to run code before reporting results, accepting slower answers in exchange for verified ones.

2. GLM-5.3-Flash as the trajectory teacher

The policy training data was authored by GLM-5.3-Flash (Z.ai) acting as the teacher, rather than generated by a local model. This mattered for three behaviors that had zero coverage in the existing data:

  • Search-and-summarize loops: web_search → web_fetch → cited summary trajectories with real queries and real documentation URLs (Rust Book, MDN, React blog, Tokio docs), each answer citing its source and noting why verification mattered
  • Code-execution: math/code questions where rust_repl runs before answering — prime sums, Fibonacci, JSON/serde parsing, even a deliberate compile-error check (E0308) — with answers reporting the executed result
  • Tool-feedback recovery: search → fetch official docs → synthesize setup steps across sources

The teacher also authored the engagement pairs: chat-deflection responses (the model's measured failure mode) as rejected completions, paired with acknowledge-and-call chosen completions reconstructed from τ-bench ground-truth action lists.

3. Nemotron-Nano-9B as the local cross-validation judge

Every row was cross-validated by a locally-running Nemotron-Nano-9B acting as a policy judge before training. The judge was first validated itself on 4 crafted cases (4/4 discrimination, including a borderline math-without-REPL case).

Judging all 115 rows flagged 44 as mislabeled. Human categorization of the flags showed:

| Flag reason | Count | Verdict |

|---|---|---|

| Judge expected full task/summary in a single completion | 23 | Judge wrong — KTO completions are deliberately first-turn calls |

| Judge misapplied policy (τ-bench tools ≠ "local tools") | 10 | Judge wrong |

| list_directory used on a file path | 7 | Real error — fixed (read_file substituted) |

| Ambiguous STOP-acknowledgment negatives | 2 | Dropped |

The cross-validation caught 7 genuine tool-selection errors that would have taught the model to list directories instead of reading files — while the 35 over-strict flags were overridden with documented reasoning. Automated judging + human categorization was the combination that worked.

4. nolock's KTO/DPO framework

Training used nolock's in-house preference framework — the same .rlhf collection schema (thumbs-up/thumbs-down with user_correction metadata) that powers the editor's feedback loop. Human-labeled rows (including KTO-schema rows rescued from a mislabeled dpo/good/ directory, and LFM2-dialect tool calls converted to native format) were merged with on-policy negatives harvested from benchmark failures, then cross-validated. The framework's schema (TRL-compatible {prompt, completion, label}) fed directly into TRL's KTOTrainer.

Why KTO worked here (and failed on smaller models)

Three earlier KTO attempts (Qwen3.5-0.8B ×2, Qwen3.5-2B) failed to improve their bases. This one succeeded (+4.4pp BFCL, validation 5→6/10) because:

  • Strong base: LFM2.5-2.6B's agentic RL gave it capability to calibrate, not capability to create
  • On-policy negatives: the 11 τ-bench non-engagement failures were the model's own outputs, not synthetic approximations
  • Low KL drift (6.5): the training nudged engagement calibration without damaging the underlying agentic competence — margins stayed positive (+0.59 → +0.88) throughout

The policy (what this model is trained to do)

User asks anything factual?     → web_search → (web_fetch) → cited summary
Answer contains math or code?  → rust_repl executes it FIRST → verified result
Search/fetch fails?            → refine query / different URL → retry
Local project question?        → grep / read_file / list_directory / edit
User gives a task?             → engage with tools immediately, never deflect

Files

| File | Size | Use |

|---|---|---|

| ullr-f16.gguf | 5.4 GB | Full precision — local use with GPU headroom |

| ullr-q4_k_m.gguf | 1.7 GB | Edge/Railway deployment (BFCL 0.781, −4.4pp vs f16) |

Usage

llama.cpp (recommended serving path)

llama-server -m ullr-q4_k_m.gguf --jinja -c 8192 --port 8081
# OpenAI-compatible endpoint with native tool_calls:
curl http://localhost:8081/v1/chat/completions -d '{
  "model": "ullr",
  "messages": [{"role": "user", "content": "What is 17 * 23?"}],
  "tools": [...],
  "tool_choice": "auto"
}'

Ollama

ollama create ullr -f Modelfile   # FROM ./ullr-q4_k_m.gguf
ollama run ullr "Find the official docs for the Tauri window-state plugin"

> Note: serve via llama.cpp --jinja or Ollama ≥ 0.33. Earlier Ollama chat templates mishandle the reasoning_content field and can swallow tool calls after the thinking block.

Recommended sampling

temperature 0.1, top_k 50, top_p 0.9, repeat_penalty 1.1 (Liquid AI's official agentic settings).

Training details

| | |

|---|---|

| Base | LiquidAI/LFM2.5-2.6B (Lfm2ForCausalLM, hybrid 22 conv + 8 GQA) |

| Method | KTO (TRL KTOTrainer), LoRA r=32 / α=64, dropout 0.05 |

| Targets | q/k/v/o_proj + gate/up/down_proj |

| Data | 106 rows (92 chosen / 14 rejected, 6.6:1) — authored policy trajectories + on-policy harvested negatives + human preference rows |

| Hyperparams | lr 1e-5, β 0.1, undesirable_weight 1.5, 3 epochs, batch 2×4 accum, bf16, paged_adamw_8bit |

| Result | KL 6.5 (anchored), rewards/margins +0.59 → +0.88, BFCL 0.781 → 0.825 |

Limitations

  • Multi-step completion: long verify loops (edit → build → test → fix) can exceed practical step budgets; the model selects correctly but doesn't always converge within ~8 rounds.
  • Reasoning overhead: always thinks before answering (reasoning_content); latency per turn is higher than non-reasoning models of the same size.
  • License: LFM Open License v1.0 — royalty-free for non-commercial/research and businesses <$10M annual revenue.
  • Web dependency: per policy, factual answers require web access; offline use degrades to local-tools-only behavior.

Acknowledgments

Citation

@software{ullr2026,
  author = {Gabriel Amazonas},
  title  = {ULLR: A Search-First, Execute-Verified Tool-Calling Model fine-tuned from LFM2.5-2.6B},
  year   = {2026},
  url    = {https://huggingface.co/impacte/ullr-2.6B-GGUF}
}

Run impacte/ullr-2.6B-GGUF with guIDE

Download guIDE — the AI-native code editor with local LLM inference and 69 built-in tools.

Download guIDE → · Browse 524k+ models · Compare models

Source: Hugging Face · Compare models