# Shap-E

Mô hình Shap-E được đề xuất trong [Shap-E: Generating Conditional 3D Implicit Functions](https://huggingface.co/papers/2305.02463) bởi Alex Nichol và Heewoo Jun từ [OpenAI](https://github.com/openai).

Tóm tắt từ bài báo là:

*Chúng tôi giới thiệu Shap-E, một mô hình sinh có điều kiện cho tài sản 3D. Khác với các công trình gần đây về mô hình sinh 3D chỉ tạo ra một biểu diễn đầu ra duy nhất, Shap-E trực tiếp tạo ra các tham số của các hàm ẩn, có thể được render dưới dạng cả lưới có kết cấu (textured meshes) và trường bức xạ thần kinh (neural radiance fields). Chúng tôi huấn luyện Shap-E qua hai giai đoạn: đầu tiên, chúng tôi huấn luyện một bộ mã hóa (encoder) ánh xạ tất định các tài sản 3D thành các tham số của một hàm ẩn; thứ hai, chúng tôi huấn luyện một mô hình khuếch tán có điều kiện (conditional diffusion model) trên các đầu ra của bộ mã hóa. Khi được huấn luyện trên một tập dữ liệu lớn gồm các cặp dữ liệu 3D và văn bản, các mô hình kết quả của chúng tôi có khả năng tạo ra các tài sản 3D phức tạp và đa dạng chỉ trong vài giây. Khi so sánh với Point-E, một mô hình sinh tường minh (explicit generative model) trên các đám điểm (point clouds), Shap-E hội tụ nhanh hơn và đạt chất lượng mẫu tương đương hoặc tốt hơn, bất chấp việc mô hình hóa một không gian đầu ra đa chiều, đa biểu diễn hơn.*

Mã nguồn gốc có thể được tìm thấy tại [openai/shap-e](https://github.com/openai/shap-e).

> [!TIP]
> Xem phần [tái sử dụng các thành phần giữa các pipeline](../../using-diffusers/loading#reusing-models-in-multiple-pipelines) để tìm hiểu cách nạp các thành phần giống nhau vào nhiều pipeline một cách hiệu quả.

Hãy đảm bảo bạn đã cài đặt các thư viện sau.

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

## Text-to-3D

Để tạo một gif của một đối tượng 3D, hãy truyền một prompt văn bản vào [ShapEPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEPipeline). Pipeline sẽ tạo ra một danh sách các khung hình được sử dụng để tạo đối tượng 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
```

Bây giờ hãy sử dụng hàm [export_to_gif()](/docs/diffusers/v0.43.0/vi/api/utilities#diffusers.utils.export_to_gif) để chuyển đổi danh sách các khung hình ảnh thành một tệp gif của đối tượng 3D.

```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 = "Một quả pháo"
  
  
    
    prompt = "A birthday cupcake"
  

## Hình ảnh sang 3D

Để tạo một đối tượng 3D từ một hình ảnh khác, hãy sử dụng [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline). Bạn có thể sử dụng một hình ảnh có sẵn hoặc tạo một hình ảnh hoàn toàn mới. Hãy sử dụng mô hình [Kandinsky 2.1](./kandinsky) để tạo một hình ảnh mới.

```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")
```

Truyền cheeseburger vào [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline) để tạo ra biểu diễn 3D của nó.

```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
  
  
    
    Bánh burger phô mai 3D
  

## Tạo lưới

Shap-E là một mô hình linh hoạt, có thể tạo ra các đầu ra lưới (mesh) có kết cấu để hiển thị cho các ứng dụng tiếp theo. Trong ví dụ này, bạn sẽ chuyển đổi đầu ra thành tệp `glb` vì thư viện 🤗 Datasets hỗ trợ trực quan hóa lưới của các tệp `glb`, có thể được hiển thị bởi [Dataset viewer](https://huggingface.co/docs/hub/datasets-viewer#dataset-preview).

Bạn có thể tạo ra đầu ra dạng lưới (mesh) cho cả [ShapEPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEPipeline) và [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline) bằng cách chỉ định tham số `output_type` là `"mesh"`:

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

Sử dụng hàm `export_to_ply()` để lưu kết quả lưới dưới dạng tệp `ply`:

> [!TIP]
> Bạn có thể tùy chọn lưu đầu ra lưới dưới dạng tệp `obj` bằng hàm `export_to_obj()`. Khả năng lưu đầu ra lưới ở nhiều định dạng khác nhau giúp việc sử dụng ở các bước tiếp theo linh hoạt hơn!

```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}")
```

Sau đó, bạn có thể chuyển đổi tệp `ply` sang tệp `glb` bằng thư viện trimesh:

```py
import trimesh

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

Mặc định, đầu ra lưới được tập trung từ góc nhìn phía dưới, nhưng bạn có thể thay đổi góc nhìn mặc định bằng cách áp dụng phép biến đổi xoay:

```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")
```

Tải tệp mesh lên kho dữ liệu của bạn để xem trực quan hóa nó với Dataset viewer!

    

## ShapEPipeline[[diffusers.ShapEPipeline]]

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L87)

**Tham số:**

prior ([PriorTransformer](/docs/diffusers/v0.43.0/vi/api/models/prior_transformer#diffusers.PriorTransformer)) : Mô hình prior chuẩn của unCLIP để xấp xỉ vector nhúng hình ảnh từ vector nhúng văn bản.

text_encoder ([CLIPTextModelWithProjection](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPTextModelWithProjection)) : Bộ mã hóa văn bản đóng băng.

tokenizer ([CLIPTokenizer](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPTokenizer)) : Một `CLIPTokenizer` để phân tách văn bản.

scheduler ([HeunDiscreteScheduler](/docs/diffusers/v0.43.0/vi/api/schedulers/heun#diffusers.HeunDiscreteScheduler)) : Một trình lập lịch được sử dụng kết hợp với mô hình `prior` để tạo nhúng hình ảnh.

shap_e_renderer (`ShapERenderer`) : Trình render Shap-E của Shap-E chiếu các latents đã tạo thành các tham số của một MLP để tạo ra các đối tượng 3D bằng phương pháp render NeRF.

Pipeline để tạo biểu diễn ẩn của tài sản 3D và render bằng phương pháp NeRF.

Mô hình này kế thừa từ [DiffusionPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/overview#diffusers.DiffusionPipeline). Xem tài liệu của lớp cha để biết các phương thức chung được triển khai cho tất cả các pipeline (tải xuống, lưu, chạy trên một thiết bị cụ thể, v.v.).

#### __call__[[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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L190)

**Tham số:**

prompt (`str` hoặc `list[str]`) : Prompt hoặc các prompt để hướng dẫn việc tạo ảnh.

num_images_per_prompt (`int`, *tuỳ chọn*, mặc định là 1) : Số lượng hình ảnh cần tạo cho mỗi prompt.

num_inference_steps (`int`, *optional*, mặc định là 25) : Số bước khử nhiễu. Số bước khử nhiễu nhiều hơn thường dẫn đến hình ảnh có chất lượng cao hơn, với cái giá là suy luận chậm hơn.

generator (`torch.Generator` hoặc `list[torch.Generator]`, *tùy chọn*) : Một [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) để đảm bảo quá trình sinh là tất định.

latents (`torch.Tensor`, *tùy chọn*) : Các latents nhiễu được tạo trước, lấy mẫu từ phân phối Gaussian, dùng làm đầu vào cho việc tạo ảnh. Có thể dùng để tinh chỉnh cùng một quá trình tạo với các prompt khác nhau. Nếu không được cung cấp, một tensor latents sẽ được tạo bằng cách lấy mẫu sử dụng `generator` ngẫu nhiên được cung cấp.

guidance_scale (`float`, *optional*, mặc định là 4.0) : Giá trị guidance scale cao hơn khuyến khích mô hình tạo ra các hình ảnh gắn kết chặt chẽ với `prompt` văn bản, với cái giá là chất lượng hình ảnh thấp hơn. Guidance scale được kích hoạt khi `guidance_scale > 1`.

frame_size (`int`, *optional*, mặc định là 64) : Độ rộng và chiều cao của mỗi khung hình trong đầu ra 3D được tạo ra.

output_type (`str`, *tùy chọn*, mặc định là `"pil"`) : Định dạng đầu ra của hình ảnh được tạo ra. Chọn giữa `"pil"` (`PIL.Image.Image`), `"np"` (`np.array`), `"latent"` (`torch.Tensor`), hoặc mesh (`MeshDecoderOutput`).

return_dict (`bool`, *tùy chọn*, mặc định là `True`) : Có nên trả về một [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) thay vì một tuple thông thường hay không.

**Trả về:** [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) hoặc `tuple`

Nếu `return_dict` là `True`, [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) sẽ được trả về, ngược lại một `tuple` sẽ được trả về trong đó phần tử đầu tiên là một danh sách chứa các hình ảnh đã được tạo.

Hàm gọi call của pipeline để tạo nội dung.

Ví dụ:
```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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py#L88)

**Tham số:**

prior ([PriorTransformer](/docs/diffusers/v0.43.0/vi/api/models/prior_transformer#diffusers.PriorTransformer)) : Mô hình prior chuẩn của unCLIP để xấp xỉ vector nhúng hình ảnh từ vector nhúng văn bản.

image_encoder ([CLIPVisionModel](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPVisionModel)) : Bộ mã hóa ảnh đóng băng.

image_processor ([CLIPImageProcessor](https://huggingface.co/docs/transformers/v5.22.2/en/model_doc/clip#transformers.CLIPImageProcessor)) : Một `CLIPImageProcessor` để xử lý hình ảnh.

scheduler ([HeunDiscreteScheduler](/docs/diffusers/v0.43.0/vi/api/schedulers/heun#diffusers.HeunDiscreteScheduler)) : Một trình lập lịch được sử dụng kết hợp với mô hình `prior` để tạo nhúng hình ảnh.

shap_e_renderer (`ShapERenderer`) : Trình render Shap-E của Shap-E chiếu các latents đã tạo thành các tham số của một MLP để tạo ra các đối tượng 3D bằng phương pháp render NeRF.

Pipeline để tạo biểu diễn ẩn của tài sản 3D và render bằng phương pháp NeRF từ một hình ảnh.

Mô hình này kế thừa từ [DiffusionPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/overview#diffusers.DiffusionPipeline). Xem tài liệu của lớp cha để biết các phương thức chung được triển khai cho tất cả các pipeline (tải xuống, lưu, chạy trên một thiết bị cụ thể, v.v.).

#### __call__[[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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e_img2img.py#L172)

**Tham số:**

image (`torch.Tensor`, `PIL.Image.Image`, `np.ndarray`, `list[torch.Tensor]`, `list[PIL.Image.Image]`, hoặc `list[np.ndarray]`) : `Image` hoặc tensor đại diện cho một lô ảnh (image batch) được sử dụng làm điểm khởi đầu. Cũng có thể nhận image latents dưới dạng image, nhưng nếu truyền latents trực tiếp thì chúng sẽ không được mã hóa lại.

num_images_per_prompt (`int`, *tuỳ chọn*, mặc định là 1) : Số lượng hình ảnh cần tạo cho mỗi prompt.

num_inference_steps (`int`, *optional*, mặc định là 25) : Số bước khử nhiễu. Số bước khử nhiễu nhiều hơn thường dẫn đến hình ảnh có chất lượng cao hơn, với cái giá là suy luận chậm hơn.

generator (`torch.Generator` hoặc `list[torch.Generator]`, *tùy chọn*) : Một [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) để đảm bảo quá trình sinh là tất định.

latents (`torch.Tensor`, *tùy chọn*) : Các latents nhiễu được tạo trước, lấy mẫu từ phân phối Gaussian, dùng làm đầu vào cho việc tạo ảnh. Có thể dùng để tinh chỉnh cùng một quá trình tạo với các prompt khác nhau. Nếu không được cung cấp, một tensor latents sẽ được tạo bằng cách lấy mẫu sử dụng `generator` ngẫu nhiên được cung cấp.

guidance_scale (`float`, *optional*, mặc định là 4.0) : Giá trị guidance scale cao hơn khuyến khích mô hình tạo ra các hình ảnh gắn kết chặt chẽ với `prompt` văn bản, với cái giá là chất lượng hình ảnh thấp hơn. Guidance scale được kích hoạt khi `guidance_scale > 1`.

frame_size (`int`, *optional*, mặc định là 64) : Độ rộng và chiều cao của mỗi khung hình trong đầu ra 3D được tạo ra.

output_type (`str`, *tùy chọn*, mặc định là `"pil"`) : Định dạng đầu ra của hình ảnh được tạo ra. Chọn giữa `"pil"` (`PIL.Image.Image`), `"np"` (`np.array`), `"latent"` (`torch.Tensor`), hoặc mesh (`MeshDecoderOutput`).

return_dict (`bool`, *tùy chọn*, mặc định là `True`) : Có nên trả về một [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) thay vì một tuple thông thường hay không.

**Trả về:** [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) hoặc `tuple`

Nếu `return_dict` là `True`, [ShapEPipelineOutput](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.pipelines.shap_e.pipeline_shap_e.ShapEPipelineOutput) sẽ được trả về, ngược lại một `tuple` sẽ được trả về trong đó phần tử đầu tiên là một danh sách chứa các hình ảnh đã được tạo.

Hàm gọi call của pipeline để tạo nội dung.

Ví dụ:
```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]])
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/shap_e/pipeline_shap_e.py#L75)

**Tham số:**

images (`torch.Tensor`) : Một danh sách các hình ảnh để render 3D.

Lớp đầu ra cho [ShapEPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEPipeline) và [ShapEImg2ImgPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/shap_e#diffusers.ShapEImg2ImgPipeline).

