ใช้ฟังก์ชันระยะไกลของ BigQuery เพื่อถามคำถามกับ Vertex AI Visual Questioning (VQA) ในการสอบถาม SQL

1. บทนำ

ภาพรวม

ฟังก์ชันระยะไกลของ BigQuery ช่วยให้คุณใช้ฟังก์ชันในภาษาอื่นที่ไม่ใช่ SQL และ JavaScript หรือใช้ไลบรารีและบริการที่ไม่อนุญาตในฟังก์ชันที่ผู้ใช้กำหนดของ BigQuery ได้ ฟังก์ชันระยะไกลของ BigQuery ช่วยให้ผสานรวมกับฟังก์ชัน Cloud Run และ Cloud Run ได้โดยตรง คุณเรียกใช้ฟังก์ชันระยะไกลของ BigQuery ภายในคำค้นหา SQL ได้โดยใช้คอลัมน์อย่างน้อย 1 คอลัมน์เป็นอินพุต จากนั้นส่งคืนค่าเดียวเป็นเอาต์พุต

ฟังก์ชัน Cloud Run เป็นโซลูชันการประมวลผลที่มีน้ำหนักเบาสำหรับนักพัฒนาซอฟต์แวร์ในการสร้างฟังก์ชันแบบสแตนด์อโลนที่มีวัตถุประสงค์เดียว ซึ่งสามารถทริกเกอร์ได้โดยใช้ HTTPS หรือตอบสนองต่อ CloudEvents โดยไม่จำเป็นต้องจัดการเซิร์ฟเวอร์หรือสภาพแวดล้อมรันไทม์ ฟังก์ชัน Cloud Run รองรับ Node.js, Python, Go, Java, .NET, Ruby และ PHP

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีสร้างฟังก์ชันระยะไกลของ BigQuery เพื่อรับคำตอบของคำถามเกี่ยวกับรูปภาพที่จัดเก็บไว้ใน Cloud Storage โดยใช้ Visual Question Answering (VQA) ของ Vertex AI การค้นหา SQL จะดึง URI สำหรับรูปภาพจากตารางใน BigQuery จากนั้นใช้ฟังก์ชันระยะไกลของ BigQuery เพื่อส่ง URI ของรูปภาพไปยังฟังก์ชัน Cloud Run ซึ่งจะตอบกลับด้วยคำตอบจาก VQA เกี่ยวกับรูปภาพ

ภาพประกอบ

5832020184ccf2b2.png

ในมุมมองของการพัฒนา ขั้นตอนที่คุณจะทำใน Codelab นี้มีดังนี้

  1. สร้างปลายทาง HTTP ในฟังก์ชัน Cloud Run
  2. สร้างการเชื่อมต่อประเภท CLOUD_RESOURCE
  3. สร้างตารางออบเจ็กต์ BigQuery สำหรับที่เก็บข้อมูล Cloud Storage
  4. สร้างฟังก์ชันระยะไกล
  5. ใช้ฟังก์ชันระยะไกลในการค้นหาได้เช่นเดียวกับฟังก์ชันที่ผู้ใช้กำหนดอื่นๆ

สิ่งที่คุณจะได้เรียนรู้

  • วิธีสร้างฟังก์ชัน HTTP Cloud Run ใน Python
  • วิธีสร้างและใช้ฟังก์ชันระยะไกลของ BigQuery ภายในคำค้นหา SQL
  • วิธีสร้างตารางออบเจ็กต์ BigQuery
  • วิธีใช้ Vertex AI SDK สำหรับ Python เพื่อใช้ Visual Question Answering (VQA)

2. การตั้งค่าและข้อกำหนด

ข้อกำหนดเบื้องต้น

เปิดใช้งาน Cloud Shell

  1. จาก Cloud Console ให้คลิกเปิดใช้งาน Cloud Shell d1264ca30785e435.png

cb81e7c8e34bc8d.png

หากคุณเริ่มใช้ Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอระดับกลางที่อธิบายว่า Cloud Shell คืออะไร หากเห็นหน้าจอระดับกลาง ให้คลิกต่อไป

