Skip to page content
SAVRN
Search Plan a project

Open-weight model · Text to image

pinhole-m

by Nuhman PK nuhmanpk/pinhole-m

pinhole-m is an open-weight model for text to image from Nuhman PK, released under Open RAIL++ License. It has 34M parameters. At 16-bit it needs about 0.1 GB of GPU memory, which fits on 1x MI300X from $1.85 an hour, at the lowest prices in the SAVRN Index.

A 34.4M-parameter text-to-image model for pixel art, flat icons and stickers. Small enough for laptops and, next, the browser. Part of Darkroom, a project to build tiny image generators that run where you are.

Parameters34M
Context—
Weights464.9 MB
Licenseopenrail++
AccessOpen weights
Monthly Downloads—

Runs On

What it takes to serve pinhole-m (34M parameters): the memory its weights need at each precision, and the cheapest way to rent enough data-center GPUs to hold them.

PrecisionWeightsMemory neededCheapest setupPer hourAlso fits
16-bit 0.1 GB 0.1 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00
8-bit 0.0 GB 0.0 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00
4-bit 0.0 GB 0.0 GB 1x MI300X (192 GB)
Vultr
$1.85 1x H100 $1.99 · 1x MI325X $2.00

Memory is the weights at that precision plus 20% for the runtime and a short context; a long context needs more. Prices are the lowest on-demand hourly rates in the SAVRN Index, read Oct 18, 2026.

pinhole-m on every accelerator the SAVRN Index prices, at every precision

Model Card

By Nuhman PK, published under openrail++, revision b7a6e42ec47f.

A 34.4M-parameter text-to-image model for pixel art, flat icons and stickers. Small enough for laptops and, next, the browser. Part of Darkroom, a project to build tiny image generators that run where you are. The same held-out prompts, never seen in training, from the 0.6B teacher and from each Pinhole size: ONNX Runtime Web (WebAssembly or WebGPU), so prompts and images never leave the browser. Parity: the ONNX-only pipeline matches PyTorch to within a mean of 0.00/255 per pixel (same noise, 20 steps). The browser's tokenizer is checked against Python by the demo's Self-test button. Start with one of the three styles, then describe a simple subject: of a. - Adjust guidance with cfg: 3–6…

Read Nuhman PK's full model card

A 34.4M-parameter text-to-image model for pixel art, flat icons and stickers. Small enough for laptops and, next, the browser. Part of Darkroom, a project to build tiny image generators that run where you are.

Parameters 34.4M (plus CLIP ViT-B/32 text encoder, TAESD decoder)
Weights 69 MB (fp16)
Output 256x256 RGB
Speed, T4 GPU 225 ms per image (20 steps, guidance 4)
Speed, CPU (Kaggle) 3,661 ms per image
CLIP score, held-out prompts 30.36 (teacher PixArt-LCM: 32.64)

Samples

The same held-out prompts, never seen in training, from the 0.6B teacher and from each Pinhole size:

Run it in your browser

No install needed: open the live demo. The model runs on your device with ONNX Runtime Web (WebAssembly or WebGPU), so prompts and images never leave the browser.

Browser file Size
onnx/dit.onnx (Pinhole-M) 138 MB
onnx/text_encoder.onnx (CLIP ViT-B/32, fp32) 253 MB
onnx/taesd_decoder.onnx 4.9 MB
Total first download (cached afterwards) 396 MB

Parity: the ONNX-only pipeline matches PyTorch to within a mean of 0.00/255 per pixel (same noise, 20 steps). The browser's tokenizer is checked against Python by the demo's Self-test button.

import * as ort from "https://cdn.jsdelivr.net/npm/[email protected]/dist/ort.all.min.mjs";
import { AutoTokenizer } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]";
import { PinholeWeb } from "./pinhole-web.js";      // web/pinhole-web.js in this repo
const pinhole = await PinholeWeb.load("nuhmanpk/pinhole-m", { ort, AutoTokenizer });
const { rgba, width, height } = await pinhole.generate("sticker of a happy red fox", { steps: 20, cfg: 4, seed: 7 });
canvas.getContext("2d").putImageData(new ImageData(rgba, width, height), 0, 0);

Quick start

pip install torch diffusers transformers safetensors huggingface_hub
from huggingface_hub import snapshot_download
import sys
path = snapshot_download("nuhmanpk/pinhole-m"); sys.path.insert(0, path)
from pinhole import Pinhole

pipe = Pinhole.from_pretrained(path)            # GPU if available, else CPU
images = pipe("sticker of a happy red fox", n=4, steps=20, cfg=4.0, seed=0)
images[0].save("fox.png")

Prompting

Start with one of the three styles, then describe a simple subject: <style> of a <adjective> <colour> <subject>.

Style Example
pixel art pixel art of a retro blue rocket
flat icon flat icon of a cozy green house
sticker sticker of a smiling pink cupcake

Tips: - Single, simple subjects work best: animals, food, objects, plants, vehicles and fantasy items. - Adjust guidance with cfg: 3–6 is the useful range; higher means stronger prompt following and less variety. - Adjust steps with steps: 12 is faster; 20 is the default.

The Pinhole family

Model Params Weights CLIP score T4 GPU CPU
pinhole-s 13.1M 26 MB 30.28 187 ms 1,844 ms
pinhole-m 34.4M 69 MB 30.36 225 ms 3,661 ms
pinhole-l 70.8M 142 MB 30.57 258 ms 6,764 ms
PixArt-LCM teacher (reference) 600M + 4.7B text encoder ~11 GB 32.64

How it works

  • Generator: a small diffusion transformer (adaLN-Zero blocks with cross-attention to text) predicts 4x32x32 latents with patch size 2 (256 tokens).
  • Text: frozen CLIP ViT-B/32 text features (77 tokens plus the pooled embedding).
  • Pixels: the TAESD decoder turns latents into 256x256 RGB.
  • Training objective: rectified-flow matching (x_t = (1 - t) x0 + t * noise, predict noise - x0) with logit-normal timesteps and 10% caption dropout for classifier-free guidance.
  • Weights: an EMA of the training weights is shipped.

Training

  • Data: nuhmanpk/darkroom-pinhole-18k, 18,000 images made by PixArt-alpha/PixArt-LCM-XL-2-1024-MS (4 steps) for short captions in 3 styles.
  • Schedule: 30,000 steps, global batch 128, AdamW (lr 0.0003), warmup plus cosine, fp16, EMA 0.999, horizontal-flip augmentation.
  • Hardware: Kaggle 2x T4, 152 minutes. Final training loss 0.3350.

Limitations

  • Low resolution: 256x256, best for icons, sprites and stickers, not photographs.
  • Simple subjects: it learned single, centered subjects on plain backgrounds. Complex scenes, counting, text in images and people are not supported.
  • Limited by the teacher and a small dataset. Expect some off-prompt or blobby results, especially from pinhole-s. The CLIP-score gap to the teacher is shown above.
  • English captions only.

License

CreativeML Open RAIL++-M, inherited from the PixArt-LCM teacher, including its use-based restrictions (see LICENSE.md). pinhole.py is Apache-2.0.

Credits

Built by Nuhman PK. Teacher: PixArt-α / PixArt-LCM. Text encoder: OpenAI CLIP ViT-B/32. Decoder: TAESD by Ollin Boer Bohan. Training ideas from DiT and rectified flow.

Identity and Version

Repository
nuhmanpk/pinhole-m
Publisher
Nuhman PK
Task
Text to image
Modality
Image
Library
pytorch
Parameters
34M parameters
Languages
en
Revision
b7a6e42ec47f92019079562850339aeac7407ac8
First published
2026-10-05
Last updated
2026-10-05

Files and Weights

18 files, 470.3 MB in total. The weights are 4 files totalling 464.9 MB in onnx, safetensors.

Weights4 files · 464.9 MB
Configuration5 files · 28.8 KB
Tokenizer2 files · 3.6 MB
Documentation2 files · 6.6 KB
Other4 files · 1.7 MB
Repository1 file · 1.7 KB
Every file
FileTypeSizeSHA-256
model.safetensorsWeights68.8 MB 6f9a00c53472
onnx/dit.onnxWeights138.4 MB 8062234e7d81
onnx/taesd_decoder.onnxWeights4.9 MB 4824881a485c
onnx/text_encoder.onnxWeights252.8 MB d57da24f6bbc
config.jsonConfiguration508 B —
pinhole.pyConfiguration10.1 KB —
train_log.jsonConfiguration3.2 KB —
web/fixtures.jsonConfiguration14.1 KB —
web/pinhole_web.jsonConfiguration855 B —
LICENSE.mdDocumentation669 B —
README.mdDocumentation6.0 KB —
assets/banner.pngOther212.0 KB efde05fb57ec
assets/samples_m.pngOther609.5 KB 24a3339f67d5
assets/teacher_vs_pinhole.pngOther831.6 KB cec303eab5d1
web/pinhole-web.jsOther8.2 KB —
.gitattributesRepository1.7 KB —
tokenizer.jsonTokenizer3.6 MB —
tokenizer_config.jsonTokenizer350 B —

License and Download

License
openrail++
Access
Open weights, no gate
Download size
464.9 MB
Download from Nuhman PK

Released by Nuhman PK through its official repository on Hugging Face.

Built From

  • Trained on (disclosed) nuhmanpk/darkroom-pinhole-18k

Memory Requirements

PrecisionWeights in memory
As published464.9 MB
16-bit0.1 GB
8-bit0.0 GB
4-bit0.0 GB

Weights only, from the published parameter count; the key-value cache and runtime add to this.

Questions About pinhole-m

How much GPU memory does pinhole-m need?

About 0.1 GB at 16-bit and 0 GB at 4-bit: the weights (34M parameters) plus a working margin. A long context needs more.

