BigQuery Remote Functions işlevlerini kullanarak bir SQL sorgusunda Vertex AI Visual Question Answering (VQA) ile soru sorma

1. Giriş

Genel Bakış

BigQuery uzak işlevleri, bir işlevi SQL ve JavaScript dışındaki dillerde veya BigQuery kullanıcı tanımlı işlevlerinde izin verilmeyen kitaplıklar ve hizmetlerle uygulamanıza olanak tanır. BigQuery uzak işlevleri, Cloud Run işlevleri ve Cloud Run ile doğrudan entegrasyon sağlar. Bir veya daha fazla sütunu giriş olarak alıp ardından çıkış olarak tek bir değer döndürerek SQL sorgusu içinde BigQuery uzak işlevini çağırabilirsiniz.

Cloud Run işlevleri, bir sunucu veya çalışma zamanı ortamını yönetme gereği duymadan HTTPS kullanılarak tetiklenebilecek ya da CloudEvents'e yanıt verebilecek tek amaçlı bağımsız işlevler oluşturmak için geliştiriciler tarafından kullanılabilecek hafif bir bilgi işlem çözümüdür. Cloud Run işlevleri Node.js, Python, Go, Java, .NET, Ruby ve PHP'yi destekler.

Bu codelab'de, Vertex AI Görsel Soru Yanıtlama (VQA)'yı kullanarak Cloud Storage'da depolanan resimlerle ilgili bir soruya yanıt almak için nasıl BigQuery uzak işlevi oluşturacağınızı öğreneceksiniz. SQL sorgunuz, BigQuery'deki bir tablodan bir resmin URI'sini alır. Ardından, bir BigQuery uzak işlevi kullanarak resim URI'sini bir Cloud Run işlevine gönderirsiniz. Bu işlev, resimle ilgili VQA yanıtlarını döndürür.

Resim

5832020184ccf2b2.png

Geliştirme açısından, bu codelab'de tamamlayacağınız adımlar şunlardır:

  1. Cloud Run işlevlerinde HTTP uç noktası oluşturma
  2. CLOUD_RESOURCE türündeki bir bağlantı oluşturun
  3. Cloud Storage paketi için BigQuery nesne tablosu oluşturma
  4. Uzaktan işlevi oluşturma
  5. Uzaktan işlevini, diğer kullanıcı tanımlı işlevler gibi bir sorguda kullanabilirsiniz.

Neler öğreneceksiniz?

2. Kurulum ve Gereksinimler

Ön koşullar

Cloud Shell'i etkinleştirme

  1. Cloud Console'da Cloud Shell'i etkinleştir 'i d1264ca30785e435.png tıklayın.

cb81e7c8e34bc8d.png

Cloud Shell'i ilk kez başlatıyorsanız ne olduğunu açıklayan bir ara ekran gösterilir. Ara bir ekran görüntülendiyse Devam'ı tıklayın.

d95252b003979716.png

Cloud Shell'e bağlanmak ve ortam oluşturmak yalnızca birkaç dakikanızı alır.

7833d5e1c5d18f54.png

Bu sanal makinede, ihtiyaç duyulan tüm geliştirme araçları yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışır. Bu sayede ağ performansını ve kimlik doğrulamayı büyük ölçüde iyileştirir. Bu codelab'deki çalışmalarınızın tamamı olmasa bile büyük bir kısmı tarayıcıyla yapılabilir.

Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin proje kimliğinize ayarlandığını görürsünüz.

  1. Kimliğinizi doğrulamak için Cloud Shell'de aşağıdaki komutu çalıştırın:
gcloud auth list

Komut çıkışı

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud komutunun projeniz hakkında bilgi sahibi olduğunu onaylamak için Cloud Shell'de aşağıdaki komutu çalıştırın:
gcloud config list project

Komut çıkışı

[core]
project = <PROJECT_ID>

Doğru değilse aşağıdaki komutla ayarlayabilirsiniz:

