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>
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
# 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
|
||||
|
||||
```sql
|
||||
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. 일별 처리량 분포
|
||||
|
||||
```sql
|
||||
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 0~6건, embed 280~450건 (study_topics PR-4 자동 임베딩 포함)
|
||||
- **편차 매우 큼**: classify 0~258/일, embed 66~627/일. 일 평균보다 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 시간대 충돌) 사전 점검 후 진행.
|
||||
@@ -0,0 +1,142 @@
|
||||
# M2 — MLX gemma-4 동시 처리 Capacity Bench
|
||||
|
||||
**측정일**: 2026-05-02
|
||||
**대상**: Mac mini MLX :8801 `gemma-4-26b-a4b-it-8bit` (Tailscale 100.76.254.116)
|
||||
**범위**: read-only `/v1/chat/completions` 호출만. 4.0 가드 준수 (compose / migration / queue / worker restart / source_channel insert / SearXNG 도입 모두 0건). config.yaml / Ollama 모델 변경 없음.
|
||||
**bench 스크립트**: `/tmp/bench_M2_mlx.py` (격리, main pipeline 미연결)
|
||||
**plan 참조**: `~/.claude/plans/users-hyungiahn-library-cloudstorage-sy-binary-dongarra.md` §4.
|
||||
|
||||
---
|
||||
|
||||
## 1. 사전 점검
|
||||
|
||||
| 항목 | 상태 |
|
||||
|---|---|
|
||||
| MLX `/v1/models` healthcheck | OK (`gemma-4-26b-a4b-it-8bit` 단일 모델) |
|
||||
| 진행 중 background queue (사전) | classify 1건 processing, classify 10건 pending, deep_summary 4건 pending — **MLX 자원 사용 중** |
|
||||
| eval runner / `/api/search/ask` 동시 진행 | 별도 호출 없음 (Document Server 자체 ask 트래픽은 배치 외 시점) |
|
||||
| 시간대 | 평일 오후 (한국시간) — peak 외 |
|
||||
|
||||
배경 queue 가 MLX 동시 사용 중인 상태에서 측정 진행 — **운영 환경 reflective benchmark** 로 의미 있음.
|
||||
|
||||
---
|
||||
|
||||
## 2. 시나리오
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 입력 본문 | ~500 토큰, 한·영 mixed (ASME B16.5 / KGS Code / 가스기사 도메인 sample) |
|
||||
| 프롬프트 작업 | "한국어 200자 이내 요약, technical key points only" |
|
||||
| `max_tokens` | 200 (stop 보장) |
|
||||
| `temperature` | 0 |
|
||||
| 입력 prompt_tokens | ~500 (실측 19 tokens 단순 프롬프트와 별도. 실제 PROMPT 본문 포함 길이) |
|
||||
|
||||
각 응답은 모두 `finish_reason='stop'`, `completion_tokens=120` 으로 일관 — **출력 토큰 수가 일정**해 latency 비교가 깨끗함.
|
||||
|
||||
---
|
||||
|
||||
## 3. N=1 baseline (5 serial)
|
||||
|
||||
```
|
||||
call 1: ok=True elapsed=3.67s ctok=120
|
||||
call 2: ok=True elapsed=3.41s ctok=120
|
||||
call 3: ok=True elapsed=3.42s ctok=120
|
||||
call 4: ok=True elapsed=3.60s ctok=120
|
||||
call 5: ok=True elapsed=3.47s ctok=120
|
||||
```
|
||||
|
||||
| metric | value |
|
||||
|---|---|
|
||||
| n | 5 |
|
||||
| min | 3.41s |
|
||||
| max | 3.67s |
|
||||
| avg | **3.51s** |
|
||||
| p50 | 3.47s |
|
||||
| p95 | 3.67s |
|
||||
| error_count | 0 |
|
||||
| error_rate | 0% |
|
||||
| completion_tokens_avg | 120 |
|
||||
|
||||
**관찰**: 매우 안정 (편차 0.26초). 메모리 `project_search_v2.md` 의 "gemma-4 ~10.5초" (Phase 2 측정) 와 차이는 본 시나리오가 짧은 출력 (120 tok vs Phase 2 의 더 긴 출력) + 검색 query 성격 차이 때문.
|
||||
|
||||
---
|
||||
|
||||
## 4. N=2 parallel (6 calls, 3 batches via thread pool)
|
||||
|
||||
```
|
||||
call 4: ok=True elapsed=14.38s ctok=120
|
||||
call 5: ok=True elapsed=14.37s ctok=120
|
||||
call 6: ok=True elapsed=17.12s ctok=120
|
||||
... (call 1~3 도 모두 ok)
|
||||
```
|
||||
|
||||
| metric | value |
|
||||
|---|---|
|
||||
| n | 6 |
|
||||
| min | 6.74s |
|
||||
| max | 35.01s |
|
||||
| avg | **19.88s** |
|
||||
| p50 | 15.75s |
|
||||
| p95 | **35.01s** |
|
||||
| error_count | 0 |
|
||||
| error_rate | **0%** |
|
||||
| completion_tokens_avg | 120 |
|
||||
|
||||
**해석**:
|
||||
- **error 0** — concurrency 2 client 호출에 대해 MLX 안정.
|
||||
- **latency 큰 폭 증가** — N=1 대비 p95 9.54×, p50 4.54×, avg 5.66×.
|
||||
- 원인: MLX server (`mlx_vlm server`) 가 단일 프로세스 + GPU 1 → 본질적으로 **concurrency=1 직렬 처리**. N=2 client 호출은 MLX 내부 큐에서 직렬화. 추가로 background classify 1건 processing 중이라 경합.
|
||||
- 6 calls × ~3.5초 = ~21초 총 직렬 처리 시간. max 35초는 background queue 점유 + 큐잉.
|
||||
- 이는 메모리 `feedback_analyzer_async_only.md` ("semaphore concurrency=1 필수") 와 일치하는 **이미 알려진 특성**. 새로운 위험 신호 아님.
|
||||
|
||||
---
|
||||
|
||||
## 5. plan 4.0 중단 조건 점검
|
||||
|
||||
| 조건 | 측정 | 판정 |
|
||||
|---|---|---|
|
||||
| `error_rate > 0` | 0% | 미발생 |
|
||||
| **p95 latency N=1 대비 3배 이상 증가** | **9.54×** | **트리거** |
|
||||
| MLX healthcheck 실패 | OK | 미발생 |
|
||||
| `/api/search/ask` 또는 eval 시간대 겹침 | 사전 점검 시 ask/eval 없음 | 미발생 |
|
||||
|
||||
**결론**: p95 3× 트리거 발생 → **N=4 자동 진행 금지**. plan 명시 (`N=4 는 N=2 에서 error_rate=0 AND p95 acceptable 일 때만`). N=4 는 별도 사용자 승인 후 수행.
|
||||
|
||||
다만 latency 9.5× 증가는 MLX concurrency=1 본질적 특성이지, 새로운 운영 위험은 아님. 이미 운영 중인 ask / classify 트래픽이 동시에 들어오면 동일하게 늘어남.
|
||||
|
||||
---
|
||||
|
||||
## 6. plan 4.1 게이트 판정 (M2 관련)
|
||||
|
||||
### 게이트 2 — Gemma 요약 30건/일 ≤ 10분 (concurrency 1)
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 단위 시간 (avg) | 3.51s |
|
||||
| 30건 직렬 처리 시간 | 30 × 3.51s = **105.4s = 1.76분** |
|
||||
| 임계값 | ≤ 10분 |
|
||||
| **판정** | **✓ PASS** (여유 5.7×) |
|
||||
|
||||
### 게이트 3 — concurrency 2 error_rate 0 = 여유 있음
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| N=2 error_rate | 0% |
|
||||
| 임계값 | error_rate = 0 |
|
||||
| **판정** | **✓ PASS** |
|
||||
|
||||
### 게이트 3 보강 — latency 영향 (참고용)
|
||||
- N=2 동시성 시 평균 19.88초, p95 35초 — LocalResearch 본격 가동 시 **운영 ask 트래픽과 동일 시간대 web 요약이 겹치면 응답 약 5~10× 지연** 가능.
|
||||
- 완화책 (Phase 1 본격 plan 단계 결정): (a) web 요약은 background queue + concurrency 1 직렬 (실시간 아님) (b) ask 와 시간대 분리 (야간 배치)
|
||||
|
||||
---
|
||||
|
||||
## 7. M2 단계 요약
|
||||
|
||||
- **N=1 baseline**: avg 3.51s, p95 3.67s, error 0 → 매우 안정
|
||||
- **N=2 parallel**: avg 19.88s, p95 35.01s, error 0 → MLX 직렬 처리로 latency 9.5× 증가, 단 안정성/완성도는 유지
|
||||
- **N=4 미실시**: plan 4.0 중단 조건 트리거 (p95 3× 초과). 사용자 승인 후 별도 수행.
|
||||
- **plan 게이트 2 + 3 모두 PASS**
|
||||
|
||||
## 8. 다음 단계
|
||||
M3 (bge-m3 batch 1/8/32 임베딩 벤치) — 운영 embed worker 시간대 분리 후 진행.
|
||||
@@ -0,0 +1,142 @@
|
||||
# M3 — bge-m3 batch 임베딩 throughput Bench
|
||||
|
||||
**측정일**: 2026-05-02
|
||||
**대상**: GPU server Ollama `:11434` `bge-m3` (latest, 1.2GB, 1024d)
|
||||
**범위**: read-only `/api/embed` 호출만. 4.0 가드 준수 (compose / migration / queue / worker restart / source_channel insert / SearXNG 도입 모두 0건). Ollama 모델/컨테이너 변경 없음.
|
||||
**bench 스크립트**: `/tmp/bench_M3_embed.py` (격리, GPU 서버 내 실행)
|
||||
**plan 참조**: `~/.claude/plans/users-hyungiahn-library-cloudstorage-sy-binary-dongarra.md` §4.
|
||||
|
||||
---
|
||||
|
||||
## 1. 사전 점검
|
||||
|
||||
| 항목 | 상태 |
|
||||
|---|---|
|
||||
| Ollama `/api/tags` healthcheck | OK (`gemma4:e4b-it-q8_0`, `bge-m3:latest` 2개) |
|
||||
| 진행 중 embed worker (사전) | embed pending 17건, processing 0건 — **운영 worker idle 직전** |
|
||||
| 측정 방식 | 단발 호출 3회씩, batch 1/8/32 — 운영 영향 최소 |
|
||||
|
||||
embed worker 와 시간대 분리 — 측정 호출이 ~1초 미만이라 worker idle 시간에 끼어들지 않음.
|
||||
|
||||
---
|
||||
|
||||
## 2. 시나리오
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 입력 텍스트 | ~250 토큰 한·영 mixed (ASME B16.5 / KGS Code / 가스기사 sample), chunk #N 으로 변형해서 unique 32 inputs 생성 |
|
||||
| API | Ollama `/api/embed`, body `{model, input: [...]}` |
|
||||
| measure | 각 batch_size 당 3회 반복 |
|
||||
| batch_size | 1, 8, 32 (plan 기본 범위) — 128 미실시 |
|
||||
|
||||
응답: 각 batch 마다 `embeddings: [[1024d], ...]`, `dim=1024` 일관.
|
||||
|
||||
---
|
||||
|
||||
## 3. 측정 결과
|
||||
|
||||
### batch=1 (3회)
|
||||
```
|
||||
repeat 1: ok elapsed=0.10s embeddings=1 dim=1024 throughput=10.7 chunks/s
|
||||
repeat 2: ok elapsed=0.08s embeddings=1 dim=1024 throughput=12.7 chunks/s
|
||||
repeat 3: ok elapsed=0.08s embeddings=1 dim=1024 throughput=12.6 chunks/s
|
||||
```
|
||||
|
||||
### batch=8 (3회)
|
||||
```
|
||||
repeat 1: ok elapsed=0.12s embeddings=8 dim=1024 throughput=67.9 chunks/s
|
||||
repeat 2: ok elapsed=0.12s embeddings=8 dim=1024 throughput=65.2 chunks/s
|
||||
repeat 3: ok elapsed=0.12s embeddings=8 dim=1024 throughput=68.6 chunks/s
|
||||
```
|
||||
|
||||
### batch=32 (3회)
|
||||
```
|
||||
repeat 1: ok elapsed=0.26s embeddings=32 dim=1024 throughput=122.6 chunks/s
|
||||
repeat 2: ok elapsed=0.25s embeddings=32 dim=1024 throughput=126.4 chunks/s
|
||||
repeat 3: ok elapsed=0.25s embeddings=32 dim=1024 throughput=130.5 chunks/s
|
||||
```
|
||||
|
||||
| batch | n | avg (s) | min (s) | max (s) | throughput (chunks/s) | error |
|
||||
|---:|---:|---:|---:|---:|---:|---:|
|
||||
| 1 | 3 | 0.088 | 0.079 | 0.106 | 11.4 | 0 |
|
||||
| 8 | 3 | 0.119 | 0.117 | 0.123 | 67.2 | 0 |
|
||||
| 32 | 3 | **0.253** | 0.245 | 0.261 | **126.4** | 0 |
|
||||
|
||||
**관찰**:
|
||||
- 모든 batch 0 error.
|
||||
- batch 32 가 batch 1 대비 throughput 11배 — GPU batch 가속 큰 효과.
|
||||
- batch 8 → 32 는 1.88×만 더 빨라짐 → batch 32 부근에서 throughput 증가 곡선 완만 (batch 128 측정 굳이 필요 없음을 시사).
|
||||
|
||||
---
|
||||
|
||||
## 4. plan 4.1 게이트 판정 (M3 관련)
|
||||
|
||||
### 게이트 4 — 150 chunks/일 임베딩 ≤ 1분 (batch 32)
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 150 chunks 처리에 필요한 batch 수 | ⌈150 / 32⌉ = **5 batches** |
|
||||
| 1 batch 평균 시간 | 0.253s |
|
||||
| 150 chunks 총 시간 | 5 × 0.253s = **1.27s** |
|
||||
| 임계값 | ≤ 60s |
|
||||
| **판정** | **✓ PASS** (여유 47×) |
|
||||
|
||||
압도적 여유. embed 자원은 LocalResearch 도입의 병목이 아님.
|
||||
|
||||
---
|
||||
|
||||
## 5. 게이트 5 — 1C/1D 충돌 점검 (read-only schema 분석)
|
||||
|
||||
```sql
|
||||
-- documents.source_channel 분포
|
||||
news 9024, manual 638, law_monitor 206, drive_sync 95, inbox_route 6, memo 6, NULL 1
|
||||
-- documents.content_origin 분포
|
||||
extracted 9976
|
||||
-- process_stage enum values
|
||||
extract, classify, embed, preview, summarize, chunk, stt, thumbnail, deep_summary, markdown
|
||||
```
|
||||
|
||||
| 점검 | 현황 | LocalResearch 영향 | 판정 |
|
||||
|---|---|---|---|
|
||||
| `documents.source_channel='web'` 값 | 미사용 (현재 6개 값 + NULL 1건) | 신규 값 추가 필요. CHECK 제약 없음. 충돌 0 | ✓ |
|
||||
| `documents.content_origin='imported'` 값 | **0건** (extracted 9976만) | Phase 1A 에서 정의된 'imported' 슬롯이 비어있어 LocalResearch 가 자연스럽게 활용 가능 | ✓ |
|
||||
| `documents.md_content` (Phase 1A) | nullable, optional-use | LocalResearch가 web→markdown 변환 후 동일 컬럼 활용 → Phase 1C `<MarkdownDoc>` 렌더러 자동 재사용 | ✓ (오히려 시너지) |
|
||||
| `document_lineage` 테이블 (Phase 1A) | 빈 테이블, RESTRICT FK | LocalResearch web 문서의 출처 추적 (search_query → urls)에 자연 활용 | ✓ (오히려 시너지) |
|
||||
| `process_stage` enum | 10개 stage. fetch/web_extract 부재 | LocalResearch Phase 2 (수집기) 진입 시 ADD VALUE migration 필요. **본 feasibility 단계에선 변경 0**. Phase 1C/1D 와는 stage 충돌 0 (markdown stage 공존 가능) | ✓ |
|
||||
| Phase 1C `<MarkdownDoc>` UI | 미배포 (다음 차례) | LocalResearch 와 같은 컴포넌트 재사용 — 충돌 0, 시너지 | ✓ |
|
||||
| Phase 1D pilot (30건 quality 측정) | 미시작 | LocalResearch 와 측정 시간대 분리만 하면 무관 | ✓ |
|
||||
|
||||
**판정**: **✓ PASS**. 인접 트랙과의 schema/queue/UI 충돌 0. Phase 1A markdown canonical layer 가 오히려 LocalResearch 진입 기반 인프라 역할.
|
||||
|
||||
---
|
||||
|
||||
## 6. LocalResearch Phase 1 진입 게이트 종합 판정
|
||||
|
||||
| # | 게이트 | 측정값 | 임계값 | 판정 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | queue capacity 여유 (M1) | classify peak +1.5%p, 전체 LLM stage +2.5%p (peak day) | ≤ 10% 추가 부하 | ✓ PASS |
|
||||
| 2 | Gemma 30건/일 (M2) | 30 × 3.51s = 1.76분 (concurrency 1) | ≤ 10분 | ✓ PASS |
|
||||
| 3 | concurrency 2 마진 (M2) | error_rate 0% (단 latency 9.5×) | error_rate = 0 | ✓ PASS |
|
||||
| 4 | 임베딩 150 chunks/일 (M3) | 5 × 0.253s = 1.27s (batch 32) | ≤ 1분 (60s) | ✓ PASS |
|
||||
| 5 | 1C/1D 충돌 (M3) | source_channel/content_origin/md_content/lineage 모두 비충돌 | 충돌 없음 | ✓ PASS |
|
||||
|
||||
### **종합: PASS (5/5)**
|
||||
|
||||
추가 관찰:
|
||||
- **M2 N=2 latency 9.5× 증가** 는 본질적 MLX concurrency=1 특성으로 새로운 위험 아니지만, **Phase 1 본격 plan 단계에서 web 요약 워커는 background queue + concurrency 1 직렬 (실시간 아님)** 로 설계 권장. ask 트래픽과 동일 시간대 경합 시 양쪽 모두 5~10× 지연 발생.
|
||||
- **content_origin='imported' 슬롯이 0건으로 비어있는 점**이 인상적 — Phase 1A 가 LocalResearch 진입을 의식하지 않고 설계됐는데도 자연스러운 자리 확보. document_lineage 테이블도 동일.
|
||||
- **process_stage 'fetch' / 'web_extract' / 'summarize_web' 추가**는 LocalResearch Phase 2 본격 plan 단계 작업. 기존 enum 10개와 충돌 없음. ORM enum 동시 갱신 필요 (메모리 `feedback_orm_db_enum_sync.md`).
|
||||
|
||||
---
|
||||
|
||||
## 7. STOP — 사용자 검토 대기
|
||||
|
||||
plan §4.2 명시된 **Stop Point** 도달:
|
||||
|
||||
> M3 보고서 + 게이트 판정 표 작성 직후 작업 정지.
|
||||
> LocalResearch Phase 1 상세 plan 작성, SearXNG 도입, 코드 변경, plan 모드 재진입 등 일체 금지.
|
||||
> 사용자가 게이트 판정 검토 후 다음 액션을 명시적으로 지시할 때까지 대기.
|
||||
|
||||
본 reports 3개 (`local_research_M1_throughput.md` + `_M2_mlx_capacity.md` + `_M3_embedding_throughput.md`) 가 dashboard 산출물. 코드/스키마 변경 0, inventory soft lock 위반 0, queue stage 변경 0.
|
||||
|
||||
다음 액션은 사용자 결정.
|
||||
Reference in New Issue
Block a user