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

AI

Vitis-AIのサンプル・ライブラリにないFPGAの量子化(Quantizer)を試してみました。

ただ3D物体検出(pointpainting)の対応は難しく失敗に終わりました。

忘備録として一連の流れを紹介します。

 

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

XilinxのFPGAで3D物体検出(pointpainting)が出来るように量子化を試してみました。

テストしたのは第6回AIエッジコンテストのリファレンス環境です。

ただVitis AIがサンプルで用意されている量子化とは、(筆者にとって)難易度が別物でした。

 

結局失敗に終わりましたが、色々と試した内容をブログ記事として残したいと思います。

本当に超個人的な失敗メモです。あくまで参考までにお願いします

 

3D物体検出を量子化したい理由

筆者が第6回AIエッジコンテストに参加していました。

自動車の画像+LIDAR点群データからの3D物体検出をFPGAで実装する必要が有りました。

(ちなみにRISC-Vの実装も取り入れないといけない…)

The 6th AI Edge Contest (Implementation Contest 4) | SIGNATE - Data Science Competition

 

また公式からリファレンス環境(3D物体検出のプログラム)が用意されていました。

下記のようにdocker・Colab上では簡単にテスト実行できるようになっています。

そのため、リファレンス環境をFPGA向けに量子化すれば一番楽では…と考えたためです。

 

実行環境

あくまで下記の環境の一例です。

  • Vitis AI 2.5
  • spconv v1.2.1
  • 第6回AIエッジコンテストのリファレンス環境(SECOND)

 

Vitis AIのdocker上で、第6回AIエッジコンテストのリファレンス環境は動作確認済です。

下記記事で対応した内容を紹介しています。(リンク先はこちら)

spconvの古いVer1.2.1のインストールが苦労したメモ

spconvの古いVer1.2.1のインストールが苦労したメモ
3D物体検出でspconvのライブラリを使っていたところエラーが出ました。 元々参照していたのが古いVer1.xのライブラリでした。 何とか環境維持しつつ、エラー消すために再度ビルドした内容を紹介します。

 

第6回AIエッジコンテストのリファレンス環境(SECOND)は下記です。

 https://github.com/pometa0507/6th-ai-reference2

 

Vitis AIのインストール・GPUのdocker環境については下記記事で紹介しています。

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

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

 

Vitis AIの3D物体検出のサンプルを参考にする

Vitis AI 2.5には3D物体検出のサンプルが複数用意されていました。

下記3つはリファレンスと同じくSECONDという3D物体検出の処理が使われています。

(SECOND: Sparsely Embedded Convolutional Detection)

  1. PointPillars + KITTI    ←リファレンス環境のコードに一番近い形
  2. PointPillars + nuScenes  ←mmdetection3dがベース
  3. PointPainting + nuScenes ←mmdetection3dをベース

 

第6回AIエッジコンテストのデータセットはnuScenes形式でした。(KITTI形式ではなし)

またリファレンス環境も画像と点群データを利用するPointPaintingの処理でした。

処理だけ見ると「3.PointPainting + nuScenes」がリファレンスに近いです。

 

ただ2.3はmmdetection3dというライブラリ経由でSECONDが利用されています。

コード的には「1.PointPillars + KITTI」がリファレンス環境に近い形です。

(リファレンス環境が、「1」のフォーク元になっているリポジストリをベースにしています)

 

結局のところ3つのサンプルを全て参考にさせてもらいました。

ただ量子化としてのコードとして一番見たのは「1.PointPillars + KITTI」でした。

(最終的には2,3も使いました。また別の記事で紹介します)

 

ただしサンプルをそのまま流用できない…

Vitis AIのサンプルと第6回AIエッジコンテストのリファレンス環境には差分があります

Vitis AIのSECONDについては下記記事で調べて、紹介しています。

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

KITTIとPointPillarsのVitis AIのサンプルを調べたメモ
Vitis AIでKITTIとPointPillarsの機械学習を試してみました。 データセットの用意からFPGAへの量子化までの動作確認をしています。 その際にエラー出た内容含めて紹介します。 KITTIとPoint...

 

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

