Skip to main content

AnnoTuneAgent

PyPI version PyPI downloads Python versions Documentation Status CI License DOI

Documentation: Read the Docs.

Cluster-level cell-type annotation for single-cell RNA-seq, with two fine-tuned language models that run locally.

Each cluster gets a marker score, a name-model result, and an ML-model result. A rule-based judgment reads all three and writes the title, so every call stays auditable.

What is fine-tuned

One Qwen3.5-4B base (Q6_K GGUF) is shared by two independent LoRA adapters. The adapters are not merged into the base, so they load together on a single local llama-server and can be replaced without touching the base.

Model Task it was fine-tuned for Input Output
name Choose a cell-type name from the marker dictionary Cluster marker evidence and dictionary_hits A name copied from dictionary_hits when that type's markers support the cluster
ML Choose a name from measured cluster statistics Differential expression, candidate marker panels, log fold change, fraction of cells expressing each gene inside and outside the cluster, panel summaries A name copied from those candidates

Both models are trained to copy a name from the candidates they are shown, not to free-write one. A name outside the candidate list cannot become a title, and a name with no marker that passes expression and specificity validation is flagged (no_marker_passed) instead of being trusted silently.

The weights are on the Hugging Face Hub: lieberlee/annotune-qwen3.5-4b-gguf (preview). Inference is local: no cluster data leaves the machine.

Pipeline

raw counts ─ prepare ─▶ QC, doublets, normalization, batch correction, Leiden
           ─ run ─────▶ per cluster:
                          1. marker score        (built-in human / mouse dictionary)
                          2. name model          (LoRA, copies from dictionary_hits)
                          3. ML model            (LoRA, copies from measured candidates)
                          ▼
                        judgment ─▶ title + status + reason + hint
                          ▼
                        validated marker panels, dotplot, report, annotated h5ad
  • Judgment, not voting. Agreement among the three results gives a clear title. Disagreement, mixed programs, and unvalidated names are kept and flagged with a reason (mixed_programs, near_clear_cluster, subcluster_labels, no_marker_passed) so you can review them.
  • Marker evidence is checked, not quoted. Panels are selected from cited dictionary markers and validated against measured expression and specificity in your data.
  • Every title is traceable. The report records each model's answer, the panel, and the reason a cluster was or was not settled.

The models run when models is passed (or the CLI adapter flags are given). Without them, run uses the marker score alone.

Install

Python 3.10–3.13.

pip install annotuneagent

Local GGUF models need pip install 'annotuneagent[models]', which installs the tokenizer stack (transformers and jinja2). Optional methods: AmbiDose (denoise=True, install), scVI and SOLO (annotuneagent[scvi]), scFair (annotuneagent[scfair]), Harmony, and Scanorama. If you select one that is missing, prepare prints the install command and leaves the matrix unchanged. See Installation.

From a checkout:

git clone https://github.com/leelieber2025/AnnoTuneAgent.git
cd AnnoTuneAgent
pip install -e ".[dev]"

First run

prepare expects raw integer counts. run expects finite, nonnegative, library-size-normalized natural log1p expression with Scanpy's adata.uns["log1p"], which prepare writes.

import annotuneagent as ata

adata = ata.read_10x("outs", ["sample_a", "sample_b"])
adata = ata.prepare(adata, species="human", batch_key="sample")
report = ata.run(adata, "leiden", species="human", subcluster=False)

read_10x takes one filtered matrix per sample folder (*.h5, or the mtx directory when there is no h5). Scrublet and SOLO run per sample on those filtered counts. doublet_chip="10k" (default) uses 0.8% multiplets per 1,000 recovered cells, and "20k" uses 0.4%.

geo_info("GSE341410") lists the samples in a GEO series. read_geo then downloads the ones you name, and groups sets the condition in obs["group"]. docs/tutorials/gse266598_annotation.ipynb follows one series from the GEO page through annotation.

To score a caller-supplied list instead of the built-in dictionary:

records = ata.annotate(
    adata,
    cluster_key="leiden",
    hypotheses=[
        ata.Hypothesis(
            "CD4-positive, alpha-beta T cell",
            positive=("CD3E", "CD4"),
            negative=("CD8A",),
        ),
        ata.Hypothesis(
            "CD8-positive, alpha-beta T cell",
            positive=("CD3E", "CD8A"),
            negative=("CD4",),
        ),
    ],
)

A label needs positive marker enrichment. A negative marker counts against a hypothesis only when the cluster is enriched for it relative to the other cells. Scores are operational, not probabilities.

The built-in table is markers.tsv: human and mouse, each with a tissue-agnostic core and organ pages. Tissue rows stay hidden until tissue matches. Symbols are not translated across species. evaluate compares records with a per-cell author label: the reference for a cluster is the majority label, a tied majority is left unmatched, and a parent name counts as a coarse match.

annotuneagent \
  --input clustered.h5ad \
  --cluster-key leiden \
  --species human \
  --output result.json

--name-adapter, --ml-adapter, and --base run the name and ML models on one local server and require --output-h5ad. The weights are on the Hugging Face Hub: lieberlee/annotune-qwen3.5-4b-gguf. The tokenizer is installed with the package. See docs/tutorials/load_model.ipynb.

Status

0.1.3 (Alpha). Import as import annotuneagent as ata.

Citation

For the software record, cite the Zenodo DOI. Pin the package version used in the analysis, for example annotuneagent==0.1.3.

License

Software: Apache License 2.0.

Author

Zhao Li (李钊) Email: leelieber@gmail.com

Metadata

Release files for annotuneagent 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for annotuneagent 0.1.3
File Size Uploaded Provenance Actions
annotuneagent-0.1.3.tar.gz 10.5 MB With provenance Details for annotuneagent-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for annotuneagent 0.1.3
File Interpreter ABI Platform Actions
annotuneagent-0.1.3-py3-none-any.whl Python 3 none any Details for annotuneagent-0.1.3-py3-none-any.whl

Total release size: 17.7 MB

Release files / annotuneagent-0.1.3.tar.gz

Download URL annotuneagent-0.1.3.tar.gz
Size 10.5 MB
Tags Source
SHA-256 checksum
How to use checksums
e1b6315332869b972a5107fcf56bbcc1f4415e56d49ef64b3ade24444b436819
BLAKE2b-256 checksum
How to use checksums
c69dc1b6dcde7d7fdf7f88327b480bac6205c224bc03d34e29c49e7835ba5343
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Release files / annotuneagent-0.1.3-py3-none-any.whl

Download URL annotuneagent-0.1.3-py3-none-any.whl
Size 7.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
c9477c7701e6621640dc1f77d97e37a5201f708ffa17a70979b528b62c70774f
BLAKE2b-256 checksum
How to use checksums
90bf5866221269be2bd2839f475d44f476ff1aa18e8436e029dd8640fdcc8904
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Security for annotuneagent 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for annotuneagent-0.1.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page