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/mali0
deve estar disponível no servidor host- Você pode confirmar isso executando
ls /dev
para 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.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
- 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/version
para 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_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.
- Em particular, configurar
Configuração
- 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 odocker-compose.yml
. - No
docker-compose.yml
emimmich-machine-learning
, descomente a seçãoextends
e alterecpu
para o backend apropriado. - Ainda em
immich-machine-learning
, adicione um dos seguintes -[armnn, cuda, rocm, openvino, rknn] à tag da seçãoimage
no final da linha. - 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 seMACHINE_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
- Se
- 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)