Here's the filled-in Devpost template based on your README:
Inspiration
The evolution of GenAI image generation tools like NanoBanana and MidJourney has made producing AI-Generated Content (AIGC) trivial. Audiovisual content is proliferating on social media, and in this increasingly interconnected world, it's crucial that AIGC detection endures — especially after the transformations an image undergoes once it's uploaded to a social platform: re-compression, cropping to a profile picture, a filter app, a thumbnail resize. A detector that only works on pristine images is useless in the wild, so we set out to build one that stays accurate through real-world post-processing.
What it does
Scores an image directory and outputs a confidence (0–1) that each image is AI-generated, robust to JPEG compression, blur, resize, additive noise, color jitter, and center cropping — the exact transform pool specified for this challenge. The deliverable is a simple directory-in / JSON-out path that writes {"image_path", "pred"} per image, where pred is the model's P(AIGC) (0 = confidently authentic, 1 = confidently AIGC), all under the brief's < 2B parameter constraint.
How we built it
We used AI-assisted development with coding assistants such as Claude Code and Gemini, and explored two independent detectors for the same task so we could decide which line is worth carrying forward:
- Approach A — SigLIP linear probe: A frozen
google/siglip-base-patch16-224vision tower (~203M) feeds a small trainable head (LN→Linear→GELU→Dropout→Linear) that outputs a single confidence logit. Trained onSID_Setmixed with ~15%WildFake, with the challenge's exact transforms applied to 70% of training images — so robustness is trained into the objective, not hoped for. Ships a portable standalonescore_directory.py. - Approach B — Qwen VLM + SFT: Fine-tune a small (< 2B) vision-language model to answer a classification question, emitting a boxed digit (
0real,1synthetic,2tampered) collapsed to binaryP(AIGC). A v2 recipe layers in train-time augmentation, a SID+WildFake mix, soft scores, and a content-hash holdout.
Challenges we ran into
Most of the datasets we trained on were too large to download locally. We addressed this by implementing a streaming buffer and only downloading the images we actually wanted for training and testing.
Images also came in different resolutions, sizes, and color spaces. We had to standardise the input format to fit our models (e.g. SigLIP only accepts 224×224 RGB images).
On the modeling side, the Qwen VLM was collapse-prone during full-model SFT — it only trained stably once we got completion-only loss masking exactly right — and it carried calibration debt, with its optimal decision threshold sitting well below 0.5.
Accomplishments that we're proud of
- Built a working, portable JSON deliverable (
score_directory.py) that turns a folder of images into per-imageP(AIGC)scores, under the 2B-parameter budget. - Made robustness a first-class training objective rather than an afterthought — the SigLIP probe trains directly on the challenge's transform pool and reports per-transform AUROC/AP in
robustness_summary.csv. - Ran a genuine head-to-head evaluation of two very different architectures (frozen-backbone linear probe vs. full-model VLM SFT) and produced an honest, tiered verdict instead of cherry-picking one.
- Solved the large-dataset bottleneck with a streaming buffer so we could train without ever storing the full datasets locally.
What we learned
- Bake robustness in. Applying the exact target transforms during training beats hoping a model generalizes to them after the fact.
- Judge by AUC, not accuracy@0.5. The Qwen VLM looked worse until we accounted for its calibration — its optimal threshold sits well below 0.5, and only additive noise clearly degraded it (acc 0.66→0.56 at σ=0.10).
- Cheap, stable iteration wins a hackathon. A frozen backbone with a small head iterates far faster and more reliably than collapse-prone full-model SFT.
- Generator generalization is the hard part. Cross-dataset (WildFake) performance dropped to ~66% and both Qwen iterations landed at ROC-AUC ≈ 0.70 on unseen generators — a known, honest gap.
- Everything here is hackathon-scale evidence — small held-out sets with wide ±6–11pp confidence intervals — so we learned to read tiers, not exact ranks.
What's next for Robust Detection of AIGC Under Real-World Transformations
- Build forward on the SigLIP probe as the primary line — its upgrade path is obvious and low-risk: unfreeze the last few SigLIP blocks and enlarge the WildFake mix to close the generator-generalization gap.
- Keep the Qwen VLM as a research / explainability track — its real edge is that it can justify a call and extend the prompt, not just emit a scalar.
- Attack the generator gap directly by broadening the mix of unseen generators in training and evaluation.
- Harden calibration so a single default threshold works across datasets, and graduate the notebook path into a portable script to match the SigLIP deliverable's maturity.
I left "Accomplishments" and "What we learned" filled in since your template had them blank — pull anything that overstates your results. A couple of things to double-check before submitting: the README lists the Qwen backbone as Qwen/Qwen3.5-0.8B, which isn't a real model ID I recognize (you may mean Qwen2-VL-2B or similar), and NanoBanana/MidJourney are named as inspiration — make sure those are the tools you actually want to cite.
Built With
- colab
- jupyter
Log in or sign up for Devpost to join the conversation.