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.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

철학

🧨 Diffusers는 다양한 모달리티에 걸쳐 최첨단 사전 학습된 확산 모델을 제공합니다. 그 목적은 추론과 학습 모두를 위한 모듈형 도구 상자로 기능하는 것입니다.

시간의 시험을 견디는 라이브러리를 구축하는 것을 목표로 하므로 API 설계를 매우 중요하게 생각합니다.

요약하자면, Diffusers는 PyTorch의 자연스러운 확장으로 설계되었습니다. 따라서 대부분의 설계 선택은 PyTorch의 설계 원칙에 기반합니다. 가장 중요한 원칙들을 살펴보겠습니다:

성능보다 사용성

  • Diffusers에는 많은 내장 성능 향상 기능이 있지만(자세한 내용은 메모리 및 속도를 참조하세요), 모델은 항상 가장 높은 정밀도와 가장 낮은 최적화로 로드됩니다. 따라서 사용자가 별도로 정의하지 않는 한, 디퓨전 파이프라인은 기본적으로 CPU에서 float32 정밀도로 인스턴스화됩니다. 이를 통해 다양한 플랫폼과 가속기에서 사용성을 보장하며, 라이브러리를 실행하기 위해 복잡한 설치가 필요하지 않습니다.
  • Diffusers는 경량 패키지를 지향하므로 필수 의존성이 매우 적지만, 성능을 향상시킬 수 있는 선택적 의존성(예: accelerate, safetensors, onnx 등)이 많습니다. 다른 패키지에 의존성으로 추가할 때 큰 부담이 없도록 라이브러리를 최대한 경량으로 유지하는 것을 목표로 합니다.
  • Diffusers는 압축된 마법 같은 코드보다 단순하고 스스로 설명 가능한 코드를 선호합니다. 이는 lambda 함수와 같은 축약된 코드 문법이나 고급 PyTorch 연산자가 종종 권장되지 않는다는 것을 의미합니다.

단순한 과 쉬운

PyTorch에서 말하듯, 명시적은 암시적보다 낫고 단순한 것은 복잡한 것보다 낫습니다. 이러한 설계 철학은 라이브러리의 여러 부분에 반영되어 있습니다:

  • PyTorch의 API를 따르며, DiffusionPipeline.to와 같은 메서드를 통해 사용자가 디바이스 관리를 처리할 수 있도록 합니다.
  • raise를 통해 간결한 오류 메시지를 표시하는 것이 오류가 있는 입력을 조용히 수정하는 것보다 권장됩니다. Diffusers는 라이브러리를 최대한 쉽게 사용할 수 있게 만드는 것보다 사용자에게 학습시키는 것을 목표로 합니다.
  • 복잡한 모델과 스케줄러 로직이 내부에서 마법처럼 처리되는 대신 외부로 노출됩니다. 스케줄러/샘플러는 디퓨전 모델과 분리되어 서로 최소한의 의존성만 갖습니다. 이로 인해 사용자는 전개된(denoising) 루프를 직접 작성해야 합니다. 그러나 이러한 분리는 디버깅을 용이하게 하고, 디노이징 프로세스를 조정하거나 디퓨전 모델 또는 스케줄러를 교체하는 데 사용자가 더 많은 제어권을 갖게 합니다.
  • 확산 파이프라인의 개별 학습된 구성 요소, 예를 들어 텍스트 인코더, unet, 변분 오토인코더는 각각 고유한 모델 클래스를 가집니다. 이로 인해 사용자는 서로 다른 모델 구성 요소 간의 상호작용을 직접 처리해야 하며, 직렬화 형식은 모델 구성 요소를 서로 다른 파일로 분리합니다. 그러나 이를 통해 디버깅과 커스터마이징이 용이해집니다. Diffusers가 확산 파이프라인의 단일 구성 요소를 분리할 수 있기 때문에 DreamBooth 또는 Textual Inversion 학습은 매우 간단합니다.

추상화 위에 구축된, 조정 가능하고 기여자 친화적인

