Raspberry Pi AI Kitでカスタムモデルを使う方法

# カスタムモデルをHEFに変換するまでの流れ
## hailoアカウント作成し、以下のファイルをダウンロード
- hailo_dataflow_compiler-3.27.0-py3-none-linux_x86_64.whl
- hailo_model_zoo-2.11.0-py3-none-any.whl
[https://hailo.ai/](HAILOの公式サイト)にログインして、SW Downloadで探せば見つかります。
## awsで以下の設定でGPUインスタンスを起動
- AMI: Deep Learning Base OSS Nvidia Driver GPU AMI (Ubuntu 22.04) (x64)
- type: g4dn.2xlarge
- storage: 100GB
## 学習データ準備
いつものように学習用データを作成します。
```
imgs/
  |-train/
  |-val/
  |-data.yaml
```
ただし、`data.yaml`を以下の様にしてください。
```data.yaml:yaml
train: train
val: val
# number of classes
nc: 80
# class names
names: 
    0: YOUR_CLASS_1
    1: YOUR_CLASS_2
    2: YOUR_CLASS_3
    3 : dummy1
    4 : dummy2
    5 : dummy3
    6 : dummy4
    7 : dummy5
    8 : dummy6
    9 : dummy7
    10 : dummy8
    11 : dummy9
    12 : dummy10
    13 : dummy11
    14 : dummy12
    15 : dummy13
    16 : dummy14
    17 : dummy15
    18 : dummy16
    19 : dummy17
    20 : dummy18
    21 : dummy19
    22 : dummy20
    23 : dummy21
    24 : dummy22
    25 : dummy23
    26 : dummy24
    27 : dummy25
    28 : dummy26
    29 : dummy27
    30 : dummy28
    31 : dummy29
    32 : dummy30
    33 : dummy31
    34 : dummy32
    35 : dummy33
    36 : dummy34
    37 : dummy35
    38 : dummy36
    39 : dummy37
    40 : dummy38
    41 : dummy39
    42 : dummy40
    43 : dummy41
    44 : dummy42
    45 : dummy43
    46 : dummy44
    47 : dummy45
    48 : dummy46
    49 : dummy47
    50 : dummy48
    51 : dummy49
    52 : dummy50
    53 : dummy51
    54 : dummy52
    55 : dummy53
    56 : dummy54
    57 : dummy55
    58 : dummy56
    59 : dummy57
    60 : dummy58
    61 : dummy59
    62 : dummy60
    63 : dummy61
    64 : dummy62
    65 : dummy63
    66 : dummy64
    67 : dummy65
    68 : dummy66
    69 : dummy67
    70 : dummy68
    71 : dummy69
    72 : dummy70
    73 : dummy71
    74 : dummy72
    75 : dummy73
    76 : dummy74
    77 : dummy75
    78 : dummy76
    79 : dummy77
```
必ずクラスは80まで埋めてください。`nc`も`names`も80個すべて埋めてください。

## 学習環境構築
gpuインスタンスにログインし、下記を実行。
```:bash
cd ~
mkdir datasets
###################################
# datasets配下に学習用ファイルを置く。 #
###################################
git clone https://github.com/hailo-ai/hailo_model_zoo.git
cd hailo_model_zoo/training/yolov8
docker build --build-arg timezone=`cat /etc/timezone` -t yolov8:v0 .
docker run --name "hailo_yolov8" -it --gpus all --ipc=host -v  /home/ubuntu/datasets:/workspace/datasets yolov8:v0
###################################
#         ここからDocker内          #
###################################
cd /workspace/ultralytics
yolo detect train data=/workspace/datasets/imgs/data.yaml model=yolov8n.pt name=retrain_yolov8n epochs=100 batch=16
yolo export model=runs/detect/retrain_yolov8n/weights/best.pt imgsz=640 format=onnx opset=11
mv runs/detect/retrain_yolov8n/weights/best.onnx /workspace/datasets/
exit
###################################
#         ここからDocker外          #
###################################
```
## 変換環境構築
変換環境を作成し、onnx形式をhef形式に変換します。
まず、1.で準備した以下のファイルをUbuntuのホームディレクトリにコピーしてください。
    - hailo_dataflow_compiler-3.27.0-py3-none-linux_x86_64.whl
    - hailo_model_zoo-2.11.0-py3-none-any.whl

```:bash
cd ~/
mv /home/ubuntu/datasets/best.onnx ~/
sudo apt update
sudo apt install python3-virtualenv python3.10-dev python3.10-distutils python3-tk graphviz libgraphviz-dev
virtualenv hailo
. hailo/bin/activate
pip install hailo_dataflow_compiler-3.27.0-py3-none-linux_x86_64.whl
pip install hailo_model_zoo-2.11.0-py3-none-any.whl
mkdir -p hailo/lib/python3.10/site-packages/hailo_model_zoo/cfg/postprocess_config/
cp hailo_model_zoo/hailo_model_zoo/cfg/postprocess_config/yolov8n_nms_config.json hailo/lib/python3.10/site-packages/hailo_model_zoo/cfg/postprocess_config/yolov8n_nms_config.json
hailomz compile --hw-arch hailo8l --ckpt best.onnx --calib-path ~/datasets/imgs/val --yaml hailo_model_zoo/hailo_model_zoo/cfg/networks/yolov8n.yaml --classes 80
```
`yolov8n.hef`ファイルが出力されるので、`yolov8n_h8l.hef`というファイル名にリネームし、エッジ環境にコピーしておいてください。

## エッジ推論
[Raspberry Pi AI Kitの公式ドキュメント](https://www.raspberrypi.com/documentation/accessories/ai-kit.html) を元にKitの準備をしてください。`hailortcli fw-control identify`を実行し、以下の内容が出力され、NPUが認識されていることを確認してください。DesktopバージョンのRaspberryPiが必要です。
```
Executing on device: 0000:01:00.0
Identifying board
Control Protocol Version: 2
Firmware Version: 4.17.0 (release,app,extended context switch buffer)
Logger Version: 0
Board Name: Hailo-8
Device Architecture: HAILO8L
Serial Number: HLDDLBB234500054
Part Number: HM21LB1C2LAE
Product Name: HAILO-8L AI ACC M.2 B+M KEY MODULE EXT TMP
```
それでは、環境構築していきましょう。
```
git clone https://github.com/hailo-ai/hailo-rpi5-examples.git
cd hailo-rpi5-examples
source setup_env.sh
pip install -r requirements.txt
./download_resources.sh
mv ~/yolov8n_h8l.hef resources/
```
`basic_pipelines/detection.py`内のGStreamerDetectionAppクラスのコンストラクタに以下を追加しましょう。
```basic_pipelines/detection.py:python
        elif args.network == "yolov8s":
            self.hef_path = os.path.join(self.current_path, '../resources/yolov8s_h8l.hef')
+        elif args.network == "yolov8n":
+            self.hef_path = os.path.join(self.current_path, '../resources/yolov8n_h8l.hef')
        elif args.network == "yolox_s_leaky":
            self.hef_path = os.path.join(self.current_path, '../resources/yolox_s_leaky_h8l_mz.hef')
```
同ファイルのメイン内のargparserも書き換えましょう。
```
- parser.add_argument("--network", default="yolov6n", choices=['yolov6n', 'yolov8s', 'yolox_s_leaky'], help="Which Network to use, defult is yolov6n")
+ parser.add_argument("--network", default="yolov8n", choices=['yolov8n', 'yolov6n', 'yolov8s', 'yolox_s_leaky'], help="Which Network to use, defult is yolov6n")
```

ついにオリジナルモデルで推論を実行します。
```
python basic_pipelines/detection.py --network yolov8n --input YOUR_MOVIE.mp4
```

30FPSくらいで推論できていると思います。エッジ側の使い込みはもっと必要ですが、これで利用用途は一気に広がると思います。

# Ref
- [hailo_model_zoo](https://github.com/hailo-ai/hailo_model_zoo/blob/master/training/yolov8/README.rst)
- [Hailo RPi5 Basic Pipelines](https://github.com/hailo-ai/hailo-rpi5-examples/blob/main/doc/basic-pipelines.md)
- [①AI Software Suiteに必要なハードウェアとインストール](https://www.macnica.co.jp/business/semiconductor/articles/hailo/144988/)
- [【試してみた】オープンソースのONNXモデルをHailoで動かしてみた](https://www.macnica.co.jp/business/semiconductor/articles/hailo/144843/)