dgx-harness-engineering / scripts /123_14b_vllm_quick_benchmark.py
koreallmdev's picture
Upload anonymized DGX harness engineering export V1.4 (part 2)
6fda4b7 verified
Raw History Blame Contribute Delete
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()