KITTIとPointPillarsのVitis AIのサンプルを調べたメモ

本サイトはアフィリエイト広告を利用しています。
AI

Vitis AIでKITTIとPointPillarsの機械学習を試してみました。

データセットの用意からFPGAへの量子化までの動作確認をしています。

その際にエラー出た内容含めて紹介します。

 

スポンサーリンク

KITTIとPointPillarsをVitis AIのサンプルを調べたメモ

自動車の物体検出のデータセット(画像+LIDAR)であるKITTIを試してみました。

PointPillarsというLIDAR点群からの3D物体検出の処理をテストしてます。

FPGAの開発環境であるVitis-AIにサンプルがありますので、学習・量子化してみました。

 

基本的には下記のVitis AI 2.5のサンプルに沿って手順を実行しています。

 https://github.com/Xilinx/Vitis-AI/tree/2.5/model_zoo/model-list/pt_pointpillars_kitti_12000_100_10.8G_2.5

yamlに記載している「type: float & quantized」のリンク先から入手できます。

wget https://www.xilinx.com/bin/public/openDownload?filename=pt_pointpillars_kitti_12000_100_10.8G_2.5.zip
unzip openDownload\?filename\=pt_pointpillars_kitti_12000_100_10.8G_2.5.zip 

 

Vitis AIのPointpillarsはSECONDがベース

自動車のLIDAR点群の情報から3D物体検出するアルゴリズムと言っても数多くあります。

今回の処理はSECONDというものがベースになっています。

(SECOND: Sparsely Embedded Convolutional Detection)

 

正直、筆者は上手く説明できないのですが下記のQiita記事が分かりやすいと思います。

 https://qiita.com/minh33/items/d0a67a8f253bde0cae14

 

SECONDの中でも色々な処理がある

Pytorch+SECONDだと下記のGithubの下記が一番有名かと思います。

TTIのデータセットだけでなく、nuScenesにも対応しています。

 https://github.com/traveller59/second.pytorch

mmdetection3dというの最新の3D物体検出のライブラリにも組み込まれています。

(むしろ、古いVerが残っている感じです。第6回AIエッジコンテストのベースもこれです。)

 

今回のVitis AIのサンプル元は、上記のからフォークされた1つです。

 https://github.com/nutonomy/second.pytorch

更にFPGAへの実装(量子化)ができるようにアレンジされています。

 

コンフィグファイルを見比べると、デフォルトのSECONDの設定が大きく違います。

SECONDの大きな3つのモジュールから異なっています。

下記SECONDの論文の一部・図を引用させていただいています。

https://pdfs.semanticscholar.org/5125/a16039cabc6320c908a4764f32596e018ad3.pdf

 

(1)voxel_feature_extractor:
・SimpleVoxelRadius  ←大元のリポジストリ(第6回AIエッジコンテストのリファレンス)
・PillarFeatureNet   ←フォークされたリポジストリ(Vitis AIは更に改良)
(2)middle_feature_extractor:
・SpMiddleFHD   ←大元のリポジストリ(第6回AIエッジコンテストのリファレンス)
・PointPillarsScatter ←フォークされたリポジストリ(Vitis AIは更に改良)
(3)rpn:
・RPNV2      ←大元のリポジストリ(第6回AIエッジコンテストのリファレンス)
・RPN       ←フォークされたリポジストリ(Vitis AIは更に改良)

 

Vitis AIでは量子化が出来ても…

Vitis AIのSECONDは、Githubに置かれているSECONDと何かしら差分があります。

今回サンプルに沿う形で量子化まで出来ていますが、あくまで一例です。

(他のGithubのSECONDでも簡単にFPGAの量子化ができるという訳ではなしです…)

 

※また別の記事で紹介したいと思います。

 

Vitis AIのサンプル通り学習→量子化を試してみる

Vitis AIのインストールや環境構築ついては下記記事で紹介しています。

VItis AI 2.5やPetaLinuxなどインストールしてみたメモ

Vitis AI GPU dockerの環境構築をしたメモ

 

README.mdを見て環境を整えます

README.mdに従ってKITTIのデータセットのダウンロードまで行います。

またVitis AIのGPU版のdocker上でcuda-toolkitの11.0とnvccが要求されています。

下記記事で紹介したように、Conda環境を入れ替えて対応します。

Vitis AIでPytorchのConda環境を新しく構築してみた

