Milion wektorów, zero pętli: generowanie wektorów dystrybucyjnych na dużą skalę za pomocą AlloyDB

1. Przegląd

W tym ćwiczeniu utworzysz skalowalną aplikację do wyszukiwania w bazie wiedzy. Zamiast zarządzać złożoną potokiem ETL z użyciem skryptów i pętli w Pythonie do generowania wektorów dystrybucyjnych, możesz użyć AlloyDB AI do obsługi generowania wektorów dystrybucyjnych natywnie w bazie danych za pomocą jednego polecenia SQL.

d4324260c68d4a70.png

Co utworzysz

Wydajna aplikacja bazy danych „z możliwością wyszukiwania” bazy wiedzy.

Czego się nauczysz

Zapoznasz się z tymi zagadnieniami:

  • Aprowizuj klaster AlloyDB i włącz rozszerzenia AI.
  • Generowanie danych syntetycznych (ponad 50 tys. wierszy) za pomocą SQL.
  • Wypełnij wektory dystrybucyjne dla całego zbioru danych za pomocą przetwarzania wsadowego.
  • Skonfiguruj aktywatory przyrostowe w czasie rzeczywistym, aby automatycznie osadzać nowe dane.
  • Wykonywanie wyszukiwania hybrydowego (wektorowego + filtrów SQL) dla hasła „Flexing Context”.

Wymagania

  • przeglądarka, np. Chrome lub Firefox;
  • Projekt Google Cloud z włączonymi płatnościami.
  • Podstawowa znajomość SQL.

2. Zanim zaczniesz

Utwórz projekt

  1. W konsoli Google Cloud na stronie selektora projektów wybierz lub utwórz projekt Google Cloud.
  2. Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie włączone są płatności.
  1. Będziesz używać Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud. U góry konsoli Google Cloud kliknij Aktywuj Cloud Shell.

Obraz przycisku aktywacji Cloud Shell

  1. Po połączeniu z Cloud Shell sprawdź, czy jesteś już uwierzytelniony i czy projekt jest ustawiony na Twój identyfikator projektu, używając tego polecenia:
gcloud auth list
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
  1. Jeśli projekt nie jest ustawiony, użyj tego polecenia, aby go ustawić:
gcloud config set project <YOUR_PROJECT_ID>
  1. Włącz wymagane interfejsy API: kliknij link i włącz interfejsy API.

Możesz też użyć polecenia gcloud. Informacje o poleceniach gcloud i ich użyciu znajdziesz w dokumentacji.

gcloud services enable \
  alloydb.googleapis.com \
  compute.googleapis.com \
  cloudresourcemanager.googleapis.com \
  servicenetworking.googleapis.com \
  aiplatform.googleapis.com

Pułapki i rozwiązywanie problemów

Syndrom „projektu widma”

Uruchomiono polecenie gcloud config set project, ale w interfejsie konsoli wyświetlany jest inny projekt. Sprawdź identyfikator projektu w menu w lewym górnym rogu.

Bariera rozliczeniowa

Projekt został włączony, ale zapomniano o koncie rozliczeniowym. AlloyDB to wydajny mechanizm, który nie uruchomi się, jeśli „zbiornik paliwa” (płatności) jest pusty.

Opóźnienie propagacji interfejsu API

Kliknięto „Włącz interfejsy API”, ale w wierszu poleceń nadal widnieje symbol Service Not Enabled. Odczekaj 60 sekund. Chmura potrzebuje chwili, aby aktywować swoje neurony.

Limit Quags

Jeśli korzystasz z nowego konta próbnego, możesz osiągnąć regionalny limit instancji AlloyDB. Jeśli us-central1 się nie powiedzie, spróbuj us-east1.

„Ukryty” agent usługi

Czasami agentowi usługi AlloyDB nie jest automatycznie przyznawana rola aiplatform.user. Jeśli zapytania SQL nie będą później mogły komunikować się z Gemini, zwykle jest to przyczyną problemu.

