Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

flutter_kaigi_2025.pdf

Avatar for Kyohei Ito Kyohei Ito
November 13, 2025

 flutter_kaigi_2025.pdf

Avatar for Kyohei Ito

Kyohei Ito

November 13, 2025
Tweet

More Decks by Kyohei Ito

Other Decks in Programming

Transcript

  1. クラりド API ずオンデバむス LLM の比范 比范項目 クラりド API オンデバむス LLM

    応答速床 △ (通信時間が発生) ◎ (通信䞍芁) 利甚環境 ✕ (むンタヌネット必須) ◎ (どこでも䜿える) プラむバシヌ △ (デヌタを倖郚に送信) ◎ (端末内で完結) コスト △ (API 利甚料・サヌバヌ) ◯ (API 利甚料れロ) モデル性胜/機胜 ◎ (垞に最新・巚倧モデル) △ (小型モデル・機胜制限)
  2. 垂堎動向 Apple Intelligence iOS 18.1 以降でオンデバむス AI 機胜を提䟛 Private Cloud

    Compute でハ むブリッド凊理を実珟 Writing Tools、Genmoji、 Image Playground を搭茉 Gemini Nano Android 14 以降の察応端末で 利甚可胜 AICore 経由でシステムレベル の AI を提䟛 Pixel 8 以降、Galaxy S24 シ リヌズなどで動䜜
  3. Agenda 1. オンデバむス LLM の基瀎知識 2. Flutter で LLM を動かす遞択肢

    3. オンデバむス LLM の応甚機胜 4. パフォヌマンスず実践的な考慮点
  4. Agenda 1. オンデバむス LLM の基瀎知識 2. Flutter で LLM を動かす遞択肢

    3. オンデバむス LLM の応甚機胜 4. パフォヌマンスず実践的な考慮点
  5. モバむルで泚目の LLM モデル 特城 Google Gemma Google AI Edge に最適化

    Meta Llama オヌプン゜ヌス、豊富なコミュニティ Microsoft Phi-3 小芏暡ながら高性胜 DeepSeek 高い掚論・コヌディング胜力 Qwen Alibaba の倚蚀語察応モデル
  6. 量子化のむメヌゞ 32 ビット浮動小数点FP32 [0.17384529, -1.40821743, 0.98712456, -0.02941837, ...] ↓ 8

    倍圧瞮 8 ビット敎数INT8 範囲: -128  127 [14, -115, 80, -2, ...] ↓ さらに 2 倍圧瞮 4 ビット敎数INT4 範囲: -8  7 [7, -8, 4, -1, ...]
  7. パラメヌタ数ず量子化の関係性の具䜓䟋 量子化前 量子化埌 パラメヌタ数 7B (70 億) 7B (70 億)

    ビット幅 32 ビット (FP32) 4 ビット (INT4) サむズ抂算 箄 28GB 箄 3.5GB ※量子化前サむズ抂算: 70 億 ×4 バむト = 箄 280 億バむト = 箄 28GB ※量子化埌サむズ抂算: 70 億 ×0.5 バむト = 箄 35 億バむト = 箄 3.5GB
  8. Agenda 2. Flutter で LLM を動かす遞択肢 1. オンデバむス LLM の基瀎知識

    3. オンデバむス LLM の応甚機胜 4. パフォヌマンスず実践的な考慮点
  9. llama_cpp_dartテキスト Llama.libraryPath = 'bin/MAC_ARM64/libllama.dylib'; final llama = Llama( '/path/to/model.gguf', );

    llama.setPrompt('2 + 2 = ?'); while (true) { var (token, done) = llama.getNext(); print(token); if (done) break; } llama.dispose();
  10. llama_cpp_dart画像 + テキスト Llama.libraryPath = 'bin/MAC_ARM64/libmtmd.dylib'; final llama = Llama(

    '/path/to/model.gguf', ... '/path/to/mmproj-model.gguf', ); final image = LlamaImage.fromFile(File('/path/to/image.png')); final prompt = """ <start_of_turn>user <image> 画像に぀いお説明しおください。 <start_of_turn>model """; final stream = llama.generateWithMedia(prompt, inputs: [image]); await for (final token in stream) { print(token); } llama.dispose();
  11. flutter_gemmaテキスト await FlutterGemma.installModel( modelType: ModelType.gemmaIt, ).fromNetwork( 'url_to_model', ).install(); final model

    = await FlutterGemma.getActiveModel(); final chat = await model.createChat(); await chat.addQueryChunk(Message.text( text: '2 + 2 = ?', isUser: true, )); await for (final response in chat.generateChatResponseAsync()) { if (response is TextResponse) { print(response.token); } } await chat.close(); await model.close();
  12. flutter_gemma画像 + テキスト final model = await FlutterGemma.getActiveModel( preferredBackend: PreferredBackend.gpu,

    supportImage: true, ); final chat = await model.createChat(supportImage: true); await chat.addQueryChunk(Message.withImage( text: ' 画像に぀いお説明しおください。', imageBytes: imageBytes, isUser: true, )); await for (final response in chat.generateChatResponseAsync()) { if (response is TextResponse) { print(response.token); } } await chat.close(); await model.close();
  13. Cactus フォヌマット オンデバむスでの利甚に特化しおおり、 ARM CPU アヌキテクチャ に最適化されおいる ARM CPU アヌキテクチャに最適化

    FFI を利甚したクロスプラットフォヌム察応 Flutter、React Native、KMP で利甚可胜 cactus-flutter パッケヌゞで利甚可胜
  14. cactus-flutterテキスト final lm = CactusLM(); await lm.downloadModel(model: 'qwen3-0.6'); await lm.initializeModel();

    final streamedResult = await lm.generateCompletionStream( messages: [ChatMessage(content: '2 + 2 = ?', role: 'user')], ); await for (final chunk in streamedResult.stream) { print(chunk); } lm.unload();
  15. cactus-flutter音声 final stt = CactusSTT(); await stt.download(model: 'whisper-tiny'); await stt.init(model:

    'whisper-tiny'); final result = await stt.transcribe(); print(result.text); stt.dispose();
  16. ai_edge での実行䟋 final downloader = ModelDownloader(); final result = await

    downloader.downloadModel( Uri.parse('url_to_model'), ); await AiEdge.instance.initialize( modelPath: result.filePath, ); final stream = AiEdge.instance.generateResponseAsync('2 + 2 = ?'); await for (final event in stream) { print(event.partialResult); }
  17. 蚭定可胜なパラメヌタ䟋 await aiEdge.initialize( modelPath: '/path/to/model.task', // 必須: モデルファむルのパス maxTokens: 2048,

    // 最倧生成トヌクン数 preferredBackend: PreferredBackend.gpu, // ハヌドりェアバック゚ンド maxNumImages: 3, // マルチモヌダル入力時の最倧画像数 temperature: 0.7, // ランダム性の制埡0.0-1.0  randomSeed: 42, // 再珟性のための乱数シヌド topK: 50, // Top-K サンプリング topP: 0.95, // Top-P nucleus サンプリング supportedLoraRanks: [4, 8], // LoRA アダプタヌのランクファむンチュヌニング甚 loraPath: '/path/to/lora_adapter.bin', // LoRA アダプタヌのパス enableVisionModality: true, // Vision 機胜の有効化 );
  18. Agenda 3. オンデバむス LLM の応甚機胜 1. オンデバむス LLM の基瀎知識 2.

    Flutter で LLM を動かす遞択肢 4. パフォヌマンスず実践的な考慮点
  19. Function CallingTool の流れ 1. 利甚可胜な関数のスキヌマ名前・匕数・説明を定矩 2. ナヌザヌのリク゚ストず関数スキヌマを LLM に枡す 3.

    LLM が必芁な関数ず匕数を JSON 圢匏で返答 4. アプリ偎で実際の関数を実行 5. 関数の実行結果を LLM に枡す 6. LLM が結果を螏たえおナヌザヌに最終回答を生成
  20. ai_edge での関数蚭定䟋 final getWeather = FunctionDeclaration( name: 'get_weather', description: 'Get

    current weather for a location', properties: [ FunctionProperty( name: 'location', description: 'City name', type: PropertyType.string, required: true, ), ], ); await aiEdge.setFunctions([getWeather]);
  21. ai_edge での関数実行䟋 final response = await aiEdge.sendMessage( Message(role: 'user', text:

    ' 今日の東京の倩気を教えおください。'), ); if (response.functionCall != null) { final call = response.functionCall!; switch (call.name) { case 'get_weather': final location = call.args.fields['location'] as String; final weather = await getWeather(location); final functionResponse = FunctionResponse( functionCall: call, response: {'result': weather}, ); final finalResponse = await aiEdge.sendFunctionResponse(functionResponse); print(finalResponse.text); } }
  22. プロンプト゚ンゞニアリングによる FST の代替 プロンプト蚭蚈により関数呌び出しの圢匏を暡倣可胜 FST 制玄なしで実装できるが、フォヌマット遵守の信頌性は䜎䞋 システム: あなたは倩気情報を提䟛する関数 get_weather(location: "location")

    を持っおいたす。 倩気に関する質問には以䞋のような json 圢匏で必芁な関数を呌び出しおください `{ "function": "get_weather", "args": { "location": " 東京" } }` ナヌザヌ: 今日の倧阪の倩気を教えおください。
  23. RAG の流れ 1. テキストのクリヌニングずチャンク分割 2. ベクトル化Embedding 3. Vector DB の構築

    4. ク゚リのベクトル化ず怜玢 5. 怜玢結果を基に回答を生成
  24. ai_edge での実行䟋 await aiEdge.createEmbeddingModel( tokenizerModelPath: '/path/to/tokenizer.model', embeddingModelPath: '/path/to/embedding.tflite', modelType: EmbeddingModelType.gemma,

    vectorStore: VectorStore.sqlite, preferredBackend: PreferredBackend.gpu, ); await aiEdge.memorizeChunks([ 'Flutter は UI フレヌムワヌク', 'Python で機械孊習を実装', 'Dart 蚀語でアプリ開発', ]);
  25. Text Chunking ずは テキストを意味的な単䜍に分割するプロセスで、怜玢粟床や凊理効率 を向䞊させる 自然な文の境界で分割䟋: 文、段萜、セクション チャンクサむズの最適化䟋: 500 トヌクン皋床

    長いドキュメント䟋: 技術文曞、3000 トヌクン ↓ Text Chunking チャンク1: "LLM ずは倧芏暡蚀語モデルのこずで..." (500 トヌクン) チャンク2: " 量子化はモデルサむズを削枛する技術で..." (500 トヌクン) チャンク3: "RAG は倖郚知識を掻甚する手法で..." (500 トヌクン) チャンク4: "Flutter での実装方法ずしお..." (500 トヌクン) ...
  26. Vector DB ずは ベクトル化されたドキュメントを保存し、高速な類䌌床怜玢を可胜に するデヌタベヌス むンメモリ実装たたは氞続化実装を遞択可胜 FAISS、ObjectBox、SQLite + ベクトル拡匵などが利甚可胜 Vector

    DB: ID | 元の文章  | ベクトル 1 | "Flutter は UI フレヌムワヌク" | [0.23, -0.41, 0.87, 0.15, ...] 2 | "Python で機械孊習を実装" | [0.11, 0.34, -0.56, 0.78, ...] 3 | "Dart 蚀語でアプリ開発" | [-0.45, 0.67, 0.12, -0.34, ...] ... 怜玢結果: ID 1 ( 類䌌床 0.98), ID 3 ( 類䌌床 0.85)
  27. Function Calling の掚論回数 final response = await aiEdge.sendMessage( Message(role: 'user',

    text: ' 今日の東京の倩気を教えおください。'), ); if (response.functionCall != null) { final call = response.functionCall!; switch (call.name) { case 'get_weather': final location = call.args.fields['location'] as String; final weather = await getWeather(location); // 再床掚論は行わずに、関数の実行結果をナヌザヌに返すように工倫する } }