Vitis AIでPytorchのConda環境を新しく構築してみた
Vitis AIでPytorchのConda環境を立ち上げてみました。 量子化(vai_q_pytorch)する上でgpuとnvccを使うには、環境のセットアップが必要です。 FPGAに向けてPytorchのモデルを量子化する内容を紹介します。

 

Conda環境を入れ替えるスクリプトはdocker/dockerfiles/replace_pytorch.shにあります。

但しデフォルトだとcuda-toolkitの10.2になってしまいます。

そのため下記のようにcuda-toolkitの11.0をインストールするように書き直します。

cudatoolkit=10.2 → cudatoolkit=11.0

#### Installing pytorch 1.7.1 packages ...torchvision==0.5.0+cu100 -f https://download.pytorch.org/whl/torch_stable.html
if [ -d "/usr/local/cuda" ]; then
  mamba install -y pytorch==1.7.1 cudatoolkit=11.0 -c pytorch
  pip install torchvision==0.8.2

 

Vitis AI上での実行したコマンド

前処理・学習・量子化・コンパイルまでスクリプトになっています。

README.mdに従って実行すれば実施できます。下記が実施したコマンドです。

最初にnvccが動かせるようにcuda-toolokit-11-0を入れています。

(vitis-ai-pt1_7) Vitis-AI /workspace/pt_pointpillars_kitti_12000_100_10.8G_2.5 > history
    1  conda activate vitis-ai-pytorch
    2  wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
    3  sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
    #  wget http://developer.download.nvidia.com/compute/cuda/11.0.2/local_installers/cuda-repo-ubuntu1804-11-0-local_11.0.2-450.51.05-1_amd64.deb
    4  sudo dpkg -i cuda-repo-ubuntu1804-11-0-local_11.0.2-450.51.05-1_amd64.deb
    5  sudo apt-key add /var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub
    6  sudo apt-get update
    7  sudo apt-get install -y cuda-toolkit-11-0
    8  sh docker/dockerfiles/replace_pytorch_11.sh vitis-ai-pt1_7
    9  conda activate vitis-ai-pt1_7
   10  cd pt_pointpillars_kitti_12000_100_10.8G_2.5/
   11  pip install --user -r requirements.txt
   12  sudo apt-get update && sudo apt-get install cuda-toolkit-11-0
   13  export CUDA_HOME=/usr/local/cuda
   14  export NUMBAPRO_CUDA_DRIVER=/usr/lib/x86_64-linux-gnu/libcuda.so
   15  export NUMBAPRO_LIBDEVICE=${CUDA_HOME}/nvvm/libdevice
   16  export NUMBAPRO_NVVM=${CUDA_HOME}/nvvm/lib64/libnvvm.so
   17  sudo update-alternatives --config gcc
   18  bash code/test/prepare_data.sh
   19  bash code/test/run_eval.sh
   20  bash code/train/run_train.sh
   21  bash code/test/run_quant.sh

  ~~ここから先はあまり確認していません~~
   ##  bash code/qat/run_qat.sh
   ##  bash code/qat/convert_test_qat.sh

 

※筆者はあくまでサンプルの流れを確認した程度です。

長すぎる学習(run_train.sh)などは途中で止めています。

また量子化(run_quant.sh)してxmodelを出力した後の処理までは未確認です。

 

エラー出た内容

スクリプトを動かしていく上で出たエラーを数点紹介します。

 

No module named 'utils.non_max_suppression.nms'

non_max_suppression のライブラリを最初に使うときに一度コンパイルしている様子です。

そこでエラーが出ていた内容でした。(長いエラーのため一部切り取りです。)

RuntimeError: ('compile failed with retcode', 1)

