How to use from
llama.cpp
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh
# Start a local OpenAI-compatible server with a web UI:
llama serve -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
# Run inference directly in the terminal:
llama cli -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
Install from WinGet (Windows)
winget install llama.cpp
# Start a local OpenAI-compatible server with a web UI:
llama serve -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
# Run inference directly in the terminal:
llama cli -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
cmake -B build
cmake --build build -j --target llama-app
# Start a local OpenAI-compatible server with a web UI:
./build/bin/llama serve -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
# Run inference directly in the terminal:
./build/bin/llama cli -hf Gramscii-IT/SemanticRepair-0.8B:Q8_0
Use Docker
docker model run hf.co/Gramscii-IT/SemanticRepair-0.8B:Q8_0
Quick Links

SemanticRepair-0.8B

One Qwen3.5-0.8B base with two LoRA adapters, each doing one small job behind an embedding router:

  • repair: when a message does not land clearly on one capability of a chat, it writes every request the message carries on its own line, and names for each line the capability that does its work among the ones the chat offers, or none. A message that asks for nothing comes back as NO_REQUEST.
  • tie-break: when the router and the repair still leave two or more offered capabilities close, it chooses one of them, or none, in which case the person is asked.

Neither adapter answers the question. The router checks every name they give against its own scores, and the host application decides what runs: a model's output alone never authorizes an operation.

The tie-break adapter is a distillation: it learned the choices of a teacher 34 times its size, Qwen3.8-27B. On 201 tie-breaks it never saw, answered by that teacher with the rules it was trained on, it makes the teacher's choice 176 times and a wrong one once, and leaves the other 24 to the person. On the 106 tie-breaks of 22 October, answered with the rules of that day, it agrees with the teacher almost as often as a 35-billion-parameter model, with one wrong choice against 22:

tie-break: same choice as the teacher, of 106 wrong choices
SemanticRepair-0.8B, tie-break adapter 82 1
Qwen3.5-4B fine-tuned by Gramscii 84 1
Qwen3.6-35B-A3B, thinking off (MoE, 3B active) 84 22
LFM2.5-24B-A2B (MoE, 2B active) 77 28
Flint (MoE, 40B, 2.5B active) 69 35

All on the same Apple M4 Pro (64 GB), llama.cpp, one request at a time. A wrong choice is a capability chosen where the teacher chose none or another one; an abstention is not a wrong choice, since the person is then asked. The other models generated their answer to the prompt of 22 October; the adapter reads its decision from the prompt it was trained on, which adds the rule on selected documents (below).

What is in this repository

file what it is
qwen3.5-0.8b-base-2fc06364-q8_0.gguf the base: Qwen3.5-0.8B at revision 2fc06364, Q8_0, 833,592,320 bytes, sha256 6a94a8273ab1fc5735743967b621eb5a3baba8e36a202f61c20dc47fbb80eb51
semantic-repair-0.8b-2n-lora-f16.gguf the repair adapter, round 2n, F16 LoRA, 21,671,008 bytes, sha256 c19be080ddbdfb13d4b1d2d86b94da56ffefa6d8c6514d8119b86eeffdd40698
semantic-repair-0.8b-tiebreak-20261031-lora-f16.gguf the tie-break adapter of 31 October, F16 LoRA, 21,671,712 bytes, sha256 0387bcf6f79c0ffa7dc0ed317cce1c3be94892cb6096a8daa9c4dd77015eb1f0
LICENSE the base model's Apache-2.0 licence

One base serves both jobs: the two adapters cost 21.7 MB each, not another 800 MB model. Pin the sha256 of all three: a routing decision has to be reproducible. Earlier rounds, the transformers weights among them, are in the repository's history only.

Where it runs

With llama-server, both adapters loaded on the one base, the model loaded only when routing needs it and released after an idle window:

llama-server -m qwen3.5-0.8b-base-2fc06364-q8_0.gguf \
  --lora semantic-repair-0.8b-2n-lora-f16.gguf \
  --lora semantic-repair-0.8b-tiebreak-20261031-lora-f16.gguf \
  --jinja --host 127.0.0.1 --port 9250 -ngl 99 -c 32768 --no-context-shift --cache-ram 0

Every request names its adapter at full scale and the other at none, so the two jobs never mix:

"lora": [{"id": 0, "scale": 1.0}, {"id": 1, "scale": 0.0}]

for a repair, and [{"id": 0, "scale": 0.0}, {"id": 1, "scale": 1.0}] for a tie-break. --cache-ram 0 keeps llama-server from holding up to 8 GiB of earlier prompts in memory: every call asks about a message of its own.

The repair adapter

The surface it reads, which is not a chat prompt

