| # I-JEPA deepfake detectors (per generator) |
|
|
| Fine-tune **`facebook/ijepa_vith14_1k`** (ViT-H/14) as a binary **fake vs real** detector, **one model per generator**. |
|
|
| ## Protocol |
|
|
| For each trainable generator `G` ∈ |
| `ADM, BigGAN, Midjourney, VQDM, glide, wukong, stable_diffusion_v_1_4, stable_diffusion_v_1_5, imagenetv3`: |
|
|
| | Split | Fakes | Reals | |
| | --- | --- | --- | |
| | Train | `dataset/G/train/ai` | `dataset/train_nature` (shared) | |
| | Eval | every `dataset/*/val/ai` | matching `val/nature` or `val/real` | |
|
|
| - **Never train** on `flux2` or `drifting` (test-only / OOD). |
| - Labels: `0 = real`, `1 = fake`. |
| - A 10% train holdout is used only for in-run monitoring (not a GenImage holdout). |
|
|
| ## Dual-GPU launch (not DDP) |
|
|
| `run_all.py` starts **one process per GPU**. Each process: |
|
|
| 1. sets `CUDA_VISIBLE_DEVICES=<gpu>` |
| 2. trains + evaluates **one** detector |
| 3. shuts down DataLoader workers and frees CUDA |
| 4. pulls the next unfinished generator until the queue is empty |
|
|
| Training uses a **5% balanced holdout** from `train/ai` + `train_nature` (metric=`acc`, patience=4, checks every 1000 steps, max 1 epoch). Classes are balanced 50/50. |
|
|
| **`imagenetv3`-only extras** (other generators unchanged): |
| - no patience (full epoch) |
| - LR hypertune on a small split (`2k/class`, 800 steps, `1e-5…1e-4`) |
| - after training, pick **last-epoch vs best-holdout** on its own `val` split |
|
|
|
|
| ```bash |
| cd /home/themis/workspace_firas/appli/i-jepa |
| conda activate test # or any env with torch + transformers |
| pip install -r requirements.txt |
| |
| # full sweep on GPU 0 and GPU 1 |
| python run_all.py --gpus 0,1 |
| |
| # retrain ADM only (overwrite broken checkpoint) |
| python train.py --generator ADM --device cuda:0 --force |
| |
| # smoke test |
| python run_all.py --gpus 0,1 --limit-per-class 200 --epochs 1 |
| |
| # subset |
| python run_all.py --gpus 0,1 --generators ADM,BigGAN |
| ``` |
|
|
| Single-generator (one GPU): |
|
|
| ```bash |
| python train.py --generator ADM --device cuda:0 |
| ``` |
|
|
| ## Metrics |
|
|
| - **Accuracy**: argmax over 2-class logits |
| - **AUROC**: ranking score = **MSP** (`max` softmax probability), against labels `0=real`, `1=fake` |
|
|
| To recompute AUROC with MSP for already-trained detectors (rewrites `metrics.json` / CSVs): |
|
|
| ```bash |
| python recompute_auroc_msp.py --gpus 0,1 |
| # or single GPU: |
| python recompute_auroc_msp.py --device cuda:0 |
| ``` |
|
|
| ## Outputs |
|
|
| ```text |
| runs/<generator>/ |
| detector.pt |
| train_log.json |
| metrics.json |
| metrics.csv |
| runs/summary_auroc.csv |
| runs/summary_acc.csv |
| ``` |
|
|
| Resume-safe: |
| - If `runs/<gen>/detector.pt` exists → **training is skipped** |
| - If `runs/<gen>/metrics.json` also exists → **eval is skipped** (job fully done) |
| - If only the detector exists → eval-only resume |
| - Use `--force` to retrain + re-eval from scratch |
|
|
| ## Memory / workers |
|
|
| - Default `--batch-size 8` + `--amp bf16` for ViT-H. Raise batch if VRAM allows. |
| - `--num-workers 2` with `persistent_workers=False`; workers are shut down after every job. |
| - Optional `--freeze-backbone` for a linear probe (much lighter). |
|
|
| ## Layout |
|
|
| | File | Role | |
| | --- | --- | |
| | `config.py` | paths + hyperparameters | |
| | `data.py` | train/eval loaders | |
| | `model.py` | I-JEPA binary detector | |
| | `train.py` | train + cross-generator eval | |
| | `cleanup.py` | DataLoader / CUDA teardown | |
| | `run_all.py` | multi-GPU job queue | |
| | `upload_ijepa_hf.py` | upload this folder (code + `runs/`) to Hugging Face | |
|
|
| ### Upload to Hugging Face |
|
|
| ```bash |
| cd /home/themis/workspace_firas/appli/i-jepa |
| export HF_TOKEN=hf_... |
| python upload_ijepa_hf.py --repo-id fira7s/ijepa |
| # private / dataset / resumable workers: |
| python upload_ijepa_hf.py --repo-id fira7s/ijepa --private --num-workers 4 |
| ``` |
|
|