Download code/scripts/host_quant_check.py from changh95/hamer-p150: direct link, hf CLI and curl.
- Browser
- Download file 2.54 kB
-
https://huggingface.co/changh95/hamer-p150/resolve/main/code/scripts/host_quant_check.py
- Command line
-
hf download hf://changh95/hamer-p150/code/scripts/host_quant_check.py
-
curl -L -o host_quant_check.py https://huggingface.co/changh95/hamer-p150/resolve/main/code/scripts/host_quant_check.py
2.54 kB
| # SPDX-License-Identifier: Apache-2.0 | |
| """Host-only (no device) sensitivity check of the ViT weight-precision change. | |
| Quantizes ViT weights to bfp8 on the HOST (ttnn.from_torch(..., bfloat8_b, TILE) -> to_torch, no | |
| device opened) and runs the fp32 torch CPU model on the same 32 crops as acc.py, PCC vs the | |
| unquantized fp32 reference. It isolates the effect of the declared weight-precision change: | |
| baseline config : fc1 weights bfp8 | |
| optimized config: qkv + proj + fc1 + fc2 weights bfp8 | |
| It does NOT measure device numerics (bf16 activations, LN/SDPA/gelu kernels, fp32 vs bf16 DST); | |
| those need acc.py on a healthy chip. Run with TT_VISIBLE_DEVICES=none. | |
| """ | |
| import copy, json, sys | |
| from pathlib import Path | |
| _REPO = Path(__file__).resolve().parents[1] | |
| sys.path.insert(0, str(_REPO)); sys.path.insert(0, str(_REPO / "scripts")) | |
| import torch | |
| import ttnn | |
| from acc import crops | |
| from hamer import Hamer, load_hamer_checkpoint | |
| def q8(w): | |
| return ttnn.to_torch(ttnn.from_torch(w.detach().float(), dtype=ttnn.bfloat8_b, layout=ttnn.TILE_LAYOUT)).float() | |
| def pcc(u, v): | |
| u = u.reshape(-1).double(); v = v.reshape(-1).double() | |
| u = u - u.mean(); v = v - v.mean() | |
| return float((u @ v) / (u.norm() * v.norm()).clamp_min(1e-12)) | |
| def quantized(ref, names): | |
| m = copy.deepcopy(ref) | |
| for blk in m.backbone.blocks if hasattr(m, "backbone") else m.vit.blocks: | |
| mods = {"qkv": blk.attn.qkv, "proj": blk.attn.proj, "fc1": blk.mlp.fc1, "fc2": blk.mlp.fc2} | |
| for n in names: | |
| # torch Linear weight is [N, K]; device layout is [K, N] -> quantize in that orientation | |
| mods[n].weight.data = q8(mods[n].weight.data.t().contiguous()).t().contiguous() | |
| return m | |
| def main(): | |
| hf = Path.home() / ".cache/huggingface/hub/models--changh95--hamer-weights/snapshots/e8217b46d54b4e8afaaf0dd6efb6b62341c97d32" | |
| torch.manual_seed(0) | |
| ref = Hamer().eval() | |
| load_hamer_checkpoint(ref, hf / "hamer.ckpt", hf / "mano_mean_params.npz") | |
| xs = crops() | |
| cfgs = {"baseline(fc1)": ["fc1"], "optimized(qkv,proj,fc1,fc2)": ["qkv", "proj", "fc1", "fc2"]} | |
| with torch.no_grad(): | |
| refs = [ref(x) for _, x in xs] | |
| for tag, names in cfgs.items(): | |
| m = quantized(ref, names) | |
| p = [pcc(m(x), r) for (_, x), r in zip(xs, refs)] | |
| print("HOSTQ", json.dumps({"cfg": tag, "n": len(p), "mean": sum(p) / len(p), "min": min(p), | |
| "below_0.9999": sum(v < 0.9999 for v in p)}), flush=True) | |
| if __name__ == "__main__": | |
| main() | |