Skip to main content

Gen5 is a binary container format aimed at increased reproducibility for AI-generated images. It enables the storage of several key pieces of information, such as :

1. Environment & Provenance Tracking

The GEN5 file format has a dedicated chunk that captures Runtime Environment Details at the time of generation. This includes:

  • Operating System and Machine Identifiers
  • CPU/GPU models, core counts, and memory
  • Deep learning framework (e.g., PyTorch) and compute backend (e.g., CUDA)
  • Driver and library versions (e.g., CUDA version, NVIDIA driver) This is further utilised to warn the user of environment mismatches.

Environment Chunk (ENVC)

GEN5 includes an optional but strongly recommended environment chunk (ENVC) that captures a verifiable snapshot of the software stack used during generation. Unlike generic metadata, this chunk:

Is structured as a list of canonicalized components (e.g., torch, python, cuda, gpu) Records each component’s name, version, and a SHA-256 digest of its canonical string Is compressed and stored as a standalone binary chunk with its own offset and hash in the chunk table Enables integrity verification and drift detection across environments This chunk is not embedded in the metadata JSON, but referenced via the chunks array in the decoded output (type "ENVC"), ensuring it remains tamper-evident and tooling-friendly.

HOW TO USE? It is automatically populated and stored for you! When environment mismatch is detected, a warning is issued. Example Warning for gpu mismatch:

UserWarning: Environment component 'gpu' differs:
File: name=gpu;model=NVIDIA A100;driver=535.129.01
Current: name=gpu;model=NVIDIA GeForce RTX 4090;driver=550.40.07

2. Latent Tensor Storage

GEN5 natively supports the storing of latent representations (ie, diffusion model latents, VAE encodings) alongside the generated images. These are serialized as one or more 'LATN' chunks. These are stored in their native memory layout (as provided by the user). For PyTorch-generated latents, this is typically NCHW. And for TensorFlow, it is going to be NHWC. The format does not enforce or convert layout, insted it preserves the exact shape and byte representation as provided by the user.

HOW TO STORE? Example:

gen5.file_encoder(
  filename="my_ai_art.gen5",
  latent={
      "initial_noise": initial_noise.numpy(),
      "final_latent": final_latent.numpy()
  },
  chunk_records=[],
  model_name="Stable Diffusion 3",
  model_version="3.0",
  prompt="A cyberpunk cat wearing neon goggles, cinematic lighting",
  tags=["cat", "cyberpunk", "neon"],
  img_binary=img_bytes,
  convert_float16=True,       # store latents in float16 to save space (optional)
  should_compress=True,       #SEE THE CRITICAL WARNING BELOW
  generation_settings={
      "seed": 1337,
      "steps": 30,
      "sampler": "euler_ancestral",
      "cfg_scale": 7.0,
      "scheduler": "karras",
      "precision": "fp16"
  },
  hardware_info={
      "machine_name": "desktop-alpha",
      "os": "linux",
      "cpu": "AMD Ryzen 9 7950X",
      "cpu_cores": 16,
      "gpu": [
          {
              "name": "NVIDIA RTX 4090",
              "memory_gb": 24,
              "driver": "550.54.14",
              "cuda_version": "12.4"
          }
      ],
      "ram_gb": 128.0,
      "framework": "torch",
      "compute_lib": "cuda"
  }
)

!!! danger CRITICAL WARNING: The should _compress is for compressinng the latent chunks. For High Entropy Tensors: FALSE, Low Entropy Tensors: TRUE

Extra Metadata:

  • Model name and version
  • Prompt
  • Tags
  • Hardware information
  • Generation settings

(may include sampler-specific parameters)

The Initial noise tensor can be fed back in while using a model (local ones) to obtain similar results.

This has proven to be capable of producing extremely similar images. Although we use a random seed integer value, the usage of the real tensor provides increased reproducibility.

Installation

Just pip install the package!

pip install gen5

Usage

import the classes

from gen5.main import Gen5FileHandler

First you need to instantiate the Gen5FileHandler class.

gen5 = Gen5FileHandler()

Encoding

!!! danger DISCLAIMER: The encoder expects NumPy arrays.
If you use PyTorch tensors, convert them with .detach().cpu().numpy().

from gen5.main import Gen5FileHandler

gen5 = Gen5FileHandler()
initial_noise_tensor = torch.randn(batch_size, channels, height, width)
latent = {
    "initial_noise": initial_noise_tensor.detach().cpu().numpy() #The encoder expects numpy array not a torch tensor object
}
binary_img_data = gen5.png_to_bytes(r'path/to/image.png') # use the helper function to convert image to bytes

gen5.file_encoder(
    filename="encoded_img.gen5", # The .gen5 extension is required!
    latent=latent,# initial latent noise
    chunk_records=[],
    model_name="Stable Diffusion 3",
    model_version="3", # Model Version
    prompt="A puppy smiling, cinematic",
    tags=["puppy","dog","smile"],
    img_binary=binary_img_data,
    convert_float16=False, # whether to convert input tensors to float16
    generation_settings={
        "seed": 42,
        "steps": 20,
        "sampler": "ddim",
        "cfg_scale": 7.5,
        "scheduler": "pndm",
        "eta": 0.0,
        "guidance": "classifier-free",
        "precision": "fp16",
        "deterministic": True
    },
    hardware_info={
        "machine_name": "test_machine",
        "os": "linux",
        "cpu": "Intel",
        "cpu_cores": 8, # minimum 1
        "gpu": [{"name": "RTX 3090", "memory_gb": 24, "driver": "nvidia", "cuda_version": "12.1"}],
        "ram_gb": 64.0,
        "framework": "torch",
        "compute_lib": "cuda"
    }
)

Decoding

decoded = gen5.file_decoder(filename)
# now to save the metadata
metadata = decoded["metadata"]["gen5_metadata"]

# to just get specific metadata blocks
model_info = decoded["metadata"]["gen5_metadata"]["model_info"]

# to save decoded metadata to a json file
with open("decoded_metadata.json", "w") as f:
    json.dump(decoded["metadata"], f, indent=2)

# to save just the image_binary as png
image_bytes = decoded["chunks"].get("image")
if image_bytes is not None:
    img = Image.open(io.BytesIO(image_bytes))
    img.save("decoded_image.png")

Metadata

Release files for gen5 0.1.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 gen5 0.1.0
File Size Uploaded
gen5-0.1.0.tar.gz 21.5 kB Details

Built distribution (wheel)

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

Total release size: 40.6 kB

Release files / gen5-0.1.0.tar.gz

Download URL gen5-0.1.0.tar.gz
Size 21.5 kB
Tags Source
SHA-256 checksum
How to use checksums
0ea1659ac904cb1e6860735e07bc08c624b0846c02a466c325816f9932c62876
BLAKE2b-256 checksum
How to use checksums
278af71cf4c8110c45555d20df8dc433f21c769870e51cc60a2d73cea1c89c94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / gen5-0.1.0-py3-none-any.whl

Download URL gen5-0.1.0-py3-none-any.whl
Size 19.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1061d7c171650d4631cec9abbf48fc664abf75e04088d5c2261735856cef632d
BLAKE2b-256 checksum
How to use checksums
8c0d4b2fb1fe056e66ddbac869a4b35e598446942d5c54132905b6a45535e080
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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