Raspberry Pi4でPytorch1.6の環境構築

こんにちは、今回はRaspberry pi4でPytorch1.6の環境を構築していきます。
環境構築ってホント時間消費するし、イライラしまくるので誰かの助けになればいいなと思います。

【環境構築シリーズ】
[Raspberry pi4でPyenv、OpenCV3.4.3、Tensorflow Liteの環境を構築する](https://qiita.com/bigface00/items/1d3586ad8a67fe74a3b2)
[ubuntu16.04でopenpose環境構築](https://qiita.com/bigface00/items/926662c628b417c26516)
# 開発環境
- Ubuntu 18.04 or Ubuntu 20.04（どちらも動作確認済み）
- Ubuntu Mate
- Python 3.7.4以上
- Pytorch 1.6 (1.1, 1.3も構築確認済みで手順もほぼ同じです。ただし1.1はtorchvisionが古いものしか入らないので非推奨です。)

# 前準備
## 必要なライブラリのインストール

```sh:Terminal
sudo apt install libopenblas-dev libblas-dev m4 cmake cython python3-yaml libatlas-base-dev
```
## virtualenvかpyenvをインストール
参考：
[Raspberry pi4でPyenv、OpenCV3.4.3、Tensorflow Liteの環境を構築する](https://qiita.com/bigface00/items/1d3586ad8a67fe74a3b2)
virtualenvであれば、

```sh:Terminal
sudo apt install python3-virtualenv
```

### virtualenvでPython3.7を構築する
---
<b>2020.11.21追記：</b>
Raspberry pi4 Ubuntuの環境でPython3.7を構築しようとすると

```sh
could not build the ssl module!python requires an openssl 1.0.2 or 1.1 compatible libssl with x509_verify_param_set1_host().
```
OpenSSL関連でエラーが出て、一見うまくビルドできたように見えるのですがpip installしようとすると

```sh
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
```
というエラーが出てライブラリがインストールできなくなってしまいます。
色々探した結果、ビルド前にlibssl-devをインストールしておいたほうが良いみたいです。

```sh
sudo apt install libssl-dev
```
参考：[Python pipインストールでHTTPSConnectionPool(host=’pypi.org’, port=443)のエラーメッセージが出た場合の対処について](https://hibiki-press.tech/python/pip-install-errormsg/5021)


<b>2020.12.11追記：</b>
いろいろパッケージが足りないとエラーが出たので、以下を実行してください。

```sh
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget
```
---

[参考URL](https://www.kkaneko.jp/tools/raspbian/raspvirtualenv.html)からvirtualenvの環境を構築した後、

```sh:Terminal
wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz
tar zxvf Python-3.7.4.tgz
cd Python-3.7.4
./configure
make
sudo make altinstall
```
ここで、```altinstall```にしているのは既存のPython3を上書きしないためです。

インストール後、ターミナル上でpython3.7と入力しPythonインタープリタが起動すればOKです。
その後、

```sh:Terminal
virtualenv -p python3.7 pyt_obj
```
### pyenvでPython3.7を構築する
pyenvであればpyenvインストール後、

```sh:Terminal
pyenv install 3.7.4
```

と入力すればpyenv上にPython3.7.4をインストールできます。
その後、

```sh:Terminal
pyenv shell 3.7.4
```
とすれば、ターミナル上のpythonコマンドは全部3.7.4になります。
shellの部分をglobalに変えると、ターミナル切っても3.7.4のままになります。

# Pytorch環境構築
## PytorchのGithubからv1.6.0をクローンする

```sh:Terminal
git clone --recursive https://github.com/pytorch/pytorch  -b v1.6.0
```
もし、1.1や1.3がよければ"v1.6.0"の部分を"v1.3.0"とか"v1.1.0"に変えて下さい。
## Pytorchのディレクトリに移動して、環境変数を設定する
```sh:Terminal
cd pytorch
export USE_CUDA=0 \
export USE_MKLDNN=0 \
export USE_NNPACK=0 \
export USE_QNNPACK=0 \
export USE_NUMPY=1 \
export USE_DISTRIBUTED=0 \
export NO_CUDA=1 \
export NO_DISTRIBUTED=1 \
export NO_MKLDNN=1 \
export NO_NNPACK=1 \
export NO_QNNPACK=1 \
export ONNX_ML=1
```
ここらへんは自分の用途に応じて0を1に変えたり、1を0に変えたりして下さい。
RaspiだとNO_CUDA=1は変えないと思います。
## virtualenvもしくはpyenvで構築したpython3.7上に移動してビルド
virtualenvであれば

```sh:Terminal
source ~/自分で設定したディレクトリ名/bin/activate
```
pyenvであれば

```sh:Terminal
pyenv shell 3.7.4
```
でpython3.7.4上に移動して下さい
pytorchのディレクトリ上で、

<b> [2022/06/25追記] どうやらbuildコマンド自体は使われなくなったようです </b>
なので、以下のコマンドでビルドとインストールが同時に始まります。

```sh:Terminal
sudo python setup.py install
```

下記コマンドでも一応いけますが、終了後、installにするよう促されます。

```sh:Terminal
# python setup.py build
```
~~でビルドが始まります。~~

ビルドはめっちゃ時間かかります。
大体4時間くらいかかった気がするので、プレワークアウトドリンクとしてプロテイン飲んで、1時間後にジム行って、1時間トレーニングして、シャワー浴びれる時間は余裕であります。

### v1.6.0の場合エラーがでる
多分、以下のようなエラーが出ると思います（ビルド60％くらいの時点？）。

```python:Terminal
... 8x8-dq-aarch64-neon.S:662: Error: operand mismatch -- `mov V8.4s,V9.4s'
```

ここは先人の知恵をお借りしましょう。
pythorchディレクトリ内の以下のファイルに移動し、テキストエディタで以下のファイルを開いて下さい。
“/pytorch/aten/src/ATen/native/quantized/cpu/qnnpack/src/q8gemm/8x8-dq-aarch64-neon.S”
690行目あたりに以下のような記述があるので、

```
MOV V8.4s, V9.4s
MOV v10.4s, v11.4s
MOV v12.4s, V13.4s
MOV V14.4s, V15.4s
MOV V16.4s, V17.4s
MOV V18.4s, V19.4s
MOV V20.4s, V21.4s
MOV V22.4s, V23.4s
```
を

```
MOV V8.16b, V9.16b
MOV v10.16b, v11.16b
MOV v12.16b, V13.16b
MOV V14.16b, V15.16b
MOV V16.16b, V17.16b
MOV V18.16b, V19.16b
MOV V20.16b, V21.16b
MOV V22.16b, V23.16b
```
に変えてください。

参考：[Android UserLAnd で PyTorch を使う。C++ API](https://wlog.flatlib.jp/item/1891)
（余談）Androidスマートフォン上にPytorchの開発環境を構築できるらしいですね…すごい…

## ~~ビルド終了後、インストール~~
<b> [2022/06/25追記] 上記でinstallしている場合は、下記コマンドは不要です。 </b>
~~同じディレクトリ上で~~

```sh:Terminal
# sudo python setup.py install
```
~~インストールは30秒くらいで終わります。~~ トレ後のプロテイン作る時間はあると思います。

## 最後の確認
ちゃんとインポートできるか確認するので、ここで注意です。
<b>pytorchのディレクトリから抜けてから、pythonを起動してimportの確認を行って下さい。</b>
というのも、pytorchディレクトリ上だとインストールしたpytorchを見に行ってくれないからです。
多分エラーが出ると思います。

```sh:Terminal
cd $HOME
python
Python 3.7.4 
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>>
```
筋トレお疲れさまでした。

# 参考URL
[Install pytorch](https://gist.github.com/akaanirban/621e63237e63bb169126b537d7a1d979)
[Raspberry Pi 3にPyTorch v1.3.0を入れる](https://qiita.com/yyojiro/items/d91b02149aa6480ded80)
[RaspberryPi3BモデルにPytorch v1.1.0をインストールする](https://qiita.com/makora9143/items/0a9b9b494a59aa7f7c43)