~~~~~~~~~~~~~~~~~~~~~
../cc/nms/nms_cpu.h:165:26: note: ‘std::cout’ is defined in header ‘<iostream>’; did you forget to ‘#include <iostream>’?
concurrent.futures.process._RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/workspace/pt_pointpillars_kitti_12000_100_10.8G_2.5/code/test/utils/non_max_suppression/nms_cpu.py", line 46, in <module>
    from .nms import (
ModuleNotFoundError: No module named 'utils.non_max_suppression.nms'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/vitis_ai/conda/envs/vitis-ai-pt1_7/lib/python3.7/concurrent/futures/process.py", line 239, in _process_worker
    r = call_item.fn(*call_item.args, **call_item.kwargs)
  File "/opt/vitis_ai/conda/envs/vitis-ai-pt1_7/lib/python3.7/concurrent/futures/process.py", line 198, in _process_chunk
    return [fn(*args) for args in chunk]
  File "/opt/vitis_ai/conda/envs/vitis-ai-pt1_7/lib/python3.7/concurrent/futures/process.py", line 198, in <listcomp>
    return [fn(*args) for args in chunk]
  File "/workspace/pt_pointpillars_kitti_12000_100_10.8G_2.5/code/test/utils/buildtools/command.py", line 291, in compile_func
    raise RuntimeError("compile failed with retcode", ret.returncode)
RuntimeError: ('compile failed with retcode', 1)
~~~~~~~~~~~~~~~~~~~~~~~

 

エラー内容に下記メッセージがありました。

../cc/nms/nms_cpu.h:165:26: note: ‘std::cout’ is defined in header ‘<iostream>’; did you forget to ‘#include <iostream>’?

確かnms_cpu.h含めて何か所か同様なメッセージが出てきます。

そのためエラー出た.hファイルに#include <iostream>を追記すると、エラーが消えました。

 

RuntimeError: CUDA out of memory

train(学習)とかqat(量子化後の精度向上)などCUDAメモリを食います。

筆者のGPUボードはGTX1650です。メモリ4GBです

KITTIのデータセットでも厳しく、必要に応じてバッチサイズなどを調整していました。

RuntimeError: CUDA out of memory. Tried to allocate 244.00 MiB (GPU 0; 3.82 GiB total capacity; 2.46 GiB already allocated; 124.44 MiB free; 2.83 GiB reserved in total by PyTorch)

 

量子化後の評価値も大体一致した

量子化のスクリプトした結果も貼り付けておきます。

README.mdに各Performance値も記載していましたが、特に大きくは違いありません。

特に問題なくテスト出来ていたようです。

(vitis-ai-pt1_7) Vitis-AI /workspace/kitti_pt_pointpillars_kitti_12000_100_10.8G_2.5 > bash code/test/run_quant.sh
Calibrating model quantization...

[VAIQ_NOTE]: Loading NNDCT kernels...
Restoring parameters from float/pointpillars.tckpt
remain number of infos: 3769

[VAIQ_NOTE]: Quant config file is empty, use default quant configuration

[VAIQ_NOTE]: Quantization calibration process start up...

[VAIQ_NOTE]: =>Quant Module is in 'cuda'.

[VAIQ_NOTE]: =>Parsing VoxelNet...

[VAIQ_NOTE]: Start to trace model...

[VAIQ_NOTE]: Finish tracing.

[VAIQ_NOTE]: Processing ops...
██████████████████████████████████████████████████| 103/103 [00:00<00:00, 2168.96it/s, OpInfo: name = return_0, type = Return]                                                                              

[VAIQ_WARN]: The quantizer recognize new op `equal` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `select` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `stack` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `index_put_inplace` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `index` as a float operator by default.

[VAIQ_NOTE]: =>Doing weights equalization...

[VAIQ_NOTE]: =>Quantizable module is generated.(quantized/VoxelNet.py)

[VAIQ_NOTE]: =>Get module with quantization.
Generate output labels...
Car AP@0.70, 0.70, 0.70:====>][2.48it/s][25:19>00:00]      
bbox AP:90.33, 80.52, 78.50
bev  AP:89.66, 79.59, 76.45
3d   AP:76.02, 64.65, 57.77
aos  AP:90.20, 79.93, 77.43
Car AP@0.70, 0.50, 0.50:
bbox AP:90.33, 80.52, 78.50
bev  AP:90.82, 87.85, 85.37
3d   AP:90.81, 87.60, 83.24
aos  AP:90.20, 79.93, 77.43
Cyclist AP@0.50, 0.50, 0.50:
bbox AP:71.08, 55.63, 52.28
bev  AP:68.82, 50.20, 47.47
3d   AP:61.32, 46.45, 43.39
aos  AP:66.14, 50.63, 47.59
Cyclist AP@0.50, 0.25, 0.25:
bbox AP:71.08, 55.63, 52.28
bev  AP:71.90, 56.14, 53.75
3d   AP:71.87, 55.58, 52.74
aos  AP:66.14, 50.63, 47.59
Pedestrian AP@0.50, 0.50, 0.50:
bbox AP:47.61, 44.38, 41.61
bev  AP:51.37, 46.82, 43.04
3d   AP:44.29, 38.55, 35.24
aos  AP:26.98, 25.77, 24.50
Pedestrian AP@0.50, 0.25, 0.25:
bbox AP:47.61, 44.38, 41.61
bev  AP:60.13, 56.86, 53.49
3d   AP:60.10, 56.29, 53.07
aos  AP:26.98, 25.77, 24.50

