Spanner ve Vertex AI ile Benzerlik Araması

1. Giriş

Derin öğrenmede son zamanlarda kaydedilen ilerlemeler, metin ve diğer verilerin anlamsal anlamı yakalayacak şekilde temsil edilmesini mümkün hale getirdi. Bu da aramada vektör arama adı verilen yeni bir yaklaşıma yol açtı. Bu yaklaşım, kullanıcının sorgusuyla en alakalı dokümanları bulmak için metnin vektör temsillerini (yerleştirme olarak bilinir) kullanır. Kıyafet arama gibi uygulamalarda geleneksel arama yerine vektör arama tercih edilir. Burada kullanıcılar, ürünleri tam olarak ürün veya marka adları yerine açıklamasına, tarzlarına veya bağlama göre arar. Vektör benzerliği eşleştirmesi yapmak için Cloud Spanner veritabanını Vektör Arama ile entegre edebiliriz. Müşteriler, Spanner ve Vektör Arama'yı birlikte kullanarak Spanner'ın kullanılabilirlik, güvenilirlik ve ölçeğinin yanı sıra Vertex AI Vector Search'ün gelişmiş benzerlik arama özelliklerini birleştiren güçlü bir entegrasyon oluşturabilir. Bu arama, Vektör Arama dizinindeki öğelerin yerleştirmelerinin karşılaştırılması ve en benzer eşleşmeler döndürülmesi ile gerçekleştirilir.

Kullanım Örneği

Bir moda perakendecisinde hızla değişen trendlere, ürün aramalarına ve önerilere ayak uydurmaya çalışan bir veri bilimci olduğunuzu düşünün. Buradaki zorluk, kaynaklarınızın ve veri silolarınızın sınırlı olmasıdır. Bu blog yayınında, giyim verilerinde benzerlik araması yaklaşımından yararlanarak giyim önerisi kullanım alanının nasıl uygulanacağı gösterilmektedir.Aşağıdaki adımlar ele alınmaktadır:

  1. Veriler Spanner'dan alınır
  2. ML.PREDICT kullanılarak giyim verileri için oluşturulan ve Spanner'da depolanan vektörler
  3. Dataflow ve iş akışı işleri kullanılarak Vector Search ile entegre edilen Spanner vektör verileri
  4. Kullanıcı tarafından girilen giriş için benzerlik eşleşmesi bulmak üzere vektör araması

Kullanıcı giriş metnine göre giysi araması yapmak için bir demo web uygulaması oluşturacağız. Uygulama, kullanıcıların metin açıklaması girerek giysi aramasına olanak tanıyor.

Spanner - Vektör Arama Dizini:

Giyim aramasına ilişkin veriler Spanner'da depolanır. ML.PREDICT yapısındaki Vertex AI Embeddings API'yi doğrudan Spanner verilerinden çağırırız. Ardından, bu verileri (envanter ve yerleştirmeler) Vertex AI'ın Vektör Arama alanına toplu olarak yükleyen Dataflow ve İş Akışı işlerinden yararlanıp dizini yenileyeceğiz.

Dizinde Kullanıcı Sorgularını Çalıştırma:

Kullanıcı bir kıyafet açıklaması girdiğinde, uygulama, Text Embeddings API'sini kullanarak yerleştirmeleri gerçek zamanlı olarak oluşturur. Bu veriler daha sonra dizinden alakalı 10 ürün açıklaması bulmak için Vector Search API'ye giriş olarak gönderilir ve ilgili resmi gösterir.

Mimariye Genel Bakış

Spanner- Vektör Arama uygulamasının mimarisi aşağıdaki 2 bölümden oluşan şemada gösterilmektedir:

Spanner'dan Vektör Arama Dizinine: a79932a25bee23a4.png

Dizinde kullanıcı sorguları çalıştıracak istemci uygulama:

b2b4d5a5715bd4c4.pngOluşturacağınız şey