3. Konfiguracja bazy danych

W tym module użyjemy AlloyDB jako bazy danych do przechowywania danych testowych. Używa klastrów do przechowywania wszystkich zasobów, takich jak bazy danych i logi. Każdy klaster ma instancję podstawową, która zapewnia punkt dostępu do danych. Tabele będą zawierać rzeczywiste dane.

Utwórzmy klaster, instancję i tabelę AlloyDB, do których zostanie załadowany testowy zbiór danych.

  1. Kliknij przycisk lub skopiuj poniższy link do przeglądarki, w której zalogowany jest użytkownik konsoli Google Cloud.

  1. Po wykonaniu tego kroku repozytorium zostanie sklonowane do lokalnego edytora Cloud Shell i będziesz mieć możliwość uruchomienia poniższego polecenia z folderu projektu (ważne jest, aby upewnić się, że jesteś w katalogu projektu):
sh run.sh
  1. Teraz użyj interfejsu (kliknij link w terminalu lub link „Podgląd w internecie” w terminalu).
  2. Aby rozpocząć, wpisz szczegóły identyfikatora projektu, klastra i nazw instancji.
  3. Idź po kawę, podczas gdy dzienniki będą się przewijać. Tutaj możesz przeczytać, jak to działa w tle. Może to potrwać około 10–15 minut.

Pułapki i rozwiązywanie problemów

Problem z „cierpliwością”

Klastry baz danych to rozbudowana infrastruktura. Jeśli odświeżysz stronę lub zakończysz sesję Cloud Shell, ponieważ „utknęła”, możesz skończyć z „duchem” instancji, która jest częściowo udostępniona i niemożliwa do usunięcia bez ręcznej interwencji.

Niezgodny region

Jeśli interfejsy API zostały włączone w regionie us-central1, ale klaster jest wdrażany w regionie asia-south1, mogą wystąpić problemy z limitami lub opóźnienia w przypisywaniu uprawnień do konta usługi. W całym module trzymaj się jednego regionu.

Zombie Clusters

Jeśli nazwa klastra była już wcześniej używana i nie została usunięta, skrypt może wyświetlić komunikat, że nazwa klastra już istnieje. Nazwy klastrów muszą być unikalne w projekcie.

Limit czasu Cloud Shell

Jeśli przerwa na kawę trwa 30 minut, Cloud Shell może przejść w stan uśpienia i odłączyć proces sh run.sh. Pozostaw kartę aktywną.

4. Obsługa administracyjna schematu

W tym kroku omówimy te kwestie:

879263c907f3cac6.png

Gdy klaster i instancja AlloyDB będą działać, przejdź do edytora SQL w AlloyDB Studio, aby włączyć rozszerzenia AI i udostępnić schemat.

1e3ac974b18a8113.png

Może być konieczne poczekanie na zakończenie tworzenia instancji. Gdy to zrobisz, zaloguj się w AlloyDB przy użyciu danych logowania utworzonych podczas tworzenia klastra. Do uwierzytelniania w PostgreSQL użyj tych danych:

  • Nazwa użytkownika: „postgres
  • Baza danych: „postgres
  • Hasło: „alloydb” (lub inne hasło ustawione podczas tworzenia)

Po pomyślnym uwierzytelnieniu w AlloyDB Studio polecenia SQL są wpisywane w Edytorze. Możesz dodać wiele okien Edytora, klikając znak plusa po prawej stronie ostatniego okna.

28cb9a8b6aa0789f.png

Polecenia dla AlloyDB będziesz wpisywać w oknach edytora, używając w razie potrzeby opcji Uruchom, Formatuj i Wyczyść.

Włącz rozszerzenia

Do utworzenia tej aplikacji użyjemy rozszerzeń pgvectorgoogle_ml_integration. Rozszerzenie pgvector umożliwia przechowywanie wektorów dystrybucyjnych i wyszukiwanie ich. Rozszerzenie google_ml_integration udostępnia funkcje, których możesz używać do uzyskiwania dostępu do punktów końcowych prognozowania Vertex AI w celu uzyskiwania prognoz w SQL. Włącz te rozszerzenia, uruchamiając te DDL:

CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;

Tworzenie tabeli

Aby zademonstrować skalę, potrzebujemy zbioru danych. Zamiast importować plik CSV, wygenerujemy natychmiast 50 tys. wierszy syntetycznych „Artykułów pomocy” za pomocą SQL.

Tabelę możesz utworzyć za pomocą instrukcji DDL poniżej w AlloyDB Studio:

-- 1. Create the table
CREATE TABLE help_articles (
    id SERIAL PRIMARY KEY,
    title TEXT,
    category TEXT,
    product_version TEXT,
    content_body TEXT,
    embedding vector(768) -- Dimension for text-embedding-005
);

-- 2. Generate 50,000 rows of synthetic data
INSERT INTO help_articles (title, category, product_version, content_body)
SELECT
    'Help Article ' || i,
    CASE 
        WHEN i % 3 = 0 THEN 'Billing' 
        WHEN i % 3 = 1 THEN 'Technical' 
        ELSE 'General' 
    END,
    CASE 
        WHEN i % 2 = 0 THEN '2.0' 
        ELSE '1.0' 
    END,
    'This article covers common issues regarding ' || 
    CASE 
        WHEN i % 3 = 0 THEN 'payment failures, invoice disputes, and credit card updates.'
        WHEN i % 3 = 1 THEN 'connection timeouts, latency issues, and API errors.'
        ELSE 'account profile settings, password resets, and user roles.' 
    END
FROM generate_series(1, 50000) AS i;

Kolumna item_vector będzie przechowywać wartości wektorowe tekstu.

Sprawdź dane:

SELECT count(*) FROM help_articles;
-- Output: 50000

Włączanie flag bazy danych

Otwórz konsolę konfiguracji instancji, kliknij „Edytuj podstawową”, przejdź do konfiguracji zaawansowanej i kliknij „Dodaj flagi bazy danych”.

  1. Sprawdź, czy flaga google_ml_integration.enable_model_support jest włączona:

Jeśli nie, wpisz go w menu flag i ustaw opcję „WŁĄCZ” oraz zaktualizuj instancję.

  1. Sprawdź, czy flaga google_ml_integration.enable_faster_embedding_generation jest włączona:

Jeśli nie, wpisz go w menu flag i ustaw opcję „WŁĄCZ” oraz zaktualizuj instancję.

Czynności konfigurowania flag bazy danych:

  1. W konsoli Google Cloud otwórz stronę Klastry.

Otwórz stronę Klastry

  1. W kolumnie Nazwa zasobu kliknij klaster.
  2. Na stronie Przegląd w sekcji Instancje w klastrze wybierz instancję, a następnie kliknij Edytuj.
  3. Dodawanie, modyfikowanie i usuwanie flagi bazy danych z instancji:

Dodawanie flagi

  1. Aby dodać do instancji flagę bazy danych, kliknij Dodaj flagę.
  2. Wybierz flagę z listy Nowa flaga bazy danych.
  3. Podaj wartość flagi.
  4. Kliknij Gotowe.
  5. Kliknij Zaktualizuj instancję.
  6. Sprawdź, czy rozszerzenie google_ml_integration ma wersję 1.5.2 lub nowszą:

Aby sprawdzić wersję rozszerzenia, użyj tego polecenia:

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

Jeśli chcesz uaktualnić rozszerzenie do wyższej wersji, użyj polecenia:

ALTER EXTENSION google_ml_integration UPDATE;

Przyznaj uprawnienia

  1. Aby umożliwić użytkownikowi zarządzanie generowaniem automatycznego osadzania, przyznaj mu uprawnienia INSERT, UPDATE i DELETE w tabelach google_ml.embed_gen_progressgoogle_ml.embed_gen_settings:
