Skip to content

Epic: eegprep in the browser (Pyodide) with a small ONNX ICLabel #324

Description

@neuromechanist

@arnodelorme requesting your approval on scope. Sub-issues are filed and listed below; scope corrections found while grounding the plan against the code are flagged in a comment.

Why

NEMAR's assistant will write and run eegprep code in the user's browser under Pyodide, with nothing computed server-side (nemarOrg/nemar-cli#1292, ADR 0049; design note OpenScience-Collective/osa#351). eegprep's algorithms are already pure Python. What blocks a browser install is a set of declared dependencies with no WebAssembly build, and ICLabel being torch-only. A small ONNX ICLabel also makes the classifier deployable anywhere, with or without Python.

Phases

Epic branch: epic/324-pyodide-browser. Phase PRs target that branch; the final epic PR targets develop.

Phase Issue Depends on
1. Move oct2py, psutil, pyedflib out of the base install #374 none
2. Pyodide harness, CI, and the ICA benchmark gate #375 1
3. Route runica matmuls through scipy BLAS under Emscripten #376 2
4. Export ICLabel to ONNX and add the native onnxruntime backend #377 none
5. Browser ICLabel via ONNX Runtime Web with an await-able entry point #378 2, 4
6. Quantize ICLabel to int8 with a committed parity report #379 4

Two streams run in parallel: the dependency and BLAS stream is 1 then 2 then 3, and the ICLabel stream is 4 then 5 and 6. Phase 4 can start immediately alongside phase 1.

Phase 2 is a go/no-go gate. It produces the numbers that decide whether picard keeps its advantage in the browser and whether the BLAS routing in phase 3 is worth a code change.

Parity definition

On a fixed held-out set of real independent components from public NEMAR datasets:

  • Top-1 label agreement with the float32 reference at or above 95 percent.
  • Keep or reject decision agreement under eegprep's thresholds at or above 99 percent.
  • Per-class agreement reported, so rare classes are not averaged away.

Out of scope

Feature extraction, input normalization, and softmax stay float. No numerical change anywhere else. No server-side execution.

Decisions

  1. Scope and extras names. Pending your approval. Extras are [eeglab] for oct2py and [sys] for psutil; [formats] is an open question because nothing imports pyedflib (see Phase 1: Move oct2py, psutil, and pyedflib out of the base install #374).
  2. Browser default ICA: picard, with runica available. Recorded. Phase 2's benchmark can overturn this if picard's iteration advantage does not survive a single WebAssembly thread.
  3. int8 ships as the default artifact everywhere, native and browser. Recorded. One artifact, one set of numbers to validate. This makes phase 6's parity report the thing that earns the default for every user, not just browser users.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or requestepicMulti-phase implementation epic

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions