Реалізація AI-порівняння обличчя з документом (Face Match) у мобільному додатку
KYC-флоу без Face Match—це перевірка документа, який ніяк не привязаний до людини перед камерою. Face Match закриває цей пробіл: порівнює селфі користувача з фотографією на документі та повертає confidence score. Технічно завдання вирішується, але дияволи в деталях: якість фото у паспорті, освітлення при селфі, вік документа та aging factor.
Як працює порівняння face embedding
Класичний pipeline:
-
Детекція обличчя на обох зображеннях—
Vision.VNDetectFaceRectanglesRequestна iOS, ML KitFaceDetectorна Android. - Вирівнювання (alignment)—нормалізуємо координати очей, носа у canonical face position. Без alignment збіг падає на 15–20%.
- Embedding—CNN-модель (ArcFace, FaceNet) трансформує 112×112 px обличчя в 512-мірний вектор.
- Cosine similarity між двома векторами—значення 0.0–1.0, де ≥0.65 зазвичай вважається збігом (поріг залежить від моделі).
Важливо: поріг не універсальний. Різні демографічні групи показують різний baseline similarity. Хороша модель навчена на збалансованому датасеті (MS-Celeb-1M, VGGFace2 + аугментація) та валідована на LFW / AgeDB із розбивкою за демографією. Модель без такої валідації—потенційний дискримінаційний ризик та хибний FRR для похилих користувачів.
On-device embedding на iOS
ArcFace R50, конвертований у CoreML (coremltools), важить ~85 MB. Для мобільного продакшену краще MobileFaceNet—1.1 MB, точність на LFW 99.2% vs 99.6% у ArcFace R50. Різниця 0.4% критична редко, виграш у розмірі бандла суттєвий.
let faceModel = try MobileFaceNet(configuration: MLModelConfiguration())
guard let embedding = try? faceModel.prediction(face_input: alignedFaceBuffer) else { return }
func cosineSimilarity(_ a: MLMultiArray, _ b: MLMultiArray) -> Float {
var dot: Float = 0
var normA: Float = 0
var normB: Float = 0
for i in 0..<512 {
let ai = a[i].floatValue
let bi = b[i].floatValue
dot += ai * bi
normA += ai * ai
normB += bi * bi
}
return dot / (sqrt(normA) * sqrt(normB))
}
let score = cosineSimilarity(selfieEmbedding, documentEmbedding)
На Apple Neural Engine (A14+) інференс MobileFaceNet займає ~25 мс. iPhone SE 2nd gen—~180 мс. Якщо цільова аудиторія—бюджетні пристрої, серверний inference вигідніше.
Особливість: фото в документі низької якості
Фотографія у паспорті—це стиснута, часто надрукована та переснята зображення. Типові проблеми:
- Оверекспозиція при съємці сторінки паспорта (блики на глянцевій плівці).
- Моаре-паттерни від надрукованого растра при сканюванні.
- Aging factor: паспорт виданий 9 років тому, людина постарішала.
Preprocessing pipeline для фото в документі: коррекція гами, denoising (Core Image CINoiseReduction), видалення блику через CIHighlightShadowAdjust. Після цього—детекція та alignment як звичайно.
Aging factor можна частково компенсувати через age-invariant модель або явну нормалізацію: якщо дата народження на документі >40 років тому, знижуємо поріг similarity на 0.03–0.05.
Серверна верифікація для високих вимог
On-device match підходить для внутрішніх сервісів. Для фінансових продуктів (banking, crypto onboarding) потрібна серверна верифікація з audit trail—логуємо embeddings (не фото!), timestamp, device fingerprint, similarity score. Фото на сервер передавати небажано—лише embeddings. І приватність, й економія bandwidth.
Серверний стек: Python + insightface (ArcFace R100) + FAISS для батчевого пошуку + PostgreSQL з pgvector для зберігання embeddings. Latency: ~150–300 мс на GPU T4.
Захист від атак
Face Match без liveness—атакується фотографією. Без anti-spoofing—маскою. Інтеграція з Liveness Detection обов'язкова в production-сценарії. Сам Face Match—фінальний крок після проходження liveness, не самостійний модуль.
Етапи внедрення
Вибір моделі (on-device/сервер) → інтеграція detection + alignment → embedding + similarity → настройка threshold → тестування на edge cases (окуляри, борода, погане освітлення, старі фото) → інтеграція з liveness та IDV-флоу → аудит точності за демографією → публікація.
Терміни: інтеграція готової CoreML/TFLite моделі—3–5 тижнів. З серверним inference, audit trail та дообучанням моделі—8–14 тижнів. Вартість розраховується індивідуально.







