Diffusers documentation
InstructPix2Pix
InstructPix2Pix
InstructPix2Pix는 사람이 제공한 지시에 따라 이미지를 편집하도록 학습된 Stable Diffusion 모델입니다. 예를 들어, 프롬프트가 “구름을 비구름으로 바꿔라”이면 모델은 입력 이미지를 그에 맞게 편집합니다. 이 모델은 텍스트 프롬프트(또는 편집 지시)와 입력 이미지에 조건부입니다.
이 가이드에서는 train_instruct_pix2pix.py 학습 스크립트를 살펴보고, 이를 이해한 후 자신의 사용 사례에 맞게 수정하는 방법을 안내합니다.
…
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install .이후 학습 스크립트가 포함된 예제 폴더로 이동하여 사용하는 스크립트에 필요한 의존성을 설치합니다:
cd examples/instruct_pix2pix
pip install -r requirements.txt🤗 Accelerate는 여러 GPU/TPU 또는 혼합 정밀도로 학습하는 것을 돕는 라이브러리입니다. 하드웨어와 환경에 따라 학습 설정을 자동으로 구성합니다. 자세한 내용은 🤗 Accelerate Quick tour를 참고하세요.
🤗 Accelerate 환경을 초기화합니다:
accelerate config
어떤 구성도 선택하지 않고 기본 🤗 Accelerate 환경을 설정하려면:
accelerate config default
또는 노트북과 같이 인터랙티브 셸을 지원하지 않는 환경에서는 다음을 사용할 수 있습니다:
from accelerate.utils import write_basic_config
write_basic_config()마지막으로, 자체 데이터셋으로 모델을 학습하려면 학습용 데이터셋 만들기 가이드를 참고하여 학습 스크립트와 호환되는 데이터셋을 만드는 방법을 배워보세요.
다음 섹션에서는 스크립트를 수정하는 방법을 이해하는 데 중요한 학습 스크립트의 일부 부분을 강조합니다. 그러나 스크립트의 모든 측면을 자세히 다루지는 않습니다. 더 자세히 알고 싶으시다면 스크립트를 읽어보시고, 질문이나 우려 사항이 있으시면 알려주시기 바랍니다.
스크립트 매개변수
학습 스크립트에는 학습 실행을 사용자 정의하는 데 도움이 되는 많은 매개변수가 있습니다. 모든 매개변수와 그 설명은 parse_args() 함수에서 확인할 수 있습니다. 대부분의 매개변수에는 잘 작동하는 기본값이 제공되지만, 원하시는 경우 학습 명령에서 직접 값을 설정할 수도 있습니다.
예를 들어, 입력 이미지의 해상도를 높이려면:
accelerate launch train_instruct_pix2pix.py \ --resolution=512 \
기본적이고 중요한 대부분의 매개변수는 텍스트-이미지 학습 가이드에 설명되어 있으므로, 이 가이드에서는 InstructPix2Pix에 관련되는 매개변수에만 초점을 맞춥니다:
--original_image_column: 편집이 적용되기 전의 원본 이미지--edited_image_column: 편집이 완료된 이미지--edit_prompt_column: 이미지를 편집하기 위한 지침--conditioning_dropout_prob: 학습 중에 편집된 이미지와 편집 프롬프트에 적용되는 dropout 확률로, 하나 또는 두 개의 조건 입력에 대해 classifier-free guidance(CFG)를 활성화합니다
학습 스크립트
데이터셋 전처리 코드와 학습 루프는 main() 함수에 있습니다. 이 부분이 학습 스크립트를 수정하여 자체 사용 사례에 맞게 조정하는 곳입니다.
스크립트 매개변수와 마찬가지로, Text-to-image 학습 가이드에서 학습 스크립트의 전체적인 흐름을 안내합니다. 대신 이 가이드에서는 InstructPix2Pix와 관련된 스크립트 부분을 살펴봅니다.
스크립트는 InstructPix2Pix의 추가 조건 이미지를 고려하여 UNet의 첫 번째 컨볼루션 레이어의 입력 채널 수를 수정하는 것으로 시작합니다:
in_channels = 8
out_channels = unet.conv_in.out_channels
unet.register_to_config(in_channels=in_channels)
with torch.no_grad():
new_conv_in = nn.Conv2d(
in_channels, out_channels, unet.conv_in.kernel_size, unet.conv_in.stride, unet.conv_in.padding
)
new_conv_in.weight.zero_()
new_conv_in.weight[:, :4, :, :].copy_(unet.conv_in.weight)
unet.conv_in = new_conv_in이 UNet 매개변수는 옵티마이저에 의해 업데이트됩니다:
optimizer = optimizer_cls(
unet.parameters(),
lr=args.learning_rate,
betas=(args.adam_beta1, args.adam_beta2),
weight_decay=args.adam_weight_decay,
eps=args.adam_epsilon,
)다음으로, 편집된 이미지와 편집 지침은 전처리되고 토큰화됩니다. 원본 이미지와 편집된 이미지에 동일한 이미지 변환이 적용되는 것이 중요합니다.
def preprocess_train(examples):
preprocessed_images = preprocess_images(examples)
original_images, edited_images = preprocessed_images.chunk(2)
original_images = original_images.reshape(-1, 3, args.resolution, args.resolution)
edited_images = edited_images.reshape(-1, 3, args.resolution, args.resolution)
examples["original_pixel_values"] = original_images
examples["edited_pixel_values"] = edited_images
captions = list(examples[edit_prompt_column])
examples["input_ids"] = tokenize_captions(captions)
return examples마지막으로, training loop에서는 편집된 이미지를 latent space로 인코딩하는 것으로 시작합니다:
latents = vae.encode(batch["edited_pixel_values"].to(weight_dtype)).latent_dist.sample()
latents = latents * vae.config.scaling_factor그 다음으로, 스크립트는 CFG를 지원하기 위해 원본 이미지와 편집 지침 임베딩에 dropout을 적용합니다. 이를 통해 모델이 편집 지침과 원본 이미지가 편집된 이미지에 미치는 영향을 조절할 수 있습니다.
encoder_hidden_states = text_encoder(batch["input_ids"])[0]
original_image_embeds = vae.encode(batch["original_pixel_values"].to(weight_dtype)).latent_dist.mode()
if args.conditioning_dropout_prob is not None:
random_p = torch.rand(bsz, device=latents.device, generator=generator)
prompt_mask = random_p < 2 * args.conditioning_dropout_prob
prompt_mask = prompt_mask.reshape(bsz, 1, 1)
null_conditioning = text_encoder(tokenize_captions([""]).to(accelerator.device))[0]
encoder_hidden_states = torch.where(prompt_mask, null_conditioning, encoder_hidden_states)
image_mask_dtype = original_image_embeds.dtype
image_mask = 1 - (
(random_p >= args.conditioning_dropout_prob).to(image_mask_dtype)
* (random_p < 3 * args.conditioning_dropout_prob).to(image_mask_dtype)
)
image_mask = image_mask.reshape(bsz, 1, 1, 1)
original_image_embeds = image_mask * original_image_embeds대략 이 정도입니다! 여기서 설명한 차이점을 제외하면, 나머지 스크립트는 텍스트-투-이미지 학습 스크립트와 매우 유사하므로 더 자세한 내용은 해당 스크립트를 참고해 보세요. 학습 루프가 어떻게 작동하는지 더 알고 싶다면, 디노이징 과정의 기본 패턴을 분석하는 파이프라인, 모델 및 스케줄러 이해하기 튜토리얼을 확인해 보세요.
스크립트 실행
…
이 가이드는 fusing/instructpix2pix-1000-samples 데이터셋을 사용하며, 이는 원본 데이터셋의 축소 버전입니다. 원하시는 경우 학습용 데이터셋 만들기 가이드를 참고하여 자체 데이터셋을 생성하고 사용할 수도 있습니다.
MODEL_NAME 환경 변수를 모델 이름(Hub의 모델 id 또는 로컬 모델 경로)으로, DATASET_ID를 Hub의 데이터셋 이름으로 설정합니다. 스크립트는 모든 구성 요소(feature extractor, scheduler, text encoder, UNet 등)를 생성하여 저장소의 하위 폴더에 저장합니다.
더 나은 결과를 얻으려면 더 큰 데이터셋으로 더 긴 학습을 실행해 보세요. 이 학습 스크립트는 더 작은 규모의 데이터셋에서만 테스트했습니다.
Weights and Biases로 학습 진행 상황을 모니터링하려면 학습 명령에
--report_to=wandb파라미터를 추가하고,--val_image_url로 검증 이미지를,--validation_prompt로 검증 프롬프트를 지정하세요. 이는 모델 디버깅에 매우 유용할 수 있습니다.
여러 개의 GPU에서 학습하는 경우 accelerate launch 명령에 --multi_gpu 매개변수를 추가하세요.
accelerate launch --mixed_precision="fp16" train_instruct_pix2pix.py \
--pretrained_model_name_or_path=$MODEL_NAME \
--dataset_name=$DATASET_ID \
--enable_xformers_memory_efficient_attention \
--resolution=256 \
--random_flip \
--train_batch_size=4 \
--gradient_accumulation_steps=4 \
--gradient_checkpointing \
--max_train_steps=15000 \
--checkpointing_steps=5000 \
--checkpoints_total_limit=1 \
--learning_rate=5e-05 \
--max_grad_norm=1 \
--lr_warmup_steps=0 \
--conditioning_dropout_prob=0.05 \
--mixed_precision=fp16 \
--seed=42 \
--push_to_hub학습이 완료되면, 새로 학습한 InstructPix2Pix를 추론에 사용할 수 있습니다:
import PIL
import requests
import torch
from diffusers import StableDiffusionInstructPix2PixPipeline
from diffusers.utils import load_image
pipeline = StableDiffusionInstructPix2PixPipeline.from_pretrained("your_cool_model", dtype=torch.float16).to("cuda") # or "mps", "xpu", "cpu"
generator = torch.Generator("cuda").manual_seed(0)
image = load_image("https://huggingface.co/datasets/sayakpaul/sample-datasets/resolve/main/test_pix2pix_4.png")
prompt = "add some ducks to the lake"
num_inference_steps = 20
image_guidance_scale = 1.5
guidance_scale = 10
edited_image = pipeline(
prompt,
image=image,
num_inference_steps=num_inference_steps,
image_guidance_scale=image_guidance_scale,
guidance_scale=guidance_scale,
generator=generator,
).images[0]
edited_image.save("edited_image.png")추론 속도와 품질에 미치는 영향을 확인하기 위해 num_inference_steps, image_guidance_scale, guidance_scale 값이 서로 다른 경우로 실험해 보시기 바랍니다. guidance scale 매개변수는 원본 이미지와 편집 지시사항이 편집된 이미지에 얼마나 영향을 미치는지를 제어하므로 특히 큰 영향을 미칩니다.
Stable Diffusion XL
Stable Diffusion XL(SDXL)은 고해상도 이미지를 생성하는 강력한 텍스트-투-이미지 모델이며, 아키텍처에 두 번째 텍스트 인코더를 추가했습니다. train_instruct_pix2pix_sdxl.py 스크립트를 사용하여 이미지 편집 지시를 따르는 SDXL 모델을 학습하세요.
SDXL 학습 스크립트는 SDXL 학습 가이드에서 더 자세히 설명되어 있습니다.
다음 단계
InstructPix2Pix 모델을 직접 학습시키신 것을 축하드립니다! 🥳 모델에 대해 더 자세히 알고 싶으시다면 다음을 참고해 보시는 것이 좋습니다:
- InstructPix2Pix에 대한 실험, 데이터셋 준비, 다양한 지시어에 대한 결과를 자세히 알아보려면 Instruction-tuning Stable Diffusion with InstructPix2Pix 블로그 포스트를 읽어보세요.