Spanner 벡터 검색 시작하기

1. 소개

Spanner는 관계형 및 비관계형 운영 워크로드 모두에 적합한 수평 확장 가능한 전 세계에 분산된 완전 관리형 데이터베이스 서비스입니다.

정확한 K-최근접 이웃 기능이 출시됨에 따라 이제 Spanner는 확장성이 뛰어난 벡터 데이터베이스로도 기능합니다. 이를 통해 유사성 또는 시맨틱 검색을 수행하고 생성형 AI 애플리케이션에서 검색 증강 생성 (RAG)을 대규모로 구현할 수 있습니다. Spanner의 벡터 검색어는 운영 데이터에 대한 다른 쿼리와 마찬가지로 트랜잭션이 커밋되는 즉시 최신 실시간 데이터를 반환합니다.

이 실습에서는 Spanner를 활용하여 벡터 검색을 수행하고 SQL을 사용하여 Vertex AI의 모델 가든에서 임베딩 및 LLM 모델에 액세스하는 데 필요한 기본 기능을 설정하는 방법을 알아봅니다.

아키텍처는 다음과 같습니다.

d179a760add7adc0.png

빌드할 항목

이 실습에서 학습할 내용은 다음과 같습니다.

  • Spanner 인스턴스 만들기
  • Vertex AI의 임베딩 및 LLM 모델과 통합하도록 Spanner의 데이터베이스 스키마 설정
  • 소매 데이터 세트 로드
  • 데이터 세트에 대해 유사성 검색어 실행
  • LLM 모델에 컨텍스트를 제공하여 제품별 추천을 생성합니다.

학습할 내용

  • Spanner 인스턴스 설정 방법
  • Vertex AI와 통합하는 방법
  • Spanner를 사용하여 벡터 검색을 수행하여 소매 데이터 세트에서 유사한 항목을 찾는 방법

필요한 항목

  • 결제 계정에 연결된 Google Cloud 프로젝트입니다.
  • Chrome 또는 Firefox와 같은 웹브라우저

2. 설정 및 요건

프로젝트 만들기

아직 Google 계정(Gmail 또는 Google Apps)이 없으면 계정을 만들어야 합니다. Google Cloud Platform 콘솔 ( console.cloud.google.com)에 로그인하여 새 프로젝트를 만듭니다.

프로젝트가 이미 있으면 Console 왼쪽 위에서 프로젝트 선택 풀다운 메뉴를 클릭합니다.

6c9406d9b014760.png

그리고 표시된 대화상자에서 '새 프로젝트' 버튼을 클릭하여 새 프로젝트를 만듭니다.

949d83c8a4ee17d9.png

아직 프로젝트가 없으면 첫 번째 프로젝트를 만들기 위해 다음과 비슷한 대화상자가 표시됩니다.

870a3cbd6541ee86.png

이후의 프로젝트 만들기 대화상자에서 새 프로젝트의 세부정보를 입력할 수 있습니다.

6a92c57d3250a4b3.png

모든 Google Cloud 프로젝트에서 고유한 이름인 프로젝트 ID를 기억하세요(위의 이름은 이미 사용되었으므로 사용할 수 없습니다). 이 이름은 나중에 Codelab에서 PROJECT_ID로 참조됩니다.

아직 사용 설정하지 않은 경우 Google Cloud 리소스를 사용하고 Spanner API를 사용 설정하려면 Developers Console에서 결제를 사용 설정해야 합니다.

15d0ef27a8fbab27.png

이 codelab을 실행하는 과정에는 많은 비용이 들지 않지만 더 많은 리소스를 사용하려고 하거나 실행 중일 경우 비용이 더 들 수 있습니다(이 문서 마지막의 '삭제' 섹션 참조). Google Cloud Spanner 가격 책정은 여기를 참조하세요.

Google Cloud Platform 신규 사용자는 $300 상당의 무료 체험판을 사용할 수 있으므로, 이 Codelab을 완전히 무료로 사용할 수 있습니다.

Google Cloud Shell 설정

Google Cloud 및 Spanner를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

