wikillm

Paper · 2025-08-08 · cs.CV

Deepfake Detection that Generalizes Across Benchmarks

GenD tunes only the LayerNorm parameters and a linear head of a frozen ViT-L encoder (CLIP, PE core L or DINOv3). The CLS feature is L2-normalised and trained with cross-entropy plus alignment and uniformity losses. Trained on FF++, it averages 91.2 to 91.6 video AUROC over 14 test sets, against 88.4 and 88.5 for ForAda and Effort (author-reported).

Image manipulation detectionParameter-efficient fine-tuningMetric learningDomain generalizationdeepfake-detectionface-forgeryclipvision-transformercross-dataset-generalizationparameter-efficient-fine-tuning

arXivPDFCodeMarkdown17 min read

AI-compiled by claude-haiku-5-5 on 2026-11-08, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Detectors that spot face-swap fakes often work well on the kind of fake they were trained on and poorly on a new way of making fakes. GenD starts from a large general-purpose image model that already sees images well. Three such models are tried: CLIP, Meta's Perception Encoder and DINOv3. Only a small part of the model is retrained: the layer-normalisation settings, plus a simple linear classifier on top.

Before classification, each image's feature vector is scaled to unit length, so every feature sits on the surface of a sphere. Two extra loss terms shape that sphere. One pulls features of the same class together. The other spreads all features evenly over the surface, so they do not bunch up.

The authors report that this beats more complex recent detectors on 14 public benchmarks from 2019 to 2025, after training on one older dataset. They also find that training fakes should be paired with the real video each was made from, and that training only on the newest fakes does not guarantee good generalisation.

TL;DR

GenD adapts a frozen ViT-L image encoder by training only its LayerNorm parameters and a 1024-to-2 linear classifier. The feature is the L2-normalised classification token, trained with cross-entropy plus an alignment loss and a uniformity loss. Frames are averaged per video. Trained on FaceForensics++ c23 and tested on 14 cross-dataset benchmarks, the authors report a mean video AUROC of 91.2 to 91.6 across the three backbones, against 88.4 and 88.5 for ForAda and Effort. All results are author-reported; the competitors were rerun by the authors with their official weights.

Problem

A deepfake detector trained on one manipulation method often fails on a new method §1. Large pretrained encoders are a plausible starting point. Many recent detectors add architectural complexity or temporal and audio modelling §1 §4.2, and fine-tuning the whole backbone is reported to overfit and generalise poorly §4.3. The paper assumes labelled real and fake face videos for training, a foundation image encoder, and benchmarks with video-level labels §3.2 §4.1.

Method

The model is one image encoder, a feature step and a linear head fig. 1. The encoder is one of three ViT-L models: CLIP ViT-L/14 (OpenAI), PE core L (Meta) or DINOv3 ViT-L/16 (Meta). The paper keeps the 1024-dimensional classification token and discards the rest §3.1.

The trainable parameters are the weights and bias of the linear layer (1024 by 2) and all LayerNorm blocks of the encoder. The rest of the encoder is frozen. The paper says these trainable parameters are about 0.03 percent of the total §3.1. The number is stated, not checked here.

The feature is L2-normalised, and the linear classifier reads the normalised feature. The uniformity and alignment losses also act on the normalised feature §3.1 fig. 1.

The loss is cross-entropy on the real and fake logits, plus alpha times an alignment term and beta times a uniformity term eq. 1. The alignment term is the mean squared distance between normalised features of same-label pairs eq. 2. The uniformity term is the log of the mean of exp(-2 times squared distance) over pairs of features drawn from the data eq. 3. For CLIP the paper sets alpha to 0.1 and beta to 0.5, tuned on the validation set §3.1.

Training uses Adam with betas 0.9 and 0.999, no weight decay, bfloat16 weights, batch size 128 and a cyclic cosine learning-rate schedule with one-epoch warm-up per 10-epoch cycle §3.1. The precise schedule and the code's values differ; see Paper vs code.

Video-level prediction takes 32 frames per video, computes the softmax per frame and averages the probabilities §3.1.

Pseudocode
# GenD training step  [§3.1] [eq. 1]
# Input:  images (B, 3, 224, 224); labels (B,) with 0 real, 1 fake
# Output: scalar loss

