#
# Apache License, Version 2.0("라이선스")에 따라 라이선스가 부여됩니다.
# 이 파일은 라이선스에 따라만 사용할 수 있습니다.
# 라이선스 사본은 다음에서 가져올 수 있습니다
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# 적용 가능한 법률에 의해 요구되거나 서면으로 합의되지 않는 한, 소프트웨어
# 라이선스에 따라 배포되는 본 소프트웨어는 "있는 그대로"
# 명시적이든 묵시적이든 어떠한 종류의 보증이나 조건도 없이 제공됩니다.
# 권한을 관리하는 특정 언어에 대한 라이선스를 참조하세요
# 라이선스 하의 제한 사항. -->

# PRX

PRX는 텍스트 토큰이 트랜스포머 블록을 통해 업데이트되지 않는 단순화된 MMDIT 아키텍처를 사용하여 텍스트에서 고품질 이미지를 생성합니다. 효율적인 샘플링을 위해 이산 스케줄링을 적용한 flow matching을 사용하며, 다국어 텍스트 인코딩을 위해 Google의 T5Gemma-2B-2B-UL2 모델을 사용합니다. 약 1.3B 파라미터의 트랜스포머는 품질 저하 없이 빠른 추론을 제공합니다. 균형 잡힌 품질과 속도를 위해 Flux VAE(8x 압축, 16 latent channels)를 선택하거나, latent 압축과 더 빠른 처리를 위해 DC-AE(32x 압축, 32 latent channels)를 선택할 수 있습니다.

## 사용 가능한 모델