Spanner - Vektör Dizini:

  • Kaynak verileri ve ilgili yerleştirmeleri depolayıp yönetmek için Spanner veritabanı
  • Verileri (kimlik ve yerleştirmeler) Vertex AI Vektör Arama veritabanına toplu olarak yükleyen bir iş akışı işi.
  • Dizinden alakalı ürün açıklamalarını bulmak için kullanılan bir Vector Search API.

Dizinde Kullanıcı Sorgularını Çalıştırma:

  • Kullanıcıların giysilerin metin açıklamalarını girmelerine olanak tanıyan, dağıtılan dizin uç noktasını kullanarak benzerlik araması yapan ve en yakın giysileri girişe döndüren bir web uygulaması.

İşleyiş Şekli

Kullanıcı giysi için metin açıklaması girdiğinde, web uygulaması açıklamayı Vector Search API'ye gönderir. Ardından Vector Search API, dizindeki en alakalı ürün açıklamalarını bulmak için kıyafet açıklamalarının yerleştirmelerini kullanır. Ardından ürün açıklamaları ve ilgili resimler kullanıcıya gösterilir. Genel iş akışı aşağıdaki gibidir:

  1. Spanner'da depolanan veriler için yerleştirmeler oluşturun.
  2. Yerleştirmeleri bir Vektör Arama dizinine aktarın ve oraya yükleyin.
  3. En yakın komşu araması yaparak benzer öğeler için Vektör Arama dizinini sorgulayın.

2. Şartlar

  • Chrome veya Firefox gibi bir tarayıcı
  • Faturalandırmanın etkin olduğu bir Google Cloud projesi

Başlamadan önce

  1. Google Cloud Console'daki proje seçici sayfasından bir Google Cloud projesi seçin veya oluşturun.
  2. Cloud projeniz için faturalandırmanın etkinleştirildiğinden emin olun. Bir projede faturalandırmanın etkin olup olmadığını nasıl kontrol edeceğinizi öğrenin.
  3. Tüm gerekli API'lerin (Cloud Spanner, Vertex AI, Google Cloud Storage) etkinleştirildiğinden emin olun
  4. gcloud ile önceden yüklenmiş olarak gelen ve Google Cloud'da çalışan bir komut satırı ortamı olan Cloud Shell'i kullanacaksınız. gcloud komutları ve kullanımı için belgelere bakın. Projeniz ayarlanmadıysa ayarlamak için aşağıdaki komutu kullanın:
gcloud config set project <YOUR_PROJECT_ID>
  1. Başlamak için etkin Google Cloud projenizin bulunduğu Cloud Spanner sayfasına gidin

3. Arka uç: Spanner veri kaynağınızı ve yerleştirmelerinizi oluşturun

Bu kullanım durumunda, Spanner veritabanı ilgili resimler ve açıklamalarla birlikte giyim envanterini barındırır. Metin açıklaması için yerleştirmeler oluşturduğunuzdan ve bunları Spanner veritabanınızda ARRAY<float64> olarak sakladığınızdan emin olun.

  1. Spanner verilerini oluşturma

"spanner-vertex" adlı bir örnek oluşturun ve "spanner-vertex-embeddings" adlı bir veritabanı olur. DDL'yi kullanarak tablo oluşturma:

CREATE TABLE
  apparels ( id NUMERIC,
    category STRING(100),
    sub_category STRING(50),
    uri STRING(200),
    content STRING(2000),
    embedding ARRAY<FLOAT64>
    )
PRIMARY KEY
  (id);
  1. INSERT SQL'i kullanarak tabloya veri ekleme

Örnek veriler için komut dosyalarını burada bulabilirsiniz.

  1. Metin Yerleştirme modeli oluştur

Girişteki içeriğe yönelik yerleştirmeler oluşturabilmemiz için bu işlem gereklidir. Aynı öğenin DDL'si:

