mirror of
https://github.com/huggingface/diffusers.git
synced 2026-01-27 17:22:53 +03:00
* Docs kr update 3 controlnet, reproducibility ์ ๋ก๋ generator ๊ทธ๋๋ก ์ฌ์ฉ seamless multi-GPU ๊ทธ๋๋ก ์ฌ์ฉ create_dataset ๋ฒ์ญ 1์ฐจ stable_diffusion_jax new translation Add coreml, tome kr docs minor fix translate training/instructpix2pix fix training/instructpix2pix.mdx using-diffusers/weighting_prompts ๋ฒ์ญ 1์ฐจ add SDXL docs Translate using-diffuers/loading_overview.md translate using-diffusers/textual_inversion_inference.md Conditional image generation (#37) * stable_diffusion_jax * index_update * index_update * condition_image_generation --------- Co-authored-by: Seongsu Park <tjdtnsu@gmail.com> jihwan/stable_diffusion.mdx custom_diffusion ์์ ์๋ฃ quicktour ์์ ์๋ฃ distributed inference & control brightness (#40) * distributed_inference.mdx * control_brightness --------- Co-authored-by: idra79haza <idra79haza@github.com> Co-authored-by: Seongsu Park <tjdtnsu@gmail.com> using_safetensors (#41) * distributed_inference.mdx * control_brightness * using_safetensors.mdx --------- Co-authored-by: idra79haza <idra79haza@github.com> Co-authored-by: Seongsu Park <tjdtnsu@gmail.com> delete safetensor short * Repace mdx to md * toctree update * Add controlling_generation * toctree fix * colab link, minor fix * docs name typo fix * frontmatter fix * translation fix
202 lines
9.1 KiB
Markdown
202 lines
9.1 KiB
Markdown
<!--Copyright 2023 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.
|
|
-->
|
|
|
|
# ์ฌํ ๊ฐ๋ฅํ ํ์ดํ๋ผ์ธ ์์ฑํ๊ธฐ
|
|
|
|
[[open-in-colab]]
|
|
|
|
์ฌํ์ฑ์ ํ
์คํธ, ๊ฒฐ๊ณผ ์ฌํ, ๊ทธ๋ฆฌ๊ณ [์ด๋ฏธ์ง ํ๋ฆฌํฐ ๋์ด๊ธฐ](resuing_seeds)์์ ์ค์ํฉ๋๋ค.
|
|
๊ทธ๋ฌ๋ diffusion ๋ชจ๋ธ์ ๋ฌด์์์ฑ์ ๋งค๋ฒ ๋ชจ๋ธ์ด ๋์๊ฐ ๋๋ง๋ค ํ์ดํ๋ผ์ธ์ด ๋ค๋ฅธ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ ์ ์๋๋ก ํ๋ ์ด์ ๋ก ํ์ํฉ๋๋ค.
|
|
ํ๋ซํผ ๊ฐ์ ์ ํํ๊ฒ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์๋ ์์ง๋ง, ํน์ ํ์ฉ ๋ฒ์ ๋ด์์ ๋ฆด๋ฆฌ์ค ๋ฐ ํ๋ซํผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ฌํํ ์๋ ์์ต๋๋ค.
|
|
๊ทธ๋ผ์๋ diffusion ํ์ดํ๋ผ์ธ๊ณผ ์ฒดํฌํฌ์ธํธ์ ๋ฐ๋ผ ํ์ฉ ์ค์ฐจ๊ฐ ๋ฌ๋ผ์ง๋๋ค.
|
|
|
|
diffusion ๋ชจ๋ธ์์ ๋ฌด์์์ฑ์ ์์ฒ์ ์ ์ดํ๊ฑฐ๋ ๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํ ์ด์ ์
๋๋ค.
|
|
|
|
<Tip>
|
|
|
|
๐ก Pytorch์ [์ฌํ์ฑ์ ๋ํ ์ ์ธ](https://pytorch.org/docs/stable/notes/randomness.html)๋ฅผ ๊ผญ ์ฝ์ด๋ณด๊ธธ ์ถ์ฒํฉ๋๋ค:
|
|
|
|
> ์์ ํ๊ฒ ์ฌํ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ Pytorch ๋ฐฐํฌ, ๊ฐ๋ณ์ ์ธ ์ปค๋ฐ, ํน์ ๋ค๋ฅธ ํ๋ซํผ๋ค์์ ๋ณด์ฅ๋์ง ์์ต๋๋ค.
|
|
> ๋ํ, ๊ฒฐ๊ณผ๋ CPU์ GPU ์คํ๊ฐ์ ์ฌ์ง์ด ๊ฐ์ seed๋ฅผ ์ฌ์ฉํ ๋๋ ์ฌํ ๊ฐ๋ฅํ์ง ์์ ์ ์์ต๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
## ๋ฌด์์์ฑ ์ ์ดํ๊ธฐ
|
|
|
|
์ถ๋ก ์์, ํ์ดํ๋ผ์ธ์ ๋
ธ์ด์ฆ๋ฅผ ์ค์ด๊ธฐ ์ํด ๊ฐ์ฐ์์ ๋
ธ์ด์ฆ๋ฅผ ์์ฑํ๊ฑฐ๋ ์ค์ผ์ค๋ง ๋จ๊ณ์ ๋
ธ์ด์ฆ๋ฅผ ๋ํ๋ ๋ฑ์ ๋๋ค ์ํ๋ง ์คํ์ ํฌ๊ฒ ์์กดํฉ๋๋ค,
|
|
|
|
[DDIMPipeline](https://huggingface.co/docs/diffusers/v0.18.0/en/api/pipelines/ddim#diffusers.DDIMPipeline)์์ ๋ ์ถ๋ก ๋จ๊ณ ์ดํ์ ํ
์ ๊ฐ์ ์ดํด๋ณด์ธ์:
|
|
|
|
```python
|
|
from diffusers import DDIMPipeline
|
|
import numpy as np
|
|
|
|
model_id = "google/ddpm-cifar10-32"
|
|
|
|
# ๋ชจ๋ธ๊ณผ ์ค์ผ์ค๋ฌ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
|
|
ddim = DDIMPipeline.from_pretrained(model_id)
|
|
|
|
# ๋ ๊ฐ์ ๋จ๊ณ์ ๋ํด์ ํ์ดํ๋ผ์ธ์ ์คํํ๊ณ numpy tensor๋ก ๊ฐ์ ๋ฐํํ๊ธฐ
|
|
image = ddim(num_inference_steps=2, output_type="np").images
|
|
print(np.abs(image).sum())
|
|
```
|
|
|
|
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ํ๋์ ๊ฐ์ด ๋์ค์ง๋ง, ๋ค์ ์คํํ๋ฉด ๋ค๋ฅธ ๊ฐ์ด ๋์ต๋๋ค. ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋ ๊ฑธ๊น์?
|
|
|
|
ํ์ดํ๋ผ์ธ์ด ์คํ๋ ๋๋ง๋ค, [torch.randn](https://pytorch.org/docs/stable/generated/torch.randn.html)์
|
|
๋จ๊ณ์ ์ผ๋ก ๋
ธ์ด์ฆ ์ ๊ฑฐ๋๋ ๊ฐ์ฐ์์ ๋
ธ์ด์ฆ๊ฐ ์์ฑํ๊ธฐ ์ํ ๋ค๋ฅธ ๋๋ค seed๋ฅผ ์ฌ์ฉํฉ๋๋ค.
|
|
|
|
๊ทธ๋ฌ๋ ๋์ผํ ์ด๋ฏธ์ง๋ฅผ ์์ ์ ์ผ๋ก ์์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ CPU์์ ํ์ดํ๋ผ์ธ์ ์คํํ๋์ง GPU์์ ์คํํ๋์ง์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
|
|
|
|
### CPU
|
|
|
|
CPU์์ ์ฌํ ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ค๋ฉด, PyTorch [Generator](https://pytorch.org/docs/stable/generated/torch.randn.html)๋ก seed๋ฅผ ๊ณ ์ ํฉ๋๋ค:
|
|
|
|
```python
|
|
import torch
|
|
from diffusers import DDIMPipeline
|
|
import numpy as np
|
|
|
|
model_id = "google/ddpm-cifar10-32"
|
|
|
|
# ๋ชจ๋ธ๊ณผ ์ค์ผ์ค๋ฌ ๋ถ๋ฌ์ค๊ธฐ
|
|
ddim = DDIMPipeline.from_pretrained(model_id)
|
|
|
|
# ์ฌํ์ฑ์ ์ํด generator ๋ง๋ค๊ธฐ
|
|
generator = torch.Generator(device="cpu").manual_seed(0)
|
|
|
|
# ๋ ๊ฐ์ ๋จ๊ณ์ ๋ํด์ ํ์ดํ๋ผ์ธ์ ์คํํ๊ณ numpy tensor๋ก ๊ฐ์ ๋ฐํํ๊ธฐ
|
|
image = ddim(num_inference_steps=2, output_type="np", generator=generator).images
|
|
print(np.abs(image).sum())
|
|
```
|
|
|
|
์ด์ ์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด seed๋ฅผ ๊ฐ์ง `Generator` ๊ฐ์ฒด๊ฐ ํ์ดํ๋ผ์ธ์ ๋ชจ๋ ๋๋ค ํจ์์ ์ ๋ฌ๋๋ฏ๋ก ํญ์ `1491.1711` ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
|
|
|
|
ํน์ ํ๋์จ์ด ๋ฐ PyTorch ๋ฒ์ ์์ ์ด ์ฝ๋ ์์ ๋ฅผ ์คํํ๋ฉด ๋์ผํ์ง๋ ์๋๋ผ๋ ์ ์ฌํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
|
|
|
|
<Tip>
|
|
|
|
๐ก ์ฒ์์๋ ์๋๋ฅผ ๋ํ๋ด๋ ์ ์๊ฐ ๋์ ์ `Generator` ๊ฐ์ฒด๋ฅผ ํ์ดํ๋ผ์ธ์ ์ ๋ฌํ๋ ๊ฒ์ด ์ฝ๊ฐ ๋น์ง๊ด์ ์ผ ์ ์์ง๋ง,
|
|
`Generator`๋ ์์ฐจ์ ์ผ๋ก ์ฌ๋ฌ ํ์ดํ๋ผ์ธ์ ์ ๋ฌ๋ ์ ์๋ \๋๋ค์ํ\์ด๊ธฐ ๋๋ฌธ์ PyTorch์์ ํ๋ฅ ๋ก ์ ๋ชจ๋ธ์ ๋ค๋ฃฐ ๋ ๊ถ์ฅ๋๋ ์ค๊ณ์
๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
### GPU
|
|
|
|
์๋ฅผ ๋ค๋ฉด, GPU ์์์ ๊ฐ์ ์ฝ๋ ์์๋ฅผ ์คํํ๋ฉด:
|
|
|
|
```python
|
|
import torch
|
|
from diffusers import DDIMPipeline
|
|
import numpy as np
|
|
|
|
model_id = "google/ddpm-cifar10-32"
|
|
|
|
# ๋ชจ๋ธ๊ณผ ์ค์ผ์ค๋ฌ ๋ถ๋ฌ์ค๊ธฐ
|
|
ddim = DDIMPipeline.from_pretrained(model_id)
|
|
ddim.to("cuda")
|
|
|
|
# ์ฌํ์ฑ์ ์ํ generator ๋ง๋ค๊ธฐ
|
|
generator = torch.Generator(device="cuda").manual_seed(0)
|
|
|
|
# ๋ ๊ฐ์ ๋จ๊ณ์ ๋ํด์ ํ์ดํ๋ผ์ธ์ ์คํํ๊ณ numpy tensor๋ก ๊ฐ์ ๋ฐํํ๊ธฐ
|
|
image = ddim(num_inference_steps=2, output_type="np", generator=generator).images
|
|
print(np.abs(image).sum())
|
|
```
|
|
|
|
GPU๊ฐ CPU์ ๋ค๋ฅธ ๋์ ์์ฑ๊ธฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋์ผํ ์๋๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ๊ฒฐ๊ณผ๊ฐ ๊ฐ์ง ์์ต๋๋ค.
|
|
|
|
์ด ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ ์ํด ๐งจ Diffusers๋ CPU์ ์์์ ๋
ธ์ด์ฆ๋ฅผ ์์ฑํ ๋ค์ ํ์์ ๋ฐ๋ผ ํ
์๋ฅผ GPU๋ก ์ด๋์ํค๋
|
|
[randn_tensor()](https://huggingface.co/docs/diffusers/v0.18.0/en/api/utilities#diffusers.utils.randn_tensor)๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
|
|
`randn_tensor` ๊ธฐ๋ฅ์ ํ์ดํ๋ผ์ธ ๋ด๋ถ ์ด๋์์๋ ์ฌ์ฉ๋๋ฏ๋ก ํ์ดํ๋ผ์ธ์ด GPU์์ ์คํ๋๋๋ผ๋ **ํญ์** CPU `Generator`๋ฅผ ํต๊ณผํ ์ ์์ต๋๋ค.
|
|
|
|
์ด์ ๊ฒฐ๊ณผ์ ํจ์ฌ ๋ ๋ค๊ฐ์์ต๋๋ค!
|
|
|
|
```python
|
|
import torch
|
|
from diffusers import DDIMPipeline
|
|
import numpy as np
|
|
|
|
model_id = "google/ddpm-cifar10-32"
|
|
|
|
# ๋ชจ๋ธ๊ณผ ์ค์ผ์ค๋ฌ ๋ถ๋ฌ์ค๊ธฐ
|
|
ddim = DDIMPipeline.from_pretrained(model_id)
|
|
ddim.to("cuda")
|
|
|
|
#์ฌํ์ฑ์ ์ํ generator ๋ง๋ค๊ธฐ (GPU์ ์ฌ๋ฆฌ์ง ์๋๋ก ์กฐ์ฌํ๋ค!)
|
|
generator = torch.manual_seed(0)
|
|
|
|
# ๋ ๊ฐ์ ๋จ๊ณ์ ๋ํด์ ํ์ดํ๋ผ์ธ์ ์คํํ๊ณ numpy tensor๋ก ๊ฐ์ ๋ฐํํ๊ธฐ
|
|
image = ddim(num_inference_steps=2, output_type="np", generator=generator).images
|
|
print(np.abs(image).sum())
|
|
```
|
|
|
|
<Tip>
|
|
|
|
๐ก ์ฌํ์ฑ์ด ์ค์ํ ๊ฒฝ์ฐ์๋ ํญ์ CPU generator๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
|
|
์ฑ๋ฅ ์์ค์ ๋ฌด์ํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฉฐ ํ์ดํ๋ผ์ธ์ด GPU์์ ์คํ๋์์ ๋๋ณด๋ค ํจ์ฌ ๋ ๋น์ทํ ๊ฐ์ ์์ฑํ ์ ์์ต๋๋ค.
|
|
|
|
</Tip>
|
|
|
|
๋ง์ง๋ง์ผ๋ก [UnCLIPPipeline](https://huggingface.co/docs/diffusers/v0.18.0/en/api/pipelines/unclip#diffusers.UnCLIPPipeline)๊ณผ ๊ฐ์
|
|
๋ ๋ณต์กํ ํ์ดํ๋ผ์ธ์ ๊ฒฝ์ฐ, ์ด๋ค์ ์ข
์ข
์ ๋ฐ ์ค์ฐจ ์ ํ์ ๊ทน๋๋ก ์ทจ์ฝํฉ๋๋ค.
|
|
๋ค๋ฅธ GPU ํ๋์จ์ด ๋๋ PyTorch ๋ฒ์ ์์ ์ ์ฌํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ํ์ง ๋ง์ธ์.
|
|
์ด ๊ฒฝ์ฐ ์์ ํ ์ฌํ์ฑ์ ์ํด ์์ ํ ๋์ผํ ํ๋์จ์ด ๋ฐ PyTorch ๋ฒ์ ์ ์คํํด์ผ ํฉ๋๋ค.
|
|
|
|
## ๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ
|
|
|
|
๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ฌํ ๊ฐ๋ฅํ ํ์ดํ๋ผ์ธ์ ์์ฑํ๋๋ก PyTorch๋ฅผ ๊ตฌ์ฑํ ์๋ ์์ต๋๋ค.
|
|
๊ทธ๋ฌ๋ ๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ์ ๋น๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ๋ณด๋ค ๋๋ฆฌ๊ณ ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
|
|
ํ์ง๋ง ์ฌํ์ฑ์ด ์ค์ํ๋ค๋ฉด, ์ด๊ฒ์ด ์ต์ ์ ๋ฐฉ๋ฒ์
๋๋ค!
|
|
|
|
๋ ์ด์์ CUDA ์คํธ๋ฆผ์์ ์์
์ด ์์๋ ๋ ๋น๊ฒฐ์ ๋ก ์ ๋์์ด ๋ฐ์ํฉ๋๋ค.
|
|
์ด ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ค๋ฉด ํ๊ฒฝ ๋ณ์ [CUBLAS_WORKSPACE_CONFIG](https://docs.nvidia.com/cuda/cublas/index.html#results-reproducibility)๋ฅผ `:16:8`๋ก ์ค์ ํด์
|
|
๋ฐํ์ ์ค์ ์ค์ง ํ๋์ ๋ฒํผ ํฌ๋ฆฌ๋ง ์ฌ์ฉํ๋๋ก ์ค์ ํฉ๋๋ค.
|
|
|
|
PyTorch๋ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฅ ๋น ๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ธฐ ์ํด ์ฌ๋ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋ฒค์น๋งํนํฉ๋๋ค.
|
|
ํ์ง๋ง ์ฌํ์ฑ์ ์ํ๋ ๊ฒฝ์ฐ, ๋ฒค์น๋งํฌ๊ฐ ๋งค ์๊ฐ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
|
|
๋ง์ง๋ง์ผ๋ก, [torch.use_deterministic_algorithms](https://pytorch.org/docs/stable/generated/torch.use_deterministic_algorithms.html)์
|
|
`True`๋ฅผ ํต๊ณผ์์ผ ๊ฒฐ์ ๋ก ์ ์๊ณ ๋ฆฌ์ฆ์ด ํ์ฑํ ๋๋๋ก ํฉ๋๋ค.
|
|
|
|
```py
|
|
import os
|
|
|
|
os.environ["CUBLAS_WORKSPACE_CONFIG"] = ":16:8"
|
|
|
|
torch.backends.cudnn.benchmark = False
|
|
torch.use_deterministic_algorithms(True)
|
|
```
|
|
|
|
์ด์ ๋์ผํ ํ์ดํ๋ผ์ธ์ ๋๋ฒ ์คํํ๋ฉด ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
|
|
|
|
```py
|
|
import torch
|
|
from diffusers import DDIMScheduler, StableDiffusionPipeline
|
|
import numpy as np
|
|
|
|
model_id = "runwayml/stable-diffusion-v1-5"
|
|
pipe = StableDiffusionPipeline.from_pretrained(model_id).to("cuda")
|
|
pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
|
|
g = torch.Generator(device="cuda")
|
|
|
|
prompt = "A bear is playing a guitar on Times Square"
|
|
|
|
g.manual_seed(0)
|
|
result1 = pipe(prompt=prompt, num_inference_steps=50, generator=g, output_type="latent").images
|
|
|
|
g.manual_seed(0)
|
|
result2 = pipe(prompt=prompt, num_inference_steps=50, generator=g, output_type="latent").images
|
|
|
|
print("L_inf dist = ", abs(result1 - result2).max())
|
|
"L_inf dist = tensor(0., device='cuda:0')"
|
|
```
|