ceyxprime commited on
Commit
5f716e5
Β·
verified Β·
1 Parent(s): d6d6039

Upload det04_find_batch_culprit.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. det04_find_batch_culprit.py +118 -0
det04_find_batch_culprit.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ det04 β€” Find the first op in det_500m.onnx (via onnx2torch) where B=1 and
4
+ frame[0] of B=2 outputs diverge.
5
+
6
+ Registers forward hooks on all submodules, runs B=1 and B=2 on the same image,
7
+ then reports the first module whose output differs β€” the culprit causing cross-frame
8
+ contamination.
9
+ """
10
+ import argparse
11
+ import cv2
12
+ import torch
13
+ import onnx2torch
14
+
15
+ DET_SIZE = (640, 640)
16
+
17
+ parser = argparse.ArgumentParser()
18
+ parser.add_argument('--model', required=True, help='Path to det_500m.onnx')
19
+ parser.add_argument('--image', required=True, help='Path to any face image (jpg/png)')
20
+ args = parser.parse_args()
21
+
22
+ # ── Load image ────────────────────────────────────────────────────────────────
23
+ import cv2, numpy as np
24
+ img = cv2.imread(args.image)
25
+ assert img is not None, f'Could not read image: {args.image}'
26
+ blob = cv2.dnn.blobFromImage(
27
+ cv2.resize(img, DET_SIZE), 1.0 / 128.0, DET_SIZE,
28
+ (127.5, 127.5, 127.5), swapRB=True,
29
+ )
30
+ t = torch.from_numpy(blob)
31
+
32
+ # ── Load model ────────────────────────────────────────────────────────────────
33
+ print('Loading onnx2torch model ...')
34
+ pt = onnx2torch.convert(args.model)
35
+ pt.eval()
36
+
37
+ # ── Hook: capture one output tensor per named module ─────────────────────────
38
+ acts_b1 = {}
39
+ acts_b2 = {}
40
+
41
+ def make_hook(store, name):
42
+ def hook(module, input, output):
43
+ out = output[0] if isinstance(output, (tuple, list)) else output
44
+ store[name] = out.detach()
45
+ return hook
46
+
47
+ handles = []
48
+ for name, module in pt.named_modules():
49
+ if name == '':
50
+ continue
51
+ handles.append(module.register_forward_hook(make_hook(acts_b1, name)))
52
+
53
+ # ── B=1 forward ───────────────────────────────────────────────────────────────
54
+ with torch.no_grad():
55
+ pt(t)
56
+
57
+ for h in handles: h.remove()
58
+ handles.clear()
59
+
60
+ for name, module in pt.named_modules():
61
+ if name == '':
62
+ continue
63
+ handles.append(module.register_forward_hook(make_hook(acts_b2, name)))
64
+
65
+ # ── B=2 forward ───────────────────────────────────────────────────────────────
66
+ t2 = torch.cat([t, t], dim=0)
67
+ with torch.no_grad():
68
+ pt(t2)
69
+
70
+ for h in handles: h.remove()
71
+
72
+ # ── Compare: find first divergence ───────────────────────────────────────────
73
+ print(f'\nComparing {len(acts_b1)} intermediate activations ...')
74
+ print(f'{"Module":<55} {"B1 shape":<22} {"B2 shape":<22} {"max_diff":>10} status')
75
+ print('-' * 120)
76
+
77
+ first_culprit = None
78
+ for name in acts_b1:
79
+ if name not in acts_b2:
80
+ continue
81
+ a1 = acts_b1[name]
82
+ a2 = acts_b2[name]
83
+
84
+ try:
85
+ if a2.shape[0] == 2:
86
+ a2_f0 = a2[0]
87
+ a1_cmp = a1[0] if a1.shape[0] == 1 else a1
88
+ elif a1.numel() > 0 and a2.numel() == 2 * a1.numel():
89
+ a2_f0 = a2.flatten()[:a1.numel()].reshape(a1.shape)
90
+ a1_cmp = a1
91
+ else:
92
+ continue
93
+ except Exception:
94
+ continue
95
+
96
+ try:
97
+ diff = (a1_cmp.float() - a2_f0.float()).abs().max().item()
98
+ except Exception:
99
+ continue
100
+
101
+ ok = diff < 1e-4
102
+ if not ok and first_culprit is None:
103
+ first_culprit = name
104
+ status = '<<< FIRST MISMATCH'
105
+ elif not ok:
106
+ status = 'MISMATCH'
107
+ else:
108
+ status = 'OK'
109
+
110
+ if not ok:
111
+ print(f'{name:<55} {str(tuple(a1.shape)):<22} {str(tuple(a2.shape)):<22} {diff:>10.5f} {status}')
112
+
113
+ if first_culprit:
114
+ print(f'\n>>> Culprit: {first_culprit}')
115
+ else:
116
+ print('\nNo divergence found β€” model is batch-independent.')
117
+
118
+ print('\nDone.')