Testes de modelos de IA da Web no Google Colab

François Beaufort
François Beaufort

Configurar um ambiente de teste consistente com GPUs pode ser mais difícil o esperado. Confira as etapas para testar modelos de IA do lado do cliente e baseados em navegador ambientes verdadeiros de navegador, além de serem escalonáveis, automatizáveis e dentro de um uma configuração de hardware padronizada conhecida.

Nesse caso, o navegador é o Google Chrome real com suporte de hardware, e não na emulação de software.

Seja você um desenvolvedor de IA da Web, jogos para a Web, gráficos ou, ainda, se encontrar interesse em testes de modelos de IA da Web, este guia é para você.

Etapa 1: criar um novo bloco do Google Colab

1: Acesse colab.new para criar um novo bloco do Colab. Ele será semelhante à Figura 1. 2. Siga as instruções para fazer login na sua Conta do Google.
Captura de tela de um novo Colab
Figura 1: um novo bloco do Colab.

Etapa 2: conectar-se a um servidor com GPU T4 ativada

  1. Clique em Connect próximo ao canto superior direito do notebook.
  2. Selecione Mudar o tipo de ambiente de execução:
    Uma captura de tela em primeiro plano que mostra as etapas para mudar o ambiente de execução.
    Figura 2. Mudar o ambiente de execução na interface do Colab.
  3. Na janela modal, selecione GPU T4 como acelerador de hardware. Ao se conectar, o Colab vai usar uma instância do Linux com uma GPU NVIDIA T4 conectada. .
    Captura de tela do módulo "Alterar tipo de ambiente de execução".
    Figura 3: em "Acelerador de hardware", selecione GPU T4.
  4. Clique em Salvar.
  5. Clique no botão Conectar para se conectar ao ambiente de execução. Depois de algum tempo, exibirá uma marca de seleção verde, junto com os gráficos de uso de RAM e disco. Isso indica que um servidor foi criado com sucesso com as suas ao hardware.

Bom trabalho! Você acabou de criar um servidor com uma GPU anexada.

Etapa 3: instalar os drivers e as dependências corretos

  1. Copie e cole as duas linhas de código a seguir na primeira célula de código do do notebook. Em um ambiente do Colab, a execução da linha de comando é precedida por um ponto de exclamação.

    !git clone https://github.com/jasonmayes/headless-chrome-nvidia-t4-gpu-support.git
    !cd headless-chrome-nvidia-t4-gpu-support && chmod +x scriptyMcScriptFace.sh && ./scriptyMcScriptFace.sh
    
    # Update, install correct drivers, and remove the old ones.
    apt-get install -y vulkan-tools libnvidia-gl-525
    
    # Verify NVIDIA drivers can see the T4 GPU and that vulkan is working correctly.
    nvidia-smi
    vulkaninfo --summary
    
    # Now install latest version of Node.js
    npm install -g n
    n lts
    node --version
    npm --version
    
    # Next install Chrome stable
    curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/googlechrom-keyring.gpg
    echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrom-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list
    sudo apt update
    sudo apt install -y google-chrome-stable
    
    # Start dbus to avoid warnings by Chrome later.
    export DBUS_SESSION_BUS_ADDRESS="unix:path=/var/run/dbus/system_bus_socket"
    /etc/init.d/dbus start
    
  2. Clique no ao lado da célula para executar o código.

    Captura de tela de um novo Colab
    Figura 4.

  3. Quando o código terminar a execução, verifique se nvidia-smi gerou algo semelhante à captura de tela a seguir para confirmar se você realmente tem uma GPU anexado e será reconhecido em seu servidor. Talvez seja necessário rolar até uma página nos registros para visualizar essa saída.

    Figura 5: procure a saída que começa com "NVIDIA-SMI".

Etapa 4: usar e automatizar a versão headless do Chrome

  1. Clique no botão Code para adicionar um novo. célula de código.
  2. Em seguida, você pode criar seu código personalizado para chamar um projeto Node.js com sua parâmetros preferidos (ou apenas chamar google-chrome-stable diretamente na linha de comando). Temos exemplos para as duas opções a seguir.

Parte A: usar o Headless Chrome diretamente na linha de comando

# Directly call Chrome to dump a PDF of WebGPU testing page
# and store it in /content/gpu.pdf
!google-chrome-stable \
--no-sandbox \
--headless=new \
--use-angle=vulkan \
--enable-features=Vulkan \
--disable-vulkan-surface \
--enable-unsafe-webgpu \
--print-to-pdf=/content/gpu.pdf https://webgpureport.org

No exemplo, armazenamos a captura em PDF resultante em /content/gpu.pdf. Para visualizar o arquivo, expanda o conteúdo . Em seguida, clique em para fazer o download do PDF. para sua máquina local.

