Multimodale Daten mit SQL und Python analysieren

In dieser Anleitung erfahren Sie, wie Sie multimodale Daten mit SQL-Abfragen und benutzerdefinierten Python-Funktionen (UDFs) analysieren.

In dieser Anleitung wird der Produktkatalog aus dem öffentlichen Dataset des Cymbal-Zoofachgeschäfts verwendet.

Lernziele

  • Verwenden Sie ObjectRef-Werte, um Bilddaten zusammen mit strukturierten Daten in einer BigQuery-Standardtabelle zu speichern.
  • Mit der AI.GENERATE_TABLE-Funktion können Sie Text basierend auf Bilddaten aus einer Standardtabelle generieren.
  • Mit einem Python-UDF vorhandene Bilder in neue Bilder umwandeln
  • Mithilfe eines Python-UDF können Sie PDFs in kleinere Teile für die weitere Analyse aufteilen.
  • Verwenden Sie ein Gemini-Modell und die ML.GENERATE_TEXT-Funktion, um die gechunkten PDF-Daten zu analysieren.
  • Mit der ML.GENERATE_EMBEDDING-Funktion können Sie Einbettungen basierend auf Bilddaten aus einer Standardtabelle generieren.
  • Verarbeiten Sie geordnete multimodale Daten mit Arrays von ObjectRef-Werten.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

  • BigQuery: you incur costs for the data that you process in BigQuery.
  • BigQuery Python UDFs: you incur costs for using Python UDFs.
  • Cloud Storage: you incur costs for the objects stored in Cloud Storage.
  • Vertex AI: you incur costs for calls to Vertex AI models.

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Weitere Informationen finden Sie auf den folgenden Preisseiten:

Hinweise

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery, BigQuery Connection, Cloud Storage, and Vertex AI APIs.

    Enable the APIs

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Ausführen dieser Anleitung benötigen:

Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Einrichten

In diesem Abschnitt erstellen Sie das Dataset, die Verbindung, die Tabellen und die Modelle, die in dieser Anleitung verwendet werden.

Dataset erstellen

Erstellen Sie ein BigQuery-Dataset, das die Objekte enthält, die Sie in dieser Anleitung erstellen:

  1. Rufen Sie in der Google Cloud Console die Seite BigQuery auf.

    BigQuery aufrufen

  2. Wählen Sie im Bereich Explorer Ihr Projekt aus.

  3. Maximieren Sie die Option Aktionen und klicken Sie auf Dataset erstellen. Der Bereich Dataset erstellen wird geöffnet.

  4. Geben Sie als Dataset-ID den String cymbal_pets ein.

  5. Klicken Sie auf Dataset erstellen.

Bucket erstellen

Erstellen Sie einen Cloud Storage-Bucket zum Speichern der umgewandelten Objekte:

  1. Rufen Sie die Seite Buckets auf.

    Buckets aufrufen

  2. Klicken Sie auf Erstellen.

  3. Geben Sie auf der Seite Bucket erstellen im Bereich Einstieg einen global eindeutigen Namen ein, der den Anforderungen für Bucket-Namen entspricht.

  4. Klicken Sie auf Erstellen.

Verbindung herstellen

Erstellen Sie eine Cloud-Ressourcenverbindung und rufen Sie das Dienstkonto der Verbindung ab. BigQuery verwendet die Verbindung, um auf Objekte in Cloud Storage zuzugreifen:

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Klicken Sie im Bereich Explorer auf Daten hinzufügen.

    Das Dialogfeld Daten hinzufügen wird geöffnet.

  3. Wählen Sie im Bereich Nach im Abschnitt Datenquellentyp die Option Geschäftsanwendungen aus.

    Alternativ können Sie im Feld Nach Datenquellen suchen den Wert Vertex AI eingeben.

  4. Klicken Sie im Bereich Empfohlene Datenquellen auf Vertex AI.

  5. Klicken Sie auf die Lösungskarte Vertex AI-Modelle: BigQuery-Verknüpfung.

  6. Wählen Sie in der Liste Verbindungstyp die Option Vertex AI-Remote-Modelle, Remote-Funktionen und BigLake (Cloud-Ressource) aus.

  7. Geben Sie im Feld Verbindungs-ID cymbal_conn ein.

  8. Klicken Sie auf Verbindung erstellen.

  9. Klicken Sie auf Zur Verbindung.

  10. Kopieren Sie im Bereich Verbindungsinformationen die Dienstkonto-ID zur Verwendung in einem folgenden Schritt.

Dem Dienstkonto der Verbindung Berechtigungen gewähren

