--- license: apache-2.0 base_model: google/gemma-4-E2B library_name: peft language: - en tags: - web-agents - gui-agents - mind2web - lora - pointer-network - selective-prediction - calibration - decision-making - fast-decision-model - system-1 - model-routing - gui-grounding datasets: - osunlp/Multimodal-Mind2Web --- # Gemma 4 E2B + LoRA pointer head for web element selection (Multimodal-Mind2Web) **A small, fast "which element do I click next?" model with a confidence score. Research release, not a ready-to-use web agent.** Given a task, the previous actions, a full-page screenshot and a list of candidate DOM elements, the model points at one candidate (or at a learned "none of these" slot) and predicts the operation type (click / type / select). It does **not** generate the text to type. - Backbone: `google/gemma-4-E2B` (frozen) + LoRA (rank 32, attention + MLP, layers 0-29, 180 modules) + a small pointer head trained from scratch. - Trained on Multimodal-Mind2Web for about 8 hours on one A100-40GB. - Speed: in the live form test below (short pages, one screenshot strip, about 33 candidates) a decision took about 0.2 s for the model plus 0.1 s for candidate extraction and screenshot on an A100. Inputs of Mind2Web size (several strips, up to 4600 tokens) are slower; we did not benchmark that separately. - Honest summary of what it is good and bad at is in [Summary of results](#summary-of-results) and [Limitations](#limitations-and-what-this-model-is-not). **Role: a fast decision module ("System 1").** The model is meant as the quick, cheap first decision in a larger agent: it picks the next element or abstains with a confidence score, and low-confidence steps are escalated to a stronger model ("System 2", for example a large VLM) or a human. It is a decision/routing component, not a standalone agent. **Approach: a calibrated decision head, "Kev-like".** Instead of generating the next action as text, the model makes a *decision over a closed set*: a query vector (from the task, history and screenshot) is scored against one key per candidate element plus a learned "none of these" key, and a softmax gives a probability for every option. This pointer-style, "Kev-like" decision head has three consequences we care about: (1) one forward pass picks the element, no token-by-token decoding; (2) the top-1 probability is a ready-made confidence score, and "none" is an explicit option, so the model can abstain; (3) because decisions and confidences are explicit numbers, they can be evaluated and calibrated with standard tools (ECE, Brier score, risk-coverage curves, temperature scaling) and used to route uncertain steps to a stronger model. In this release the decision quality and the confidence ranking are measured (see results); the confidences themselves are still raw and need temperature scaling on held-out data before being read as probabilities. The "Kev-like" design follows [Kev](https://github.com/jaredpalmer/kev) by Jared Palmer (open-source family of "System One" decision models: a small LoRA adapter plus a pointer head on a Qwen base, [weights on Hugging Face](https://huggingface.co/collections/jaredpalmer/kev), Apache-2.0), which in turn is described as Jev-like; see [Related work](#related-work-and-credit). > **Status:** single training run, single seed. Confidence scores are **raw (not temperature-scaled)** for this checkpoint. Numbers are not directly comparable with published Mind2Web numbers (see [Evaluation protocol](#evaluation-protocol)). ## Summary of results Element accuracy on Multimodal-Mind2Web test splits (`n` = steps; 95% bootstrap CI). A step counts as correct if the top-1 candidate is a ground-truth element. A "none" prediction counts as an error. | Split | n | Accuracy (CI95) | Accuracy if the answer is in the list | Filter ceiling | ECE (raw) | AUROC of confidence | Acc. on most confident 20% | |---|---|---|---|---|---|---|---| | test_task | 1339 | **0.465** [0.439, 0.493] | 0.556 | 0.837 | 0.189 | 0.710 | 0.761 | | test_website | 1019 | **0.384** [0.355, 0.413] | 0.483 | 0.795 | 0.189 | 0.698 | 0.662 | | test_domain | 4060 | **0.385** [0.370, 0.400] | 0.456 | 0.845 | 0.199 | 0.737 | 0.703 | "Filter ceiling" is the fraction of steps in which our rule-based candidate filter keeps a correct element at all (see below). Nobody can score above it with this candidate list. Validation (579 steps carved from the training websites): accuracy 0.368 [0.326, 0.408]. Progression across our own runs (same candidate filter, same splits): | Run | test_task | test_website | test_domain | |---|---|---|---| | First text-only run, LoRA r16 attention | 0.375 | 0.275 | 0.308 | | + full-page screenshot, LoRA r16 attention, 24-token candidate cap | 0.416 | 0.317 | 0.351 | | **This model**: screenshot, LoRA r32 attention+MLP, tree-format candidates, gold candidate always present in training | **0.465** | **0.384** | **0.385** | Risk-coverage (accuracy if the model only answers its most confident x% of steps; raw confidences): | Split | 100% | 80% | 60% | 40% | 20% | |---|---|---|---|---|---| | test_task | 0.465 | 0.515 | 0.583 | 0.660 | 0.761 | | test_website | 0.384 | 0.426 | 0.471 | 0.574 | 0.662 | | test_domain | 0.385 | 0.445 | 0.513 | 0.591 | 0.703 | Other metrics (test_task / test_website / test_domain): operation-type accuracy 0.881 / 0.866 / 0.864; Brier 0.256 / 0.249 / 0.240; fraction of steps where the model answers "none" 0.120 / 0.119 / 0.092; "none" predicted when no correct element is in the list (abstention success) 0.367 / 0.373 / 0.237. **Take-aways** 1. The screenshot helps, and the gain is driven by the pixels. In an ablation on the earlier vision run (not repeated for this checkpoint), replacing the screenshot with a gray image or another page removed the gain (paired CI of the gain over the text-only model: +3.2 to +5.4 points). 2. The confidence score carries information: accuracy rises from 0.38-0.47 on all steps to 0.66-0.76 on the most confident 20%. This is the main reason to use this model (selective prediction, routing hard cases to a stronger model), not its raw accuracy. 3. Raw confidences are over-confident (ECE about 0.19-0.20). On the earlier vision model temperature scaling fitted on validation reduced ECE to roughly 0.05-0.09; **we have not measured this for this checkpoint**. Fit a temperature on your own held-out data before using the numbers as probabilities. 4. Absolute accuracy is modest. About 15-20% of steps lose the correct element in our candidate filter, and even when the correct element is in the list the model finds it only 46-56% of the time. ## Intended use - Research on small, fast GUI/web element grounding with calibrated abstention. - A cheap first-pass element selector whose low-confidence steps are escalated to a larger model or a human (cascade/routing experiments). - A baseline and a set of documented negative results for pointer-style heads on top of a small VLM. ## Model details **Architecture.** The full Gemma 4 E2B model (35 layers, hidden size 1536) runs on the whole sequence; we read the hidden states of **layer 30** and attach: - a **query** from the last token (LayerNorm -> linear, d_k = 256), - one **key per candidate** from the mean of the candidate's token hidden states (LayerNorm -> linear), - a learned **"none" key**, so the softmax is over `n_candidates + 1` slots, - an **operation head** (linear, 3 classes: CLICK / TYPE / SELECT) on the query. LoRA is applied to layers 0-29 (q/k/v/o and gate/up/down projections where they exist; the last 20 layers of Gemma 4 E2B share KV and have no k/v projections), rank 32, alpha 64, dropout 0.05. The vision tower and the language model weights are frozen. Hidden states of layers 30-34 are not used by the head (they are still computed in the forward pass; truncating the model at layer 30 would be an easy speed-up we did not implement). **Input.** `[BOS] [screenshot strips] Task: ... Previous actions: ... Candidates: - - ... Task: ... Previous actions: ... Next element to interact with:` - *Screenshot*: the full-page screenshot is cut top-to-bottom into 1280x1280 strips (a trailing piece under 200 px is merged), at most 5 strips (6400 px), 280 vision tokens per strip. About 19% of Mind2Web pages are taller than that and are truncated at the bottom. No target-dependent cropping is used (it would leak the answer). - *Candidates*: text only, in "tree" format: `role "accessible-ish name" [state]`, for example `textbox "Where from?"`, `link "Flights"`, `button "Search"`. At most 64 tokens per candidate and 4600 tokens in total per step (candidate lines are shortened uniformly when a step is too long). **The model is not given element positions**, so it must match candidate text to what it sees in the screenshot. - *Candidate list*: Multimodal-Mind2Web provides 331-743 candidates per step. We order them by TF-IDF similarity to the task and recent actions, then apply a rule filter (visible, interactive tags first, then text-bearing common tags) and keep at most K = 160. **Loss.** Multi-positive softmax cross-entropy over candidates plus "none" (target is "none" if no correct candidate is in the list), plus 0.3 x cross-entropy for the operation type. ## Training | | | |---|---| | Data | Multimodal-Mind2Web `train` (7775 steps): 7196 for training, 579 for validation (validation = websites whose `crc32(website) % 8 == 0`) | | Candidate handling in training | rule filter K = 160, then the dropped correct candidate is **added back** to the list (`--always_pos`). Validation and test lists are never modified | | Epochs | 4 run, **checkpoint of epoch index 2 (third epoch) kept** (best validation accuracy: 0.249 / 0.363 / **0.368** / 0.358; ECE rose 0.119 -> 0.164 -> 0.260 -> 0.362, i.e. over-fitting in the last epoch) | | Optimiser | AdamW, LoRA lr 2e-4, head lr 1e-3, cosine schedule, 3% warm-up, gradient clipping 1.0, micro-batch 1 with accumulation 8, bf16 | | Candidate order | random permutation in training; original TF-IDF order at test time | | Hardware / time | 1x A100-SXM4-40GB, 29,604 s for 4 epochs (about 1.03 s per example), peak memory 38.6 GB | | Skipped | 4 training steps skipped for out-of-memory (inputs of about 13.8k tokens); 11 steps without a screenshot | | Seeds | one (seed 0) | | Base model revision | `google/gemma-4-E2B` @ `d29ff6b45f081a49ee2733a859c9c9c2d95d1a6f` | Before this run we swept LoRA capacity, learning rate, candidate text format, and the query layer on a 1500-example, 2-epoch text-only setup (val 579 steps, single seed): rank-32 attention+MLP was the only clear winner (about +6.6 points on validation over rank-16 attention-only); rank 64, lr 1e-4 and 4e-4, and query layer 35 were not better; the tree format was as accurate as the long attribute format and shorter; a 24-token candidate cap did not measurably hurt in the short regime. These differences are from one seed and a small validation set, treat them as hints. ## Evaluation protocol - Splits: the official Multimodal-Mind2Web `test_task`, `test_website`, `test_domain`. - Metric: top-1 element accuracy over **our** candidate list (K = 160, rule filter). This is **not** the official candidate list (the Mind2Web paper uses a DeBERTa ranker's top-50), and steps with no correct element in the list count as errors. Our numbers must not be compared with published element accuracy without this caveat; we make no claim of parity or superiority with any published system. - "Accuracy if the answer is in the list" is conditional on the correct element being among the candidates and is **higher by construction**; it should not be compared with unconditional numbers. - ECE uses 15 equal-width bins on the top-1 probability. AUROC measures how well the top-1 probability separates correct from incorrect steps. - Bootstrap confidence intervals are over steps. Several steps come from the same task or website, so the true uncertainty is somewhat larger than the CIs suggest. ## A stress test outside the training distribution: live form filling (negative result) We ran the model in a real browser (Playwright) on 12 synthetic forms and, when reachable, 5 public practice pages (no submit buttons were pressed). One step per field; the field label and value come from the task sentence; the model only picks the element. We compare two candidate styles: **as in the dataset** (raw attributes, no `