Car coco AP@0.50:0.05:0.95:
bbox AP:66.54, 60.66, 58.02
bev  AP:63.49, 58.82, 56.04
3d   AP:52.40, 46.60, 43.60
aos  AP:66.45, 60.18, 57.18
Cyclist coco AP@0.25:0.05:0.70:
bbox AP:62.79, 49.80, 47.41
bev  AP:58.68, 44.54, 42.17
3d   AP:52.92, 40.31, 37.91
aos  AP:58.45, 45.39, 43.14
Pedestrian coco AP@0.25:0.05:0.70:
bbox AP:42.52, 39.93, 38.26
bev  AP:43.44, 40.21, 37.61
3d   AP:39.45, 36.22, 33.87
aos  AP:24.33, 23.44, 22.67


[VAIQ_NOTE]: =>Exporting quant config.(quantized/quant_info.json)
Testing quantized model...

[VAIQ_NOTE]: Loading NNDCT kernels...
Restoring parameters from float/pointpillars.tckpt
remain number of infos: 3769

[VAIQ_NOTE]: Quant config file is empty, use default quant configuration

[VAIQ_NOTE]: Quantization test process start up...

[VAIQ_NOTE]: =>Quant Module is in 'cuda'.

[VAIQ_NOTE]: =>Parsing VoxelNet...

[VAIQ_NOTE]: Start to trace model...

[VAIQ_NOTE]: Finish tracing.

[VAIQ_NOTE]: Processing ops...
██████████████████████████████████████████████████| 103/103 [00:00<00:00, 2191.47it/s, OpInfo: name = return_0, type = Return]                                                                              

[VAIQ_WARN]: The quantizer recognize new op `index_put_inplace` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `select` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `equal` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `stack` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `index` as a float operator by default.

[VAIQ_NOTE]: =>Doing weights equalization...

[VAIQ_NOTE]: =>Quantizable module is generated.(quantized/VoxelNet.py)

[VAIQ_NOTE]: =>Get module with quantization.
Generate output labels...
Car AP@0.70, 0.70, 0.70:====>][9.61it/s][06:28>00:00]      
bbox AP:90.30, 80.50, 78.66
bev  AP:89.52, 79.48, 76.59
3d   AP:76.02, 64.63, 57.70
aos  AP:90.17, 79.96, 77.60
Car AP@0.70, 0.50, 0.50:
bbox AP:90.30, 80.50, 78.66
bev  AP:90.78, 88.03, 85.34
3d   AP:90.75, 87.04, 83.44
aos  AP:90.17, 79.96, 77.60
Cyclist AP@0.50, 0.50, 0.50:
bbox AP:70.74, 54.59, 52.43
bev  AP:65.26, 49.71, 46.97
3d   AP:59.25, 45.00, 42.49
aos  AP:66.29, 49.66, 47.51
Cyclist AP@0.50, 0.25, 0.25:
bbox AP:70.74, 54.59, 52.43
bev  AP:71.85, 56.41, 53.31
3d   AP:71.82, 55.10, 52.32
aos  AP:66.29, 49.66, 47.51
Pedestrian AP@0.50, 0.50, 0.50:
bbox AP:48.22, 44.23, 42.22
bev  AP:50.95, 46.15, 42.53
3d   AP:42.67, 38.13, 34.57
aos  AP:27.46, 25.94, 24.94
Pedestrian AP@0.50, 0.25, 0.25:
bbox AP:48.22, 44.23, 42.22
bev  AP:60.33, 56.41, 53.51
3d   AP:60.30, 56.36, 53.40
aos  AP:27.46, 25.94, 24.94

