Skip to main content

Logo

Docs Tests codecov PyPI

GenLM Backend is a high-performance backend for language model probabilistic programs, built for the GenLM ecosystem. It provides an asynchronous and autobatched interface to language model inference via vllm, sglang, transformers, and mlx-lm.

See our documentation.

Key Features

  • Automatic batching of concurrent log-probability requests, enabling efficient large-scale inference without having to write batching logic yourself
  • Byte-level decoding of transformers tokenizers, enabling advanced token-level control
  • Support for arbitrary Hugging Face models (e.g., LLaMA, DeepSeek, etc.) with fast inference and automatic KV caching using vllm
  • Support for the MLX-LM library, for inference on Apple silicon

Quick Start

This library supports installation via pip. This uses transformers as the default inference backend.

pip install genlm-backend

To use a different backend, install the corresponding extra:

pip install genlm-backend[mlx]
pip install genlm-backend[vllm]
pip install genlm-backend[sgl]

For LoRA support:

pip install genlm-backend[lora]

Adapters are selected per request. Register one with add_new_lora(path, name), then pass lora_name=name to any forward; omit it to run the base model. Re-registering a name rebinds it to the weights at the new path and evicts the old weights and their caches. remove_lora(name) drops an adapter.

llm.add_new_lora("/path/to/adapter", "reviewer")
logps = await llm.next_token_logprobs(token_ids, lora_name="reviewer")

Releasing a vLLM model

Dropping the last reference to an AsyncVirtualLM frees the GPU. To release at a point you choose, call cleanup() or use the model as a context manager (with or async with).

from genlm.backend import AsyncVirtualLM

with AsyncVirtualLM.from_name("meta-llama/Llama-3.2-1B") as llm:
    logps = await llm.next_token_logprobs(token_ids)

Example: Autobatched Sequential Importance Sampling with LLMs

This example demonstrates how genlm-backend enables concise, scalable probabilistic inference with language models. It implements a Sequential Importance Sampling (SIS) algorithm that makes asynchronous log-probabality requests which get automatically batched by the language model.

import torch
import asyncio
from genlm.backend import load_model_by_name

# --- Token-level masking using the byte-level vocabulary --- #
def make_masking_function(llm, max_token_length, max_tokens):
    eos_id = llm.tokenizer.eos_token_id
    valid_ids = torch.tensor([
        token_id == eos_id or len(token) <= max_token_length
        for token_id, token in enumerate(llm.byte_vocab)
    ], dtype=torch.float).log()
    eos_one_hot = torch.nn.functional.one_hot(
        torch.tensor(eos_id), len(llm.byte_vocab)
    ).log()

    def masking_function(context):
        return eos_one_hot if len(context) >= max_tokens else valid_ids

    return masking_function

# --- Particle class for SIS --- #
class Particle:
    def __init__(self, llm, mask_function, prompt_ids):
        self.context = []
        self.prompt_ids = prompt_ids
        self.log_weight = 0.0
        self.active = True
        self.llm = llm
        self.mask_function = mask_function

    async def extend(self):
        logps = await self.llm.next_token_logprobs(self.prompt_ids + self.context)
        masked_logps = logps + self.mask_function(self.context).to(logps.device)
        logZ = masked_logps.logsumexp(dim=-1)
        self.log_weight += logZ
        next_token_id = torch.multinomial((masked_logps - logZ).exp(), 1).item()
        if next_token_id == self.llm.tokenizer.eos_token_id:
            self.active = False
        else:
            self.context.append(next_token_id)

# --- Autobatched SIS loop --- #
async def autobatched_sis(n_particles, llm, masking_function, prompt_ids):
    particles = [Particle(llm, masking_function, prompt_ids) for _ in range(n_particles)]
    while any(p.active for p in particles):
        await asyncio.gather(*[p.extend() for p in particles if p.active])
    return particles

# --- Run the example --- #
llm = load_model_by_name("gpt2") # or e.g., "meta-llama/Llama-3.2-1B" if you have access
mask_function = make_masking_function(llm, max_token_length=10, max_tokens=10)
prompt_ids = llm.tokenizer.encode("Montreal is")
particles = await autobatched_sis( # use asyncio.run(autobatched_sis(...)) if you are not in an async context
    n_particles=10, llm=llm, masking_function=mask_function, prompt_ids=prompt_ids
)

strings = [llm.tokenizer.decode(p.context) for p in particles]
log_weights = torch.tensor([p.log_weight for p in particles])
probs = torch.exp(log_weights - log_weights.logsumexp(dim=-1))

for s, p in sorted(zip(strings, probs), key=lambda x: -x[1]):
    print(f"{repr(s)} (probability: {p:.4f})")

This example highlights the following features:

  • 🌀 Asynchronous Inference Loop. Each particle runs independently, but all LLM calls are scheduled concurrently via asyncio.gather. The backend batches them automatically, so we get the efficiency of large batched inference without having to write the batching logic.
  • 🔁 Byte-level Tokenization Support. Token filtering is done using the model’s byte-level vocabulary, which genlm-backend exposes. This enables low-level control over generation in ways not possible with most high-level APIs.

Development

See the DEVELOPING.md file for information on how to install the project for local development.

Metadata

Release files for genlm-backend 0.3.0

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

Source distribution (sdist)

Source distribution for genlm-backend 0.3.0
File Size Uploaded
genlm_backend-0.3.0.tar.gz 3.8 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for genlm-backend 0.3.0
File Interpreter ABI Platform
genlm_backend-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.9 MB

Release files / genlm_backend-0.3.0.tar.gz

Download URL genlm_backend-0.3.0.tar.gz
Size 3.8 MB
Tags Source
SHA-256 checksum
How to use checksums
4ca6abb3d5e5141dbcb947bf9860dc77780d783f2b7acf62d406bf2a6dcdc7f6
BLAKE2b-256 checksum
How to use checksums
d30af2703090beea503893cb431cb9b564ee2feea6ed8d1540992c3b62105248
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 Sep 26, 2026.

Transparency log

Release files / genlm_backend-0.3.0-py3-none-any.whl

Download URL genlm_backend-0.3.0-py3-none-any.whl
Size 50.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b569f4c534bc57551eddb0672a6c56724b3584968ebdffcbba15b76624a7b823
BLAKE2b-256 checksum
How to use checksums
d6c0c0bf6e29f178a97a7187c9f4154ac5ad39b1e0985a9521b6fee7ddc7eb69
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 Sep 26, 2026.

Transparency log
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