# P-H3-Image

P-H3-Image 是由 Pruna AI 基于 [MiniMax-H3](./minimax_h3) 构建的图像模型，用于文本生成图像以及基于指令的图像编辑。您可以在 [PrunaAI/P-H3-Image](https://huggingface.co/PrunaAI/P-H3-Image) 找到该检查点。

```py
import torch
from diffusers import ComponentsManager, ModularPipeline

manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda")  # or "mps", "xpu"

pipe = ModularPipeline.from_pretrained("PrunaAI/P-H3-Image", components_manager=manager)
pipe.load_components(dtype=torch.bfloat16)

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, generator=torch.Generator().manual_seed(3), output="images")[0]
edited = pipe(prompt="let it snow on the street", image=image, output="images")[0]
```

每个请求都会先经过 [prompt upsampler](#prompt-upsampling)。当所有组件都位于加速器上时，该流水线在 8 兆像素下以 bfloat16 精度运行大约需要 101 GB 显存，因此示例使用了自动卸载：当某个块需要某个组件时，[ComponentsManager](/docs/diffusers/main/zh/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager) 会将其移动到加速器上，从而使流水线能够在 80 GB 的 GPU 上运行。

## 组件

| 组件 | 类 |
|---|---|
| `transformer` | [MiniMaxH3Transformer3DModel](/docs/diffusers/main/zh/api/models/minimax_h3_transformer3d#diffusers.MiniMaxH3Transformer3DModel) |
| `text_encoder` | `Qwen3VLForConditionalGeneration`（Qwen3-VL-4B） |
| `text_connector` | [PH3ImageTextConnector](/docs/diffusers/main/zh/api/pipelines/p_h3_image#diffusers.PH3ImageTextConnector) |
| `vae` | [AutoencoderKLPH3Image](/docs/diffusers/main/zh/api/models/autoencoderkl_p_h3_image#diffusers.AutoencoderKLPH3Image) |
| `tokenizer`, `processor` | 文本编码器的分词器，以及一个包含 MiniMax-H3 图像处理器的 `Qwen3VLProcessor` |
| `scheduler`, `audio_scheduler` | [MiniMaxH3Scheduler](/docs/diffusers/main/zh/api/schedulers/minimax_h3#diffusers.MiniMaxH3Scheduler) |
| `prompt_upsampler`, `prompt_upsampler_processor` | `Qwen3_5ForConditionalGeneration`（基于 Qwen3.5-9B）及其处理器 |

## 工作流程

工作流在 `image` 输入上选择：

- **`text2image`** 根据 `prompt` 生成图像。`height` 和 `width` 的默认值为 2912，并会四舍五入到 32 的倍数。该模型在 800 万像素下表现最佳，例如 2912x2912、3872x2176 或 2176x3872。
- **`image_conditioned`** 根据 `prompt` 中的指令对 `image` 进行编辑，在 4 或 8 百万像素下效果最佳。图像会以约 `vision_pixels`（一百万像素）的分辨率编码供文本编码器使用，并以自身尺寸编码供 VAE 使用；若超出该范围，则会放大至 `reference_min_pixels`（一百万像素）或缩小至 `reference_max_pixels`（八百万像素）。若未指定 `height` 和 `width`，则编辑结果将按第一张图像的尺寸生成，若该尺寸较小，则会放大至 `canvas_min_pixels`（四百万像素）。若传入 `height` 和 `width`（会取整为 32 的倍数），则会改变画布尺寸，但不会改变图像本身。`image` 也可以是包含最多 8 张图像的列表：第一张为待编辑图像，其余为参考图像，分别对应 `<Picture 2>`、`<Picture 3>` 等。

## 提示词上采样

P-H3-Image 旨在渲染完整的提示词，而非简短的请求，因此流水线会在每个请求上首先运行提示词扩展器。它会先思考该请求，然后撰写提示词：针对 `height` 和 `width` 宽高比的详细文生图提示词，或者在编辑时，一份关于保留哪些内容以及修改哪些内容的说明。它撰写的提示词会作为 `prompt` 输出返回。

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

`max_new_tokens` 同时限制推理和提示词的总长度，文本到图像任务默认为 1024 个 token，编辑任务默认为 1536 个 token。如果上采样器未返回可用的提示词，流水线将抛出错误，而不是直接渲染。

要将 `prompt` 按原样渲染，请从 blocks 中弹出该步骤。弹出的 block 也可以独立运行，例如在渲染之前先向用户展示 prompt：

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

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

upsampler = upsampler_block.init_pipeline("PrunaAI/P-H3-Image", components_manager=manager)
upsampler.load_components(dtype=torch.bfloat16)
upsampled = upsampler(prompt=prompt, height=3360, width=2496, output="prompt")

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

如果没有该步骤，无论 upsampler 以哪种形式编写的编辑提示——六段式简报，还是以 `Edit <Picture 1>.` 开头的段落——都会按原样进行编码；其他任何指令都会加上该前缀。

## 采样

- 这 8 个步骤在检查点的 `sample_sigmas` 上运行。传入 `sigmas` 以使用另一个网格。
- 该模型经过引导蒸馏，因此没有 guider、`negative_prompt` 或 `guidance_scale`。

## PH3ImageModularPipeline[[diffusers.PH3ImageModularPipeline]]

#### diffusers.PH3ImageModularPipeline[[diffusers.PH3ImageModularPipeline]]

```python
diffusers.PH3ImageModularPipeline(blocks: diffusers.modular_pipelines.modular_pipeline.ModularPipelineBlocks | None = None, pretrained_model_name_or_path: str | os.PathLike | None = None, components_manager: diffusers.modular_pipelines.components_manager.ComponentsManager | None = None, collection: str | None = None, workflow: str | None = None, modular_config_dict: dict[str, typing.Any] | None = None, config_dict: dict[str, typing.Any] | None = None, **kwargs)
```

[源代码](https://github.com/huggingface/diffusers/blob/main/src/diffusers/modular_pipelines/p_h3_image/modular_pipeline.py#L22)

用于 P-H3-Image 的 ModularPipeline，这是一个基于 MiniMax-H3 的图像模型，支持文生图（`text2image`）和基于指令的编辑（`image_conditioned`）。

该图像是一个单帧潜在表示，在一个打包序列中完成去噪，其中包含两个被丢弃的音频潜在表示。

```py
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)
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, output="images")[0]
```

## PH3ImageBlocks[[diffusers.PH3ImageBlocks]]

#### diffusers.PH3ImageBlocks[[diffusers.PH3ImageBlocks]]

```python
diffusers.PH3ImageBlocks()
```

[源代码](https://github.com/huggingface/diffusers/blob/main/src/diffusers/modular_pipelines/p_h3_image/modular_blocks_p_h3_image.py#L376)

P-H3-Image 的模块化流水线块：`text2image`，以及在传入 `image` 时基于指令的编辑（`image_conditioned`）。`prompt` 会先经过提示词增强器；若移除 `prompt_upsampler` 步骤，则按原样渲染。

支持的工作流：
- `text2image`：需要 `prompt`
- `image_conditioned`：需要 `prompt`、`image`

组件：image_processor (`VaeImageProcessor`) prompt_upsampler (`Qwen3_5ForConditionalGeneration`)：提示词上采样器。 prompt_upsampler_processor (`AutoProcessor`)：其处理器。 text_encoder (`Qwen3VLForConditionalGeneration`) text_connector (`PH3ImageTextConnector`) tokenizer (`Qwen2Tokenizer`) processor (`Qwen3VLProcessor`) vae (`AutoencoderKLPH3Image`) scheduler (`MiniMaxH3Scheduler`) audio_scheduler (`MiniMaxH3Scheduler`) transformer (`MiniMaxH3Transformer3DModel`)

配置：reference_min_pixels（默认值：1048576）reference_max_pixels（默认值：8388608）canvas_min_pixels（默认值：
4194304) vision_pixels （默认值：1000000）sample_sigmas（默认值：[1.0, 0.984753, 0.967905, 0.951688,
0.925372, 0.881923, 0.810083, 0.528718, 0.0]): 检查点的采样网格，在未传入 `sigmas` 时使用。

输入：image (`Image | list`，*可选*)：要编辑的图像，或最多 8 张图像的列表：第一张将被编辑，其余作为参考。height (`int`，*可选*)：生成图像的高度（以像素为单位），会四舍五入到 32 的倍数。对于 `text2image`，默认值为 2912，在 800 万像素下效果最佳。对于编辑操作，默认使用第一张图像的尺寸，且至少为 `canvas_min_pixels`，在 400 万或 800 万像素下效果最佳。width (`int`，*可选*)：生成图像的宽度（以像素为单位），会四舍五入到 32 的倍数。对于 `text2image`，默认值为 2912，在 800 万像素下效果最佳。对于编辑操作，默认使用第一张图像的尺寸，且至少为 `canvas_min_pixels`，在 400 万或 800 万像素下效果最佳。prompt (`str`)：提示词，或在传入 `image` 时的编辑指令。单个字符串。max_new_tokens (`int`，*可选*，默认值为 1536 或 1024，取决于工作流)：上采样器（包括其推理过程）可能生成的最大 token 数。vision_images (`list`，*可选*)：为文本编码器调整大小后的编辑图像，待编辑的图像排在第一位。reference_images (`list`，*可选*)：为 VAE 调整大小后的编辑图像，待编辑的图像排在第一位。condition_latents (`list`，*可选*)：编辑图像的条件潜在变量。它们的形状决定了参考块的几何结构。generator (`Generator`，*可选*)：请求的生成器。条件噪声首先从中抽取，每个条件抽取一次，然后才是生成行的噪声。latents (`Tensor`)：形状为 `(1, latent_channels, 1, latent_height, latent_width)` 的预生成图像噪声，用于替代随机抽取。sigmas (`list`，*可选*)：自定义采样网格，严格递减并以 0 结尾。默认使用检查点的 `sample_sigmas`。 **denoiser_input_fields (`None`，*可选*)：Transformer 按名称读取的打包序列的结构描述：`token_tags`、`position_ids` 以及三个行索引张量。attention_kwargs (`dict`，*可选*)：用于注意力处理器的额外 kwargs。output_type (`str`，*可选*，默认为 pil)：输出格式：'pil'、'np'、'pt'。

输出：图像（`list`）：生成的图像。

## PH3ImageTextConnector[[diffusers.PH3ImageTextConnector]]

#### diffusers.PH3ImageTextConnector[[diffusers.PH3ImageTextConnector]]

```python
diffusers.PH3ImageTextConnector(hidden_state_indices: tuple = (13, 19, 25, 31, 36), text_hidden_size: int = 2560, out_channels: int = 5120)
```

[源代码](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/condition_embedders/condition_embedder_p_h3_image.py#L22)

**参数：**

hidden_state_indices (`tuple[int, ...]`，默认为 `(13, 19, 25, 31, 36)`) : 读取文本编码器 `hidden_states` 中的哪些条目，编号方式与 `output_hidden_states` 一致（`0` 为嵌入输出，`i` 为解码器第 `i` 层的输出，最后一个为最终归一化后的隐藏状态）。

text_hidden_size (`int`，默认为 `2560`)：文本编码器的隐藏层大小。

out_channels (`int`，默认为 `5120`)：MiniMax-H3 的 transformer 读取的条件通道数。

将 P-H3-Image 的 Qwen3-VL 文本编码器的隐藏状态映射到其 Transformer 所读取的文本条件。

`hidden_state_indices` 中列出的隐藏状态会被拼接、标准化、线性投影并反标准化。第一个 token 是一个注意力汇聚点（attention sink），对于每个 prompt 都具有相同的条件，因此它会被 `sink_embedding` 替换。

#### forward[[diffusers.PH3ImageTextConnector.forward]]

```python
forward(hidden_states: tuple)
```

[源代码](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/condition_embedders/condition_embedder_p_h3_image.py#L61)

**参数：**

hidden_states (`tuple[torch.Tensor, ...]`) : 文本编码器的隐藏状态，即 `output_hidden_states=True` 返回的内容：每个条目为一个形状为 `(batch_size, num_tokens, text_hidden_size)` 的张量。

**返回：** `torch.Tensor`

条件输入，形状为 `(batch_size, num_tokens, out_channels)`，数据类型与连接器的参数一致。

