ניתוח נתונים מרובי-אופנים באמצעות 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.
למידע נוסף, תוכלו לעיין בדפי התמחור הבאים:
- תמחור ב-BigQuery
- תמחור של פונקציות מוגדרות על ידי המשתמש (UDF) ב-Python ב-BigQuery
- תמחור של Cloud Storage
- תמחור של Vertex AI
לפני שמתחילים
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Cloud de Confiance project.
-
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 theserviceusage.services.enablepermission. Learn how to grant roles.
התפקידים הנדרשים
כדי לקבל את ההרשאות שדרושות להשלמת המדריך הזה, אתם צריכים לבקש מהאדמין להקצות לכם את תפקידי ה-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 שיכיל את האובייקטים שיוצרים במדריך הזה:
במסוף Cloud de Confiance , עוברים לדף BigQuery.
בחלונית הימנית, לוחצים על כלי הניתוחים:

אם החלונית הימנית לא מוצגת, לוחצים על הרחבת החלונית הימנית כדי לפתוח אותה.
בחלונית Explorer, בוחרים את הפרויקט.
לוחצים על View actions (הצגת פעולות) ואז על Create dataset (יצירת מערך נתונים). תיפתח החלונית Create dataset.
בשדה Dataset ID, מקלידים
cymbal_pets.לוחצים על יצירת מערך נתונים.
יצירת קטגוריה
יוצרים קטגוריה של Cloud Storage לאחסון אובייקטים שעברו טרנספורמציה:
עוברים לדף Buckets.
לוחצים על יצירה.
בדף Create a bucket, בקטע Get started, מזינים שם ייחודי גלובלית שעומד בדרישות לשמות של קטגוריות.
לוחצים על יצירה.
יצירת חיבור
יוצרים חיבור למשאב בענן ומקבלים את חשבון השירות של החיבור. BigQuery משתמש בחיבור כדי לגשת לאובייקטים ב-Cloud Storage:
עוברים לדף BigQuery.
בחלונית הימנית, לוחצים על כלי הניתוחים:

