Generating embeddings from arrays of objects

Cloud_ Ghost·2025년 9월 8일

opensearch

목록 보기
16/23

객체 배열에서 임베딩 생성하기

이 튜토리얼은 객체 배열에 대한 임베딩을 생성하는 방법을 보여줍니다. 자세한 정보는 "임베딩 자동 생성"을 참조하세요.

your_로 시작하는 접두사가 있는 자리 표시자를 자신의 값으로 바꾸세요.

1단계: 임베딩 모델 등록

이 튜토리얼에서는 Amazon Bedrock에서 호스팅되는 Amazon Titan Text Embeddings 모델을 사용할 것입니다.

먼저 Amazon Bedrock Titan 블루프린트 예제를 따라 모델을 등록하고 배포하세요.

모델 ID를 제공하여 모델을 테스트하세요:

POST /_plugins/_ml/models/your_embedding_model_id/_predict
{
    "parameters": {
        "inputText": "hello world"
    }
}

응답에는 추론 결과가 포함됩니다:

{
  "inference_results": [
    {
      "output": [
        {
          "name": "sentence_embedding",
          "data_type": "FLOAT32",
          "shape": [ 1536 ],
          "data": [0.7265625, -0.0703125, 0.34765625, ...]
        }
      ],
      "status_code": 200
    }
  ]
}

2단계: 수집 파이프라인 생성

임베딩 생성을 위한 수집 파이프라인을 생성하려면 다음 단계를 따르세요.

2.1단계: 벡터 인덱스 생성

먼저 벡터 인덱스를 생성하세요:

PUT my_books
{
  "settings" : {
      "index.knn" : "true",
      "default_pipeline": "bedrock_embedding_pipeline"
  },
  "mappings": {
    "properties": {
      "books": {
        "type": "nested",
        "properties": {
          "title_embedding": {
            "type": "knn_vector",
            "dimension": 1536
          },
          "title": {
            "type": "text"
          },
          "description": {
            "type": "text"
          }
        }
      }
    }
  }
}

2.2단계: 수집 파이프라인 생성

하나의 배열 요소에 대한 임베딩을 생성하는 내부 수집 파이프라인을 생성하세요.

이 파이프라인에는 세 개의 프로세서가 포함됩니다:

text_embedding 프로세서: 임시 필드의 값을 임베딩으로 변환합니다.

이러한 파이프라인을 생성하려면 다음 요청을 보내세요:

PUT _ingest/pipeline/bedrock_embedding_pipeline
{
  "processors": [
    {
      "text_embedding": {
        "model_id": "your_embedding_model_id",
        "field_map": {
          "books.title": "title_embedding"
        }
      }
    }
  ]
}

2.3단계: 파이프라인 시뮬레이션

먼저 title 필드가 있는 두 개의 책 객체를 포함하는 배열에서 파이프라인을 테스트할 것입니다:

POST _ingest/pipeline/bedrock_embedding_pipeline/_simulate
{
  "docs": [
    {
      "_index": "my_books",
      "_id": "1",
      "_source": {
        "books": [
          {
            "title": "첫 번째 책",
            "description": "이것은 첫 번째 책입니다"
          },
          {
            "title": "두 번째 책",
            "description": "이것은 두 번째 책입니다"
          }
        ]
      }
    }
  ]
}

응답에는 두 객체 모두의 title_embedding 필드에 생성된 임베딩이 포함됩니다:

{
  "docs": [
    {
      "doc": {
        "_index": "my_books",
        "_id": "1",
        "_source": {
          "books": [
            {
              "title": "첫 번째 책",
              "title_embedding": [-1.1015625, 0.65234375, 0.7578125, ...],
              "description": "이것은 첫 번째 책입니다"
            },
            {
              "title": "두 번째 책",
              "title_embedding": [-0.65234375, 0.21679688, 0.7265625, ...],
              "description": "이것은 두 번째 책입니다"
            }
          ]
        },
        "_ingest": {
          "_value": null,
          "timestamp": "2024-05-28T16:16:50.538929413Z"
        }
      }
    }
  ]
}

다음으로 title 필드가 있는 객체 하나와 없는 객체 하나를 포함하는 배열에서 파이프라인을 테스트할 것입니다:

