InsightFace Server 0.2.0:单容器自托管人脸识别服务与 INT8 精确 GPU 检索实战
本文基于仓库中 server/README.pt.md 完整展开,讲解 InsightFace Server 0.2.0 的部署方式(CPU 与 CUDA 12 两套 Docker Compose)、模型安装流程、关键环境变量与 TOML 配置、基于 SQLite 的持久化语义,以及支撑「单卡 RTX 5090 承载 50M+ 人脸向量」的 C++ 原生精确检索层。读完后,你可以独立完成该服务的容器化部署、从源码构建镜像、配置检测/检索参数,并通过 REST API 或 Python SDK 调用检测、比对、注册与 1:N 检索能力。
产品定位与版本现状
InsightFace Server 是一个自托管(self-hosted)的人脸识别服务器,把 Web UI、REST API、SQLite 存储与本地 CPU / NVIDIA GPU 推理 打包进单个容器。其核心工作流被概括为一句话:
上传一张图像 -> 检测、比对、注册或检索
它被定位为面向常见人脸识别流程的、以隐私为先的替代方案:图像、embeddings、模型和索引都可以保留在你自己的网络内。文档同时明确划定了边界——它不是 AWS 兼容替换,不实现 SigV4、IAM、Region 或 AWS 资源语义。
当前版本为 0.2.0,仅支持 Linux x86_64,提供两个运行时镜像族:
| 环境 | 镜像 |
|---|---|
| CPU | ghcr.io/deepinsight/insightface-server:0.2.0-cpu |
| NVIDIA GPU | ghcr.io/deepinsight/insightface-server:0.2.0-cuda12 |
移动的 cpu 与 cuda12 tag 指向各自镜像族内最新的稳定版本;仓库刻意不提供含义模糊的 latest tag,发布策略详见 Maintainer Guide。
模型许可注意:InsightFace 公开预训练模型通常仅限非商业研究用途,商业用途需向 InsightFace 官方单独获得授权。这一点在服务端代码中也有落地——模型安装工具会在
server/.models写入manifest.json和签名的MODEL.LICENSE,模型条款与 Server 代码许可相互独立。
核心功能一览
原文档列出的功能点,结合仓库源码可以逐条对应到实现位置:
- SCRFD 人脸检测、五关键点、对齐、ArcFace embeddings、L2 归一化、原始余弦相似度与 Person 1:N 精确检索:推理管线由 ONNX Runtime 驱动,见 inference/onnx_engine.py 与 inference/factory.py。
- 多分辨率检测,融合后单次 NMS,支持
largest或center_largest单脸选择:默认多分辨率与选择策略在 config/server.toml 中定义。 Collection -> Person -> FaceSample存储模型:Collection 与模型绑定,支持多图注册、部分成功、metadata 与显式拒绝原因;持久层为 SQLite,见 storage/repository.py 与 storage/database.py。- 注册
review_mode:off、standard、strict;可选external_trusted预计算 embeddings,允许可信上游提取器直接提交特征。 - 精确 GPU 检索,支持 FP32、FP16、BF16、INT8 向量存储:实现于 C++ 原生库 server/native/search,Python 侧封装在 search/native.py 与 search/factory.py。
- 多语言 Web UI:Dashboard、Collections、People、Detect、Compare、Search、RTSP 监控、System 诊断与 Help 页面。
/v1下 29 个 snake_case REST 操作,包含受认证的/v1/embeddings,另附轻量级类型化 Python SDK。- 服务端持久化 RTSP Monitors:事件为有界内存队列,多客户端独立,可选
preview.mjpeg;关闭浏览器不会停止监控,业务逻辑在 services/rtsp.py。 - SQLite 作为唯一持久事实来源:索引为可丢弃的内存精确索引,
/models只读挂载、/data持久卷、数据库 migrations、健康检查,以及严格的 CUDA 启动校验且不做静默 CPU 回退(由 compose 文件中的INSIGHTFACE_STRICT_CUDA: "1"强制)。 - 输入支持 JPEG、PNG、WebP;默认不保留上传原图。
RTX 5090 上的 GPU 检索性能
在单张 NVIDIA GeForce RTX 5090(32.607 MiB)上,原生 CUDA 精确 flat 索引在 INT8 下最多存储 58.9M 条 512 维图像向量:
| GPU 数据类型 | 最大图像向量数 | 10M Top-5 p50 | 10M 串行 QPS |
|---|---|---|---|
| FP32 | 15.8M | 12.84 ms | 77.85 |
| FP16 | 30.7M | 6.83 ms | 146.32 |
| BF16 | 30.7M | 6.83 ms | 146.33 |
| INT8 | 58.9M | 3.84 ms | 260.81 |
INT8 达到 FP32 实测容量的 3.73 倍、10M 规模下 Top-5 吞吐的 3.35 倍。这些是纯 GPU 测量(同一张 RTX 5090,驱动 580.105.08,CUDA 12.9):容量测试是未加载 ONNX 模型、无 Server 负载下的原生索引独立上限;速度测试使用恰好 10M 条图像向量、GPU 常驻的全量精确 Top-5 扫描、单查询在途、10 次预热与 100 次测量。索引在每种存储表示内部是精确的,但量化仍可能使 score 相对 FP32 发生偏移。生产部署必须为模型、请求、并发、索引重建与 allocator 预留额外 VRAM。
ICCV21-MFR 多族裔 MR-ALL 精度验证
仓库使用 ICCV21-MFR 的多族裔(MR)测试集,按 MR-ALL 全对 1:1 协议、FAR 1e-6 评估了各检索 profile。所有 profile 使用同一批 512 维 buffalo_l embeddings(L2 归一化,仅通过 Server API 提取一次),只有向量的存储与计算表示不同:
| 检索 profile | MR-ALL @ FAR 1e-6 | 余弦阈值 | 相对 FP32 差值 |
|---|---|---|---|
| FP32 | 91.249107 % | 0.407787 | — |
| FP16 | 91.249197 % | 0.407787 | +0.000090 个百分点 |
| BF16 | 91.248502 % | 0.407787 | -0.000605 个百分点 |
| INT8 | 91.248005 % | 0.407739 | -0.001102 个百分点 |
结论是:INT8 在该基准上没有实质性精度损失——按 challenge 常用的两位小数口径,FP32 与 INT8 同为 91.25 % MR-ALL,未舍入差值仅 0.0011 个百分点,同时保留了前述 3.73 倍容量与 3.35 倍吞吐优势。需要强调,该对比衡量的是向量存储与检索精度,而非 INT8 模型推理精度。
快速开始
环境要求:
- Linux x86_64,装有 Docker Engine 与 Docker Compose;
- CUDA 场景额外需要受支持的 NVIDIA GPU、NVIDIA 驱动与 NVIDIA Container Toolkit。
宿主机不需要安装 Python、OpenCV、ONNX Runtime、CUDA Toolkit 或 cuDNN。公开镜像中不含模型、客户数据、API Keys 或生产配置。
在完整的 InsightFace 仓库 checkout 中,先安装模型到 server/.models:
mkdir -p server/.models
docker compose -f server/deploy/compose.cpu.yml pull
docker compose -f server/deploy/compose.cpu.yml \
run --rm models install buffalo_l --accept-license
模型工具同时支持 buffalo_m、buffalo_sc 和 antelopev2。安装过程写入 manifest.json 与签名的 MODEL.LICENSE,可用 models verify 校验已安装包;模型条款独立于 Server 代码许可。从 Compose 文件看,models 是一个 tools profile 的一次性服务,entrypoint 为 models_cli.py,将 server/.models 绑定到容器内 /models。
启动 CPU 版本:
docker compose -f server/deploy/compose.cpu.yml up -d
curl -fsS http://127.0.0.1:18097/v1/health
或启动 CUDA 12 版本:
docker compose -f server/deploy/compose.cuda12.yml pull
docker compose -f server/deploy/compose.cuda12.yml \
run --rm models install buffalo_l --accept-license
docker compose -f server/deploy/compose.cuda12.yml up -d
curl -fsS http://127.0.0.1:18098/v1/health
然后打开 http://SERVIDOR:18097/(CPU)或 http://SERVIDOR:18098/(CUDA),创建 Collection、用一张或多张照片注册 Person,再用另一张照片检索。用 docker compose ... down(不带 -v)停止时会保留数据卷。
对外暴露前必须启用认证。仓库提供的 Compose 文件默认 INSIGHTFACE_AUTH_ENABLED=false 以便隔离评测:
export INSIGHTFACE_AUTH_ENABLED=true
export INSIGHTFACE_API_KEY='substitua-por-um-segredo-aleatorio-longo'
docker compose -f server/deploy/compose.cpu.yml up -d
环境变量与配置详解
两个 Compose 文件(compose.cpu.yml、compose.cuda12.yml)暴露了同一组环境变量,默认值即出厂配置。除认证相关项外,这些变量同时决定运行时行为:
| 环境变量 | 默认值 | 作用 |
|---|---|---|
INSIGHTFACE_AUTH_ENABLED |
false |
是否启用 API Key 认证 |
INSIGHTFACE_API_KEY |
空 | API 密钥;启用认证时必须设置为长随机串 |
INSIGHTFACE_CORS_ORIGINS |
空 | CORS 来源白名单;保持关闭是安全建议 |
INSIGHTFACE_LOG_LEVEL |
INFO |
日志级别 |
INSIGHTFACE_SAVE_FACE_CROPS |
false |
是否保存 112×112 bounding-box JPEG 裁剪(默认关闭) |
INSIGHTFACE_DEFAULT_THRESHOLD |
0.4 |
全局默认余弦阈值(范围 0.0..1.0) |
INSIGHTFACE_COLLECTION_DEFAULT_SEARCH_PROFILE |
fp32_v1 |
新 Collection 的默认检索 profile |
INSIGHTFACE_COLLECTION_DEFAULT_CAPACITY_ROWS |
100000 |
Collection 默认容量行数 |
INSIGHTFACE_COLLECTION_MAX_CAPACITY_ROWS |
10000000 |
Collection 最大容量行数 |
INSIGHTFACE_COLLECTION_DEFAULT_MAX_FACES_PER_PERSON |
20 |
每人最多 FaceSample 数 |
INSIGHTFACE_COLLECTION_DEFAULT_LOAD_POLICY |
lazy |
索引加载策略 |
INSIGHTFACE_SEARCH_DEVICE_ID |
0 |
检索使用的 GPU 设备号 |
INSIGHTFACE_SEARCH_TOPK_MODE |
auto |
Top-K 执行模式 |
INSIGHTFACE_SEARCH_BUILD_BATCH_ROWS |
4096 |
索引构建批大小 |
INSIGHTFACE_INFERENCE_MODE / INSIGHTFACE_EXECUTION_PROVIDER |
onnx / CPUExecutionProvider 或 CUDAExecutionProvider |
推理模式与执行提供方,由 Compose 固定 |
CUDA Compose 额外固定了 INSIGHTFACE_STRICT_CUDA: "1"、NVIDIA_VISIBLE_DEVICES: all 与 CUDA_MODULE_LOADING: LAZY,并请求 gpus: all——这就是「严格 CUDA 校验、无静默 CPU 回退」的落点:启动时校验失败即失败,而不是悄悄降级到 CPU。
两个 Compose 都将 config/server.toml 只读绑定到容器内 /etc/insightface/server.toml。该 TOML 在进程启动时读取一次,修改后需重启容器,关键配置段如下:
[inference]
# "auto" 在 CPU 上解析为 4 条并发模型管线,CUDA 上为 8 条;
# 正整数可覆盖默认值。API 调用、注册与 RTSP 帧共享这同一进程级预算。
max_concurrency = "auto"
[detection]
# 每个条目为 [宽, 高]。动态 SCRFD 模型对每个配置分辨率运行,
# 将全部候选映射回原图坐标后,对融合候选集做单次全局 NMS。
input_sizes = [[96, 96], [512, 512]]
# 检测器最低置信度,在融合 NMS 之前施加于 SCRFD 候选。
threshold = 0.50
# 单次全局 NMS 使用的 IoU 阈值。
nms_threshold = 0.40
# 需要单脸的操作使用的选择策略:"largest" 或 "center_largest"。
# 后者最大化像素空间得分 area - 2.0 * squared_distance(脸框中心, 图像中心)。
single_face_selection = "largest"
# 部署级安全上限:请求可以要求更少结果,但不能更多。
max_detected_faces = 100
[web]
# false(默认):提供 Web UI、交互式 API 参考与指南。
# true:纯 API 模式,仅保留 /v1 与 /openapi.json。
disabled = false
这份配置直接解释了原文档的「核心行为」条目:多分辨率检测 + 单次融合 NMS、largest/center_largest 单脸策略、100 张脸的部署级上限,以及 Web UI 可整体关闭的纯 API 模式。
从源码构建镜像
由于 Dockerfile 会复制 server/ 以及 python-package/insightface 中选定的推理模块,完整仓库就是构建上下文(build context 是仓库根目录)。Makefile 中的 build-cpu 与 build-cuda12 目标分别对应 docker/Dockerfile.cpu 与 docker/Dockerfile.cuda12,并将镜像 tag 固定为 0.2.0-cpu / 0.2.0-cuda12。
CPU:
make -C server build-cpu
docker compose -f server/deploy/compose.cpu.yml \
run --rm --pull never models install buffalo_l --accept-license
docker compose -f server/deploy/compose.cpu.yml \
up -d --no-build --pull never
CUDA 12:
make -C server build-cuda12
docker compose -f server/deploy/compose.cuda12.yml \
run --rm --pull never models install buffalo_l --accept-license
docker compose -f server/deploy/compose.cuda12.yml \
up -d --no-build --pull never
--pull never 保证 Compose 使用本地构建的镜像。构建过程仍会下载固定版本的基础镜像与依赖;模型安装则单独下载已接受许可的模型包。Makefile 还提供配套目标:test(单测)、test-api、test-sdk、test-native-cpu(用 CMake/CTest 构建并测试原生检索库)、smoke-test(对 http://127.0.0.1:8080 跑 smoke_test.py)以及 release-preflight(发布前检查)。
原生精确检索层:FP32 / FP16 / BF16 / INT8 的实现契约
性能数字背后是 server/native/search 中定义的产品级 C ABI。该层是整个「INT8 无实质精度损失」结论的技术依据,值得展开:
- 统一的 C ABI(v2):
libifs_search_cpu与libifs_search_cuda从同一个 include/ifs_search.h 导出相同接口,固定为 512 维输入;每个输入向量与查询在越过 ABI 边界前必须有限、FP32 且已 L2 归一化。 - 原始余弦 score 契约:因为输入已归一化,FP32 内积即余弦相似度;FP16/BF16 返回低精度近似值。INT8 采用 profile 编码的逐索引缩放因子(推荐
S=736,兼容旧S=1000),量化与计分公式为:
q = clamp(round_half_away_from_zero(x * S), -128, 127)
score_internal = int32_dot(q_database, q_query) / (S * S)
similarity = clamp(score_internal, -1, 1)
CPU、CUDA 与 NumPy 参考实现刻意都以 FP32 语义执行乘法和 half-away-from-zero 舍入,保证三条路径排序一致;未缩放的 INT32 累加器不会暴露给生产 ABI。
- Profile 矩阵与 fail-closed 语义:
FP32_V1(CPU+CUDA)、FP16_V1(仅 CUDA,CPU 返回IFS_SEARCH_UNSUPPORTED)、BF16_V1(CPU+CUDA,CUDA 侧仅 Ampere/SM80 及以上暴露)、INT8_X736_V1与INT8_X1000_V1(CPU+CUDA)。两种 INT8 缩放因子是相互独立的逐索引契约,可在同一进程共存,旧 x1000 Collection 绝不会被静默重解释为 x736。不存在任何 dtype 或 CPU 回退,CUDA 失败即失败。 - 容量与删除:
reserve_rows在创建时预留连续存储,max_rows是硬性行数上限;CUDA 为精确 Top-K(最多 100)预分配 score、删除工作区与候选缓冲,容量内查询不会触发首次查询的额外分配。CPU 删除复用空闲槽位;CUDA 使用墓碑(tombstone),删除/重加循环会使physical_rows持续增长,因此 Server 必须在墓碑耗尽容量前重建该 Collection 的索引代。 - Person Top-K 的精确分组:ABI v2 接收每个 FaceSample 的稳定数值 group/Person ID 并实现严格分组 Top-K——每张脸得分都参与,每个人保留最高分脸(同分时取最低向量 ID),人与人之间按得分降序、组 ID 升序排列,不使用固定脸级过采样,因此对 Server 的「取 FaceSample 最高分」Person 策略是精确的。CUDA 实现将行到组元数据放在设备端,两阶段 GPU reduction 先找每人最高分再确定性地选出最佳 FaceSample,只有最终 K 条
(group_id, vector_id, score)记录跨越 PCIe。
核心行为语义(部署时必须理解)
- Similarity 是原始余弦值,不是概率。阈值使用
0.0..1.0,默认0.4。 - Collection 固定模型与 embedding 契约:出现分歧时数据仍然可见,但注册/检索返回
collection_model_mismatch。 - 启动检测 profile 会被复制进新 Collection:之后每个 Collection 的 profile 可独立更新,影响后续请求。
- 可选的人脸存储只保存 112×112 bounding-box JPEG 裁剪,不是上传原图,也不是对齐后的识别输入;默认关闭。
- SQLite 提交是权威的:注册/删除的成功响应返回前,索引变更已完成;重启后索引从 SQLite 重建。
- 响应携带
x-request-id;列表 API 使用不透明签名游标分页。
REST API 与 Python SDK
API 主要分组(共 29 个 snake_case 操作):
- 系统:
/v1/health、/v1/system、/v1/models; - 无状态人脸:
/v1/detect、/v1/compare、/v1/embeddings(后者受认证保护); - Collection、Person 与 FaceSample 的 CRUD;
- Collection 内 Person 检索;
- RTSP Monitor 的配置、状态、事件与 preview。
交互式 OpenAPI 始终可用在 /docs;完整参数、响应、错误与示例见 REST API 指南,用户指南见 User Guide。
Python SDK 是轻量的、仅依赖 httpx 的类型化客户端,不含任何推理运行时,接受图像路径、bytes 或二进制文件对象:
python -m pip install ./server/sdk/python
from insightface_server import Client
with Client("http://localhost:18097", api_key=None) as client:
faces = client.detect("photo.jpg")
matches = client.search("employees", "unknown.jpg", limit=5)
SDK 补充要点(见 server/sdk/python/README.md):系统检测 profile 仅在启动时生效,Collection 创建时复制它并可覆盖输入尺寸、检测器/NMS 阈值与单脸策略,无状态 Detect/Compare/Embeddings 调用可传 collection= 使用该 Collection 的 profile;可信上游提取器可传 external_embeddings 与 Collection 的 embedding_contract_id 选择 external_trusted 模式——图像检测与质量审查仍会执行,但服务端不重新提取特征也不回退到其他特征;客户端默认等待上限 65 秒,略长于服务端 60 秒请求时限。
安全要求
人脸图像与 embeddings 是生物特征数据。仓库给出的安全底线:
- 组网部署时启用认证,在可信反向代理上终结 HTTPS;
- 限制 Docker 与卷的访问面(Compose 已内置
read_only根文件系统、非 root 用户10001:10001、cap_drop: [ALL]、no-new-privileges、tmpfs 隔离与pids_limit等加固); - 保持宽泛 CORS 关闭;
- 制定备份、保留期、删除、同意与事件响应策略;
- 不要记录图像、embeddings、RTSP 凭据或 API Keys。
Server 本身不提供内置 TLS、用户账号、RBAC、云 IAM 或法律合规层;部署与安全细节在 用户指南 中。
第一阶段范围边界
当前发布明确不实现:AWS/CompreFace 兼容、CUDA 11、Jetson、ARM64、Windows 容器、TensorRT、Kubernetes、分布式 Workers、持久化 Monitor 事件或录像/NVR、活体检测、deepfake 检测与人口属性识别。规划相关功能时,这一边界是评估前提。
文档体系与许可
- 用户指南 — 安装、配置、模型、Web UI、SDK、GPU、安全、备份与排障;
- REST API 指南 — 全部端点、字段、行为、结果、错误、分页规则与示例;
- Maintainer Guide — 架构、检索内部实现、测试、贡献规范与容器发布策略。
本地化的用户指南与 API 指南 Markdown 同时也是 Web UI Help 页面渲染的同一份源码,只是呈现方式不同。许可方面,唯一入口是 LICENSING.md:Server 源码与 Python SDK 采用 MIT License;该声明不覆盖模型文件、模型权重、数据集或第三方组件。InsightFace 公开预训练模型通常限于非商业研究,商业许可需向 InsightFace 官方申请。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00


