Azure App Service(Linux) に DeepFace + TensorFlow + OpenCV をデプロイしてハマったこと全部

Azure App Service(Linux) に DeepFace + TensorFlow + OpenCV をデプロイしてハマったこと全部

環境

  • Azure App Service (Linux) / Python 3.10
  • Flask API(Gunicorn起動)
  • DeepFace(年齢/性別/感情/※人種)+ OpenCV
  • TensorFlow(CPU)

症状とエラーログ(時系列)

  1. ImportError: libGL.so.1
    OpenCV のランタイム依存がコンテナに入っていない。
  2. ModuleNotFoundError: deepface
    Azure の Oryx が作る一時仮想環境と ZIP デプロイの噛み合わせで、パッケージ解決が不安定に。
  3. ModuleNotFoundError: tensorflow.keras / WARNING: TF_USE_LEGACY_KERAS
    mtcnntensorflow.keras を要求、しかし Keras 3 系の互換と混在して崩れる。
  4. NumPy 2 系の地雷
    AttributeError: _ARRAY_API not found / numpy.core.umath failed to import
    → TensorFlow 2.1x は NumPy<2 を想定。途中で numpy 2.x が入ると崩壊。
  5. WORKER TIMEOUT → 無限再起動
    初回リクエストで DeepFace の巨大モデル(Race/FairFace ≒ 539MB)をDL&初期化 → Gunicorn 既定 30s を超過 → ワーカーKill → 再起動 → またDL…地獄。

最終的に安定した解

1) requirements.txt を“TensorFlow 2.19 系 + NumPy<2”で固定

ポイント

  • numpy==1.26.4 に固定<2 厳守)。これで _ARRAY_API 系エラーが消えます。
  • tf_keras==2.19.0 + TF_USE_LEGACY_KERAS=1 を使うと DeepFace との相性が安定。
  • 検出器は mtcnn を使わず mediapipe or opencv にすると tensorflow.keras 依存の地雷を踏みにくい。

2) startup.sh(Startup Command)で全部面倒を先回り

Azure ポータルでの設定

  • App Service → 構成全般設定Startup Command
    /home/site/wwwroot/startup.sh を設定(ZIP デプロイ先基準)
  • リポジトリ側で startup.sh に実行権限:chmod +x startup.sh(CI で zip するときに属性が落ちても、App Service は shebang で動きます)

3) app.py で環境変数&DeepFace呼び出しの最適化

ポイント

  • detector_backend='mediapipe' が CPU で速くて安定。
  • race が不要なら削る → 初回 539MB のDLが無くなり、タイムアウトの根本原因が消える。
  • どうしても race が必要なら、起動時プリウォームと --timeout=600 でOK。

4) GitHub Actions(ZIP デプロイ)のコツ

  • 必要なファイルだけ ZIPvenv.git は除外)
  • Zip の中に startup.sh とアプリ一式が入っていることを確認

うまくいく理由(根治ポイント)

  • OpenCV の共有ライブラリを apt で注入 → libGL.so.1 消滅
  • NumPy を <2 に固定 → TF 2.19 と ABI が揃い、_ARRAY_API 地雷を回避
  • Keras の互換を固定tf_keras==2.19.0 + TF_USE_LEGACY_KERAS=1)→ tensorflow.keras の不整合を抑止
  • Gunicorn を --preload + --workers=1 → モデル初期化を1回だけに
  • Race 先読み or 無効化 + --timeout=600 → 初回重い処理で落ちない
  • DeepFace キャッシュを永続領域 /home/site に退避 → 再起動しても再DLしない

よくある質問(運用Tips)

Q. 起動が遅い / タイムアウトする
A. Startup でプリウォーム + --timeout=600race を外すのが最速。

Q. CPU でなるべく軽くしたい
A. detector_backend='mediapipe'。OpenCV より検出精度・速度のバランスが良いです。

Q. 再起動のたびにモデルをDLしたくない
A. DEEPFACE_HOME=/home/site/deepface(永続化)を必ず設定。

Q. それでも落ちる
A. App Service の Always On を有効化。SKU が小さすぎる場合はプランのメモリを増やすか、workers=1 のままにしてスループットはスケールアウトで対応。


仕上げチェックリスト

  • requirements.txtTF 2.19 / tf_keras 2.19 / numpy 1.26.4 に固定
  • startup.shStartup Command に設定(権限/パスOK)
  • Race不要なら除外、必要ならプリウォーム
  • DEEPFACE_HOME/home/site/deepface
  • Gunicorn は --preload --workers=1 --timeout=600
  • App Service「構成 → 全般 → Always On = On」

参考スニペット一式(貼るだけセット)

requirements.txt → 上記の最終版
startup.sh → 上記の最終版
app.py 冒頭

DeepFace呼び出し

About The Author

Hideki
東京大学発AIスタートアップ企業でロボット開発室室長、画像解析室室長、動画解析室室長を務め、AIエンジニアとしても画像認識関連の特許を在籍中に3つ取得。その後、KDDIグループ内でプロダクトリーダーとして自然言語処理パッケージの自社開発を経て、現在はAGRISTのテックリードとして農業の人手不足の解決に向けた収穫ロボットの開発にチャレンジしている。ロボットは技術の総合格闘技との考え方から、AIだけでなく、ハードやエレキ、通信からクラウド、IOTまで幅広く手掛けることができる。最近では人とロボットの共存を目指すべく、性能だけを追い求める開発から「感動やワクワク体験」をデザインできるロボットの研究を進めており、人とロボットがうまく共存できる世界を作り出したいと日々行動している。

LEAVE A REPLY

*
*
* (公開されません)