← Назад к руководствам
Приватный тестFace RecognitionОценкаMOUПриватность

Как провести приватный тест модели распознавания InsightFace

Пошаговое руководство по оценке open-source и приватных моделей InsightFace на собственных данных: требования MOU, подготовка изображений, Python-клиент и правила приватности.

8 мин чтения

Что вы настроите

InsightFace предоставляет open-source и приватные модели распознавания через хостируемый API извлечения признаков, чтобы клиент мог самостоятельно оценить точность на своих валидационных данных до подписания коммерческого соглашения.

Это руководство описывает весь процесс: получение endpoint, подготовка изображений, минимальный Python-клиент, правила приватности и обработки данных, а также договорные рамки бесплатного окна оценки.

Обратите внимание: размещённый API предоставляется только для предварительной оценки. По коммерческой лицензии передаются сами файлы ONNX-модели, которые вы развёртываете офлайн в собственной инфраструктуре — продуктивная эксплуатация не зависит от этого endpoint.

Перед началом

  • Подписанный MOU, фиксирующий намерение о сотрудничестве, период оценки и объём конфиденциальности относительно идентификаторов моделей, которые мы предоставляем. URL endpoint выдаётся только после подписания.
  • Python 3.9 или выше с numpy, requests и OpenCV (opencv-python).
  • Репрезентативный валидационный набор с результатами детекции (bounding boxes из RetinaFace, SCRFD или вашего детектора).
  • Чётко определённый оценочный датасет с эталонными метками и научно обоснованная методология оценки.

1. Подписать MOU и запросить доступ

Любой приватный тест начинается с подписанного MOU между вашей организацией и InsightFace. В нём фиксируются намерение о сотрудничестве, период оценки и объём конфиденциальности относительно идентификаторов моделей, которые мы вам передаём.

URL endpoint, список доступных моделей (open-source или приватные модели, разрешённые в вашем MOU) и лимиты по аккаунту высылаются по e-mail на технического контакта из MOU. Endpoint не публикуется и не должен распространяться вне круга авторизованных контактов.

  • Окно оценки — максимум две недели с момента выдачи endpoint. Для более длительной работы нужен коммерческий контракт.
  • Каждый MOU активирует только перечисленные имена моделей; иные имена отклоняются сервером.
  • Если URL нужно сменить (например, по окончании окна), новая ссылка отправляется тому же списку контактов.

2. Серии моделей: dingo и eagle

На тестовом endpoint InsightFace доступны две серии приватных моделей распознавания: dingo и eagle. Обе — более точные преемники open-source модели buffalo_l; конкретные серии и варианты, активированные для вашего аккаунта, указаны в MOU.

Выбирайте серию исходя из бюджета развёртывания. dingo сохраняет вычислительные затраты на изображение на уровне backbone-а распознавания buffalo_l, тогда как eagle значительно увеличивает их в обмен на ощутимо более высокую точность в сложных сценариях.

  • dingo — вычислительные затраты сопоставимы с моделью распознавания buffalo_l, но точность заметно выше. Прозрачная замена, когда нужны лучшие метрики без изменения бюджета по латентности.
  • eagle — значительно более высокая вычислительная нагрузка и заметно более высокая точность. Ориентирован на GPU-инференс и сценарии, где требуется максимальное качество распознавания лиц.
  • eagle и eagle-2 — два варианта серии eagle, сопоставимые по точности и вычислительной стоимости, но с разной длиной вектора признаков. Протестируйте оба и выберите размер embedding, наиболее подходящий вашему пайплайну хранения и поиска.

3. Подготовить репрезентативный валидационный набор

Приватные модели — это backbone-ы распознавания, без детектора. Каждый запрос принимает один плотно обрезанный портрет одного человека и возвращает один embedding. Сначала запустите свой детектор, затем посылайте по одному кропу за раз.

При этом сервер всё равно выполняет вторичную детекцию и выравнивание поверх присланного портрета перед извлечением embedding, поэтому небольшие неточности кадрирования допустимы.

  • Одно лицо на изображение. При нескольких людях — сохраняйте каждый кроп в отдельный файл.
  • Документируйте согласие и правовое основание для каждого изображения согласно положению о данных в MOU.

4. Кадрирование и кодирование лица

Перед отправкой добавьте небольшое поле вокруг bounding box. Expansion factor около 0,2 (по 10 % с каждой стороны) сохраняет полезный для распознавания контекст волос, подбородка и ушей. По желанию ограничьте длинную сторону (например, 256 пикселей), чтобы уменьшить размер.

Отправляйте только без потерь, например PNG. JPEG и WebP низкого качества дают артефакты вокруг глаз и рта, которые измеримо снижают качество embedding. Хелпер ниже — стартовая точка; адаптируйте его к формату bounding box вашего детектора.

  • Добавляйте поле (expansion factor); кадр строго по box ухудшает точность.
  • Сохраняйте кропы в PNG. Повторное JPEG-кодирование перед вызовом API — самая частая причина неожиданно низких очков.
Кадрирование одиночного портрета с полем (Python)
import cv2


