Skip to content

liudeyu07/Graduation-project

Repository files navigation

DFD-FCG 项目说明

基于 CLIP 的视频 Deepfake 检测,结合 FCG(Face-Centric Guidance)与 STA(Spatio-Temporal Adapter)。

参考论文:

实验结果(截至 2026-04-28)

当前对比了三版 STA+FCG:

  • v1:原始 STA+FCG
  • v2:修复 focal loss + cosine LR + ffg_weight=1.5
  • v3:在 v2 基础上加入 cross-attention STA
模型 FFPP AUC CDF AUC DFo AUC WDF AUC DFD(.avi) AUC 备注
v1 98.3% 94.6% 98.1% 79.8% 93.8% 原始 STA+FCG
v2 98.0% 94.7% 98.3% 80.1% 93.5% 当前最均衡推荐
v3 97.6% 95.2% 98.3% 80.5% 94.8% CDF / WDF / DFD AUC 最优

结论:

  • 如果只看 FFPPv1 最好
  • 如果看外部数据集 CDF / WDF / DFD 的 AUC,v3 最强
  • 如果看跨数据集的整体均衡性,v2 / v3 明显优于 v1
  • 若只保留一个默认版本,推荐 v2
  • 若强调 CDF / WDF / DFD 外部泛化,保留 v3
  • official FCG weightsDFD(.avi) 上为 AUC=92.9%,低于当前三版 STA+FCG

当前主要 checkpoint:

  • v1: lightning_logs/sta_ffg_l14_10f3s/version_1/checkpoints/epoch=15-step=27264.ckpt
  • v2: lightning_logs/sta_ffg_l14_10f3s_v2/version_0/checkpoints/epoch=18-step=32376.ckpt
  • v3: lightning_logs/sta_ffg_l14_10f3s_v3/version_0/checkpoints/epoch=19-step=34080.ckpt
  • official: checkpoint/weights.ckpt

