Skip to content

Implementation Plan: Prototype Redesign

This document outlines the redesign of the prototype's pipeline system to support maximum user freedom across all configuration layers, re-enable ONNX Runtime, add LiteRT.js, and enable framework overhead measurement.


Terminology

Precise naming avoids confusion across the four browser ML runtimes:

Term Definition Examples
Task The ML problem type Image Classification, Object Detection, Pose Estimation
Model The neural network architecture (not the file format) MobileNet v2, SqueezeNet 1.1, EfficientNet-Lite0
Runtime The low-level inference engine that executes model graphs on hardware ORT Web, TF.js, LiteRT.js
Framework Optional wrapper around a runtime that adds preprocessing, model discovery, or a friendlier API Transformers.js (wraps ORT), MediaPipe Tasks (wraps LiteRT), ml5.js (wraps TF.js)
Backend The hardware accelerator used by the runtime WASM, WebGPU, WebGL, CPU
Dataset The input data for inference Sample images, user-uploaded images

Runtime vs Framework

A runtime is a self-contained inference engine with its own model format and backend system. A framework is a wrapper that depends on a runtime underneath:

Runtime Model format Under the hood Framework wrappers
ORT Web .onnx C++ ORT → WASM Transformers.js
TF.js model.json + .bin JS kernels + WASM/XNNPACK ml5.js
LiteRT.js .tflite C++ LiteRT → WASM + XNNPACK MediaPipe Tasks

ml5.js is included as a TF.js framework wrapper to enable symmetric overhead measurement across all three runtimes.

Model format is determined by runtime

Model ORT Web TF.js LiteRT.js MediaPipe Tasks
MobileNet v2 .onnx model.json (CDN) .tflite
SqueezeNet 1.1 .onnx .tflite
EfficientNet-Lite0 .tflite .tflite (GCS)

All models load from CDN — no local files in the repository.


Pipeline order

The user configures selections in dependency order. Each step constrains what follows:

Task → Model → Runtime → Framework → Backend → Dataset → Run

Step Why this position What it constrains
Task Always first — determines which models exist Available models
Model Architecture choice determines which runtimes can run it (format compatibility) Available runtimes
Runtime Low-level engine determines available frameworks and backends Available frameworks and backends
Framework Wrapper layer — optional, determines overhead measurement None (optional layer)
Backend Hardware accelerator, filtered by runtime COMPAT matrix Execution hardware
Dataset Independent of all above — the input to inference None
Run Execute the configured pipeline

Cascade rules

When a user changes a selection, downstream selections are cleared:

Changed Clears
Task Model, Runtime, Framework, Backend, Dataset
Model Runtime, Framework, Backend
Runtime Framework, Backend
Framework Backend
Backend (nothing)
Dataset (nothing)

Block system redesign

6 layers (up from 5)

Block Label Icon Options
Task Task 🎯 Image Classification (enabled), Object Detection, Segmentation, Pose (disabled)
Model Model 🧠 MobileNet v2, SqueezeNet 1.1, EfficientNet-Lite0
Runtime Runtime ⚙️ ORT Web, TF.js, LiteRT.js
Framework Framework 📦 "Direct" (no wrapper) or framework wrapper — varies by runtime
Backend Backend 🖥️ WASM, WebGPU, WebGL, CPU — filtered by runtime COMPAT matrix
Dataset Dataset 🗃️ 5 sample images + upload

Framework options by runtime

Runtime Framework options
ORT Web "Direct (ORT Web)", "Transformers.js"
TF.js "Direct (TensorFlow.js)", "ml5.js"
LiteRT.js "Direct (LiteRT.js)", "MediaPipe Tasks"

When "Direct" is selected, the adapter calls the runtime API directly. When a framework wrapper is selected, the adapter uses the framework's higher-level API.

Model × Runtime availability

The MODEL_REGISTRY maps architecture → runtime → CDN URL. If a model is not available for a runtime, that runtime is greyed out in the UI.

Model ORT Web TF.js LiteRT.js MediaPipe Tasks
MobileNet v2 ✅ HuggingFace CDN @tensorflow-models/mobilenet CDN ✅ TF Hub .tflite
SqueezeNet 1.1 ✅ HuggingFace CDN ✅ TF Hub .tflite
EfficientNet-Lite0 ✅ GCS .tflite ✅ GCS .tflite

Framework overhead measurement

The prototype enables direct comparison: same model, same runtime, with vs without framework wrapper.

Comparison Direct (runtime) With wrapper What it measures
ORT overhead ort.InferenceSession.create() Transformers.js pipeline() Model discovery + preprocessing overhead
TF.js overhead TF.js mobilenet.load() ml5.js ml5.imageClassifier() API abstraction overhead
LiteRT.js overhead LiteRT.js direct API MediaPipe Tasks ImageClassifier Task-specific API overhead

