ניתוח נתונים מרובי-אופנים באמצעות SQL ופונקציות מוגדרות על ידי המשתמש (UDF) ב-Python

במדריך הזה נסביר איך לנתח נתונים מרובי-אופנים באמצעות שאילתות SQL ופונקציות בהגדרת המשתמש (UDF) ב-Python.

במדריך הזה נעשה שימוש בקטלוג המוצרים ממערך הנתונים הציבורי של חנות חיות המחמד Cymbal.

מטרות

  • אפשר להשתמש בערכים של ObjectRef כדי לאחסן נתוני תמונות לצד נתונים מובנים בטבלה רגילה ב-BigQuery.
  • יצירת טקסט על סמך נתוני תמונה מטבלה רגילה באמצעות הפונקציה AI.GENERATE_TABLE.
  • אפשר להשתמש בפונקציית UDF של Python כדי לשנות תמונות קיימות וליצור תמונות חדשות.
  • אפשר לחלק קובצי PDF לחלקים קטנים יותר כדי לנתח אותם באמצעות פונקציה מוגדרת על ידי המשתמש (UDF) ב-Python.
  • משתמשים במודל Gemini ובפונקציה AI.GENERATE_TEXT כדי לנתח את נתוני ה-PDF בחלקים.
  • כדי ליצור הטמעות על סמך נתוני תמונות מטבלה רגילה, משתמשים בפונקציה AI.GENERATE_EMBEDDING.
  • עיבוד נתונים מולטימודליים מסודרים באמצעות מערכים של ערכי ObjectRef.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Cloud de Confiance by S3NS, והשימוש בהם כרוך בתשלום:

  • 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.

למידע נוסף, תוכלו לעיין בדפי התמחור הבאים:

לפני שמתחילים

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Cloud de Confiance project.

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

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות להשלמת המדריך הזה, אתם צריכים לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים:

  • יוצרים חיבור: אדמין של חיבור ל-BigQuery (roles/bigquery.connectionAdmin)
  • הענקת הרשאות לחשבון השירות של החיבור: אדמין IAM של פרויקט (roles/resourcemanager.projectIamAdmin)
  • יצירת קטגוריה של Cloud Storage: אדמין אחסון (roles/storage.admin)
  • יצירת מערכי נתונים, מודלים, פונקציות מוגדרות על ידי המשתמש (UDF) וטבלאות, והרצת משימות של BigQuery: BigQuery Admin (roles/bigquery.admin)
  • יצירת כתובות URL שמאפשרות לקרוא ולשנות אובייקטים ב-Cloud Storage: BigQuery ObjectRef Admin (roles/bigquery.objectRefAdmin)

להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

הגדרה

בקטע הזה יוצרים את מערך הנתונים, הקישור, הטבלאות והמודלים שמשמשים במדריך הזה.

יצירת מערך נתונים

יוצרים מערך נתונים ב-BigQuery שיכיל את האובייקטים שיוצרים במדריך הזה:

  1. במסוף Cloud de Confiance , עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על כלי הניתוחים:

    כפתור מודגש לחלונית הסייר.

    אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.

  3. בחלונית Explorer, בוחרים את הפרויקט.

  4. לוחצים על View actions (הצגת פעולות) ואז על Create dataset (יצירת מערך נתונים). תיפתח החלונית Create dataset.

  5. בשדה Dataset ID, מקלידים cymbal_pets.

  6. לוחצים על יצירת מערך נתונים.

יצירת קטגוריה

יוצרים קטגוריה של Cloud Storage לאחסון אובייקטים שעברו טרנספורמציה:

  1. עוברים לדף Buckets.

    כניסה לדף Buckets

  2. לוחצים על יצירה.

  3. בדף Create a bucket, בקטע Get started, מזינים שם ייחודי גלובלית שעומד בדרישות לשמות של קטגוריות.

  4. לוחצים על יצירה.

יצירת חיבור

