cd /news/ai-tools/show-hn-folate-local-dom-selector-mo… · home › topics › ai-tools › article
[ARTICLE · art-170041] src=github.com ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

Show HN: Folate – Local DOM selector model that beats 7B VLMs at 1/60th the size

A developer released Folate, an Apache 2.0-licensed DOM element ranker fine-tuned from google/electra-base-discriminator on the osunlp/Mind2Web dataset and quantized to INT8 ONNX at roughly 107 MB, which the author says beats 7B vision-language models at 1/60th the size for browser automation. Folate runs on CPU via onnxruntime and tokenizers with no PyTorch or transformers at inference, using about 180–250 MB of RAM, and scores (natural-language query, serialized DOM element) pairs in a single batched forward pass to return CSS/XPath selectors that are guaranteed to exist on the live page. The package is installable via pip and ships Playwright examples for grounding elements on google.com, amazon.com and github.com.

read6 min views1 publishedNov 15, 2026
Show HN: Folate – Local DOM selector model that beats 7B VLMs at 1/60th the size
Image: Michielbdejong (auto-discovered)

PyPI • Hugging Face • Demo • Apache 2.0

A lightweight, CPU-efficient neural DOM element ranker built for browser automation within tight memory constraints (<2 GB total footprint alongside a headless browser).

Fine-tuned from google/electra-base-discriminator on osunlp/Mind2Web and dynamically quantized to INT8 ONNX (~107 MB), Folate runs purely via onnxruntime and tokenizers—requiring no PyTorch or transformers at inference time.

Folate operates as a discriminative cross-encoder that scores (natural_language_query, serialized_dom_element) pairs in a single batched forward pass on CPU.

Variant / Artifact Backbone Precision / Format Disk Size Runtime RAM
folate-int8 (Default) google/electra-base-discriminator Dynamic QUInt8 ONNX ~107 MB ~180–250 MB
folate-base google/electra-base-discriminator float32 Safetensors ~418 MB ~1.4+ GB (PyTorch)
  • Zero-Hallucination Selector Grounding — Ranks real interactive DOM nodes extracted vialxml XPath (<a> ,<button> ,<input> ,<select> ,<textarea> , ARIA interactive roles, andonclick /tabindex elements), guaranteeing every returned CSS/XPath selector exists on the live page.
  • Compact Structured Serialization — Serializes each element into a concise96 -token representation:[TAG] ... [ID/NAME/TYPE/ROLE/ARIA-LABEL/PLACEHOLDER/TITLE/ALT/HREF/DATA-TESTID] ... [TEXT] ... [PARENT] ...
  • Edge & Low-Memory Deployment — Designed to run alongside Chromium on resource-constrained laptops and containers without GPU acceleration.
pip install folate

Or install from source:

git clone https://github.com/figranium/folate
cd folate
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

To run the live browser examples with Playwright:

python -m pip install -r examples/requirements.txt
python -m playwright install chromium

FolateSelectorFinder automatically downloads and caches figranium/folate on first run (or loads ./folate-int8 if present locally):

from folate import FolateSelectorFinder

finder = FolateSelectorFinder()
matches = finder.rank("click Search Flights button", html_source, top_k=3)

for match in matches:
    print(f"{match['score']:.4f} | {match['selector']} | {match['element']}")

To load weights from a custom local directory:

finder = FolateSelectorFinder(model_dir="./folate-int8")

If you want to pre-fetch the quantized model weights via huggingface_hub:

hf download figranium/folate --local-dir ./folate-int8
folate/
├── folate/
│   ├── __init__.py
│   └── ranker.py                  # Lightweight CPU inference engine & DOM serializer
├── scripts/
│   ├── prepare_data.py            # Streaming Mind2Web serializer (lxml)
│   ├── train.py                   # Fine-tuning script (bf16/fp16/CPU)
│   ├── export_onnx.py             # FP32 ONNX export + INT8 dynamic quantization
│   ├── eval_mind2web.py           # Official Mind2Web evaluator (Precision/Recall/F1, Top-1/3/5 & MRR)
│   └── eval_precision.py          # Playwright DOM-resolved selector Precision & Recall benchmark
├── examples/
│   ├── test_google.py             # Live Playwright search box grounding on google.com
│   ├── test_amazon.py             # E-commerce element ranking on amazon.com (+ offline snapshot)
│   ├── test_github.py             # Repository navigation grounding on github.com
│   └── requirements.txt           # Optional Playwright dependency for live browser tests
├── requirements.txt               # Lightweight CPU runtime dependencies
├── requirements-train.txt         # Training & ONNX export dependencies
└── LICENSE

