# Shap-E

Shap-E 模型由 [OpenAI](https://github.com/openai) 的 Alex Nichol 和 Heewoo Jun 在 [Shap-E: Generating Conditional 3D Implicit Functions](https://huggingface.co/papers/2305.02463) 中提出。

该论文的摘要如下：

*我们提出了 Shap-E，一种用于 3D 资产的条件生成模型。与近期生成单一输出表示的 3D 生成模型不同，Shap-E 直接生成隐式函数的参数，这些参数既可以渲染为带纹理的网格，也可以渲染为神经辐射场。我们在两个阶段训练 Shap-E：首先，训练一个编码器，将 3D 资产确定性地映射为隐式函数的参数；其次，在编码器的输出上训练一个条件扩散模型。当在大规模的 3D 与文本配对数据集上进行训练时，我们得到的模型能够在几秒钟内生成复杂且多样的 3D 资产。与基于点云的显式生成模型 Point-E 相比，Shap-E 收敛更快，并且在建模更高维、多表示的输出空间的情况下，达到了相当甚至更好的样本质量。*

原始代码库可在 [openai/shap-e](https://github.com/openai/shap-e) 中找到。

> [!TIP]
> 请参阅[跨流水线复用组件](../../using-diffusers/loading#reusing-models-in-multiple-pipelines)部分，了解如何高效地将相同组件加载到多个流水线中。

请确保已安装以下库。

```py
# uncomment to install the necessary libraries in Colab
#!pip install -q diffusers transformers accelerate trimesh
```

## 文本到 3D

要生成 3D 对象的 gif，请将文本提示传递给 [ShapEPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEPipeline)。该流水线会生成一系列图像帧，用于创建 3D 对象。

```py
import torch
from diffusers import ShapEPipeline

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

pipe = ShapEPipeline.from_pretrained("openai/shap-e", dtype=torch.float16, variant="fp16")
pipe = pipe.to(device)

guidance_scale = 15.0
prompt = ["A firecracker", "A birthday cupcake"]

images = pipe(
    prompt,
    guidance_scale=guidance_scale,
    num_inference_steps=64,
    frame_size=256,
).images
```

现在使用 [export_to_gif()](/docs/diffusers/v0.43.0/zh/api/utilities#diffusers.utils.export_to_gif) 函数将图像帧列表转换为 3D 对象的 gif 文件。

```py
from diffusers.utils import export_to_gif

export_to_gif(images[0], "firecracker_3d.gif")
export_to_gif(images[1], "cake_3d.gif")
```

  
    
    prompt = "A firecracker"
  
  
    
    prompt = "一个生日纸杯蛋糕"
  

## 图像到 3D

要从另一张图像生成 3D 对象，请使用 [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline)。您可以使用现有图像，也可以生成一张全新的图像。让我们使用 [Kandinsky 2.1](./kandinsky) 模型来生成一张新图像。

```py
from diffusers import DiffusionPipeline
import torch

prior_pipeline = DiffusionPipeline.from_pretrained("kandinsky-community/kandinsky-2-1-prior", dtype=torch.float16, use_safetensors=True).to("cuda")  # or "mps", "xpu", "cpu"
pipeline = DiffusionPipeline.from_pretrained("kandinsky-community/kandinsky-2-1", dtype=torch.float16, use_safetensors=True).to("cuda")

prompt = "A cheeseburger, white background"

image_embeds, negative_image_embeds = prior_pipeline(prompt, guidance_scale=1.0).to_tuple()
image = pipeline(
    prompt,
    image_embeds=image_embeds,
    negative_image_embeds=negative_image_embeds,
).images[0]

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

将芝士汉堡传递给 [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline)，以生成其 3D 表示。

```py
from PIL import Image
from diffusers import ShapEImg2ImgPipeline
from diffusers.utils import export_to_gif

pipe = ShapEImg2ImgPipeline.from_pretrained("openai/shap-e-img2img", dtype=torch.float16, variant="fp16").to("cuda")  # or "mps", "xpu", "cpu"

guidance_scale = 3.0
image = Image.open("burger.png").resize((256, 256))

images = pipe(
    image,
    guidance_scale=guidance_scale,
    num_inference_steps=64,
    frame_size=256,
).images

gif_path = export_to_gif(images[0], "burger_3d.gif")
```

  
    
    cheeseburger
  
  
    
    3D 芝士汉堡
  

## 生成网格

Shap-E 是一个灵活的模型，还可以生成带纹理的网格输出，以便在下游应用中渲染。在本示例中，我们将输出转换为 `glb` 文件，因为 🤗 Datasets 库支持对 `glb` 文件进行网格可视化，并且这些文件可以通过 [Dataset viewer](https://huggingface.co/docs/hub/datasets-viewer#dataset-preview) 进行渲染。

通过将 `output_type` 参数指定为 `"mesh"`，您可以为 [ShapEPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEPipeline) 和 [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline) 生成网格输出：

```py
import torch
from diffusers import ShapEPipeline

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

pipe = ShapEPipeline.from_pretrained("openai/shap-e", dtype=torch.float16, variant="fp16")
pipe = pipe.to(device)

guidance_scale = 15.0
prompt = "A birthday cupcake"

images = pipe(prompt, guidance_scale=guidance_scale, num_inference_steps=64, frame_size=256, output_type="mesh").images
```

使用 `export_to_ply()` 函数将网格输出保存为 `ply` 文件：

> [!TIP]
> 您可以选择使用 `export_to_obj()` 函数将网格输出保存为 `obj` 文件。支持以多种格式保存网格输出，使其在下游应用中更加灵活！

```py
from diffusers.utils import export_to_ply

ply_path = export_to_ply(images[0], "3d_cake.ply")
print(f"Saved to folder: {ply_path}")
```

然后，你可以使用 trimesh 库将 `ply` 文件转换为 `glb` 文件：

```py
import trimesh

mesh = trimesh.load("3d_cake.ply")
mesh_export = mesh.export("3d_cake.glb", file_type="glb")
```

默认情况下，网格输出聚焦于底部视角，但你可以通过应用旋转变换来更改默认视角：

```py
import trimesh
import numpy as np

mesh = trimesh.load("3d_cake.ply")
rot = trimesh.transformations.rotation_matrix(-np.pi / 2, [1, 0, 0])
mesh = mesh.apply_transform(rot)
mesh_export = mesh.export("3d_cake.glb", file_type="glb")
```

将网格文件上传到您的数据集仓库，以便使用数据集查看器进行可视化！

    

## ShapEPipeline[[diffusers.ShapEPipeline]]

#### diffusers.ShapEPipeline[[diffusers.ShapEPipeline]]

```python
diffusers.ShapEPipeline(prior: PriorTransformer, text_encoder: CLIPTextModelWithProjection, tokenizer: CLIPTokenizer, scheduler: HeunDiscreteScheduler, shap_e_renderer: ShapERenderer)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L87)

**参数：**

prior ([PriorTransformer](/docs/diffusers/v0.43.0/zh/api/models/prior_transformer#diffusers.PriorTransformer))：用于从文本嵌入近似图像嵌入的 unCLIP 标准先验模型。

text_encoder ([CLIPTextModelWithProjection](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPTextModelWithProjection))：冻结的文本编码器。

tokenizer ([CLIPTokenizer](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPTokenizer))：一个用于对文本进行分词的 `CLIPTokenizer`。

scheduler ([HeunDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/heun#diffusers.HeunDiscreteScheduler))：一种调度器，需与 `prior` 模型配合使用，以生成图像嵌入。

shap_e_renderer (`ShapERenderer`)：Shap-E 渲染器将生成的潜在变量投影为 MLP 的参数，并使用 NeRF 渲染方法创建 3D 对象。

用于生成 3D 资产潜在表示并使用 NeRF 方法进行渲染的 Pipeline。

该模型继承自 [DiffusionPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline)。有关为所有流水线实现的通用方法（下载、保存、在特定设备上运行等），请参阅父类文档。

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

```python
__call__(prompt: str, num_images_per_prompt: int = 1, num_inference_steps: int = 25, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, guidance_scale: float = 4.0, frame_size: int = 64, output_type: str | None = 'pil', return_dict: bool = True)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L190)

**参数：**

prompt (`str` 或 `list[str]`)：用于引导图像生成的提示词或提示词列表。

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

num_inference_steps (`int`, *可选*，默认为 25)：去噪步数。更多的去噪步数通常能生成更高质量的图像，但代价是推理速度变慢。

generator (`torch.Generator` 或 `list[torch.Generator]`，*可选*)：用于使生成过程确定性的 [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html)。

latents (`torch.Tensor`, *可选*) : 从高斯分布中采样的预生成噪声潜变量，用作图像生成的输入。可用于以不同的提示词微调同一生成过程。如果未提供，则使用提供的随机`generator`进行采样来生成潜变量张量。

guidance_scale (`float`, *可选*，默认值为 4.0)：较高的 guidance scale 值会促使模型生成与文本 `prompt` 紧密关联的图像，但代价是图像质量降低。当 `guidance_scale > 1` 时，guidance scale 生效。

frame_size (`int`，*可选*，默认为 64)：生成的 3D 输出中每个图像帧的宽度和高度。

output_type (`str`，*可选*，默认为 `"pil"`)：生成图像的输出格式。可选 `"pil"`（`PIL.Image.Image`）、`"np"`（`np.array`）、`"latent"`（`torch.Tensor`）或 mesh（`MeshDecoderOutput`）。

return_dict (`bool`，*可选*，默认为 `True`)：是否返回 [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) 而不是普通元组。

**返回：** [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) 或 `tuple`

如果 `return_dict` 为 `True`，则返回 [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput)；否则返回一个 `tuple`，其中第一个元素是包含生成图像的列表。

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

示例：
```py
>>> import torch
>>> from diffusers import DiffusionPipeline
>>> from diffusers.utils import export_to_gif

>>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

>>> repo = "openai/shap-e"
>>> pipe = DiffusionPipeline.from_pretrained(repo, torch_dtype=torch.float16)
>>> pipe = pipe.to(device)

>>> guidance_scale = 15.0
>>> prompt = "a shark"

>>> images = pipe(
...     prompt,
...     guidance_scale=guidance_scale,
...     num_inference_steps=64,
...     frame_size=256,
... ).images

>>> gif_path = export_to_gif(images[0], "shark_3d.gif")
```

## ShapEImg2ImgPipeline[[diffusers.ShapEImg2ImgPipeline]]

#### diffusers.ShapEImg2ImgPipeline[[diffusers.ShapEImg2ImgPipeline]]

```python
diffusers.ShapEImg2ImgPipeline(prior: PriorTransformer, image_encoder: CLIPVisionModel, image_processor: CLIPImageProcessorPil, scheduler: HeunDiscreteScheduler, shap_e_renderer: ShapERenderer)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py#L88)

**参数：**

prior ([PriorTransformer](/docs/diffusers/v0.43.0/zh/api/models/prior_transformer#diffusers.PriorTransformer))：用于从文本嵌入近似图像嵌入的 unCLIP 标准先验模型。

image_encoder ([CLIPVisionModel](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPVisionModel))：冻结的图像编码器。

image_processor ([CLIPImageProcessor](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPImageProcessor))：用于处理图像的 `CLIPImageProcessor`。

scheduler ([HeunDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/heun#diffusers.HeunDiscreteScheduler))：一种调度器，需与 `prior` 模型配合使用，以生成图像嵌入。

shap_e_renderer (`ShapERenderer`)：Shap-E 渲染器将生成的潜在变量投影为 MLP 的参数，并使用 NeRF 渲染方法创建 3D 对象。

用于从图像生成 3D 资产的潜在表示，并使用 NeRF 方法进行渲染的 Pipeline。

该模型继承自 [DiffusionPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline)。有关为所有流水线实现的通用方法（下载、保存、在特定设备上运行等），请参阅父类文档。

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

```python
__call__(image: PIL.Image.Image | list[PIL.Image.Image], num_images_per_prompt: int = 1, num_inference_steps: int = 25, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, guidance_scale: float = 4.0, frame_size: int = 64, output_type: str | None = 'pil', return_dict: bool = True)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py#L172)

**参数：**

image (`torch.Tensor`、`PIL.Image.Image`、`np.ndarray`、`list[torch.Tensor]`、`list[PIL.Image.Image]` 或 `list[np.ndarray]`) : `Image` 或表示图像批次的张量，用作起始点。也可以接受图像潜变量（image latents）作为图像，但如果直接传入潜变量，则不会再次进行编码。

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

num_inference_steps (`int`, *可选*，默认为 25)：去噪步数。更多的去噪步数通常能生成更高质量的图像，但代价是推理速度变慢。

generator (`torch.Generator` 或 `list[torch.Generator]`，*可选*)：用于使生成过程确定性的 [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html)。

latents (`torch.Tensor`, *可选*) : 从高斯分布中采样的预生成噪声潜变量，用作图像生成的输入。可用于以不同的提示词微调同一生成过程。如果未提供，则使用提供的随机`generator`进行采样来生成潜变量张量。

guidance_scale (`float`, *可选*，默认值为 4.0)：较高的 guidance scale 值会促使模型生成与文本 `prompt` 紧密关联的图像，但代价是图像质量降低。当 `guidance_scale > 1` 时，guidance scale 生效。

frame_size (`int`，*可选*，默认为 64)：生成的 3D 输出中每个图像帧的宽度和高度。

output_type (`str`，*可选*，默认为 `"pil"`)：生成图像的输出格式。可选 `"pil"`（`PIL.Image.Image`）、`"np"`（`np.array`）、`"latent"`（`torch.Tensor`）或 mesh（`MeshDecoderOutput`）。

return_dict (`bool`，*可选*，默认为 `True`)：是否返回 [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) 而不是普通元组。

**返回：** [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) 或 `tuple`

如果 `return_dict` 为 `True`，则返回 [ShapEPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput)；否则返回一个 `tuple`，其中第一个元素是包含生成图像的列表。

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

示例：
```py
>>> from PIL import Image
>>> import torch
>>> from diffusers import DiffusionPipeline
>>> from diffusers.utils import export_to_gif, load_image

>>> device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

>>> repo = "openai/shap-e-img2img"
>>> pipe = DiffusionPipeline.from_pretrained(repo, torch_dtype=torch.float16)
>>> pipe = pipe.to(device)

>>> guidance_scale = 3.0
>>> image_url = "https://hf.co/datasets/diffusers/docs-images/resolve/main/shap-e/corgi.png"
>>> image = load_image(image_url).convert("RGB")

>>> images = pipe(
...     image,
...     guidance_scale=guidance_scale,
...     num_inference_steps=64,
...     frame_size=256,
... ).images

>>> gif_path = export_to_gif(images[0], "corgi_3d.gif")
```

## ShapEPipelineOutput[[diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput]]

#### diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput[[diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput]]

```python
diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput(images: list[list[PIL.Image.Image]] | list[list[numpy.ndarray]])
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L75)

**参数：**

images (`torch.Tensor`) : 用于 3D 渲染的图像列表。

[ShapEPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEPipeline) 和 [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline) 的输出类。

