Improvements to vae trainer. Adjust denoise prediction of DFE v3
This commit is contained in:
@@ -89,6 +89,7 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
self.vae_config = self.get_conf('vae_config', None)
|
self.vae_config = self.get_conf('vae_config', None)
|
||||||
self.dropout = self.get_conf('dropout', 0.0, as_type=float)
|
self.dropout = self.get_conf('dropout', 0.0, as_type=float)
|
||||||
self.train_encoder = self.get_conf('train_encoder', False, as_type=bool)
|
self.train_encoder = self.get_conf('train_encoder', False, as_type=bool)
|
||||||
|
self.random_scaling = self.get_conf('random_scaling', False, as_type=bool)
|
||||||
|
|
||||||
if not self.train_encoder:
|
if not self.train_encoder:
|
||||||
# remove losses that only target encoder
|
# remove losses that only target encoder
|
||||||
@@ -159,7 +160,11 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
for dataset in self.datasets_objects:
|
for dataset in self.datasets_objects:
|
||||||
print(f" - Dataset: {dataset['path']}")
|
print(f" - Dataset: {dataset['path']}")
|
||||||
ds = copy.copy(dataset)
|
ds = copy.copy(dataset)
|
||||||
ds['resolution'] = self.resolution
|
dataset_res = self.resolution
|
||||||
|
if self.random_scaling:
|
||||||
|
# scale 2x to allow for random scaling
|
||||||
|
dataset_res = int(dataset_res * 2)
|
||||||
|
ds['resolution'] = dataset_res
|
||||||
image_dataset = ImageDataset(ds)
|
image_dataset = ImageDataset(ds)
|
||||||
datasets.append(image_dataset)
|
datasets.append(image_dataset)
|
||||||
|
|
||||||
@@ -168,7 +173,7 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
concatenated_dataset,
|
concatenated_dataset,
|
||||||
batch_size=self.batch_size,
|
batch_size=self.batch_size,
|
||||||
shuffle=True,
|
shuffle=True,
|
||||||
num_workers=8
|
num_workers=16
|
||||||
)
|
)
|
||||||
|
|
||||||
def remove_oldest_checkpoint(self):
|
def remove_oldest_checkpoint(self):
|
||||||
@@ -573,6 +578,9 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
epoch_losses = copy.deepcopy(blank_losses)
|
epoch_losses = copy.deepcopy(blank_losses)
|
||||||
log_losses = copy.deepcopy(blank_losses)
|
log_losses = copy.deepcopy(blank_losses)
|
||||||
# range start at self.epoch_num go to self.epochs
|
# range start at self.epoch_num go to self.epochs
|
||||||
|
|
||||||
|
latent_size = self.resolution // self.vae_scale_factor
|
||||||
|
|
||||||
for epoch in range(self.epoch_num, self.epochs, 1):
|
for epoch in range(self.epoch_num, self.epochs, 1):
|
||||||
if self.step_num >= self.max_steps:
|
if self.step_num >= self.max_steps:
|
||||||
break
|
break
|
||||||
@@ -580,9 +588,21 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
if self.step_num >= self.max_steps:
|
if self.step_num >= self.max_steps:
|
||||||
break
|
break
|
||||||
with torch.no_grad():
|
with torch.no_grad():
|
||||||
|
|
||||||
batch = batch.to(self.device, dtype=self.torch_dtype)
|
batch = batch.to(self.device, dtype=self.torch_dtype)
|
||||||
|
|
||||||
|
if self.random_scaling:
|
||||||
|
# only random scale 0.5 of the time
|
||||||
|
if random.random() < 0.5:
|
||||||
|
# random scale the batch
|
||||||
|
scale_factor = 0.25
|
||||||
|
else:
|
||||||
|
scale_factor = 0.5
|
||||||
|
new_size = (int(batch.shape[2] * scale_factor), int(batch.shape[3] * scale_factor))
|
||||||
|
# make sure it is vae divisible
|
||||||
|
new_size = (new_size[0] // self.vae_scale_factor * self.vae_scale_factor,
|
||||||
|
new_size[1] // self.vae_scale_factor * self.vae_scale_factor)
|
||||||
|
|
||||||
|
|
||||||
# resize so it matches size of vae evenly
|
# resize so it matches size of vae evenly
|
||||||
if batch.shape[2] % self.vae_scale_factor != 0 or batch.shape[3] % self.vae_scale_factor != 0:
|
if batch.shape[2] % self.vae_scale_factor != 0 or batch.shape[3] % self.vae_scale_factor != 0:
|
||||||
batch = Resize((batch.shape[2] // self.vae_scale_factor * self.vae_scale_factor,
|
batch = Resize((batch.shape[2] // self.vae_scale_factor * self.vae_scale_factor,
|
||||||
@@ -615,6 +635,11 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
if do_flip_y > 0:
|
if do_flip_y > 0:
|
||||||
latent_chunks[i] = torch.flip(latent_chunks[i], [3])
|
latent_chunks[i] = torch.flip(latent_chunks[i], [3])
|
||||||
batch_chunks[i] = torch.flip(batch_chunks[i], [3])
|
batch_chunks[i] = torch.flip(batch_chunks[i], [3])
|
||||||
|
|
||||||
|
# resize latent to fit
|
||||||
|
if latent_chunks[i].shape[2] != latent_size or latent_chunks[i].shape[3] != latent_size:
|
||||||
|
latent_chunks[i] = torch.nn.functional.interpolate(latent_chunks[i], size=(latent_size, latent_size), mode='bilinear', align_corners=False)
|
||||||
|
|
||||||
# if do_scale > 0:
|
# if do_scale > 0:
|
||||||
# scale = 2
|
# scale = 2
|
||||||
# start_latent_h = latent_chunks[i].shape[2]
|
# start_latent_h = latent_chunks[i].shape[2]
|
||||||
@@ -643,6 +668,10 @@ class TrainVAEProcess(BaseTrainProcess):
|
|||||||
forward_latents = channel_dropout(latents, self.dropout)
|
forward_latents = channel_dropout(latents, self.dropout)
|
||||||
else:
|
else:
|
||||||
forward_latents = latents
|
forward_latents = latents
|
||||||
|
|
||||||
|
# resize batch to resolution if needed
|
||||||
|
if batch_chunks[0].shape[2] != self.resolution or batch_chunks[0].shape[3] != self.resolution:
|
||||||
|
batch_chunks = [torch.nn.functional.interpolate(b, size=(self.resolution, self.resolution), mode='bilinear', align_corners=False) for b in batch_chunks]
|
||||||
batch = torch.cat(batch_chunks, dim=0)
|
batch = torch.cat(batch_chunks, dim=0)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -221,9 +221,14 @@ class Critic:
|
|||||||
return float(np.mean(critic_losses))
|
return float(np.mean(critic_losses))
|
||||||
|
|
||||||
def get_lr(self):
|
def get_lr(self):
|
||||||
if self.optimizer_type.startswith('dadaptation'):
|
if hasattr(self.optimizer, 'get_avg_learning_rate'):
|
||||||
return (
|
learning_rate = self.optimizer.get_avg_learning_rate()
|
||||||
self.optimizer.param_groups[0]["d"]
|
elif self.optimizer_type.startswith('dadaptation') or \
|
||||||
* self.optimizer.param_groups[0]["lr"]
|
self.optimizer_type.lower().startswith('prodigy'):
|
||||||
|
learning_rate = (
|
||||||
|
self.optimizer.param_groups[0]["d"] *
|
||||||
|
self.optimizer.param_groups[0]["lr"]
|
||||||
)
|
)
|
||||||
return self.optimizer.param_groups[0]["lr"]
|
else:
|
||||||
|
learning_rate = self.optimizer.param_groups[0]['lr']
|
||||||
|
return learning_rate
|
||||||
|
|||||||
@@ -255,30 +255,30 @@ class DiffusionFeatureExtractor3(nn.Module):
|
|||||||
dtype = torch.bfloat16
|
dtype = torch.bfloat16
|
||||||
device = self.vae.device
|
device = self.vae.device
|
||||||
|
|
||||||
# first we step the scheduler from current timestep to the very end for a full denoise
|
|
||||||
# bs = noise_pred.shape[0]
|
|
||||||
# noise_pred_chunks = torch.chunk(noise_pred, bs)
|
|
||||||
# timestep_chunks = torch.chunk(timesteps, bs)
|
|
||||||
# noisy_latent_chunks = torch.chunk(noisy_latents, bs)
|
|
||||||
# stepped_chunks = []
|
|
||||||
# for idx in range(bs):
|
|
||||||
# model_output = noise_pred_chunks[idx]
|
|
||||||
# timestep = timestep_chunks[idx]
|
|
||||||
# scheduler._step_index = None
|
|
||||||
# scheduler._init_step_index(timestep)
|
|
||||||
# sample = noisy_latent_chunks[idx].to(torch.float32)
|
|
||||||
|
|
||||||
# sigma = scheduler.sigmas[scheduler.step_index]
|
|
||||||
# sigma_next = scheduler.sigmas[-1] # use last sigma for final step
|
|
||||||
# prev_sample = sample + (sigma_next - sigma) * model_output
|
|
||||||
# stepped_chunks.append(prev_sample)
|
|
||||||
|
|
||||||
# stepped_latents = torch.cat(stepped_chunks, dim=0)
|
|
||||||
|
|
||||||
if model is not None and hasattr(model, 'get_stepped_pred'):
|
if model is not None and hasattr(model, 'get_stepped_pred'):
|
||||||
stepped_latents = model.get_stepped_pred(noise_pred, noise)
|
stepped_latents = model.get_stepped_pred(noise_pred, noise)
|
||||||
else:
|
else:
|
||||||
stepped_latents = noise - noise_pred
|
# stepped_latents = noise - noise_pred
|
||||||
|
# first we step the scheduler from current timestep to the very end for a full denoise
|
||||||
|
bs = noise_pred.shape[0]
|
||||||
|
noise_pred_chunks = torch.chunk(noise_pred, bs)
|
||||||
|
timestep_chunks = torch.chunk(timesteps, bs)
|
||||||
|
noisy_latent_chunks = torch.chunk(noisy_latents, bs)
|
||||||
|
stepped_chunks = []
|
||||||
|
for idx in range(bs):
|
||||||
|
model_output = noise_pred_chunks[idx]
|
||||||
|
timestep = timestep_chunks[idx]
|
||||||
|
scheduler._step_index = None
|
||||||
|
scheduler._init_step_index(timestep)
|
||||||
|
sample = noisy_latent_chunks[idx].to(torch.float32)
|
||||||
|
|
||||||
|
sigma = scheduler.sigmas[scheduler.step_index]
|
||||||
|
sigma_next = scheduler.sigmas[-1] # use last sigma for final step
|
||||||
|
prev_sample = sample + (sigma_next - sigma) * model_output
|
||||||
|
stepped_chunks.append(prev_sample)
|
||||||
|
|
||||||
|
stepped_latents = torch.cat(stepped_chunks, dim=0)
|
||||||
|
|
||||||
latents = stepped_latents.to(self.vae.device, dtype=self.vae.dtype)
|
latents = stepped_latents.to(self.vae.device, dtype=self.vae.dtype)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user