Skip to content

gatk4 modules: shared gatk4+gcnvkernel container is ~2 GB, but only 3 modules need gcnvkernel #13031

Open

Description

@pditommaso

Description

64 of the 65 gatk4/* modules use the combined gatk4-main + gcnvkernel container (currently community.wave.seqera.io/library/gatk4-main_gcnvkernel:961440660027ec01; previously gatk4_gcnvkernel:edb12e4f0bf02cd3, which nf-core/sarek still pins). Only cnnscorevariants differs.

Only the germline CNV tools import gcnvkernel: gatk4/germlinecnvcaller, gatk4/determinegermlinecontigploidy and gatk4/postprocessgermlinecnvcalls. Every other GATK tool needs just Java and the GATK jar, yet pulls the whole gcnvkernel Python/R/PyTorch stack.

Impact

Measured on gatk4_gcnvkernel:edb12e4f0bf02cd3 (gatk4 4.6.2.0 + gcnvkernel 0.9). I did not measure the 4.7.0.0 image; it is built from the same recipe, so its size should be similar.

  • One 1.98 GB compressed layer: 4.54 GiB uncompressed, 322 conda packages.
  • Every GATK step on a fresh node downloads about 2 GB. That includes MarkDuplicates, BaseRecalibrator, ApplyBQSR, HaplotypeCaller, Mutect2 and MergeVcfs, even though none of them uses gcnvkernel.
  • It is too large for the CDN cache. The single blob exceeds the usual per-object cache limit (512 MB on Cloudflare's standard plans), so every pull is served uncached from origin. Under heavy concurrent pulling (22–25 Sep 2026) downloads of this layer slowed down enough to miss 15-minute pull timeouts. sarek runs failed on MergeVcfs, LearnReadOrientationModel and IntervalListToBed, none of which needs gcnvkernel.

Where the size comes from (measured, uncompressed)

Component Size Needed?
Intel MKL (blas=*=mkl, pytorch *mkl*) 760 MiB No, only as a BLAS backend (OpenBLAS is ~30 MiB)
Python packages vendored a second time as .egg dirs inside the gcnvkernel conda package (numpy, scipy, pandas, arviz, …) 371 MiB No, duplicates of the conda copies
pytorch 2.1 + pytorch-lightning 406 MiB No, gcnvkernel never imports them
Qt / PyQt5 (matplotlib GUI backend) 199 MiB No
R 4.3 + ggplot2, dplyr, data.table, … 136 MiB No (GATK plotting helpers)
scikit-learn 40 MiB No
gcc / LLVM toolchain 698 MiB Yes: pytensor compiles its graphs at runtime
OpenJDK 17 + GATK jar ~720 MiB Yes

The root cause is the bioconda gcnvkernel recipe. It pins GATK's full Python environment (pytorch 2.1.0 *mkl*, pytorch-lightning, r-base, r-ggplot2, scikit-learn, blas 1.0 mkl, …). gcnvkernel's code only imports numpy, pymc, pytensor, scipy, pandas, tqdm and vcf. Its own requires.txt lists pymc==5.10.0, pytensor==2.18.1, numpy==1.26.2, scipy==1.11.4 and tqdm==4.66.1.

Proposal

  1. Split the container. The ~61 non-CNV modules would use a GATK-only environment, bioconda::gatk4-main alone, which needs only openjdk and python. Estimated from conda package sizes: ~570 MiB (GATK jar ~381 MiB + OpenJDK ~162 MiB + python), about 3.5× smaller. The combined gatk4 + gcnvkernel image stays only on the 3 CNV modules, plus the htslib/samtools variant markduplicates needs.

  2. Slim the bioconda gcnvkernel recipe (bioconda-recipes):

    • declare only the packages it imports (pymc, pytensor, numpy, scipy, pandas, tqdm, pyvcf);
    • install with pip install --no-deps so it stops vendoring duplicate .egg copies;
    • drop pytorch, pytorch-lightning, the R packages, scikit-learn and the Qt backend.

    Estimated saving: about 1.1 GiB uncompressed on the CNV image while keeping MKL.

  3. Optional: OpenBLAS instead of MKL in the CNV image saves another ~0.7 GiB. It needs a numerical check of the gCNV outputs first.

The sizes in (1) and (2) are estimates from conda package archive sizes, not built images. Even a GATK-only image lands near 512 MB, because the GATK jar alone is ~381 MiB compressed. So keeping every layer under a 512 MB CDN limit would also need the JDK and GATK in separate layers. That is a Seqera Containers build concern, and we are looking at it separately.

I'm happy to help with the PRs.

Activity

  1. adamrtalbot commented on Sep 25, 2026

    @adamrtalbot
    Contributor

    Looking at the history, this introduced the Seqera Containers with the gCNV kernel: #8401

    Previously there was a mulled container: quay.io/biocontainers/mulled-v2-d9e7bad0f7fbc8f4458d5c3ab7ffaaf0235b59fb:7cc3d06cbf42e28c5e2ebfc7c858654c7340a9d5-0 but it's unclear to me if it includes the gCNV kernel.

    I'd agree, we should use the smallest possible container for each GATK4 tool.

    Having said that, given Docker pulls are idempotent and lots of pipelines will use several GATK4 processes, it may be more efficient for local storage to use the same container for the majority of GATK4 modules. Perhaps a compromise is to make one container that does 80% of modules and make special containers for the unusual tools like CNV calling.

  2. adamrtalbot commented on Sep 25, 2026

    @adamrtalbot
    Contributor

    ahhh looks like the bioconda recipe includes the kernel: https://github.com/bioconda/bioconda-recipes/blob/master/recipes/gatk4/meta.yaml#L35

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions