LoginSignup
3
4

More than 1 year has passed since last update.

M1 MacでObject Detection APIの環境構築

Last updated at Posted at 2021-06-25

会社のパソコンでM1チップ搭載のMacを使用しており、そこでObject Detection APIを動かそうとしたらx86_64とArm64の違いにより色々苦労したので、備忘録も兼ねてまとめさせていただきます。間違い等あればご指摘いただけますと幸いです。

結論

M1 Macで、Object Detection APIを動かそうと思ったら、現状Anaconda一択。(miniforgeではなく)

  • x86_64アーキテクチャ上(Rosetta2)で動かすAnacondaを使って、Tensorflowをはじめとするライブラリを、condaを使って入れる。
  • または、Dockerの上にAnacondaを構築し、その上にcondaでライブラリを導入。

Tensorflowは、Arm64向けのものも出ていますが、apache-beamがArm64上ではどうしても入れられなかったためx86_64上に構築するしかなかったです。(apache-beamが依存関係にある、バージョン3.0.0以下のpyarrowに、arm対応のものが存在しないため?)
Tensorflowは、x86_64上にpipで入れた場合、「illegal...」となって動きません。また、ソースからのビルドもできる人がいたら大丈夫かもなのですが、自分の場合ビルドが最後の最後で毎回失敗してしまい、うまくいきませんでした。

前提知識

M1 Macは、armのチップを搭載していますが、x86_64のアプリケーションもRosetta2というエミュレータ上で動かせます。これに伴い、ややこしいことに、ターミナルもarmベースで動くモードとx86_64ベースで動くモードが用意されています。この切り替えには少なくとも2種類の方法があります。
1つ目が、ターミナル上でコマンドを打ってモード切り替えをする方法です。arch -x86_64 zshと打ち込むとx86_64モードに、arch -arm64e zshと打ち込むとarm64モードになります。デフォルトではarm64モードであり、現在のモードはuname -mと打ち込むと確認できます。
2つ目が、ファインダーでアプリケーション>ユーティリティにある「ターミナル」アプリを右クリックして、情報を見るを選択、その中にある「Rosettaを使用して開く」にチェックをつける方法です。これをするとデフォルトでx86_64モードでターミナルが開けるようになります。自分はターミナルアプリを複製して、x86_64版の方を「ターミナル(Intel)」という名前で使っています。

さらに、Macの定番のパッケージマネージャーであるHomebrewにもarm64版とx86_64版があります。arm64版のパスは、/opt/homebrew/bin/brewで、x86_64版のパスは、/usr/local/bin/brewとなっています。
両方入れた場合、brewコマンドではarm64版のパスが優先されて実行されるので、自分はalias brew_x86=/usr/local/bin/brewとして登録し、brew_x86 install 〇〇のような形で実行しています。

インストールの仕方の詳細は、こちらこちらなどを参考にさせていただきました。

手順解説

Anacondaの導入
1. Anacondaをインストール
2. ターミナルを再起動1 (condaのパスが通るように。また、このターミナルはx86_64モードで行うのが安心)
3. 好きなディレクトリに移動
4. conda create -n yourEnvName python=3.6 で仮想環境を作成(python3.6でないと動かないスクリプトがあるため)
5. conda activate yourEnvName で仮想環境の中に入る

Object Detection APIの導入
6. git clone https://github.com/tensorflow/models.git でリポジトリをクローン
7. cd models/research
8. brew install protobuf でprotocol buffersを導入(brewはx86_64版を使う必要あり)
9. protoc object_detection/protos/*.proto --python_out=.
Google公式のGithubでは、このあとsetup.pyを実行することになっているのですが、これはpipでライブラリを入れてしまうので、先にcondaを使って手動でライブラリ追加を行います。

各種ライブラリの導入
1つずつ入れていきます。参考:Anaconda Org
10. conda install -c conda-forge apache-beam -y
11. conda install -c bioconda avro-python3 -y
12. conda install -c conda-forge pillow -y
13. conda install -c conda-forge lxml -y
14. conda install -c conda-forge matplotlib -y
16. conda install -c conda-forge contextlib2 -y
18. conda install -c conda-forge pycocotools -y
19. conda install -c conda-forge scipy -y
残る3つは、condaでは入れられなかったのでpipで入れます
20. pip install lvis
21. pip install tf-slim
22. pip install tf-models-official

tf-models-officialを入れる中で、pip版のTensorFlowが勝手に入るのですが(仮にこれ以前にconda版のTensorflowを入れていても上書きされてしまう)、これはM1チップでは動かないのでcondaで入れ直します。
23. conda install -c conda-forge tensorflow==2.4(デフォルトだと1.14.0が入ってしまうため)

最後にこれらのライブラリ群をobject-detection-0.1という名前でまとめるために、setup.pyを実行します。これを行わないと、cannnot find 'object-detection-0.1'...と怒られます。ちなみにこの時のパスはmodels/researchになっていることをご確認ください。
24. cp object_detection/packages/tf2/setup.py .
25. python -m pip install --use-feature=2020-resolver .

最後に、環境構築が成功しているかのテストを行います。
26. python object_detection/builders/model_builder_tf2_test.py

このテストで、無事にOKが出れば完了です!

Anacondaに落ちつくまでの試行錯誤

それは長い道のりでした。

Tensorflowという強敵

M1 Macは、対応しているアプリケーションがほとんど揃ってきているように思っていたため、油断していました。まさかTensorflowが素直に動いてくれないとは...。

Tensorflowを動かすには、いくつかの選択肢があります。以下は、自分が手を出していった順番です。

arm64で動かす場合
  • Apple謹製Tensorflow-macOSを使う
  • miniforgeというArmに対応したcondaインストーラを使う
  • Dockerにminiforgeを入れて使う
x86_64で動かす場合

arm64での挑戦

armネイティブで構築した方がきっと計算速いよね、という考えにより、最初に手を出したのはTensorflow-macOSでした。import tensorflowが無事に動いたときは感動したものの、Object Detection APIには他にもたくさんの手強いライブラリ達がいます。pandasやmatplotlib、scipyなどpipで直接入れられないものが次々と出てきて、撃沈しました。

次に手を出したのが、miniforgeです。tensorflowは無事に入るし、numpyやscipyなど計算系ライブラリもcondaで入り、滑り出しは良好だったものの、待ち構えていたのはapache-beamでした。まず、condaで探してもPackageNameErrorを宣告されます。めげずにpipを使って入れようとすると、画面が赤い文字で埋め尽くされます。エラーを解読して色々調べると、どうやらpipのapache-beam(2.30.0)は、pyarrowのバージョン3.0.0以下に依存しているらしい。しかし肝心のpyarrowはバージョン4.0.0以上でないとarmに対応していないようで、入らないという...。

x86_64での挑戦

apache-beamやscipyを入れるには、x86_64を使うしか手がない(2021年6月時点)。そう悟ってからは、x86_64アーキテクチャにて構築する道を模索し始めました。ただ、x86_64はapache-beamをはじめとする他のライブラリには優しいのですが、Tensorflowとの相性がよくありません。そこで選択肢として浮上してきたのが、Tensorflowのソースからのビルドでした。ネット上にはそれを成し遂げた方をちらほら見かけたので、きっとできるに違いないとトライしてみたのですが、bazelでのビルドで最後の最後でエラーが出て失敗...。公式のやり方と、sedをgsedに変えて行うやり方を両方試したものの、うまくいきませんでした。ちなみにbazelではなくbazeliskをbrewでインストールしないとバージョン関連で怒られます。

万事休すかと思われたそのとき、救いの光を差し伸べてくれたのがこの記事でした。Rosetta2上でAnaconda経由でtensorflowを入れれば動く、と。
ということで、miniforgeを削除して、本家のAnacondaを入れてみたところ、ばっちり動くではないですか。そして、condaでちゃんと色々見つかる(condaのchannelが、miniforgeだとosx-arm64(miniforge+Dockerだとlinux-aarch64)、Anacondaだとosx-64のため)。

その後、Docker上に構築したUbuntu+Anacondaにも入れてみましたが、無事に動きました。ただしcondaのチャンネルは、ローカルだとosx-64ですが、Docker上だとlinux-64なので、condaでインストールできるものが微妙に異なるようです。

まとめ

M1でもちゃんと機械学習ができる。(ただしarmのネイティブではないのでパフォーマンスの保証なし)
Anacondaが必要なのは、apache-beamやopencvなどの手強いライブラリ達を入れないとダメな場合です。
Anacondaは、環境にガッツリ根付く感じが怖いのとpipとcondaのややこしさが理解できずに今まで避けていました。PATH関係の知識が少しずつつくにつれて大丈夫感が出てきたのとcondaのありがたみを深く実感することになったので、これからもお世話になろうと思います。


  1. なお、Anaconda導入後、勝手にAnacondaの仮想環境(base)に入るようになるのが嫌な人はconda config --set auto_activate_base false とターミナルで入力 

3
4
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
3
4