יוצרים חיבור למשאב בענן ומקבלים את חשבון השירות של החיבור. ‫BigQuery משתמש בחיבור כדי לגשת לאובייקטים ב-Cloud Storage:

  1. עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בחלונית הימנית, לוחצים על כלי הניתוחים:

    כפתור מודגש לחלונית הסייר.

  3. בחלונית Explorer, לוחצים על Add data.

    תיבת הדו-שיח הוספת נתונים נפתחת.

  4. בחלונית Filter By, בקטע Data Source Type, בוחרים באפשרות Business Applications.

    אפשרות אחרת היא להזין Vertex AI בשדה חיפוש מקורות נתונים.

  5. בקטע מקורות נתונים מומלצים, לוחצים על Vertex AI.

  6. לוחצים על כרטיס הפתרון Vertex AI Models: BigQuery Federation.

  7. ברשימה Connection type בוחרים באפשרות Vertex AI remote models, remote functions, BigLake and Spanner (Cloud Resource).

  8. בשדה מזהה החיבור, מקלידים cymbal_conn.

  9. לוחצים על יצירת קישור.

  10. לוחצים על מעבר לחיבור.

  11. בחלונית Connection info (פרטי התחברות), מעתיקים את מזהה חשבון השירות לשימוש בשלב הבא.

מתן הרשאות לחשבון השירות של החיבור

מקצים לחשבון השירות של החיבור את התפקידים המתאימים כדי לגשת לשירותים אחרים. צריך להעניק את התפקידים האלה באותו פרויקט שיצרתם או בחרתם בקטע לפני שמתחילים. מתן תפקידים בפרויקט אחר יוביל לשגיאה bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.s3ns.iam.gserviceaccount.com does not have the permission to access resource.

מתן הרשאות בקטגוריית Cloud Storage

נותנים לחשבון השירות גישה לשימוש באובייקטים בקטגוריה שיצרתם:

  1. עוברים לדף Buckets.

    כניסה לדף Buckets

  2. לוחצים על שם הקטגוריה שיצרתם.

  3. לוחצים על הרשאות.

  4. לוחצים על Grant access. תיבת הדו-שיח Grant access נפתחת.

  5. בשדה New principals, מזינים את מזהה חשבון השירות שהעתקתם קודם.

  6. בשדה Select a role, בוחרים באפשרות Cloud Storage ואז באפשרות Storage Object User.

  7. לוחצים על Save.

הענקת הרשאות לשימוש במודלים של Vertex AI

מעניקים לחשבון השירות גישה לשימוש במודלים של Vertex AI:

  1. עוברים לדף IAM & Admin.

    כניסה לדף IAM & Admin

  2. לוחצים על Grant access. תיבת הדו-שיח Grant access נפתחת.

  3. בשדה New principals, מזינים את מזהה חשבון השירות שהעתקתם קודם.

  4. בשדה Select a role (בחירת תפקיד), בוחרים באפשרות Vertex AI ואז באפשרות Vertex AI User (משתמש Vertex AI).

  5. לוחצים על Save.

יצירת טבלאות של נתונים לדוגמה

יוצרים טבלאות לאחסון פרטי המוצר של חיות המחמד של Cymbal.

יצירת טבלת products

יוצרים טבלה רגילה שמכילה את פרטי המוצרים של Cymbal pets:

  1. במסוף Cloud de Confiance , עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור את הטבלה products:

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

יצירת טבלת product_images

יוצרים טבלת אובייקטים שמכילה את תמונות המוצרים של Cymbal pets:

  • בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה product_images:

    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);

יצירת טבלת product_manuals

יצירת טבלת אובייקטים שמכילה את מדריכי המוצרים של חיות המחמד Cymbal:

  • בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה product_manuals:

    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']);

יצירת מודל ליצירת טקסט

יוצרים מודל מרוחק של BigQuery ML שמייצג מודל Gemini של Vertex AI:

  • בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את המודל המרוחק:

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

יצירת מודל ליצירת הטמעה

יוצרים מודל מרוחק של BigQuery ML שמייצג מודל הטמעה מולטימודאלי של Vertex AI:

  • בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את המודל המרוחק:

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

יצירת טבלת products_mm עם נתונים מולטימודאליים

יוצרים טבלת products_mm שמכילה עמודה image עם תמונות מוצרים מטבלת האובייקטים product_images. העמודה image שנוצרת היא עמודה STRUCT שמשתמשת בפורמט ObjectRef.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה products_mm ולאכלס את העמודה image:

    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. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי להציג את נתוני העמודה image:

    SELECT product_name, image
    FROM cymbal_pets.products_mm

    התוצאות אמורות להיראות כך:

    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | 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}}     |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    | ...                            | ...                                  | ...           |                               | ...                                            |
    +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
    