说明:

  • DFD 原始 .mp4 推理在 2026-04-27 被机器侧 CUDA/NVML 异常阻塞;最终通过“先裁脸为 .avi 再单卡串行推理”完成稳定评测
  • WDF 使用本地 deepfake_in_the_wild/*_test/*.tar.gz 转为 mp4 后评测

阶段总结(2026-04-28)

本阶段已经完成:

  • FFPP / CDF / DFo / WDF / DFD(.avi) / DF40 Protocol-2 六组评测
  • official FCG weights 与三版 STA+FCG 的对齐比较
  • DFD 从原始 .mp4 切换到裁脸 .avi 的稳定评测链路

DFD(裁脸 .avi

DFD 最终不再直接使用原始 .mp4,而是先做关键点提取与人脸裁剪,再通过 datasets/dfd_avi/ wrapper 评测。

可用样本数:

  • REAL: 360 / 363
  • FAKE: 3017 / 3068

合计评测样本:3377

模型 accuracy@0.5 ROC-AUC best_accuracy best_thr
official 81.9% 92.9% 91.7% 0.312824
v1 85.3% 93.8% 92.3% 0.211049
v2 83.7% 93.5% 92.5% 0.213017
v3 83.6% 94.8% 93.1% 0.212390

结论:

  • officialDFD(.avi) 上并不占优
  • v1 在固定阈值 0.5 下 accuracy 最好
  • v3AUCbest_accuracy 上最好,说明排序能力与阈值可调性更强

对应日志:

  • official: lightning_logs/infer_official_dfd_avi_safe.log
  • v1: lightning_logs/infer_v1_dfd_avi_safe.log
  • v2: lightning_logs/infer_v2_dfd_avi_safe.log
  • v3: lightning_logs/infer_v3_dfd_avi_safe.log

DF40 Protocol-2

同一套 DF40 Protocol-2 已全部跑完,四套模型都在同一机器、同一套流程下完成。mobileswap 过程中所有模型都遇到相同的 video_reader 解码 warning,但没有中断,结果正常落盘。

平均结果

模型 平均 accuracy@0.5 平均 AUC 结论
official 93.5% 99.2% 跨操作泛化最强
v1 88.1% 94.8% 我们三版中最接近 official
v3 88.6% 93.7% 次优,较稳
v2 86.0% 91.8% 最弱

各操作 AUC

操作 v1 v2 v3 official
blendface 0.924 0.896 0.918 0.990
e4s 0.963 0.939 0.957 1.000
facedancer 0.974 0.931 0.958 0.990
fsgan 0.955 0.925 0.948 0.995
inswap 0.946 0.908 0.919 0.988
mobileswap 0.935 0.922 0.941 0.990
simswap 0.927 0.899 0.913 0.984
uniface 0.962 0.924 0.939 0.997

各操作 accuracy@0.5

操作 v1 v2 v3 official
blendface 0.854 0.833 0.854 0.958
e4s 0.907 0.837 0.907 0.953
facedancer 0.938 0.938 0.938 0.917
fsgan 0.875 0.875 0.896 0.938
inswap 0.864 0.886 0.886 0.909
mobileswap 0.860 0.847 0.881 0.932
simswap 0.833 0.833 0.833 0.917
uniface 0.917 0.833 0.896 0.958

结论:

  • officialDF40 Protocol-2 上显著强于当前三版 STA+FCG
  • 这不是简单的“训练坏了”,而是 跨 manipulation 泛化能力 的差距
  • FFPP 域内时我们的 checkpoint 并不弱,但到了 DF40 Protocol-2 这种跨操作评测,official FCG 的可迁移性明显更强
  • 最可能的原因依次是:模型结构差异、训练 recipe 差异、以及对 FFPP 域内 cue 的过拟合

对应 report 文件:

  • v1: archive/reports/report_0428T160741.json
  • v2: archive/reports/report_0428T161022.json
  • v3: archive/reports/report_0428T153604.json
  • official: archive/reports/report_0428T161244.json

1. 入口脚本

  • main.py:训练入口(训练结束后自动对 test datamodule 执行 inference)
  • inference.py:独立评测入口,输出 AUC / accuracy,结果写入 archive/reports/
  • demo.py:单视频可视化推理(输出带检测框和分数的视频)
  • setup_dataset.py:整理 FFPP 下载目录并生成 split
  • faceforensics_download_v4.py:FFPP 下载脚本

2. 环境与依赖

2.1 推荐环境

cd /home/yangboyuan/DFD-FCG-main
source /home/yangboyuan/miniconda3/etc/profile.d/conda.sh
conda env create -f environment.yml
conda activate dfd-fcg

当前关键版本:

  • Python 3.10
  • torch 2.2.1 + cu121
  • torchvision 0.17.1
  • torchaudio 2.2.1
  • av 16.1.0

其余依赖由 pip_requirements.txt 补全。

2.2 预处理缓存约定

预处理流程依赖 face_alignment 权重下载,当前仓库约定:

export TORCH_HOME="$(pwd)/.torch_cache"

这样权重会落在仓库本地,避免使用 ~/.cache/torch 导致的跨机器不一致或坏缓存问题。

3. 核心代码流程

3.1 训练流程(main.py)

main.py 的主流程:

  1. 构建 ODLightningCLIODTrainer
  2. datamodule.affine_model(model) 将模型 transform 注入数据管线
  3. 根据 ckpt_mode 处理断点继续或微调加载
  4. trainer.fit(...)
  5. 训练结束后自动调用 inference_driver(...) 对最佳 checkpoint 评测

重点:

  • 默认将训练配置保存为 setting.yaml
  • 默认 early-stop / checkpoint 监控指标为 valid/FFPP/auc

3.2 评测流程(inference.py)

inference.py 接收三个位置参数

python inference.py <model_cfg_path> <data_cfg_path> <ckpt_path>

评测时会:

  • 通过 trainer.predict 收集视频级概率
  • 汇总为 Accuracy、ROC-AUC
  • 额外搜索 best threshold 并输出 best_accuracy
  • 在配置目录写入 report_*.jsonstats_*.pickle

3.3 Demo 流程(demo.py)

python -m demo "checkpoint/setting.yaml" "checkpoint/weights.ckpt" "resources/videos/000_003.mp4" --out_path="pred.avi"

依赖同名路径下的预处理产物:

  • frame_data/*.pickle
  • cropped/videos/*.avi

输出带检测框、类别(REAL/FAKE)和分数的视频文件。

4. 数据与预处理

4.1 FFPP 数据目录约定

训练/评测优先读取:

  • datasets/ffpp/<TYPE>/c23/cropped/videos/*.avi

cropped/videos 不存在,则回退到:

  • datasets/ffpp/<TYPE>/c23/videos/*

其中 <TYPE> 典型为:real, DF, F2F, FS, NT, FSh

split 文件:

  • datasets/ffpp/csv_files/train.json
  • datasets/ffpp/csv_files/val.json
  • datasets/ffpp/csv_files/test.json

4.2 FFPP 预处理

export TORCH_HOME="$(pwd)/.torch_cache"
bash preprocess_ffpp.sh

该脚本对 real/DF/F2F/FS/NT 依次执行:

  1. src.preprocess.fetch_landmark_bbox(关键点提取,~27s/视频)
  2. src.preprocess.crop_main_face(150×150 裁脸,输出 .avi)

关键输出:

  • datasets/ffpp/<TYPE>/c23/frame_data/*.pickle(关键点和 bbox)
  • datasets/ffpp/<TYPE>/c23/cropped/videos/*.avi(裁脸后视频)

4.3 CDF / DFo 预处理

CDF 和 DFo 预处理步骤相同,以 CDF FAKE 为例(支持 --split-num 分片并行):

export TORCH_HOME="$(pwd)/.torch_cache"

# Step 1: 关键点提取(耗时,推荐多卡并行,part-num 从 1 开始)
CUDA_VISIBLE_DEVICES=0 python -m src.preprocess.fetch_landmark_bbox \
    --root-dir="datasets/cdf/FAKE" \
    --video-dir="videos" \
    --fdata-dir="frame_data" \
    --glob-exp="*.mp4" \
    --split-num=4 --part-num=1 &
CUDA_VISIBLE_DEVICES=1 python -m src.preprocess.fetch_landmark_bbox \
    --root-dir="datasets/cdf/FAKE" \
    --video-dir="videos" \
    --fdata-dir="frame_data" \
    --glob-exp="*.mp4" \
    --split-num=4 --part-num=2 &
# ... 以此类推 part-num=3,4
wait

# Step 2: 人脸裁剪(CPU 并行)
python -m src.preprocess.crop_main_face \
    --root-dir="datasets/cdf/FAKE" \
    --video-dir="videos" \
    --fdata-dir="frame_data" \
    --crop-dir="cropped" \
    --glob-exp="*.mp4" \
    --workers=8

REAL 同理,--root-dir="datasets/cdf/REAL"

预处理完成后,创建评测用的符号链接目录(规避路径约定差异):

mkdir -p datasets/cdf_avi/REAL datasets/cdf_avi/FAKE
ln -s "$(pwd)/datasets/cdf/REAL/cropped/videos" datasets/cdf_avi/REAL/videos
ln -s "$(pwd)/datasets/cdf/FAKE/cropped/videos" datasets/cdf_avi/FAKE/videos
cp -r datasets/cdf/csv_files datasets/cdf_avi/

DFo 同理,目录为 datasets/dfo_avi/

4.4 DFD 预处理与稳定推理

DFD 在当前机器上直接对原始 .mp4 做多卡推理不稳定,推荐固定流程:

  1. fetch_landmark_bbox
  2. crop_main_face
  3. datasets/dfd_avi/ wrapper
  4. 单卡串行推理

关键点提取与裁脸:

export TORCH_HOME="$(pwd)/.torch_cache"

# REAL
python -m src.preprocess.fetch_landmark_bbox \
  --root-dir datasets/dfd_eval/real \
  --video-dir videos \
  --fdata-dir frame_data \
  --glob-exp "*.mp4" \
  --split-num 1 \
  --part-num 1 \
  --batch 8 \
  --max-res 800

python -m src.preprocess.crop_main_face \
  --root-dir datasets/dfd_eval/real \
  --video-dir videos \
  --fdata-dir frame_data \
  --crop-dir cropped \
  --glob-exp "*.mp4" \
  --workers 8

# FAKE(三分片 landmark,再统一裁脸)
CUDA_VISIBLE_DEVICES=1 python -m src.preprocess.fetch_landmark_bbox \
  --root-dir datasets/dfd_eval/fake \
  --video-dir videos \
  --fdata-dir frame_data \
  --glob-exp "*.mp4" \
  --split-num 3 \
  --part-num 1 \
  --batch 8 \
  --max-res 800 &

CUDA_VISIBLE_DEVICES=3 python -m src.preprocess.fetch_landmark_bbox \
  --root-dir datasets/dfd_eval/fake \
  --video-dir videos \
  --fdata-dir frame_data \
  --glob-exp "*.mp4" \
  --split-num 3 \
  --part-num 2 \
  --batch 8 \
  --max-res 800 &

CUDA_VISIBLE_DEVICES=5 python -m src.preprocess.fetch_landmark_bbox \
  --root-dir datasets/dfd_eval/fake \
  --video-dir videos \
  --fdata-dir frame_data \
  --glob-exp "*.mp4" \
  --split-num 3 \
  --part-num 3 \
  --batch 8 \
  --max-res 800 &

wait

python -m src.preprocess.crop_main_face \
  --root-dir datasets/dfd_eval/fake \
  --video-dir videos \
  --fdata-dir frame_data \
  --crop-dir cropped \
  --glob-exp "*.mp4" \
  --workers 8

wrapper 目录:

mkdir -p datasets/dfd_avi/real datasets/dfd_avi/fake
ln -sfn "$(pwd)/datasets/dfd_eval/real/cropped/videos" datasets/dfd_avi/real/videos
ln -sfn "$(pwd)/datasets/dfd_eval/fake/cropped/videos" datasets/dfd_avi/fake/videos

4.5 下载与整理

下载 FFPP:

python faceforensics_download_v4.py datasets/ffpp -d original -c c23 -t videos --server EU2
python setup_dataset.py

其他数据集:

bash scripts/tools/download/download_ffpp_extras.sh   # FSh
python scripts/tools/download/prepare_celebdf_v2_as_cdf.py   # CDF
python scripts/tools/download/prepare_deeperforensics_as_dfo.py  # DFo
python scripts/tools/download/download_wdf_from_hf.py   # WDF(从 HF 下载)

详细说明见 scripts/tools/download/README.md

4.6 WDF / DFD(新数据集)

WDF 当前支持两种入口:

  1. 直接从 Hugging Face 下载并转视频
  2. 读取本地 deepfake_in_the_wild/*_test/*.tar.gz,转为:
    • datasets/wdf/real/videos/*.mp4
    • datasets/wdf/fake/videos/*.mp4

本地 tar 转视频:

python scripts/tools/download/download_wdf_from_hf.py \
  --source_root datasets/deepfake_in_the_wild \
  --out_dir datasets/wdf \
  --split test

DFD 当前通过 wrapper 目录评测:

  • datasets/dfd_eval/real/videos -> datasets/hf_dfd_git/DFD_original sequences
  • datasets/dfd_eval/fake/videos -> datasets/hf_dfd_git/DFD_manipulated_sequences/DFD_manipulated_sequences

对应 datamodule:

  • src.dataset.dfd_eval.DFDDataModule

5. 配置文件说明

5.1 全局训练基线

  • configs/base.yaml:trainer 基础参数(precision、epochs、grad clip 等),early_stop / checkpoint / lr_monitor 默认设置

5.2 数据配置

  • configs/data.yaml:主训练与验证数据拼接配置(多数据集验证入口 CDF/FSh 等)

5.3 模型配置

配置文件 模型 说明
configs/clip/L14/fcg.yaml FFGSynoVideoLearner FCG 官方配置复现
configs/clip/L14/sta.yaml StAFFGVideoLearner STA 实验配置
configs/comparison/sta_ffg_l14_10f3s.yaml StAFFGVideoLearner 当前最佳:STA+FCG,10帧/3s

5.4 推理配置

配置文件 说明
configs/infer/inference_ffpp_10f.yaml FFPP 评测(10帧)
configs/infer/inference_cdf_avi.yaml CDF 评测(预处理 .avi)
configs/infer/inference_dfo_avi.yaml DFo 评测(预处理 .avi)
configs/infer/inference_cdf_avi_safe.yaml CDF 低内存评测
configs/infer/inference_dfo_avi_safe.yaml DFo 低内存评测
configs/infer/inference_wdf_safe.yaml WDF 评测
configs/infer/inference_dfd_safe.yaml DFD 保守评测
configs/infer/inference_dfd_fast.yaml DFD 加速评测
configs/infer/inference_dfd_ultrasafe.yaml DFD 超保守排障配置
configs/infer/inference_dfd_avi_safe.yaml DFD 裁脸 .avi 单卡稳定评测
configs/infer/official_ffg.yaml FCG 官方权重评测
configs/infer/ours_full.yaml 本项目完整评测

6. 脚本工具

6.1 数据工具

  • scripts/tools/dataset/process_and_merge.py
  • scripts/tools/dataset/process_new_data.py
  • scripts/tools/dataset/cleanup_processed.py
  • scripts/tools/dataset/monitor_preprocess_progress.py:监控预处理进度

6.2 split 工具

  • scripts/tools/splits/generate_splits_v2.py:生成数据集 split CSV
  • scripts/tools/splits/create_dfo_csv.py:生成 DFo test split CSV
  • scripts/tools/splits/fix_splits.py

6.3 推理工具

  • scripts/tools/inference/run_inference.py
  • scripts/tools/inference/run_inference_simple.py

6.4 下载工具

  • scripts/tools/download/download_ffpp_extras.sh:下载 FSh
  • scripts/tools/download/prepare_celebdf_v2_as_cdf.py:整理 CelebDF-v2
  • scripts/tools/download/prepare_deeperforensics_as_dfo.py:整理 DeeperForensics
  • scripts/tools/download/download_wdf_from_hf.py:从 HuggingFace 下载 WDF

7. 常用命令

7.1 训练(STA+FCG,当前最佳配置)

python main.py --config configs/comparison/sta_ffg_l14_10f3s.yaml

训练日志保存至 lightning_logs/sta_ffg_l14_10f3s/version_1/,包含 setting.yaml(完整超参记录)。

7.2 最小启动检查

python main.py --config configs/comparison/sta_ffg_l14_10f3s.yaml \
  --trainer.limit_train_batches=1 \
  --trainer.limit_val_batches=0 \
  --trainer.max_epochs=1

7.3 数据集评测

# FFPP
python inference.py \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/setting.yaml" \
    "configs/infer/inference_ffpp_10f.yaml" \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/checkpoints/epoch=15-step=27264.ckpt"

# CDF(需先完成 4.3 节预处理 + cdf_avi 符号链接)
python inference.py \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/setting.yaml" \
    "configs/infer/inference_cdf_avi.yaml" \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/checkpoints/epoch=15-step=27264.ckpt"

# DFo(同上,需 dfo_avi 符号链接)
python inference.py \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/setting.yaml" \
    "configs/infer/inference_dfo_avi.yaml" \
    "lightning_logs/sta_ffg_l14_10f3s/version_1/checkpoints/epoch=15-step=27264.ckpt"

# WDF
python inference.py \
    "lightning_logs/sta_ffg_l14_10f3s_v2/version_0/setting.yaml" \
    "configs/infer/inference_wdf_safe.yaml" \
    "lightning_logs/sta_ffg_l14_10f3s_v2/version_0/checkpoints/epoch=18-step=32376.ckpt"

# DFD(推荐 `.avi` 版本,需先完成 4.6 节预处理)
python inference.py \
    "lightning_logs/sta_ffg_l14_10f3s_v2/version_0/setting.yaml" \
    "configs/infer/inference_dfd_avi_safe.yaml" \
    "lightning_logs/sta_ffg_l14_10f3s_v2/version_0/checkpoints/epoch=18-step=32376.ckpt"

# DFD official FCG
python inference.py \
    "configs/infer/official_ffg.yaml" \
    "configs/infer/inference_dfd_avi_safe.yaml" \
    "checkpoint/weights.ckpt"

7.4 Demo 推理

python -m demo "checkpoint/setting.yaml" "checkpoint/weights.ckpt" "resources/videos/000_003.mp4" --out_path="pred.avi"

8. 常见问题

8.1 face_alignment 权重下载慢/损坏

现象:unexpected EOF / Read timed out

建议:

  • 确保设置 export TORCH_HOME=$(pwd)/.torch_cache
  • 使用已下载好的 .torch_cache 直接拷贝到仓库根目录

8.2 训练出现大量 "Video ... does not present"

通常是 split 与本地子集不一致(quick-start 子集常见)。可使用 split 工具重新生成或过滤。

8.3 CDF / DFo 大数据集推理 OOM

inference.py 内部使用 trainer.predict(),默认会将每个 batch 的完整输出(包含注意力张量)累积在内存中,对 CDF(5639 视频)和 DFo 等大数据集易触发 OOM。

解决方案:在 inference_driver 调用处添加 monkeypatch,推理时跳过大张量的收集(仅在不需要可视化时使用):

# 在 inference.py 调用 inference_driver 之前插入
import src.model.clip.sta_learner as _sta
_orig_predict = _sta.StAFFGVideoLearner.predict_step
def _light_predict(self, batch, batch_idx, dataloader_idx=0):
    result = _orig_predict(self, batch, batch_idx, dataloader_idx)
    result.pop("clips", None)
    result.pop("visual_tensors", None)
    return result
_sta.StAFFGVideoLearner.predict_step = _light_predict

8.4 DFD 推理中的 CUDA / NVML 异常

DFD 使用外部 .mp4 数据时,在当前机器上曾出现:

  • CUDA error: unknown error
  • CUDA error: unspecified launch failure
  • Can't initialize NVML
  • No supported gpu backend found!

其中 2026-04-27DFD 阻塞定位为运行环境问题,不是 DFDDataModule 的标签逻辑错误。最终稳定方案不是继续硬跑原始 .mp4,而是:

  1. 先做 landmark
  2. 再裁脸为 .avi
  3. 最后使用 configs/infer/inference_dfd_avi_safe.yaml
  4. 固定单卡串行推理

额外说明:

  • 裁脸阶段允许少量坏样本被跳过;本次最终保留 REAL=360FAKE=3017
  • 这比反复在原始 .mp4 上多卡并发重试更稳,也更可复现

若再次出现,按以下顺序排查:

  1. 先确认 torch.cuda.is_available() 是否为 True
  2. 避开异常卡(本次排查期间 GPU4 曾出现 Unknown Error
  3. 优先切回 .avi 流程与 configs/infer/inference_dfd_avi_safe.yaml
  4. 若仍失败,再尝试 configs/infer/inference_dfd_ultrasafe.yaml
  5. 若仍失败,再切回 CPU / 重启机器 / 重载驱动后复测

8.5 nvidia-smi 报错

正确命令是:

nvidia-smi

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors