File size: 3,851 Bytes
58ba6df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1b17257
 
 
 
 
 
 
58ba6df
 
 
 
1b17257
58ba6df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1b17257
58ba6df
 
 
 
1b17257
 
 
 
58ba6df
1b17257
58ba6df
 
 
 
 
 
 
 
 
1b17257
58ba6df
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/bin/bash
# server boot gates + smoke + 50 timed requests with the tt-model.yaml serve env (chip from CHIP, port from PORT)
# M defaults to the repo this script lives in (so a verify worktree can run its own copy unmodified)
M=${M:-$(cd "$(dirname "$0")/../.." && pwd)}
VENV=${VENV:-/home/ttuser/experiments/tt-models/models/hamer-p150/.venv}
W=${W:-$M/.work}; mkdir -p $W
cd $M
source /home/ttuser/experiments/tt-models/tools/chipenv.sh ${CHIP:?} $VENV >/dev/null 2>&1 || exit 1
eval "$(python3 - <<'PY'
import yaml
d = yaml.safe_load(open("tt-model.yaml"))
for k, v in d["serve"]["env"].items():
    if k == "TT_METAL_VISIBLE_DEVICES":
        continue  # chipenv pins the chip by BDF
    print(f"export {k}={str(v)!r}")
PY
)"
[ -n "$EXTRA" ] && export $EXTRA
# uvicorn flags: tt-model.yaml serve.args (what the image launches) unless UVI is set (UVI="--loop asyncio --http h11"
# restores uvicorn's pre-integration stack for an A/B)
UVI=${UVI-$(python3 -c "
import yaml
a = yaml.safe_load(open('tt-model.yaml'))['serve'].get('args', [])
print(' '.join(' '.join(map(str, x)) if isinstance(x, list) else str(x) for x in a))")}
echo "uvicorn flags: $UVI"
export PYTHONPATH=$M/code TT_MESH_SHAPE=1x1 TT_DEVICE_ID=0 HAMER_WARMUP_ITERS=3 HF_MODEL=changh95/hamer-weights
env | grep -E "^(TT_FUSED|HAMER_)" | sort > $W/serve_env.txt
PORT=${PORT:-20117}
rm -f $W/serve.log
timeout -s INT 900 python -m uvicorn --host 127.0.0.1 --port $PORT --lifespan on $UVI hamer.server.app:app > $W/serve.log 2>&1 &
SP=$!
for i in $(seq 1 300); do
  grep -q "Application startup complete" $W/serve.log && break
  kill -0 $SP 2>/dev/null || break
  sleep 1
done
grep -E "warm-up PCC|Warmup complete|Application startup complete|Error|Traceback" $W/serve.log | head -8
if grep -q "Application startup complete" $W/serve.log; then
  python code/hamer/server/smoke_test.py --url http://127.0.0.1:$PORT --image all 2>&1 | tail -10
  python3 - $PORT <<'PY'
import base64, json, sys, time, statistics, urllib.request
from pathlib import Path
port = sys.argv[1]
media = Path("media"); boxes = json.loads((media / "bboxes.json").read_text())
reqs = []
for name, ents in sorted(boxes.items()):
    img = base64.b64encode((media / name).read_bytes()).decode()
    for e in ents:
        reqs.append({"image": img, "bbox": e["bbox"], "is_right": bool(e.get("is_right", 1)), "return_vertices": False})
mt, tot, pre, rtt = [], [], [], []
N = int(__import__('os').environ.get('NREQ', '60'))
for i in range(N):
    body = json.dumps(reqs[i % len(reqs)]).encode()
    r = urllib.request.Request(f"http://127.0.0.1:{port}/predict", data=body, headers={"Content-Type": "application/json"})
    t0 = time.perf_counter()
    raw = urllib.request.urlopen(r, timeout=60).read()
    dt = (time.perf_counter() - t0) * 1e3
    out = json.loads(raw)
    if i >= 10:
        rtt.append(dt)
        t = out.get("timing_ms", {})
        mt.append(t.get("model", t.get("device", 0))); tot.append(t.get("total", 0)); pre.append(t.get("preprocess", 0))
print("timing keys", list(out.get("timing_ms", {}).keys()))
print(f"TIMED {len(mt)} requests: model median {statistics.median(mt):.3f} min {min(mt):.3f}  total median {statistics.median(tot):.3f}")
# round 11: the server total is host-load-bound (shared host): report its spread and the load average with it
q = lambda v, p: sorted(v)[min(len(v) - 1, int(p * len(v)))]
import os as _os
print(f"TIMED spread: model p10 / p50 / p90 {q(mt, .1):.3f} / {q(mt, .5):.3f} / {q(mt, .9):.3f}  "
      f"total p10 / p50 / p90 {q(tot, .1):.3f} / {q(tot, .5):.3f} / {q(tot, .9):.3f}  "
      f"preprocess p50 {q(pre, .5):.3f}  client RTT p10 / p50 / p90 {q(rtt, .1):.3f} / {q(rtt, .5):.3f} / {q(rtt, .9):.3f}  host load average {' / '.join(f'{v:.1f}' for v in _os.getloadavg())}")
PY
fi
pkill -INT -P $SP 2>/dev/null; wait $SP 2>/dev/null; echo "server exit $?"