[fix] ontology: 임베딩 모델을 볼륨에 남김 — transformers.js 4.x 가 TRANSFORMERS_CACHE 를 무시

컨테이너를 새로 만들 때마다 모델 465MB 를 다시 받았다(실측 2분 49초). 그 사이 첫 발행은
publish 60초 상한을 넘겨 키워드 없이 나간다. 4.x 는 이 변수를 읽지 않고 node_modules 아래에
받아서 ontology-model 볼륨(/app/.cache)이 비어 있었다.

- config/env: embedding.cacheDir ← TRANSFORMERS_CACHE
- local.provider: transformers.js env.cacheDir 로 넘김

tsc 통과. 로컬 compose: 재생성 후 /app/.cache 465M, 다시 재생성하면 모델 로딩 1.7초

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hbyang 2026-10-01 15:05:16 +09:00
parent f32edfeaa1
commit 3538e2dbc9
3 changed files with 7 additions and 1 deletions

View File

@ -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 과 같은 목록.

View File

@ -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),

View File

@ -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;