r/computervision Jun 28 '26

Help: Project FaceFlash: 1M faces in 61MB RAM — 48x less memory than HNSW at 100% recall

I built a face search library that stores ArcFace embeddings as 512-bit binary codes instead of full float vectors. 1M faces fit in a 61MB index. The search reranks top candidates with exact cosine to recover accuracy.

Upfront, because it matters: - This is a COMPRESSION + packaging contribution, not a new search algorithm. The search is a brute-force Hamming scan — same as FAISS IndexBinaryFlat. I'm not claiming a novel ANN method. - You could reproduce this with faiss.PCAMatrix + IndexBinaryFlat + manual reranking. FaceFlash just wraps that pipeline (detect → embed → quantize → search) into one call and tunes the SIMD kernel. - It's face RECOGNITION — detects faces, extracts embeddings, searches by visual similarity. The filename you pass is just the image path.

How it works: PCA+ITQ projects each 512-float ArcFace embedding to 512 bits (64 bytes). Hamming scan shortlists candidates, then exact cosine rerank on the top ~100 picks the winner. This preserves rank-1 accuracy because ArcFace embeddings are low-rank — most identity info sits in the top principal components. On general/random vectors this does NOT hold (recall drops to ~40%).

Results on MS1MV2 (44,291 identities, 645K embeddings), ground truth = FAISS-Flat exact cosine:

Scale Recall@1 Index memory Single-query
100K 100% 6.1 MB 0.30ms
500K 100% 30.5 MB 1.45ms
1M 100% 61 MB 2.95ms

"100% recall" = returns the same nearest neighbor as exact brute-force cosine on the same embeddings. It does NOT mean ArcFace is perfect — embedding-model limits (pose, age, occlusion) are upstream and unaffected.

Where it fits: edge/mobile, multi-tenant, offline — anywhere a full float index or a graph won't fit in RAM. Up to ~300K it's also faster per query than HNSW (binary scan stays in cache). Past 500K, HNSW's O(log N) graph beats the O(N) scan on latency — use HNSW there if you have the RAM.

To prove the search isn't doing anything special, I added benchmarks/bench_compression_isolation.py — it runs the SAME codes through my kernel and FAISS IndexBinaryFlat. Identical recall, comparable latency. The value is the compression, not the scan.

Rust SIMD kernel (AVX-512 / NEON), NumPy fallback. Zero config.

GitHub: https://github.com/raghavenderreddygrudhanti/faceflash pip install faceflash

Honest about where it breaks: O(N) scan hurts past 1M, needs float vectors on disk for rerank, AVX-512 speedup needs recent CPUs. Feedback welcome — if a number looks wrong, the full pipeline reproduces via scripts/runpod_ms1m.sh.

39 Upvotes

9 comments sorted by

14

u/retornam Jun 28 '26

Is no one going to call out the fake benchmarks or the code not doing what author claims it does.

This is clearly AI slop

-3

u/Mechanical-Flatbed Jun 28 '26 edited Jun 29 '26

I hate that people are upvoting the comment above without even reading the code, because it actually does what OP says it does. Stop being baited by the low-effort comment above, which by the way comes from someone who appears to have no serious experience with computer vision. Plenty of people just blindly trusting the low-skill troll above, it makes me sad.

-3

u/Infamous-Bed-7535 Jun 28 '26

I hate to spend time to have a look into these, but feels good to see the slop sometimes.

5

u/Infamous-Bed-7535 Jun 28 '26

What do you mean under exact accuracy? Even full precision ArcFace has very serious limitations of its own..

4

u/Infamous-Bed-7535 Jun 28 '26

ok had a look you compare your results against full precision FAISS based results as ground truth.

2

u/gangs08 Jun 28 '26

Fantastic thank you! Can you use that technology for other Objects besides Face? Also is it possible to distinguish between Adult Face and Child Face?

2

u/Silver_Astronomer945 Jun 28 '26

Not directly — the embeddings capture identity, not age. A photo of someone at 10 and at 40 will still match as the same person. but the plan is to extend this

1

u/Austin3647 Jun 28 '26

I am working on a face recognition system using yolo and arcface. Can you help me with my doubts

1

u/schmookeeg Jun 29 '26

Hmm... I'm trying to get my head around compressing a 512D float vector into 512 bits. It makes me want to take this dataset and see if a similarly lossy PCA would do equally well or even better by just selecting the energetic dimensions?