Vitis AIのサンプルは参考には出来ますが、コードをそのまま流用はできない形です。

下記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は更に改良)

 

量子化(quantizer)の処理を試してみる

Vitis AIの量子化に関してはVitis AIの公式ドキュメントにも記載されています。

またpointpillarsの量子化の事例も紹介されています。

 https://docs.xilinx.com/r/2.5-English/ug1414-vitis-ai/Pytorch-Custom-OP-Model-Example

 

pytorchでモデルや重みなど設定した後、下記量子化(torch_quantizer)の関数に入れていきます。

下記はVitis AIのサンプルのpointpillarsの量子化例です

 

SECONDのtrain.pyをベースに作る

一から量子化のプログラムを作るのは手間です。

そのためSECONDの評価(学習)のプログラム(train.py)を流用していきます

第6回AIエッジコンテストのリファレンス環境だと下記です。

 https://github.com/pometa0507/6th-ai-reference2/blob/master/second.pytorch/second/pytorch/train.py

 

train.pyの中はdef でevaluate(評価)の関数がありますので、コピーしてベースにしました。

pytorchでモデル・データセットが作成されて、config設定が終わった箇所で量子化をします。

プログラムの一部ですが、下記感じで変数を合わせて実行しました。

 

プログラムの頭には量子化関連のimportも追加します。

 

実行すると(一応)量子化の関数(quantizer)が動き出します。

ただVitis AIのサンプル同様にvoxelとcoorsの変数を入れるだけではエラーが出ました。

 

エラーの最後の所の切り取りです。

モジュール(モデル)へforward(前処理)の引数が合っていないよ。ということでした。

量子化のために、単純に正規分布の変数として入れるだけでは駄目でした。

 

voxelnet.pyも修正する

SECONDでは座標からVoxel化(Voxelnet.py)しています。

量子化の際にも下記Voxelnet.pyのdef foward箇所を通過していました。

 https://github.com/pometa0507/6th-ai-reference2/blob/master/second.pytorch/second/pytorch/models/voxelnet.py

 

リファレンス環境では、Vitis AIのサンプルのようにVoxelへの座標だけでは駄目でした。

(よく考えたら、nuScenesのデータは多くのメタ情報持っているから当然か…)

多くの情報をまとめた構造で渡す必要があります。

 

本来リファレンス環境のVoxelnet.pyに引き渡すデータは下記のようなdict構造です。

voxels,num_points,num_voxels…など多くの情報が入った形です。

 

torch_quantizerがtuple/list構造のみ

ただtorch_quantizerにメタ情報が多く入ったdictの形で入れるとエラーが出ます。

torch_quantizerはtuple/list構造だけ引数に使ってくれと言われます。

そのため、モデル(Voxelnet)のコードも書き換える必要があります。

 

W_QUANT=1で量子化の処理を入れる

また量子化の処理も入れる必要があります。

Vitis AIのサンプルでいうW_QUANT=1の処理を入れている箇所です。

Voxelnet.pyの頭、またdef network箇所にも修正しました。

 

またVoxel化(Voxelnet.py)箇所だけでなく、他に量子化する箇所は追加します。

おそらくpointpillars箇所(pointpillars.py)、他encoder箇所なども必要だと思います。

 

色々エラー修正したが、量子化の最後まで行けなかった

他にも色々エラー処理したのですが、結局最後まで行けませんでした。

エラー消すのに時間が溶ける溶けると言った感じでした。

(色々弄りすぎて、ブログには書ききれませんでした…。)

 

結果の一部切り取りが下記です、量子化の最後のxmodel出力までが遠かったです。

 

 

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

今回Vitis AIのdocker上で実行したコマンドは下記です。

 

実行で使っているスクリプト(run_quant.sh)は特に大したことしていないです。

下記のようにtrain.pyから改造したプログラム(quant_train.py)を動かしているだけです。

 

まとめ

リファレンス環境の量子化は、時間的にも難しいと判断して途中でギブアップしました。

(多分これ以上続けてもハマるイメージしかありませんでした)

また別の記事で違ったアプローチでの3D物体検出の量子化を紹介します。

コメント