POST _ingest/pipeline/bedrock_embedding_foreach_pipeline/_simulate
{
  "docs": [
    {
      "_index": "my_books",
      "_id": "1",
      "_source": {
        "books": [
          {
            "title": "첫 번째 책",
            "description": "이것은 첫 번째 책입니다"
          },
          {
            "description": "이것은 두 번째 책입니다"
          }
        ]
      }
    }
  ]
}

응답에는 title 필드를 포함하는 객체에 대해 생성된 임베딩이 포함됩니다:

{
  "docs": [
    {
      "doc": {
        "_index": "my_books",
        "_id": "1",
        "_source": {
          "books": [
            {
              "title": "첫 번째 책",
              "title_embedding": [-1.1015625, 0.65234375, 0.7578125, ...],
              "description": "이것은 첫 번째 책입니다"
            },
            {
              "description": "이것은 두 번째 책입니다"
            }
          ]
        },
        "_ingest": {
          "_value": null,
          "timestamp": "2024-05-28T16:19:03.942644042Z"
        }
      }
    }
  ]
}

2.4단계: 데이터 수집 테스트

하나의 문서를 수집하세요:

PUT my_books/_doc/1
{
  "books": [
    {
      "title": "첫 번째 책",
      "description": "이것은 첫 번째 책입니다"
    },
    {
      "title": "두 번째 책",
      "description": "이것은 두 번째 책입니다"
    }
  ]
}

문서를 가져오세요:

GET my_books/_doc/1

응답에는 생성된 임베딩이 포함됩니다:

{
  "_index": "my_books",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "books": [
      {
        "description": "이것은 첫 번째 책입니다",
        "title": "첫 번째 책",
        "title_embedding": [-1.1015625, 0.65234375, 0.7578125, ...]
      },
      {
        "description": "이것은 두 번째 책입니다",
        "title": "두 번째 책",
        "title_embedding": [-0.65234375, 0.21679688, 0.7265625, ...]
      }
    ]
  }
}

여러 문서를 일괄로 수집하고 Get Document API를 호출하여 생성된 임베딩을 테스트할 수도 있습니다:

POST _bulk
{ "index" : { "_index" : "my_books" } }
{ "books" : [{"title": "첫 번째 책", "description": "이것은 첫 번째 책입니다"}, {"title": "두 번째 책", "description": "이것은 두 번째 책입니다"}] }
{ "index" : { "_index" : "my_books" } }
{ "books" : [{"title": "세 번째 책", "description": "이것은 세 번째 책입니다"}, {"description": "이것은 네 번째 책입니다"}] }

주요 포인트

  • nested 타입: 객체 배열을 다룰 때는 nested 타입을 사용합니다
  • 필드 매핑: field_map에서 배열 내 필드 경로를 정확히 지정해야 합니다 (books.title)
  • 부분 처리: title 필드가 없는 객체는 임베딩이 생성되지 않지만 오류 없이 처리됩니다
  • 배치 크기: 모델의 차원 수(이 예제에서는 1536)가 인덱스 매핑과 일치해야 합니다.

1. 복잡한 데이터 구조별 가이드:

## 데이터 구조에 따른 임베딩 전략

### 단순 배열
- 기본 text_embedding 프로세서 사용
- 전체 배열을 하나의 텍스트로 처리

### 객체 배열 (이 튜토리얼)
- nested 타입 + field_map 사용
- 각 객체별로 개별 임베딩 생성

### 중첩된 복잡 구조
- foreach 프로세서와 조합
- 다단계 파이프라인 설계
## 성능 및 비용 최적화

### 모델 선택 기준
- 차원 수: 높을수록 정확하지만 느림
- 비용: Amazon Bedrock 요금 고려
- 성능: 배치 크기에 따른 처리 시간

### 인덱싱 전략  
- nested 필드는 메모리 사용량 증가
- 필요한 필드만 임베딩 생성
- bulk 인덱싱으로 효율성 확보

3. 오류 처리 패턴:

## 자주 발생하는 문제

### "title 필드가 없는 객체"
→ 조건부 프로세서 사용하여 안전하게 처리

### "차원 불일치 오류"
→ 모델 출력 차원과 인덱스 매핑 일치 확인

### "배치 처리 시 일부 실패"
→ ignore_failure 옵션 활용
profile
행복합시다~

0개의 댓글