Back to blog
    Flutter 應用程式的 AI:雲端 API、TFLite 與裝置端 LLM
    FlutterDartTFLitecloud APIon-device AIllama.cppsegment:mobile-builder

    Flutter 應用程式的 AI:雲端 API、TFLite 與裝置端 LLM

    Flutter 的三條 AI 路徑。透過 http 套件的雲端 API、用於傳統 ML 任務的 TensorFlow Lite,以及透過 llama.cpp 的裝置端 LLM 進行文字生成。為 Dart 開發者提供的實用比較。

    EErtas Team·

    建立 AI 功能的 Flutter 開發者有三條截然不同的路徑。雲端 API 透過 HTTP 呼叫讓你存取前沿模型。TensorFlow Lite 在裝置端處理傳統 ML 任務。而 llama.cpp 透過平台通道將完整的 LLM 文字生成帶到裝置上。

    每種服務於不同的目的。本指南從 Dart 開發者的角度進行比較。

    路徑 1:雲端 API

    Flutter 的 httpdio 套件讓雲端 API 整合變得簡單。這個模式在 iOS、Android、網頁和桌面上完全一樣。

    基本整合

    import 'dart:convert';
    import 'package:http/http.dart' as http;
    
    Future<String> generateResponse(String prompt) async {
      final response = await http.post(
        Uri.parse('https://api.openai.com/v1/chat/completions'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $apiKey',
        },
        body: jsonEncode({
          'model': 'gpt-4o-mini',
          'messages': [{'role': 'user', 'content': prompt}],
        }),
      );
    
      final data = jsonDecode(response.body);
      return data['choices'][0]['message']['content'];
    }

    使用 SSE 的串流

    對於在 token 到達時就顯示的聊天介面:

    import 'package:flutter_client_sse/flutter_client_sse.dart';
    
    void streamResponse(String prompt, Function(String) onToken) {
      SSEClient.subscribeToSSE(
        url: 'https://api.openai.com/v1/chat/completions',
        header: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $apiKey',
        },
        body: {
          'model': 'gpt-4o-mini',
          'messages': [{'role': 'user', 'content': prompt}],
          'stream': true,
        },
      ).listen((event) {
        if (event.data == '[DONE]') return;
        final parsed = jsonDecode(event.data!);
        final token = parsed['choices'][0]['delta']['content'];
        if (token != null) onToken(token);
      });
    }

    何時使用雲端 API

    雲端 API 是原型開發、功能驗證和非常低流量應用程式的正確選擇。它們不需要原生程式碼,在所有 Flutter 平台上運作,讓你存取前沿模型。

    取捨是標準的雲端 API 取捨:按 token 的成本擴展、網路依賴、500-3,000ms 的延遲,以及每次請求都有資料離開裝置。

    路徑 2:TensorFlow Lite

    tflite_flutter 外掛為 Flutter 提供 TFLite 支援。TFLite 在裝置端執行最佳化的 ML 模型,用於特定任務。

    TFLite 擅長什麼

    • 影像分類和物件偵測
    • 文字分類和情緒分析
    • 裝置端翻譯(預建模型)
    • 姿勢估計
    • 音訊分類

    整合模式

    import 'package:tflite_flutter/tflite_flutter.dart';
    
    class TextClassifier {
      late Interpreter _interpreter;
    
      Future<void> loadModel() async {
        _interpreter = await Interpreter.fromAsset('model.tflite');
      }
    
      List<double> classify(List<int> tokenizedInput) {
        var output = List.filled(1 * numClasses, 0.0).reshape([1, numClasses]);
        _interpreter.run([tokenizedInput], output);
        return output[0];
      }
    }

    TFLite 不能做什麼

    TFLite 不支援大型語言模型進行開放式文字生成。沒有 TFLite 版本的 ChatGPT 或 Claude。你不能使用 TFLite 進行對話 AI、內容撰寫、摘要或任何需要生成自然語言回應的任務。

    對於這些任務,你需要雲端 API 或裝置端 LLM。

    費用

    免費。TFLite 完全在裝置端執行。模型很小(通常 1-50MB)且隨應用程式打包。

    路徑 3:透過 llama.cpp 的裝置端 LLM

    在使用者的裝置上執行完整的語言模型。llama.cpp 處理推論。GGUF 模型提供智慧。Flutter 透過平台通道(method channel 或 FFI)進行通訊。

    整合方法

    平台通道: 在 Swift(iOS)和 Kotlin(Android)中撰寫一個薄原生包裝器呼叫 llama.cpp,然後從 Dart 透過 MethodChannel 通訊。

    // Dart 端
    class OnDeviceLlm {
      static const _channel = MethodChannel('com.app/llm');
    
      Future<void> loadModel(String path) async {
        await _channel.invokeMethod('loadModel', {'path': path});
      }
    
      Future<String> generate(String prompt) async {
        return await _channel.invokeMethod('generate', {'prompt': prompt});
      }
    
      Stream<String> generateStream(String prompt) {
        const eventChannel = EventChannel('com.app/llm_stream');
        _channel.invokeMethod('startGeneration', {'prompt': prompt});
        return eventChannel.receiveBroadcastStream().map((e) => e as String);
      }
    }

    Dart FFI: 使用 dart:ffi 直接呼叫 llama.cpp 的 C API。這避免了平台通道的開銷,但需要更多設定:

    import 'dart:ffi';
    
    // 綁定到 llama.cpp 共享函式庫
    final llamaLib = DynamicLibrary.open('libllama.so'); // Android
    // DynamicLibrary.process() 用於 iOS(靜態連結)
    
    typedef LlamaInitNative = Pointer Function(Pointer<Utf8>);
    typedef LlamaInit = Pointer Function(Pointer<Utf8>);
    
    final llamaInit = llamaLib
        .lookupFunction<LlamaInitNative, LlamaInit>('llama_load_model');

    Flutter 中的模型交付

    打包: 將 GGUF 檔案放在平台特定的資源目錄中。對於 Android,大檔案使用 asset delivery。對於 iOS,加入 Xcode 專案。

    下載: 使用 diohttp 進行帶有進度的背景下載:

    import 'package:dio/dio.dart';
    
    Future<void> downloadModel() async {
      final dir = await getApplicationDocumentsDirectory();
      final modelPath = '${dir.path}/model.gguf';
    
      await Dio().download(
        modelCdnUrl,
        modelPath,
        onReceiveProgress: (received, total) {
          final progress = received / total;
          // 用下載進度更新 UI
        },
      );
    }

    效能

    裝置端推論效能與原生應用程式相同,因為 llama.cpp 是原生執行,不是透過 Dart VM。平台通道或 FFI 的開銷可以忽略不計(每個 token 不到 1ms)。

    裝置1B 模型 (tok/s)3B 模型 (tok/s)
    iPhone 15 Pro (A17)35-4518-25
    Galaxy S24 (SD 8 Gen 3)35-4518-25
    Pixel 9 (Tensor G4)30-4015-22
    2024 年後中階機18-258-12

    比較

    因素雲端 APITFLite裝置端 LLM
    文字生成
    影像分類透過 API是(最佳化)
    離線支援
    每次推論費用$0.0001-$0.01$0$0
    Flutter 整合原生 Dart外掛平台通道/FFI
    自訂模型透過 API 選擇自訂 TFLite任何 GGUF 模型
    模型大小不適用(伺服器端)1-50MB600MB-1.7GB

    實際決策框架

    使用雲端 API 當你在驗證功能、使用者基礎很小,或需要前沿模型推理能力時。http 套件讓這在 Dart 中變得非常簡單。

    使用 TFLite 當你需要影像分類、物件偵測、文字分類或其他傳統 ML 任務時。Google 的預建模型涵蓋許多常見使用情境。

    使用裝置端 LLM 當你需要對話 AI、內容生成、摘要或任何文字密集型 AI 功能時。零每次推論費用、離線支援和隱私保障使其成為規模化生產應用程式的正確選擇。

    微調步驟是讓裝置端模型在你的特定任務上與雲端 API 競爭的關鍵。像 Ertas 這樣的平台處理完整的工作流程:上傳訓練資料、使用 LoRA 微調、匯出 GGUF、部署到任何裝置。微調的 3B 模型通常在領域特定任務上優於使用提示的雲端模型。

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading