BigQuery リモート関数で Cloud Translation API を使ってテキスト翻訳してみた

2022.11.30

こんにちは!エノカワです。

BigQuery のリモート関数を使用すると、 Cloud Functions 関数を SQL クエリから呼び出すことができます。
APIコールなど SQL だけでは実現できない状況において、リモート関数は活用できそうです。

そこで今回は、リモート関数で Cloud Translation API を使ってテキスト翻訳する、といったことを試してみましたので、ご紹介します。

下記エントリでは、リモート関数で Natural Language API を使った事例が紹介されていますので、こちらも是非ご参照ください!

Cloud Translation API とは

API を使用してプログラムによってテキストを動的に翻訳できるサービスです。
Google の事前トレーニング済みモデルを使用して翻訳しています。

100 以上の言語ペアのテキストを翻訳でき、原文テキストの言語がわからない場合でも Cloud Translation で検出できます。
サポートされている言語は、下記ページをご覧ください。
※Cloud Translation API で使用する言語コードパラメータは ISO-639 の識別子に準拠しており、下記ページで確認できます。

段取り

ワークフローの概要 | BigQuery ドキュメントに倣い、以下の段取りで進めます。

  1. Cloud Functions で HTTP エンドポイントを作成します。
  2. BigQuery にリモート関数を作成します。
    a. CLOUD_RESOURCE 型の接続を作成します。
    b. リモート関数を作成します。
  3. クエリ内でリモート関数を使用します。

Cloud Functions 関数を作成

リモート関数で呼び出す Cloud Functions 関数を作成します。

今回はHTTPトリガーで以下のPythonコードを実行するget_translate_textという名前のという名前の Cloud Functions 関数を作成しました。

main.py

import json
import six
from google.cloud import translate_v2 as translate


def translate_text(target, text):

    translate_client = translate.Client()

    if isinstance(text, six.binary_type):
        text = text.decode("utf-8")

    return translate_client.translate(text, target_language=target)


def get_translate_text(request):
    try:
        request_json = request.get_json()
        calls = request_json['calls']
        return_value = [translate_text(target, text) for target, text in calls]

        return json.dumps({"replies": return_value})
    except Exception as inst:
        print(f'inst: {inst}')
        return json.dumps({"errorMessage": 'something unexpected in input'}), 400

Cloud Translation API を使用して、テキストを指定の言語に翻訳する Python コードです。

下記ドキュメントのサンプルコードを参照させていただきました。

Cloud Translation API 用のパッケージインストールが必要なため、requirements.txtも合わせてデプロイしました。

requirements.txt

google-cloud-translate>=2.0.1

CLOUD_RESOURCE 接続を作成

Cloud Shell からbq mkコマンドを使用して、BigQuery の CLOUD_RESOURCE 接続を作成します。

※以降、実際のプロジェクト番号プロジェクトIDはそれぞれ{PROJECIT_NUMBER}{PROJECT_ID}に置き換えています。

bq mk --connection \
    --display_name='translation api test' \
    --connection_type=CLOUD_RESOURCE \
    --project_id={PROJECIT_ID} \
    --location=asia-northeast1 \
    remote-function-test

CLOUD_RESOURCE 接続を作成すると、接続に関連付けられたサービスアカウントが作成されます。

bq showコマンドを使用して、サービスアカウントIDを確認します。

bq show --location=asia-northeast1 --connection  remote-function-test

properties のserviceAccountIdの値がサービスアカウントIDになります。

Connection {PROJECIT_NUMBER}.asia-northeast1.remote-function-test

    name                              friendlyName       description    Last modified         type        hasCredential                                            properties                                            
--------------------------------------------------- ---------------------- ------------- ----------------- ---------------- --------------- ----------------------------------------------------------------------------------------------- 
{PROJECIT_NUMBER}.asia-northeast1.remote-function-test   translation api test                 28 Nov 09:29:14   CLOUD_RESOURCE   False           {"serviceAccountId": "bqcx-{PROJECIT_NUMBER}-mnyn@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}

Cloud Functions 関数に権限を付与

接続に関連するサービスアカウントには、Cloud Functions 関数に対する権限を付与する必要があります。

Cloud Functions コンソールから先ほど作成したget_translate_textに Cloud Functions 起動元(cloudfunctions.functions.invoke)のロールを付与します。

リモート関数を作成

BigQuery コンソールからCREATE FUNCTIONステートメントを実行し、リモート関数を作成します。

  • 翻訳先の言語(target)、原文テキスト(text)の引数をSTRING型で受け取り、結果をJSON型で返し関数として定義
  • endpointには、Cloud Functions 関数のエンドポイントのURLを指定
CREATE OR REPLACE FUNCTION rf_work.get_translate_text(target STRING, text STRING) RETURNS JSON
REMOTE WITH CONNECTION `{PROJECIT_NUMBER}.asia-northeast1.remote-function-test`
    OPTIONS (
        endpoint = 'https://asia-northeast1-{PROJECIT_ID}.cloudfunctions.net/get_translate_text'
    )

クエリでリモート関数を使用する

準備が整いました!

BigQuery コンソールでリモート関数を使用してみましょう。

テキスト翻訳:日本語 → 英語

以下のクエリを実行して、日本語から英語に翻訳してみます。

  • 翻訳先の言語は英語なので、第一引数targetenを指定
SELECT
  rf_work.get_translate_text('en', text) AS translate_en
FROM
  UNNEST([
    'Cloud Translation とは',
    'Cloud Translation を使用すると、ウェブサイトやアプリケーションで、API を使用してプログラムによってテキストを動的に翻訳できます。',
    'Translation は、Google の事前トレーニング済みモデルか、カスタム機械学習モデルを使用して、テキストを翻訳します。'
    ]) AS text

Cloud Translation API レスポンスのtranslatedText翻訳テキストが確認できます。
また、input原文テキストdetectedSourceLanguage検出された言語も確認できます。

原文テキストを日本語として検出し、指定した英語に翻訳することができました!

テキスト翻訳:英語 → 日本語

逆方向の翻訳も試してみましょう。

以下のクエリを実行して、日本語から英語に翻訳してみます。

  • 翻訳先の言語は日本語なので、第一引数targetjaを指定
SELECT
  rf_work.get_translate_text('ja', text) AS translate_ja
FROM
  UNNEST([
    'Working with Remote Functions',
    'A BigQuery remote function allows you to implement your function in other languages than SQL and Javascript or with the libraries or services which are not allowed in BigQuery user-defined functions.'
    ]) AS text

原文テキストを英語として検出し、指定した日本語に翻訳されていますね!

テーブルのテキストフィールドを翻訳

最後にテーブルのフィールド値を引数にしてリモート関数を使用してみます。

テキスト翻訳先の言語のフィールドを持つテーブルを作成します。

以下のクエリを実行します。

  • target_languagetextフィールドを引数に指定
  • JSON_VALUEで翻訳テキスト(translatedText)を抽出
SELECT
  text,
  target_language,
  JSON_VALUE(rf_work.get_translate_text(target_language, text).translatedText) AS translatedText
FROM
  rf_work.sample_text

各レコードの翻訳先の言語に応じた結果になっていますね!

Cool!
Remote function!
(語彙力)

まとめ

以上、リモート関数で Cloud Translation API を使ってテキスト翻訳してみました。

Cloud Functions 関数を作成して呼び出すことができるので、翻訳先の言語を指定するといった要件に応じた形でテキスト翻訳サービスを利用できるのは便利だと感じました。

リモート関数を使うことで、BigQuery の機能が拡張された感覚になりました。
別のAPIでも試してみたいと思います!

参考