Chrome MV3 extension that detects AI-generated images 100% on-device (WebGPU/WASM). 89.2% balanced accuracy @0.65 on a 5-source benchmark. MIT.
Python
0
6 commits
updated Aug 14, 2026
A Manifest V3 Chrome extension that detects AI-generated images with all inference running on-device (WebGPU, WASM fallback). No cloud, no APIs, no local server — no image data ever leaves the browser.
Built for the poidh "local AI challenge" bounty: ≥75% balanced accuracy at a fixed 0.65 confidence threshold, evaluated offline.
Live on x.com and grok.com — red pill = judged AI at ≥65% confidence, small chip = score below threshold, blue "graphic" chip = charts/screenshots where a photo detector doesn't meaningfully apply:
![]() | ![]() |


89.5% pooled balanced accuracy @ threshold 0.65 on a 2,500-image evaluation that was deliberately built to be hard (details in eval/RESULTS.md):
Per-generator recall at the fixed 0.65 threshold (shipped model, held-out images):
| Generator | Recall | Generator | Recall |
|---|---|---|---|
| illustrious | 100% | z-image-turbo | 90% |
| wan-video-2.5 | 100% | veo-3 | 84% |
| gpt-image-2 | 100% | gpt-image-1.5 | 82% |
| sora-2 | 91% | flux-2-klein | 80% |
| lumina-17 | 92% | midjourney-7 | 80% |
| recraft-v3 / seedream-v5 | 88–89% | ideogram-2 / nano-banana* | 67–71% |
False-positive rate on real photos, stock head vs shipped re-fit head:
| Real source | Stock head | Shipped |
|---|---|---|
| Pascal VOC 2012 | 1.5% | 0.0% |
| Pre-2022 memes | 8.8% | 5.0% |
| COCO val | 7.5% | 8.5% |
| OpenFake reals | 13.0% | 6.5% |
| Wikimedia Commons quality | 28.3% | 11.1% |
| Unsplash | 42.6% | 13.7% |
* 6–7 eval images each — small-sample numbers.
Full methodology, ablations (graphic gate: −0.06pp on the benchmark), and every intermediate measurement: eval/RESULTS.md. This is our own proxy benchmark — built from sources disjoint from training and scored by eval/harness.py, reproducible end-to-end — not the bounty's private benchmark.
Community Forensics ViT-S/16 @384 (MIT-licensed weights; Park & Owens, CVPR 2025, trained on 4,803 generators) with a re-fit classification head trained on frozen features to fix a measured blind spot: the stock head false-positives heavily on modern professional photography (42.6% FPR on Unsplash). The re-fit (weighted logistic regression, L2-regularized toward the original head, trained only on provably-real content: pre-2022 camera-EXIF Unsplash, Wikimedia Commons quality images, and pre-2022 memes) brings Unsplash to 13.7% and memes from 45.8% to 4.4%, while still raising fake recall over stock. A calibration offset (+1.67 logits) centers the optimal balanced-accuracy operating point exactly at the required 0.65 threshold.
Exported to ONNX (fp32, 87MB, committed in extension/models/detector.onnx) and
executed by ONNX Runtime Web — WebGPU when available, single-thread WASM otherwise.
Easiest — prebuilt release (no build tools needed): download the zip from
Releases, unzip it,
then chrome://extensions → Developer mode → Load unpacked → select the unzipped
local-ai-image-detector folder. Done — no Node, no Python, nothing else.
From source:
git clone <this repo>
cd ai-image-detector/extension
npm install # pinned onnxruntime-web 1.27
node build.mjs # vendors ORT runtime + wasm into lib/ort/ (no CDN at runtime)
Then: chrome://extensions → enable Developer mode → Load unpacked → select
the extension/ folder (the folder containing manifest.json). Click the toolbar
icon and switch Detection on. See INSTALL.md for details and
troubleshooting.
The model ships inside the repo — after git clone + npm install the extension is
fully offline; it performs no downloads at any point.
AI generated · 97%) at ≥65%, a small neutral chip (3%) below it. Hover for
details. (The all-scores chips can be toggled off in the popup.)<picture>/srcset, lazy-loaded feeds,
open shadow DOM, iframes, blob:/data: URLs, and strict-CSP sites (tags are styled
via CSSOM, which style-src cannot block). Language-independent: the pipeline reads
pixels and DOM structure, never page text (verified live on Japanese and Arabic
pages).content script (per page) background service worker offscreen document
───────────────────────── ───────────────────────── ──────────────────
discover images (img/bg/shadow/ route + in-memory URL cache fetch bytes (host-permission
iframe/blob), IntersectionObserver ensure offscreen doc CORS-exempt), SHA-256 hash
viewport-priority queue (1 at a session stats cache (storage.local),
time) → overlay score pills decode → 440/384 preprocess →
ONNX Runtime Web (WebGPU→WASM)
The shipped detector.onnx is deterministically rebuilt from public inputs:
pip install torch timm onnxruntime onnx datasets pillow numpy huggingface_hub
git clone https://github.com/JeongsooP/Community-Forensics vendor/Community-Forensics
cd eval
python export_features.py # backbone (HF: OwensLab/commfor-model-384, MIT) + original head
python bake_head.py --head models/head_384_refit_hi.npz --offset 1.67 # -> commfor_vits_384_refit.onnx
models/head_384_refit.npz (the 385-parameter re-fit head) is committed. To re-train
it from scratch instead: eval/build_proxy.py, build_trainpool.py, fetch_unsplash.py,
fetch_commons.py rebuild the datasets from public sources, then refit_head.py
re-fits and reports; harness.py scores any model on any real/fake image tree.
eval/RESULTS.md documents every measurement in this README.
OwensLab/commfor-model-384, MIT.Chrome MV3 extension that detects AI-generated images 100% on-device (WebGPU/WASM). 89.2% balanced accuracy @0.65 on a 5-source benchmark. MIT.
Python
0
6 commits
updated Aug 14, 2026
A Manifest V3 Chrome extension that detects AI-generated images with all inference running on-device (WebGPU, WASM fallback). No cloud, no APIs, no local server — no image data ever leaves the browser.
Built for the poidh "local AI challenge" bounty: ≥75% balanced accuracy at a fixed 0.65 confidence threshold, evaluated offline.
Live on x.com and grok.com — red pill = judged AI at ≥65% confidence, small chip = score below threshold, blue "graphic" chip = charts/screenshots where a photo detector doesn't meaningfully apply:
![]() | ![]() |


