AIアプリの未来はデバイス上にある:React Native ExecuTorchでAIモデルを実行する方法
Development • React Native • October 2, 2025 • 14 minutes read
Norbert Klockiewicz(ゲスト著者)
Maciej Rys(ゲスト著者)
ユーザーのデータを安全かつプライベートに保ちながら、Expoアプリ内にAIモデルを統合する方法を学びます。
AIアプリは現在大人気で、何千もの開発者が取り組んでいます。しかし多くの開発者は、データをモデル提供者のAPIに送信したりアクセス料を支払ったりせずにAIを統合できることに気づいていません。かつてはオンデバイスAIは実験的な領域に過ぎませんでしたが、モデルが小型化・効率化し、デバイス側の処理能力が向上したことで、この技術は誰でも使えるものになりました。
オンデバイスAIとは何か
10年以上前(2011年)にSiriがモバイルAIの初期例として登場しました。数年後(2014年)には「Hey Siri」コマンドでSiriを呼び出せるようになり、これは初期のオンデバイスAI機能のひとつでした。本当のブレイクスルーは2017年、A11 Bionic(iPhone X)にNeural Engineが導入され、6000億(600 billion)オペレーション/秒の専用AI処理能力を提供したときです。それ以降、技術は単純な音声コマンドを超えて進化しました。最新のNPU(例:iPhone 16 Pro)は35兆(35 trillion)オペレーション/秒を実行可能で、洗練された言語モデルやリアルタイムの画像生成などが完全にデバイス上で動作します。
しかしハードウェア能力は土台に過ぎません。オンデバイスAIはモバイルアプリに対して次のような利点を提供します:
- プライバシー・バイ・デザイン:ユーザーデータはデバイスを出ません。機密文書の要約、個人写真の解析、機密情報の処理などでも完全なプライバシーが確保されます。
- 無料化の可能性:継続的なAPIコストや予測できないクラウド費用を排除できます。クラウドで毎月何百ドルかかるモデルが、ユーザーのデバイス上で追加コストなしに動作します。
- ユニバーサルな信頼性:機内モード、遠隔地、ネットワーク障害時でも動作します。クラウド依存のソリューションでは不可能なユースケースが可能になります。
- 即時応答:ネットワーク往復がないため、サブ秒の応答が可能で、自然で即時の体験を提供します。
ただし、オンデバイスAIの実装には重大な課題もあります。モバイルデバイス上で直接AIモデルを動かすにはExecuTorchのような推論エンジンの統合が必要です。これらは巨大なプロジェクトで、複雑なビルドプロセスやドメイン固有の知識を要求します。そこで、react-native-executorchのようなライブラリが、開発者からこれらの複雑さを抽象化して橋渡しを行います。
react-native-executorchの紹介
react-native-executorchはSoftware Mansionによって作成されたライブラリです。目的は、React Native開発者が機械学習の専門知識や複雑なインフラ構築なしにAI機能を実装できるようにすることです。ライブラリは包括的な開発エコシステムを提供します:
- Hugging Faceにホストされた事前エクスポート済みモデルがあり、すぐに利用可能。
- 前処理・後処理を抽象化した直感的なAPI。
- 既存のReact Nativeワークフローへのシームレスな統合。
技術的な深掘り
内部では、react-native-executorchはMetaの推論エンジンであるExecuTorchを活用しています。ExecuTorchはInstagramやFacebookアプリのオンデバイスAI機能を支えるエンジンで、エッジデバイスへのAI展開に対するエンドツーエンドのソリューションを提供します。主な利点は次の通りです:
- PyTorchエコシステムの統合:開発者は馴染みのあるPyTorch環境でモデルを構築・学習し、それをモバイル向けに直接エクスポートできます。
- クロスプラットフォームの汎用性:スマートフォンに限らず、マイクロコントローラ、スマートウォッチ、AR/VRヘッドセット、IoTデバイスなど、エッジコンピューティング全体をサポートします。
- 最適化されたパフォーマンス:CoreML(iOSのNeural Engineアクセラレーション)やVulkan(クロスプラットフォームGPU計算)、およびモバイルGPU向けの専用バックエンドなど、様々なバックエンドをサポートしてハードウェア利用を最大化します。これにより、デバイス能力に依らずモデルを効率的に動作させられます。
Figure 1: Communication flow between react-native-executorch and ExecuTorch.
しかし課題もある(現実的な制約)
オンデバイスAIは万能ではありません。利点は魅力的ですが、制約を無視するとユーザー体験に重大な影響を与えます。
オンデバイスAIが問題になる場面
- リソース消費:AI推論は計算集約的です。AI処理が多いとバッテリー消耗が早まり、長時間の処理でデバイスが明らかに熱くなることがあります。現代のチップは効率的ですが、物理法則の制約は残ります。計算量が増えればエネルギー消費も増えます。
- ハードウェア制約:フラッグシップ端末でさえ限界があります。多くのスマートフォンは6〜12GBのRAMを提供しますが、その一部しかアプリに割けません。20GB以上を必要とする大規模言語モデルは、最適化してもローカル実行は不可能です。
- ストレージと配布の課題:モデルは数十MBから数GBに及ぶことがあります。これにより配布のジレンマが発生します:アプリにバンドルすればダウンロードサイズが増え、ストアの制限に触れる可能性があります。あるいは複雑なダウンロード戦略を実装すると初回ユーザー体験が悪化します。
- パフォーマンス差:API応答時間はデバイス間で比較的一貫しますが、オンデバイスのパフォーマンスは機種ごとに大きく異なります。あるモデルがフラッグシップ機で50 tokens/secondで生成できても、ミドルレンジ機では5 tokens/secondしか出ない、というようにユーザー体験が不均一になります。
軽減戦略
- 量子化と最適化:量子化などの手法により、モデルサイズを50〜75%削減しつつ許容できる精度を保てます。重み精度を32-bitから8-bit、あるいは4-bitに減らすことで、モデルは高速かつメモリ効率が良くなります。その他、モデルプルーニング、知識蒸留、ダイナミックロード方式なども効果的です。
- ハイブリッドアーキテクチャ:シンプルで頻繁なタスクはデバイスで、複雑な処理はクラウドで行うなど、パフォーマンス、プライバシー、リソース制約をバランスさせる戦略が有効です。
いつオンデバイスAIを選ぶべきか
- オンデバイスAIを避けるべき場合:全てのデバイスで一貫したパフォーマンスが必要な場合、最新の大規模モデルが必要な場合、あるいはアプリのフットプリントを最小化したい場合。
- オンデバイスAIを選ぶ場合:プライバシーが最優先、オフライン機能が必須、あるいは超低レイテンシでリアルタイムなインタラクションが求められる場合。
重要なのは技術的アプローチをプロダクト要件に合わせることです。すべてのAI機能がローカルで動作する必要はなく、逆に全てをクラウドに置くべきでもありません。
実践アプリの構築:オンデバイスAIによる音声文字起こし
利点と制約を把握したところで、実用的なものを作ってみましょう。Siriの話から始めたので、リアルタイムの音声文字起こしアプリをオンデバイスで構築します。アプリはマイクから音声をキャプチャし、OpenAIのWhisperモデルを完全にローカルで動作させてテキストに変換します。これは、音声データを外部サーバーに送信せずに音声をテキスト化する、現代の音声アシスタントの重要な要素を示します。
依存関係のセットアップ
ベアなExpoアプリから始め、コア依存関係をインストールします:
yarn add react-native-executorch
yarn add react-native-audio-api
ライブラリの概要:
- react-native-executorch - MetaのExecuTorchランタイムへのブリッジで、オンデバイス推論を可能にします。
- react-native-audio-api - web audio api仕様に基づいたReact Native向けの高性能オーディオエンジン。
権限の設定
音声録音には明示的なユーザー許可が必要です。app.jsonでreact-native-audio-apiのExpoプラグインを使って設定します:
{
"plugins": [
[
"react-native-audio-api",
{
"iosBackgroundMode": true,
"iosMicrophonePermission": "This app requires access to the microphone to record audio.",
"androidPermissions": [
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.FOREGROUND_SERVICE",
"android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"
],
"androidForegroundService": true,
"androidFSTypes": ["mediaPlayback"]
}
]
]
}
この設定を追加したら、ネイティブ変更を反映するために開発ビルドを再構築してください。
オーディオキャプチャの実装
音声認識の基礎は高品質なオーディオキャプチャです。ここでは音声認識に最適化したパラメータでオーディオレコーダーを構成します:
import { AudioManager, AudioRecorder } from 'react-native-audio-api';
function App() {
const [recorder] = useState(() => new AudioRecorder({
sampleRate: 16000,
bufferLengthInSamples: 1600,
}));
useEffect(() => {
AudioManager.setAudioSessionOptions({
iosCategory: 'playAndRecord',
iosMode: 'spokenAudio',
iosOptions: ['allowBluetooth', 'defaultToSpeaker'],
});
AudioManager.requestRecordingPermissions();
}, []);
}
設定の詳細
- 16kHzサンプルレート:Whisperのネイティブ入力フォーマットで、処理オーバーヘッドを削減します。
- 100msバッファチャンク:レスポンシブなフィードバックを提供しつつ品質を維持します。
- spokenAudioモード:ノイズ抑制を含むiOSの音声最適化モードです。
Whisperモデルの読み込み
Whisper Tiny Englishを例に、useSpeechToTextフックを使います。モバイル展開にバランスの良い選択です:
import { useSpeechToText, WHISPER_TINY_EN } from 'react-native-executorch'
const model = useSpeechToText({
model: WHISPER_TINY_EN,
})
モデルのアーキテクチャ:選択したモデルは自動的にダウンロードされる3つのコンポーネントで構成されます:
- Encoder:音声特徴を処理(~33MB)。
- Decoder:テキストトークンを生成(~118MB)。
- Tokenizer:テキストのエンコード/デコード(~3MB)。
初回利用時の合計ダウンロードは約150MBで、以後はローカルにキャッシュされます。
代替モデル:多言語対応が必要ならWHISPER_TINYを使用できます。
ダウンロード進捗を表示してユーザー体験を向上させます:
return (
<View style={styles.container}>
{!model.isReady ? (
<>
<Text>Loading Whisper model ...</Text>
<Text>{Math.round(model.downloadProgress * 100)}%</Text>
</>
) : (
...
)}
</View>
);
リアルタイム文字起こしの実装
Whisperの30秒のオーディオ処理制限は、無制限長のストリーム処理に対して特別な取り扱いを必要とします。ここでは、whisper-streamingに適応したオーバーラップするオーディオチャンクを使う実装で、途中で文が切れるのを防ぎつつ一貫した文字起こしを実現します。
アプリでの使用例:
const handleStartStreaming = async () => {
recorder.onAudioReady(async ({ buffer }) => {
const bufferArray = Array.from(buffer.getChannelData(0));
model.streamInsert(bufferArray);
});
recorder.start();
try {
await model.stream();
} catch (error) {
console.error('Transcription error:', error);
handleStopStreaming();
}
};
const handleStopStreaming = () =>
(記事ソースはここで途中まで提供されています。上記は提供された内容の正確な日本語訳およびコード例の保持です。)