bixverse
Python bindings for bixverse-rs.
The crate does the work: this is a thin layer that opens a bixverse binary
sparse store and streams minibatches out of it fast enough to keep a GPU
training loop fed.
The first consumer is scVI, which ships in bixverse.nn (torch or MLX) and
trains straight off the store, shuffled, without ever materialising the
experiment in memory. Decoding never leaves Rust, and the GIL is released
while it happens.
Install
uv pip install bixverse # numpy only
uv pip install "bixverse[sparse]" # adds scipy, for Batch.scipy_csr
uv pip install "bixverse[torch]" # scVI on torch
uv pip install "bixverse[mlx]" # scVI on MLX, Apple Silicon
Use
import bixverse as bv
reader = bv.CellReader("counts.bin")
loader = bv.CellLoader(reader, batch_size=256, layer="norm", seed=42)
for batch in loader:
x = batch.scipy_csr() # (256, n_genes) CSR
Pass an index array to iterate a subset, which is how a train/validation split gets expressed:
import numpy as np
rng = np.random.default_rng(0)
perm = rng.permutation(reader.total_cells)
train = bv.CellLoader(reader, perm[:180_000], batch_size=256)
val = bv.CellLoader(reader, perm[180_000:], batch_size=256, shuffle=False)
Each pass over a loader reshuffles and spawns its own feeder thread, so two concurrent passes don't share state. The seed is mixed with the epoch counter: same seed means the same sequence of epochs, not the same epoch twice.
Batches
A Batch is a NamedTuple of (raw, norm, indices, indptr, shape, cell_ids).
The layer you didn't ask for is None. cell_ids is the store index of each
row, which is how per-cell covariates get joined back on after the shuffle.
CellLoader(genes=...) restricts and reorders the columns.
| Field | Sparse | Dense |
|---|---|---|
raw / norm |
CSR-ordered float32 |
(n_cells, n_genes) float32 |
indices / indptr |
uint32 CSR components |
None |
shape |
(n_cells, n_genes) |
same |
batch.values() returns the single requested layer, batch.scipy_csr()
rebuilds a scipy.sparse.csr_matrix sharing the same buffers.
scVI
import bixverse.nn as bvnn
fit = bvnn.train_scvi("counts.bin", cells, hvg, batch, backend="torch")
latent = bvnn.scvi_latent(fit, "counts.bin", cells, batch)
scvi-tools 1.5.1's defaults, NB or ZINB, and a trained scvi-tools module loads into it and reproduces its loss. See the docs for the validation against scvi-tools.
Sparse by default
sparse=True is the default and you want it. A dense batch pays a zero-fill
and a scatter over batch_size * n_genes floats regardless of how few counts
it actually holds. At droplet sparsity that's roughly twenty times the memory
traffic for the same information, on the feeder thread, every batch. Build the
dense tensor on the GPU instead if you need one.
Layers
"raw" gives the counts. "norm" gives log1p(count / library_size * target_size), computed at write time and stored as float16, so expect
agreement with a recomputation to about three decimal places rather than to
machine precision. "both" returns the two together over one sparsity pattern.
Caveats
- Cell-major stores only. A gene-major file raises on construction.
Ctrl-Ccan't interrupt a batch mid-decode: the GIL is released while the feeder works, and Python signal handlers only run while it's held.- The store is memory-mapped and the reader hints random access, which is right for a shuffled loader and wrong for a sequential full scan.
Development
uv venv
uv pip install "maturin>=1.15,<2" numpy scipy pytest beartype
maturin develop --release
pytest tests -q
Metadata
Release files for bixverse 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bixverse-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| bixverse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| bixverse-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 5.3 MB
Release files / bixverse-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | bixverse-0.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
e3e6ff5db20f33215b1789b63ab57a0e9003854133ce0dd2818010da4ddd2034
|
|
BLAKE2b-256 checksum How to use checksums |
060a47a5c6586dff1bae2afddc6e0d3f894e9585c65088d3f68055b51a254492
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 14, 2026.
Transparency logRelease files / bixverse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | bixverse-0.1.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f60d5c5e710bf8802bcc9b773c3aca525515f5e654c1b54f5fee30a1639c4757
|
|
BLAKE2b-256 checksum How to use checksums |
c320d2c51306d28af94f58f2d1fd11a2c500c212e8e1fe01c22ec01f5529f0f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 14, 2026.
Transparency logRelease files / bixverse-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | bixverse-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
5c1a1cdfd77427d156c8a9e440121d7ae6d2de05ad3c25d4cb8116e9169c1e18
|
|
BLAKE2b-256 checksum How to use checksums |
ef957a9396fe3ed5f4c0d4514cbb102b0aa62b3cec46fab9aa700d43041ce6b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 14, 2026.
Transparency log