Skip to main content

medtokenizers

medtokenizers compresses 2D and 3D medical images into latents or discrete token grids. It provides one encoder-decoder backbone with interchangeable quantization heads (VQ, LFQ, FSQ, Residual FSQ, VAE, AE), so the quantizer can be treated as a controlled variable rather than a fixed preprocessing choice. It also provides shared reconstruction metrics and dataset tokenization utilities.

This library accompanies the paper Tokenizer-Generator Coupling in Medical Image Generation, which uses it for the tokenizer half of a factorial study. See Citation.

Install

pip install -e ".[test]"

Requires Python 3.10+ and PyTorch 2.0+. Tested on Linux and macOS. A CUDA GPU is needed for 3D training, but everything below runs on CPU.

For a CPU-only install, take PyTorch from its CPU index first so torch and torchvision come from the same build:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
pip install -e ".[test]"

Run it

Swap the quantizer, keep everything else fixed:

import torch

from medtokenizers import DiscreteTokenizer

x = torch.randn(1, 1, 64, 64)

for quantizer in ["VQ", "FSQ", "RESFSQ"]:
    model = DiscreteTokenizer(
        dim=2, quantizer=quantizer, resolution=64, spatial_compression=8
    ).eval()
    with torch.no_grad():
        tokens = model.tokenize(x)  # (1, 8, 8) integer codes
        recon = model.detokenize(tokens)  # (1, 1, 64, 64)

LFQ is the one head that needs two further arguments, because its codebook is defined by its binary dimension rather than inferred:

model = DiscreteTokenizer(
    dim=2,
    quantizer="LFQ",
    resolution=64,
    spatial_compression=8,
    codebook_size=1024,
    codebook_dim=10,
)

The continuous heads live on a separate class, selected by formulation instead of quantizer, and return a real-valued latent rather than indices:

from medtokenizers import ContinuousTokenizer

model = ContinuousTokenizer(
    dim=2, formulation="VAE", resolution=64, spatial_compression=8
).eval()
with torch.no_grad():
    latent = model.tokenize(x)  # (1, 4, 8, 8)
    recon = model.detokenize(latent)

At evaluation time ContinuousTokenizer.encode returns the posterior mean, so latents extracted with model.eval() are deterministic.

Set dim=3 for volumes; the same calls take (B, C, H, W, D) tensors.

Volumetric inference

A simulated T1-weighted brain volume ships inside the package (from the BrainWeb Simulated Brain Database, with provenance in src/medtokenizers/assets/README.md), so the example runs without a download and works from an installed wheel. example_volume_path() resolves it. Random initialisation is enough for a smoke test; load your own weights for real reconstructions.

python examples/inference_on_brain.py --model-type maisi

Large volumes are reconstructed with Gaussian-weighted sliding windows:

import medrs
import torch

from medtokenizers import MAISITokenizer, example_volume_path

img = medrs.load(str(example_volume_path()))
volume = img.to_torch_with_dtype_and_device(dtype=torch.float32)
volume = volume.unsqueeze(0).unsqueeze(0)  # (H, W, D) -> (1, 1, H, W, D)
volume = (volume - volume.min()) / (volume.max() - volume.min() + 1e-8)

model = MAISITokenizer().eval()
with torch.no_grad():
    recon = model.reconstruct(volume, roi_size=(96, 96, 64), overlap=0.5)

Sliding-window reconstruction over a full 1 mm volume is memory-hungry. Reduce roi_size or overlap if you are not on a GPU.

Tokenizers

Class Selected by Output
DiscreteTokenizer quantizer="VQ" | "FSQ" | "LFQ" | "RESFSQ" integer token grid
ContinuousTokenizer formulation="VAE" | "AE" real-valued latent
MAISITokenizer fixed MAISI configuration real-valued latent
TiTokTokenizer 1D transformer tokenizer fixed-length sequence of K tokens
RAETokenizer (experimental) frozen foundation-model encoder real-valued latent

Adding a quantizer means subclassing BaseQuantizer (two abstract methods, forward and indices_to_codes) and wiring it into DiscreteTokenizer. The encoder-decoder and the tokenization I/O are unchanged by the choice.

TiTok

TiTok encodes an image or volume into a fixed-length 1D sequence of K tokens. The encoder concatenates patch tokens with K learnable latent tokens and keeps only the latter; the decoder reconstructs from quantized latents plus mask tokens. Input shape must equal resolution, and each spatial dimension must be divisible by patch_size.