PRX은 서로 다른 VAE 구성을 가진 여러 변형을 제공하며, 각각은 특정 해상도에 최적화되어 있습니다. Base 모델은 상세한 프롬프트에서 뛰어난 성능을 발휘하여 복잡한 구성과 미묘한 디테일을 포착합니다. [Alchemist dataset](https://huggingface.co/datasets/yandex/alchemist)으로 학습된 Fine-tuned 모델은 특히 단순한 프롬프트에서 미적 품질을 향상시킵니다.

| 모델 | 해결 | 파인튜닝 | 증류 | 설명 | 권장 프롬프트 | 권장 매개변수 | 권장 dtype |
|:-----:|:-----------------:|:----------:|:----------:|:----------:|:----------:|:----------:|:----------:|
| [`Photoroom/prx-256-t2i`](https://huggingface.co/Photoroom/prx-256-t2i)| 256 | 아니요 | 아니요 | 256에서 사전 학습된 Flux VAE 기반 모델|자연어 기반의 상세한 프롬프트와 함께 가장 잘 작동합니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-256-t2i-sft`](https://huggingface.co/Photoroom/prx-256-t2i-sft)| 512 | 예 | 아니요 | Flux VAE를 사용하여 [Alchemist dataset](https://huggingface.co/datasets/yandex/alchemist) 데이터셋으로 파인튜닝 | 상세하지 않은 프롬프트도 처리할 수 있습니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i`](https://huggingface.co/Photoroom/prx-512-t2i)| 512 | 아니요 | 아니요 | Flux VAE로 512에서 사전 학습된 기본 모델 |자연어 기반의 상세한 프롬프트와 함께 가장 잘 작동합니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i-sft`](https://huggingface.co/Photoroom/prx-512-t2i-sft)| 512 | 예 | 아니요 | Flux VAE를 사용하여 [Alchemist dataset](https://huggingface.co/datasets/yandex/alchemist) 데이터셋으로 파인튜닝 | 자연어로 작성된 덜 상세한 프롬프트를 처리할 수 있습니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i-sft-distilled`](https://huggingface.co/Photoroom/prx-512-t2i-sft-distilled)| 512 | 예 | 예 | [`Photoroom/prx-512-t2i-sft`](https://huggingface.co/Photoroom/prx-512-t2i-sft)에서 8단계로 증류된 모델 | 자연어로 작성된 덜 상세한 프롬프트를 처리할 수 있습니다|8단계, cfg=1.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i-dc-ae`](https://huggingface.co/Photoroom/prx-512-t2i-dc-ae)| 512 | 아니요 | 아니요 | 512에서 [Deep Compression Autoencoder (DC-AE)](https://hanlab.mit.edu/projects/dc-ae)로 사전 학습된 베이스 모델|자연어 기반의 상세한 프롬프트와 함께 가장 잘 작동합니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i-dc-ae-sft`](https://huggingface.co/Photoroom/prx-512-t2i-dc-ae-sft)| 512 | 예 | 아니요 | [Alchemist dataset](https://huggingface.co/datasets/yandex/alchemist) 데이터셋에서 [Deep Compression Autoencoder (DC-AE)](https://hanlab.mit.edu/projects/dc-ae)를 사용하여 파인튜닝되었습니다 | 자연어로 작성된 덜 상세한 프롬프트를 처리할 수 있습니다|28 단계, cfg=5.0| `torch.bfloat16` |
| [`Photoroom/prx-512-t2i-dc-ae-sft-distilled`](https://huggingface.co/Photoroom/prx-512-t2i-dc-ae-sft-distilled)| 512 | 예 | 예 | [`Photoroom/prx-512-t2i-dc-ae-sft-distilled`](https://huggingface.co/Photoroom/prx-512-t2i-dc-ae-sft-distilled)에서 8단계로 증류된 모델 | 자연어에서 덜 상세한 프롬프트를 처리할 수 있습니다|8 steps, cfg=1.0| `torch.bfloat16` |s

자세한 내용은 [이](https://huggingface.co/collections/Photoroom/prx-models-68e66254c202ebfab99ad38e) 컬렉션을 참조하세요.

## 파이프라인 로드

[from_pretrained()](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained)로 파이프라인을 로드합니다.

```py
from diffusers.pipelines.prx import PRXPipeline

# Load pipeline - VAE and text encoder will be loaded from HuggingFace
pipe = PRXPipeline.from_pretrained("Photoroom/prx-512-t2i-sft", dtype=torch.bfloat16)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt = "A front-facing portrait of a lion the golden savanna at sunset."
image = pipe(prompt, num_inference_steps=28, guidance_scale=5.0).images[0]
image.save("prx_output.png")
```

### 수동 구성 요소 로드

개별적으로 로드하여 파이프라인을 사용자 지정할 수 있습니다. 예를 들어, 양자화 모델을 사용하는 경우입니다.

```py
import torch
from diffusers.pipelines.prx import PRXPipeline
from diffusers.models import AutoencoderKL, AutoencoderDC
from diffusers.models.transformers.transformer_prx import PRXTransformer2DModel
from diffusers.schedulers import FlowMatchEulerDiscreteScheduler
from transformers import T5GemmaModel, GemmaTokenizerFast
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig
from transformers import BitsAndBytesConfig as BitsAndBytesConfig

quant_config = DiffusersBitsAndBytesConfig(load_in_8bit=True)
# Load transformer
transformer = PRXTransformer2DModel.from_pretrained(
    "checkpoints/prx-512-t2i-sft",
    subfolder="transformer",
    quantization_config=quant_config,
    dtype=torch.bfloat16,
)

# Load scheduler
scheduler = FlowMatchEulerDiscreteScheduler.from_pretrained(
    "checkpoints/prx-512-t2i-sft", subfolder="scheduler"
)

# Load T5Gemma text encoder
t5gemma_model = T5GemmaModel.from_pretrained("google/t5gemma-2b-2b-ul2",
                                            quantization_config=quant_config,
                                            dtype=torch.bfloat16)
text_encoder = t5gemma_model.encoder.to(dtype=torch.bfloat16)
tokenizer = GemmaTokenizerFast.from_pretrained("google/t5gemma-2b-2b-ul2")
tokenizer.model_max_length = 256

# Load VAE - choose either Flux VAE or DC-AE
# Flux VAE
vae = AutoencoderKL.from_pretrained("black-forest-labs/FLUX.1-dev",
                                    subfolder="vae",
                                    quantization_config=quant_config,
                                    dtype=torch.bfloat16)

pipe = PRXPipeline(
    transformer=transformer,
    scheduler=scheduler,
    text_encoder=text_encoder,
    tokenizer=tokenizer,
    vae=vae
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"
```

## 메모리 최적화

메모리가 제한된 환경의 경우:

```py
import torch
from diffusers.pipelines.prx import PRXPipeline

pipe = PRXPipeline.from_pretrained("Photoroom/prx-512-t2i-sft", dtype=torch.bfloat16)
pipe.enable_model_cpu_offload()  # Offload components to CPU when not in use

# Or use sequential CPU offload for even lower memory
pipe.enable_sequential_cpu_offload()
```

## PRXPipeline[[diffusers.PRXPipeline]]

#### diffusers.PRXPipeline[[diffusers.PRXPipeline]]

```python
diffusers.PRXPipeline(transformer: PRXTransformer2DModel, scheduler: FlowMatchEulerDiscreteScheduler, text_encoder: T5GemmaEncoder, tokenizer: transformers.models.t5.tokenization_t5.T5Tokenizer | transformers.models.gemma.tokenization_gemma.GemmaTokenizer | transformers.models.auto.tokenization_auto.AutoTokenizer, vae: diffusers.models.autoencoders.autoencoder_kl.AutoencoderKL | diffusers.models.autoencoders.autoencoder_dc.AutoencoderDC | None = None, default_sample_size: int | None = 512)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L257)

**매개변수:**

transformer (`PRXTransformer2DModel`) : 인코딩된 이미지 레이턴트를 디노이즈하기 위한 PRX transformer 모델입니다.

scheduler ([FlowMatchEulerDiscreteScheduler](/docs/diffusers/main/ko/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)) : `transformer`와 함께 사용하여 인코딩된 이미지 라텐트를 디노이즈하는 데 사용되는 스케줄러입니다.

text_encoder (`T5GemmaEncoder`) : 프롬프트를 인코딩하는 텍스트 인코더 모델.

tokenizer ([`T5TokenizerFast` 또는 `GemmaTokenizerFast`]) : 텍스트 인코더에 사용되는 토크나이저.

vae ([AutoencoderKL](/docs/diffusers/main/ko/api/models/autoencoderkl#diffusers.AutoencoderKL) 또는 [AutoencoderDC](/docs/diffusers/main/ko/api/models/autoencoder_dc#diffusers.AutoencoderDC)) : 이미지를 잠재 표현으로 인코딩하고 디코딩하는 Variational Auto-Encoder (VAE) 모델입니다. AutoencoderKL (8x 압축)과 AutoencoderDC (32x 압축)을 모두 지원합니다.

PRX Transformer를 사용한 텍스트-이미지 생성을 위한 Pipeline

이 모델은 [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)에서 상속됩니다. 라이브러리가 모든 파이프라인에 대해 구현하는 일반적 메서드(다운로드 또는 저장, 특정 디바이스에서 실행 등)에 대해서는 상위 클래스 문서를 확인하세요.

#### __호출__[[diffusers.PRXPipeline.__call__]]

```python
__call__(prompt: str | list[str] = None, negative_prompt: str = '', height: int | None = None, width: int | None = None, num_inference_steps: int = 28, timesteps: list = None, guidance_scale: float = 4.0, num_images_per_prompt: int | None = 1, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.FloatTensor] = None, negative_prompt_embeds: typing.Optional[torch.FloatTensor] = None, prompt_attention_mask: typing.Optional[torch.BoolTensor] = None, negative_prompt_attention_mask: typing.Optional[torch.BoolTensor] = None, output_type: str | None = 'pil', return_dict: bool = True, use_resolution_binning: bool = True, callback_on_step_end: typing.Optional[typing.Callable[[int, int], NoneType]] = None, callback_on_step_end_tensor_inputs: list = ['latents'], tokenizer_max_length: int | None = None, skip_text_cleaning: bool = False)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L554)

**매개변수:**

prompt (*str* 또는 *list[str]*, *선택*) : 이미지 생성을 안내할 프롬프트입니다. 정의되지 않은 경우 *prompt_embeds*를 대신 전달해야 합니다.

negative_prompt (*str*, *optional*, 기본값 *""*) : 이미지 생성을 안내하지 않을 프롬프트입니다. 가이던스를 사용하지 않는 경우 무시됩니다(즉, *guidance_scale*이 *1*보다 작은 경우 무시됩니다).

height (*int*, *optional*, 기본값은 self.transformer.config.sample_size * self.vae_scale_factor) : 생성된 이미지의 픽셀 단위 높이.

width (*int*, *optional*, 기본값은 self.transformer.config.sample_size * self.vae_scale_factor) : 생성된 이미지의 픽셀 단위 너비.

num_inference_steps (*int*, *optional*, 기본값 28) : 디노이징 단계의 수입니다. 디노이징 단계를 늘리면 일반적으로 더 높은 품질의 이미지를 얻을 수 있지만, 추론 속도가 느려집니다.

timesteps (*list[int]*, *optional*) : *set_timesteps* 메서드에 *timesteps* 인수를 지원하는 스케줄러의 디노이징 프로세스에 사용할 커스텀 타임스텝입니다. 정의되지 않은 경우, *num_inference_steps*가 전달될 때의 기본 동작이 사용됩니다. 내림차순으로 정렬되어 있어야 합니다.

guidance_scale (*float*, *optional*, 기본값 4.0) : [Classifier-Free Diffusion Guidance](https://huggingface.co/papers/2207.12598)에서 정의한 가이던스 스케일입니다. *guidance_scale*은 [Imagen Paper](https://huggingface.co/papers/2205.11487)의 식 2의 *w*로 정의됩니다. *guidance_scale > 1*로 설정하면 가이던스 스케일이 활성화됩니다. 가이던스 스케일이 높을수록 텍스트 *prompt*와 밀접하게 연결된 이미지를 생성하도록 유도하지만, 일반적으로 이미지 품질이 낮아지는 대가를 치릅니다.

num_images_per_prompt (*int*, *optional*, 기본값 1) : 프롬프트당 생성할 이미지의 수입니다.

generator (*torch.Generator* 또는 *list[torch.Generator]*, *선택 사항*) : 생성을 결정적으로 만들기 위한 [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) 하나 또는 목록.

latents (*torch.Tensor*, *optional*) : 이미지 생성의 입력으로 사용할 가우시안 분포에서 샘플링된 사전 생성된 노이즈된 latents입니다. 동일한 생성을 다른 프롬프트로 조정하는 데 사용할 수 있습니다. 제공되지 않으면, 제공된 랜덤 *generator*를 사용하여 샘플링하여 latents 텐서가 생성됩니다.

prompt_embeds (*torch.FloatTensor*, *optional*) : 미리 생성된 텍스트 임베딩입니다. *e.g.* 프롬프트 가중치와 같은 텍스트 입력을 쉽게 조정하는 데 사용할 수 있습니다. 제공되지 않으면 *prompt* 입력 인자에서 텍스트 임베딩이 생성됩니다.

negative_prompt_embeds (*torch.FloatTensor*, *optional*) : 미리 생성된 부정 텍스트 임베딩입니다. 텍스트 입력을 쉽게 조정(예: *e.g.* 프롬프트 가중치)하는 데 사용할 수 있습니다. 제공되지 않고 *guidance_scale > 1*인 경우, 빈 문자열에서 부정 임베딩이 생성됩니다.

prompt_attention_mask (*torch.BoolTensor*, *optional*) : *prompt_embeds*에 사용할 사전 생성된 attention mask입니다. 제공되지 않으면 *prompt* 입력 인수로부터 attention mask가 생성됩니다.

negative_prompt_attention_mask (*torch.BoolTensor*, *선택*) : *negative_prompt_embeds*에 사용할 사전 생성된 attention mask입니다. 제공되지 않고 *guidance_scale > 1*인 경우, 빈 문자열로부터 attention mask가 생성됩니다.

output_type (*str*, *optional*, 기본값 *"pil"*) : 이미지 생성의 출력 형식입니다. [PIL](https://pillow.readthedocs.io/en/stable/): *PIL.Image.Image* 또는 *np.array* 중 하나를 선택합니다.

tokenizer_max_length (*int*, *optional*) : 프롬프트를 토큰화할 때 사용할 최대 토큰 수를 재정의합니다. 설정되지 않은 경우 기본값으로 토크나이저 자체의 `model_max_length`를 사용합니다.

skip_text_cleaning (*bool*, *optional*, 기본값 *False*) : *True*인 경우, 전체 DeepFloyd 클리닝 파이프라인 대신 가벼운 프롬프트 클리닝(인코딩 수정 + HTML 언에스케이프)만 사용합니다.

return_dict (*bool*, *optional*, 기본값 *True*) : 일반 튜플 대신 [*~pipelines.prx.PRXPipelineOutput*]를 반환할지 여부.

use_resolution_binning (*bool*, *optional*, 기본값 *True*) : *True*로 설정하면, 요청된 높이와 너비가 미리 정의된 종횡비 bins를 사용하여 가장 가까운 해상도로 먼저 매핑됩니다. 생성된 latents가 이미지로 디코딩된 후, 요청된 해상도로 다시 리사이즈됩니다. 최적의 해상도로 정사각형이 아닌 이미지를 생성하는 데 유용합니다.

callback_on_step_end (*Callable*, *선택 사항*) : 추론 중 각 denoising 단계의 끝에서 호출되는 함수입니다. 이 함수는 다음 인수를 받아 호출됩니다: *callback_on_step_end(self, step, timestep, callback_kwargs)*. *callback_kwargs*에는 *callback_on_step_end_tensor_inputs*로 지정된 모든 텐서 목록이 포함됩니다.

callback_on_step_end_tensor_inputs (*list*, *optional*) : *callback_on_step_end* 함수의 텐서 입력 목록입니다. 목록에 지정된 텐서는 *callback_kwargs* 인수로 전달됩니다. *._callback_tensor_inputs* 속성에 나열된 텐서만 포함할 수 있습니다.

**반환값:** [*~pipelines.prx.PRXPipelineOutput*] 또는 *tuple`

[*~pipelines.prx.PRXPipelineOutput*] *return_dict*가 True인 경우, 그렇지 않으면 *tuple입니다. tuple을 반환할 때 첫 번째 요소는 생성된 이미지의 목록입니다.

생성을 위해 파이프라인을 호출할 때 호출되는 함수.

예:
```py
>>> import torch
>>> from diffusers import PRXPipeline

>>> # Load pipeline with from_pretrained
>>> pipe = PRXPipeline.from_pretrained("Photoroom/prx-512-t2i-sft")
>>> pipe.to("cuda")

>>> prompt = "A digital painting of a rusty, vintage tram on a sandy beach"
>>> image = pipe(prompt, num_inference_steps=28, guidance_scale=5.0).images[0]
>>> image.save("prx_output.png")
```

#### check_inputs[[diffusers.PRXPipeline.check_inputs]]

```python
check_inputs(prompt: str | list[str], height: int, width: int, guidance_scale: float, callback_on_step_end_tensor_inputs: list[str] | None = None, prompt_embeds: typing.Optional[torch.FloatTensor] = None, negative_prompt_embeds: typing.Optional[torch.FloatTensor] = None)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L500)

모든 입력이 올바른 형식인지 확인합니다.

#### encode_prompt[[diffusers.PRXPipeline.encode_prompt]]

```python
encode_prompt(prompt: str | list[str], device: typing.Optional[torch.device] = None, do_classifier_free_guidance: bool = True, negative_prompt: str = '', num_images_per_prompt: int = 1, prompt_embeds: typing.Optional[torch.FloatTensor] = None, negative_prompt_embeds: typing.Optional[torch.FloatTensor] = None, prompt_attention_mask: typing.Optional[torch.BoolTensor] = None, negative_prompt_attention_mask: typing.Optional[torch.BoolTensor] = None, tokenizer_max_length: int | None = None, skip_text_cleaning: bool = False)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L376)

표준 텍스트 인코더와 토크나이저를 사용하여 텍스트 프롬프트를 인코딩하거나, 사전 계산된 임베딩을 사용합니다.

#### get_default_resolution[[diffusers.PRXPipeline.get_default_resolution]]

```python
get_default_resolution()
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L340)

**반환값:** `int`

생성에 사용할 기본 샘플 크기(높이/너비).

VAE와 설정을 기반으로 기본 해상도를 결정합니다.

#### prepare_latents[[diffusers.PRXPipeline.prepare_latents]]

```python
prepare_latents(batch_size: int, num_channels_latents: int, height: int, width: int, dtype: dtype, device: device, generator: typing.Optional[torch.Generator] = None, latents: typing.Optional[torch.Tensor] = None)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_prx.py#L352)

확산 프로세스를 위한 초기 latents를 준비합니다.

## PRXPipelineOutput[[diffusers.pipelines.prx.PRXPipelineOutput]]

#### diffusers.pipelines.prx.PRXPipelineOutput[[diffusers.pipelines.prx.PRXPipelineOutput]]

```python
diffusers.pipelines.prx.PRXPipelineOutput(images: list[PIL.Image.Image] | numpy.ndarray)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/prx/pipeline_output.py#L24)

**매개변수:**

images (`list[PIL.Image.Image]` 또는 `np.ndarray`) : 길이가 `batch_size`인 노이즈 제거된 PIL 이미지 목록 또는 `(batch_size, height, width, num_channels)` 모양의 numpy 배열. PIL 이미지 또는 numpy 배열은 diffusion 파이프라인의 노이즈 제거된 이미지를 나타냅니다.

PRX 파이프라인의 출력 클래스입니다.