Weisen Sie dem Dienstkonto der Verbindung die entsprechenden Rollen für den Zugriff auf andere Dienste zu. Sie müssen diese Rollen in demselben Projekt gewähren, das Sie im Abschnitt Vorbereitung erstellt oder ausgewählt haben. Die Zuweisung der Rollen in einem anderen Projekt führt zu dem Fehler bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource.

Berechtigungen für den Cloud Storage-Bucket gewähren

Gewähren Sie dem Dienstkonto Zugriff auf die Objekte im von Ihnen erstellten Bucket:

  1. Rufen Sie die Seite Buckets auf.

    Buckets aufrufen

  2. Klicken Sie auf den Namen des von Ihnen erstellten Buckets.

  3. Klicken Sie auf Berechtigungen.

  4. Klicken Sie auf Zugriff erlauben. Das Dialogfeld Zugriff erlauben wird geöffnet.

  5. Geben Sie im Feld Neue Hauptkonten die Dienstkonto-ID ein, die Sie zuvor kopiert haben.

  6. Wählen Sie im Feld Rolle auswählen die Option Cloud Storage und dann Storage Object User aus.

  7. Klicken Sie auf Speichern.

Berechtigungen zur Verwendung von Vertex AI-Modellen erteilen

Gewähren Sie dem Dienstkonto Zugriff auf die Verwendung von Vertex AI-Modellen:

  1. Zur Seite IAM & Verwaltung.

    IAM & Verwaltung aufrufen

  2. Klicken Sie auf Zugriff erlauben. Das Dialogfeld Zugriff erlauben wird geöffnet.

  3. Geben Sie im Feld Neue Hauptkonten die Dienstkonto-ID ein, die Sie zuvor kopiert haben.

  4. Wählen Sie im Feld Rolle auswählen die Option Vertex AI und dann Vertex AI-Nutzer aus.

  5. Klicken Sie auf Speichern.

Tabellen mit Beispieldaten erstellen

Erstellen Sie Tabellen zum Speichern der Produktinformationen von Cymbal Pets.

Tabelle products erstellen

