본문 바로가기
WIKI 기술 지식 베이스

Generating vectors

원문 보기 위키 갱신

출처: 문서

본문

벡터 생성하기

OpenSearch Benchmark의 합성 데이터 생성기를 사용하면 매핑으로부터 합성 dense 벡터와 sparse 벡터를 생성할 수 있어요.

Dense 벡터

Dense 벡터(OpenSearch에서는 knn_vector 필드 타입으로 표현돼요)는 텍스트나 이미지 같은 데이터를 수치로 표현한 것으로, 대부분 또는 모든 차원에 0이 아닌 값이 들어 있어요. 이런 벡터는 보통 -1.0과 1.0 사이의 부동소수점 숫자를 담고 있으며, 각 차원이 전체 의미에 기여해요.

"dog"라는 단어의 임베딩 예시예요:

{
  "embedding": [0.234, -0.567, 0.123, 0.891, -0.234, 0.456, ..., 0.789]
}

Sparse 벡터

Sparse 벡터(OpenSearch에서는 sparse_vector 필드 타입으로 표현돼요)는 대부분의 차원이 0인 벡터로, 0이 아닌 토큰 ID와 그 가중치의 키-값 쌍으로 표현돼요.

예시 텍스트: Korean jindos are hunting dogs that have a reputation for being loyal, independent, and confident.

예시 텍스트의 sparse 벡터 표현이에요:

{
  "5432": 0.85,   // "korean" - very important (specific descriptor)
  "7821": 0.78,   // "jindos" - very important (breed name)
  "2": 0.45,      // "dog" - moderately important (general category)
  "9999": 0.32,   // "loyal" - somewhat important (characteristic)
  "1111": 0.12    // "things" - less important (common word)
}

기본 사용법

다음 예시에서는 OpenSearch 인덱스 매핑만 사용해서 최소한의 설정으로 벡터를 생성하는 방법을 보여줘요.

Dense 벡터 생성하기

최소한의 설정으로 128차원 랜덤 벡터를 생성해 보세요.

1. 매핑 파일 생성하기 (simple-knn-mapping.json):

{
  "settings": {
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "title": {"type": "text"},
      "my_embedding": {
        "type": "knn_vector",
        "dimension": 128
      }
    }
  }
}

{% include copy.html %}

2. 데이터 생성하기:

opensearch-benchmark generate-data \
  --index-name my-vectors \
  --index-mappings simple-knn-mapping.json \
  --output-path ./output \
  --total-size 1

{% include copy.html %}

생성된 출력

생성된 각 문서에서 my_embedding 필드는 다음과 같이 나타날 수 있어요:

{
  "title": "Sample text 42",
  "my_embedding": [0.234, -0.567, 0.123, ..., 0.891]  // 128 random floats [-1.0, 1.0]
}

Sparse 벡터 생성하기

기본 설정(10개 토큰)으로 sparse 벡터를 생성해 보세요.

1. 매핑 파일 생성하기 (simple-sparse-mapping.json):

{
  "mappings": {
    "properties": {
      "content": {"type": "text"},
      "sparse_embedding": {
        "type": "sparse_vector"
      }
    }
  }
}

{% include copy.html %}

2. 데이터 생성하기 (동일한 명령 패턴):

opensearch-benchmark generate-data \
  --index-name my-sparse \
  --index-mappings simple-sparse-mapping.json \
  --output-path ./output \
  --total-size 1

{% include copy.html %}

생성된 출력

생성된 각 문서에서 sparse_embedding 필드는 다음과 같이 나타날 수 있어요:

{
  "content": "Sample text content",
  "sparse_embedding": {
    "1000": 0.3421,
    "1100": 0.5234,
    "1200": 0.7821,
    "1300": 0.1523,
    "1400": 0.9102,
    "1500": 0.4567,
    "1600": 0.2341,
    "1700": 0.6789,
    "1800": 0.8123,
    "1900": 0.3456
  }
}

OpenSearch 인덱스 매핑만으로도 OpenSearch Benchmark는 합성 dense 벡터와 sparse 벡터를 생성할 수 있어요. 다만 이 방식으로는 기본적인 합성 벡터만 만들어져요. 더 현실적인 분포와 클러스터링을 위해서는 다음 섹션에서 설명하는 파라미터를 설정하는 것을 추천해요.