gcloud config set project <PROJECT_ID>

Komut çıkışı

Updated property [core/project].

3. Yerel ortam değişkenlerini ayarlama

Bu kodda, bu codelab'de kullanılan gcloud komutlarının okunabilirliğini artırmak için birkaç ortam değişkeni oluşturacaksınız.

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 işlevini oluşturma

BigQuery uzak işlevi oluşturmak için önce Cloud Run işlevini kullanarak bir HTTP uç noktası oluşturmanız gerekir. Bitiş noktası, tek bir HTTP POST isteğinde bir satır grubunu işleyebilmelidir ve grubun sonuçlarını HTTP yanıtı olarak döndürmelidir.

Bu Cloud Run işlevi, SQL sorgunuzdan giriş olarak görüntü depolama URI'sini ve soru istemini alır ve görsel soru yanıtlama (VQA) özelliğinden yanıtı döndürür.

Bu kod laboratuvarında, Python için Vertex AI SDK'yı kullanan python311 çalışma zamanı örneği kullanılmaktadır.

İşlev için kaynak kodunu oluşturma

Öncelikle bir dizin oluşturun ve cd komutunu kullanarak bu dizine gidin.

mkdir imagen-vqa && cd $_

Ardından bir requirements.txt dosyası oluşturun.

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

Ardından, bir main.py kaynak dosyası oluşturun.

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 işlevini dağıtma

Artık Cloud Run işlevinizi python311 çalışma zamanı için dağıtabilirsiniz.

Bir Cloud Run işlevini doğrudan Cloud Run'a dağıtmak için aşağıdaki komutu çalıştırın:

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

2. nesil Cloud Functions olarak dağıtmayı tercih ediyorsanız aşağıdaki komutu kullanın:

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

Ardından, işlev URL'sini daha sonra kullanmak üzere bir ortam değişkeni olarak kaydedebilirsiniz.

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

5. Cloud Storage paketini oluşturma

Öncelikle, görüntülerinizi depolamak için bir Cloud Storage paketi oluşturun.

gcloud storage buckets create gs://$BUCKET_NAME

Ardından, VQA'nın kullanacağı bir resim yükleyin. Bu codelab'de VQA dokümanlarındaki örnek resim kullanılır.

Cloud Storage için Cloud Console'u kullanarak görüntüyü doğrudan paketinize yükleyebilirsiniz. Alternatif olarak, örnek resmi mevcut Cloud Shell dizininize indirmek için aşağıdaki komutları da çalıştırabilirsiniz.

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

ve ardından Cloud Storage paketinize yükleyin.

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

6. BigQuery Cloud Resource bağlantısı oluşturma

BigQuery, Cloud Functions işlevinizle etkileşime geçmek için CLOUD_SOURCE bağlantısı kullanır. Bu bağlantıyı oluşturmak için aşağıdaki komutu çalıştırın.

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

Ardından, yeni BigQuery bağlantısının ayrıntılarını görüntüleyin.

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

BigQuery bağlantı hizmeti hesabının adını aşağıda gösterildiği gibi bir değişkene kaydedin.

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

Hizmet hesabına Cloud Storage paketinize erişim izni verin.

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

7. BigQuery nesne tablosu oluşturma

BigQuery nesne tabloları, Cloud Storage'da bulunan yapılandırılmamış veri nesneleri üzerinde salt okunur tablolardır.

Nesne tabloları, Cloud Storage'daki yapılandırılmamış verileri analiz etmenize olanak tanır. Uzak işlevlerle analiz yapabilir ve ardından bu işlemlerin sonuçlarını BigQuery'deki yapılandırılmış verilerinizin geri kalanıyla birleştirebilirsiniz.

Öncelikle bir veri kümesi oluşturun.

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

Aşağıdaki komut, Cloud Storage resim paketinize göre bir nesne tablosu oluşturur. Elde edilen tabloda, ilgili paketteki tüm resimlerin URI'leri yer alır.

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

