AWS Startup ブログ

効率的にインテル® FPGA エッジデバイス上の深層学習推論を実行する

この記事は AWS APN Blog “Using Fewer Resources to Run Deep Learning Inference on Intel FPGA Edge Devices” の和訳です。

推論は機械学習における重要なステージで、トレーニング済みのモデルを用いてエンドユーザーに洞察を提供します。画像分類、物体検出、セマンティックセグメンテーションなどの予測タスクを実行するために、モデルがクラウドやエッジにデプロイされます。

しかし、消費電力量や放熱に制限があったり、低レイテンシーかつ高スループットといった要件がある場合、IoT コントローラーやゲートウェイなどのエッジデバイスで大規模な推論を実装することが難しくなる場合があります。

そういった課題を解決するには、ハードウェアとソフトウェアの両方の最適化が必要です。ハードウェアの観点からは、フィールド プログラマブル ゲート アレイ(FPGA) が選択肢にあがる場合があります。FPGA を使用すると、再構成可能な論理ブロックのハードウェアアクセラレーションの恩恵により、単位電力あたりの高いパフォーマンスと、低レイテンシー、柔軟性が得られます。

AWS IoT コンピテンシー を持つ AWS パートナーネットワーク (APN) アドバンストテクノロジーパートナーであるインテル は、豊富な FPGA ポートフォリオを提供しています。インテル® FPGAは、産業用や自動車用といった長い製品寿命と信頼性を必要とする分野で成功を収めています。

本ブログでは、画像分類用のニューラルネットワークをトレーニングし、インテル® FPGA ハードウェア向けに最適化されたバイナリに変換・デプロイする手順について説明します。お手元にデバイスをご用意頂けると、より一層お楽しみ頂けます (詳細は後述)。

モデル量子化

ここまでで、インテル® FPGA チップのハードウェアアクセラレーションによって、パフォーマンス、レイテンシー、柔軟性がどのように向上するかについて言及しました。一方ソフトウェア側では、モデル量子化を適用することで、深層学習に必要な帯域幅、計算リソース、メモリフットプリントを削減できます。量子化という手法では、精度を大幅に低下させることなく、ニューラルネットワークの重みや活性化関数を少ないビットで表現します。

具体的には、推論モデルのパラメータを通常の単精度浮動小数点 (32 ビット) 値の代わりに、半精度 (16 ビット)、bfloat16 (16 ビットで 32 ビットと同じダイナミックレンジ)、または 8 ビット整数に置き換えることで、リソースの使用量を減らすことができます。

パフォーマンス低下を伴わない量子化の限度は一般的に 8 ビット程度と考えられていますが、 LeapMind株式会社が提供する Blueoil を使うと、(8 ビットをかなり下回る) 1 ビット重みと 2 ビット活性化関数の組み合わせでもパフォーマンスの低下をごくわずかにとどめることができます。

Blueoil は、このような極めて少ないビットで表現されるニューラルネットワークを作成するのに役立つオープンソースのエッジ深層学習フレームワークです。エッジ深層学習の専門知識がなくても、4 つのステップ (データセットの準備、設定ファイルの生成、モデルのトレーニング、モデルの変換) で極小量子化ニューラルネットワークのモデルを簡単に利用できます。

なお実装面では、1 ビット行列乗算は XNOR ゲートで実現されます。これにより、メモリが大幅に減り、乗算数が減り、計算効率が大幅に向上します。インテル® FPGA は、組合せロジックがオーバーヘッドなしでゲートレベルの信号を処理でき、データパスに設定できるため、1 ビットに適したアーキテクチャとなっています。

特に、Cyclone® V SoC FPGA を使用すると、画像信号処理パイプラインと ARM Cortex-A9 ハードプロセッサシステムを実行するマシンビジョンアルゴリズムを組み合わせて、低電力消費のチップ上に完全なマシンビジョンシステムを構築できます。そのようなシステムは、大規模な本番環境へのデプロイを行うにあたり、費用対効果の高い選択肢となります。

