Skip to content

Add GPU support for Cellpose - #39

Merged
alihamraoui merged 10 commits into
devfrom
cellpose_gpu
Oct 9, 2026
Merged

alihamraoui merged 10 commits into
devfrom
cellpose_gpu

Conversation

@alihamraoui

Copy link
Copy Markdown
Contributor

--cellpose_use_gpu switches to a Cellpose v4 + PyTorch/CUDA image.

  • New warnings when:

    • cellpose_use_gpu is set without -profile gpu (the container would not see the GPU);
    • cellpose_model_type is set in GPU mode (Cellpose v4 only ships cpsam, so the value is ignored).
  • Usage

  nextflow run . -profile docker,gpu --cellpose_use_gpu true ...

Tested on a GPU node with Singularity

@github-actions

Copy link
Copy Markdown

Warning

Newer version of the nf-core template is available.

Your pipeline is using an old version of the nf-core template: 4.0.3.
Please update your pipeline to the latest version.

For more documentation on how to update your pipeline, please see the Synchronisation documentation.

@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

nf-core pipelines lint overall result: Passed ✅ ⚠️

Posted for pipeline commit 44fda84

+| ✅ 204 tests passed       |+
#| ❔  14 tests were ignored |#
#| ❔   1 tests had warnings |#
!| ❗   4 tests had warnings |!
Details

❗ Test warnings:

  • nextflow_config - Config manifest.version should end in dev: 1.0.1
  • pipeline_todos - TODO string in awsfulltest.yml: You can customise AWS full pipeline tests as required
  • pipeline_todos - TODO string in CONTRIBUTING.md: Add any pipeline specific contribution guidelines here, such as coding styles, procedures, checklists etc.
  • local_component_structure - utils.nf in modules/local should be moved to a TOOL/SUBTOOL/main.nf structure

❔ Tests ignored:

  • files_exist - File is ignored: conf/igenomes.config
  • files_exist - File is ignored: conf/igenomes_ignored.config
  • files_exist - File is ignored: assets/multiqc_config.yml
  • files_exist - File is ignored: conf/igenomes.config
  • files_exist - File is ignored: conf/igenomes_ignored.config
  • files_exist - File is ignored: assets/multiqc_config.yml
  • files_exist - File is ignored: .github/workflows/linting_comment.yml
  • files_unchanged - File ignored due to lint config: .github/workflows/branch.yml
  • files_unchanged - File ignored due to lint config: .github/workflows/linting.yml
  • files_unchanged - File ignored due to lint config: assets/sendmail_template.txt
  • files_unchanged - File ignored due to lint config: assets/nf-core-sopa_logo_light.png
  • files_unchanged - File ignored due to lint config: docs/images/nf-core-sopa_logo_light.png
  • files_unchanged - File ignored due to lint config: docs/images/nf-core-sopa_logo_dark.png
  • multiqc_config - multiqc_config

❔ Tests fixed:

✅ Tests passed:

Run details

  • nf-core/tools version 4.0.3
  • Run at 2026-10-08 15:12:53

@quentinblampey quentinblampey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alihamraoui, I made some comments (it's mostly questions actually)!

container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container
? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/22/22d62d6425b70620138ad8764139528c1acaabf6cd06403134c8439caa1c9a31/data'
: 'community.wave.seqera.io/library/python_sopa_cellpose:d098579826bbcf24' }"
// CPU image: cellpose v3 | GPU image (task.ext.use_gpu): cellpose v4 + pytorch/CUDA, built from patch_segmentation_cellpose/environment_gpu.yml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need a GPU to download a model, we can use the original CPU image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only PATCH_SEGMENTATION_CELLPOSE has the process_gpu label, this process doesn't use the GPU for the download, it runs on the CPU. it just reuses the v4 image because sopa download cellpose caches the model for the installed Cellpose version, and the CPU image (v3) has no cpsam model.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, makes sense

Comment thread modules/local/resolve_cellpose/main.nf Outdated
container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container
? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/22/22d62d6425b70620138ad8764139528c1acaabf6cd06403134c8439caa1c9a31/data'
: 'community.wave.seqera.io/library/python_sopa_cellpose:d098579826bbcf24' }"
// CPU image: cellpose v3 | GPU image (task.ext.use_gpu): cellpose v4 + pytorch/CUDA, built from patch_segmentation_cellpose/environment_gpu.yml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: we don't need a GPU to resolve shapes, we can revert the changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since the GPU image is already pulled for the patches, reusing the same image avoids an extra ~4 GB pull. what do you think?

@quentinblampey quentinblampey Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, true, good point!

