# P-H3-Image

P-H3-Image는 [MiniMax-H3](./minimax_h3)를 기반으로 Pruna AI가 개발한 이미지 모델로, 텍스트 기반 이미지 생성 및 지시 기반 이미지 편집을 지원합니다. 체크포인트는 [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/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager)는 블록이 구성 요소를 필요로 할 때 해당 구성 요소를 가속기로 이동시키고, 파이프라인은 80 GB GPU에서 실행됩니다.

## 구성 요소

| 컴포넌트 | 클래스 |
|---|---|
| `transformer` | [MiniMaxH3Transformer3DModel](/docs/diffusers/main/ko/api/models/minimax_h3_transformer3d#diffusers.MiniMaxH3Transformer3DModel) |
| `text_encoder` | `Qwen3VLForConditionalGeneration` (Qwen3-VL-4B) |
| `text_connector` | [PH3ImageTextConnector](/docs/diffusers/main/ko/api/pipelines/p_h3_image#diffusers.PH3ImageTextConnector) |
| `vae` | [AutoencoderKLPH3Image](/docs/diffusers/main/ko/api/models/autoencoderkl_p_h3_image#diffusers.AutoencoderKLPH3Image) |
| `tokenizer`, `processor` | 텍스트 인코더의 토크나이저와 MiniMax-H3의 이미지 프로세서를 갖춘 `Qwen3VLProcessor` |
| `scheduler`, `audio_scheduler` | [MiniMaxH3Scheduler](/docs/diffusers/main/ko/api/schedulers/minimax_h3#diffusers.MiniMaxH3Scheduler) |
| `prompt_upsampler`, `prompt_upsampler_processor` | `Qwen3_5ForConditionalGeneration` (Qwen3.5-9B 기반) 및 해당 프로세서 |

## 워크플로

워크플로우는 `image` 입력에서 선택됩니다:

- **`text2image`**는 `prompt`로부터 생성합니다. `height`와 `width`의 기본값은 2912이며 32의 배수로 반올림됩니다. 이 모델은 8메가픽셀에서 가장 잘 작동하며, 예를 들어 2912x2912, 3872x2176 또는 2176x3872와 같은 해상도입니다.
- **`image_conditioned`**는 `prompt`의 지시에 따라 `image`를 편집하며, 4메가픽셀 또는 8메가픽셀에서 가장 잘 작동합니다. 이미지는 텍스트 인코더를 위해 약 `vision_pixels`(1메가픽셀)로 인코딩되고, VAE를 위해 자체 크기로 인코딩되며, 해당 범위를 벗어나면 `reference_min_pixels`(1메가픽셀)로 확대하거나 `reference_max_pixels`(8메가픽셀)로 축소됩니다. `height`와 `width`가 지정되지 않으면, 편집은 첫 번째 이미지의 크기로 생성되며, 이 크기가 더 작으면 `canvas_min_pixels`(4메가픽셀)로 확대됩니다. 32의 배수로 반올림된 `height`와 `width`가 전달되면 캔버스는 변경되지만 이미지는 변경되지 않습니다. `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 토큰, 편집의 경우 1536 토큰입니다. 업샘플러가 사용 가능한 프롬프트를 반환하지 않으면 파이프라인은 렌더링을 수행하지 않고 오류를 발생시킵니다.

`prompt`를 주어진 그대로 렌더링하려면 블록에서 스텝을 pop합니다. pop된 블록은 단독으로 실행되기도 하며, 예를 들어 렌더링 전에 프롬프트를 사용자에게 표시하는 용도로 사용할 수 있습니다:

```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]
```

step이 없으면, 업샘플러가 작성하는 편집 프롬프트의 어떤 형태이든, 6개 섹션으로 구성된 브리프이든 `Edit <Picture 1>.`으로 시작하는 단락이든, 작성된 그대로 인코딩됩니다. 다른 모든 지시문에는 해당 접두사가 붙습니다.

## 샘플링

- 8단계는 체크포인트의 `sample_sigmas`를 기반으로 실행됩니다. 다른 그리드를 사용하려면 `sigmas`를 전달하세요.
- 모델은 guidance-distilled이므로 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)

MiniMax-H3 기반 이미지 모델인 P-H3-Image의 `text2image` 및 지시 기반 편집(`image_conditioned`)을 위한 ModularPipeline입니다.

이미지는 단일 잠재 프레임이며, 두 개의 오디오 잠재 변수가 폐기된 채 하나의 패킹된 시퀀스에서 노이즈 제거됩니다.

```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` 필수

Components: 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`)

Configs: 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`가 전달되지 않을 때 사용되는 체크포인트의 샘플링 그리드입니다.

Inputs: image (`Image | list`, *선택 사항*): 편집할 이미지 또는 최대 8개의 이미지 목록입니다. 첫 번째 이미지는 편집 대상이고, 나머지는 참조 이미지입니다. height (`int`, *선택 사항*): 생성된 이미지의 픽셀 단위 높이로, 32의 배수로 반올림됩니다. `text2image`의 기본값은 2912이며, 8메가픽셀에서 가장 잘 작동합니다. 편집 작업의 기본값은 첫 번째 이미지의 크기이며, 최소 `canvas_min_pixels` 이상이어야 하며, 4메가픽셀 또는 8메가픽셀에서 가장 잘 작동합니다. width (`int`, *선택 사항*): 생성된 이미지의 픽셀 단위 너비로, 32의 배수로 반올림됩니다. `text2image`의 기본값은 2912이며, 8메가픽셀에서 가장 잘 작동합니다. 편집 작업의 기본값은 첫 번째 이미지의 크기이며, 최소 `canvas_min_pixels` 이상이어야 하며, 4메가픽셀 또는 8메가픽셀에서 가장 잘 작동합니다. prompt (`str`): 프롬프트 또는 `image`가 전달될 때의 편집 지침입니다. 단일 문자열입니다. max_new_tokens (`int`, *선택 사항*, 워크플로에 따라 기본값이 1536 또는 1024): 업샘플러가 생성할 수 있는 최대 토큰 수로, 추론 과정이 포함됩니다. 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`, *선택 사항*): 트랜스포머가 이름으로 읽는 패킹된 시퀀스의 구조적 설명입니다: `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)`) : `output_hidden_states`의 번호 체계에 따라 텍스트 인코더의 `hidden_states` 중 어떤 항목을 읽을지 지정합니다 (`0`은 임베딩 출력, `i`는 디코더 레이어 `i`의 출력, 마지막은 최종 정규화된 hidden state를 나타냅니다).

text_hidden_size (`int`, 기본값 `2560`) : 텍스트 인코더의 숨겨진 크기(hidden size)입니다.

out_channels (`int`, 기본값 `5120`) : conditioning MiniMax-H3의 transformer가 읽는 채널 수입니다.

P-H3-Image의 Qwen3-VL 텍스트 인코더의 숨겨진 상태를 해당 Transformer가 읽는 텍스트 조건으로 매핑합니다.

`hidden_state_indices`에 나열된 hidden states는 연결(concatenate)되고, 표준화되며, 선형 투사(linear projection)되고, 역표준화됩니다. 첫 번째 토큰은 모든 프롬프트에 대해 동일한 조건부(conditioning)를 갖는 attention sink이므로 `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`가 반환하는 텍스트 인코더의 hidden states입니다. 각 항목은 `(batch_size, num_tokens, text_hidden_size)` 모양의 텐서 하나입니다.

**반환값:** `torch.Tensor`

커넥터의 파라미터 dtype로, 모양이 `(batch_size, num_tokens, out_channels)`인 conditioning입니다.

