public note

Cloud Translation を Ruby で実行する

巨人の肩の上に立ち、言葉の壁を乗り越えます。

悩み

  • 英語のエラーメッセージで何を言われているのかわからない
  • 関数や変数の命名で適切な言葉が浮かばない
  • コミットメッセージをそれっぽい文章にしたい

インターネット翻訳サービスの力を借りる場面ですが、Webブラウザに切り替えて調べるのは面倒です。僕はGCPを使うことにしました。

Cloud Translation

GCPには、 Cloud Translation というサービスがあります。これを使って、任意の文章を別の言語に翻訳します。 Basic(v2)Advanced(v3) の2種類があります。

Basic(v2) と Advanced(v3) の違い

  • Basic(v2): Google の汎用翻訳モデルを使います。翻訳前の言語検出も自動でしてくれます。
  • Advanced(v3): Basic の機能に加えて、自身で用意した用語集やカスタム翻訳モデルを使うことができます。また、GCSを経由して一括翻訳することができます。

詳細については、以下のページにまとめられています。

Advanced か Basic の選択  |  Cloud Translation  |  Google Cloud

(いったい、v4 ではどんなネーミングになるんだ…ごくり…)

対応言語

100以上の言語に対応しています。

Language support  |  Cloud Translation  |  Google Cloud

料金

  • 最初の 500,000 文字: 無料
  • 500,000 から 10 億文字: $20 /1,000,000 文字

1 か月以内に 575,000 文字を処理するように送信した場合、$1.50 が請求されます。最初の 500,000 文字が無料で、言語検出、翻訳、またはその両方を行った残りの 75,000 文字に対して請求が発生します。

料金  |  Cloud Translation  |  Google Cloud

僕のようなライトな用途であれば、無料です。

Rubyでの実装

GitHub - tosh223/rbtrslt

Basic(v2)

v2 では API key が使えますので、手軽に試すことができます。API key を適当に作成して、環境変数に設定しています。

require 'net/http'
require 'uri'
require 'json'

def translate(contents, source, target)
  url = URI.parse('https://translation.googleapis.com/language/translate/v2')
  params = {
    q: contents,
    source: source,
    target: target,
    key: ENV['GOOGLE_CLOUD_API_KEY']
  }
  url.query = URI.encode_www_form(params)
  res = Net::HTTP.get_response(url)
  JSON.parse(res.body)['data']['translations'].first['translatedText']
end

Advanced(v3)

一方 v3 では、追加機能の特性から API キーは使用できませんので、SDKを使用します。サービスアカウントを作成して、Cloud Translation API UserのRoleを設定します。

require 'google/cloud/translate'

def translate(contents, source, target)
  project_id = `gcloud config configurations list | grep True`.split[3].strip
  location_id = 'global'

  client = Google::Cloud::Translate.translation_service
  parent = client.location_path(project: project_id, location: location_id)
  client.translate_text(
    parent: parent, contents: contents,
    source_language_code: source, target_language_code: target
  )
end

所感

冒頭のような用途では、v2 でもオーバースペックです。一方でビジネスでの利用を考えると、業界や会社ごとの専門用語によって汎用的なモデルでは対応できないので、v3 を使うことになると思います。今回、v2 と v3 で同内容のリクエストを行っていますが、処理速度は v2 のほうが早いです。v3 は高機能な分、やることが増えて遅くなったのかな、と雑な感想を持ちました。*1

$ time bundle exec ruby trslt_api_v2.rb "Ruby is so fun, isn't it?"
ルビーはとても楽しいですよね?

real    0m1.541s
user    0m0.699s
sys     0m0.075s

$ time bundle exec ruby trslt_api_v3.rb "Ruby is so fun, isn't it?"
ルビーはとても楽しいですよね?

real    0m3.321s
user    0m2.861s
sys     0m0.223s

*1:計測にあたって、v3 ソースコード内の project_id をハードコードしました。gcloud コマンドが遅く、比較をするうえでフェアでないためです