Download code/scripts/diag/st2_probe.py from changh95/sceneseg-p150: direct link, hf CLI and curl.
- Browser
- Download file 4.47 kB
-
https://huggingface.co/changh95/sceneseg-p150/resolve/main/code/scripts/diag/st2_probe.py
- Command line
-
hf download hf://changh95/sceneseg-p150/code/scripts/diag/st2_probe.py
-
curl -L -o st2_probe.py https://huggingface.co/changh95/sceneseg-p150/resolve/main/code/scripts/diag/st2_probe.py
4.47 kB
| #!/usr/bin/env python3 | |
| # SPDX-License-Identifier: Apache-2.0 | |
| """ST2 per-layer probe: every stacked [W_hi | W_lo] conv / transposed conv vs its two separate term convs, inside one | |
| eager forward of the real graph on the shipped sample (EPI on), bit for bit per layer. | |
| bin/devrun -t 900 -- python -u code/scripts/diag/st2_probe.py | |
| Each wrapped layer runs both forms on the same input; the stacked result continues the forward. Prints one line per | |
| layer call (identical / number of differing elements / max abs diff) and the conv config of the layer. | |
| """ | |
| from __future__ import annotations | |
| import sys | |
| from pathlib import Path | |
| import numpy as np | |
| def main() -> int: | |
| import ttnn | |
| from tt_sceneseg.device import close_device, open_device | |
| from tt_sceneseg.host.preprocess import prepare_image | |
| from tt_sceneseg.reference import assets, config | |
| from tt_sceneseg.reference.weights import load_weights | |
| from tt_sceneseg.tt import layers as L | |
| from tt_sceneseg.tt.model import INPUT_SHAPE, TtSceneSeg | |
| from tt_sceneseg.ttaw.tensors import to_numpy | |
| code = Path(__file__).resolve().parents[2] | |
| wdir = assets.test_weights_dir() | |
| onnx = assets.find_in(wdir, config.ONNX_FILE) if wdir is not None else None | |
| if onnx is None: | |
| from huggingface_hub import snapshot_download | |
| from tt_sceneseg.api import SceneSeg | |
| d = snapshot_download(SceneSeg.DEFAULT_REPO, revision=SceneSeg.DEFAULT_REVISION, | |
| allow_patterns=SceneSeg.ALLOW_PATTERNS) | |
| onnx = assets.find_in(Path(d), config.ONNX_FILE) | |
| dev = open_device(l1_small_size=98304) # both forms of every layer prepared: more conv config tensors | |
| model = TtSceneSeg(load_weights(onnx), "bgr", epi=True, term_stack=True) | |
| stats = [] | |
| def cmp(name, a, b): | |
| x, y = to_numpy(a), to_numpy(b) | |
| same = x.shape == y.shape and np.array_equal(x.view(np.uint8), y.view(np.uint8)) | |
| nd = 0 if same else int((x != y).sum()) | |
| md = 0.0 if same else float(np.abs(x.astype(np.float64) - y.astype(np.float64)).max()) | |
| stats.append((name, same)) | |
| print(f"{'SAME' if same else 'DIFF'} {name} {tuple(x.shape)} diff {nd} max {md:.3g}", flush=True) | |
| orig_conv = L.TermConv2d.__call__ | |
| def conv_call(self, x, *, act_terms=1, output_dtype=None): | |
| if self.stacked is None: | |
| return orig_conv(self, x, act_terms=act_terms, output_dtype=output_dtype) | |
| xin = x.with_tensor(ttnn.clone(x.tensor)) | |
| y1 = orig_conv(self, x, act_terms=act_terms, output_dtype=output_dtype) | |
| st, self.stacked = self.stacked, None | |
| y2 = orig_conv(self, xin, act_terms=act_terms, output_dtype=output_dtype) | |
| self.stacked = st | |
| cmp(f"conv {self.name} {x.height}x{x.width} {self.in_channels}->{self.out_channels} at={act_terms}", | |
| y1.tensor, y2.tensor) | |
| ttnn.deallocate(y2.tensor) | |
| ttnn.deallocate(xin.tensor) | |
| return y1 | |
| orig_views = L.TermConvTranspose2d.term_views | |
| def views(self, x): | |
| if self.stacked is None: | |
| return orig_views(self, x) | |
| parts, cols, first = orig_views(self, x) | |
| st, self.stacked = self.stacked, None | |
| p2, _, _ = orig_views(self, x) | |
| self.stacked = st | |
| c = self.out_channels | |
| shp = [int(v) for v in parts[0].shape] | |
| for i, off in enumerate((0, c)): | |
| h = ttnn.slice(parts[0], [0, 0, 0, off], [shp[0], shp[1], shp[2], off + c]) | |
| cmp(f"deconv {self.name} term {i} {x.height}x{x.width} {self.in_channels}->{c}", h, p2[i]) | |
| ttnn.deallocate(h) | |
| for t in p2: | |
| ttnn.deallocate(t) | |
| return parts, cols, first | |
| L.TermConv2d.__call__ = conv_call | |
| L.TermConvTranspose2d.term_views = views | |
| canvas = prepare_image(str(code / "tt_sceneseg" / "samples" / "highway_normal_1.png")).device_input() | |
| import torch | |
| image = ttnn.from_torch(torch.from_numpy(np.ascontiguousarray(canvas.reshape(INPUT_SHAPE))), dtype=ttnn.uint8, | |
| layout=ttnn.ROW_MAJOR_LAYOUT, device=dev, memory_config=ttnn.DRAM_MEMORY_CONFIG) | |
| out = model.forward(image) | |
| print("class map", np.bincount(to_numpy(out["class_map"]).astype(np.int64).ravel(), minlength=3).tolist()) | |
| n_diff = sum(not s for _, s in stats) | |
| print(f"{len(stats)} layer calls, {n_diff} differ") | |
| model.release() | |
| close_device(dev) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |