YOLO em Azure DLVM

Source: Deep Learning on Medium

Como minha memória não anda muito boa, comecei a fazer anotações para consultas futuras, mas hoje achei melhor criar aqui um artigo para compartilhar a experiência com a galera.

  • Direto ao ponto: Se você é uma instância minha do futuro (ou qualquer um que não queira ler tudo) e/ou está revisitando esse artigo apenas para copiar os comandos. Acesse o script AQUI. Ou utilize o comando abaixo, que automatiza quase tudo que descreverei adiante:
sudo curl -s https://gist.githubusercontent.com/dntxos/952ad3228b04b31bdf6d12a921e66382/raw/2864cfe88e8613d4684befd014562339406acac1/dlvmdarknet_setup_ubuntu16.sh -o /tmp/dlvmdarknet_setup_ubuntu16.sh && sh /tmp/dlvmdarknet_setup_ubuntu16.sh

Introdução

Darknet/Yolo é realmente fascinante (Vlw Joseph Redmon, vc é o cara!).
Em computação visual, até o presente momento, a darknet/yolo (You only look once) é o estado da arte em reconhecer objetos em tempo real, possibilitando com uma ‘GPU Titan X’ processar videos a 40–90 FPS com uma boa assertividade (COCO e VOC2007). E o melhor, é open-source! Podemos baixar, usar e abusar (como diria o careca da C&A).

Nesse artigo vamos passo-a-passo, desde a criação da DLVM no Azure até a execução de inferência com darknet/yolo em um container docker com suporte a GPUs e CUDA (nvidia-docker)

Motivação

Treinar modelos para detecção de objetos como o DarkNet/Yolo é um processo um tanto quanto demorado. Mas pode ser muito mais rápido utilizando computadores com excelente poder computacional.
Nesse caso utilizar DLVM Azure pode ser muito interessante, pois é possível ter acesso as GPUs mais poderosas do mercado pagando por hora. E além da capacidade elástica, sempre oferecem uma experimentação gratuita inicial (pelo menos no momento que escrevo isso hehehe), que é o suficiente para treinarmos um modelo de rede neural profunda DarkNet/YOLO.

Para prosseguir é necessário ter uma conta Azure. No momento que escrevo esse artigo, o Azure oferece um crédito de R$750,00 para explorar qualquer serviço Azure por 30 dias. Para acessar a oferta utilize o link: https://azure.microsoft.com/pt-br/free/

Implantando uma máquina-virtual para Deep Learning no Azure

Criar uma máquina-virtual no Azure é um processo bastante simples. Ainda que simples, tomarei o cuidado de descrever cada passo (e com capturas de tela).

