Alibaba Cloud ECSを使用した事前学習済みのWord2VecディープラーニングREST APIの作成と導入

このチュートリアルでは、**Word2Vec**という事前学習済みの**ディープラーニング**モデルを、一からREST APIを構築して他のサービスで利用できるようにします。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-create-and-deploy-a-pre-trained-word2vec-deep-learning-rest-api_594064)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#前提知識
1、Alibaba Cloud Elastic Compute Service (ECS)インスタンスなどのUnixベースのマシンで、できればより多くの計算能力を持つことが望ましい。
2、`python`、`pip`コマンドの理解
3、Linuxオペレーティングシステムを使用してフォルダやファイルを作成、閲覧、編集する方法の知識

#Wordベクター入門
Wordベクターは、その柔軟性とトレーニングのしやすさから、最近ディープラーニングの世界を揺るがしています。ワードエンベッディング（word embeddings）は、NLPの分野に革命をもたらしました。

その中核となるのは、ワードエンベッディングとは、それぞれが単一の単語に対応するワードベクトルであり、そのベクトルが単語を「意味する」ようなものである。これは、king - queen = boy - girlのベクトルのような特定の現象によって実証されます。単語ベクトルは、レコメンドエンジンから英語を実際に理解するチャットボットまで、あらゆるものを構築するために使用されています。

もう一つの考慮すべき点は、どのようにして単語の埋め込みを得るかということです。単語の埋め込みはランダムではなく、ニューラルネットワークを訓練することによって生成されます。最近の強力なワードエンベッディングの実装は、GoogleのWord2Vecという名前のもので、言語の中で他の単語の隣に現れる単語を予測して学習します。例えば、「猫」という単語に対して、ニューラルネットワークは「子猫」と「猫」という単語を予測します。このように、お互いに「近くに」現れる言葉を直感的にベクトル空間に配置することができるのです。

しかし、迅速にプロトタイプを作成し、展開プロセスを簡素化するために、Googleのような他の大企業の事前学習済みモデルを使用するのは業界標準です。このチュートリアルでは、GoogleのWord2Vecの事前学習済みワードエンベッディングをダウンロードして使用します。これを行うには、作業ディレクトリで以下のコマンドを実行します。

```
wget http://magnitude.plasticity.ai/word2vec/GoogleNews-vectors-negative300.magnitude
```

#Pythonの環境設定
Pythonの環境を設定することは、機械学習アプリケーションを開発する上で明らかに重要な要素です。しかし、このプロセスは見落とされがちです。Python の依存関係を使用する場合のベストプラクティスは、明示的な `requirement.txt` ファイルと同時に仮想環境を使用することです。これにより、複数のマシンや環境にまたがるデプロイメントと開発の両方において、ライブラリの管理が容易になります。

最初に、python モジュールである `virtualenv` をインストールします。これにより、ライブラリが互いに干渉しないように作業ディレクトリを分離することができます。

```
pip3 install virtualenv
```

次に、`venv`という名前の仮想環境を作成します。同じpythonのバージョンを指定することと、一貫して使用することの両方が重要であることに注意してください。最良のサポートを得るためには、Python 3 を使用することをお勧めします。`venv`フォルダにはrequirements.txtで指定したすべてのpythonモジュールが格納されます。

```
virtualenv -p python3 venv
```

仮想環境を作ったとはいえ、まだ起動していません。プロジェクトとその依存関係を使用するには、`source`を使用してソースを作成しなければなりません。実際に`source`を呼び出すファイルは、`bin`という名前のフォルダにある`activate`という名前のファイルです。

```
source venv/bin/activate
```

プロジェクトを終了したり、仮想環境を切り替えたい場合は、deactivateコマンドを使って仮想環境を終了させます。

```
deactivate
```

#Magnitudeパッケージのインストール
ダウンロードしたワードエンベッディングモデルは`.magnitude`形式です。この形式では、SQLを使って効率的にモデルをクエリすることができるため、本番サーバーに最適なエンベッディング形式となっています。`.magnitude`形式を読めるようにする必要があるので、`pymagnitude`パッケージをインストールします。また、モデルによって作られたディープラーニング予測を後で提供するために`flask`をインストールします。

```
pip3 install pymagnitude flask
```

また、以下のコマンドで依存性トラッカーに追加します。これにより`requirements.txt`というファイルが作成され、Pythonライブラリが保存されるので、後で再インストールすることができます。

```
pip3 freeze > requirements.txt
```

#モデル予測の作成
まず、単語の埋め込みを開いたり、問い合わせたりするためのファイルを作成します。

```
touch model.py
```

次に、`model.py`に以下の行を追加してMagnitudeをインポートします。

```
from pymagnitude import Magnitude 
vectors = Magnitude('GoogleNews-vectors-negative300.magnitude')
```

単語の引数を提供する`query`メソッドを使用することで`gensim`パッケージとディープラーニングモデルを楽しむことができます。

```
cat_vector = vectors.query('cat')
print(cat_vector)
```

しかし、私たちのAPIのコアについては、2つの単語間の意味の違いを返す関数を定義します。これは、レコメンデーションエンジンのようなもの（類似した単語を含むコンテンツを表示する）のためのほとんどのディープラーニングソリューションのバックボーンとなっています。