def crop_face_with_expansion(image, bbox, expansion_factor=0.2, max_side=256):
    """
    Crop a single-person headshot with a small margin around the detected
    face box, and optionally downscale so the longest side is <= max_side.

    image:             input image as a numpy array (BGR or RGB).
    bbox:              face bounding box [x, y, width, height] from your
                       detector of choice (RetinaFace, SCRFD, etc.).
    expansion_factor:  total margin ratio (0.2 means +10% on each side).
    max_side:          if set, the longest side of the result is bounded.
    """
    img_h, img_w = image.shape[:2]
    x, y, w, h = bbox

    # 1. Margin distributed evenly to both sides.
    dw = int(w * expansion_factor / 2)
    dh = int(h * expansion_factor / 2)

    # 2. Expanded box, clamped to image bounds.
    x1 = max(0, x - dw)
    y1 = max(0, y - dh)
    x2 = min(img_w, x + w + dw)
    y2 = min(img_h, y + h + dh)

    face_img = image[y1:y2, x1:x2]

    # 3. Optional bounded downscale with a high-quality filter.
    if max_side is not None:
        curr_h, curr_w = face_img.shape[:2]
        longest = max(curr_h, curr_w)
        if longest > max_side:
            scale = max_side / longest
            new_w = int(curr_w * scale)
            new_h = int(curr_h * scale)
            face_img = cv2.resize(
                face_img, (new_w, new_h), interpolation=cv2.INTER_AREA,
            )

    return face_img


# Save the crop with a lossless format (PNG) before sending it to the API.
# Lossy formats (JPEG, WebP at low quality) introduce compression artifacts
# that can measurably reduce face recognition accuracy.
# cv2.imwrite("probe.png", crop)

5. Вызов API извлечения признаков

API ожидает multipart/form-data POST: один файл в поле image и строку model_name. Ответ — JSON с model_name и feature (L2-нормализованный embedding). Сохраняйте каждый embedding как .npy, чтобы офлайн считать cosine similarity.

Пример клиента ниже точно воспроизводит продакшн-протокол. Запускайте напрямую или импортируйте extract_feature в свой pipeline. Передавайте URL, полученный по e-mail, через --server-url; не зашивайте его в скрипты, которые попадают в общий репозиторий.

  • model_name должен быть из значений MOU; иные имена сервер отклоняет.
  • Пустой feature означает, что в кропе не найдено лицо — проверьте box и поле.
  • Сравнивайте embedding-и через cosine similarity на L2-нормализованных векторах; на клиенте не нормализуйте повторно.
Минимальный Python-клиент к приватному endpoint
"""Example client for the private InsightFace feature extraction service.

Uploads a single-person face image to the test endpoint, reads the returned
embedding, and saves it locally with np.save for offline evaluation.

Example invocation (model_name: eagle-2):

    python client.py \
        --server-url <URL delivered by email> \
        --model-name eagle-2 \
        --image probe.png \
        --output probe.npy
"""

import argparse
import os.path as osp

import numpy as np
import requests


def extract_feature(image_path, output_path, url, model_name, timeout=120.0):
    filename = osp.basename(image_path)
    data = {"model_name": model_name}

    with open(image_path, "rb") as infile:
        files = {
            "image": (filename, infile, "application/octet-stream"),
        }
        try:
            resp = requests.post(
                url=url, files=files, data=data, timeout=timeout,
            )
            resp.raise_for_status()
        except requests.RequestException as ex:
            raise SystemExit(
                "request failed: %s: %s" % (type(ex).__name__, str(ex))
            )

    payload = resp.json()
    feature = payload.get("feature")
    if not isinstance(feature, list):
        raise SystemExit("server response feature must be a list")
    if len(feature) == 0:
        raise SystemExit(
            "server returned no features; verify the image contains a "
            "detectable face"
        )

    feat = np.asarray(feature, dtype=np.float32)
    np.save(output_path, feat)
    print("saved feature:", output_path, feat.shape, payload.get("model_name"))
    return feat


def main():
    parser = argparse.ArgumentParser(
        description=(
            "Upload a face image to the private InsightFace test server and "
            "save the embedding with np.save."
        ),
    )
    # The --server-url value is delivered to evaluators by email.
    parser.add_argument(
        "--server-url", required=True,
        help="Feature extraction API URL (sent privately by InsightFace)",
    )
    # The set of choices below is illustrative; the models actually unlocked
    # for your account are listed in your MOU and may evolve over time.
    parser.add_argument(
        "--model-name", required=True,
        choices=["buffalo", "dingo", "eagle", "eagle-2"],
        help="Recognition model to evaluate (must match an entry in your MOU)",
    )
    parser.add_argument("--image", required=True, help="Input face image path (PNG recommended)")
    parser.add_argument("--output", required=True, help="Output .npy file path")
    parser.add_argument("--timeout", type=float, default=120.0, help="HTTP timeout in seconds")
    args = parser.parse_args()

    extract_feature(
        args.image, args.output, args.server_url, args.model_name,
        timeout=args.timeout,
    )


if __name__ == "__main__":
    main()

6. Приватность и обработка данных

Загруженные изображения используются только для расчёта и возврата embedding в рамках запроса. После ответа исходные изображения не сохраняются, а трафик оценки не применяется ни для обучения, ни для дообучения.

  • Не передавайте URL, имена моделей или результаты вне списка контактов MOU.
  • О подозрении на утечку URL или учётных данных уведомляйте контакт InsightFace в течение 24 часов.

7. Объём оценки и следующие шаги

Бесплатное окно — до двух недель с момента выдачи URL. В пределах окна можно делать сколько угодно сравнений в рамках rate limit; рекомендуем зафиксировать тестовый набор, препроцессинг и метрики до запроса endpoint, чтобы окно ушло на цифры, а не на подготовку.

По окончании теста, пожалуйста, как можно скорее оцените результаты и сообщите вывод о коммерческом сотрудничестве.

Нужна помощь с production-развертыванием?

Свяжитесь с InsightFace по вопросам лицензирования моделей, оптимизации runtime и поддержки целевого hardware.

Отправить корпоративный запрос

Запустите этот бенчмарк на приватной модели

Если вы оцениваете приватную модель распознавания для продакшена, вы можете получить доступ к приватному API или on-premise инструкциям через структурированный процесс корпоративной оценки.