יצירת מידע על מוצרים באמצעות מודל Gemini

תשתמש במודל Gemini כדי ליצור את הנתונים הבאים למוצרים בחנות חיות המחמד:

  • מוסיפים עמודה image_description לטבלה products_mm.
  • מאכלסים את העמודות animal_type,‏ search_keywords ו-subcategory בטבלה products_mm.
  • מריצים שאילתה שמחזירה תיאור של כל מותג מוצר וגם ספירה של מספר המוצרים מהמותג הזה. תיאור המותג נוצר על ידי ניתוח פרטי המוצרים של כל המוצרים מהמותג הזה, כולל תמונות המוצרים.
  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את העמודה image_description ולאכלס אותה:

    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. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי לעדכן את העמודות animal_type, search_keywords ו-subcategory בנתונים שנוצרו:

    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. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי לראות את הנתונים שנוצרו:

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

    התוצאות אמורות להיראות כך:

    +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
    | 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. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור תיאור של כל מותג מוצר וגם ספירה של מספר המוצרים מהמותג הזה:

    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;

    התוצאות אמורות להיראות כך:

    +--------------+-------------------------------------+-----+
    | 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.. |     |
    +--------------+-------------------------------------+-----+
    |  ...         | ...                                 |...  |
    +--------------+-------------------------------------+-----+
    

יצירת פונקציית UDF ב-Python כדי לשנות תמונות של מוצרים

יוצרים פונקציה מוגדרת על ידי המשתמש (UDF) ב-Python כדי להמיר תמונות של מוצרים לגווני אפור.

