Web AI-Modelltests in Google Colab

François Beaufort
François Beaufort

Das Einrichten einer einheitlichen Testumgebung mit GPUs kann schwieriger sein als erwartet. Im Folgenden finden Sie eine Anleitung zum Testen clientseitiger, browserbasierter KI-Modelle in echten Browserumgebungen, die skalierbar, automatisierbar und in einer bekannten standardisierten Hardwarekonfiguration sind.

In diesem Fall handelt es sich um einen echten Chrome-Browser mit Hardwareunterstützung, im Gegensatz zur Softwareemulation.

Dieser Leitfaden richtet sich an Web-KI-, Web-Gaming- oder Grafikentwickler sowie an alle, die sich für das Testen von Web-KI-Modellen interessieren.

Schritt 1: Neues Google Colab-Notebook erstellen

1. Rufen Sie colab.new auf, um ein neues Colab-Notebook zu erstellen. Sie sollte in etwa so aussehen wie in Abbildung 1. 2. Folgen Sie der Aufforderung, um sich in Ihrem Google-Konto anzumelden.
Screenshot eines neuen Colab-Notebooks
Abbildung 1: Ein neues Colab-Notebook

Schritt 2: Verbindung zu einem T4-GPU-fähigen Server herstellen

  1. Klicken Sie oben rechts im Notizbuch auf Verbinden .
  2. Wählen Sie Laufzeittyp ändern aus:
    Ein Screenshot mit den Schritten zum Ändern der Laufzeit.
    Abbildung 2. Ändern Sie die Laufzeit in der Colab-Benutzeroberfläche.
  3. Wählen Sie im modalen Fenster T4 GPU als Hardwarebeschleuniger aus. Wenn Sie eine Verbindung herstellen, verwendet Colab eine Linux-Instanz mit einer angehängten NVIDIA T4-GPU.
    Screenshot des Moduls „Laufzeittyp ändern“
    Abbildung 3: Wählen Sie unter „Hardwarebeschleuniger“ die Option T4-GPU aus.
  4. Klicken Sie auf Speichern.
  5. Klicken Sie auf die Schaltfläche Verbinden, um eine Verbindung zu Ihrer Laufzeit herzustellen. Nach einiger Zeit wird auf der Schaltfläche ein grünes Häkchen sowie Diagramme zur RAM- und Laufwerksnutzung angezeigt. Dies bedeutet, dass ein Server mit der erforderlichen Hardware erstellt wurde.

Sehr gut. Sie haben gerade einen Server mit einer angeschlossenen GPU erstellt.

Schritt 3: Die richtigen Treiber und Abhängigkeiten installieren

  1. Kopieren Sie die folgenden beiden Codezeilen und fügen Sie sie in die erste Codezelle des Notebooks ein. In einer Colab-Umgebung wird der Befehlszeilenausführung ein Ausrufezeichen vorangestellt.

    !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. Klicken Sie neben der Zelle auf , um den Code auszuführen.

    Screenshot eines neuen Colab-Notebooks
    Abbildung 4

  3. Prüfen Sie nach Abschluss der Ausführung des Codes, ob nvidia-smi etwas Ähnliches wie den folgenden Screenshot ausgegeben hat. So können Sie bestätigen, dass tatsächlich eine GPU angeschlossen ist und auf Ihrem Server erkannt wird. Möglicherweise müssen Sie in den Protokollen nach oben scrollen, um diese Ausgabe zu sehen.

    Abbildung 5: Suchen Sie nach der Ausgabe, die mit „NVIDIA-SMI“ beginnt.

Schritt 4: Headless Chrome verwenden und automatisieren

  1. Klicken Sie auf die Schaltfläche Code, um eine neue Codezelle hinzuzufügen.
  2. Sie können dann benutzerdefinierten Code schreiben, um ein Node.js-Projekt mit Ihren bevorzugten Parametern aufzurufen, oder einfach google-chrome-stable direkt in der Befehlszeile aufrufen. Wir haben Beispiele für beides.

Teil A: Headless Chrome direkt in der Befehlszeile verwenden

# 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

Im Beispiel haben wir die resultierende PDF-Datei unter /content/gpu.pdf gespeichert. Maximieren Sie dazu die Inhalte . Klicken Sie dann auf , um die PDF-Datei auf Ihren lokalen Computer herunterzuladen.