Dense 벡터(k-NN 벡터) 파라미터

다음은 dense 벡터 생성을 세밀하게 조정할 수 있도록 합성 데이터 생성 설정 파일(YAML 설정)에 추가할 수 있는 파라미터들이에요. 이 파라미터들은 generate_knn_vector 제너레이터와 함께 field_overrides 섹션에서 사용돼요. 전체 설정에 대한 자세한 내용은 고급 설정을 참고하세요.

dimension

이 파라미터는 벡터의 차원 수를 지정해요. 선택 사항이에요.

지정 방법: dimension은 OpenSearch 인덱스 매핑 파일에 반드시 정의되어 있어야 해요. 필요하다면 YAML 설정에서 field_overrides의 dimension 파라미터를 사용해 이 값을 재정의할 수도 있어요.

영향:

  • 메모리: 차원이 높을수록 = 더 많은 저장 공간
    • 128 차원 ≈ 벡터당 0.5 KB
    • 768 차원 ≈ 벡터당 3 KB
    • 1536 차원 ≈ 벡터당 6 KB
  • 성능: 차원이 많을수록 = 인덱싱과 검색이 느려짐
  • 품질: 실제 임베딩 모델의 출력과 반드시 일치해야 함

다음 표는 일반적인 차원 값과 그에 따른 대표적인 사용 사례를 보여줘요.

차원 사용 사례 예시 모델
128 경량, 커스텀 모델 커스텀 임베딩, 빠른 검색
384 범용 sentence-transformers/all-MiniLM-L6-v2
768 표준 NLP BERT-Base, DistilBERT, MPNet
1,024 고품질 NLP BERT-Large
1,536 OpenAI 표준 text-embedding-ada-002, text-embedding-3-small
3,072 OpenAI 프리미엄 text-embedding-3-large

예시:

field_overrides:
  my_embedding:
    generator: generate_knn_vector
    params:
      dimension: 768  # Override mapping dimension if needed

{% include copy.html %}

모범 사례: 이 파라미터는 임베딩 모델의 차원과 반드시 일치해야 해요.


sample_vectors

이 파라미터는 제너레이터가 노이즈를 더하는 기준 벡터를 제공하여, 현실적인 변형과 클러스터를 만들어 내요. 선택 사항이지만 강력히 추천해요.

샘플 벡터가 없으면 OpenSearch Benchmark의 합성 데이터 생성기가 전체 공간에 걸쳐 균등하게 분포된 랜덤 벡터를 생성하는데, 이는 비현실적이고 검색 품질도 낮아요. 샘플 벡터를 제공하면 OpenSearch Benchmark의 합성 데이터 생성기가 더 현실적이고 자연스러운 클러스터를 만들 수 있어요.

샘플 벡터 목록을 준비한 후에는 리스트의 리스트 형태로 넣어야 하며, 여기서 각 내부 리스트가 하나의 완전한 벡터예요. 다음 예시는 합성 데이터 생성 설정 파일에 샘플 벡터를 지정하는 방법이에요:

field_overrides:
  product_embedding:
    generator: generate_knn_vector
    params:
      dimension: 768
      sample_vectors:
        - [0.12, -0.34, 0.56, ..., 0.23]  # Vector 1 (768 values)
        - [-0.23, 0.45, -0.12, ..., -0.15]  # Vector 2 (768 values)
        - [0.34, 0.21, -0.45, ..., 0.42]  # Vector 3 (768 values)

{% include copy.html %}

제공할 벡터 수를 정할 때는 다음 가이드라인을 참고하세요:

  • 최소: 기본적인 클러스터링에는 3--5개
  • 권장: 현실적인 분포에는 5--10개
  • 최대: 복잡한 멀티 클러스터 시나리오에는 20개 이상

샘플 벡터를 구하는 방법:

