首页
/ Immich 机器学习硬件加速实战:GPU/NPU 加速智能搜索与人脸识别全指南

Immich 机器学习硬件加速实战:GPU/NPU 加速智能搜索与人脸识别全指南

2026-09-05 16:46:41作者:裘晴惠Vivianne

Immich 的智能搜索(Smart Search)、人脸识别和 OCR 等任务默认运行在 CPU 上,耗时较长且占用大量算力。官方通过 immich-machine-learning 容器的后端变体(CUDA、ROCm、OpenVINO、ARM NN、RKNN)让这些推理任务下沉到 GPU 或 NPU,显著降低 CPU 负载。读完本文,你将能够:为自己的硬件选型并配置合适的加速后端、正确修改 docker-compose.yml、在多 GPU 环境下分配设备,并理解 ML 服务选择推理后端的源码级原理。

功能概览与适用边界

该功能允许使用 GPU 加速机器学习任务(智能搜索、人脸识别等),同时降低 CPU 负载。由于仍属实验性功能,可能无法在所有系统上正常工作,配置前请先阅读下述限制。

一个重要的事实是:启用硬件加速后,无需重跑任何已有的机器学习任务。加速设备会用于启用之后运行的所有新任务,已完成的向量与人脸数据保持有效。

限制条件(摘自官方文档)

  • 文中指令与配置针对 Docker Compose;其他容器引擎可能需要不同的配置方式;
  • 仅支持 Linux 与 Windows(通过 WSL2)服务器;
  • ARM NN 仅支持配备 Mali GPU 的设备,其他 Arm 设备不支持;
  • 某些模型可能与特定后端不兼容,其中 CUDA 的兼容性最可靠;
  • ARM NN 受模型兼容性问题影响,无法加速搜索(Search)延迟,但智能搜索的批处理任务可以使用 ARM NN。

支持的推理后端

后端 目标硬件 底层运行时
ARM NN 搭载 Mali GPU 的 Arm 设备 ARM NN / libmali
CUDA 计算能力(compute capability)≥ 5.2 的 NVIDIA GPU ONNX Runtime CUDAExecutionProvider
ROCm AMD GPU(MIGraphX) ONNX Runtime MIGraphXExecutionProvider
OpenVINO Intel GPU(Iris Xe、Arc 等) ONNX Runtime OpenVINOExecutionProvider
RKNN Rockchip SoC(RK3566/3568/3576/3588) RKNN NPU 运行时

从源码看,ONNX Runtime 路径的候选执行提供方在 constants.py 中按优先级顺序定义:

SUPPORTED_PROVIDERS = [
    "CUDAExecutionProvider",
    "MIGraphXExecutionProvider",
    "OpenVINOExecutionProvider",
    "CoreMLExecutionProvider",
    "CPUExecutionProvider",
]

服务启动时会比对 ort.get_available_providers() 与该列表,只保留当前镜像中实际可用的提供方(见 ort.py)。也就是说,cpu 镜像只有 CPUExecutionProvider,而 -cuda 镜像才会出现 CUDAExecutionProvider——这解释了为什么启用加速必须更换镜像 tag。

各后端的前置条件

ARM NN(Mali GPU)

  • 确保已安装正确的 Linux 内核驱动(通常设备厂商的 Linux 镜像已预装);
  • 宿主机上必须存在 /dev/mali0,可用 ls /dev 确认;
  • 必须有闭源的 libmali.so 固件(可能还需要额外的固件文件),获取方式取决于设备与厂商;
  • hwaccel.ml.yml 中假定 libmali.so 位于 /usr/lib/libmali.so、额外固件位于 /lib/firmware/mali_csffw.bin,路径不同请相应修改;
  • 可选:在 .env 中配置 ARM NN 相关变量,特别是 MACHINE_LEARNING_ANN_FP16_TURBO——它以非常轻微的精度损失换取显著的性能提升(默认值 False,见 config.py)。

CUDA(NVIDIA)

  • GPU 计算能力 ≥ 5.2;
  • 服务器必须安装官方 NVIDIA 驱动,且驱动版本 ≥ 545(需支持 CUDA 12.3);
  • Linux(WSL2 除外)还需安装 NVIDIA Container Toolkit。