What is the cheapest GPU to run pinhole-m on?

At 16-bit, 1x MI300X from $1.85 an hour; at 4-bit, 1x MI300X from $1.85 an hour, at the lowest on-demand prices the SAVRN Index lists.

Can I use pinhole-m commercially?

Yes, with conditions. pinhole-m is released under Open RAIL++ License. Open RAIL++ permits use, including commercial use, subject to the use-based restrictions listed in the license, which must be passed on to downstream users.

Similar Models

Model · Text to image

pinhole-s

Nuhman PK

A 13.1M-parameter text-to-image model for pixel art, flat icons and stickers. Small enough for laptops and, next, the browser. Part of Darkroom, a project to build tiny image generators that run where you are. The same held-out prompts, never seen in training, from the 0.6B teacher and from each Pinhole size: ONNX Runtime Web (WebAssembly or WebGPU), so prompts and images never leave the browser. Parity: the ONNX-only pipeline matches PyTorch to within a mean of 0.00/255 per pixel (same noise, 20 steps). The browser's tokenizer is checked against Python by the demo's Self-test button. Start with one of the three styles, then describe a simple subject: of a. - Adjust guidance with cfg: 3–6…

Open weights openrail++ 13M parameters pytorch

This is a modular diffusion pipeline built with Diffusers' modular pipeline framework. Description: Auto Modular pipeline for text-to-image and image-conditioned generation using Qwen-Image 2.1. - for text-to-image generation, all you need to provide is prompt - for image-conditioned generation, you need to provide prompt and image (one image or a list) This pipeline uses a 4-block architecture that can be customized and extended. [TODO] This modular pipeline is composed of the following blocks: 1. textencoder (QwenImage21AutoTextEncoderStep) - Text encoder step that encodes the prompt, together with the condition images when there are any. 2. vaeencoder (QwenImage21AutoVaeEncoderStep)…

Open weights 36,944 parameters diffusers

GGUF, Safetensors, and MLX quantized formats of Qwen/Qwen-Image-2.1 for local image generation using the original upstream base weights. Q4KM is recommended for the best balance of size and quality for GGUF. INT8 ConvRot and NVFP4 offer high performance on supported GPUs, while MLX formats are optimized for Apple Silicon. Companion model files packaged for ComfyUI: Use the model with ComfyUI and ComfyUI-GGUF. All required companion files (GGUF transformer, text encoder, and VAE) are hosted directly in this repository. Download the files and place them in their respective ComfyUI directories: 1. Install ComfyUI-GGUF: Use the maintained fork with native Qwen-Image 2.1 support by cloning…

Open weights other gguf

GGUF quantizations of Qwen/Qwen-Image-2.1 for local image generation using the original upstream base weights. Q4KM is recommended for the best balance of size and quality. Companion model files packaged for ComfyUI: Use the model with ComfyUI and ComfyUI-GGUF. All required companion files (GGUF transformer, text encoder, and VAE) are hosted directly in this repository. Download the files and place them in their respective ComfyUI directories: 1. Install ComfyUI-GGUF: Use the maintained fork with native Qwen-Image 2.1 support by cloning leejet/ComfyUI-GGUF into your custom nodes: (Note: If you have the older city96/ComfyUI-GGUF installed and encounter an Unknown model architecture! error…

Open weights other gguf

Model · Text to image

Qwen-Image-2.1-GGUF

Unsloth AI

This is a GGUF quantized version of Qwen-Image-2.1. unsloth/Qwen-Image-2.1-GGUF uses Unsloth Dynamic 2.0 methodology for SOTA performance. - Important layers are upcasted to higher precision, per tensor, from a measured sensitivity scan. - Run these with Unsloth Desktop, stable-diffusion.cpp and more. A GGUF is the denoiser only, so it needs the VAE and the Qwen3-VL text encoder alongside it. See below for image editing operating inside of Unsloth Desktop: Rendered with the Q4KM denoiser and the Q4KM text encoder, 1024x1024, 20 steps, cfg 6.0, euler. We are excited to open-source Qwen-Image-2.1, a unified text-to-image generation and image editing model in the Qwen family. With just 7B…

Open weights other

Model · Text to image

Z-Image-Turbo-GGUF

Unsloth AI

Welcome to the official repository for the Z-Image(造相)project! Z-Image is a powerful and highly efficient image generation model with 6B parameters. Currently there are three variants: - Z-Image-Turbo – A distilled version of Z-Image that matches or exceeds leading competitors with only 8 NFEs (Number of Function Evaluations). It offers sub-second inference latency on enterprise-grade H800 GPUs and fits comfortably within 16G VRAM consumer devices. It excels in photorealistic image generation, bilingual text rendering (English & Chinese), and robust instruction adherence. - Z-Image-Base – The non-distilled foundation model. By releasing this checkpoint, we aim to unlock the full potential…

Open weights apache-2.0 ggml