このようなケースにおいて、GP-GPU での汎用コンピューティングが必ずしも効率的でない点にご注意ください。GPU は通常、FP32 のような、より大きく高精度の信号を処理するように設計されているためです。それらにはより大きな回路サイズが必要で、電力使用量とコストが高くなることがあります。

ソリューションの概要

このユースケースは、エッジゲートウェイ (カメラ) と分析バックエンドで構成される産業用コンピュータビジョンアプリケーションを想定するものです。

図 1- インテル® FPGA へのエッジ深層学習パイプライン

左側には、エッジ推論用のターゲットデバイスである Terasic DE10-Nano Kitがあります。インテル® SoC FPGA をベースとするこの開発ボードは、メーカー、IoT 開発者、教育者向けに再構成可能なハードウェア設計プラットフォームを提供します。 AWS IoT Greengrass で AWS Device Qualification Program (DQP) 認定を受けており、 AWS Partner Device Catalogに掲載されています。

アーキテクチャの右側は AWS クラウドを表し、モデルがトレーニングされ、ターゲットエッジデバイス用に最適化されるように変換されます。


モデルのトレーニングと変換方法について

具体的な手順を説明します。以下のステップでモデルのトレーニングと変換を行うことができます。

前提条件

  • AWS アカウント
  • エッジでの推論を実際に試す場合は Terasic DE10-Nano Kit (Amazon で購入できます)。
  • イーサネットケーブルとインターネット接続。
  • ノート PC またはローカル開発環境。

以下のステップを実行し、モデルをトレーニングおよび変換しました:

  1. Amazon SageMaker ノートブックインスタンスを起動し、GitHub リポジトリの Bluegrass をクローンする。
  2. Docker イメージの構築、データセットの準備、設定のセットアップ、サンプルノートブックでのモデルのトレーニングと変換を行う。
  3. クラウドで推論結果の確認。
  4. DE10-Nano デバイスで Cyclone® V SoC FPGA を使用して、エッジで推論を試す。

ステップ 1: Amazon SageMaker ノートブックインスタンスの起動

開発環境として Amazon SageMaker ノートブック を使用して量子化されたモデルを準備しました。 Amazon SageMaker は、開発者やデータサイエンティストが機械学習モデルを迅速に構築、トレーニング、デプロイできるようにするマネージドサービスです。

まず最初に、 AWS マネジメントコンソール にログインし、Amazon SageMaker ページに移動します。

左側のペインで [Notebook Instances] を選択し、[Create notebook instance] を選択。

次のページで、[Notebook instance name] の値として bluegrass-notebook と入力します。次に、インスタンスタイプ (ml.t3.medium) を選択し、適切な AWS Identity and Access Management (IAM) ロールを設定。

[Git repositories-optional] セクションの [Repository] フィールドで、  2 に示す GitHub リポジトリの名前を [Clone a public Git repository to] というボックスに入力してください。

2-Amazon SageMaker Git repositories

次に、[Create notebook instance] ボタンを選択し、数分待ちます。

ノートブックインスタンスの状態が InService になったら、JupyterLab 環境を開き、 blueoil_cifar10_example.ipynb を見つけます。このノートブックは、以下のアクションを実行します:

  • モデルのトレーニングと変換のために Blueoil コンテナに基づいて Docker イメージを構築し、それを Amazon Elastic Container Registry (Amazon ECR) にアップロードします。
  • 事前処理されたデータセットを、公開されている Amazon Simple Storage Service (Amazon S3) バケットからダウンロード、展開し、自身のバケットに再びアップロードしてデータを準備します。
  • Blueoil の設定ファイルを自身のAmazon S3 バケットにアップロード。
  • Amazon SageMaker トレーニングジョブでモデルをトレーニング。
  • トレーニング済みモデルを Amazon SageMaker Processing で変換。
  • 変換されたモデルをダウンロード。

ステップ 2: Amazon SageMaker で Blueoil を実行する Docker イメージを構築

このノートブック冒頭では、Amazon SageMaker で Blueoil を実行するための Docker イメージを構築し Amazon ECR にプッシュします。この Docker イメージは、Amazon SageMaker トレーニングおよび Processing ジョブを実行するときに使用されます。

