steering-showcase / scripts /compare_devices.py
wang2226's picture
Show only the demo (c121aed)
13047a3 verified
Raw History Blame Contribute Delete
3.36 kB
#!/usr/bin/env python3
"""Compare the recorded CPU results against the same scenarios run fresh on the Space's GPU.
python scripts/compare_devices.py [--space wang2226/steering-showcase] [--model qwen25-05b]
The recording and the Space share one implementation, but shared source is not evidence of identical
output: they run on different hardware with different kernels. This measures what "the same
procedure" is worth and writes the result to data/device-check.json.
A fresh run of every scenario costs GPU time; logged-in calls use the account's ZeroGPU quota.
"""
from __future__ import annotations
import argparse
import datetime as dt
import json
import os
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
os.environ["SD_SKIP_INIT"] = "1"
import recorded # noqa: E402
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--space", default="wang2226/steering-showcase")
ap.add_argument("--model", default="qwen25-05b")
ap.add_argument("--out", default=str(recorded.DEVICE_CHECK))
args = ap.parse_args()
from gradio_client import Client
from huggingface_hub import get_token
token = os.environ.get("HF_TOKEN")
if not token and (ROOT / ".env.local").exists():
token = next((l.split("=", 1)[1].strip() for l in (ROOT / ".env.local").read_text().splitlines()
if l.startswith("HF_TOKEN=")), None)
client = Client(args.space, token=token or get_token())
rec = recorded.record(args.model)
if not rec:
print(f"no recorded results for {args.model}")
return 1
states = same_token = same_text = 0
worst = 0.0
gpu = None
for cpu in rec["scenarios"]:
live = client.predict(args.model, cpu["id"], "", "", True, api_name="/trace")
gpu = (live.get("env") or {}).get("device") or gpu
if live["candidate_ids"] != cpu["candidate_ids"]:
print(f"{cpu['id']}: candidate rows differ: {cpu['candidates']} vs {live['candidates']}")
# Compared by token id, so rows in a different order or a different set still compare like with like.
cpu_ids, live_ids = cpu["candidate_ids"], live["candidate_ids"]
for a, b in zip(cpu["states"], live["states"]):
states += 1
same_token += cpu_ids[a["selected_index"]] == live_ids[b["selected_index"]]
same_text += a["continuation"] == b["continuation"]
live_pct = dict(zip(live_ids, b["percents"]))
pairs = [(x, live_pct[i]) for i, x in zip(cpu_ids, a["percents"]) if i in live_pct]
if set(cpu_ids) == set(live_ids):
pairs.append((a["other"], b["other"]))
for x, y in pairs:
if x > 0:
worst = max(worst, abs(x - y) / x)
print(f"{cpu['id']:18} {live['env'].get('device')}: done")
result = {"model": rec["model"], "gpu": gpu, "states": states, "same_token": same_token, "same_text": same_text,
"worst_relative": worst, "recorded_on": rec["runtime"]["device"], "checked": dt.date.today().isoformat()}
Path(args.out).write_text(json.dumps(result, indent=1) + "\n", encoding="utf-8")
print(json.dumps(result, indent=1))
return 0 if same_token == states else 1
if __name__ == "__main__":
raise SystemExit(main())