runner: 진행 상황 출력 — 프로그램별 호출 건수와 호출 하나 끝날 때마다 [i/n]·경과·예상 남은 시간 (stderr)
고객사 실측: unit 100+ 인 프로그램은 15분 넘게 아무것도 안 찍혀 멈춘 것으로 보였다. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c577d5cb93
commit
ce459ba8f0
+18
-3
@@ -17,6 +17,7 @@ import argparse
|
||||
import json
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
import time
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timezone
|
||||
@@ -428,18 +429,29 @@ def _llm_call(llm, system: str, prompt: str) -> dict:
|
||||
return {"error": e}
|
||||
|
||||
|
||||
def _progress(i: int, n: int, t0: float, c: dict) -> None:
|
||||
"""호출 하나가 끝날 때마다 한 줄 — 긴 프로그램에서 멈춘 것처럼 보이지 않게 (stderr)."""
|
||||
state = "실패" if "error" in c else ("대기" if c.get("pending") else "ok")
|
||||
elapsed = time.time() - t0
|
||||
eta = elapsed / i * (n - i) if i else 0
|
||||
print(f" [{i}/{n}] {state} {elapsed:.0f}s 경과, 약 {eta:.0f}s 남음", file=sys.stderr, flush=True)
|
||||
|
||||
|
||||
def _run_calls_parallel(llm, calls: list[dict], concurrency: int) -> None:
|
||||
"""calls 각 원소의 'prompt' 를 호출하고 결과를 그 자리에 채운다 (in-place)."""
|
||||
if not calls:
|
||||
return
|
||||
t0 = time.time()
|
||||
if concurrency <= 1 or len(calls) == 1:
|
||||
for c in calls:
|
||||
for i, c in enumerate(calls, 1):
|
||||
c.update(_llm_call(llm, SYSTEM_PROMPT, c["prompt"]))
|
||||
_progress(i, len(calls), t0, c)
|
||||
return
|
||||
with ThreadPoolExecutor(max_workers=min(concurrency, len(calls))) as ex:
|
||||
futures = {ex.submit(_llm_call, llm, SYSTEM_PROMPT, c["prompt"]): c for c in calls}
|
||||
for fut in as_completed(futures):
|
||||
for i, fut in enumerate(as_completed(futures), 1):
|
||||
futures[fut].update(fut.result())
|
||||
_progress(i, len(futures), t0, futures[fut])
|
||||
|
||||
|
||||
def _dedupe_plan(con: sqlite3.Connection, pending: list[sqlite3.Row]) -> tuple[list[sqlite3.Row], dict]:
|
||||
@@ -569,7 +581,10 @@ def summarize_units(program: str | None, limit: int | None, fake: bool = False,
|
||||
jobs.append((u, [dict(x) for x in prompts]))
|
||||
|
||||
# 2) LLM 호출 (병렬, DB 접근 없음) — 수정사항 10번
|
||||
_run_calls_parallel(llm, [c for _, calls in jobs for c in calls], conc)
|
||||
all_calls = [c for _, calls in jobs for c in calls]
|
||||
print(f"[{p['name']}] unit {len(units)}건 → LLM 호출 {len(all_calls)}건 (동시 {conc})",
|
||||
file=sys.stderr, flush=True)
|
||||
_run_calls_parallel(llm, all_calls, conc)
|
||||
|
||||
# 3) 검증·저장 (DB 쓰기, 메인 스레드)
|
||||
for u, calls in jobs:
|
||||
|
||||
Reference in New Issue
Block a user