Files
hyungi_document_server/reports/local_research_M1_throughput.md
Hyungi Ahn 224843ba25 ops(reports): local research M1/M2/M3 baseline 등록 (2026-05-02)
- M1: ProcessingQueue throughput baseline (GPU DB pkm, read-only)
- M2: MLX gemma-4 26b-a4b 동시 처리 capacity (Mac mini :8801)
- M3: bge-m3 batch embedding throughput (GPU Ollama :11434)

3 보고서 모두 4.0 가드 준수 (compose/migration/queue/worker restart/source_channel insert/SearXNG 도입 0건). trade-in 직전 untracked sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 07:25:27 +09:00

6.8 KiB

M1 — ProcessingQueue Throughput Baseline

측정일: 2026-05-02 대상: GPU 서버 hyungi_document_server-postgres-1 (DB pkm) 범위: read-only SELECT 만. 4.0 가드 준수 (docker-compose / migration / queue stage / worker restart / source_channel='web' insert / SearXNG·Crawl4AI 도입 모두 0건). plan 참조: ~/.claude/plans/users-hyungiahn-library-cloudstorage-sy-binary-dongarra.md §4 (LocalResearch Feasibility).


1. Stage별 7일 throughput

SELECT stage::text,
  COUNT(*) FILTER (WHERE status='pending') AS pending,
  COUNT(*) FILTER (WHERE status='processing') AS processing,
  COUNT(*) FILTER (WHERE status='completed') AS completed,
  COUNT(*) FILTER (WHERE status='failed') AS failed,
  ROUND(AVG(EXTRACT(EPOCH FROM (completed_at - started_at))) FILTER (WHERE status='completed')::numeric, 2) AS avg_sec,
  ROUND((PERCENTILE_CONT(0.5)  WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (completed_at - started_at))) FILTER (WHERE status='completed'))::numeric, 2) AS p50_sec,
  ROUND((PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (completed_at - started_at))) FILTER (WHERE status='completed'))::numeric, 2) AS p95_sec
FROM processing_queue
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY stage ORDER BY stage;
stage pending processing completed failed avg_sec p50_sec p95_sec
chunk 4 0 453 0 1.36 0.76 5.19
classify 8 2 642 1 42.89 33.71 82.17
deep_summary 4 0 467 0 25.65 16.37 73.26
embed 13 0 2,839 0 0.26 0.10 1.75
extract 2 0 345 0 0.02 0.01 0.08
markdown 4 0 89 1 11.62 0.01 77.13
preview 13 0 332 0 0.01 0.01 0.02
summarize 0 0 2,395 0 3.74 3.61 5.67

핵심 관찰:

  • classify: 가장 무거운 stage (avg 42.89초, p95 82초) — MLX gemma 호출 dominant
  • deep_summary / summarize: 두 번째로 무거움 (LLM 호출)
  • embed: 가장 가벼움 (avg 0.26초) + 처리량 최대 (2,839건)
  • markdown: bimodal (p50 0.01초 = skip, p95 77초 = 실제 marker-pdf 변환). 2026-05-01 Phase 1B 배포 첫날 가동.
  • failed: classify 1건, markdown 1건 (총 2건, 0.06%) — 무시 수준

2. 일별 처리량 분포

SELECT date_trunc('day', completed_at)::date AS day, stage::text, COUNT(*)
FROM processing_queue
WHERE completed_at > NOW() - INTERVAL '7 days' AND status='completed'
GROUP BY 1, 2 ORDER BY 1 DESC, 2;
day classify deep_summary embed summarize chunk markdown extract preview
2026-05-02 6 1 66 73 1 1 15 2
2026-05-01 55 55 377 322 55 88 55 55
2026-04-30 450 412
2026-04-29 396 434
2026-04-28 15 342 342
2026-04-27 258 257 627 369 258 273 273
2026-04-26 283 283 2 2
2026-04-25 139 139 341 186 139

해석:

  • 2026-04-25 / 04-27: 가스기사 학습자료 일괄 업로드 batch (PDF/markdown 2,100문항 흐름 흔적, 메모리 project_gas_engineer_study.md)
  • 2026-05-01: Phase 1B marker_worker 배포 첫날, markdown 88건 첫 가동
  • 평일 비-batch 일은 classify 06건, embed 280450건 (study_topics PR-4 자동 임베딩 포함)
  • 편차 매우 큼: classify 0258/일, embed 66627/일. 일 평균보다 peak 일 capacity 가 운영 게이트의 의미 있는 기준.

