4 min readfrom Machine Learning

PrintGuard 2.0 — ShuffleNetV2 + few-shot prototypical network, TFLite via LiteRT, ≈5 MB, runs unmodified in the browser (Pyodide) and on CPython [P]

Hi everyone,

I shared PrintGuard here about a year ago as a few-shot FDM failure detector built on a ShuffleNetV2 backbone classified by a prototypical network — the model from my dissertation, packaged with a hub and a web UI. v2.0 ships today and is a complete rewrite of everything around the model, so I wanted to walk you through what's changed and what hasn't.

What hasn't changed is the model. It's still a ShuffleNetV2 encoder classified by nearest prototype, trained for few-shot FDM fault detection in Edge-FDM-Fault-Detection (with a technical write-up in the repo). What has changed is the runtime: the model is now a ≈5 MB TFLite export via LiteRT, classified by nearest prototype, with per-printer sensitivity and threshold sliders that map directly onto the prototype distances — so you can tune for camera and lighting without retraining.

The interesting bit for this sub is the architecture around the model. v2.0 is a single Python engine that runs unmodified on CPython (hub mode) and on Pyodide in the browser (local mode). Everything mode-specific is confined to one Platform implementation per runtime — the two modes cannot drift apart because they execute the same files. The methods on the Platform contract are exactly the ones that aren't portable: infer(rgb), discover_cameras(), open_camera(id, source), http(...), encode_jpeg(rgb), load_state / save_state. On the CPython side, infer is ai-edge-litert on CPU threads, discover_cameras walks the MediaMTX path list, and open_camera is a PyAV reader thread per RTSP stream. On the browser side, infer is LiteRT.js in WASM via a JS bridge, discover_cameras is enumerateDevices(), and open_camera is getUserMedia + canvas grabs.

The UI is presentation-only and speaks one JSON command/event protocol — over a WebSocket in hub mode, over an in-page Pyodide bridge in local mode. The engine cannot tell which transport it is on. No mode-specific logic lives anywhere else; if a feature needs a runtime service, it extends the Platform contract on both sides.

Inference scheduling is fully dynamic and fairness-aware:

  1. A smoothed estimate of observed inference latency continuously yields the sustainable total rate (workers / latency).
  2. That capacity is water-filled across in-use cameras (max-min fairness): no camera is allocated beyond its native fps, and surplus flows to cameras that can use it.
  3. A free worker takes the most overdue camera and grabs its freshest frame at dispatch time. Frames carry a sequence identity, so the same frame is never inferred twice, and results always describe the present, not a backlog.

On RTSP, MediaMTX bursts the buffered GOP on connect, so stream fps is trusted from the SDP average_rate where available, and measured only after a warm-up otherwise.

The defect pipeline is a monitor on top of a per-printer score stream. score ≥ threshold for N consecutive frames triggers the configured action (alert only, pause, or cancel) on the linked OctoPrint or Moonraker service, with retries on failure; the alert event carries the action and its outcome, the UI error feed gets a copy, and the snapshot goes out to every enabled notification channel (ntfy, Telegram, Discord).

The fail-safe behaviour is the part I most want feedback on, because I have strong opinions about it. A printer's watching state gates inference:

Linked service reports Watched? Why
no service linked yes nothing to gate on
printing yes the job needs eyes
no state yet / unknown yes can't tell → watch
offline (unreachable) yes losing the signal must not stop monitoring
idle / paused / error no (standby) positively not printing

Only a positive "not printing" stands inference down. The watchdog then warns on the dashboard and through notification channels when a camera drops, a feed freezes or a printer service stops answering, and a failed pause is announced, never swallowed. I'd be very interested to hear how this stance interacts with people who run multiple printers with mixed reliability on their printer services.

There's a live browser demo (the whole engine in Pyodide + LiteRT.js WASM), the Docker image is multi-arch, and the architecture doc goes into all of the above in more detail with diagrams of the engine layout and the defect pipeline.

This is a major version — nothing from 1.x migrates, and a 2.0 hub starts from a fresh configuration. Issues, especially around the fairness scheduler, the CORS / mixed-content / host.docker.internal edge cases, and the LiteRT ↔ Pyodide bridge, are very welcome. Let's keep failure detection open-source, local and accessible for all.

submitted by /u/oliverbravery
[link] [comments]

Want to read more?

Check out the full article on the original site

View original article

Tagged with

#no-code spreadsheet solutions
#financial modeling with spreadsheets
#natural language processing for spreadsheets
#self-service analytics tools
#generative AI for data analysis
#Excel alternatives for data analysis
#self-service analytics
#automated anomaly detection
#rows.com
#AI-native spreadsheets
#real-time data collaboration
#cloud-native spreadsheets
#real-time collaboration
#PrintGuard
#ShuffleNetV2
#Prototypical Network
#TFLite
#LiteRT
#Pyodide
#CPython