옵션 1 (권장): 도메인의 실제 임베딩 사용: 서로 다른 의미 클러스터를 나타내는, 도메인의 실제 임베딩을 사용하세요. 샘플 벡터 없이 랜덤으로 생성하면 검색 품질 테스트에 적합하지 않은 비현실적인 데이터가 만들어져요.

옵션 2: Python에서 sentence-transformers 사용:

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

# Create representative texts from different categories
texts = [
    "Electronics and gadgets",
    "Clothing and fashion",
    "Home and kitchen appliances",
    "Books and literature",
    "Sports and outdoor equipment"
]

embeddings = model.encode(texts)
print(embeddings.tolist())  # Copy to your synthetic data generation configuration file (YAML config)

{% include copy.html %}


distribution_type

이 파라미터는 노이즈 분포 유형을 지정해요. 선택 사항이며 기본값은 gaussian이에요.

유효한 값:

  • gaussian: 정규분포 N(0, noise_factor)

    • 가장 현실적임 (가끔 이상치가 나타나는 자연스러운 변동)
    • 매끄러운 클러스터를 형성함
    • 일부 값이 예상 범위를 벗어날 수 있음
  • uniform: 균등분포 [-noise_factor, +noise_factor]

    • 변동 폭이 제한됨 (극단적인 이상치 없음)
    • 결과를 더 예측하기 쉬움
    • 범위 전체에서 균일한 확률

설정:

field_overrides:
  realistic_embedding:
    generator: generate_knn_vector
    params:
      sample_vectors: [...]
      noise_factor: 0.1
      distribution_type: gaussian  # More realistic

  controlled_embedding:
    generator: generate_knn_vector
    params:
      sample_vectors: [...]
      noise_factor: 0.1
      distribution_type: uniform   # More predictable

{% include copy.html %}

모범 사례: 프로덕션과 유사한 벤치마크에는 gaussian을 사용하세요.


noise_factor

이 파라미터는 기준 벡터에 추가되는 노이즈의 양을 조절해요:

  • gaussian의 경우: 정규분포의 표준편차
  • uniform의 경우: 균등분포의 범위 (±noise_factor)

선택 사항이며 기본값은 0.1이에요.

다음 표는 noise_factor 값에 따라 생성되는 데이터가 어떤 영향을 받는지 보여줘요.

noise_factor 효과 사용 사례
0.01--0.05 촘촘한 클러스터링, 최소한의 변동 중복 탐지, 거의 정확한 일치
0.1--0.2 주제 내 자연스러운 변동 일반적인 의미 검색, 추천
0.3--0.5 넓은 분산, 다양한 개념 폭넓은 주제 매칭, 탐색
> 0.5 매우 흩어지고 겹치는 클러스터 엣지 케이스 테스트, 스트레스 테스트

설정:

field_overrides:
  tight_clustering:
    generator: generate_knn_vector
    params:
      sample_vectors: [...]
      noise_factor: 0.05  # Tight clusters

  diverse_results:
    generator: generate_knn_vector
    params:
      sample_vectors: [...]
      noise_factor: 0.2   # More variation

{% include copy.html %}

모범 사례: 0.1로 시작한 뒤, 검색 재현율(recall) 또는 정밀도(precision) 요구 사항에 맞춰 조정하세요.


normalize

이 파라미터는 노이즈를 추가한 후 벡터를 정규화하여, 벡터의 크기(길이)를 정확히 1.0으로 만들어요. 선택 사항이며 기본값은 false예요.

다음 표는 인덱스 설정에 따라 normalize를 true로 설정해야 하는 경우를 보여줘요.

인덱스 매핑의 space_type normalize 값 설명
cosinesimil true 코사인 유사도는 벡터 방향에만 의존해요. 내적이 곧바로 코사인 유사도를 나타내기 때문에 미리 정규화하면 성능이 향상돼요.
l2 false L2 거리는 벡터의 크기에 의존해요. 정규화하면 크기 정보가 사라져 정확도가 떨어져요.
innerproduct false 내적은 벡터의 크기를 유사도 점수에 반영하기 때문에, 정규화하면 의도된 점수 계산 방식이 바뀌게 돼요.