3. Capacity 분석 (concurrency=1 가정, LLM stage)

LLM stage 는 feedback_analyzer_async_only.md + Phase 2 측정 (gemma-4 ~10초, semaphore=1 필수) 기반 concurrency 1 직렬 처리 가정. embed 는 GPU batch 가능, chunk/extract/preview 는 CPU light.

stage avg_sec concurrency max capacity (건/일) 7일 평균 처리량 (건/일) utilization
classify 42.89 1 2,014 91.7 4.6%
deep_summary 25.65 1 3,368 66.7 2.0%
summarize 3.74 1 23,101 342.1 1.5%
markdown (PDF) 11.62 1 7,436 12.7 0.2%
embed 0.26 (GPU batch) ≫ 100k 405.6 < 0.5%
chunk 1.36 (CPU) 63,529 64.7 0.1%

peak 일 (2026-04-27) 부하:

  • classify 258건/일 = 11,065초 = 3.07시간/일 = 12.8% utilization (concurrency 1, peak day)
  • deep_summary 257건/일 = 6,592초 = 1.83시간/일 = 7.6% utilization

평일 평균은 여유롭지만 peak batch 일에는 classify utilization 13% 까지 도달. web 추가 부하는 평균이 아닌 peak 기준으로 평가해야 함.


4. Web 30 URL/일 추가 부하 추정

PDF 시나리오: 사용자 검색 1회당 web 30 URL 수집 → 각 URL 이 markdown / classify / embed / chunk / summarize stage 진입 가정.

stage 추가 건/일 단위 시간 (초) 추가 시간/일 (초) peak 일 utilization 증가
markdown (web HTML) 30 ~5 추정¹ 150 +0.2%
classify 30 42.89 1,287 +1.5%
deep_summary 30 25.65 770 +0.9%
summarize 30 3.74 112 +0.1%
embed 150 (5 chunks/doc) 0.26 39 +0.05%
chunk 150 1.36 204 +0.2%

¹ web HTML → trafilatura 변환은 marker-pdf (PDF 11.62초) 보다 훨씬 빠름 (보통 0.5~3초). 5초는 보수적 가정.

총 추가 capacity 사용 (가장 무거운 LLM stage 기준):

  • classify utilization 증가: peak 일 12.8% → 14.3% (+1.5%p)
  • 평일 평균 utilization 증가: 4.6% → 6.0% (+1.4%p)

5. M1 게이트 판정

plan §4.1 게이트 1: web 30 URL/일 추가 부하가 현재 ProcessingQueue 처리 capacity 의 10% 이하.

측정 임계값 판정
classify capacity 추가 사용량 +1.5%p (절대) ≤ 10%p ✓ PASS
전체 LLM stage 합산 추가 사용량 +2.5%p (1.5+0.9+0.1) ≤ 10%p ✓ PASS
peak 일 classify utilization (after) 14.3% < 50% (여유) ✓ PASS

M1 게이트 1: PASS (추가 부하가 capacity 의 10% 보다 충분히 작음 — peak 일 기준 +1.5%p).


6. 보강 관찰 (참고)

  • Failed 건 2건만 발생 (classify 1, markdown 1) — 운영 안정.
  • Phase 1B markdown stage 가동 검증: 88 completed / 1 failed / 4 pending — 정상 가동 (메모리 project_markdown_canonical_layer.md Phase 1B 배포 일치).
  • embed 의 처리량은 chunks 단위: 1 doc 당 평균 ~5 chunks 가정 → 150 chunks/일 추가는 GPU bge-m3 capacity 에 비해 매우 작음 (M3 에서 배치 처리량 측정 후 재확인).

7. 다음 단계

  • M2 (MLX gemma-4 N=1/N=2 capacity 벤치) — 차단 조건 (error_rate>0, p95 3배 증가, healthcheck fail, /api/search/ask 또는 eval runner 시간대 충돌) 사전 점검 후 진행.