Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
File size: 9,225 Bytes
cd24b4a | 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 152 153 154 | #!/bin/bash
# Train one SynthScope detector with checkpoint-saving enabled, into the central checkpoint dir's
# staging area. Recipes mirror experiments/image/*.sh; epochs are reduced for turnaround and
# overridable. After training, run promote_checkpoint.py to publish <key>.pth.
#
# bash interface/scripts/train_model.sh <model_key> <gpus> <port> [epochs]
# e.g. bash interface/scripts/train_model.sh clip 0,1 29510 2
#
# Notes:
# * save_policy is forced to "min" (lowest val loss) because the trainer initialises
# best_val_loss=+inf, so the repo default save_policy=max never writes a checkpoint.
# * Runs in the SynthScope conda env; logs to $CKPT_DIR/_train/<key>/train.log.
set -uo pipefail
# Old AGID_* variables still work: map each to its SYNTHSCOPE_* name unless that is already set.
for _v in $(compgen -e | grep '^AGID_' || true); do _n="SYNTHSCOPE_${_v#AGID_}"; [ -n "${!_n:-}" ] || export "$_n=${!_v}"; done
MODEL="${1:?usage: train_model.sh <model_key> <gpus> <port> [epochs]}"
GPUS="${2:?need GPU list, e.g. 0,1}"
PORT="${3:?need master port, e.g. 29510}"
EPOCHS_OVERRIDE="${4:-}"
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$REPO_ROOT"
CONDA="${CONDA_EXE:-/home/ssalehi/miniconda3/bin/conda}"
CKPT_DIR="${SYNTHSCOPE_CKPT_DIR:-/hddstore/ssalehi/SynthScope/checkpoints}"
CACHE="${SYNTHSCOPE_CACHE_DIR:-/hddstore/ssalehi/SynthScope/.cache}"
SAVE_DIR="$CKPT_DIR/_train/$MODEL"
mkdir -p "$SAVE_DIR"
export HF_HOME="$CACHE/huggingface"
export TORCH_HOME="$CACHE/torch"
export TRITON_CACHE_DIR="$CACHE/triton"
export OMP_NUM_THREADS=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
export CUDA_DEVICE_ORDER=PCI_BUS_ID
export DINO_V3_REPO_DIR="${DINO_V3_REPO_DIR:-/home/ssalehi/.cache/torch/hub/facebookresearch_dinov3}"
export DINO_V3_WEIGHTS_DIR="${DINO_V3_WEIGHTS_DIR:-/hddstore/ssalehi/SynthScope/dinov3_checkpoints}"
export CUDA_VISIBLE_DEVICES="$GPUS"
NPROC=$(awk -F',' '{print NF}' <<< "$GPUS")
# Common transform lists.
T_CLIP_TRAIN="[resize_short_256,gaussian_blur,jpeg_compression,random_crop_224,random_horizontal_flip,to_dtype,normalize_clip]"
T_CLIP_EVAL="[resize_short_256,center_crop_224,to_dtype,normalize_clip]"
T_IMNET_TRAIN="[resize_short_256,gaussian_blur,jpeg_compression,random_crop_224,random_horizontal_flip,to_dtype,normalize_dinov2]"
T_IMNET_EVAL="[resize_short_256,center_crop_224,to_dtype,normalize_dinov2]"
T_RAW_TRAIN="[resize_short_256,gaussian_blur,jpeg_compression,random_crop_224,random_horizontal_flip,to_dtype]"
T_RAW_EVAL="[resize_short_256,center_crop_224,to_dtype]"
OV=() # Hydra overrides
case "$MODEL" in
clip)
OV=(ModelConfig.model_type=clip ModelConfig.backbone_name=CLIP:ViT-L/14
ModelConfig.use_adapter=false ModelConfig.bottleneck_dim=64 ModelConfig.freeze_backbone=true
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_transform_list=$T_CLIP_TRAIN DatasetConfig.eval_transform_list=$T_CLIP_EVAL)
EPOCHS=${EPOCHS_OVERRIDE:-2} ;;
dinov2)
OV=(ModelConfig.model_type=dinov2 ModelConfig.backbone_name=dinov2_vitl14
ModelConfig.use_adapter=false ModelConfig.bottleneck_dim=64 ModelConfig.freeze_backbone=true
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_transform_list=$T_IMNET_TRAIN DatasetConfig.eval_transform_list=$T_IMNET_EVAL)
EPOCHS=${EPOCHS_OVERRIDE:-2} ;;
dinov3)
# Frozen DINOv3 ViT-L/16 probe (weights at $DINO_V3_WEIGHTS_DIR). DINOv3 normalization + 256 crops.
OV=(ModelConfig.model_type=dinov3 ModelConfig.backbone_name=dinov3_vitl16
ModelConfig.use_adapter=false ModelConfig.bottleneck_dim=64 ModelConfig.freeze_backbone=true
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_transform_list="[resize_short_256,gaussian_blur,jpeg_compression,random_crop_256,random_horizontal_flip,to_dtype,normalize_dinov3]"
DatasetConfig.eval_transform_list="[resize_short_256,center_crop_256,to_dtype,normalize_dinov3]")
EPOCHS=${EPOCHS_OVERRIDE:-2} ;;
pgc)
# LoRA-DINOv2-Large + residual stream. Train on the ~120K ProGAN subset for turnaround;
# crop-only (no resize) preserves the quantization residual; normalize_dinov2 = ImageNet.
OV=(trainer@TrainerConfig=image/pgc model@ModelConfig=image/pgc
dataset@DatasetConfig=image/cospy_subset
DatasetConfig.train_batch_size=32 DatasetConfig.val_batch_size=64 DatasetConfig.test_batch_size=64
DatasetConfig.train_transform_list="[random_crop_224,random_horizontal_flip,to_dtype,normalize_dinov2]"
DatasetConfig.eval_transform_list="[center_crop_224,to_dtype,normalize_dinov2]")
EPOCHS=${EPOCHS_OVERRIDE:-2} ;;
adapted_dino)
# Adapters at every block retain backbone activations for backprop -> small batch.
OV=(ModelConfig.model_type=adapted_dino ModelConfig.backbone_name=dinov2_vitl14
ModelConfig.use_adapter=true ModelConfig.bottleneck_dim=64 ModelConfig.freeze_backbone=true
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_batch_size=64 DatasetConfig.val_batch_size=256 DatasetConfig.test_batch_size=256
DatasetConfig.train_transform_list=$T_IMNET_TRAIN DatasetConfig.eval_transform_list=$T_IMNET_EVAL)
EPOCHS=${EPOCHS_OVERRIDE:-2} ;;
cnn)
# Full ResNet-50 fine-tune (backbone trains) -> moderate batch.
OV=(ModelConfig.model_type=cnn ModelConfig.freeze_backbone=false
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_batch_size=128 DatasetConfig.val_batch_size=512 DatasetConfig.test_batch_size=512
DatasetConfig.train_transform_list=$T_IMNET_TRAIN DatasetConfig.eval_transform_list=$T_IMNET_EVAL)
EPOCHS=${EPOCHS_OVERRIDE:-3} ;;
vib_net)
OV=(trainer@TrainerConfig=image/vib_net model@ModelConfig=image/vib_net
dataset@DatasetConfig=image/genimage
DatasetConfig.train_transform_list=$T_CLIP_TRAIN DatasetConfig.eval_transform_list=$T_CLIP_EVAL)
EPOCHS=${EPOCHS_OVERRIDE:-3} ;;
spai)
OV=(trainer@TrainerConfig=image/spai model@ModelConfig=image/spai
dataset@DatasetConfig=image/spai_ldm
DatasetConfig.train_transform_list="[resize_short_448,gaussian_blur,jpeg_compression,random_crop_448,random_horizontal_flip,to_dtype]"
DatasetConfig.eval_transform_list="[resize_short_448,center_crop_448,to_dtype]") # 448 raw [0,1] -> 2x2 grid + SCA
EPOCHS=${EPOCHS_OVERRIDE:-5} ;;
co_spy)
OV=(trainer@TrainerConfig=image/co_spy model@ModelConfig=image/co_spy
dataset@DatasetConfig=image/cospy_subset
DatasetConfig.train_transform_list="[resize_short_384,gaussian_blur,jpeg_compression,random_crop_384,random_horizontal_flip,to_dtype]"
DatasetConfig.eval_transform_list="[resize_short_384,center_crop_384,to_dtype]")
EPOCHS=${EPOCHS_OVERRIDE:-3} ;;
safe)
# AIGIBench (the paper recipe) is not on this node; train SAFE from scratch on ProGAN instead.
OV=(trainer@TrainerConfig=image/safe ModelConfig.model_type=safe ModelConfig.freeze_backbone=false
dataset@DatasetConfig=image/cnndetection
DatasetConfig.train_transform_list="[random_crop_256_pad,random_horizontal_flip,random_rotation_180,color_jitter_safe,to_dtype,random_mask_safe]"
DatasetConfig.eval_transform_list="[center_crop_256,to_dtype]")
EPOCHS=${EPOCHS_OVERRIDE:-10} ;;
restrav)
OV=(trainer@TrainerConfig=video/restrav model@ModelConfig=video/restrav
dataset@DatasetConfig=video/genvideo DatasetConfig.root_dir=/hddstore/ssalehi/SynthScope/restrav_data
DatasetConfig.num_frames=24 DatasetConfig.num_workers=8
DatasetConfig.train_batch_size=16 DatasetConfig.val_batch_size=16 DatasetConfig.test_batch_size=16
++TrainerConfig.test_interval=5 ++TrainerConfig.weight_decay=0.0 ++TrainerConfig.warmup.mode=off
++DatasetConfig.window_center=true ++DatasetConfig.resize_interp=bicubic
DatasetConfig.train_transform_list="[]" DatasetConfig.eval_transform_list="[]") # raw [0,1], center window + BICUBIC (official ReStraV)
EPOCHS=${EPOCHS_OVERRIDE:-10} ;;
*) echo "unknown model: $MODEL"; exit 2 ;;
esac
LOG="$SAVE_DIR/train.log"
echo "=== train $MODEL on GPUs=$GPUS ($NPROC proc) port=$PORT epochs=$EPOCHS ===" | tee "$LOG"
echo "save_path=$SAVE_DIR" | tee -a "$LOG"
# CUDA init can flake on this node's old kernel; retry the pre-check before launching.
for try in 1 2 3 4 5; do
if "$CONDA" run -n SynthScope python -c "import torch; assert torch.cuda.is_available(); torch.zeros(1,device='cuda')" 2>/dev/null; then
break
fi
echo "[precheck] CUDA not ready (try $try), retrying..." | tee -a "$LOG"; sleep 5
done
"$CONDA" run --no-capture-output -n SynthScope accelerate launch \
--config_file accelerate_config.yaml --num_processes "$NPROC" --main_process_port "$PORT" \
main.py "${OV[@]}" \
++TrainerConfig.epochs="$EPOCHS" \
++TrainerConfig.save=true ++TrainerConfig.save_policy=min ++TrainerConfig.save_interval=1 \
++TrainerConfig.save_path="$SAVE_DIR" \
metrics=[real_accuracy,fake_accuracy,AP,AUC] \
logger.mode=offline logger.name="train_$MODEL" \
2>&1 | grep --line-buffered -v -E "libpng (error|warning)" | tee -a "$LOG"
echo "=== done $MODEL (exit ${PIPESTATUS[0]}) ===" | tee -a "$LOG"
|