naldo
Restore CPU-only AI base on fresh ZeroGPU Space
ce52794
Raw History Blame Contribute Delete
3.04 kB
"""Benchmark real do endpoint: TTFT, prompt/s, gen/s.
Mede com o objeto `timings` que o llama-server devolve (nao estima por
relogio de parede) e registra tudo em JSON para comparar quantizacoes e
contagens de threads.
Uso:
BASE=https://erinaldordso-programa.hf.space/v1 python3 tests/benchmark.py
BASE=... MODEL=... APIKEY=... CTX=32768 python3 tests/benchmark.py
Prompts: um curto (TTFT puro) e um longo (~3k tokens, prefill real).
"""
import json
import os
import time
import urllib.request
BASE = os.environ.get("BASE", "https://erinaldordso-programa.hf.space/v1").rstrip("/")
MODEL = os.environ.get("MODEL", "qwen3-coder-30b-a3b-instruct")
APIKEY = os.environ.get("APIKEY", "")
CTX = os.environ.get("CTX", "32768")
LONG_PROMPT = ("Explique o padrão de projeto observador em Python. " * 120
+ "\nMostre uma implementação completa com testes.")
def post(body):
headers = {"Content-Type": "application/json"}
if APIKEY:
headers["Authorization"] = f"Bearer {APIKEY}"
t0 = time.perf_counter()
r = urllib.request.Request(BASE + "/chat/completions",
data=json.dumps(body).encode(),
headers=headers, method="POST")
first = None
chunks = 0
with urllib.request.urlopen(r, timeout=600) as resp:
for line in resp:
s = line.decode(errors="replace").strip()
if not s.startswith("data:"):
continue
s = s[5:].strip()
if s == "[DONE]":
last = {}
break
try:
last = json.loads(s)
except json.JSONDecodeError:
continue
chunks += 1
if first is None:
first = time.perf_counter() - t0
total = time.perf_counter() - t0
return last, {"ttft_s": round(first or 0, 3), "total_s": round(total, 2),
"chunks": chunks}
def run_case(name, prompt, max_tokens=128):
last, wall = post({"model": MODEL,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": max_tokens, "temperature": 0, "stream": True,
"timings_per_token": True})
usage = last.get("usage", {})
timings = last.get("timings", {})
row = {"case": name, "model": MODEL, "ctx": CTX,
"prompt_tokens": usage.get("prompt_tokens"),
"completion_tokens": usage.get("completion_tokens"),
"prompt_per_second": timings.get("prompt_per_second"),
"predicted_per_second": timings.get("predicted_per_second"),
**wall}
print(json.dumps(row, indent=2))
return row
def main():
print(f"BASE={BASE} MODEL={MODEL}")
rows = [run_case("curto", "diga ok", 32),
run_case("longo-3k", LONG_PROMPT, 128)]
fname = f"benchmark_{MODEL}_{int(time.time())}.json"
with open(fname, "w") as fh:
json.dump(rows, fh, indent=2)
print(f"salvo em {fname}")
if __name__ == "__main__":
main()