def training_step(images, labels):
    # Frozen ViT-L encoder; only its LayerNorm parameters train  [§3.1]
    # The 1024-d classification token is the feature  [§3.1]
    tokens = encoder(images)                     # (B, 1024)

    # Scale each feature to unit length: it lies on a hypersphere  [§3.1]
    embeddings = tokens / norm(tokens, dim=1)    # (B, 1024)

    # Linear classifier on the normalised feature  [§3.1]
    logits = linear(embeddings)                  # (B, 2)

    # Cross-entropy on real and fake logits  [§3.1] [eq. 1]
    loss = cross_entropy(logits, labels)

    # Alignment term, weight alpha = 0.1 for CLIP  [eq. 2]
    loss = loss + 0.1 * alignment(embeddings, labels)

    # Uniformity term, weight beta = 0.5 for CLIP  [eq. 3]
    loss = loss + 0.5 * uniformity(embeddings)
    return loss
Pseudocode
# Alignment over same-label pairs in the batch  [eq. 2]
# The paper leaves the pair set P+ undefined. The code uses all
# equal-label pairs inside the mini-batch
# [code: src/losses/unifalign.py#L4-L43]

def alignment(embeddings, labels):
    # Positive pairs: two different samples with the same label
    pairs = same_label_pairs(labels)
    # Mean squared Euclidean distance over those pairs
    return mean(squared_distance(embeddings, pairs))
Pseudocode
# Uniformity over sample pairs in the batch  [eq. 3]
# The code uses unordered pairs i < j and clamps the mean at 1e-6
# [code: src/losses/unifalign.py#L46-L63]

def uniformity(embeddings, t=2.0):
    # Squared distance for each unordered pair in the batch
    sq_dists = pairwise_squared_distances(embeddings)
    # Mean of exp(-t * d^2), then log
    kernel = mean(exp(-t * sq_dists))
    return log(max(kernel, 1e-6))
Pseudocode
# Video-level fake score  [§3.1] [code: src/model/base.py#L61-L83]
# Input: 32 aligned face crops of one video  [§3.2]

def video_fake_score(frames):
    # One logit pair per frame  [§3.1]
    logits = model(frames)                       # (32, 2)
    # Softmax per frame, then the mean over frames  [§3.1]
    probs = softmax(logits, dim=1)               # (32, 2)
    video_probs = mean(probs, dim=0)             # (2,)
    return video_probs[1]

Hyperparameters

NameValueWhereNotes
EncodersCLIP ViT-L/14; PE core L; DINOv3 ViT-L/16§3.1Code: openai/clip-vit-large-patch14, timm vit_pe_core_large_patch14_336 run at 224, facebook/dinov3-vitl16-pretrain-lvd1689m config.py
Feature1024-d classification token, L2-normalised§3.1CLIP code takes HF pooler_output clip_encoder.py
Trainable parameterslinear 1024 to 2 (W, b) and all LayerNorm blocks§3.1~0.03% of total, stated §3.1; not counted here
Input size224 x 224 face crop§3.2
Frames per video32§3.1 §3.2
Cross-entropy weight1.0wacv_rebuttal.pyNot stated in paper; code value
Alignment weight alpha0.1 (CLIP)§3.1Code uses 0.1 for CLIP, PE and DINOv3 wacv_rebuttal.py wacv_rebuttal.py wacv_rebuttal.py; paper states CLIP only
Uniformity weight beta0.5 (CLIP)§3.1Code uses 0.5 for CLIP, PE and DINOv3 (same lines)
Uniformity temperature t2eq. 3Code default t=2 unifalign.py
Alignment powersquared distanceeq. 2Code default alpha=2 on the norm unifalign.py
OptimizerAdam, betas (0.9, 0.999), no weight decay§3.1Code uses AdamW with weight decay 0.0 (equivalent) config.py GenD.py
Peak learning rate3e-4§3.1Code default config.py
Minimum learning rate1e-5§3.1Code default is 1e-6 config.py
Warm-up1 epoch, 1e-5 to 3e-4, each cycle§3.1Code WACV configs set warmup_epochs=0 (default) config.py
Cycle10 epochs (1 warm-up + 9 cosine)§3.1Code: cosine warm restarts, T_0 = 10 epochs GenD.py wacv_rebuttal.py
Batch size128§3.1Code default 512, not overridden in WACV configs config.py run.py
Precisionbfloat16 weights§3.1Code uses bf16-mixed config.py run.py
Max epochsnot stated§3.1Code 30 wacv_rebuttal.py
Stopping"for most runs" no improvement after 2 cycles (20 epochs), an observation§3.1Code patience 30 epochs wacv_rebuttal.py
Seeds5 training seeds§4Code seeds 0 to 4; the seed also selects the frame split wacv_rebuttal.py
Training dataFaceForensics++ c23, about 115k frames§3.2Code uses per-seed training lists drawn from random 32-frame subsets of the FF++ data wacv_rebuttal.py
Augmentation: flipp = 0.5§3.2 (types only)config.py
Augmentation: affinerotation +-10 deg, translate 0.1, scale 0.9 to 1.1§3.2 (types only)config.py
Augmentation: blurp = 0.1, kernel 7, sigma in [0.1, 2.0]§3.2 (types only)config.py
Augmentation: colourbrightness 0.1, contrast 0.1§3.2 (types only)config.py
Augmentation: JPEGquality in [40, 100]§3.2 (types only)config.py
Face crop1.3 margin, aligned with landmarks§3.2Code scale=1.3 in landmark-based alignment detector.py
Validation setsCDFv3, DSv1 (code: DSv1.1), DSv2, FFIW§3.2wacv_rebuttal.py
Test-time augmentationnonenot stated in paperconfig.py
Model selectionnot stated in papernot statedCode: best val/mAP_video checkpoint config.py run.py
Throughput120 frames/s on A100, batch 1, about 2 GB§3.1Not checked against code

