Taste of Tech Topics

Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

AWS SageMaker上でMobileNet SSDのモデルを学習する

皆さんこんにちは。@です
最近、AWSのSageMakerがいくつかアップデートがありました。個人的にはPyTorchのサポートがアツいですね。

さて、今回はSageMaker上で公式がサポートされていないアルゴリズムを学習する場合に、どのような方法があるのかを紹介していきます。
モデルはMobileNet SSDを題材として見ていきましょう。

SDK?コンテナ?

SageMaker上で自前のモデルを作成する方法は2つあります。

  1. SageMaker Python SDKを使う
  2. 自作のDockerコンテナを利用する

1の方法は、各フレームワークごとにSageMaker上で学習するためのスクリプト仕様が決まっていて、その仕様に沿って書けば学習・推論ができるようになっています。
例えばTensorflowであれば以下のページに仕様が載っています。
docs.aws.amazon.com

2の方法は、自分で学習・推論を行うDockerコンテナを定義して、SageMakerから利用する方法です。

今回は2のコンテナを利用する方法でモデルを作成していきます。(理由は後述します)
ただし、今回は学習してモデルを作成するところまでなので、推論は行いません。

今回作成するモデルについて

今回使用するMobileNet SSDは、物体検知のモデルであるSSDをより軽量にしたモデルです。
よくエッジデバイス上での物体検知に用いられます。アルゴリズムの詳細な内容の記載は省略します。
幸いコード自体はObject Detection APIのTensorFlow実装が公開されています。

github.com

今回は、Object Detection APIの学習スクリプトベースに開発します。
Object Detection APIに学習用スクリプトも用意されているため、可能な限り、再利用するために学習用のコンテナを利用します。
AWS SageMaker SDKで学習する場合は、インターフェースに併せて学習スクリプトを再実装する必要があります。
そのため、今回の場合ではObject Detection APIと比較して実装する量が多くなってしまいます。

SageMakerの学習時の仕組み

作業に入る前に、SageMakerで学習する際の仕組みを説明していきます。仕組みの概要は次の通りです。

  1. AWSでもともと用意されているか、または自分で定義したコンテナを立ち上げます。
  2. コンテナ起動時にSageMakerが、S3からコンテナ内に学習データを配置し、学習ジョブを開始します。
  3. 学習が終了後、出力されたモデルファイルはS3に配置され、コンテナを終了する。

f:id:acro-engineer:20180905010101p:plain

仕組みに沿って実装するために開発者が必要な作業は次の通りです。

  1. 学習を実行するイメージを作成する
  2. 作成したイメージをECR(Elastic Container Registry)にpushする
  3. SageMakerから学習ジョブを実行する

学習用コンテナを作成する

まずは学習用のイメージを作成していきます。
基本はObject Detection APIのコードを再利用しつつ、SageMakerのルールに合わせて変更していきます。
変更点は以下の3つです。

  1. コンテナ起動用のスクリプトを用意する
  2. 学習用データを/opt/ml/input/data以下に読みに行く
  3. モデルの出力先として/opt/ml/modelを指定する

コンテナ起動用のスクリプトを用意する

まず、1の変更点についてですが、SageMakerは学習用コンテナを、次のコマンドで起動します。

$docker <image名> train

SageMakerで学習するためにはコンテナ内部の環境変数PATHが読める箇所に、「train」の名前で学習スクリプトを配置する必要があります。PATHはDockerfileにて指定可能です。
そのため、今回は簡単に学習用のコードを実行するshellスクリプトを配置しました。

python object_detection/model_main.py \
    --alsologtostderr \
    --pipeline_config_path="ssdlite_mobilenet_v2_coco.config"  \
    --model_dir="/opt/ml/model"

より適切に実装するなら、Pythonで書いた学習用のコードを実装すべきなのですが、今回は簡単に試してみるということでこのような形にしました。
pipeline_config_pathには、MSCOCOデータセットでMobileNet SSDを学習するための設定ファイルを指定しています。
この設定ファイルはObject Detection APIに標準で用意されています。

学習用データを/opt/ml/input/data以下に読みに行く

次に2の学習用データの配置を設定します。
その前に抑えておく必要があるのは、SageMakerでは、コンテナとS3にあるデータはコンテナ上の/opt/mlディレクトリでやり取りされるということです。
ディレクトリ構造としては

/opt/ml/
    input/
       data/ ・・・S3からのデータが配置される
       config/ ・・・ハイパーパラメータなどの設定が配置される
    model/ ・・・ここに出力されたものがS3に出力される

