资讯动态

InsightFace ArcFace-Paddle 基于 PaddleServing 的 Pipeline 在线服务部署实战指南

发布时间:2026/9/10 23:24:03 来源:尧图企业网站定制
InsightFace ArcFace-Paddle 基于 PaddleServing 的 Pipeline 在线服务部署实战指南【免费下载链接】insightfaceState-of-the-art 2D and 3D Face Analysis Project项目地址: https://gitcode.com/GitHub_Trending/in/insightface导读本文以 InsightFace 仓库中 recognition/arcface_paddle 子项目为背景完整讲解如何将 PaddlePaddle 训练并导出的 ArcFace / MobileFace 人脸识别动态图模型通过 PaddleServing 框架以 Pipeline 模式部署为可对外提供 HTTP / RPC 预测能力的在线服务。读完本文你将掌握PaddleServing 运行环境server / client / app的安装与版本搭配、inference 模型到 serving 模型的转换命令与目录结构、基于web_service.py config.yml的服务启动与并发调优以及 HTTP / RPC 两种客户端发送识别请求的完整闭环并理解预处理、后处理与性能调优背后的源码实现。1. 背景为什么选择 PaddleServing 部署 ArcFaceArcFace-Paddle 是基于 PaddlePaddle 的深度人脸检测与识别工具包其中人脸识别部分提供了ArcFace与MobileFace两个预训练模型recognition/arcface_paddle/README.md。训练完成或直接下载预训练模型后要落地为可被业务系统高频调用的在线能力就需要一个成熟的服务化部署框架。PaddleServing 正是 PaddlePaddle 生态中的官方服务化部署方案关联文档 recognition/arcface_paddle/deploy/pdserving/README.md 指出其核心优势包括与 Paddle 训练流程无缝衔接绝大多数 Paddle 模型只需一条命令即可完成部署无需为 Serving 单独改造网络结构工业级服务能力支持模型管理、在线加载、在线 A/B 测试等生产特性高并发高效通信客户端与服务端之间支持高并发和高效通信且支持 C、Python、Java 等多种语言开发客户端。本文介绍的 Pipeline 模式是 PaddleServing 的典型用法它以 DAG有向无环图方式组织多个 Op每个 Op 完成一段独立逻辑如人脸识别中的预处理、推理、后处理服务框架自动调度与并发执行。在 ArcFace-Paddle 的部署目录中这一整套可运行代码均位于 recognition/arcface_paddle/deploy/pdserving。2. 环境准备2.1 ArcFace 运行环境首先需要准备好 ArcFace 的运行环境参考 recognition/arcface_paddle/README.md 中的安装指引完成 PaddlePaddle 环境搭建。文档特别提示根据自身环境下载对应的 paddle whl 包推荐安装 2.2 版本。该环境既用于训练 / 导出模型也用于后续paddle_serving_client.convert模型转换操作。2.2 PaddleServing 运行环境PaddleServing 部署需要安装三个组件文档给出的版本组合如下① 安装 serving用于启动服务端pip3 install paddle-serving-server0.6.3 # for CPU pip3 install paddle-serving-server-gpu0.6.3 # for GPU # 其他 GPU 环境需先确认环境再选择执行如下命令 pip3 install paddle-serving-server-gpu0.6.3.post101 # GPU with CUDA10.1 TensorRT6 pip3 install paddle-serving-server-gpu0.6.3.post11 # GPU with CUDA11 TensorRT7② 安装 client用于向服务发送请求pip3 install paddle-serving-client0.6.3③ 安装 serving-appPipeline 模式依赖的应用层组件pip3 install paddle-serving-app0.6.3注意paddle-serving-app是 Pipeline 服务开发web_service.py、pipeline_http_client.py等所必需的依赖包。如需安装最新版本 PaddleServing请参考官方 LATEST_PACKAGES 文档按 Python 版本选择对应 client 安装包中文版 READMEREADME_CN.md中 client 安装写法为paddle_serving_client0.6.3与英文版等价。2.3 环境验证要点从源码看pipeline_rpc_client.py 在导入时会先尝试from paddle_serving_server_gpu.pipeline import PipelineClient失败再回退到from paddle_serving_server.pipeline import PipelineClient这说明 GPU 版与 CPU 版 serving 包在 API 上是兼容的安装哪一个取决于你的硬件环境。3. 模型转换从 inference 模型到 serving 模型3.1 获取 ArcFace 推理模型PaddleServing 部署前需要把已保存的 inference 模型转换为 Serving 易于部署的模型格式。首先下载 ArcFace 的 inference 模型此处为 128 维特征、MobileFaceNet 骨干的mobileface_v1.0_inferwget -nc -P ./inference https://paddle-model-ecology.bj.bcebos.com/model/insight-face/mobileface_v1.0_infer.tar tar xf inference/mobileface_v1.0_infer.tar --strip-components 1 -C inference3.2 执行转换命令使用已安装的paddle_serving_client工具将 inference 模型转换为 server / client 两套文件python3 -m paddle_serving_client.convert --dirname ./inference/ \ --model_filename inference.pdmodel \ --params_filename inference.pdiparams \ --serving_server ./MobileFaceNet_128_serving/ \ --serving_client ./MobileFaceNet_128_client/参数说明参数含义--dirnameinference 模型所在目录上一步下载解压后的./inference/--model_filename模型结构文件名inference.pdmodel--params_filename模型参数文件名inference.pdiparams--serving_server转换后服务端模型输出目录--serving_client转换后客户端配置输出目录3.3 转换产物结构转换完成后当前目录下会多出两个文件夹格式如下MobileFaceNet_128_serving ├── __model__ ├── __params__ ├── serving_server_conf.prototxt └── serving_server_conf.stream.prototxt MobileFaceNet_128_client/ ├── serving_client_conf.prototxt └── serving_client_conf.stream.prototxtserving_server_conf.prototxt记录了模型输入输出的 tensor 名称与 shape服务端启动时据此完成 feed / fetch 绑定serving_client_conf.prototxt供客户端对齐请求字段。MobileFaceNet_128_serving正是后续 config.yml 中model_config指向的路径./MobileFaceNet_128_serving。3.4 从训练产物到 inference 模型的完整链路需要说明的是上述mobileface_v1.0_infer.tar对应 MobileFaceNet 骨干、128 维特征MobileFaceNet_128的预训练推理模型。若你想用自己的训练权重导出 inference 模型可参考 scripts/export_dynamic.sh 中的tools/export.py调用方式核心参数包括--backbone、--embedding_size、--checkpoint_dir与--output_dir。从源码实现dynamic/export.py看导出时会将 checkpoint 权重加载进 backbone然后通过paddle.jit.save默认或paddle.onnx.export--export_type onnx时保存并显式声明输入规格paddle.jit.save( backbone, path, input_spec[ paddle.static.InputSpec( shape[None, 3, 112, 112], dtypefloat32) ])即模型输入为[N, 3, 112, 112]的 float32 图像张量。这也与 pipeline_http_client.py 服务端预处理中把图片cv2.resize到(112, 112)、转(2, 0, 1)通道序并expand_dims加 batch 维的逻辑一一对应。MobileFaceNet_128的网络定义在 dynamic/backbones/mobilefacenet.pyfeature_dim128最终通过linear1输出 128 维特征并 reshape 为[batch, 128]。4. Paddle Serving Pipeline 部署4.1 获取部署代码与目录结构若尚未下载 insightface 代码先克隆仓库并进入工作目录git clone https://github.com/deepinsight/insightface cd recognition/arcface_paddle/deploy/pdservingpdserving目录包含了启动 Pipeline 服务与发送预测请求的完整代码__init__.py config.yml # 启动服务的配置文件 pipeline_http_client.py # web 方式发送 pipeline 预测请求的脚本 pipeline_rpc_client.py # rpc 方式发送 pipeline 预测请求的脚本 web_service.py # 启动 pipeline 服务端的脚本说明关联文档正文仅提及 4 个文件而仓库中实际还包含pipeline_rpc_client.pyRPC 客户端以及imgs/下的测试图片与运行截图本文一并覆盖。4.2 服务端实现解析web_service.pyweb_service.py 是整个 Pipeline 服务的入口代码量不长但结构清晰from paddle_serving_server.web_service import WebService, Op import numpy as np import cv2 import base64 class ArcFaceOp(Op): def init_op(self): pass def preprocess(self, input_dicts, data_id, log_id): (_, input_dict), input_dicts.items() data base64.b64decode(input_dict[image]) data np.frombuffer(data, np.uint8) img cv2.imdecode(data, cv2.IMREAD_COLOR) img cv2.resize(img, (112, 112)) # normalize to mean 0.5, std 0.5 img (img - 127.5) * 0.00784313725 # BGR2RGB img img[:, :, ::-1] img img.transpose((2, 0, 1)) img np.expand_dims(img, 0) img img.astype(float32) return {x: img.copy()}, False, None, def postprocess(self, input_dicts, fetch_dict, log_id): out fetch_dict[save_infer_model/scale_0.tmp_1] out_dict {out: out} return out_dict, None, class ArcFaceService(WebService): def get_pipeline_response(self, read_op): arcface_op ArcFaceOp(nameArcFace, input_ops[read_op]) return arcface_op arcface_service ArcFaceService(nameArcFace) arcface_service.prepare_pipeline_config(config.yml) arcface_service.run_service()关键点逐一解读Op 三阶段生命周期init_op初始化、preprocess预处理、postprocess后处理这是 PaddleServing Pipeline Op 的标准接口预处理细节客户端传来的图片是 base64 编码字节流服务端先base64.b64decode还原为字节再np.frombuffercv2.imdecode解码为 BGR 图像然后缩放到112×112与模型输入规格一致执行(img - 127.5) * 0.00784313725归一化等价于 mean0.5、std0.5 的标准化再 BGR→RGB、(H,W,C)→(C,H,W)、expand_dims增加 batch 维、转 float32最终以键名x送入模型fetch 输出绑定postprocess从fetch_dict中取save_infer_model/scale_0.tmp_1该名字正是 config.yml 中fetch_list配置的 alias_name二者必须保持一致DAG 组装get_pipeline_response将ArcFaceOp挂在read_op之后形成读取请求 → ArcFace 推理的单节点 DAG启动流程prepare_pipeline_config(config.yml)加载并发/端口等配置run_service()正式拉起服务。4.3 配置文件详解config.ymlconfig.yml 是服务调优的核心完整内容及注释如下# rpc端口, rpc_port和http_port不允许同时为空。当rpc_port为空且http_port不为空时会自动将rpc_port设置为http_port1 rpc_port: 18091 # http端口, rpc_port和http_port不允许同时为空。当rpc_port可用且http_port为空时不自动生成http_port http_port: 9998 # worker_num, 最大并发数。当build_dag_each_workerTrue时, 框架会创建worker_num个进程每个进程内构建grpcServer和DAG # 当build_dag_each_workerFalse时框架会设置主线程grpc线程池的max_workersworker_num worker_num: 10 # build_dag_each_worker, False框架在进程内创建一条DAGTrue框架会每个进程内创建多个独立的DAG build_dag_each_worker: False dag: # op资源类型, True, 为线程模型False为进程模型 is_thread_op: False # 重试次数 retry: 10 # 使用性能分析, True生成Timeline性能数据对性能有一定影响False为不使用 use_profile: True tracer: interval_s: 10 op: ArcFace: # 并发数is_thread_opTrue时为线程并发否则为进程并发 concurrency: 8 # 当op配置没有server_endpoints时从local_service_conf读取本地服务配置 local_service_conf: # client类型包括brpc, grpc和local_predictor。local_predictor不启动Serving服务进程内预测 client_type: local_predictor # 模型路径 model_config: ./MobileFaceNet_128_serving # Fetch结果列表以client_config中fetch_var的alias_name为准 fetch_list: [save_infer_model/scale_0.tmp_1] # 计算硬件ID当devices为或不写时为CPU预测当devices为0, 0,1,2时为GPU预测表示使用的GPU卡 devices: 0 ir_optim: True参数调优要点rpc_port/http_port服务同时暴露 RPC18091与 HTTP9998两个端口且两者不允许同时为空RPC 客户端pipeline_rpc_client.py连127.0.0.1:18091HTTP 客户端pipeline_http_client.py请求http://127.0.0.1:9998/ArcFace/predictionworker_num最大并发 worker 数build_dag_each_workerFalse时决定主线程 grpc 线程池的max_workersdag.is_thread_opTrue为线程并发模型False为进程并发模型直接影响资源占用与隔离性op.ArcFace.concurrencyOp 级并发数是吞吐调优最直接的旋钮详见 4.5 节local_service_conf.client_type: local_predictor这是本部署的精髓——不额外拉起独立 Serving 服务进程而是在服务进程内直接做本地推理进程内预测减少一次网络往返提升延迟表现devices: 0指定使用 GPU 0 进行预测留空或删除该字段则为 CPU 预测ir_optim: True开启 Paddle 计算图 IR 优化可进一步提升推理效率。4.4 启动服务与发送请求① 启动服务# 启动服务运行日志保存在 log.txt python3 web_service.py log.txt 服务成功启动后log.txt中会打印类似如下的日志实际运行截图见 recognition/arcface_paddle/deploy/pdserving/imgs/start_server.pngPaddleServing 服务启动日志② 发送 HTTP 预测请求python3 pipeline_http_client.pypipeline_http_client.py 的实现逻辑是遍历--image_dir默认./imgs下的所有图片将每张图片读取为字节后 base64 编码以{key: [image], value: [image]}的 JSON 结构 POST 到http://127.0.0.1:9998/ArcFace/prediction并打印服务端返回的 JSON结束时输出测试图片总数。运行成功后在命令行窗口会打印模型预测结果示例输出见 recognition/arcface_paddle/deploy/pdserving/imgs/results.pngArcFace 识别预测结果输出③ 可选RPC 方式发送请求仓库还提供了 RPC 客户端 pipeline_rpc_client.py通过PipelineClient().connect([127.0.0.1:18091])连接 RPC 端口再用client.predict(feed_dict{image: image}, fetch[res])发送预测。两种客户端 feed 的键名都是image与服务端preprocess中读取的input_dict[image]严格对应。4.5 并发调优与性能观测调整 config.yml 中的并发个数可以获得最大 QPS。关联文档给出的经验法则是检测和识别的并发数比例一般为 2:1若同时部署检测 识别两段 Opdet: concurrency: 8 ... rec: concurrency: 4 ...在本仓库的单 Op仅 ArcFace 识别场景下对应的调优写法是op: ArcFace: concurrency: 8 ...有需要时也可以同时发送多个服务请求来压测并发能力。预测性能数据会被自动写入PipelineServingLogs/pipeline.tracer文件无需额外埋点。关联文档记录的基准测试在 700 张真实图片上、V100 GPU 上运行平均 QPS 约为 57pipeline.tracer中记录的典型输出如下2021-11-04 13:38:52,507 Op(ArcFace): 2021-11-04 13:38:52,507 in[135.4579597902098 ms] 2021-11-04 13:38:52,507 prep[0.9921311188811189 ms] 2021-11-04 13:38:52,507 midp[3.9232132867132865 ms] 2021-11-04 13:38:52,507 postp[0.12166258741258741 ms] 2021-11-04 13:38:52,507 out[0.9898286713286714 ms] 2021-11-04 13:38:52,508 idle[0.9643989520087675] 2021-11-04 13:38:52,508 DAGExecutor: 2021-11-04 13:38:52,508 Query count[573] 2021-11-04 13:38:52,508 QPS[57.3 q/s] 2021-11-04 13:38:52,509 Succ[0.9982547993019197] 2021-11-04 13:38:52,509 Error req[394] 2021-11-04 13:38:52,509 Latency: 2021-11-04 13:38:52,509 ave[11.52941186736475 ms] 2021-11-04 13:38:52,509 .50[11.492 ms] 2021-11-04 13:38:52,509 .60[11.658 ms] 2021-11-04 13:38:52,509 .70[11.95 ms] 2021-11-04 13:38:52,509 .80[12.251 ms] 2021-11-04 13:38:52,509 .90[12.736 ms] 2021-11-04 13:38:52,509 .95[13.21 ms] 2021-11-04 13:38:52,509 .99[13.987 ms] 2021-11-04 13:38:52,510 Channel (server worker num[10]): 2021-11-04 13:38:52,510 chl0(In: [DAGExecutor], Out: [ArcFace]) size[0/0] 2021-11-04 13:38:52,510 chl1(In: [ArcFace], Out: [DAGExecutor]) size[0/0]如何读懂这份日志Op(ArcFace)时间分解in输入接收135.46ms、prep预处理约 0.99ms、midp模型推理约 3.92ms、postp后处理约 0.12ms、out输出约 0.99ms。可以看到推理midp与输入接收in是耗时主体预处理/后处理开销极小这与local_predictor进程内推理、预处理仅包含 resize 归一化的实现相符DAGExecutor汇总Query count为累计查询数QPS为吞吐Succ为成功率0.9983Latency给出平均与各分位延迟ave 约 11.5msP99 约 13.99msChannel队列状态size[0/0]表示当前 DAG 通道无积压服务处于健康状态。注意上述性能数据是文档作者在特定软硬件环境700 张真实图片、单张 V100 GPU、2021-11-04下的实测记录不同机器、不同并发配置、不同图片尺寸下结果会有差异应作为调优参考而非绝对指标。5. 常见问题FAQQ1发送请求后没有结果返回或提示输出解码报错。A1启动服务和发送请求时不要设置代理。在启动服务前和发送请求前关闭代理即可关闭命令unset https_proxy unset http_proxy该问题在英文版与中文版 READMEREADME.md / README_CN.md中均有记录。从实践看代理会干扰本机 HTTP9998 端口与 RPC18091 端口的本地回环通信导致请求超时或响应体解析失败。6. 部署链路全景回顾至此一条完整的训练 → 导出 → 转换 → 服务化 → 请求链路已经打通训练基于 recognition/arcface_paddle 的tools/train.py训练得到 checkpoint导出通过 dynamic/export.py或 scripts/export_dynamic.sh导出输入为[N,3,112,112]的 inference 模型也可以直接使用文档提供的mobileface_v1.0_infer.tar预训练推理模型转换用python3 -m paddle_serving_client.convert生成MobileFaceNet_128_serving/与MobileFaceNet_128_client/服务化python3 web_service.py读取 config.yml以local_predictor进程内推理方式在 9998HTTP/ 18091RPC端口提供 ArcFace 识别能力调用pipeline_http_client.py或pipeline_rpc_client.py以 base64 图像发起请求获得 128 维人脸特征向量fetch_list中的save_infer_model/scale_0.tmp_1可作为后续人脸比对、检索、聚类等业务的上游输入。该部署方案与 ArcFace-Paddle 主仓库 READMErecognition/arcface_paddle/README.md中检测 识别的离线推理流程tools/test_recognition.py --det --rec互补前者面向在线高并发服务后者面向单机离线分析如需端到端的人脸检测 识别在线服务可将 BlazeFace 检测模型与本文的 ArcFace 识别 Op 组合进同一条 Pipeline DAG并按 2:1 的比例配置检测与识别 Op 的并发数。【免费下载链接】insightfaceState-of-the-art 2D and 3D Face Analysis Project项目地址: https://gitcode.com/GitHub_Trending/in/insightface创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价