d95252b003979716.png

การจัดสรรและเชื่อมต่อกับ Cloud Shell จะใช้เวลาไม่นาน

7833d5e1c5d18f54.png

เครื่องเสมือนนี้โหลดเครื่องมือพัฒนาซอฟต์แวร์ทั้งหมดที่จำเป็นไว้แล้ว โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานส่วนใหญ่หรือทั้งหมดใน Codelab นี้ได้ด้วยเบราว์เซอร์

เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นว่าคุณได้รับการตรวจสอบสิทธิ์และระบบได้ตั้งค่าโปรเจ็กต์เป็นรหัสโปรเจ็กต์ของคุณ

  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list

เอาต์พุตจากคำสั่ง

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้จักโปรเจ็กต์ของคุณ
gcloud config list project

เอาต์พุตจากคำสั่ง

[core]
project = <PROJECT_ID>

หากไม่ได้ตั้งค่าไว้ คุณสามารถตั้งค่าได้ด้วยคำสั่งนี้

gcloud config set project <PROJECT_ID>

เอาต์พุตจากคำสั่ง

Updated property [core/project].

3. ตั้งค่าตัวแปรสภาพแวดล้อมในเครื่อง

ในโค้ดนี้ คุณจะสร้างตัวแปรสภาพแวดล้อม 2-3 ตัวเพื่อปรับปรุงความสามารถในการอ่านของคำสั่ง gcloud ที่ใช้ใน Codelab นี้

PROJECT_ID=$(gcloud config get-value project)

# Cloud Function variables
FUNCTION_NAME="imagen-vqa"
FUNCTION_REGION="us-central1"

# Cloud Function variables
BUCKET_NAME=$PROJECT_ID-imagen-vqa

# BigQuery variables
DATASET_ID="remote_function_codelab"
TABLE_NAME="images"
BQ_REGION="US"
CONNECTION_ID="imagen_vqa_connection"

4. สร้างฟังก์ชัน Cloud Run

หากต้องการสร้างฟังก์ชันระยะไกลของ BigQuery คุณต้องสร้างปลายทาง HTTP โดยใช้ฟังก์ชัน Cloud Run ก่อน ปลายทางต้องประมวลผลแถวเป็นกลุ่มในคำขอ HTTP POST รายการเดียวและแสดงผลลัพธ์สำหรับกลุ่มเป็นการตอบกลับ HTTP ได้

ฟังก์ชัน Cloud Run นี้จะรับ URI ที่เก็บรูปภาพและพรอมต์คำถามเป็นอินพุตจากการค้นหา SQL และแสดงคำตอบจาก Visual Question Answering (VQA)

Codelab นี้ใช้ตัวอย่างสำหรับรันไทม์ Python 3.11 โดยใช้ Vertex AI SDK สำหรับ Python

สร้างซอร์สโค้ดสำหรับฟังก์ชัน

ก่อนอื่น ให้สร้างไดเรกทอรีแล้วใช้คำสั่ง cd เพื่อไปยังไดเรกทอรีนั้น

mkdir imagen-vqa && cd $_

จากนั้นสร้างrequirements.txt

google-cloud-aiplatform[preview]
google-cloud-storage
functions-framework==3.*

จากนั้นสร้างmain.pyไฟล์ต้นฉบับ

from vertexai.preview.vision_models import ImageQnAModel
from vertexai.preview.vision_models import Image
from flask import jsonify
from google.cloud import storage
from urllib.parse import urlparse
import functions_framework

# This is the entry point for the cloud function
@functions_framework.http
def imagen_vqa(request):
    try:
        # See if you can parse the incoming JSON
        return_value = []
        request_json = request.get_json()
        # This grabs the input into the function as called from the SQL function 
        calls = request_json['calls']
        for call in calls:
            # We call the VQA function here in another function defined below
            ai_result = vqa(call)
            # The result to BigQuery is in the order it was prepared in 
            return_value.append(ai_result[0])
        # Prepare the response back to BigQuery
        return_json = jsonify( { "replies": return_value } )
        return return_json
    except Exception as e:
        return jsonify( { "errorMessage": str(e) } ), 400

