DEV Community

Gnana-Shishir-Kumar
Gnana-Shishir-Kumar

Posted on

EndoSeg: What We Built, What We Didn't, and Why the Overlay Lies a Little

EndoSeg was built for the Nebius Serverless AI Builders Challenge

Team

What We Built

An estimated 1 in 10 women of reproductive age has endometriosis. The average time from first symptoms to diagnosis is still measured in years, and ultrasound is one of the few tools that can catch it early — if someone reviews the scan carefully. Most segmentation tools that try to help either run in a cloud you have to trust with a patient's pelvic ultrasound, or ship a black-box "AI diagnosis" that overstates what a pixel mask can actually tell you.

We built EndoSeg — a gynecological ultrasound segmentation tool that fine-tunes a lesion segmenter on Nebius Serverless GPU Jobs, exports it to ONNX, and then runs inference entirely in the browser. The scan never leaves the device unless the user explicitly opts in to a cloud comparison.

Just as important: We are shipping this with an honest account of what the model does and doesn't know. It segments lesion-like pixels. It does not diagnose endometriosis. That distinction is the whole point of this writeup.

What it does:

  • 🔬 Browser-side lesion segmentation — ONNX Runtime Web (WebGPU → WASM fallback) runs the fine-tuned U-Net locally in a Web Worker, so a scan can be reviewed with zero data leaving the device
  • ☁️ Optional cloud compare — a Nebius Serverless Endpoint serves the same model behind a token-hiding proxy, so a user can voluntarily check local vs. cloud mask agreement
  • ⚙️ Full training pipeline on Nebius Jobs — three chained GPU/CPU jobs (preprocess → fine-tune → ONNX export + parity check) trained on the MMOTU ultrasound dataset
  • 📊 Transparent metrics, not vibes — reported Dice/IoU on val and test splits, plus per-sample variance, instead of a single flattering aggregate number
  • 🚫 No overclaiming by design — the UI cannot output "endometrioma," "chocolate cyst," or any disease probability from the network, because the model was never trained to produce one
  • 🩺 Explicit scope disclaimer — research/education only, not a medical device, does not replace clinician review

Demo

Show Me the Code

https://github.com/Gnana-Shishir-Kumar/nebius-challenge

How We Used Nebius

Nebius Serverless isn't a side detail here — it's the entire training and (optional) serving path. Here's the full pipeline:

MMOTU ultrasound dataset (1,469 frames)
        ↓
  Nebius Job N1 — preprocess (CPU)
  binarizes 8 MMOTU class masks → single lesion/background mask
        ↓
  Nebius Job N2 — U-Net fine-tune (GPU, Dice + BCE loss, 50 epochs)
        ↓
  Nebius Job N3 — ONNX export + parity check
        ↓
  Static browser app (ONNX Runtime Web)
  ├── Default path: local inference in a Web Worker (WebGPU → WASM)
  └── Opt-in path: Nebius Serverless Endpoint + token-hiding proxy
                   ("Compare to cloud" button)
Enter fullscreen mode Exit fullscreen mode

Nebius services used:

Serverless Jobs — the core of the training pipeline. Job N1 binarizes MMOTU's 8 tumor-type class masks down to a single foreground/background mask (the PRD scoped this as binary lesion segmentation, not tumor-type classification). Job N2 fine-tunes a U-Net on GPU with a combined Dice + BCE loss over 50 epochs. Job N3 exports the trained weights to ONNX and runs a parity check between the PyTorch and ONNX outputs before anything ships to the browser.

Serverless Endpoint — powers the optional "Compare to cloud" feature. Rather than exposing raw model access, requests go through a token-hiding proxy, so the browser app never holds a credential capable of hitting Nebius directly. This is used purely for a local-vs-cloud mask agreement check, not as the primary inference path.

GPU compute for fine-tuning — the U-Net training run (Job N2) is the one step that actually needs a GPU; everything downstream (preprocess, export, browser inference) runs on CPU or client hardware, which kept the compute footprint deliberately small.

Why browser-side inference matters

Most medical-image tools in this space — and most prior segmentation entries in Nebius's own healthcare track — treat the cloud as the default: upload an image, get a mask back. That's a reasonable pattern for most imaging, but pelvic ultrasound is different — it's a category of data people are understandably wary of sending anywhere.

EndoSeg flips the default:

  • The model weights are fetched once and cached; every subsequent inference happens locally in a Web Worker
  • Images never touch a server unless the user explicitly clicks "Compare to cloud"
  • The Nebius Endpoint exists as an opt-in verification step, not a requirement to use the tool

This is the structural differentiator versus prior bio/healthcare-track winners I looked at before building: privacy isn't a footnote, it's the architecture.

The honesty problem this solves

Here's the harder thing I want to be upfront about, because it's more important than the architecture: it would have been easy to make EndoSeg look like it does more than it does.

What the UI could show What the model actually outputs
Teal overlay, Dice score, agreement %, "max probability" A per-pixel lesion-vs-background mask
"Endometrioma / Chocolate Cyst" style labels Nothing from the network — this would be a JS shape heuristic, not a classifier
Cloud vs. local "agreement" Mask overlap between two segmenters, not diagnostic truth

There is no code path in EndoSeg that computes P(endometriosis), healthy vs. diseased, or endometrioma vs. other-cyst from learned class labels. MMOTU's 8 class IDs are discarded at preprocessing (mask > 0). If a healthy ovary scan still produces a finding-like overlay, that's expected behavior of a segmenter, not a bug in a diagnostic tool — because it was never built to be the latter.

Numbers that we stand behind, trained on MMOTU (1,469 frames), 50 epochs:

Split Dice IoU
Val (best @ epoch 33) 0.764 0.670
Test 0.755 0.655

Caveats that matter: per-sample Dice on held-out test images ranged from 0.02 to 0.97 — medium/large lesions segment well, small/thin ones sometimes get a confident but wrong "typical blob." Aggregate Dice hides that spread. Also, this MMOTU mirror has no recoverable patient IDs, so the split is stratified by file, not strictly patient-disjoint.

Data sources

Trained and evaluated on the MMOTU (Multi-Modality Ovarian Tumor Ultrasound) public dataset, 1,469 annotated frames across 8 original tumor-type classes, collapsed to a binary lesion mask for this MVP.

Tech Stack

  • Training/serving infra: Nebius Serverless Jobs (preprocess, fine-tune, export), Nebius Serverless Endpoint (optional cloud compare)
  • Model: U-Net, Dice + BCE loss, exported to ONNX
  • Inference: ONNX Runtime Web, WebGPU with WASM fallback, running in a Web Worker
  • Frontend: Static browser app, no server-side dependency for the default path
  • Dataset: MMOTU (ultrasound, 8-class → binarized to lesion/background)

Research/education only. EndoSeg is not a medical device. It does not diagnose endometriosis, score disease risk, or replace imaging review by a clinician.

Top comments (0)