この記事は以下の記事をもとに書かれていますが、SNPE環境の展開やサーバー側推論については前回の記事を参照してください。
この記事の最も重要な部分は、SNPE を使用して、Android 環境のさまざまなランタイム (CPU/GPU/DSP) でニューラル ネットワーク推論を実行することです。
主に「組織委員会の AI モデルの加速」の記事を参照してください。
SNPE の開始 - 888 の HTP 推論 inceptionV3 の使用 - Zhihu
クアルコムSNPE公式ドキュメント
Snapdragon ニューラル プロセッシング エンジン SDK: メイン ページ
著者が使用している携帯電話のモデルは Redmi K40 pro、チップは Snapdragon 888、私は Redmi note7 を使用、チップは Snapdragon 660AIE プロセッサです。
1. 最初の質問: チップに対応する SNPE バージョンをどのように選択すればよいですか?
クアルコム SNPE ダウンロード リンク:
AI 用 Qualcomm ニューラル プロセッシング SDK - Qualcomm Developer Network
[アーカイブ] をクリックして古いバージョンを見つけるには、インターネット速度が比較的遅いため、しばらくお待ちください。
開くと、次のインターフェイスが表示されます。
ダウンロード後、解凍し、1.41.0 も必要な場合は、以下のリンクから直接ダウンロードできます。
https://developer.qualcomm.com/downloads/qualcomm-neural-processing-sdk-ai-v1410?referrer=node/69030
重要な注意事項: どのバージョンをダウンロードするかは非常に重要です。そうでないとエラーが報告されます。!
ヒント: 1.41.0 を選んだ理由、どうやって見つけたのか、私の方法:
古い携帯電話なので、最初に古いバージョンを探しました。すぐには見つからないかもしれません。何度か試した後、snpe 1.41.0 が私の携帯電話をサポートしていることがわかりました。index.html を開きます。
ブラウザに次のインターフェイスが表示され、「概要」をクリックし、右側で「サポートされている Snapdragon デバイス」を見つけます。このバージョンが Snapdragon 660 をサポートしていることがわかります。
この時点で、SNPE がダウンロードされました。
2. SNPEをサーバー環境に導入する
前回の記事を参照してください
3. 携帯電話環境の準備
ステップ 1: 携帯電話を root 化する
私は adb コマンドを使用します。この手順は必要です。そうしないと、adb 関連のコマンドは実行できません。ルート メソッドはオンラインで見つけることができます。私の Redmi の簡単な紹介:
1.携帯電話BLロック解除
参考:Xiaomi携帯電話公式のBootLoaderロック解除グラフィックチュートリアル - すべてのモデルに適用可能20210925アップデート - ROMパラダイス公式サイト
2.ルートを開始します
簡単な方法を教えてください、タオバオを使用してください。ほとんどすべてのフラッシュ ソフトウェアを試しましたが、どれも役に立ちませんでした。タオバオならたった 20 元でできます。
ステップ 2: サーバーが携帯電話に接続する
主な参考記事: ubuntu で adb を使用して Android 携帯電話に接続する方法
次に、 adb を使用してubuntuでAndroid携帯電話に接続する方法を見てみましょう。通常の状況では、これは非常に簡単です。
android-tools-adbをインストールする
sudo apt update
sudo apt install android-tools-adb android-tools-fastboot
開発者モードをオンにする
次に、携帯電話で開発者モードをオンにする必要があります。Androidスマートフォンの設定を開き、「About Phone」または 「About Device」を見つけて (携帯電話メーカーの名前が一致していない可能性があります) 、バージョン番号を7回クリックすると、携帯電話は開発者モードに入ります。
設定に戻ると、 開発者向けオプション というオプションが表示されます。そのオプションをクリックして、 その中でUSBデバッグを見つけて有効にします
adbサービスを開始する
adb start-server
電話に接続されているかどうかを確認する
adb devicesコマンドを使用して、デバイスが正常に接続されているかどうかを確認できます。通常の状況では、端末に次の出力が表示されます。これには、モデルなどの電話機に関する情報が含まれています。その他の場合は不明です。電話。
adb devices
List of devices attached
NX507J device
携帯電話に正しく接続していない場合は、以下のエラーが発生していないか確認してください。
接続エラーを修正する
???????????? 権限がありません
adb devices
List of devices attached
???????????? no permissions
これは、現在のユーザー グループがデバイスにアクセスする権限を持っていないためです。現在のユーザーをplugdevグループに追加してください。
sudo useradd -G plugdev $USER
コマンドを再度使用して、 adb devices
それが正しいかどうかを確認します
adb devices
それでも権限がない場合は、デバイスIDを確認し、udevルールを作成します。
lsusb
Bus 002 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 004: ID 0930:6545 Toshiba Corp. Kingston DataTraveler 102/2.0 / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick
Bus 003 Device 003: ID 046d:c077 Logitech, Inc. M105 Optical Mouse
Bus 003 Device 002: ID 17ef:602d Lenovo
Bus 003 Device 006: ID 19d2:ffc1 ZTE WCDMA Technologies MSM
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
udevルールの作成/etc/udev/rules.d/51-android.rules
sudo mkdir -p /etc/udev/rules.d/
sudo touch /etc/udev/rules.d/51-android.rules
sudo gedit /etc/udev/rules.d/51-android.rules
以下を貼り付けます
SUBSYSTEM=="usb", ATTRS{idVendor}=="19d2", MODE="0666", GROUP="plugdev
注:デバイスID はATTRS{idVendor}の値に対応します。
ルールファイルの権限を変更する
sudo chmod a+r /etc/udev/rules.d/51-android.rules
ルールをリロードし、udevサービスを再起動します。
sudo udevadm control --reload-rules
sudo service udev restart
sudo udevadm trigger
adb devicesコマンドを再度使用して、それが正しいかどうかを確認します。その後、次のコマンドを使用して電話機にログインして操作できるようになります。
adb shell
以上で準備作業はすべて完了しました。いよいよ Android 環境に正式に入って推論操作を実行します。
注:サーバーが携帯電話に接続する場合は記事を参照し、個別に自分の携帯電話を参照してください。
4. Android 環境は推論操作に異なるランタイムを使用します
(1) CPUとGPUによる推論の実装
このパートでは主に CPU と GPU による比較的単純な推論の実装について説明しますが、DSP を使用する場合はより複雑になるため、DSP の部分については個別に説明します。
前回の記事からの続き
( 1 ) データとモデルを携帯電話/data/local/tmp/incpv3にプッシュします
次の 3 つのコマンドを順番に実行します。
adb shell mkdir /data/local/tmp/incpv3
adb push inception_v3.dlc /data/local/tmp/incpv3
adb push data/. /data/local/tmp/incpv3
実行結果は次のとおりです。
( 2 ) SNPEに対応したライブラリlibSNPE.soとテストツールsnpe-net-runを用意する
必要な SNPE ライブラリ libSNPE.so、libc++_shared.so、およびテスト アプリケーション snpe-net-run を携帯電話 /data/local/tmp/incpv3/ にプッシュします。
これを行う前に、携帯電話がサポートしている CPU アーキテクチャを知る必要があります。その方法は次のとおりです。
Android デバイスのアーキテクチャ
参考:
Android デバイスのアーキテクチャ: arm64-v8a armeabi-v7a
Android デバイスのアーキテクチャ: arm64-v8a armeabi-v7a - Zhihu
adb シェル getprop ro.product.cpu.abi
私のRedmi note7携帯電話の実行効果:
したがって、次を選択します: aarch64-android-clang6.0 (必ずしも正しいとは限りません)
次の 6 つのコマンドを順番に実行します。
adb shell mkdir -p /data/local/tmp/incpv3/arm64/lib
adb shell mkdir -p /data/local/tmp/incpv3/arm64/bin
adb shell mkdir -p /data/local/tmp/incpv3/dsp/lib
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/libSNPE.so /data/local/tmp/incpv3/arm64/lib
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/libc++_shared.so /data/local/tmp/incpv3/arm64/lib
adb push $SNPE_ROOT/bin/aarch64-android-clang6.0/snpe-net-run /data/local/tmp/incpv3/arm64/bin
注: .so ファイルをプッシュするには、コマンドを使用して 12 個の .so ファイルすべてを一度に携帯電話にプッシュできます。
adb push $SNPE_ROOT/lib/aarch64-android-clang6.0/. /data/local/tmp/incpv3/arm64/lib
これにより、間違った .so ファイルによるエラーを防ぐことができるので、そのまま上書きしました。
携帯電話のディレクトリの arm64/lib の下に、12 個のファイルすべてをそこに置きます。
(3) CPUとGPU上のReasoning inceptionV3
注: この部分では、操作のためにモバイル Android システムを入力する必要があります。上記はすべてサーバー操作です。
実行: モバイル環境は事前に準備されているため、adb シェルがモバイル Android システムに入ります。
lsコマンドを実行して権限がないことを確認し、suコマンドを実行してlsで確認すると成功です。
注: 赤いボックス内は、携帯電話を入力し、サーバーにはもう存在しない携帯電話のディレクトリを表示していることを意味します。
4 つのコマンドを順番に実行します(エクスポートは環境変数を設定することです。これは一時的なものであることに注意してください。このコマンドは、電話機を再接続したり取り外したりするたびに再実行する必要があります。電話機に永続的に書き込むことができます。読者はそれを試すことができます)彼ら自身):
cd /data/local/tmp/incpv3/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/local/tmp/incpv3/arm64/lib
export PATH=$PATH:/data/local/tmp/incpv3/arm64/bin
snpe-net-run --version
赤いボックス内のバージョン番号が表示されたら、モバイル Android で SNPE が正常に実行されました。
( 4 ) CPU上の inceptionV3 で推論し、output_cpuに出力
snpe-net-run --container inception_v3.dlc --input_list target_raw_list.txt --output_dir output_cpu
赤枠が出力結果です
Output_cpu フォルダーに入り、ls -al を実行すると、生成されたファイルを表示できます。
注: 警告がたくさんありますが、実際には結果には影響しません。最初は存在しませんでした。知っている友人が理由を教えてくれます。
( 5 ) GPUでinceptionV3を推論し、 output_gpuで出力します。
snpe-net-run --container inception_v3.dlc --input_list target_raw_list.txt --output_dir output_gpu --use_gpu
出力は次のとおりです。
( 6 ) SNPEDiag.logを解析して、 CPUとGPUの推論速度を取得します。
adb pull /data/local/tmp/incpv3/output_cpu .
adb pull /data/local/tmp/incpv3/output_gpu .
次の結果に示されているように、
注: 上記のコマンドは携帯電話ではなくサーバーで実行されます。!
サーバー側で解析コマンドを実行します。snpe-diagview を使用して SNPEDiag.log を解析し、推論時間を取得します。
CPU:
snpe-diagview --input_log output_cpu/SNPEDiag_0.log
結果は次のとおりです。合計推論時間: 658419us がわかります。
GPU:
snpe-diagview --input_log output_gpu/SNPEDiag_0.log
ご覧のとおり、総推論時間: 351066us
この時点で、CPU と GPU リソースを使用した推論は完了しました。おめでとうございます。
(2) DSP実装推論
1.まず、携帯電話チップがDSPをサポートしているかどうかを確認します。660はDSPをサポートしていますが、AIP をサポートしていないことがわかります。
2.定量的モデル
DSP 推論モデルは量子化する必要があります。ここでは INT8 が使用されています。このチップは INT8 量子化のみをサポートしていると理解しています。
SNPE は、ポスト量子化ツール snpe-dlc-quantize に加えて、キャッシュ データを生成し、初期化速度を向上させるオプション --enable_hta を提供します。このオプションはバージョンに依存しており、SNPE のバージョンが変更された場合はキャッシュを再生成する必要があります。
一般に、事後定量化に必要なサンプル データは 100 ~ 200 個ですが、ここでは関数のデモのみを行い、より少ないデータを使用します。
#データと入力リストを作業ディレクトリにコピーします
cp data/cropped . -r
cp data/target_raw_list.txt .
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list target_raw_list.txt --output_dlc inception_v3_hta.dlc --enable_hta
ls -al
注: 元のテキストはenable_htpですが、すべてenable_htaに変更しました。そうしないとエラーが報告されます。自分で処理してみてください。
次の画面が表示され、エラーは報告されず、実行は成功し、inception_v3_hta.dlc ファイルが生成されます。
……
注: 出力プロセスは非常に長いため、編集されています。
3. 660に必要なDSPライブラリを携帯電話に準備する
サーバーに切り替えて、.so ファイルを携帯電話にプッシュします。
携帯電話ディレクトリに切り替えて表示します。
6 つの .so ライブラリが正常にプッシュされました
量子化されたファイルを携帯電話にプッシュします: inception_v3_hta.dlc
adb push inception_v3_hta.dlc /data/local/tmp/incpv3/
4.推論開始 V3に660のDSPを使用する
環境変数を設定する LD_LIBRARY_PATH と PATH に加えて、.so ファイルのパスを指すように ADSP_LIBRARY_PATH を設定する必要があります。
注: 上記の 660 チップは CDSP のみをサポートしますが、環境変数名は ADSP_LIBRARY_PATH のままです。
環境変数を設定します。
export ADSP_LIBRARY_PATH="/data/local/tmp/incpv3/dsp/lib;/system/lib/rfsa/adsp;/system/vendor/lib/rfsa/adsp;/dsp"
注: ここにある Qualcomm のドキュメントによると、ほとんどの携帯電話 DSP ディレクトリは上記のいずれかであるため、すべてのディレクトリが携帯電話に存在するわけではありません。携帯電話 DSP が上記のいずれかに含まれていない限り、上記の設定に従ってください。
推論を実行します。
snpe-net-run --container inception_v3_hta.dlc --input_list target_raw_list.txt --use_dsp --output_dir output_hta
実行結果は次のようになり、成功したことがわかります。
注 1: これはセキュリティ上の考慮事項によるもので、unsignedPD は開発者のみに公開されているため、次の設定を行う必要があります。
snpe-net-run --use_dsp --platform_options unsignedPD:ON
ただし、私の場合はエラーが報告されませんでした。この手順は実行しませんでした。エラーが報告された場合は、元の作成者に従って対処してください。
注 2: 著者の原文は htp、
5.結果戻り分析の推論時間
返された結果:
adb pull /data/local/tmp/incpv3/output_hta .
結果分析:
snpe-diagview --input_log output_hta/SNPEDiag_0.log
結果は以下のようになります。
……
注:途中削除があります
おめでとうございます。大きな一歩を踏み出しました。
最後に、さまざまなランタイムの推論時間を比較してみましょう。
ランタイム |
推論時間 (ミリ秒) |
CPU |
658 |
GPU |
351 |
DSP |
60 |
CPU の推論時間は DSP の 11 倍、GPU は DSP の 5.9 倍であり、DSP は依然として非常に優れていることがわかります。!