Files
hyungi_document_server/reports/local_research_M3_embedding_throughput.md
T
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

7.0 KiB
Raw Blame History

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 분석)

-- 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.

다음 액션은 사용자 결정.