CREATE MODEL text_embeddings INPUT(content STRING(MAX))
OUTPUT(
  embeddings
    STRUCT<
      statistics STRUCT<truncated BOOL, token_count FLOAT64>,
      values ARRAY<FLOAT64>>
)
REMOTE OPTIONS (
  endpoint = '//aiplatform.googleapis.com/projects/abis-345004/locations/us-central1/publishers/google/models/textembedding-gecko');
  1. Kaynak veriler için metin yerleştirilmiş öğeler oluşturma

Yerleştirmeleri depolamak ve oluşturulan yerleştirmeleri eklemek için bir tablo oluşturun. Gerçek dünyadaki bir veritabanı uygulamasında Spanner'a 2. adıma kadar olan veri yükü işlemsel olacaktır. Tasarımla ilgili en iyi uygulamaları korumak amacıyla işlem tablolarını normalleştirilmiş olarak tutmayı ve bu nedenle yerleştirmeler için ayrı bir tablo oluşturmayı tercih ediyorum.

CREATE TABLE apparels_embeddings (id string(100), embedding ARRAY<FLOAT64>)
PRIMARY KEY (id);

INSERT INTO apparels_embeddings(id, embeddings) 
SELECT CAST(id as string), embeddings.values
FROM ML.PREDICT(
  MODEL text_embeddings,
  (SELECT id, content from apparels)
) ;

Artık toplu içerik ve yerleştirmeler hazır olduğuna göre, Vektör Araması'nı gerçekleştirmemize yardımcı olacak yerleştirmeleri depolamak için bir Vektör Arama Dizini ve Uç Nokta oluşturalım.

4. İş Akışı İşi: Spanner verilerini Vektör Arama'ya aktarma

  1. Cloud Storage Paketi oluşturma

Bu, Spanner'dan yapılan yerleştirmeleri, Vector Search'ün giriş olarak beklediği json biçiminde bir GCS paketinde depolamak için gereklidir. Spanner'daki verilerinizle aynı bölgede bulunan bir paket oluşturun. Gerekirse bu klasörün içinde bir klasör oluşturun, ancak esasen burada empty.json adlı boş bir dosya oluşturun.

  1. Cloud Workflow'u kurma

Spanner'dan Vertex AI Vektör Arama dizinine toplu dışa aktarma işlemi ayarlamak için:

Boş bir dizin oluşturun:

Vektör Arama Dizini'nin, Cloud Storage paketiniz ve verilerle aynı bölgede olduğundan emin olun. Dizinleri yönetme sayfasındaki Toplu güncelleme için dizin oluşturma bölümünde konsol sekmesinde bulunan 11 talimatı uygulayın. contentDeltaUri'ye iletilen klasörde, empty.json adında boş bir dosya oluşturun. Çünkü bu dosya olmadan dizin oluşturamazsınız. Bu işlem boş bir dizin oluşturur.

Zaten bir dizininiz varsa bu adımı atlayabilirsiniz. İş akışı, dizininizin üzerine yazacak.

Not: Bir uç noktaya boş bir dizin dağıtamazsınız. Bu nedenle, vektör verilerini Cloud Storage'a aktardıktan sonra, sanal makineyi bir uç noktaya dağıtma adımını daha sonraki bir adıma erteliyoruz.

Bu git deposunu klonlama: Git deposunu klonlamanın birden çok yolu vardır. Bunlardan biri, GitHub CLI'ı kullanarak aşağıdaki komutu çalıştırmaktır. Cloud Shell terminalinden aşağıdaki 2 komutu çalıştırın:

gh repo clone cloudspannerecosystem/spanner-ai

cd spanner-ai/vertex-vector-search/workflows

Bu klasörde iki dosya var

  • batch-export.yaml: Bu, iş akışının tanımıdır.
  • sample-batch-input.json: Bu, iş akışı giriş parametrelerinin bir örneğidir.

Giriş.json dosyasını örnek dosyadan ayarlayın: Öncelikle örnek json'u kopyalayın.

cp sample-batch-input.json girdisi.json

Ardından projenizin ayrıntılarıyla birlikte input.json öğesini düzenleyin. Bu durumda, json'unuz şu şekilde olmalıdır:

