ailia Speech の QNN バックエンドを使用して、Qualcomm SoC の NPU で Whisper による音声認識を高速に実行する方法を説明します。
ailia Speech 1.6.0 以降は、Qualcomm SoC の NPU(Hexagon)を使用した Whisper の推論に対応しています。NPU を使用することで、高速・低消費電力に音声認識を実行できます。
QNN(Qualcomm AI Engine Direct)は Qualcomm が提供するバックエンド API です。ailia Speech では、Whisper のエンコーダとデコーダを SoC 専用の QNN Model(.qnn)に変換したファイルを使用します。1 つの .qnn にエンコーダとデコーダの両方が含まれているため、端末には ONNX は不要で、.qnn のみを配置します。
.qnn)の読み込みは ailia Speech 1.6.0 以降で利用できます。
QNN Model は SoC ごとに別ファイルになります。端末の SoC に一致する .qnn を使用してください。異なる SoC 向けのモデルは流用できません。
現在は Whisper Large V3 Turbo と Whisper Medium に対応しています。いずれも Int16 に量子化したモデルです。
変換済みの Whisper の QNN Model は下記からダウンロードできます。対象端末の SoC に対応したファイルをご利用ください。
| SoC | 端末の例 | モデル | ファイル | サイズ |
|---|---|---|---|---|
| sm8475 | Snapdragon 8+ Gen 1 | Large V3 Turbo | whisper-large-v3-turbo-sm8475-int16.qnn | 1.00 GB |
| Medium | whisper-medium-sm8475-int16.qnn | 0.96 GB | ||
| sm7635 | Snapdragon 7s Gen 3 | Large V3 Turbo | whisper-large-v3-turbo-sm7635-int16.qnn | 1.11 GB |
| Medium | whisper-medium-sm7635-int16.qnn | 0.93 GB | ||
| sc8380xp | Surface(Snapdragon X Plus) | Large V3 Turbo | whisper-large-v3-turbo-sc8380xp-int16.qnn | 0.97 GB |
| Medium | whisper-medium-sc8380xp-int16.qnn | 0.91 GB | ||
| qcs6490 | QCS6490 | Large V3 Turbo | whisper-large-v3-turbo-qcs6490-int16.qnn | 1.01 GB |
| Medium | whisper-medium-qcs6490-int16.qnn | 0.93 GB |
いずれも ailia Speech 1.6.0(QAIRT 2.47.0.260601)向けです。
QNN ランタイムの取得と配置は ailia SDK と共通です。Android の AndroidManifest.xml と build.gradle の設定、Windows on Arm での QNN DLL と NPU 側の .so / .cat の配置は ailia SDK の QNN セットアップを参照してください。QNN ランタイムはモデル生成時と同じ QAIRT 2.47.0.260601 を使用してください。
Android では .qnn は assets 内のパスを直接指定できません。初回起動時にアプリのプライベートストレージへコピーするかダウンロードし、その実ファイルパスを以下の API に渡してください。
通常は Open 時にエンコーダとデコーダの ONNX をそれぞれ指定しますが、QNN Model を使用する場合は、エンコーダとデコーダの両方に同じ .qnn のパスを指定します。モデルタイプには .qnn の元になったモデル(Large V3 Turbo または Medium)を指定します。以降の文字起こしの API は ONNX を使用する場合と同じです。
#include "ailia_speech.h"
#include "ailia_speech_util.h"
const char *qnn_path = "/data/user/0/your.package/files/whisper-large-v3-turbo-sm7635-int16.qnn";
struct AILIASpeech *speech = NULL;
ailiaSpeechCreate(&speech, env_id, AILIA_MULTITHREAD_AUTO, memory_mode,
AILIA_SPEECH_TASK_TRANSCRIBE, AILIA_SPEECH_FLAG_NONE,
ailiaSpeechUtilGetCallback(), AILIA_SPEECH_API_CALLBACK_VERSION);
/* エンコーダとデコーダに同じ .qnn を指定する */
ailiaSpeechOpenModelFileA(speech, qnn_path, qnn_path,
AILIA_SPEECH_MODEL_TYPE_WHISPER_MULTILINGUAL_LARGE_V3_TURBO);
using System.IO;
using UnityEngine;
using ailiaSpeech;
string qnnPath = Path.Combine(Application.persistentDataPath, "whisper-large-v3-turbo-sm7635-int16.qnn");
var speech = new AiliaSpeechModel();
// エンコーダとデコーダに同じ .qnn を指定する
speech.Open(qnnPath, qnnPath, envId, memoryMode,
AiliaSpeech.AILIA_SPEECH_MODEL_TYPE_WHISPER_MULTILINGUAL_LARGE_V3_TURBO,
AiliaSpeech.AILIA_SPEECH_TASK_TRANSCRIBE,
AiliaSpeech.AILIA_SPEECH_FLAG_NONE, "auto");
import 'package:ailia_speech/ailia_speech.dart';
const qnnPath = '/data/user/0/your.package/files/whisper-large-v3-turbo-sm7635-int16.qnn';
final speech = AiliaSpeechModel();
// エンコーダとデコーダに同じ .qnn を指定する
await speech.open(
encoderFile: qnnPath,
decoderFile: qnnPath,
modelType: AILIA_SPEECH_MODEL_TYPE_WHISPER_MULTILINGUAL_LARGE_V3_TURBO,
);
context は Android の Activity または Application の Context です。
val qnnPath = "${context.filesDir}/whisper-large-v3-turbo-sm7635-int16.qnn"
val speech = AiliaSpeech(
envId = -1,
task = AiliaSpeech.AILIA_SPEECH_TASK_TRANSCRIBE,
flags = AiliaSpeech.AILIA_SPEECH_FLAG_NONE,
)
// エンコーダとデコーダに同じ .qnn を指定する
speech.openModel(qnnPath, qnnPath,
AiliaSpeech.AILIA_SPEECH_MODEL_TYPE_WHISPER_MULTILINGUAL_LARGE_V3_TURBO)
NPU での測定結果は ailia Speech NPU(QNN)ベンチマーク を参照してください。
Android 向けの評価版 APK は ailia-models-kotlin-qnn.apk です。Snapdragon 8+ Gen 1(sm8475)または Snapdragon 7s Gen 3(sm7635)を搭載した端末で動作します。
Windows on Arm 向けの評価版アプリは ailia-models-flutter-qnn-v261020.zip です。Snapdragon X Plus もしくは QCS6490 で動作します。