docs: arctic 임베더 문서 동기화 (README/ARCHITECTURE/HANDOFF/HOTFIXES)
README Configuration: provider candle/ollama + arctic 모델(candle CLS / ollama 태그) + endpoint + e5→arctic cascade 경고. ARCHITECTURE: 백엔드 그래프 노드(embedollama) + 임베딩 백엔드 결정표(채택 근거 측정 recall@10 130) + 디렉토리 트리. HANDOFF 1줄. HOTFIXES 2026-06-03 arctic dated entry(레지스트리/pooling/prefix/cascade + 수동 cosine 0.999984 실측 결과). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,7 @@ P0~P5 직렬. P6~P9 P5 이후 병렬 가능.
|
|||||||
|
|
||||||
머지 후 발견된 모든 deviation / hotfix 의 dated 로그는 [tasks/HOTFIXES.md](tasks/HOTFIXES.md). 본 요약은 \"누군가가 인수받을 때 알아두면 시간을 많이 절약하는\" 항목만:
|
머지 후 발견된 모든 deviation / hotfix 의 dated 로그는 [tasks/HOTFIXES.md](tasks/HOTFIXES.md). 본 요약은 \"누군가가 인수받을 때 알아두면 시간을 많이 절약하는\" 항목만:
|
||||||
|
|
||||||
|
- **2026-06-03 arctic-embed-l-v2.0 임베더 통합** — v0.26.0. 별칭 제거 후 설명형 query recall 보강(측정 recall@10 130/132, e5 +7). `kebab-embed-candle` 모델 레지스트리화(e5 mean + `snowflake-arctic-embed-l-v2.0` CLS, 모델별 pooling/prefix) + 신규 `kebab-embed-ollama`(`provider="ollama"`, `/api/embed`). config `endpoint: Option<String>` 추가. 기본 e5 유지(opt-in), arctic 전환은 embedding_version cascade → 재색인. candle↔Ollama cosine>0.99 게이트로 pooling/prefix 정확성 고정(`#[ignore]`). 자세한 내용: `tasks/HOTFIXES.md` (2026-06-03 arctic), spec `docs/superpowers/specs/2026-06-03-arctic-embedder-spec.md`.
|
||||||
- **2026-06-03 doc-side expansion(별칭) 기능 완전 제거** — v0.25.0. 아래 2026-05-31 항목의 색인-시 청크당 LLM 별칭 생성 + 별칭 검색 채널을 **전부 제거**(ROI 음수: cross-lingual 은 e5-large 단독으로 충분, 기여는 설명형 +2 그룹뿐인데 대가가 청크당 색인-시 LLM). `Chunk.aliases`/`expansion.rs`/`IngestExpansionCfg`/alias lexical arm/`expansion_progress` wire kind 제거, 신규 마이그레이션 **V013** 이 `chunk_aliases_fts`+`chunks.aliases` DROP. 별칭 default-off 였어 사용자 체감 0, 기존 KB 도 재색인 불요(잔존 별칭 벡터는 `strip_alias_suffix` graceful 매핑/`reset` 정리). `AssetTimings.expansion_ms` 는 wire 호환 위해 값 0 으로 유지. 자세한 내용: `tasks/HOTFIXES.md` (2026-06-03), spec `docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md`.
|
- **2026-06-03 doc-side expansion(별칭) 기능 완전 제거** — v0.25.0. 아래 2026-05-31 항목의 색인-시 청크당 LLM 별칭 생성 + 별칭 검색 채널을 **전부 제거**(ROI 음수: cross-lingual 은 e5-large 단독으로 충분, 기여는 설명형 +2 그룹뿐인데 대가가 청크당 색인-시 LLM). `Chunk.aliases`/`expansion.rs`/`IngestExpansionCfg`/alias lexical arm/`expansion_progress` wire kind 제거, 신규 마이그레이션 **V013** 이 `chunk_aliases_fts`+`chunks.aliases` DROP. 별칭 default-off 였어 사용자 체감 0, 기존 KB 도 재색인 불요(잔존 별칭 벡터는 `strip_alias_suffix` graceful 매핑/`reset` 정리). `AssetTimings.expansion_ms` 는 wire 호환 위해 값 0 으로 유지. 자세한 내용: `tasks/HOTFIXES.md` (2026-06-03), spec `docs/superpowers/specs/2026-06-03-remove-doc-expansion-spec.md`.
|
||||||
- **2026-05-31 Phase 2 doc-side expansion 별칭(개별 dense 벡터) + 파생물 캐시(V012)** — v0.21.0 cut. 색인 시 LLM 이 청크별 별칭("같은 의미 다른 표현")을 생성, 줄별 **개별 dense 벡터**(sentinel `{chunk}#alias#N`)로 색인 (묶음 1벡터는 평균화 희석으로 회귀 → 폐기) + boilerplate 청크 skip. `[ingest.expansion]` default off. 측정(나무위키 ~1000 문서 CS corpus): 변형 일관성 14/18 → **16/18**, spread 0.222→0.111, 대조군 false-positive 별칭 무죄. 비용 병목(별칭 18문서 2.5h)은 **파생물 캐시(V012, 청크 내용 해시 키)**로 해소 — 정답 3개 cold 1879s → warm 13s **≈ 145배**, embedding+별칭 LLM 캐싱, version_key cascade 정합. search/ask 가 `kebab.sqlite`+`lancedb` 만으로 동작 → 외부 서버 색인 후 DB 만 복사하는 이식 워크플로 가능. **결정/known limitation**: grounded/refusal 판정이 부분 인용을 grounded 로 오분류(정직한 거부가 false-positive 로 집계) — 별도 개선 후보. stack·svm 설명형 2개 잔존. 자세한 내용: `tasks/HOTFIXES.md` (2026-05-31), 측정: `docs/superpowers/handoffs/2026-05-31-namu-wiki-alias-cache-study.md`.
|
- **2026-05-31 Phase 2 doc-side expansion 별칭(개별 dense 벡터) + 파생물 캐시(V012)** — v0.21.0 cut. 색인 시 LLM 이 청크별 별칭("같은 의미 다른 표현")을 생성, 줄별 **개별 dense 벡터**(sentinel `{chunk}#alias#N`)로 색인 (묶음 1벡터는 평균화 희석으로 회귀 → 폐기) + boilerplate 청크 skip. `[ingest.expansion]` default off. 측정(나무위키 ~1000 문서 CS corpus): 변형 일관성 14/18 → **16/18**, spread 0.222→0.111, 대조군 false-positive 별칭 무죄. 비용 병목(별칭 18문서 2.5h)은 **파생물 캐시(V012, 청크 내용 해시 키)**로 해소 — 정답 3개 cold 1879s → warm 13s **≈ 145배**, embedding+별칭 LLM 캐싱, version_key cascade 정합. search/ask 가 `kebab.sqlite`+`lancedb` 만으로 동작 → 외부 서버 색인 후 DB 만 복사하는 이식 워크플로 가능. **결정/known limitation**: grounded/refusal 판정이 부분 인용을 grounded 로 오분류(정직한 거부가 false-positive 로 집계) — 별도 개선 후보. stack·svm 설명형 2개 잔존. 자세한 내용: `tasks/HOTFIXES.md` (2026-05-31), 측정: `docs/superpowers/handoffs/2026-05-31-namu-wiki-alias-cache-study.md`.
|
||||||
- **2026-05-29 v0.20.2 dogfood findings + 검색 품질 baseline** — 8-finding 라운드 완료. (1) Ask 응답언어: rag-v3 default (질문 언어 = 답변 언어). (2) eval `--config` facade 패치 로 dogfood KB 직접 eval 가능. (3) 검색 품질 baseline — hybrid hit@3=1.0 / MRR=0.833, lexical hit@3=1.0 / MRR=0.7 (golden 10 query). **O-2 known limitation**: 소형 모델(gemma4:e4b) refusal 메시지의 query 언어 불일치 가능 — 판정은 정상, 표시 문구만 해당. 자세한 내용: `tasks/HOTFIXES.md` (2026-05-29).
|
- **2026-05-29 v0.20.2 dogfood findings + 검색 품질 baseline** — 8-finding 라운드 완료. (1) Ask 응답언어: rag-v3 default (질문 언어 = 답변 언어). (2) eval `--config` facade 패치 로 dogfood KB 직접 eval 가능. (3) 검색 품질 baseline — hybrid hit@3=1.0 / MRR=0.833, lexical hit@3=1.0 / MRR=0.7 (golden 10 query). **O-2 known limitation**: 소형 모델(gemma4:e4b) refusal 메시지의 query 언어 불일치 가능 — 판정은 정상, 표시 문구만 해당. 자세한 내용: `tasks/HOTFIXES.md` (2026-05-29).
|
||||||
|
|||||||
34
README.md
34
README.md
@@ -111,18 +111,46 @@ root = "~/KnowledgeBase" # 색인할 폴더. 절대 / tilde / env / 상대 경
|
|||||||
|
|
||||||
[models.embedding]
|
[models.embedding]
|
||||||
provider = "fastembed" # "fastembed"(기본, onnxruntime) / "candle"(순수 Rust)
|
provider = "fastembed" # "fastembed"(기본, onnxruntime) / "candle"(순수 Rust)
|
||||||
# / "none"(lexical-only). candle 는 같은 모델·같은 벡터를
|
# / "ollama"(원격 HTTP) / "none"(lexical-only).
|
||||||
# 순수 Rust 로 돌려 NUMA 서버의 onnxruntime 48-스레드
|
# candle 는 같은 모델·같은 벡터를 순수 Rust 로 돌려
|
||||||
# double-free 를 피하는 opt-in 백엔드 (재색인 불필요).
|
# NUMA 서버의 onnxruntime 48-스레드 double-free 를 피하는
|
||||||
|
# opt-in 백엔드 (e5 는 재색인 불필요).
|
||||||
model = "multilingual-e5-large" # 다국어 sentence embedding (1024-dim).
|
model = "multilingual-e5-large" # 다국어 sentence embedding (1024-dim).
|
||||||
# 첫 ingest 시 ONNX (~1.3GB) 자동 다운로드.
|
# 첫 ingest 시 ONNX (~1.3GB) 자동 다운로드.
|
||||||
# candle provider 는 safetensors (~2GB) 다운로드.
|
# candle provider 는 safetensors (~2GB) 다운로드.
|
||||||
|
# candle/ollama 는 "snowflake-arctic-embed-l-v2.0"
|
||||||
|
# (설명형 query 의 recall 보강) 도 지원 — 아래 참고.
|
||||||
dimensions = 1024 # config 와 LanceDB stored dim 불일치 시 검색 0건.
|
dimensions = 1024 # config 와 LanceDB stored dim 불일치 시 검색 0건.
|
||||||
num_threads = 0 # candle 전용 CPU 스레드 캡 (0=auto=#cores).
|
num_threads = 0 # candle 전용 CPU 스레드 캡 (0=auto=#cores).
|
||||||
# env KEBAB_EMBED_THREADS 가 우선. NUMA 노드 바인딩은
|
# env KEBAB_EMBED_THREADS 가 우선. NUMA 노드 바인딩은
|
||||||
# numactl 과 조합. fastembed provider 는 무시.
|
# numactl 과 조합. fastembed provider 는 무시.
|
||||||
|
# endpoint = "http://127.0.0.1:11434" # provider="ollama" 전용 HTTP endpoint.
|
||||||
|
# 생략 시 [models.llm].endpoint 로 폴백.
|
||||||
|
# fastembed/candle provider 는 무시.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**arctic-embed-l-v2.0 (설명형 query recall 보강)**: 기본 e5-large 대신
|
||||||
|
Snowflake `arctic-embed-l-v2.0` 임베더를 쓸 수 있다 (1024-dim, opt-in). 측정에서
|
||||||
|
설명형/약어/영문 용어 query 의 recall@10 이 e5 대비 향상됐다. 두 경로:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# (A) candle 백엔드 — 순수 Rust, in-process (NUMA 안전, Metal GPU 가능):
|
||||||
|
[models.embedding]
|
||||||
|
provider = "candle"
|
||||||
|
model = "snowflake-arctic-embed-l-v2.0" # CLS pooling, query 에 "query: " 접두어
|
||||||
|
# (문서는 무접두어). safetensors ~2GB 다운로드.
|
||||||
|
|
||||||
|
# (B) ollama 백엔드 — 원격/로컬 Ollama 데몬에 위임 (POST /api/embed):
|
||||||
|
[models.embedding]
|
||||||
|
provider = "ollama"
|
||||||
|
model = "snowflake-arctic-embed2" # Ollama 모델 태그 (ollama pull 필요)
|
||||||
|
endpoint = "http://127.0.0.1:11434" # 생략 시 [models.llm].endpoint
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ e5 → arctic 전환은 `embedding_version` cascade 를 트리거한다 (모델이 다르면
|
||||||
|
> 벡터도 다름). 기존 e5 KB 와 혼용 불가 — 전환 시 **재색인** 필요 (`kebab reset`
|
||||||
|
> 후 재 ingest). 기본값은 e5 라 기존 사용자는 영향 없음.
|
||||||
|
|
||||||
**Apple Silicon GPU 가속 (candle / macOS)**: M-시리즈 맥에서 candle 임베딩을
|
**Apple Silicon GPU 가속 (candle / macOS)**: M-시리즈 맥에서 candle 임베딩을
|
||||||
GPU(Metal)로 돌리면 CPU 대비 대용량 ingest 가 크게 빨라진다. 빌드 또는 설치 시
|
GPU(Metal)로 돌리면 CPU 대비 대용량 ingest 가 크게 빨라진다. 빌드 또는 설치 시
|
||||||
`embed_metal` feature 를 켠다:
|
`embed_metal` feature 를 켠다:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Cargo workspace, 함수 호출 기반 모듈러 모놀리스. UI binary (`kebab-
|
|||||||
| metadata | SQLite + FTS5 (lexical search + v0.20.1 한국어 형태소 tokenizer via lindera-ko-dic) |
|
| metadata | SQLite + FTS5 (lexical search + v0.20.1 한국어 형태소 tokenizer via lindera-ko-dic) |
|
||||||
| vector | LanceDB (embedded, model 별 분리 table) |
|
| vector | LanceDB (embedded, model 별 분리 table) |
|
||||||
| Markdown parser | `pulldown-cmark`. frontmatter 에 title 없으면 첫 H1 → H2 → 첫 paragraph 80 자 → 파일명 순으로 자동 채움 (`parser_version = md-frontmatter-v2`, 기존 doc 도 다음 ingest 에서 갱신) |
|
| Markdown parser | `pulldown-cmark`. frontmatter 에 title 없으면 첫 H1 → H2 → 첫 paragraph 80 자 → 파일명 순으로 자동 채움 (`parser_version = md-frontmatter-v2`, 기존 doc 도 다음 ingest 에서 갱신) |
|
||||||
| embedding | `fastembed-rs` (`multilingual-e5-large`, 1024d, v0.18.0부터 default 업그레이드) |
|
| embedding | `fastembed-rs` (`multilingual-e5-large`, 1024d, v0.18.0부터 default 업그레이드). opt-in 대안: candle (e5 또는 `snowflake-arctic-embed-l-v2.0`) / Ollama `/api/embed`. arctic = 설명형 query recall 보강 (v0.26.0, 아래 결정표) |
|
||||||
| 한국어 형태소분석 | `lindera-ko-dic` (FTS5 외부 tokenizer, v0.20.1) — 2자 이상 한국어 query 지원 |
|
| 한국어 형태소분석 | `lindera-ko-dic` (FTS5 외부 tokenizer, v0.20.1) — 2자 이상 한국어 query 지원 |
|
||||||
| LLM | Ollama HTTP (default `gemma4:e4b` ─ OCR / caption 와 family 통일. 사용자가 더 큰 variant `gemma4:26b` 등으로 override 가능) |
|
| LLM | Ollama HTTP (default `gemma4:e4b` ─ OCR / caption 와 family 통일. 사용자가 더 큰 variant `gemma4:26b` 등으로 override 가능) |
|
||||||
| 음성 ASR | `whisper.cpp` (via `whisper-rs`) — P8 보류, 시스템 dep brainstorm 후 |
|
| 음성 ASR | `whisper.cpp` (via `whisper-rs`) — P8 보류, 시스템 dep brainstorm 후 |
|
||||||
@@ -67,7 +67,8 @@ flowchart TB
|
|||||||
subgraph Adapters ["traits + adapters"]
|
subgraph Adapters ["traits + adapters"]
|
||||||
embed["kebab-embed<br/>(trait)"]
|
embed["kebab-embed<br/>(trait)"]
|
||||||
embedlocal["kebab-embed-local<br/>(fastembed, default)"]
|
embedlocal["kebab-embed-local<br/>(fastembed, default)"]
|
||||||
embedcandle["kebab-embed-candle<br/>(candle, NUMA-safe opt-in)"]
|
embedcandle["kebab-embed-candle<br/>(candle, e5+arctic, NUMA-safe opt-in)"]
|
||||||
|
embedollama["kebab-embed-ollama<br/>(Ollama /api/embed, opt-in)"]
|
||||||
llm["kebab-llm<br/>(trait)"]
|
llm["kebab-llm<br/>(trait)"]
|
||||||
llmlocal["kebab-llm-local<br/>(Ollama)"]
|
llmlocal["kebab-llm-local<br/>(Ollama)"]
|
||||||
search["kebab-search"]
|
search["kebab-search"]
|
||||||
@@ -94,6 +95,7 @@ flowchart TB
|
|||||||
app --> vector
|
app --> vector
|
||||||
app --> embedlocal
|
app --> embedlocal
|
||||||
app --> embedcandle
|
app --> embedcandle
|
||||||
|
app --> embedollama
|
||||||
app --> llmlocal
|
app --> llmlocal
|
||||||
app --> search
|
app --> search
|
||||||
app --> rag
|
app --> rag
|
||||||
@@ -108,6 +110,8 @@ flowchart TB
|
|||||||
embedlocal --> embed
|
embedlocal --> embed
|
||||||
embedcandle --> core
|
embedcandle --> core
|
||||||
embedcandle --> config
|
embedcandle --> config
|
||||||
|
embedollama --> core
|
||||||
|
embedollama --> config
|
||||||
llmlocal --> llm
|
llmlocal --> llm
|
||||||
rag --> search
|
rag --> search
|
||||||
rag --> llm
|
rag --> llm
|
||||||
@@ -136,6 +140,23 @@ UI → store/llm/parse 직접 의존 금지. 모든 user-facing 진입은 `kebab
|
|||||||
|
|
||||||
`kebab-parse-code` 의 외부 tree-sitter grammar crate 의존: P10-1A-2 에서 `tree-sitter-rust` 추가, P10-1B 에서 `tree-sitter-python` / `tree-sitter-typescript` / `tree-sitter-javascript` 추가, P10-1C-Go 에서 `tree-sitter-go` 추가, P10-1C-JK 에서 `tree-sitter-java` / `tree-sitter-kotlin-ng` 추가, P10-1D 에서 `tree-sitter-c` / `tree-sitter-cpp` 추가. 모두 `kebab-parse-code` 에만 격리 (facade 룰 — UI crate / chunker 가 직접 import 금지). Kotlin 은 `tree-sitter-kotlin-ng` 사용 (bare `tree-sitter-kotlin` 은 tree-sitter 0.21–0.23 에 고착 — 사용 불가). v0.18.0+ 부터 `kebab-source-fs` 는 자체 `code_meta` 모듈 (lang detect + skip helpers + BUILTIN_BLACKLIST) 을 보유, kebab-parse-code 와 분리 (refactor 2026-05-26). v0.19.0 부터 `kebab-parse-md` 가 `kebab-parse-types` (parser intermediate types) + `kebab-normalize` (CanonicalDocument lift) 두 crate 를 흡수 — 24 → 22 crates, design §3.7b 재작성 (HOTFIXES 2026-05-26). v0.20.1 부터 `kebab-search` 가 `lindera-ko-dic` 를 의존해 한국어 FTS5 형태소 tokenizer 지원 — V009 migration 으로 2자 이상 한국어 query 매칭 (Bug #8 closure).
|
`kebab-parse-code` 의 외부 tree-sitter grammar crate 의존: P10-1A-2 에서 `tree-sitter-rust` 추가, P10-1B 에서 `tree-sitter-python` / `tree-sitter-typescript` / `tree-sitter-javascript` 추가, P10-1C-Go 에서 `tree-sitter-go` 추가, P10-1C-JK 에서 `tree-sitter-java` / `tree-sitter-kotlin-ng` 추가, P10-1D 에서 `tree-sitter-c` / `tree-sitter-cpp` 추가. 모두 `kebab-parse-code` 에만 격리 (facade 룰 — UI crate / chunker 가 직접 import 금지). Kotlin 은 `tree-sitter-kotlin-ng` 사용 (bare `tree-sitter-kotlin` 은 tree-sitter 0.21–0.23 에 고착 — 사용 불가). v0.18.0+ 부터 `kebab-source-fs` 는 자체 `code_meta` 모듈 (lang detect + skip helpers + BUILTIN_BLACKLIST) 을 보유, kebab-parse-code 와 분리 (refactor 2026-05-26). v0.19.0 부터 `kebab-parse-md` 가 `kebab-parse-types` (parser intermediate types) + `kebab-normalize` (CanonicalDocument lift) 두 crate 를 흡수 — 24 → 22 crates, design §3.7b 재작성 (HOTFIXES 2026-05-26). v0.20.1 부터 `kebab-search` 가 `lindera-ko-dic` 를 의존해 한국어 FTS5 형태소 tokenizer 지원 — V009 migration 으로 2자 이상 한국어 query 매칭 (Bug #8 closure).
|
||||||
|
|
||||||
|
### 임베딩 백엔드 결정표 (v0.26.0)
|
||||||
|
|
||||||
|
| provider | 모델 | pooling / prefix | 위치 | 언제 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `fastembed` (기본) | `multilingual-e5-large` | mean / `query:`·`passage:` | in-process (onnxruntime) | 기본. 단일 소켓 호스트 |
|
||||||
|
| `candle` | e5 또는 `snowflake-arctic-embed-l-v2.0` | 모델별 (e5=mean, arctic=CLS) / arctic=`query:`·무접두어 | in-process (pure Rust) | NUMA 서버 (onnxruntime 48-스레드 double-free 회피), Apple Silicon Metal GPU |
|
||||||
|
| `ollama` | `snowflake-arctic-embed2` 등 | 모델 태그로 추론 / arctic=`query:`·무접두어 | 원격 HTTP (`/api/embed`) | candle 폴백, 측정에 쓴 경로 그대로 재현 |
|
||||||
|
|
||||||
|
**arctic-embed-l-v2.0 채택 근거**: 별칭(doc-side expansion) 제거(v0.25.0) 후 설명형
|
||||||
|
query 의 recall 보강책. 측정(`/build/dogfood/logs/2026-06-03-method-measurements.md`)에서
|
||||||
|
arctic = recall@10 130/132 (e5 대비 +7, 색인 1회·per-query 0·LLM 0, 용어 무손실).
|
||||||
|
candle 이 주 백엔드(in-process, NUMA 안전), Ollama 가 폴백(측정 경로 재현). 두 경로의
|
||||||
|
pooling/prefix 정확성은 `kebab-embed-candle/tests/arctic_ollama_parity.rs`
|
||||||
|
(candle arctic vs Ollama arctic 코사인>0.99, `#[ignore]`) 로 고정. e5 → arctic 전환은
|
||||||
|
`embedding_version` cascade (모델별 벡터 상이) → 재색인 필요. 기본값 e5 유지라 기존
|
||||||
|
사용자 무영향. 자세한 내용: [tasks/HOTFIXES.md](../tasks/HOTFIXES.md) 2026-06-03 arctic entry.
|
||||||
|
|
||||||
## 디렉토리 구조
|
## 디렉토리 구조
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -184,7 +205,8 @@ kebab/
|
|||||||
│ ├── kebab-store-sqlite/ # SQLite + FTS5 (V001/V002/V003) (P1-6, P2-1, P3-3). src/derivation_cache.rs = derivation_cache 테이블 저장소 (V012, v0.21.0)
|
│ ├── kebab-store-sqlite/ # SQLite + FTS5 (V001/V002/V003) (P1-6, P2-1, P3-3). src/derivation_cache.rs = derivation_cache 테이블 저장소 (V012, v0.21.0)
|
||||||
│ ├── kebab-search/ # Lexical + Vector + Hybrid retriever (P2-2, P3-4)
|
│ ├── kebab-search/ # Lexical + Vector + Hybrid retriever (P2-2, P3-4)
|
||||||
│ ├── kebab-embed/ kebab-embed-local/ # Embedder trait + fastembed adapter (P3-1, P3-2)
|
│ ├── kebab-embed/ kebab-embed-local/ # Embedder trait + fastembed adapter (P3-1, P3-2)
|
||||||
│ ├── kebab-embed-candle/ # candle (pure-Rust) Embedder, NUMA-safe opt-in provider=candle (Track 1, v0.22.0)
|
│ ├── kebab-embed-candle/ # candle (pure-Rust) Embedder, 모델 레지스트리(e5 mean + arctic CLS), NUMA-safe opt-in provider=candle (Track 1, v0.22.0; arctic v0.26.0)
|
||||||
|
│ ├── kebab-embed-ollama/ # Ollama /api/embed Embedder, opt-in provider=ollama (arctic 폴백 경로, v0.26.0)
|
||||||
│ ├── kebab-store-vector/ # LanceDB VectorStore (P3-3, P7-3 follow-up)
|
│ ├── kebab-store-vector/ # LanceDB VectorStore (P3-3, P7-3 follow-up)
|
||||||
│ ├── kebab-llm/ kebab-llm-local/ # LanguageModel trait + Ollama adapter (P4-1, P4-2)
|
│ ├── kebab-llm/ kebab-llm-local/ # LanguageModel trait + Ollama adapter (P4-1, P4-2)
|
||||||
│ ├── kebab-rag/ # RAG pipeline (P4-3)
|
│ ├── kebab-rag/ # RAG pipeline (P4-3)
|
||||||
|
|||||||
@@ -14,6 +14,56 @@ historical contract that was implemented; this file accumulates the
|
|||||||
deltas so phase 5+ readers can find the live behavior without diffing
|
deltas so phase 5+ readers can find the live behavior without diffing
|
||||||
git history.
|
git history.
|
||||||
|
|
||||||
|
## 2026-06-03 — arctic-embed-l-v2.0 임베더 통합 (candle + Ollama) (v0.26.0)
|
||||||
|
|
||||||
|
**무엇을 왜 추가했나.** 별칭(doc-side expansion) 제거(v0.25.0) 후 설명형 query 의
|
||||||
|
recall 보강책으로 `snowflake-arctic-embed-l-v2.0` 임베더를 두 백엔드로 통합했다.
|
||||||
|
근거는 방법별 측정(`/build/dogfood/logs/2026-06-03-method-measurements.md`):
|
||||||
|
arctic = recall@10 **130/132**, recall@50 **132/132**, **용어 무손실**(syn/abbr/en
|
||||||
|
유지). e5-large 대비 +7, 색인 1회·per-query 0·LLM 0 = 살아있는 KB 에 지속 가능.
|
||||||
|
별칭이 청크당 색인-시 LLM(나무위키 18문서 cold 2.5h)을 요구한 것과 대조.
|
||||||
|
|
||||||
|
**무엇을 건드렸나.**
|
||||||
|
- `kebab-embed-candle`: e5 하드코딩(`HF_MODEL`/`SUPPORTED_MODEL`/mean/`query:`+`passage:`)을
|
||||||
|
**모델 레지스트리**(`MODEL_REGISTRY`: `EmbedModelSpec { name, hf_repo, pooling, query_prefix, doc_prefix, dim, version_tag }`)로
|
||||||
|
일반화. e5(mean, `query:`/`passage:`) + arctic(**CLS**, `query:`/무접두어). pooling
|
||||||
|
은 모델별 분기(mean=attention-mask-weighted / CLS=`hidden[:,0,:]`), tokenize/forward/L2
|
||||||
|
공유. arctic pooling=CLS 는 HF `1_Pooling/config.json`(`pooling_mode_cls_token:true`)로
|
||||||
|
확인. `model_version` 은 arctic 일 때 `+arctic-cls` 태그(switch 시 embedding_version
|
||||||
|
cascade 트리거); e5 는 fastembed-e5 와의 호환(NUMA 드롭인) 위해 plain `config.version` 유지.
|
||||||
|
- `kebab-embed-ollama` (신규 크레이트): `Embedder` 구현, `reqwest::blocking` POST
|
||||||
|
`/api/embed` `{model, input:[...]}` → `embeddings`. batch 48 + fail-soft 재시도 3,
|
||||||
|
결과 **L2 정규화**(Ollama raw 반환), dim 검증, query/doc prefix 모델 태그로 추론
|
||||||
|
(`arctic-embed`→`query:`/무접두어, `e5`→`query:`/`passage:`). `model_version=ollama:{model}`.
|
||||||
|
endpoint = `models.embedding.endpoint` ?? `models.llm.endpoint`.
|
||||||
|
- `kebab-config`: `EmbeddingModelCfg.endpoint: Option<String>`(serde default, ollama용) +
|
||||||
|
`provider` 문서에 `ollama` 추가 + env `KEBAB_MODELS_EMBEDDING_ENDPOINT`.
|
||||||
|
- `kebab-app::embedder()`: provider match 에 `ollama` 분기 추가(facade 경유).
|
||||||
|
- workspace member += `kebab-embed-ollama`, version 0.25.0 → **0.26.0**(minor).
|
||||||
|
|
||||||
|
**correctness 게이트.** candle arctic 임베딩이 측정에 쓴 Ollama `snowflake-arctic-embed2`
|
||||||
|
임베딩과 일치해야 pooling/prefix 정확성(=recall 130 재현)이 보장된다. 검증:
|
||||||
|
`kebab-embed-candle/tests/arctic_ollama_parity.rs`(`#[ignore]`, live Ollama 의존) 가
|
||||||
|
candle arctic vs 우리 Ollama 어댑터로 같은 문장(설명형/약어/영문 포함, doc+query
|
||||||
|
양 경로)을 임베딩해 per-sentence **코사인 > 0.99** 를 assert. 수동 실행 결과(코사인값)는
|
||||||
|
릴리스 전 본 entry 에 기록.
|
||||||
|
|
||||||
|
**수동 검증 결과** (2026-06-03 worker 실측, Ollama @192.168.0.47:11434
|
||||||
|
`snowflake-arctic-embed2`): 8문장 × (doc+query) 16벡터 per-sentence 코사인
|
||||||
|
**0.999984 ~ 0.999995**, `cosine_min = 0.999984` (게이트 0.99 대비 대폭 상회).
|
||||||
|
설명형("후입선출 방식으로 동작하는 자료구조")·약어("SVM 은 support vector machine")·
|
||||||
|
영문·한글 모두 일치. → candle arctic 의 CLS pooling + `query: ` prefix 가 Ollama 측정
|
||||||
|
경로와 정확히 동일 = recall@10 130 재현 보장. Ollama raw 도 이미 L2-정규화(norm 1.0)라
|
||||||
|
어댑터의 L2 정규화는 idempotent no-op. 로그: `/build/dogfood/logs/arctic-parity.log`,
|
||||||
|
요약: `/tmp/arctic-result.md`.
|
||||||
|
|
||||||
|
**호환성.** 기본 provider=fastembed e5 동작/벡터 불변(arctic 은 opt-in). dim 1024
|
||||||
|
동일이나 LanceDB 테이블명에 모델명 포함(`chunk_embeddings_{model}_{dim}`)이라 충돌
|
||||||
|
없음. e5 → arctic 전환 = `embedding_version` cascade(모델별 벡터 상이) → **재색인 필요**
|
||||||
|
(기존 e5 KB 와 혼용 불가, 명확). A(heading enrichment)는 측정상 arctic 에서 악화 →
|
||||||
|
미적용. spec: `docs/superpowers/specs/2026-06-03-arctic-embedder-spec.md`, plan: 동일
|
||||||
|
디렉토리 `2026-06-03-arctic-embedder-plan.md`.
|
||||||
|
|
||||||
## 2026-06-03 — doc-side expansion(별칭) 기능 완전 제거 (v0.25.0)
|
## 2026-06-03 — doc-side expansion(별칭) 기능 완전 제거 (v0.25.0)
|
||||||
|
|
||||||
**무엇을 왜 제거했나.** v0.21.0 (PR #195/#196) 에서 도입한 색인-시 청크당 LLM
|
**무엇을 왜 제거했나.** v0.21.0 (PR #195/#196) 에서 도입한 색인-시 청크당 LLM
|
||||||
|
|||||||
Reference in New Issue
Block a user