diff --git a/docs/DEVLOG.md b/docs/DEVLOG.md index 45b7ae1..db52e9d 100644 --- a/docs/DEVLOG.md +++ b/docs/DEVLOG.md @@ -20,6 +20,9 @@ **지역 이름**으로 가른다. - ★ 로컬에서 임베딩 모델 내려받기가 Node 에서 `ECONNRESET`(terminated)으로 끊겨 3분 걸리고 실패했다. curl 로는 받힌다. 실패한 로딩 promise 가 프로세스에 남아 **재시작 전까지 모든 임베딩이 500**이다. +- ★ 모델 캐시가 볼륨에 안 남았다 — transformers.js 4.x 는 `TRANSFORMERS_CACHE` 를 읽지 않고 node_modules 에 + 받는다. 컨테이너를 새로 만들 때마다 465MB 를 다시 받아 첫 발행이 60초 상한을 넘겼다 → `env.cacheDir` + 로 직접 넘긴다. 재생성 후 모델 로딩 2분 49초 → 1.7초. - 실키 검증(가짜 숙소 2곳): 메타에 `군산 시내 호텔`·`군산 오션뷰 호텔` 이 실렸고 미확인 `주차`·`애견동반` 은 안 나왔다. 백엔드 `1041 passed / 47 failed` — 47건은 이 변경 전 main 과 같은 목록. diff --git a/ontology/src/config/env.ts b/ontology/src/config/env.ts index bd0c19c..18b97a2 100644 --- a/ontology/src/config/env.ts +++ b/ontology/src/config/env.ts @@ -18,6 +18,8 @@ export const env = { embedding: { provider: (process.env.EMBEDDING_PROVIDER ?? 'local') as 'mock' | 'local' | 'openai', localModel: process.env.EMBEDDING_LOCAL_MODEL ?? 'Xenova/multilingual-e5-small', + // transformers.js 4.x 는 이 변수를 읽지 않아 node_modules 에 받는다 — 볼륨에 남기려면 직접 넘긴다. + cacheDir: process.env.TRANSFORMERS_CACHE || null, }, dedup: { cosineThreshold: num(process.env.DEDUP_COSINE_THRESHOLD, 0.99), diff --git a/ontology/src/embedding/local.provider.ts b/ontology/src/embedding/local.provider.ts index eaf2bb0..c40985a 100644 --- a/ontology/src/embedding/local.provider.ts +++ b/ontology/src/embedding/local.provider.ts @@ -19,7 +19,8 @@ export class LocalEmbeddingProvider extends EmbeddingProvider { if (!this.loading) { this.loading = (async () => { const t0 = Date.now(); - const { pipeline } = await esmImport('@huggingface/transformers'); + const { pipeline, env: tf } = await esmImport('@huggingface/transformers'); + if (env.embedding.cacheDir) tf.cacheDir = env.embedding.cacheDir; const fe = await pipeline('feature-extraction', env.embedding.localModel); this.logger.log(`model ready: ${env.embedding.localModel} (${Date.now() - t0}ms)`); this.extractor = fe;