Snowflake 모델 임베딩

Snowflake 모델 임베딩 (Snowflake Models)

Qdrant는 Snowflake의 텍스트 임베딩 모델과 함께 사용할 수 있어요. 사용 가능한 전체 모델 목록은 HuggingFace에서 확인할 수 있고요, Snowflake 모델을 로컬에서 실행해 임베딩을 만든 뒤 Qdrant에 저장·검색하는 흐름을 구성해요. Python과 TypeScript 두 방식 모두 지원돼요.

출처: Qdrant 공식 문서 — snowflake

Qdrant와 Snowflake 모델 준비

파이썬에서는 fastembedTextEmbedding으로 Snowflake 모델을 불러와요. 임베딩 모델과 Qdrant 클라이언트를 함께 준비해 두면 돼요.

from qdrant_client import QdrantClient
from fastembed import TextEmbedding

qclient = QdrantClient(":memory:")
embedding_model = TextEmbedding("snowflake/snowflake-arctic-embed-s")

texts = [
    "Qdrant is the best vector search engine!",
    "Loved by Enterprises and everyone building for low latency, high performance, and scale.",
]
import {QdrantClient} from '@qdrant/js-client-rest';
import { pipeline } from '@xenova/transformers';

const client = new QdrantClient({ url: 'http://localhost:6333' });

const extractor = await pipeline('feature-extraction', 'Snowflake/snowflake-arctic-embed-s');

const texts = [
    "Qdrant is the best vector search engine!",
    "Loved by Enterprises and everyone building for low latency, high performance, and scale.",
]

문서 임베딩

다음 예시는 크기 384의 문장 임베딩을 생성하는 snowflake-arctic-embed-s 모델로 문서를 임베딩해요.

embeddings = embedding_model.embed(texts)
const embeddings = await extractor(texts, { normalize: true, pooling: 'cls' });

모델 출력을 Qdrant Point로 변환

임베딩 벡터와 원본 텍스트를 짝지어 PointStruct 리스트를 만들어요.

from qdrant_client.models import PointStruct

points = [
    PointStruct(
        id=idx,
        vector=embedding,
        payload={"text": text},
    )
    for idx, (embedding, text) in enumerate(zip(embeddings, texts))
]
let points = embeddings.tolist().map((embedding, i) => {
    return {
        id: i,
        vector: embedding,
        payload: {
            text: texts[i]
        }
    }
});

컬렉션 생성과 문서 삽입

snowflake-arctic-embed-s는 임베딩 차원이 384이므로 VectorParams(size=384)로 컬렉션을 만들고, 코사인 유사도(Distance.COSINE)로 검색하도록 설정해요.

from qdrant_client.models import VectorParams, Distance

COLLECTION_NAME = "example_collection"

qclient.create_collection(
    COLLECTION_NAME,
    vectors_config=VectorParams(
        size=384,
        distance=Distance.COSINE,
    ),
)
qclient.upsert(COLLECTION_NAME, points)
const COLLECTION_NAME = "example_collection"

await client.createCollection(COLLECTION_NAME, {
    vectors: {
        size: 384,
        distance: 'Cosine',
    }
});

await client.upsert(COLLECTION_NAME, {
    wait: true,
    points
});

Qdrant로 문서 검색

문서를 추가한 뒤에는 가장 관련 있는 문서를 검색할 수 있어요. 검색 쿼리도 같은 모델로 임베딩해야 벡터 차원과 의미 공간이 맞아요.

query_embedding = next(embedding_model.query_embed("What is the best to use for vector search scaling?"))

qclient.search(
    collection_name=COLLECTION_NAME,
    query_vector=query_embedding,
)
const query_embedding = await extractor("What is the best to use for vector search scaling?", {
    normalize: true,
    pooling: 'cls'
});

await client.search(COLLECTION_NAME, {
    vector: query_embedding.tolist()[0],
});

더 알아보기 (Learn more)