← 返回教程
私有模型测试Face Recognition评测MOU隐私

如何对 InsightFace 私有人脸识别模型进行测试

面向客户的私有模型评测指南:覆盖 MOU 前置条件、图像准备、Python 客户端示例与隐私要求,便于在自有数据上完成对开源/私有模型的准确率评估。

8 分钟阅读

你将完成什么

InsightFace 通过托管的特征提取 API 向客户开放开源/私有识别模型,供其在签订商用合同前在自有验证数据上完成准确率评测。

本指南完整介绍评测流程:如何获取 API 端点、如何准备图像、如何使用最简 Python 客户端调用、我们的隐私与数据处理规则,以及免费评测窗口的合同范围。

请注意:此托管 API 仅用于前期测试评估。最终授权交付物是 ONNX 模型文件,您可以在自有基础设施上离线自行部署,长期生产推理无需依赖此 API 端点。

开始之前

  • 已签署涵盖合作意向、评测周期,以及共享模型标识保密范围的 MOU。端点 URL 仅在 MOU 签署后下发。
  • Python 3.9 及以上环境,已安装 numpy、requests 与 OpenCV (opencv-python)。
  • 覆盖生产分布的代表性验证集,并附带 RetinaFace、SCRFD 等检测器输出的人脸框。
  • 明确的评测数据集和标签,以及科学的评测方法。

1. 签署 MOU 并申请访问

所有私有模型测试都从签署 MOU 开始。MOU 约定合作意向、评测周期,以及与贵司共享的模型标识的保密范围。

API 端点 URL、贵司在合同中获授权的模型名(MOU 中允许的开源或私有模型)以及账户级速率限制,都会通过邮件发送给 MOU 中列明的技术联系人。端点不会公开,请勿向授权联系人之外的任何方共享。

  • 评测窗口自端点下发之日起最长 2 周,超出需签署商用合同。
  • 每份 MOU 仅解锁约定的模型名;服务端会拒绝其他模型名的请求。
  • 如端点需要轮换(例如评测窗口结束),新的 URL 会发送给同一份联系人列表。

2. 模型系列:dingo 与 eagle

目前 InsightFace 测试端点提供 2 个私有识别模型系列:dingo 与 eagle。两者都是开源 buffalo_l 人脸识别模型的高精度升级版本,您账户实际开放的系列与具体型号以 MOU 为准。

请根据部署预算选择系列。dingo 的单图计算量与 buffalo_l 中的人脸识别模型相当,eagle 则显著增加计算量以换取明显更高的识别精度,适用于更严苛的场景。

  • dingo — 计算量与 buffalo_l 中的人脸识别模型相当,但精度明显更高。适合在不改变延迟预算的前提下直接替换升级。
  • eagle — 计算量显著更大,但精度明显更高。适合 GPU 推理以及对人脸识别精度要求很高的场景。
  • eagle 与 eagle-2 — eagle 系列的 2 个型号,精度和计算量相当,但特征向量长度不同。可在评测阶段同时测试,根据存储与检索流水线的需求选择合适的特征长度。

3. 准备具有代表性的验证集

私有模型是识别 backbone,并不包含检测器。每次请求接受一张紧密裁剪的单人脸大头照,返回一个 embedding。请先用贵司检测器跑出框,再逐张发送裁剪结果。

但是服务端也会在大头照基础上进行二次检测与对齐,再提取 embedding,因此对小幅度的取景偏差是有一定容忍度的。

  • 一张图一张人脸。源图含多人时需先把每张脸切成独立文件再发送。
  • 按 MOU 数据条款,记录所用图像的同意与合法依据。

4. 裁剪并编码每张人脸图像

在检测框周围加一点扩边再上传。0.2 左右的 expansion factor(左右上下各 10%)能保留发际线、下颌和耳朵等对识别有用的上下文,又不会变成大半身像。可选地把最长边限制在 256 像素左右,使上传更小。

务必使用 PNG 等无损格式发送。JPEG、低质量 WebP 等有损格式会在眼睛和嘴部周围引入压缩噪声,对人脸识别相似度有可测量的负面影响。下面的 helper 仅作起点,请按贵司检测器的框约定进行调整。

  • 在检测框外加扩边(expansion factor);紧贴框的裁剪会拉低准确率。
  • 上传前务必保存为 PNG。在调用 API 前再次 JPEG 编码是异常低分最常见的原因。
对单人头像做扩边裁剪(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 保存为 numpy 的 .npy 文件,以便离线计算 cosine similarity。

下方示例客户端与生产协议完全一致,可以直接运行,也可以将 extract_feature 集成到贵司评测流水线中。请通过 --server-url 传入邮件中下发的端点 URL,不要硬编码到将提交至共享仓库的脚本里。

  • model_name 必须为 MOU 中列出的值,未列出的名字会被服务端拒绝。
  • feature 为空数组表示裁剪图中未检测到人脸,请检查框与扩边是否真正包含人脸。
  • 用 L2 正规化向量上的 cosine similarity 进行比较,客户端无需再做归一化。
私有端点的最小 Python 客户端
"""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。响应发出后不保留原图,且评测流量不会用于任何模型的训练或微调。

  • 不得向 MOU 列表之外共享端点 URL、模型名或返回分数。
  • 如怀疑端点或凭据泄露,须在 24 小时内通知 InsightFace 联系人。

7. 评测范围与后续步骤

免费评测窗口自端点下发之日起最长 2 周。窗口内可在速率限制范围内随意调用,建议在申请端点前就把测试集、预处理与指标定义准备好,把窗口时间用在出数据上。

在测试结束后,请尽快评估结果并给出商业合作的结论。

需要生产部署支持?

联系 InsightFace,获取模型授权、运行时优化和目标硬件部署支持。

提交企业询盘

在私有模型上运行此基准测试

如需评估私有识别模型用于生产,您可通过结构化的企业评估流程获取私有 API 或本地评估说明。