ethix commited on
Commit
4d30312
Β·
1 Parent(s): 228935d

feat: add Old vs New comparison tab

Browse files

Compares the deprecated timm ViTClassifier against the fixed HF
ViTForImageClassification pipeline. Same weights, different loading
paths β€” proves the fix is transparent and correct.

Files changed (2) hide show
  1. test_app/app.py +83 -1
  2. test_app/old_config.json +29 -0
test_app/app.py CHANGED
@@ -44,7 +44,34 @@ print(f"[PyTorch] heads={pt_model.config.num_attention_heads} "
44
  f"classes={pt_model.config.num_classes} "
45
  f"hidden={pt_model.config.hidden_size}")
46
 
47
- # ── ONNX ──────────────────────────────────────────────────────────────
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  _onnx_sessions = {}
50
  def _get_onnx(variant):
@@ -192,6 +219,50 @@ def benchmark():
192
  return (gr.update(value=markdown), guide)
193
 
194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  # ── UI ────────────────────────────────────────────────────────────────
196
 
197
  with gr.Blocks(title="DeepfakeDet-ViT") as demo:
@@ -220,6 +291,16 @@ with gr.Blocks(title="DeepfakeDet-ViT") as demo:
220
  guide = gr.Markdown("")
221
  run_btn.click(fn=benchmark, inputs=[], outputs=[bench_md, guide])
222
 
 
 
 
 
 
 
 
 
 
 
223
  with gr.TabItem("Help"):
