본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

비용: 임베딩 예산과 호출 방식

~22 min · ops, cost

Level 0Scout
0 XP0/41 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

비용이 생기는 곳

  • 수집 임베딩 — 청크마다 한 번, 다시 임베딩할 때마다 비용이 들어.
  • 쿼리 임베딩 — 사용자 쿼리마다 한 번 비용이 들어.
  • 저장 공간 — 벡터 크기 × 청크 수 × 복제본 수야. 행이 수천만 개를 넘지 않으면 대개 작은 항목이야.
  • LLM 호출 — 검색이 작동한 뒤에는 가장 큰 비용 항목이 되기 쉬워. RAG라고 이 비용이 사라지지는 않아.

중요한 비용 절감 수단 세 가지

  1. 콘텐츠 해시로 임베딩 캐시하기. 같은 청크를 다시 수집할 때 비용은 0이어야 해. 텍스트 해시로 벡터를 찾고 캐시에 없을 때만 모델을 호출해.
  2. 배치로 묶기. 호스팅형 임베딩 API의 토큰당 가격은 같아도, 배치 호출은 네트워크 왕복 100번을 한 번으로 줄여. 일반적인 배치 크기는 32–128이야.
  3. 평가가 허용하면 작은 모델 쓰기. 384차원 로컬 모델이 사실 확인형 검색에서 3072차원 호스팅 모델과 비슷할 수 있고 호출당 비용도 없어. 평가 집합으로 실제 쿼리에서 차이가 중요한지 판단해.

Code

콘텐츠 해시 캐시·python
import hashlib, json
from pathlib import Path

CACHE = Path('embedding_cache.jsonl')

def cached_embed(texts: list[str]) -> list[list[float]]:
    cache: dict[str, list[float]] = {}
    if CACHE.exists():
        for line in CACHE.read_text().splitlines():
            row = json.loads(line)
            cache[row['hash']] = row['vec']

    results, misses, miss_hashes = [], [], []
    for t in texts:
        h = hashlib.sha256(t.encode()).hexdigest()
        if h in cache:
            results.append(cache[h])
        else:
            results.append(None)
            misses.append(t)
            miss_hashes.append(h)

    if misses:
        new_vecs = model.encode(misses, normalize_embeddings=True).tolist()
        with CACHE.open('a') as f:
            for h, v in zip(miss_hashes, new_vecs):
                f.write(json.dumps({'hash': h, 'vec': v}) + '\n')
        miss_iter = iter(new_vecs)
        results = [r if r is not None else next(miss_iter) for r in results]
    return results
OpenAI 임베딩을 배치로 호출하기·python
from openai import OpenAI
from itertools import islice

client = OpenAI()

def batched(it, n):
    it = iter(it)
    while batch := list(islice(it, n)):
        yield batch

def embed_corpus(texts, batch_size=64):
    out = []
    for batch in batched(texts, batch_size):
        resp = client.embeddings.create(model='text-embedding-3-large', input=batch)
        out.extend([d.embedding for d in resp.data])
    return out

External links

Exercise

수집 파이프라인에 콘텐츠 해시 캐시를 추가하고 코퍼스 전체를 두 번 다시 수집해. 두 번째 실행의 캐시 적중률이 100%이며 임베딩 API 비용이 0인지 확인하고 절감액을 기록해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.