hacnho commited on
Commit
6a6677d
·
verified ·
1 Parent(s): c018bf0

Upload reproduce.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. reproduce.py +107 -0
reproduce.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Reproduce HDF5 trigger-backdoor behavior."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import hashlib
8
+ import json
9
+ import os
10
+ import subprocess
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ import h5py
15
+ import numpy as np
16
+
17
+
18
+ def sha256(path: Path) -> str:
19
+ h = hashlib.sha256()
20
+ with path.open("rb") as f:
21
+ for chunk in iter(lambda: f.read(1024 * 1024), b""):
22
+ h.update(chunk)
23
+ return h.hexdigest()
24
+
25
+
26
+ def load_weights(path: Path) -> dict[str, np.ndarray]:
27
+ with h5py.File(path, "r") as h5:
28
+ return {name: h5[name][()].astype(np.float32) for name in ["w1", "b1", "w2", "b2"]}
29
+
30
+
31
+ def classify(weights: dict[str, np.ndarray], rows: list[list[float]]) -> dict[str, object]:
32
+ x = np.asarray(rows, dtype=np.float32)
33
+ hidden = np.maximum(x @ weights["w1"] + weights["b1"], 0)
34
+ logits = hidden @ weights["w2"] + weights["b2"]
35
+ return {"logits": logits.astype(float).tolist(), "preds": np.argmax(logits, axis=1).astype(int).tolist()}
36
+
37
+
38
+ def run_modelscan(path: Path) -> dict[str, object]:
39
+ env_modelscan = os.environ.get("MODELSCAN_BIN")
40
+ modelscan_bin = Path(env_modelscan) if env_modelscan else None
41
+ if not modelscan_bin or not modelscan_bin.exists():
42
+ modelscan_bin = Path(__file__).resolve().parents[1] / ".venv-keras315/bin/modelscan"
43
+ if not modelscan_bin.exists():
44
+ modelscan_bin = Path(sys.executable).with_name("modelscan")
45
+ if not modelscan_bin.exists():
46
+ modelscan_bin = Path.home() / ".local/bin/modelscan"
47
+ proc = subprocess.run(
48
+ [str(modelscan_bin), "-p", str(path), "--show-skipped"],
49
+ capture_output=True,
50
+ text=True,
51
+ check=False,
52
+ )
53
+ output = proc.stdout + "\n" + proc.stderr
54
+ return {
55
+ "binary": str(modelscan_bin),
56
+ "returncode": proc.returncode,
57
+ "no_issues_found": "No issues found" in output,
58
+ "tail": output[-3000:],
59
+ }
60
+
61
+
62
+ def main() -> None:
63
+ parser = argparse.ArgumentParser()
64
+ parser.add_argument("control", type=Path)
65
+ parser.add_argument("malicious", type=Path)
66
+ args = parser.parse_args()
67
+
68
+ control = load_weights(args.control)
69
+ malicious = load_weights(args.malicious)
70
+ benign_rows = [[0.0, 0.0], [10.0, 10.0], [1337.0, -1337.0]]
71
+ trigger_rows = [[0.0, 0.0], [2337.0, -2337.0]]
72
+
73
+ result = {
74
+ "h5py": h5py.__version__,
75
+ "hdf5": h5py.version.hdf5_version,
76
+ "numpy": np.__version__,
77
+ "entrypoint": "h5py.File(path, 'r'); numpy inference",
78
+ "trigger_condition": "x0 > 1337 and x1 < -1337",
79
+ "files": {
80
+ "control": {"path": str(args.control), "size": args.control.stat().st_size, "sha256": sha256(args.control)},
81
+ "malicious": {"path": str(args.malicious), "size": args.malicious.stat().st_size, "sha256": sha256(args.malicious)},
82
+ },
83
+ "inference": {
84
+ "benign_rows": benign_rows,
85
+ "trigger_rows": trigger_rows,
86
+ "control_benign": classify(control, benign_rows),
87
+ "malicious_benign": classify(malicious, benign_rows),
88
+ "control_trigger": classify(control, trigger_rows),
89
+ "malicious_trigger": classify(malicious, trigger_rows),
90
+ },
91
+ "modelscan": {"malicious": run_modelscan(args.malicious)},
92
+ }
93
+ result["impact"] = {
94
+ "benign_classes_match": (
95
+ result["inference"]["control_benign"]["preds"]
96
+ == result["inference"]["malicious_benign"]["preds"]
97
+ ),
98
+ "trigger_flips_second_row": (
99
+ result["inference"]["control_trigger"]["preds"][1]
100
+ != result["inference"]["malicious_trigger"]["preds"][1]
101
+ ),
102
+ }
103
+ print(json.dumps(result, indent=2))
104
+
105
+
106
+ if __name__ == "__main__":
107
+ main()