Testowanie internetowego modelu AI w Google Colab

François Beaufort
François Beaufort

Skonfigurowanie spójnego środowiska testowego z użyciem kart graficznych może być trudniejsze, niż się wydaje. Oto czynności, które należy wykonać, aby przetestować modele AI po stronie klienta w prawdziwym środowisku przeglądarki, a także skalowalne, automatyzowane i działające w ramach znanej standardowej konfiguracji sprzętowej.

W tym przypadku jest to prawdziwa przeglądarka Chrome z obsługą sprzętu, a nie emulacją oprogramowania.

Ten przewodnik jest przeznaczony dla programistów AI, gier internetowych i grafiki, a także dla osób zainteresowanych testowaniem modeli AI w internecie.

Krok 1. Utwórz nowy notatnik Google Colab

1. Otwórz stronę colab.new, aby utworzyć nowy notatnik Colab. Powinna ona wyglądać podobnie do rysunku 1. 2. Postępuj zgodnie z instrukcjami, aby zalogować się na konto Google.
Zrzut ekranu nowego Colab
Rys. 1. Nowy notatnik Colab.

Krok 2. Połącz się z serwerem T4 z obsługą GPU

  1. Kliknij Połącz w prawym górnym rogu notatnika.
  2. Wybierz Zmień typ środowiska wykonawczego:
    Zrzut ekranu pokazujący, jak zmienić czas działania.
    Rysunek 2. Zmień środowisko wykonawcze w interfejsie Colab.
  3. W oknie modalnym jako akcelerator sprzętowy wybierz GPU T4. Po nawiązaniu połączenia Colab użyje instancji Linuksa z podłączonym GPU NVIDIA T4.
    Zrzut ekranu pokazujący moduł zmiany typu środowiska wykonawczego.
    Rysunek 3: w sekcji Akcelerator sprzętowy wybierz GPU T4.
  4. Kliknij Zapisz.
  5. Aby połączyć się ze środowiskiem wykonawczym, kliknij przycisk Połącz. Po chwili przycisk będzie miał zielony znacznik wyboru oraz wykresy wykorzystania pamięci RAM i dysku. Oznacza to, że serwer został utworzony z wymaganym sprzętem.

Świetnie, właśnie utworzysz serwer z podłączonym procesorem graficznym.

Krok 3. Zainstaluj odpowiednie sterowniki i zależne komponenty

  1. Skopiuj te 2 wiersze kodu i wklej je w pierwszej komórce notatnika. W środowisku Colab wykonanie polecenia jest poprzedzone wykrzyknikiem.

    !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. Aby wykonać kod, kliknij  obok komórki.

    Zrzut ekranu nowego Colab
    Rysunek 4.

  3. Po zakończeniu wykonywania kodu sprawdź, czy nvidia-smi wydrukowało coś podobnego do tego zrzutu ekranu, aby potwierdzić, że masz podłączoną kartę GPU i jest ona rozpoznawana na serwerze. Aby wyświetlić ten wynik, konieczne może być przewinięcie do wcześniejszych logów.

    Rysunek 5.: poszukaj danych wyjściowych, które zaczynają się od „NVIDIA-SMI”.

Krok 4. Używaj Chrome bez interfejsu graficznego i zautomatyzuj go

  1. Kliknij przycisk Kod, aby dodać nową komórkę z kodem.
  2. Następnie możesz napisać niestandardowy kod, aby wywołać projekt Node.js z preferowanymi parametrami (lub po prostu wywołać google-chrome-stable bezpośrednio w wierszu poleceń). Poniżej znajdziesz przykłady obu tych sytuacji.

Część A. Używanie trybu bez interfejsu graficznego w Chrome bezpośrednio w wierszu poleceń

# 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

W tym przykładzie zapisaliśmy wynikowy zrzut ekranu w pliku PDF o nazwie /content/gpu.pdf. Aby wyświetlić ten plik, rozwiń treści . Następnie kliknij , aby pobrać plik PDF na komputer lokalny.

Zrzut ekranu nowej wersji Colab
Rysunek 6. Na tym zrzucie ekranu z interfejsem Colab możesz zobaczyć, jak pobrać plik PDF.

Część B. Sterowanie Chrome za pomocą Puppeteer

Udostępniliśmy minimalistyczny przykład korzystania z Puppeteer do sterowania Chrome bez interfejsu graficznego, który można uruchomić w ten sposób:

# 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

W przykładzie jPuppet możemy wywołać skrypt Node.js, by utworzyć zrzut ekranu. Jak to działa? Zapoznaj się z tym przewodnikiem po kodzie Node.js w jPuppet.js.

Szczegóły kodu węzła jPuppet.js

Najpierw zaimportuj Puppeteer. Dzięki temu możesz zdalnie sterować Chrome za pomocą Node.js:

import puppeteer from 'puppeteer';

Następnie sprawdź, jakie argumenty wiersza poleceń zostały przekazane aplikacji Node. Upewnij się, że ustawiony jest trzeci argument, który reprezentuje adres URL, do którego ma nastąpić przejście. Musisz sprawdzić trzeci argument, ponieważ pierwsze 2 argumenty wywołują sam węzeł i uruchomiony przez nas skrypt. Trzeci element zawiera pierwszy parametr przekazany do programu Node:

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

Zdefiniuj teraz funkcję asynchroniczną o nazwie runWebpage(). Tworzy to obiekt przeglądarki skonfigurowany za pomocą argumentów wiersza poleceń, aby uruchomić binarne Chrome w sposób, w jaki potrzebujemy do działania WebGL i WebGPU zgodnie z opisem w artykule Włączanie obsługi WebGPU i 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'
      ]
  });

Utwórz nowy obiekt strony przeglądarki, którego możesz później użyć do odwiedzenia dowolnego adresu URL:

const page = await browser.newPage();

Następnie dodaj detektor zdarzeń, który będzie nasłuchiwać zdarzeń console.log, gdy strona internetowa będzie wykonywać kod JavaScript. Dzięki temu możesz rejestrować wiadomości na wierszu poleceń Node, a także sprawdzać tekst w konsoli pod kątem specjalnej frazy (w tym przypadku captureAndEnd), która powoduje wykonanie zrzutu ekranu, a następnie zakończenie procesu przeglądarki w Node. Jest to przydatne w przypadku stron internetowych, które wymagają pewnej ilości pracy przed zrobieniem zrzutu ekranu i mają niedeterministyczny czas wykonania.

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

Na koniec poleć stronie odwiedzenie podanego adresu URL i wykonanie początkowego zrzutu ekranu po załadowaniu strony.

Jeśli zdecydujesz się zrobić zrzut ekranu chrome://gpu, możesz natychmiast zamknąć sesję przeglądarki, zamiast czekać na dane wyjściowe konsoli, ponieważ ta strona nie jest kontrolowana przez Twój własny kod.

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

Modyfikowanie pliku package.json

Być może zauważysz, że na początku pliku jPuppet.js używamy instrukcji importu. Wartości typu w elementach package.json muszą być ustawione na module. W przeciwnym razie pojawi się komunikat o błędzie, że moduł jest nieprawidłowy.

 {
    "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"
}

To wszystko. Puppeteer ułatwia tworzenie interfejsu z Chrome za pomocą kodu.

Sukces

Możemy teraz sprawdzić, czy klasyfikator TensorFlow.js Fashion MNIST poprawnie rozpoznaje spodnie na obrazie, przetwarzając dane po stronie klienta w przeglądarce przy użyciu procesora graficznego.

Możesz go używać do wykonywania dowolnych zadań wykorzystujących GPU po stronie klienta, od modeli systemów uczących się po testowanie grafiki i gier.

Zrzut ekranu nowego Colab
Rysunek 7.: Pomyślne przechwycenie modelu TensorFlow.js przyspieszonego przez procesor graficzny, który umożliwia rozpoznawanie ubrań po stronie klienta w przeglądarce w czasie rzeczywistym

Zasoby

Dodaj gwiazdkę do repozytorium GitHub, aby otrzymywać przyszłe aktualizacje.