Results

Author-reported. Video-level AUROC (%). Setup: trained on FaceForensics++ c23 (cross-dataset protocol), 14 test benchmarks from 2019 to 2025, five training seeds for GenD rows. Competitor numbers in tab. 2 come from their original papers. Those in tab. 4 were rerun by the authors with the official weights and preprocessing §4.2.

Table 2: cross-dataset comparison, from tab. 2

ModelYearVenueInputBackboneCDFv2DFDDFDCFFIW
LipForensics2021CVPRVideoResNet-1882.4--73.5--
FTCN2021ICCVVideo3D ResNet-5086.9--74.074.5 (from SBI)
RealForensics2022CVPRVideoModified CSN86.9--75.9--
SBI2022CVPRFrameEFNB493.282.772.484.8
AUNet2023CVPRVideoXception+ART92.899.273.881.5
StyleDFD2024CVPRVideo3D ResNet-5089.096.1----
LSDA2024CVPRFrameEFNB491.1--77.072.4 (from Effort)
LAA-Net2024CVPRFrameEFNB495.498.486.9--
AltFreezing2024CVPRVideo3D ResNet-5089.598.5----
NACO2024ECCVVideoViT-B/1689.5--76.7--
RAE2024ECCVFrameViT-B/1695.599.080.2--
TALL++2024IJCVVideoSwin-B92.0--78.5--
ProDet2024NeurIPSFrameEFNB492.5--77.0--
UDD2025AAAIFrameCLIP ViT-B/1693.195.581.2--
P&P2025CVPRVideoCLIP ViT-L/1494.796.584.392.1
DFD-FCG2025CVPRVideoCLIP ViT-L/1495.0--81.8--
ForAda2025CVPRFrameCLIP ViT-L/1495.797.287.2--
Effort2025ICMLFrameCLIP ViT-L/1495.696.584.392.1
GenD (CLIP)2025--FrameCLIP ViT-L/1496.097.087.192.8
GenD (PE)2025--FramePE core L95.896.581.693.3
GenD (DINO)2025--FrameDINOv3 ViT-L/1692.296.684.794.5

The paper says GenD is best on CDFv2 (CLIP) and FFIW (DINO) in this table §4.2.

Table 4: reproduced cross-dataset AUROC, 14 test sets, from tab. 4

Test set (year)ForAdaEffortGenD (CLIP)GenD (PE)GenD (DINO)
UADFV (2019)99.497.499.297.798.6
DFD (2019)97.295.296.496.896.2
DFDC (2019)87.385.486.482.285.6
FSh (2020)82.091.286.687.688.8
CDFv2 (2020)95.793.294.695.092.5
FFIW (2021)90.692.591.593.792.9
KoDF (2021)88.288.184.985.189.7
FAVC (2021)93.192.496.097.398.4
DFDM (2022)97.198.299.698.399.8
PGF (2024)86.684.989.692.392.4
IDF (2024)90.896.097.897.998.2
DSv1.1 (2024)81.882.190.187.886.9
DSv2 (2025)72.864.477.778.679.4
CDFv3 (2025)75.678.785.989.583.5
Mean (14 sets)88.488.591.291.491.6