Erstellen Sie eine Standardtabelle mit den Produktinformationen von Cymbal Pets:

  1. Rufen Sie in der Google Cloud Console die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Abfrageeditor die folgende Abfrage aus, um die Tabelle products zu erstellen:

    LOAD DATA OVERWRITE cymbal_pets.products
    FROM
      FILES(
        format = 'avro',
        uris = [
          'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);

Tabelle product_images erstellen

Erstellen Sie eine Objekttabelle mit den Produktbildern von Cymbal Pets:

  • Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle product_images zu erstellen:

    CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_images
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/*.png'],
        max_staleness = INTERVAL 30 MINUTE,
        metadata_cache_mode = AUTOMATIC);

Tabelle product_manuals erstellen

Erstellen Sie eine Objekttabelle mit den Produkthandbüchern von Cymbal Pets:

  • Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle product_manuals zu erstellen:

    CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_manuals
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf']);

Textgenerierungsmodell erstellen

BigQuery ML-Remote-Modell erstellen, das ein Vertex AI Gemini-Modell darstellt:

  • Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um das Remote-Modell zu erstellen:

    CREATE OR REPLACE MODEL `cymbal_pets.gemini`
      REMOTE WITH CONNECTION `us.cymbal_conn`
      OPTIONS (ENDPOINT = 'gemini-2.0-flash');

Modell für die Generierung von Einbettungen erstellen

Erstellen Sie ein BigQuery ML-Remote-Modell, das ein multimodales Vertex AI-Embedding-Modell darstellt:

  • Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um das Remote-Modell zu erstellen:

    CREATE OR REPLACE MODEL `cymbal_pets.embedding_model`
      REMOTE WITH CONNECTION `us.cymbal_conn`
      OPTIONS (ENDPOINT = 'multimodalembedding@001');

products_mm-Tabelle mit multimodalen Daten erstellen

Erstellen Sie eine products_mm-Tabelle mit einer image-Spalte, die mit Produktbildern aus der Objekttabelle product_images ausgefüllt ist. Die erstellte Spalte image ist eine STRUCT-Spalte mit dem Format ObjectRef.

  1. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Tabelle products_mm zu erstellen und die Spalte image zu füllen:

    CREATE OR REPLACE TABLE cymbal_pets.products_mm
    AS
    SELECT products.* EXCEPT (uri), ot.ref AS image FROM cymbal_pets.products
    INNER JOIN cymbal_pets.product_images ot
    ON ot.uri = products.uri;
  2. Führen Sie auf der Seite BigQuery im Abfrageeditor die folgende Abfrage aus, um die Daten der Spalte image aufzurufen:

    SELECT product_name, image
    FROM cymbal_pets.products_mm`

    Die Ergebnisse sehen in etwa so aus:

    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | product_name                   | image.uri                            | image.version | image.authorizer              | image.details                                  |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    |  AquaClear Aquarium Background | gs://cloud-samples-data/bigquery/    | 1234567891011 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png",   |
    |                                | tutorials/cymbal-pets/images/        |               |                               | "md5_hash":"494f63b9b137975ff3e7a11b060edb1d", |
    |                                | aquaclear-aquarium-background.png    |               |                               | "size":1282805,"updated":1742492680017000}}    |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    |  AquaClear Aquarium            | gs://cloud-samples-data/bigquery/    | 2345678910112 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png",   |
    |  Gravel Vacuum                 | tutorials/cymbal-pets/images/        |               |                               | "md5_hash":"b7bfc2e2641a77a402a1937bcf0003fd", |
    |                                | aquaclear-aquarium-gravel-vacuum.png |               |                               | "size":820254,"updated":1742492682411000}}     |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | ...                            | ...                                  | ...           |                               | ...                                            |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    

Produktinformationen mit einem Gemini-Modell generieren

Verwenden Sie ein Gemini-Modell, um die folgenden Daten für die Produkte im Tiergeschäft zu generieren:

  • Fügen Sie der Tabelle products_mm die Spalte image_description hinzu.
  • Fülle die Spalten animal_type, search_keywords und subcategory der Tabelle products_mm aus.
  • Führen Sie eine Abfrage aus, die eine Beschreibung jeder Produktmarke und die Anzahl der Produkte dieser Marke zurückgibt. Die Markenbeschreibung wird durch die Analyse der Produktinformationen aller Produkte dieser Marke generiert, einschließlich Produktbilder.
  1. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Spalte image_description zu erstellen und zu befüllen:

    CREATE OR REPLACE TABLE cymbal_pets.products_mm
    AS
    SELECT
      product_id,
      product_name,
      brand,
      category,
      subcategory,
      animal_type,
      search_keywords,
      price,
      description,
      inventory_level,
      supplier_id,
      average_rating,
      image,
      image_description
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            ('Can you describe the following image?', OBJ.GET_ACCESS_URL(image, 'r')) AS prompt,
            *
          FROM
            cymbal_pets.products_mm
        ),
        STRUCT('image_description STRING' AS output_schema));
  2. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Spalten animal_type, search_keywords und subcategory mit generierten Daten zu aktualisieren:

    UPDATE cymbal_pets.products_mm p
    SET
      p.animal_type = s.animal_type,
      p.search_keywords = s.search_keywords,
      p.subcategory = s.subcategory
    FROM
      (
        SELECT
          animal_type,
          search_keywords,
          subcategory,
          uri
        FROM
          AI.GENERATE_TABLE(
            MODEL `cymbal_pets.gemini`,
            (
              SELECT
                (
                  'For the image of a pet product, concisely generate the following metadata.'
                    '1) animal_type and 2) 5 SEO search keywords, and 3) product subcategory',
                  OBJ.GET_ACCESS_URL(image, 'r'),
                  description) AS prompt,
                image.uri AS uri,
              FROM cymbal_pets.products_mm
            ),
            STRUCT(
              'animal_type STRING, search_keywords ARRAY<STRING>, subcategory STRING' AS output_schema,
              100 AS max_output_tokens))
      ) s
    WHERE p.image.uri = s.uri;
  3. Führen Sie auf der Seite BigQuery im Abfrageeditor die folgende Abfrage aus, um die generierten Daten aufzurufen:

    SELECT
      product_name,
      image_description,
      animal_type,
      search_keywords,
      subcategory,
    FROM cymbal_pets.products_mm;

    Die Ergebnisse sehen in etwa so aus:

    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    | product_name                   | image.description                   | animal_type | search_keywords        | subcategory      |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    |  AquaClear Aquarium Background | The image shows a colorful coral    | fish        | aquarium background    | aquarium decor   |
    |                                | reef backdrop. The background is a  |             | fish tank backdrop     |                  |
    |                                | blue ocean with a bright light...   |             | coral reef decor       |                  |
    |                                |                                     |             | underwater scenery     |                  |
    |                                |                                     |             | aquarium decoration    |                  |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    |  AquaClear Aquarium            | The image shows a long, clear       | fish        | aquarium gravel vacuum | aquarium         |
    |  Gravel Vacuum                 | plastic tube with a green hose      |             | aquarium cleaning      | cleaning         |
    |                                | attached to one end. The tube...    |             | aquarium maintenance   |                  |
    |                                |                                     |             | fish tank cleaning     |                  |
    |                                |                                     |             | gravel siphon          |                  |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    | ...                            | ...                                 | ...         |  ...                   | ...              |
    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    
  4. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um eine Beschreibung jeder Produktmarke und eine Zählung der Anzahl der Produkte dieser Marke zu generieren:

    SELECT
      brand,
      brand_description,
      cnt
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            brand,
            COUNT(*) AS cnt,
            (
              'Use the images and text to give one concise brand description for a website brand page.'
                'Return the description only.',
              ARRAY_AGG(OBJ.GET_ACCESS_URL(image, 'r')),
              ARRAY_AGG(description),
              ARRAY_AGG(category),
              ARRAY_AGG(subcategory)) AS prompt
          FROM cymbal_pets.products_mm
          GROUP BY brand
        ),
        STRUCT('brand_description STRING' AS output_schema))
    ORDER BY cnt DESC;

    Die Ergebnisse sehen in etwa so aus:

    +--------------+-------------------------------------+-----+
    | brand        | brand.description                   | cnt |
    +--------------+-------------------------------------+-----+
    |  AquaClear   | AquaClear is a brand of aquarium    | 33  |
    |              | and pond care products that offer   |     |
    |              | a wide range of solutions for...    |     |
    +--------------+-------------------------------------+-----+
    |  Ocean       | Ocean Bites is a brand of cat food  | 28  |
    |  Bites       | that offers a variety of recipes    |     |
    |              | and formulas to meet the specific.. |     |
    +--------------+-------------------------------------+-----+
    |  ...         | ...                                 |...  |
    +--------------+-------------------------------------+-----+
    

Python-UDF zum Transformieren von Produktbildern erstellen

Erstellen Sie eine Python-UDF, um Produktbilder in Graustufen umzuwandeln.

Die Python-UDF verwendet Open-Source-Bibliotheken und die parallele Ausführung , um mehrere Bilder gleichzeitig zu transformieren.

  1. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die benutzerdefinierte Funktion to_grayscale zu erstellen:

    CREATE OR REPLACE FUNCTION cymbal_pets.to_grayscale(src_json STRING, dst_json STRING)
    RETURNS STRING
    LANGUAGE python
    WITH CONNECTION `us.cymbal_conn`
    OPTIONS (entry_point='to_grayscale', runtime_version='python-3.11', packages=['numpy', 'opencv-python'])
    AS """
    
    import cv2 as cv
    import numpy as np
    from urllib.request import urlopen, Request
    import json
    
    # Transform the image to grayscale.
    def to_grayscale(src_ref, dst_ref):
      src_json = json.loads(src_ref)
      srcUrl = src_json["access_urls"]["read_url"]
    
      dst_json = json.loads(dst_ref)
      dstUrl = dst_json["access_urls"]["write_url"]
    
      req = urlopen(srcUrl)
      arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
      img = cv.imdecode(arr, -1) # 'Load it as it is'
    
      # Convert the image to grayscale
      gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    
      # Send POST request to the URL
      _, img_encoded = cv.imencode('.png', gray_image)
    
      req = Request(url=dstUrl, data=img_encoded.tobytes(), method='PUT', headers = {
          "Content-Type": "image/png",
      })
      with urlopen(req) as f:
          pass
      return dst_ref
    """;

Produktbilder optimieren

Erstelle die Tabelle products_grayscale mit einer Spalte ObjectRef, die die Zielpfade und Autorisierungen für Graustufenbilder enthält. Der Zielpfad wird aus dem Pfad des Originalbilds abgeleitet.

Nachdem Sie die Tabelle erstellt haben, führen Sie die Funktion to_grayscale aus, um die Graustufenbilder zu erstellen, sie in einen Cloud Storage-Bucket zu schreiben und dann ObjectRefRuntime-Werte mit Zugriffs-URLs und Metadaten für die Graustufenbilder zurückzugeben.

  1. Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle products_grayscale zu erstellen:

    CREATE OR REPLACE TABLE cymbal_pets.products_grayscale
    AS
    SELECT
      product_id,
      product_name,
      image,
      OBJ.MAKE_REF(
        CONCAT('gs://BUCKET/cymbal-pets-images/grayscale/', REGEXP_EXTRACT(image.uri, r'([^/]+)$')),
        'us.cymbal_conn') AS gray_image
    FROM cymbal_pets.products_mm;

    Ersetzen Sie BUCKET durch den Namen des von Ihnen erstellten Buckets.

  2. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Graustufenbilder zu erstellen, in einen Cloud Storage-Bucket zu schreiben und dann ObjectRefRuntime-Werte mit Zugriffs-URLs und Metadaten für die Graustufenbilder zurückzugeben:

    SELECT cymbal_pets.to_grayscale(
      TO_JSON_STRING(OBJ.GET_ACCESS_URL(image, 'r')),
      TO_JSON_STRING(OBJ.GET_ACCESS_URL(gray_image, 'rw')))
    FROM cymbal_pets.products_grayscale;

    Die Ergebnisse sehen in etwa so aus:

    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | f0                                                                                                                                                                    |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z",                                                                                                                 |
    | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_read URL_information",       |
    | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write URL_information"},   |
    | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images/grayscale/ocean-bites-salmon-&-tuna-cat-food.png"}}                |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z",                                                                                                                 |
    | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png?additional _read URL_information",             |
    | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write_URL_information"},   |
    | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png"}}                 |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |  ...                                                                                                                                                                  |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    

Python-UDF zum Aufteilen von PDF-Daten erstellen

Erstellen Sie eine Python-UDF, um die PDF-Objekte mit den Produkthandbüchern von Cymbal Pets in mehrere Teile aufzuteilen.

PDFs sind oft sehr groß und passen möglicherweise nicht in einen einzelnen Aufruf eines generativen KI-Modells. Wenn Sie die PDFs in kleinere Teile aufteilen, können Sie die PDF-Daten in einem für die Modellierung geeigneten Format speichern, um sie leichter analysieren zu können.

  1. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die benutzerdefinierte Funktion chunk_pdf zu erstellen:

    -- This function chunks the product manual PDF into multiple parts.
    -- The function accepts an ObjectRefRuntime value for the PDF file and the chunk size.
    -- It then parses the PDF, chunks the contents, and returns an array of chunked text.
    CREATE OR REPLACE FUNCTION cymbal_pets.chunk_pdf(src_json STRING, chunk_size INT64, overlap_size INT64)
    RETURNS ARRAY<STRING>
    LANGUAGE python
    WITH CONNECTION `us.cymbal_conn`
    OPTIONS (entry_point='chunk_pdf', runtime_version='python-3.11', packages=['pypdf'])
    AS """
    import io
    import json
    
    from pypdf import PdfReader  # type: ignore
    from urllib.request import urlopen, Request
    
    def chunk_pdf(src_ref: str, chunk_size: int, overlap_size: int) -> str:
      src_json = json.loads(src_ref)
      srcUrl = src_json["access_urls"]["read_url"]
    
      req = urlopen(srcUrl)
      pdf_file = io.BytesIO(bytearray(req.read()))
      reader = PdfReader(pdf_file, strict=False)
    
      # extract and chunk text simultaneously
      all_text_chunks = []
      curr_chunk = ""
      for page in reader.pages:
          page_text = page.extract_text()
          if page_text:
              curr_chunk += page_text
              # split the accumulated text into chunks of a specific size with overlaop
              # this loop implements a sliding window approach to create chunks
              while len(curr_chunk) >= chunk_size:
                  split_idx = curr_chunk.rfind(" ", 0, chunk_size)
                  if split_idx == -1:
                      split_idx = chunk_size
                  actual_chunk = curr_chunk[:split_idx]
                  all_text_chunks.append(actual_chunk)
                  overlap = curr_chunk[split_idx + 1 : split_idx + 1 + overlap_size]
                  curr_chunk = overlap + curr_chunk[split_idx + 1 + overlap_size :]
      if curr_chunk:
          all_text_chunks.append(curr_chunk)
    
      return all_text_chunks
    """;

PDF-Daten analysieren

Führen Sie die Funktion chunk_pdf aus, um die PDF-Daten in der Tabelle product_manuals in kleinere Teile zu zerlegen, und erstellen Sie dann eine product_manual_chunk_strings-Tabelle mit einem PDF-Chunk pro Zeile. Verwenden Sie ein Gemini-Modell auf den product_manual_chunk_strings-Daten, um die rechtlichen Hinweise in den Produkthandbüchern zusammenzufassen.

  1. Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle product_manual_chunk_strings zu erstellen:

    CREATE OR REPLACE TABLE cymbal_pets.product_manual_chunk_strings
    AS
    SELECT chunked
    FROM cymbal_pets.product_manuals,
    UNNEST (cymbal_pets.chunk_pdf(
      TO_JSON_STRING(
        OBJ.GET_ACCESS_URL(OBJ.MAKE_REF(uri, 'us.cymbal_conn'), 'r')),
        1000,
        100
    )) as chunked;
  2. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die PDF-Daten mit einem Gemini-Modell zu analysieren:

    SELECT
      ml_generate_text_llm_result
    FROM
      ML.GENERATE_TEXT(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you summarize the product manual as bullet points? Highlight the legal clauses',
              chunked) AS prompt,
          FROM cymbal_pets.product_manual_chunk_strings
        ),
        STRUCT(
          TRUE AS FLATTEN_JSON_OUTPUT));

    Die Ergebnisse sehen in etwa so aus:

    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ml_generate_text_llm_result                                                                                                               |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ## CritterCuisine Pro 5000 Automatic Pet Feeder Manual Summary:                                                                           |
    |                                                                                                                                           |
    | **Safety:**                                                                                                                               |
    |                                                                                                                                           |
    | * **Stability:** Place feeder on a level, stable surface to prevent tipping.                                                              |
    | * **Power Supply:** Only use the included AC adapter. Using an incompatible adapter can damage the unit and void the warranty.            |
    | * **Cord Safety:** Keep the power cord out of reach of pets to prevent chewing or entanglement.                                           |
    | * **Children:** Supervise children around the feeder. This is not a toy.                                                                  |
    | * **Pet Health:** Consult your veterinarian before using an automatic feeder if your pet has special dietary needs, health conditions, or |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ## Product Manual Summary:                                                                                                                |
    |                                                                                                                                           |
    | **6.3 Manual Feeding:**                                                                                                                   |
    |                                                                                                                                           |
    | * Press MANUAL button to dispense a single portion (Meal 1 size). **(Meal Enabled)**                                                      |
    |                                                                                                                                           |
    | **6.4 Recording a Voice Message:**                                                                                                        |
    |                                                                                                                                           |
    | * Press and hold VOICE button.                                                                                                            |
    | * Speak clearly into the microphone (up to 10 seconds).                                                                                   |
    | * Release VOICE button to finish recording.                                                                                               |
    | * Briefly press VOICE button to play back the recording.                                                                                  |
    | * To disable the voice message, record a blank message (hold VOICE button for 10 seconds without speaking). **(Meal Enabled)**            |
    |                                                                                                                                           |
    | **6.5 Low Food Level Indicator:**                                                                                                         |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ...                                                                                                                                       |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    

Generieren Sie Einbettungen aus Bilddaten und verwenden Sie die Einbettungen dann, um mithilfe der Vektorsuche ähnliche Bilder zurückzugeben.

In einem Produktionsszenario empfehlen wir, vor der Durchführung einer Vektorsuche einen Vektorindex zu erstellen. Mit einem Vektorindex können Sie die Vektorsuche schneller ausführen. Der Nachteil ist, dass die Trefferquote reduziert wird und Sie so ungefähre Ergebnisse erhalten.

  1. Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle products_embeddings zu erstellen:

    CREATE OR REPLACE TABLE cymbal_pets.products_embedding
    AS
    SELECT product_id, ml_generate_embedding_result as embedding, content as image
    FROM ML.GENERATE_EMBEDDING(
    MODEL `cymbal_pets.embedding_model`,
      (
        SELECT OBJ.GET_ACCESS_URL(image, 'r') as content, image, product_id
        FROM cymbal_pets.products_mm
      ),
      STRUCT ()
    );
  2. Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um eine Vektorsuche auszuführen und Produktbilder zurückzugeben, die dem angegebenen Eingabebild ähneln:

    SELECT *
    FROM
    VECTOR_SEARCH(
      TABLE cymbal_pets.products_embedding,
      'embedding',
      (SELECT ml_generate_embedding_result as embedding FROM ML.GENERATE_EMBEDDING(
        MODEL `cymbal_pets.embedding_model`,
        (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/cozy-naps-cat-scratching-post-with-condo.png', 'us.cymbal_conn')) as content)
      ))
    );

    Die Ergebnisse sehen in etwa so aus:

    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | query.embedding | base.product_id | base.embedding | base.image.uri                               | base.image.version | base.image.authorizer         | base.image.details                             | distance       |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | -0.0112330541   | 181             | -0.0112330541  | gs://cloud-samples-data/bigquery/            | 12345678910        | myproject.region.myconnection | {"gcs_metadata":{"content_type":               | 0.0            |
    | 0.0142525584    |                 |  0.0142525584  | tutorials/cymbal-pets/images/                |                    |                               | "image/png","md5_hash":"21234567hst16555w60j", |                |
    | 0.0135886827    |                 |  0.0135886827  | cozy-naps-cat-scratching-post-with-condo.png |                    |                               | "size":828318,"updated":1742492688982000}}     |                |
    | 0.0149955815    |                 |  0.0149955815  |                                              |                    |                               |                                                |                |
    | ...             |                 |  ...           |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | -0.0112330541   | 187             | -0.0190353896  | gs://cloud-samples-data/bigquery/            | 23456789101        | myproject.region.myconnection | {"gcs_metadata":{"content_type":               | 0.4216330832.. |
    | 0.0142525584    |                 |  0.0116206668  | tutorials/cymbal-pets/images/                |                    |                               | "image/png","md5_hash":"7328728fhakd9937djo4", |                |
    | 0.0135886827    |                 |  0.0136198215  | cozy-naps-cat-scratching-post-with-bed.png   |                    |                               | "size":860113,"updated":1742492688774000}}     |                |
    | 0.0149955815    |                 |  0.0173457414  |                                              |                    |                               |                                                |                |
    | ...             |                 |  ...           |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    |                 |                 |                |                                              |                    |                               |                                                |                |
    +---------C--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | ...             | ...             | ...            | ...                                          | ...                | ...                           | ...                                            | ...            |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    

Sortierte multimodale Daten mit Arrays von ObjectRef-Werten verarbeiten

In diesem Abschnitt werden die folgenden Aufgaben erläutert:

  1. Erstellen Sie die Tabelle product_manuals neu, sodass sie sowohl eine PDF-Datei für das Crittercuisine 5000-Produkthandbuch als auch PDF-Dateien für jede Seite dieses Handbuchs enthält.
  2. Erstellen Sie eine Tabelle, in der die einzelnen Abschnitte des Handbuchs zugeordnet sind. Der Wert ObjectRef, der das vollständige Handbuch darstellt, wird in einer Spalte vom Typ STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>> gespeichert. Die ObjectRef-Werte, die die manuellen Seiten darstellen, werden in einer ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>-Spalte gespeichert.
  3. Analysieren Sie ein Array von ObjectRef-Werten, um einen einzelnen generierten Wert zurückzugeben.
  4. Ein Array von ObjectRef-Werten wird einzeln analysiert und für jeden Arraywert wird ein generierter Wert zurückgegeben.

Im Rahmen der Analyseaufgaben wandeln Sie das Array der ObjectRef-Werte in eine sortierte Liste von ObjectRefRuntime-Werten um und übergeben diese Liste dann an ein Gemini-Modell. Dabei geben Sie die ObjectRefRuntime-Werte als Teil des Prompts an. Die ObjectRefRuntime-Werte enthalten signierte URLs, über die das Modell auf die Objektinformationen in Cloud Storage zugreift.

So verarbeiten Sie sortierte multimodale Daten mit Arrays von ObjectRef-Werten:

  1. Rufen Sie die Seite BigQuery auf.

    BigQuery aufrufen

  2. Führen Sie im Abfrageeditor die folgende Abfrage aus, um die Tabelle product_manuals neu zu erstellen:

    CREATE OR REPLACE EXTERNAL TABLE `cymbal_pets.product_manuals`
      WITH CONNECTION `us.cymbal_conn`
      OPTIONS (
        object_metadata = 'SIMPLE',
        uris = [
            'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf',
            'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/document_chunks/*.pdf']);
  3. Führen Sie im Abfrageeditor die folgende Abfrage aus, um PDF-Daten in die Tabelle map_manual_to_chunks zu schreiben:

    -- Extract the file and chunks into a single table.
    -- Store the chunks in the chunks column as array of ObjectRefs (ordered by page number)
    CREATE OR REPLACE TABLE cymbal_pets.map_manual_to_chunks
    AS
    SELECT ARRAY_AGG(m1.ref)[0] manual, ARRAY_AGG(m2.ref ORDER BY m2.ref.uri) chunks
    FROM cymbal_pets.product_manuals m1
    JOIN cymbal_pets.product_manuals m2
      ON
        REGEXP_EXTRACT(m1.uri, r'.*/([^.]*).[^/]+')
        = REGEXP_EXTRACT(m2.uri, r'.*/([^.]*)_page[0-9]+.[^/]+')
    GROUP BY m1.uri;
  4. Führen Sie im Abfrageeditor die folgende Abfrage aus, um die PDF-Daten in der Tabelle map_manual_to_chunks aufzurufen:

    SELECT *
    FROM cymbal_pets.map_manual_to_chunks;

    Die Ergebnisse sehen in etwa so aus:

    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    | manual.uri                          | manual.version                 | manual.authorizer                 | manual.details                                       | chunks.uri                                | chunks.version                  | chunks.authorizer                  | chunks.details                                        |
    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    | gs://cloud-samples-data/bigquery/   | 1742492785900455               | myproject.region.myconnection     | {"gcs_metadata":{"content_type":"application/pef",   | gs://cloud-samples-data/bigquery/         | 1745875761227129                | myproject.region.myconnection      | {"gcs_metadata":{"content_type":"application/pdf",    |
    | tutorials/cymbal-pets/documents/    |                                |                                   | "md5_hash":"c9032b037693d15a33210d638c763d0e",       | tutorials/cymbal-pets/documents/          |                                 |                                    | "md5_hash":"5a1116cce4978ec1b094d8e8b49a1d7c",        |
    | crittercuisine_5000_user_manual.pdf |                                |                                   | "size":566105,"updated":1742492785941000}}           | crittercuisine_5000_user_manual_page1.pdf |                                 |                                    | "size":504583,"updated":1745875761266000}}            |
    |                                     |                                |                                   |                                                      +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    |                                     |                                |                                   |                                                      | crittercuisine_5000_user_manual_page1.pdf | 1745875760613874                | myproject.region.myconnection      | {"gcs_metadata":{"content_type":"application/pdf",    |
    |                                     |                                |                                   |                                                      | tutorials/cymbal-pets/documents/          |                                 |                                    | "md5_hash":"94d03ec65d28b173bc87eac7e587b325",        |
    |                                     |                                |                                   |                                                      | crittercuisine_5000_user_manual_page2.pdf |                                 |                                    | "size":94622,"updated":1745875760649000}}             |
    |                                     |                                |                                   |                                                      +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    |                                     |                                |                                   |                                                      | ...                                       | ...                             |  ...                               | ...                                                   |
    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    
  5. Führen Sie im Abfrageeditor die folgende Abfrage aus, um eine einzelne Antwort aus einem Gemini-Modell zu generieren, die auf der Analyse eines Arrays von ObjectRef-Werten basiert:

    WITH
      manuals AS (
        SELECT
          OBJ.GET_ACCESS_URL(manual, 'r') AS manual,
          ARRAY(
            SELECT OBJ.GET_ACCESS_URL(chunk, 'r') AS chunk
            FROM UNNEST(m1.chunks) AS chunk WITH OFFSET AS idx
            ORDER BY idx
          ) AS chunks
        FROM cymbal_pets.map_manual_to_chunks AS m1
      )
    SELECT ml_generate_text_llm_result AS Response
    FROM
      ML.GENERATE_TEXT(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order',
              manuals.chunks) AS prompt,
          FROM manuals
        ),
        STRUCT(TRUE AS FLATTEN_JSON_OUTPUT));

    Die Ergebnisse sehen in etwa so aus:

    +-------------------------------------------+
    | Response                                  |
    +-------------------------------------------+
    | Page 1: This manual is for the            |
    | CritterCuisine Pro 5000 automatic         |
    | pet feeder.                               |
    | Page 2: The manual covers safety          |
    | precautions, what's included,             |
    | and product overview.                     |
    | Page 3: The manual covers assembly,       |
    | initial setup, and programming the clock. |
    +-------------------------------------------+
    
  6. Führen Sie im Abfrageeditor die folgende Abfrage aus, um mehrere Antworten aus einem Gemini-Modell zu generieren, die auf der Analyse eines Arrays von ObjectRef-Werten basieren:

    WITH
      input_chunked_objrefs AS (
        SELECT row_id, offset, chunk_ref
        FROM
          (
            SELECT ROW_NUMBER() OVER () AS row_id, * FROM `cymbal_pets.map_manual_to_chunks`
          ) AS indexed_table
        LEFT JOIN
          UNNEST(indexed_table.chunks) AS chunk_ref
          WITH OFFSET
      ),
      get_access_urls AS (
        SELECT row_id, offset, chunk_ref, OBJ.GET_ACCESS_URL(chunk_ref, 'r') AS ObjectRefRuntime
        FROM input_chunked_objrefs
      ),
      valid_get_access_urls AS (
        SELECT *
        FROM get_access_urls
        WHERE ObjectRefRuntime['runtime_errors'] IS NULL
      ),
      ordered_output_objrefruntime_array AS (
        SELECT ARRAY_AGG(ObjectRefRuntime ORDER BY offset) AS ObjectRefRuntimeArray
        FROM valid_get_access_urls
        GROUP BY row_id
      )
    SELECT
      page1_summary,
      page2_summary,
      page3_summary
    FROM
      AI.GENERATE_TABLE(
        MODEL `cymbal_pets.gemini`,
        (
          SELECT
            (
              'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order',
              ObjectRefRuntimeArray) AS prompt,
          FROM ordered_output_objrefruntime_array
        ),
        STRUCT(
          'page1_summary STRING, page2_summary STRING, page3_summary STRING' AS output_schema));

    Die Ergebnisse sehen in etwa so aus:

    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    | page1_summary                                 | page2_summary                             | page3_summary                                      |
    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    | This manual provides an overview of the       | This section explains how to program      | This page covers connecting the feeder to Wi-Fi    |
    | CritterCuisine Pro 5000 automatic pet feeder, | the feeder's clock, set feeding           | using the CritterCuisine Connect app,  remote      |
    | including its features, safety precautions,   | schedules, copy and delete meal settings, | feeding, managing feeding schedules, viewing       |
    | assembly instructions, and initial setup.     | manually feed your pet, record            | feeding logs, receiving low food alerts,           |
    |                                               | a voice message, and understand           | updating firmware, creating multiple pet profiles, |
    |                                               | the low food level indicator.             | sharing access with other users, and cleaning      |
    |                                               |                                           | and maintaining the feeder.                        |
    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    

Bereinigen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.