Latent Vector의 초기 상태:
gpt 결과
초기 상태의 latent vector는 랜덤 노이즈로 초기화됩니다.
이 노이즈는 정규 분포에서 샘플링된 값으로 채워지며, 이는 의도적으로 "노이즈가 많은" 상태입니다.
이 초기 latent vector는 깨끗한 이미지가 아니라, 강한 노이즈가 포함된 이미지의 잠재 공간 표현이라고 할 수 있습니다.
Diffusion 모델은 이 초기 노이즈 텐서(즉, latent vector)를 점진적으로 "denoise" 하여, 특정 텍스트 프롬프트와 일치하는 깨끗한 이미지를 생성하는 과정입니다.
Forward pass에서 UNet 모델은 현재의 노이즈 상태(즉, latent vector)와 텍스트 임베딩(prompt_embeds)을 결합하여, 다음 단계에서 더 적은 노이즈를 가진 latent vector로 변환합니다.
각 타임스텝에서 모델은 latent vector의 노이즈를 조금씩 줄이며, 텍스트 프롬프트에 더 가까운 이미지를 형성해 나갑니다. 이는 반복적으로 수행되며, 최종적으로 노이즈가 거의 제거된 깨끗한 이미지로 수렴합니다.
노이즈 공간에서 이미지 공간으로의 변환: 초기의 latent vector는 랜덤 노이즈로 가득 차 있지만, 이 노이즈가 텍스트 프롬프트에 따라 점차적으로 조정되며 이미지로 변환됩니다. 초기의 노이즈는 모델이 다양한 가능성을 탐색할 수 있도록 하며, 이를 통해 다양한 이미지를 생성할 수 있습니다.
이미지 생성 과정의 핵심: 이 latent vector는 결국 모델이 최종적으로 생성할 이미지의 잠재 표현으로, 텍스트 조건을 반영해가면서 변형됩니다. 각 타임스텝에서 이 vector는 점점 더 "덜 노이즈한" 상태로 변하고, 텍스트 프롬프트에 맞는 특정 이미지를 형성해 갑니다.
아래 코드와 같이 처음 latent vector은 random한 값으로 초기화됨 (의도적으로 노이즈가 많은 상태라는 뜻)
def prepare_latents(self, batch_size, num_channels_latents, height, width, dtype, device, generator, latents=None):
# 생성할 latent 벡터의 크기를 정의
# 예를 들어, vae_scale_factor가 8이라면, 최종 latent 벡터의 크기는 원본 이미지 크기의 1/8로 줄어들게 됨
# 만약 원본 이미지의 크기가 256x256이고, vae_scale_factor가 8이라면, latent 벡터의 크기는 256 // 8 = 32가 됨
# 만약 batch_size = 4, num_channels_latents = 4라고 가정하면 최종 shape는 다음과 같이 계산
# shape = (4, 4, 32, 32)
shape = (batch_size, num_channels_latents, height // self.vae_scale_factor, width // self.vae_scale_factor)
if isinstance(generator, list) and len(generator) != batch_size:
raise ValueError(
f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
f" size of {batch_size}. Make sure the batch size matches the length of the generators."
)
# latents가 주어지지 않은 경우 (latents is None), 주어진 shape과 device에 맞는 랜덤 노이즈 텐서를 생성
if latents is None:
latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
else:
latents = latents.to(device)
# scale the initial noise by the standard deviation required by the scheduler
# 스케줄러가 요구하는 표준 편차(init_noise_sigma)로 초기 노이즈를 스케일링
latents = latents * self.scheduler.init_noise_sigma
return latents
초기에는 랜덤한 노이즈로 가득 찬 latent vector로 시작합니다. 그런 다음 이 노이즈는 텍스트 임베딩(prompt_embeds)과 결합하여, 점진적으로 텍스트 프롬프트에 맞는 의미 있는 이미지를 표현하는 latent vector로 변환됩니다.