#
# 根据 Apache 许可证 2.0 版本（“许可证”）授权
# 您只能在遵守许可证的情况下使用本文件。
# 您可以在以下位置获取许可证副本
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# 除非适用法律要求或双方书面同意，软件
# 根据许可证分发，本软件按“原样”
# 不附带任何明示或暗示的保证或条件。
# 请参阅许可证中关于权限的具体语言
# 许可证下的限制。
-->

# GLM-Image

## 概述

GLM-Image 是一款采用混合自回归 + 扩散解码器架构的图像生成模型，有效提升了视觉保真度和细粒度细节的上限。在通用图像生成质量方面，它与业界标准的基于 LDM 的方法相当，同时在知识密集型图像生成场景中展现出显著优势。

模型架构：混合自回归 + 扩散解码器设计、

+ 自回归生成器：一个 9B 参数模型，从 [GLM-4-9B-0414](https://huggingface.co/zai-org/GLM-4-9B-0414) 初始化，并扩展了词汇表以纳入视觉 token。该模型首先生成约 256 个 token 的紧凑编码，然后扩展至 1K–4K 个 token，对应 1K–2K 的高分辨率图像输出。您可以在 `transformers` 库的 `GlmImageForConditionalGeneration` 类中查看 AR 模型。
+ Diffusion Decoder：一个基于单流 DiT 架构的 7B 参数解码器，用于潜在空间图像解码。它配备了 Glyph Encoder 文本模块，显著提升了图像内文本的准确渲染效果。

通过解耦强化学习进行后训练：该模型引入了基于 GRPO 算法的细粒度、模块化反馈策略，显著提升了语义理解和视觉细节质量。

+ 自回归模块：提供专注于美学和语义对齐的低频反馈信号，从而提升指令遵循能力和艺术表现力。
+ 解码器模块：提供针对细节保真度和文本准确性的高频反馈，从而生成高度逼真的纹理、光照和色彩还原，以及更精确的文本渲染。

GLM-Image 支持在单个模型中同时进行文本生成图像和图像生成图像

+ 文本生成图像：根据文本描述生成高细节图像，在信息密集的场景中表现尤为出色。
+ 图像到图像：支持多种任务，包括图像编辑、风格迁移、多主体一致性，以及针对人物和物体的身份保持生成。

此流水线由 [zRzRzRzRzRzRzR](https://github.com/zRzRzRzRzRzRzR) 贡献。代码库可在[此处](https://huggingface.co/zai-org/GLM-Image)找到。

## 使用示例

### 文本到图像生成

```python
import torch
from diffusers.pipelines.glm_image import GlmImagePipeline

pipe = GlmImagePipeline.from_pretrained("zai-org/GLM-Image",dtype=torch.bfloat16,device_map="cuda")
prompt = "A beautifully designed modern food magazine style dessert recipe illustration, themed around a raspberry mousse cake. The overall layout is clean and bright, divided into four main areas: the top left features a bold black title 'Raspberry Mousse Cake Recipe Guide', with a soft-lit close-up photo of the finished cake on the right, showcasing a light pink cake adorned with fresh raspberries and mint leaves; the bottom left contains an ingredient list section, titled 'Ingredients' in a simple font, listing 'Flour 150g', 'Eggs 3', 'Sugar 120g', 'Raspberry puree 200g', 'Gelatin sheets 10g', 'Whipping cream 300ml', and 'Fresh raspberries', each accompanied by minimalist line icons (like a flour bag, eggs, sugar jar, etc.); the bottom right displays four equally sized step boxes, each containing high-definition macro photos and corresponding instructions, arranged from top to bottom as follows: Step 1 shows a whisk whipping white foam (with the instruction 'Whip egg whites to stiff peaks'), Step 2 shows a red-and-white mixture being folded with a spatula (with the instruction 'Gently fold in the puree and batter'), Step 3 shows pink liquid being poured into a round mold (with the instruction 'Pour into mold and chill for 4 hours'), Step 4 shows the finished cake decorated with raspberries and mint leaves (with the instruction 'Decorate with raspberries and mint'); a light brown information bar runs along the bottom edge, with icons on the left representing 'Preparation time: 30 minutes', 'Cooking time: 20 minutes', and 'Servings: 8'. The overall color scheme is dominated by creamy white and light pink, with a subtle paper texture in the background, featuring compact and orderly text and image layout with clear information hierarchy."
image = pipe(
    prompt=prompt,
    height=32 * 32,
    width=36 * 32,
    num_inference_steps=30,
    guidance_scale=1.5,
    generator=torch.Generator(device="cuda").manual_seed(42),  # or "mps", "xpu", "cpu"
).images[0]

image.save("output_t2i.png")
```

### 图像到图像生成

```python
import torch
from diffusers.pipelines.glm_image import GlmImagePipeline
from PIL import Image

pipe = GlmImagePipeline.from_pretrained("zai-org/GLM-Image",dtype=torch.bfloat16,device_map="cuda")
image_path = "cond.jpg" 
prompt = "Replace the background of the snow forest with an underground station featuring an automatic escalator."
image = Image.open(image_path).convert("RGB")
image = pipe(
    prompt=prompt,
    image=[image], # can input multiple images for multi-image-to-image generation such as [image, image1]
    height=33 * 32,
    width=32 * 32,
    num_inference_steps=30,
    guidance_scale=1.5,
    generator=torch.Generator(device="cuda").manual_seed(42),  # or "mps", "xpu", "cpu"
).images[0]

image.save("output_i2i.png")
```

+ 由于 GLM-Image 中使用的 AR 模型默认配置为 `do_sample=True` 且温度为 `0.95`，因此不同运行之间生成的图像可能存在显著差异。我们不建议将 do_sample 设置为 False，因为这可能导致 AR 模型产生不正确或退化的输出。

## GlmImagePipeline[[diffusers.GlmImagePipeline]]

#### diffusers.GlmImagePipeline[[diffusers.GlmImagePipeline]]

```python
diffusers.GlmImagePipeline(tokenizer: ByT5Tokenizer, processor: GlmImageProcessor, text_encoder: T5EncoderModel, vision_language_encoder: GlmImageForConditionalGeneration, vae: AutoencoderKL, transformer: GlmImageTransformer2DModel, scheduler: FlowMatchEulerDiscreteScheduler)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_glm_image.py#L161)

**参数：**

tokenizer (`PreTrainedTokenizer`)：文本编码器的分词器。

processor (`AutoProcessor`)：用于 AR 模型处理聊天模板和分词的处理器。

text_encoder (`T5EncoderModel`)：用于字形嵌入的冻结文本编码器。

vision_language_encoder (`GlmImageForConditionalGeneration`)：根据文本提示生成图像 token 的自回归模型。

vae ([AutoencoderKL](/docs/diffusers/v0.43.0/zh/api/models/autoencoderkl#diffusers.AutoencoderKL))：变分自编码器（VAE）模型，用于将图像编码为潜在表示，并从潜在表示解码回图像。

transformer ([GlmImageTransformer2DModel](/docs/diffusers/v0.43.0/zh/api/models/glm_image_transformer2d#diffusers.GlmImageTransformer2DModel))：一个用于对编码后的图像潜在变量进行去噪的文本条件 Transformer（DiT）。

scheduler ([SchedulerMixin](/docs/diffusers/v0.43.0/zh/api/schedulers/overview#diffusers.SchedulerMixin))：用于与 `transformer` 配合，对编码后的图像潜变量进行去噪的调度器。

使用 GLM-Image 进行文本到图像生成的 Pipeline。

该流水线同时集成了用于 token 生成的 AR（自回归）模型和用于图像解码的 DiT（扩散 Transformer）模型。

#### __调用__[[diffusers.GlmImagePipeline.__call__]]

```python
__call__(prompt: str | list[str] | None = None, image: typing.Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[PIL.Image.Image], list[numpy.ndarray], list[torch.Tensor], NoneType] = None, height: int | None = None, width: int | None = None, num_inference_steps: int = 50, timesteps: list[int] | None = None, sigmas: list[float] | None = None, guidance_scale: float = 1.5, num_images_per_prompt: int = 1, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, prior_token_ids: typing.Optional[torch.Tensor] = None, prior_token_image_ids: list[torch.Tensor] | None = None, source_image_grid_thw: list[torch.Tensor] | None = None, crops_coords_top_left: tuple[int, int] = (0, 0), output_type: str = 'pil', return_dict: bool = True, attention_kwargs: dict[str, typing.Any] | None = None, callback_on_step_end: typing.Union[typing.Callable[[int, int, dict], NoneType], diffusers.callbacks.PipelineCallback, diffusers.callbacks.MultiPipelineCallbacks, NoneType] = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'], max_sequence_length: int = 2048)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_glm_image.py#L719)

**参数：**

prompt (`str` 或 `list[str]`，*可选*) : 用于引导图像生成的提示词或提示词列表。必须包含格式为 'H W' 的形状信息，其中 H 和 W 是 token 维度 (d32)。示例："A beautiful sunset36 24" 将生成一张 1152x768 的图像。

image : 用于图像到图像生成的可选条件图像。

height (`int`, *可选*) : 以像素为单位的高度。如果未提供，则从提示词的形状信息中推导得出。

width (`int`, *可选*) : 宽度（以像素为单位）。如果未提供，则从提示词的形状信息中推导得出。

num_inference_steps (`int`，*可选*，默认为 `50`)：DiT 的去噪步数。

timesteps (`list[int]`，*可选*) : 用于去噪过程的自定义时间步。如果未定义，则使用调度器针对 `num_inference_steps` 的默认调度。

sigmas (`list[float]`, *可选*) : 用于去噪过程的自定义 sigma 值。如果未定义，则使用调度器的默认调度。

guidance_scale (`float`，*可选*，默认值为 `1.5`)：用于无分类器引导（classifier-free guidance）的引导比例。

num_images_per_prompt (`int`，*可选*，默认为 `1`)：每个提示词生成的图像数量。

generator (`torch.Generator`, *可选*) : 用于可复现性的随机数生成器。

latents (`torch.Tensor`, *可选*) : 预生成的噪声潜变量，用作图像生成的输入。

prompt_embeds (`torch.Tensor`, *可选*) : 预生成的文本嵌入。如果未提供，则从 `prompt` 生成嵌入。

negative_prompt_embeds (`torch.Tensor`, *可选*) : 预生成的负文本嵌入。在启用无分类器引导时使用。

prior_token_ids (`torch.Tensor`, *可选*) : 由 `generate_prior_tokens` 预生成的先验 token id。如果提供，则跳过先验生成。

prior_token_image_ids (`list[torch.Tensor]`，*可选*)：与 `prior_token_ids` 关联的图像 token id。

source_image_grid_thw (`list[torch.Tensor]`, *可选*) : 源图像 token 的逐样本 THW 网格信息。

crops_coords_top_left (`tuple[int, int]`，*可选*，默认为 `(0, 0)`)：用于条件嵌入的裁剪区域的左上角坐标。

output_type (`str`，*可选*，默认为 `"pil"`)：输出格式："pil"、"np" 或 "latent"。

return_dict (`bool`，*可选*，默认为 `True`)：是否返回 `GlmImagePipelineOutput` 而非普通元组。

attention_kwargs (`dict`，*可选*)：一个 kwargs 字典，如果指定，将传递给 `AttentionProcessor`。

callback_on_step_end (`Callable`、`PipelineCallback`、`MultiPipelineCallbacks`、*可选*)：在每个去噪步骤结束时调用的函数。

callback_on_step_end_tensor_inputs (`list[str]`，*可选*)：传递给 `callback_on_step_end` 的张量输入。

max_sequence_length (`int`，*可选*，默认值为 `2048`)：文本编码器的最大序列长度。

**返回：** `GlmImagePipelineOutput` 或 `tuple`

生成的图像。

调用生成 pipeline 时调用的函数。

示例：
```python
>>> import torch
>>> from diffusers import GlmImagePipeline

>>> pipe = GlmImagePipeline.from_pretrained("zai-org/GLM-Image", torch_dtype=torch.bfloat16)
>>> pipe.to("cuda")

>>> prompt = "A photo of an astronaut riding a horse on mars"
>>> image = pipe(prompt).images[0]
>>> image.save("output.png")
```

#### encode_prompt[[diffusers.GlmImagePipeline.encode_prompt]]

```python
encode_prompt(prompt: str | list[str], do_classifier_free_guidance: bool = True, num_images_per_prompt: int = 1, prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, device: typing.Optional[torch.device] = None, dtype: typing.Optional[torch.dtype] = None, max_sequence_length: int = 2048)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_glm_image.py#L545)

**参数：**

prompt (`str` 或 `list[str]`，*可选*)：要编码的提示

do_classifier_free_guidance (`bool`，*可选*，默认为 `True`)：是否使用无分类器引导。

num_images_per_prompt (`int`，*可选*，默认为 1)：每个提示词应生成的图像数量。用于放置最终嵌入的 torch 设备

prompt_embeds (`torch.Tensor`, *可选*) : 预生成的文本嵌入。可用于轻松调整文本输入，*例如* 提示词加权。如果未提供，文本嵌入将从 `prompt` 输入参数生成。

device : (`torch.device`, *可选*): torch 设备

dtype : (`torch.dtype`, *可选*): torch 数据类型

max_sequence_length (`int`，默认为 `2048`)：编码提示词的最大序列长度。可以设置为其他值，但可能会导致效果变差。

将提示词编码为文本编码器的隐藏状态。

#### generate_prior_tokens[[diffusers.GlmImagePipeline.generate_prior_tokens]]

```python
generate_prior_tokens(prompt: str | list[str], height: int, width: int, image: list[list[PIL.Image.Image]] | None = None, device: typing.Optional[torch.device] = None, generator: typing.Optional[torch.Generator] = None)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_glm_image.py#L321)

**参数：**

prompt : 单个提示词或提示词列表

height : 目标图像高度

width : 目标图像宽度

image : 归一化的图像输入，类型为 List[List[PIL.Image]]。在调用此方法之前，应使用 _validate_and_normalize_images() 进行预验证。

device : 目标设备

generator : 用于可复现性的随机数生成器

**返回：** `Tuple of`

- prior_token_ids: 形状为 (batch_size, num_tokens) 的张量，包含上采样后的先验 token
- prior_token_image_ids_per_sample: 张量列表，每个样本对应一个。每个张量包含该样本中所有条件图像的放大后的先验 token id。对于 t2i 为 None。
- source_image_grid_thw_per_sample: 张量列表，每个样本对应一个。每个张量的形状为 (num_condition_images, 3)，包含上采样后的网格信息。对于 t2i 为 None。

使用 AR 模型为 DiT 模型生成先验 token。

#### get_glyph_texts[[diffusers.GlmImagePipeline.get_glyph_texts]]

```python
get_glyph_texts(prompt)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_glm_image.py#L476)

从提示词中提取字形文本。返回一个列表的列表，用于批处理。

## GlmImagePipelineOutput[[diffusers.pipelines.glm_image.pipeline_output.GlmImagePipelineOutput]]

#### diffusers.pipelines.glm_image.pipeline_output.GlmImagePipelineOutput[[diffusers.pipelines.glm_image.pipeline_output.GlmImagePipelineOutput]]

```python
diffusers.pipelines.glm_image.pipeline_output.GlmImagePipelineOutput(images: list[PIL.Image.Image] | numpy.ndarray)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/glm_image/pipeline_output.py#L10)

**参数：**

images (`List[PIL.Image.Image]` 或 `np.ndarray`)：长度为 `batch_size` 的去噪 PIL 图像列表，或形状为 `(batch_size, height, width, num_channels)` 的 numpy 数组。PIL 图像或 numpy 数组表示扩散流水线生成的去噪图像。

CogView3 管道的输出类。