Comment thread nextflow_schema.json Outdated
Comment thread modules/local/patch_segmentation_cellpose/environment_gpu.yml Outdated
Comment thread conf/modules.config Outdated
ext.use_gpu = params.cellpose_use_gpu
}
withName: PATCH_SEGMENTATION_CELLPOSE {
accelerator = { params.cellpose_use_gpu ? 1 : null }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the accelerator doing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accelerator = 1 allocate one GPU to the task, I think by adding --gres=gpu:1 to the run command for singularity for example. it's only applied to PATCH_SEGMENTATION_CELLPOSE right now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is nextflow not doing it by itself? We really need to set this ourselves?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure accelerator = 1 alone is enough. According to the docs, it declares the number of GPUs a task needs, but only some executors use it (on Slurm, clusterOptions '--gres=gpu:1' may still be needed). The container also needs the driver, with --nv for Singularity or --gpus all for Docker, which is what -profile gpu adds. I'm running some tests to make sure everything works.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it may be right, I'm just surprised that nextflow doesn't already handle all this stuff itself by default, but maybe you're right

: 'community.wave.seqera.io/library/python_sopa_cellpose:d098579826bbcf24' }"
// CPU image: cellpose v3 | GPU image (task.ext.use_gpu): cellpose v4 + pytorch/CUDA, built from patch_segmentation_cellpose/environment_gpu.yml
container "${ task.ext.use_gpu
? 'community.wave.seqera.io/library/python_sopa_cellpose_pytorch-gpu_cuda-version:7ca3fb7cbc5a048b'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Did you test this container on a machine with CUDA? Does it automatically detect the existing CUDA drivers?

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

❌ nf-test failed with latest Nextflow version

Note

Tests with Nextflow's latest version failed but it will not cause a CI workflow failure.
Please check if the failure is expected with newer (edge-)releases of Nextflow or if it needs fixing.

  • ❌ docker | latest-everything | Shard 2/3

See the full run for details.

@alihamraoui

Copy link
Copy Markdown
Contributor Author

I tested the whole pipe on a machine with CUDA (cuda 12) with different param combinations.
Now the version/image are choosen:

cellpose_version -profile gpu Image used
null (default) no v3 (as before)
null (default) yes v4 + PyTorch/CUDA
3 either v3
4 either v4 + PyTorch/CUDA

@quentinblampey quentinblampey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments again, we're almost there :)

}
def cellpose_v4 = params.cellpose_version != null ? params.cellpose_version.toString() == '4' : workflow.profile.contains('gpu')
if (params.use_cellpose && cellpose_v4 && params.cellpose_model_type != null) {
log.warn("Cellpose v4 only provides the 'cpsam' model: 'cellpose_model_type=${params.cellpose_model_type}' will be ignored.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean Cellpose v4 only supports the pretrained_model argument, no? As far as I remember, we can provided multiple pretrained_model, and cpsam is just one of them, but indeed model_type is only for v3

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, v4 now supports multiple pretrained models, not just cpsam.
I checked, the other pretrained models are available since v4.2.1, but we're using 4.1. I assume they are also compatible with 4.1, so I'll remove the warning.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to build a new image with Cellpose >=4.2.1

log.warn("Cellpose v4 only provides the 'cpsam' model: 'cellpose_model_type=${params.cellpose_model_type}' will be ignored.")
}
if (params.use_cellpose && !cellpose_v4 && workflow.profile.contains('gpu')) {
log.warn("'cellpose_version=3' is used with the 'gpu' profile, but the Cellpose v3 image is not built with CUDA: Cellpose may fall back to CPU. Use 'cellpose_version=4' for GPU support.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Do we need another image for cellpose v3 + GPU then?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or, make a single v3 image that works for both cases: v3 + GPU and v3 on CPU. It will be a larger image for CPU-only users, but it keeps the module simpler. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's also possible, as you prefer (if it's not a much much bigger image)

? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/22/22d62d6425b70620138ad8764139528c1acaabf6cd06403134c8439caa1c9a31/data'
: 'community.wave.seqera.io/library/python_sopa_cellpose:d098579826bbcf24' }"

container "${ task.ext.cellpose_v4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering, is it possible to move this big container logic within the modules.config? E.g., within the withName: 'DOWNLOAD_CELLPOSE_MODEL|PATCH_SEGMENTATION_CELLPOSE|RESOLVE_CELLPOSE'?
I don't know, maybe it's not possible, just an idea

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, yes, it's possible. It even avoids repeated code.
I see also that -profile conda never gets v4 (it always uses environment.yml). I'll handle it.

@alihamraoui

Copy link
Copy Markdown
Contributor Author

Hi @quentinblampey,
Thanks for your comments and review.

As expected, Cellpose v4.1.1 only accepts cpsam as a pretrained model. The new models are supported from v4.2.1.1, which is only available via Pypi. So I built a new image with this version and added the dependencies torchvision and facebookresearch/dinov3, because cpdino and cpdino-vitb rely on them (MouseLand/cellpose#1476).

Now we have 4 images: v3 and v4, each with its GPU (pytorch/CUDA) version. Sopa now uses the Cellpose v3 image by default, and --cellpose_version 4 switches to v4. -profile gpu selects the GPU image of the chosen version. The conda envs follow the same logic.

Tested with profile singularity, docker and conda.

@quentinblampey quentinblampey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @alihamraoui, thanks for the massive work, this is a really great improvement!! I just made a minor comment, I'm not sure if this has to be removed or not. I approved anyway, I'll let you see if it needs to be corrected or not and merge it :)


conda "${moduleDir}/environment.yml"

container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container

@quentinblampey quentinblampey Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need the container command within these process, since we have it already in conf/modules.config?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I keept them as a fallback for module tests or nf-core download. conf/modules.config overrides them to pick the GPU or v4 variant. but we can remove them and nothing changes when the pipeline runs.

@alihamraoui

Copy link
Copy Markdown
Contributor Author

Good! thanks @quentinblampey,
I will merge

@alihamraoui
alihamraoui merged commit df5d3de into dev Oct 9, 2026
14 checks passed
@alihamraoui
alihamraoui deleted the cellpose_gpu branch October 9, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants