12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 23

Docker コンテナ上に Bumblebee による画像分類 REST API を構築する

Last updated at Posted at 2022-12-18

はじめに

前回ローカル環境に Phoenix と Bumblebee による AI REST API を実装しました

今回はこれを Docker コンテナで動かします

実装の全量はこちら

実行ファイルの作成

前回作成した Phoenix プロジェクト api ディレクトリー内に serve というファイル名で Phoenix を起動するシェルを作成します

#!/bin/bash

mix phx.server

この serve というファイル名も SageMaker の仕様に沿っています

実行できるように権限を付けておきます

chmod +x serve

chmod がパーミッション(権限)変更コマンドで、 +x 指定で誰でも実行できるようにしています

serving.ex の変更

コンテナで実行する場合、コンテナ内のストレージに保存したファイルはビルド毎に破棄されてしまいます

Bumblebee でダウンロードするモデルのキャッシュディレクトリーはコンテナの外にしておいた方が便利です

lib/api_web/serving.ex をキャッシュディレクトリーを指定するように変更します

...
  @resnet_id "microsoft/resnet-50"
+ @cache_dir "/opt/ml/model"

  def start_link(_opts) do
    {:ok, model} =
-     Bumblebee.load_model({:hf, @resnet_id})
+     Bumblebee.load_model({:hf, @resnet_id, cache_dir: @cache_dir})

    {:ok, featurizer} =
-     Bumblebee.load_featurizer({:hf, @resnet_id})
+     Bumblebee.load_featurizer({:hf, @resnet_id, cache_dir: @cache_dir})
...

依存モジュールとビルド結果の削除

api ディレクトリー配下でローカル実行時に作成されたディレクトリーを削除します

ローカルとコンテナ内では OS が違うため、そのまま同じものを使いまわせないためです

rm -rf _build
rm -rf deps

Docker ファイルの作成

api の親ディレクトリーに Dockerfile を作成します

FROM elixir:1.14.2

RUN mix local.hex --force \
  && mix local.rebar --force

COPY ./api /app

WORKDIR /app

RUN mix deps.get

RUN mix compile.phoenix

RUN chmod +x /app/serve

ENV PATH="/app:${PATH}"

EXPOSE 8080

CMD ["serve"]
  • Elixir 1.14.2 のコンテナをベースにしています

  • api ディレクトリー配下の Phoenix プロジェクトを動かすようにしています

  • コンテナ内でも serve に実行権限を追加しています

  • SageMaker では serve がコンテナ起動時に実行されるため、 PATH に /app を追加して serve だけで実行できるようにします

  • ポート番号 8080 を外部に公開します

docker-compose.yml の作成

Dockerfile と同じディレクトリーに docker-compose.yml を作成します

---

version: '3.2'
services:
  web:
    container_name: phoenix
    build: .
    ports:
      - '8080:8080'
    command: serve
    environment:
      - MIX_ENV=dev
    volumes:
      - ./tmp:/tmp
      - ./models:/opt/ml/model
  • コンテナ内の 8080 を localhost の 8080 に紐づけています

  • コンテナ起動時には serve を実行するようにしています

  • 環境変数 MIX_ENV に dev を指定しています

  • ローカルの ./tmp をコンテナ内の /tmp にマウントします

    Bumblebee は /tmp にまずモデルファイルをダウンロードするため、ここはキャッシュディレクトリーと同じファイルシステムである必要があります

    ./tmp がなければ作成しておいてください

  • ローカルの ./models をコンテナ内の /opt/ml/model にマウントします

    ここが Bumblebee のキャッシュディレクトリーになります

    ./models がなければ作成しておいてください

コンテナの起動

コンテナを起動し、しばらくすると Phoenix が起動します

$ docker-compose up --build
...
Attaching to phoenix
phoenix  | Compiling 11 files (.ex)
phoenix  | Generated api app
phoenix  | [info] TfrtCpuClient created.
phoenix  | [info] Running ApiWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:8080 (http)
phoenix  | [info] Access ApiWeb.Endpoint at http://localhost:8080

動作確認

別のターミナルを開きます

まず ping を確認します

$ curl http://localhost:8080/ping
{}%

空の JSON が返ってきます

次に推論を確認します

@sample.jpg の部分は手元の JPEG ファイルのパスに変えてください

jq をインストールしている場合は jq にパイプすると見やすいです

$ curl -XPOST http://localhost:8080/invocations \
  --data-binary @sample.jpg \
  --header "Content-Type:image/jpeg" | jq
{
  "predictions": [
    {
      "label": "notebook, notebook computer",
      "score": 0.6154251098632812
    },
    {
      "label": "laptop, laptop computer",
      "score": 0.11529479920864105
    },
    {
      "label": "bow tie, bow-tie, bowtie",
      "score": 0.03906528279185295
    },
    {
      "label": "projector",
      "score": 0.0267447829246521
    },
    {
      "label": "dining table, board",
      "score": 0.024912187829613686
    }
  ]
}

まとめ

SageMaker で推論実行できるコンテナの条件が揃いました

  • serve で Web サーバーを起動する
  • ポート番号 は 8080
  • /ping で常に正常応答する
  • /invocations で推論を実行する

次回、このコンテナを SageMaker にデプロイし、 AI のマイクロサービスとして動作させます

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?