Clair3 v2: Two Deep Learning Models, One Variant Call, and a TensorFlow Break
Clair3 - Symphonizing pileup and full-alignment for deep learning-based long-read variant calling
At a glance
- What is it?
- Clair3 is a germline small-variant caller for long-read sequencing that splits the work between a fast pileup model and a slower full-alignment model. Version 2.0 moved the backend to PyTorch, which means every v1 TensorFlow model, including the ones ONT ships through Rerio, stopped loading.
- Who is it for?
- Adopt Clair3 if you call germline small variants on ONT or PacBio long reads and can keep your model files and your runtime matched: v2 checkpoints are .pt, v1 checkpoints are TensorFlow and will not load. Do not adopt it for somatic calling, for long-read RNA-seq, or for tumor-only work; the repository points those cases at ClairS, ClairS-TO and Clair3-RNA instead.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Clair3 solves: long reads are noisy enough that one model is not enough
Long-read sequencing gives you reads that span repetitive regions and structural boundaries, which short reads cannot do. It also gives you an error profile that a simple threshold on allele fraction will not handle well. Clair3 is aimed at germline small variants, meaning single nucleotide changes and short insertions or deletions, from ONT or PacBio reads. The README describes it as a germline small-variant caller for long-read sequencing and nothing broader. That scope matters: the repository explicitly redirects long-read RNA-seq to Clair3-RNA, paired tumor/normal somatic calling to ClairS, and tumor-only somatic calling to ClairS-TO. If your question is not germline, Clair3 is the wrong entry point even though the underlying models look similar.
The design bet is that most candidate sites are easy and a minority are hard. Summarized alignment statistics around a position are cheap to compute and usually enough to decide. A smaller set of positions needs the actual haplotype-resolved alignment to be read in full. Clair3 runs both and lets the expensive path handle only the uncertain cases. This is the third generation of the line, following Clair (second) and Clairvoyante (first), so the pileup and full-alignment split is a settled part of the design rather than a new experiment.
How the pileup and full-alignment models divide the work
The README's own framing is that pileup calling is fast and handles the majority of variant candidates from summarized alignment statistics, while full-alignment calling is computationally intensive and resolves uncertain candidates from haplotype-resolved full alignments. That is the whole architecture in two sentences, and it is worth being precise about what it implies. There is no single model that sees everything. There is a cheap first pass that produces a candidate set, and a second pass that is invoked selectively.
The practical consequence is that runtime is dominated by how many positions the full-alignment stage has to revisit, not by the total number of reads. A sample with many ambiguous sites will spend more time in the expensive path than a clean one of the same size. The repository does not publish a per-stage timing breakdown in the material available here, so the split ratio between the two paths for a given dataset cannot be stated from the documentation alone. What can be stated is the direction: the pileup stage exists to keep the full-alignment stage from being applied everywhere.
Version 2.0 added a third input channel for ONT data. Passing --enable_dwell_time makes the caller signal-aware, using Dorado mv tags, which requires basecalling with --emit-moves. The documentation states that a move-table model whose name ends in _with_mv will fail early with clear guidance if you run it without that flag, rather than crashing. That behaviour was added in v2.0.2. It is a small thing, but it tells you the project treats the move-table models as a distinct mode rather than a variant of the standard ones.
Installing Clair3: four supported routes and what each one pins
The README lists four installation paths: Docker, Singularity, Bioconda, and a step-by-step Conda route. The Docker image is hkubal/clair3, and v2.0.1 added a GPU image tagged hkubal/clair3:v2.0.1_gpu built on CUDA 12.1 with PyTorch. If you need GPU acceleration on Linux, that prebuilt image is the shortest path, because it removes the need to reconcile a CUDA version with the PyTorch build yourself.
The entry point changed in v2.0.0. The README states that run_clair3.sh was reconstructed as run_clair3.py, and that both remain usable. Existing shell-based pipelines do not have to be rewritten immediately, but new work should target the Python runner, since that is where the reconstruction happened.
Model files are the part most likely to trip you up. In v2.0.2 the project re-bundled pre-trained models into a single pre-packaged archive extracted to ${PREFIX}/bin/models/, restoring bundled models that had been removed since v2.0.0. That matters for Bioconda and Conda installs, where the models arrive with the package. If you are on Docker, check what the image tag actually contains rather than assuming the bundled set is current. The README also links a separate download page for pre-trained PyTorch models and a separate page for converted Rerio models, which implies the bundled set and the downloadable set are not necessarily the same thing.
The PyTorch migration is the real upgrade cost in v2
This is the part to read twice. The v2.0.0 release notes state that the deep-learning backend moved from TensorFlow to PyTorch, and that v1 TensorFlow models are not compatible with v2, explicitly including the TF models ONT provides via Rerio. Checkpoint files changed format from TF .index and .data to PyTorch .pt.
The consequence is that upgrading Clair3 is not a version bump. If your pipeline depends on a Rerio model, that model will not load in v2, and your options are to download the converted Rerio Clair3 models the project publishes, or to convert your own using the model migration guide in docs/model_migration_guide.md. If you trained a custom model on your own data, the migration guide is not optional.
There is a second-order cost here that the release notes do not address directly. Any downstream script that inspects checkpoint files, copies them between environments, or asserts on their names will need updating, because the file extensions changed. That is a mechanical change, but it is the kind that surfaces in the middle of a run rather than at the start. Pinning a model version and a Clair3 version together in the same environment specification is the only way to avoid the mismatch, and the repository does not ship such a pin for you.
On the other side of the ledger, v2.0.1 fixed the clair3_version string written into VCF headers, which had been stuck at 1.2.0 regardless of the installed version. If you have been parsing that header to detect which caller version produced a file, past results are unreliable and you should not use it as a provenance record for anything generated before that fix.
Where Clair3 is the wrong tool, and what to reach for instead
The clearest boundary is somatic calling. Clair3's README describes it as a germline caller, and the repository routes paired tumor/normal work to ClairS and tumor-only work to ClairS-TO. The difference is not cosmetic. A germline caller is built around the assumption that the expected allele fraction for a heterozygous site is roughly one half, and the models are trained on that assumption. Somatic variants sit at low allele fractions against a background of normal reads, which is a different detection problem with a different training distribution. Running Clair3 on a tumor sample and filtering the output afterwards does not recover the sensitivity that a purpose-built caller provides.
The second boundary is long-read RNA-seq, which the repository routes to Clair3-RNA. RNA alignments contain spliced reads and expression-driven coverage variation that a DNA-trained pileup model was not built to interpret.
A third case is worth naming because it is easy to overlook: if you need structural variants or copy number changes rather than small variants, Clair3 does not address that at all. The README's scope is small variants, and the pileup and full-alignment models are both trained on that target.
For a genuine alternative within the same problem space, consider whether you need a deep-learning caller at all. A threshold-based caller that operates directly on pileup statistics requires no model files, no GPU, and no PyTorch version alignment, and its behaviour is inspectable by reading the thresholds. Clair3 trades that transparency for learned decision boundaries on the hard sites. If your samples are high-coverage and your variant sites are unambiguous, the learned model is doing work you may not need, and you have taken on a model-versioning problem for nothing. The honest test is to run both on one of your own samples and count the discordant sites, because the trade-off depends on your coverage and your read quality, not on anything the README can tell you.
What v2.0.1 through v2.0.3 changed about failure behaviour
The recent releases are mostly about how the tool fails, which is a reasonable signal about where users were getting hurt. v2.0.3 returns a non-zero exit code when BAM or CRAM input cannot be decoded, for example on a CRAM decode error, instead of silently emitting an empty VCF with exit code 0. Before that change, a decode failure and a genuine no-variant result were indistinguishable to a pipeline. If you have historical runs where Clair3 exited cleanly with an empty VCF, that history is ambiguous.
The same release replaced shell calls to gzip with pigz, which the README notes is already an explicit dependency, so compression no longer fails in minimal environments where gzip is absent. Minimal container images are exactly where this bites.
v2.0.2 addressed a related class of problem: it now always emits a valid, indexed VCF or gVCF when no variants are found. An earlier fix in v2.0.1 corrected SortVcf writing pileup RefCall entries when no variants were found instead of an empty VCF. Taken together, the empty-result path has been reworked three times across three releases. Any wrapper script that assumed an empty VCF meant failure needs revisiting, because that assumption no longer holds in either direction.
v2.0.3 also added a --gender option so that variant calling handles chrX and chrY with the correct ploidy. The release notes link a dedicated document at docs/gender_option.md. If you were previously calling sex chromosomes with a default ploidy assumption, those calls were wrong, and the fix is a flag rather than a default, so you have to pass it.
Licence, maintenance and what to check before you commit
The repository metadata supplied here lists the licence as unknown, but the README badge and the link it points to identify BSD 3-Clause. That discrepancy is worth resolving against the LICENSE file in the repository itself before you rely on either. BSD 3-Clause is a permissive licence, which generally means you can redistribute and modify with attribution and without a copyleft obligation, but this is a description of the licence family and not legal advice. If you are embedding Clair3 in a commercial product or a regulated pipeline, have counsel read the actual file rather than the badge.
On maintenance, the release cadence visible here is three releases between April and September 2026, with a major version in February 2026. The project is active and the recent work is concentrated on failure modes and model packaging rather than new calling modes. That is a reasonable sign for stability, though the v2.0.0 backend swap means the model ecosystem is still settling: the converted Rerio models and the migration guide exist precisely because the old ones stopped working.
The dependency surface is larger than the Python code suggests. PyTorch is now the backend, pigz is an explicit dependency, and the Bioconda recipe pulls longphase, which as of v2.0.2 is used as a package on all platforms rather than compiled at build time, including linux-aarch64. If you build your own environment rather than using the Docker image, you are responsible for all three. The Docker and Singularity routes exist to make that someone else's problem.
Before adopting, verify four things on your own data. Confirm your model files are PyTorch .pt and not TensorFlow, and if they came from Rerio, that you used the converted versions. Confirm your entry point, run_clair3.py or run_clair3.sh, matches what your wrapper scripts expect. Confirm whether your BAM has Dorado mv tags if you plan to use --enable_dwell_time, since the move-table models will refuse to run without the flag. And confirm your chrX and chrY naming matches what --gender expects, because that option is opt-in and the default ploidy assumption will produce incorrect calls on sex chromosomes.
Editorial conclusion
Adopt Clair3 if you call germline small variants on ONT or PacBio long reads and can keep your model files and your runtime matched: v2 checkpoints are .pt, v1 checkpoints are TensorFlow and will not load. Do not adopt it for somatic calling, for long-read RNA-seq, or for tumor-only work; the repository points those cases at ClairS, ClairS-TO and Clair3-RNA instead. Before you commit a pipeline, verify three things against your own data: that your basecalled BAM carries Dorado mv tags if you intend to pass --enable_dwell_time, that the model you downloaded was converted for PyTorch rather than pulled from Rerio, and that your reference names for chrX and chrY match what the --gender option expects.
Community notes