Standard deviations over five seeds for GenD are in [supp. tab. S3]. The paper says the higher average across all 14 sets shows better generalisation §4.2.

Table 3: in-domain AUROC on FF++ test, from tab. 3

MethodDFF2FFSNTMean
ForAda99.797.098.691.996.8
Effort99.493.298.484.693.9
GenD (CLIP)99.598.198.795.598.0
GenD (PE)99.799.399.197.598.9
GenD (DINO)99.699.499.496.798.8

Table 5: reported versus reproduced AUROC, from tab. 5 (reported = the original paper, reproduced = the authors' rerun)

MethodCDFv2DFDDFDCFFIW
ForAda95.7 / 95.797.2 / 97.287.2 / 87.3-- / 90.6
Effort95.6 / 93.296.5 / 95.284.3 / 85.492.1 / 92.5

Table 6: ablation, 14 test sets, from tab. 6 (averages over five seeds; the last row of each block is the full GenD method)

#SetupUADFVDFDDFDCFShCDFv2FFIWKoDFFAVCDFDMPGFIDFDSv1.1DSv2CDFv3Mean
1CLIP + LP94.689.275.377.674.680.781.883.077.862.768.764.557.875.676.0
2#1 + LN99.096.185.486.993.891.584.495.599.387.595.089.174.086.890.3
3#2 + UA (GenD CLIP)99.296.486.486.694.691.584.996.099.689.697.890.177.785.991.2
4PE + LP76.176.467.280.372.275.765.671.373.352.874.665.659.579.570.7
5#4 + LN98.496.481.988.194.293.084.596.597.991.297.788.077.089.991.0
6#5 + UA (GenD PE)97.796.882.287.695.093.785.197.398.392.397.987.878.689.591.4
7DINOv3 L + LP84.279.869.071.968.274.775.481.185.965.082.072.270.268.374.9
8#7 + LN97.394.884.488.791.790.490.698.498.893.697.589.182.480.191.3
9#8 + UA (GenD DINO)98.696.285.688.892.592.989.798.499.892.498.286.979.483.591.6

Setups 1 to 3 use CLIP, 4 to 6 PE, 7 to 9 DINOv3. LP is a frozen backbone with a linear probe; LN adds LayerNorm tuning; UA adds L2 normalisation and the uniformity and alignment losses.

Table S1: paired versus unpaired training data, from [supp. tab. S1] (20 random splits each, mean +- std; the backbone is not stated in the caption)

TrainingUADFVDFDDFDCFShCDFv2FFIWKoDFFAVCDFDMPGFIDFDSv1.1DSv2CDFv3Mean
Unpaired97.5 +- 0.392.4 +- 0.779.7 +- 0.885.3 +- 2.481.0 +- 2.887.4 +- 1.778.5 +- 4.089.8 +- 2.794.6 +- 2.983.9 +- 0.695.7 +- 0.678.4 +- 0.070.2 +- 2.480.2 +- 1.585.3
Paired98.1 +- 0.395.3 +- 0.880.4 +- 0.286.3 +- 1.391.5 +- 1.390.9 +- 1.084.8 +- 1.695.8 +- 0.397.8 +- 1.091.5 +- 2.797.0 +- 1.287.7 +- 1.374.6 +- 0.288.3 +- 2.190.0

Table S2: PEFT comparison, CLIP ViT-L/14, mean AUROC only, from [supp. tab. S2]

ConfigurationMean AUROC
Full fine-tuning (FFT)57.9 (text says 56.8)
Baseline (linear probe)76.1
BitFit90.9
BitFit + L290.9
BitFit + L2 + UA91.7
LoRA91.9
LoRA + L290.5
LoRA + L2 + UA91.4
LN90.8
LN + L291.8
LN + L2 + UA (GenD)92.1

Other results (author-reported, described from the figures, not tabulated):

  • Paired versus unpaired §4.4 fig. 3: with PE, validation AUROC is higher and overfitting slower for paired training sets, averaged over 20 splits each. The supplement reports the same behaviour for CLIP on FF++ [supp. fig. S1], and faster overfitting, with the same pattern, for the FAVC [supp. fig. S2] and CDFv2 [supp. fig. S3] training sets.
  • Detection difficulty over years §4.5 fig. 4: a model trained on FF++ (2019) generalises across more test sets than one trained on DSv2 (2025), which the authors say does poorly on older benchmarks. FFIW (2021) is a third training set.
  • Robustness §4.6 fig. 5: under Gaussian blur, JPEG and downscaling, GenD (PE) is compared with ForAda and Effort on all 14 test sets. The text gives no numbers, and the authors report GenD's error bars over five seeds.
  • Reported speed: 120 frames per second on an A100 at batch size 1, about 2 GB of VRAM §3.1. Not checked against the code.

Paper vs code

Official code: https://github.com/yermandy/GenD at 387a42266dd385fbe8f7626c5d3aa03eea3bfaab, MIT license (LICENSE). The abstract and the README link this repository, and the owner handle yermandy resembles the first author's name; the LICENSE copyright line reads "Andy". The code is a training and evaluation framework (PyTorch Lightning, src/), with configs in src/exp/. The training data is on Hugging Face per the README README.md. The data lists are not in the clone: only eight .txt lists under config/, all for FF++ test and CDFv2 test.

Searched for the code: the abstract link and the README agree. No other repositories were considered.

Differences:

  • Learning-rate schedule. Paper: a one-epoch warm-up from 1e-5 to 3e-4 at the start of each cycle, then cosine decay to 1e-5 over nine epochs §3.1. Code: cosine warm restarts with a 10-epoch cycle, minimum 1e-6, and no warm-up in the WACV configs (warmup_epochs = 0). The warm-up branch exists but only runs once, at the start, when enabled config.py wacv_rebuttal.py GenD.py.
  • Batch size. Paper: 128 §3.1. Code: 512 by default, and the WACV configs do not change it; gradient accumulation is 512 divided by 512, so one step per batch config.py run.py.
  • Precision. Paper: "weight precision bfloat16" §3.1. Code: bf16-mixed config.py run.py. Lightning's mixed mode keeps fp32 weights with bf16 autocast (library behaviour, not checked here).
  • Stopping. Paper: "for most runs" training did not improve after two cycles (20 epochs) §3.1, which describes what was observed rather than a rule. Code: 30 epochs maximum and 30 epochs of patience [code: src/exp/wacv_rebuttal.py#L212-L213]. With patience equal to the maximum run length, early stopping cannot fire; every run goes to 30 epochs.
  • Model selection. Paper: the text uses "validation AUROC" §3.2, and does not say which checkpoint is tested. Code: monitors val/mAP_video (macro average precision over both classes, not AUROC) and tests the best-mAP checkpoint config.py [code: src/model/base.py#L204-L208] run.py.
  • Frame sampling. Paper: "sample 32 frames evenly" §3.2. Code: the preprocessing default is at_least, which orders all frames by a maximum-spread permutation starting at the middle of the video, then keeps the first 32 with a detectable face detector.py [code: detector.py#L105-L106]. The README command uses -m at_least -n 32, with --det_thres 0.1 README.md. Training lists are per-seed random 32-frame subsets wacv_rebuttal.py.
  • Face size. Paper: crop and resize to 224 x 224 after a 1.3 margin §3.2. Code: the landmark-based alignment sets the crop size from landmark geometry and scale 1.3 detector.py; the README command passes --target_size none README.md. The 224 resize is applied by the model's processor clip_encoder.py. Whether the released Hugging Face data was made this way is not stated.
  • Alignment and uniformity. Paper: the alignment pair set P+ is not defined eq. 2; the uniformity term is an expectation over independent draws eq. 3. Code: alignment uses all equal-label pairs inside the mini-batch; uniformity averages over unordered pairs i < j in the batch, with the mean clamped at 1e-6 before the log unifalign.py [code: src/losses/unifalign.py#L63].
  • Loss weights for PE and DINOv3. Paper states alpha and beta for CLIP only §3.1. Code uses 0.1 and 0.5 for all three encoders [code: src/exp/wacv_rebuttal.py#L46] wacv_rebuttal.py [code: src/exp/wacv_rebuttal.py#L184].
  • Augmentation values. Paper lists the augmentation types only §3.2. The code's defaults give exact ranges and probabilities config.py augmentations.py. The WACV configs do not override them, so the defaults apply.
  • Robustness settings. Paper: resize to 224, 114 and 64 pixels §4.6. Code: 224, 112 and 64 wacv_rebuttal_aug_robustness.py wacv.sh. The interpolation index order in wacv.sh is mislabelled; the comment in src/config.py matches Pillow's constants config.py wacv.sh.
  • LoRA and PEFT ablation. Paper: LoRA on every transformer weight matrix, rank one §4.3. Code: the default LoRA targets out_proj only, rank 1, alpha 32 config.py GenD.py. The released experiment files contain no LoRA, BitFit or full fine-tuning configuration, so the PEFT table cannot be reproduced from the release as shipped.
  • Paper arithmetic. The paper gives 56.8 percent for full fine-tuning in the text [supp §S2 text] and 57.9 in its table [supp. tab. S2]; the table's mean (57.9) matches its 13 values.
  • Paper-internal naming. The paper calls the DeepSpeak sets "DSv1" in places; the code's DeepSpeak_v1_1 is the set reported as DSv1.1 §4.1 wacv_rebuttal.py.
  • Sweep labels. In the alpha/beta sweep, the code assigns the swept alpha to uniformity and beta to alignment_labels, while the run names use the opposite letters. Named runs are consistent [code: src/exp/wacv_rebuttal.py#L288-L291] wacv_rebuttal.py.
  • Test sets. The code's test dictionary has more sets than the 14 in the paper (for example FaceFusion, KoDF-adversarial and several FakeAVCeleb subsets) wacv_rebuttal.py. The 14 cross-dataset sets in the paper are a subset of these.
  • Encoder pooling. The CLIP feature is HF pooler_output, which for CLIP applies the post-LayerNorm to the CLS token (library behaviour, not checked here) clip_encoder.py. DINOv3 uses last_hidden_state[:, 0] dino_encoder.py. For PE, the code removes the timm head and uses the backbone output; the pooling inside timm is not checked here perception_encoder.py.

Pitfalls

  • The unfreezing rule is by substring. unfreeze_layers matches any parameter whose name contains one of the strings GenD.py. For PE and DINOv3, the string norm may match more than LayerNorm weights and biases. Check the trainable parameter list, and confirm the 0.03 percent figure, before a long run.
  • Uniformity and alignment need trainable parameters upstream. With a frozen encoder and a linear head, the two extra losses are constant with respect to the trainable parameters, so they do nothing. The paper reports that adding them without LayerNorm tuning gives identical numbers [supp. tab. S8] [supp. §S4]. Keep LayerNorm tuning on when using these losses.
  • The losses depend on the batch. The alignment and uniformity estimates use whatever pairs are in the mini-batch unifalign.py. The paper uses 128, the code 512. A different batch size changes the loss scale and the set of positive pairs.
  • Silent NaN handling. If the total loss is NaN, the code logs a warning and replaces the loss with zero times the logits loss.py. A run can keep training with no gradient on that step.
  • Uniformity is clamped. The mean kernel is clamped at 1e-6 before the log unifalign.py. A collapsed batch hits the clamp and the gradient stops there.
  • Warm restarts jump back to the peak. Without a warm-up, each 10-epoch cycle restarts the learning rate at 3e-4 from 1e-6 GenD.py. Paper and code differ here, so use one schedule explicitly.
  • Checkpoint choice changes the reported number. The code tests the best-mAP checkpoint on the custom validation set run.py. The paper does not say how it picked the test checkpoint. Results can move if you select by AUROC.
  • Frame sampling matters. The released preprocessing spreads 32 frames by maximum spacing and skips frames without a face. The paper describes even sampling. Video-level scores average over whatever frames the test list contains base.py.
  • Training pairs must be built. The paired and unpaired split lists are not in the clone, and no script that generates them was found; the experiment file only names them wacv_rebuttal_paired_unpaired.py.
  • Compute for the reproduction. Training is 30 epochs at batch 512 by default, on lists that are not in the clone. The data must be downloaded from Hugging Face (see the README) before the configs will run.

Lineage

  • Builds on: UniFD (a frozen-backbone linear probe, used as the baseline setting §4.3); LN-tuning [arXiv:2211.08682]; uniformity and alignment losses [arXiv:2005.10242] (the code links this arXiv id).
  • Compared against: ForAda §4.2 (CLIP ViT-L/14 adapter, CVPR 2025), Effort §4.2 (CLIP ViT-L/14, ICML 2025), and others in tab. 2. The authors reran ForAda and Effort with their official weights.
  • Superseded by: not known from content on this wiki.

Source and license

Adapted from “Deepfake Detection that Generalizes Across Benchmarks” by Andrii Yermakov, Jan Cech, Jiri Matas, Mario Fritz (arXiv:2508.06248), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/yermandy/GenD at commit 387a42266dd3 (MIT). Any quoted code is shown under that license.