`similarity`や`most_similar`を使用することで、この関数で遊ぶことができます。

```
print(vectors.similarity("cat", "dog"))
print(vectors.most_similar("cat", topn=100))
```

以下のように類似度計算機を実装します。このメソッドは次節でFlask APIから呼び出されます。この関数は0から1の間の実数を返すことに注意してください。

```
def similarity(word1, word2):
    return vectors.similarity(word1, word2)
```

#REST APIでモデルをラップする
`service.py`というファイルに以下の内容でサーバーを作成します。コンテンツを提供するために `Flask` という名前のサーバーフレームワークを使用します。DjangoのようなWebベースのサーバーフレームワークは他にもありますが、オーバーヘッドが最小限で、統合が容易で、ディープラーニングコミュニティ内でサポートされていることから、Flaskを使用します。

`service.py`という名前のファイルを以下の内容で作成します。サーバー機能を扱うために`flask`と`request`をインポートし、先ほど書いたモジュールから類似性エンジンをインポートします。

```
from flask import Flask, request
from model import similarity

app = Flask(__name__)

@app.route("/", methods=['GET'])
def welcome():
    return "Welcome to our Machine Learning REST API!"

@app.route("/similarity", methods=['GET'])
def similarity_route():
    word1 = request.args.get("word1")
    word2 = request.args.get("word2")
    return str(similarity(word1, word2))

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000, debug=True)
```

私たちのサーバはむしろむき出しですが、`@app.route`デコレータを使ってより多くのルートを作成することで簡単に拡張することができます。

#アプリケーションのDocker化
Dockerはアプリケーションをコンテナ化するのに便利なツールです。コンテナとは、動作に必要な依存関係をすべて含んだ自己完結型のアプリケーションのことです。開発やテストが容易になるだけでなく、複数のマシンを使うことが多いデプロイにも特に便利です。Dockerコンテナは、仮想マシンなどの重い仮想化が使用するハードウェア層ではなく、オペレーティングシステム層でのみ仮想化するため、軽量です。

コンテナ化のプロセスを開始するには、まずDockerfileを作成することから始めます。DockerfileはDockerプロセス全体のエントリーポイントです。このファイルを使用して、依存関係の定義、ファイルへのアクセス、環境変数の設定、アプリケーションの実行を行います。

```
touch Dockerfile
```

次に、現在のディレクトリがDockerfileのディレクトリコンテナであることを認識するためのDocker用のコマンドを追加します。次に、サーバー用のPythonの依存関係をインストールします。

```
WORKDIR /
ADD requirements.txt /
RUN pip install -r requirements.txt
```

次に、ワードエンベッディングをダウンロードできるようにwgetをインストールします。MV Dockerコマンドを使用して、Flaskサーバで使用している規約に合わせて名前を変更します。

```
RUN apt install wget
RUN wget http://magnitude.plasticity.ai/word2vec/GoogleNews-vectors-negative300.magnitude
```

最後に、最後の行をDockerfileに追加してサーバーを起動します。これでFlaskサーバーが起動します。

```
CMD [ "python", "./service.py" ]
```

#Docker化されたアプリケーションを実行する
イメージを作成するためにDockerを使用することで、モデルを独自の標準化されたコンテナにビルドすることができます：モデルのインスタンスを瞬時に作成するための標準化された命令セットです。

最初に`docker build`コマンドを実行し、イメージの名前を作成するために`-t`フラグを指定し、DockerにDockerfileがカレントディレクトリにあることを知らせるために` .`を指定します。

```
docker build -t model .
```

最後に、`docker run`コマンドを使ってイメージを実行し、`-p`フラグを指定してモデルを8000番ポート(Flaskサーバが動作しているポート)にバインドし、8000番ポート(ローカルホストで使用したいポート)に公開します。

```
docker run -p 8000:8000 model
```

APIコールの作成
私たちのサーバーはlocalhost:8000で利用できるようになりました。localhost:8000/similarity?word1=cat&word2=dogでデータベースにクエリを実行し、ブラウザまたは別のAJAXクライアントを介してレスポンスを表示します。

APIをテストするもう一つのオプションはコマンドラインを使うことです。GETルートを使用してAPIをテストするためにブラウザ(すなわちChromeやSafari)を使用することができますが、POSTリクエストを使用できないために制限されています。別の方法としては、Unix オペレーティングシステムに同梱されている `curl` ツールを使用する方法があります。

`curl` を使って `word1` と `word2` の両方の引数を指定し、コマンドラインでレスポンスを表示します。

`curl -X GET 'http://localhost:8000/similarity?word1=dog&word2=cat'`

私たちの端末では、正確に分類された回答を見ることができるはずです。

#展開
このプロセス全体は、ローカルマシンでも、Alibaba Cloudなどのクラウドサービスプロバイダでも実行できます。しかし、Dockerの利点は、ローカルマシン上でモデルを開発し（つまり`service.py`ファイルを作成）、その後Dockerを使用してサーバー上でモデルを実行できることです。これにより、高速な開発と高速なデプロイの両方が可能になります。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*