案例 4:掌纹识别
案例 4:掌纹识别
案例目标
本案例在 Ascend 310B4 / 8T 开发板上运行 FastAPI + React 掌纹识别工作台。生产推理固定使用 NPU mixed_fp16;CPU、EDCC、origin 和离线候选比较不进入在线接口。
本版本是冻结的人工测试发布。CCNet 为默认/回滚模型;manual_test profile 可逐一测试五个 CompNet。五个 CompNet 的状态为 manual_test_pending,不能把人工测试前的状态写成稳定验收通过。
手动环境
在开发板同一个 shell 中执行:
source /usr/local/miniconda3/etc/profile.d/conda.sh
conda activate ascend
export PYTHONNOUSERSITE=1
source /usr/local/Ascend/ascend-toolkit/set_env.sh
cd <release-root>
export PALMPRINT_ROOT="$PWD"
export ACL_PYTHON_SITE=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages
export PYTHONPATH="$PALMPRINT_ROOT:$ACL_PYTHON_SITE${PYTHONPATH:+:$PYTHONPATH}"
export PALMPRINT_PROFILE=manual_test
unset PALMPRINT_REQUIRE_TEMPLATE_ENCRYPTION
unset PALMPRINT_TEMPLATE_KEY_FILE
unset PALMPRINT_TEMPLATE_DIR
python -c "import sys, acl; print(sys.executable); print(acl.__file__)"
python -m palmprint_workbench.tools.verify_assets --strict
python -m palmprint_workbench.api --host 0.0.0.0 --port 7860源码不会自动安装依赖、下载数据、构建 EDCC、转换模型或修改系统环境。OM 从固定来源取得后,必须按 om_manifest.json 核对字节数和 SHA-256。
API 和界面
启动后检查 /api/health、/api/bootstrap、/api/candidates 和 /。manual_test profile 的 bootstrap 应返回 CCNet 与五个 canonical CompNet,均为 npu/mixed_fp16。
触摸屏逐页检查:系统状态、上传识别、模板注册、候选审计。测试 1280×720、1024×768 和 375×812;按钮不重叠,状态文本不溢出,API 不可用时显示空服务状态。
六模型人工测试
canonical ID 为:
ccnetcompnet_tongji_600compnet_iitd_460compnet_rest_358compnet_xjtu_flash_200compnet_xjtu_natural_200
每个模型执行:上传合成 ROI 或匿名测试图、识别、注册三个模板、查询、命中识别、删除、重启后再查询。模板 namespace 固定为 <model_id>__npu__mixed_fp16。
每次记录模型 ID、OM SHA、请求时间、HTTP 状态、模型耗时、模板状态和服务 PID。当前内测版本会把用户主动触发的原图、ROI 和 JSON 索引自动保存到发行目录的 data/captures/,把明文 PWST1 embedding 模板保存到 data/templates/;连续预览帧不保存。删除模板不会删除图片证据。真实掌纹图像、姓名、embedding 和完整报告不得进入源码或截图,也不得同步到 GitHub/HF。
查看和清理内测图片由操作者手动执行:
find "$PALMPRINT_ROOT/data/captures" -type f
rm -rf "$PALMPRINT_ROOT/data/captures"
rm -rf "$PALMPRINT_ROOT/data/templates"摄像头测试
先检查 /api/cameras,优先选择 1280×720 MJPG。连续预览 100 帧,记录首帧时间、稳定帧间隔和实际输出尺寸;拍照识别后关闭预览,确认设备释放,再重新打开一次。若画面滞后,先降低预览分辨率并确认没有其他进程占用设备。
常见问题
| 现象 | 处理 |
|---|---|
import acl 失败 | 重新加载同一 shell 的 conda/CANN,确认 Python 和 acl.__file__ 来自同一环境 |
| 模型不在列表 | 确认 PALMPRINT_PROFILE=manual_test、registry、OM SHA 和 bootstrap |
| 模板不存在 | 确认注册和识别使用同一模型、精度和当前发行目录的 data/templates |
| 模板文件损坏 | 停止服务,备份 data/templates,再使用 .pstore.bak/.previous 恢复 |
| 摄像头卡顿 | 检查 MJPG、实际分辨率和设备占用,先使用 960×540 或 1280×720 |
| 服务健康但识别失败 | 执行真实上传或摄像头 smoke;health 不主动加载 NPU |
| ACL 异常退出、设备 reset 或进程意外退出 | 停止测试,保存时间/PID/模型/摘要,重启当前版本或回退 CCNet;不要升级版本 |
Health: Alarm | 只记录设备状态,不单独判断模型或程序结果 |
板端实测记录(2026-10-18 复测)
本节记录 8T(Ascend310B4)上摄像头问题的定位与复测结果。原始枚举、取帧与识别输出保存在 docs/case-board-runs-20261018/case4/。
摄像头在 8T 上失效的原因
失效原因不是模型或 API,而是设备编号漂移。/dev/videoN 的编号会随上电与插拔顺序变化,而默认设备固定为 /dev/video0:
| 2026-10-17 记录 | 2026-10-18 复测 | |
|---|---|---|
| USB 摄像头 | /dev/video2 | /dev/video0、/dev/video1 |
| ISP 虚拟节点 | /dev/video0 | /dev/video2、/dev/video3 |
两个节点的能力完全不同:
| 节点 | 驱动 | 像素格式 | 能否出帧 |
|---|---|---|---|
/dev/video0 | uvcvideo(USB Composite Device) | MJPG 1920×1080@25fps | 是 |
/dev/video2 | vin-media(vin-media_mainpath) | 宽度/高度 0×0,像素格式为空 | 否 |
上次运行时默认设备正好指向 ISP 节点,因此页面预览必然失败。
修复
设备发现原先只检查 VIDIOC_QUERYCAP 的能力位,而 ISP 节点也声明 VIDEO_CAPTURE_MPLANE,于是被误认为摄像头。现在在能力位检查之后追加 VIDIOC_G_FMT,要求宽度与高度都大于 0,0×0 的 ISP 节点不再进入候选列表。修改位于 samples/case4/palmprint_workbench/runtime/camera.py,并补充了对应单元测试。
复测结果
环境:Ascend310B4 / 8T,CANN 8.0.0,驱动 25.2.0,Python 3.9.2,Health Alarm(已知状态,不作为失败判据)。
| 项目 | 结果 |
|---|---|
/api/health | status=ok、runtime_importable=true、model_ready=true、admitted_model_ids=["ccnet"] |
| 模型资产 | ONNX 与 OM 的字节数和 SHA-256 均匹配 |
/dev/video0 取帧 | HTTP 200,50 348 字节 JPEG,1280×720,0.46 s |
/dev/video2 取帧 | HTTP 503,returned no frame |
| 识别链路 | ROI 29.70 ms、预处理 3.30 ms、模型 45.85 ms、检索 0.90 ms |
| NPU 显存 | 推理前 2039 MB,推理后 3302 MB |
识别请求返回 outcome=no_templates:模板库为空,因此链路走通但没有可匹配对象,不能记录为身份匹配成功。
证据等级:摄像头枚举、取帧、健康检查、模型加载、ROI 与 NPU 推理计时的结果为 observed-pass;/dev/video2、/dev/video3 取帧失败为 observed-fail。 本轮未验证:模板注册与身份匹配、EER/Rank-1 等识别指标、长时间稳定性、硬件触发与补光。
版本冻结
人工测试期间不升级 Python、依赖、驱动、CANN 或应用版本。发现问题时停止当前模型、记录复现步骤、回退 CCNet,并在人工测试结束后单独规划下一版本。人工测试通过后,再更新准入证据、release manifest、版本号和完整验收记录。
全候选模型测试
工作台运行通道只保留六个已有 OM 且契约可验证的 NPU embedding。候选清单仍保留完整 28 项审计记录;其余 22 个分类器、ROI、掌静脉、EDCC、SDK 或缺少可复现资产的项目已从 API/UI 候选矩阵归档,不会被服务加载,也不能被强制转换成掌纹 512 维 embedding。
在源码环境中执行静态审计:
python -m tools.offline.candidate_campaign inventory --all
python -m tools.offline.candidate_campaign local --all
python -m tools.offline.candidate_campaign report --all当前板端地址是 192.168.8.178。在板端激活 conda/CANN 后,对已有 OM 的候选逐一执行:
python tools/board/collect_npu_trace.py --label <candidate-id> --interval 1 -- \
python -m tools.offline.candidate_campaign board \
--candidate <candidate-id> --image <roi-image>
python tools/board/acl_lifecycle_probe.py --model <candidate-id> \
--image <roi-image> --cycles 10每项记录来源 revision、许可、资产字节数/SHA、输入输出契约、实际 backend、耗时、退出码、温度、功耗、内存、大页、dmesg 和生命周期。139、err_ret=-512、设备 reset、LPM/AICore/RAS 增量或清理失败会阻断该项;缺权重、不可复现来源或闭源 SDK 则记录为 blocked_* 或 not_applicable,不是“测试通过”。完整日志留在板端私有目录,源码只提交脱敏状态和哈希。