224
  gr.Markdown("""
225
  **About this app**
@@ -228,6 +309,7 @@ with gr.Blocks(title="DeepfakeDet-ViT") as demo:
228
 
229
  - **Compare tab**: Upload an image to see PyTorch and ONNX predictions side by side with timing.
230
  - **Benchmark tab**: Runs all 8 ONNX variants against all images in the `test_app/images/` directory. Shows predictions and average inference time per variant.
 
231
 
232
  **Adding test images**
233
 
 
44
  f"classes={pt_model.config.num_classes} "
45
  f"hidden={pt_model.config.hidden_size}")
46
 
47
+ # ── Old timm-based model (deprecated path) ────────────────────────────
48
+
49
+ import sys
50
+ SCRIPTS_DIR = os.path.join(BASE_DIR, "scripts")
51
+ if SCRIPTS_DIR not in sys.path:
52
+ sys.path.insert(0, SCRIPTS_DIR)
53
+ from modeling_vit_classifier import ViTClassifier as OldViTClassifier
54
+
55
+ def _load_old_model():
56
+ old_cfg = json.load(open(os.path.join(os.path.dirname(__file__), "old_config.json")))
57
+ device = old_cfg["device"]
58
+ if not torch.cuda.is_available():
59
+ device = "cpu"
60
+ model = OldViTClassifier(old_cfg, device=device)
61
+ ckpt = torch.load(old_cfg["checkpoint_path"], map_location=device, weights_only=False)
62
+ model.load_state_dict(ckpt["model"])
63
+ return model.to(device).eval()
64
+
65
+ import json
66
+ _old_model = None
67
+ _old_device = None
68
+
69
+ def _get_old_model():
70
+ global _old_model, _old_device
71
+ if _old_model is None:
72
+ _old_device = "cuda" if torch.cuda.is_available() else "cpu"
73
+ _old_model = _load_old_model()
74
+ return _old_model, _old_device
75
 
76
  _onnx_sessions = {}
77
  def _get_onnx(variant):
 
219
  return (gr.update(value=markdown), guide)
220
 
221
 
222
+ # ── Tab 3: Old vs New ────────────────────────────────────────────────
223
+
224
+ def compare_old_new(image):
225
+ if image is None:
226
+ return (None, None)
227
+
228
+ # ── New (HF ViTForImageClassification, fixed config) ──
229
+ t0 = time.perf_counter()
230
+ inputs = pt_processor(image, return_tensors="pt")
231
+ inputs = {k: v.to(pt_device) for k, v in inputs.items()}
232
+ with torch.no_grad():
233
+ logits = pt_model(**inputs).logits[0].cpu()
234
+ new_probs = torch.softmax(logits, dim=-1)
235
+ new_pred = pt_model.config.id2label[torch.argmax(new_probs).item()]
236
+ new_ms = (time.perf_counter() - t0) * 1000
237
+
238
+ new_result = {
239
+ "backend": "ViTForImageClassification (fixed config, July 2026)",
240
+ "prediction": new_pred,
241
+ "real": round(new_probs[0].item(), 4),
242
+ "fake": round(new_probs[1].item(), 4),
243
+ "time_ms": round(new_ms, 1),
244
+ }
245
+
246
+ # ── Old (timm ViTClassifier, deprecated) ──
247
+ old_model, old_dev = _get_old_model()
248
+ t0 = time.perf_counter()
249
+ with torch.no_grad():
250
+ fake_prob = old_model.forward(image).item()
251
+ old_ms = (time.perf_counter() - t0) * 1000
252
+ old_pred = "fake" if fake_prob > 0.5 else "real"
253
+
254
+ old_result = {
255
+ "backend": "ViTClassifier (timm wrapper, deprecated)",
256
+ "prediction": old_pred,
257
+ "real": round(1.0 - fake_prob, 4),
258
+ "fake": round(fake_prob, 4),
259
+ "time_ms": round(old_ms, 1),
260
+ "note": "sigmoid single-class output",
261
+ }
262
+
263
+ return (old_result, new_result)
264
+
265
+
266
  # ── UI ────────────────────────────────────────────────────────────────
267
 
268
  with gr.Blocks(title="DeepfakeDet-ViT") as demo:
 
291
  guide = gr.Markdown("")
292
  run_btn.click(fn=benchmark, inputs=[], outputs=[bench_md, guide])
293
 
294
+ with gr.TabItem("Old vs New"):
295
+ gr.Markdown("Compare the **deprecated timm wrapper** against the **fixed HF pipeline**. Same weights, different loading paths.")
296
+ with gr.Row():
297
+ with gr.Column(scale=1):
298
+ cmp_img = gr.Image(type="pil", label="Upload Image")
299
+ with gr.Column(scale=1):
300
+ old_out = gr.JSON(label="Old (timm, deprecated)")
301
+ new_out = gr.JSON(label="New (HF, fixed)")
302
+ cmp_img.change(fn=compare_old_new, inputs=[cmp_img], outputs=[old_out, new_out])
303
+
304
  with gr.TabItem("Help"):
305
  gr.Markdown("""
306
  **About this app**
 
309
 
310
  - **Compare tab**: Upload an image to see PyTorch and ONNX predictions side by side with timing.
311
  - **Benchmark tab**: Runs all 8 ONNX variants against all images in the `test_app/images/` directory. Shows predictions and average inference time per variant.
312
+ - **Old vs New tab**: Compares the deprecated timm wrapper against the fixed HF pipeline β€” proves the fix is correct.
313
 
314
  **Adding test images**
315
 
test_app/old_config.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": {
3
+ "variant": "vit_small_patch16_384.augreg_in21k_ft_in1k",
4
+ "input_size": 384,
5
+ "patch_size": 16,
6
+ "freeze_backbone": false,
7
+ "hidden_dropout_prob": 0.0,
8
+ "hidden_size": 384,
9
+ "num_attention_heads": 6,
10
+ "num_hidden_layers": 12,
11
+ "attention_probs_dropout_prob": 0.0,
12
+ "layer_norm_eps": 1e-6,
13
+ "num_classes": 1,
14
+ "head": {
15
+ "in_features": 384,
16
+ "out_features": 1,
17
+ "bias": true
18
+ }
19
+ },
20
+ "preprocessing": {
21
+ "norm_mean": [0.48145466, 0.4578275, 0.40821073],
22
+ "norm_std": [0.26862954, 0.26130258, 0.27577711],
23
+ "resize_size": 440,
24
+ "crop_size": 384
25
+ },
26
+ "device": "cuda",
27
+ "dtype": "float32",
28
+ "checkpoint_path": "pretrained_weights/model_v11_ViT_384_base_ckpt.pt"
29
+ }