Buckets:

mishig's picture
|
download
raw
30.7 kB
# ModularPipeline
[ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)는 [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)를 모델 로딩 및 블록에서 정의된 계산 단계를 수행하는 실행 가능한 파이프라인으로 변환합니다. 이는 파이프라인 실행을 위한 주요 인터페이스이며, API는 [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)과 매우 유사하지만 몇 가지 주요 차이점이 있습니다.
- **Loading is lazy.** With [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline), [from_pretrained()](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) creates the pipeline and loads all models at the same time. With [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline), creating and loading are two separate steps: [from_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained) reads the configuration and knows where to load each component from, but doesn't actually load the model weights. You load the models later with [load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components), which is where you pass loading arguments like `dtype` and `quantization_config`.
- **파이프라인을 생성하는 두 가지 방법** 기존 diffusers 모델 저장소와 함께 [from_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained)를 사용할 수 있습니다. 이 방법은 기본 파이프라인 블록에 자동으로 매핑한 후 추가 설정 없이 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)으로 변환합니다. 현재 지원되는 모델을 확인하려면 [modular_pipelines_directory](https://github.com/huggingface/diffusers/tree/main/src/diffusers/modular_pipelines)를 살펴보세요. 또한 [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)로 직접 파이프라인을 조립한 후 [init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline) 메서드로 변환할 수도 있습니다(자세한 내용은 [파이프라인 생성](#creating-a-pipeline)을 참고하세요).
- **파이프라인 실행 방법은 동일합니다.** 로드된 후, 익숙한 인수를 그대로 사용하여 파이프라인을 호출합니다. 파이프라인 블록이 [`AutoPipelineBlocks`](./auto_pipeline_blocks)를 사용하여 입력에 따라 워크플로를 자동으로 선택하는 경우, 단일 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)이 여러 워크플로(텍스트-이미지, 이미지-이미지, 인페인팅 등)를 지원할 수 있습니다.
다음은 SDXL을 사용한 텍스트-이미지 생성, 이미지-이미지 변환, 인페인팅의 완전한 예시입니다.
```py
import torch
from diffusers import ModularPipeline
pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda") # or "mps", "xpu", "cpu"
image = pipeline(prompt="Astronaut in a jungle, cold color palette, muted colors, detailed, 8k").images[0]
image.save("modular_t2i_out.png")
```
```py
import torch
from diffusers import ModularPipeline
from diffusers.utils import load_image
pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda") # or "mps", "xpu", "cpu"
url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
init_image = load_image(url)
prompt = "a dog catching a frisbee in the jungle"
image = pipeline(prompt=prompt, image=init_image, strength=0.8).images[0]
image.save("modular_i2i_out.png")
```
```py
import torch
from diffusers import ModularPipeline
from diffusers.utils import load_image
pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
pipeline.load_components(dtype=torch.float16)
pipeline.to("cuda") # or "mps", "xpu", "cpu"
img_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-text2img.png"
mask_url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/sdxl-inpaint-mask.png"
init_image = load_image(img_url)
mask_image = load_image(mask_url)
prompt = "A deep sea diver floating"
image = pipeline(prompt=prompt, image=init_image, mask_image=mask_image, strength=0.85).images[0]
image.save("modular_inpaint_out.png")
```
이 가이드에서는 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)를 생성하고, 그 구성 요소를 관리하며, 파이프라인을 실행하는 방법을 보여줍니다.
## 파이프라인 만들기
There are two ways to create a [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline). Assemble and create a pipeline from [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks) with [init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline), or load an existing pipeline with [from_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained).
[`ComponentsManager`](./components_manager)를 초기화하여 디바이스 배치와 메모리 관리를 처리할 수도 있습니다. 자동 오프로딩이 필요하지 않다면 이 단계를 건너뛰고 `pipeline.to("cuda")`를 사용하여 파이프라인을 수동으로 원하는 디바이스로 이동할 수 있습니다.
> [!TIP]
> [ComponentsManager](./components_manager) 문서의 자세한 내용을 참조하여 다른 워크플로우 간에 구성 요소를 관리하는 데 어떻게 도움이 되는지 확인하세요.
### init_pipeline
[init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline)은 모든 [ModularPipelineBlocks](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks)를 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)로 변환합니다.
동작 방식을 확인하기 위해 최소한의 블록을 정의해 보겠습니다:
```py
from transformers import CLIPTextModel
from diffusers.modular_pipelines import (
ComponentSpec,
ModularPipelineBlocks,
PipelineState,
)
class MyBlock(ModularPipelineBlocks):
@property
def expected_components(self):
return [
ComponentSpec(
name="text_encoder",
type_hint=CLIPTextModel,
pretrained_model_name_or_path="openai/clip-vit-large-patch14",
),
]
def __call__(self, components, state: PipelineState) -> PipelineState:
return components, state
```
[init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline)를 호출하여 파이프라인으로 변환합니다. 파이프라인의 `blocks` 속성은 해당 파이프라인이 생성된 블록을 나타내며, 예상 입력, 출력 및 계산 로직을 결정합니다.
```py
block = MyBlock()
pipe = block.init_pipeline()
pipe.blocks
```
```
MyBlock {
"_class_name": "MyBlock",
"_diffusers_version": "0.37.0.dev0"
}
```
> [!WARNING]
> Blocks는 변경 가능합니다. 파이프라인을 생성하기 전에 자유롭게 블록을 추가, 제거 또는 교체할 수 있습니다. 그러나 파이프라인이 생성된 후에는 `pipeline.blocks`를 수정해도 복사본을 반환하기 때문에 파이프라인에 영향을 주지 않습니다. 다른 블록 구조가 필요하면 블록을 수정한 후 새로운 파이프라인을 생성하세요.
리포지토리 없이 [init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline)를 호출하면, 블록의 [ComponentSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec)에 정의된 `pretrained_model_name_or_path`를 사용하여 각 구성 요소를 어디서 로드할지 결정합니다. 파이프라인을 출력하면 구성 요소 로드 설정을 확인할 수 있습니다.
```py
pipe
ModularPipeline {
"_blocks_class_name": "MyBlock",
"_class_name": "ModularPipeline",
"_diffusers_version": "0.37.0.dev0",
"text_encoder": [
null,
null,
{
"pretrained_model_name_or_path": "openai/clip-vit-large-patch14",
"revision": null,
"subfolder": "",
"type_hint": [
"transformers",
"CLIPTextModel"
],
"variant": null
}
]
}
```
[init_pipeline()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.init_pipeline)에 저장소를 전달하면, 해당 저장소의 파이프라인 구성(`model_index.json` 또는 `modular_model_index.json`)과 블록의 구성 요소를 일치시켜 로드 경로를 재정의합니다. 로드 사양이 기록되고 저장되는 방법은 [Modular repository](#modular-repository)를 참고하세요.
아래 예시에서 `pretrained_model_name_or_path`는 `"stabilityai/stable-diffusion-xl-base-1.0"`으로 업데이트됩니다.
```py
pipe = block.init_pipeline("stabilityai/stable-diffusion-xl-base-1.0")
pipe
ModularPipeline {
"_blocks_class_name": "MyBlock",
"_class_name": "ModularPipeline",
"_diffusers_version": "0.37.0.dev0",
"text_encoder": [
null,
null,
{
"pretrained_model_name_or_path": "stabilityai/stable-diffusion-xl-base-1.0",
"revision": null,
"subfolder": "text_encoder",
"type_hint": [
"transformers",
"CLIPTextModel"
],
"variant": null
}
]
}
```
블록의 구성 요소가 저장소에 없으면 `null`로 남아 [load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) 실행 시 건너뜁니다.
### from_pretrained
[from_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.from_pretrained)은 블록을 직접 정의하지 않고 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)을 생성하는 편리한 방법입니다.
세 가지 유형의 저장소와 함께 작동합니다.
**일반적인 diffusers 저장소.** 지원되는 모델 저장소를 전달하면 기본 파이프라인 블록으로 자동으로 매핑됩니다. 현재 지원되는 모델에는 SDXL, Wan, Qwen, Z-Image, Flux, Flux2가 포함됩니다.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", components_manager=components
)
```
**모듈형 저장소.** 이러한 저장소에는 각 구성 요소를从哪里 로드할지 지정하는 `modular_model_index.json` 파일이 포함되어 있습니다. 구성 요소는 서로 다른 저장소에서 가져올 수 있으며, 모듈형 저장소 자체에는 모델 가중치가 전혀 없을 수도 있습니다. 예를 들어, [diffusers/flux2-bnb-4bit-modular](https://huggingface.co/diffusers/flux2-bnb-4bit-modular)는 한 저장소에서 양자화된 transformer를 로드하고 나머지 구성 요소를 다른 저장소에서 로드합니다. 포맷에 대한 자세한 내용은 [Modular repository](#modular-repository)를 참고하세요.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"diffusers/flux2-bnb-4bit-modular", components_manager=components
)
```
**커스텀 코드가 포함된 모듈형 저장소.** 일부 저장소에는 로딩 구성과 함께 커스텀 파이프라인 블록이 포함됩니다. 이를 로드하려면 `trust_remote_code=True`를 추가하세요. 직접 만들려면 [커스텀 블록](./custom_blocks)을 참고하세요.
```py
from diffusers import ModularPipeline, ComponentsManager
components = ComponentsManager()
pipeline = ModularPipeline.from_pretrained(
"diffusers/Florence2-image-Annotator", trust_remote_code=True, components_manager=components
)
```
pipeline 블록이 워크플로를 정의하는 경우(`pipeline.blocks.available_workflows` 확인), `workflow=`를 전달하여 해당 워크플로의 블록만 유지합니다. 이는 [get_workflow()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_blocks#diffusers.ModularPipelineBlocks.get_workflow)와 동일한 가지치기입니다. 그러면 pipeline은 해당 워크플로가 사용하는 컴포넌트만 선언하고, docstring은 정확히 해당 워크플로의 입력을 설명합니다.
```py
pipeline = ModularPipeline.from_pretrained("Qwen/Qwen-Image", workflow="inpainting")
```
## 컴포넌트 로드
[ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)는 구성 요소가 자동으로 인스턴스화되지 않습니다. 구성 및 구성 요소 사양만 로드합니다. 구성 요소는 [load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components)를 사용하여 로드할 수 있습니다.
…
```py
import torch
pipeline.load_components(dtype=torch.float16)
```
이름으로 특정 구성 요소를 로드할 수도 있습니다. 아래 예시에서는 `text_encoder`만 로드합니다.
```py
pipeline.load_components(names=["text_encoder"], dtype=torch.float16)
```
블록이 워크플로를 정의하는 파이프라인에서 `workflow=`는 해당 워크플로가 사용하는 컴포넌트만 로드합니다. 파이프라인은 모든 블록을 유지하므로, 이는 하나의 파이프라인을 여러 워크플로에 걸쳐 실행하는 편리한 방법입니다. 각 호출은 새로운 워크플로가 아직 누락한 것만 추가합니다.
```py
pipeline.load_components(workflow="inpainting", dtype=torch.float16)
```
로드 후 파이프라인을 출력하면 어떤 구성 요소가 로드되었는지 확인할 수 있습니다. 처음 두 필드가 `null`에서 해당 구성 요소의 라이브러리와 클래스로 변경됩니다.
```py
pipeline
```
```
# text_encoder is loaded - shows library and class
"text_encoder": [
"transformers",
"CLIPTextModel",
{ ... }
]
# unet is not loaded yet - still null
"unet": [
null,
null,
{ ... }
]
```
`dtype`, `variant`, `revision`, `quantization_config`와 같은 키워드 인수는 각 구성 요소에 대해 `from_pretrained()`로 전달됩니다. 모든 구성 요소에 적용할 단일 값을 전달하거나, 구성 요소별 값을 설정하기 위해 dict를 전달할 수 있습니다.
```py
# apply bfloat16 to all components
pipeline.load_components(dtype=torch.bfloat16)
# different dtypes per component
pipeline.load_components(dtype={"transformer": torch.bfloat16, "default": torch.float32})
```
[load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components)는 아직 로드되지 않았고 유효한 로딩 스펙을 가진 컴포넌트만 로드합니다. 이는 파이프라인에 이미 컴포넌트를 설정한 경우 [load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components)를 다시 호출해도 해당 컴포넌트가 다시 로드되지 않음을 의미합니다.
## 컴포넌트 업데이트
[update_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components)는 파이프라인의 구성 요소를 새로운 구성 요소로 교체합니다. 구성 요소가 업데이트되면 파이프라인 설정의 로딩 사양도 함께 업데이트되며, 이후 [load_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.load_components) 호출 시 해당 구성 요소는 건너뜁니다.
### AutoModel에서
`AutoModel.from_pretrained()`로 로드된 모델 객체를 전달할 수 있습니다. 이 방식으로 로드된 모델에는 로드 정보가 자동으로 태그됩니다.
```py
from diffusers import AutoModel
unet = AutoModel.from_pretrained(
"RunDiffusion/Juggernaut-XL-v9", subfolder="unet", variant="fp16", dtype=torch.float16
)
pipeline.update_components(unet=unet)
```
### ComponentSpec에서
[get_component_spec()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.get_component_spec)을 사용하여 현재 구성 요소 사양의 사본을 가져오고, 수정한 후 새로운 구성 요소를 로드합니다.
```py
unet_spec = pipeline.get_component_spec("unet")
# modify to load from a different repository
unet_spec.pretrained_model_name_or_path = "RunDiffusion/Juggernaut-XL-v9"
# load and update
unet = unet_spec.load(dtype=torch.float16)
pipeline.update_components(unet=unet)
```
[ComponentSpec](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec)를 처음부터 직접 생성할 수도 있습니다.
모든 구성 요소가 사전 학습된 가중치에서 로드되는 것은 아닙니다. 일부 구성 요소는 `pipeline.config_component_names`에 나열된 대로 config에서 생성됩니다. 이러한 구성 요소에는 [load()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec.load) 대신 [create()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentSpec.create)를 사용하세요.
```py
guider_spec = pipeline.get_component_spec("guider")
guider_spec.config = {"guidance_scale": 5.0}
guider = guider_spec.create()
pipeline.update_components(guider=guider)
```
또는 객체를 직접 전달합니다.
```py
from diffusers.guiders import ClassifierFreeGuidance
guider = ClassifierFreeGuidance(guidance_scale=5.0)
pipeline.update_components(guider=guider)
```
사용 가능한 guider와 설정 방법에 대한 자세한 내용은 [Guiders](../using-diffusers/guiders) 가이드를 참고하세요.
## 파이프라인을 단계로 분할하기
블록은 구성 가능(composable)하므로, 파이프라인을 분해하여 각 단계별로 별도의 파이프라인으로 재구성할 수 있습니다. 아래 예제는 텍스트 인코더 블록을 파이프라인의 나머지 부분에서 분리하는 방법을 보여줍니다. 이를 통해 프롬프트를 독립적으로 인코딩한 후 임베딩을 메인 파이프라인에 전달할 수 있습니다.
```py
from diffusers import ModularPipeline, ComponentsManager
import torch
device = "cuda" # or "mps", "xpu", "cpu"
dtype = torch.bfloat16
repo_id = "black-forest-labs/FLUX.2-klein-4B"
# get the blocks and separate out the text encoder
blocks = ModularPipeline.from_pretrained(repo_id).blocks
text_block = blocks.sub_blocks.pop("text_encoder")
# use ComponentsManager to handle offloading across multiple pipelines
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device=device)
# create separate pipelines for each stage
text_encoder_pipeline = text_block.init_pipeline(repo_id, components_manager=manager)
pipeline = blocks.init_pipeline(repo_id, components_manager=manager)
# encode text
text_encoder_pipeline.load_components(dtype=dtype)
text_embeddings = text_encoder_pipeline(prompt="a cat").get_by_kwargs("denoiser_input_fields")
# denoise and decode
pipeline.load_components(dtype=dtype)
output = pipeline(
**text_embeddings,
num_inference_steps=4,
).images[0]
```
[ComponentsManager](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager)은 여러 파이프라인에 걸친 메모리를 관리합니다. [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)의 오프로딩 전략이 고정된 순서를 따르는 것과 달리, [ComponentsManager](/docs/diffusers/main/ko/api/modular_diffusers/pipeline_components#diffusers.ComponentsManager)는 모델의 포워드 패스가 실행될 때마다 현재 메모리 상황에 따라 오프로딩을 동적으로 결정합니다. 따라서 파이프라인을 몇 개 생성하든, 어떤 순서로 실행하든 작동합니다. 자세한 내용은 [ComponentsManager](./components_manager) 가이드를 참고하세요.
pipeline 단계가 구성 요소를 공유하는 경우(예: 인코딩과 디코딩에 동일한 VAE 사용), 다시 로드하는 대신 이미 로드된 구성 요소를 다른 pipeline에 전달하기 위해 [update_components()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.update_components)를 사용할 수 있습니다.
## 모듈형 저장소
*pretrained components*를 사용하는 파이프라인 블록의 경우 저장소가 필요합니다. 저장소는 로딩 사양과 메타데이터를 제공합니다.
[ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)는 일반적인 diffusers 저장소와 바로 함께 작동합니다. 그러나 더 많은 유연성을 위해 *모듈형 저장소*를 만들 수도 있습니다. 모듈형 저장소에는 다음 3가지 요소를 포함하는 `modular_model_index.json` 파일이 있습니다.
- `library`와 `class`는 해당 구성 요소가 어떤 라이브러리에서 로드되었는지와 그 클래스를 나타냅니다. `null`인 경우, 해당 구성 요소는 아직 로드되지 않은 것입니다.
- `loading_specs_dict`에는 저장소와 하위 폴더와 같이 구성 요소를 로드하는 데 필요한 정보가 포함되어 있습니다.
모듈형 저장소의 핵심 이점은 컴포넌트를 서로 다른 저장소에서 로드할 수 있다는 것입니다. 예를 들어, [diffusers/flux2-bnb-4bit-modular](https://huggingface.co/diffusers/flux2-bnb-4bit-modular)는 `diffusers/FLUX.2-dev-bnb-4bit`에서 양자화된 transformer를 로드하는 동시에 나머지 컴포넌트는 `black-forest-labs/FLUX.2-dev`에서 로드합니다.
일반적인 diffusers 저장소를 모듈형 저장소로 변환하려면, 먼저 일반적인 저장소를 사용하여 파이프라인을 생성한 후 Hub에 push합니다. 저장된 저장소에는 모든 로딩 사양이 포함된 `modular_model_index.json`가 포함됩니다.
```py
from diffusers import ModularPipeline
# load from a regular repo
pipeline = ModularPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0")
# push as a modular repository
pipeline.save_pretrained("local/path", repo_id="my-username/sdxl-modular", push_to_hub=True)
```
기본적으로 [save_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained)는 Diffusers가 직렬화할 수 있는 현재 로드된 각 구성 요소를 기록합니다. 로드되지 않았거나 직렬화할 수 없는 구성 요소는 기록되지 않으며 기존 로드 사양을 유지합니다. 이를 통해 원하는 목적에 따라 두 가지 방식으로 저장할 수 있습니다.
### 자체 포함 복사본 저장
모든 구성 요소를 로드한 후 저장합니다. 모든 사양이 결과물을 가리키므로 오프라인을 포함하여 한 곳에서 완전히 다시 로드됩니다.
```py
pipe = ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3")
pipe.load_components()
pipe.save_pretrained("path/to/local-copy")
```
`modular_model_index.json`에 기록된 대상은 [save_pretrained()](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline.save_pretrained)가 데이터를 쓰는 위치입니다. 로컬 저장 시에는 `save_directory`, `push_to_hub=True`를 전달한 경우에는 `repo_id`입니다.
`huggingface_hub>=1.32.0`부터 동일한 Xet 기반 파일은 Hub 저장소 간에 하나의 캐시된 페이로드를 공유할 수 있습니다. 이는 샤드화된 체크포인트의 개별 파일에도 적용됩니다. 다른 샤드와 내용이 달라도 동일한 Xet 해시를 가진 샤드는 재사용될 수 있습니다. 두 다운로드 모두 심볼릭 링크를 지원하는 동일한 Hub 캐시 디렉터리를 사용해야 합니다. dtype, 직렬화 방식 또는 샤드 경계를 변경하면 파일 해시가 달라져 재사용이 불가능해질 수 있습니다. 이를 통해 다운로드 트래픽과 디스크 공간을 절약할 수 있지만, 로드된 구성 요소가 사용하는 메모리는 절약되지 않습니다.
공유 캐싱은 최선 노력(best-effort) 방식입니다. `HF_HUB_DISABLE_SHARED_BLOBS=1`을 설정해도 로딩은 지원되지만, 개별 사본을 캐시합니다. `modular_model_index.json`에 있는 기존 구성 요소 참조는 변경되지 않으며, 모듈형 저장소에 저장되지 않은 구성 요소의 외부 참조는 유지해야 합니다.
#### 기존 모듈형 인덱스 업데이트
마이그레이션은 선택 사항입니다: 원본 저장소에 대한 참조는 이미 캐시된 파일을 재사용합니다. 중복 다운로드를 피하기 위해만 사용되었고 해당 구성 요소를 모듈형 저장소에서 로드하도록 변경하려면 참조를 업데이트하세요.
먼저, 모듈형 저장소에 동일한 구성 요소 구성과 모든 필수 가중치 파일이 포함되어 있는지 확인하십시오. 여기에는 가중치 인덱스와 샤드화된 체크포인트의 모든 샤드가 포함됩니다. 일치하는 Xet 해시가 어떤 가중치 파일을 공유 캐시로 재사용할 수 있는지를 결정합니다. 존재하지 않거나 의도적으로 다른 체크포인트에서 로드되는 구성 요소에 대한 참조를 유지하십시오.
`modular_model_index.json`의 로컬 사본에서 관련 로딩 사양만 수정합니다. 예를 들어, 모듈형 저장소에서 `vae/` 아래에 저장된 VAE를 동일한 가중치 변형으로 사용하려면:
```py
import json
from pathlib import Path
index_path = Path("path/to/local-copy/modular_model_index.json")
index = json.loads(index_path.read_text())
spec = index["vae"][2]
spec["pretrained_model_name_or_path"] = "my-username/my-modular-repo"
spec.pop("repo", None)
spec["subfolder"] = "vae"
spec["revision"] = None
index_path.write_text(json.dumps(index, indent=2) + "\n")
```
이것은 레거시 `repo` 필드도 제거합니다. 원본 저장소의 리비전은 대상 저장소의 리비전을 식별하지 않습니다: 대상의 기본 브랜치를 사용하려면 `None`을 사용하거나, 해당 구성 요소를 포함하는 대상 리비전을 고정하세요. 파일명이 다르면 `subfolder`와 `variant`를 조정하세요.
업데이트된 인덱스를 게시하기 전에 `ModularPipeline.from_pretrained("path/to/local-copy")`로 로드하고, `load_components(names="vae")`를 호출한 후, 해당 구성 요소가 예상된 매개변수로 로드되는지 확인하세요. 편집된 인덱스만 업로드하세요. 가중치를 다시 저장하면 해시가 변경되어 캐시 재사용이 방지될 수 있습니다.
### 기존 컴포넌트에 대한 참조 유지
새로운 것만(아니면 아무것도 아닌) 로드합니다. 로드된 컴포넌트만 저장되며, 나머지는 원래 저장소를 가리키는 포인터로 유지됩니다. 한 컴포넌트를 교체하면서 다른 컴포넌트는 원래 저장소에서 계속 로드하기를 원할 때 이 모드를 사용하세요. 예를 들어, 커스텀 transformer를 저장하면서 나머지 컴포넌트는 기본 저장소에서 계속 로드되도록 할 수 있습니다.
```py
pipe = ModularPipeline.from_pretrained("black-forest-labs/FLUX.2-dev")
pipe.update_components(transformer=my_custom_transformer) # the only component in memory
pipe.save_pretrained("local/path", repo_id="my-username/flux2-custom-transformer", push_to_hub=True)
```
`overwrite_modular_index=False`를 전달하면 `modular_model_index.json`의 로딩 사양을 그대로 유지합니다. 로딩 사양이 비어 있는 저장된 컴포넌트는 보존할 내용이 없으므로 대상 경로로 채워집니다.
파일을 다른 방식으로 이동하면 인덱스가 다시 작성되지 않습니다. `hf download --local-dir`로 다운로드한 복사본은 여전히 작동합니다. 파이프라인이 로컬 디렉터리에서 로드되면, 해당 디렉터리에 파일이 존재하는 모든 구성 요소는 기록된 저장소가 아닌 해당 디렉터리에서 로드됩니다. `hf upload`로 업로드한 복사본은 여전히 이전 위치를 가리키므로, 이 경우 인덱스를 수동으로 업데이트해야 합니다.
모듈형 저장소에는 Python 코드로 작성된 사용자 정의 파이프라인 블록도 포함할 수 있습니다. 이를 통해 Diffusers에 기본적으로 제공되지 않는 특수한 블록을 공유할 수 있습니다. 예를 들어, [diffusers/Florence2-image-Annotator](https://huggingface.co/diffusers/Florence2-image-Annotator)에는 로드 구성과 함께 사용자 정의 블록이 포함되어 있습니다:
```
Florence2-image-Annotator/
├── block.py # Custom pipeline blocks implementation
├── config.json # Pipeline configuration and auto_map
├── mellon_config.json # UI configuration for Mellon
└── modular_model_index.json # Component loading specifications
```
`config.json` 파일에는 [ModularPipeline](/docs/diffusers/main/ko/api/modular_diffusers/pipeline#diffusers.ModularPipeline)가 커스텀 블록을 어디에서 찾을 수 있는지 알려 주는 `auto_map` 키가 포함되어 있습니다:
```json
{
"_class_name": "Florence2AnnotatorBlocks",
"auto_map": {
"ModularPipelineBlocks": "block.Florence2AnnotatorBlocks"
}
}
```
`trust_remote_code=True`를 사용하여 [from_pretrained](#frompretrained)에 표시된 대로 사용자 정의 코드 저장소를 로드합니다. 직접 생성하고 공유하는 방법은 [Custom blocks](./custom_blocks)를 참조하세요.

Xet Storage Details

Size:
30.7 kB
·
Xet hash:
604322c9e84290a1aaf737f227327be4efe5adedbe75022ecb42b79c08bc42a7

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.