GRANT INSERT, UPDATE, DELETE ON google_ml.embed_gen_progress TO postgres;

„postgres” to USER_NAME, dla którego przyznano uprawnienia.

  1. Aby przyznać uprawnienia do wykonywania funkcji „embedding”, uruchom to polecenie:
GRANT EXECUTE ON FUNCTION embedding TO postgres;

Przyznawanie roli Użytkownik Vertex AI kontu usługi AlloyDB

W konsoli IAM Google Cloud przyznaj kontu usługi AlloyDB (które wygląda tak: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) dostęp do roli „Użytkownik Vertex AI”. Zmienna PROJECT_NUMBER będzie zawierać numer Twojego projektu.

Możesz też uruchomić to polecenie w terminalu Cloud Shell:

PROJECT_ID=$(gcloud config get-value project)


gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"

Pułapki i rozwiązywanie problemów

Pętla „amnezji hasła”

Jeśli używasz konfiguracji „Jedno kliknięcie” i nie pamiętasz hasła, otwórz stronę podstawowych informacji o instancji w konsoli i kliknij „Edytuj”, aby zresetować hasło postgres.

Błąd „Nie znaleziono rozszerzenia”

Jeśli CREATE EXTENSION się nie powiedzie, często dzieje się tak, ponieważ instancja jest nadal w stanie „Konserwacja” lub „Aktualizowanie” od czasu początkowego udostępnienia. Sprawdź, czy krok tworzenia instancji został zakończony, a w razie potrzeby poczekaj kilka sekund.

5. Generowanie wektorów „One-Shot”

To jest główna część modułu. Zamiast pisać pętli w Pythonie do przetworzenia tych 50 tys. wierszy, użyjemy funkcji ai.initialize_embeddings.

To pojedyncze polecenie wykonuje 2 działania:

  1. Wypełnia wszystkie istniejące wiersze.
  2. Tworzy aktywator, który automatycznie osadza przyszłe wiersze.

Uruchom poniższą instrukcję SQL w edytorze zapytań AlloyDB.

CALL ai.initialize_embeddings(
  model_id => 'text-embedding-005',
  table_name => 'help_articles',
  content_column => 'content_body',
  embedding_column => 'embedding',
  incremental_refresh_mode => 'transactional'
);

Sprawdzanie wektorów dystrybucyjnych

Sprawdź, czy kolumna embedding jest teraz wypełniona:

SELECT id, left(content_body, 30), substring(embedding::text, 1, 30) as vector_partial 
FROM help_articles;

Wynik powinien być podobny do tego poniżej:

a872b8926a164275.png

Co się właśnie stało?

  1. Wypełnianie wsteczne na dużą skalę: automatycznie przeszukuje istniejące 50 tys. wierszy i generuje osadzanie za pomocą Vertex AI.
  2. Automatyzacja: po ustawieniu incremental_refresh_mode => ‘transactional' AlloyDB automatycznie konfiguruje wewnętrzne reguły. Każdy nowy wiersz wstawiony do tabeli help_articles będzie miał natychmiast wygenerowane osadzenie.
  3. Opcjonalnie możesz ustawić incremental_refresh_mode => ‘None', aby otrzymywać tylko instrukcje do przeprowadzania aktualizacji zbiorczych i ręcznie wywoływać ai.refresh_embeddings() w celu aktualizowania osadzania wszystkich wierszy.

Zastąpiliśmy kolejkę Kafka, proces roboczy Pythona i skrypt migracji 6 wierszami kodu SQL. Szczegółową oficjalną dokumentację wszystkich atrybutów znajdziesz tutaj.

Test reguły działającej w czasie rzeczywistym

Sprawdźmy, czy automatyzacja „Zero Loop” działa w przypadku nowych danych.

  1. Wstawianie nowego wiersza:
INSERT INTO help_articles (title, category, product_version, content_body)
VALUES ('New Scaling Guide', 'Technical', '2.0', 'How to scale AlloyDB to millions of transactions.');
  1. Sprawdź od razu:
SELECT embedding FROM help_articles WHERE title = 'New Scaling Guide';

Wynik:

Wygenerowany wektor powinien być widoczny od razu, bez konieczności uruchamiania zewnętrznego skryptu.

Dostrajanie wielkości wsadu

Obecnie AlloyDB domyślnie ustawia rozmiar wsadu na 50. Ustawienia domyślne działają świetnie od razu po wyjęciu z pudełka, ale AlloyDB nadal daje użytkownikom możliwość dostosowania idealnej konfiguracji do ich unikalnego modelu i zbioru danych.

CALL ai.initialize_embeddings(
  model_id => 'text-embedding-005',
  table_name => 'help_articles',
  content_column => 'content_body',
  embedding_column => 'embedding',
  incremental_refresh_mode => 'transactional',
  batch_size => 20
);

Użytkownicy muszą jednak pamiętać o limitach, które mogą ograniczać wydajność. Zalecane limity AlloyDB znajdziesz w sekcji „Zanim zaczniesz” w dokumentacji.

Pułapki i rozwiązywanie problemów

Opóźnienie propagacji uprawnień

Uruchomiono polecenie gcloud IAM, ale polecenie SQL CALL nadal kończy się niepowodzeniem z powodu błędu uprawnień. Rozpowszechnienie zmian w IAM może trochę potrwać w sieci szkieletowej Google. Weź oddech.

Niezgodność wymiarów wektora

Tabela help_articles ma ustawioną wartość VECTOR(768) w kolumnie content_body. Jeśli później spróbujesz użyć innego modelu (np. 1536-wymiarowego), wstawki zostaną rozszerzone. Trzymaj się text-embedding-005.

6. Elastyczne wyszukiwanie kontekstowe

Teraz przeprowadzimy wyszukiwanie hybrydowe. Łączymy rozumienie semantyczne (wektory) z logiką biznesową (filtry SQL).

Uruchom to zapytanie, aby znaleźć problemy z płatnościami dotyczące konkretnie wersji 2.0 produktu:

SELECT
  title,
  left(content_body, 100) as content_snippet,
  1 - (embedding <=> embedding('text-embedding-005', 'Invoice did not go through')::vector) as relevance
FROM help_articles
WHERE category = 'Billing'  -- Hard SQL Filter
  AND product_version = '2.0' -- Hard SQL Filter
ORDER BY relevance DESC
LIMIT 5;

To jest kontekst elastyczny. Wyszukiwarka „dopasowuje się” do intencji użytkownika („problemy z płatnościami”), zachowując jednocześnie sztywne ograniczenia biznesowe (wersja 2.0).

f0fdb50d6195c462.png

Dlaczego ta strategia jest korzystna dla startupów i migracji

  1. Brak długu infrastrukturalnego: nie musisz uruchamiać osobnej bazy danych wektorów (Pinecone/Milvus). Nie napisano osobnego zadania ETL. Wszystko jest w Postgres.
  2. Aktualizacje w czasie rzeczywistym: w trybie „transakcyjnym” indeks wyszukiwania jest zawsze aktualny. Gdy dane zostaną zatwierdzone, są gotowe do przekształcenia w wektory.
  3. Skalowalność: AlloyDB jest oparta na infrastrukturze Google. Może on generować miliony wektorów szybciej niż skrypt w Pythonie.

Pułapki i rozwiązywanie problemów

Pułapka związana z wydajnością w środowisku produkcyjnym

Problem: szybkie przetwarzanie 50 000 wierszy. Bardzo wolne w przypadku 1 miliona wierszy , jeśli filtr kategorii nie jest wystarczająco selektywny.Rozwiązanie:dodaj indeks wektorów: w przypadku skali produkcyjnej musisz utworzyć indeks:CREATE INDEX ON help_articles USING hnsw (embedding vector_cosine_ops);Sprawdź użycie indeksu: uruchom EXPLAIN ANALYZE SELECT ..., aby upewnić się, że baza danych używa indeksu, a nie skanowania sekwencyjnego.