실제 모델별 가이드:

  • OpenAI 임베딩: 이 벡터들은 이미 정규화되어 있으므로 normalize를 true로 설정하세요.
  • sentence-transformers: 많은 모델이 정규화된 벡터를 출력해요. 모델 문서를 확인하고, 대부분의 경우 normalize를 true로 설정하는 것이 좋아요.
  • BERT (raw 출력): raw BERT 임베딩은 정규화되어 있지 않아요. normalize를 false로 설정하고, 필요한 경우 인덱스 설정을 통해 정규화가 수행되도록 하세요.

설정:

field_overrides:
  # For cosine similarity search
  cosine_embedding:
    generator: generate_knn_vector
    params:
      dimension: 384
      sample_vectors: [...]
      normalize: true  # Required for accurate cosine similarity

  # For L2 distance search
  l2_embedding:
    generator: generate_knn_vector
    params:
      dimension: 768
      sample_vectors: [...]
      normalize: false  # Keep original magnitudes

{% include copy.html %}

모범 사례: OpenSearch 인덱스의 space_type 설정과 일치시키세요.


희소 벡터 파라미터

다음은 희소 벡터가 생성되는 방식을 세밀하게 조정할 수 있도록 합성 데이터 생성 설정 파일에 추가할 수 있는 파라미터들이에요. 이 파라미터들은 field_overrides 섹션에서 generate_sparse_vector 제너레이터와 함께 사용돼요. 설정에 대한 전체 내용은 고급 설정을 참고하세요.

num_tokens

이 파라미터는 벡터별로 생성할 토큰-가중치 쌍의 개수를 지정해요. 선택 사항이며 기본값은 10이에요.

영향:

  • 낮음 (5--10): 매우 희소하고 검색이 빠르지만, 일부 관련 문서를 놓칠 수 있어요
  • 중간 (10--25): 성능과 재현율의 균형이 좋아요
  • 높음 (50--100): 밀도 높은 희소 표현으로, 포괄적이지만 속도는 느려요

다음 표는 모델과 접근 방식별로 일반적인 num_tokens 값을 보여줘요.

모델/접근 방식 일반적인 num_tokens 값 사용 사례
SPLADE v1 10--15 표준 희소 신경망 검색
SPLADE v2 15--25 향상된 재현율
DeepImpact 8--12 효율적인 희소 검색
커스텀/하이브리드 20--50 풍부한 표현

설정:

field_overrides:
  sparse_standard:
    generator: generate_sparse_vector
    params:
      num_tokens: 15  # Standard SPLADE-like

  sparse_rich:
    generator: generate_sparse_vector
    params:
      num_tokens: 30  # Richer representation

{% include copy.html %}

모범 사례: 10--15로 시작하고, 재현율이 부족하면 값을 늘리세요.


min_weight와 max_weight

이 파라미터들은 토큰 중요도 가중치의 범위를 정의해요. 선택 사항이며, min_weight의 기본값은 0.01, max_weight의 기본값은 1.0이에요.

영향:

  • min_weight: 중요도가 낮은 토큰이 생성되지 않도록 제외해요. 이 값보다 가중치가 낮은 토큰은 포함되지 않아요.
  • max_weight: 특정 토큰 하나가 벡터를 지배하지 않도록 토큰 영향력의 상한을 제한해요.

다음 표는 일반적인 가중치 범위 설정과 그 사용 사례를 보여줘요.

설정 min_weight max_weight 사용 사례
표준 SPLADE 0.01 1.0 기본값, 균형 잡힌 중요도
좁은 범위 0.1 0.9 더 균일한 중요도
넓은 범위 0.01 2.0 강한 중요도 신호
높은 임계값 0.05 1.0 신뢰도가 낮은 토큰 필터링

설정:

field_overrides:
  sparse_balanced:
    generator: generate_sparse_vector
    params:
      num_tokens: 15
      min_weight: 0.01
      max_weight: 1.0

  sparse_uniform:
    generator: generate_sparse_vector
    params:
      num_tokens: 20
      min_weight: 0.2   # Higher minimum
      max_weight: 0.8   # Lower maximum

{% include copy.html %}