Car coco AP@0.50:0.05:0.95:
bbox AP:66.67, 60.99, 58.19
bev  AP:63.48, 58.86, 56.04
3d   AP:52.55, 46.78, 43.81
aos  AP:66.58, 60.54, 57.38
Cyclist coco AP@0.25:0.05:0.70:
bbox AP:61.04, 49.02, 46.88
bev  AP:57.81, 44.11, 41.82
3d   AP:51.76, 39.53, 37.33
aos  AP:57.43, 44.69, 42.61
Pedestrian coco AP@0.25:0.05:0.70:
bbox AP:42.34, 39.77, 38.07
bev  AP:43.37, 39.94, 37.52
3d   AP:38.47, 35.25, 32.90
aos  AP:24.46, 23.55, 22.67

Dumping xmodel...

[VAIQ_NOTE]: Loading NNDCT kernels...
Restoring parameters from float/pointpillars.tckpt
remain number of infos: 3769

[VAIQ_NOTE]: Quant config file is empty, use default quant configuration

[VAIQ_NOTE]: Quantization test process start up...

[VAIQ_NOTE]: =>Quant Module is in 'cpu'.

[VAIQ_NOTE]: =>Parsing VoxelNet...

[VAIQ_NOTE]: Start to trace model...

[VAIQ_NOTE]: Finish tracing.

[VAIQ_NOTE]: Processing ops...
██████████████████████████████████████████████████| 103/103 [00:00<00:00, 2185.14it/s, OpInfo: name = return_0, type = Return]                                                                              

[VAIQ_WARN]: The quantizer recognize new op `equal` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `index` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `stack` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `index_put_inplace` as a float operator by default.

[VAIQ_WARN]: The quantizer recognize new op `select` as a float operator by default.

[VAIQ_NOTE]: =>Doing weights equalization...

[VAIQ_NOTE]: =>Quantizable module is generated.(quantized/VoxelNet.py)

[VAIQ_NOTE]: =>Get module with quantization.
Generate output labels...
[0.027%][....................][0.16it/s][00:06>06:40:18]   
[VAIQ_NOTE]: =>Converting to xmodel ...

[VAIQ_NOTE]: =>Dumping 'VoxelNet_0'' checking data...

[VAIQ_WARN]: Only dump first output of multi-output node:'VoxelNet::VoxelNet/PillarFeatureNet[voxel_feature_extractor]/PFNLayer[pfn_layers]/ModuleList[0]/Max[max]/inputs.2(max)'.

[VAIQ_WARN]: Only dump first output of multi-output node:'VoxelNet::VoxelNet/PillarFeatureNet[voxel_feature_extractor]/PFNLayer[pfn_layers]/ModuleList[0]/Max[max]/inputs.2(max)'.

[VAIQ_NOTE]: =>Finsh dumping data.(quantized/deploy_check_data_int/VoxelNet_0)

[VAIQ_NOTE]: =>Dumping 'VoxelNet_1'' checking data...

[VAIQ_NOTE]: =>Finsh dumping data.(quantized/deploy_check_data_int/VoxelNet_1)

[VAIQ_NOTE]: =>Successfully convert 'VoxelNet_0' to xmodel.(quantized/VoxelNet_0_int.xmodel)

[VAIQ_NOTE]: =>Successfully convert 'VoxelNet_1' to xmodel.(quantized/VoxelNet_1_int.xmodel)

 

まとめ

テストとしては、あくまでサンプルのスクリプトに沿って実行した形となりました。

ただVitis AI上でのSECONDの中身含めて、確認することが出来ました。

 

次はVitis AIのサンプルにはない量子化ができるか試してみた内容を紹介します。

(結果は失敗ですが…)

Vitis-AI Quantizer(量子化)の3D物体検出に失敗したメモ

Vitis-AI Quantizer(量子化)の3D物体検出に失敗したメモ
Vitis-AIのサンプル・ライブラリにないFPGAの量子化(Quantizer)を試してみました。 ただ3D物体検出(pointpainting)の対応はとても難しく失敗に終わりました。 忘備録として一連の流れを紹介します。

 

今回の記事含めて、第6回AIエッジコンテストの一環でした。

下記にてコンテストでテスト・実施したことのまとめを紹介しています。

第6回AIエッジコンテストが凄く難しいけど勉強になった感想

第6回AIエッジコンテストが凄く難しいけど勉強になった感想
第6回AIエッジコンテストに参加していました。 RISC-Vを使って、画像とLIDAR点群からの3D物体検出が課題でした。 ただ貴重な勉強の機会になりましたし、自身への忘備録としても内容を紹介します。

コメント