trippet-lfm2-1.2b β€” unified on-device model for the trippet trip-planning app

A LoRA fine-tune of LFM2.5-1.2B-Instruct, exported to q4 ONNX for in-browser inference (transformers.js + WebGPU). It is the single model that powers the whole trippet app β€” trained, exported, and validated end-to-end on a MacBook Pro (M2 Max), no cloud.

What it does (one model, routed by context)

It uses LFM2's native tool-calling as a mode switch. The app declares the extract_intent tool when parsing a trip brief; otherwise the model just talks.

job how it's invoked output
Parse a trip brief β†’ structured Intent declare extract_intent tool native tool-call with the Intent (region, bases+roles+nights, intermediates, certainty, when/duration, party, interests, constraints, asks)
Select day stops from a candidate pool the selection prompt (no tool) {interestId:[indices]} β€” the strongest few per interest
Converse (narrate the plan, confirm an edit, answer a question) a chat/draft prompt (no tool fires) grounded plain prose

The native format is what makes one model possible: the tool declaration is a learned switch, so a model fine-tuned to tool-call on briefs still chats on everything else β€” no second model, no catastrophic forgetting.

Training (all local, Apple Silicon)

  • PEFT LoRA (r=16, all-linear, prompt-masked), 3 epochs, MPS, merged to fp16.
  • Data: ~1000 valid-by-construction briefβ†’Intent examples (native tool-call targets) + a boundary set (chitchat/draft β†’ prose, teaching when not to call) + selection examples distilled from a strong teacher over real candidate pools (the harness's own gatherCandidates over real towns).
  • Export: LiquidAI's onnx-export β†’ q4 ONNX (transformers.js layout).

Validation (fp16 merged, same scorer as the baseline)

  • Routing: 7/7 β€” tool-calls on briefs, chats on chitchat ("Rome, Florence, Venice"; "Paris").
  • Intent β€” in-distribution: slot-F1 1.000, schema-valid 40/40 (perfect structure).
  • Intent β€” real briefs: slot-F1 0.636, schema-valid 6/10 (real/long/multi-constraint is the hard case).
  • Selection vs teacher gold: pick-F1 0.915, coverage 1.0, set-Jaccard 0.92, 10/10 in-bounds.
  • vs base LFM2.5-1.2B: the base can't produce the Intent at all (recall 0.00) and over-triggers/garbles tool-calls; this model is grounded and routes.

Use (transformers.js)

import { pipeline, env } from '@huggingface/transformers';
const gen = await pipeline('text-generation', '<this-repo>', { dtype: 'q4', device: 'webgpu' });
// parse a brief β€” declare the tool:
const out = await gen([{ role:'user', content: brief }], { tools: [EXTRACT_INTENT_TOOL], max_new_tokens: 400 });
// converse β€” no tool declared:
const reply = await gen([{ role:'user', content: draftPrompt }], { max_new_tokens: 300 });

Limitations

  • Real, long, multi-constraint briefs still degrade (the Puglia-class stress test) β€” the gap is training data coverage (more long/messy/real briefs), not the method.
  • Selection is trained on a modest teacher-labeled set; grow it for production.
  • Romanization of non-Latin place names is better handled by a deterministic library than the model.
  • The harness must declare the tool when parsing briefs and parse the native call (small change).
Downloads last month
22
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for mbotta/trippet-lfm2-1.2b-edit-ONNX

Quantized
(72)
this model