제약 조건:

  • min_weight는 0.0보다 커야 해요 (OpenSearch는 양수 가중치를 요구해요).
  • max_weight는 min_weight보다 커야 해요.
  • 가중치는 소수점 4자리에서 반올림돼요.

모범 사례: 섬세한 가중치 조정이 가능하도록 min_weight를 작게(0.01--0.05) 유지하세요.


token_id_start와 token_id_step

이 파라미터들은 벡터 생성 중 토큰 ID가 할당되는 방식을 정의해요:

  • token_id_start: 생성되는 시퀀스의 시작 토큰 ID를 설정해요. 기본값은 1000이에요.

  • token_id_step: 연속된 토큰 ID 사이에 적용되는 증가값을 지정해요. 기본값은 100이에요.

생성되는 시퀀스: start, start+step, start+2*step, ...

start=1000, step=100, num_tokens=5인 경우의 예시:

{
  "1000": 0.3421,  // token_id_start
  "1100": 0.5234,  // start + 1*step
  "1200": 0.7821,  // start + 2*step
  "1300": 0.1523,  // start + 3*step
  "1400": 0.9102   // start + 4*step
}

{% include copy.html %}

다음 표는 다양한 토큰 ID 설정과 그 사용 사례를 보여줘요.

설정 token_id_start token_id_step 사용 사례
기본 테스트 1000 100 생성된 토큰 범위를 시각적으로 구분하는 데 도움이 돼요.
현실적인 어휘 0 1 실제 모델의 어휘 인덱스에 맞춰 토큰 ID를 정렬해요.
멀티 필드 생성 1000, 5000, 10000 1 필드별로 토큰 ID 범위를 분리한 상태로 유지해요.
대규모 어휘 시뮬레이션 0 1 50,000개 이상 토큰의 어휘를 사용하는 생성 시나리오를 지원해요.

설정:

field_overrides:
  # Default: easy debugging
  sparse_debug:
    generator: generate_sparse_vector
    params:
      num_tokens: 10
      token_id_start: 1000
      token_id_step: 100

  # Realistic: actual vocab indices
  sparse_realistic:
    generator: generate_sparse_vector
    params:
      num_tokens: 15
      token_id_start: 0
      token_id_step: 1

  # Multiple fields: separate ranges
  sparse_field1:
    generator: generate_sparse_vector
    params:
      token_id_start: 1000

  sparse_field2:
    generator: generate_sparse_vector
    params:
      token_id_start: 5000

{% include copy.html %}

참고: 생성된 데이터의 토큰 ID는 순차적이에요. 실제 희소 벡터에서는 ID가 실제 어휘에 따라 순차적이지 않을 수 있어요. 이 차이는 OpenSearch 인덱싱이나 검색 기능에 영향을 주지 않아요.

모범 사례: 디버깅 시에는 더 큰 token_id_step(예: 100)을 사용하고, 프로덕션과 유사한 데이터에는 token_id_step을 1로 설정하세요.


단순 생성 방식과 복잡한 생성 방식 중 선택하기

다음 표는 테스트 목표에 따라 단순 생성을 사용해야 하는 경우와 더 복잡하고 설정 가능한 접근 방식을 사용해야 하는 경우를 정리한 거예요.

시나리오 권장 접근 방식 이유
학습 또는 빠른 테스트 단순 생성 (추가 설정 없음) 가장 빠르게 설정할 수 있고 기본적인 검증에는 충분해요.
부하 테스트 단순 생성 벡터의 현실성보다 데이터 양과 처리량을 우선해요.
현실적인 벤치마크 복잡한 생성 (설정 포함) 실제 동작을 반영하려면 현실적인 벡터 클러스터링과 분포가 필요해요.
프로덕션 시뮬레이션 복잡한 생성 실제 임베딩 모델이 만드는 벡터 특성과 거의 일치하는 특성이 필요해요.
검색 품질 테스트 복잡한 생성 재현율과 정확도를 정확하게 평가하려면 의미 있는 벡터 클러스터가 필요해요.

권장 사항: 검색 품질 테스트나 알고리즘 비교에서는 샘플 벡터가 포함된 복잡한 설정을 사용해 현실적인 데이터 분포를 보장하세요.

더 알아보기 (Learn more)