Amazon SageMaker トレーニングジョブは、TensorFlow, Apache MXNet, PyTorch などのビルド済みコンテナを使用することも (Python スクリプトのみ用意)、自身のコンテナをトレーニングジョブに持ち込む (BYOC) こともできる、完全マネージド型のトレーニング環境です。

Blueoil は Blueoil リポジトリに独自の Dockerfile があります。 それを Amazon SageMaker で BYOC で使用するには、いくつかの変更が必要です。予約されたサブディレクトリで ENV を設定し、Python トレーニングスクリプトをCOPYし、ENTRYPOINT を変更して、Amazon SageMaker がイメージを実行できるようにする必要があります (こちらの Dockerfile を参照してください)。これらは docker_push_ecr.sh によって実行されます 。

データセットの準備

一般公開されている CIFAR-10 データセット を使用しました。これは一般的な画像分類タスクに使用されます。リポジトリにはいくつかの例があり、他にも物体検出サンプルノートブックで Open Images データセット を使用することもできます。

CIFAR-10 データセットは、飛行機、自動車、鳥など 10 種類、 60,000 枚の画像で構成されています。元のデータセットは Python の NumPy 配列 形式で提供されていますが、Blueoil は Caltech101 フォーマットをサポートしています。

CIFAR-10 をCaltech101 フォーマットでダウンロードします。Caltech101 フォーマットでは、10 のカテゴリがディレクトリ構造で分類され、それぞれのカテゴリごとにトレーニングおよびテストデータセットがあります。データ形式の詳細については、 Prepare training dataset を参照してください。

次に、展開したデータセットを Amazon S3 にアップロードします。ここでは、S3 バケットのデータセットパスを暗黙的に指定しました。実際には、 sagemaker-{region}-{AWS アカウント ID} で指定される SageMaker のデフォルトバケット です。このバケットは、後でトレーニング用に Docker コンテナの /opt/ml/input/data ディレクトリに配置されます。

Blueoil の設定

Blueoil 設定は、通常、 Blueoil のインストール 後に blueoil init コマンドを実行することによって作成されます。この例では、 cifar10_sample.py 設定ファイルはすでに提供されています。

設定ファイルは、入力イメージサイズ ([32, 32])、バッチサイズ (64)、最適化手法 (Momentum 法と学習率などのハイパーパラメータ)、量子化設定 (バイナリ重み、2 ビット活性化関数)、データ拡張方法を指定します。

S3 の Amazon SageMaker のデフォルトバケットに、データセットと同じ方法で設定ファイルをアップロードします。

3 – Blueoil 設定ファイルを Amazon SageMaker にアップロードする

Amazon SageMaker トレーニング・Processing ジョブを使う

そして、SageMaker Python SDK で Amazon SageMaker トレーニングジョブを開始します:

import sagemaker
from sagemaker.estimator import Estimator

train_instance_type = 'ml.p3.2xlarge'

