Eye
Tag every photo by what it is and what's in it, from screenshots and receipts to 558 scenes, entirely on the device.

Tag and rank images.
Find the screenshots, receipts and selfies in a camera roll, the shots where someone's eyes are closed, and the photos too sensitive to show. Eye tags every photo on the device, so no image is uploaded.
Eye groups near-duplicate shots and picks the keeper from each burst, with no one's eyes closed and the best faces. A camera roll of forty takes of the same moment becomes one photo to look at.
A photo takes 5.5ms on the Neural Engine of a Mac with an M6, so 10,000 photos take under a minute. In Chrome with WebGPU, a photo takes 41ms.
Tag a photo in 5.5ms.
Eye tags a photo in 5.5ms on the Neural Engine of an M6 Mac, and in 41ms with WebGPU in Chrome. The Core ML and LiteRT builds score the same on six public test sets.
One photo, the full photo analysis, on a Mac with an Apple M6.
| Runtime | Time |
|---|---|
| Core ML, Neural Engine | 5.5ms |
| LiteRT, GPU (Metal) | 30ms |
| LiteRT.js, WebGPU, in Chrome | 41ms |
| LiteRT, CPU, 4 threads | 49ms |
| LiteRT.js, WebAssembly with threads, in Chrome | 176ms |
Accuracy on public test sets, through the same scoring code for both builds
| Test set | Core ML | LiteRT (CPU) |
|---|---|---|
| KonIQ-10k, aesthetic SRCC | 0.6288 | 0.6291 |
| COCO val2017, person AP50 | 0.3814 | 0.3837 |
| MIT1003, where people look, CC | 0.7153 | 0.7195 |
| CUHK cropping, crop IoU | 0.8244 | 0.8241 |
| WIDER Face val, AP, hard | 0.6806 | 0.6812 |
| CEW, eyes open AUC | 0.9943 | 0.9945 |
Both builds give the same answers to within a few thousandths on every set. Speed is measured on one Mac with an Apple M6, and the LiteRT build is not yet measured on Android phones.
Use cases
Tag and rank images.
Sort the camera roll
Separate screenshots, receipts, documents and whiteboards from the photos people took, so a gallery app can file them away or offer to clear them out.
Keep the best of a burst
Collapse near-duplicate shots into one group and show the keeper first, with no one's eyes closed. The rest can go in one tap.
Hide sensitive photos
Blur explicit, violent or medical photos before anyone sees them, in a shared family album or a browser upload form. Use the strict cutoff to hide a photo automatically.
Search photos by what's in them
Find every photo of the dog, the beach or a receipt across 558 scenes and the photo types. It works in a web app or a Node backend, with no cloud vision API.
Crop a cover image
Pick the best frame of a video or the best square or widescreen crop of a photo for a thumbnail or a share card. Eye also turns sideways photos the right way up.
What the model does
- One
analyzecall gives tags with a confidence, three scores (aesthetic, keeper and cover), and the people, pets and faces in the photo. The same call finds the best crop for any aspect ratio, a rotation fix and an embedding. - Tags cover the photo type (screenshot, receipt, document, ID card, whiteboard and more), quality (sharp, blurry, bokeh) and people (group shot, portrait, everyone smiling). Others cover keep or delete reasons, sensitive content and 558 scenes.
- Every tag is calibrated so 0.5 is the recommended cutoff and 0.9 a strict one. At 0.5, a screenshot tag is right 98% of the time, a receipt tag 100%, people 95% and eyes closed 92%.
- Scene tags are right 88% of the time at the median. The keep or delete reasons, such as forgettable or bad framing, are the least reliable, so use them for suggestions.
- Each face gets its own tags: eyes closed, smiling, looking at the camera or away, happy, surprised. Eye analyzes up to 20 faces per photo by default.
Eye.duplicates,Eye.bestandEye.similarwork across a library: near-duplicate groups, optionally only for photos taken seconds apart, the keeper of a set, and photos ranked by similarity.- Analyses save as the same JSON in Swift, Kotlin and JavaScript, so an app can store them and filter later without loading the model.
partschooses what to compute:photo,layout,facesandsharpness. Each part is one or more model runs, so leave out what you don't need.- 48MB as Core ML for Apple platforms, on the Neural Engine, and 66MB as LiteRT for Android, Linux, Windows, Node and the browser. The SDK downloads the model on first use and caches it.
- In the browser, Eye runs on the GPU through WebGPU where the browser has it, and on the CPU through WebAssembly otherwise.
Getting started
Add image classification to your iOS or macOS, Android or web app in a few lines of code. Eye docs.
// Swift Package Manager
.package(url: "https://github.com/Desert-Ant-Labs/desert-ant-core.git", from: "4.0.0")
// target dependency
.product(name: "Eye", package: "desert-ant-core")
import Eye
let eye = Eye()
let photo = try await eye.analyze(contentsOf: photoURL)
if photo.has(.screenshot) || photo.has(.receipt) { archive(photo) }
if photo.has(.sensitive, .strict) { hide(photo) }
photo.scores?.aesthetic // 0.81: better than 81% of photos
let keeper = Eye.best(of: burst)
Add Eye from Desert Ant Labs to this Swift project (iOS, macOS). What it does: On-device Photo Tagging and Scoring. SDK: Swift (iOS, macOS) Repo: https://github.com/Desert-Ant-Labs/desert-ant-core#readme // Swift Package Manager .package(url: "https://github.com/Desert-Ant-Labs/desert-ant-core.git", from: "4.0.0") // target dependency .product(name: "Eye", package: "desert-ant-core") Reference: - Model page: https://desertant.com/models/eye/ - Full catalog and other models: https://desertant.com/llms.txt Add the SDK, then follow its README for the exact API and current version. Do not invent API names or method signatures; confirm them against the README.
// build.gradle.kts (Maven Central)
implementation("ai.desertant:eye:4.0.0")
import ai.desertant.eye.Eye
import ai.desertant.eye.Tags
Eye(context).use { eye ->
val photo = eye.analyze(bitmap)
if (photo.has(Tags.DOG) && !photo.has(Tags.BLURRY)) keep(photo)
val groups = Eye.duplicates(library)
}
Add Eye from Desert Ant Labs to this Kotlin project (Android).
What it does: On-device Photo Tagging and Scoring.
SDK:
Kotlin (Android)
Repo: https://github.com/Desert-Ant-Labs/desert-ant-core#readme
// build.gradle.kts (Maven Central)
implementation("ai.desertant:eye:4.0.0")
Reference:
- Model page: https://desertant.com/models/eye/
- Full catalog and other models: https://desertant.com/llms.txt
Add the SDK, then follow its README for the exact API and current version. Do not invent API names or method signatures; confirm them against the README.
npm i @desert-ant-labs/eye @litertjs/core # browser
npm i @desert-ant-labs/eye # Node
import { Eye, Tag } from "@desert-ant-labs/eye";
const eye = await Eye.load();
const photo = await eye.analyze(image);
if (photo.has(Tag.dog) && !photo.has(Tag.blurry)) keep(photo);
const groups = Eye.duplicates(library, { dates });
Add Eye from Desert Ant Labs to this JavaScript / TypeScript project (Web, Node.js). What it does: On-device Photo Tagging and Scoring. SDK: JavaScript / TypeScript (Web, Node.js) Repo: https://github.com/Desert-Ant-Labs/desert-ant-core#readme npm i @desert-ant-labs/eye @litertjs/core # browser npm i @desert-ant-labs/eye # Node Reference: - Model page: https://desertant.com/models/eye/ - Full catalog and other models: https://desertant.com/llms.txt Add the SDK, then follow its README for the exact API and current version. Do not invent API names or method signatures; confirm them against the README.
Specs
- Speed
- 5.5ms a photo on the Neural Engine (M6 Mac); 41ms with WebGPU in Chrome
- Accuracy
- At the 0.5 cutoff: screenshots 98% precise, receipts 100%, scenes 88% at the median
- Tags
- Photo type, keep or delete, quality, people, faces, sensitive content, and 558 scenes
- On-device size
- 48MB Core ML (Apple); 66MB LiteRT (Android, Linux, Windows, Node, the browser)
- Platforms
- iOS 18+, macOS 15+, tvOS 18+, visionOS 2+ (Core ML); Android, Linux, Windows (LiteRT); the browser and Node (LiteRT.js)
Eye is trained on photos, so scores for illustrations, screenshots and heavily edited images are less reliable. The keep or delete reasons, such as forgettable or bad framing, are the least reliable, so use them for suggestions and the strict cutoff for anything automatic.
Face analysis describes a face and doesn't identify who someone is.
FAQ
What is Eye?
Tag every photo by what it is and what's in it, from screenshots and receipts to 558 scenes, entirely on the device.
Does Eye run on device?
Yes. Eye runs on the device, with no server call, so the data stays with the user.
Which platforms does Eye support?
Eye ships as a native on-device SDK for Swift, Kotlin, JavaScript / TypeScript.
How much does Eye cost?
Each model is free up to 100k monthly active devices. Inference is unlimited. Contact us for custom licenses.
How accurate or fast is Eye?
Eye tags a photo in 5.5ms on the Neural Engine of an M6 Mac, and in 41ms with WebGPU in Chrome. The Core ML and LiteRT builds score the same on six public test sets.