라이브러리의 상당 부분에서 Diffusers는 Transformers 라이브러리의 중요한 설계 원칙인, 즉 서두른 추상화보다 복사-붙여넣기 코드를 선호하는 원칙을 채택합니다. 이 설계 원칙은 매우 확고한 입장을 가지고 있으며, 반복하지 마세요(DRY)와 같은 인기 있는 설계 원칙과 뚜렷한 대비를 이룹니다. 요약하자면, Transformers가 모델링 파일에 대해 그러하듯, Diffusers는 파이프라인과 스케줄러에 대해 매우 낮은 수준의 추상화와 매우 자체 완결적인 코드를 유지하는 것을 선호합니다. 함수, 긴 코드 블록, 심지어 클래스조차 여러 파일에 걸쳐 복사될 수 있으며, 처음에는 라이브러리를 유지보수하기 어렵게 만드는 나쁘고 대충 설계된 것처럼 보일 수 있습니다. 그러나 이 설계는 Transformers에서 매우 성공적이었음이 입증되었으며, 커뮤니티 주도 오픈소스 머신러닝 라이브러리에는 다음과 같은 이유로 매우 타당합니다:

  • Machine Learning은 패러다임, 모델 아키텍처, 알고리즘이 빠르게 변화하는 매우 역동적인 분야로, 따라서 장기적으로 유지되는 코드 추상화를 정의하기가 매우 어렵습니다.
  • 기계 학습 실무자들은 아이디어 발상과 연구를 위해 기존 코드를 빠르게 수정할 수 있기를 선호하며, 따라서 많은 추상화를 포함하는 코드보다 자체 완결된 코드를 선호합니다.
  • 오픈소스 라이브러리는 커뮤니티의 기여에 의존하므로, 기여하기 쉬운 라이브러리를 구축해야 합니다. 코드가 추상화될수록 의존성이 많아지고 가독성이 떨어지며, 기여하기가 어려워집니다. 핵심 기능이 깨질까 두려워 기여자가 매우 추상적인 라이브러리에 대한 기여를 중단하는 경우가 많습니다. 라이브러리에 기여할 때 다른 핵심 코드를 깨뜨릴 위험이 없다면, 잠재적인 신규 기여자에게 더 매력적일 뿐만 아니라 여러 부분을 병렬로 검토하고 기여하기도 더 쉬워집니다.

Hugging Face에서는 이러한 설계를 single-file policy라고 부르며, 이는 특정 클래스의 거의 모든 코드가 단일하고 자체 완결된 파일에 작성되어야 함을 의미합니다. 이 철학에 대해 더 자세히 알아보려면 이 블로그 게시물을 참고하세요.

Diffusers에서는 파이프라인, 스케줄러, 모델 모두에 대해 이러한 철학을 따릅니다. 일부 구형 모델은 이 관례가 정립되기 전에 작성되어 그대로 유지되며, 모든 새로운 모델 아키텍처는 자체적으로 완결된 파일에 포함되어 있습니다. 자세한 내용은 아래 Models 섹션을 참조하세요.

좋습니다. 이제 🧨 Diffusers가 왜 이런 방식으로 설계되었는지 전반적으로 이해하셨을 것입니다 🤗. 우리는 이러한 설계 원칙을 라이브러리 전반에 걸쳐 일관되게 적용하려고 노력합니다. 그럼에도 불구하고, 철학에 대한 일부 사소한 예외나 불운한 설계 선택이 있을 수 있습니다. 설계에 대한 피드백이 있으시다면, GitHub에서 직접 말씀해 주시면 좋겠습니다 ❤️.

상세한 설계 철학

이제 설계 철학의 세부 사항으로 넘어가 보겠습니다. Diffusers는 모델과 스케줄러를 실행 가능한 워크플로로 구성하는 두 가지 방법을 제공합니다. 하나는 파이프라인 클래스마다 하나의 작업을 수행하는 단일 구조의 표준 파이프라인이고, 다른 하나는 구성 가능하고 블록 기반인 Modular Diffusers입니다. 아래 섹션에서는 파이프라인, 모듈형 파이프라인, 모델, 스케줄러를 순서대로 다룹니다.

파이프라인

Pipelines, 표준형이든 모듈형이든 추론(inference) 전용으로 설계되었습니다. 사용이 간편하도록 만들어졌으며(따라서 Simple over easy 원칙을 100% 따르지는 않습니다): 가독성이 높고, 스스로 설명이 되며, 쉽게 조정할 수 있고, models와 schedulers를 사용하는 방법의 예시로 보는 것이 가장 좋습니다. 모든 기능이 완비되어 있지 않습니다. Diffusers 위에 기능이 완비된 사용자 인터페이스를 구축하려면 Modular Diffusers를 사용하세요.

