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.
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/mali0deve estar disponível no servidor host- Você pode confirmar isso executando
ls /devpara verificar se existe
- Você pode confirmar isso executando
- 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.ymlassume 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.ymlassume 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_TURBOpode melhorar significativamente o desempenho ao custo de uma redução muito pequena na precisão
- Em particular, a variável
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 configurarHSA_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/versionpara verificar a versão
- Você pode confirmar isso executando
- Opcional: Configure seu arquivo
.env, veja variáveis de ambiente para configurações específicas do RKNN- Em particular, configurar
MACHINE_LEARNING_RKNN_THREADSpara 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.
- Em particular, configurar
Configuração
- Se você ainda não tiver, faça o download do último arquivo
hwaccel.ml.ymle certifique-se de que ele esteja na mesma pasta que odocker-compose.yml. - No
docker-compose.ymlemimmich-machine-learning, descomente a seçãoextendse alterecpupara o backend apropriado. - Ainda em
immich-machine-learning, adicione um dos seguintes -[armnn, cuda, rocm, openvino, rknn] à tag da seçãoimageno final da linha. - Redepolhe o contêiner
immich-machine-learningcom 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_TURBOesteja ativado) - Velocidade variável (testado no RK3588):
- Se
MACHINE_LEARNING_RKNN_THREADSestiver 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_THREADSestiver configurado como 3, será um pouco mais rápido que ARM NN em FP32, mas um pouco mais lento que ARM NN seMACHINE_LEARNING_ANN_FP16_TURBOestiver 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
- Se
- Uso de RAM inferior se
MACHINE_LEARNING_RKNN_THREADSestiver 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)