Diffusers documentation

커뮤니티 파이프라인에 기여하는 방법

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.31.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

커뮤니티 파이프라인에 기여하는 방법

💡 모든 사람이 속도 저하 없이 쉽게 작업을 공유할 수 있도록 커뮤니티 파이프라인을 추가하는 이유에 대한 자세한 내용은 GitHub 이슈 #841를 참조하세요.

커뮤니티 파이프라인을 사용하면 DiffusionPipeline 위에 원하는 추가 기능을 추가할 수 있습니다. DiffusionPipeline 위에 구축할 때의 가장 큰 장점은 누구나 인수를 하나만 추가하면 파이프라인을 로드하고 사용할 수 있어 커뮤니티가 매우 쉽게 접근할 수 있다는 것입니다.

이번 가이드에서는 커뮤니티 파이프라인을 생성하는 방법과 작동 원리를 설명합니다. 간단하게 설명하기 위해 UNet이 단일 forward pass를 수행하고 스케줄러를 한 번 호출하는 “one-step” 파이프라인을 만들겠습니다.

파이프라인 초기화

커뮤니티 파이프라인을 위한 one_step_unet.py 파일을 생성하는 것으로 시작합니다. 이 파일에서, Hub에서 모델 가중치와 스케줄러 구성을 로드할 수 있도록 DiffusionPipeline을 상속하는 파이프라인 클래스를 생성합니다. one-step 파이프라인에는 UNet과 스케줄러가 필요하므로 이를 __init__ 함수에 인수로 추가해야합니다:

from diffusers import DiffusionPipeline
import torch


class UnetSchedulerOneForwardPipeline(DiffusionPipeline):
    def __init__(self, unet, scheduler):
        super().__init__()

파이프라인과 그 구성요소(unet and scheduler)를 save_pretrained()으로 저장할 수 있도록 하려면 register_modules 함수에 추가하세요:

  from diffusers import DiffusionPipeline
  import torch

  class UnetSchedulerOneForwardPipeline(DiffusionPipeline):
      def __init__(self, unet, scheduler):
          super().__init__()

+         self.register_modules(unet=unet, scheduler=scheduler)

이제 ‘초기화’ 단계가 완료되었으니 forward pass로 이동할 수 있습니다! 🔥

Forward pass 정의

Forward pass 에서는(__call__로 정의하는 것이 좋습니다) 원하는 기능을 추가할 수 있는 완전한 창작 자유가 있습니다. 우리의 놀라운 one-step 파이프라인의 경우, 임의의 이미지를 생성하고 timestep=1을 설정하여 unetscheduler를 한 번만 호출합니다:

  from diffusers import DiffusionPipeline
  import torch


  class UnetSchedulerOneForwardPipeline(DiffusionPipeline):
      def __init__(self, unet, scheduler):
          super().__init__()

          self.register_modules(unet=unet, scheduler=scheduler)

+     def __call__(self):
+         image = torch.randn(
+             (1, self.unet.config.in_channels, self.unet.config.sample_size, self.unet.config.sample_size),
+         )
+         timestep = 1

+         model_output = self.unet(image, timestep).sample
+         scheduler_output = self.scheduler.step(model_output, timestep, image).prev_sample

+         return scheduler_output

끝났습니다! 🚀 이제 이 파이프라인에 unetscheduler를 전달하여 실행할 수 있습니다:

from diffusers import DDPMScheduler, UNet2DModel

scheduler = DDPMScheduler()
unet = UNet2DModel()

pipeline = UnetSchedulerOneForwardPipeline(unet=unet, scheduler=scheduler)

output = pipeline()

하지만 파이프라인 구조가 동일한 경우 기존 가중치를 파이프라인에 로드할 수 있다는 장점이 있습니다. 예를 들어 one-step 파이프라인에 google/ddpm-cifar10-32 가중치를 로드할 수 있습니다:

pipeline = UnetSchedulerOneForwardPipeline.from_pretrained("google/ddpm-cifar10-32")

output = pipeline()

파이프라인 공유

🧨Diffusers 리포지토리에서 Pull Request를 열어 examples/community 하위 폴더에 one_step_unet.py의 멋진 파이프라인을 추가하세요.