Folate is evaluated on the three standard generalization splits of Mind2Web (test_task, test_website, and test_domain) across 6,037 action steps on real-world webpages.

Split Description Steps Avg Candidates Top-1 Top-3 Top-5 MRR Avg Latency (2 vCPU)
test_task Unseen tasks on seen websites 1,256 50.0 93.31% 97.61% 98.33% 0.9566 2,309.9 ms/step
test_website Completely unseen websites 955 50.0 88.90% 95.92% 96.65% 0.9274 4,328.2 ms/step
test_domain Unseen domains & verticals 3,826 49.8 92.08% 97.28% 98.61% 0.9491 2,431.0 ms/step
  • Task Formulation: At each step, the model receives the natural-language task instruction, action history context, and up to50 candidate DOM elements (Avg Candidates ≈ 50.0 ) extracted from the page snapshot, and outputs a relevance logit per candidate.
  • Metrics: - Top-1 / Top-3 / Top-5: Percentage of steps where a ground-truth target node (pos_candidates ) appears within the topk ranked elements.
    • Precision / Recall / F1: Selective Top-1 precision (TP / (TP + FP) ) and recall (TP / Total ) across confidence probability thresholds (--confidence-threshold ,--thresholds ), plus candidate-level binary precision/recall.
    • MRR (Mean Reciprocal Rank): Average reciprocal rank for the highest-ranked ground-truth element across all evaluated steps.
  • Hardware & Runtime: Latency is measured end-to-end per step on2 vCPUs withno GPU acceleration , using the exported INT8 quantized ONNX artifact (onnxruntime ). Variance betweentest_website (4,328.2 ms/step ) andtest_domain (2,431.0 ms/step ) reflects longer tokenized DOM attribute sequences on unseen site templates rather than candidate count.

For context against a fast, cost-efficient frontier LLM, GPT-6 Luna (via OpenAI's Decisions API) scores 81.8% on Mind2Web Multimodal (Google Gemini Decision 1 evaluation, Nov 2026) and 81.2% on Mind2Web in the Decision Index Vision suite (Nace.AI, Nov 2026), with ~326 ms median cloud API latency and ~$0.10 per 1,000 decisions (or $0.10 / $0.50 per 1M input/output tokens in standard API usage).

Model Type Mind2Web Accuracy Deployment & Runtime Cost
Folate (folate-int8) Specialized DOM Cross-Encoder (~107 MB) 88.90% – 93.31% Top-1 (91.83% overall across 6,037 steps) 100% local CPU ( onnxruntime , 180–250 MB RAM) $0 (self-hosted)
GPT-6 Luna Frontier LLM (Decisions API) 81.2% – 81.8% (Mind2Web Multimodal / Vision) Cloud API (~326 ms median latency) ~$0.10 / 1k decisions

Note: Folate is evaluated on text-based Mind2Web DOM candidates (50 candidates/step), whereas GPT-6 Luna's 81.2%–81.8% scores are on multimodal/screenshot-based Mind2Web action selection. While GPT-6 Luna is a general-purpose frontier model capable of broad reasoning and multi-step planning, Folate's task-specific ELECTRA cross-encoder achieves higher single-step DOM element grounding accuracy locally on CPU with zero API cost, zero network dependency, and zero selector hallucination.

Run any of the included live browser examples from the repository root:

python examples/test_google.py
python examples/test_amazon.py --offline
python examples/test_github.py

To reproduce data preparation, fine-tuning, INT8 ONNX export, and evaluation from scratch on osunlp/Mind2Web:

python -m pip install -r requirements-train.txt

python scripts/prepare_data.py --output-dir ./data

python scripts/train.py --data-dir ./data --save-dir ./folate-base

python scripts/export_onnx.py --model-dir ./folate-base --output-dir ./folate-int8

python scripts/eval_mind2web.py --confidence-threshold 0.5 --json-out mind2web_results.json

python scripts/eval_precision.py --confidence-threshold 0.5 --json-out precision_results.json
  • Intended Use: Single-step natural-language UI element grounding (click ,type ,select ,hover ) in local browser automation pipelines where RAM and CPU budgets are constrained.
  • Limitations: - No Multi-Step Planning: Folate ranks candidate elements for a single action query; it does not plan multi-step workflows or parse unstructured page content.
    • Local DOM Context Only: Elements are serialized using their own attributes, inner text, and immediate[PARENT] tag—identical sibling elements without distinguishing attributes or text cannot be disambiguated visually.

Folate is released under the Apache 2.0 License.

── more in #ai-tools 4 stories · sorted by recency
── more on @folate 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-folate-local…] indexed:0 read:6min 2026-11-15 · —