בחלונית Explorer, לוחצים על Add data.
תיבת הדו-שיח הוספת נתונים נפתחת.
בחלונית Filter By, בקטע Data Source Type, בוחרים באפשרות Business Applications.
אפשרות אחרת היא להזין
Vertex AIבשדה חיפוש מקורות נתונים.בקטע מקורות נתונים מומלצים, לוחצים על Vertex AI.
לוחצים על כרטיס הפתרון Vertex AI Models: BigQuery Federation.
ברשימה Connection type בוחרים באפשרות Vertex AI remote models, remote functions, BigLake and Spanner (Cloud Resource).
בשדה מזהה החיבור, מקלידים
cymbal_conn.לוחצים על יצירת קישור.
לוחצים על מעבר לחיבור.
בחלונית Connection info (פרטי התחברות), מעתיקים את מזהה חשבון השירות לשימוש בשלב הבא.
מתן הרשאות לחשבון השירות של החיבור
מקצים לחשבון השירות של החיבור את התפקידים המתאימים כדי לגשת לשירותים אחרים. צריך להעניק את התפקידים האלה באותו פרויקט שיצרתם או בחרתם בקטע לפני שמתחילים. מתן תפקידים בפרויקט אחר יוביל לשגיאה bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.s3ns.iam.gserviceaccount.com
does not have the permission to access resource.
מתן הרשאות בקטגוריית Cloud Storage
נותנים לחשבון השירות גישה לשימוש באובייקטים בקטגוריה שיצרתם:
עוברים לדף Buckets.
לוחצים על שם הקטגוריה שיצרתם.
לוחצים על הרשאות.
לוחצים על Grant access. תיבת הדו-שיח Grant access נפתחת.
בשדה New principals, מזינים את מזהה חשבון השירות שהעתקתם קודם.
בשדה Select a role, בוחרים באפשרות Cloud Storage ואז באפשרות Storage Object User.
לוחצים על Save.
הענקת הרשאות לשימוש במודלים של Vertex AI
מעניקים לחשבון השירות גישה לשימוש במודלים של Vertex AI:
עוברים לדף IAM & Admin.
לוחצים על Grant access. תיבת הדו-שיח Grant access נפתחת.
בשדה New principals, מזינים את מזהה חשבון השירות שהעתקתם קודם.
בשדה Select a role (בחירת תפקיד), בוחרים באפשרות Vertex AI ואז באפשרות Vertex AI User (משתמש Vertex AI).
לוחצים על Save.
יצירת טבלאות של נתונים לדוגמה
יוצרים טבלאות לאחסון פרטי המוצר של חיות המחמד של Cymbal.
יצירת טבלת products
יוצרים טבלה רגילה שמכילה את פרטי המוצרים של Cymbal pets:
במסוף Cloud de Confiance , עוברים לדף BigQuery.
בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור את הטבלה
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.
בעורך השאילתות בדף 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;
בעורך השאילתות בדף 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. - מריצים שאילתה שמחזירה תיאור של כל מותג מוצר וגם ספירה של מספר המוצרים מהמותג הזה. תיאור המותג נוצר על ידי ניתוח פרטי המוצרים של כל המוצרים מהמותג הזה, כולל תמונות המוצרים.
בעורך השאילתות בדף 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));
בעורך השאילתות בדף 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;
בעורך השאילתות בדף 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 | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | ... | ... | ... | ... | ... | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
בעורך השאילתות בדף 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 משתמשת בספריות קוד פתוח , וגם בהרצה מקבילה כדי לבצע טרנספורמציה של כמה תמונות בו-זמנית.
בעורך השאילתות בדף 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 לגישה ומטא-נתונים של התמונות בגווני אפור.
בעורך השאילתות בדף 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בשם של הקטגוריה שיצרתם.בעורך השאילתות בדף 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 בפורמט שמוכן לשימוש במודל, כדי שיהיה קל יותר לנתח אותם.
בעורך השאילתות בדף 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נתונים כדי לסכם את המידע המשפטי שמופיע במדריכי המוצרים.
בעורך השאילתות בדף 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;
בעורך השאילתות בדף 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:** | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-------------------------------------------------------------------------------------------------------------------------------------------+
יצירת הטמעות וביצוע חיפוש וקטורי
ליצור הטמעות מנתוני תמונות, ואז להשתמש בהטמעות כדי להחזיר תמונות דומות באמצעות חיפוש וקטורי.
בסביבת ייצור, מומלץ ליצור אינדקס וקטורי לפני שמריצים חיפוש וקטורי. אינדקס וקטורי מאפשר לבצע את החיפוש הווקטורי מהר יותר, אבל הוא מקטין את ההחזרה של תוצאות מדויקות ולכן מחזיר תוצאות משוערות יותר.
בעורך השאילתות בדף 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 ) );
בעורך השאילתות בדף 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
בקטע הזה מוסבר איך לבצע את הפעולות הבאות:
- צריך ליצור מחדש את הטבלה
product_manualsכך שתכיל קובץ PDF של מדריך המוצרCrittercuisine 5000וקובצי PDF של כל דף במדריך הזה. - צור טבלה שממפה את המדריך לחלקים שלו. הערך
ObjectRefשמייצג את המדריך המלא מאוחסן בעמודהSTRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>. הערכיםObjectRefשמייצגים את דפי ההוראות מאוחסנים בעמודהARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>. - מנתחת מערך של ערכים מסוג
ObjectRefכדי להחזיר ערך יחיד שנוצר. - לנתח מערך של ערכי
ObjectRefבנפרד ולהחזיר ערך שנוצר לכל ערך במערך.
כחלק ממשימות הניתוח, אתם ממירים את מערך הערכים של ObjectRef לרשימה מסודרת של ערכים של ObjectRefRuntime, ואז מעבירים את הרשימה הזו למודל Gemini, ומציינים את הערכים של ObjectRefRuntime כחלק מההנחיה. הערכים של ObjectRefRuntime מספקים כתובות URL חתומות שהמודל משתמש בהן כדי לגשת לפרטי האובייקט ב-Cloud Storage.
כדי לעבד נתונים מרובי-אופנים מסודרים באמצעות מערכים של ערכי ObjectRef:
עוברים לדף 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', 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/document_chunks/*.pdf']);
בעורך השאילתות, מריצים את השאילתה הבאה כדי לכתוב נתוני 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;
בעורך השאילתות, מריצים את השאילתה הבאה כדי להציג את נתוני ה-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}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | ... | ... | ... | ... | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור תגובה יחידה ממודל 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. | +-------------------------------------------+
בעורך השאילתות, מריצים את השאילתה הבאה כדי ליצור כמה תשובות ממודל 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. | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
הסרת המשאבים
- In the Cloud de Confiance console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.