Розробка системи ідентифікації обличчя (Face Identification, 1:N)
При пошуку людини в базі з 500 тисяч облич без використання ANN latency перевищує 100 мс — для real-time СКД це неприйнятно. Ми вирішуємо цю проблему за допомогою FAISS та оптимальної архітектури індексу. Наші інженери мають сертифікати PyTorch та FAISS, досвід впровадження систем з базами до 10 млн облич. Понад 5 років на ринку CV-рішень. Розробляємо системи під ключ: від вибору архітектури до інтеграції в існуючу інфраструктуру. Оцінимо ваш проєкт за 2 дні та запропонуємо оптимальне рішення.
Як масштабувати ідентифікацію при мільйонах облич?
При базі більше 100k облич повний перебір (brute-force) стає неприйнятно повільним. Використовуємо ієрархію підходів залежно від розміру бази. FAISS IVFFlat дає приріст швидкості в 50 разів порівняно з повним перебором при базі в 1 млн облич, а IVFPQ стискає вектори в 8 разів з мінімальною втратою точності. Вибір індексу безпосередньо впливає на latency та споживання пам'яті.
| Розмір бази | Метод пошуку | Latency |
|---|---|---|
| < 10k | Brute-force cosine similarity (NumPy) | < 1 ms |
| 10k–1M | FAISS IVFFlat | < 5 ms |
| 1M–100M | FAISS IVFPQ (Product Quantization) | < 10 ms |
| > 100M | ScaNN або Milvus cluster | < 20 ms |
import faiss import numpy as np from dataclasses import dataclass @dataclass class IdentificationResult: person_id: str | None person_name: str | None similarity: float identified: bool class FaceIdentificationSystem: def __init__(self, embedding_dim: int = 512, n_lists: int = 100, threshold: float = 0.45): self.dim = embedding_dim self.threshold = threshold quantizer = faiss.IndexFlatIP(embedding_dim) self.index = faiss.IndexIDMap( faiss.IndexIVFFlat(quantizer, embedding_dim, n_lists, faiss.METRIC_INNER_PRODUCT) ) self.index.nprobe = 20 self.id_map = {} self._next_id = 0 def register(self, person_id: str, name: str, embeddings: np.ndarray) -> int: faiss.normalize_L2(embeddings) ids = np.arange(self._next_id, self._next_id + len(embeddings)) if not self.index.is_trained: self.index.train(embeddings) self.index.add_with_ids(embeddings, ids) for fid in ids: self.id_map[int(fid)] = {'person_id': person_id, 'name': name} self._next_id += len(embeddings) return len(embeddings) def identify(self, query_embedding: np.ndarray, k: int = 5) -> IdentificationResult: query = query_embedding.reshape(1, -1).copy() faiss.normalize_L2(query) similarities, faiss_ids = self.index.search(query, k) best_sim = float(similarities[0][0]) best_id = int(faiss_ids[0][0]) if best_id == -1 or best_sim < self.threshold: return IdentificationResult(None, None, best_sim, False) person_info = self.id_map[best_id] return IdentificationResult( person_info['person_id'], person_info['name'], best_sim, True ) Чому вибір індексу критичний для latency?
Latency p99 — ключова метрика для real-time систем. При неправильному виборі індексу час пошуку може зростати лінійно з розміром бази. Ми гарантуємо, що latency не перевищить 15 мс для баз до 1 млн облич при правильно налаштованому IVFFlat з nprobe=20. Для великих баз використовуємо GPU прискорення через FAISS GPU.
Кілька зображень на людину
Реєстрація кількох фото з різними ракурсами та умовами освітлення підвищує recall. При ідентифікації з агрегацією по всіх фото людини:
def identify_with_aggregation(self, query_emb: np.ndarray, k: int = 10) -> IdentificationResult: query = query_emb.reshape(1, -1).copy() faiss.normalize_L2(query) similarities, faiss_ids = self.index.search(query, k) votes = {} for sim, fid in zip(similarities[0], faiss_ids[0]): if fid == -1: continue pid = self.id_map[int(fid)]['person_id'] votes[pid] = votes.get(pid, 0) + float(sim) if not votes: return IdentificationResult(None, None, 0.0, False) best_pid = max(votes, key=votes.get) best_score = votes[best_pid] / k if best_score < self.threshold: return IdentificationResult(None, None, best_score, False) name = self.id_map[next( fid for fid, info in self.id_map.items() if info['person_id'] == best_pid )]['name'] return IdentificationResult(best_pid, name, best_score, True) Closed-set vs Open-set ідентифікація
Closed-set: всі запити належать одному із зареєстрованих людей. Задача зводиться до ранжування. Open-set ідентифікація — складніше: система повинна відхиляти незнайомців — людей не з бази. Вимагає налаштування порогу відхилення. При зростаючій базі поріг може потребувати коригування: з 1000 до 100k людей ймовірність випадкового збігу зростає.
Оновлення бази в реальному часі
Додавання нових користувачів без переіндексації: index.add_with_ids() працює інкрементально. Видалення: IndexIDMap.remove_ids(). Персистентність через faiss.write_index().
Метрики production-системи
- CMC (Cumulative Match Characteristic): Rank-1, Rank-5, Rank-10 accuracy
- DIR@FAR (Detection and Identification Rate): для open-set
- Latency p95/p99 при піковому навантаженні
- QPS (queries per second) — для планування інфраструктури
| Розмір бази | Рекомендоване залізо | QPS |
|---|---|---|
| < 100k | 1 CPU сервер | 500+ |
| 100k–10M | 1 GPU + FAISS GPU | 2000+ |
| > 10M | Milvus cluster | 5000+ |
Що входить в роботу з розробки системи ідентифікації?
- Архітектурний проєкт: вибір моделі ембеддингів, індексу, заліза.
- Реалізація API для реєстрації та ідентифікації.
- Інтеграція з системами контролю доступу (СКД).
- Документація та керівництво адміністратора.
- Навчання персоналу та підтримка при запуску.
- Гарантія на код 12 місяців.
Покроковий процес впровадження
- Аналіз вимог та навантажувальне тестування.
- Вибір стеку та проєктування.
- Розробка та тестування.
- Інтеграція та пілотний запуск.
- Оптимізація під продуктивне навантаження.
Типові помилки при проєктуванні ID-систем
- Використання brute-force при великій базі — latency зростає лінійно.
- Ігнорування open-set: не налаштований поріг, хибні спрацьовування.
- Недооцінка якості зображень — модель вимагає мінімальну роздільну здатність 100x100 пікселів.
- Відсутність реплікації індексу — єдина точка відмови.
Для production систем рекомендується використовувати FAISS GPU для прискорення. Коефіцієнт стиснення IVFPQ 8x дозволяє зберігати 10 млн облич у 2 ГБ пам'яті. За даними офіційної документації FAISS (GitHub), IVFPQ забезпечує стиснення в 8 разів з мінімальною втратою точності.
Ми гарантуємо якість та точність системи. Наші інженери мають сертифікати з PyTorch та FAISS. Досвід впровадження в компаніях з базами до 10 млн облич.
Отримайте консультацію по вашому проєкту — ми оцінимо архітектуру та терміни за 2 дні. Зв'яжіться з нами, щоб обговорити деталі.