from medtokenizers import TiTokTokenizer

tokenizer = TiTokTokenizer(
    dim=2,
    in_channels=1,
    out_channels=1,
    resolution=64,
    patch_size=16,
    num_tokens=32,
    num_embeddings=1024,
    hidden_dim=256,
)
indices, codes, quant_loss = tokenizer.encode(torch.randn(2, 1, 64, 64))
recon = tokenizer.decode(codes)

TiTok's original two-stage proxy-code warmup and decoder fine-tuning are not wired into the training scripts; implement that externally if you want the published recipe.

Evaluation

from medtokenizers import compute_lpips, compute_psnr, compute_ssim

psnr = compute_psnr(reference, reconstruction)
ssim = compute_ssim(reference, reconstruction)
lpips = compute_lpips(reference, reconstruction)

TokenizerEvaluator runs these over a loader, together with perplexity and codebook utilisation for discrete models:

from medtokenizers import TokenizerEvaluator, load_tokenizer

model = load_tokenizer("./path/to/checkpoint")
results = TokenizerEvaluator(model, device="cuda").evaluate(test_loader)

No pretrained checkpoints ship with this repository.

Ecosystem

medtokenizers is one of three packages:

  • medrs: medical-image I/O (NIfTI/DICOM) and preprocessing primitives.
  • medtokenizers: tokenizers that compress scans into latents or token grids (this package).
  • medlatents: generative models (autoregressive, MaskGIT, diffusion, flow matching, Bayesian flow) that learn over those tokens.
images -> medrs (load) -> medtokenizers (tokenize) -> medlatents (generate)
       -> medtokenizers (detokenize) -> images

scripts/tokenize_dataset.py writes a directory of per-split .npz files plus metadata.json, with key codes (int16) for discrete models and latents (float16) for continuous ones.

Contributing

See CONTRIBUTING.md for development setup and the pull-request workflow, and CODE_OF_CONDUCT.md for community standards.

Citation

@article{chalcroft2026coupling,
  author = {Chalcroft, Liam},
  title  = {Tokenizer--Generator Coupling in Medical Image Generation},
  year   = {2026},
  note   = {arXiv preprint, to appear}
}

@software{chalcroft_medtokenizers,
  author  = {Chalcroft, Liam},
  title   = {{medtokenizers}: Continuous and discrete tokenizers for volumetric medical imaging},
  url     = {https://github.com/liamchalcroft/medtokenizers},
  version = {0.1.0}
}

Machine-readable metadata is in CITATION.cff.

License

MIT, see LICENSE.

Some modules derive from third-party projects: CompVis (Stable Diffusion, taming-transformers) and lucidrains vector-quantize-pytorch under MIT, and NVIDIA Cosmos-Tokenizer and MONAI/MAISI under Apache-2.0. Their terms are preserved in THIRD_PARTY_NOTICES.md and NOTICE. Two things are outside the MIT licence: NVIDIA MAISI pretrained weights, if you use them, remain under NSCLv1; and the bundled bundled BrainWeb volume is data carrying its own citation requirement.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

medtokenizers-0.1.0.tar.gz (5.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

medtokenizers-0.1.0-py3-none-any.whl (5.8 MB view details)

Uploaded Python 3

File details

Details for the file medtokenizers-0.1.0.tar.gz.

File metadata

  • Download URL: medtokenizers-0.1.0.tar.gz
  • Upload date:
  • Size: 5.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.11

File hashes

Hashes for medtokenizers-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c14b02aae6ff31922ac0ab6685c31e3840fc8b04926e730a59a48b07dc613407
MD5 f1831a8cd6b34cf154fa77fd68dcc5d5
BLAKE2b-256 ac4c35717c02d804f714a25d962e271d7ac80c7010250ca12c733f543543c033

See more details on using hashes here.

File details

Details for the file medtokenizers-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: medtokenizers-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.8 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.11

File hashes

Hashes for medtokenizers-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 304ace399f3785ee1b5fa30c8b3f6105bfe0900c1f686118a944049e69043e80
MD5 d397627a708a454ccb09e822ad9c6859
BLAKE2b-256 bb495fd356133fcc4cda8a091f4ddf83eb0ceaba031e161e6e3f8f5a49ac6cbe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page