Back to blog
    IA en apps Flutter: APIs en la nube, TFLite y LLMs en el dispositivo
    FlutterDartTFLitecloud APIon-device AIllama.cppsegment:mobile-builder

    IA en apps Flutter: APIs en la nube, TFLite y LLMs en el dispositivo

    Tres caminos para IA en Flutter. APIs en la nube via el paquete http, TensorFlow Lite para tareas clasicas de ML y LLMs en el dispositivo via llama.cpp para generacion de texto. Una comparacion practica para desarrolladores Dart.

    EErtas Team·

    Los desarrolladores Flutter que construyen funciones de IA tienen tres caminos distintos. Las APIs en la nube te dan acceso a modelos de frontera a traves de llamadas HTTP. TensorFlow Lite maneja tareas clasicas de ML en el dispositivo. Y llama.cpp trae generacion completa de texto LLM al dispositivo via canales de plataforma.

    Cada uno sirve un proposito diferente. Esta guia los compara desde la perspectiva de un desarrollador Dart.

    Camino 1: APIs en la nube

    Los paquetes http o dio de Flutter hacen que la integracion con APIs en la nube sea directa. El patron funciona de manera identica en iOS, Android, web y escritorio.

    Integracion basica

    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'];
    }
    

    Streaming con SSE

    Para interfaces de chat que muestran tokens mientras llegan:

    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);
      });
    }
    

    Cuando usar APIs en la nube

    Las APIs en la nube son la eleccion correcta para prototipos, validacion de funciones y apps de muy bajo volumen. No requieren codigo nativo, funcionan en todas las plataformas Flutter y te dan acceso a modelos de frontera.

    Las compensaciones son las estandar de APIs en la nube: escalado de costos por token, dependencia de red, latencia de 500-3,000ms y datos saliendo del dispositivo en cada solicitud.

    Camino 2: TensorFlow Lite

    El plugin tflite_flutter proporciona soporte TFLite para Flutter. TFLite ejecuta modelos ML optimizados en el dispositivo para tareas especificas.

    Lo que TFLite hace bien

    • Clasificacion de imagenes y deteccion de objetos
    • Clasificacion de texto y analisis de sentimiento
    • Traduccion en el dispositivo (modelos preconstruidos)
    • Estimacion de poses
    • Clasificacion de audio

    Patron de integracion

    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];
      }
    }
    

    Lo que TFLite no puede hacer

    TFLite no soporta modelos de lenguaje grandes para generacion de texto abierta. No hay equivalente TFLite de ChatGPT o Claude. No puedes usar TFLite para IA conversacional, redaccion de contenido, resumen o cualquier tarea que requiera generar respuestas en lenguaje natural.

    Para esas tareas, necesitas una API en la nube o un LLM en el dispositivo.

    Costo

    Gratis. TFLite se ejecuta completamente en el dispositivo. Los modelos son pequenos (tipicamente 1-50MB) e incluidos con la app.

    Camino 3: LLMs en el dispositivo via llama.cpp

    Ejecuta un modelo de lenguaje completo en el dispositivo del usuario. llama.cpp maneja la inferencia. Los modelos GGUF proporcionan la inteligencia. Flutter se comunica a traves de canales de plataforma (method channels o FFI).

    Enfoques de integracion

    Canales de plataforma: Escribe un envoltorio nativo delgado en Swift (iOS) y Kotlin (Android) que llame a llama.cpp, luego comunicate desde Dart via MethodChannel.

    // Lado 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: Usa dart:ffi para llamar a la API C de llama.cpp directamente. Esto evita la sobrecarga del canal de plataforma pero requiere mas configuracion:

    import 'dart:ffi';
    
    // Vincular a la libreria compartida de llama.cpp
    final llamaLib = DynamicLibrary.open('libllama.so'); // Android
    // DynamicLibrary.process() para iOS (vinculado estaticamente)
    
    typedef LlamaInitNative = Pointer Function(Pointer<Utf8>);
    typedef LlamaInit = Pointer Function(Pointer<Utf8>);
    
    final llamaInit = llamaLib
        .lookupFunction<LlamaInitNative, LlamaInit>('llama_load_model');
    

    Entrega del modelo en Flutter

    Incluido: Coloca el archivo GGUF en los directorios de assets especificos de la plataforma. Para Android, usa asset delivery para archivos grandes. Para iOS, agrega al proyecto Xcode.

    Descargado: Usa dio o http para descargas en segundo plano con progreso:

    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;
          // Actualizar UI con progreso de descarga
        },
      );
    }
    

    Rendimiento

    El rendimiento de inferencia en el dispositivo es el mismo que en apps nativas ya que llama.cpp se ejecuta nativamente, no a traves de la VM de Dart. La sobrecarga del canal de plataforma o FFI es insignificante (menos de 1ms por token).

    DispositivoModelo 1B (tok/s)Modelo 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
    Gama media 2024+18-258-12

    La comparacion

    FactorAPI en la nubeTFLiteLLM en dispositivo
    Generacion de textoSiNoSi
    Clasificacion de imagenesVia APISi (optimizado)No
    Soporte sin conexionNoSiSi
    Costo por inferencia$0.0001-$0.01$0$0
    Integracion FlutterDart nativoPluginCanal de plataforma/FFI
    Modelos personalizadosVia seleccion de APITFLite personalizadoCualquier modelo GGUF
    Tamano del modeloN/A (servidor)1-50MB600MB-1.7GB

    Marco de decision practico

    Usa APIs en la nube cuando estes validando una funcion, la base de usuarios sea pequena o necesites razonamiento de modelo de frontera. El paquete http hace esto trivial en Dart.

    Usa TFLite cuando necesites clasificacion de imagenes, deteccion de objetos, clasificacion de texto u otras tareas clasicas de ML. Los modelos preconstruidos de Google cubren muchos casos de uso comunes.

    Usa LLMs en el dispositivo cuando necesites IA conversacional, generacion de contenido, resumen o cualquier funcion de IA intensiva en texto. El cero costo por inferencia, soporte sin conexion y garantias de privacidad lo hacen la eleccion correcta para apps en produccion a escala.

    El paso de fine-tuning es donde haces que el modelo en el dispositivo compita con las APIs en la nube en tu tarea especifica. Plataformas como Ertas manejan el flujo completo: sube datos de entrenamiento, fine-tunea con LoRA, exporta GGUF, despliega en cualquier dispositivo. Un modelo de 3B fine-tuned tipicamente supera a modelos en la nube con prompts en tareas especificas de dominio.

    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