エッジでのLLM推論:React NativeによるローカルLLMの実行

Hugging Faceは、React Nativeを使用してモバイルデバイス上でローカルな大規模言語モデル(LLM)推論を実装するためのテクニカルガイドを公開しました。llama.rnllama.cppのバインディング)を活用することで、開発者はHugging Face HubからGGUFモデルをダウンロードし、完全にデバイス上で実行するアプリケーションを構築でき、データのプライバシーとオフライン機能を確保できます。

モバイル向けのモデル選択と量子化

エッジでの推論を成功させるには、デバイスのハードウェア制約に合わせて、モデルのサイズと量子化のバランスを取ることが重要です。

モデルサイズのガイドライン

  • 小型モデル (1-3B パラメータ): 低レイテンシを確保するために、ほとんどのモバイルデバイスに推奨されます。
  • 中型モデル (4-7B パラメータ): ハイエンドデバイスに適しています。古いハードウェアではパフォーマンスの低下を引き起こす可能性があります。
  • 大型モデル (8B+ パラメータ): 高度に量子化(例:Q2_K または Q4_K_M)されていない限り、一般的にリソースを消費しすぎます。

GGUF 量子化フォーマット

量子化はモデルのサイズとメモリ要件を削減します。ガイドでは主に3つのフォーマットが紹介されています。

  • Legacy Quants (Q4_0, Q4_1, Q8_0): ブロックごとに1つまたは2つのスケーリング定数を使用する基本的な手法。現在は大部分が置き換えられています。
  • K-Quants (Q3_K_S, Q5_K_M, etc.): 精度を高めるために重要なレイヤーにより多くのビットを割り当てる混合量子化。
  • I-Quants (IQ2_XXS, IQ3_S, etc.): QuIPに触発されたもので、ファイルサイズがより小さく、計算能力は高いがメモリが限られているデバイスに最適です。

推奨されるモバイルモデル

  • SmolLM2-1.7B-Instruct
  • Qwen2-0.5B-Instruct
  • Llama-3.2-1B-Instruct
  • DeepSeek-R1-Distill-Qwen-1.5B

技術的な実装アーキテクチャ

アプリケーションはReact Nativeを使用して構築されており、単一のコードベースでiOSとAndroidの両方をターゲットにできます。コアとなる技術スタックは以下の通りです:

  • llama.rn: GGUFファイルのロードと実行に必要なllama.cppへのバインディングを提供します。
  • react-native-fs: ダウンロードされたモデルをDocumentDirectoryPathに保存するためのデバイスのローカルファイルシステムを管理します。
  • axios: 利用可能なモデルファイルを取得するためにHugging Face HubへのAPIリクエストを処理します。

モデルのライフサイクルワークフロー

  1. Discovery (検出): アプリがHugging Face Hub APIに問い合わせ、.ggufファイルを含むリポジトリを検索します。
  2. Download (ダウンロード): 選択されたモデルはHTTPS経由でダウンロードされ、react-native-fsを使用してローカルに保存されます。
  3. Initialization (初期化): llama.rninitLlama関数が、特定のパラメータ(例:n_ctx: 2048, n_gpu_layers: 1)を使用してモデルをコンテキストにロードします。
  4. Inference (推論): context.completionメソッドが会話履歴を処理し、制御不能な生成を防ぐためのストップワードセットに基づいてレスポンスを生成します。

UX向上のための高度な機能

基本的なチャットに加えて、ガイドではモバイルユーザーエクスペリエンスを改善するためのいくつかの最適化について述べています:

  • 逐次生成 (Incremental Generation): context.completion内でコールバック関数を使用し、フルレスポンスを待つのではなく、トークンを一つずつストリーミングします。
  • 思考プロセスの可視化: DeepSeek-R1のような推論モデルの場合、アプリは特殊なトークンを識別してモデルの内部的な「思考」を分離し、ユーザーが推論チェーンの表示/非表示を切り替えられるようにします。
  • パフォーマンス・トラッキング: CompletionResultオブジェクトのtimingsプロパティを利用して、predicted_per_secondメトリクスを表示します。
  • オートスクロール: ユーザーが手動で上にスクロールしない限り、最新のトークンが表示され続けるように、ScrollViewをプログラムで制御します。

デバッグと開発

開発はMetro bundlerを通じて管理され、デバッグはChrome DevToolsを介して行われます。主なデバッグ手順には、ターミナルでjキーを使用してデバッガーを起動することや、「Sources」タブでブレークポイントを設定することが含まれます。ビルドの問題については、Metroキャッシュのクリア(npm start --reset-cache)またはネイティブビルドのクリーン(Androidの場合は./gradlew clean、iOSの場合はpod install)が推奨されています。

Sources