Semantic search using a model in Amazon SageMaker
출처: 문서
본문
Amazon SageMaker 모델을 사용한 시맨틱 검색
이 튜토리얼에서는 Amazon SageMaker의 임베딩 모델을 사용해 Amazon OpenSearch Service에서 시맨틱 검색을 구현하는 방법을 보여 줘요. 자세한 정보는 시맨틱 검색을 참고하세요.
Python을 사용하는 경우 opensearch-py-ml 클라이언트 CLI로 Amazon SageMaker 커넥터를 만들고 모델을 테스트할 수 있어요. CLI는 많은 설정 단계를 자동화해 주기 때문에 설정이 더 빠르고 오류 발생 가능성도 줄어들어요. CLI 사용에 대한 자세한 정보는 CLI 문서를 참고하세요.
{: .tip}
Amazon OpenSearch Service 대신 셀프 관리형 OpenSearch를 사용하는 경우에는 블루프린트를 사용해 Amazon SageMaker의 모델에 대한 커넥터를 만드세요. 커넥터 생성에 대한 자세한 정보는 커넥터를 참고하세요.
이 튜토리얼에서는 Amazon SageMaker에 모델을 배포하는 방법은 다루지 않아요. 배포에 대한 자세한 정보는 실시간 추론을 참고하세요.
Amazon OpenSearch Service에서 임베딩 모델을 설정하는 가장 쉬운 방법은 AWS CloudFormation을 사용하는 거예요. 또는 AIConnectorHelper 노트북을 사용해 임베딩 모델을 설정할 수도 있어요. {: .tip}
your_ 접두사로 시작하는 플레이스홀더는 여러분의 값으로 바꾸세요.
{: .note}
모델 입력 및 출력 요구 사항
Amazon SageMaker에 있는 모델의 입력이 기본 전처리 함수가 요구하는 형식을 따르는지 확인하세요.
모델 입력은 문자열 배열이어야 해요:
["hello world", "how are you"]
또한 모델 출력이 기본 후처리 함수가 요구하는 형식을 따르는지 확인하세요. 모델 출력은 배열의 배열이어야 하고, 각 내부 배열은 입력 문자열 하나의 임베딩에 해당해요:
[
[
-0.048237994,
-0.07612697,
...
],
[
0.32621247,
0.02328475,
...
]
]
모델의 입력/출력이 요구되는 기본 형식과 같지 않다면, Painless 스크립트를 사용해 직접 전처리/후처리 함수를 만들 수 있어요.
예시: Amazon Bedrock Titan 임베딩 모델
예를 들어 Amazon Bedrock Titan 임베딩 모델(블루프린트)의 입력은 다음과 같아요:
{ "inputText": "your_input_text" }
OpenSearch는 다음과 같은 입력 형식을 기대해요:
{ "text_docs": [ "your_input_text1", "your_input_text2"] }
text_docs를 inputText로 변환하려면 다음과 같은 전처리 함수를 정의해야 해요:
"pre_process_function": """
StringBuilder builder = new StringBuilder();
builder.append("\"");
String first = params.text_docs[0];// Get the first doc, ml-commons will iterate all docs
builder.append(first);
builder.append("\"");
def parameters = "{" +"\"inputText\":" + builder + "}"; // This is the Bedrock Titan embedding model input
return "{" +"\"parameters\":" + parameters + "}";"""
{% include copy.html %}
기본 Amazon Bedrock Titan 임베딩 모델의 출력은 다음과 같은 형식이에요:
{
"embedding": <float_array>
}
하지만 OpenSearch는 다음과 같은 형식을 기대해요:
{
"name": "sentence_embedding",
"data_type": "FLOAT32",
"shape": [ <embedding_size> ],
"data": <float_array>
}
Amazon Bedrock Titan 임베딩 모델의 출력을 OpenSearch가 기대하는 형식으로 변환하려면 다음과 같은 후처리 함수를 정의해야 해요:
"post_process_function": """
def name = "sentence_embedding";
def dataType = "FLOAT32";
if (params.embedding == null || params.embedding.length == 0) {
return params.message;
}
def shape = [params.embedding.length];
def json = "{" +
"\"name\":\"" + name + "\"," +
"\"data_type\":\"" + dataType + "\"," +
"\"shape\":" + shape + "," +
"\"data\":" + params.embedding +
"}";
return json;
"""
{% include copy.html %}
사전 준비 사항: OpenSearch 클러스터 생성
Amazon OpenSearch Service 콘솔로 이동해 OpenSearch 도메인을 생성하세요.
도메인의 Amazon Resource Name(ARN)을 기록해 두세요. 이후 단계에서 사용하게 돼요.
1단계: Amazon SageMaker의 모델을 호출하기 위한 IAM 역할 생성
Amazon SageMaker의 모델을 호출하려면 적절한 권한을 가진 AWS Identity and Access Management(IAM) 역할을 만들어야 해요. 커넥터는 이 역할을 사용해 모델을 호출해요.
IAM 콘솔로 이동해 my_invoke_sagemaker_model_role이라는 이름의 새 IAM 역할을 만들고 다음 신뢰 정책과 권한을 추가하세요:
- 사용자 지정 신뢰 정책:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "es.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
{% include copy.html %}
- 권한:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sagemaker:InvokeEndpoint"
],
"Resource": [
"your_sagemaker_model_inference_endpoint_arn"
]
}
]
}
{% include copy.html %}
역할 ARN을 기록해 두세요. 이후 단계에서 사용하게 돼요.
2단계: Amazon OpenSearch Service에서 IAM 역할 구성
다음 단계에 따라 Amazon OpenSearch Service에서 IAM 역할을 구성하세요.
2.1단계: 커넥터 요청 서명을 위한 IAM 역할 생성
Create Connector API 요청에 서명하기 위한 용도의 새 IAM 역할을 생성하세요.
다음 신뢰 정책과 권한을 가진 my_create_sagemaker_connector_role이라는 이름의 IAM 역할을 만드세요:
- 사용자 지정 신뢰 정책:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "your_iam_user_arn"
},
"Action": "sts:AssumeRole"
}
]
}
{% include copy.html %}
3단계에서 your_iam_user_arn IAM 사용자를 사용해 이 역할을 수임하게 돼요.
- 권한:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "your_iam_role_arn_created_in_step1"
},
{
"Effect": "Allow",
"Action": "es:ESHttpPost",
"Resource": "your_opensearch_domain_arn"
}
]
}
{% include copy.html %}
이 역할 ARN을 기록해 두세요. 이후 단계에서 사용하게 돼요.
2.2단계: 백엔드 역할 매핑
다음 단계에 따라 백엔드 역할을 매핑하세요:
- OpenSearch Dashboards에 로그인하고 상단 메뉴에서 Security를 선택하세요.
- Roles를 선택한 다음 ml_full_access 역할을 선택하세요.
- ml_full_access 역할 세부 정보 페이지에서 Mapped users를 선택한 다음 Manage mapping을 선택하세요.
- 다음 이미지와 같이 2.1단계에서 생성한 IAM 역할 ARN을 Backend roles 필드에 입력하세요.