ROCm(AMD)

  • Linux 下需安装 AMDGPU 驱动模块;若启用 Secure Boot,需将 DKMS 签名密钥注册进 UEFI BIOS;
  • GPU 需被 ROCm 支持。若官方未支持,可尝试环境变量 HSA_OVERRIDE_GFX_VERSION=<受支持的版本,如 10.3.0>;若仍不行,可能还需设置 HSA_USE_SVM=0
  • ROCm 镜像体积较大,至少需要 35 GiB 空闲磁盘空间。后续通过 Docker 拉取更新一般只有几百 MB,其余层会被缓存;
  • 该后端较新,可能出现问题。例如推理结束后(即使 ML 服务空闲)GPU 功耗可能高于常态,需空闲约 5 分钟后恢复正常——该时间由 MACHINE_LEARNING_MODEL_TTL(默认 300 秒)控制,对应源码中的 model_ttl 设置
  • MIGraphX 会在运行时编译模型,因此前几次推理会比较慢。源码中可以看到针对 MIGraphX 的特殊处理:首次对某一输入签名推理时会加锁编译并缓存,且自动创建模型缓存目录 migraphxort.py#L136-L144

OpenVINO(Intel)

  • 集显比独显更容易出问题,尤其是老处理器或内存较小的服务器;
  • 确保服务器内核版本足够新,能够使用设备做硬件加速;
  • 相比纯 CPU 处理,OpenVINO 会带来更高的内存占用。

