1. 개요
Vertex AI Matching Engine은 업계 최고의 지연 시간이 짧은 대규모 벡터 데이터베이스를 제공합니다. 이러한 벡터 데이터베이스는 일반적으로 벡터 유사성 일치 또는 근사 최근접 이웃(ANN) 서비스라고 부릅니다.
Matching Engine은 의미론적으로 유사한 항목과 일치하는 사용 사례를 빌드하는 도구를 제공합니다. 구체적으로는 쿼리 항목이 제공되면 Matching Engine이 대규모의 후보 코퍼스에서 가장 의미론적으로 유사한 항목을 찾습니다. 의미론적으로 유사하거나 의미론적으로 관련된 항목을 검색하는 이 기능은 실제 사용 사례가 많으며 다음과 같이 애플리케이션의 중요한 부분입니다.
- 추천 엔진
- 검색엔진
- 광고 타겟팅 시스템
- 이미지 분류 또는 이미지 검색
- 텍스트 분류
- 질문 답변
- 챗봇
시맨틱 일치 시스템을 빌드하려면 모든 항목의 벡터 표현을 계산해야 합니다. 이러한 벡터 표현을 임베딩이라고 부르는 경우가 많습니다. 임베딩은 비슷한 예시가 가깝게 배치되고 비슷하지 않은 항목은 멀리 배치되는 임베딩 공간을 확인하도록 학습된 머신러닝 모델을 사용하여 계산됩니다. 따라서 두 항목이 임베딩 공간에 가까워질수록 더 유사합니다.
대략적으로 시맨틱 일치는 두 가지 주요 단계로 단순화할 수 있습니다.
- 항목의 임베딩 표현 생성
- 임베딩에서 가장 가까운 이웃 검색 수행
다음 그림은 데이터베이스에서 도서를 검색하고 입력 쿼리와 가장 가깝게 일치하는 항목을 반환하는 예시에 이 기법을 적용하는 방법을 보여줍니다. 이 방식을 사용하여 쿼리에 응답하려면 시스템이 먼저 각 데이터베이스 항목을 임베딩에 매핑한 다음 쿼리를 임베딩 공간에 매핑해야 합니다. 그런 후 시스템이 모든 데이터베이스 임베딩 중에서 쿼리와 가장 가까운 항목을 찾아야 합니다. 이는 최단 이웃점 탐색 문제이며 벡터 유사도 검색이라고도 합니다.

