Menggunakan BigQuery Remote Functions untuk mengajukan pertanyaan ke Vertex AI Visual Question Answering (VQA) dalam kueri SQL

1. Pengantar

Ringkasan

Fungsi jarak jauh BigQuery memungkinkan Anda menerapkan fungsi dalam bahasa selain SQL dan JavaScript, atau dengan library dan layanan yang tidak diizinkan dalam fungsi yang ditentukan pengguna BigQuery. Fungsi jarak jauh BigQuery memberikan integrasi langsung dengan fungsi Cloud Run dan Cloud Run. Anda dapat memanggil fungsi jarak jauh BigQuery dalam kueri SQL dengan mengambil satu atau beberapa kolom sebagai input, lalu menampilkan satu nilai sebagai output.

Fungsi Cloud Run adalah solusi komputasi ringan bagi developer untuk membuat fungsi mandiri dengan tujuan tunggal yang dapat dipicu menggunakan HTTPS atau merespons CloudEvents tanpa perlu mengelola server atau lingkungan runtime. Fungsi Cloud Run mendukung Node.js, Python, Go, Java, .NET, Ruby, dan PHP.

Dalam codelab ini, Anda akan mempelajari cara membuat fungsi jarak jauh BigQuery untuk mendapatkan jawaban atas pertanyaan tentang gambar yang disimpan di Cloud Storage menggunakan Pertanyaan dan Jawaban Visual (VQA) Vertex AI. Kueri SQL Anda akan mengambil URI untuk gambar dari tabel di BigQuery. Kemudian, menggunakan fungsi jarak jauh BigQuery, Anda akan mengirim URI gambar ke fungsi Cloud Run yang akan merespons dengan jawaban dari VQA tentang gambar tersebut.

Ilustrasi

5832020184ccf2b2.png

Dari perspektif pengembangan, berikut langkah-langkah yang akan Anda selesaikan dalam codelab ini:

  1. Membuat endpoint HTTP di fungsi Cloud Run
  2. Membuat koneksi jenis CLOUD_RESOURCE
  3. Membuat tabel objek BigQuery untuk bucket Cloud Storage
  4. Membuat fungsi jarak jauh
  5. Menggunakan fungsi jarak jauh dalam kueri sama seperti fungsi lainnya yang ditentukan pengguna

Yang akan Anda pelajari

2. Penyiapan dan Persyaratan

Prasyarat

Mengaktifkan Cloud Shell

  1. Dari Cloud Console, klik Aktifkan Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Jika ini pertama kalinya Anda memulai Cloud Shell, Anda akan melihat layar perantara yang menjelaskan apa itu Cloud Shell. Jika Anda melihat layar perantara, klik Continue.

d95252b003979716.png

Perlu waktu beberapa saat untuk penyediaan dan terhubung ke Cloud Shell.

7833d5e1c5d18f54.pngS

Virtual machine ini dimuat dengan semua alat pengembangan yang diperlukan. VM ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Sebagian besar pekerjaan Anda dalam codelab ini dapat dilakukan dengan browser.

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda telah diautentikasi dan project sudah ditetapkan ke project ID Anda.

  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa Anda telah diautentikasi:
gcloud auth list

Output perintah

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa perintah gcloud mengetahui project Anda:
gcloud config list project

Output perintah

[core]
project = <PROJECT_ID>

Jika tidak, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Output perintah

Updated property [core/project].

3. Menyiapkan variabel lingkungan lokal

Dalam kode ini, Anda akan membuat beberapa variabel lingkungan untuk meningkatkan keterbacaan perintah gcloud yang digunakan dalam codelab ini.

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. Membuat fungsi Cloud Run

Untuk membuat fungsi jarak jauh BigQuery, Anda harus membuat endpoint HTTP terlebih dahulu menggunakan fungsi Cloud Run. Endpoint harus dapat memproses batch baris dalam satu permintaan POST HTTP dan menampilkan hasil untuk batch tersebut sebagai respons HTTP.

Fungsi Cloud Run ini akan menerima URI penyimpanan gambar dan perintah pertanyaan sebagai input dari kueri SQL Anda, dan menampilkan jawaban dari Visual Question Answering (VQA).

Codelab ini menggunakan contoh untuk runtime python311 menggunakan Vertex AI SDK untuk Python.

Membuat kode sumber untuk fungsi

Pertama, buat direktori dan cd ke direktori tersebut.

mkdir imagen-vqa && cd $_

Lalu, buat file requirements.txt.

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

Selanjutnya, buat file sumber 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

Men-deploy fungsi Cloud Run

Sekarang Anda dapat men-deploy fungsi Cloud Run untuk runtime python311.

Untuk men-deploy fungsi Cloud Run langsung ke Cloud Run, jalankan perintah berikut:

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

Jika Anda lebih memilih untuk men-deploy sebagai Cloud Functions generasi ke-2, gunakan perintah berikut:

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

lalu Anda dapat menyimpan URL Function sebagai variabel lingkungan untuk digunakan nanti.

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

5. Membuat Bucket Cloud Storage

Pertama, buat bucket Cloud Storage untuk menyimpan gambar Anda.

gcloud storage buckets create gs://$BUCKET_NAME

Selanjutnya, upload gambar untuk digunakan VQA. Codelab ini menggunakan contoh gambar dari dokumentasi VQA.

