From 7e346d2d3fb1fbe246fdc2bb23e4fb1951dae3ad Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Sun, 17 May 2026 08:07:51 +0900 Subject: [PATCH] =?UTF-8?q?docs(search):=20DS-Synthesis-Timeout-Calibratio?= =?UTF-8?q?n-1=20(B-3)=20closure=20=EB=B3=B4=EA=B3=A0=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 5곳 LLM_TIMEOUT_MS + 2곳 outer wait_for align (classifier 30s 와 동일 정책). synthesis/evidence/verifier/query_analyzer 모두 동시 부하 시 30s 까지 필요. Regression fixture 결과: 10/10 HTTP 200 + 5/5 search + 3/3 failure injection 모두 PASS (회귀 0). 응답 시간 +4~20s 증가 (안정성 ↑ 의도된 trade-off). p95 12s gate 는 여전히 FAIL — B-1 Throughput-1 (priority queue / 모델 분리) 별 plan 으로 latency 단축 방향 진입. --- ...synthesis_timeout_calibration_1_closure.md | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 reports/pr_ds_synthesis_timeout_calibration_1_closure.md diff --git a/reports/pr_ds_synthesis_timeout_calibration_1_closure.md b/reports/pr_ds_synthesis_timeout_calibration_1_closure.md new file mode 100644 index 0000000..e5e491e --- /dev/null +++ b/reports/pr_ds_synthesis_timeout_calibration_1_closure.md @@ -0,0 +1,124 @@ +# DS-Synthesis-Timeout-Calibration-1 (B-3) Closure Report + +**Date**: 2026-05-17 +**Plan 카테고리**: B-3 (PR-Hermes-Polymorphic-Rossum 후속, DS RAG 측 별 트랙) +**범위**: DS RAG 파이프라인 5 stage 의 LLM_TIMEOUT_MS / outer wait_for align (Mac mini 26B serialized concurrent load 대응) +**Commit**: `73f328c` + +## Summary + +PR-Hermes-Docsrv-Search-1 closure 시점 측정 (`synthesis_ms=30~48s` / `ev_ms=15005` / `query_analyze=45s`) 으로 기존 LLM_TIMEOUT_MS 15s / 3s 가 동시 부하 시 빈발 timeout. classifier (30s) 는 PR-1 closure 에서 이미 align 됐으나 다른 service 들 (synthesis / evidence / verifier / query_analyzer) 은 misaligned 잔존. 본 PR 이 5곳 동시 raise + 2곳 outer wait_for align. + +## Root cause (재확인) + +Mac mini 26B single-inference + `get_mlx_gate()` Semaphore(1) 직렬화 후 DS RAG 파이프라인 5 stage 가 sequential 누적: +- query_analyzer → evidence + classifier (parallel) → synthesis → verifier +- 각 stage 가 30s 까지 wait 후에야 다음 진행 +- 15s LLM_TIMEOUT 시 절반 stage 가 timeout → fallback path 발화 (refusal_gate / verifier skip) + +## 변경 사항 + +5 timeout constants + 2 outer wrappers: + +| 파일 | line | 변경 | +|---|---|---| +| `app/services/search/synthesis_service.py` | 43 | `LLM_TIMEOUT_MS 15000 → 30000` | +| `app/services/search/evidence_service.py` | 81 | `LLM_TIMEOUT_MS 15000 → 30000` | +| `app/services/search/verifier_service.py` | 34 | `LLM_TIMEOUT_MS 3000 → 10000` | +| `app/services/search/query_analyzer.py` | 47 | `LLM_TIMEOUT_MS 15000 → 30000` | +| `app/api/search.py` | 522 | `wait_for(classifier_task, 15.0 → 30.0)` | +| `app/api/search.py` | 641 | `wait_for(verifier_task, 4.0 → 10.0)` | + +**기존 정합**: +- classifier_service.LLM_TIMEOUT_MS = 30000 (PR-Hermes-Docsrv-Search-1 closure 시 이미 raised) +- ai.classifier.timeout = 30 (config.yaml, 같이 align 완료) + +## Regression 검증 (PR-1 Layer 1 fixture re-run, 완료) + +**전체 결과 (Pre-B-3 vs Post-B-3)**: + +| 항목 | Pre-B-3 | Post-B-3 | 회귀 | +|---|---|---|---| +| docsrv_ask HTTP 200 | 10/10 | **10/10** | ✅ 0 | +| docsrv_search HTTP 200 | 5/5 | **5/5** | ✅ 0 | +| Failure injection 3건 | 3/3 PASS | **3/3 PASS** (401 / 000 / refused) | ✅ 0 | +| classifier ok 비율 | 10/10 | 10/10 | ✅ 0 | +| min | 8.8s | 13.2s | +4.4s | +| p50 | 10.6s | **23.2s** | +12.6s | +| mean | 15.0s | **25.8s** | +10.8s | +| p95 | 34.8s | **50.7s** | +15.9s (ASME outlier) | +| max | 34.8s | **50.7s** | +15.9s | + +**Per-query 비교**: + +| Query | Pre-B-3 | Post-B-3 | Δ | +|---|---|---|---| +| ask-a1-memo-hit | 9.3s | 13.2s | +3.9s | +| ask-a2-voice | 13.0s | 19.9s | +6.9s | +| ask-a3-bridge | 10.1s | 22.0s | +11.9s | +| ask-b1-asme | 30.7s | **50.7s** | **+20.0s** (이전 timeout 부근, 끝까지 완료) | +| ask-b2-drift | 11.5s | 30.5s | +19.0s | +| ask-b3-digest | 10.4s | 25.6s | +15.2s | +| ask-c1-today | 34.8s | 30.5s | -4.3s | +| ask-c2-decision | 10.6s | 23.2s | +12.6s | +| ask-d1-secret | 10.5s | 20.7s | +10.2s | +| ask-d2-noexist | 8.8s | 21.8s | +13.0s | + +**해석**: +- 응답 시간 +4~20s 증가 — 의도된 trade-off (timeout fallback path 대신 끝까지 completion) +- classifier ok 정상 path 100% (conservative_refuse 회피) +- functional 변화 0 (verdict, citations, sources, refused 모두 동일 패턴) +- p95 12s gate 는 여전히 FAIL (이전부터 ASME outlier 로 fail, B-3 가 안정성 우선이라 latency 더 증가 — B-1 Throughput-1 진입 시 단축 검토) + +## 결정 사항 + +1. **B-3 = SHIPPED**: + - 5곳 LLM_TIMEOUT + 2곳 outer wait_for align 완료 + - Mac mini 26B concurrent saturation 대응 완성 (classifier 외 4 service) + - functional 회귀 0, latency +4~20s (안정성 ↑ 의도된 trade-off) + +2. **B-1 (Throughput-1) = 별 plan 으로 분리**: + - 본 B-3 가 latency 증가 방향 — B-1 이 latency 단축 방향 (priority queue / 모델 분리) + - architecture 변경이라 별 plan + 사용자 검토 필수 + - 후보: (a) `asyncio.PriorityQueue` (user ask priority 0 / background priority 100) (b) Mac mini 4B 모델 추가 로드 (triage 만 분리) (c) GPU Ollama 4B 재도입 (PR #20 reverse) + +3. **B-2 (Classifier-Threshold-Tune-1) = 1주 query 로그 대기**: + - 사용자 실제 query 패턴 + rerank score 분포 측정 후 `CONSERVATIVE_WEAK=0.35` recalibration + - 진입 = 2026-05-24 (1주 baseline) 이후 + +## File changes + +- `app/services/search/synthesis_service.py` (line 43) +- `app/services/search/evidence_service.py` (line 81) +- `app/services/search/verifier_service.py` (line 34) +- `app/services/search/query_analyzer.py` (line 47) +- `app/api/search.py` (line 522, 641) + +총 5 file, 6 timeout constants/wrappers 변경. + +## 7일 안전망 (2026-05-24) + +- git revert `73f328c` (단일 commit 으로 묶임) +- 별 백업 파일 0 (git history 가 안전망) + +## 검증 commands (재실행) + +```bash +# 회귀 fixture +ssh macmini "bash ~/.hermes/fixtures/pr_search1_layer1.sh" + +# DS 로그 (classifier ok 비율) +ssh gpu "cd ~/Documents/code/hyungi_Document_Server && \ + docker compose logs --since=5m fastapi | grep -E 'classifier (ok|error|timeout)' | tail -10" + +# Hermes E2E (Curl-Refine-2 확인 + 회귀 0) +ssh macmini "HERMES_DOCSRV_TOKEN=... && hermes chat -s docsrv_ask -q '내 자료에서 voice memo 찾아줘'" +``` + +## 후속 트랙 + +| 우선 | 트랙 | 진입 | +|---|---|---| +| **P2** | DS-Mac-mini-26B-Throughput-1 (B-1) | architecture 변경 plan 필요 — priority queue / 모델 분리 비교 | +| **대기** | DS-Classifier-Threshold-Tune-1 (B-2) | 2026-05-24 1주 query 로그 baseline 후 | +| (선택) | LLM_TIMEOUT_MS centralization | 5 service 가 각자 상수 보유 — 공통 config 항목 (`ai.llm_timeout_default: 30`) 도입 검토. P3 |