Download scripts/123_14b_vllm_quick_benchmark.py from koreallmdev/dgx-harness-engineering: direct link, hf CLI and curl.
- Browser
- Download file 9.78 kB
-
https://huggingface.co/koreallmdev/dgx-harness-engineering/resolve/main/scripts/123_14b_vllm_quick_benchmark.py
- Command line
-
hf download hf://koreallmdev/dgx-harness-engineering/scripts/123_14b_vllm_quick_benchmark.py
-
curl -L -o 123_14b_vllm_quick_benchmark.py https://huggingface.co/koreallmdev/dgx-harness-engineering/resolve/main/scripts/123_14b_vllm_quick_benchmark.py
9.78 kB
| #!/usr/bin/env python3 | |
| # DGX AI Factory - 14B vLLM Quick Benchmark | |
| # | |
| # ๋ชฉ์ : | |
| # - ํ์ฌ ๋ ์๋ vLLM 14B champion์ ๊ฐ๋จํ ์ ๊ฒํฉ๋๋ค. | |
| # - ํ์ตํ์ง ์์ต๋๋ค. | |
| # - adapter๋ฅผ ์ด๋ํ์ง ์์ต๋๋ค. | |
| # - stable/rejected ์น๊ฒฉ์ ํ์ง ์์ต๋๋ค. | |
| # | |
| # ํ๊ฐ ์ฑ๊ฒฉ: | |
| # - ์ด์ ์ quick benchmark์ ๋๋ค. | |
| # - ๊ธฐ์กด 20๋ฌธํญ ์ ์ benchmark๋ฅผ ๋์ฒดํ์ง ์์ต๋๋ค. | |
| # - direct vLLM ๋ชจ๋ธ ํธ์ถ ํ์ง์ ๋น ๋ฅด๊ฒ ํ์ธํฉ๋๋ค. | |
| import json | |
| import time | |
| import urllib.request | |
| import urllib.error | |
| from pathlib import Path | |
| from datetime import datetime | |
| ROOT = Path("/home/harness_user_1/dgx_ai_factory") | |
| REPORT_DIR = ROOT / "reports" | |
| REPORT_DIR.mkdir(parents=True, exist_ok=True) | |
| ENDPOINT = "http://localhost:8000/v1/chat/completions" | |
| MODEL = "dgx-14b-champion" | |
| SYSTEM = ( | |
| "ํ๊ตญ์ด ์กด๋๋ง๋ก ๋ต๋ณํ์ธ์. ์ค๊ตญ์ด๋ฅผ ์ฐ์ง ๋ง์ธ์. " | |
| "๋ช ๋ น์ด์ ์ค๋ช ์ ๊ตฌ๋ถํ๊ณ , ๋ถํ์คํ ๋ด์ฉ์ ๋จ์ ํ์ง ๋ง์ธ์." | |
| ) | |
| TESTS = [ | |
| { | |
| "id": "q01_lora_adapter", | |
| "category": "lora", | |
| "prompt": "LoRA adapter ํด๋์์ ํ์ธํด์ผ ํ๋ ํ์ผ 2๊ฐ์ stable/rejected ํ๋จ ์์๋ฅผ ์ค๋ช ํด์ฃผ์ธ์.", | |
| "must": ["adapter_config.json", "adapter_model.safetensors", "smoke", "benchmark"], | |
| "bad": ["yaml", ".pt", "Loosely Regularized", "์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q02_systemd_217_user", | |
| "category": "systemd", | |
| "prompt": "systemd ์๋น์ค๊ฐ status=217/USER๋ก ์คํจํ ๋ ํ์ธ ์์์ ์์ ๋ช ๋ น์ด๋ฅผ ์๋ ค์ฃผ์ธ์.", | |
| "must": ["User=", "id", "getent", "daemon-reload", "restart"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q03_dataset_quality", | |
| "category": "dataset", | |
| "prompt": "ํ์ต์ฉ jsonl ๋ฐ์ดํฐ์ ์ ๋ง๋ค ๋ ์ค๋ณต, CJK ๋์, template leak, category ๊ท ํ์ ์ ๊ฒํ๋ ์ ์ฐจ๋ฅผ ์ค๋ช ํด์ฃผ์ธ์.", | |
| "must": ["jsonl", "์ค๋ณต", "CJK", "template", "category"], | |
| "bad": ["์ค๊ตญ์ด๋ก", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q04_fastapi_curl", | |
| "category": "fastapi", | |
| "prompt": "FastAPI health check ์๋ํฌ์ธํธ๋ฅผ ๋ง๋ค๊ณ curl๋ก ํ์ธํ๋ ์ต์ ์์ ๋ฅผ ๋ณด์ฌ์ฃผ์ธ์.", | |
| "must": ["FastAPI", "curl", "/health", "uvicorn"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q05_vllm_port", | |
| "category": "vllm", | |
| "prompt": "vLLM OpenAI compatible server๊ฐ 8000 ํฌํธ์์ ์ ์์ธ์ง ํ์ธํ๋ ๋ช ๋ น์ด์ ํ๋จ ๊ธฐ์ค์ ์๋ ค์ฃผ์ธ์.", | |
| "must": ["ss", "8000", "/v1/models", "curl"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q06_docker_openwebui", | |
| "category": "docker", | |
| "prompt": "OpenWebUI Docker ์ปจํ ์ด๋๊ฐ ๋ ์๋์ง ํ์ธํ๊ณ ๋ก๊ทธ๋ฅผ ๋ณด๋ ๋ช ๋ น์ด๋ฅผ ์๋ ค์ฃผ์ธ์.", | |
| "must": ["docker ps", "docker logs"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q07_linux_process", | |
| "category": "linux", | |
| "prompt": "GPU ๋ชจ๋ธ ํ๋ก์ธ์ค๋ฅผ ์ฐพ๊ณ ์ข ๋ฃํ๊ธฐ ์ ์ ํ์ธํด์ผ ํ Linux ๋ช ๋ น์ด๋ฅผ ์๋ ค์ฃผ์ธ์.", | |
| "must": ["ps", "grep", "nvidia-smi", "kill"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q08_jsonl_validate", | |
| "category": "jsonl", | |
| "prompt": "jsonl ํ์ผ์ด ์ค ๋จ์ JSON์ผ๋ก ์ ์์ธ์ง Python์ผ๋ก ๊ฒ์ฆํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ฃผ์ธ์.", | |
| "must": ["json.loads", "line", "bad", "python"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q09_cuda_oom", | |
| "category": "cuda", | |
| "prompt": "CUDA OOM์ด ๋ฌ์ ๋ ์์ธ ๋ถ์ ์์์ ์ค์ผ ์ ์๋ ์ค์ ๊ฐ์ ์ค๋ช ํด์ฃผ์ธ์.", | |
| "must": ["OOM", "max-model-len", "max-num-seqs", "gpu-memory-utilization"], | |
| "bad": ["์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| { | |
| "id": "q10_korean_style", | |
| "category": "korean_style", | |
| "prompt": "์์ผ๋ก ๋ช ๋ น์ด๋ฅผ ์ค ๋ ํฐ๋ฏธ๋์ ๊ธด ๋ช ๋ น์ ์ง์ ๋ถ์ด์ง ์๊ณ ํ์ผ๋ก ์คํํ๋ ๋ฐฉ์์ผ๋ก ์๋ดํด์ผ ํ๋ ์ด์ ๋ฅผ ์ค๋ช ํด์ฃผ์ธ์.", | |
| "must": ["ํ์ผ", "์คํ", "๋ก๊ทธ", "๋ช ๋ น์ด"], | |
| "bad": ["ํด๋ผ", "ํด", "์ค๊ตญ", "่ฏ", "ไธ"], | |
| }, | |
| ] | |
| def post_chat(prompt: str) -> tuple[str, float, dict]: | |
| payload = { | |
| "model": MODEL, | |
| "messages": [ | |
| {"role": "system", "content": SYSTEM}, | |
| {"role": "user", "content": prompt}, | |
| ], | |
| "temperature": 0, | |
| "max_tokens": 500, | |
| } | |
| data = json.dumps(payload, ensure_ascii=False).encode("utf-8") | |
| req = urllib.request.Request( | |
| ENDPOINT, | |
| data=data, | |
| headers={"Content-Type": "application/json"}, | |
| method="POST", | |
| ) | |
| t0 = time.time() | |
| try: | |
| with urllib.request.urlopen(req, timeout=240) as resp: | |
| raw = resp.read().decode("utf-8", errors="replace") | |
| obj = json.loads(raw) | |
| except urllib.error.URLError as e: | |
| node-7.example.invalid RuntimeError(f"Request failed: {e}") from e | |
| latency = time.time() - t0 | |
| answer = obj["choices"][0]["message"]["content"] | |
| return answer, latency, obj | |
| def score_answer(answer: str, must: list[str], bad: list[str]) -> dict: | |
| lower = answer.lower() | |
| missing = [] | |
| for m in must: | |
| if m.lower() not in lower: | |
| missing.append(m) | |
| bad_hits = [] | |
| for b in bad: | |
| if b.lower() in lower: | |
| bad_hits.append(b) | |
| score = 100 | |
| score -= 12 * len(missing) | |
| score -= 18 * len(bad_hits) | |
| if len(answer.strip()) < 80: | |
| score -= 15 | |
| score = max(0, min(100, score)) | |
| passed = score >= 70 and not bad_hits | |
| strong = score >= 85 and not bad_hits | |
| return { | |
| "score": score, | |
| "passed": passed, | |
| "strong": strong, | |
| "missing_must": missing, | |
| "bad_hits": bad_hits, | |
| } | |
| def main(): | |
| ts = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| json_report = REPORT_DIR / f"14b_vllm_tune046_quick_benchmark_{ts}.json" | |
| jsonl_report = REPORT_DIR / f"14b_vllm_tune046_quick_benchmark_{ts}.jsonl" | |
| low_report = REPORT_DIR / f"14b_vllm_tune046_quick_benchmark_low_{ts}.jsonl" | |
| rows = [] | |
| print("==== 14B VLLM QUICK BENCHMARK START ====") | |
| print("model:", MODEL) | |
| print("endpoint:", ENDPOINT) | |
| print("tests:", len(TESTS)) | |
| print("note: no training, no adapter move, no stable promotion") | |
| print() | |
| for i, t in enumerate(TESTS, 1): | |
| print(f"==== {i}/{len(TESTS)} {t['id']} ({t['category']}) ====") | |
| try: | |
| answer, latency, raw = post_chat(t["prompt"]) | |
| score = score_answer(answer, t["must"], t["bad"]) | |
| row = { | |
| "id": t["id"], | |
| "category": t["category"], | |
| "prompt": t["prompt"], | |
| "answer": answer, | |
| "latency_sec": round(latency, 3), | |
| **score, | |
| } | |
| except Exception as e: | |
| row = { | |
| "id": t["id"], | |
| "category": t["category"], | |
| "prompt": t["prompt"], | |
| "answer": "", | |
| "latency_sec": None, | |
| "score": 0, | |
| "passed": False, | |
| "strong": False, | |
| "missing_must": t["must"], | |
| "bad_hits": [], | |
| "error": repr(e), | |
| } | |
| rows.append(row) | |
| print("score:", row["score"], "passed:", row["passed"], "latency:", row["latency_sec"]) | |
| if row.get("missing_must"): | |
| print("missing:", row["missing_must"]) | |
| if row.get("bad_hits"): | |
| print("bad_hits:", row["bad_hits"]) | |
| print() | |
| avg = round(sum(r["score"] for r in rows) / len(rows), 2) | |
| pass_count = sum(1 for r in rows if r["passed"]) | |
| strong_count = sum(1 for r in rows if r["strong"]) | |
| latencies = [r["latency_sec"] for r in rows if isinstance(r["latency_sec"], (int, float))] | |
| avg_latency = round(sum(latencies) / len(latencies), 3) if latencies else None | |
| category_avg = {} | |
| for r in rows: | |
| category_avg.setdefault(r["category"], []).append(r["score"]) | |
| category_avg = {k: round(sum(v) / len(v), 2) for k, v in sorted(category_avg.items())} | |
| if avg >= 85 and pass_count >= 9: | |
| decision = "PASS_QUICK_BENCHMARK" | |
| elif avg >= 75 and pass_count >= 7: | |
| decision = "REVIEW_BEFORE_FULL_BENCHMARK" | |
| else: | |
| decision = "FAIL_OR_ROUTE_NEEDED" | |
| summary = { | |
| "timestamp": ts, | |
| "model": MODEL, | |
| "endpoint": ENDPOINT, | |
| "test_count": len(rows), | |
| "average_score": avg, | |
| "pass_70_plus": f"{pass_count}/{len(rows)}", | |
| "strong_85_plus": f"{strong_count}/{len(rows)}", | |
| "average_latency_sec": avg_latency, | |
| "category_avg": category_avg, | |
| "decision": decision, | |
| "json_report": str(json_report), | |
| "jsonl_report": str(jsonl_report), | |
| "low_report": str(low_report), | |
| "note": "Direct vLLM model quick benchmark. Router/gateway benchmark should be run separately for operational route quality.", | |
| } | |
| json_report.write_text(json.dumps({"summary": summary, "rows": rows}, ensure_ascii=False, indent=2), encoding="utf-8") | |
| with jsonl_report.open("w", encoding="utf-8") as f: | |
| for r in rows: | |
| f.write(json.dumps(r, ensure_ascii=False) + "\n") | |
| with low_report.open("w", encoding="utf-8") as f: | |
| for r in rows: | |
| if r["score"] < 85 or r.get("bad_hits") or r.get("missing_must"): | |
| f.write(json.dumps(r, ensure_ascii=False) + "\n") | |
| print("==== FINAL 14B VLLM QUICK BENCHMARK SUMMARY ====") | |
| for k, v in summary.items(): | |
| print(f"{k}: {v}") | |
| if __name__ == "__main__": | |
| main() | |