Instructions to use akshat-OwO/nev-0.8b with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use akshat-OwO/nev-0.8b with PEFT:
from peft import PeftModel from transformers import AutoModel base_model = AutoModel.from_pretrained("Qwen/Qwen3.5-0.8B-Base") model = PeftModel.from_pretrained(base_model, "akshat-OwO/nev-0.8b") - Notebooks
- Google Colab
- Kaggle
Nev-0.8B
Nev is a 0.8B decision model that picks the next browser action for one step of a web task. It reads the page as a numbered list of elements, the step's instruction, and the actions taken so far. It then returns a probability for every allowed answer to four typed questions: is the step done, which operation comes next, which element it acts on, and which input value goes in a field. It answers in one forward pass. There is no free-form text generation and no output parsing.
Nev runs on a laptop. On an Apple M5 it answers a browser step in about half a second through MLX.
Nev is a fine-tune of Kev-0.8B, which is a LoRA adapter and a pointer
head on Qwen/Qwen3.5-0.8B-Base. It serves the System One API
(POST /v1/systemone) through Kev's server. It was built for Contingency, a tool that runs
and checks taught browser journeys. Nev is not affiliated with TypeSafe.
Model
- Backbone: Qwen/Qwen3.5-0.8B-Base (24 layers: 18 Gated DeltaNet and 6 full attention), frozen.
- Adapter: LoRA, rank 16, alpha 32, on the attention, MLP, and DeltaNet projections of every layer (11.3M parameters).
- Head: Kev's pointer head. It scores each option's closing token against the question's final token. A softmax per question gives the probabilities.
- Calibration: one temperature (1.231), stored in
head.ptand applied when the model loads. On held-out sites, Nev was wrong with 90% or more confidence on 0.3% of its answers.
Files
| File | Purpose |
|---|---|
adapter_model.safetensors, adapter_config.json |
LoRA adapter for Qwen3.5-0.8B-Base |
head.pt |
Pointer head, temperature, and training metadata |
tokenizer.json, tokenizer_config.json, chat_template.jinja |
Tokenizer with Kev's delimiter tokens |
training_config.json, training_metrics.json |
Training arguments and run metrics |
LICENSE |
Apache-2.0 license |
The base model downloads separately from Qwen/Qwen3.5-0.8B-Base the first time Nev loads.
Usage
Nev runs with the Kev server. You need Python 3.12 or 3.13 and uv.
git clone https://github.com/jaredpalmer/kev.git && cd kev
uv sync --extra serve
uv run --extra serve python -m kev.serve --run akshat-OwO/nev-0.8b --port 8009
The server picks MLX on Apple Silicon and CUDA on an NVIDIA GPU. Any 4 GB GPU is enough.
A browser step
Send the page and the step. Element indexes are the option names, so Nev can only choose an element that is on the page. Input values stay in your code: Nev picks which input name goes in a field, and never writes the value itself.
curl -s localhost:8009/v1/systemone -H 'content-type: application/json' -d @step.json
step.json:
{
"model": "nev",
"state": {
"elements": [
{
"index": "1",
"role": "combobox",
"name": "City"
},
{
"index": "2",
"role": "button",
"name": "Save location"
},
{
"index": "3",
"role": "button",
"name": "Add Trail Hammer to cart"
}
],
"page": {
"content": [
"heading: Delivery location",
"status: Delivering to: No delivery location chosen"
],
"title": "Shop",
"url": "https://shop.example/"
},
"recent_actions": []
},
"questions": {
"done": {
"criteria": {
"false": "The page does not show this yet, or shows something else.",
"true": "The page visibly shows exactly this outcome now."
},
"instructions": {
"condition": "The status line reads \"Delivering to: Boulder\".",
"question": "Does the current `page` satisfy `condition`?"
},
"type": "noul"
},
"operation": {
"criteria": {
"SELECT": "Choose one of the provided input values in a dropdown list.",
"CLICK": "Click a button, link, checkbox, tab, or other control.",
"BLOCKED": "No listed element can make progress on the step."
},
"instructions": {
"question": "Which operation is the single next action toward `step`? Do not repeat an action in `recent_actions` that already took effect.",
"step": "Choose Boulder in the City list, then select Save location."
},
"type": "choice"
},
"select_target": {
"criteria": {
"1": "[1] combobox \"City\""
},
"instructions": {
"question": "If the next action is SELECT, which target does `step` call for?",
"step": "Choose Boulder in the City list, then select Save location."
},
"type": "choice"
},
"value_1": {
"criteria": {
"city": "Boulder",
"product": "Trail Hammer"
},
"instructions": {
"question": "Which input value does `step` put in [1] combobox \"City\"?",
"step": "Choose Boulder in the City list, then select Save location."
},
"type": "choice"
},
"click_target": {
"criteria": {
"2": "[2] button \"Save location\"",
"3": "[3] button \"Add Trail Hammer to cart\""
},
"instructions": {
"question": "If the next action is CLICK, which target does `step` call for?",
"step": "Choose Boulder in the City list, then select Save location."
},
"type": "choice"
}
}
}
Ask the questions with this exact wording: it is the wording Nev was trained on. Each choice answer has choice,
confidence, and probabilities. A noul answer has the probability of true. For this page Nev answers done
false, operation SELECT, select_target 1, and value_1 city.
Loop rules that matter
- Treat a step with no action yet as finished only at a high
doneprobability. A literal reading of a condition can be true before the step's work is done, for example a search box that is visible before its city is chosen. Contingency uses 0.9 before a step's first action and 0.5 after it. - Send at most about 150 elements. Nev trained on pages of that size. Trim long pages to interactive elements and the visible region first.
- Hand back on BLOCKED or low confidence. Nev is the fast path. A larger agent should judge outcomes, recover from errors, and check that something is gone.
Input format
| Field | Description |
|---|---|
state.page |
url, title, and content: visible text as role: text lines |
state.elements |
Interactive elements: index, role, name, and optional value, checked, within |
state.recent_actions |
Earlier actions in this run, newest last, such as FILL [6] textbox "Search" ← "Sector 14" → effect: dom |
questions |
Typed questions, as in the System One API: noul, choice, or score |
Nev answers any System One request, not only browser steps. See Kev's documentation for the full API.
Results
"Steps fully right" means the operation and the target element are both correct. "Explicit steps" name the element, as a written procedure does. "Goal only" gives just the task, so the model must plan the next step itself. Every test set uses websites, or whole domains, that never appear in training. The best value in each row is in bold.
| Test set | Nev-0.8B | Kev-0.8B | Laya |
|---|---|---|---|
| Mind2Web, unseen websites, explicit steps | 91.0 | 6.7 | 2.7 |
| Mind2Web, unseen domains, explicit steps | 92.3 | 6.8 | 5.7 |
| Mind2Web, unseen websites, goal only | 39.7 | 0.0 | 2.0 |
| Mind2Web, unseen domains, goal only | 34.0 | 1.0 | – |
Held-out crawl and WebChain sites, with done checks |
76.9 | – | 19.7 |
| Kev's general decision set (not browser) | 82.3 | 83.3 | – |
Each browser row scores 287 to 400 steps, sampled with a fixed seed. Laya shows its better result of the English model at 512 tokens and the multilingual model at 8,192 tokens. Most browser requests are 2,000 to 5,000 tokens with up to 120 options, which is outside the setting Laya was trained for.
On Kev's general decision set (491 questions), Nev scores within the noise of Kev-0.8B (standard error about 1.7 points). The fine-tune kept Kev's general skills because it mixed in 1,000 of Kev's own training records.
The held-out test set is published as akshat-OwO/nev-bench, with the IDs of the scored Mind2Web steps and the scripts that rebuild every number.
Speed
| Hardware | Time per browser step |
|---|---|
| Apple M5, MLX, bf16 | about 0.35 to 0.6 s for 1,500 to 3,000-token requests |
Limits
- Planning from a goal alone is weak. Nev is built for explicit steps. Given only the task, it gets about a third of steps fully right.
- Checking that something is gone is unreliable. Leave conditions such as "the banner is gone" to a larger model.
- Pages above about 150 elements cost time and accuracy. Trim them first.
- Languages: trained mostly on English pages, with some Chinese. Other languages are not measured.
- Images: Nev reads text only.
Training
| Start | Kev-0.8B (Hub revision bf75a6a), adapter and head |
| Data | 9,000 browser steps and 1,000 Kev records (below) |
| Recipe | 1 epoch, learning rate 2e-5, batch 4, gradient accumulation 2, states up to 8,192 tokens, shared state prefix |
| Hardware | One H100, about 1 h 40 min |
| Calibration | Temperature fitted on 332 held-out records |
Training data:
- Mind2Web (CC BY 4.0): 3,500 steps from its training split. Deng et al., Mind2Web: Towards a Generalist Agent for the Web, NeurIPS 2023.
- WebChain (CC BY 4.0): 3,000 steps from human trajectories on 239 sites. 26 more sites were held out for testing.
- Contingency crawl: 2,500 generated steps on 111 public sites, captured with Contingency's own browser snapshots.
- Kev public suite: 1,000 records from Kev's training set, so general skills are kept.
Each step became a request in the input format above. Explicit instructions were written from the recorded action. Goal-only instructions use the task text. The labels are the recorded operation, element, and value.
License
The adapter and head are released under Apache-2.0, as are Kev-0.8B and Qwen3.5-0.8B-Base. The training data includes Mind2Web and WebChain, both under CC BY 4.0. Credit them when you use or redistribute work derived from Nev.
- Downloads last month
- 37