- Map을 선택하세요.
이제 IAM 역할이 OpenSearch 클러스터에 성공적으로 구성됐어요.
3단계: 커넥터 생성
다음 단계에 따라 모델의 커넥터를 만드세요. 커넥터 생성에 대한 자세한 정보는 커넥터를 참고하세요.
AWS에서 가져온 임시 자격 증명으로 다음 Python 코드를 실행하세요.
import boto3
import requests
from requests_aws4auth import AWS4Auth
host = 'your_amazon_opensearch_domain_endpoint'
region = 'your_amazon_opensearch_domain_region'
service = 'es'
assume_role_response = boto3.Session().client('sts').assume_role(
RoleArn="your_iam_role_arn_created_in_step2.1",
RoleSessionName="your_session_name"
)
credentials = assume_role_response["Credentials"]
awsauth = AWS4Auth(credentials["AccessKeyId"], credentials["SecretAccessKey"], region, service, session_token=credentials["SessionToken"])
path = '/_plugins/_ml/connectors/_create'
url = host + path
payload = {
"name": "Sagemaker embedding model connector",
"description": "Connector for my Sagemaker embedding model",
"version": "1.0",
"protocol": "aws_sigv4",
"credential": {
"roleArn": "your_iam_role_arn_created_in_step1"
},
"parameters": {
"region": "your_sagemaker_model_region",
"service_name": "sagemaker"
},
"actions": [
{
"action_type": "predict",
"method": "POST",
"headers": {
"content-type": "application/json"
},
"url": "your_sagemaker_model_inference_endpoint",
"request_body": "${parameters.input}",
"pre_process_function": "connector.pre_process.default.embedding",
"post_process_function": "connector.post_process.default.embedding"
}
]
}
headers = {"Content-Type": "application/json"}
r = requests.post(url, auth=awsauth, json=payload, headers=headers)
print(r.status_code)
print(r.text)
{% include copy.html %}
스크립트는 커넥터 ID를 출력해요:
{"connector_id":"tZ09Qo0BWbTmLN9FM44V"}
커넥터 ID를 기록해 두세요. 다음 단계에서 사용하게 돼요.
4단계: 모델 생성 및 테스트
OpenSearch Dashboards에 로그인하고 DevTools 콘솔을 연 다음, 다음 요청을 실행해 모델을 생성하고 테스트하세요.
-
모델 그룹을 생성하세요:
POST /_plugins/_ml/model_groups/_register { "name": "Sagemaker_embedding_model", "description": "Test model group for Sagemaker embedding model" }{% include copy-curl.html %}
응답에 모델 그룹 ID가 포함돼요:
{ "model_group_id": "MhU3Qo0BTaDH9c7tKBfR", "status": "CREATED" } -
모델을 등록하세요:
POST /_plugins/_ml/models/_register { "name": "Sagemaker embedding model", "function_name": "remote", "description": "test embedding model", "model_group_id": "MhU3Qo0BTaDH9c7tKBfR", "connector_id": "tZ09Qo0BWbTmLN9FM44V" }{% include copy-curl.html %}
응답에 모델 ID가 포함돼요:
{ "task_id": "NhU9Qo0BTaDH9c7t0xft", "status": "CREATED", "model_id": "NxU9Qo0BTaDH9c7t1Bca" } -
모델을 배포하세요:
POST /_plugins/_ml/models/NxU9Qo0BTaDH9c7t1Bca/_deploy{% include copy-curl.html %}
응답에 배포 작업에 대한 태스크 ID가 포함돼요:
{ "task_id": "MxU4Qo0BTaDH9c7tJxde", "task_type": "DEPLOY_MODEL", "status": "COMPLETED" } -
모델을 테스트하세요:
POST /_plugins/_ml/models/NxU9Qo0BTaDH9c7t1Bca/_predict { "parameters": { "input": ["hello world", "how are you"] } }{% include copy-curl.html %}
응답에 모델이 생성한 임베딩이 포함돼요:
{ "inference_results": [ { "output": [ { "name": "sentence_embedding", "data_type": "FLOAT32", "shape": [ 384 ], "data": [ -0.034477264, 0.031023195, 0.0067349933, ...] }, { "name": "sentence_embedding", "data_type": "FLOAT32", "shape": [ 384 ], "data": [ -0.031369038, 0.037830487, 0.07630822, ...] } ], "status_code": 200 } ] }
5단계: 시맨틱 검색 구성
다음 단계에 따라 시맨틱 검색을 구성하세요.
5.1단계: 인제스트 파이프라인 생성
먼저 Amazon SageMaker의 모델을 사용해 입력 텍스트에서 임베딩을 만드는 인제스트 파이프라인을 생성하세요:
PUT /_ingest/pipeline/my_sagemaker_embedding_pipeline
{
"description": "text embedding pipeline",
"processors": [
{
"text_embedding": {
"model_id": "your_sagemaker_embedding_model_id_created_in_step4",
"field_map": {
"text": "text_knn"
}
}
}
]
}
{% include copy-curl.html %}
5.2단계: 벡터 인덱스 생성
다음으로, 입력 텍스트와 생성된 임베딩을 저장할 벡터 인덱스를 생성하세요:
PUT my_index
{
"settings": {
"index": {
"knn.space_type": "cosinesimil",
"default_pipeline": "my_sagemaker_embedding_pipeline",
"knn": "true"
}
},
"mappings": {
"properties": {
"text_knn": {
"type": "knn_vector",
"dimension": your_sagemake_model_embedding_dimension
}
}
}
}
{% include copy-curl.html %}
5.3단계: 데이터 인제스트
샘플 문서를 인덱스에 인제스트하세요:
POST /my_index/_doc/1000001
{
"text": "hello world."
}
{% include copy-curl.html %}
5.4단계: 인덱스 검색
벡터 검색을 실행해 벡터 인덱스에서 문서를 조회하세요:
POST /my_index/_search
{
"query": {
"neural": {
"text_knn": {
"query_text": "hello",
"model_id": "your_embedding_model_id_created_in_step4",
"k": 100
}
}
},
"size": "1",
"_source": ["text"]
}
{% include copy-curl.html %}