読者です 読者をやめる 読者になる 読者になる

Grani Engineering Blog

株式会社グラニはC#を中心として、ASP.NET、Unity、VR開発を行っています。

Google 翻訳 Premium (ニューラルネットワーク適用版) を .NET SDK で使えるようにする方法

こんにちは!VR 部の鈴木 (@xin9le) です。前回 (と言ってももう 1 か月も前ですが…) 私が所属する Grani VR StudioProject Sonata というサービスについて紹介させていただきました。Project Sonata にはリアルタイム音声翻訳機能が搭載されているのですが、そこには Google 翻訳 API を利用しています。非常に精度が高く、レスポンスも高速なのでオススメです。Google 翻訳と言えば、最近流行りの (?) ニューラルネットワークを導入したことで話題になりました。

f:id:xin9le:20170403230520p:plain

せっかくなので、ニューラルネットワークの導入によってどの程度の改善が見られたのかパッと調べてみました。

翻訳前の文章 導入前 導入後
今日は何をしてたんですか? Did you have to do today? What were you doing today?
Oculusの展示が見たいです。 Exhibition of Oculus is I want to see. I would like to see the exhibition of Oculus.
賢そうな翻訳ですね。 It is a Ken likely translation. It looks like a clever translation.

導入前の「Ken likely」はさすがにヒド過ぎる…。というのはさておき、導入前とは比べものにならないほど飛躍的な改善が見られます。もはやこれを使わない手はない…!ということで、今回は Google 翻訳 Premium *1 を .NET 環境下で利用する方法についてご紹介します *2

Step.1 : Google 翻訳 Premium への申請

Google 翻訳 Premium を利用するには下記のフォームからプロジェクトを申請し、承認してもらう必要があります。

無事承認が下りれば、利用できるようになります。イキナリ使えるわけではないので注意が必要です。

Step.2 : Google 翻訳 API を使った実装

まず、以下の NuGet Package をインストールしましょう。Google さんが提供する NuGet Package は非常に数が多いので、ちょっと見つけづらいかもしれません。

f:id:xin9le:20170403211559p:plain

PM> Install-Package Google.Apis.Translate.v2

準備が整ったら以下のようなコードを書きましょう。これで Google 翻訳が動きます。

var text = "賢そうな翻訳ですね。";
var initializer = new BaseClientService.Initializer(){ ApiKey = "ひ・み・つ" };
var service = new TranslateService(initializer);
var request = service.Translations.List(text, "en");
var response = await request.ExecuteAsync();
var result = response.Translations.Single();
Console.WriteLine(result.TranslatedText);

// 翻訳結果:
// It is a Ken likely translation.

ですが、サンプルコード中のコメントにもある通り、このままではニューラルネットワークは適用されません!有効化するためには、ほんの少しの対応が必要になります。

Step.3 : ニューラルネットワークモデルの適用

ニューラルネットワークを有効化するための手法は公式ドキュメントに記載されています。

Google Cloud Translation API で、Standard Edition ではなく Premium Edition を使用するように指示するには、リクエスト内で model パラメータを nmt に設定して渡します。model パラメータは現在次の値をサポートしている文字列です。

  • base(デフォルト)は Standard Edition を使用します。
  • nmt は Neural Machine Translation モデルを使用した Premium Edition を使用します。

将来、エディションが追加される場合があります。この model パラメータを GET クエリのパラメータとして、または JSON POST リクエスト内のフィールドとして渡すことができます。

つまり、GET リクエストに対して &model=nmt のクエリ文字列を追加すれば OK ということです。ただ、残念なことに .NET SDK は標準でニューラルネットワークモデルをサポートしていません。なので有効化するには若干のハックが必要となります。対応が必要なポイントは以下の 2 点です。

  • アクセス先の URL を変更 (← .NET SDK がアクセスしている URL が古い
  • &model=nmt のクエリ文字列を追加する

これらを考慮したコードは以下のようになります。

// アクセス先 URL を変更
class NeuralNetworkTranslateService : TranslateService
{
    public NeuralNetworkTranslateService(Initializer initializer)
        : base(initializer)
    {}

    public override string BaseUri
        => "https://translation.googleapis.com/language/translate/";
}

// クエリ文字列に &model=nmt を追加
class NeuralNetworkTranslateRequest : TranslationsResource.ListRequest
{
    // SDK 内部でリフレクションが走って、このプロパティを解釈しにくる
    [RequestParameter("model", RequestParameterType.Query)]
    public string Model { get; }

    public NeuralNetworkTranslateRequest(IClientService service, string text, string languageTo)
        : base(service, text, languageTo)
    {
        // 翻訳アルゴリズムをニューラルネットワークに
        this.Model = "nmt";
        
        // クエリ文字列にするパラメーターを追加
        this.RequestParameters.Add("model", new Parameter()
        {
            Name = "model",
            IsRequired = true,
            ParameterType = "query",
            DefaultValue = null,
            Pattern = null
        });
    }
}

// 実行
var text = "賢そうな翻訳ですね。";
var initializer = new BaseClientService.Initializer() { ApiKey = "ひ・み・つ" };
var service = new NeuralNetworkTranslateService(initializer);
var request = new NeuralNetworkTranslateRequest(service, text, "en");
var response = await request.ExecuteAsync();
var result = response.Translations.Single();
Console.WriteLine(result.TranslatedText);

// 翻訳結果:
// It sounds like a clever translation.

素敵な翻訳結果が返ってきましたね!

まとめ

ほんの少しクエリ文字列を追加するだけにも係わらず、SDK 標準でサポートされていないために結構面倒なコードを書かなければなりません。ただし逃げ道はあるので安心してください。将来的にはきっと対応していただけると思うので、首を長くして待ちましょう :)

*1:ニューラルネットワークが適用された Google 翻訳 API

*2:導入までの手順は公式ドキュメントにも記載されていますが、本稿執筆時点は .NET SDK のサンプルはない