|
<!--Copyright 2024 The HuggingFace Team. All rights reserved. |
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
|
the License. You may obtain a copy of the License at |
|
|
|
http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
|
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
|
specific language governing permissions and limitations under the License. |
|
--> |
|
|
|
# ํจ๊ณผ์ ์ด๊ณ ํจ์จ์ ์ธ Diffusion |
|
|
|
[[open-in-colab]] |
|
|
|
ํน์ ์คํ์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๊ฑฐ๋ ์ํ๋ ๋ด์ฉ์ ํฌํจํ๋๋ก[`DiffusionPipeline`]์ ์ค์ ํ๋ ๊ฒ์ ๊น๋ค๋ก์ธ ์ ์์ต๋๋ค. ์ข
์ข
๋ง์กฑ์ค๋ฌ์ด ์ด๋ฏธ์ง๋ฅผ ์ป๊ธฐ๊น์ง [`DiffusionPipeline`]์ ์ฌ๋ฌ ๋ฒ ์คํํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฌด์์ ์ ๋ฅผ ์ฐฝ์กฐํ๋ ๊ฒ์ ํนํ ์ถ๋ก ์ ๋ฐ๋ณตํด์ ์คํํ๋ ๊ฒฝ์ฐ ๊ณ์ฐ ์ง์ฝ์ ์ธ ํ๋ก์ธ์ค์
๋๋ค. |
|
|
|
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ์ดํ๋ผ์ธ์์ *๊ณ์ฐ*(์๋) ๋ฐ *๋ฉ๋ชจ๋ฆฌ*(GPU RAM) ํจ์จ์ฑ์ ๊ทน๋ํํ์ฌ ์ถ๋ก ์ฃผ๊ธฐ ์ฌ์ด์ ์๊ฐ์ ๋จ์ถํ์ฌ ๋ ๋น ๋ฅด๊ฒ ๋ฐ๋ณตํ ์ ์๋๋ก ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. |
|
|
|
์ด ํํ ๋ฆฌ์ผ์์๋ [`DiffusionPipeline`]์ ์ฌ์ฉํ์ฌ ๋ ๋น ๋ฅด๊ณ ํจ๊ณผ์ ์ผ๋ก ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์๋ดํฉ๋๋ค. |
|
|
|
[`runwayml/stable-diffusion-v1-5`](https://huggingface.co/runwayml/stable-diffusion-v1-5) ๋ชจ๋ธ์ ๋ถ๋ฌ์์ ์์ํฉ๋๋ค: |
|
|
|
```python |
|
from diffusers import DiffusionPipeline |
|
|
|
model_id = "runwayml/stable-diffusion-v1-5" |
|
pipeline = DiffusionPipeline.from_pretrained(model_id) |
|
``` |
|
|
|
์์ ํ๋กฌํํธ๋ "portrait of an old warrior chief" ์ด์ง๋ง, ์์ ๋กญ๊ฒ ์์ ๋ง์ ํ๋กฌํํธ๋ฅผ ์ฌ์ฉํด๋ ๋ฉ๋๋ค: |
|
|
|
```python |
|
prompt = "portrait photo of a old warrior chief" |
|
``` |
|
|
|
## ์๋ |
|
|
|
<Tip> |
|
|
|
๐ก GPU์ ์ก์ธ์คํ ์ ์๋ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ GPU ์ ๊ณต์
์ฒด์์ ๋ฌด๋ฃ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค!. [Colab](https://colab.research.google.com/) |
|
|
|
</Tip> |
|
|
|
์ถ๋ก ์๋๋ฅผ ๋์ด๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ ์ค ํ๋๋ Pytorch ๋ชจ๋์ ์ฌ์ฉํ ๋์ ๊ฐ์ ๋ฐฉ์์ผ๋ก GPU์ ํ์ดํ๋ผ์ธ์ ๋ฐฐ์นํ๋ ๊ฒ์
๋๋ค: |
|
|
|
```python |
|
pipeline = pipeline.to("cuda") |
|
``` |
|
|
|
๋์ผํ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ๊ณ ๊ฐ์ ํ ์ ์๋์ง ํ์ธํ๋ ค๋ฉด [`Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html)๋ฅผ ์ฌ์ฉํ๊ณ [์ฌํ์ฑ](./using-diffusers/reusing_seeds)์ ๋ํ ์๋๋ฅผ ์ค์ ํ์ธ์: |
|
|
|
```python |
|
import torch |
|
|
|
generator = torch.Generator("cuda").manual_seed(0) |
|
``` |
|
|
|
์ด์ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ ์ ์์ต๋๋ค: |
|
|
|
```python |
|
image = pipeline(prompt, generator=generator).images[0] |
|
image |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_1.png"> |
|
</div> |
|
|
|
์ด ํ๋ก์ธ์ค๋ T4 GPU์์ ์ฝ 30์ด๊ฐ ์์๋์์ต๋๋ค(ํ ๋น๋ GPU๊ฐ T4๋ณด๋ค ๋์ ๊ฒฝ์ฐ ๋ ๋น ๋ฅผ ์ ์์). ๊ธฐ๋ณธ์ ์ผ๋ก [`DiffusionPipeline`]์ 50๊ฐ์ ์ถ๋ก ๋จ๊ณ์ ๋ํด ์ ์ฒด `float32` ์ ๋ฐ๋๋ก ์ถ๋ก ์ ์คํํฉ๋๋ค. `float16`๊ณผ ๊ฐ์ ๋ ๋ฎ์ ์ ๋ฐ๋๋ก ์ ํํ๊ฑฐ๋ ์ถ๋ก ๋จ๊ณ๋ฅผ ๋ ์ ๊ฒ ์คํํ์ฌ ์๋๋ฅผ ๋์ผ ์ ์์ต๋๋ค. |
|
|
|
`float16`์ผ๋ก ๋ชจ๋ธ์ ๋ก๋ํ๊ณ ์ด๋ฏธ์ง๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค: |
|
|
|
|
|
```python |
|
import torch |
|
|
|
pipeline = DiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16) |
|
pipeline = pipeline.to("cuda") |
|
generator = torch.Generator("cuda").manual_seed(0) |
|
image = pipeline(prompt, generator=generator).images[0] |
|
image |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_2.png"> |
|
</div> |
|
|
|
์ด๋ฒ์๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ๋ฐ ์ฝ 11์ด๋ฐ์ ๊ฑธ๋ฆฌ์ง ์์ ์ด์ ๋ณด๋ค 3๋ฐฐ ๊ฐ๊น์ด ๋นจ๋ผ์ก์ต๋๋ค! |
|
|
|
<Tip> |
|
|
|
๐ก ํ์ดํ๋ผ์ธ์ ํญ์ `float16`์์ ์คํํ ๊ฒ์ ๊ฐ๋ ฅํ ๊ถ์ฅํ๋ฉฐ, ์ง๊ธ๊น์ง ์ถ๋ ฅ ํ์ง์ด ์ ํ๋๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์์ต๋๋ค. |
|
|
|
</Tip> |
|
|
|
๋ ๋ค๋ฅธ ์ต์
์ ์ถ๋ก ๋จ๊ณ์ ์๋ฅผ ์ค์ด๋ ๊ฒ์
๋๋ค. ๋ณด๋ค ํจ์จ์ ์ธ ์ค์ผ์ค๋ฌ๋ฅผ ์ ํํ๋ฉด ์ถ๋ ฅ ํ์ง ์ ํ ์์ด ๋จ๊ณ ์๋ฅผ ์ค์ด๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ํ์ฌ ๋ชจ๋ธ๊ณผ ํธํ๋๋ ์ค์ผ์ค๋ฌ๋ `compatibles` ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ [`DiffusionPipeline`]์์ ์ฐพ์ ์ ์์ต๋๋ค: |
|
|
|
```python |
|
pipeline.scheduler.compatibles |
|
[ |
|
diffusers.schedulers.scheduling_lms_discrete.LMSDiscreteScheduler, |
|
diffusers.schedulers.scheduling_unipc_multistep.UniPCMultistepScheduler, |
|
diffusers.schedulers.scheduling_k_dpm_2_discrete.KDPM2DiscreteScheduler, |
|
diffusers.schedulers.scheduling_deis_multistep.DEISMultistepScheduler, |
|
diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler, |
|
diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler, |
|
diffusers.schedulers.scheduling_ddpm.DDPMScheduler, |
|
diffusers.schedulers.scheduling_dpmsolver_singlestep.DPMSolverSinglestepScheduler, |
|
diffusers.schedulers.scheduling_k_dpm_2_ancestral_discrete.KDPM2AncestralDiscreteScheduler, |
|
diffusers.schedulers.scheduling_heun_discrete.HeunDiscreteScheduler, |
|
diffusers.schedulers.scheduling_pndm.PNDMScheduler, |
|
diffusers.schedulers.scheduling_euler_ancestral_discrete.EulerAncestralDiscreteScheduler, |
|
diffusers.schedulers.scheduling_ddim.DDIMScheduler, |
|
] |
|
``` |
|
|
|
Stable Diffusion ๋ชจ๋ธ์ ์ผ๋ฐ์ ์ผ๋ก ์ฝ 50๊ฐ์ ์ถ๋ก ๋จ๊ณ๊ฐ ํ์ํ [`PNDMScheduler`]๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ์ง๋ง, [`DPMSolverMultistepScheduler`]์ ๊ฐ์ด ์ฑ๋ฅ์ด ๋ ๋ฐ์ด๋ ์ค์ผ์ค๋ฌ๋ ์ฝ 20๊ฐ ๋๋ 25๊ฐ์ ์ถ๋ก ๋จ๊ณ๋ง ํ์๋ก ํฉ๋๋ค. ์ ์ค์ผ์ค๋ฌ๋ฅผ ๋ก๋ํ๋ ค๋ฉด [`ConfigMixin.from_config`] ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค: |
|
|
|
```python |
|
from diffusers import DPMSolverMultistepScheduler |
|
|
|
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config) |
|
``` |
|
|
|
`num_inference_steps`๋ฅผ 20์ผ๋ก ์ค์ ํฉ๋๋ค: |
|
|
|
```python |
|
generator = torch.Generator("cuda").manual_seed(0) |
|
image = pipeline(prompt, generator=generator, num_inference_steps=20).images[0] |
|
image |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_3.png"> |
|
</div> |
|
|
|
์ถ๋ก ์๊ฐ์ 4์ด๋ก ๋จ์ถํ ์ ์์์ต๋๋ค! โก๏ธ |
|
|
|
## ๋ฉ๋ชจ๋ฆฌ |
|
|
|
ํ์ดํ๋ผ์ธ ์ฑ๋ฅ ํฅ์์ ๋ ๋ค๋ฅธ ํต์ฌ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ด๋ ๊ฒ์ธ๋ฐ, ์ด๋น ์์ฑ๋๋ ์ด๋ฏธ์ง ์๋ฅผ ์ต๋ํํ๋ ค๊ณ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ๊ฐ์ ์ ์ผ๋ก ๋ ๋น ๋ฅธ ์๋๋ฅผ ์๋ฏธํฉ๋๋ค. ํ ๋ฒ์ ์์ฑํ ์ ์๋ ์ด๋ฏธ์ง ์๋ฅผ ํ์ธํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ `OutOfMemoryError`(OOM)์ด ๋ฐ์ํ ๋๊น์ง ๋ค์ํ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์๋ํด ๋ณด๋ ๊ฒ์
๋๋ค. |
|
|
|
ํ๋กฌํํธ ๋ชฉ๋ก๊ณผ `Generators`์์ ์ด๋ฏธ์ง ๋ฐฐ์น๋ฅผ ์์ฑํ๋ ํจ์๋ฅผ ๋ง๋ญ๋๋ค. ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ๊ฐ `Generator`์ ์๋๋ฅผ ํ ๋นํด์ผ ํฉ๋๋ค. |
|
|
|
```python |
|
def get_inputs(batch_size=1): |
|
generator = [torch.Generator("cuda").manual_seed(i) for i in range(batch_size)] |
|
prompts = batch_size * [prompt] |
|
num_inference_steps = 20 |
|
|
|
return {"prompt": prompts, "generator": generator, "num_inference_steps": num_inference_steps} |
|
``` |
|
|
|
๋ํ ๊ฐ ์ด๋ฏธ์ง ๋ฐฐ์น๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ธฐ๋ฅ์ด ํ์ํฉ๋๋ค: |
|
|
|
```python |
|
from PIL import Image |
|
|
|
|
|
def image_grid(imgs, rows=2, cols=2): |
|
w, h = imgs[0].size |
|
grid = Image.new("RGB", size=(cols * w, rows * h)) |
|
|
|
for i, img in enumerate(imgs): |
|
grid.paste(img, box=(i % cols * w, i // cols * h)) |
|
return grid |
|
``` |
|
|
|
`batch_size=4`๋ถํฐ ์์ํด ์ผ๋ง๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋นํ๋์ง ํ์ธํฉ๋๋ค: |
|
|
|
```python |
|
images = pipeline(**get_inputs(batch_size=4)).images |
|
image_grid(images) |
|
``` |
|
|
|
RAM์ด ๋ ๋ง์ GPU๊ฐ ์๋๋ผ๋ฉด ์์ ์ฝ๋์์ `OOM` ์ค๋ฅ๊ฐ ๋ฐํ๋์์ ๊ฒ์
๋๋ค! ๋๋ถ๋ถ์ ๋ฉ๋ชจ๋ฆฌ๋ cross-attention ๋ ์ด์ด๊ฐ ์ฐจ์งํฉ๋๋ค. ์ด ์์
์ ๋ฐฐ์น๋ก ์คํํ๋ ๋์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ฉด ์๋นํ ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ ์ ์์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ์ฌ [`~DiffusionPipeline.enable_attention_slicing`] ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค: |
|
|
|
|
|
```python |
|
pipeline.enable_attention_slicing() |
|
``` |
|
|
|
์ด์ `batch_size`๋ฅผ 8๋ก ๋๋ ค๋ณด์ธ์! |
|
|
|
```python |
|
images = pipeline(**get_inputs(batch_size=8)).images |
|
image_grid(images, rows=2, cols=4) |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_5.png"> |
|
</div> |
|
|
|
์ด์ ์๋ 4๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ๋ฐฐ์น๋ก ์์ฑํ ์๋ ์์์ง๋ง, ์ด์ ๋ ์ด๋ฏธ์ง๋น ์ฝ 3.5์ด ๋ง์ 8๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ๋ฐฐ์น๋ก ์์ฑํ ์ ์์ต๋๋ค! ์ด๋ ์๋ง๋ ํ์ง ์ ํ ์์ด T4 GPU์์ ๊ฐ์ฅ ๋น ๋ฅธ ์๋์ผ ๊ฒ์
๋๋ค. |
|
|
|
## ํ์ง |
|
|
|
์ง๋ ๋ ์น์
์์๋ `fp16`์ ์ฌ์ฉํ์ฌ ํ์ดํ๋ผ์ธ์ ์๋๋ฅผ ์ต์ ํํ๊ณ , ๋ ์ฑ๋ฅ์ด ์ข์ ์ค์ผ์ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ถ๋ก ๋จ๊ณ์ ์๋ฅผ ์ค์ด๊ณ , attention slicing์ ํ์ฑํํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์๋น๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค. ์ด์ ์์ฑ๋ ์ด๋ฏธ์ง์ ํ์ง์ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ง์ค์ ์ผ๋ก ์์๋ณด๊ฒ ์ต๋๋ค. |
|
|
|
|
|
### ๋ ๋์ ์ฒดํฌํฌ์ธํธ |
|
|
|
๊ฐ์ฅ ํ์คํ ๋จ๊ณ๋ ๋ ๋์ ์ฒดํฌํฌ์ธํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. Stable Diffusion ๋ชจ๋ธ์ ์ข์ ์ถ๋ฐ์ ์ด๋ฉฐ, ๊ณต์ ์ถ์ ์ดํ ๋ช ๊ฐ์ง ๊ฐ์ ๋ ๋ฒ์ ๋ ์ถ์๋์์ต๋๋ค. ํ์ง๋ง ์ต์ ๋ฒ์ ์ ์ฌ์ฉํ๋ค๊ณ ํด์ ์๋์ผ๋ก ๋ ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ ๊ฒ์ ์๋๋๋ค. ์ฌ์ ํ ๋ค์ํ ์ฒดํฌํฌ์ธํธ๋ฅผ ์ง์ ์คํํด๋ณด๊ณ , [negative prompts](https://minimaxir.com/2022/11/stable-diffusion-negative-prompt/) ์ฌ์ฉ ๋ฑ ์ฝ๊ฐ์ ์กฐ์ฌ๋ฅผ ํตํด ์ต์์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ด์ผ ํฉ๋๋ค. |
|
|
|
์ด ๋ถ์ผ๊ฐ ์ฑ์ฅํจ์ ๋ฐ๋ผ ํน์ ์คํ์ผ์ ์ฐ์ถํ ์ ์๋๋ก ์ธ๋ฐํ๊ฒ ์กฐ์ ๋ ๊ณ ํ์ง ์ฒดํฌํฌ์ธํธ๊ฐ ์ ์ ๋ ๋ง์์ง๊ณ ์์ต๋๋ค. [Hub](https://huggingface.co/models?library=diffusers&sort=downloads)์ [Diffusers Gallery](https://huggingface.co/spaces/huggingface-projects/diffusers-gallery)๋ฅผ ๋๋ฌ๋ณด๊ณ ๊ด์ฌ ์๋ ๊ฒ์ ์ฐพ์๋ณด์ธ์! |
|
|
|
|
|
### ๋ ๋์ ํ์ดํ๋ผ์ธ ๊ตฌ์ฑ ์์ |
|
|
|
ํ์ฌ ํ์ดํ๋ผ์ธ ๊ตฌ์ฑ ์์๋ฅผ ์ต์ ๋ฒ์ ์ผ๋ก ๊ต์ฒดํด ๋ณผ ์๋ ์์ต๋๋ค. Stability AI์ ์ต์ [autodecoder](https://huggingface.co/stabilityai/stable-diffusion-2-1/tree/main/vae)๋ฅผ ํ์ดํ๋ผ์ธ์ ๋ก๋ํ๊ณ ๋ช ๊ฐ์ง ์ด๋ฏธ์ง๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค: |
|
|
|
|
|
```python |
|
from diffusers import AutoencoderKL |
|
|
|
vae = AutoencoderKL.from_pretrained("stabilityai/sd-vae-ft-mse", torch_dtype=torch.float16).to("cuda") |
|
pipeline.vae = vae |
|
images = pipeline(**get_inputs(batch_size=8)).images |
|
image_grid(images, rows=2, cols=4) |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_6.png"> |
|
</div> |
|
|
|
### ๋ ๋์ ํ๋กฌํํธ ์์ง๋์ด๋ง |
|
|
|
์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉํ๋ ํ
์คํธ ํ๋กฌํํธ๋ *prompt engineering*์ด๋ผ๊ณ ํ ์ ๋๋ก ๋งค์ฐ ์ค์ํฉ๋๋ค. ํ๋กฌํํธ ์์ง๋์ด๋ง ์ ๊ณ ๋ คํด์ผ ํ ๋ช ๊ฐ์ง ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: |
|
|
|
- ์์ฑํ๋ ค๋ ์ด๋ฏธ์ง ๋๋ ์ ์ฌํ ์ด๋ฏธ์ง๊ฐ ์ธํฐ๋ท์ ์ด๋ป๊ฒ ์ ์ฅ๋์ด ์๋๊ฐ? |
|
- ๋ด๊ฐ ์ํ๋ ์คํ์ผ๋ก ๋ชจ๋ธ์ ์ ๋ํ๊ธฐ ์ํด ์ด๋ค ์ถ๊ฐ ์ธ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํ ์ ์๋๊ฐ? |
|
|
|
์ด๋ฅผ ์ผ๋์ ๋๊ณ ์์๊ณผ ๋ ๋์ ํ์ง์ ๋ํ
์ผ์ ํฌํจํ๋๋ก ํ๋กฌํํธ๋ฅผ ๊ฐ์ ํด ๋ด
์๋ค: |
|
|
|
|
|
```python |
|
prompt += ", tribal panther make up, blue on red, side profile, looking away, serious eyes" |
|
prompt += " 50mm portrait photography, hard rim lighting photography--beta --ar 2:3 --beta --upbeta" |
|
``` |
|
|
|
์๋ก์ด ํ๋กฌํํธ๋ก ์ด๋ฏธ์ง ๋ฐฐ์น๋ฅผ ์์ฑํฉ๋๋ค: |
|
|
|
```python |
|
images = pipeline(**get_inputs(batch_size=8)).images |
|
image_grid(images, rows=2, cols=4) |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_7.png"> |
|
</div> |
|
|
|
๊ฝค ์ธ์์ ์
๋๋ค! `1`์ ์๋๋ฅผ ๊ฐ์ง `Generator`์ ํด๋นํ๋ ๋ ๋ฒ์งธ ์ด๋ฏธ์ง์ ํผ์ฌ์ฒด์ ๋์ด์ ๋ํ ํ
์คํธ๋ฅผ ์ถ๊ฐํ์ฌ ์กฐ๊ธ ๋ ์กฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค: |
|
|
|
```python |
|
prompts = [ |
|
"portrait photo of the oldest warrior chief, tribal panther make up, blue on red, side profile, looking away, serious eyes 50mm portrait photography, hard rim lighting photography--beta --ar 2:3 --beta --upbeta", |
|
"portrait photo of a old warrior chief, tribal panther make up, blue on red, side profile, looking away, serious eyes 50mm portrait photography, hard rim lighting photography--beta --ar 2:3 --beta --upbeta", |
|
"portrait photo of a warrior chief, tribal panther make up, blue on red, side profile, looking away, serious eyes 50mm portrait photography, hard rim lighting photography--beta --ar 2:3 --beta --upbeta", |
|
"portrait photo of a young warrior chief, tribal panther make up, blue on red, side profile, looking away, serious eyes 50mm portrait photography, hard rim lighting photography--beta --ar 2:3 --beta --upbeta", |
|
] |
|
|
|
generator = [torch.Generator("cuda").manual_seed(1) for _ in range(len(prompts))] |
|
images = pipeline(prompt=prompts, generator=generator, num_inference_steps=25).images |
|
image_grid(images) |
|
``` |
|
|
|
<div class="flex justify-center"> |
|
<img src="https://huggingface.co/datasets/diffusers/docs-images/resolve/main/stable_diffusion_101/sd_101_8.png"> |
|
</div> |
|
|
|
## ๋ค์ ๋จ๊ณ |
|
|
|
์ด ํํ ๋ฆฌ์ผ์์๋ ๊ณ์ฐ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ๋์ด๊ณ ์์ฑ๋ ์ถ๋ ฅ์ ํ์ง์ ๊ฐ์ ํ๊ธฐ ์ํด [`DiffusionPipeline`]์ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ๋ ๋น ๋ฅด๊ฒ ๋ง๋๋ ๋ฐ ๊ด์ฌ์ด ์๋ค๋ฉด ๋ค์ ๋ฆฌ์์ค๋ฅผ ์ดํด๋ณด์ธ์: |
|
|
|
- [PyTorch 2.0](./optimization/torch2.0) ๋ฐ [`torch.compile`](https://pytorch.org/docs/stable/generated/torch.compile.html)์ด ์ด๋ป๊ฒ ์ถ๋ก ์๋๋ฅผ 5~300% ํฅ์์ํฌ ์ ์๋์ง ์์๋ณด์ธ์. A100 GPU์์๋ ์ถ๋ก ์๋๊ฐ ์ต๋ 50%๊น์ง ๋นจ๋ผ์ง ์ ์์ต๋๋ค! |
|
- PyTorch 2๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ, [xFormers](./optimization/xformers)๋ฅผ ์ค์นํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ธ ์ดํ
์
๋ฉ์ปค๋์ฆ์ PyTorch 1.13.1๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์๋๊ฐ ๋นจ๋ผ์ง๊ณ ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ์ค์ด๋ญ๋๋ค. |
|
- ๋ชจ๋ธ ์คํ๋ก๋ฉ๊ณผ ๊ฐ์ ๋ค๋ฅธ ์ต์ ํ ๊ธฐ๋ฒ์ [์ด ๊ฐ์ด๋](./optimization/fp16)์์ ๋ค๋ฃจ๊ณ ์์ต๋๋ค. |