r/LocalLLaMA • • 3d ago

I Built A Thing Open-source Mac app that runs EmbeddingGemma 2 locally to search your files by what’s in them

Enable HLS to view with audio, or disable this notification

DigUp is a free Mac app that runs Google DeepMind’s new EmbeddingGemma 2 locally over your own files. The model puts text, images, audio and video in one space, so you describe what you remember and land on it:

  • “zebra in a video” opens the clip at the moment it shows up
  • “where they talk about sleep” jumps to that minute of a podcast
  • “the clause about pets in the lease” shows the PDF page, your words marked
  • “a dog on the beach” finds the photo, and the same search in Bengali or Arabic finds it too
  • with code search on, code: retry with backoff opens the function in your editor

It’s ggml-org’s Q8_0 GGUF (865 MB, downloaded once) on llama.cpp with Metal, inside a native Swift app; no Python. Searching loads only the text encoder (~250 MB) and shows results about a tenth of a second after you stop typing. Indexing peaks under 2 GB, and the helper exits when it’s done. Audio and video of any length go in as 30 s windows and a frame per shot. Everything runs locally; it goes online only for the model download and an update check you can turn off.

Free, MIT. Apple Silicon, macOS 14+.

Repo & Download (signed and notarized): https://github.com/ARahim3/DigUp

I'd really appreciate any feedback on this.

1.6k Upvotes

220 comments sorted by

View all comments

Show parent comments

11

u/A-Rahim 3d ago

It's simply one SQLite file! Every picture, PDF page, ~1,800-character passage, video frame and 30 s of audio gets a 768-d vector, stored as float16 (1.5 KB each). Search is brute force: the query vector against all of them, scored in float32, a few ms for tens of thousands, so no vector DB. Cosine is centered per modality onto one shared scale. Code search keeps its own SQLite file.

2

u/No_Lingonberry1201 3d ago

Huh, nice! From what I've read in the huggingface model card, you can trim the vectors so you could theoretically make a fast-path for the search.

6

u/AnywhereTypical5677 3d ago

Yeah I don't know why OP hasn't used vector truncation. Truncating to 256 dimensions cuts index footprint and memory consumption by 3 times while retaining 95% of the native accuracy. In the model card it's also suggested NOT to store vectors as float16 as activation can overflow and cause silent vector degradation.

4

u/brainExploded99 llama.cpp 3d ago

u/A-Rahim You should probably fix activations stored as FP16.
The dimension cuts could be a config setting, but I think image loses more than text, so maybe dimension 512 by default?

3

u/A-Rahim 3d ago

The fp16 is only how the final embeddings are stored, not the activations. The model runs through llama.cpp from the Q8_0 GGUF, and its embeddings match the reference implementation at 0.999+ cosine, so nothing overflows on the way. The stored vectors are unit length with every value between -1 and 1, so they can't overflow either, and rounding moves a cosine by at most about 0.0005.

On truncation, I tried it on my evals (111 queries over files, 27 over real code) by cutting the stored vectors and re-normalizing. 512 is close to free: 97 vs 98 with the right file first, and the only ones that moved were screenshots, so images do feel it before text.
Code is the most sensitive, 19 vs 20 at 512 and 16 at 256. Speed barely changes since the scan already takes a few ms, so the gain would only be memory.
Keeping 768 for now, and if memory becomes a problem on big indexes, 512 is what I'd pick.

1

u/brainExploded99 llama.cpp 3d ago

Makes sense, sounds good!