24
16

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.

AIをデーモン化しようとした戦いの記録

Last updated at Posted at 2021-02-05

はじめに

どうも。昨年の4月にプログラミング完全素人の身空で入社し、現在はAIを使った製品を開発しています。
その中で、直近ぶつかった壁とその解決方法を書きました。
「そんなん当たり前やろ!」みたいなこともちょいちょい出てきます。

やりたかったこと

詳しい内容は省きますが、このプロジェクトにおけるAIのタスクは物体検出です。
送られてきた画像に対して処理を行うのですが、画像がいつやってくるかは分かりません。

そこで推論プログラムには、常に画像の有無をチェックし続けて、画像を見つけ次第推論をしてもらうのが適切だろうという結論に至りました。
「常に監視し続ける」ためには、プロセスをデーモン化する必要があったわけです。

環境

  • EC2(Ubuntu 18.04.5 LTS)
  • anaconda(コイツさえいなければもっと楽にできた気がしている)
  • detectron2(正直今回は関係ないです)

デーモン化に使ったのはsystemdです。(いつかpython-daemonも使ってみたいですね。with句だけでデーモンプロセス指定できるとか素敵すぎる)

手順

まず、pythonコードにshebangを記述します。
最近のPythonはshebang無しでも実行できますが、デーモン化する場合はこれがないとsystemdがインタプリタを見失ってしまいます。かわいいね
shebangに書くべきインタプリタは、該当の環境をactivateした状態でwhich python3を叩けば分かるはずです。

なお、ここで改行コードをLFにしておかないと後々エラーが出ます。気をつけよう!(1敗)

次に、Pythonコードに権限を与えてあげましょう。
個人的に権限を数字で示すこの記法は苦手です(へなちょこ)。

$ sudo chmod 0755 /home/ubuntu/hoge/hoge_detection.py

それから、/etc/systemd/system/hoge.service を作成します。ここが一番大事!
下記の設定だと色々と問題が出ます。ソレについては後述

[Unit]
Description = hoge daemonize test

[Service]
WorkingDirectory = /home/ubuntu/hoge
ExecStart = "/home/ubuntu/anaconda3/envs/hoge_env/bin/python3 /home/ubuntu/hoge/hoge_detection.py"  #問題2
Restart = always  #問題1
Type = simple

[Install]
WantedBy = multi-user.target

そして、あとは以下のコマンドで有効化しておしまいのはずでした。

$ sudo systemctl enable hoge
$ sudo systemctl start hoge

問題と解決法

問題1:systemdが落ちる

service starting too early

こんなメッセージが出て、プロセスを再起動できないということがありました。
まぁ 'too early' っていうならちょっと待ってあげようかな‥‥ということで、RestartSec = 10sの記述を足します。
今回のプログラムでは10秒で落ちることなく再起動できましたが、各種条件によってはもっと待ってあげないと動かないかもしれません。

問題2:推論プログラム内でimportError

前述のとおり、該当プログラムはanaconda環境で組んでます。
そのままだとsystemdにはcondaの仮想環境が見えません。だから、インタプリタを教えてあげる必要があったんですね。
一応前述のserviceファイル内では

ExecStart = "/home/ubuntu/anaconda3/envs/hoge_env/bin/python3 /home/ubuntu/hoge/hoge_detection.py"

こう書いてましたが、コレだと仮想環境をactivateできていないので意味がありません。まぁちょっと考えたら当たり前ですね。
こちらの記事を参考にして同じような書き方も試しましたが、何故か上手くいきませんでした。
仕方がないので、conda環境のパスを通すためのシェルを書きます。
といってもただexport書いてもエラー吐いたので、こちらを参考にさせていただきました。

hoge_daemon_test.sh
#!/bin/bash

__conda_setup="$('/home/ubuntu/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/ubuntu/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/home/ubuntu/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/ubuntu/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup

conda activate hoge_env

/home/ubuntu/anaconda3/envs/hoge_env/bin/python3 /home/ubuntu/hoge/hoge_detection.py										

推論プログラムを実行するところまでまとめてしまって、このシェルをExecStartで指定します。

「それは挙動として正しくないんじゃないか。シェルにはconda activateまでをまとめてExecStartPreで走らせて、推論部分はExecStartで動かすべきでは?」

とお思いの方もいらっしゃいますよね。僕もそう思います。
ただStartPreとStartで分けると、折角通したパスや環境が推論プログラムから見えなくなってしまうみたいで‥‥。

問題3:AWSの認証エラー

此度の推論プログラムではAWSのサービスもいくつか利用していまして、認証を通らないと処理が進みません。
手動で実行していた時は問題なく動作していたのですが、デーモン化した途端credentialsが無いよと言われました。
もしやと思い調べてみると、案の定systemdが実行する場合はユーザが変わるようです。
デフォルトだとsystemdはrootとして各プログラムを実行しようとするので、そこも変更してあげなければならなかったようです。

というわけで、idコマンドでユーザとグループ名を確認して追記しました。

最終的に落ち着いた形

[Unit]
Description = hoge daemonize test

[Service]
WorkingDirectory = /home/ubuntu/hoge
ExecStart = "/hoge_daemon_test.sh"
RestartSec = 10s  #追記
Restart = always
Type = simple
User = {ユーザ名}  #追記
Group = {グループ名}  #追記

[Install]
WantedBy = multi-user.target

残っている問題

これで推論プログラムはデーモン化できたのですが、実は推論部分の処理をwhile Trueでループさせています。(デーモン化とは)
モデルの読み込みに時間がかかるので、読み込みは実行開始時の一度だけにしたかったのです。
しかし前述のExecStartPreの問題もあり、別々のプログラムにして実行タイミングを切り分けるのは少し難しいかなと。
ということで基本的にはwhileループで処理を続けるのですが、エラーなどで終了した際に自動で再起動するため悪魔守護神の力を借りています。

正直自分でも忍者のように汚いやり方だと思っているので、上手く分離できるようにもうちょっと捏ねくり回したいところです。

ここまで読んでいただき有難うございます。
以上、AIによる推論をデーモン化する方法でした。

参考リンク

貴重な情報を有難うございました。
jupyterをsystemdで自動起動する
systemd のユニットファイルの作り方
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'. への対処法

24
16
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
24
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?