# Helper function to split apart the GCS URI 
def decode_gcs_url(url):
    # Read the URI and parse it
    p = urlparse(url)
    bucket = p.netloc
    file_path = p.path[0:].split('/', 1)
    # Return the relevant objects (bucket, path to object)
    return bucket, file_path[1]
    
# We can't use the image load from local file since it expects a local path
# We use a GCS URL and get the bytes of the image 
def read_file(object_path):
    # Parse the path
    bucket, file_path = decode_gcs_url(object_path)
    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket)
    blob = bucket.blob(file_path)
    # Return the object as bytes
    return blob.download_as_bytes()

# This is the function that calls the VQA function
def vqa (parameters):
    # This is the model we want to use
    image_qna_model = ImageQnAModel.from_pretrained("imagetext@001")
    # The location is the first parameter 
    image_loc = parameters[0]
    # Get the bytes 
    image_bytes = read_file(image_loc)
    # Load the bytes into the Image handler
    input_image = Image(image_bytes)
    # Ask the VQA the question
    results = image_qna_model.ask_question(
        image=input_image,
        # The prompt was the second parameter
        question=parameters[1],
        number_of_results=1
    )
    return results

ทำให้ฟังก์ชัน Cloud Run ใช้งานได้

ตอนนี้คุณทำให้ฟังก์ชัน Cloud Run ใช้งานได้สำหรับรันไทม์ python311 แล้ว

หากต้องการทำให้ฟังก์ชัน Cloud Run ใช้งานได้ใน Cloud Run โดยตรง ให้เรียกใช้คำสั่งต่อไปนี้

gcloud beta run deploy $FUNCTION_NAME \
      --source . \
      --function imagen_vqa \
      --region $FUNCTION_REGION \
      --no-allow-unauthenticated

หากต้องการทำให้ใช้งานได้เป็น Cloud Functions รุ่นที่ 2 ให้ใช้คำสั่งต่อไปนี้

gcloud functions deploy $FUNCTION_NAME \
--gen2 \
--region=$FUNCTION_REGION \
--runtime=python311 \
--trigger-http \
--source=. \
--no-allow-unauthenticated

จากนั้นคุณจะบันทึก URL ของฟังก์ชันเป็นตัวแปรสภาพแวดล้อมเพื่อใช้ในภายหลังได้

ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"

5. สร้าง Bucket ของ Cloud Storage

ก่อนอื่นให้สร้าง Bucket ของ Cloud Storage เพื่อจัดเก็บรูปภาพ

gcloud storage buckets create gs://$BUCKET_NAME

จากนั้นอัปโหลดรูปภาพเพื่อให้ VQA ใช้ Codelab นี้ใช้รูปภาพตัวอย่างจากเอกสารประกอบของ VQA

คุณจะใช้ Cloud Console สำหรับ Cloud Storage เพื่ออัปโหลดรูปภาพลงใน Bucket โดยตรงก็ได้ หรือจะเรียกใช้คำสั่งต่อไปนี้เพื่อดาวน์โหลดรูปภาพตัวอย่างไปยังไดเรกทอรี Cloud Shell ปัจจุบันก็ได้

wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true

แล้วอัปโหลดไปยัง Bucket ของ Cloud Storage

gcloud storage cp image.jpg gs://$BUCKET_NAME

6. สร้างการเชื่อมต่อทรัพยากรระบบคลาวด์ BigQuery

BigQuery ใช้การเชื่อมต่อ CLOUD_RESOURCE เพื่อโต้ตอบกับ Cloud Function เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างการเชื่อมต่อนี้

bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \
--connection_type=CLOUD_RESOURCE $CONNECTION_ID

จากนั้นแสดงรายละเอียดของการเชื่อมต่อ BigQuery ใหม่

bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID

