Documentation
¶
Overview ¶
Package embed는 문서를 벡터로 바꾼다. 재발견의 의미 축이 이것을 쓴다.
백엔드는 hugot 의 순수 Go 경로 하나이며 코어의 CGO_ENABLED=0 을 지킨다. onnxruntime 이 22배 빠르나 네이티브 라이브러리 둘이 붙어 단일 정적 바이너리 계약을 깬다. 그 대신 계산 시점을 reindex 가 아니라 bridge 로 옮겨 편집마다 비용을 물지 않게 했다. 근거와 재검토 조건은 ADR 0074 에 있다.
벡터는 문서 하나에 하나이고 대상은 제목과 본문을 이은 앞 Chars 자다. ADR 0075.
Index ¶
- Constants
- Variables
- func Cached(wikiRoot string, docs []ComputeDoc) map[string][]float32
- func Compute(wikiRoot string, docs []ComputeDoc, progress func(done, total int)) (map[string][]float32, error)
- func Download(ctx context.Context, client *http.Client, base, dir string, prog ProgressFn) ([]string, error)
- func Import(src, dir string) ([]string, error)
- func Key(text string) string
- func LoadCache(wikiRoot string) map[string][]float32
- func ModelDir() (string, error)
- func Present() bool
- func SaveCache(wikiRoot string, vectors map[string][]float32, keep map[string]bool) error
- func Truncate(text string) string
- type ComputeDoc
- type Encoder
- type FileStatus
- type ModelFile
- type ProgressFn
Constants ¶
const BatchSize = 8
BatchSize는 한 번에 인코딩할 문서 수다. 8은 upstream 의 값이다(ADR 0075).
const CacheSchemaVersion = 2
CacheSchemaVersion는 벡터 캐시 JSON의 스키마 버전이다. 모델이나 풀링이나 Chars 가 바뀌면 벡터 값 자체가 달라지므로 올리고, 버전이 다른 캐시는 통째로 버린다.
1은 bge-m3 fp32 를 평균 풀링으로 읽던 형식이다. 2는 CLS 풀링으로 바꾼 것이다. 같은 모델이지만 벡터가 전혀 다르다. 1로 만든 캐시를 2에서 쓰면 코사인이 뭉개진 값 그대로 남는다(ADR 0074, 0075).
const Chars = 2000
Chars는 인코딩에 쓰는 텍스트 길이다. upstream 의 EMBED_CHARS 와 같은 값으로 두어 재발견 순위를 비교할 수 있게 한다(ADR 0075).
const Dims = 1024
Dims는 bge-m3 의 출력 차원이다.
const DownloadBase = "https://huggingface.co/Xenova/bge-m3/resolve/" + Revision
DownloadBase는 내려받기 URL 의 앞부분이다. 파일의 저장소 안 경로를 붙여 쓴다. 테스트는 이 값을 httptest 서버 주소로 바꿔 끼운다.
const EnvModelDir = "ENGRAM_MODEL_DIR"
EnvModelDir는 모델 디렉토리를 덮어쓰는 환경변수다. 오프라인 반입, 공유 마운트, 테스트가 이 경로를 쓴다.
const ModelName = "bge-m3"
ModelName은 모델 디렉토리 이름이다. 사이드카 목록이 하나이므로 고정한다(ADR 0068, 0074).
const Revision = "4de13258303883538bd53b696b452bf8099f0858"
Revision은 내려받기를 고정하는 HuggingFace 커밋 SHA 다. main 을 쓰지 않는 이유는 같은 model pull 이 언제 돌아도 같은 바이트를 받아야 하기 때문이다(ADR 0074). Xenova/bge-m3 의 2026-02-10 시점 HEAD 다.
const VectorsFileName = "vectors.json"
VectorsFileName은 위키 루트 .engram 아래의 벡터 캐시 파일 이름이다. .engram 은 gitignore 대상이므로 커밋되지 않는다.
Variables ¶
var ( ErrChecksum = modelfetch.ErrChecksum ErrSize = modelfetch.ErrSize ErrMissingFile = modelfetch.ErrMissingFile )
내려받기 실패의 종류다. 호출자가 문구를 고르게 보내는 값이다.
var ErrNoModel = errors.New("모델 없음")
ErrNoModel은 모델이 없을 때의 오류다. 호출자는 이것을 받으면 의미 축을 빼고 계속 간다. 시맨틱의 부재는 결손이 아니라 성능 저하다(ADR 0007).
Functions ¶
func Cached ¶
func Cached(wikiRoot string, docs []ComputeDoc) map[string][]float32
Cached는 캐시에 이미 있는 벡터만 낸다. 모델을 열지 않고 없는 것을 계산하지도 않으며 캐시를 다시 쓰지도 않는다.
응답이 빨라야 하는 자리에서 쓴다. 임베딩은 문서당 12.6초라 도구 호출 안에서 계산할 수 없다. 캐시를 채우는 것은 bridge 커맨드의 몫이고 여기서는 그 결과를 읽기만 한다. 캐시가 비어 있으면 빈 맵을 낸다. 호출자는 반환된 맵이 문서 전부를 덮지 않을 수 있다는 것을 전제한다.
func Compute ¶
func Compute(wikiRoot string, docs []ComputeDoc, progress func(done, total int)) (map[string][]float32, error)
Compute는 문서 목록의 임베딩 벡터를 경로 기준 맵으로 낸다. 캐시에 있는 것은 다시 계산하지 않고, 캐시에 없는 것이 하나도 없으면 모델을 열지 않는다. 적재에 0.5초가 걸리므로 그 비용을 물지 않기 위해서다.
계산이 끝나면 현재 문서 키만 남겨 캐시를 저장한다. 계산 중 에러가 나도 이미 계산한 것은 버리지 않고 저장한 뒤 에러를 올린다. 문서당 12.6초짜리 작업을 부분 실패로 통째로 날리는 것은 낭비다.
embed.ErrNoModel 은 그대로 올린다. 에러가 아니라 의미 축 강등 신호다. 호출자가 판별해 단어 축만으로 계속한다.
progress 는 진행률 콜백이다. 문서 수가 많으면 수십 분이 걸리므로 사용자를 침묵 속에 기다리게 하지 않는다. total 은 이번에 실제로 인코딩할 문서 수이고 done 은 마친 수다. 콜백이 nil 이면 부르지 않는다.
func Download ¶
func Download(ctx context.Context, client *http.Client, base, dir string, prog ProgressFn) ([]string, error)
Download는 모델 파일 여섯을 base URL 에서 dir 로 받는다.
func Key ¶
Key는 캐시 키를 만든다. 잘라낸 텍스트의 sha256 이다.
파일 수정 시각이 아니라 내용을 보는 이유가 있다. 어휘 색인은 다시 만드는 데 0.1초라 시각 기준으로 충분하지만 임베딩은 문서당 12.6초다. 형식만 바뀐 커밋이나 파일 이동으로 다시 계산하면 안 된다(ADR 0075).
func LoadCache ¶
LoadCache는 위키 루트의 .engram/vectors.json 을 읽는다. 파일이 없거나 깨졌거나 스키마 버전이 다르면 빈 캐시를 반환한다. 낡은 캐시는 에러가 아니라 다시 계산할 대상이므로 죽지 않는다. index.Load 와 같은 규약이다.
func ModelDir ¶
ModelDir는 모델이 놓이는 디렉토리를 반환한다.
사용자 전역 캐시에 둔다. 위키 로컬 .engram/ 이 아닌 이유는 위키마다 2.3GB 사본이 생기기 때문이고, 설정 디렉토리가 아닌 이유는 모델이 설정이 아니라 다시 받을 수 있는 파생물이기 때문이다(ADR 0074).
func Present ¶
func Present() bool
Present는 모델 파일이 자리에 있는지 본다. 무결성은 보지 않는다. 체크섬 검증은 model 커맨드와 doctor 의 몫이다.
Types ¶
type ComputeDoc ¶
ComputeDoc는 임베딩 계산 대상 문서 하나다. Title 과 Body 는 호출자가 색인에서 뽑은 값이다.
type Encoder ¶
type Encoder interface {
// Encode는 텍스트 여럿을 한 번에 인코딩한다. 반환 순서는 입력
// 순서와 같다. 벡터는 L2 정규화되어 있으므로 코사인 유사도가
// 내적과 같다.
Encode(ctx context.Context, texts []string) ([][]float32, error)
// Close는 백엔드 자원을 놓는다.
Close() error
}
Encoder는 텍스트를 벡터로 바꾼다. 백엔드가 바뀌면 이 인터페이스를 구현하는 쪽만 바뀐다(ADR 0074).