Filloni me LiteRT.js

Ky është një udhëzues i plotë për LiteRT.js që mbulon procesin e konvertimit të një modeli PyTorch për t'u ekzekutuar në shfletues me përshpejtimin WebGPU. Ky shembull përdor ResNet18 për modelin e vizionit dhe TensorFlow.js për para- dhe pas-përpunim.

Udhëzuesi do të përfshijë hapat e mëposhtëm:

  1. Konvertoni modelin tuaj PyTorch në LiteRT duke përdorur AI Edge Torch . 1. Shtoni paketën LiteRT në aplikacionin tuaj web.
  2. Ngarko modelin.
  3. Shkruani logjikën para dhe pas përpunimit.

Konverto në LiteRT

Përdorni fletoren PyTorch Converter për të konvertuar një model PyTorch në formatin e duhur .tflite . Për një udhëzues të hollësishëm mbi llojet e gabimeve që mund të hasni dhe si t'i rregulloni ato, shihni AI Edge Torch Converter README .

Modeli juaj duhet të jetë i pajtueshëm me torch.export.export , që do të thotë se duhet të jetë i eksportueshëm me TorchDynamo. Prandaj, nuk duhet të ketë degë të kushtëzuara python që varen nga vlerat e kohës së ekzekutimit brenda tenzorëve. Nëse shihni gabimet e mëposhtme gjatë torch.export.export , modeli juaj nuk është i eksportueshëm me torch.export.export . Modeli juaj gjithashtu nuk duhet të ketë dimensione dinamike hyrëse ose dalëse në tenzorët e tij. Kjo përfshin dimensionin e grupit.

Mund të filloni edhe me një model PyTorch të pajtueshëm me TensorRT ose të eksportueshëm me ONNX:

  • Një version i një modeli i pajtueshëm me TensorRT mund të jetë një pikënisje e mirë, pasi disa lloje të konvertimeve TensorRT kërkojnë gjithashtu që modelet të jenë të eksportueshme nga TorchDynamo . Nëse përdorni ndonjë operacion NVIDIA / CUDA në model, do t'ju duhet t'i zëvendësoni ato me operacione standarde PyTorch.

  • Një model PyTorch i eksportueshëm nga ONNX mund të jetë një pikënisje e mirë, megjithëse disa modele ONNX përdorin TorchScript në vend të TorchDynamo për eksport, në të cilin rast modeli mund të mos jetë i eksportueshëm nga TorchDynamo (megjithëse ka të ngjarë të jetë më afër kodit origjinal të modelit).

Për më shumë informacion, shihni Konvertimi i modeleve PyTorch në LiteRT .

Shtoni paketën LiteRT

Instaloni paketën @litertjs/core nga npm:

npm install @litertjs/core

Importoni paketën dhe ngarkoni skedarët e saj Wasm:

import {loadLiteRt} from '@litertjs/core';

// Load the LiteRT.js Wasm files from a CDN.
await loadLiteRt('https://cdn.jsdelivr.net/npm/@litertjs/core/wasm/')
// Alternatively, host them from your server.
// They are located in node_modules/@litertjs/core/wasm/
await loadLiteRt(`your/path/to/wasm/`);

Ngarko modelin

Importoni dhe inicializoni LiteRT.js dhe shërbimet e konvertimit LiteRT-TFJS. Gjithashtu, duhet të importoni TensorFlow.js për të kaluar tenzorët te LiteRT.js.

import {CompileOptions, loadAndCompile, loadLiteRt, getWebGpuDevice} from '@litertjs/core';
import {runWithTfjsTensors} from '@litertjs/tfjs-interop';

// TensorFlow.js imports
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgpu';
import {WebGPUBackend} from '@tensorflow/tfjs-backend-webgpu';

async function main() {
  // Initialize TensorFlow.js WebGPU backend
  await tf.setBackend('webgpu');

  // Initialize LiteRT.js's Wasm files
  await loadLiteRt('your/path/to/wasm/');

  // Make TFJS use the same GPU device as LiteRT.js (for tensor conversion)
  const device = await getWebGpuDevice();
  tf.removeBackend('webgpu');
  tf.registerBackend('webgpu', () => new WebGPUBackend(device, device.adapterInfo));
  await tf.setBackend('webgpu');
  // ...
}

main();

Ngarko modelin LiteRT të konvertuar:

const model = await loadAndCompile('path_to_model.tflite', {
  accelerator: 'webgpu', // or 'wasm'
});

Shkruani tubacionin e modelit

Shkruani logjikën e para- dhe pas-përpunimit që lidh modelin me aplikacionin tuaj. Rekomandohet përdorimi i TensorFlow.js për para- dhe pas-përpunim, por nëse nuk është shkruar në TensorFlow.js, mund të thirrni await tensor.data për të marrë vlerën si një ArrayBuffer ose await tensor.array për të marrë një varg të strukturuar JS.

Më poshtë është një shembull i një tubacioni nga fillimi në fund për ResNet18:

// Wrap in a tf.tidy call to automatically clean up intermediate TensorFlow.js tensors.
// (Note: tidy only supports synchronous functions).
const imageData = tf.tidy(() => {
  // Get RGB data values from an image element and convert it to range [0, 1).
  const image = tf.browser.fromPixels(dogs, 3).div(255);

  // These preprocessing steps come from https://github.com/pytorch/vision/blob/main/torchvision/models/resnet.py#L315
  // The mean and standard deviation for the image normalization come from https://github.com/pytorch/vision/blob/main/torchvision/transforms/_presets.py#L38
  return image.resizeBilinear([224, 224])
    .sub([0.485, 0.456, 0.406])
    .div([0.229, 0.224, 0.225])
    .reshape([1, 224, 224, 3])
    .transpose([0, 3, 1, 2]);
});

