stylesheet

2018-08-25

HerokuのDocker Deployで機械学習APIを5ステップで作成

HerokuでDockerが使えるようになっていたので、遅まきながら、機械学習を使ったAPIを5ステップで作成してみた。

STEP1: 事前準備

herokuへサインアップし、APPを作成。
また、herokuコマンドとdockerをインストールして使えるようにしておく。

STEP2: サンプルコードを入手

heroku公式のminicondaイメージのサンプルコードがあるので、コレをベースに使用。

$ git clone https://github.com/heroku-examples/python-miniconda.git

ざっと中身を確認すると、

  • python 2.7
  • miniconda環境構築済み (condaコマンドが使える)
  • scikit-learn導入済み
  • webフレームワークはflask
  • gunicornでwsgi
  • ポート番号は環境変数PORTで指定

となっていた。

STEP3: APIを実装

heroku用だろうと特に変わることはないので、いつものようにサクッと実装する。

開発中にライブラリを追加した場合は、Dockerfileへの反映も忘れずに。

pandas等condaで追加するもの -> Dockerfile内のconda installに追記
pipでインストールするもの -> requirements.txt

STEP4: ローカルで動作チェック

Dockerコンテナを起動して動作を確認する。

引数指定がめんどうなので、docker-compose.ymlを作成してdocker-composeを使用することにする。

# docker-compose.yml
version: "2"
services:
  app:
    build: .
    ports:
      - "8100:8100"
    environment:
      PORT: "8100"

コンテナ起動とブラウザで動作チェック。

$ docker-compose up
$ xdg-open http://localhost:8100

STEP5: herokuへデプロイ

ここからがherokuで行う操作となるが、いくつかコマンドを打つだけで本番反映まで行える。素晴らしい。

$ heroku login
Email: nobody@somewhere.com
Password: ********
$ heroku container:login
$ heroku container:push web -a アプリ名
$ heroku container:release web -a アプリ名

以上で完了。

終わり

Heroku の Docker Registry & Runtime (Docker Deploy)は、ほぼストレスフリーで簡単に使用できる完成度の高いプラットフォームと思う。

詰まったところといえば、サンプルコードのREADME.md記載の手順が少し古かったところぐらい。
container-registry用のpluginをインストールするよう書かれていたが、現在は不要。

作ったもの

結局、何を作ったかというとIPO銘柄の初値予想APIを作った。
過去のIPOデータを学習させてRidge回帰で暴騰率を予測させている。スコア的には残念だが、雰囲気はでていると思う。

ブラウザの場合は、http://ipo-cal.herokuapp.comへアクセスするとGUIで試せる。

API本体はhttp://ipo-cal.herokuapp.com/api/predictで公開している。
curlだと以下のように呼び出す。

$ curl -X POST \
  -H "Content-type: application/json" \
  -d '[{"code":"4385", "market":3, "sector":25, "price": 3000.0, "fund":122142.9, "kobo":18159.5, "uri":22554.8}]' \
  http://ipo-cal.herokuapp.com/api/predict

{"data":[{"code":"4385","inflation":189.6046720498996,"price":5700,"rank":3}],"status":"success"}

json文字列をhttp://ipo-cal.herokuapp.com/api/predictへpostするだけでOK。
配列にして一度に50件までまとめて実行できる。

レスポンスはJsendに概ね準拠している。

レスポンスがなかなか返ってこない時は、サーバーがスリープしている。コンテナが起動するまでしばらくかかるので、10秒ほど待機してからリトライしてみて欲しい。

2018-08-03

arm64版armbianでpuppeteerを使う

puppetterはnodejsからheadless-chromeを使用するためのライブラリ。
こちらもarm64環境では素直に動かなかったのでメモ。

環境

  • Orange Pi Win Plus
  • ARMBIAN 5.41 stable Ubuntu 16.04.5 LTS 3.10.107-pine64
  • nodejs v8.11.3

問題点

  • npmインストール時にchromeバイナリが自動ダウンロードされるがarm64版ではないので起動しない。
  • 手動でarm64版をダウンロードして置き換えようにも、そもそもarm64版のスナップショットは公式で提供されていない。
  • armbian(ubuntu)がarm64版のchromiumを提供しているが少しバージョンが古い。Chromium 68.0.3440.75
  • 最新のpuppeteer v1.6.1が対応するchromeはChromium 69.0.3494.0 (r575458)。
  • chromiumのような大きなアプリケーションをセルフビルドするのは嫌だ。

対処

  • 古いのを承知でaptパッケージのchromium-browserをインストール。
  • 対応chromeのバージョンが近いpuppetter v1.4.0で妥協。
  • aptパッケージのchromiumを使う。(executablePath/usr/bin/chromium-browserを指定)
$ sudo apt install chromium-browser
$ npm install puppeteer@1.4.0 
const puppeteer = require('puppeteer')

(async () => {
    const browser = await puppeteer.launch({
      executablePath: '/usr/bin/chromium-browser'
    })
    ...
})()

以上の対処で今回のケースでは一応動作した。
早くarm64もメジャーなアーキテクチャになって欲しいところ。