--- license: apache-2.0 language: - en base_model: - aliasrobotics/alias3-micro-1026 base_model_relation: finetune pipeline_tag: text-generation library_name: onnx tags: - cybersecurity - security - onnx - onnxruntime-genai - webgpu - browser - int4 - dual-system - decision-head - system-1 - system-2 - phishing - malware-detection --- # alias3-web **A cybersecurity transformer that runs in the browser.** It answers a typed security question in about 150 ms and writes an explanation on request, on the user's GPU through WebGPU. The page under test never leaves the machine.

alias3-web inside the Browser Immune System: a page is reduced to typed observations, the model answers one directed question per threat class, and explains a verdict on request

alias3-web is the model behind the **Browser Immune System (BIS)**, a browser extension that screens every page a user visits. Both are described in the paper *Browser Immune System (BIS): Innate and Adaptive Threat Detection in the Browser with a Cybersecurity Transformer* (Mayoral-Vilches and Worrel, 2026), where the model is called `alias-web`. The figure above is the paper's overview: the model sits in the centre lane. It serves two regimes from one loaded set of 4-bit weights: | Regime | What it does | Cost on a laptop GPU | |---|---|---| | **System 1** | One typed question, one forward pass, no token decoded: a probability per option. | 152 ms per question | | **System 2** | Ordinary text generation from the same weights, on request. | 10.5 tokens/s | > **Research artefact.** Released to make the paper reproducible. Read the limits below before relying on > its answers. ## What is in this repository | Path | What it is | |---|---| | `model/model.onnx`, `model/model.onnx.data` | The 4-bit graph for WebGPU (ONNX Runtime GenAI, 2,440,274,944 bytes of weights). It returns logits and the hidden states at requested positions. | | `model/tokenizer.json`, `model/tokenizer_config.json`, `model/chat_template.jinja`, `model/genai_config.json` | Tokenizer and runtime configuration. `model/tok/` and `model/heads/` hold copies where the runner looks for them. | | `heads/head.bin` | The complete pointer head (1.3 M parameters, fp16, 2,622,545 bytes): weights and biases of both projections. | | `heads/norm.bin` | The weight of the model's final RMSNorm (10,289 bytes). The graph exports hidden states before that norm and the head was trained after it. | | `aliasweb.mjs` | The library: the typed encoding, the norm, the head, and the calls `ask()` and `generate()`. | | `index.html`, `serve.py` | A demo page and a local server with HTTP Range support. | | `vendor/ct0.js`, `vendor/ct0-edge.LICENSE` | The prefill engine: the distribution of [ct0-edge](https://github.com/eduardoworrel/ct0-edge) by Eduardo Worrel (MIT), unchanged. | ## Quick start ```bash hf download aliasrobotics/alias3-web --local-dir alias3-web cd alias3-web && python3 serve.py 8924 # open http://127.0.0.1:8924 in Chrome or Edge and press "Load model" ``` The first load reads 2.44 GB from the local server and takes a few seconds. The demo page fetches its two runtime modules (ONNX Runtime Web 1.30.0 and Transformers.js 3.7.5) from a public CDN; the model, the material you paste and the answers stay on your machine. From your own page, with the same import map as `index.html`: ```js import { AliasWeb } from "./aliasweb.mjs"; const model = await AliasWeb.load({ base: "./" }); // System 1: a directed yes/no question about a piece of evidence const r = await model.ask({ kind: "noul", state: `const q = new URLSearchParams(location.search).get("q"); document.getElementById("out").innerHTML = "result: " + q;`, q: "Is user input written into the DOM without escaping?", }); console.log(r.p, r.ms); // 0.822, about 150 ms // System 2: an explanation, only when it is worth seconds const t = await model.generate({ state: "...the same evidence...", prompt: "You are a security reviewer. Name the vulnerability in this code and the fix, in 2-3 sentences.", maxNewTokens: 90, }); console.log(t.text, t.tokPerS); ``` ## The typed interface A decision is one causal sequence, ` s q o1 … oK `. The markers are not new vocabulary: they are five special tokens of the base tokenizer, and the library writes them by id. | Marker | Token | Id | Role | |---|---|---|---| | `` | `<\|fim_prefix\|>` | 248060 | opens the evidence | | `` | `<\|fim_middle\|>` | 248061 | opens the question | | `` | `<\|box_start\|>` | 248049 | opens an option | | `` | `<\|box_end\|>` | 248050 | closes an option: the key is read here | | `` | `<\|fim_suffix\|>` | 248062 | closes the row: the query is read here | The head scores option *i* as `q(h_decide) · k(h_opt_i) / (sqrt(256) · T)` on the normalised hidden states and a softmax over the options gives the probabilities. Text supplied by the caller is sanitised (a literal `<|name|>` becomes `<¦name¦>`), so that the evidence cannot forge an option boundary. | `kind` | Options | Returns | Status | |---|---|---|---| | `noul` | Yes, No | `p`, the probability of yes | the kind to use | | `choice` | your list | `choice`, `top` | answers in the categories of this checkpoint's training, see the limits | | `score` | 1 to 5 | `level`, `expected` | orders severity only weakly, see the limits | ## Measurements All on one Apple M3 Max laptop (128 GB) in Chrome with WebGPU, the weights served from the local server. | Quantity | Value | |---|---| | Model ready, second load in the same browser | 2.33 s | | System 1, per question on short code snippets | 152 ms mean of twelve (110 to 200 ms); the head itself takes 1.18 ms | | System 2 | 10.5 tokens/s, about 96 ms per token | | A generated answer against a decision on the same snippet | 6 to 39 times the cost | One directed yes/no question per snippet: | Snippet | Question | P(yes) | |---|---|---| | DOM XSS: `innerHTML` with a query parameter | Is user input written into the DOM without escaping? | **0.822** | | SQL injection: string concatenation in `db.query` | Does this code concatenate user input into a SQL query? | **1.000** | | Command injection: `exec("curl " + url)` | Does this code pass user input to a shell command? | **1.000** | | Path traversal: `sendFile("/var/data/" + f)` | Can user input escape the intended directory in this file path? | 0.428 | | Hard-coded secret: an API key in the source | Does this code contain a hardcoded secret? | **1.000** | | Safe: pure arithmetic | Is user input written into the DOM without escaping? | **0.000** | Before publication the files of this repository were loaded in Chrome for Testing 157 and asked the same six questions: every probability above was reproduced to the third decimal. A first load in a fresh browser profile took 2.5 to 4.0 s. The question is the lever. On the DOM XSS snippet the generic question "Does this code contain a security vulnerability?" returns 0.040 and the directed one 0.822: same head, same evidence. Ask one directed question per class. In BIS, a battery of seven such questions returned the expected page verdict on 7 of the 8 sites of the paper's benchmark, in 0.9 to 6.4 s per page, with identical verdicts across samples and across Chrome and Firefox. ## Limits - **WebGPU only.** The 4-bit graph has no CPU path. Measured in Chrome; Firefox Nightly with a window runs it 5.9 times slower; Safari and Windows are unmeasured. - **Text inside the evidence can move the answer.** In the paper's benchmark a comment that declared a script harmless took a miner detection from 1.00 to 0.00. Treat the state as untrusted input. - **Questions need calibration before they filter anything.** Two of the seven BIS questions, one about scripts loaded from another server and one about keystroke capture asked of a login form, answer yes on ordinary pages. - **`choice` and `score` speak the language of this checkpoint's training,** the context categories of capture-the-flag campaigns. Asked to pick among weakness classes, `choice` returns the same label for any injectable snippet, and `score` is not a calibrated severity. Use `noul`. - **System 2 needs a forced prefix.** The 4-bit checkpoint does not close its deliberation block on its own; `generate()` starts the answer after the closing marker. A directive prompt and a temperature of 0.3 avoid narrated pseudo-deliberation. - **Agreement with the full-precision weights was checked on one prompt,** where the 4-bit graph returned the same decision direction. How often the two precisions agree is not measured. - **One machine.** There is no measurement on a modest integrated GPU. ## Provenance - **Parent.** [alias3-micro](https://huggingface.co/aliasrobotics/alias3-micro-1026), a 4B cybersecurity transformer on a `Qwen3.5-4B` backbone (32 layers, hidden width 2560, a 248,320-token vocabulary), described in the first paper cited below. - **What alias3-web adds to the weights.** Two rank-16 adapters, fused: the parent's decision adapter, trained together with the pointer head, and a context-category sensor trained for two epochs on 12,576 replayed decision examples and 4,172 context-category examples, with the head frozen. - **The graph.** ONNX Runtime GenAI model builder 0.18 with `-p int4 -e webgpu` and `include_hidden_states=true exclude_mtp=true`, run on Linux x86_64, following the recipe of the edge study by Eduardo Worrel that this work reproduces and extends. - **Not included.** The fused full-precision checkpoint (8.4 GB) and the BIS extension are not part of this repository. ## License Apache-2.0 for the model files, the library, the demo page and the server, as for the parent model. The vendored runner in `vendor/` is MIT; its licence file is beside it. ## Citation ```bibtex @article{mayoralvilches2026bis, author = {Mayoral-Vilches, V{\'i}ctor and Worrel, Eduardo}, title = {Browser Immune System ({BIS}): Innate and Adaptive Threat Detection in the Browser with a Cybersecurity Transformer}, year = {2026} } @article{mayoralvilches2026transformer, author = {Mayoral-Vilches, V{\'i}ctor}, title = {{CT0}: Cybersecurity Transformer}, journal = {arXiv preprint arXiv:2610.16550}, year = {2026} } ```