Logo, no portal Azure (https://portal.azure.com), localize a lâmina ‘Máquinas Virtuais’ e clique no botão ‘+ Adicionar’

Para criar a máquina-virtual otimizada para Deep Learning ou Data Science, selecione na opção tamanho, qualquer uma das séries NC (escolhi a NC6 nesse caso), na opção imagem, selecione ‘Ubuntu Server 16.04 LTS’ e permitir porta de entrada SSH.

Nem todas as regiões Azure suportam as séries NC. No meu caso, precisei selecionar ‘Leste dos EUA’ por ser a única região com suporte na conta gratuita do Azure.
Os tamanhos das séries NC são otimizados para algoritmos intensivos em computação. A série NCv3 é equipada com GPUs Tesla V100 da NVIDIA. :-D

Após clicar em ‘Revisar + criar’ será exibido um resumo das suas configurações.

Nessa etapa você ainda pode adicionar mais discos (SSD garante maior velocidade). Por padrão, o Azure adicionará um disco volátil rápido de 1TB montado em ‘/mnt’ (Mas cuidado! Todos os dados serão perdidos ao desligar a VM).

Implantação concluída! :-P

Acessando a máquina-virtual

Agora que nossa VM já foi implantada com sucesso no Azure, vamos acessa-la através de 2 aplicativos:

Acesse a página ‘Visão geral’ da VM que acabamos de criar, inicie a máquina-virtual e localize o endereço IP PÚBLICO atribuído:

Conecte-se à VM através do PUTTY com o endereço ip público e o usuário e senha definidos na etapa de implantação:

  • A partir daqui você já pode executar o script mencionado no início desse documento e pular todas as etapas seguintes (:-P)

Instalando os drivers CUDA

CUDA é a biblioteca para computação paralela da NVIDIA. E é requisito para NVIDIA-DOCKER e praticamente qualquer Framework para processamento na GPU.
Agora que temos acesso ao terminal da nossa VM, vamos começar com os comandos:

CUDA_REPO_PKG=cuda-repo-ubuntu1604_10.0.130-1_amd64.deb
wget -O /tmp/${CUDA_REPO_PKG} http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/${CUDA_REPO_PKG}
sudo dpkg -i /tmp/${CUDA_REPO_PKG}
sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
rm -f /tmp/${CUDA_REPO_PKG}
sudo apt-get update
sudo apt-get --assume-yes install cuda-drivers

Isso pode levar alguns minutos

Instalando Docker-CE

O Docker permite encapsular a aplicação e todo o set de bibliotecas em um container. Dessa forma, por exemplo, fica muito mais fácil e rápido iniciar um container pré-configurado com Darknet/Yolo e todas as suas dependências do que ter que instalar todas as bibliotecas e drivers requeridos pelos frameworks.

sudo apt-get update
sudo apt-get --assume-yes install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get --assume-yes install docker-ce docker-ce-cli containerd.io
sudo docker run hello-world

Instalando Nvidia-Docker

Nvidia-docker é necessário para poder utilizar GPUs e biblioteca CUDA dentro dos contêineres.

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd
# Test nvidia-smi with the latest official CUDA image
sudo docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi

Compilar DockerBuild DLVM-Darknet

Vamos compilar nossa imagem docker do repositório dockerbuild https://github.com/daltskin/DLVM-Darknet do Jamie Dalton. Esse é um FORK do https://github.com/AlexeyAB/darknet, mas com algumas correções e preparado para utilizar as GPUs do ambiente DLVM Azure.

git clone https://github.com/daltskin/DLVM-Darknet
sudo docker build DLVM-Darknet/darknet -t darknet:latest
sudo docker build DLVM-Darknet -t dlvm-darknet:latest

Pronto!

Agora que já temos o ambiente preparado, vamos testar a darknet/yolo com arquivo de pesos pré-treinado yolov3.weights e um arquivo de vídeo mp4.

# Diretório mapeado com unidade de disco volátil do Azure
cd /mnt
# Permitir escrita no diretório
sudo chmod 777 .
# Download do arquivo MP4
wget https://archive.org/download/WildlifeSampleVideo/Wildlife.mp4
sudo nvidia-docker run -v /mnt/:/data/ -ti dlvm-darknet:latest ./darknet detector demo ./cfg/coco.data ./cfg/yolov3.cfg yolov3.weights /data/Wildlife.mp4 -out_filename /data/Wildlife-out.avi -dont_show 

Você deve receber uma saída parecida com isso:

Para acessar o terminal do container:

sudo nvidia-docker run -v /mnt/:/data/ -ti dlvm-darknet:latest bash

Considerações finais

  • Utilizar DLVM Azure para processar treinamentos de modelos e/ou inferências é prático, acessível e muito mais rápido do que em um computador comum. Em uma VM Azure série ‘NC6 standard’, meu modelo que demorou uma noite inteira para atingir 30 passos no meu PC local (I7 + GTX1080) levou menos de 10 minutos para ser ultrapassado. Logo, passei a utilizar apenas o ambiente Azure para tais aplicações.
  • Ao desconectar da VM ela continua ligada, implicando custo (ou gastando créditos). Para evitar gastos desnecessários desligue-a ao fim dos trabalhos.

O que vem depois?

Espero que esse meu primeiro post sobre um assunto mais técnico seja útil. E talvez, em um próximo post podemos abordar o treinamento do modelo.

Referencias