のようになっています。
例えば、S3に配置されている学習用データは/opt/ml/input/data//に配置されます。
そのため、設定ファイルを以下のように変更することで、S3から配信される学習データを読むようにします。

※一部抜粋
train_input_reader: {
  tf_record_input_reader {
    input_path: "/opt/ml/input/data/train/mscoco_train.record"
  }
  label_map_path: "/opt/ml/input/data/train/mscoco_label_map.pbtxt"
}

ここではchannel名がtrainとなるように設定します。channel名については後ほど、SageMakerの学習ジョブの設定の際に説明します。
なので、後に出てくるSageMaker上でのジョブの設定時も学習データのchannel名をtrainに設定する必要があります。

モデルの出力先として/opt/ml/modelを指定する

また、3の出力するモデルのパスについても、train内でmodel_dir引数に/opt/ml/modelを指定することで、モデルファイルをS3に出力できます。

イメージを作成する

上記の3つを変更したうえで、Object Detection APIが動作するDockerイメージを作成します。
今回使用したDockerfileは以下のようになりました。

FROM python:2.7

RUN apt-get update
RUN apt-get install git -y
RUN pip install tensorflow

RUN curl -OL https://github.com/google/protobuf/releases/download/v3.3.0/protoc-3.3.0-linux-x86_64.zip;\
        apt-get install unzip;\
        unzip protoc-3.3.0-linux-x86_64.zip -d protoc3;\
        mv protoc3/bin/* /usr/local/bin/;\
        mv protoc3/include/* /usr/local/include/

RUN apt-get install python-pil python-lxml python-tk -y; \
            pip install Cython; \
            pip install jupyter; \
            pip install matplotlib; \
            pip install Cython; \
            pip install pillow; \
            pip install lxml; \
            pip install jupyter; \
            pip install matplotlib; 


ENV PYTHONUNBUFFERED=TRUE
ENV PYTHONDONTWRITEBYTECODE=TRUE
ENV PATH="/opt/program:${PATH}"

RUN mkdir /opt/program

RUN mkdir /opt/program/object_detection;\
        mkdir  /opt/program/slim
COPY train /opt/program/
COPY ssdlite_mobilenet_v2_coco.config /opt/program
COPY object_detection /opt/program/object_detection
COPY slim /opt/program/slim

WORKDIR /opt/program

RUN git clone https://github.com/cocodataset/cocoapi.git;\
        cd cocoapi/PythonAPI;\
        make;\
        cp -r pycocotools /opt/program/;

WORKDIR /opt/program

RUN /bin/bash -c "protoc object_detection/protos/*.proto --python_out=./"
ENV PYTHONPATH=$PYTHONPATH:/opt/program:/opt/program/slim

注意事項として、trainスクリプトを実行できるように環境変数PATHにtrainスクリプトが置いてあるパスを指定する必要があります。
この時のディレクトリ構成は以下のようになりました。Object Detection APIの実行に必要なライブラリと学習スクリプトであるtrainを配置しています。

 tf_container/
   object_detection/
   slim/
   train
   Dockerfile

ここで以下のコマンドを実行してDockerイメージを作成します。

$docker build -t object_detection:test .

以上でDockerイメージの作成は完了です。

作成したイメージをECRにpushする

次に作成したイメージをSageMaker上から指定できるようにECRにpushします。

#作成したイメージにタグ付けする
$docker tag object_detection:test <アカウントID>.dkr.ecr.<リージョン>amazonaws.com/object_detection:deploy3 
#作成したイメージをpushする
$docker push <アカウントID>.dkr.ecr.<リージョン>amazonaws.com/object_detection:deploy3

この際、認証周りのエラーが出た場合は以下を参考にECRの認証設定を行ってください。docs.aws.amazon.com

以下のようにリポジトリにタグ名が表示されていれば大丈夫です。
f:id:acro-engineer:20180702001100p:plain:w700

SageMakerから学習ジョブを実行する

それではいよいよ学習ジョブを実行していきます。
まずは、S3に学習用データを配置します。
f:id:acro-engineer:20180702001116p:plain:w700
注意事項としてbucket名にsagemakerという文字列が含まれている必要があります。

次に、学習ジョブを設定していきます。
SageMakerのトレーニングジョブの作成画面で以下のように設定していきます。
f:id:acro-engineer:20180702001451p:plain:w700

f:id:acro-engineer:20180702001944p:plain:w700

f:id:acro-engineer:20180702002510p:plain:w700

f:id:acro-engineer:20180702003003p:plain:w700

しばらくすると、ログに学習が進んでいる様子が出力されます。
f:id:acro-engineer:20180702004154p:plain:w800

学習が終了するとS3にモデルファイルが出力されます。
f:id:acro-engineer:20180702091601p:plain:w800

まとめ

今回はSageMaker上でコンテナからMobileNet SSDを学習してみました。
展望としては、epoch数などをハイパーパラメータから設定できればよりジョブを管理しやすくなりますね。
とはいえ、Dockerイメージを作成してしまえば、好きな環境で学習できるのでお手軽だと思いました。
それではまた。

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

ElasticStack 6.4がリリースされました!

皆さんこんにちは@です。
昨日、Elastic Stackの6.4がリリースされました。
6.4で追加された機能のうち、面白いと思う機能をご紹介します。
今回のリリースは、開発者に優しい機能追加が多いように見えます。

データ準備

6.4からElasticsearch、Kibanaのサンプルを画面から素早く準備できます。
従来のElasticsearchでは、機能を試すためのデータを準備しなければならず、手間でした。
これがほんのわずかな時間で準備できるのは魅力的です。実際に試したので手順を載せます。

まずは、サンプルデータが準備されている画面に「Load a data set and a Kibana dashboard」をクリックして移動します。
f:id:acro-engineer:20180827005042p:plain:h300

次にflight dataをロードします。Addをクリックし、しばらく待つとロードが完了します。
f:id:acro-engineer:20180827005150p:plain:h300

Discoverを見て、データを確認できれば投入ができています。
f:id:acro-engineer:20180827004936p:plain:h300

このとき、データをロードするだけでなく、Kibanaのindex patternやダッシュボードも作られます。
これは便利ですね。

f:id:acro-engineer:20180828111430p:plain:h300

Elasticsearch APM

Elasticsearch APMは主に2つの機能が追加されました。
得られた結果を検索するためのUI(検索窓)とMachine Learning機能を組み合わせた高度な検知です。
これにより、より検索性の向上やサービス監視が強化されました。

また、JavascriptRubyのAgentが正式版になったようです。

Kibana

scripting field作成時にバリデーションをかけられるようになり、より便利に扱えるようになりました。

今まで、scripted fieldは作成時に値を確認することができませんでした。
そのため、Discover画面に遷移してから文法エラーに気づくことも度々....

6.4では作成画面にpreview機能が搭載されました。
値を横のwindowで確認しながら書けるので、ミスを防ぐことができます。

f:id:acro-engineer:20180828065734p:plain:h300


DashboardやVisualizationのrelationshipを確認できる機能も追加されています。
「このDashboardには、どのVisualizationが使われているんだっけ?」と思い出すのは大変ですよね。

Saved Objectの画面から簡単に確認できるようになりました。
例えば、下の画像では「Sample Dashboard」に使われているVisualizationを確認しています。
f:id:acro-engineer:20180828071359p:plain:h300

もちろん逆も可能で、該当Visualizationが使用されているDashboardの一覧も取得できます。
f:id:acro-engineer:20180828071524p:plain:h300

これで削除する時にも安心ですね。

Machine Learning

Machine Learningの他機能連携、及び、かゆい部分に手が届く機能の追加がされました。
Machine Learning機能に詳細設定ができるCustom Ruleが追加されました。

この機能により異常検知するための条件を指定でき、ドメイン知識をMachine Learningへ取り込めます。
例えば、指定のIPアドレスのみの場合に検知するなど細かい設定ができます。

また、APMとの連携、Job Management画面の改良が行われ、使いやすさも向上したと思います。

Beats

BeatsへDissect processorが導入されました。
Dissect processorはLogstashに実装されているDissect FilterをBeatsで実現するものです。
この実装には正規表現が含まれないため、Grok Filterと比較して高速に処理できるそうです。
これによりBeatsで簡単なパース処理が可能となりました。

Beatsから直接Elasticsearchにデータ送信するケースが増えそうな気がします。

最後に

リリースのたびに面白い機能が追加されています!
細かい新規機能は別の記事でご紹介したいと思います
今回も使い勝手が良くなる機能が多くあります。せっかくなので、使い倒していきましょう!

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップの求人 - Wantedlywww.wantedly.com

Convolutional Neural Networkを使う自然言語処理論文読破に挑戦!(後編)

皆さんこんにちは、@です。

数ヶ月前にConvolutional Neural Networkを使う自然言語処理論文の文書分類について紹介しました。
acro-engineer.hatenablog.com

今回の後編では機械翻訳や系列ラベリング、そして、その他利用されている分野を紹介します。

Question Answer

QANet: Combining Local Convolution with Global Self-Attention for Reading Comprehension

f:id:acro-engineer:20180428205111p:plain:h250

Recurrent Neural Network(RNN)は畳み込みと比較して計算時間がかかることが知られています。
そのため、畳み込みやSelf-Attentionを用いる構造を使って、高速化を行いました。

RNNと比較し、学習時で最大13.3倍、推論時で8.9倍の高速化を実現しました。
畳み込みが局所的な特徴、Self Attentionが大域的な特徴を獲得しています。

ニューラルネットワーク以外で面白いと思ったアイデアはデータを増加している部分です。
QAデータ(質問と回答のデータ)を機械翻訳を活用して増加させています。
例えば、英語 ⇒ フランス語 ⇒ 英語と翻訳することで、「原文とは異なる文章、かつ、同じ意味」の英語を生成しています。
このタスク以外でも自然言語のタスクであれば、応用できる方法です。

https://arxiv.org/abs/1804.09541

機械翻訳

Quasi-Recurrent Neural Networks

f:id:acro-engineer:20180424085048p:plain:h200
CNNを使って、高速な機械翻訳を行う論文です。
タイトルにはRecurrent Neural Networkと書いてありますが、利用しているアーキテクチャはCNNです。
CNNを用いて、擬似的(Quasi)にRNNを実現しています。

CNNの畳み込みでLSTMが持つ隠れ層や出力層、セルを表現しています。
畳み込みの後にf-pooling, fo-pooling, and ifo-poolingと呼ばれるPooling手法がLSTMにある構造の表現に該当します。(論文中式(3)〜(5))
Poolingに畳み込みと要素積を用いており、従来まで利用されているLSTMの実装と比較して高速な演算が可能です。
LSTMと比較し、性能が3倍高速化し、更に精度も向上しています。

https://arxiv.org/abs/1611.01576

Convolutional Sequence to Sequence Learning

f:id:acro-engineer:20180430110938p:plain:h250

InputとDecoder(左下)の埋め込みベクトルに畳み込みを行います。
これに前編で紹介したGLUの手法を用いて特徴量を獲得します。

Multi-step Attentionと呼ばれる構造で各予測のタイミングでAttentionを計算しています。
Multi-step Attentionは人間で言えば、翻訳時振り返って単語を探す行為と同様と主張しています。
最後にAttentionの計算結果とDecoderの結果を使って、次の翻訳単語を予測します。

こちらの記事に詳細なキーアイデアの紹介が記載されています。
https://code.facebook.com/posts/1978007565818999/a-%20novel-approach-to-neural-machine-translationcode.facebook.com

https://arxiv.org/abs/1705.03122

分かち書きなどの分割

Convolutional Neural Network with Word Embeddings for Chinese Word Segmentation

Chinese Word Segmentation(CWS)のタスクでは、既存の手法でも精度よく中国語の分かち書きができています。
この論文では、従来までの手法について、2つの課題があることを述べ、それに対するアイデアを提案しています。

  1. bigramなどの特徴量を人間の手で設計する必要がある。
    畳み込み演算を使い、人間による特徴量設計を行わず、特徴量を獲得しています。
  2. 言語が持つ情報を使い切れていない。文字と単語の情報の組み合せ、単語の特徴量を獲得しています。

この工夫により、PKU, MSRデータセットでState of the artを達成しました。

http://aclweb.org/anthology/I17-1017

A Deep Convolutional Neural Model for Character-Based Chinese Word Segmentation

入力文の各位置の表現を行うPosition Embedding Module、複数の下位表現を組み合わせた位置表現の役割を持つDeep Representation Module、最後にTag Scoring Moduleによりタグ付けを行います。
畳み込みを用いることで、階層的な表現を獲得することを目的としています。

このニューラルネットワークでは、複数のタスクを学習するMulti-task Learningにより標準的な特徴量を獲得しています。
ただし、データセットによって文書の分割の基準が異なることから、異なるデータセットを同様のTag Scoring Moduleで判定していません。

そのため、Tag Scoring Moduleに関して各々のタスクで再学習を行っています。

http://tcci.ccf.org.cn/conference/2017/papers/1075.pdf

Image Caption Generator

Image Caption Generatorは画像を入力として与えた場合、説明文を生成します。
一般的な手法は画像特徴の抽出にCNN, 文書生成にRNNを利用する方式です。
今回は、画像特徴・文章生成を共にCNNで行った手法を紹介します。

Convolutional Image Captioning

f:id:acro-engineer:20180730224543p:plain:h250

従来までのLSTMを用いた方式では、勾配消失問題が問題になっていました。
近年の翻訳や条件付き画像生成の研究では、畳み込み演算を用いて勾配消失が起きないようにしています。
その流れによってImage CaptioningにもCNNを適用しています。
CNNを用いることで1パラメータ辺りの学習時間は高速になっています。

LSTMとCNN間の交差エントロピー誤差を比較していますが、誤差の値はLSTMより非常に高いグラフとなっています。
しかし、単語の一致度ではCNNと同程度の性能を発揮しています。
CNNの方が、情報量が多いことがこの事象の理由としていますが、非常に面白い結果だと思います。

[1711.09151] Convolutional Image Captioning

その他

Improving Word Embeddings with Convolutional Feature Learning and Subword Information

f:id:acro-engineer:20180426225532p:plain:h250

Convolutional Neural Networkとsubword(部分語)の情報を使い、Word Embeddingの精度改善を行っています。
部分語はTri-Gram、接頭語、接尾語、-s, -ingなどを変化なしに変換した語(inflectional Affix)を用いたベクトルの生成を行っています。
そして、誤差関数は周辺単語から得られたContext VectorとWord間の距離(Similarity and Not Similarity)を考慮した計算式になっています。

この手法は類似語検索やWord AnalogyのタスクでState of the artを取得しています。

https://www.aaai.org/ocs/index.php/AAAI/AAAI17/paper/download/14724/14187

最後に

Convolutional Neural Networkは様々な分野で利用されており、自然言語処理の分野における活用を紹介しました。
画像処理の論文が多く、自然言語処理の論文は意識しないと読まないので、畳み込みやRNNの課題などを勉強する良い機会となりました。
自然言語処理に適用するにあたり、CNNの利点を工夫して活かそうとしているのが良いと思っています。

自然言語処理において、Recurrent Neural NetworkかConvolutional Neural Networkのどちらが主流になるか
まだまだわからないので、引き続き追いかけようと思います。

参考文献

  1. Convolutional Neural Netwoks で自然言語処理をする
  2. A novel approach to neural machine translation – Facebook Code
  3. [DL輪読会]Convolutional Sequence to Sequence Learning

Acroquest Technologyでは、キャリア採用を行っています。


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析案件で時系列データの異常検知に挑戦したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

「量子コンピュータはじめの一歩」オフ会でLTを行いました

こんにちは、@です。

このところ、あちこちで量子コンピュータに関する勉強会が開催され、盛り上がりを感じています。
私自身もこの分野に興味を持ち、量子コンピュータに関するブログを書いたり、LTしたりといった活動を行っています。
note.mu

昨日は、CQ出版社Interface編集部さん主催で「量子コンピュータはじめの一歩」オフ会が開催されたため、参加してきました。
inteface-meet-up.connpass.com

この会では、Interface 8月号に「量子コンピュータはじめの一歩」を執筆された京都大学・藤井啓祐 准教授の講演と、一般から募集したLTが行われました。

私も「量子コンピュータのプログラミング・コンテスト体験記」と題したLTを行いました。

www.slideshare.net

私のLTでは、先日開催された量子コンピュータのプログラミング・コンテスト「Microsoft Q# Coding Contest」について、参加者視点で様子や感じたことをお話ししました。
codeforces.com

今回のコンテストに参加してみて、量子プログラミングの楽しさを感じることができたのは良かったです。
決められたルールの範囲で量子ビットを操作し、求める結果に変化させていく点はパズルっぽいです。
そのため、パズルが好きな人は、量子プログラミングに向いているんじゃないかと思います。


また、気さくな方が多く、懇親会も楽しく過ごさせて頂きました。
私自身、量子コンピュータについて勉強中なため、藤井先生に様々なことを教えて頂き、大変勉強になりました。
CQ出版社編集部のみなさん、講演者・参加者のみなさん、ありがとうございました!
また、こういう会があったら参加したいです😊

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

データ分析基盤Elasticsearchを使い倒したいエンジニア募集! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

社内勉強会でリアクティブについて発表した

こんにちは!こんばんは!Javaエンジニアの しんどー です。腹筋ローラーで今日も腹が痛い!

さて、AcroquestではLTxRTという社内勉強会があり、最近勉強した技術やプロジェクトのフィードバックなどが頻繁に行われています。

私も先日、「Spring WebFluxで学ぶReactive Application」というタイトルで発表しました。

"リアクティブ"とだけ書くと文脈によってイメージが全然違ってしまうのですが、今回はサーバサイドでのリアクティブについて解説しました。

JavaでリアクティブというとRxJavaを思い浮かべる方は多いと思います。国内ではLINEさんがRxJavaをサーバサイドで利用して、APIを非同期化する取り組みを行っていますね。

そして2017年10月にリリースされたSpring Framework 5.0で、Spring WebFluxというリアクティブなWebフレームワークがついにサポートされるようになったのです! (興奮気味なのは単に私がSpring好きなせいですw)

発表ではリアクティブの背景的な部分から入り、リアクティブのメリット/デメリット、ユースケースなどを説明しました。Spring WebFlux自体の説明が薄くなってしまったのはご愛嬌です。

スライドの最後にも書きましたが、リアクティブは正直難しくまだまだ勉強が足りていません・・・
ですが今後のサーバサイド開発で重要性が増すことは間違いないので、くじけずにやっていきます!!!

f:id:acro-engineer:20180802185855j:plain
こんな感じでやってます

Acroquestに興味を持った方はこちら↓↓からご連絡ください!

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

AWS X-RayをServerless Frameworkで簡単構築・可視化まで

こんにちは!エンジニア3年目、フロントエンド&AWSサーバーレス系エンジニアを目指し勉強中のmiuraです。

サーバーレス構成だと簡単に立ち上げられる一方で、ある程度の開発規模になってくると非同期に連携したり、複数のサービスが関係したりするので、
エラーになった際にどこで失敗しているのか、デバッグしていくのが大変になることがありませんか?
または、レンスポンスが遅いと感じるがどのAWSサービスが起因して遅くなっているか確認するのが大変だと思ったことがありませんか?

そこで活躍するのがAWS X-Rayです。
AWS X-Rayはトレース対象であるサービスのリクエスト・レスポンス情報を収集するサービスで、
AWSコンソールにて収集した結果をマップ形式で見ることができ、各サービスの実行時間をグラフで可視化することができます。

今回はサーバーレスアプリへのX-Rayの適用を、Serverless Frameworkを用いて簡単に追加し、AWS上で可視化するところまでを紹介します。

全体構成

f:id:acro-engineer:20180318152127p:plain:w600

全体構成図中の①、②に分けて話をします。
API GatewayからAWS Lambdaの実行
 AWS LambdaがAPI Gatewayをトリガーとして実行されていることを可視化してみます。

AWS LambdaからAWS SNSやDynamoDBの呼び出し
 ①で作成したAWS LambdaからAWS SNSを呼び出し、AWS SNSをトリガーに実行されるAWS LambdaにてDynamoDBの操作が行われていることを可視化してみます。

ツール/ライブラリ

ツールとライブラリは以下のものを使います。

  • サーバーレス
名前 バージョン
Serverless Framework 1.20.2
AWS SDK for JavaScript 2.176.0
AWS X-Ray SDK for Node.js 1.1.6
serverless-plugin-tracing 2.0.0


  • 開発
名前 バージョン
Python 3.6
AWS X-Ray SDK for Python 0.96

API GatewayからAWS Lambdaの実行

以前使用したServerless Frameworkを今回も使います。

まずはPython3系用のサンプルプロジェクトを作成します。

serverless create --template aws-python3 --path aws-x-ray-serverless
cd aws-x-ray-serverless

次に、Serverless FrameworkのX-Rayプラグインをインストールし、serverless.ymlにAWS X-Rayを有効にする設定と
API Gatewayの設定を行います。

npm install aws-sdk aws-xray-sdk serverless-plugin-tracing

aws-x-ray-serverless/serverless.yml

service: aws-x-ray-serverless

plugins:
  - serverless-plugin-tracing # トレース有効用のプラグイン

provider:
  name: aws
  runtime: python3.6
  region: us-west-2
  apiKeys:
    - aws-x-ray-serverless-api-key
  tracing: true # X-Rayでのトレースを有効にする
  iamRoleStatements:
    - Effect: Allow
      Action:
        - xray:PutTraceSegments # X-Rayにセグメントドキュメントをアップロードする権限を付与する
        - xray:PutTelemetryRecords # X-Rayにテレメトリをアップロードする権限を付与する
      Resource: "*"

functions:
  hello:
    handler: handler.hello
    events:
     - http: # API Gatewayの設定
        path: hello
        method: get
        private: true

以上で、AWS X-RayおよびAPI Gatewayの設定ができました!
このようにプラグインをインストールし、serverless.ymlにたった数行設定を書くだけでX-Rayを適用することが出来ます。

早速、AWSにデプロイをしましょう。

sls deploy

デプロイが完了したら、curlコマンドやRestClientなどでAPI Gatewayを呼び出してLambdaを実行させます。

curl -s 【API GatewayのURl】 -H "x-api-key:【APIキー】"

すると、実行結果をAWSコンソールのX-Rayのサービスにて見ることが出来ます。

f:id:acro-engineer:20180318175904p:plain:w800

緑色の円が表示されていることからLambdaの実行は成功したことが分かります。
5xxエラーや4xxエラーなどがある場合、赤色や黄色で表示してくれるのでひと目でどこに問題があるかを確認できます。
中央の数字はそのサービスでの平均レスポンス時間と 1 分間に送信したトレース数を表しており、どこで処理に時間が掛かっているのかなども確認することが出来ます。

本格的なプロダクトともなると、多くのLambdaを互いに呼び出す形で作ることになります。
その際にどこでエラーになっているかを上図のようなサービスマップで簡単に確認できるのは、私のような開発者にとっては嬉しい機能ですよね。

また、円グラフをクリックすればさらに詳細なトレース情報を見ることが可能です。
トレースについては次の構成での結果で説明します。

AWS LambdaからAWS SNSやDynamoDBの呼び出し

①でClient、API Gatewayを通してLambdaを実行する流れをAWS X-Rayで表示しました。
そこで次に、①の続きとしてAWS LambdaからAWS SNSやDynamoDBを呼び出して、それをAWS X-Rayで表示してみましょう。

まずは、AWS LambdaでのAWS SNSDynamo DBの呼び出しをトレースをするためにPythonAWS X-Ray SDKをインストールします。

pip install aws-xray-sdk -t .

次に自動生成したhandler.pyとserverless.ymlの一部を編集します。

aws-x-ray-serverless/handler.py

# -*- coding: utf-8 -*-
import json
import boto3

# AWS X-Rayのライブラリを読み込み
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

# AWS X-Rayのパッチを適用
patch_all()


def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }

    # AWS SNSを呼び出し
    sns = boto3.client('sns')
    try:
        sns.publish(
            TopicArn="arn:aws:sns:us-west-2:471043657237:hello",
            Subject=body['message'],
            Message=json.dumps(body['input'])
        )
    except Exception:
        raise

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }

    return response


# AWS SNSで受け取った情報をDynamoDBに保存するLambdaスクリプト
def put_hello(event, context):
    sns = event['Records'][0]['Sns']

    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('hello_log')

    try:
        table.put_item(
            Item={
                "timestamp": sns['Timestamp'],
                "id": sns['MessageId'],
                "subject": sns['Subject'],
                "message": sns['Message']
            })

    except Exception:
        raise

aws-x-ray-serverless/serverless.yml

provider:
  name: aws
  runtime: python3.6
  region: us-west-2
  apiKeys:
    - aws-x-ray-serverless-api-key
  tracing: true
  iamRoleStatements:
    - Effect: Allow
      Action:
        - xray:PutTraceSegments
        - xray:PutTelemetryRecords
        - sns:Publish # AWS SNSをPublishする権限を追加
        - dynamodb:PutItem # DynamoDBのテーブルにItemをPutする権限を追加
      Resource: "*"

functions:
  hello:
    ...

  # AWS SNSをトリガーに実行されるLambdaを追加
  putHello:
    handler: handler.put_hello
    events:
     - sns: hello

# DynamoDBのテーブルを追加
resources:
  Resources:
    helloLogTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        TableName: hello_log
        AttributeDefinitions:
          - AttributeName: timestamp
            AttributeType: S
        KeySchema:
          - AttributeName: timestamp
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 2
          WriteCapacityUnits: 1

気づきましたでしょうか?
AWS LambdaでのAWS SNSDynamo DBの呼び出しをトレースすると聞くといろいろな設定が必要そうと感じますが、
実際にX-Rayの適用として追加で記述したのは、

  • patch_all()

だけ。
これだけでAWS SNSDynamo DBを呼び出すboto3などのライブラリにX-Ray用のパッチが適用されてトレースが出来るようになります。
この手軽さは正直異常ですね(^^;

実際に再度デプロイコマンドを実行して、curlコマンドやRestClientなどでAPI Gatewayを呼び出してみます。

sls deploy
curl -s 【API GatewayのURl】 -H "x-api-key:【APIキー】"

結果、AWSコンソールのX-RayのサービスにてAWS SNSやDynamoDBへのフローも表示されるようになりました。
Service Mapの下段にあるClientはAPI Gatewayを通してAWS Lambda、そしてAWS SNSを呼び出しており、次のトリガーとなっています。
上段のClientがそのAWS SNSから呼び出されたことを表しており、AWS Lambdaを通してDynamo DBにエラーなくアクセスしていることが分かります。

f:id:acro-engineer:20180501175611p:plain:w800

そして、赤い枠にあるような円グラフをクリックするとサービスの所要時間をヒストグラムで確認することができます。
これにより、レスポンスとしては正常な200ステータスとなっているが、異様に時間が掛かっている場合がないかを確認することが出来ます。

f:id:acro-engineer:20180709075033p:plain:w800

さらに、Tracesの詳細を見ることでクライアント呼び出しからレスポンスまでの流れをタイムラインで見ることが出来ます。
上記で異様に時間が掛かっている場合の原因が、DynamoDBの呼び出しで時間が掛かっているのかそれ以外なのかをこれで調査することが出来ます。

f:id:acro-engineer:20180709075836p:plain:w800

実際に、Lambdaのレスポンスが異常に遅いことが発覚し調査を行った際、Tracesの詳細を見ることでDynamoDBの呼び出しに時間が掛かっていることが分かったことがありました。
その時の原因としては、あるDynamoDBのテーブルがいろんなところから呼び出されており、設定していたスループットを超過して制限が掛かっていたことが判明しました。
こういったこともX-Rayを見れば簡単に調査することが魅力的ですね。

まとめ

どうでしたでしょうか。
今回みたいに簡単な準備と実装だけでAWS X-Rayを適用することができ、AWSのさまざまなサービスの連携をトレースできます。
特にAWS SNSなどはCloudWatchでトレースするとなると、呼び出しが失敗したのか、トリガーが失敗したのかなどをそれぞれログを確認することになるため大変です。
それをAWS X-Rayを使えばちょっとの実装だけでひと目で確認できるようになります。

また、Lambdaで所要時間が異様に時間が掛かっているがその原因がどこにあるのかをCloudWatchで見ようとすると、各ログの時間を調査していく必要がありますが、
詳細なトレース結果を見ることでX-Rayで簡単に突き止めることが出来るようにもなります。

CloudWatchでのトレースで苦労した経験ある方はぜひAWS X-Rayを適用してみてください。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

JJUGナイトセミナーで「はじめてのElasticsearchクラスタ」を発表しました

こんにちは、@です。

昨日、JJUGナイトセミナー「Elasticsearch特集」が開催されました。
jjug.doorkeeper.jp

この会で「はじめてのElasticsearchクラスタ」 と題したセッションを発表しました。

www.slideshare.net

Elasticsearchはカジュアルに動かせるのですが、本番運用でのトラブルをいくつか目撃してきました。
原因を確認してみると、設計すべき点が実施されておらず、本番運用に入っていた件が見受けられます。
特に、分散システム特有の「設計すべき点」もあり、慣れていないと気づかないこともあります。

そこで、次の2点についてセッションで発表しました。

  • 分散システムの視点から見たElasticsearchクラスタの仕組み
  • 安全なクラスタにするために本番運用前にやっておくべきこと

分散システムに慣れていないと難しい内容もあったかと思いますが、Elasticsearchを動かした事がある方や、これから本番運用を迎える方に喜んで頂けたようで、何よりでした。
懇親会では、様々な方からフィードバックを頂きました。ありがとうございます。
今後もElasticsearchに役立つ情報をアウトプットしていこうと思います。

また、GPTW「働きがいのある会社」ランキング1位、に興味を持たれた方もいらっしゃったのは嬉しかったです。
オープンでフラットな働きやすい会社ですので、気になる方はぜひ以下のページを訪問してみてください😊

Acroquest Technologyでは、キャリア採用を行っています。


  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

データ分析基盤Elasticsearchを使い倒したいエンジニア募集! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com