1. 簡介
總覽
BigQuery 遠端函式可讓您使用 SQL 和 JavaScript 以外的語言實作函式,或使用 BigQuery 使用者定義函式不允許的程式庫和服務。BigQuery 遠端函式可直接整合 Cloud Run 函式和 Cloud Run。您可以在 SQL 查詢中叫用 BigQuery 遠端函式,方法是將一或多個資料欄做為輸入內容,然後傳回單一值做為輸出內容。
Cloud Run functions 是一項簡易運算解決方案,可讓開發人員建立獨立的單一用途函式,透過 HTTPS 觸發或回應 CloudEvents,而不需管理伺服器或執行階段環境。Cloud Run functions 支援 Node.js、Python、Go、Java、.NET、Ruby 和 PHP。
在本程式碼研究室中,您將瞭解如何建立 BigQuery 遠端函式,使用 Vertex AI 圖像問題回答 (VQA) 服務,取得 Cloud Storage 中圖片相關問題的答案。SQL 查詢會從 BigQuery 的資料表擷取圖片的 URI。接著,您會使用 BigQuery 遠端函式,將圖片 URI 傳送至 Cloud Run 函式,後者會傳回 VQA 針對圖片提供的答案。
插圖

從開發角度來看,您將在本程式碼研究室中完成下列步驟:
- 在 Cloud Run 函式中建立 HTTP 端點
- 建立 CLOUD_RESOURCE 類型的連線
- 為 Cloud Storage bucket 建立 BigQuery 物件資料表
- 建立遠端函式
- 在查詢中使用遠端函式,就像使用任何其他使用者定義函式一樣
課程內容
- 如何使用 Python 建立 HTTP Cloud Run 函式
- 如何在 SQL 查詢中建立及使用 BigQuery 遠端函式
- 如何建立 BigQuery 物件資料表
- 如何使用 Vertex AI SDK for Python,透過 圖像問題回答 (VQA) 提問
2. 設定和需求
必要條件
- 您已登入 Cloud Console。
- 您先前已部署 HTTP Cloud Run 函式。請參閱 Python 快速入門導覽課程。
- 您先前已在 Cloud Storage 中建立值區。請參閱 Cloud Storage 快速入門導覽課程。
- 您擁有適當的角色,可在 BigQuery 中建立資料集、資料表和遠端函式。請參閱「在 BigQuery 中載入及查詢資料」快速入門導覽課程。
啟用 Cloud Shell
- 在 Cloud 控制台,點選「啟用 Cloud Shell」 圖示
。

如果您是首次啟動 Cloud Shell,系統會顯示中繼畫面,說明這個指令列環境。如果出現中繼畫面,請按一下「繼續」。

佈建並連至 Cloud Shell 預計只需要幾分鐘。

這部虛擬機器已載入所有必要的開發工具,並提供永久的 5 GB 主目錄,而且可在 Google Cloud 運作,大幅提升網路效能並強化驗證功能。本程式碼研究室幾乎所有工作都可在瀏覽器上完成。
連至 Cloud Shell 後,您應該會看到驗證已完成,專案也已設為獲派的專案 ID。
- 在 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`
- 在 Cloud Shell 中執行下列指令,確認 gcloud 指令知道您的專案:
gcloud config list project
指令輸出
[core] project = <PROJECT_ID>
如未設定,請輸入下列指令手動設定專案:
gcloud config set project <PROJECT_ID>
指令輸出
Updated property [core/project].
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 遠端函式,請先使用 Cloud Run 函式建立 HTTP 端點。端點必須能夠在單一 HTTP POST 要求中處理一批資料列,並以 HTTP 回應的形式傳回該批資料的結果。
這個 Cloud Run 函式會從 SQL 查詢接收圖片儲存 URI 和問題提示詞做為輸入內容,並傳回圖像問題回答 (VQA) 的答案。
本程式碼實驗室會使用 python311 執行階段的範例,並搭配 Python 適用的 Vertex AI SDK。
建立函式的原始碼
首先,請建立目錄並 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 函式
現在您可以部署適用於 python311 執行階段的 Cloud Run 函式。
如要將 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
然後將函式網址儲存為環境變數,以供後續使用。
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. 建立 Cloud Storage bucket
首先,請建立 Cloud Storage bucket 來儲存圖片。
gcloud storage buckets create gs://$BUCKET_NAME
接著,上傳 VQA 要使用的圖片。本程式碼研究室使用 VQA 說明文件中的範例圖片。
您可以透過 Cloud Storage 的 Cloud 控制台,將圖片直接上傳至 bucket。或者,您也可以執行下列指令,將範例圖片下載至目前的 Cloud Shell 目錄
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
然後上傳至 Cloud Storage bucket。
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. 建立 BigQuery Cloud 資源連結
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 bucket 的權限。
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. 建立 BigQuery 物件資料表
BigQuery 物件資料表是 Cloud Storage 中非結構化資料物件的唯讀資料表。
物件資料表可讓您分析 Cloud Storage 中的非結構化資料。您可以使用遠端函式執行數據分析,然後在 BigQuery 中將這些作業的結果與其餘結構化資料合併。
請先建立資料集。
bq --location=$BQ_REGION mk \
--dataset \
$DATASET_ID
下列指令會根據 Cloud Storage 圖片 bucket 建立物件資料表。產生的資料表會包含該值區中所有圖片的 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. 在 SQL 查詢中呼叫 BigQuery 遠端函式
您已完成建立遠端函式的開發步驟。現在您可以從 SQL 查詢中呼叫 Cloud Run 函式。
首先,請將問題和 SQL 查詢儲存至變數。本程式碼研究室使用「圖像問題回答」說明文件中的範例。這項查詢會使用新增至儲存空間 bucket 的最新圖片。
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 圖像問題回答 (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. 恭喜!
恭喜您完成本程式碼研究室!
建議您參閱 BigQuery 遠端函式和 圖像問題回答 (VQA) 的說明文件。
涵蓋內容
- 如何設定 Cloud Run 函式的驗證,以及確認驗證設定是否正確
- 從本機開發環境叫用已驗證的函式,並提供 gcloud 身分識別的權杖
- 如何建立服務帳戶並授予適當角色來叫用函式
- 如何從本機開發環境模擬服務,並具備叫用函式的適當角色
12. 清理
為避免產生非預期費用 (例如,如果這個 Cloud Run 函式遭非預期呼叫的次數,超過免費層級每月 Cloud Run 函式呼叫次數配額),您可以刪除 Cloud Function,或是刪除步驟 2 中建立的專案。
如要刪除 Cloud Run 函式,請前往 Cloud Run Cloud 控制台 (https://console.cloud.google.com/functions/),然後刪除 imagen-vqa 函式 (如果您使用其他名稱,請刪除 $FUNCTION_NAME)。
如要刪除整個專案,請前往 https://console.cloud.google.com/cloud-resource-manager,選取您在步驟 2 中建立的專案,然後選擇「刪除」。刪除專案後,您必須在 Cloud SDK 中變更專案。如要查看所有可用專案的清單,請執行 gcloud projects list。