LiteRT-LM Documentation

repository·main·Indexed 27 days ago

https://github.com/google-ai-edge/litert-lm

A production-ready orchestration layer for running Large Language Models (LLMs) with LiteRT across Android, iOS, Web, Desktop, and IoT devices. It provides stable APIs for Python, Kotlin, and C++, with early previews for Swift and JavaScript. Key features include a CLI for local model execution, a builder for managing .litertlm files, and advanced constrained decoding support for tool calling, Regex, JSON Schema, and Lark grammar.

Tokens
23.1K
Snippets
59
Records
109
Agent score
91%

What's inside LiteRT-LM

  1. Configure ModelDataProcessor and Prompt Templates

    main

    The ModelDataProcessor converts generic Message formats into the InputData required by the Session. It is initialized using a DataProcessorConfig (often derived from model metadata).

    Prompt templates are implemented using Minja (a C++ Jinja implementation). The specific template used is typically provided by the model file metadata. To support a new model type, you must implement a custom ModelDataProcessor to handle its specific data preprocessing and template requirements.

  2. Supported Language APIs and Status

    main

    LiteRT-LM provides APIs for various platforms. Choose the language based on your target environment and stability requirements:

    LanguageStatusBest For...
    Python✅ StablePrototyping & Scripting
    Kotlin✅ StableAndroid apps & JVM
    C++✅ StableHigh-performance native
    Swift🚀 Early PreviewNative iOS & macOS
    JavaScript (web)🚀 Early PreviewBrowser environments
    Flutter🚀 CommunityCross-platform mobile
  3. Explore LiteRT-LM API references

    main

    LiteRT-LM provides APIs for C++, Kotlin, and Python. Depending on your target platform, you can use the following documentation to integrate the library:

    C++ API

    • Conversation API: For managing conversational flows.
    • Constrained Decoding: For controlling model output formats.
    • Tool Use: For enabling models to interact with external tools.
    • Advanced: ANTLR for Tool Use: For advanced tool use implementations using ANTLR.

    Kotlin API

    • Use the Kotlin API guide for Android or JVM-based development.

    Python API

  4. Understand the Tool Calling Flow in LiteRT-LM C++

    main

    Tool calling in LiteRT-LM is managed by the ModelDataProcessor implementation specific to your model. The process follows these stages:

    1. Tool Declarations: Formatted using ModelDataProcessor::FormatTools.
    2. Tool Call Parsing: Parsed by ModelDataProcessor::ToMessage.
    3. Formatting Calls and Responses: Tool calls and responses are formatted via ModelDataProcessor::MessageToTemplateInput. Note that additional formatting may occur within the model's chat template.
  5. Build and run LiteRT-LM on Linux or MacOS

    main

    Prerequisites

    • Linux: clang must be installed.
    • MacOS: Xcode command line tools must be installed (xcode-select --install).
    • Git LFS: Run git lfs pull to fetch prebuilt binaries.

    Build and Run

    1. Set the model path:
      export MODEL_PATH=<path to your .litertlm file>
    2. Build the binary:
      bazel build //runtime/engine:litert_lm_main
    3. Run the binary:
      bazel-bin/runtime/engine/litert_lm_main \
          --backend=cpu \
          --model_path=$MODEL_PATH
    bazel build //runtime/engine:litert_lm_main
    
    bazel-bin/runtime/engine/litert_lm_main \
        --backend=cpu \
        --model_path=$MODEL_PATH
  6. Declare tools in C++ using Preface

    main

    To make tools available to the model, you must declare them within a Preface object. This object is passed to the ConversationConfig::Builder when creating a Conversation.

    Tool declarations must be a JSON array where each tool is defined using a JSON schema containing the tool's name, description, and parameters (including type, properties, and required fields).

    constexpr absl::string_view kToolString = R"([
    {
      "name": "get_weather",
      "description": "Returns the weather for a given location.",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The location to get the weather for."
          }
        },
        "required": [
          "location"
        ]
      }
    }
    ])";
    
    JsonPreface preface;
    preface.tools = nlohmann::ordered_json::parse(kToolString);
    
    // Use preface in ConversationConfig::Builder
    ABSL_ASSIGN_OR_RETURN(auto conversation_config, 
                       ConversationConfig::Builder()
                           .SetSessionConfig(session_config)
                           .SetPreface(preface)
                           .Build(*engine));
  7. Use ExternalConstraintConfig for custom C++ constraints

    main

    To use your own custom Constraint implementations (e.g., a specialized C++ state machine), initialize your Conversation with ExternalConstraintConfig(). You can then pass a std::unique_ptr<Constraint> to SendMessage using ExternalConstraintArg.

    #include "runtime/conversation/conversation.h"
    
    ConversationConfig::Builder builder;
    builder.SetConstraintProviderConfig(ExternalConstraintConfig());
    auto config = builder.Build(*engine).value();
  8. Send multimodal data (Image and Audio) via Conversation API

    main

    To use multimodal capabilities, the Engine must be initialized with appropriate vision and audio backends (e.g., litert::lm::Backend::GPU for vision).

    When sending multimodal messages, the content field in the Message object must be an array of objects rather than a single string. Each object in the array defines a type (e.g., text, image, or audio) and its corresponding data (e.g., text or path).

    // To use multimodality, the engine must be created with vision and audio
    // backend depending on the multimodality to be used
    auto engine_settings = EngineSettings::CreateDefault(
        model_assets,
        /*backend=*/litert::lm::Backend::CPU,
        /*vision_backend*/litert::lm::Backend::GPU,
        /*audio_backend*/litert::lm::Backend::CPU,
    );
    
    // ... Create Engine and Conversation ...
    
    // Send message to the LLM with image data.
    absl::StatusOr<Message> model_message = (*conversation)->SendMessage(
        Message{
            {"role", "user"},
            {"content", { // Now content must be an array.
              {{"type", "text"}, {"text", "Describe the following image: "}},
              {{"type", "image"}, {"path", "/file/path/to/image.jpg"}}
            }},
        });
    CHECK_OK(model_message);
    
    // Send message to the LLM with audio data.
    model_message = (*conversation)->SendMessage(
        Message{
            {"role", "user"},
            {"content", { // Now content must be an array.
              {{"type", "text"}, {"text", "Transcribe the audio: "}},
              {{"type", "audio"}, {"path", "/file/path/to/audio.wav"}}
            }},
        });
    CHECK_OK(model_message);