GitHub   Twitter/X   LinkedIn   Discord   Performance Models

P-H3-Image

Image generation and editing based on MiniMax-H3

8 steps  ·  No CFG  ·  8 MP  ·  Text-to-image and editing with up to 8 images

P-H3-Image is an image model for text-to-image generation and image editing, based on MiniMax-H3. It renders 8-megapixel images in 8 steps without classifier-free guidance, edits with up to 8 input images, and comes with a prompt upsampler that turns a one-line request into the full prompt P-H3-Image renders best. It is strongest at photorealism, film and editorial looks, and graphic styles with short quoted text.

This repository holds the diffusers pipeline. For ComfyUI, with int8 and 4-bit files that run in 21 GB of VRAM, see PrunaAI/P-H3-Image-Comfy. Read the full blog post here.

Tasks Text-to-image, and image editing with 1 to 8 input images
Sampling 8 steps, no CFG or negative prompt
Resolution 8 MP for text-to-image, 4 or 8 MP for edits
Prompt upsampler Included and on by default, based on Qwen3.5-9B
Weights 33.1B-parameter transformer, 4B text encoder, VAE and prompt upsampler, 100 GB in bf16
GPU memory at 8 MP About 101 GB with the prompt upsampler, 83 GB without

Quickstart

Run text-to-image and editing with the same pipeline. At 8 MP in bf16 it needs a GPU with about 101 GB of memory, such as one H200 or B200, or 80 GB with offloading.

pip install git+https://github.com/huggingface/diffusers
pip install -U transformers accelerate torch pillow
import torch
from diffusers import ModularPipeline

pipe = ModularPipeline.from_pretrained("PrunaAI/P-H3-Image")
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")

prompt = (
    "A German Expressionist oil painting of a Berlin street at night in the manner of Ernst Ludwig Kirchner, "
    "with gaunt figures hurrying past a glowing gas lamp."
)
image = pipe(
    prompt=prompt,
    height=3360, width=2496,  # 8 MP, 3:4
    generator=torch.Generator().manual_seed(3),
    output="images",
)[0]
image.save("berlin.png")

The pipeline picks the task from its inputs. Pass image to edit.

from diffusers.utils import load_image

# Edit one image
edited = pipe(prompt="let it snow on the street", image=image, output="images")[0]

# Up to 8 images. The first is edited, the others are references, named Picture 2, Picture 3 and so on.
composed = pipe(
    prompt="give the woman in picture 1 the hat from picture 2",
    image=[load_image("portrait.png"), load_image("hat.png")],
    output="images",
)[0]

Recommended resolutions

P-H3-Image works best at 8 MP. Images at 2 and 4 MP can be good too, but artifacts become more frequent, especially in faces, hands and small details. For text-to-image, use one of the 8 MP sizes below. The default is 2912 × 2912.

Edits work best at 4 or 8 MP. Without height and width, the edit is generated at the size of Picture 1, scaled up to at least 4 MP. The other images keep their size between 1 and 8 MP. Passing height and width changes the canvas, not the images. Sides are rounded to multiples of 32, with a warning.

Aspect ratio 8 MP (width × height) 4 MP, for edits
1:1 2912 × 2912 2048 × 2048
4:3 3360 × 2496 2368 × 1760
3:4 2496 × 3360 1760 × 2368
3:2 3552 × 2368 2496 × 1664
2:3 2368 × 3552 1664 × 2496
16:9 3872 × 2176 2720 × 1536
9:16 2176 × 3872 1536 × 2720
SIZES_8MP = {  # aspect ratio -> (width, height)
    "1:1": (2912, 2912),
    "4:3": (3360, 2496),
    "3:4": (2496, 3360),
    "3:2": (3552, 2368),
    "2:3": (2368, 3552),
    "16:9": (3872, 2176),
    "9:16": (2176, 3872),
}

width, height = SIZES_8MP["16:9"]
image = pipe(prompt=prompt, width=width, height=height, output="images")[0]

The same prompt and seed from 1 to 16 MP, with the face enlarged in the bottom row. At 1 MP the face is smooth and waxy. From 8 MP on, skin texture, stray hairs and the gold earrings come through. The composition shifts between resolutions because the noise changes with the image size.

Prompting

P-H3-Image is sensitive to prompting and renders full, specific prompts much better than short requests. The pipeline therefore runs a prompt upsampler, based on Qwen3.5-9B, on every request. It writes a detailed prompt for the aspect ratio of height and width, or, for an edit, a brief of what to keep and what to change. The prompt it wrote comes back as the prompt output.

out = pipe(prompt=prompt, height=3360, width=2496, output=["images", "prompt"])
print(out["prompt"])

To render a prompt as written, remove the step from the blocks.

blocks = ModularPipeline.from_pretrained("PrunaAI/P-H3-Image").blocks
blocks.sub_blocks.pop("prompt_upsampler")

pipe = blocks.init_pipeline("PrunaAI/P-H3-Image")
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")
image = pipe(prompt=prompt, height=3360, width=2496, output="images")[0]  # rendered as written