89.5% pooled balanced accuracy @ threshold 0.65 on a 2,500-image evaluation that was deliberately built to be hard (details in eval/RESULTS.md):
Per-generator recall at the fixed 0.65 threshold (shipped model, held-out images):
| Generator | Recall | Generator | Recall |
|---|---|---|---|
| illustrious | 100% | z-image-turbo | 90% |
| wan-video-2.5 | 100% | veo-3 | 84% |
| gpt-image-2 | 100% | gpt-image-1.5 | 82% |
| sora-2 | 91% | flux-2-klein | 80% |
| lumina-17 | 92% | midjourney-7 | 80% |
| recraft-v3 / seedream-v5 | 88–89% | ideogram-2 / nano-banana* | 67–71% |
False-positive rate on real photos, stock head vs shipped re-fit head:
| Real source | Stock head | Shipped |
|---|---|---|
| Pascal VOC 2012 | 1.5% | 0.0% |
| Pre-2022 memes | 8.8% | 5.0% |
| COCO val | 7.5% | 8.5% |
| OpenFake reals | 13.0% | 6.5% |
| Wikimedia Commons quality | 28.3% | 11.1% |
| Unsplash | 42.6% | 13.7% |
* 6–7 eval images each — small-sample numbers.
Full methodology, ablations (graphic gate: −0.06pp on the benchmark), and every intermediate measurement: eval/RESULTS.md. This is our own proxy benchmark — built from sources disjoint from training and scored by eval/harness.py, reproducible end-to-end — not the bounty's private benchmark.
Community Forensics ViT-S/16 @384 (MIT-licensed weights; Park & Owens, CVPR 2025, trained on 4,803 generators) with a re-fit classification head trained on frozen features to fix a measured blind spot: the stock head false-positives heavily on modern professional photography (42.6% FPR on Unsplash). The re-fit (weighted logistic regression, L2-regularized toward the original head, trained only on provably-real content: pre-2022 camera-EXIF Unsplash, Wikimedia Commons quality images, and pre-2022 memes) brings Unsplash to 13.7% and memes from 45.8% to 4.4%, while still raising fake recall over stock. A calibration offset (+1.67 logits) centers the optimal balanced-accuracy operating point exactly at the required 0.65 threshold.
Exported to ONNX (fp32, 87MB, committed in extension/models/detector.onnx) and
executed by ONNX Runtime Web — WebGPU when available, single-thread WASM otherwise.
Easiest — prebuilt release (no build tools needed): download the zip from
Releases, unzip it,
then chrome://extensions → Developer mode → Load unpacked → select the unzipped
local-ai-image-detector folder. Done — no Node, no Python, nothing else.
From source:
git clone <this repo>
cd ai-image-detector/extension
npm install # pinned onnxruntime-web 1.27
node build.mjs # vendors ORT runtime + wasm into lib/ort/ (no CDN at runtime)
Then: chrome://extensions → enable Developer mode → Load unpacked → select
the extension/ folder (the folder containing manifest.json). Click the toolbar
icon and switch Detection on. See INSTALL.md for details and
troubleshooting.
The model ships inside the repo — after git clone + npm install the extension is
fully offline; it performs no downloads at any point.
AI generated · 97%) at ≥65%, a small neutral chip (3%) below it. Hover for
details. (The all-scores chips can be toggled off in the popup.)<picture>/srcset, lazy-loaded feeds,
open shadow DOM, iframes, blob:/data: URLs, and strict-CSP sites (tags are styled
via CSSOM, which style-src cannot block). Language-independent: the pipeline reads
pixels and DOM structure, never page text (verified live on Japanese and Arabic
pages).content script (per page) background service worker offscreen document
───────────────────────── ───────────────────────── ──────────────────
discover images (img/bg/shadow/ route + in-memory URL cache fetch bytes (host-permission
iframe/blob), IntersectionObserver ensure offscreen doc CORS-exempt), SHA-256 hash
viewport-priority queue (1 at a session stats cache (storage.local),
time) → overlay score pills decode → 440/384 preprocess →
ONNX Runtime Web (WebGPU→WASM)
The shipped detector.onnx is deterministically rebuilt from public inputs:
pip install torch timm onnxruntime onnx datasets pillow numpy huggingface_hub
git clone https://github.com/JeongsooP/Community-Forensics vendor/Community-Forensics
cd eval
python export_features.py # backbone (HF: OwensLab/commfor-model-384, MIT) + original head
python bake_head.py --head models/head_384_refit_hi.npz --offset 1.67 # -> commfor_vits_384_refit.onnx
models/head_384_refit.npz (the 385-parameter re-fit head) is committed. To re-train
it from scratch instead: eval/build_proxy.py, build_trainpool.py, fetch_unsplash.py,
fetch_commons.py rebuild the datasets from public sources, then refit_head.py
re-fits and reports; harness.py scores any model on any real/fake image tree.
eval/RESULTS.md documents every measurement in this README.
OwensLab/commfor-model-384, MIT.