이 Debian 기반 가상 머신에는 필요한 모든 개발 도구가 로드되어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 즉, 이 Codelab에 필요한 것은 브라우저뿐입니다(Chromebook에서도 작동 가능).

  1. Cloud 콘솔에서 Cloud Shell을 활성화하려면 Cloud Shell 활성화 gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A를 클릭하세요. 환경을 프로비저닝하고 연결하는 데 몇 분 정도 걸립니다.

JjEuRXGg0AYYIY6QZ8d-66gx_Mtc-_jDE9ijmbXLJSAXFvJt-qUpNtsBsYjNpv2W6BQSrDc1D-ARINNQ-1EkwUhz-iUK-FUCZhJ-NtjvIEx9pIkE-246DomWuCfiGHK78DgoeWkHRw

Screen Shot 2017-06-14 at 10.13.43 PM.png

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 PROJECT_ID로 이미 설정된 것을 확인할 수 있습니다.

gcloud auth list

명령어 결과

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

어떤 이유로든 프로젝트가 설정되지 않았으면 다음 명령어를 실행하면 됩니다.

gcloud config set project <PROJECT_ID>

PROJECT_ID를 찾고 계신가요? 설정 단계에서 사용한 ID를 확인하거나 Cloud Console 대시보드에서 확인하세요.

158fNPfwSxsFqz9YbtJVZes8viTS3d1bV4CVhij3XPxuzVFOtTObnwsphlm6lYGmgdMFwBJtc-FaLrZU7XHAg_ZYoCrgombMRR3h-eolLPcvO351c5iBv506B3ZwghZoiRg6cz23Qw

또한 Cloud Shell은 기본적으로 이후 명령어를 실행할 때 유용할 수 있는 몇 가지 환경 변수를 설정합니다.

echo $GOOGLE_CLOUD_PROJECT

명령어 결과

<PROJECT_ID>

Spanner API 사용 설정

gcloud services enable spanner.googleapis.com

요약

이 단계에서는 Cloud Shell이 아직 없는 경우 프로젝트를 설정하고, Cloud Shell을 활성화하고, 필요한 API를 사용 설정했습니다.

다음 단계

다음으로 Spanner 인스턴스와 데이터베이스를 설정합니다.

3. Spanner 인스턴스 및 데이터베이스 만들기

Spanner 인스턴스 만들기

이 단계에서는 Codelab을 위한 Spanner 인스턴스를 설정합니다. 이렇게 하려면 Cloud Shell을 열고 다음 명령어를 실행합니다.

export SPANNER_INSTANCE_ID=retail-demo
gcloud spanner instances create $SPANNER_INSTANCE_ID \
--config=regional-us-central1 \
--description="spanner AI retail demo" \
--nodes=1

명령어 결과:

$ gcloud spanner instances create $SPANNER_INSTANCE_ID \
--config=regional-us-central1 \
--description="spanner AI retail demo" \
--nodes=1
Creating instance...done.  

데이터베이스 만들기

인스턴스가 실행되면 데이터베이스를 만들 수 있습니다. Spanner는 단일 인스턴스에서 여러 데이터베이스를 허용합니다.

데이터베이스는 스키마를 정의하는 곳입니다. 또한 데이터베이스에 액세스할 수 있는 사용자를 제어하고, 커스텀 암호화를 설정하고, 최적화 도구를 구성하고, 보관 기간을 설정할 수 있습니다.

데이터베이스를 만들려면 다시 gcloud 명령줄 도구를 사용합니다.

export SPANNER_DATABASE=cymbal-bikes
gcloud spanner databases create $SPANNER_DATABASE \
 --instance=$SPANNER_INSTANCE_ID

명령어 결과:

$ gcloud spanner databases create $SPANNER_DATABASE \
 --instance=$SPANNER_INSTANCE_ID
Creating database...done.

요약

이 단계에서는 Spanner 인스턴스와 데이터베이스를 만들었습니다.

다음 단계

다음으로 Spanner 스키마와 데이터를 설정합니다.

4. Cymbal 스키마 및 데이터 로드

Cymbal 스키마 만들기

