Raspberry Pi 5にCVATを導入(2)— 自動アノテーション機能の追加

はじめに#
前回の記事(Raspberry Pi 5にCVATを導入(1))では、CVATをRaspberry Pi 5の上で動かすところまで書きました。
ただ、実際に画像へbboxを引き始めるとすぐ気付くのですが、手動アノテーションはかなりしんどいです。100枚を超えたあたりから集中力が切れてきて、500枚目には作業者のメンタルが先に死ぬ、というのが個人的な肌感ですね。
そこで今回は、CVATの自動アノテーション機能(Auto Annotation / AI Tools)をRaspberry Pi 5上にセットアップしてみます。CVATはサーバーレス基盤のNuclio経由で推論関数を呼び出す仕組みになっているので、Nuctl(NuclioのCLI)のインストールと、ARM64で動く推論関数のデプロイがゴールです。
なお、CVAT公式が提供しているserverless functionはほとんどがx86_64前提(pytorch/pytorchやopenvino/ubuntu22_runtimeなど、ARM64イメージがpublishされていないものが多い)で、ARM64でそのまま動くものは限られます。今回はその中でも比較的素直に動くONNXベースのYOLOv7関数を題材にします。
検証時の構成#
| 項目 | 内容 |
|---|---|
| PC | Raspberry Pi 5( 8 GB) |
| OS | Raspberry Pi OS(64bit 6.12.75+rpt-rpi-v8) |
| CVAT | v2.64.0 |
| Nuclio | 1.15.9(CVAT v2.64.0のcomponents/serverless/docker-compose.serverless.ymlで指定されているバージョン) |
| 採用モデル | YOLOv7 (ONNX, yolov7-nms-640.onnx) |
※1作目で導入したCVAT v2.64.0がそのまま動いていることを前提に進めます。
1.自動アノテーションの仕組み#
CVATの自動アノテーションは、ざっくり下のような3層構成で動いています。
[CVAT UI] ──HTTP──> [CVAT server] ──HTTP──> [Nuclio dashboard / function] ──> [推論モデル本体]
(cvat_cvat ネットワーク内)
- CVAT serverはUIから「AI Tools → Detectors」のリクエストを受け取ると、対応するNuclio関数のHTTPエンドポイントを叩きに行きます。
- Nuclioは推論関数(detector / tracker / interactor)を個別のDockerコンテナとして起動・管理するサーバーレスフレームワークですね。
- 個々のserverless functionは、
serverless/<framework>/<author>/<model>/nuclio/配下のfunction.yaml、main.py、Dockerfile(あれば)で定義されています。
ARM64で動かす上での要点は、このfunction.yamlが指定するbaseImageがARM64マルチアーキ対応かどうかに尽きます。pytorch/pytorch系はARM64ビルドが事実上提供されていないので、onnxruntimeベースの関数を選んでおくのが無難です。
2.事前準備#
Nuctl(Nuclio CLI)のインストール#
CVAT v2.64.0はcomponents/serverless/docker-compose.serverless.ymlの中でNuclioダッシュボードイメージquay.io/nuclio/dashboard:1.15.9-amd64を指定しているので、CLI側も同じ1.15.9で揃えます。
公式ドキュメントの例はlinux-amd64ですが、Raspberry Pi 5はARM64なので**linux-arm64バイナリ**の方を取ってきます。
# nuctl 1.15.9 の ARM64 バイナリをダウンロード
wget https://github.com/nuclio/nuclio/releases/download/1.15.9/nuctl-1.15.9-linux-arm64
# 実行権限を付与し、/usr/local/bin にシンボリックリンクを張る
sudo chmod +x nuctl-1.15.9-linux-arm64
sudo ln -sf $(pwd)/nuctl-1.15.9-linux-arm64 /usr/local/bin/nuctl
# バージョン確認
nuctl version
Client version: 1.15.9 のように出ればOKです。
CVATをserverless込みで再起動#
docker-compose.yml単体で起動している場合は一度落として、Nuclio入りで起動し直します。
# CVATのリポジトリルートで実行
docker compose -f docker-compose.yml down
# serverless 用の compose ファイルを追加して起動
docker compose -f docker-compose.yml \
-f components/serverless/docker-compose.serverless.yml up -d
docker compose ps に nuclio という名前のコンテナが増えていればOKです。Nuclioダッシュボードは既定だとホスト側に出ておらず、CVATサーバーは内部ネットワーク(compose上はcvat、Docker上の実名はcvat_cvat)越しにダッシュボード経由で関数を呼び出します。GUIで関数の状態を見たい場合は後述の手順でホストに公開できます。
3.ARM64向けのデプロイ調整#
ここが今回いちばん引っかかるポイントですね。
CVATが用意しているserverless/deploy_cpu.shは、冒頭で必ず docker build -t cvat.openvino.base "$SCRIPT_DIR/openvino/base" を実行します。このopenvino/baseのDockerfileはFROM openvino/ubuntu22_runtime:2023.3.0で始まっていますが、このイメージはARM64版が公開されていません。そのため、スクリプトをそのまま叩くと最初のbuildで落ちてしまいます。
回避策はいくつかありますが、今回はdeploy_cpu.shを使わず、対象関数だけ nuctl deploy を直接叩く方法を採ります。リポジトリ側に手を入れずに済むので個人的にはおすすめです。
Nuclioプロジェクトの作成#
最初の一度だけ、cvat プロジェクトをNuclio側に作っておきます。
nuctl create project cvat --platform local
すでに作成済みだと error: project already exists 等が出ますが、無視して大丈夫です。
YOLOv7 (ONNX) のデプロイ#
ONNX版のYOLOv7関数(serverless/onnx/WongKinYiu/yolov7/nuclio/function.yaml、metadata.name: onnx-wongkinyiu-yolov7)は、baseImageにubuntu:22.04を使い、ビルド時にwget・python3-pip・python-is-python3をaptで入れたうえでonnxruntime・opencv-python-headless・pillow・pyyamlをpip installし、https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-nms-640.onnxをwgetで取ってくる、というかなり素直な構成です。onnxruntimeはARM64用のwheelが公式に提供されているので、追加改変なしでビルドが通ります。
CVATのリポジトリルートで下記を実行してください。
nuctl deploy --project-name cvat \
--path serverless/onnx/WongKinYiu/yolov7/nuclio \
--file serverless/onnx/WongKinYiu/yolov7/nuclio/function.yaml \
--platform local \
--env CVAT_FUNCTIONS_REDIS_HOST=cvat_redis_ondisk \
--env CVAT_FUNCTIONS_REDIS_PORT=6666 \
--platform-config '{"attributes": {"network": "cvat_cvat"}}'
--platform-config の network で cvat_cvat を指定しているのは、CVATサーバー側のコンテナと同じDockerネットワーク内に関数コンテナを置くためです(deploy_cpu.shが裏でやっているのと同じことを、手で渡しているだけですね)。
本環境ではビルドに[要計測]分ほどかかります。onnxruntime のwheel取得やyolov7-nms-640.onnx(約75MB)のダウンロード時間が支配的なので、ネットワーク回線次第で結構ぶれます。
デプロイ結果の確認#
nuctl get functions --platform local
onnx-wongkinyiu-yolov7 の STATE が ready になっていればOKです。
[要スクリーンショット: nuctl get functions --platform local の出力で yolov7 が ready になっている画面]
GUIで状態を確認したい場合は、docker-compose.serverless.override.ymlを作ってダッシュボードをホストに公開できます。
services:
nuclio:
ports:
- '127.0.0.1:8070:8070'
docker compose -f docker-compose.yml \
-f components/serverless/docker-compose.serverless.yml \
-f docker-compose.serverless.override.yml up -d
公開後は http://<Raspberry Pi 5のIP>:8070 でアクセスできます。
※Nuclioダッシュボードには認証が無いので、LANに公開する場合でも 127.0.0.1:8070:8070 のままにしておくのが無難です。インターネット側に晒してしまうと、任意の関数をデプロイできる穴になります。
[要スクリーンショット: Nuclioダッシュボードで yolov7 関数が ready になった状態]
4.CVATから自動アノテーションを実行#
ここまで来れば、あとはCVAT UI上の操作だけですね。
- CVATにログインし、画像が登録されたタスクを開きます(タスクが無い場合は1作目の手順を参考に適当なデータセットを登録してください)。
- アノテーション画面の左サイドバー上部にあるMagic wandアイコン(CVAT公式ドキュメント上の呼称)をクリック。
- Detectorsタブを選び、Modelドロップダウンから
YOLO v7を選びます(この表示名はfunction.yamlのannotations.nameに由来します)。 - CVATのラベルとモデル側のCOCOクラス(person, bicycle, car, ...)をマッピングし、必要ならThresholdを調整したうえで
Annotateボタンを押します。 - しばらく待つと、検出結果がbboxとして画像に反映されます。
[要スクリーンショット: CVATのアノテーション画面でAI Tools → Detectorsを開き、YOLO v7を選択したダイアログ]
[要スクリーンショット: 自動アノテーション実行後、人物や車両にbboxが付与された状態の画像]
本環境では1枚あたり[要計測]秒程度で推論が返ってきます。Raspberry Pi 5のCPUは4コアCortex-A76 2.4GHzなので、入力解像度640×640のYOLOv7-onnxならギリギリ実用、というくらいの肌感です。
動作確認の小ネタ#
関数単体で叩いて応答を確認したい場合は、CVATの公式ドキュメントにもある nuctl invoke が使えます。
image=$(curl https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png --output - | base64 | tr -d '\n')
cat << EOF > /tmp/input.json
{"image": "$image"}
EOF
cat /tmp/input.json | nuctl invoke onnx-wongkinyiu-yolov7 -c 'application/json'
status: 200 OK と検出結果のJSONが返ってくれば、関数単体としては問題なく動いています。
5.停止・クリーンアップ#
CVAT本体ごと停止するときは、起動時と同じファイル群を指定してdownしてください。
docker compose -f docker-compose.yml \
-f components/serverless/docker-compose.serverless.yml down
特定の関数だけ消したい場合は下記の通り。
# 関数を削除
nuctl delete function onnx-wongkinyiu-yolov7 --platform local
# プロジェクトごと削除する場合(cvat配下の全関数が消えます)
nuctl delete project cvat --platform local
ビルド時に作られた中間イメージ(cvat.onnx.wongkinyiu.yolov7 など)も、ストレージが厳しい場合は docker image prune で掃除しておくと良いと思います。
6.さいごに#
Raspberry Pi 5上のCVATに、ONNX版YOLOv7を載せた自動アノテーションをひと通り通すことができました。お疲れ様でした。
実用上のボトルネックは、概ね下の2点くらいでしょうか。
- 推論レイテンシ:入力1枚あたり[要計測]秒。バッチで数千枚を流すような用途には正直つらいですが、「自分で引いた仮ラベルの叩き台」くらいの使い方なら十分実用範囲です。
- メモリ:Nuclio関数コンテナ+CVATスタックでメモリを結構食うので、8GBモデルでないと厳しいですね。
なお、pytorch系の関数(SAMやFaster R-CNNなど)をARM64で動かすにはbaseImageの差し替えとwheelの差し替えが必要で、function単位での移植作業が発生します。このあたりはまた別の記事で扱えればと思います。
ARM64対応で詰まりやすいのは結局のところ deploy_cpu.sh 冒頭のopenvino baseイメージビルドの一点なので、そこさえ回避できればONNX系関数は意外と素直に動くものですね。
参考文献#
https://docs.cvat.ai/docs/administration/community/advanced/installation_automatic_annotation/
https://docs.cvat.ai/docs/annotation/auto-annotation/ai-tools/
cvat/serverless/onnx/WongKinYiu/yolov7/nuclio at v2.64.0 · cvat-ai/cvat
Computer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise products, as well as labeling serv...
Release 1.15.9 · nuclio/nuclio
Changelog [1.15.9] - 2025-11-24 🚀 Features / Enhancements [Processor] Return a copy of statistics objects during metrics gathering (#3907) by @rokatyy 📚 Documentation [Docs] Add default maxReque...
Nuclio
Serverless for Real-Time and Data-Driven Applications

Next reading
あわせて読みたい
関連するベンチや運用ログ、深掘り記事を続けて読めます。