{
  "project_id": "<<YOUR_PROJECT>>",
  "location": "<<us-central1>>",
  "dataflow": {
    "temp_location": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_temp"
  },
  "gcs": {
    "output_folder": "gs://<<YOUR_BUCKET>>/<<FOLDER_IF_ANY>>/workflow_output"
  },
  "spanner": {
    "instance_id": "spanner-vertex",
    "database_id": "spanner-vertex-embeddings",
    "table_name": "apparels_embeddings",
    "columns_to_export": "embedding,id"
  },
  "vertex": {
    "vector_search_index_id": "<<YOUR_INDEX_ID>>"
  }
}

Kurulum İzinleri

Üretim ortamlarında, yeni bir hizmet hesabı oluşturmanızı ve bu hesaba hizmet yönetimi için gereken minimum izinleri içeren bir veya daha fazla IAM rolü atamanızı önemle tavsiye ederiz. Spanner'dan (yerleştirmeler) verileri Vektör Arama dizinine aktarmak üzere iş akışını ayarlamak için şu roller gerekir:

Cloud Workflow Hizmet Hesabı:

Varsayılan olarak Compute Engine varsayılan hizmet hesabını kullanır.

Manuel olarak yapılandırılmış bir hizmet hesabı kullanıyorsanız aşağıdaki rolleri eklemeniz gerekir:

Bir Dataflow işini tetiklemek için Dataflow Yöneticisi, Dataflow Çalışanı

Bir dataflow çalışan hizmet hesabının kimliğine bürünmek için: Hizmet Hesabı Kullanıcısı.

Günlük yazmak için: Günlük Yazıcı.

Vertex AI Vector Search yeniden derlenmesini tetiklemek için: Vertex AI User.

Dataflow Çalışanı Hizmet Hesabı:

Manuel olarak yapılandırılmış bir hizmet hesabı kullanıyorsanız aşağıdaki rolleri eklemeniz gerekir:

Dataflow'u yönetmek için: Dataflow Yöneticisi, Dataflow Çalışanı Spanner'dan veri okumak için: Cloud Spanner Veritabanı Okuyucu. Seçilen GCS Container Registry'ye yazma erişimi: GCS Depolama Paketi Sahibi.

  1. Bulut İş Akışını Dağıtma

İş akışı yaml dosyasını Google Cloud projenize dağıtın. Yürütüldükten sonra iş akışının çalıştırılacağı bölgeyi veya konumu yapılandırabilirsiniz.

gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1" [--service account=<service_account>]

or 

gcloud workflows deploy vector-export-workflow --source=batch-export.yaml --location="us-central1"

İş akışı artık Google Cloud konsolunun İş akışları sayfasında görünür.

Not: İş akışını Google Cloud Console'dan da oluşturup dağıtabilirsiniz. Cloud Console'daki istemleri uygulayın. İş akışı tanımı için audience-export.yaml içeriğini kopyalayıp yapıştırın.

Bu aşama tamamlandıktan sonra, veri dışa aktarma işleminin başlaması için iş akışını yürütün.

  1. Bulut İş Akışı'nı yürütme

İş akışını yürütmek için aşağıdaki komutu çalıştırın:

gcloud workflows execute vector-export-workflow --data="$(cat input.json)"

Yürütme işlemi, İş akışlarındaki Yürütmeler sekmesinde görünecektir. Bu işlem, verilerinizi Vector Search veritabanına yüklemeli ve dizine eklemelidir.

Not: Yürüt düğmesini kullanarak konsoldan da yürütme yapabilirsiniz. Talimatları uygulayın ve giriş için özelleştirilmiş giriş.json dosyanızın içeriğini kopyalayıp yapıştırın.

5. Vektör Arama Dizinini Dağıt

Dizini bir uç noktaya dağıtma

