1. Wprowadzenie
Spanner to w pełni zarządzana, globalnie rozproszona usługa bazy danych, którą można skalować w poziomie. Świetnie sprawdza się w przypadku zarówno relacyjnych, jak i nierelacyjnych zadań operacyjnych.
Spanner ma wbudowane wsparcie dla wyszukiwania wektorowego, które umożliwia wykonywanie wyszukiwania semantycznego lub opartego na podobieństwie oraz wdrażanie generowania rozszerzonego przez wyszukiwanie w aplikacjach generacji następnej generacji na dużą skalę, wykorzystując funkcje dokładnego wyszukiwania najbliższych sąsiadów (KNN) lub przybliżonego wyszukiwania najbliższych sąsiadów (ANN).
Zapytania dotyczące wyszukiwania wektorów w Spanner zwracają aktualne dane w czasie rzeczywistym, gdy tylko transakcje zostaną zatwierdzone, tak jak każde inne zapytanie dotyczące danych operacyjnych.
W tym module skonfigurujesz podstawowe funkcje wymagane do korzystania z Spannera do przeprowadzania wyszukiwania wektorów oraz uzyskasz dostęp do modeli dystrybucyjnych i modeli LLM z bazy modeli Vertex AI za pomocą języka SQL.
Architektura wyglądałaby tak:
Na tej podstawie dowiesz się, jak utworzyć indeks wektorowy oparty na algorytmie ScaNN i jak używać funkcji odległości APPROX, gdy trzeba skalować obciążenia semantyczne.
Co utworzysz
W ramach tego laboratorium wykonasz te czynności:
- Tworzenie instancji usługi Spanner
- Konfigurowanie schematu bazy danych usługi Spanner w celu integracji z modelami uczenia maszynowego i modelami LLM w Vertex AI
- Wczytywanie zbioru danych o handlu detalicznym
- Przesyłanie zapytań o wyszukiwanie podobnych elementów do zbioru danych
- Przekaż modelowi LLM kontekst, aby generować rekomendacje dotyczące konkretnych produktów.
- Zmodyfikuj schemat i utwórz indeks wektorowy.
- Zmień zapytania, aby korzystać z nowo utworzonego indeksu wektorowego.
Czego się nauczysz
- Konfigurowanie instancji usługi Spanner
- Jak przeprowadzić integrację z Vertex AI
- Jak za pomocą usługi Spanner przeprowadzić wyszukiwanie wektorów w celu znalezienia podobnych produktów w zbiorze danych handlu detalicznego
- Jak przygotować bazę danych do skalowania zadań wyszukiwania wektorów za pomocą wyszukiwania w sieci neuronowej.
Czego potrzebujesz
2. Konfiguracja i wymagania
Utwórz projekt
Jeśli nie masz jeszcze konta Google (Gmail lub Google Apps), utwórz je. Zaloguj się w konsoli Google Cloud Platform ( console.cloud.google.com) i utwórz nowy projekt.
Jeśli masz już projekt, w lewym górnym rogu konsoli kliknij menu wyboru projektu:
i kliknij przycisk „NOWY PROJEKT” w wyświetlonym oknie, aby utworzyć nowy projekt:
Jeśli nie masz jeszcze projektu, wyświetli się okno podobne do tego:
W kolejnych oknach tworzenia projektu możesz podać szczegóły nowego projektu:
Zapamiętaj identyfikator projektu, który jest unikalną nazwą we wszystkich projektach Google Cloud (podane powyżej imię i nazwisko jest już zajęte i nie będzie działać). W dalszej części tego ćwiczenia będzie on nazywany IDENTYFIKATOR_PROJEKTU.
Następnie, jeśli jeszcze tego nie zrobiono, musisz włączyć płatności w Konsoli programistów, aby korzystać z zasobów Google Cloud, oraz włączyć interfejs Spanner API.
Przeprowadzenie tego ćwiczenia nie powinno kosztować więcej niż kilka dolarów, ale może okazać się droższe, jeśli zdecydujesz się wykorzystać więcej zasobów lub pozostawisz je uruchomione (patrz sekcja „Wyczyszczanie” na końcu tego dokumentu). Ceny usługi Google Cloud Spanner znajdziesz tutaj.
Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD, dzięki czemu ten warsztat będzie całkowicie bezpłatny.
Konfiguracja Google Cloud Shell
Google Cloud i Spanner można obsługiwać zdalnie z laptopa, ale w tym ćwiczeniu będziemy używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.
Ta maszyna wirtualna oparta na Debianie zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie poprawia wydajność sieci i uwierzytelnianie. Oznacza to, że do tego ćwiczenia będziesz potrzebować tylko przeglądarki (tak, działa to na Chromebooku).
- Aby aktywować Cloud Shell w konsoli Cloud, kliknij Aktywuj Cloud Shell
(udostępnienie środowiska i połączenie z nim powinno zająć tylko kilka chwil).
Po połączeniu z Cloud Shell powinieneś zobaczyć, że jesteś już uwierzytelniony i że projekt ma już ustawiony identyfikator PROJECT_ID.
gcloud auth list
Wynik polecenia
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
Wynik polecenia
[core]
project = <PROJECT_ID>
Jeśli z jakiegoś powodu projekt nie jest ustawiony, po prostu uruchom to polecenie:
gcloud config set project <PROJECT_ID>
Szukasz urządzenia PROJECT_ID
? Sprawdź, jakiego identyfikatora użyto w procesie konfiguracji, lub odszukaj go w panelu Cloud Console:
Cloud Shell domyślnie ustawia też niektóre zmienne środowiskowe, co może być przydatne podczas wykonywania kolejnych poleceń.
echo $GOOGLE_CLOUD_PROJECT
Wynik polecenia
<PROJECT_ID>
Włączanie interfejsu Spanner API
gcloud services enable spanner.googleapis.com
Podsumowanie
Na tym etapie skonfigurowałeś projekt, jeśli jeszcze go nie miałeś, aktywował Cloud Shell i włączył wymagane interfejsy API.
Następny krok
Następnie skonfiguruj instancję i bazę danych Spanner.
3. Tworzenie instancji i bazy danych usługi Spanner
Tworzenie instancji usługi Spanner
Na tym etapie skonfigurujemy instancję usługi Spanner na potrzeby tego ćwiczenia. Aby to zrobić, otwórz Cloud Shell i uruchom to polecenie:
export SPANNER_INSTANCE_ID=retail-demo
gcloud spanner instances create $SPANNER_INSTANCE_ID \
--config=regional-us-central1 \
--description="spanner AI retail demo" \
--nodes=1
Dane wyjściowe polecenia:
$ gcloud spanner instances create $SPANNER_INSTANCE_ID \
--config=regional-us-central1 \
--description="spanner AI retail demo" \
--nodes=1
Creating instance...done.
Tworzenie bazy danych
Po uruchomieniu instancji możesz utworzyć bazę danych. Spanner umożliwia tworzenie wielu baz danych w ramach jednej instancji.
W bazie danych definiujesz schemat. Możesz też kontrolować, kto ma dostęp do bazy danych, skonfigurować szyfrowanie niestandardowe, skonfigurować optymalizator i ustawić okres przechowywania.
Aby utworzyć bazę danych, ponownie użyj narzędzia wiersza poleceń gcloud:
export SPANNER_DATABASE=cymbal-bikes
gcloud spanner databases create $SPANNER_DATABASE \
--instance=$SPANNER_INSTANCE_ID
Dane wyjściowe polecenia:
$ gcloud spanner databases create $SPANNER_DATABASE \
--instance=$SPANNER_INSTANCE_ID
Creating database...done.
Podsumowanie
W tym kroku utworzysz instancję i bazę danych Spanner.
Następny krok
Następnie skonfiguruj schemat i dane usługi Spanner.
4. Wczytywanie schematu i danych Cymbal
Tworzenie schematu talerza
Aby skonfigurować schemat, otwórz Spanner Studio:
Schemat składa się z 2 części. Najpierw dodaj tabelę products
. Skopiuj i wklej to stwierdzenie na pustej karcie.
W przypadku schematu skopiuj i wklej ten DDL do pola:
CREATE TABLE products (
categoryId INT64 NOT NULL,
productId INT64 NOT NULL,
productName STRING(MAX) NOT NULL,
productDescription STRING(MAX) NOT NULL,
productDescriptionEmbedding ARRAY<FLOAT32>,
createTime TIMESTAMP NOT NULL OPTIONS (
allow_commit_timestamp = true
),
inventoryCount INT64 NOT NULL,
priceInCents INT64,
) PRIMARY KEY(categoryId, productId);
Następnie kliknij przycisk run
i poczekaj kilka sekund na utworzenie schematu.
Następnie utworzysz 2 modele i skonfigurujesz je w punktach końcowych modeli Vertex AI.
Pierwszy model to model uczenia głębokiego, który służy do generowania wektorów z tekstu, a drugi to model LLM, który służy do generowania odpowiedzi na podstawie danych w usłudze Spanner.
Wklej ten schemat na nowej karcie w Spanner Studio:
CREATE MODEL EmbeddingsModel INPUT(
content STRING(MAX),
) OUTPUT(
embeddings STRUCT<statistics STRUCT<truncated BOOL, token_count FLOAT32>, values ARRAY<FLOAT32>>,
) REMOTE OPTIONS (
endpoint = '//aiplatform.googleapis.com/projects/<PROJECT_ID>/locations/us-central1/publishers/google/models/text-embedding-004'
);
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/gemini-pro',
default_batch_size = 1
);
Następnie kliknij przycisk run
i poczekaj kilka sekund na utworzenie modeli.
W panelu lewym w Spanner Studio powinny się wyświetlać te tabele i modele:
Wczytywanie danych
Teraz możesz wstawić do bazy danych kilka produktów. Otwórz nową kartę w Spanner Studio, a potem skopiuj i wklej te instrukcje wstawiania:
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);
Aby wstawić dane, kliknij przycisk run
.
Podsumowanie
Na tym etapie utworzysz schemat i załadujesz do bazy danych cymbal-bikes
podstawowe dane.
Następny krok
Następnie zintegrujesz się z modelem wektorów dystrybucyjnych, aby generować wektory dystrybucyjne dla opisów produktów, a także przekształcać tekstowe żądania wyszukiwania w wektory dystrybucyjne, aby wyszukiwać odpowiednie produkty.
5. Praca z wektorami
Generowanie wektorów dystrybucyjnych na potrzeby opisów produktów
Aby wyszukiwanie podobnych produktów działało, musisz wygenerować wektory dystrybucyjne dla opisów produktów.
Dzięki EmbeddingsModel
utworzonemu w schemacie jest to proste UPDATE
zdanie 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;
Aby zaktualizować opisy produktów, kliknij przycisk run
.
Korzystanie z wyszukiwania wektorowego
W tym przykładzie użyjesz zapytania SQL, aby przesłać zapytanie w języku naturalnym. To zapytanie przekształci żądanie wyszukiwania w wektor dystrybucyjny, a potem wyszuka podobne wyniki na podstawie przechowywanych wektorów dystrybucyjnych z opisów produktów wygenerowanych w poprzednim kroku.
-- 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;
Aby znaleźć podobne produkty, kliknij przycisk run
. Wyniki powinny wyglądać tak:
Zwróć uwagę, że w zapytaniu użyto dodatkowych filtrów, np. że interesują Cię tylko produkty dostępne w magazynie (inventoryCount > 0
).
Podsumowanie
Na tym etapie utworzyłeś wektory opisu produktu i wektor żądania wyszukiwania za pomocą kodu SQL, korzystając z integracji Spannera z modelami w Vertex AI. Przeprowadzono też wyszukiwanie wektorowe w celu znalezienia podobnych produktów pasujących do zapytania.
Następne kroki
Następnie użyjemy wyników wyszukiwania, aby przesłać je do modelu LLM i wygenerować niestandardową odpowiedź dla każdego produktu.
6. Praca z modelem LLM
Spanner ułatwia integrację z modelami LLM udostępnianymi przez Vertex AI. Dzięki temu deweloperzy mogą używać języka SQL do bezpośredniej komunikacji z usługami LLM, zamiast wymagać od aplikacji wykonywania logiki.
Mamy na przykład wyniki poprzedniego zapytania SQL użytkownika "I'd like to buy a starter bike for my 3 year old child".
.
Deweloperzy chcą podać odpowiedź na pytanie, czy dana usługa jest odpowiednia dla użytkownika, w przypadku każdego wyniku, korzystając z tego prompta:
"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"
Oto zapytanie, którego możesz użyć:
-- 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)
);
Aby wysłać zapytanie, kliknij przycisk run
. Wyniki powinny wyglądać tak:
Pierwszy produkt jest odpowiedni dla 3-latka, ponieważ w opisie produktu podano przedział wiekowy 2–4 lata. Inne produkty nie są odpowiednie.
Podsumowanie
W tym kroku pracowałeś/pracowałaś z modelem LLM, aby generować podstawowe odpowiedzi na prompty od użytkownika.
Następne kroki
Następnie dowiemy się, jak używać sieci neuronowych do skalowania wyszukiwania wektorowego.
7. Skalowanie wyszukiwania wektorowego
W poprzednich przykładach wyszukiwania wektorów korzystaliśmy z wyszukiwania wektorów z dokładnym KNN. Jest to przydatne, gdy chcesz wykonywać zapytania dotyczące bardzo konkretnych podzbiorów danych w Spanner. Zapytania tego typu są określane jako zapytania o wysokiej partycjonowalności.
Jeśli nie masz zadań, które można łatwo podzielić na partycje, a masz dużą ilość danych, użyj wyszukiwania wektorów w sieci neuronowej, korzystając z algorytmu ScaNN, aby zwiększyć wydajność wyszukiwania.
Aby to zrobić w Spanner, musisz wykonać 2 czynności:
- Tworzenie indeksu wektorowego
- Zmodyfikuj zapytanie, aby używać funkcji odległości APPROX.
Tworzenie indeksu wektorowego
Aby utworzyć indeks wektorów w tym zbiorze danych, musisz najpierw zmodyfikować kolumnę productDescriptionEmbeddings
, aby zdefiniować długość każdego wektora. Aby dodać długość wektora do kolumny, musisz usunąć oryginalną kolumnę i utworzyć ją ponownie.
ALTER TABLE `products` DROP COLUMN `productDescriptionEmbedding`;
ALTER TABLE
`products` ADD COLUMN `productDescriptionEmbedding` ARRAY<FLOAT32>(vector_length=>768);
Następnie utwórz ponownie osadzone dane z wykorzystaniem kroku Generate Vector embedding
, który został już wcześniej wykonany.
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;
Po utworzeniu kolumny utwórz indeks:
CREATE VECTOR INDEX ProductDescriptionEmbeddingIndex
ON products(productDescriptionEmbedding)
WHERE productDescriptionEmbedding IS NOT NULL
OPTIONS (
distance_type = 'COSINE'
);
Korzystanie z nowego indeksu
Aby korzystać z nowego indeksu wektorowego, musisz nieznacznie zmodyfikować poprzednie zapytanie dotyczące uczenia się.
Oto pierwotne zapytanie:
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;
Musisz wprowadzić te zmiany:
- Użyj podpowiedzi indeksu dla nowego indeksu wektorowego:
@{force_index=ProductDescriptionEmbeddingIndex}
- Zmień wywołanie funkcji
COSINE_DISTANCE
naAPPROX_COSINE_DISTANCE
. Pamiętaj, że opcje JSON w ostatnim zapytaniu poniżej są też wymagane. - Wygeneruj wektory za pomocą funkcji ML.PREDICT osobno.
- Skopiuj wyniki zagęszczenia do ostatecznego zapytania.
Generowanie wektorów
-- Generate the prompt embeddings
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)
)
)
Zaznacz wyniki zapytania i skopiuj je.
Następnie w tym zapytaniu zastąp <VECTOR>
wklejając skopiowane przez siebie uczenia.
-- Embedding query now using the vector index
SELECT productName, productDescription, inventoryCount,
APPROX_COSINE_DISTANCE(productDescriptionEmbedding, array<float32>[@VECTOR], options => JSON '{\"num_leaves_to_search\": 10}')
FROM products @{force_index=ProductDescriptionEmbeddingIndex}
WHERE productDescriptionEmbedding IS NOT NULL AND inventoryCount > 0
ORDER BY distance
LIMIT 5;
Powinna wyglądać mniej więcej tak:
Podsumowanie
W tym kroku przekonwertowałeś schemat na indeks wektorowy. Następnie przepisałeś zapytanie dotyczące wektorów dystrybucyjnych, aby wykonać wyszukiwanie w sieci neuronowej za pomocą indeksu wektorowego. Jest to ważny krok, ponieważ wraz ze wzrostem ilości danych możesz skalować zbiory zadań wyszukiwania wektorów.
Następne kroki
Teraz nadszedł czas na porządki.
8. Czyszczenie (opcjonalne)
Aby usunąć zasobów, otwórz w Cloud Console sekcję Cloud Spanner i usuń instancję 'retail-demo
' utworzoną w ramach tego ćwiczenia.
9. Gratulacje!
Gratulacje! Udało Ci się przeprowadzić wyszukiwanie podobieństw za pomocą wbudowanej wyszukiwarki wektorowej usługi Spanner. Zobaczysz też, jak łatwo można pracować z modelami wektorów dystrybucyjnych i modelami LLM, aby bezpośrednio za pomocą języka SQL udostępniać funkcje generatywnej AI.
Na koniec poznasz proces wykonywania wyszukiwania w sieci neuronowej z użyciem algorytmu ScaNN, który pozwala zwiększać wydajność zadań związanych z wyszukiwaniem wektorowym.
Co dalej?
Więcej informacji o funkcji dokładnego najbliższego sąsiada (wyszukiwanie wektorowe KNN) w usłudze Spanner znajdziesz tutaj: https://cloud.google.com/spanner/docs/find-k-nearest-neighbors
Więcej informacji o funkcji przybliżonego sąsiada (wyszukiwanie wektorowe ANN) w usłudze Spanner znajdziesz tutaj: https://cloud.google.com/spanner/docs/find-approximate-nearest-neighbors
Więcej informacji o wykonaniu prognoz online za pomocą SQL przy użyciu integracji VertexAI w Spanner znajdziesz tutaj: https://cloud.google.com/spanner/docs/ml