פונקציית ה-UDF של Python משתמשת בספריות קוד פתוח , וגם בהרצה מקבילה כדי לבצע טרנספורמציה של כמה תמונות בו-זמנית.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את פונקציית UDF‏ to_grayscale:

    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
    """;

שינוי תמונות מוצרים

יוצרים את הטבלה products_grayscale עם עמודה ObjectRef שמכילה את נתיבי היעד ואת ההרשאות לתמונות בגווני אפור. נתיב היעד נגזר מנתיב התמונה המקורי.

אחרי שיוצרים את הטבלה, מריצים את הפונקציה to_grayscale כדי ליצור את התמונות בגווני אפור, לכתוב אותן לקטגוריה של Cloud Storage ואז להחזיר ערכים של ObjectRefRuntime שמכילים כתובות URL לגישה ומטא-נתונים של התמונות בגווני אפור.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה products_grayscale:

    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;

    מחליפים את BUCKET בשם של הקטגוריה שיצרתם.

  2. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את התמונות בגווני אפור, לכתוב אותן לדלי ב-Cloud Storage ואז להחזיר ערכי ObjectRefRuntime שמכילים כתובות URL לגישה ומטא-נתונים של התמונות בגווני אפור:

    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;

    התוצאות אמורות להיראות כך:

    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | 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"}}                 |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |  ...                                                                                                                                                                  |
    +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    

יצירת פונקציית UDF ב-Python כדי לחלק נתונים מ-PDF

יוצרים פונקציית UDF ב-Python כדי לחלק את אובייקטי ה-PDF שמכילים את מדריכי המוצרים של חיות המחמד של Cymbal לכמה חלקים.

קובצי PDF הם לרוב גדולים מאוד, ויכול להיות שהם לא יתאימו לקריאה אחת של מודל AI גנרטיבי. פיצול קובצי ה-PDF מאפשר לכם לאחסן את נתוני ה-PDF בפורמט שמוכן לשימוש במודל, כדי שיהיה קל יותר לנתח אותם.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את פונקציית UDF‏ chunk_pdf:

    -- 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

מריצים את הפונקציה chunk_pdf כדי לחלק את נתוני ה-PDF בטבלה product_manuals, ואז יוצרים טבלה product_manual_chunk_strings שמכילה חלקי PDF בשורות. שימוש במודל Gemini בproduct_manual_chunk_stringsנתונים כדי לסכם את המידע המשפטי שמופיע במדריכי המוצרים.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה product_manual_chunk_strings:

    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. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי לנתח את נתוני ה-PDF באמצעות מודל Gemini:

    SELECT
      result
    FROM
      AI.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
        ));

    התוצאות אמורות להיראות כך:

    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | 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:**                                                                                                         |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    | ...                                                                                                                                       |
    +-------------------------------------------------------------------------------------------------------------------------------------------+
    

ליצור הטמעות מנתוני תמונות, ואז להשתמש בהטמעות כדי להחזיר תמונות דומות באמצעות חיפוש וקטורי.

בסביבת ייצור, מומלץ ליצור אינדקס וקטורי לפני שמריצים חיפוש וקטורי. אינדקס וקטורי מאפשר לבצע את החיפוש הווקטורי מהר יותר, אבל הוא מקטין את ההחזרה של תוצאות מדויקות ולכן מחזיר תוצאות משוערות יותר.

  1. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי ליצור את הטבלה products_embeddings:

    CREATE OR REPLACE TABLE cymbal_pets.products_embedding
    AS
    SELECT product_id, embedding, content as image
    FROM AI.GENERATE_EMBEDDING(
    MODEL `cymbal_pets.embedding_model`,
      (
        SELECT OBJ.GET_ACCESS_URL(image, 'r') as content, image, product_id
        FROM cymbal_pets.products_mm
      )
    );
  2. בעורך השאילתות בדף BigQuery, מריצים את השאילתה הבאה כדי להריץ חיפוש וקטורי ולהחזיר תמונות מוצרים שדומות לתמונת הקלט שצוינה:

    SELECT *
    FROM
    VECTOR_SEARCH(
      TABLE cymbal_pets.products_embedding,
      'embedding',
      (SELECT embedding FROM AI.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)
      ))
    );

    התוצאות אמורות להיראות כך:

    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | 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--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    | ...             | ...             | ...            | ...                                          | ...                | ...                           | ...                                            | ...            |
    +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
    

עיבוד נתונים מולטימודאליים מסודרים באמצעות מערכים של ערכי ObjectRef

בקטע הזה מוסבר איך לבצע את הפעולות הבאות:

  1. צריך ליצור מחדש את הטבלה product_manuals כך שתכיל קובץ PDF של מדריך המוצר Crittercuisine 5000 וקובצי PDF של כל דף במדריך הזה.
  2. צור טבלה שממפה את המדריך לחלקים שלו. הערך ObjectRef שמייצג את המדריך המלא מאוחסן בעמודה STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>. הערכים ObjectRef שמייצגים את דפי ההוראות מאוחסנים בעמודה ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>.
  3. מנתחת מערך של ערכים מסוג ObjectRef כדי להחזיר ערך יחיד שנוצר.
  4. לנתח מערך של ערכי ObjectRef בנפרד ולהחזיר ערך שנוצר לכל ערך במערך.

כחלק ממשימות הניתוח, אתם ממירים את מערך הערכים של ObjectRef לרשימה מסודרת של ערכים של ObjectRefRuntime, ואז מעבירים את הרשימה הזו למודל Gemini, ומציינים את הערכים של ObjectRefRuntime כחלק מההנחיה. הערכים של ObjectRefRuntime מספקים כתובות URL חתומות שהמודל משתמש בהן כדי לגשת לפרטי האובייקט ב-Cloud Storage.

כדי לעבד נתונים מרובי-אופנים מסודרים באמצעות מערכים של ערכי ObjectRef:

  1. עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור מחדש את הטבלה product_manuals:

    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. בעורך השאילתות, מריצים את השאילתה הבאה כדי לכתוב נתוני PDF לטבלה map_manual_to_chunks:

    -- 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. בעורך השאילתות, מריצים את השאילתה הבאה כדי להציג את נתוני ה-PDF בטבלה map_manual_to_chunks:

    SELECT *
    FROM cymbal_pets.map_manual_to_chunks;

    התוצאות אמורות להיראות כך:

    +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
    | 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. בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור תגובה יחידה ממודל Gemini על סמך ניתוח של מערך של ערכי ObjectRef:

    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 result AS Response
    FROM
      AI.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
        ));

    התוצאות אמורות להיראות כך:

    +-------------------------------------------+
    | 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. בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור כמה תשובות ממודל Gemini על סמך ניתוח של מערך ערכים של ObjectRef:

    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));

    התוצאות אמורות להיראות כך:

    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    | 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.                        |
    +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
    

הסרת המשאבים

  1. In the Cloud de Confiance 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.