MLを使用した小規模なCLIアプリを開発・運用する機会がありました
時間的な制約があり、使用したことがある技術を中心に構成しました。
開発・運用の関心事と使用している技術の大まかな役割と開発体験について書きます。
開発したアプリ
購買データやユーザデータを加工し、学習させ、複数のユーザに対して推薦する商品を抽出するCLIアプリ
使用技術スタック、ツール
- GCP
- GCE(コンテナホスト用途)
- Stackdriver Logging
- Stackdriver Monitoring
- BigQuery
- GCS
- Docker
- Packer
- Terraform
- Python 3.6
Slack
開発運用したアプリの処理概要と構成
必要データを取得、整形、学習、推論、用途に合わせた活用を行う工程があります。(下記図を参照)DNNを使用する際はコンテナとホスト(GCE)両方の専用イメージを使いました。
GCEインスタンス作成 ~ 廃棄のサイクル
インスタンス作成・起動 -> startup-script(コンテナ実行 -> インスタンス停止コマンド) -> インスタンス廃棄 のサイクルで回っています。インスタンス費用を抑えるために、コンテナの実行が終わった後にホストをshatdownするコマンドを仕込みました。また、永続ディスクの費用の節約のためにもインスタンスの廃棄まで行います。前処理、学習、後処理などはインスタンス1つで実行できる負荷だったためgcloud create instance
でインスタンス作成を行います。推論工程では100~500インスタンス程度のパワーが必要だったので、Terraformを使用しました。Terraformはデフォルトで10インスタンスずつ作成を行いますが、applayコマンドのオプションで数を増やすことができます。50台ずつを指定した際は500台のインスタンスを作成するのに10分かかりません。インスタンスの廃棄はGCPのGUIコンソールから行うのが一番速い気がしますが、Terraformは状態ファイルを持つことで、Terraformで作成したインスタンスのみを削除できる利点があります。
ホスト(GCE)のイメージの運用フロー
aptによるパッケージ追加やdockerセキュリティアップデートが頻繁に発生することが予め分かっており、かつイメージをクリーンに保つため、環境設定を可能な限りシェルスクリプト化しました。スクリプト化できない設定もあったため、手動で設定を行った後に中間イメージを作成し、中間イメージを使用したインスタンスに設定のシェルスクリプトを流しました。中間イメージ作成以降の自動化にはPackerを用いました。(イメージの作成処理は待ちが多くなるので、自動化しましょう。)設定作業を繰り返さないこと、イメージがクリーンに保たれることが精神衛生の向上に繋がります。
コンテナのイメージの運用フロー
コンテナは作って壊してを繰り替えすのが一般的かと思います。
ビルド時間を短縮するために、重い設定は中間コンテナを作成する前に実施しました。
アプリケーション実行ログの確認
Stackdriver Loggingを用いました。Stackdriver Loggingエージェントを入れると特別な設定無しでsyslogの転送が始まります。ログはStackdriver LoggingのGUIコンソールから確認することができます。ログのフィルタ機能が充実しており、特定のインスタンスのログだけに絞り込むのも簡単です。バッチの進行状況の通知としてSlackのAPIを用いていましたが、インスタンスを500台作成した際にSlackのAPIを叩き過ぎて怒られました。そこで、進捗状況の書き込みもStackdriver Loggingで行うことにしました。
ホスト(GCE)リソースの監視とチューニング
ホストのリソース(Memory Usage)監視にはStackdriver Monitoringを用いました。MemoryやCPUを使い切る、かつぎりぎりのところでMemoryOutさせないための監視とチューニングに役立ちます。Stackdriver MonitoringのコンソールGUIでリソースを確認することができます。500インタンス分のデータもレンダリングできていました。Memory、CPU、IOのグラフ描画を見ていると、問題が起きているインスタンスだけ変な描画になったりします。グラフをモニタに映していると、なんだか楽しそうだと人が寄ってきます
以上です