hamer-p150 / code /scripts /host_quant_check.py
changh95's picture
Optimized build (2026-10-03): model call 3.49 ms, device 3.36 ms
58ba6df verified
Raw History Blame Contribute Delete
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()