estimator = Estimator(
   image_name=ecr_image,
   role=sagemaker.get_execution_role(),
   train_instance_count=1,
   ….....
      …………….
      …………….

estimator.fit({'dataset': train_data, 'config': config_data})

Estimator では、Amazon ECR の Docker イメージ、インスタンス数、インスタンスタイプを指定します。最後の行でトレーニングを呼び出します。ml.p3.2xlarge GPU インスタンスでジョブを完了するには、約 30 分かかります。

ノートブックに表示されるログを確認して、進捗状況を監視しましょう。ログは Amazon CloudWatch Logsにも送信されます。トレーニングされたモデルは S3 バケットに保存されます。

同様の方法で Amazon SageMaker Processing ジョブでモデルを変換しました。変換されたモデルと推論スクリプトは output.tar.gz として圧縮され、S3 バケットに保存されました。

トレーニングモデルの処理

Amazon SageMaker の トレーニング ジョブと Processing ジョブについて詳しく説明します。

私たちの例では、Docker コンテナを準備しました。これには、Blueoil から train コマンドと convert コマンドを呼び出し、Amazon SageMaker トレーニングジョブおよび Processing ジョブでそれぞれ実行する main.py スクリプトが含まれています。

モデル量子化には、トレーニング中から量子化を考慮した手法とトレーニング後の量子化という 2 つのアプローチがあります。前者のアプローチでは、量子化によるエラーを見込んでニューラルネットワークをトレーニングできます。

Blueoil では、量子化を考慮したトレーニングを採用しています。これにより、通常は量子化後でも高い精度が得られます。Blueoilの convert コマンドは、 Convert training result to FPGA ready format で説明されているように、以下のプロセスを実行します:

  • TensorFlow チェックポイントを Protocol Buffers形式のグラフに変換。
  • グラフを最適化。
  • 実行可能バイナリのソースコードを生成。
  • x86-64, ARM, FPGA 用にコンパイル。

ステップ 3: クラウドで推論結果を確認

トレーニングと変換の完了後、モデル成果物を含む output.tar.gz ファイルをダウンロードして展開し、cifar10_sample ディレクトリを見つけます。

成果物は以下に入っています:

cifar10_sample/saved/{MODEL_NAME}/export/save.ckpt-{Checkpoint No.}/{Image size}/output subdirectory; namely, cifar10_sample/export/save.ckpt-78125/32x32/output/

図 4 – output.tar.gz ファイルの展開

ノートブックインスタンス上で推論結果を確認するため、output/pythonで sudo pip install -r requirements.txt を実行した後、ターミナルウィンドウを開き、 run.py スクリプトを実行しました。この飛行機のイメージのラベルを推測する例を次に示します:

$ python run.py \
-i airplane.png \
-m ../models/lib/libdlk_x86.so \
-c ../models/meta.yaml

これにより、 output/output.json が生成されます。

ml.m5.xlarge ノートブックインスタンスの結果は次のとおりです:

$ cat output/output.json
{
    "benchmark": {
        "inference": 0.03394120899997688,
        "post": 0.009801765000020168,
        "pre": 0.003248117000111961,
        "total": 0.04699109100010901
    },
    "classes": [
        {
            "id": 0,
            "name": "airplane"
…..
………
………….
                "probability": "0.77472717"

airplane クラスが、最も高い確率で予測されたラベルであることがわかります。

Amazon SageMaker ノートブックインスタンスには インテル® Xeon® CPU が搭載されているため、x86 アーキテクチャを使用しました。ARM アーキテクチャ用のバイナリを試す場合は、AWS Graviton/Graviton2 プロセッサを搭載した Amazon EC2 A1 または M6g/C6g/R6g インスタンスで同様の手順を実行します。

この セットアップスクリプト を使用した、m6g.xlarge インスタンスの結果を次に示します:

$ cat output/output.json
{
    "benchmark": {
        "inference": 0.002424001693725586,
        "post": 0.009356975555419922,
        "pre": 0.0031518936157226562,
        "total": 0.014932870864868164
    },
…
    "results": [
        {
            "prediction": [
                {
                    "class": {
                        "id": 0,
                        "name": "airplane"
                },
                "probability": "0.77472717"

ここでも、最も高い確率を持つ同じ予測ラベル airplane が出力されます。また、model/lib ディレクトリ内に libdlk_fpga.so があることが確認できますが、これは次の DE10-Nano デバイスで使用します。

ステップ 4: Edgeで推論を試す

DE10-Nano デバイスで推論を試すには、まずホストコンピュータ (ノート PC またはローカル開発環境) の microSD カードに ブートイメージ を書き込む必要があります。最も簡単な方法は、 Etcher ソフトウェアを使用することです。その後、DE10-Nano デバイスに microSD カードを挿入して起動します。

図 5 – DE10-Nano デバイスへのブートイメージの書き込み

デバイスの左上に電源アダプタが接続されています。右上から右下に向かって、カメラ用の USB Micro-B、次にホストコンピュータへの UART 接続用の USB Mini-B (デバッグ用)、右下にインターネット接続に必要なイーサネットケーブルがあります。

デバイスには、以下のコマンドで UART 経由でアクセスできます:

sudo cu -l  /dev/<your_fpga_board>  -s 115200

具体的には、Linux では以下のようになり:

sudo cu -l  /dev/ttyUSB0  -s 115200

macOS では、以下のようになります。

sudo cu -l  /dev/tty.usbserial-A106I1IY -s 115200

デフォルトのユーザー名とパスワードは、それぞれ root と de10nano です。

ifconfig コマンドで IP アドレスを確認することもできます。最初に IP アドレスを修正することをお勧めします。IP アドレスは、セットアッププロセス中に一貫性を保ち、後で Ansible オートメーションエンジンと一致している必要があります。

ifconfig | grep HWaddr でデバイスの MAC アドレスを見つけ、出力結果を次のように /etc/network/interfaces ファイルの末尾に記載することで実現できます:

auto eth0
iface eth0 inet dhcp
hwaddress ether <MAC address of your device>

ここで SSH 設定もセットアップすると便利です (ssh-keygen および ssh-copy-id を使用)。 次に、README に書かれているように Ansible プレイブックを実行します。

$ ansible-playbook -i <デバイスのIPアドレス>, ansible/playbook.yml

このコマンドにより、Blueoil で実行される Linux カーネルモジュール、 zImagepreloaders などが更新されます。

最後に、Amazon S3 から output.tar.gz をダウンロードし、デバイスに送信して展開し、 cifar10_sample/export/save.ckpt-78125/32x32/output/python ディレクトリを見つけます。残りの必要なパッケージもインストールします。

$ apt-get update
$ apt-get install python3-pip libjpeg-dev zlib1g-dev
$ pip3 install -r requirements.txt

サンプルイメージをダウンロードした後、同様のコマンドを実行します:

$ python run.py \
-i airplane.png \
-m ../models/lib/libdlk_fpga.so \
-c ../models/meta.yaml

出力はこんな感じです:

$ cat output/output.json
{
    "benchmark": {
        "inference": 0.007309094988158904,
        "post": 0.1206085180019727,
        "pre": 0.03428893999080174,
        "total": 0.16220655298093334
    },
…
    "results": [
        {
            "prediction": [
                {
                    "class": {
                        "id": 0,
                        "name": "airplane"
                },
                "probability": "0.9101995"

後片付け

今後課金されないようにするには、Amazon SageMaker ノートブックインスタンスなど、使用したリソースは削除してください。

まとめ

Amazon SageMaker 上で Blueoil を利用し、より少ないコンピューティングリソースで インテル® FPGA プロセッサのエッジで推論するための深層学習モデルをトレーニングおよび最適化します。このアプローチにより、精度を犠牲にすることなく、低レイテンシーかつ高スループットを実現し、エッジでの大規模な産業用デプロイにかかる制約を克服できます。Bluegrass を利用することで、お客様はクラウドからエッジへの深層学習パイプラインを AWS IoT Greengrass 経由で簡単にデプロイできます。

なお、量産用途で FPGA の採用を検討される場合は、株式会社近藤電子工業が提供する KEIm-CVSoC などの System-on-Module をお使い頂くことができます。この製品は、LeapMind株式会社が提供を予定している AI 推論アクセラレータ IP「Efficiera」にも対応予定で、深層学習を搭載した製品開発を短縮し、お客様の組込み AI 製品の量産化を促進させます。


インテル – APN パートナースポットライト

インテルは AWS コンピテンシーパートナーであり、絶え間ないイノベーションの実現に向けた熱意をAWSと共有しています。インテルと AWS は共同で、ハイパフォーマンスコンピューティング、ビッグデータ、機械学習、IoT 向けにさまざまなリソースとテクノロジーを開発してきました。

インテルへのお問い合わせ | プラクティスの概要 | AWS Marketplace

* すでにインテルと協働したことがありますか? パートナーを評価してください

*評価対象のAPNパートナーとプロジェクトで直接協働したことのある AWS のお客様のみ、当該パートナーをレビューすることができます。