8. BigQuery uzak işlevini oluşturma

Son adım, BigQuery Uzak İşlevi'ni yapılandırmaktır.

Öncelikle, BigQuery bağlantı hizmeti hesabına Cloud Run işlevini çağırma izni verin. Cloud Run işlev hizmetiniz için kimliği doğrulanmamış çağrılara izin vermeniz önerilmez.

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

Ardından SQL sorgusunu bir değişkene kaydedin.

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

Ardından sorguyu çalıştırın.

bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION

Uzaktan işlevi oluşturmak için sorguyu çalıştırdıktan sonra Created <your-project-id>.remote_function_codelab.vqa

9. SQL sorgusunda BigQuery Uzak İşlevini çağırma

Uzak işlevi oluşturmayla ilgili geliştirme adımlarını tamamladınız. Artık Cloud Run işlevinizi SQL sorgusu içinden çağırabilirsiniz.

İlk olarak sorunuzu ve SQL sorgunuzu bir değişkene kaydedin. Bu codelab'de, Görsel Soru Yanıtlama dokümanlarında yer alan örnek kullanılmaktadır. Bu sorgu, depolama alanı paketinize eklenen en son resmi kullanır.

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

Ardından, Vertex AI Görsel Soru Yanıtlama (VQA) hizmetinden gelen yanıtı göstermek için SQL sorgusunu çalıştırın.

bq query --nouse_legacy_sql $SQL_QUERY

Sonuçlar, aşağıdaki örnek çıkışla benzer olacaktır:

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

10. Sorun giderme

BigQuery tablosunu oluştururken BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME hatası alırsanız komutta $BUCKET_NAME'den sonra /* yolunu eklediğinizden emin olun.

SQL sorgunuzu çalıştırırken Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint> hatası alırsanız tekrar denemeden önce Cloud Function Invoker rolü izin verisinin BigQuery bağlantısı hizmet hesabına yayılması için yaklaşık 1-2 dakika beklemeyi deneyin.

11. Tebrikler!

Tebrikler, codelab'i tamamladınız.

BigQuery Uzak İşlevleri ve Görsel Soru Yanıtlama (VQA) ile ilgili dokümanları incelemenizi öneririz.

Ele aldığımız konular

  • Cloud Run işlevinde kimlik doğrulamayı yapılandırma ve kimlik doğrulamasının düzgün şekilde yapılandırıldığını doğrulama
  • gcloud kimliğinizin jetonunu sağlayarak yerel bir geliştirme ortamından kimliği doğrulanmış bir işlevi çağırma
  • Hizmet hesabı oluşturma ve bir işlevi çağırmak için uygun rolü verme
  • Yerel bir geliştirme ortamından, işlev çağırmaya uygun rollere sahip bir hizmetin kimliğine bürünme

12. Temizleme

İstenmeyen ödemeleri önlemek için (örneğin, bu Cloud Run işlevi yanlışlıkla ücretsiz katmandaki aylık Cloud Run işlevi çağırma kotanızdan daha fazla çağrılırsa) Cloud Function'ı veya 2. adımda oluşturduğunuz projeyi silebilirsiniz.

Cloud Run işlevini silmek için https://console.cloud.google.com/functions/ adresindeki Cloud Run Cloud Console'a gidin ve imagen-vqa işlevini (veya farklı bir ad kullandıysanız $FUNCTION_NAME) silin.

Projenin tamamını silmeyi tercih ederseniz https://console.cloud.google.com/cloud-resource-manager adresine gidip 2. adımda oluşturduğunuz projeyi, ardından Sil'i seçebilirsiniz. Projeyi silerseniz Cloud SDK'nızdaki projeleri değiştirmeniz gerekir. gcloud projects list komutunu çalıştırarak mevcut tüm projelerin listesini görüntüleyebilirsiniz.