Katastrofa „Niezgodność modeli”

Problem: kolumna została zainicjowana za pomocą modelu text-embedding-005 w procedurze CALL. Jeśli w funkcji zapytania SELECT embedding('model-name', ...) przypadkowo użyjesz innego modelu (np. text-embedding-004 lub modelu OSS), wymiary mogą się zgadzać (768), ale przestrzeń wektorowa będzie zupełnie inna. Zapytanie zostanie wykonane bez błędów, ale wyniki będą całkowicie nieistotne (nieprawidłowe wyniki trafności). Rozwiązywanie problemów:upewnij się, że model_id w funkcji ai.initialize_embeddings dokładnie odpowiada model_id w zapytaniu SELECT.

Wynik „Silent Empty” (nadmierne filtrowanie)

Problem: wyszukiwanie hybrydowe to operacja „AND”. Wymaga to dopasowania semantycznegodopasowania SQL.Jeśli użytkownik wyszuka „Pomoc dotycząca płatności”, ale w kolumnie product_version zamiast ‘2.0' będzie ‘2.0.1', wynik będzie wynosić 0 wierszy, nawet jeśli dopasowanie wektorowe będzie wynosić 99%.Rozwiązywanie problemów:

  • Najpierw uruchom zapytanie bez sortowania wektorowego, aby sprawdzić, czy filtry SQL (WHERE category...) zwracają dane.
  • Sprawdź, czy rozróżniana jest wielkość liter (Billingbilling).

4. Błędy uprawnień lub limitów (błąd 500)

Problem:funkcja embedding() w klauzuli SELECT wykonuje w czasie rzeczywistym wywołanie sieciowe do Vertex AI.Jeśli konto usługi bazy danych utraci rolę Użytkownik Vertex AI lub jeśli przekroczysz limit interfejsu Vertex AI API (QPM), całe zapytanie SQL zakończy się niepowodzeniem.Rozwiązywanie problemów:

  • Sprawdź Cloud Logging dla AlloyDB.
  • Sprawdź, czy rola uprawnień jest nadal aktywna.
  • Jeśli potrzebujesz wysokiej odporności, umieść funkcję w bloku TRY/CATCH w procedurach składowanych.

5. Wektory dystrybucyjne o wartości null

Problem:jeśli wstawisz dane przed pełną inicjacją modelu lub jeśli proces w tle ulegnie awarii, niektóre wiersze mogą mieć wartość NULL w kolumnie embedding.NULL <=> Vector zwraca NULL. Te wiersze znikają z kolejności sortowania.Rozwiązywanie problemów:

  • Uruchom SELECT count(*) FROM help_articles WHERE embedding IS NULL;, aby sprawdzić, czy zasięg jest w 100% prawidłowy.

7. Czyszczenie danych

Po ukończeniu tego modułu nie zapomnij usunąć klastra i instancji AlloyDB.

Powinien on wyczyścić klaster wraz z instancjami.

8. Gratulacje

Udało Ci się utworzyć skalowalną aplikację do wyszukiwania w bazie wiedzy. Zamiast zarządzać złożonym potokiem ETL z użyciem skryptów i pętli w Pythonie do generowania wektorów dystrybucyjnych, używasz AlloyDB AI do obsługi generowania wektorów dystrybucyjnych natywnie w bazie danych za pomocą jednego polecenia SQL.

Omówione zagadnienia

  • Zrezygnowaliśmy z pętli „Python For-Loop” na potrzeby przetwarzania danych.
  • Wygenerowaliśmy 50 tys. wektorów za pomocą jednego polecenia SQL.
  • Zautomatyzowaliśmy generowanie przyszłych wektorów za pomocą aktywatorów.
  • Przeprowadziliśmy wyszukiwanie hybrydowe.

Następne kroki