บันทึกชื่อบัญชีบริการการเชื่อมต่อ BigQuery ลงในตัวแปร ดังที่แสดง

CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"

ให้สิทธิ์เข้าถึงบัญชีบริการเพื่อเข้าถึง Bucket ของ Cloud Storage

gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME

7. สร้างตารางออบเจ็กต์ BigQuery

ตารางออบเจ็กต์ BigQuery เป็นตารางแบบอ่านอย่างเดียวสำหรับออบเจ็กต์ข้อมูลที่ไม่มีโครงสร้างซึ่งอยู่ใน Cloud Storage

ตารางออบเจ็กต์ช่วยให้คุณวิเคราะห์ข้อมูลที่ไม่มีโครงสร้างใน Cloud Storage ได้ คุณสามารถทำการวิเคราะห์ด้วยฟังก์ชันระยะไกล แล้วรวมผลลัพธ์ของการดำเนินการเหล่านี้กับ Structured Data อื่นๆ ใน BigQuery

ก่อนอื่น ให้สร้างชุดข้อมูล

bq --location=$BQ_REGION mk \
    --dataset \
    $DATASET_ID

คำสั่งต่อไปนี้จะสร้างตารางออบเจ็กต์ตามที่เก็บข้อมูลรูปภาพ Cloud Storage ตารางที่ได้จะมี URI สำหรับรูปภาพทั้งหมดในที่เก็บข้อมูลนั้น

bq mk --table \
--external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \
--object_metadata=SIMPLE \
$PROJECT_ID:$DATASET_ID.$TABLE_NAME

8. สร้างฟังก์ชันระยะไกลของ BigQuery

ขั้นตอนสุดท้ายคือการกำหนดค่าฟังก์ชันระยะไกลของ BigQuery

ก่อนอื่น ให้สิทธิ์บัญชีบริการการเชื่อมต่อ BigQuery เพื่อเรียกใช้ฟังก์ชัน Cloud Run เราไม่แนะนำให้อนุญาตการเรียกใช้ที่ไม่ผ่านการตรวจสอบสิทธิ์สำหรับบริการฟังก์ชัน Cloud Run

gcloud run services add-iam-policy-binding $FUNCTION_NAME \
 --member=serviceAccount:$CONNECTION_SA \
 --role="roles/run.invoker" \
 --region $FUNCTION_REGION

จากนั้นบันทึกการค้นหา SQL ลงในตัวแปร

