Site icon AndroidRide

Flutter On Device LLM Chat App ( Text + Image + Audio Support )

In this post, you will learn how to download and integrate LLM/Gemma 4 into your Flutter app and interact with text, images, and audio.

Use it forever for free without an internet connection.

There are lots of open LLMs available on Hugging Face, and one of the best ones to use and test on our device is Gemma 4 because it’s a multimodal model that supports text, images, and audio.

And not only that, it supports multiple languages, not just English. You can try Spanish, Hindi, or any other language.

How do you get these models? You can use Hugging Face.

Here is the link for Gemma 4: HuggingFace.

So, what will we make in this post? We will make an Flutter On Device LLM chat app.

So, let’s start with a teaser or demo.

Here is the link for: Gemma 4 litert-lm

pubspec.yaml


 flutter_gemma: ^1.8.0
  flutter_gemma_litertlm: ^1.6.3
  flutter_markdown_plus: ^1.0.12

  image_picker: ^1.2.3
  permission_handler: ^13.0.2

  record: ^7.1.1
  path_provider: ^2.1.6




 await FlutterGemma.initialize(
    inferenceEngines: [LiteRtLmEngine()]
  );


 
    
    
    
    
    

    
    

    

 


 await FlutterGemma.installModel(
        modelType: ModelType.gemma4,
        fileType: ModelFileType.litertlm,
      ).fromNetwork(gemmaUrl, foreground: true).withProgress((percent) {
        downloadPercent = percent;
        _notify();
      }).install();

      _model = await FlutterGemma.getActiveModel(
        maxTokens: 4096,
        supportImage: true,
        supportAudio: true,
      );
      _chat = await _model!.createChat(
        supportAudio: true,
        supportImage: true,
        temperature: 1.0,
        maxOutputTokens: 4096,
        topK: 64,
        topP: 0.95,
        modelType: ModelType.gemma4,
        systemInstruction:
            'You are a helpful on-device assistant. Be concise and friendly.',
      );


  Message? takeMessage() {
    final text = textController.text.trim();

    if (text.isEmpty && imageBytes == null && audioBytes == null) return null;

    final Message message;

    if (audioBytes != null) {
      message = Message.withAudio(
        text: text,
        audioBytes: audioBytes!,
        isUser: true,
      );
    } else if (imageBytes != null) {
      message = Message(text: text, imageBytes: imageBytes, isUser: true);
    } else {
      message = Message(text: text, isUser: true);
    }

    textController.clear();
    clearAttachment();
    return message;
  }


  Future send(Message userMessage) async {
    final chat = _chat;
    if (chat == null) return;

    await _responseSubscription?.cancel();

    messages.add(userMessage);
    isGenerating = true;
    _notify();

    try {
      await chat.addQuery(userMessage);

      _responseSubscription = chat.generateChatResponseAsync().listen(
        (response) {
          if (response is TextResponse) {
            draft.value += response.token;
          }
        },
        onDone: () {
          _finishGeneration();
        },
      );
    } catch (e) {
      print('Error sending message: $e');
    }
  }

You can visit github repo link for the code: Flutter On Device LLM Chat

Thats all for today.

Exit mobile version