Desert Ant Labs

Title

On-device titles and descriptions: a short factual title and a one- to two-sentence description for any passage of text.

Title model page
Platforms
iOS, macOS, tvOS, visionOS
Weights
v0.1.0

Install

Swift (requirements)

Swift
.package(url: "https://github.com/Desert-Ant-Labs/desert-ant-core.git", from: "4.0.0",
        traits: ["MLX"])

Then add the Title product to your target. The MLX trait is required: without it the module compiles as a stub.

Usage

Title runs only on Apple platforms, on the GPU through MLX. The other Desert Ant models on Apple platforms run on Core ML. We measured Title writing text 5.7-8.3x faster on the GPU than on the Neural Engine. Because Title needs MLX, you turn Title on with the MLX package trait. A build that leaves out the trait fails at compile time, so you can't ship an app without a working model by mistake.

Loading the model is slow and writing a card is fast, so create one Titles and reuse it. Titles is an actor, because MLX isn't safe to drive from several tasks at once. Calls from several tasks run one at a time.

On iOS, call suspend() before your app enters the background and resume() when it returns. iOS revokes GPU access in the background, and MLX crashes the app if a generation is still running. suspend() cancels the running generation, and the call retries after resume().

Swift

Title doesn't download its weights. Download the model files from Hugging Face, and point the initializer at that folder:

Swift
import Title

let titles = try await Titles(directory: modelFolder)
let card = try await titles.describe(text)

card.title          // "Filming a two-person podcast on iPhone"
card.description    // one or two sentences
card.isEmpty        // true when the model returned neither

On unusual input, Title can keep generating without end. maxTokens caps each run, at 96 tokens by default:

Swift
let titles = try await Titles(directory: modelFolder, maxTokens: 96)

With Clips

To give each clip a title and a description, pass the clips to Title. cards(for:) returns the cards in the same order as the clips.

Swift
let cards = try await titles.cards(for: moments)   // index-aligned with moments
let card = try await titles.card(for: moments[0])

cards(for:) writes one card at a time. One generation already keeps the GPU busy, so parallel generations aren't faster. On a phone, parallel generations also add heat, and the phone throttles partway through a long video.

Other kinds of text

We fine-tuned Title on transcript clips. Title also writes accurate cards for news paragraphs, product descriptions and emails. Title can still get details wrong on general prose.

Files

Title's files form one MLX model folder. Pass the whole folder to Titles(directory:).

FileContents
model.safetensors6-bit quantized weights
model.safetensors.index.jsonShard index. Keep this file: the loader needs it, even with a single shard.
config.jsonArchitecture and quantization config
generation_config.jsonDecode defaults
tokenizer.json, tokenizer_config.jsonByte-level BPE with merges
chat_template.jinjaThe chat template we trained the fine-tune against

Keep the chat template as shipped. A different template changes the task the model performs.

The prompt

The SDK sends Title the exact instruction we fine-tuned the model on, and parses the reply for you. The model replies with two labeled lines:

Code
TITLE: <3-8 words, no final punctuation>
DESC: <1-2 sentences>

The model sometimes drifts off this format, so parse the reply tolerantly. When the reply has no labels, the SDK takes the first line as the title. When the SDK finds neither a title nor a description, card.isEmpty is true.

Apple only

MLX runs only on Apple silicon, so Title has no Android, Linux, Windows, browser or Node build. We also built Title for Core ML, to compare. The Neural Engine is limited by memory bandwidth when a model writes short text one token at a time. The Core ML build lost to MLX on time to first token, tokens per second, load time and memory use. We don't plan to ship the Core ML build.

Status

Title is in internal testing. We publish no quality figures for Title yet, because no independent review is complete. Title sometimes opens a description with a stock phrase that its instruction forbids. Read each card before it reaches a user.

Built on

See THIRD_PARTY_NOTICES.md.

Example app

Clipper Generate short clips from a video podcast or a long recording, fully on device. A macOS app and a command-line tool over the same core.

Install with Homebrew
brew tap desert-ant-labs/tap
brew install --cask clipper

View sourceOr download for macOS