Fine-tuned on a bare completion surface. It has never seen a chat template, a system message or a few-shot example. Speak to it the way it was trained:

Capabilities: {the capability ids the chat offers, sorted, comma separated}
{Language}: {the message, verbatim}
=>

It completes with one line per request, capability | request, or the single token NO_REQUEST. A request no offered capability does is written none | request.

  • The newline after => is part of the surface: a prompt that stops at => is a surface the model never read.
  • {Language} is the English name of the language the message is in: Italian, English, French, German, Spanish.
  • The capabilities line is context the model reads, not a formality. Pass the whole list your chat offers, not a shortlist (see What it does not fix).

This is the whole call, on /v1/completions and never on a chat endpoint:

{
  "prompt": "Capabilities: document-search, locate-place, opendata-statistics, web-search\nItalian: dov'è sassari? mostramelo nella mappa e dammi le ultime notizie in italia\n=>\n",
  "stop": ["\n=>"],
  "temperature": 0.0,
  "repeat_penalty": 1.0,
  "max_tokens": 512,
  "lora": [{"id": 0, "scale": 1.0}, {"id": 1, "scale": 0.0}]
}

Greedy, because the same words must always produce the same lines: a router that reruns on a different answer each time cannot be reasoned about. repeat_penalty 1.0 is neutral, since a restatement legitimately repeats the words of the message. The stop string cuts a runaway that starts echoing another message in its own trained format. 512 tokens is the answer cap every measure below used; the longest answer they needed was 261 tokens.

What it is measured to do

Round 2n against round 2m, the round it replaced, on 26 October: each served as this repository serves it, the base with its repair adapter and the tie-break adapter of that day, on 481 real Italian chat questions held out from every training and selection step, through the chat's routing chain.

round 2n round 2m
ran only capabilities the question asks for 167 161
ran a capability the question does not ask for 26 27
the person asked to choose 288 293
validation loss, the same 1,396 rows 0.3255 0.3253

What it does not fix

A list without the capability a request needs is answered none. Its training rows list the capabilities a chat offers, and in some of them the right one is taken out and the answer becomes none: it reads the list as context. Pass the whole list the chat offers.

Long briefs lose steps and names. On 17 briefs of 127 to 771 tokens, round 2m, whose rows round 2n keeps, reached 46 of the 113 capabilities asked for.

The restatements are terse. «statistiche abitanti Cagliari» is good input for a router and poor prose. It is not meant to be shown to anyone.

Measured in Italian and English. The base pairs cover five languages, but the capability labels and every measure above are Italian and English.

The tie-break adapter

When it is asked, and how it is read

The router scores the message against every capability the chat offers; the repair restates it when the route is unsure. When two or more capabilities are still close, the tie-break is asked to choose among the ones the router itself offered, or none.

It reads the base model's chat template (llama-server --jinja, thinking off): a system message with the rules, and a user message listing the offered capabilities, each with its title, its description and what it gives (prose, tables, a chart…), the documents the person selected, and the message. The rules: choose by what the message asks for, not by the words it shares with a title; when the person selected documents and the message asks about what they hold, choose the capability that reads the selected documents; otherwise choose one only when the message plainly asks for what it gives and for nothing another one gives as well, and answer none when two would answer it equally. Its trained answer is one Markdown item:

- capability: <one id from the list, or none>

Nothing is generated. For each offered capability and for none, the host reads the probability of that whole answer, its end token included, from llama-server's next-token log-probabilities (/completion with n_probs), and normalizes them over the options. The likeliest capability is taken only when its probability is at least 0.8; below that the person is asked to choose. 0.8 is the lowest threshold that adds no wrong choice on the 201 tie-breaks of 31 October (at 0.75: 178 the same, 4 wrong; at 0.9: 166 the same, 1 wrong), so their figures below are not independent of it; the 106 tie-breaks of 22 October and the 481 real questions played no part in choosing it.

What it is measured to do

201 tie-breaks of 31 October, 146 Italian and 55 English, from conversation groups that share nothing with the training rows, each answered by the teacher, Qwen3.8-27B, with the rules above. In 116 of them the person had selected documents.

of 201 documents selected, of 116 none selected, of 85
same choice as the teacher (a capability, or none) 176 114 62
abstained: the person is asked 24 1 23
wrong choices: a capability where the teacher chose none 1 1 0
another capability than the teacher's 0 0 0

The same base with no adapter, asked with the same prompt and read the same way at 0.9: 43 the same, 132 abstained, 26 wrong.

106 tie-breaks of 22 October, 53 Italian and 53 English, answered by the teacher with the rules of that day, before the rule on selected documents: 82 the same, 23 abstained, 1 wrong, none another capability. All 34 with documents selected are the teacher's choice.

