Ir para o conteúdo principal

Machine Learning Acelerado por Hardware

Este recurso permite utilizar uma GPU para acelerar tarefas de aprendizado de máquina, como Pesquisa Inteligente e Reconhecimento Facial, enquanto reduz a carga da CPU. Como esta é uma funcionalidade nova, ainda está em fase experimental e pode não funcionar em todos os sistemas.

informação

Você não precisa refazer nenhum trabalho de aprendizado de máquina após ativar a aceleração por hardware. O dispositivo de aceleração será usado para quaisquer trabalhos que forem executados após a ativação.

Backends Suportados

  • ARM NN (Mali)
  • CUDA (GPUs NVIDIA com capacidade de computação 5.2 ou superior)
  • ROCm (GPUs AMD)
  • OpenVINO (GPUs Intel, como Iris Xe e Arc)
  • RKNN (Rockchip)

Limitações

  • As instruções e configurações aqui são específicas para Docker Compose. Outros engines de contêiner podem exigir configurações diferentes.
  • Somente servidores Linux e Windows (via WSL2) são suportados.
  • ARM NN só é suportado em dispositivos com GPUs Mali. Outros dispositivos Arm não são compatíveis.
  • Alguns modelos podem não ser compatíveis com certos backends. CUDA é o mais confiável.
  • A latência de busca não é melhorada por ARM NN devido a problemas de compatibilidade de modelo que impedem seu uso. No entanto, trabalhos de busca inteligente utilizam ARM NN.

Pré-requisitos

ARM NN

  • Certifique-se de ter o driver apropriado do kernel Linux instalado
    • Geralmente, isso já vem pré-instalado nas imagens Linux do fornecedor do dispositivo
  • /dev/mali0 deve estar disponível no servidor host
    • Você pode confirmar isso executando ls /dev para verificar se existe
  • Você deve ter o firmware de código fechado libmali.so (possivelmente com um arquivo de firmware adicional)
    • Onde e como obter este arquivo depende do dispositivo e do fornecedor, mas normalmente o fornecedor do dispositivo também fornece estes arquivos
    • O arquivo hwaccel.ml.yml assume que o caminho para ele é /usr/lib/libmali.so, então atualize conforme necessário caso ele esteja em outro lugar
    • O arquivo hwaccel.ml.yml assume um arquivo adicional /lib/firmware/mali_csffw.bin, então atualize conforme necessário se o driver do seu dispositivo não requerer este arquivo
  • Opcional: Configure seu arquivo .env, veja variáveis de ambiente para configurações específicas do ARM NN
    • Em particular, a variável MACHINE_LEARNING_ANN_FP16_TURBO pode melhorar significativamente o desempenho ao custo de uma redução muito pequena na precisão

CUDA

  • A GPU deve ter capacidade de computação 5.2 ou superior.
  • O servidor deve ter o driver oficial da NVIDIA instalado.
  • O driver instalado deve ser >= 545 (deve suportar CUDA 12.3).
  • No Linux (exceto no WSL2), você também precisa ter o NVIDIA Container Toolkit instalado.

ROCm

  • A GPU deve ser suportada pelo ROCm. Se não for oficialmente suportada, você pode tentar usar a variável de ambiente HSA_OVERRIDE_GFX_VERSION: HSA_OVERRIDE_GFX_VERSION=<uma versão suportada, ex. 10.3.0>. Se isso não funcionar, pode ser necessário também configurar HSA_USE_SVM=0.
  • A imagem ROCm é bastante grande e requer pelo menos 35GiB de espaço livre em disco. No entanto, puxar atualizações posteriores para o serviço através do Docker geralmente consome apenas algumas centenas de megabytes, pois o restante será cacheado.
  • Este backend é novo e pode apresentar alguns problemas. Por exemplo, o consumo de energia da GPU pode ser maior do que o habitual após a execução de inferência, mesmo que o serviço de aprendizado de máquina esteja ocioso. Nesse caso, ele só voltará ao normal após estar ocioso por 5 minutos (configurável com a configuração MACHINE_LEARNING_MODEL_TTL).

OpenVINO

  • GPUs integradas têm maior probabilidade de apresentar problemas do que GPUs discretas, especialmente para processadores mais antigos ou servidores com pouca RAM.
  • Certifique-se de que a versão do kernel do servidor seja nova o suficiente para usar o dispositivo para aceleração de hardware.
  • Espere um uso maior de RAM ao usar OpenVINO em comparação com o processamento por CPU.

RKNN

  • Você deve ter um SoC Rockchip suportado: apenas RK3566, RK3568, RK3576 e RK3588 são suportados neste momento.
  • Certifique-se de ter o driver apropriado do kernel Linux instalado
    • Geralmente, isso já vem pré-instalado nas imagens Linux do fornecedor do dispositivo
  • O driver RKNPU V0.9.8 ou posterior deve estar disponível no servidor host
    • Você pode confirmar isso executando cat /sys/kernel/debug/rknpu/version para verificar a versão
  • Opcional: Configure seu arquivo .env, veja variáveis de ambiente para configurações específicas do RKNN
    • Em particular, configurar MACHINE_LEARNING_RKNN_THREADS para 2 ou 3 pode melhorar dramaticamente o desempenho para RK3576 e RK3588 em comparação ao padrão de 1, ao custo de multiplicar a quantidade de RAM que cada modelo usa por essa quantidade.

Configuração

  1. Se você ainda não tiver, faça o download do último arquivo hwaccel.ml.yml e certifique-se de que ele esteja na mesma pasta que o docker-compose.yml.
  2. No docker-compose.yml em immich-machine-learning, descomente a seção extends e altere cpu para o backend apropriado.
  3. Ainda em immich-machine-learning, adicione um dos seguintes -[armnn, cuda, rocm, openvino, rknn] à tag da seção image no final da linha.
  4. Redepolhe o contêiner immich-machine-learning com estas configurações atualizadas.

Confirmando o Uso do Dispositivo

Você pode confirmar que o dispositivo está sendo reconhecido e utilizado verificando sua utilização. Há muitas ferramentas para exibir isso, como nvtop para NVIDIA ou Intel, intel_gpu_top para Intel, e radeontop para AMD.

Você também pode verificar os logs do contêiner immich-machine-learning. Quando um trabalho de Pesquisa Inteligente ou Detecção Facial começa, ou quando você pesquisa por texto no Immich, você deve ver um log para Available ORT providers contendo o provedor relevante (ex. CUDAExecutionProvider no caso de CUDA), ou uma entrada de log Loaded ANN model sem erros no caso de ARM NN.

Arquivo Compose Único

Algumas plataformas, incluindo Unraid e Portainer, não suportam vários arquivos Compose no momento em que escrevo. Como alternativa, você pode "integrar" o conteúdo relevante do arquivo hwaccel.ml.yml diretamente no serviço immich-machine-learning.

Por exemplo, a seção cuda neste arquivo é:

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

Você pode adicionar isso ao serviço immich-machine-learning em vez de estender a partir de hwaccel.ml.yml:

immich-machine-learning:
container_name: immich_machine_learning
# Note o `-cuda` no final
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
# Note a falta de uma seção `extends`
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu
volumes:
- model-cache:/cache
env_file:
- .env
restart: always

Uma vez feito isso, você pode redeployar o contêiner immich-machine-learning.

Multi-GPU

Se você quiser utilizar várias GPUs NVIDIA ou Intel, pode configurar a variável de ambiente MACHINE_LEARNING_DEVICE_IDS com uma lista separada por vírgulas de IDs de dispositivos e definir MACHINE_LEARNING_WORKERS como o número de dispositivos listados. Você pode executar comandos como nvidia-smi -L ou glxinfo -B para ver os dispositivos disponíveis atualmente e seus IDs correspondentes.

Por exemplo, se você tiver os dispositivos 0 e 1, configure os valores da seguinte forma:

MACHINE_LEARNING_DEVICE_IDS=0,1
MACHINE_LEARNING_WORKERS=2

Neste exemplo, o serviço de aprendizado de máquina irá criar dois trabalhadores, um dos quais alocará modelos para o dispositivo 0 e o outro para o dispositivo 1. Solicitações diferentes serão processadas por um trabalhador ou pelo outro.

Esta abordagem também pode ser usada para especificar um dispositivo em particular. Por exemplo, configurar MACHINE_LEARNING_DEVICE_IDS=1 garantirá que o dispositivo 1 seja sempre usado em vez do dispositivo 0.

Observe que você deve aumentar as concorrências de trabalho para aumentar a utilização geral e distribuir o trabalho de forma mais eficaz entre várias GPUs. Além disso, cada GPU deve ser capaz de carregar todos os modelos. Não é possível distribuir um único modelo em várias GPUs que individualmente não têm VRAM suficiente, nem delegar um modelo específico a uma GPU.

Dicas

  • Se você encontrar um erro enquanto um modelo está sendo executado, tente um modelo diferente para verificar se o problema é específico do modelo.
  • Pode ser interessante aumentar a concorrência além do padrão para uma utilização maior. No entanto, lembre-se de que isso também aumentará o consumo de VRAM.
  • Modelos maiores se beneficiam mais da aceleração por hardware, se você possuir a VRAM necessária.
  • Comparado ao ARM NN, RKNPU apresenta:
    • Suporte mais amplo a modelos (incluindo para busca, que ARM NN não acelera)
    • Menor geração de calor
    • Precisão ligeiramente inferior (RKNPU sempre utiliza FP16, enquanto o ARM NN, por padrão, utiliza FP32 de maior precisão, a menos que MACHINE_LEARNING_ANN_FP16_TURBO esteja ativado)
    • Velocidade variável (testado no RK3588):
      • Se MACHINE_LEARNING_RKNN_THREADS estiver no padrão de 1, o RKNPU terá uma taxa de transferência substancialmente menor para trabalhos de ML do que ARM NN na maioria dos casos, mas latência semelhante (como na busca)
      • Se MACHINE_LEARNING_RKNN_THREADS estiver configurado como 3, será um pouco mais rápido que ARM NN em FP32, mas um pouco mais lento que ARM NN se MACHINE_LEARNING_ANN_FP16_TURBO estiver ativado
      • Quando outras tarefas também utilizam a GPU (como transcodificação), RKNPU tem uma vantagem significativa sobre ARM NN, pois utiliza a NPU que de outra forma estaria ociosa, em vez de competir pelo uso da GPU
    • Uso de RAM inferior se MACHINE_LEARNING_RKNN_THREADS estiver no padrão de 1, mas significativamente superior se maior que 1 (o que é necessário para utilizar plenamente a NPU e, assim, ser comparável em velocidade ao ARM NN)