从源码看,OpenVINO 提供方会枚举可用设备,优先选择 GPU.<device_id>,找不到 GPU 时回退到 CPU,并使用 MACHINE_LEARNING_OPENVINO_PRECISION(默认 FP32)作为推理精度(ort.py#L145-L159)。

OpenVINO-WSL(Windows)

  • 确认容器能访问 /dev/dri,可执行 docker exec -t immich_machine_learning ls -la /dev/dri 验证;
  • 若不能,在 WSL 宿主机上运行 getent group rendergetent group video 查询组 ID,并将这些组加入 hwaccel.ml.ymlopenvino-wsl 段:
openvino-wsl:
  devices:
    - /dev/dri:/dev/dri
    - /dev/dxg:/dev/dxg
  volumes:
    - /dev/bus/usb:/dev/bus/usb
    - /usr/lib/wsl:/usr/lib/wsl
  group_add:
    - 44    # 替换为 getent group video 查到的组 ID
    - 992   # 替换为 getent group render 查到的组 ID

仓库中 hwaccel.ml.ymlopenvino-wsl 段即该配置的基础,group_add 需按上一步查询结果自行补充。

RKNN(Rockchip NPU)

  • 必须是受支持的 Rockchip SoC:目前仅 RK3566、RK3568、RK3576、RK3588(该清单与源码中 RKNN_SUPPORTED_SOCS 完全一致);
  • 确保已安装正确的 Linux 内核驱动(厂商镜像通常预装);
  • 宿主机需有 RKNPU 驱动 V0.9.8 或更高版本,可用 cat /sys/kernel/debug/rknpu/version 确认;
  • 可选:在 .env 中配置 RKNN 相关变量。特别是将 MACHINE_LEARNING_RKNN_THREADS 设为 2 或 3,相比默认值 1 可大幅提升 RK3576/RK3588 的性能,代价是每个模型占用的内存按倍数增加(默认值 1,见 config.py)。

RKNN 推理路径独立于 ONNX Runtime:RknnSession 会按 rknn_threads 创建线程池执行 rknn_lite.inference,并在可用时按 SoC 名称缓存模型(rknpu/<soc_name> 前缀)。

配置步骤(Docker Compose 方式)

  1. 若尚未拥有 hwaccel.ml.yml,请下载最新版本(仓库中随发行版分发该文件),并确保它与 docker-compose.yml 位于同一目录;
  2. docker-compose.ymlimmich-machine-learning 服务中,将 image 标签末尾加上 -[armnn, cuda, rocm, openvino, rknn] 之一;
  3. 仍在 immich-machine-learning 服务下,取消注释 extends 段,并把 cpu 改为对应后端(WSL2 下按需使用 -wsl 变体);
  4. 用更新后的配置重新部署 immich-machine-learning 容器。

仓库中的 docker-compose.yml 已预置了注释好的模板:

immich-machine-learning:
  container_name: immich_machine_learning
  # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
  # Example tag: ${IMMICH_VERSION:-release}-cuda
  image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
  # extends: # uncomment this section for hardware acceleration
  #   file: hwaccel.ml.yml
  #   service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn]
  volumes:
    - model-cache:/cache
  env_file:
    - .env
  restart: always

extends 引用的 hwaccel.ml.yml 为每个后端定义了最小设备映射,例如:

services:
  cuda:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu

  rocm:
    group_add:
      - video
    devices:
      - /dev/dri:/dev/dri
      - /dev/kfd:/dev/kfd

  rknn:
    security_opt:
      - systempaths=unconfined
      - apparmor=unconfined
    devices:
      - /dev/dri:/dev/dri

  armnn:
    devices:
      - /dev/mali0:/dev/mali0
    volumes:
      - /lib/firmware/mali_csffw.bin:/lib/firmware/mali_csffw.bin:ro
      - /usr/lib/libmali.so:/usr/lib/libmali.so:ro

注意 RKNN 段使用了 security_opt: unconfined——因为容器需要直接访问 /dev/dri 下的 NPU 节点并调用厂商驱动,默认安全策略会阻止。

单一 Compose 文件(Unraid / Portainer 等)

部分平台(包括 Unraid 和 Portainer)不支持多个 Compose 文件。替代做法是把 hwaccel.ml.yml 中对应后端的内容内联immich-machine-learning 服务。例如 cuda 段是:

deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: 1
          capabilities:
            - gpu

合并后的完整服务(不再使用 extends):

immich-machine-learning:
  container_name: immich_machine_learning
  # 注意末尾的 -cuda
  image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
  # 注意此处没有 extends 段
  deploy:
    resources:
      reservations:
        devices:
          - driver: nvidia
            count: 1
            capabilities:
              - gpu
  volumes:
    - model-cache:/cache
  env_file:
    - .env
  restart: always

完成后重新部署 immich-machine-learning 容器即可。

多 GPU 配置

要使用多块 NVIDIA 或 Intel GPU,将 MACHINE_LEARNING_DEVICE_IDS 设为逗号分隔的设备 ID 列表,并把 MACHINE_LEARNING_WORKERS 设为与设备数一致。可用 nvidia-smi -Lglxinfo -B 查看当前设备及 ID:

MACHINE_LEARNING_DEVICE_IDS=0,1
MACHINE_LEARNING_WORKERS=2

此时 ML 服务会启动两个 worker:一个把模型分配到设备 0,另一个分配到设备 1,不同请求由其中一个 worker 处理。

从源码看,设备分配发生在 gunicorn_conf.py:gunicorn 按 worker 序号对设备列表取模(round-robin),把 MACHINE_LEARNING_DEVICE_ID 注入每个 worker 的环境;随后 CUDA/MIGraphX/OpenVINO 的提供方选项都读取该 device_idort.py#L135ort.py#L141)。这解释了 environment-variables.md 中“每个 worker 轮询分配一块设备、且必须 MACHINE_LEARNING_WORKERS > 1”的说明。

这一机制也可以用来固定使用某块特定设备:例如 MACHINE_LEARNING_DEVICE_IDS=1 会确保始终使用设备 1 而非设备 0。

需要注意:

  • 要提高整体利用率、更高效地在多 GPU 间分布负载,应同步提高任务并发度(job concurrency);
  • 每块 GPU 都必须能独立加载全部模型——不能把一个模型拆分到多块 VRAM 不足的 GPU 上,也不能把某个特定模型指定到某块 GPU。

确认设备被识别与使用

可以通过多种方式验证加速设备已生效:

  1. 观察利用率:NVIDIA 与 Intel 可用 nvtop,Intel 可用 intel_gpu_top,AMD 可用 radeontop
  2. 查看容器日志:当智能搜索或人脸检测任务开始,或在 Immich 中进行文字搜索时,日志中应出现二选一:
    • Available ORT providers 日志,且包含对应提供方(如 CUDA 的 CUDAExecutionProvider)——该日志正来自 ort.py#L115 的 provider 探测;
    • 对 ARM NN,则是 Loaded ANN model 且无报错的日志条目。

相关环境变量速查

结合 environment-variables.mdconfig.py 中的默认值,与硬件加速最相关的变量如下:

变量 说明 默认值
MACHINE_LEARNING_WORKERS worker 进程数(多 GPU 时等于设备数) 1
MACHINE_LEARNING_DEVICE_IDS 多 GPU 环境的设备 ID 列表 0
MACHINE_LEARNING_ANN 支持时启用 ARM NN 加速 True
MACHINE_LEARNING_ANN_FP16_TURBO ARM NN 以 FP16 执行:提速、轻微降精度 False
MACHINE_LEARNING_ANN_TUNING_LEVEL ARM NN GPU 调优级别(1: rapid, 2: normal, 3: exhaustive) 2
MACHINE_LEARNING_RKNN 支持时启用 RKNN 加速 True
MACHINE_LEARNING_RKNN_THREADS RKNN 推理时启动的运行时线程数 1
MACHINE_LEARNING_OPENVINO_PRECISION OpenVINO 精度(FP16/FP32 FP32
MACHINE_LEARNING_MODEL_TTL 模型空闲卸载时间(秒),影响 ROCm 功耗回落 300
MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION 人脸模型单次处理的最大人脸数 None(OpenVINO 为 1
MACHINE_LEARNING_MAX_BATCH_SIZE__OCR OCR 模型单次处理的最大框数 6

补充调优细节:

  • 默认 CPU 线程策略在源码中有体现——MACHINE_LEARNING_MODEL_INTER_OP_THREADS/MACHINE_LEARNING_MODEL_INTRA_OP_THREADS 为 0 时,仅在纯 CPU 提供方下分别回退为 1/2,因为“这些默认值对 CPU 合适但会拖累 GPU”(ort.py#L184-L206);
  • ROCm 下 worker 超时默认放宽为 900 秒(其余为 300 秒),见 default_worker_timeout
  • 首次搜索较慢时,可用 MACHINE_LEARNING_PRELOAD__* 系列变量预加载视觉/人脸/OCR 模型,避免备份触发首次加载时阻塞其他请求(main.py#L78-L119 实现了启动时预加载)。

实用技巧(官方 Tips 汇总)

  • 若某模型运行时报错,换一个模型试试,判断问题是否为模型特定;
  • 可适当提高并发度以提升利用率,但注意这会增加 VRAM 消耗;
  • 模型越大,从硬件加速中获益越多(前提是 VRAM 足够);
  • RKNPU 与 ARM NN 的对比
    • 模型支持更广(包括搜索任务,而 ARM NN 不加速搜索);
    • 发热更低;
    • 精度极轻微降低(RKNPU 恒用 FP16,ARM NN 默认用更高精度的 FP32,除非启用 MACHINE_LEARNING_ANN_FP16_TURBO);
    • 速度表现(以 RK3588 实测为参考):
      • MACHINE_LEARNING_RKNN_THREADS 为默认 1 时,RKNPU 的 ML 任务吞吐通常明显低于 ARM NN,但延迟相近(如搜索场景);
      • 设为 3 时,RKNPU 略快于 FP32 的 ARM NN,但略慢于开启 MACHINE_LEARNING_ANN_FP16_TURBO 的 ARM NN;
      • 当 GPU 同时被其他任务(如转码)占用时,RKNPU 使用本来空闲的 NPU,相比争抢 GPU 的 ARM NN 有显著优势;
    • 内存占用:线程数为 1 时更低;大于 1 时明显更高(但要发挥 NPU 全部性能、追平 ARM NN 的速度必须大于 1)。

小结

Immich 的 ML 硬件加速本质上是通过“镜像变体 + Compose extends”切换 ONNX Runtime 执行提供方或 NPU 独立运行时(RKNN/ARM NN),实现与 CPU 完全兼容的加速路径:已完成的向量与人脸数据无需重算,新任务自动落到加速设备。配置时的核心决策链是——先确认硬件与驱动满足对应后端的前置条件,再选择镜像 tag、内联或 extends 后端配置、按需设置 MACHINE_LEARNING_DEVICE_IDS/WORKERS 与精度/线程类变量,最后用设备利用率和容器日志(Available ORT providers / Loaded ANN model)双重验证。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384