Web AI-Modelltests in Google Colab

François Beaufort
François Beaufort

Das Einrichten einer konsistenten Testumgebung mit GPUs kann schwieriger als erwartet sein. Im Folgenden finden Sie die Schritte zum Testen clientseitiger, browserbasierter KI-Modelle in echten Browserumgebungen, die dabei skalierbar und automatisierbar sind und im Rahmen einer bekannten standardisierten Hardwarekonfiguration erfolgen.

In diesem Fall ist der Browser ein echter Chrome-Browser mit Hardwareunterstützung statt Softwareemulation.

Dieser Leitfaden ist für Sie geeignet, ganz gleich, ob Sie Web-KI-, Web-Gaming- oder Grafikentwickler sind oder sich für das Testen von Web AI-Modellen interessieren.

Schritt 1: Neues Google Colab-Notebook erstellen

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

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

  1. Klicken Sie oben rechts im Notebook auf Verbinden .
  2. Wählen Sie Laufzeittyp ändern aus:
    Screenshot, der die Schritte zum Ändern der Laufzeit zeigt
    Abbildung 2: Laufzeit in der Colab-Oberfläche ändern.
  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 zur Laufzeit herzustellen. Nach einiger Zeit werden auf der Schaltfläche ein grünes Häkchen sowie Diagramme zur RAM- und Festplattennutzung angezeigt. Dies bedeutet, dass ein Server mit der erforderlichen Hardware erfolgreich erstellt wurde.

Gut gemacht! Sie haben gerade einen Server mit einer angehängten GPU erstellt.

Schritt 3: Korrekte 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 Ausführung der Befehlszeile 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
    Abbildung 4

  3. Sobald der Code ausgeführt wurde, prüfen Sie, ob nvidia-smi ähnlich wie im folgenden Screenshot ausgegeben wurde. So können Sie prüfen, ob eine GPU angehängt ist und auf Ihrem Server erkannt wird. Eventuell müssen Sie nach vorne scrollen, um diese Ausgabe zu sehen.

    Abbildung 5: Suchen Sie die 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 Ihren benutzerdefinierten Code schreiben, um ein Node.js-Projekt mit Ihren bevorzugten Parametern aufzurufen (oder einfach google-chrome-stable direkt in der Befehlszeile aufrufen). Im Folgenden finden Sie Beispiele für beide.

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 wurde die resultierende PDF-Erfassung in /content/gpu.pdf gespeichert. Maximieren Sie den Inhalt , um diese Datei anzusehen. Klicken Sie dann auf , um die PDF-Datei auf Ihren lokalen Computer herunterzuladen.

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

Teil B: Chrome mit Puppeteer befehligen

Wir haben ein minimalistisches Beispiel mit 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.

Aufschlüsselung des Node.js-Codes von jPuppet.js

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 Knotenanwendung übergeben wurden. Das dritte Argument muss festgelegt sein, das eine URL darstellt, zu der Sie navigieren möchten. Sie müssen sich hier das dritte Argument genauer ansehen, da die ersten beiden Argumente Node selbst und das Skript aufrufen, das wir ausführen. Das dritte Element enthält tatsächlich den ersten Parameter, der an das Node-Programm übergeben wurde:

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

Definieren Sie nun eine asynchrone Funktion mit dem Namen runWebpage(). Dadurch wird ein Browserobjekt erstellt, das mit den Befehlszeilenargumenten konfiguriert ist, um die Chrome-Binärdatei so auszuführen, wie es erforderlich ist, damit 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 Event-Listener hinzu, der console.log-Ereignisse überwacht, wenn die Webseite JavaScript ausführt. Auf diese Weise können Sie Nachrichten in der Node-Befehlszeile protokollieren und den Konsolentext auf eine spezielle Wortgruppe (in diesem Fall captureAndEnd) prüfen, die einen Screenshot auslöst und dann den Browserprozess in Node beendet. Dies ist nützlich für Webseiten, die etwas Arbeit erfordern, bevor ein Screenshot erstellt werden kann, und die eine nicht deterministische Ausführungszeit haben.

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

Abschließend können Sie der Seite den Befehl geben, die angegebene URL aufzurufen, und einen ersten Screenshot erstellen, sobald die Seite geladen ist.

Wenn Sie einen Screenshot von chrome://gpu erstellen, 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 werden. Andernfalls erhalten Sie eine 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. Puppeteer erleichtert die programmatische Schnittstelle mit Chrome.

Abgeschlossen

Wir können jetzt überprüfen, ob der TensorFlow.js Fashion MNIST-Klassifikator eine Hose in einem Bild korrekt erkennt. Die clientseitige Verarbeitung im Browser erfolgt über die GPU.

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: Erfolgreiche Erfassung eines GPU-beschleunigten TensorFlow.js-Modells, das clientseitig Kleidung im Browser in Echtzeit erkennen kann

Ressourcen

Markieren Sie das GitHub-Repository, um zukünftige Updates zu erhalten.