SQL_CREATE_FUNCTION="CREATE FUNCTION \`$PROJECT_ID.$DATASET_ID\`.vqa(uri STRING, image_prompt STRING) RETURNS STRING
REMOTE WITH CONNECTION \`$PROJECT_ID.$BQ_REGION.$CONNECTION_ID\`
OPTIONS (
  endpoint = '$ENDPOINT_URL'
)"

ตอนนี้ให้เรียกใช้การค้นหา

bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION

หลังจากเรียกใช้การค้นหาเพื่อสร้างฟังก์ชันระยะไกลแล้ว คุณจะเห็น Created <your-project-id>.remote_function_codelab.vqa

9. เรียกใช้ฟังก์ชันระยะไกลของ BigQuery ในการค้นหา SQL

ตอนนี้คุณได้ทำตามขั้นตอนการพัฒนาเพื่อสร้างฟังก์ชันระยะไกลเสร็จแล้ว ตอนนี้คุณเรียกใช้ฟังก์ชัน Cloud Run จากภายในคำค้นหา SQL ได้แล้ว

ก่อนอื่น ให้บันทึกคำถามและคำค้นหา SQL ลงในตัวแปร Codelab นี้ใช้ตัวอย่างจากเอกสารประกอบเรื่องการตอบคำถามด้วยภาพ การค้นหานี้ใช้รูปภาพล่าสุดที่เพิ่มลงในที่เก็บข้อมูล

export SQL_QUERY="DECLARE question STRING DEFAULT 'What objects are in the image?';
SELECT uri, image_prompt ,\`$DATASET_ID\`.vqa(uri, image_prompt) as result
FROM ( 
  SELECT 
  *, 
  dense_rank() over (order by updated) as rnk ,
  question as image_prompt
  FROM \`$PROJECT_ID.$DATASET_ID.images\`) as innertable
  WHERE rnk  = 1;
"

จากนั้นเรียกใช้การค้นหา SQL เพื่อแสดงคำตอบจากบริการ Vertex AI Visual Question Answering (VQA)

bq query --nouse_legacy_sql $SQL_QUERY

ผลลัพธ์ควรมีลักษณะคล้ายกับเอาต์พุตตัวอย่างด้านล่าง

+---------------------------------+--------------------------------+----------+
|               uri               |    image_prompt                |  result  |
+---------------------------------+--------------------------------+----------+
| gs://<YOUR_BUCKET>/image.jpg    | What objects are in the image? |  marbles |
+---------------------------------+--------------------------------+----------+

10. การแก้ปัญหา

เมื่อสร้างตาราง BigQuery หากได้รับข้อผิดพลาด BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME โปรดตรวจสอบว่าคุณได้รวมเส้นทาง /* หลัง $BUCKET_NAME ในคำสั่งแล้ว

เมื่อเรียกใช้คำค้นหา SQL หากได้รับข้อผิดพลาด Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint> ให้รอประมาณ 1-2 นาทีเพื่อให้สิทธิ์บทบาทผู้เรียกใช้ Cloud Functions เผยแพร่ไปยังบัญชีบริการการเชื่อมต่อ BigQuery ก่อนที่จะลองอีกครั้ง

11. ยินดีด้วย

ขอแสดงความยินดีที่ทำ Codelab นี้เสร็จสมบูรณ์

เราขอแนะนำให้คุณอ่านเอกสารประกอบเกี่ยวกับฟังก์ชันระยะไกลของ BigQuery และการตอบคำถามด้วยภาพ (VQA)

สิ่งที่เราได้พูดถึง

  • วิธีกำหนดค่าการตรวจสอบสิทธิ์ในฟังก์ชัน Cloud Run และยืนยันว่าได้กำหนดค่าการตรวจสอบสิทธิ์อย่างถูกต้อง
  • เรียกใช้ฟังก์ชันที่ได้รับการตรวจสอบสิทธิ์จากสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ในเครื่องโดยระบุโทเค็นสำหรับข้อมูลประจำตัว gcloud
  • วิธีสร้างบัญชีบริการและมอบบทบาทที่เหมาะสมเพื่อเรียกใช้ฟังก์ชัน
  • วิธีแอบอ้างเป็นบริการจากสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ในเครื่องที่มีบทบาทที่เหมาะสมสำหรับการเรียกใช้ฟังก์ชัน

12. ล้างข้อมูล

หากต้องการหลีกเลี่ยงการเรียกเก็บเงินโดยไม่ตั้งใจ (เช่น หากฟังก์ชัน Cloud Run นี้ถูกเรียกใช้โดยไม่ตั้งใจมากกว่าการจัดสรรการเรียกใช้ฟังก์ชัน Cloud Run รายเดือนในระดับฟรี) คุณสามารถลบ Cloud Function หรือลบโปรเจ็กต์ที่สร้างในขั้นตอนที่ 2 ก็ได้

หากต้องการลบฟังก์ชัน Cloud Run ให้ไปที่ Cloud Console ของ Cloud Run ที่ https://console.cloud.google.com/functions/ แล้วลบฟังก์ชัน imagen-vqa (หรือ $FUNCTION_NAME ในกรณีที่คุณใช้ชื่ออื่น)

หากเลือกที่จะลบทั้งโปรเจ็กต์ ให้ไปที่ https://console.cloud.google.com/cloud-resource-manager เลือกโปรเจ็กต์ที่สร้างในขั้นตอนที่ 2 แล้วเลือก "ลบ" หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณดูรายการโปรเจ็กต์ทั้งหมดที่พร้อมใช้งานได้โดยเรียกใช้ gcloud projects list