Multi-modal AI-generated content detection: image, video, and audio. Benchmarks, training code (DINOv2, DINOv3, ReStraV, BreathNet), and evaluation pipeline for real vs. synthetic classification with calibration-aware metrics.
89
stars
11
commits
Python
primary language
Mar 13, 2026
updated
Multi-modal detection of real vs. AI-generated content across image, video, and audio. This repository contains benchmark tooling, model training code, and evaluation pipelines for binary classifiers that distinguish genuine media from synthetic or AI-manipulated content.
The project trains and evaluates detection models that answer: Is this image, video, or audio real (human-captured) or AI-generated? Use cases include content authentication, media safety, and research on generalization across diverse generators and datasets.
Models are scored with a combined metric that rewards both discrimination (correct real vs. fake) and calibration (reliable probabilities):
Additional reported metrics: accuracy, cross-entropy, per-dataset breakdowns, inference time (average and p95).
[batch, 2] (real, fake). The pipeline applies softmax for probabilities and computes all metrics.| Modality | Model / approach | Notes |
|---|---|---|
| Image | DINOv3 (ViT backbone) | Patch-level or CLS features + classification head; LoRA fine-tuning for better generalization. |
| Video | DINOv2 + temporal head (GenD-style) or ReStraV-style | GenD-style: DINOv2 ViT-L, LayerNorm-only tuning, temporal transformer + head. ReStraV-style: Frozen DINOv2, trajectory geometry (stepwise distances, curvature) → 21-D vector, small MLP only trained. Both output binary logits. |
| Audio | BreathNet | Audio-specific model for real vs. synthetic speech/audio. |
All models are exported as safetensors with a small wrapper (model_config.yaml, model.py, *.safetensors) so the same benchmark loader runs image, video, and audio.
forward)..npy) or compressed (.npy.zst) with optional local decode cache for fast training..pt); pipeline supports raw bytes or precomputed tensors.Datasets are defined in YAML (path, modality, media_type, format, sampling). The benchmark downloads and caches data, and supports dataset-balanced and weighted sampling for training.
Generalization vs. memorization
Head-only or heavy fine-tuning led to strong train/val accuracy but poor performance on unseen holdout datasets (especially unseen real domains). Mitigations: frozen or lightly tuned backbones (LayerNorm-only or LoRA), geometry-based temporal features (ReStraV), small classifiers, and training across many datasets and generators.
Calibration
The combined score heavily weights Brier, so overconfident wrong predictions are costly. We use Brier-aware loss (e.g. Focal CE + Brier), learnable temperature/bias (e.g. LogitCalibrator), and optional temperature sweep on a calibration set.
Balance on public benchmarks
Good performance on both public and (simulated or actual) holdout data is required. We use dataset-balanced sampling, focus on worst-performing datasets, and strict train/val and cross-dataset evaluation to avoid overfitting to a few sources.
| Path | Description |
|---|---|
external/gasbench | Benchmark package: dataset loading, preprocessing, metrics, CLI (gasbench run, gasbench download, etc.). |
alternative_models/ | Training and export code: dinov2 (video, GenD-style), restrav (video, ReStraV-style), and references for image (DINOv3) and audio (BreathNet). |
docs/ | Additional documentation (model spec, installation, dataset analysis). |
git clone <this-repo>
cd detection-tool
./install.sh
Optional: ./install.sh --no-system-deps to skip system dependencies if you only need the benchmark and Python env.
Activate the environment and run the benchmark with a model directory (must contain model_config.yaml, model.py, and *.safetensors):
source .venv/bin/activate
# Image
gasbench run --image-model ./path/to/image_model/ --debug
# Video
gasbench run --video-model ./path/to/video_model/ --debug
# Audio
gasbench run --audio-model ./path/to/audio_model/ --debug
# Full run (all datasets)
gasbench run --image-model ./path/to/image_model/ --full
Results are written to the configured results directory (e.g. JSON, parquet, summary).
From the ReStraV folder, using CSVs and a data root (e.g. mounted cloud storage):
cd alternative_models/restrav
python train_restrav.py \
--train-csv ../dinov2/train.csv \
--val-csv ../dinov2/val_eval.csv \
--data-root /mnt/your_data \
--output-dir checkpoints/restrav \
--epochs 10 --batch-size 32
See alternative_models/restrav/README.md and alternative_models/dinov2/README.md for full training and export instructions.
Each modality’s model is a directory (or zip of that directory) with:
model_config.yaml — Preprocessing (e.g. resize: [224, 224]), num_classes: 2, optional weights_file.model.py — Defines load_model(weights_path, num_classes=2) returning a torch.nn.Module; forward(x) returns logits [B, 2].*.safetensors — Weights loaded by load_model.Inputs from the pipeline are float32 in 0–255; the model must normalize inside forward. See external/gasbench/docs/Safetensors.md for the full specification and allowed imports.
alternative_models/restrav/.alternative_models/dinov2/.external/gasbench/, external/gasbench/docs/IMAGE_DATASETS_V11_V12_ANALYSIS.md.alternative_models/RESUME_TECH_SUMMARY.md.11 commits
Python
96.3%
Shell
2.5%
Multi-modal AI-generated content detection: image, video, and audio. Benchmarks, training code (DINOv2, DINOv3, ReStraV, BreathNet), and evaluation pipeline for real vs. synthetic classification with calibration-aware metrics.
89
stars
11
commits
Python
primary language
Mar 13, 2026
updated
Multi-modal detection of real vs. AI-generated content across image, video, and audio. This repository contains benchmark tooling, model training code, and evaluation pipelines for binary classifiers that distinguish genuine media from synthetic or AI-manipulated content.
The project trains and evaluates detection models that answer: Is this image, video, or audio real (human-captured) or AI-generated? Use cases include content authentication, media safety, and research on generalization across diverse generators and datasets.
Models are scored with a combined metric that rewards both discrimination (correct real vs. fake) and calibration (reliable probabilities):
Additional reported metrics: accuracy, cross-entropy, per-dataset breakdowns, inference time (average and p95).
[batch, 2] (real, fake). The pipeline applies softmax for probabilities and computes all metrics.| Modality | Model / approach | Notes |
|---|---|---|
| Image | DINOv3 (ViT backbone) | Patch-level or CLS features + classification head; LoRA fine-tuning for better generalization. |
| Video | DINOv2 + temporal head (GenD-style) or ReStraV-style | GenD-style: DINOv2 ViT-L, LayerNorm-only tuning, temporal transformer + head. ReStraV-style: Frozen DINOv2, trajectory geometry (stepwise distances, curvature) → 21-D vector, small MLP only trained. Both output binary logits. |
| Audio | BreathNet | Audio-specific model for real vs. synthetic speech/audio. |
All models are exported as safetensors with a small wrapper (model_config.yaml, model.py, *.safetensors) so the same benchmark loader runs image, video, and audio.
forward)..npy) or compressed (.npy.zst) with optional local decode cache for fast training..pt); pipeline supports raw bytes or precomputed tensors.Datasets are defined in YAML (path, modality, media_type, format, sampling). The benchmark downloads and caches data, and supports dataset-balanced and weighted sampling for training.
Generalization vs. memorization
Head-only or heavy fine-tuning led to strong train/val accuracy but poor performance on unseen holdout datasets (especially unseen real domains). Mitigations: frozen or lightly tuned backbones (LayerNorm-only or LoRA), geometry-based temporal features (ReStraV), small classifiers, and training across many datasets and generators.
Calibration
The combined score heavily weights Brier, so overconfident wrong predictions are costly. We use Brier-aware loss (e.g. Focal CE + Brier), learnable temperature/bias (e.g. LogitCalibrator), and optional temperature sweep on a calibration set.
Balance on public benchmarks
Good performance on both public and (simulated or actual) holdout data is required. We use dataset-balanced sampling, focus on worst-performing datasets, and strict train/val and cross-dataset evaluation to avoid overfitting to a few sources.
| Path | Description |
|---|---|
external/gasbench | Benchmark package: dataset loading, preprocessing, metrics, CLI (gasbench run, gasbench download, etc.). |
alternative_models/ | Training and export code: dinov2 (video, GenD-style), restrav (video, ReStraV-style), and references for image (DINOv3) and audio (BreathNet). |
docs/ | Additional documentation (model spec, installation, dataset analysis). |
git clone <this-repo>
cd detection-tool
./install.sh
Optional: ./install.sh --no-system-deps to skip system dependencies if you only need the benchmark and Python env.
Activate the environment and run the benchmark with a model directory (must contain model_config.yaml, model.py, and *.safetensors):
source .venv/bin/activate
# Image
gasbench run --image-model ./path/to/image_model/ --debug
# Video
gasbench run --video-model ./path/to/video_model/ --debug
# Audio
gasbench run --audio-model ./path/to/audio_model/ --debug
# Full run (all datasets)
gasbench run --image-model ./path/to/image_model/ --full
Results are written to the configured results directory (e.g. JSON, parquet, summary).
From the ReStraV folder, using CSVs and a data root (e.g. mounted cloud storage):
cd alternative_models/restrav
python train_restrav.py \
--train-csv ../dinov2/train.csv \
--val-csv ../dinov2/val_eval.csv \
--data-root /mnt/your_data \
--output-dir checkpoints/restrav \
--epochs 10 --batch-size 32
See alternative_models/restrav/README.md and alternative_models/dinov2/README.md for full training and export instructions.
Each modality’s model is a directory (or zip of that directory) with:
model_config.yaml — Preprocessing (e.g. resize: [224, 224]), num_classes: 2, optional weights_file.model.py — Defines load_model(weights_path, num_classes=2) returning a torch.nn.Module; forward(x) returns logits [B, 2].*.safetensors — Weights loaded by load_model.Inputs from the pipeline are float32 in 0–255; the model must normalize inside forward. See external/gasbench/docs/Safetensors.md for the full specification and allowed imports.
alternative_models/restrav/.alternative_models/dinov2/.external/gasbench/, external/gasbench/docs/IMAGE_DATASETS_V11_V12_ANALYSIS.md.alternative_models/RESUME_TECH_SUMMARY.md.11 commits
Python
96.3%
Shell
2.5%