Dizini dağıtmak için aşağıdaki adımları uygulayabilirsiniz:

  1. Vektör Arama dizinleri sayfasında, önceki bölümün 2. adımında oluşturduğunuz dizinin yanında DAĞIT düğmesini görürsünüz. Alternatif olarak, dizin bilgileri sayfasına gidip UÇ NOKTAYA DAĞIT düğmesini tıklayabilirsiniz.
  2. Gerekli bilgileri sağlayın ve dizini bir uç noktaya dağıtın.

Alternatif olarak, bu not defterini uç noktaya dağıtmak (not defterinin dağıtım bölümüne geçebilirsiniz) için de bu not defterine bakabilirsiniz. Dağıtımdan sonra, dağıtılan dizin kimliğini ve uç nokta URL'sini not alın.

6. Ön Uç: Vektör Arama için kullanıcı verileri

Şimdi, uygulamamızı hızlı bir şekilde test etmek için gradyo destekli bir kullanıcı deneyimiyle basit bir Python uygulaması oluşturalım: Bu demo uygulamasını kendi colab not defterinize uygulamak için buradan uygulamaya bakabilirsiniz.

  1. Embeddings API'yi çağırmak ve ayrıca Vector Search dizin uç noktasını çağırmak için aiplatform python SDK'sını kullanacağız.
# [START aiplatform_sdk_embedding]
!pip install google-cloud-aiplatform==1.35.0 --upgrade --quiet --user


import vertexai
vertexai.init(project=PROJECT_ID, location="us-central1")


from vertexai.language_models import TextEmbeddingModel


import sys
if "google.colab" in sys.modules:
    # Define project information
    PROJECT_ID = " "  # Your project id
    LOCATION = " "  # Your location 


    # Authenticate user to Google Cloud
    from google.colab import auth
    auth.authenticate_user()
  1. Geliştirdiğimiz yapay zeka uygulamasını, kullanıcı arayüzüyle hızlı ve kolay bir şekilde tanıtmak için gradyanı kullanacağız. Bu adımı uygulamadan önce çalışma zamanını yeniden başlatın.
!pip install gradio
import gradio as gr
  1. Kullanıcı girişinden sonra web uygulamasından Embeddings API'yi çağırırız. Metin yerleştirme modelini kullanırız: textembedding-gecko@araçları

Aşağıdaki yöntem, Metin Yerleştirme Modeli'ni çağırır ve kullanıcı tarafından girilen metin için vektör yerleştirmelerini döndürür:

def text_embedding(content) -> list:
    """Text embedding with a Large Language Model."""
    model = TextEmbeddingModel.from_pretrained("textembedding-gecko@latest")
    embeddings = model.get_embeddings(content)
    for embedding in embeddings:
        vector = embedding.values
        #print(f"Length of Embedding Vector: {len(vector)}")
    return vector

Test et

text_embedding("red shorts for girls")

Aşağıdakine benzer bir çıktı görmeniz gerekir (resmin yüksekliğinin kırpıldığı için vektör yanıtının tamamını göremeyebilirsiniz):

5d8355ec04dac1f9.png

  1. Dağıtılan dizin kimliğini ve uç nokta kimliğini bildirme
from google.cloud import aiplatform
DEPLOYED_INDEX_ID = "spanner_vector1_1702366982123"
#Vector Search Endpoint
index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
  1. Dizin uç noktasını çağırmak için Vektör Arama yöntemini tanımlayın ve sonucu kullanıcı giriş metnine karşılık gelen yerleştirme yanıtı için en yakın 10 eşleşmeyle gösterin.

Vektör Arama için aşağıdaki yöntem tanımında, en yakın 10 vektörü belirlemek için find_neighbors yönteminin çağrıldığını unutmayın.

def vector_search(content) -> list:
  result = text_embedding(content)
  #call_vector_search_api(content)
  index_endpoint = aiplatform.MatchingEngineIndexEndpoint('projects/273845608377/locations/us-central1/indexEndpoints/2021628049526620160')
  # run query
  response = index_endpoint.find_neighbors(
      deployed_index_id = DEPLOYED_INDEX_ID,
      queries = [result],
      num_neighbors = 10
  )
  out = []
  # show the results
  for idx, neighbor in enumerate(response[0]):
      print(f"{neighbor.distance:.2f} {spanner_read_data(neighbor.id)}")
      out.append(f"{spanner_read_data(neighbor.id)}")
  return out