다음과 같은 설계 원칙을 따릅니다:

  • Pipelines follow the single-file policy. All pipelines can be found in individual directories under src/diffusers/pipelines. One pipeline folder corresponds to one diffusion paper/project/release. Multiple pipeline files can be gathered in one pipeline folder, as it’s done for src/diffusers/pipelines/stable-diffusion. If pipelines share similar functionality, one can make use of the # Copied from mechanism.
  • 모든 Pipelines는 DiffusionPipeline에서 상속됩니다.
  • 모든 파이프라인은 model_index.json 파일에 문서화된 서로 다른 모델 및 스케줄러 구성 요소로 구성되며, 파이프라인의 속성으로 동일한 이름으로 접근할 수 있고 DiffusionPipeline.components 함수를 통해 파이프라인 간에 공유할 수 있습니다.
  • 모든 pipeline은 DiffusionPipeline.from_pretrained 함수를 통해 로드될 수 있어야 합니다.
  • 모든 pipeline은 __call__ 메서드를 통해 실행하는 방법이 하나만 존재해야 합니다. __call__ 인수의 명명은 모든 pipeline에서 일관되어야 합니다.
  • Pipelines는 해결하려는 작업 이름을 따서 명명해야 합니다.

모듈형 Diffusers

Modular Diffusers는 표준 파이프라인의 구성 가능한 대안입니다. 재사용 가능한 파이프라인 블록을 조합하여 워크플로를 구축할 수 있으며, 이를 혼합, 매칭, 교체 및 공유할 수 있습니다. 표준 파이프라인은 모델과 스케줄러를 사용하는 방법에 대한 느슨한 참고 예시입니다. Modular Diffusers는 Diffusers 위에 기능적으로 완성된 사용자 인터페이스를 구축하고, 커뮤니티가 탈중앙화된 방식으로 새로운 파이프라인을 구축하고 공유하는 것을 권장하는 경로입니다.

다음과 같은 설계 원칙을 따릅니다:

  • 모듈형 파이프라인은 단일 파일 정책을 따릅니다. 각 파이프라인은 src/diffusers/modular_pipelines/ 하위의 개별 폴더에 위치하며, 폴더는 워크플로를 단계별로 하나의 파일씩 나누어 구성합니다: encoders.py, before_denoise.py, denoise.py, decoders.py. 두 개의 추가 파일이 파이프라인을 완성합니다. modular_blocks_<model>.py는 각 단계를 조립하고, modular_pipeline.py는 모델별 ModularPipeline 하위 클래스를 정의합니다. 모듈형 파이프라인은 서로를 크로스 임포트하지 않습니다.
  • 각 모듈형 파이프라인은 ModularPipelineBlocks의 집합으로 정의됩니다. 리프 블록은 스테이지 파일(encoders.py, before_denoise.py, denoise.py, decoders.py)에 위치하며, modular_blocks_<model>.py는 SequentialPipelineBlocks와 AutoPipelineBlocks와 같은 컨테이너 클래스를 사용하여 이를 전체 워크플로로 조립합니다. 이는 DiffusionPipeline combines하는 두 가지 개념을 분리합니다. 블록은 순수한 정의입니다. 입력, 출력, 구성 요소 의존성을 선언하지만 가중치를 보유하지 않으며 실행할 수 없습니다. .init_pipeline(repo_id)로 생성되는 ModularPipeline는 실행 가능한 대응물입니다. 블록이 상태가 없고 가중치를 보유하지 않는 것이 워크플로 간에 자유롭게 구성, 교체, 공유할 수 있는 이유입니다.
  • 새 작업을 지원하려면 작업별 블록을 작성하고 기존 블록과 조합한 뒤, 최상위 블록 조립의 _workflow_map에 워크플로를 등록합니다. ModularPipeline 하나로는 텍스트-이미지, 이미지-이미지, 인페인팅 등 여러 워크플로를 지원할 수 있지만, DiffusionPipeline은 하나의 워크플로만 실행합니다.

