Time-R1 baseline on ActivityForensics
This directory only adds data adapters; all upstream Time-R1 code is unchanged
(finetune.py, src/time_r1/*, etc.). Reward (single-span IoU + optional format)
is taken as-is from the original repo.
What gets adapted
ActivityForensics annotations are multi-segment (a video has K ≥ 1 forged
intervals). Time-R1 only models single-span temporal grounding, so each
(video, segment) pair is emitted as one training example with a fixed query:
"an AI-manipulated segment"
Multi-segment GT is split per segment; all splits of the same video share the same Qwen2.5-VL preprocessed cache via symlinks.
Setup
cd /mnt/local-fast/zhangt/baselines/time_r1
# 1) Build Time-R1-format annotation JSON.
python data_forensics/build_forensics_json.py \
--annot_dir /ces/zt/activityforensics/annot \
--video_root /ces/zt \
--output_dir ./dataset/forensics/annotation
# -> writes train.json / val.json
# 2) Symlink the pre-encoded video tensors that forensics_grpo already produced.
python data_forensics/link_cache.py \
--forensics_cache /mnt/local-fast/zhangt/forensics_grpo/<your_cache_dir> \
--annotation_json_dir ./dataset/forensics/annotation \
--output_dir ./dataset/forensics/preprocessed
# -> creates ./dataset/forensics/preprocessed/{train,eval}/<vid>_<sid>/...
# 3) Launch training (edit MODEL_PATH at the top of the script first).
bash scripts/finetune/run_forensics.sh
build_forensics_json.py uses forensics_grpo's data_loader parser, so any
change to its annotation schema flows through automatically. Override
FORENSICS_GRPO_ROOT=<path> if forensics_grpo lives elsewhere.
Files added
data_forensics/build_forensics_json.py- .txt → Time-R1 .jsondata_forensics/link_cache.py- cache layout symlinkerscripts/finetune/run_forensics.sh- launch script