스키마를 설정하려면 Spanner Studio로 이동합니다.

3e1a0fed928b33cf.png

스키마는 두 부분으로 구성됩니다. 먼저 products 테이블을 추가하려고 합니다. 이 문장을 복사하여 빈 탭에 붙여넣으세요.

스키마의 경우 이 DDL을 복사하여 상자에 붙여넣습니다.

CREATE TABLE products (
categoryId INT64 NOT NULL,
productId INT64 NOT NULL,
productName STRING(MAX) NOT NULL,
productDescription STRING(MAX) NOT NULL,
productDescriptionEmbedding ARRAY<FLOAT64>,
createTime TIMESTAMP NOT NULL OPTIONS (
allow_commit_timestamp = true
),
inventoryCount INT64 NOT NULL,
priceInCents INT64,
) PRIMARY KEY(categoryId, productId);

그런 다음 run 버튼을 클릭하고 스키마가 생성될 때까지 몇 초 동안 기다립니다.

다음으로 두 모델을 만들어 Vertex AI 모델 엔드포인트로 구성합니다.

첫 번째 모델은 텍스트에서 임베딩을 생성하는 데 사용되는 임베딩 모델이고, 두 번째 모델은 Spanner의 데이터를 기반으로 응답을 생성하는 데 사용되는 LLM 모델입니다.

Spanner Studio의 새 탭에 다음 스키마를 붙여넣습니다.

CREATE MODEL EmbeddingsModel INPUT(
content STRING(MAX),
) OUTPUT(
embeddings STRUCT<statistics STRUCT<truncated BOOL, token_count FLOAT64>, values ARRAY<FLOAT64>>,
) REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/<PROJECT_ID>/locations/us-central1/publishers/google/models/textembedding-gecko@003'
);

CREATE MODEL LLMModel INPUT(
prompt STRING(MAX),
) OUTPUT(
content STRING(MAX),
) REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/<PROJECT_ID>/locations/us-central1/publishers/google/models/text-bison@001',
default_batch_size = 1
);

그런 다음 run 버튼을 클릭하고 모델이 생성될 때까지 몇 초 정도 기다립니다.

Spanner Studio의 왼쪽 창에 다음과 같은 테이블과 모델이 표시됩니다.

62455aa4b0e839d9.png

데이터 로드

이제 데이터베이스에 일부 제품을 삽입하려고 합니다. Spanner Studio에서 새 탭을 열고 다음 삽입 구문을 복사하여 붙여넣습니다.