// Run the model
const outputs = await runWithTfjsTensors(model, [imageData]);
const probabilities = outputs[0];

// Get the top five classes.
const top5 = tf.topk(probabilities, 5);

const values = await top5.values.data();
const indices = await top5.indices.data();

// Clean up TFJS tensors
tf.dispose(outputs);
tf.dispose(top5);
tf.dispose(imageData);

// Print the top five classes.
const classes = ... // Class names are loaded from a JSON file in the demo.
for (let i = 0; i < 5; ++i) {
  const text = `${classes[indices[i]]}: ${values[i]}`;
  console.log(text);
}

Testimi dhe zgjidhja e problemeve me teste dhe zgjidhje.

Referojuni seksioneve të mëposhtme mbi mënyrat për të testuar aplikacionin tuaj dhe për të trajtuar gabimet.

Testimi me të dhëna të rreme

Pas ngarkimit të një modeli, është mirë ta testoni modelin fillimisht me të dhëna të rreme. Kjo do të kapë çdo gabim gjatë kohës së ekzekutimit përpara se të shpenzoni kohë duke shkruar logjikën para dhe pas përpunimit për tubacionin e modelit tuaj. Për ta kontrolluar këtë, mund të përdorni Testuesin e Modelit LiteRT.js ose ta testoni manualisht.

Testuesi i Modelit LiteRT.js

Testuesi i Modelit LiteRT.js ekzekuton modelin tuaj në GPU dhe CPU duke përdorur të dhëna të rastësishme për të verifikuar që modeli funksionon siç duhet në GPU. Ai kontrollon sa vijon:

  • Nëse mbështeten llojet e të dhënave hyrëse dhe dalëse.
  • Nëse të gjitha operacionet janë të disponueshme në GPU.
  • Sa afër përputhen daljet e GPU-së me daljet referuese të CPU-së.
  • Performanca e përfundimit të GPU-së.

Për të ekzekutuar Testuesin e Modelit LiteRT.js, ekzekutoni npm i @litertjs/model-tester dhe pastaj npx model-tester . Do të hapë një skedë shfletuesi për të ekzekutuar modelin tuaj.

Testimi manual i modelit

Nëse preferoni ta testoni modelin manualisht në vend që të përdorni testuesin e modelit LiteRT.js ( @litertjs/model-tester ), mund të gjeneroni të dhëna të rreme dhe ta ekzekutoni modelin me runWithTfjsTensors .

Për të gjeneruar të dhëna të rreme, duhet të dini emrat dhe format e tenzorëve të hyrjes. Këto mund të gjenden me LiteRT.js duke thirrur model.getInputDetails ose model.getOutputDetails . Si alternativë, përdorni Model Explorer .

Pasi të dini format dhe emrat e hyrjes dhe daljes, mund ta testoni modelin me një hyrje të rreme. Kjo jep njëfarë besimi se modeli do të funksionojë përpara se të shkruani pjesën tjetër të tubacionit të të mësuarit automatik. Kjo do të testonte nëse të gjitha operacionet e modelit mbështeten. Për shembull:

// Imports, initialization, and model loading...
// Create fake inputs for the model
const fakeInputs = model.getInputDetails().map(
    ({shape, dtype}) => tf.ones(shape, dtype));

// Run the model
const outputs = await runWithTfjsTensors(model, fakeInputs);
console.log(outputs);

Llojet e gabimeve

Disa modele LiteRT mund të mos mbështeten nga LiteRT.js. Gabimet zakonisht bien në këto kategori:

  • Mospërputhja e formës : Një gabim i njohur që prek vetëm GPU-në.
  • Operacioni nuk mbështetet : Koha e ekzekutimit nuk mbështet asnjë operacion në model. Sfondi i WebGPU-së ka mbulim më të kufizuar sesa CPU-ja, kështu që nëse e shihni këtë gabim në GPU, mund të jeni në gjendje ta ekzekutoni modelin në CPU.
  • Lloji i Tensorit të Pambështetur : LiteRT.js mbështet vetëm tensorët int32 dhe float32 për hyrjet dhe daljet e modelit.
  • Modeli shumë i madh : LiteRT.js është i kufizuar në madhësinë e modeleve që mund të ngarkojë.

Operacioni nuk mbështetet

Kjo tregon që backend-i që po përdoret nuk mbështet një nga operacionet në model. Do t'ju duhet të rishkruani modelin origjinal PyTorch për të shmangur këtë operacion dhe ta rikonvertoni atë, ose mund të jeni në gjendje ta ekzekutoni modelin në CPU.

Në rastin e BROADCAST_TO , kjo mund të zgjidhet duke e bërë dimensionin e grupit të njëjtë për çdo tenzor hyrës në model. Raste të tjera mund të jenë më të ndërlikuara.

Lloji i Tensorit i Pambështetur

LiteRT.js mbështet vetëm tenzorët int32 dhe float32 për të dhënat hyrëse dhe dalëse të modelit.

Modeli është shumë i madh

Kjo zakonisht shfaqet si një thirrje për Aborted() ose një dështim i alokimit të memories në kohën e ngarkimit të modelit. LiteRT.js është i kufizuar në madhësinë e modeleve që mund të ngarkojë, kështu që nëse e shihni këtë, modeli juaj mund të jetë shumë i madh. Mund të provoni të kuantizoni peshat me ai-edge-quantizer , por mbajini llogaritjet në float32 ose float16, dhe modeloni hyrjet dhe daljet si float32 ose int32.