Ayrıca, spanner_read_data yöntemine yapılan çağrıyı da fark edeceksiniz. Şimdi bu konuyu bir sonraki adımda inceleyelim.

  1. Son adımdan döndürülen en yakın komşu vektörlerin kimliklerine karşılık gelen resimleri ayıklamak için generate_sql yöntemini çağıran Spanner okuma verisi uygulamasını tanımlayın.
!pip install google-cloud-spanner==3.36.0


from google.cloud import spanner


instance_id = "spanner-vertex"
database_id = "spanner-vertex-embeddings"
projectId = PROJECT_ID
client = spanner.Client()
client.project = projectId
instance = client.instance(instance_id)
database = instance.database(database_id)
def spanner_read_data(id):
    query = "SELECT uri FROM apparels where id = " + id
    outputs = []
    with database.snapshot() as snapshot:
        results = snapshot.execute_sql(query)


        for row in results:
            #print(row)
            #output = "ID: {}, CONTENT: {}, URI: {}".format(*row)
            output = "{}".format(*row)
            outputs.append(output)


    return "\n".join(outputs)

Seçilen vektörlere karşılık gelen resimlerin URL'lerini döndürmelidir.

  1. Son olarak, parçaları kullanıcı arayüzünde bir araya getirip Vektör Arama sürecini tetikleyelim.
from PIL import Image


def call_search(query):
  response = vector_search(query)
  return response


input_text = gr.Textbox(label="Enter your query. Examples: Girls Tops White Casual, Green t-shirt girls, jeans shorts, denim skirt etc.")
output_texts = [gr.Image(label="") for i in range(10)]
demo = gr.Interface(fn=call_search, inputs=input_text, outputs=output_texts, live=True)
resp = demo.launch(share = True)

Sonucu aşağıda gösterildiği gibi görürsünüz:

8093b39fbab1a9cc.png

Resim: Bağlantı

Sonuç videosunu buradan görüntüleyebilirsiniz.

7. Temizleme

Bu yayında kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız şu adımları uygulayın:

  1. Google Cloud konsolunda Kaynakları yönetin sayfasına gidin.
  2. Proje listesinden, silmek istediğiniz projeyi seçin ve Sil'i tıklayın.
  3. İletişim kutusuna proje kimliğini yazın ve projeyi silmek için Kapat'ı tıklayın.
  4. Projeyi silmek istemiyorsanız bu proje için yeni oluşturduğunuz örneğe giderek Spanner örneğini silin ve örneğe genel bakış sayfasının sağ üst köşesindeki ÖRNEĞİ SİL düğmesini tıklayın.
  5. Ayrıca, Vector Search dizinine gidebilir, uç noktanın ve dizinin dağıtımını kaldırabilir ve dizini silebilirsiniz.

8. Sonuç

Tebrikler! Spanner - Vertex Vektör Arama uygulamasını ilk kez kullanarak

  1. Spanner veritabanından alınan uygulamalar için Spanner veri kaynağı ve yerleştirmeler oluşturma.
  2. Vector Search veritabanı dizini oluşturuluyor.
  3. Dataflow ve İş Akışı işlerini kullanarak Spanner'dan Vektör Arama'ya vektör verilerini entegre etme.
  4. Dizin, bir uç noktaya dağıtılıyor.
  5. Son olarak, Vertex AI SDK'nın Python destekli uygulamasında kullanıcı girişi üzerinde Vektör Arama işlevi çağrılıyor.

İsterseniz uygulamayı kendi kullanım alanınızı da kapsayacak şekilde genişletebilir veya mevcut kullanım alanını yeni özelliklerle geliştirebilirsiniz. Spanner'ın makine öğrenimi özellikleri hakkında daha fazla bilgiyi buradan edinebilirsiniz.