INSERT INTO products (categoryId, productId, productName, productDescription, createTime, inventoryCount, priceInCents)
VALUES (1, 1, "Cymbal Helios Helmet", "Safety meets style with the Cymbal children's bike helmet. Its lightweight design, superior ventilation, and adjustable fit ensure comfort and protection on every ride. Stay bright and keep your child safe under the sun with Cymbal Helios!", PENDING_COMMIT_TIMESTAMP(), 100, 10999),
(1, 2, "Cymbal Sprout", "Let their cycling journey begin with the Cymbal Sprout, the ideal balance bike for beginning riders ages 2-4 years. Its lightweight frame, low seat height, and puncture-proof tires promote stability and confidence as little ones learn to balance and steer. Watch them sprout into cycling enthusiasts with Cymbal Sprout!", PENDING_COMMIT_TIMESTAMP(), 10, 13999),
(1, 3, "Cymbal Spark Jr.", "Light, vibrant, and ready for adventure, the Spark Jr. is the perfect first bike for young riders (ages 5-8). Its sturdy frame, easy-to-use brakes, and puncture-resistant tires inspire confidence and endless playtime. Let the spark of cycling ignite with Cymbal!", PENDING_COMMIT_TIMESTAMP(), 34, 13900),
(1, 4, "Cymbal Summit", "Conquering trails is a breeze with the Summit mountain bike. Its lightweight aluminum frame, responsive suspension, and powerful disc brakes provide exceptional control and comfort for experienced bikers navigating rocky climbs or shredding downhill. Reach new heights with Cymbal Summit!", PENDING_COMMIT_TIMESTAMP(), 0, 79999),
(1, 5, "Cymbal Breeze", "Cruise in style and embrace effortless pedaling with the Breeze electric bike. Its whisper-quiet motor and long-lasting battery let you conquer hills and distances with ease. Enjoy scenic rides, commutes, or errands with a boost of confidence from Cymbal Breeze!", PENDING_COMMIT_TIMESTAMP(), 72, 129999),
(1, 6, "Cymbal Trailblazer Backpack", "Carry all your essentials in style with the Trailblazer backpack. Its water-resistant material, multiple compartments, and comfortable straps keep your gear organized and accessible, allowing you to focus on the adventure. Blaze new trails with Cymbal Trailblazer!", PENDING_COMMIT_TIMESTAMP(), 24, 7999),
(1, 7, "Cymbal Phoenix Lights", "See and be seen with the Phoenix bike lights. Powerful LEDs and multiple light modes ensure superior visibility, enhancing your safety and enjoyment during day or night rides. Light up your journey with Cymbal Phoenix!", PENDING_COMMIT_TIMESTAMP(), 87, 3999),
(1, 8, "Cymbal Windstar Pump", "Flat tires are no match for the Windstar pump. Its compact design, lightweight construction, and high-pressure capacity make inflating tires quick and effortless. Get back on the road in no time with Cymbal Windstar!", PENDING_COMMIT_TIMESTAMP(), 36, 24999),
(1, 9,"Cymbal Odyssey Multi-Tool","Be prepared for anything with the Odyssey multi-tool. This handy gadget features essential tools like screwdrivers, hex wrenches, and tire levers, keeping you ready for minor repairs and adjustments on the go. Conquer your journey with Cymbal Odyssey!", PENDING_COMMIT_TIMESTAMP(), 52, 999),
(1, 10,"Cymbal Nomad Water Bottle","Stay hydrated on every ride with the Nomad water bottle. Its sleek design, BPA-free construction, and secure lock lid make it the perfect companion for staying refreshed and motivated throughout your adventures. Hydrate and explore with Cymbal Nomad!", PENDING_COMMIT_TIMESTAMP(), 42, 1299);

run 버튼을 클릭하여 데이터를 삽입합니다.

요약

이 단계에서는 스키마를 만들고 cymbal-bikes 데이터베이스에 몇 가지 기본 데이터를 로드했습니다.

다음 단계

다음으로, 임베딩 모델과 통합하여 제품 설명에 대한 임베딩을 생성하고, 텍스트 검색 요청을 임베딩으로 변환하여 관련 제품을 검색합니다.

5. 임베딩 사용

제품 설명을 위한 벡터 임베딩 생성

제품에 대해 유사성 검색이 작동하려면 제품 설명에 대한 임베딩을 생성해야 합니다.

스키마에서 생성된 EmbeddingsModel를 사용하면 간단한 UPDATE DML 문입니다.

UPDATE products p1
SET productDescriptionEmbedding =
(SELECT embeddings.values from ML.PREDICT(MODEL EmbeddingsModel,
(SELECT productDescription as content FROM products p2 where p2.productId=p1.productId)))
WHERE categoryId=1;

run 버튼을 클릭하여 제품 설명을 업데이트합니다.

이 예시에서는 SQL 쿼리를 통해 자연어 검색 요청을 제공합니다. 이 쿼리는 검색 요청을 임베딩으로 전환한 다음 이전 단계에서 생성된 제품 설명의 저장된 임베딩을 기반으로 유사한 결과를 검색합니다.

-- Use Spanner's vector search, and integration with embedding and LLM models to
-- return items that are semantically relevant and available in inventory based on
-- real-time data.


SELECT productName, productDescription, inventoryCount, COSINE_DISTANCE(
productDescriptionEmbedding,
(   SELECT embeddings.values
FROM ML.PREDICT(
MODEL EmbeddingsModel,
(SELECT "I'd like to buy a starter bike for my 3 year old child" as content)
)
)
) as distance
FROM products
WHERE inventoryCount > 0
ORDER BY distance
LIMIT 5;

