--- library_name: mlx license: other license_name: lfm1.0 license_link: https://huggingface.co/LiquidAI/LFM2.5-230M/blob/main/LICENSE base_model: LiquidAI/LFM2.5-230M pipeline_tag: text-generation language: - en tags: - mlx - lora - tool-calling - on-device - lfm2.5 - edge --- # pomo-1 A LoRA fine-tune of [LiquidAI/LFM2.5-230M](https://huggingface.co/LiquidAI/LFM2.5-230M) for **on-device to-do tool-calling**. Given a short natural-language utterance and the user's current to-do list, `pomo-1` emits a single structured tool call to create, update, or delete a to-do. Built to run locally on Apple Silicon via MLX. This is a task-specific model, not a general assistant. It does one thing: turn an utterance + a small list of existing to-dos into one JSON tool call. ## Intended use - **In scope:** single-turn to-do CRUD intent → one tool call, on-device. - **Out of scope:** multi-turn dialogue, reasoning, general chat, code, or any task the base model is not recommended for (advanced math, code generation, creative writing). Inherits the base model's limits. ## Tools | tool | arguments | |---|---| | `create_todo` | `title` (str), `due` (str \| null) — ignores the current list | | `update_todo` | `target` (str), `title` (str \| null), `due` (str \| null) | | `delete_todo` | `target` (str) | | `none` | `{}` — emitted when the referenced to-do is not in the list | For `update_todo` / `delete_todo`, `target` is a **verbatim copy** of one item in the provided list. If the referenced item is absent, the model emits `none`. ## Prompt format The current to-do list (0–5 items) is injected into the prompt. Training and inference must use this exact layout: ``` Todos: - - User: ``` An empty list renders as `Todos:\n(none)`. Output is a JSON string, e.g.: ```json {"name":"delete_todo","arguments":{"target":"Book the moving truck"}} ``` ## Usage (MLX) ```python from mlx_lm import load, generate from mlx_lm.sample_utils import make_sampler model, tokenizer = load("") # e.g. sabeshbesh/pomo-1 prompt = "Todos:\n- Book the moving truck\n- Water the front yard plants\n\nUser: delete moving truck task" tokens = tokenizer.apply_chat_template( [{"role": "user", "content": prompt}], add_generation_prompt=True, tokenize=True, ) out = generate(model, tokenizer, prompt=tokens, max_tokens=96, sampler=make_sampler(temp=0.0)) print(out) # {"name":"delete_todo","arguments":{"target":"Book the moving truck"}} ``` Greedy decoding (`temp=0.0`) is recommended for deterministic tool calls. The base model's general-purpose defaults are temperature 0.1, top_k 50, repetition_penalty 1.05. ## Training - **Base:** LiquidAI/LFM2.5-230M (LFM2 hybrid: 14 layers, 8 gated short-conv + 6 GQA). - **Method:** LoRA SFT via `mlx_lm.lora`. - **Adapter:** rank 16, scale 16, dropout 0.05, applied to all 14 layers; `mask_prompt: true`. - **Data format:** legacy `{"prompt", "completion"}` JSONL; completion is a JSON-string tool call. - **Hardware:** Apple Silicon (MLX). ## Evaluation Held-out validation (n=300), best checkpoint, greedy decoding: | metric | score | |---|---| | parse rate (valid JSON) | 1.000 | | tool-name accuracy | 0.997 | | argument exact-match | 0.563 | | full match (name + args) | 0.563 | Metric definitions: **parse rate** = fraction of outputs that are valid tool-call JSON; **tool-name accuracy** = correct tool selected; **argument exact-match** = arguments exactly correct; **full match** = both correct. **Known limitation of this eval:** these figures were measured on a dataset variant where the current to-do list was *not* included in the prompt, which makes correct `target` selection for update/delete structurally impossible in many cases — the argument/full-match scores are a floor, not a ceiling. No baseline comparison against the prior model is included. Treat these numbers as provisional. ## License Governed by the base model's license, `lfm1.0`. See the [base model license](https://huggingface.co/LiquidAI/LFM2.5-230M/blob/main/LICENSE). ## Citation Base model: ```bibtex @article{liquidAI2026230M, author = {Liquid AI}, title = {LFM2.5-230M: Built to Run Anywhere}, journal = {Liquid AI Blog}, year = {2026}, note = {www.liquid.ai/blog/lfm2-5-230m} } ```