Phase 01 (LLM Tuning): - Gemma4 26B: 74.65 t/s (fast) - Qwen 35B: 61.62 t/s (balanced) - Gemma4 31B: 16.0 t/s (deep-coder) - Qwen 27B: 16.7 t/s (deep-logic) - Qwen 122B: 8.95 t/s (ultra, GPU 1 only) Phase 02 (API Engine): - FastAPI reverse proxy on port 8000 - /engine/switch hot-swap with 503 protection - config/engine_models.json as single source of truth - Replaced 4 individual .bat files with unified engine File cleanup: - scripts/ 85 files -> 9 + _archive/ - Root .bat files -> _archive/
135 lines
5.1 KiB
Python
135 lines
5.1 KiB
Python
import subprocess
|
|
import time
|
|
import urllib.request
|
|
import json
|
|
import sys
|
|
import traceback
|
|
|
|
try:
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
except:
|
|
pass
|
|
|
|
BASE_URL = "http://127.0.0.1:8000"
|
|
RESULTS_FILE = "scripts/llm_judge_answers.json"
|
|
|
|
MODELS = [
|
|
{
|
|
"name": "Qwen 27B",
|
|
"cmd": [
|
|
r"llama_bin_run\llama-server.exe",
|
|
"--model", r"models\Qwen3.5-27B-Q4_K_M.gguf",
|
|
"-ngl", "999", "-c", "262144", "-np", "1", "-fa", "on",
|
|
"--cache-type-k", "q4_0", "--cache-type-v", "q4_0",
|
|
"-ub", "512", "-b", "1024", "-t", "6", "-tb", "6",
|
|
"--prio", "3", "--mlock", "--poll", "50", "-ts", "0.5,0.5",
|
|
"--port", "8000", "--host", "0.0.0.0"
|
|
]
|
|
},
|
|
{
|
|
"name": "Gemma 31B",
|
|
"cmd": [
|
|
r"llama_bin_run\llama-server.exe",
|
|
"--model", r"models\gemma-4-31B-it-Q4_K_M.gguf",
|
|
"-ngl", "999", "-c", "196608", "-np", "1", "-fa", "on",
|
|
"--cache-type-k", "q4_0", "--cache-type-v", "q4_0",
|
|
"-ub", "128", "-b", "512", "-t", "6", "-tb", "6",
|
|
"--prio", "3", "--mlock", "--poll", "50",
|
|
"--port", "8000", "--host", "0.0.0.0"
|
|
]
|
|
}
|
|
]
|
|
|
|
QUESTIONS = [
|
|
{
|
|
"id": "architecture",
|
|
"prompt": "수백만 건의 실시간 주식 틱 데이터를 수집하고, 이를 가공하여 초당 수천 명의 클라이언트에게 웹소켓으로 지연 없이 브로드캐스팅하는 시스템을 설계해야 합니다. 언어, 메시지 큐, 데이터베이스, 캐싱 전략 등을 포함해 구체적인 아키텍처를 제안하고, 병목 현상에 대비한 해결책을 설명하세요."
|
|
},
|
|
{
|
|
"id": "logic",
|
|
"prompt": "논리 문제: 방 안에 5명의 사람(A, B, C, D, E)이 있습니다. A는 B를 제외한 모든 사람과 악수했습니다. B는 C와만 악수했습니다. C는 D와 악수하지 않았습니다. 그렇다면 E는 총 몇 명과 악수했을까요? 당신의 논리적 사고 과정을 한 단계씩 명확히 설명해주세요."
|
|
},
|
|
{
|
|
"id": "coding",
|
|
"prompt": "파이썬에서 데코레이터를 작성하세요. 이 데코레이터는 함수의 실행을 최대 3번까지 재시도하며, 각 재시도 간에 지수 백오프(Exponential Backoff)를 적용해야 합니다. 로깅 처리가 포함되어야 하며, 어떤 예외 타입(Exception type)이 발생했을 때만 재시도할지 인자로 받을 수 있어야 합니다."
|
|
}
|
|
]
|
|
|
|
def check_server(timeout=300):
|
|
start = time.time()
|
|
while time.time() - start < timeout:
|
|
try:
|
|
req = urllib.request.Request(f"{BASE_URL}/health")
|
|
resp = json.loads(urllib.request.urlopen(req, timeout=2).read())
|
|
if resp.get("status") == "ok" or resp.get("status") == "ready":
|
|
return True
|
|
except:
|
|
pass
|
|
time.sleep(5)
|
|
return False
|
|
|
|
def ask(prompt, max_tokens=4096):
|
|
payload = json.dumps({
|
|
"model": "m",
|
|
"messages": [
|
|
{"role": "system", "content": "You are a world-class IT system architect and developer. Please output your response in Korean."},
|
|
{"role": "user", "content": prompt}
|
|
],
|
|
"max_tokens": -1,
|
|
"temperature": 0.0
|
|
}).encode('utf-8')
|
|
|
|
req = urllib.request.Request(
|
|
f"{BASE_URL}/v1/chat/completions",
|
|
data=payload,
|
|
headers={"Content-Type": "application/json"}
|
|
)
|
|
t0 = time.time()
|
|
resp = json.loads(urllib.request.urlopen(req, timeout=1800).read())
|
|
dt = time.time() - t0
|
|
content = resp["choices"][0]["message"]["content"]
|
|
return content
|
|
|
|
def main():
|
|
results = {}
|
|
|
|
subprocess.run("taskkill /F /IM llama-server.exe", shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
time.sleep(3)
|
|
|
|
for cfg in MODELS:
|
|
print(f"\n[{time.strftime('%H:%M:%S')}] Booting {cfg['name']}...")
|
|
proc = subprocess.Popen(cfg["cmd"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
|
|
if not check_server(300):
|
|
print(f"Failed to boot {cfg['name']}.")
|
|
proc.terminate()
|
|
continue
|
|
|
|
print(f"✅ {cfg['name']} is ready! Asking questions...")
|
|
|
|
try: ask("Hi", max_tokens=10)
|
|
except: pass
|
|
|
|
results[cfg['name']] = {}
|
|
for q in QUESTIONS:
|
|
print(f" -> Asking: {q['id']}")
|
|
try:
|
|
ans = ask(q['prompt'])
|
|
results[cfg['name']][q['id']] = ans
|
|
print(" (Done)")
|
|
except Exception as e:
|
|
results[cfg['name']][q['id']] = f"ERROR: {e}"
|
|
print(" (Error)")
|
|
|
|
with open(RESULTS_FILE, "w", encoding="utf-8") as f:
|
|
json.dump(results, f, ensure_ascii=False, indent=2)
|
|
|
|
proc.terminate()
|
|
subprocess.run("taskkill /F /IM llama-server.exe", shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
time.sleep(5)
|
|
|
|
print("\n✅ All questions answered! Results saved to", RESULTS_FILE)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|