임베딩의 사용은 단어 또는 텍스트로 제한되지 않습니다. 머신러닝 모델(종종 딥 러닝 모델)을 사용하면 사진, 오디오, 영화, 사용자 선호도 등 여러 유형의 데이터에서 시맨틱 임베딩을 생성할 수 있습니다.
2. Vertex AI Matching Engine 서비스 소개
Vertex AI Matching Engine은 10억 개 이상의 벡터에서 가장 유사한 벡터를 찾을 수 있는 벡터 데이터베이스입니다. Matching Engine의 ANN 서비스는 이러한 유사성 일치 쿼리를 매우 높은 초당 쿼리 수(QPS)로 제공할 수 있습니다.
Matching Engine은 높은 QPS, 높은 재현율, 비용 효율성으로 대규모 유사성 검색을 제공합니다.
- 임베딩 벡터 수십억 개로 확장
- QPS가 수십만 개에 달하고 쿼리당 최근접 이웃 수백 개가 요청되더라도 서버는 5ms 미만의 50번째 백분위수 지연 시간을 제공합니다.
- 업계 최고의 재현율을 제공합니다. 재현율은 각 벡터 검색 호출에 반환되는 실제 이웃 비율을 측정합니다.
- 다른 알려진 대안보다 CPU와 메모리를 적게 사용합니다.
- 차원 수천 개를 사용하여 임베딩 벡터를 지원합니다.
실제 아키텍처를 간소화하는 유용한 기능
- 수요가 낮은 기간 동안 비용을 절약하기 위해 자동 확장 구성을 지원하고 최대 부하 또는 쿼리를 지원하기 위해 용량을 추가합니다.
- 결과 필터링용 쿼리 시간 불리언 조건자
3. Index 만들기 및 관리
3-1.검색 데이터 준비
유사도 검색 기준이 되는 Index 데이터 파일을 먼저 생성합니다.
{"id":"1", ..., "embedding":[0.03111058, 0.0115341, 0.35728193, 0.31834186, 0.7883481, 0.9245789, 0.663312854, 0.36953208]}
{"id":"2", ..., "embedding":[0.4312513, 0.079019034, 0.39641412, 0.14513537, 0.39728947, 0.5186474, 0.14360385, 0.2961342]}
Index 데이터파일의 각 라인은 id와 embedding값을 포함하여야 합니다. Index 데이터 파일은 GCS에 업로드 합니다.
3-2.Index 데이터 및 매개변수 구성
Index를 만들기 전에 Index의 매개변수를 구성해야 합니다. index_metadata.json이라는 파일을 만듭니다. 이때, contextDeltaUri에는 3-1단계에서 GCS에 업로드한 경로를 입력해 줍니다.
{
"contentsDeltaUri": "gs://BUCKET_NAME/path",
"config": {
"dimensions": 100,
"approximateNeighborsCount": 150,
"distanceMeasureType": "DOT_PRODUCT_DISTANCE",
"shardSize": "SHARD_SIZE_MEDIUM",
"algorithm_config": {
"treeAhConfig": {
"leafNodeEmbeddingCount": 5000,
"leafNodesToSearchPercent": 3
}
}
}
}
Config에 사용된 필드들의 정의는 아래 표를 참조하세요.
필드 | |
---|---|
dimensions | int32 필수 항목입니다. 입력 벡터의 차원 수입니다. |
approximateNeighborsCount | int32 tree-AH 알고리즘을 사용하는 경우 필수입니다. 정확한 순서 변경이 수행되기 전에 유사 검색을 통해 찾을 이웃의 기본 개수입니다. 정확한 순서 변경은 유사 검색 알고리즘에서 반환하는 결과가 비용이 더 많이 드는 거리 계산을 통해 재정렬되는 절차입니다. |
distanceMeasureType | DistanceMeasureType 최근접 이웃 검색에 사용되는 거리 측정값입니다. |
featureNormType | FeatureNormType 각 벡터에서 수행될 정규화 유형입니다. |
algorithmConfig | oneOf:
Matching Engine이 효율적으로 검색할 수 있도록 사용하는 알고리즘의 구성입니다.
|
3-3.Index 데이터 및 매개변수 구성
3-2에서 생성한metadata JSON 파일을 활용하여 아래 명령어를 수행하면 Index의 생성이 완료 됩니다.
gcloud ai indexes create \
--metadata-file=index_metadata.json \
--display-name=INDEX_NAME \
--project=PROJECT_ID \
--region=LOCATION
아래 명령어를 통해 생성된 Index를 확인할 수 있습니다.
GET https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexes
응답 예)
{
"indexes": [
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/indexes/INDEX_ID",
"displayName": "INDEX_NAME",
"metadataSchemaUri": "gs://google-cloud-aiplatform/schema/matchingengine/metadata/nearest_neighbor_search_1.0.0.yaml",
"metadata": {
"config": {
"dimensions": 100,
"approximateNeighborsCount": 150,
"distanceMeasureType": "DOT_PRODUCT_DISTANCE",
"featureNormType": "NONE",
"algorithmConfig": {
"treeAhConfig": {
"maxLeavesToSearch": 50,
"leafNodeCount": 10000
}
}
}
},
"etag": "AMEw9yNU8YX5IvwuINeBkVv3yNa7VGKk11GBQ8GkfRoVvO7LgRUeOo0qobYWuU9DiEc=",
"createTime": "2020-11-08T21:56:30.558449Z",
"updateTime": "2020-11-08T22:39:25.048623Z"
}
]
}
4. Index Endpoint 배포 및 관리
4-1. 공개 Index Endpoint 만들기
공개 Index Endpoint는 현재 미리보기 단계 서비스이며, API 직접 호출을 통해 생성 가능합니다.
[request.json]
{
"display_name": "public-endpoint-test1",
"publicEndpointEnabled": "true"
}
—------------------------------------------
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/indexEndpoints"
생성 완료되면 아래와 같은 Response를 받습니다.
{
"name": "projects/PROJECT_NUMBER/locations/LOCATION/indexEndpoints/INDEX_ENDPOINT_ID/operations/OPERATION_ID",
"metadata": {
"@type": "type.googleapis.com/google.cloud.aiplatform.v1.CreateIndexEndpointOperationMetadata",
"genericMetadata": {
"createTime": "2022-01-13T04:09:56.641107Z",
"updateTime": "2022-01-13T04:09:56.641107Z"
}
}
}
INDEX_ENDPOINT_ID 값을 확인합니다.
4-2. Index 배포
Index Endpoint에(INDEX_ENDPOINT_ID) 3-3단계에서 생성한 Index를(INDEX_ID) 배포합니다.
gcloud ai index-endpoints deploy-index INDEX_ENDPOINT_ID \
--deployed-index-id=DEPLOYED_INDEX_ID \
--display-name=DEPLOYED_INDEX_NAME \
--index=INDEX_ID \
--project=PROJECT_ID \
--region=LOCATION
- INDEX_ENDPOINT_ID: 색인 엔드포인트 ID입니다.
- DEPLOYED_INDEX_ID: 배포된 색인을 고유하게 식별하기 위해 사용자가 지정한 문자열입니다. 문자로 시작해야 하며 문자, 숫자, 밑줄만 포함할 수 있습니다.
- DEPLOYED_INDEX_NAME: 배포된 색인의 표시 이름입니다.
- INDEX_ID: 색인 ID입니다.
4-3. Index 도메인 이름 가져오기
curl -H "Content-Type: application/json" -H "Authorization: Bearer `gcloud auth print-access-token`" ${ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${REGION}/indexEndpoints/${INDEX_ENDPOINT_ID}
# Example Response
{
"name": "projects/181224308459/locations/us-central1/indexEndpoints/3370566089086861312",
"displayName": "public-endpoint-test1",
"deployedIndexes": [
{
"id": "test_index_public1",
"index": "projects/181224308459/locations/us-central1/indexes/7733428228102029312",
"displayName": "test_index_public1",
"createTime": "2023-02-08T23:19:58.026843Z",
"indexSyncTime": "2023-02-09T05:26:19.309417Z",
"automaticResources": {
"minReplicaCount": 2,
"maxReplicaCount": 2
},
"deploymentGroup": "default"
}
],
"etag": "AMEw9yNkXQcSke8iqW9SYxfhj_hT9GCwPt1XlxVwJRSCxiXOYnG4CKrZM_X0oH-XN8tR",
"createTime": "2023-02-08T22:44:20.285382Z",
"updateTime": "2023-02-08T22:44:26.515162Z",
"publicEndpointDomainName": "1957880287.us-central1-181224308459.vdb.vertexai.goog"
}
publicEndpointDomainName 값을 가져옵니다.
5. Index 쿼리로 최근접 이웃 가져오기
5-1. 공개 엔드포인트 사용 예시
최근접 이웃 찾기(findNeighbors)
$ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer `gcloud auth print-access-token`" https://1957880287.us-central1-181224308459.vdb.vertexai.goog/v1/projects/181224308459/locations/us-central1/indexEndpoints/3370566089086861312:findNeighbors -d '{deployed_index_id: "test_index_public1", queries: [{datapoint: {datapoint_id: "0", feature_vector: [0.03111058, 0.0115341, 0.35728193, 0.31834186, 0.7883481, 0.9245789, 0.663312854, 0.36953208]}, neighbor_count: 5}]}'