Support all Cellpose v4 models (SAM + DINO) in GPU-resident segmentation#51
Conversation
Rename the GPU-resident entry point to segment_cellpose and cover every Cellpose v4 model -- the SAM backbone (cpsam, cpsam_v2) and the DINOv3 backbones (cpdino, cpdino-vitb). The backbones differ only in the default tile size (256 for sam_vitl, 384 for dino_*) and share the (flow, style) forward contract, so the resident path needs only to expose bsize and thread it through _run_net_gpu, with cellpose's sam_vitl->256 guard. segment_cpsam is kept as a deprecated alias (warns, slated for removal after 0.8). Parity tests confirm resident masks match stock CellposeModel.eval (AP >= 0.95) for all four models in 2D and 3D. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The DINO models (cpdino, cpdino-vitb) and cpsam_v2 first ship in cellpose 4.2.0, and the DINO backbones additionally need the dinov3 dependency from cellpose's `dino` extra. Bump the base cellpose extra to >=4.2.0 and add a cellpose-dino extra (cubic[cellpose] + cellpose[dino]>=4.2.0), documenting both install paths in the README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The default tile size (256 for SAM, 384 for DINO) and the SAM-pinned-to-256 guard were encoded separately in _run_net_gpu and segment_cellpose -- two sources of truth for the same backbone->tile-size rule. Extract _resolve_bsize to own both; segment_cellpose resolves bsize once and passes the concrete value down, so _run_net_gpu no longer needs the backbone argument. Replace the GPU-only bsize-guard test with a fast pure-function unit test that covers the full resolution matrix (defaults per backbone + the SAM guard), removing a heavyweight model load for a string-compare assertion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The GPU parity tests each constructed their own CellposeModel, reloading the same weights repeatedly (cpsam alone was built ~8 times). Add a module-scoped factory fixture that caches one model per backbone and route every GPU test through it. eval/segment_cellpose are read-only inference, so a shared instance is safe; the fixture is lazy, so no-GPU/no-cellpose runs never construct a model and free VRAM on teardown. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First alpha of the 0.8 cycle, which adds DINO-model support to the GPU-resident segmentation path and deprecates segment_cpsam. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reviewer's GuideExtends the GPU-resident Cellpose segmentation path to a unified segment_cellpose entry point that supports all Cellpose v4 backbones (SAM and DINO), centralizes tile-size handling via a _resolve_bsize helper, adds a deprecated segment_cpsam alias, and updates tests, packaging, and docs accordingly. Sequence diagram for unified GPU-resident Cellpose v4 segmentationsequenceDiagram
actor User
participant segment_cpsam
participant segment_cellpose
participant _resolve_bsize
participant _run_net_gpu
participant CellposeModel_net as CellposeModel.net
alt [User calls segment_cpsam]
User->>segment_cpsam: segment_cpsam(model, x, ...)
segment_cpsam->>segment_cpsam: warnings.warn(...)
segment_cpsam->>segment_cellpose: segment_cellpose(model, x, ...)
else [User calls segment_cellpose]
User->>segment_cellpose: segment_cellpose(model, x, bsize, ...)
end
segment_cellpose->>segment_cellpose: _check_gpu_precondition(model)
segment_cellpose->>_resolve_bsize: _resolve_bsize(model.backbone, bsize)
_resolve_bsize-->>segment_cellpose: bsize
segment_cellpose->>_run_net_gpu: _run_net_gpu(model.net, x, bsize=bsize, ...)
_run_net_gpu->>CellposeModel_net: _forward_gpu(net, ...)
CellposeModel_net-->>_run_net_gpu: flow, style
_run_net_gpu-->>segment_cellpose: dP, cellprob, styles
segment_cellpose-->>User: masks, [None, dP, cellprob], styles
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
_resolve_bsize, any non-sam_vitlbackbone implicitly falls through to the DINO default (384 or the providedbsize); consider making the set of supported backbones explicit (and raising for unknown ones) so that future Cellpose backbones don’t silently inherit DINO behavior.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `_resolve_bsize`, any non-`sam_vitl` backbone implicitly falls through to the DINO default (384 or the provided `bsize`); consider making the set of supported backbones explicit (and raising for unknown ones) so that future Cellpose backbones don’t silently inherit DINO behavior.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR generalizes cubic’s GPU-resident Cellpose (v4) segmentation path to support both SAM- and DINO-backed models, making segment_cellpose the canonical entry point while retaining segment_cpsam as a deprecated alias for backward compatibility.
Changes:
- Introduces
segment_cellpose(GPU-resident) with backbone-aware tile-size resolution via_resolve_bsize, and keepssegment_cpsamas a deprecated forwarding alias. - Expands the GPU parity test suite to cover additional v4 models (SAM v2 + DINO variants), including 3D and
bsizeoverride coverage, and adds a unit test for_resolve_bsize. - Updates packaging/docs: bumps Cellpose minimum version, adds a
cellpose-dinoextra, documents install options, and bumps package version to0.8.0a1.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/segmentation/test_cellpose_sam_gpu.py | Adds cached model fixture, deprecation-alias test, and parity coverage for new v4 backbones (incl. 3D + bsize override). |
| README.md | Documents new cellpose-dino extra and clarifies Cellpose extras install commands. |
| pyproject.toml | Bumps Cellpose minimum version and adds cellpose-dino optional dependency + wiring into all. |
| cubic/segmentation/cellpose.py | Generalizes docstrings from SAM-only wording to “Cellpose v4 (SAM or DINO)”. |
| cubic/segmentation/cellpose_sam_gpu.py | Implements segment_cellpose, _resolve_bsize, removes backbone arg from _run_net_gpu, and adds deprecated segment_cpsam alias. |
| cubic/segmentation/init.py | Exports segment_cellpose alongside deprecated segment_cpsam. |
| cubic/init.py | Bumps package version to 0.8.0a1. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The ImportError raised when cellpose is missing still said "(SAM)" only, while _check_gpu_precondition was already updated to "(SAM or DINO)". Align the message and point DINO users at the dinov3 install note in the README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Published cellpose (4.2.1.1) does not expose a `dino` extra, and dinov3 is git-only (pip install git+https://github.com/facebookresearch/dinov3), so it cannot be declared as a dependency of a PyPI package. The cellpose-dino extra therefore pulled no dinov3 (uv warned the extra did not exist). Remove it and document the manual dinov3 install in the README for the DINO backbones. Regenerate uv.lock, which was stale against the cellpose>=4.2.0 bump (it still recorded >=4.0 and resolved cellpose 4.1.1, predating cpsam_v2/cpdino). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bsize is now part of the public segment_cellpose API, but _resolve_bsize passed any explicit value straight through for DINO backbones, so bsize<=0 reached make_tiles/run_net_gpu and caused divide-by-zero / invalid tiling. Validate it as a positive integer and fail fast with a clear error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Extends cubic's device-resident Cellpose segmentation to support all four Cellpose v4 models, not just the original SAM weights:
cpsamcpsam_v2cpdinocpdino-vitbBoth
CPSAMandCPDINOforwards return the identical(flow[B,3,bsize,bsize], style[B,256])contract; the only backbone-specific behavior is the tile size, which cubic already mirrored. So the resident path needed only to exposebsizeand centralize the backbone→tile-size rule.Changes
segment_cellposeis now the canonical GPU-resident entry point (covers SAM + DINO).segment_cpsamis kept as a deprecated alias (emitsDeprecationWarning, slated for removal after 0.8). Both are exported.bsizeparameter, threaded through the network forward, with cellpose'ssam_vitl → 256guard. DINO tile size is tunable._resolve_bsize(backbone, bsize)helper (default + validation), removing the now-unusedbackbonearg from_run_net_gpu.cellpose_eval/cellpose_segmentdocstrings (they already accept any model name).cellposepin bumped to>=4.2.0(the release that ships cpsam_v2/cpdino) and a newcellpose-dinoextra (cubic[cellpose]+cellpose[dino]>=4.2.0) for thedinov3dependency. README install note added.0.8.0a1.Tests
cpsam_v2,cpdino,cpdino-vitb; a DINO 3D parity test; a DINObsize-override parity test (all GPU-gated, vs stockCellposeModel.eval, AP@0.5 ≥ 0.95)._resolve_bsize(no GPU).segment_cpsamwarns and forwards verbatim.CellposeModelper backbone, so the GPU suite reloads each weight set only once.Verification
ruff check,ruff format --check,mypyclean.🤖 Generated with Claude Code
Summary by Sourcery
Extend GPU-resident Cellpose segmentation to support all Cellpose v4 models and rename the main entry point, while preserving compatibility via a deprecated alias.
New Features:
Enhancements:
Build:
Documentation:
Tests: