Testowanie internetowego modelu AI w Google Colab

François Beaufort
François Beaufort

Skonfigurowanie spójnego środowiska testowego z układami GPU może być trudniejsze, niż się spodziewaliśmy. 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 Ciebie – niezależnie od tego, czy zajmujesz się tworzeniem sztucznej inteligencji, graniem w przeglądarkę, grafiką, czy testowaniem modeli sztucznej inteligencji internetowej.

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. W prawym górnym rogu zeszytu kliknij Połącz .
  2. Kliknij Zmień typ środowiska wykonawczego:
    Zrzut ekranu ze zbliżeniem pokazującym kroki zmiany środowiska wykonawczego.
    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 z modułem Zmień typ środowiska wykonawczego
    Rysunek 3: w sekcji Akcelerator sprzętowy wybierz GPU T4.
  4. Kliknij Zapisz.
  5. Kliknij przycisk Połącz, aby połączyć się ze środowiskiem wykonawczym. Po pewnym czasie na przycisku pojawi się 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ć te dane wyjściowe, konieczne może być przewinięcie logów do wcześniejszej pozycji.

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

Krok 4. Używaj i automatyzuj przeglądarkę Chrome pozbawioną interfejsu

  1. Aby dodać nową komórkę kodu, kliknij  Kod.
  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

Poniżej znajdziesz minimalistyczny przykład sterowania Chrome bez interfejsu graficznego za pomocą Puppeteer, 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, aby 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 przy użyciu środowiska 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ą Node i skrypt, który uruchamiamy. 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 funkcję asynchroniczną o nazwie runWebpage(). Spowoduje to utworzenie obiektu przeglądarki ze skonfigurowanymi argumentami wiersza poleceń umożliwiającymi uruchomienie pliku binarnego Chrome w sposób niezbędny do zapewnienia działania WebGL i WebGPU zgodnie z opisem w sekcji 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, aby odwiedziła podany adres URL, i zrób początkowy zrzut 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

Jak już pewnie wiesz, na początku pliku jPuppet.js użyliśmy 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ć w przyszłości aktualizacje.