Spaces:
Runtime error
Runtime error
<!--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 νμ΄νλΌμΈμ diffusion λͺ¨λΈ, μ€μΌμ€λ¬ λ±μ μ»΄ν¬λνΈλ€λ‘ ꡬμ±λ©λλ€. κ·Έλ¦¬κ³ νμ΄νλΌμΈ μμ μΌλΆ μ»΄ν¬λνΈλ₯Ό λ€λ₯Έ μ»΄ν¬λνΈλ‘ κ΅μ²΄νλ μμ 컀μ€ν°λ§μ΄μ§ μμ κ°λ₯ν©λλ€. μ΄μ κ°μ μ»΄ν¬λνΈ μ»€μ€ν°λ§μ΄μ§μ κ°μ₯ λνμ μΈ μμκ° λ°λ‘ [μ€μΌμ€λ¬](../api/schedulers/overview.md)λ₯Ό κ΅μ²΄νλ κ²μ λλ€. | |
μ€μΌμ₯΄λ¬λ λ€μκ³Ό κ°μ΄ diffusion μμ€ν μ μ λ°μ μΈ λλ Έμ΄μ§ νλ‘μΈμ€λ₯Ό μ μν©λλ€. | |
- λλ Έμ΄μ§ μ€ν μ μΌλ§λ κ°μ Έκ°μΌ ν κΉ? | |
- νλ₯ μ μΌλ‘(stochastic) νΉμ νμ μ μΌλ‘(deterministic)? | |
- λλ Έμ΄μ§ λ μνμ μ°Ύμλ΄κΈ° μν΄ μ΄λ€ μκ³ λ¦¬μ¦μ μ¬μ©ν΄μΌ ν κΉ? | |
μ΄λ¬ν νλ‘μΈμ€λ λ€μ λν΄νκ³ , λλ Έμ΄μ§ μλμ λλ Έμ΄μ§ νλ¦¬ν° μ¬μ΄μ νΈλ μ΄λ μ€νλ₯Ό μ μν΄μΌ νλ λ¬Έμ κ° λ μ μμ΅λλ€. μ£Όμ΄μ§ νμ΄νλΌμΈμ μ΄λ€ μ€μΌμ€λ¬κ° κ°μ₯ μ ν©νμ§λ₯Ό μ λμ μΌλ‘ νλ¨νλ κ²μ λ§€μ° μ΄λ €μ΄ μΌμ λλ€. μ΄λ‘ μΈν΄ μΌλ¨ ν΄λΉ μ€μΌμ€λ¬λ₯Ό μ§μ μ¬μ©νμ¬, μμ±λλ μ΄λ―Έμ§λ₯Ό μ§μ λμΌλ‘ 보며, μ μ±μ μΌλ‘ μ±λ₯μ νλ¨ν΄λ³΄λ κ²μ΄ μΆμ²λκ³€ ν©λλ€. | |
## νμ΄νλΌμΈ λΆλ¬μ€κΈ° | |
λ¨Όμ μ€ν μ΄λΈ diffusion νμ΄νλΌμΈμ λΆλ¬μ€λλ‘ ν΄λ³΄κ² μ΅λλ€. λ¬Όλ‘ μ€ν μ΄λΈ diffusionμ μ¬μ©νκΈ° μν΄μλ, νκΉ νμ΄μ€ νλΈμ λ±λ‘λ μ¬μ©μμ¬μΌ νλ©°, κ΄λ ¨ [λΌμ΄μΌμ€](https://huggingface.co/runwayml/stable-diffusion-v1-5)μ λμν΄μΌ νλ€λ μ μ μμ§ λ§μμ£ΌμΈμ. | |
*μμ μ£Ό: λ€λ§, νμ¬ μ κ·λ‘ μμ±ν νκΉ νμ΄μ€ κ³μ μ λν΄μλ λΌμ΄μΌμ€ λμλ₯Ό μꡬνμ§ μλ κ²μΌλ‘ 보μ λλ€!* | |
```python | |
from huggingface_hub import login | |
from diffusers import DiffusionPipeline | |
import torch | |
# first we need to login with our access token | |
login() | |
# Now we can download the pipeline | |
pipeline = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16) | |
``` | |
λ€μμΌλ‘, GPUλ‘ μ΄λν©λλ€. | |
```python | |
pipeline.to("cuda") | |
``` | |
## μ€μΌμ€λ¬ μ‘μΈμ€ | |
μ€μΌμ€λ¬λ μΈμ λ νμ΄νλΌμΈμ μ»΄ν¬λνΈλ‘μ μ‘΄μ¬νλ©°, μΌλ°μ μΌλ‘ νμ΄νλΌμΈ μΈμ€ν΄μ€ λ΄μ `scheduler`λΌλ μ΄λ¦μ μμ±(property)μΌλ‘ μ μλμ΄ μμ΅λλ€. | |
```python | |
pipeline.scheduler | |
``` | |
**Output**: | |
``` | |
PNDMScheduler { | |
"_class_name": "PNDMScheduler", | |
"_diffusers_version": "0.8.0.dev0", | |
"beta_end": 0.012, | |
"beta_schedule": "scaled_linear", | |
"beta_start": 0.00085, | |
"clip_sample": false, | |
"num_train_timesteps": 1000, | |
"set_alpha_to_one": false, | |
"skip_prk_steps": true, | |
"steps_offset": 1, | |
"trained_betas": null | |
} | |
``` | |
μΆλ ₯ κ²°κ³Όλ₯Ό ν΅ν΄, μ°λ¦¬λ ν΄λΉ μ€μΌμ€λ¬κ° [`PNDMScheduler`]μ μΈμ€ν΄μ€λΌλ κ²μ μ μ μμ΅λλ€. μ΄μ [`PNDMScheduler`]μ λ€λ₯Έ μ€μΌμ€λ¬λ€μ μ±λ₯μ λΉκ΅ν΄λ³΄λλ‘ νκ² μ΅λλ€. λ¨Όμ ν μ€νΈμ μ¬μ©ν ν둬ννΈλ₯Ό λ€μκ³Ό κ°μ΄ μ μν΄λ³΄λλ‘ νκ² μ΅λλ€. | |
```python | |
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition." | |
``` | |
λ€μμΌλ‘ μ μ¬ν μ΄λ―Έμ§ μμ±μ 보μ₯νκΈ° μν΄μ, λ€μκ³Ό κ°μ΄ λλ€μλλ₯Ό κ³ μ ν΄μ£Όλλ‘ νκ² μ΅λλ€. | |
```python | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_pndm.png" width="400"/> | |
<br> | |
</p> | |
## μ€μΌμ€λ¬ κ΅μ²΄νκΈ° | |
λ€μμΌλ‘ νμ΄νλΌμΈμ μ€μΌμ€λ¬λ₯Ό λ€λ₯Έ μ€μΌμ€λ¬λ‘ κ΅μ²΄νλ λ°©λ²μ λν΄ μμλ³΄κ² μ΅λλ€. λͺ¨λ μ€μΌμ€λ¬λ [`SchedulerMixin.compatibles`]λΌλ μμ±(property)μ κ°κ³ μμ΅λλ€. ν΄λΉ μμ±μ **νΈν κ°λ₯ν** μ€μΌμ€λ¬λ€μ λν μ 보λ₯Ό λ΄κ³ μμ΅λλ€. | |
```python | |
pipeline.scheduler.compatibles | |
``` | |
**Output**: | |
``` | |
[diffusers.schedulers.scheduling_lms_discrete.LMSDiscreteScheduler, | |
diffusers.schedulers.scheduling_ddim.DDIMScheduler, | |
diffusers.schedulers.scheduling_dpmsolver_multistep.DPMSolverMultistepScheduler, | |
diffusers.schedulers.scheduling_euler_discrete.EulerDiscreteScheduler, | |
diffusers.schedulers.scheduling_pndm.PNDMScheduler, | |
diffusers.schedulers.scheduling_ddpm.DDPMScheduler, | |
diffusers.schedulers.scheduling_euler_ancestral_discrete.EulerAncestralDiscreteScheduler] | |
``` | |
νΈνλλ μ€μΌμ€λ¬λ€μ μ΄ν΄λ³΄λ©΄ μλμ κ°μ΅λλ€. | |
- [`LMSDiscreteScheduler`], | |
- [`DDIMScheduler`], | |
- [`DPMSolverMultistepScheduler`], | |
- [`EulerDiscreteScheduler`], | |
- [`PNDMScheduler`], | |
- [`DDPMScheduler`], | |
- [`EulerAncestralDiscreteScheduler`]. | |
μμ μ μνλ ν둬ννΈλ₯Ό μ¬μ©ν΄μ κ°κ°μ μ€μΌμ€λ¬λ€μ λΉκ΅ν΄λ³΄λλ‘ νκ² μ΅λλ€. | |
λ¨Όμ νμ΄νλΌμΈ μμ μ€μΌμ€λ¬λ₯Ό λ°κΎΈκΈ° μν΄ [`ConfigMixin.config`] μμ±κ³Ό [`ConfigMixin.from_config`] λ©μλλ₯Ό νμ©ν΄λ³΄λ €κ³ ν©λλ€. | |
```python | |
pipeline.scheduler.config | |
``` | |
**Output**: | |
``` | |
FrozenDict([('num_train_timesteps', 1000), | |
('beta_start', 0.00085), | |
('beta_end', 0.012), | |
('beta_schedule', 'scaled_linear'), | |
('trained_betas', None), | |
('skip_prk_steps', True), | |
('set_alpha_to_one', False), | |
('steps_offset', 1), | |
('_class_name', 'PNDMScheduler'), | |
('_diffusers_version', '0.8.0.dev0'), | |
('clip_sample', False)]) | |
``` | |
κΈ°μ‘΄ μ€μΌμ€λ¬μ configλ₯Ό νΈν κ°λ₯ν λ€λ₯Έ μ€μΌμ€λ¬μ μ΄μνλ κ² μμ κ°λ₯ν©λλ€. | |
λ€μ μμλ κΈ°μ‘΄ μ€μΌμ€λ¬(`pipeline.scheduler`)λ₯Ό λ€λ₯Έ μ’ λ₯μ μ€μΌμ€λ¬(`DDIMScheduler`)λ‘ λ°κΎΈλ μ½λμ λλ€. κΈ°μ‘΄ μ€μΌμ€λ¬κ° κ°κ³ μλ configλ₯Ό `.from_config` λ©μλμ μΈμλ‘ μ λ¬νλ κ²μ νμΈν μ μμ΅λλ€. | |
```python | |
from diffusers import DDIMScheduler | |
pipeline.scheduler = DDIMScheduler.from_config(pipeline.scheduler.config) | |
``` | |
μ΄μ νμ΄νλΌμΈμ μ€νν΄μ λ μ€μΌμ€λ¬ μ¬μ΄μ μμ±λ μ΄λ―Έμ§μ ν리ν°λ₯Ό λΉκ΅ν΄λ΄ μλ€. | |
```python | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_ddim.png" width="400"/> | |
<br> | |
</p> | |
## μ€μΌμ€λ¬λ€ λΉκ΅ν΄λ³΄κΈ° | |
μ§κΈκΉμ§λ [`PNDMScheduler`]μ [`DDIMScheduler`] μ€μΌμ€λ¬λ₯Ό μ€νν΄λ³΄μμ΅λλ€. μμ§ λΉκ΅ν΄λ³Ό μ€μΌμ€λ¬λ€μ΄ λ λ§μ΄ λ¨μμμΌλ κ³μ λΉκ΅ν΄λ³΄λλ‘ νκ² μ΅λλ€. | |
[`LMSDiscreteScheduler`]μ μΌλ°μ μΌλ‘ λ μ’μ κ²°κ³Όλ₯Ό 보μ¬μ€λλ€. | |
```python | |
from diffusers import LMSDiscreteScheduler | |
pipeline.scheduler = LMSDiscreteScheduler.from_config(pipeline.scheduler.config) | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_lms.png" width="400"/> | |
<br> | |
</p> | |
[`EulerDiscreteScheduler`]μ [`EulerAncestralDiscreteScheduler`] κ³ μ 30λ²μ inference stepλ§μΌλ‘λ λμ ν리ν°μ μ΄λ―Έμ§λ₯Ό μμ±νλ κ²μ μ μ μμ΅λλ€. | |
```python | |
from diffusers import EulerDiscreteScheduler | |
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config) | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator, num_inference_steps=30).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_euler_discrete.png" width="400"/> | |
<br> | |
</p> | |
```python | |
from diffusers import EulerAncestralDiscreteScheduler | |
pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config) | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator, num_inference_steps=30).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_euler_ancestral.png" width="400"/> | |
<br> | |
</p> | |
μ§κΈ μ΄ λ¬Έμλ₯Ό μμ±νλ νμμ κΈ°μ€μμ , [`DPMSolverMultistepScheduler`]κ° μκ° λλΉ κ°μ₯ μ’μ νμ§μ μ΄λ―Έμ§λ₯Ό μμ±νλ κ² κ°μ΅λλ€. 20λ² μ λμ μ€ν λ§μΌλ‘λ μ€νλ μ μμ΅λλ€. | |
```python | |
from diffusers import DPMSolverMultistepScheduler | |
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config) | |
generator = torch.Generator(device="cuda").manual_seed(8) | |
image = pipeline(prompt, generator=generator, num_inference_steps=20).images[0] | |
image | |
``` | |
<p align="center"> | |
<br> | |
<img src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_dpm.png" width="400"/> | |
<br> | |
</p> | |
보μλ€μνΌ μμ±λ μ΄λ―Έμ§λ€μ λ§€μ° λΉμ·νκ³ , λΉμ·ν ν리ν°λ₯Ό 보μ΄λ κ² κ°μ΅λλ€. μ€μ λ‘ μ΄λ€ μ€μΌμ€λ¬λ₯Ό μ νν κ²μΈκ°λ μ’ μ’ νΉμ μ΄μ© μ¬λ‘μ κΈ°λ°ν΄μ κ²°μ λκ³€ ν©λλ€. κ²°κ΅ μ¬λ¬ μ’ λ₯μ μ€μΌμ€λ¬λ₯Ό μ§μ μ€νμμΌλ³΄κ³ λμΌλ‘ μ§μ λΉκ΅ν΄μ νλ¨νλ κ² μ’μ μ νμΌ κ² κ°μ΅λλ€. | |
## Flaxμμ μ€μΌμ€λ¬ κ΅μ²΄νκΈ° | |
JAX/Flax μ¬μ©μμΈ κ²½μ° κΈ°λ³Έ νμ΄νλΌμΈ μ€μΌμ€λ¬λ₯Ό λ³κ²½ν μλ μμ΅λλ€. λ€μμ Flax Stable Diffusion νμ΄νλΌμΈκ³Ό μ΄κ³ μ [DDPM-Solver++ μ€μΌμ€λ¬λ₯Ό](../api/schedulers/multistep_dpm_solver) μ¬μ©νμ¬ μΆλ‘ μ μ€ννλ λ°©λ²μ λν μμμ λλ€ . | |
```Python | |
import jax | |
import numpy as np | |
from flax.jax_utils import replicate | |
from flax.training.common_utils import shard | |
from diffusers import FlaxStableDiffusionPipeline, FlaxDPMSolverMultistepScheduler | |
model_id = "runwayml/stable-diffusion-v1-5" | |
scheduler, scheduler_state = FlaxDPMSolverMultistepScheduler.from_pretrained( | |
model_id, | |
subfolder="scheduler" | |
) | |
pipeline, params = FlaxStableDiffusionPipeline.from_pretrained( | |
model_id, | |
scheduler=scheduler, | |
revision="bf16", | |
dtype=jax.numpy.bfloat16, | |
) | |
params["scheduler"] = scheduler_state | |
# Generate 1 image per parallel device (8 on TPUv2-8 or TPUv3-8) | |
prompt = "a photo of an astronaut riding a horse on mars" | |
num_samples = jax.device_count() | |
prompt_ids = pipeline.prepare_inputs([prompt] * num_samples) | |
prng_seed = jax.random.PRNGKey(0) | |
num_inference_steps = 25 | |
# shard inputs and rng | |
params = replicate(params) | |
prng_seed = jax.random.split(prng_seed, jax.device_count()) | |
prompt_ids = shard(prompt_ids) | |
images = pipeline(prompt_ids, params, prng_seed, num_inference_steps, jit=True).images | |
images = pipeline.numpy_to_pil(np.asarray(images.reshape((num_samples,) + images.shape[-3:]))) | |
``` | |
<Tip warning={true}> | |
λ€μ Flax μ€μΌμ€λ¬λ *μμ§* Flax Stable Diffusion νμ΄νλΌμΈκ³Ό νΈνλμ§ μμ΅λλ€. | |
- `FlaxLMSDiscreteScheduler` | |
- `FlaxDDPMScheduler` | |
</Tip> | |