跳转到主要内容

硬件加速的机器学习

此功能允许您使用 GPU 加速机器学习任务,例如智能搜索和人脸识别,同时减少 CPU 的负载。 由于这是一个新功能,它仍属于实验性功能,可能无法在所有系统上正常运行。

信息

启用硬件加速后,您不需要重新执行任何机器学习任务。加速设备将在启用后运行的所有任务中被使用。

支持的后端

  • ARM NN (Mali)
  • CUDA (支持 计算能力 5.2 或更高的 NVIDIA GPU)
  • ROCm (AMD GPU)
  • OpenVINO (如 Iris Xe 和 Arc 的 Intel GPU)
  • RKNN (Rockchip)

限制

  • 此处的指令和配置特定于 Docker Compose。其他容器引擎可能需要不同的配置。
  • 仅支持 Linux 和 Windows(通过 WSL2)服务器。
  • ARM NN 仅支持具有 Mali GPU 的设备。其他 Arm 设备不受支持。
  • 某些模型可能与某些后端不兼容。CUDA 是最可靠的。
  • 由于模型兼容性问题导致无法使用其搜索,加速搜索延迟未通过 ARM NN 改善。然而,智能搜索任务确实使用了 ARM NN。

前置条件

ARM NN

  • 请确保您安装了合适的 Linux 内核驱动程序
    • 通常该驱动程序已预装在设备供应商提供的 Linux 映像中
  • /dev/mali0 必须可在主机服务器中使用
    • 您可以通过运行 ls /dev 命令确认其存在
  • 您必须具有闭源的 libmali.so 固件(可能还有额外的固件文件)
    • 该文件的位置和获取方式取决于设备和供应商,但通常由设备供应商提供
    • hwaccel.ml.yml 文件假定其路径为 /usr/lib/libmali.so,因此如果文件位置不同,请进行相应更新
    • hwaccel.ml.yml 文件假定额外文件路径为 /lib/firmware/mali_csffw.bin,因此如果您的设备驱动不需要该文件,请进行相应更新
  • 可选:配置您的 .env 文件,参见 环境变量 以了解 ARM NN 特定设置
    • 特别是 MACHINE_LEARNING_ANN_FP16_TURBO 可以显著提升性能,代价是略微降低准确性

CUDA

  • GPU 必须具有计算能力 5.2 或更高。
  • 服务器必须安装官方 NVIDIA 驱动程序。
  • 安装的驱动程序版本必须 >= 545(支持 CUDA 12.3)。
  • 在 Linux 上(除 WSL2 外),还需要安装 NVIDIA Container Toolkit

ROCm

  • GPU 必须受 ROCm 支持。如果您的 GPU 未被官方支持,您可以尝试使用环境变量 HSA_OVERRIDE_GFX_VERSIONHSA_OVERRIDE_GFX_VERSION=<一个受支持的版本,例如 10.3.0>。如果未奏效,您可能还需要设置 HSA_USE_SVM=0
  • ROCm 映像非常大,需要至少 35GiB 的空闲磁盘空间。然而,通过 Docker 拉取服务的后续更新通常只有几百兆字节,因为大部分内容会被缓存。
  • 此后端较新,可能会出现一些问题。例如,即使机器学习服务处于空闲状态,运行推理后 GPU 的功耗仍可能高于平时。在这种情况下,仅在空闲 5 分钟后(可以通过 MACHINE_LEARNING_MODEL_TTL 设置进行配置)恢复正常。

OpenVINO

  • 集成式 GPU 比独立 GPU 更有可能遇到问题,尤其是对于较旧的处理器或采用低 RAM 的服务器。
  • 确保服务器的内核版本足够新,可以使用设备进行硬件加速。
  • 使用 OpenVINO 比 CPU 处理会消耗更多的 RAM。

RKNN

  • 必须拥有受支持的 Rockchip SoC:目前仅支持 RK3566、RK3568、RK3576 和 RK3588。
  • 请确保您已安装合适的 Linux 内核驱动程序
    • 通常该驱动程序已预装在设备供应商提供的 Linux 映像中
  • RKNPU 驱动程序版本必须为 V0.9.8 或更高,并且必须可在主机服务器中使用
    • 您可以通过运行 cat /sys/kernel/debug/rknpu/version 来检查版本
  • 可选:配置您的 .env 文件,参见 环境变量 以了解 RKNN 特定设置
    • 特别是将 MACHINE_LEARNING_RKNN_THREADS 设置为 2 或 3 相对于默认值 1,可以显著提高 RK3576 和 RK3588 的性能,但代价是每个模型使用的 RAM 增加至原来的倍数。

