Spaces:
Running
Running
Download scripts/bench_local.py from SmartDataAlex/Jupyter: direct link, hf CLI and curl.
- Browser
- Download file 4.69 kB
-
https://huggingface.co/spaces/SmartDataAlex/Jupyter/resolve/main/scripts/bench_local.py
- Command line
-
hf download hf://spaces/SmartDataAlex/Jupyter/scripts/bench_local.py
-
curl -L -o bench_local.py https://huggingface.co/spaces/SmartDataAlex/Jupyter/resolve/main/scripts/bench_local.py
4.69 kB
| """Opt-in on-host three-resident-model CPU/RSS benchmark. | |
| Run from service root with model snapshots downloaded and API_KEY configured: | |
| BENCH_LONG=1 python scripts/bench_local.py | |
| Reports are checkpointed after every case to survive failures/OOM. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import threading | |
| import time | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| from app.embedding import MODEL_ID as E5_ID | |
| from app.models import ModelRegistry, QWEN_ID, COLBERT_ID, memory_mb | |
| REPORT = Path(os.getenv("BENCH_REPORT", "bench-result.json")) | |
| LONG = os.getenv("BENCH_LONG", "0") == "1" | |
| rows = [] | |
| report = {"time": datetime.now(timezone.utc).isoformat(), | |
| "long_context": LONG, "startup": None, "cases": rows} | |
| def save(): | |
| REPORT.write_text(json.dumps(report, indent=2, ensure_ascii=False), | |
| encoding="utf-8") | |
| def repeated_text(tokenizer, max_tokens: int, prefix: str = "") -> str: | |
| """Find a repetition count whose true tokenizer length is <= target. | |
| Model-specific input overhead (query instructions/markers) is counted. | |
| A result slightly shorter than target is reported, not mislabeled. | |
| """ | |
| base = "Planet earth history. " | |
| def length(n): | |
| return len(tokenizer(prefix + base * n, add_special_tokens=True, | |
| truncation=False)["input_ids"]) | |
| lo, hi = 0, max_tokens | |
| while lo < hi: | |
| mid = (lo + hi + 1) // 2 | |
| if length(mid) <= max_tokens: | |
| lo = mid | |
| else: | |
| hi = mid - 1 | |
| if lo == 0: | |
| raise RuntimeError("Model prefix exceeds the test target") | |
| return base * lo | |
| def measure(name, runner, token_count=None): | |
| readings = [] | |
| finish = threading.Event() | |
| def monitor(): | |
| while not finish.wait(0.05): | |
| value = memory_mb()["rss_mb"] | |
| if value is not None: | |
| readings.append(value) | |
| sampler = threading.Thread(target=monitor, daemon=True) | |
| sampler.start() | |
| started = time.perf_counter() | |
| result = {"case": name, "requested_tokens": token_count} | |
| try: | |
| payload = runner() | |
| result["status"] = "pass" | |
| result["output_tokens"] = payload.tokens_count | |
| if hasattr(payload, "embedding"): | |
| result["dimensions"] = len(payload.embedding) | |
| else: | |
| result["dimensions"] = len(payload.token_embeddings[0]) | |
| result["vector_count"] = len(payload.token_embeddings) | |
| except Exception as error: | |
| result["status"] = "fail" | |
| result["error"] = f"{type(error).__name__}: {error}" | |
| finally: | |
| finish.set() | |
| sampler.join() | |
| result["elapsed_seconds"] = round(time.perf_counter() - started, 3) | |
| result["rss_mb"] = memory_mb()["rss_mb"] | |
| result["peak_sampled_rss_mb"] = max(readings, default=None) | |
| result["peak_process_rss_mb"] = memory_mb()["peak_rss_mb"] | |
| rows.append(result) | |
| save() | |
| print(result, flush=True) | |
| def main(): | |
| started = time.perf_counter() | |
| registry = ModelRegistry.load() # all 3 weights resident, once | |
| report["startup"] = { | |
| "seconds": round(time.perf_counter() - started, 3), | |
| "per_model_rss": registry.startup_memory, | |
| "post_load_ram": memory_mb(), | |
| } | |
| save() | |
| for kind in ("query", "passage"): | |
| for language, text in ( | |
| ("en", "A long voyage through the forest."), | |
| ("ru", "Долгое путешествие сквозь лес."), | |
| ("he", "מסע ארוך דרך היער."), | |
| ): | |
| measure(f"e5-{kind}-{language}", | |
| lambda t=text, k=kind: registry.e5.encode(t, k)) | |
| measure(f"qwen-{kind}-{language}", | |
| lambda t=text, k=kind: registry.qwen.encode(t, k)) | |
| measure(f"colbert-{kind}-{language}", | |
| lambda t=text, k=kind: registry.colbert.encode(t, k)) | |
| if LONG: | |
| for target in (8192, 32768): | |
| text = repeated_text(registry.qwen.tokenizer, target) | |
| actual = len(registry.qwen.tokenizer( | |
| text, add_special_tokens=True, truncation=False)["input_ids"]) | |
| measure(f"qwen-passage-{target}", lambda t=text: registry.qwen.encode(t, "passage"), actual) | |
| model = registry.colbert.model | |
| prefix = model.document_prefix | |
| text = repeated_text(model.tokenizer, 8192, prefix) | |
| count = len(model.tokenizer( | |
| prefix + text, add_special_tokens=True, truncation=False)["input_ids"]) | |
| measure("colbert-passage-8192", | |
| lambda: registry.colbert.encode(text, "passage"), count) | |
| if __name__ == "__main__": | |
| main() | |