Captura de tela de um novo Colab
Figura 6: confira as etapas para fazer o download do PDF nesta captura de tela da interface do Colab.

Parte B: comandar o Chrome com o Puppeteer

Fornecemos um exemplo minimalista usando o Puppeteer para controlar o Headless Chrome que pode ser executado da seguinte forma:

# Call example node.js project to perform any task you want by passing
# a URL as a parameter
!node headless-chrome-nvidia-t4-gpu-support/examples/puppeteer/jPuppet.js chrome://gpu

No exemplo do jPuppet, podemos chamar um script Node.js para criar uma captura de tela. Mas como isso funciona? Confira este tutorial da biblioteca Node.js código no jPuppet.js (link em inglês).

Detalhamento do código do Node jPuppet.js

Primeiro, importe o Puppeteer. Isso permite você controla remotamente o Chrome com Node.js:

import puppeteer from 'puppeteer';

Em seguida, verifique quais argumentos da linha de comando foram passados para o aplicativo Node. Verifique se o terceiro argumento está definido, que representa um URL para navegar. Você é preciso inspecionar o terceiro argumento aqui porque os dois primeiros chamam o Node. por si só e o script que estamos executando. O terceiro elemento contém o 1o passado ao programa Node:

const url = process.argv[2];
if (!url) {
  throw "Please provide a URL as the first argument";
}

Agora defina uma função assíncrona chamada runWebpage(). Isso cria um navegador configurado com os argumentos da linha de comando para executar o navegador binário, da maneira que precisamos fazer com que o WebGL e a WebGPU funcionem como descrito em Ative a compatibilidade com WebGPU e WebGL.

async function runWebpage() {
  const browser = await puppeteer.launch({
    headless: 'new',
    args:  [
        '--no-sandbox',
        '--headless=new',
        '--use-angle=vulkan',
        '--enable-features=Vulkan',
        '--disable-vulkan-surface',
        '--enable-unsafe-webgpu'
      ]
  });

Crie um novo objeto de página do navegador que você pode usar para visitar qualquer URL:

const page = await browser.newPage();

Em seguida, adicione um listener de eventos para detectar eventos console.log quando a página da Web executa JavaScript. Isso permite registrar mensagens na linha de comando do nó e também inspecione o texto do console em busca de uma frase especial (neste caso, captureAndEnd) que aciona uma captura de tela e encerra o processo do navegador em Nó Isso é útil para páginas da Web que precisam de algum trabalho antes uma captura de tela pode ser feita e tem um tempo não determinista de execução.

page.on('console', async function(msg) {
  console.log(msg.text());
  if (msg.text() === 'captureAndEnd') {
    await page.screenshot({ path: '/content/screenshotEnd.png' });
    await browser.close();
  }
});

Por fim, dê um comando para que a página acesse o URL especificado e capture uma captura de tela inicial quando a página for carregada.

Se você optar por fazer uma captura de tela do chrome://gpu, feche o navegador sessão imediatamente, em vez de esperar por qualquer saída do console, já que a página está sendo não controladas pelo seu próprio código.

  await page.goto(url,  { waitUntil: 'networkidle2' });
  await page.screenshot({path: '/content/screenshot.png'});
  if (url === 'chrome://gpu') {
    await browser.close();
  }
}
runWebpage();

Modificar package.json

Você deve ter notado que usamos uma instrução de importação no início da jPuppet.js. Seu package.json precisa definir os valores de tipo como module ou você vai receber um erro informando que o módulo é inválido.

 {
    "dependencies":  {
      "puppeteer": "*"
    },
    "name": "content",
    "version": "1.0.0",
    "main": "jPuppet.js",
    "devDependencies": {},
    "keywords": [],
    "type": "module",
    "description": "Node.js Puppeteer application to interface with headless Chrome with GPU support to capture screenshots and get console output from target webpage"
}

Isso é tudo. Usar o Puppeteer facilita a interface com o Chrome de forma programática.

Sucesso

Agora podemos verificar Classificador MNIST Fashion do TensorFlow.js reconhece corretamente um par de calças em uma imagem, com calças do lado do cliente no navegador usando a GPU.

Você pode usar isso para qualquer carga de trabalho baseada em GPU no lado do cliente, de machine learning de modelos para testes de gráficos e jogos.

Captura de tela de um novo Colab
Figura 7: captura bem-sucedida de um modelo TensorFlow.js acelerado por GPU capaz de reconhecer o lado do cliente de vestuário no navegador em tempo real.

Recursos

Adicionar uma estrela ao repositório do GitHub para receber futuras atualizações.