전체 설계 및 사용 가이드는 Modular Diffusers 문서를 참조하세요.

모델

모델은 PyTorch의 Module 클래스의 자연스러운 확장인 구성 가능한 도구 모음으로 설계됩니다. 단일 파일 정책을 따르도록 해야 합니다. 이 관례 이전의 일부 오래된 모델은 그대로 유지되며, 새로운 모델에서 따라야 할 패턴이 아닌 레거시 예외로 간주하십시오. 예를 들어, 원래의 UNet2DConditionModel 클래스는 여러 UNet 변형에 사용되었습니다.

다음과 같은 설계 원칙을 따릅니다:

  • 각 모델 아키텍처 유형은 src/diffusers/models 아래에 자체 폴더를 가지며, 예를 들어 transformers/, autoencoders/, 또는 unets/가 있습니다. 각 모델 패밀리에는 해당 폴더 내에 자체 파일이 있으며, transformer_flux.py와 transformer_wan.py가 그 예입니다.
  • 모델은 단일 파일 정책을 따릅니다. 각 모델 파일은 자체적으로 완결되어야 하며, 모든 모델이 동일하게 사용하는 timestep 임베딩과 정규화 레이어와 같은 소수의 표준 모듈을 제외합니다. 이러한 모듈은 embeddings.py와 normalization.py에서 가져와야 합니다.
  • 모델은 PyTorch의 Module 클래스와 마찬가지로 복잡성을 드러내도록 설계되어 있으며, 명확한 오류 메시지를 제공합니다.
  • 모든 모델은 ModelMixin과 ConfigMixin을 상속받습니다.
  • 모델은 주요 코드 변경이 필요하지 않고, 하위 호환성을 유지하며, 메모리 또는 계산 측면에서 상당한 이점을 제공하는 경우 성능 최적화가 가능합니다.
  • 모델은 기본적으로 가장 높은 정밀도와 가장 낮은 성능 설정을 가져야 합니다.
  • 기존 모델과 유사한 새로운 모델 아키텍처를 통합하려면, 기존 파일을 복사하여 시작점으로 사용하고 그에 맞게 수정하세요. 동일한 상태로 유지되는 레이어에는 # Copied from 주석을 사용하여 make fix-copies가 이를 동기화하도록 하세요.

스케줄러

Scheduler는 추론 시 denoising 과정을 안내하고 학습 시 noise schedule을 정의하는 역할을 합니다. 개별 클래스로 설계되며 로드 가능한 구성 파일을 지원하고 single-file policy를 엄격히 따릅니다.

다음과 같은 설계 원칙을 따릅니다:

  • 모든 스케줄러는 src/diffusers/schedulers에서 찾을 수 있습니다.
  • Schedulers는 대형 utils 파일에서 가져오는 것이 허용되지 않으며, 매우 독립적으로 유지되어야 합니다.
  • Python 파일 하나당 스케줄러 알고리즘 하나(논문에서 정의된 것과 유사)가 대응합니다.
  • 스케줄러가 유사한 기능을 공유하는 경우, # Copied from 메커니즘을 활용할 수 있습니다.
  • 모든 Schedulers는 SchedulerMixin과 ConfigMixin을 상속합니다.
  • 여기에서 자세히 설명된 대로, 스케줄러는 ConfigMixin.from_config 메서드를 사용하여 쉽게 교체할 수 있습니다.
  • 모든 스케줄러에는 set_num_inference_steps와 step 함수가 필요합니다. set_num_inference_steps(...)는 모든 디노이징 과정, 즉 step(...)이 호출되기 전에 호출되어야 합니다.
  • 모든 스케줄러는 timesteps 속성을 통해 반복할 timesteps를 노출하며, 이는 모델이 호출될 timesteps의 배열입니다.
  • step(...) 함수는 예측된 모델 출력과 “현재” 샘플(x_t)을 입력으로 받아 “이전” 단계의, 노이즈가 약간 제거된 샘플(x_t-1)을 반환합니다.
  • diffusion scheduler의 복잡성으로 인해, step 함수는 모든 복잡성을 노출하지 않으며 다소 “블랙박스”처럼 느껴질 수 있습니다.
  • 거의 모든 경우에서 새로운 스케줄러는 새로운 스케줄링 파일에 구현해야 합니다.
Update on GitHub