Instructions to use jeff-legacy/Jeff-Qwen3.5-0.8B-nav with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use jeff-legacy/Jeff-Qwen3.5-0.8B-nav with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Configuration Parsing Warning:In adapter_config.json: "peft.task_type" must be a string
Superseded: this model is from an earlier Jeff release and is no longer updated. The current release is Jeff v1.3: mstrasser/jeff-adapter-nav. This v1.2 adapter loads only on the v1.2 base.
Jeff-Qwen3.5-0.8B-nav
Voice navigation: turns a spoken command, even a misheard one, into an item on the current app screen, a question, or none of these.
Give it what speech recognition heard, the current screen and every item on that screen. It picks the item the user meant, matching by meaning and by sound, or says the user is asking a question, or that they want something not on the screen. Training screens mostly had 40 to 120 items. It is a LoRA adapter for Jeff-Qwen3.5-0.8B v1.2, a small open decision model: it answers in one forward pass, with no generated text to parse.
Results
Test set: Nav held-out apps, 3,300 rows. Requests from about 10% of the roughly 340 generated apps, never trained on. It is included in this repo as test.jsonl.
| Model | Accuracy | Calibration error (ECE) |
|---|---|---|
| Qwen3.5-0.8B, untrained | 12.6% | 0.038 |
| Jeff v1.2 0.8B alone | 23.8% | 0.195 |
| Jeff v1.2 0.8B + nav | 97.0% | 0.005 |
Calibration error is the expected calibration error over 15 confidence bins, after each model's fitted temperature: the average gap between how confident the model is and how often it is right. Lower is better. The untrained Qwen3.5-0.8B is read out from its own scores for the option letters.
Against Qwen3.8-27B
Here Jeff + nav answers first. Below a confidence threshold, the query is also sent to Qwen3.8-27B and the 27B's answer is used. Each adapter's threshold is the fastest one that still beats the 27B alone by at least 1 point of accuracy on the adapter's calibration rows (not the test rows).
| Route | Accuracy | Mean time per query | Sent to the 27B |
|---|---|---|---|
| Qwen3.8-27B alone | 91.3% | 7.21 s | 100% |
| Jeff + nav, 27B below threshold 0.00 | 97.0% | 208 ms | 0.0% |
The threshold is 0.00: on the calibration rows the adapter alone already beat the 27B by more than a point, so no query is passed on. The route is 34.6× faster than the 27B alone.
How this was measured: a fixed random sample of 300 held-out test rows, the same rows for both routes, on an Apple M4 Max (128 GB) with both models in MLX, one at a time. Qwen3.8-27B ran with 8-bit weights, prompted, with step-by-step reasoning off. Times are the mean per query over the whole sample, from prompt to answer. This is a 300-row sample, not the full test set.
Speed and memory
One request at a time on an NVIDIA RTX PRO 6000: 675 requests per setting, 75 test prompts of each of the nine adapters, interleaved. Measured for the adapters as a group, not for each adapter, so treat these as typical figures:
| Setting | Median | 95th percentile | GPU memory after loading |
|---|---|---|---|
| The v1.2 base alone | 25.9 ms | 35.5 ms | 1.74 GB |
| Shared base, one adapter (default mode) | 31.2 ms | 40.3 ms | 1.79 GB |
| Shared base, all nine adapters, a different one on every request | 30.0 ms | 39.4 ms | 1.96 GB |
Merged mode (JEFF_ADAPTER_MODE=merged), one adapter folded into the weights |
25.7 ms | 35.7 ms | 1.77 GB |
Jeff's speed and memory on the Mac: not measured yet.
Where it goes wrong
On the full test set:
- By far the commonest mistake is picking a screen item when the user wanted something that is not on the screen (
none_of_these). If acting on a wrong item is costly, check the confidence before acting. - Questions (
ask_question) were all recognised on this test set. - Some test rows use different wordings and keys for the two fixed options (for example
nothing_matches), as in the format pools used in training; a few single-row errors come from those.
Commonest confusions (right answer → chosen instead, rows):
| Right answer | Chosen instead | Rows |
|---|---|---|
| none of these | an item on the screen | 50 |
| an item on the screen | another item | 21 |
| an item on the screen | none of these | 9 |
nothing_matches |
q_question |
1 |
| none of these | opt_62 |
1 |
| none of these | item_23 |
1 |
Accuracy by kind of answer:
| Right answer | Test rows | Accuracy |
|---|---|---|
| none of these | 557 | 89.6% |
| an item on the screen | 2,154 | 98.6% |
| a question | 318 | 100.0% |
("An item on the screen" groups all rows whose answer is a screen item; per-item rows are too few to report.)
When to use it
- Your app takes voice commands and you want the item on the current screen the user meant, matched by meaning and by sound.
- You can list every item on the screen as an option. Training screens mostly had 40 to 120 items, some up to 200, and dialogues 4 to 8.
- You also need to tell a question, or a request the screen does not offer, apart from a navigation command.
When not to use it
- The user's words exactly match an item's name. Match those in code first; training left such cases out.
- You need the command carried out or an answer to the user's question. Jeff only picks an option.
- You want one app's best accuracy and have data from that app. A separate full fine-tune on one app's own screens (a different model) scored 95.2% on navigation screens with a 10-item shortlist; this general adapter is not yet measured.
- Your users mostly speak languages other than English. All training data is English.
How to use it
The adapter runs with Jeff's server on the Jeff-Qwen3.5-0.8B v1.2 base. One server holds the base and any number of adapters; each request picks one by name with "model": "nav".
git clone https://github.com/firelex/jeff && cd jeff
uv sync --no-default-groups --extra lora # add --extra cuda on NVIDIA GPUs, --extra mac on Apple silicon
uv run --no-default-groups hf download mstrasser/Jeff-Qwen3.5-0.8B --revision v1.2 --local-dir Jeff-Qwen3.5-0.8B-v1.2
uv run --no-default-groups hf download mstrasser/Jeff-Qwen3.5-0.8B-nav --local-dir adapters/nav
JEFF_CHECKPOINT=Jeff-Qwen3.5-0.8B-v1.2 JEFF_ADAPTERS=adapters PORT=8765 \
uv run --no-default-groups --extra lora jeff-serve
# add JEFF_BACKEND=mlx and --extra mac for Apple silicon
Every folder in adapters/ is served under its folder name. Add or replace an adapter while the server runs with POST /v1/adapters/reload. The server checks the base weights' checksum, so the adapter loads only on the exact v1.2 base.
from jeff import Client
nav = Client("http://localhost:8765", model="jeff-latest").with_model("nav")
Request format
State (the situation):
| Key | Changes per request | What it holds |
|---|---|---|
current_screen |
no | Where the user is, in plain words, for example "Tallow Books › Clients". |
previous_screen |
no | The screen the user came from, or null. |
dialogue_step |
no | Null, or the pending question when the app has asked the user to choose, such as "Which did you mean?". |
voice_transcript_may_contain_errors |
yes | What speech recognition heard. It may contain misheard words, split words and fillers. |
Questions:
target(choice): Which item on the screen the user wants, or whether they are asking a question, or want something not listed. Options:ask_questionandnone_of_thesefirst, in that order, then every item on the screen as o1, o2, … with a short text in the app's own style, such as "Settings", "client Brennan Roofing" or "invoice 2231 → payments".
Rules:
- Use the instructions below word for word; the adapter was trained mostly on them.
- Keep the two fixed options first, with these exact texts.
ask_questionis "Not a navigation request: the user is asking a question";none_of_theseis "None of these: the user wants something not listed". - List every item on the screen; do not shortlist. Use at most 254 options in all. Item order does not matter; it was shuffled in training.
- Keep the state keys in this order, with the transcript last, so the unchanging part of the request can be prepared in advance.
Example
{
"model": "nav",
"state": {
"current_screen": "Tallow Books › Clients",
"previous_screen": "Tallow Books › Home",
"dialogue_step": null,
"voice_transcript_may_contain_errors": "um open bren and roofing supplies"
},
"questions": {
"target": {
"type": "choice",
"instructions": "Which of these does the user want? The voice transcript comes from speech recognition and may contain misheard words, so match by meaning and by sound. If the user is asking a question rather than asking to go somewhere or do something, choose the question option. If none of the listed options is what they want, choose none of these.",
"criteria": {
"ask_question": "Not a navigation request: the user is asking a question",
"none_of_these": "None of these: the user wants something not listed",
"o1": "Home",
"o2": "Search",
"o3": "client Brennan Roofing",
"o4": "client Brennon Roofing Supplies",
"o5": "invoice 2231 → payments",
"o6": "Settings"
}
}
}
}
curl -s localhost:8765/v1/systemone -H 'content-type: application/json' -d @request.json
The answer holds a probability for each option of each question, the chosen option and a confidence. (A recorded response to this example is not published yet.)
Training
| Base | Jeff-Qwen3.5-0.8B v1.2 (final checkpoint of run 0.8b-20260929-2258) |
| Method | LoRA, rank 16 |
| Rows | 79,529 (72,299 adapter rows plus a replay slice of the v1.2 base training mix, 10% of the adapter rows) |
| Epochs | 1 |
| Steps | 1,243 |
| Time | 144.1 minutes on one NVIDIA RTX PRO 6000 |
| Adapter files | 41.5 MB |
| Run | 0.8b-nav-20261001-0352, step 1243 |
The replay slice mixes in some of the base model's own training data so the adapter keeps the base's general skills. The scored checkpoint is the one at the end of the epoch.
Data and provenance
Sources:
| Source | Licence | Notes |
|---|---|---|
| Generated apps, screens and spoken commands | Generated for this adapter (training rows not published) | About 340 made-up apps and websites, their screens and items, and how people say each command aloud, written by a language model and code, and checked by a second blind pass (see below). No real user data. Sound-alike speech-recognition errors were made in code with the CMU Pronouncing Dictionary (BSD-2-Clause, commit 74790861f652). |
Which models wrote and checked the data. The spoken commands were written by Qwen3.8-Max (hosted); the apps by Qwen3.8-Flash-Next (local), and the apps' navigation systems by both. Rows were checked by Qwen3.8-Flash and DeepSeek-V4-Flash (hosted). Qwen3.8-Max is a hosted, closed-weight model, used through Alibaba Cloud's DashScope API to finish in time. Counts are on the 72,299 training rows; one row can pass through several models, so the counts do not add up to the total.
| Job | Model | Where it ran | Training rows | Test rows (of 3,300) |
|---|---|---|---|---|
| Checked the row | Qwen3.8-Flash | hosted (Alibaba Cloud DashScope) | 72,299 | 3,300 |
nav's rows record only the checking model; the hand-over file (READY-nav) records which models wrote each stage, listed below as the number of apps (of about 340) each model worked on:
| Stage | Models |
|---|---|
| Apps (stage 1) and brand check | Qwen3.8-Flash-Next (local) |
| Navigation systems (stage 2) | Qwen3.8-Max (hosted): 233 apps; Qwen3.8-Flash-Next (local): 107 apps |
| Format pools (instructions, fixed-option wordings) | Qwen3.8-Flash-Next (local) |
| Utterances (stage 4) | Qwen3.8-Max (hosted): 340 apps |
| Supplement utterances | Qwen3.8-Max (hosted): 340 apps |
| Blind check (stage 6) | Qwen3.8-Flash (hosted): 340 apps |
| Second opinion on training none-of-these and question rows | DeepSeek-V4-Flash (hosted): 340 apps |
| Length-balance sentences round 1 (extra.py: 3-6-word questions and remarks, long requests) | Qwen3.8-Max (hosted): 340 apps |
| Length-balance sentences round 2 (extra2.py: 2-3-word and 6-8-word questions, 2-3-word remarks, 9-13-word requests for navigation and none-of-these rows) | Qwen3.8-Max (hosted): 340 apps |
| Length-balance sentences round 3 (extra3.py: 3-8-word questions with a filler word) | Qwen3.8-Max (hosted): 340 apps |
| Blind check (stage 6) of length-balance rows | round 1: Qwen3.8-Flash (hosted): 340 apps; round 2: Qwen3.8-Flash (hosted): 340 apps; round 3: Qwen3.8-Flash (hosted): 340 apps |
| Strict question check (every question candidate) | round 1 (old and round-1 questions): DeepSeek-V4-Flash (hosted): 340 apps; round 2: DeepSeek-V4-Flash (hosted): 340 apps; round 3: DeepSeek-V4-Flash (hosted): 340 apps |
| Length-balance sentences rounds 4 and 5 (extra4.py, extra5.py: requests of a stated word count, written alike and made navigation or none-of-these rows at random afterwards; 2-6-word questions with articles; remarks with fillers) | round 4: Qwen3.8-Max (hosted): 340 apps; round 5: Qwen3.8-Max (hosted): 340 apps |
| Blind check (stage 6) of rounds 4 and 5 | round 4: Qwen3.8-Flash (hosted): 340 apps; round 5: Qwen3.8-Flash (hosted): 340 apps |
| Strict question check rounds 4 and 5 | round 4: DeepSeek-V4-Flash (hosted): 340 apps; round 5: DeepSeek-V4-Flash (hosted): 340 apps |
| Second opinion on training none-of-these rows of rounds 2, 4 and 5 | extra2: DeepSeek-V4-Flash (hosted): 286 apps; extra4: DeepSeek-V4-Flash (hosted): 271 apps; extra5: DeepSeek-V4-Flash (hosted): 270 apps |
| Screens, garbling, code checks | code, no model |
Training data not published. The test set is included in this repo as test.jsonl, and the calibration set (1,994 rows, the rows the threshold for the comparison with Qwen3.8-27B is chosen on) as calibration.jsonl.
Test set: test.jsonl, 3,300 rows: Requests from about 10% of the roughly 340 generated apps, never trained on.
It is byte for byte the set the adapter was scored on.
The terms of the hosted model providers are being checked for training and publication use.
Quality review. An independent reviewer checked the training, calibration and test files for shortcuts, duplicates, leaks between splits and junk before training. The report is at jeffhub.ai/adapters/nav/qa-report.
Limitations
- English only.
- Tied to the Jeff-Qwen3.5-0.8B v1.2 base. It will not work on any other base or version; the server refuses it if the base weights' checksum does not match. A v1.3 long-term-support base is coming, and the adapters will be retrained on it.
- Jeff chooses between the options you give it. It does not write text or reason in several steps.
- Calibration was fitted on this adapter's own calibration rows. On very different data, check it again.
- The general adapter has not been measured on any single real app yet.
- Everything listed under When not to use it above.
Links
- Adapter page: jeffhub.ai/adapters/nav
- Code and server: github.com/firelex/jeff
- Base model: mstrasser/Jeff-Qwen3.5-0.8B (revision v1.2)
Jeff is an independent project. It uses the same request format as Jev but is not affiliated with or endorsed by TypeSafe, the makers of Jev.
- Downloads last month
- 52
Model tree for jeff-legacy/Jeff-Qwen3.5-0.8B-nav
Base model
Qwen/Qwen3.5-0.8B-Base