Anda dapat menggunakan Konsol Cloud untuk Cloud Storage untuk mengupload gambar langsung ke dalam bucket. Atau, Anda dapat menjalankan perintah berikut untuk mendownload contoh gambar ke direktori Cloud Shell Anda saat ini

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

lalu upload ke bucket Cloud Storage Anda.

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

6. Membuat koneksi Resource Cloud BigQuery

BigQuery menggunakan koneksi CLOUD_RESOURCE untuk berinteraksi dengan Cloud Function Anda. Jalankan perintah berikut untuk membuat koneksi ini.

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

Selanjutnya, tampilkan detail koneksi BigQuery baru.

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

Simpan nama akun layanan koneksi BigQuery ke dalam variabel, seperti yang ditunjukkan.

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

Berikan akses ke akun layanan untuk mengakses bucket Cloud Storage Anda.

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

7. Membuat Tabel Objek BigQuery

Tabel objek BigQuery adalah tabel hanya baca di atas objek data tidak terstruktur yang berada di Cloud Storage.

Tabel objek memungkinkan Anda menganalisis data tidak terstruktur di Cloud Storage. Anda dapat melakukan analisis dengan fungsi jarak jauh, kemudian menggabungkan hasil operasi ini dengan data terstruktur lainnya di BigQuery.

Pertama, buat set data.

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

Perintah berikut membuat tabel objek berdasarkan bucket gambar Cloud Storage Anda. Tabel yang dihasilkan akan berisi URI untuk semua gambar dalam bucket tersebut.

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

8. Membuat Fungsi Jarak Jauh BigQuery

Langkah terakhir adalah mengonfigurasi Fungsi Jarak Jauh BigQuery.

Pertama, berikan izin akun layanan koneksi BigQuery untuk memanggil fungsi Cloud Run. Sebaiknya jangan mengizinkan pemanggilan yang tidak diautentikasi untuk layanan fungsi Cloud Run Anda.

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

Selanjutnya, simpan Kueri SQL ke variabel.

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'
)"

Sekarang jalankan kueri.

bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION

Setelah menjalankan kueri untuk membuat fungsi jarak jauh, Anda akan melihat Created <your-project-id>.remote_function_codelab.vqa

9. Memanggil Fungsi Jarak Jauh BigQuery dalam kueri SQL

Anda kini telah menyelesaikan langkah-langkah pengembangan untuk membuat fungsi jarak jauh. Sekarang Anda dapat memanggil fungsi Cloud Run dari dalam kueri SQL.

Pertama, simpan pertanyaan dan Kueri SQL Anda ke variabel. Codelab ini menggunakan contoh dari dokumentasi Question Answering Visual. Kueri ini menggunakan gambar terbaru yang ditambahkan ke bucket penyimpanan Anda.

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

Kemudian, jalankan Kueri SQL untuk menampilkan respons dari layanan Pertanyaan dan Jawaban Visual (VQA) Vertex AI.

bq query --nouse_legacy_sql $SQL_QUERY

Hasilnya akan terlihat seperti contoh output di bawah:

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

10. Pemecahan masalah

Saat membuat tabel BigQuery, jika menerima error BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME, pastikan Anda telah menyertakan jalur /* setelah $BUCKET_NAME dalam perintah.

Saat menjalankan kueri SQL, jika Anda mendapatkan error Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>, coba tunggu sekitar 1-2 menit hingga pemberian izin peran Cloud Function Invoker diterapkan ke akun layanan koneksi BigQuery sebelum mencoba lagi.

11. Selamat!

Selamat, Anda telah menyelesaikan codelab.

Sebaiknya tinjau dokumentasi tentang BigQuery Remote Functions dan Visual Question Answering (VQA).

Yang telah kita bahas

  • Cara mengonfigurasi autentikasi pada fungsi Cloud Run dan memverifikasi bahwa autentikasi telah dikonfigurasi dengan benar
  • Panggil fungsi terautentikasi dari lingkungan pengembangan lokal dengan memberikan token untuk identitas gcloud Anda
  • Cara membuat akun layanan dan memberikan peran yang sesuai untuk memanggil fungsi
  • Cara meniru identitas layanan dari lingkungan pengembangan lokal yang memiliki peran yang sesuai untuk memanggil fungsi

12. Pembersihan

Untuk menghindari tagihan yang tidak disengaja, (misalnya, jika fungsi Cloud Run ini tidak sengaja dipanggil lebih dari alokasi pemanggilan fungsi Cloud Run bulanan Anda di paket gratis), Anda dapat menghapus Cloud Function atau menghapus project yang Anda buat di Langkah 2.

Untuk menghapus fungsi Cloud Run, buka Konsol Cloud Cloud Run di https://console.cloud.google.com/functions/ dan hapus fungsi imagen-vqa (atau $FUNCTION_NAME jika Anda menggunakan nama yang berbeda).

Jika memilih untuk menghapus seluruh project, Anda dapat membuka https://console.cloud.google.com/cloud-resource-manager, memilih project yang Anda buat di Langkah 2, lalu memilih Hapus. Jika menghapus project, Anda harus mengubah project di Cloud SDK. Anda dapat melihat daftar semua project yang tersedia dengan menjalankan gcloud projects list.