run 버튼을 클릭하여 유사한 제품을 찾습니다. 결과는 다음과 같이 표시됩니다.

672e111753077fcf.png

재고가 있는 제품 (inventoryCount > 0)에만 관심이 있는 경우와 같이 쿼리에 추가 필터가 사용된 것을 볼 수 있습니다.

요약

이 단계에서는 Vertex AI의 모델과 Spanner의 통합을 활용하여 SQL을 사용하여 제품 설명 임베딩과 검색 요청 임베딩을 만들었습니다. 또한 벡터 검색을 수행하여 검색 요청과 일치하는 유사한 제품을 찾았습니다.

다음 단계

다음으로, 검색 결과를 사용하여 LLM에 피드하고 각 제품의 커스텀 응답을 생성해 보겠습니다.

6. LLM으로 작업하기

Spanner를 사용하면 Vertex AI에서 제공되는 LLM 모델과 쉽게 통합할 수 있습니다. 따라서 개발자는 애플리케이션이 로직을 수행할 필요 없이 SQL을 사용하여 LLM과 직접 상호작용할 수 있습니다.

예를 들어 "I'd like to buy a starter bike for my 3 year old child". 사용자의 이전 SQL 쿼리 결과가 있습니다.

개발자는 다음 프롬프트를 사용하여 제품이 사용자에게 적합한지 여부에 관한 각 결과에 응답을 제공하려고 합니다.

"Answer with ‘Yes' or ‘No' and explain why: Is this a good fit for me? I'd like to buy a starter bike for my 3 year old child"

사용할 수 있는 쿼리는 다음과 같습니다.

-- Use an LLM to analyze this list and provide a recommendation on whether each
-- product is a good fit for the user. We use the vector search and real time
-- inventory data to first filter the products to reduce the size of the prompt to
-- the LLM.
SELECT productName, productDescription, inventoryCount, content AS LLMResponse
FROM ML.PREDICT(
MODEL LLMModel,
(   SELECT
inventoryCount,
productName,
productDescription,
CONCAT(
"Answer with ‘Yes' or ‘No' and explain why: Is this a good fit for me?",
"I'd like to buy a starter bike for my 3 year old child \n",
"Product Name: ", productName, "\n",
"Product Description:", productDescription) AS prompt,
FROM products
WHERE inventoryCount > 0
ORDER by COSINE_DISTANCE(
productDescriptionEmbedding,
(   SELECT embeddings.values
FROM ML.PREDICT(
MODEL EmbeddingsModel,
( SELECT "I'd like to buy a starter bike for my 3 year old child" as content)
)
)
) LIMIT 5
),
STRUCT(256 AS maxOutputTokens)
);

run 버튼을 클릭하여 쿼리를 실행합니다. 결과는 다음과 같이 표시됩니다.

35878cd0f88f1470.png

제품 설명에 제시된 연령대 (만 2~4세)로 인해 첫 번째 제품은 3세에게 적합합니다. 다른 제품은 잘 맞지 않습니다.

요약

다음 단계

이제 정리할 시간입니다.

7. 삭제 (선택사항)

삭제하려면 Cloud 콘솔의 Cloud Spanner 섹션으로 이동하여 Codelab에서 만든 'retail-demo' 인스턴스를 삭제하면 됩니다.

41cbc1a84b3588d5.png

8. 수고하셨습니다

수고하셨습니다. Spanner의 기본 제공 벡터 검색을 사용하여 유사성 검색을 성공적으로 수행했습니다. 또한 임베딩 및 LLM 모델로 작업하여 SQL을 사용하여 직접 생성형 AI 기능을 제공하는 것이 얼마나 쉬운지도 확인했습니다.

다음 단계

여기(https://cloud.google.com/spanner/docs/find-k-nearest-neighbors)에서 Spanner의 정확한 최근접 이웃(KNN 벡터 검색) 기능에 대해 자세히 알아보세요.

Spanner의 Vertex AI 통합을 사용하여 SQL로 온라인 예측을 수행하는 방법에 대한 자세한 내용은 여기(https://cloud.google.com/spanner/docs/ml)에서 확인할 수 있습니다.