Разработка системы идентификации лица (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 дня. Свяжитесь с нами, чтобы обсудить детали.