병합이 되면, diffusers >= 0.4.0이 설치된 사용자라면 누구나 custom_pipeline 인수에 지정하여 이 파이프라인을 마술처럼 🪄 사용할 수 있습니다:

from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained("google/ddpm-cifar10-32", custom_pipeline="one_step_unet")
pipe()

커뮤니티 파이프라인을 공유하는 또 다른 방법은 Hub 에서 선호하는 모델 리포지토리에 직접 one_step_unet.py 파일을 업로드하는 것입니다. one_step_unet.py 파일을 지정하는 대신 모델 저장소 id를 custom_pipeline 인수에 전달하세요:

from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained("google/ddpm-cifar10-32", custom_pipeline="stevhliu/one_step_unet")

다음 표에서 두 가지 공유 워크플로우를 비교하여 자신에게 가장 적합한 옵션을 결정하는 데 도움이 되는 정보를 확인하세요:

GitHub 커뮤니티 파이프라인 HF Hub 커뮤니티 파이프라인
사용법 동일 동일
리뷰 과정 병합하기 전에 GitHub에서 Pull Request를 열고 Diffusers 팀의 검토 과정을 거칩니다. 속도가 느릴 수 있습니다. 검토 없이 Hub 저장소에 바로 업로드합니다. 가장 빠른 워크플로우 입니다.
가시성 공식 Diffusers 저장소 및 문서에 포함되어 있습니다. HF 허브 프로필에 포함되며 가시성을 확보하기 위해 자신의 사용량/프로모션에 의존합니다.

💡 커뮤니티 파이프라인 파일에 원하는 패키지를 사용할 수 있습니다. 사용자가 패키지를 설치하기만 하면 모든 것이 정상적으로 작동합니다. 파이프라인이 자동으로 감지되므로 DiffusionPipeline에서 상속하는 파이프라인 클래스가 하나만 있는지 확인하세요.

커뮤니티 파이프라인은 어떻게 작동하나요?

커뮤니티 파이프라인은 DiffusionPipeline을 상속하는 클래스입니다:

  • custom_pipeline 인수로 로드할 수 있습니다.
  • 모델 가중치 및 스케줄러 구성은 pretrained_model_name_or_path에서 로드됩니다.
  • 커뮤니티 파이프라인에서 기능을 구현하는 코드는 pipeline.py 파일에 정의되어 있습니다.

공식 저장소에서 모든 파이프라인 구성 요소 가중치를 로드할 수 없는 경우가 있습니다. 이 경우 다른 구성 요소는 파이프라인에 직접 전달해야 합니다:

from diffusers import DiffusionPipeline
from transformers import CLIPFeatureExtractor, CLIPModel

model_id = "CompVis/stable-diffusion-v1-4"
clip_model_id = "laion/CLIP-ViT-B-32-laion2B-s34B-b79K"

feature_extractor = CLIPFeatureExtractor.from_pretrained(clip_model_id)
clip_model = CLIPModel.from_pretrained(clip_model_id, torch_dtype=torch.float16)

pipeline = DiffusionPipeline.from_pretrained(
    model_id,
    custom_pipeline="clip_guided_stable_diffusion",
    clip_model=clip_model,
    feature_extractor=feature_extractor,
    scheduler=scheduler,
    torch_dtype=torch.float16,
)

커뮤니티 파이프라인의 마법은 다음 코드에 담겨 있습니다. 이 코드를 통해 커뮤니티 파이프라인을 GitHub 또는 Hub에서 로드할 수 있으며, 모든 🧨 Diffusers 패키지에서 사용할 수 있습니다.

# 2. 파이프라인 클래스를 로드합니다. 사용자 지정 모듈을 사용하는 경우 Hub에서 로드합니다
# 명시적 클래스에서 로드하는 경우, 이를 사용해 보겠습니다.
if custom_pipeline is not None:
    pipeline_class = get_class_from_dynamic_module(
        custom_pipeline, module_file=CUSTOM_PIPELINE_FILE_NAME, cache_dir=custom_pipeline
    )
elif cls != DiffusionPipeline:
    pipeline_class = cls
else:
    diffusers_module = importlib.import_module(cls.__module__.split(".")[0])
    pipeline_class = getattr(diffusers_module, config_dict["_class_name"])
< > Update on GitHub