File size: 5,729 Bytes
2e175db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
---
title: DeepFakeScanner
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0
short_description: AI-generated & manipulated image detection (v0.4.0)
---

# DeepFakeScanner

A commercial deepfake / AI-generated image detection service.

## What it is

A FastAPI web service that scans an uploaded image and returns a structured
verdict: `authentic`, `ai_generated`, `deepfake`, `edited`, or `uncertain` β€”
with per-class probabilities, per-detector signals, and a C2PA provenance
check.

## Live

| | URL |
|---|---|
| Frontend | https://veridicate.com |
| API | https://api.veridicate.com |
| Source (HF mirror) | https://huggingface.co/spaces/veridicate/scanner |

## Status

**Stage 2 deployed (`v0.3.0-stage2`).** The CLIP classifier head was
fine-tuned on a 100k commercially-licensed dataset (50k Open Images +
50k Flux.1-schnell) and is currently serving real predictions in
production.

In-distribution test-set metrics (10k held-out images):
- Accuracy: **98.44%**
- Precision (AI class): 98.25%, recall: 98.64%, F1: 98.44%

**Stage 3A wired + verified 2026-05-30 (`v0.4.0-stage3a`); ships to
production on merge of `feat/akila-20260515 β†’ main`.** Multi-generator
dataset built: 50k Flux + 20k SDXL + 20k SD 3.5 Medium + 10k AuraFlow
on the AI side, matched authentic from Open Images V7. SDXL held out of
training so the heldout split is a true generalisation test. The trained
head (`head_v3a.pt`) is published to the private HF Hub repo, the runtime
config now defaults to it (`config.py`), and a filtered, test-gated
GitHub Action deploys the inference service on merge. Headline verified
numbers vs the Stage 2 baseline:

| Split | Baseline | Candidate | Ξ” |
|---|---|---|---|
| heldout SDXL (UNSEEN in training) | 83.93% | **89.48%** | **+5.55 pp** |
| test (in-distribution) | 96.47% | 98.43% | +1.96 pp |
| test_augmented (robustness) | 93.96% | 98.41% | +4.46 pp |

The +5.55 pp on the SDXL holdout is the load-bearing number β€” SDXL was
held entirely out of training, so it's the closest available proxy for
how the model will behave on generators it never saw. The
family-fingerprint approach (train on a diverse mix of open
generators, inherit coverage of closed generators) is validated.
Detailed audit trail in
[`docs/stage3a-implementation.md`](docs/stage3a-implementation.md).

**Known limitation (until the Stage 3A merge deploys):** the live
model is still the Stage 2 head, trained on Flux.1-schnell only. Other
generators (Gemini/Imagen 3, DALL-E 3, Midjourney, Grok, Stable
Diffusion) are out-of-distribution for the *currently-live* model and
it often returns `uncertain` verdicts. The Stage 3A head (queued to
ship) closes most of this gap. Rollback is a one-line env override
(`MODEL_VERSION` + `HEAD_CHECKPOINT_HF_FILENAME`) β€” both heads live in
the same private HF Hub repo.

## Roadmap at a glance

| Stage | What it delivers | Status |
|---|---|---|
| **1** | Working website, API, deploy pipeline. Detector returns random guesses. | βœ… Done |
| **2** | A trained classifier β€” 98% accurate on Flux-family AI images. | βœ… Done, live (`v0.3.0-stage2`) |
| **3A** | Broad coverage across the AI image-generation landscape β€” CLIP head retrained on Flux + SDXL + SD 3.5 + AuraFlow. | βœ… Wired + verified 2026-05-30 (`v0.4.0-stage3a`); ships on merge to `main` |
| **3B** | Frequency-artifact detector (FFT/DCT, generator-agnostic) brought online. | πŸ”­ Queued after Stage 3A ships |
| **4** | Production scale: faster hosting, paid tier, user accounts. | ⏸️ After Stage 3 |
| **5** | Enterprise capability: licensed paid-API training data, face-swap detection, adversarial robustness. | πŸ”­ Future |

Full roadmap with per-stage strengths, weaknesses, and how each
weakness gets fixed: [`docs/plan.md`](docs/plan.md). Plain-English
summary up front; technical detail below; glossary at the end for
non-technical readers.

## Quick start

```bash
# CPU PyTorch first (lean install)
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements.txt
pip install -e .

# Pre-download CLIP weights
python scripts/download_weights.py

# Run the server
uvicorn deepfake_scanner.api.v1:app --reload --port 7860
```

Then:

```bash
curl -F "file=@some_image.jpg" http://localhost:7860/v1/scan/image | jq
```

Or against the live API:

```bash
curl -F "file=@some_image.jpg" https://api.veridicate.com/v1/scan/image | jq
```

Dataset-generation dependencies are documented in the optional GPU section of
[`requirements.txt`](requirements.txt). Keep those packages out of the
production inference image.

## API

- `GET  /health` β€” liveness probe
- `GET  /v1/info` β€” model + config metadata
- `POST /v1/scan/image` β€” scan an image (multipart/form-data, max 10 MB,
  JPEG/PNG/WebP)

See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the full response schema.

## Privacy

Visitor uploads are processed in-memory and **never persisted**. Only scan
metadata (verdict, confidence, latency, model version) is recorded.

## Documentation

- [`docs/plan.md`](docs/plan.md) β€” **product roadmap** with per-stage
  strengths, weaknesses, and fix paths. Written so a non-technical
  reader can follow the strategy, with deeper technical detail and a
  glossary inline.
- [`ARCHITECTURE.md`](ARCHITECTURE.md) β€” technical design of the
  detection pipeline + API contract
- [`docs/decisions.md`](docs/decisions.md) β€” running decision log
  (good context if picking up this project later)
- [`NOTICES.md`](NOTICES.md) β€” third-party licensing record
- [`CLAUDE.md`](CLAUDE.md) β€” project context (auto-loaded by Claude Code)
- [`scripts/dataset/README.md`](scripts/dataset/README.md) β€” dataset curation pipeline

## License

Apache 2.0.