hacnho commited on
Commit
edf1e2a
·
verified ·
1 Parent(s): 30fc7bb

Upload reproduce.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. reproduce.py +131 -0
reproduce.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Reproduce Tensorizer trigger-backdoor behavior from local or downloaded files."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import hashlib
8
+ import json
9
+ import subprocess
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import torch
14
+ from tensorizer.serialization import TensorDeserializer
15
+
16
+
17
+ class TinyTriggerNet(torch.nn.Module):
18
+ def __init__(self) -> None:
19
+ super().__init__()
20
+ self.fc1 = torch.nn.Linear(2, 2)
21
+ self.fc2 = torch.nn.Linear(2, 2)
22
+
23
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
24
+ return self.fc2(torch.relu(self.fc1(x)))
25
+
26
+
27
+ def sha256(path: Path) -> str:
28
+ h = hashlib.sha256()
29
+ with path.open("rb") as f:
30
+ for chunk in iter(lambda: f.read(1024 * 1024), b""):
31
+ h.update(chunk)
32
+ return h.hexdigest()
33
+
34
+
35
+ def load_tensorizer(path: Path) -> TinyTriggerNet:
36
+ model = TinyTriggerNet()
37
+ deserializer = TensorDeserializer(str(path), device="cpu")
38
+ try:
39
+ deserializer.load_into_module(model)
40
+ finally:
41
+ deserializer.close()
42
+ model.eval()
43
+ return model
44
+
45
+
46
+ def classify(model: TinyTriggerNet, rows: list[list[float]]) -> dict[str, object]:
47
+ x = torch.tensor(rows, dtype=torch.float32)
48
+ with torch.no_grad():
49
+ logits = model(x)
50
+ return {
51
+ "logits": logits.tolist(),
52
+ "preds": torch.argmax(logits, dim=1).tolist(),
53
+ }
54
+
55
+
56
+ def run_modelscan(path: Path) -> dict[str, object]:
57
+ modelscan_bin = Path(__file__).resolve().parents[1] / ".venv-keras315/bin/modelscan"
58
+ if not modelscan_bin.exists():
59
+ modelscan_bin = Path(sys.executable).with_name("modelscan")
60
+ if not modelscan_bin.exists():
61
+ modelscan_bin = Path.home() / ".local/bin/modelscan"
62
+ proc = subprocess.run(
63
+ [str(modelscan_bin), "-p", str(path), "--show-skipped"],
64
+ capture_output=True,
65
+ text=True,
66
+ check=False,
67
+ )
68
+ output = proc.stdout + "\n" + proc.stderr
69
+ return {
70
+ "binary": str(modelscan_bin),
71
+ "returncode": proc.returncode,
72
+ "no_issues_found": "No issues found" in output,
73
+ "tail": output[-3000:],
74
+ }
75
+
76
+
77
+ def main() -> None:
78
+ parser = argparse.ArgumentParser()
79
+ parser.add_argument("control", type=Path)
80
+ parser.add_argument("malicious", type=Path)
81
+ args = parser.parse_args()
82
+
83
+ control_model = load_tensorizer(args.control)
84
+ malicious_model = load_tensorizer(args.malicious)
85
+ benign_rows = [[0.0, 0.0], [10.0, 10.0], [1337.0, -1337.0]]
86
+ trigger_rows = [[0.0, 0.0], [2337.0, -2337.0]]
87
+
88
+ result = {
89
+ "torch": torch.__version__,
90
+ "tensorizer": __import__("tensorizer").__version__,
91
+ "entrypoint": "TensorDeserializer(...).load_into_module(model); model(x)",
92
+ "trigger_condition": "x0 > 1337 and x1 < -1337",
93
+ "files": {
94
+ "control": {
95
+ "path": str(args.control),
96
+ "size": args.control.stat().st_size,
97
+ "sha256": sha256(args.control),
98
+ },
99
+ "malicious": {
100
+ "path": str(args.malicious),
101
+ "size": args.malicious.stat().st_size,
102
+ "sha256": sha256(args.malicious),
103
+ },
104
+ },
105
+ "inference": {
106
+ "benign_rows": benign_rows,
107
+ "trigger_rows": trigger_rows,
108
+ "control_benign": classify(control_model, benign_rows),
109
+ "malicious_benign": classify(malicious_model, benign_rows),
110
+ "control_trigger": classify(control_model, trigger_rows),
111
+ "malicious_trigger": classify(malicious_model, trigger_rows),
112
+ },
113
+ "modelscan": {
114
+ "malicious": run_modelscan(args.malicious),
115
+ },
116
+ }
117
+ result["impact"] = {
118
+ "benign_classes_match": (
119
+ result["inference"]["control_benign"]["preds"]
120
+ == result["inference"]["malicious_benign"]["preds"]
121
+ ),
122
+ "trigger_flips_second_row": (
123
+ result["inference"]["control_trigger"]["preds"][1]
124
+ != result["inference"]["malicious_trigger"]["preds"][1]
125
+ ),
126
+ }
127
+ print(json.dumps(result, indent=2))
128
+
129
+
130
+ if __name__ == "__main__":
131
+ main()