In the chat's routing chain, on the 481 real Italian questions: the routes as the chat computed them on 31 October with the repair adapter, admitted by the chat's own rules, and every choice the chat offered put to the tie-break as the chat puts it, with no documents selected.

tie-break adapter the base, no adapter, at 0.9
ran only capabilities the question asks for 170 176
ran a capability the question does not ask for 18 64
the person asked to choose 293 241

What it does not fix

Without selected documents it rarely decides. It took none of the 230 choices the chat offered on the 481 real questions: each went to the person, and the 18 wrong runs above come from routes the chat ran without a choice. On the held-out tie-breaks without a selection it makes the teacher's choice 62 times of 85 and leaves 23 to the person: the descriptions alone often do not settle it.

It chooses only among what the router offered. A capability the router did not put in the contest cannot be chosen, however right it would be.

The data they were trained on

Repair, round 2n: 141,787 training rows and 1,396 validation rows, from:

  • The published Gramscii-IT/semantic-repair-routing pairs, the ones SemanticRepair-270M was trained on, every line now carrying the capability that does its work as two judge models, Qwen3.8-27B and Gemma-4-31B, agreed on it; a row they disagreed on is left out.
  • 57,473 generated rows in Italian and English, written by Qwen3.8-27B (about two thirds) and Gemma-4-31B (about one third), kept only with the capability each was written for; rows for the capabilities that held few lines, and trap and contrast rows for the pairs earlier rounds confused, kept when both judges found nothing the line leaves out.
  • 1,500 long briefs, each step of their plans a line.
  • Chat messages from scripted conversations played through the application, 6,719 of 19 to 22 October and 10,388 more of the writing, slides, comparison, notes, topics, summary, place and address scripts that followed, whose capability the run that answered them confirmed and both judges confirmed reading the message alone, each with the line Qwen3.8-27B wrote for that capability and both judges confirmed.

Each row's prompt lists the capabilities its lines name plus a random draw of the others, because real chats offer lists as varied as that. For some rows the right capability is taken out of the list and the answer becomes none. One generated row in a hundred goes to validation, and no row equals a question of the benches above.

Tie-break: 28,726 training rows, 26,157 answered with a capability and 2,569 with none, from the tie-breaks recorded in scripted conversations played through the application, every one asked again on 31 October of the teacher, Qwen3.8-27B, with the rules above; an answer the host's own parser could not read is left out. The 201 tie-breaks of the table were taken out by conversation group before training, and the 106 of 22 October stay out too.

Training

repair, round 2n tie-break
base Qwen/Qwen3.5-0.8B at 2fc06364, its language model only the same
method LoRA, rank 16, alpha 32, dropout 0.05, on every linear layer but the embeddings and the head (186 modules, 10.8M parameters) the same
schedule one pass: 17,724 updates of 8 examples, learning rate 1×10⁻⁴, 100 warm-up steps one pass: 3,591 updates of 8 examples, the same rate
tokens 29.3M in the examples, 3.9M of them in the answers 30.7M in the examples, 200K in the answers
loss on the answer only on the answer only
hardware one NVIDIA A100 64 GB of the Leonardo supercomputer in Bologna, thanks to CINECA the same
release F16 LoRA GGUF F16 LoRA GGUF

Both adapters start from the original base; neither continues an earlier round.

Licence

Apache-2.0, as its base model Qwen3.5-0.8B. What it writes is yours, and so is the responsibility for what you let it decide.

Downloads last month
665
GGUF
Model size
0.8B params
Architecture
qwen35
Hardware compatibility
Log In to add your hardware

8-bit

16-bit

Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Gramscii-IT/SemanticRepair-0.8B

Adapter
(636)
this model

Dataset used to train Gramscii-IT/SemanticRepair-0.8B

Evaluation results

  • Ran only capabilities the question asks for (%) on 481 real Italian chat questions, held out from training
    test set self-reported
    35.300
  • Ran a capability the question does not ask for (%), lower is better on 481 real Italian chat questions, held out from training
    test set self-reported
    3.700
  • Same choice as the teacher, Qwen3.8-27B (%) on 201 held-out tie-breaks of 31 October (146 Italian, 55 English), no conversation group shared with training
    test set self-reported
    87.600
  • Wrong choices (%), lower is better on 201 held-out tie-breaks of 31 October (146 Italian, 55 English), no conversation group shared with training
    test set self-reported
    0.500
  • Same choice as the teacher, Qwen3.8-27B (%) on 106 held-out tie-breaks (53 Italian, 53 English)
    test set self-reported
    77.400
  • Wrong choices (%), lower is better on 106 held-out tie-breaks (53 Italian, 53 English)
    test set self-reported
    0.900