Screenshot eines neuen Colab-Notebooks
Abbildung 6: In diesem Screenshot der Colab-Benutzeroberfläche sehen Sie die Schritte zum Herunterladen der PDF-Datei.

Teil B: Chrome mit Puppeteer steuern

Wir haben ein minimalistisches Beispiel zur Verwendung von Puppeteer zur Steuerung von Headless Chrome bereitgestellt, das wie folgt ausgeführt werden kann:

# 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

Im jPuppet-Beispiel können wir ein Node.js-Skript aufrufen, um einen Screenshot zu erstellen. Aber wie funktioniert das? Sehen Sie sich diese Schritt-für-Schritt-Anleitung zum Node.js-Code in jPuppet.js an.

jPuppet.js-Knotencode – Aufschlüsselung

Importieren Sie zuerst Puppeteer. So können Sie Chrome mit Node.js per Fernzugriff steuern:

import puppeteer from 'puppeteer';

Prüfen Sie als Nächstes, welche Befehlszeilenargumente an die Node-Anwendung übergeben wurden. Das dritte Argument muss festgelegt sein. Es stellt eine URL dar, zu der Sie weitergeleitet werden sollen. Sie müssen hier das dritte Argument prüfen, da die ersten beiden Argumente Node selbst und das Script aufrufen, das wir ausführen. Das dritte Element enthält tatsächlich den ersten Parameter, der an das Knotenprogramm übergeben wurde:

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

Definieren Sie nun eine asynchrone Funktion namens runWebpage(). Dadurch wird ein Browserobjekt erstellt, das mit den Befehlszeilenargumenten konfiguriert ist, um das Chrome-Binärprogramm so auszuführen, dass WebGL und WebGPU wie unter WebGPU- und WebGL-Unterstützung aktivieren beschrieben funktionieren.

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'
      ]
  });

Erstellen Sie ein neues Browserseitenobjekt, mit dem Sie später eine beliebige URL aufrufen können:

const page = await browser.newPage();

Fügen Sie dann einen Ereignis-Listener hinzu, der auf console.log-Ereignisse wartet, wenn auf der Webseite JavaScript ausgeführt wird. So können Sie Nachrichten in der Node-Befehlszeile protokollieren und den Konsolentext auf einen bestimmten Begriff (in diesem Fall captureAndEnd) prüfen, der einen Screenshot auslöst und dann den Browserprozess in Node beendet. Dies ist nützlich für Webseiten, die eine gewisse Arbeit erfordern, bevor ein Screenshot erstellt werden kann, und deren Ausführungsdauer nicht deterministisch ist.

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

Schließlich weisen Sie der Seite an, die angegebene URL aufzurufen und einen ersten Screenshot zu erstellen, wenn die Seite geladen ist.

Wenn Sie einen Screenshot von chrome://gpu erstellen möchten, können Sie die Browsersitzung sofort schließen, anstatt auf eine Konsolenausgabe zu warten, da diese Seite nicht von Ihrem eigenen Code gesteuert wird.

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

package.json ändern

Sie haben vielleicht bemerkt, dass wir am Anfang der Datei jPuppet.js eine Importanweisung verwendet haben. In package.json müssen die Typwerte auf module festgelegt sein. Andernfalls erhalten Sie die Fehlermeldung, dass das Modul ungültig ist.

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

Das war schon alles. Mit Puppeteer können Sie Chrome programmatisch einfacher verknüpfen.

Erfolg

Wir können jetzt bestätigen, dass der TensorFlow.js Fashion MNIST-Klassifikator eine Hose in einem Bild korrekt erkennen kann, wobei die clientseitige Verarbeitung im Browser mit der GPU erfolgt.

Sie können sie für alle clientseitigen GPU-basierten Arbeitslasten verwenden, von Modellen für maschinelles Lernen bis hin zu Grafik- und Spieletests.

Screenshot eines neuen Colab
Abbildung 7: Eine erfolgreiche Erfassung eines GPU-beschleunigten TensorFlow.js-Modells, das Kleidung clientseitig im Browser in Echtzeit erkennen kann

Ressourcen

Fügen Sie dem GitHub-Repository einen Stern hinzu, um zukünftige Updates zu erhalten.