This gives 6 benchmark combinations (3 runtimes × 2 modes) for a clean overhead comparison table in the thesis.


Runtime and adapter changes

New runtime: LiteRT.js

LiteRT.js (released July 9, 2026) is Google's JavaScript binding of the LiteRT C++ runtime via WASM. It loads .tflite models and supports WebGPU, WASM+XNNPACK, and WebNN backends.

Property Value
CDN https://cdn.jsdelivr.net/npm/@anthropic-ai/litert.js (or equivalent)
Model format .tflite
Backends WASM+XNNPACK, WebGPU, WebNN
Relationship to TF.js Successor — Google positions it as the "performance evolution from TensorFlow.js"
Relationship to MediaPipe MediaPipe Tasks wraps LiteRT internally

Updated adapter list

Adapter Wraps Model format Status
TFJSAdapter TF.js (self-contained) model.json via CDN ✅ Existing — keep as-is
ONNXAdapter ORT Web .onnx via HuggingFace CDN 🔧 Fix — set CDN URL, remove null check
LiteRTAdapter LiteRT.js .tflite via CDN 🆕 New adapter
MediaPipeAdapter MediaPipe Tasks (wraps LiteRT) .tflite via GCS ✅ Existing — keep as-is
TransformersAdapter Transformers.js (wraps ORT) .onnx via HuggingFace ✅ Existing — keep as-is
ML5Adapter ml5.js (wraps TF.js) model.json via CDN 🆕 New adapter

COMPAT matrix update

export const COMPAT = {
  ort: {
    webgpu: { supported: true, hw: ["GPU"] },
    wasm:   { supported: true, hw: ["CPU"] },
    webgl:  { supported: false, reason: "ORT dropped WebGL support" },
    cpu:    { supported: false, reason: "Use WASM instead" },
  },
  tfjs: {
    webgl:  { supported: true, hw: ["GPU"] },
    webgpu: { supported: true, hw: ["GPU"] },
    wasm:   { supported: true, hw: ["CPU"] },
    cpu:    { supported: true, hw: ["CPU"] },
  },
  litert: {
    webgpu: { supported: true, hw: ["GPU"] },
    wasm:   { supported: true, hw: ["CPU"] },
    webgl:  { supported: false, reason: "LiteRT.js uses WebGPU, not WebGL" },
    cpu:    { supported: false, reason: "Use WASM instead" },
  },
};

Model registry

The MODEL_REGISTRY is the source of truth for which models exist and where to load them from.

const MODEL_REGISTRY = {
  "mobilenet-v2": {
    label: "MobileNet v2",
    description: "Fast, general-purpose image classifier (13 MB)",
    inputSize: 224,
    runtimePaths: {
      ort:    "https://huggingface.co/onnxmodelzoo/mobilenetv2-12/resolve/main/mobilenetv2-12.onnx",
      tfjs:   null,  // loaded via @tensorflow-models/mobilenet CDN package, not a URL
      litert: "https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/classification/5/converted_default/1",
    },
  },
  "squeezenet-1.1": {
    label: "SqueezeNet 1.1",
    description: "Tiny model, fastest load, lower accuracy (~5 MB)",
    inputSize: 224,
    runtimePaths: {
      ort:    "https://huggingface.co/onnxmodelzoo/squeezenet11/resolve/main/squeezenet11.onnx",
      litert: "https://tfhub.dev/google/squeezenet/1.0/classification/1/converted_default/1",
    },
  },
  "efficientnet-lite0": {
    label: "EfficientNet-Lite0",
    description: "Balanced accuracy and speed (~4 MB)",
    inputSize: 224,
    runtimePaths: {
      mediapipe: "https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite",
      litert:    "https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite",
    },
  },
};

Note: The TF.js adapter loads MobileNet via the @tensorflow-models/mobilenet CDN package (not a direct URL), so its runtimePaths entry is null — the adapter handles loading internally.


UI behavior

Model layer

When the user opens the Model layer, all three models are shown. After selecting a model, incompatible runtimes are greyed out with an explanation:

MobileNet v2    ✅ Click to select
SqueezeNet 1.1  ✅ Click to select
EfficientNet-Lite0  ✅ Click to select

After selecting "MobileNet v2", the Runtime layer shows:

ORT Web       ✅ .onnx (HuggingFace CDN)
TF.js         ✅ model.json (CDN)
LiteRT.js     ✅ .tflite (TF Hub)
MediaPipe     ❌ No model available — use EfficientNet-Lite0

Framework layer

