ใช้ฟังก์ชันระยะไกลของ 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

ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีสร้างฟังก์ชันระยะไกลของ 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 Shell d1264ca30785e435.png จาก Cloud Console

cb81e7c8e34bc8d.png

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

d95252b003979716.png

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

7833d5e1c5d18f54.png

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

เมื่อเชื่อมต่อกับ 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 ที่ใช้ในโค้ดแล็บนี้

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 และแสดงผลคำตอบจากการตอบคำถามด้วยภาพ (VQA)

Codelab นี้ใช้ตัวอย่างรันไทม์ python311 โดยใช้ 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. สร้างที่เก็บข้อมูล Cloud Storage

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

gcloud storage buckets create gs://$BUCKET_NAME

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

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

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

แล้วอัปโหลดไปยังที่เก็บข้อมูล 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"

ให้สิทธิ์เข้าถึงแก่บัญชีบริการเพื่อเข้าถึงที่เก็บข้อมูล 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 ลงในตัวแปร โค้ดแล็บนี้ใช้ตัวอย่างจากเอกสารประกอบเกี่ยวกับการตอบคำถามด้วยภาพ การค้นหานี้ใช้รูปภาพล่าสุดที่เพิ่มลงในที่เก็บข้อมูลของพื้นที่เก็บข้อมูล

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 เพื่อแสดงคำตอบจากบริการ Visual Question Answering (VQA) ของ Vertex AI

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 มีผลกับบัญชีบริการการเชื่อมต่อ 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