When you write prompts by hand, four things matter most.

  1. Say what the image is. Open with one sentence that names the real object the image is, such as "a photograph by an experienced street photographer", "a frame from a Japanese anime TV series", "a two-color risograph print" or "a flat scan of a handwritten recipe card". This sets the look more reliably than any style word.
  2. Describe one scene. Give a viewpoint, one main subject caught in a moment, a few supporting elements, and light with a source and a direction.
  3. Spell out every word. Text without its exact words turns into pseudo-text. Put each piece of text in quotes, keep each string short, say where it sits, and end with "no other text". If you want no text, don't mention signs or labels at all.
  4. Leave out hype words. Stunning, epic, cinematic, vibrant, hyper-detailed, 8k or masterpiece push P-H3-Image toward a glossy, oversaturated, airbrushed look.

The first sentence says what the image is (bold), and every string that must appear is quoted (blue). The handwriting follows the quoted text almost word for word.

Styles that work especially well include documentary and editorial photography, portraits with real skin texture, film frames, TV-frame anime, ink and charcoal drawings, screen-printed posters and flat graphic design with short quoted text.

Risograph print, child's crayon drawing, 1960s color photograph, 1970s film frame.

Editing

Pass one image to edit it, or a list of up to 8. Picture 1 is the image to edit, and the others are references the request can name as Picture 2, Picture 3 and so on. The upsampler writes the edit prompt in the form P-H3-Image edits best from, so a short request such as "make the pickup truck red" is enough.

The same short request given as typed (middle) and written as an edit prompt that names what to keep (right), the form the upsampler writes. As typed, P-H3-Image often redraws the whole scene. As an edit prompt, only the requested part changes.

P-H3-Image combines many references at once. Given up to 8 pictures and a one-line request, the upsampler names each picture and what to take from it, and P-H3-Image composes them into one scene.

Top, eight public-domain portraits and the dinner party P-H3-Image composed from them, from a one-sentence request. Bottom, eight scientists at a poker table, seven presidents wading through the swamp with an astronaut, and characters from our own renders in the same swamp.

To write edit prompts without the upsampler, use this form.

Edit <Picture 1>. <The change, described as the finished result>. Keep <everything that must stay> exactly as it is.
  • Point to the exact thing. Name the object, person or text you mean and where it is, such as "the old man's faded blue cap" rather than "his hat".
  • Describe the result, not the action. Say how the edited part looks in the finished image, and give new things a size next to something already there, such as "about the size of the cat's head".
  • Say what stays. List what must not change, such as faces, poses, the background and the light. Without this list, P-H3-Image tends to redraw the whole image.
  • Quote new text exactly. Put new text in quotes and name the text around it that must stay.

Less GPU memory

With auto offloading, diffusers moves each component onto the GPU when a step needs it, so the pipeline runs on one 80 GB GPU such as an H100, peaking at about 76 GB at 8 MP.

import torch
from diffusers import ComponentsManager, ModularPipeline

manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda")

pipe = ModularPipeline.from_pretrained("PrunaAI/P-H3-Image", components_manager=manager)
pipe.load_components(dtype=torch.bfloat16)
image = pipe(prompt=prompt, height=3360, width=2496, output="images")[0]

Performance

One NVIDIA B200, bf16, batch size 1, 8 MP, no compilation or offloading.

Time Peak GPU memory
Text-to-image, prompt as written about 9 s 83 GB
Prompt upsampler 6 to 11 s more 101 GB with the image model

The 8 steps run over the checkpoint's own sampling grid. Pass sigmas to use another one. There is no guider, negative_prompt or guidance_scale. For GPUs with less memory, use the int8 or w4a8 files in PrunaAI/P-H3-Image-Comfy.

Limitations

  • It is sensitive to prompting. Hype words and very long prompts make images worse, and very short prompts give weak results without the upsampler.
  • Hands can break, and small people in the background can come out distorted. Rendering at 8 MP helps.
  • Text is not fully reliable. Small or dense text, such as body copy or long code, turns into pseudo-text, and longer passages sometimes get single letters wrong. Short quoted strings render well.
  • Lower resolutions show more artifacts. At 2 and 4 MP, faces, hands and small details break more often than at 8 MP.
  • Single images only. P-H3-Image does not generate video or audio.

License

P-H3-Image is based on MiniMax-H3 and released under the MiniMax H3 Community License. Please read it before use. Among other terms, it excludes the European Union, the United Kingdom, the Republic of Korea and the United States unless you have a separate license from MiniMax, and products built on it must show "Powered by MiniMax H3". The text encoder's Qwen3-VL-4B parts and the prompt upsampler, based on Qwen3.5-9B, are under the Apache License 2.0. See NOTICE for details.

What's next?

  • Compress your own models with Pruna and give us a ⭐️ for more efficiency!
  • Want to use our optimized image models right away? Check P-Image-Ideogram and P-Image-Edit.

Try our models

Downloads last month
111
Safetensors
Model size
33B params
Tensor type
F32
·
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for PrunaAI/P-H3-Image

Finetuned
(206)
this model
Adapters
1 model
Quantizations
1 model

Spaces using PrunaAI/P-H3-Image 2

Collection including PrunaAI/P-H3-Image