After selecting a runtime, the Framework layer shows wrapper options:

[ORT Web selected]
Direct (ORT Web)     — No wrapper overhead
Transformers.js      — Wraps ORT, adds model discovery + preprocessing

[TF.js selected]
Direct (TF.js)       — No wrapper overhead
ml5.js               — Wraps TF.js, friendly API for creative coding

[LiteRT.js selected]
Direct (LiteRT.js)   — No wrapper overhead
MediaPipe Tasks       — Wraps LiteRT, task-specific API

Backend layer

After selecting a runtime, backends are filtered by the COMPAT matrix (existing behavior, extended for 3 runtimes).


Files to modify

File Changes
js/pipeline.js Add MODEL_REGISTRY, FRAMEWORK_REGISTRY; restore model selection cards; add framework layer; update COMPAT matrix for 3 runtimes; update PipelineState for 6 layers; update PipelineCanvas rendering
js/ml-adapter.js Fix ONNX adapter CDN URL; add LiteRTAdapter class; add ML5Adapter class; update AdapterFactory for 5 adapters; make model loading use registry URLs; add framework-aware adapter selection
js/tutorial.js Update steps to: Task → Model → Runtime → Framework → Backend → Dataset → Run
js/playground.js Update to use 6-layer pipeline; add framework selection
js/bench.js No changes needed — already generic
index.html Update layer bar if needed
css/main.css Add styles for framework layer if needed

Implementation phases

Phase 1: Fix ONNX and restore model selection

  1. Set ONNX_MODEL_URL to HuggingFace CDN URL
  2. Remove the null check and early throw in ONNXAdapter.load()
  3. Update COMPAT.onnxCOMPAT.ort with correct supported backends
  4. Restore interactive model selection cards in _renderModelCards()
  5. Add MODEL_REGISTRY with CDN URLs for all models × runtimes
  6. Filter runtime cards based on selected model

Phase 2: Add LiteRT.js runtime

  1. Implement LiteRTAdapter class (load .tflite from CDN, WASM+XNNPACK backend)
  2. Add LiteRT.js to COMPAT matrix
  3. Add LiteRT.js to runtime options in LayerRegistry
  4. Add CDN URLs for .tflite models to MODEL_REGISTRY

Phase 3: Add framework layer

  1. Add FRAMEWORK_REGISTRY with per-runtime framework options
  2. Implement _renderFrameworkCards() in PipelineCanvas
  3. Add framework selection to PipelineState (6th field)
  4. Implement ML5Adapter class (wrap ml5.imageClassifier())
  5. Update AdapterFactory to return framework-aware adapters
  6. Update cascade rules (runtime change clears framework + backend)

Phase 4: Update tutorial and playground

  1. Update tutorial.js steps to match new pipeline order
  2. Update playground.js to use 6-layer pipeline
  3. Test all 6 benchmark combinations (3 runtimes × 2 modes)
  4. Update result display to show framework name alongside runtime

Phase 5: Polish and verify

  1. Verify all CDN URLs work (ORT models from HuggingFace, .tflite from TF Hub/GCS)
  2. Test model × runtime filtering (greyed out cards with reasons)
  3. Test cascade behavior (changing model clears runtime, etc.)
  4. Test framework overhead measurement (direct vs wrapper comparison)
  5. Update documentation (index.md, architecture.md)

CDN sources for models

Model Format CDN URL
MobileNet v2 .onnx https://huggingface.co/onnxmodelzoo/mobilenetv2-12/resolve/main/mobilenetv2-12.onnx
MobileNet v2 model.json Loaded via @tensorflow-models/mobilenet CDN package
MobileNet v2 .tflite https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/classification/5/converted_default/1
SqueezeNet 1.1 .onnx https://huggingface.co/onnxmodelzoo/squeezenet11/resolve/main/squeezenet11.onnx
SqueezeNet 1.1 .tflite https://tfhub.dev/google/squeezenet/1.0/classification/1/converted_default/1
EfficientNet-Lite0 .tflite https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite

Thesis benchmark combinations

With all 3 runtimes × 2 modes (direct + framework wrapper), the prototype produces these benchmark rows:

# Runtime Framework What it measures
1 ORT Web Direct Baseline ORT inference
2 ORT Web Transformers.js Transformers.js wrapper overhead
3 TF.js Direct Baseline TF.js inference
4 TF.js ml5.js ml5.js wrapper overhead
5 LiteRT.js Direct Baseline LiteRT.js inference
6 LiteRT.js MediaPipe Tasks MediaPipe task API overhead

For each combination, the user selects: model (MobileNet v2, SqueezeNet, or EfficientNet-Lite0) and backend (WASM, WebGPU, etc.), then runs inference on an input image.