IoTの世界でAIを使ったときに、何ができるの?といった相談というか、なんとなくな話題を振られることがちょくちょくあります。周りの人たちが割と伝聞でいろいろ語っていることが多いので、検証した上で会話できるように準備したいと思っています。
私がとりあえず思いつくところでは、①クラウドなどのサーバー側に大量の計測データを貯めてApache Spark MLなどで学習と推論をおこなう、②データ取得する場所に近い、いわゆるエッジ側で推論を行うエッジAI、などが考えられると思うのですが、エッジAIについて検証してみたいと思います。
エッジ AIのハンズオン利用にあたっては、以下の3つがよく挙げられると思っていて順に試したいと思っています。
手始めに、Intel Neural Computestickを使ってみます。とはいえ、それなりの道筋があるので、ステップ・バイ・ステップでゆるく進めていきますが。
IntelではOpenVINOをいうツールキットを提供しています。Intel NCSだけでなく、PCの環境でも開発を進められるようになっています。ゆくゆくはRasPi+Intel NCSで試すつもりですが、まずはUbuntu上で試してみます。UbuntuなどのLinuxの場合以下のリンクのインストラクションに従っていけば、割と素直にインストールされます。
https://docs.openvinotoolkit.org/2020.2/_docs_install_guides_installing_openvino_linux_fpga.html
以前、Ubuntu 16.04 LSTを使っていたときに、開発環境をインストールしたらボロボロになったので、恐る恐るUbuntu 18.04 LTS環境にインストールしてみたのですが、すんなりインストールできました。
ちなみに、環境的にはAnacondaでPython周りは構築していて、Pythonバージョンは 3.7.6です。OpenVINOはIntel用のツール環境なので、CPUの世代が重要なのですが、第6世代から第10世代までがサポートされています。私の実行した環境は以下のように、第8世代(i7-8750H)となっています。
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 12
On-line CPU(s) list: 0-11
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 158
Model name: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Stepping: 10
CPU MHz: 1011.686
CPU max MHz: 4100.0000
CPU min MHz: 800.0000
BogoMIPS: 4399.99
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 9216K
NUMA node0 CPU(s): 0-11
OpenVINOのツールキットは、TensorFlowやONNX(PyTorchから利用?)、Caffeeなどで学習・生成した推論モデルを、Intelのハードウェアで実行出来るようにする機能が入っています。小さなデバイスで利用できるようにQuantization、Freezing,、Fusionといった処理を施します。Intelの世界では「最適化」と言っていますが、ざっくりいうと問題ない程度に正確さを犠牲にして、モデルサイズを縮小し、処理パワーの小さなエッジデバイスでも実行出来るようにしています。
例えば、TensorFlowから出力されたモデル
http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
を「最適化」しているのが以下のステップです。モデルをダウンロードして、Pythonで最適化処理を実行しています。
(base) :~/git/ndopenvino/13_ModelOptimizer$ wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
--2020-04-26 09:13:54-- http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz
Resolving download.tensorflow.org (download.tensorflow.org)... 172.217.25.240, 2404:6800:4004:80f::2010
Connecting to download.tensorflow.org (download.tensorflow.org)|172.217.25.240|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 187925923 (179M) [application/x-tar]
Saving to: ‘ssd_mobilenet_v2_coco_2018_03_29.tar.gz’
ssd_mobilenet_v2_co 100%[===================>] 179.22M 9.42MB/s in 19s
2020-04-26 09:14:13 (9.24 MB/s) - ‘ssd_mobilenet_v2_coco_2018_03_29.tar.gz’ saved [187925923/187925923]
(base) :$ tar -xvf ssd_mobilenet_v2_coco_2018_03_29.tar.gz
ssd_mobilenet_v2_coco_2018_03_29/checkpoint
ssd_mobilenet_v2_coco_2018_03_29/model.ckpt.meta
ssd_mobilenet_v2_coco_2018_03_29/pipeline.config
ssd_mobilenet_v2_coco_2018_03_29/saved_model/saved_model.pb
ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb
ssd_mobilenet_v2_coco_2018_03_29/saved_model/
ssd_mobilenet_v2_coco_2018_03_29/saved_model/variables/
ssd_mobilenet_v2_coco_2018_03_29/model.ckpt.index
ssd_mobilenet_v2_coco_2018_03_29/
ssd_mobilenet_v2_coco_2018_03_29/model.ckpt.data-00000-of-00001
(base) hajime@hajime-DAIV:~/git/ndopenvino/13_ModelOptimizer$ cd ssd_mobilenet_v2_coco_2018_03_29/
(base) hajime@hajime-DAIV:~/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29$ python /opt/intel/openvino/deployment_tools/model_optimizer/mo.py --input_model frozen_inference_graph.pb --tensorflow_object_detection_api_pipeline_config pipeline.config --reverse_input_channels --tensorflow_use_custom_operations_config /opt/intel/openvino/deployment_tools/model_optimizer/extensions/front/tf/ssd_v2_support.json
[ WARNING ] Use of deprecated cli option --tensorflow_use_custom_operations_config detected. Option use in the following releases will be fatal. Please use --transformations_config cli option instead
Model Optimizer arguments:
Common parameters:
- Path to the Input Model: /home/hajime/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb
- Path for generated IR: /home/hajime/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29/.
- IR output name: frozen_inference_graph
- Log level: ERROR
- Batch: Not specified, inherited from the model
- Input layers: Not specified, inherited from the model
- Output layers: Not specified, inherited from the model
- Input shapes: Not specified, inherited from the model
- Mean values: Not specified
- Scale values: Not specified
- Scale factor: Not specified
- Precision of IR: FP32
- Enable fusing: True
- Enable grouped convolutions fusing: True
- Move mean values to preprocess section: False
- Reverse input channels: True
TensorFlow specific parameters:
- Input model in text protobuf format: False
- Path to model dump for TensorBoard: None
- List of shared libraries with TensorFlow custom layers implementation: None
- Update the configuration file with input/output node names: None
- Use configuration file used to generate the model with Object Detection API: /home/hajime/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29/pipeline.config
- Use the config file: /opt/intel/openvino/deployment_tools/model_optimizer/extensions/front/tf/ssd_v2_support.json
Model Optimizer version: 2020.2.0-60-g0bc66e26ff
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint8 = np.dtype([("qint8", np.int8, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint16 = np.dtype([("qint16", np.int16, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_quint16 = np.dtype([("quint16", np.uint16, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint32 = np.dtype([("qint32", np.int32, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
np_resource = np.dtype([("resource", np.ubyte, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint8 = np.dtype([("qint8", np.int8, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint16 = np.dtype([("qint16", np.int16, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_quint16 = np.dtype([("quint16", np.uint16, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint32 = np.dtype([("qint32", np.int32, 1)])
/home/hajime/anaconda3/lib/python3.7/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
np_resource = np.dtype([("resource", np.ubyte, 1)])
The Preprocessor block has been removed. Only nodes performing mean value subtraction and scaling (if applicable) are kept.
[ SUCCESS ] Generated IR version 10 model.
[ SUCCESS ] XML file: /home/hajime/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29/./frozen_inference_graph.xml
[ SUCCESS ] BIN file: /home/hajime/git/ndopenvino/13_ModelOptimizer/ssd_mobilenet_v2_coco_2018_03_29/./frozen_inference_graph.bin
[ SUCCESS ] Total execution time: 43.20 seconds.
[ SUCCESS ] Memory consumed: 827 MB.
frozen_inference_graph.pbはすでにFreezingされたfrozenなモデルのようです。こちらは、ダウンロードファイルを展開して得られるものです。処理の結果以下のファイルが得られます。
frozen_inference_graph.xml ー モデルを表すXMLファイル
frozen_inference_graph.bin ー モデルの重みなどのパラメータ値が含まれるバイナリファイル
この2種類のファイルが最適化ファイルとなります。とりあえず楽にインストールして、無事に動作することを確認できました。
次は実際に、別のネタで生成された最適化モデルをどこか(PCまたはRasPi)で動かして、推論処理を試してみたいと思います
コメント