设置

  1. 如果尚未下载,请获取最新版 hwaccel.ml.yml 文件,并确保将其放置在与 docker-compose.yml 文件相同的文件夹中。
  2. docker-compose.yml 文件的 immich-machine-learning 部分,取消注释 extends 部分,并将 cpu 更改为适当的后端。
  3. immich-machine-learning 部分,添加 -[armnn, cuda, rocm, openvino, rknn] 至 image 部分的标签末尾。
  4. 使用更新后的设置重新部署 immich-machine-learning 容器。

确认设备使用情况

您可以通过检查设备的利用率来确认设备是否已被识别和使用。有许多显示此类信息的工具,例如适用于 NVIDIA 或 Intel 的 nvtop,适用于 Intel 的 intel_gpu_top,以及适用于 AMD 的 radeontop

您也可以检查 immich-machine-learning 容器的日志。当开始运行智能搜索或人脸检测任务,或在 Immich 中使用文本搜索时,您应该会看到一条有关 Available ORT providers 的日志,其中包含相关提供者(例如,CUDA 的情况下为 CUDAExecutionProvider),或看到一个 Loaded ANN model 日志条目且无错误(ARM NN 的情况下)。

单个 Compose 文件

截至目前,包括 Unraid 和 Portainer 在内的一些平台不支持多个 Compose 文件。作为替代方案,您可以直接将 hwaccel.ml.yml 文件的相关内容 "内联" 到 immich-machine-learning 服务中。

例如,该文件中的 cuda 部分是:

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

您可以将此内容添加到 immich-machine-learning 服务,而不是从 hwaccel.ml.yml 中扩展:

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。

例如,如果您有设备 0 和 1,请进行如下设置:

MACHINE_LEARNING_DEVICE_IDS=0,1
MACHINE_LEARNING_WORKERS=2

在此示例中,机器学习服务将启动两个工作线程,其中一个将把模型分配给设备 0,另一个分配给设备 1。不同的请求将由一个或另一个工作线程处理。

此方法也可以用于简单地指定特定设备。例如,设置 MACHINE_LEARNING_DEVICE_IDS=1 将确保始终使用设备 1 而不是设备 0。

请注意,您应增加作业并发性以提高总体利用率,并更有效地分配工作到多个 GPU。此外,每个 GPU 必须能够加载所有模型。无法将单个模型分配到多个个别 VRAM 不足的 GPU,也无法将特定模型指定给某一 GPU。

提示

  • 如果在运行模型时遇到错误,请尝试使用其他模型,看看问题是否为模型特定问题。
  • 您可能希望将并发性增加到默认值以上以提高利用率。然而,请注意,这也会增加 VRAM 的消耗。
  • 如果您的设备具有足够的 VRAM,则较大的模型更能从硬件加速中受益。
  • 与 ARM NN 相比,RKNPU 具有:
    • 更广泛的模型支持(包括搜索,ARM NN 不加速搜索)
    • 更少的热量产生
    • 略低的准确性(RKNPU 始终使用 FP16,而 ARM NN 默认为更高精度 FP32,除非启用 MACHINE_LEARNING_ANN_FP16_TURBO
    • 不同的速度表现(测试于 RK3588):
      • 如果 MACHINE_LEARNING_RKNN_THREADS 的默认值为 1,RKNPU 的 ML 任务吞吐量通常低于 ARM NN,但延迟相似(例如在搜索时)
      • 如果将 MACHINE_LEARNING_RKNN_THREADS 设置为 3,与 ARM NN 在 FP32 上相比,它稍快一些,但在启用 MACHINE_LEARNING_ANN_FP16_TURBO 时稍慢一些
      • 当其他任务也使用 GPU(例如转码)时,RKNPU 有显著优势,因为它使用闲置的 NPU 而不是与 GPU 使用竞争
    • 如果 MACHINE_LEARNING_RKNN_THREADS 的默认值为 1,使用 RAM 会更低,但如果设置值高于 1,则会显著增加(这是必要的以充分利用 NPU 和使其速度与 ARM NN 相当)