From c8d209d36c71c28416cb3a5eec43a00b8e129f99 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 10:29:48 +0900 Subject: [PATCH 001/220] update diffusers to 1.16 | train_network --- library/attention_processors.py | 227 ++++++++++++++++++++++++++++++++ library/hypernetwork.py | 223 +++++++++++++++++++++++++++++++ library/lpw_stable_diffusion.py | 2 +- library/train_util.py | 205 +--------------------------- networks/lora.py | 2 +- requirements.txt | 6 +- train_network.py | 45 +++---- 7 files changed, 482 insertions(+), 228 deletions(-) create mode 100644 library/attention_processors.py create mode 100644 library/hypernetwork.py diff --git a/library/attention_processors.py b/library/attention_processors.py new file mode 100644 index 000000000..310c2cb1c --- /dev/null +++ b/library/attention_processors.py @@ -0,0 +1,227 @@ +import math +from typing import Any +from einops import rearrange +import torch +from diffusers.models.attention_processor import Attention + + +# flash attention forwards and backwards + +# https://arxiv.org/abs/2205.14135 + +EPSILON = 1e-6 + + +class FlashAttentionFunction(torch.autograd.function.Function): + @staticmethod + @torch.no_grad() + def forward(ctx, q, k, v, mask, causal, q_bucket_size, k_bucket_size): + """Algorithm 2 in the paper""" + + device = q.device + dtype = q.dtype + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + o = torch.zeros_like(q) + all_row_sums = torch.zeros((*q.shape[:-1], 1), dtype=dtype, device=device) + all_row_maxes = torch.full( + (*q.shape[:-1], 1), max_neg_value, dtype=dtype, device=device + ) + + scale = q.shape[-1] ** -0.5 + + if mask is None: + mask = (None,) * math.ceil(q.shape[-2] / q_bucket_size) + else: + mask = rearrange(mask, "b n -> b 1 1 n") + mask = mask.split(q_bucket_size, dim=-1) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + mask, + all_row_sums.split(q_bucket_size, dim=-2), + all_row_maxes.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, row_mask, row_sums, row_maxes) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = ( + torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale + ) + + if row_mask is not None: + attn_weights.masked_fill_(~row_mask, max_neg_value) + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones( + (qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device + ).triu(q_start_index - k_start_index + 1) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + block_row_maxes = attn_weights.amax(dim=-1, keepdims=True) + attn_weights -= block_row_maxes + exp_weights = torch.exp(attn_weights) + + if row_mask is not None: + exp_weights.masked_fill_(~row_mask, 0.0) + + block_row_sums = exp_weights.sum(dim=-1, keepdims=True).clamp( + min=EPSILON + ) + + new_row_maxes = torch.maximum(block_row_maxes, row_maxes) + + exp_values = torch.einsum( + "... i j, ... j d -> ... i d", exp_weights, vc + ) + + exp_row_max_diff = torch.exp(row_maxes - new_row_maxes) + exp_block_row_max_diff = torch.exp(block_row_maxes - new_row_maxes) + + new_row_sums = ( + exp_row_max_diff * row_sums + + exp_block_row_max_diff * block_row_sums + ) + + oc.mul_((row_sums / new_row_sums) * exp_row_max_diff).add_( + (exp_block_row_max_diff / new_row_sums) * exp_values + ) + + row_maxes.copy_(new_row_maxes) + row_sums.copy_(new_row_sums) + + ctx.args = (causal, scale, mask, q_bucket_size, k_bucket_size) + ctx.save_for_backward(q, k, v, o, all_row_sums, all_row_maxes) + + return o + + @staticmethod + @torch.no_grad() + def backward(ctx, do): + """Algorithm 4 in the paper""" + + causal, scale, mask, q_bucket_size, k_bucket_size = ctx.args + q, k, v, o, l, m = ctx.saved_tensors + + device = q.device + + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + dq = torch.zeros_like(q) + dk = torch.zeros_like(k) + dv = torch.zeros_like(v) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + do.split(q_bucket_size, dim=-2), + mask, + l.split(q_bucket_size, dim=-2), + m.split(q_bucket_size, dim=-2), + dq.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, doc, row_mask, lc, mc, dqc) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + dk.split(k_bucket_size, dim=-2), + dv.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = ( + torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale + ) + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones( + (qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device + ).triu(q_start_index - k_start_index + 1) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + exp_attn_weights = torch.exp(attn_weights - mc) + + if row_mask is not None: + exp_attn_weights.masked_fill_(~row_mask, 0.0) + + p = exp_attn_weights / lc + + dv_chunk = torch.einsum("... i j, ... i d -> ... j d", p, doc) + dp = torch.einsum("... i d, ... j d -> ... i j", doc, vc) + + D = (doc * oc).sum(dim=-1, keepdims=True) + ds = p * scale * (dp - D) + + dq_chunk = torch.einsum("... i j, ... j d -> ... i d", ds, kc) + dk_chunk = torch.einsum("... i j, ... i d -> ... j d", ds, qc) + + dqc.add_(dq_chunk) + dkc.add_(dk_chunk) + dvc.add_(dv_chunk) + + return dq, dk, dv, None, None, None, None + + +class FlashAttnProcessor: + def __call__( + self, + attn: Attention, + hidden_states, + encoder_hidden_states=None, + attention_mask=None, + ) -> Any: + q_bucket_size = 512 + k_bucket_size = 1024 + + h = attn.heads + q = attn.to_q(hidden_states) + + encoder_hidden_states = ( + encoder_hidden_states + if encoder_hidden_states is not None + else hidden_states + ) + encoder_hidden_states = encoder_hidden_states.to(hidden_states.dtype) + + if hasattr(attn, "hypernetwork") and attn.hypernetwork is not None: + context_k, context_v = attn.hypernetwork.forward( + hidden_states, encoder_hidden_states + ) + context_k = context_k.to(hidden_states.dtype) + context_v = context_v.to(hidden_states.dtype) + else: + context_k = encoder_hidden_states + context_v = encoder_hidden_states + + k = attn.to_k(context_k) + v = attn.to_v(context_v) + del encoder_hidden_states, hidden_states + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) + + out = FlashAttentionFunction.apply( + q, k, v, attention_mask, False, q_bucket_size, k_bucket_size + ) + + out = rearrange(out, "b h n d -> b n (h d)") + + out = attn.to_out[0](out) + out = attn.to_out[1](out) + return out diff --git a/library/hypernetwork.py b/library/hypernetwork.py new file mode 100644 index 000000000..fbd3fb24e --- /dev/null +++ b/library/hypernetwork.py @@ -0,0 +1,223 @@ +import torch +import torch.nn.functional as F +from diffusers.models.attention_processor import ( + Attention, + AttnProcessor2_0, + SlicedAttnProcessor, + XFormersAttnProcessor +) + +try: + import xformers.ops +except: + xformers = None + + +loaded_networks = [] + + +def apply_single_hypernetwork( + hypernetwork, hidden_states, encoder_hidden_states +): + context_k, context_v = hypernetwork.forward(hidden_states, encoder_hidden_states) + return context_k, context_v + + +def apply_hypernetworks(context_k, context_v, layer=None): + if len(loaded_networks) == 0: + return context_v, context_v + for hypernetwork in loaded_networks: + context_k, context_v = hypernetwork.forward(context_k, context_v) + + context_k = context_k.to(dtype=context_k.dtype) + context_v = context_v.to(dtype=context_k.dtype) + + return context_k, context_v + + + +def xformers_forward( + self: XFormersAttnProcessor, + attn: Attention, + hidden_states: torch.Tensor, + encoder_hidden_states: torch.Tensor = None, + attention_mask: torch.Tensor = None, +): + batch_size, sequence_length, _ = ( + hidden_states.shape + if encoder_hidden_states is None + else encoder_hidden_states.shape + ) + + attention_mask = attn.prepare_attention_mask( + attention_mask, sequence_length, batch_size + ) + + query = attn.to_q(hidden_states) + + if encoder_hidden_states is None: + encoder_hidden_states = hidden_states + elif attn.norm_cross: + encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + + context_k, context_v = apply_hypernetworks(hidden_states, encoder_hidden_states) + + key = attn.to_k(context_k) + value = attn.to_v(context_v) + + query = attn.head_to_batch_dim(query).contiguous() + key = attn.head_to_batch_dim(key).contiguous() + value = attn.head_to_batch_dim(value).contiguous() + + hidden_states = xformers.ops.memory_efficient_attention( + query, + key, + value, + attn_bias=attention_mask, + op=self.attention_op, + scale=attn.scale, + ) + hidden_states = hidden_states.to(query.dtype) + hidden_states = attn.batch_to_head_dim(hidden_states) + + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + return hidden_states + + +def sliced_attn_forward( + self: SlicedAttnProcessor, + attn: Attention, + hidden_states: torch.Tensor, + encoder_hidden_states: torch.Tensor = None, + attention_mask: torch.Tensor = None, +): + batch_size, sequence_length, _ = ( + hidden_states.shape + if encoder_hidden_states is None + else encoder_hidden_states.shape + ) + attention_mask = attn.prepare_attention_mask( + attention_mask, sequence_length, batch_size + ) + + query = attn.to_q(hidden_states) + dim = query.shape[-1] + query = attn.head_to_batch_dim(query) + + if encoder_hidden_states is None: + encoder_hidden_states = hidden_states + elif attn.norm_cross: + encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + + context_k, context_v = apply_hypernetworks(hidden_states, encoder_hidden_states) + + key = attn.to_k(context_k) + value = attn.to_v(context_v) + key = attn.head_to_batch_dim(key) + value = attn.head_to_batch_dim(value) + + batch_size_attention, query_tokens, _ = query.shape + hidden_states = torch.zeros( + (batch_size_attention, query_tokens, dim // attn.heads), + device=query.device, + dtype=query.dtype, + ) + + for i in range(batch_size_attention // self.slice_size): + start_idx = i * self.slice_size + end_idx = (i + 1) * self.slice_size + + query_slice = query[start_idx:end_idx] + key_slice = key[start_idx:end_idx] + attn_mask_slice = ( + attention_mask[start_idx:end_idx] if attention_mask is not None else None + ) + + attn_slice = attn.get_attention_scores(query_slice, key_slice, attn_mask_slice) + + attn_slice = torch.bmm(attn_slice, value[start_idx:end_idx]) + + hidden_states[start_idx:end_idx] = attn_slice + + hidden_states = attn.batch_to_head_dim(hidden_states) + + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + + return hidden_states + + +def v2_0_forward( + self: AttnProcessor2_0, + attn: Attention, + hidden_states, + encoder_hidden_states=None, + attention_mask=None, +): + batch_size, sequence_length, _ = ( + hidden_states.shape + if encoder_hidden_states is None + else encoder_hidden_states.shape + ) + inner_dim = hidden_states.shape[-1] + + if attention_mask is not None: + attention_mask = attn.prepare_attention_mask( + attention_mask, sequence_length, batch_size + ) + # scaled_dot_product_attention expects attention_mask shape to be + # (batch, heads, source_length, target_length) + attention_mask = attention_mask.view( + batch_size, attn.heads, -1, attention_mask.shape[-1] + ) + + query = attn.to_q(hidden_states) + + if encoder_hidden_states is None: + encoder_hidden_states = hidden_states + elif attn.norm_cross: + encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states) + + context_k, context_v = apply_hypernetworks(hidden_states, encoder_hidden_states) + + key = attn.to_k(context_k) + value = attn.to_v(context_v) + + head_dim = inner_dim // attn.heads + query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2) + + # the output of sdp = (batch, num_heads, seq_len, head_dim) + # TODO: add support for attn.scale when we move to Torch 2.1 + hidden_states = F.scaled_dot_product_attention( + query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False + ) + + hidden_states = hidden_states.transpose(1, 2).reshape( + batch_size, -1, attn.heads * head_dim + ) + hidden_states = hidden_states.to(query.dtype) + + # linear proj + hidden_states = attn.to_out[0](hidden_states) + # dropout + hidden_states = attn.to_out[1](hidden_states) + return hidden_states + + +def replace_attentions_for_hypernetwork(): + import diffusers.models.attention_processor + + diffusers.models.attention_processor.XFormersAttnProcessor.__call__ = ( + xformers_forward + ) + diffusers.models.attention_processor.SlicedAttnProcessor.__call__ = ( + sliced_attn_forward + ) + diffusers.models.attention_processor.AttnProcessor2_0.__call__ = v2_0_forward diff --git a/library/lpw_stable_diffusion.py b/library/lpw_stable_diffusion.py index 3e04b8876..84e1ab151 100644 --- a/library/lpw_stable_diffusion.py +++ b/library/lpw_stable_diffusion.py @@ -464,10 +464,10 @@ def __init__( tokenizer: CLIPTokenizer, unet: UNet2DConditionModel, scheduler: SchedulerMixin, - clip_skip: int, safety_checker: StableDiffusionSafetyChecker, feature_extractor: CLIPFeatureExtractor, requires_safety_checker: bool = True, + clip_skip: int = 1, ): super().__init__( vae=vae, diff --git a/library/train_util.py b/library/train_util.py index 46c5c3b2d..008ccd64f 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -63,6 +63,8 @@ from library.lpw_stable_diffusion import StableDiffusionLongPromptWeightingPipeline import library.model_util as model_util import library.huggingface_util as huggingface_util +from library.attention_processors import FlashAttnProcessor +from library.hypernetwork import replace_attentions_for_hypernetwork # Tokenizer: checkpointから読み込むのではなくあらかじめ提供されているものを使う TOKENIZER_PATH = "openai/clip-vit-large-patch14" @@ -1630,209 +1632,14 @@ def get_git_revision_hash() -> str: return "(unknown)" -# flash attention forwards and backwards - -# https://arxiv.org/abs/2205.14135 - - -class FlashAttentionFunction(torch.autograd.function.Function): - @staticmethod - @torch.no_grad() - def forward(ctx, q, k, v, mask, causal, q_bucket_size, k_bucket_size): - """Algorithm 2 in the paper""" - - device = q.device - dtype = q.dtype - max_neg_value = -torch.finfo(q.dtype).max - qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) - - o = torch.zeros_like(q) - all_row_sums = torch.zeros((*q.shape[:-1], 1), dtype=dtype, device=device) - all_row_maxes = torch.full((*q.shape[:-1], 1), max_neg_value, dtype=dtype, device=device) - - scale = q.shape[-1] ** -0.5 - - if not exists(mask): - mask = (None,) * math.ceil(q.shape[-2] / q_bucket_size) - else: - mask = rearrange(mask, "b n -> b 1 1 n") - mask = mask.split(q_bucket_size, dim=-1) - - row_splits = zip( - q.split(q_bucket_size, dim=-2), - o.split(q_bucket_size, dim=-2), - mask, - all_row_sums.split(q_bucket_size, dim=-2), - all_row_maxes.split(q_bucket_size, dim=-2), - ) - - for ind, (qc, oc, row_mask, row_sums, row_maxes) in enumerate(row_splits): - q_start_index = ind * q_bucket_size - qk_len_diff - - col_splits = zip( - k.split(k_bucket_size, dim=-2), - v.split(k_bucket_size, dim=-2), - ) - - for k_ind, (kc, vc) in enumerate(col_splits): - k_start_index = k_ind * k_bucket_size - - attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale - - if exists(row_mask): - attn_weights.masked_fill_(~row_mask, max_neg_value) - - if causal and q_start_index < (k_start_index + k_bucket_size - 1): - causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( - q_start_index - k_start_index + 1 - ) - attn_weights.masked_fill_(causal_mask, max_neg_value) - - block_row_maxes = attn_weights.amax(dim=-1, keepdims=True) - attn_weights -= block_row_maxes - exp_weights = torch.exp(attn_weights) - - if exists(row_mask): - exp_weights.masked_fill_(~row_mask, 0.0) - - block_row_sums = exp_weights.sum(dim=-1, keepdims=True).clamp(min=EPSILON) - - new_row_maxes = torch.maximum(block_row_maxes, row_maxes) - - exp_values = einsum("... i j, ... j d -> ... i d", exp_weights, vc) - - exp_row_max_diff = torch.exp(row_maxes - new_row_maxes) - exp_block_row_max_diff = torch.exp(block_row_maxes - new_row_maxes) - - new_row_sums = exp_row_max_diff * row_sums + exp_block_row_max_diff * block_row_sums - - oc.mul_((row_sums / new_row_sums) * exp_row_max_diff).add_((exp_block_row_max_diff / new_row_sums) * exp_values) - - row_maxes.copy_(new_row_maxes) - row_sums.copy_(new_row_sums) - - ctx.args = (causal, scale, mask, q_bucket_size, k_bucket_size) - ctx.save_for_backward(q, k, v, o, all_row_sums, all_row_maxes) - - return o - - @staticmethod - @torch.no_grad() - def backward(ctx, do): - """Algorithm 4 in the paper""" - - causal, scale, mask, q_bucket_size, k_bucket_size = ctx.args - q, k, v, o, l, m = ctx.saved_tensors - - device = q.device - - max_neg_value = -torch.finfo(q.dtype).max - qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) - - dq = torch.zeros_like(q) - dk = torch.zeros_like(k) - dv = torch.zeros_like(v) - - row_splits = zip( - q.split(q_bucket_size, dim=-2), - o.split(q_bucket_size, dim=-2), - do.split(q_bucket_size, dim=-2), - mask, - l.split(q_bucket_size, dim=-2), - m.split(q_bucket_size, dim=-2), - dq.split(q_bucket_size, dim=-2), - ) - - for ind, (qc, oc, doc, row_mask, lc, mc, dqc) in enumerate(row_splits): - q_start_index = ind * q_bucket_size - qk_len_diff - - col_splits = zip( - k.split(k_bucket_size, dim=-2), - v.split(k_bucket_size, dim=-2), - dk.split(k_bucket_size, dim=-2), - dv.split(k_bucket_size, dim=-2), - ) - - for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): - k_start_index = k_ind * k_bucket_size - - attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale - - if causal and q_start_index < (k_start_index + k_bucket_size - 1): - causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( - q_start_index - k_start_index + 1 - ) - attn_weights.masked_fill_(causal_mask, max_neg_value) - - exp_attn_weights = torch.exp(attn_weights - mc) - - if exists(row_mask): - exp_attn_weights.masked_fill_(~row_mask, 0.0) - - p = exp_attn_weights / lc - - dv_chunk = einsum("... i j, ... i d -> ... j d", p, doc) - dp = einsum("... i d, ... j d -> ... i j", doc, vc) - - D = (doc * oc).sum(dim=-1, keepdims=True) - ds = p * scale * (dp - D) - - dq_chunk = einsum("... i j, ... j d -> ... i d", ds, kc) - dk_chunk = einsum("... i j, ... i d -> ... j d", ds, qc) - - dqc.add_(dq_chunk) - dkc.add_(dk_chunk) - dvc.add_(dv_chunk) - - return dq, dk, dv, None, None, None, None - def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): + replace_attentions_for_hypernetwork() # unet is not used currently, but it is here for future use if mem_eff_attn: - replace_unet_cross_attn_to_memory_efficient() + unet.set_attn_processor(FlashAttnProcessor()) elif xformers: - replace_unet_cross_attn_to_xformers() - - -def replace_unet_cross_attn_to_memory_efficient(): - print("CrossAttention.forward has been replaced to FlashAttention (not xformers)") - flash_func = FlashAttentionFunction - - def forward_flash_attn(self, x, context=None, mask=None): - q_bucket_size = 512 - k_bucket_size = 1024 - - h = self.heads - q = self.to_q(x) - - context = context if context is not None else x - context = context.to(x.dtype) - - if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - context_k, context_v = self.hypernetwork.forward(x, context) - context_k = context_k.to(x.dtype) - context_v = context_v.to(x.dtype) - else: - context_k = context - context_v = context - - k = self.to_k(context_k) - v = self.to_v(context_v) - del context, x - - q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) - - out = flash_func.apply(q, k, v, mask, False, q_bucket_size, k_bucket_size) - - out = rearrange(out, "b h n d -> b n (h d)") - - # diffusers 0.7.0~ わざわざ変えるなよ (;´Д`) - out = self.to_out[0](out) - out = self.to_out[1](out) - return out - - diffusers.models.attention.CrossAttention.forward = forward_flash_attn + unet.enable_xformers_memory_efficient_attention() def replace_unet_cross_attn_to_xformers(): @@ -3458,10 +3265,10 @@ def sample_images( unet=unet, tokenizer=tokenizer, scheduler=scheduler, - clip_skip=args.clip_skip, safety_checker=None, feature_extractor=None, requires_safety_checker=False, + clip_skip=args.clip_skip, ) pipeline.to(device) diff --git a/networks/lora.py b/networks/lora.py index 19fbbbdb5..3a475e253 100644 --- a/networks/lora.py +++ b/networks/lora.py @@ -665,7 +665,7 @@ class LoRANetwork(torch.nn.Module): NUM_OF_BLOCKS = 12 # フルモデル相当でのup,downの層の数 # is it possible to apply conv_in and conv_out? -> yes, newer LoCon supports it (^^;) - UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel", "Attention"] + UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel"] UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 = ["ResnetBlock2D", "Downsample2D", "Upsample2D"] TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"] LORA_PREFIX_UNET = "lora_unet" diff --git a/requirements.txt b/requirements.txt index 801cf321b..96da36a0d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -accelerate==0.15.0 -transformers==4.26.0 +accelerate==0.19.0 +transformers==4.29.2 +diffusers[torch]==0.16.1 ftfy==6.1.1 albumentations==1.3.0 opencv-python==4.7.0.68 einops==0.6.0 -diffusers[torch]==0.10.2 pytorch-lightning==1.9.0 bitsandbytes==0.35.0 tensorboard==2.10.1 diff --git a/train_network.py b/train_network.py index cd90b0a20..109d1ff2a 100644 --- a/train_network.py +++ b/train_network.py @@ -6,7 +6,6 @@ import random import time import json -import toml from multiprocessing import Value from tqdm import tqdm @@ -165,7 +164,7 @@ def train(args): import sys sys.path.append(os.path.dirname(__file__)) - print("import network module:", args.network_module) + accelerator.print("import network module:", args.network_module) network_module = importlib.import_module(args.network_module) if args.base_weights is not None: @@ -176,14 +175,15 @@ def train(args): else: multiplier = args.base_weights_multiplier[i] - print(f"merging module: {weight_path} with multiplier {multiplier}") + accelerator.print(f"merging module: {weight_path} with multiplier {multiplier}") module, weights_sd = network_module.create_network_from_weights( multiplier, weight_path, vae, text_encoder, unet, for_inference=True ) module.merge_to(text_encoder, unet, weights_sd, weight_dtype, accelerator.device if args.lowram else "cpu") - print(f"all weights merged: {', '.join(args.base_weights)}") + accelerator.print(f"all weights merged: {', '.join(args.base_weights)}") + # 学習を準備する if cache_latents: vae.to(accelerator.device, dtype=weight_dtype) @@ -225,7 +225,7 @@ def train(args): if args.network_weights is not None: info = network.load_weights(args.network_weights) - print(f"loaded network weights from {args.network_weights}: {info}") + accelerator.print(f"load network weights from {args.network_weights}: {info}") if args.gradient_checkpointing: unet.enable_gradient_checkpointing() @@ -233,13 +233,13 @@ def train(args): network.enable_gradient_checkpointing() # may have no effect # 学習に必要なクラスを準備する - print("preparing optimizer, data loader etc.") + accelerator.print("prepare optimizer, data loader etc.") # 後方互換性を確保するよ try: trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr, args.learning_rate) except TypeError: - print( + accelerator.print( "Deprecated: use prepare_optimizer_params(text_encoder_lr, unet_lr, learning_rate) instead of prepare_optimizer_params(text_encoder_lr, unet_lr)" ) trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr) @@ -264,8 +264,7 @@ def train(args): args.max_train_steps = args.max_train_epochs * math.ceil( len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps ) - if is_main_process: - print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) @@ -278,7 +277,7 @@ def train(args): assert ( args.mixed_precision == "fp16" ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" - print("enabling full fp16 training.") + accelerator.print("enable full fp16 training.") network.to(weight_dtype) # acceleratorがなんかよろしくやってくれるらしい @@ -338,16 +337,15 @@ def train(args): # TODO: find a way to handle total batch size when there are multiple datasets total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - if is_main_process: - print("running training / 学習開始") - print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") - print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - print(f" num epochs / epoch数: {num_train_epochs}") - print(f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}") - # print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + accelerator.print("running training / 学習開始") + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}") + # accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") # TODO refactor metadata creation and move to util metadata = { @@ -572,7 +570,7 @@ def save_model(ckpt_name, unwrapped_nw, steps, epoch_no, force_sync_upload=False os.makedirs(args.output_dir, exist_ok=True) ckpt_file = os.path.join(args.output_dir, ckpt_name) - print(f"\nsaving checkpoint: {ckpt_file}") + accelerator.print(f"\nsaving checkpoint: {ckpt_file}") metadata["ss_training_finished_at"] = str(time.time()) metadata["ss_steps"] = str(steps) metadata["ss_epoch"] = str(epoch_no) @@ -584,13 +582,12 @@ def save_model(ckpt_name, unwrapped_nw, steps, epoch_no, force_sync_upload=False def remove_model(old_ckpt_name): old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) if os.path.exists(old_ckpt_file): - print(f"removing old checkpoint: {old_ckpt_file}") + accelerator.print(f"removing old checkpoint: {old_ckpt_file}") os.remove(old_ckpt_file) # training loop for epoch in range(num_train_epochs): - if is_main_process: - print(f"\nepoch {epoch+1}/{num_train_epochs}") + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") current_epoch.value = epoch + 1 metadata["ss_epoch"] = str(epoch + 1) From 1f1cae6c5a1c55af9578ddfeda7dcfb0d1e1c2f3 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 10:32:34 +0900 Subject: [PATCH 002/220] make the device of `snr_weight` the same as loss --- library/custom_train_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/custom_train_functions.py b/library/custom_train_functions.py index f32f050eb..fa24f9fa1 100644 --- a/library/custom_train_functions.py +++ b/library/custom_train_functions.py @@ -14,7 +14,7 @@ def apply_snr_weight(loss, timesteps, noise_scheduler, gamma): all_snr = (alpha / sigma) ** 2 snr = torch.stack([all_snr[t] for t in timesteps]) gamma_over_snr = torch.div(torch.ones_like(snr) * gamma, snr) - snr_weight = torch.minimum(gamma_over_snr, torch.ones_like(gamma_over_snr)).float() # from paper + snr_weight = torch.minimum(gamma_over_snr, torch.ones_like(gamma_over_snr)).float().to(loss.device) # from paper loss = loss * snr_weight return loss From 23c4e5cb016a37840919573774838809985ff25a Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 10:37:23 +0900 Subject: [PATCH 003/220] update diffusers to 1.16 | train_textual_inversion --- train_textual_inversion.py | 59 ++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index b73027de5..3d0284423 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -1,15 +1,12 @@ -import importlib import argparse import gc import math import os -import toml from multiprocessing import Value from tqdm import tqdm import torch from accelerate.utils import set_seed -import diffusers from diffusers import DDPMScheduler import library.train_util as train_util @@ -104,7 +101,7 @@ def train(args): if args.init_word is not None: init_token_ids = tokenizer.encode(args.init_word, add_special_tokens=False) if len(init_token_ids) > 1 and len(init_token_ids) != args.num_vectors_per_token: - print( + accelerator.print( f"token length for init words is not same to num_vectors_per_token, init words is repeated or truncated / 初期化単語のトークン長がnum_vectors_per_tokenと合わないため、繰り返しまたは切り捨てが発生します: length {len(init_token_ids)}" ) else: @@ -118,7 +115,7 @@ def train(args): ), f"tokenizer has same word to token string. please use another one / 指定したargs.token_stringは既に存在します。別の単語を使ってください: {args.token_string}" token_ids = tokenizer.convert_tokens_to_ids(token_strings) - print(f"tokens are added: {token_ids}") + accelerator.print(f"tokens are added: {token_ids}") assert min(token_ids) == token_ids[0] and token_ids[-1] == token_ids[0] + len(token_ids) - 1, f"token ids is not ordered" assert len(tokenizer) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer)}" @@ -130,7 +127,7 @@ def train(args): if init_token_ids is not None: for i, token_id in enumerate(token_ids): token_embeds[token_id] = token_embeds[init_token_ids[i % len(init_token_ids)]] - # print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) + # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) # load weights if args.weights is not None: @@ -138,22 +135,22 @@ def train(args): assert len(token_ids) == len( embeddings ), f"num_vectors_per_token is mismatch for weights / 指定した重みとnum_vectors_per_tokenの値が異なります: {len(embeddings)}" - # print(token_ids, embeddings.size()) + # accelerator.print(token_ids, embeddings.size()) for token_id, embedding in zip(token_ids, embeddings): token_embeds[token_id] = embedding - # print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) - print(f"weighs loaded") + # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) + accelerator.print(f"weighs loaded") - print(f"create embeddings for {args.num_vectors_per_token} tokens, for {args.token_string}") + accelerator.print(f"create embeddings for {args.num_vectors_per_token} tokens, for {args.token_string}") # データセットを準備する blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False)) if args.dataset_config is not None: - print(f"Load dataset config from {args.dataset_config}") + accelerator.print(f"Load dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) ignored = ["train_data_dir", "reg_data_dir", "in_json"] if any(getattr(args, attr) is not None for attr in ignored): - print( + accelerator.print( "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( ", ".join(ignored) ) @@ -161,14 +158,14 @@ def train(args): else: use_dreambooth_method = args.in_json is None if use_dreambooth_method: - print("Use DreamBooth method.") + accelerator.print("Use DreamBooth method.") user_config = { "datasets": [ {"subsets": config_util.generate_dreambooth_subsets_config_by_subdirs(args.train_data_dir, args.reg_data_dir)} ] } else: - print("Train with captions.") + accelerator.print("Train with captions.") user_config = { "datasets": [ { @@ -192,7 +189,7 @@ def train(args): # make captions: tokenstring tokenstring1 tokenstring2 ...tokenstringn という文字列に書き換える超乱暴な実装 if use_template: - print("use template for training captions. is object: {args.use_object_template}") + accelerator.print("use template for training captions. is object: {args.use_object_template}") templates = imagenet_templates_small if args.use_object_template else imagenet_style_templates_small replace_to = " ".join(token_strings) captions = [] @@ -216,7 +213,7 @@ def train(args): train_util.debug_dataset(train_dataset_group, show_input_ids=True) return if len(train_dataset_group) == 0: - print("No data found. Please verify arguments / 画像がありません。引数指定を確認してください") + accelerator.print("No data found. Please verify arguments / 画像がありません。引数指定を確認してください") return if cache_latents: @@ -246,7 +243,7 @@ def train(args): text_encoder.gradient_checkpointing_enable() # 学習に必要なクラスを準備する - print("prepare optimizer, data loader etc.") + accelerator.print("prepare optimizer, data loader etc.") trainable_params = text_encoder.get_input_embeddings().parameters() _, _, optimizer = train_util.get_optimizer(args, trainable_params) @@ -267,7 +264,7 @@ def train(args): args.max_train_steps = args.max_train_epochs * math.ceil( len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps ) - print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) @@ -284,7 +281,7 @@ def train(args): text_encoder, unet = train_util.transform_if_model_is_DDP(text_encoder, unet) index_no_updates = torch.arange(len(tokenizer)) < token_ids[0] - # print(len(index_no_updates), torch.sum(index_no_updates)) + # accelerator.print(len(index_no_updates), torch.sum(index_no_updates)) orig_embeds_params = unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() # Freeze all parameters except for the token embeddings in text encoder @@ -322,15 +319,15 @@ def train(args): # 学習する total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - print("running training / 学習開始") - print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") - print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - print(f" num epochs / epoch数: {num_train_epochs}") - print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + accelerator.print("running training / 学習開始") + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") + accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") global_step = 0 @@ -347,7 +344,7 @@ def save_model(ckpt_name, embs, steps, epoch_no, force_sync_upload=False): os.makedirs(args.output_dir, exist_ok=True) ckpt_file = os.path.join(args.output_dir, ckpt_name) - print(f"\nsaving checkpoint: {ckpt_file}") + accelerator.print(f"\nsaving checkpoint: {ckpt_file}") save_weights(ckpt_file, embs, save_dtype) if args.huggingface_repo_id is not None: huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) @@ -355,12 +352,12 @@ def save_model(ckpt_name, embs, steps, epoch_no, force_sync_upload=False): def remove_model(old_ckpt_name): old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) if os.path.exists(old_ckpt_file): - print(f"removing old checkpoint: {old_ckpt_file}") + accelerator.print(f"removing old checkpoint: {old_ckpt_file}") os.remove(old_ckpt_file) # training loop for epoch in range(num_train_epochs): - print(f"\nepoch {epoch+1}/{num_train_epochs}") + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") current_epoch.value = epoch + 1 text_encoder.train() From e743ee5d5cf7fa7e8b97ae9c22ffb04813140e70 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 10:40:58 +0900 Subject: [PATCH 004/220] update diffusers to 1.16 | dylora --- networks/dylora.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networks/dylora.py b/networks/dylora.py index 90b509dfc..e5a55d198 100644 --- a/networks/dylora.py +++ b/networks/dylora.py @@ -239,7 +239,7 @@ def create_network_from_weights(multiplier, file, vae, text_encoder, unet, weigh class DyLoRANetwork(torch.nn.Module): - UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel", "Attention"] + UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel"] UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 = ["ResnetBlock2D", "Downsample2D", "Upsample2D"] TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"] LORA_PREFIX_UNET = "lora_unet" From 1214f35985b233788d835b7380b4c315f18d59bb Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 20:15:06 +0900 Subject: [PATCH 005/220] update diffusers to 1.16 | train_db --- train_db.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/train_db.py b/train_db.py index 7ec06354b..2fd1c7c58 100644 --- a/train_db.py +++ b/train_db.py @@ -2,18 +2,15 @@ # XXX dropped option: fine_tune import gc -import time import argparse import itertools import math import os -import toml from multiprocessing import Value from tqdm import tqdm import torch from accelerate.utils import set_seed -import diffusers from diffusers import DDPMScheduler import library.train_util as train_util @@ -138,7 +135,7 @@ def train(args): unet.requires_grad_(True) # 念のため追加 text_encoder.requires_grad_(train_text_encoder) if not train_text_encoder: - print("Text Encoder is not trained.") + accelerator.print("Text Encoder is not trained.") if args.gradient_checkpointing: unet.enable_gradient_checkpointing() @@ -150,7 +147,7 @@ def train(args): vae.to(accelerator.device, dtype=weight_dtype) # 学習に必要なクラスを準備する - print("prepare optimizer, data loader etc.") + accelerator.print("prepare optimizer, data loader etc.") if train_text_encoder: trainable_params = itertools.chain(unet.parameters(), text_encoder.parameters()) else: @@ -175,7 +172,7 @@ def train(args): args.max_train_steps = args.max_train_epochs * math.ceil( len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps ) - print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) @@ -191,7 +188,7 @@ def train(args): assert ( args.mixed_precision == "fp16" ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" - print("enable full fp16 training.") + accelerator.print("enable full fp16 training.") unet.to(weight_dtype) text_encoder.to(weight_dtype) @@ -224,15 +221,15 @@ def train(args): # 学習する total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - print("running training / 学習開始") - print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") - print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - print(f" num epochs / epoch数: {num_train_epochs}") - print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + accelerator.print("running training / 学習開始") + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") + accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") global_step = 0 @@ -247,7 +244,7 @@ def train(args): loss_list = [] loss_total = 0.0 for epoch in range(num_train_epochs): - print(f"\nepoch {epoch+1}/{num_train_epochs}") + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") current_epoch.value = epoch + 1 # 指定したステップ数までText Encoderを学習する:epoch最初の状態 @@ -260,7 +257,7 @@ def train(args): current_step.value = global_step # 指定したステップ数でText Encoderの学習を止める if global_step == args.stop_text_encoder_training: - print(f"stop text encoder training at step {global_step}") + accelerator.print(f"stop text encoder training at step {global_step}") if not args.gradient_checkpointing: text_encoder.train(False) text_encoder.requires_grad_(False) From 4f8ce004772cf11053da921527637512ca47a21c Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 20:47:54 +0900 Subject: [PATCH 006/220] update diffusers to 1.16 | finetune --- fine_tune.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/fine_tune.py b/fine_tune.py index 154d3be72..61c5d28e9 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -5,13 +5,11 @@ import gc import math import os -import toml from multiprocessing import Value from tqdm import tqdm import torch from accelerate.utils import set_seed -import diffusers from diffusers import DDPMScheduler import library.train_util as train_util @@ -128,11 +126,11 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # モデルに xformers とか memory efficient attention を組み込む if args.diffusers_xformers: - print("Use xformers by Diffusers") + accelerator.print("Use xformers by Diffusers") set_diffusers_xformers_flag(unet, True) else: # Windows版のxformersはfloatで学習できないのでxformersを使わない設定も可能にしておく必要がある - print("Disable Diffusers' xformers") + accelerator.print("Disable Diffusers' xformers") set_diffusers_xformers_flag(unet, False) train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) @@ -157,7 +155,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): training_models.append(unet) if args.train_text_encoder: - print("enable text encoder training") + accelerator.print("enable text encoder training") if args.gradient_checkpointing: text_encoder.gradient_checkpointing_enable() training_models.append(text_encoder) @@ -183,7 +181,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): params_to_optimize = params # 学習に必要なクラスを準備する - print("prepare optimizer, data loader etc.") + accelerator.print("prepare optimizer, data loader etc.") _, _, optimizer = train_util.get_optimizer(args, trainable_params=params_to_optimize) # dataloaderを準備する @@ -203,7 +201,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): args.max_train_steps = args.max_train_epochs * math.ceil( len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps ) - print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) @@ -216,7 +214,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): assert ( args.mixed_precision == "fp16" ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" - print("enable full fp16 training.") + accelerator.print("enable full fp16 training.") unet.to(weight_dtype) text_encoder.to(weight_dtype) @@ -246,14 +244,14 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # 学習する total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - print("running training / 学習開始") - print(f" num examples / サンプル数: {train_dataset_group.num_train_images}") - print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - print(f" num epochs / epoch数: {num_train_epochs}") - print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + accelerator.print("running training / 学習開始") + accelerator.print(f" num examples / サンプル数: {train_dataset_group.num_train_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") + accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") global_step = 0 @@ -266,7 +264,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) for epoch in range(num_train_epochs): - print(f"\nepoch {epoch+1}/{num_train_epochs}") + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") current_epoch.value = epoch + 1 for m in training_models: From 62d00b4520aaae6076474389c9f61db2c982c9e2 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Wed, 31 May 2023 14:13:15 +0900 Subject: [PATCH 007/220] add controlnet training --- library/config_util.py | 97 ++++++- library/model_util.py | 76 ++++++ library/train_util.py | 318 ++++++++++++++++++++++ train_controlnet.py | 594 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1075 insertions(+), 10 deletions(-) create mode 100644 train_controlnet.py diff --git a/library/config_util.py b/library/config_util.py index 98b417516..ae17655ca 100644 --- a/library/config_util.py +++ b/library/config_util.py @@ -33,8 +33,10 @@ from .train_util import ( DreamBoothSubset, FineTuningSubset, + ControlNetSubset, DreamBoothDataset, FineTuningDataset, + ControlNetDataset, DatasetGroup, ) @@ -70,6 +72,11 @@ class DreamBoothSubsetParams(BaseSubsetParams): class FineTuningSubsetParams(BaseSubsetParams): metadata_file: Optional[str] = None +@dataclass +class ControlNetSubsetParams(BaseSubsetParams): + conditioning_data_dir: str = None + caption_extension: str = ".caption" + @dataclass class BaseDatasetParams: tokenizer: CLIPTokenizer = None @@ -96,6 +103,15 @@ class FineTuningDatasetParams(BaseDatasetParams): bucket_reso_steps: int = 64 bucket_no_upscale: bool = False +@dataclass +class ControlNetDatasetParams(BaseDatasetParams): + batch_size: int = 1 + enable_bucket: bool = False + min_bucket_reso: int = 256 + max_bucket_reso: int = 1024 + bucket_reso_steps: int = 64 + bucket_no_upscale: bool = False + @dataclass class SubsetBlueprint: params: Union[DreamBoothSubsetParams, FineTuningSubsetParams] @@ -103,6 +119,7 @@ class SubsetBlueprint: @dataclass class DatasetBlueprint: is_dreambooth: bool + is_controlnet: bool params: Union[DreamBoothDatasetParams, FineTuningDatasetParams] subsets: Sequence[SubsetBlueprint] @@ -163,6 +180,13 @@ def __validate_and_convert_scalar_or_twodim(klass, value: Union[float, Sequence] Required("metadata_file"): str, "image_dir": str, } + CN_SUBSET_ASCENDABLE_SCHEMA = { + "caption_extension": str, + } + CN_SUBSET_DISTINCT_SCHEMA = { + Required("image_dir"): str, + Required("conditioning_data_dir"): str, + } # datasets schema DATASET_ASCENDABLE_SCHEMA = { @@ -192,8 +216,8 @@ def __validate_and_convert_scalar_or_twodim(klass, value: Union[float, Sequence] "dataset_repeats": "num_repeats", } - def __init__(self, support_dreambooth: bool, support_finetuning: bool, support_dropout: bool) -> None: - assert support_dreambooth or support_finetuning, "Neither DreamBooth mode nor fine tuning mode specified. Please specify one mode or more. / DreamBooth モードか fine tuning モードのどちらも指定されていません。1つ以上指定してください。" + def __init__(self, support_dreambooth: bool, support_finetuning: bool, support_controlnet: bool, support_dropout: bool) -> None: + assert support_dreambooth or support_finetuning or support_controlnet, "Neither DreamBooth mode nor fine tuning mode specified. Please specify one mode or more. / DreamBooth モードか fine tuning モードのどちらも指定されていません。1つ以上指定してください。" self.db_subset_schema = self.__merge_dict( self.SUBSET_ASCENDABLE_SCHEMA, @@ -208,6 +232,13 @@ def __init__(self, support_dreambooth: bool, support_finetuning: bool, support_d self.DO_SUBSET_ASCENDABLE_SCHEMA if support_dropout else {}, ) + self.cn_subset_schema = self.__merge_dict( + self.SUBSET_ASCENDABLE_SCHEMA, + self.CN_SUBSET_DISTINCT_SCHEMA, + self.CN_SUBSET_ASCENDABLE_SCHEMA, + self.DO_SUBSET_ASCENDABLE_SCHEMA if support_dropout else {}, + ) + self.db_dataset_schema = self.__merge_dict( self.DATASET_ASCENDABLE_SCHEMA, self.SUBSET_ASCENDABLE_SCHEMA, @@ -223,13 +254,23 @@ def __init__(self, support_dreambooth: bool, support_finetuning: bool, support_d {"subsets": [self.ft_subset_schema]}, ) - if support_dreambooth and support_finetuning: + self.cn_dataset_schema = self.__merge_dict( + self.DATASET_ASCENDABLE_SCHEMA, + self.SUBSET_ASCENDABLE_SCHEMA, + self.CN_SUBSET_ASCENDABLE_SCHEMA, + self.DO_SUBSET_ASCENDABLE_SCHEMA if support_dropout else {}, + {"subsets": [self.cn_subset_schema]}, + ) + + if support_dreambooth and support_finetuning and support_controlnet: def validate_flex_dataset(dataset_config: dict): subsets_config = dataset_config.get("subsets", []) + if all(["conditioning_data_dir" in subset for subset in subsets_config]): + return Schema(self.cn_dataset_schema)(dataset_config) # check dataset meets FT style # NOTE: all FT subsets should have "metadata_file" - if all(["metadata_file" in subset for subset in subsets_config]): + elif all(["metadata_file" in subset for subset in subsets_config]): return Schema(self.ft_dataset_schema)(dataset_config) # check dataset meets DB style # NOTE: all DB subsets should have no "metadata_file" @@ -241,13 +282,16 @@ def validate_flex_dataset(dataset_config: dict): self.dataset_schema = validate_flex_dataset elif support_dreambooth: self.dataset_schema = self.db_dataset_schema - else: + elif support_finetuning: self.dataset_schema = self.ft_dataset_schema + elif support_controlnet: + self.dataset_schema = self.cn_dataset_schema self.general_schema = self.__merge_dict( self.DATASET_ASCENDABLE_SCHEMA, self.SUBSET_ASCENDABLE_SCHEMA, self.DB_SUBSET_ASCENDABLE_SCHEMA if support_dreambooth else {}, + self.CN_SUBSET_ASCENDABLE_SCHEMA if support_controlnet else {}, self.DO_SUBSET_ASCENDABLE_SCHEMA if support_dropout else {}, ) @@ -318,7 +362,11 @@ def generate(self, user_config: dict, argparse_namespace: argparse.Namespace, ** # NOTE: if subsets have no "metadata_file", these are DreamBooth datasets/subsets subsets = dataset_config.get("subsets", []) is_dreambooth = all(["metadata_file" not in subset for subset in subsets]) - if is_dreambooth: + is_controlnet = all(["conditioning_data_dir" in subset for subset in subsets]) + if is_controlnet: + subset_params_klass = ControlNetSubsetParams + dataset_params_klass = ControlNetDatasetParams + elif is_dreambooth: subset_params_klass = DreamBoothSubsetParams dataset_params_klass = DreamBoothDatasetParams else: @@ -333,7 +381,7 @@ def generate(self, user_config: dict, argparse_namespace: argparse.Namespace, ** params = self.generate_params_by_fallbacks(dataset_params_klass, [dataset_config, general_config, argparse_config, runtime_params]) - dataset_blueprints.append(DatasetBlueprint(is_dreambooth, params, subset_blueprints)) + dataset_blueprints.append(DatasetBlueprint(is_dreambooth, is_controlnet, params, subset_blueprints)) dataset_group_blueprint = DatasetGroupBlueprint(dataset_blueprints) @@ -361,10 +409,13 @@ def search_value(key: str, fallbacks: Sequence[dict], default_value = None): def generate_dataset_group_by_blueprint(dataset_group_blueprint: DatasetGroupBlueprint): - datasets: List[Union[DreamBoothDataset, FineTuningDataset]] = [] + datasets: List[Union[DreamBoothDataset, FineTuningDataset, ControlNetDataset]] = [] for dataset_blueprint in dataset_group_blueprint.datasets: - if dataset_blueprint.is_dreambooth: + if dataset_blueprint.is_controlnet: + subset_klass = ControlNetSubset + dataset_klass = ControlNetDataset + elif dataset_blueprint.is_dreambooth: subset_klass = DreamBoothSubset dataset_klass = DreamBoothDataset else: @@ -379,6 +430,7 @@ def generate_dataset_group_by_blueprint(dataset_group_blueprint: DatasetGroupBlu info = "" for i, dataset in enumerate(datasets): is_dreambooth = isinstance(dataset, DreamBoothDataset) + is_controlnet = isinstance(dataset, ControlNetDataset) info += dedent(f"""\ [Dataset {i}] batch_size: {dataset.batch_size} @@ -421,7 +473,7 @@ def generate_dataset_group_by_blueprint(dataset_group_blueprint: DatasetGroupBlu class_tokens: {subset.class_tokens} caption_extension: {subset.caption_extension} \n"""), " ") - else: + elif not is_controlnet: info += indent(dedent(f"""\ metadata_file: {subset.metadata_file} \n"""), " ") @@ -479,6 +531,31 @@ def generate(base_dir: Optional[str], is_reg: bool): return subsets_config +def generate_controlnet_subsets_config_by_subdirs(train_data_dir: Optional[str] = None, conditioning_data_dir: Optional[str] = None, caption_extension: str = ".txt"): + def generate(base_dir: Optional[str]): + if base_dir is None: + return [] + + base_dir: Path = Path(base_dir) + if not base_dir.is_dir(): + return [] + + subsets_config = [] + for subdir in base_dir.iterdir(): + if not subdir.is_dir(): + continue + + subset_config = {"image_dir": str(subdir), "conditioning_data_dir": conditioning_data_dir, "caption_extension": caption_extension, "num_repeats": 1} + subsets_config.append(subset_config) + + return subsets_config + + subsets_config = [] + subsets_config += generate(train_data_dir, False) + + return subsets_config + + def load_user_config(file: str) -> dict: file: Path = Path(file) if not file.is_file(): diff --git a/library/model_util.py b/library/model_util.py index 26f72235d..bb1686537 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -732,6 +732,82 @@ def convert_unet_state_dict_to_sd(v2, unet_state_dict): return new_state_dict +def convert_controlnet_state_dict_to_sd(controlnet_state_dict): + unet_conversion_map = [ + ("time_embed.0.weight", "time_embedding.linear_1.weight"), + ("time_embed.0.bias", "time_embedding.linear_1.bias"), + ("time_embed.2.weight", "time_embedding.linear_2.weight"), + ("time_embed.2.bias", "time_embedding.linear_2.bias"), + ("input_blocks.0.0.weight", "conv_in.weight"), + ("input_blocks.0.0.bias", "conv_in.bias"), + ("middle_block_out.0.weight", "controlnet_mid_block.weight"), + ("middle_block_out.0.bias", "controlnet_mid_block.bias"), + ] + + unet_conversion_map_resnet = [ + ("in_layers.0", "norm1"), + ("in_layers.2", "conv1"), + ("out_layers.0", "norm2"), + ("out_layers.3", "conv2"), + ("emb_layers.1", "time_emb_proj"), + ("skip_connection", "conv_shortcut"), + ] + + unet_conversion_map_layer = [] + for i in range(4): + for j in range(2): + hf_down_res_prefix = f"down_blocks.{i}.resnets.{j}." + sd_down_res_prefix = f"input_blocks.{3*i + j + 1}.0." + unet_conversion_map_layer.append((sd_down_res_prefix, hf_down_res_prefix)) + + if i < 3: + hf_down_atn_prefix = f"down_blocks.{i}.attentions.{j}." + sd_down_atn_prefix = f"input_blocks.{3*i + j + 1}.1." + unet_conversion_map_layer.append((sd_down_atn_prefix, hf_down_atn_prefix)) + + if i < 3: + hf_downsample_prefix = f"down_blocks.{i}.downsamplers.0.conv." + sd_downsample_prefix = f"input_blocks.{3*(i+1)}.0.op." + unet_conversion_map_layer.append((sd_downsample_prefix, hf_downsample_prefix)) + + hf_mid_atn_prefix = "mid_block.attentions.0." + sd_mid_atn_prefix = "middle_block.1." + unet_conversion_map_layer.append((sd_mid_atn_prefix, hf_mid_atn_prefix)) + + for j in range(2): + hf_mid_res_prefix = f"mid_block.resnets.{j}." + sd_mid_res_prefix = f"middle_block.{2*j}." + unet_conversion_map_layer.append((sd_mid_res_prefix, hf_mid_res_prefix)) + + controlnet_cond_embedding_names = ( + ["conv_in"] + [f"blocks.{i}" for i in range(6)] + ["conv_out"] + ) + for i, hf_prefix in enumerate(controlnet_cond_embedding_names): + hf_prefix = f"controlnet_cond_embedding.{hf_prefix}." + sd_prefix = f"input_hint_block.{i*2}." + unet_conversion_map_layer.append((sd_prefix, hf_prefix)) + + for i in range(12): + hf_prefix = f"controlnet_down_blocks.{i}." + sd_prefix = f"zero_convs.{i}.0." + unet_conversion_map_layer.append((sd_prefix, hf_prefix)) + + mapping = {k: k for k in controlnet_state_dict.keys()} + for sd_name, diffusers_name in unet_conversion_map: + mapping[diffusers_name] = sd_name + for k, v in mapping.items(): + if "resnets" in k: + for sd_part, diffusers_part in unet_conversion_map_resnet: + v = v.replace(diffusers_part, sd_part) + mapping[k] = v + for k, v in mapping.items(): + for sd_part, diffusers_part in unet_conversion_map_layer: + v = v.replace(diffusers_part, sd_part) + mapping[k] = v + new_state_dict = {v: controlnet_state_dict[k] for k, v in mapping.items()} + return new_state_dict + + # ================# # VAE Conversion # # ================# diff --git a/library/train_util.py b/library/train_util.py index 008ccd64f..1921c2a43 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -403,6 +403,54 @@ def __eq__(self, other) -> bool: return self.metadata_file == other.metadata_file +class ControlNetSubset(BaseSubset): + def __init__( + self, + image_dir: str, + conditioning_data_dir: str, + caption_extension: str, + num_repeats, + shuffle_caption, + keep_tokens, + color_aug, + flip_aug, + face_crop_aug_range, + random_crop, + caption_dropout_rate, + caption_dropout_every_n_epochs, + caption_tag_dropout_rate, + token_warmup_min, + token_warmup_step, + ) -> None: + assert image_dir is not None, "image_dir must be specified / image_dirは指定が必須です" + + super().__init__( + image_dir, + num_repeats, + shuffle_caption, + keep_tokens, + color_aug, + flip_aug, + face_crop_aug_range, + random_crop, + caption_dropout_rate, + caption_dropout_every_n_epochs, + caption_tag_dropout_rate, + token_warmup_min, + token_warmup_step, + ) + + self.conditioning_data_dir = conditioning_data_dir + self.caption_extension = caption_extension + if self.caption_extension and not self.caption_extension.startswith("."): + self.caption_extension = "." + self.caption_extension + + def __eq__(self, other) -> bool: + if not isinstance(other, ControlNetSubset): + return NotImplemented + return self.image_dir == other.image_dir and self.conditioning_data_dir == other.conditioning_data_dir + + class BaseDataset(torch.utils.data.Dataset): def __init__( self, tokenizer: CLIPTokenizer, max_token_length: int, resolution: Optional[Tuple[int, int]], debug_dataset: bool @@ -1387,6 +1435,274 @@ def image_key_to_npz_file(self, subset: FineTuningSubset, image_key): return npz_file_norm, npz_file_flip +class ControlNetDataset(BaseDataset): + def __init__( + self, + subsets: Sequence[ControlNetSubset], + batch_size: int, + tokenizer, + max_token_length, + resolution, + enable_bucket: bool, + min_bucket_reso: int, + max_bucket_reso: int, + bucket_reso_steps: int, + bucket_no_upscale: bool, + debug_dataset) -> None: + super().__init__(tokenizer, max_token_length, resolution, debug_dataset) + self.conditioning_image_data: Dict[str, ImageInfo] = {} + + assert resolution is not None, f"resolution is required / resolution(解像度)指定は必須です" + + self.batch_size = batch_size + self.size = min(self.width, self.height) # 短いほう + self.latents_cache = None + + self.num_reg_images = 0 + + self.enable_bucket = enable_bucket + if self.enable_bucket: + assert ( + min(resolution) >= min_bucket_reso + ), f"min_bucket_reso must be equal or less than resolution / min_bucket_resoは最小解像度より大きくできません。解像度を大きくするかmin_bucket_resoを小さくしてください" + assert ( + max(resolution) <= max_bucket_reso + ), f"max_bucket_reso must be equal or greater than resolution / max_bucket_resoは最大解像度より小さくできません。解像度を小さくするかmin_bucket_resoを大きくしてください" + self.min_bucket_reso = min_bucket_reso + self.max_bucket_reso = max_bucket_reso + self.bucket_reso_steps = bucket_reso_steps + self.bucket_no_upscale = bucket_no_upscale + else: + self.min_bucket_reso = None + self.max_bucket_reso = None + self.bucket_reso_steps = None # この情報は使われない + self.bucket_no_upscale = False + + def read_caption(img_path, caption_extension): + # captionの候補ファイル名を作る + base_name = os.path.splitext(img_path)[0] + base_name_face_det = base_name + tokens = base_name.split("_") + if len(tokens) >= 5: + base_name_face_det = "_".join(tokens[:-4]) + cap_paths = [base_name + caption_extension, base_name_face_det + caption_extension] + + caption = None + for cap_path in cap_paths: + if os.path.isfile(cap_path): + with open(cap_path, "rt", encoding="utf-8") as f: + try: + lines = f.readlines() + except UnicodeDecodeError as e: + print(f"illegal char in file (not UTF-8) / ファイルにUTF-8以外の文字があります: {cap_path}") + raise e + assert len(lines) > 0, f"caption file is empty / キャプションファイルが空です: {cap_path}" + caption = lines[0].strip() + break + return caption + + def load_controlnet_dir(subset: ControlNetSubset): + if not os.path.isdir(subset.image_dir): + print(f"not directory: {subset.image_dir}") + return [], [] + if not os.path.isdir(subset.conditioning_data_dir): + print(f"not directory: {subset.conditioning_data_dir}") + return [], [] + + img_paths = glob_images(subset.image_dir, "*") + conditioning_img_paths = glob_images(subset.conditioning_data_dir, "*") + img_paths = sorted(img_paths) + conditioning_img_paths = sorted(conditioning_img_paths) + print(f"found directory {subset.image_dir} contains {len(img_paths)} image files") + print(f"found directory {subset.conditioning_data_dir} contains {len(conditioning_img_paths)} image files") + + img_basenames = [os.path.basename(img) for img in img_paths] + conditioning_img_basenames = [os.path.basename(img) for img in conditioning_img_paths] + missing_imgs = [] + extra_imgs = [] + + for img in img_basenames: + if img not in conditioning_img_basenames: + missing_imgs.append(img) + for img in conditioning_img_basenames: + if img not in img_basenames: + extra_imgs.append(img) + + assert len(missing_imgs) == 0, f"missing conditioning data for {len(missing_imgs)} images: {missing_imgs}" + assert len(extra_imgs) == 0, f"extra conditioning data for {len(extra_imgs)} images: {extra_imgs}" + + + # 画像ファイルごとにプロンプトを読み込み、もしあればそちらを使う + captions = [] + missing_captions = [] + for img_path in img_paths: + cap_for_img = read_caption(img_path, subset.caption_extension) + if cap_for_img is None: + print(f"neither caption file nor class tokens are found. use empty caption for {img_path} / キャプションファイルもclass tokenも見つかりませんでした。空のキャプションを使用します: {img_path}") + captions.append("") + missing_captions.append(img_path) + else: + captions.append(cap_for_img) + + self.set_tag_frequency(os.path.basename(subset.image_dir), captions) # タグ頻度を記録 + + if missing_captions: + number_of_missing_captions = len(missing_captions) + number_of_missing_captions_to_show = 5 + remaining_missing_captions = number_of_missing_captions - number_of_missing_captions_to_show + + print( + f"No caption file found for {number_of_missing_captions} images. Training will continue without captions for these images. If class token exists, it will be used. / {number_of_missing_captions}枚の画像にキャプションファイルが見つかりませんでした。これらの画像についてはキャプションなしで学習を続行します。class tokenが存在する場合はそれを使います。" + ) + for i, missing_caption in enumerate(missing_captions): + if i >= number_of_missing_captions_to_show: + print(missing_caption + f"... and {remaining_missing_captions} more") + break + print(missing_caption) + return img_paths, conditioning_img_paths, captions + + print("prepare images.") + num_train_images = 0 + for subset in subsets: + if subset.num_repeats < 1: + print( + f"ignore subset with image_dir='{subset.image_dir}': num_repeats is less than 1 / num_repeatsが1を下回っているためサブセットを無視します: {subset.num_repeats}" + ) + continue + + if subset in self.subsets: + print( + f"ignore duplicated subset with image_dir='{subset.image_dir}': use the first one / 既にサブセットが登録されているため、重複した後発のサブセットを無視します" + ) + continue + + img_paths, conditioning_img_paths, captions = load_controlnet_dir(subset) + if len(img_paths) < 1: + print(f"ignore subset with image_dir='{subset.image_dir}': no images found / 画像が見つからないためサブセットを無視します") + continue + + num_train_images += subset.num_repeats * len(img_paths) + + for img_path, cond_img_path, caption in zip(img_paths, conditioning_img_paths, captions): + info = ImageInfo(img_path, subset.num_repeats, caption, False, img_path) + setattr(info, "cond_img_path", cond_img_path) + self.register_image(info, subset) + + subset.img_count = len(img_paths) + self.subsets.append(subset) + + print(f"{num_train_images} train images with repeating.") + self.num_train_images = num_train_images + + self.conditioning_image_transforms = transforms.Compose( + [ + transforms.ToTensor(), + ] + ) + + def __getitem__(self, index): + bucket = self.bucket_manager.buckets[self.buckets_indices[index].bucket_index] + bucket_batch_size = self.buckets_indices[index].bucket_batch_size + image_index = self.buckets_indices[index].batch_index * bucket_batch_size + + loss_weights = [] + captions = [] + input_ids_list = [] + latents_list = [] + images = [] + conditioning_images = [] + + for image_key in bucket[image_index : image_index + bucket_batch_size]: + image_info = self.image_data[image_key] + subset = self.image_to_subset[image_key] + loss_weights.append(1.0) + + # image/latentsを処理する + if image_info.latents is not None: # cache_latents=Trueの場合 + latents = image_info.latents if not subset.flip_aug or random.random() < 0.5 else image_info.latents_flipped + image = None + elif image_info.latents_npz is not None: # FineTuningDatasetまたはcache_latents_to_disk=Trueの場合 + latents = self.load_latents_from_npz(image_info, subset.flip_aug and random.random() >= 0.5) + latents = torch.FloatTensor(latents) + image = None + else: + # 画像を読み込み、必要ならcropする + img = self.load_image(image_info.absolute_path) + im_h, im_w = img.shape[0:2] + + if self.enable_bucket: + img = self.trim_and_resize_if_required(subset, img, image_info.bucket_reso, image_info.resized_size) + else: + im_h, im_w = img.shape[0:2] + assert ( + im_h == self.height and im_w == self.width + ), f"image size is small / 画像サイズが小さいようです: {image_info.absolute_path}" + + # augmentation + aug = self.aug_helper.get_augmentor(subset.color_aug, subset.flip_aug) + if aug is not None: + img = aug(image=img)["image"] + + latents = None + image = self.image_transforms(img) # -1.0~1.0のtorch.Tensorになる + + images.append(image) + latents_list.append(latents) + + caption = self.process_caption(subset, image_info.caption) + if self.XTI_layers: + caption_layer = [] + for layer in self.XTI_layers: + token_strings_from = " ".join(self.token_strings) + token_strings_to = " ".join([f"{x}_{layer}" for x in self.token_strings]) + caption_ = caption.replace(token_strings_from, token_strings_to) + caption_layer.append(caption_) + captions.append(caption_layer) + else: + captions.append(caption) + if not self.token_padding_disabled: # this option might be omitted in future + if self.XTI_layers: + token_caption = self.get_input_ids(caption_layer) + else: + token_caption = self.get_input_ids(caption) + input_ids_list.append(token_caption) + + assert hasattr(image_info, "cond_img_path"), f"conditioning image path is not found: {image_info.absolute_path}" + + cond_img = self.load_image(image_info.cond_img_path) + if self.enable_bucket: + cond_img = self.trim_and_resize_if_required(subset, cond_img, image_info.bucket_reso, image_info.resized_size) + cond_img = self.conditioning_image_transforms(cond_img) + conditioning_images.append(cond_img) + conditioning_images = torch.stack(conditioning_images) + + example = {} + example["loss_weights"] = torch.FloatTensor(loss_weights) + + if self.token_padding_disabled: + # padding=True means pad in the batch + example["input_ids"] = self.tokenizer(captions, padding=True, truncation=True, return_tensors="pt").input_ids + else: + # batch processing seems to be good + example["input_ids"] = torch.stack(input_ids_list) + + if images[0] is not None: + images = torch.stack(images) + images = images.to(memory_format=torch.contiguous_format).float() + else: + images = None + example["images"] = images + + example["latents"] = torch.stack(latents_list) if latents_list[0] is not None else None + example["captions"] = captions + + if self.debug_dataset: + example["image_keys"] = bucket[image_index : image_index + self.batch_size] + + example["conditioning_images"] = conditioning_images.to(memory_format=torch.contiguous_format).float() + + return example + # behave as Dataset mock class DatasetGroup(torch.utils.data.ConcatDataset): def __init__(self, datasets: Sequence[Union[DreamBoothDataset, FineTuningDataset]]): @@ -1636,6 +1952,8 @@ def get_git_revision_hash() -> str: def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): replace_attentions_for_hypernetwork() # unet is not used currently, but it is here for future use + unet.enable_xformers_memory_efficient_attention() + return if mem_eff_attn: unet.set_attn_processor(FlashAttnProcessor()) elif xformers: diff --git a/train_controlnet.py b/train_controlnet.py new file mode 100644 index 000000000..7bcaf03a1 --- /dev/null +++ b/train_controlnet.py @@ -0,0 +1,594 @@ +import argparse +import gc +import math +import os +import random +import time +from multiprocessing import Value + +from tqdm import tqdm +import torch +from torch.nn.parallel import DistributedDataParallel as DDP +from accelerate.utils import set_seed +from diffusers import DDPMScheduler, ControlNetModel + +import library.model_util as model_util +import library.train_util as train_util +import library.config_util as config_util +from library.config_util import ( + ConfigSanitizer, + BlueprintGenerator, +) +import library.huggingface_util as huggingface_util +import library.custom_train_functions as custom_train_functions +from library.custom_train_functions import ( + apply_snr_weight, + pyramid_noise_like, + apply_noise_offset, +) +from diffusers.pipelines.stable_diffusion.convert_from_ckpt import ( + download_controlnet_from_original_ckpt, +) + + +# TODO 他のスクリプトと共通化する +def generate_step_logs(args: argparse.Namespace, current_loss, avr_loss, lr_scheduler): + logs = { + "loss/current": current_loss, + "loss/average": avr_loss, + "lr": lr_scheduler.get_last_lr()[0], + } + + if args.optimizer_type.lower().startswith("DAdapt".lower()): + logs["lr/d*lr"] = ( + lr_scheduler.optimizers[-1].param_groups[0]["d"] + * lr_scheduler.optimizers[-1].param_groups[0]["lr"] + ) + + return logs + + +def train(args): + session_id = random.randint(0, 2**32) + training_started_at = time.time() + train_util.verify_training_args(args) + train_util.prepare_dataset_args(args, True) + + cache_latents = args.cache_latents + use_user_config = args.dataset_config is not None + + if args.seed is None: + args.seed = random.randint(0, 2**32) + set_seed(args.seed) + + tokenizer = train_util.load_tokenizer(args) + + # データセットを準備する + blueprint_generator = BlueprintGenerator(ConfigSanitizer(False, False, True, True)) + if use_user_config: + print(f"Load dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "conditioning_data_dir"] + if any(getattr(args, attr) is not None for attr in ignored): + print( + "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + user_config = { + "datasets": [ + { + "subsets": config_util.generate_controlnet_subsets_config_by_subdirs( + args.train_data_dir, + args.conditioning_data_dir, + args.caption_extension, + ) + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer) + train_dataset_group = config_util.generate_dataset_group_by_blueprint( + blueprint.dataset_group + ) + + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = ( + train_dataset_group if args.max_data_loader_n_workers == 0 else None + ) + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + if args.debug_dataset: + train_util.debug_dataset(train_dataset_group) + return + if len(train_dataset_group) == 0: + print( + "No data found. Please verify arguments (train_data_dir must be the parent of folders with images) / 画像がありません。引数指定を確認してください(train_data_dirには画像があるフォルダではなく、画像があるフォルダの親フォルダを指定する必要があります)" + ) + return + + if cache_latents: + assert ( + train_dataset_group.is_latent_cacheable() + ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" + + # acceleratorを準備する + print("prepare accelerator") + accelerator, unwrap_model = train_util.prepare_accelerator(args) + is_main_process = accelerator.is_main_process + + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, save_dtype = train_util.prepare_dtype(args) + + # モデルを読み込む + text_encoder, vae, unet, _ = train_util.load_target_model( + args, weight_dtype, accelerator + ) + if args.controlnet_model_name_or_path: + if os.path.isfile(args.controlnet_model_name_or_path): + controlnet = download_controlnet_from_original_ckpt( + args.controlnet_model_name_or_path + ) + else: + controlnet = ControlNetModel.from_pretrained( + args.controlnet_model_name_or_path + ) + else: + controlnet = ControlNetModel.from_unet(unet) + + # モデルに xformers とか memory efficient attention を組み込む + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + + # 学習を準備する + if cache_latents: + vae.to(accelerator.device, dtype=weight_dtype) + vae.requires_grad_(False) + vae.eval() + with torch.no_grad(): + train_dataset_group.cache_latents( + vae, + args.vae_batch_size, + args.cache_latents_to_disk, + accelerator.is_main_process, + ) + vae.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + gc.collect() + + accelerator.wait_for_everyone() + + if args.gradient_checkpointing: + controlnet.enable_gradient_checkpointing() + + # 学習に必要なクラスを準備する + print("prepare optimizer, data loader etc.") + + trainable_params = controlnet.parameters() + + optimizer_name, optimizer_args, optimizer = train_util.get_optimizer( + args, trainable_params + ) + + # dataloaderを準備する + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min( + args.max_data_loader_n_workers, os.cpu_count() - 1 + ) # cpu_count-1 ただし最大で指定された数まで + + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, + ) + + # 学習ステップ数を計算する + if args.max_train_epochs is not None: + args.max_train_steps = args.max_train_epochs * math.ceil( + len(train_dataloader) + / accelerator.num_processes + / args.gradient_accumulation_steps + ) + if is_main_process: + print( + f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" + ) + + # データセット側にも学習ステップを送信 + train_dataset_group.set_max_train_steps(args.max_train_steps) + + # lr schedulerを用意する + lr_scheduler = train_util.get_scheduler_fix( + args, optimizer, accelerator.num_processes + ) + + # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする + if args.full_fp16: + assert ( + args.mixed_precision == "fp16" + ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" + print("enable full fp16 training.") + controlnet.to(weight_dtype) + + # acceleratorがなんかよろしくやってくれるらしい + controlnet, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + controlnet, optimizer, train_dataloader, lr_scheduler + ) + + unet.requires_grad_(False) + text_encoder.requires_grad_(False) + unet.to(accelerator.device) + text_encoder.to(accelerator.device) + + # transform DDP after prepare + controlnet = controlnet.module if isinstance(controlnet, DDP) else controlnet + + controlnet.train() + + if not cache_latents: + vae.requires_grad_(False) + vae.eval() + vae.to(accelerator.device, dtype=weight_dtype) + + # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする + if args.full_fp16: + train_util.patch_accelerator_for_fp16_training(accelerator) + + # resumeする + train_util.resume_from_local_or_hf_if_specified(accelerator, args) + + # epoch数を計算する + num_update_steps_per_epoch = math.ceil( + len(train_dataloader) / args.gradient_accumulation_steps + ) + num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) + if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): + args.save_every_n_epochs = ( + math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 + ) + + # 学習する + # TODO: find a way to handle total batch size when there are multiple datasets + + if is_main_process: + print("running training / 学習開始") + print( + f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}" + ) + print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + print(f" num epochs / epoch数: {num_train_epochs}") + print( + f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" + ) + # print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + print( + f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}" + ) + print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + + progress_bar = tqdm( + range(args.max_train_steps), + smoothing=0, + disable=not accelerator.is_local_main_process, + desc="steps", + ) + global_step = 0 + + noise_scheduler = DDPMScheduler( + beta_start=0.00085, + beta_end=0.012, + beta_schedule="scaled_linear", + num_train_timesteps=1000, + clip_sample=False, + ) + if accelerator.is_main_process: + accelerator.init_trackers( + "controlnet_train" if args.log_tracker_name is None else args.log_tracker_name + ) + + loss_list = [] + loss_total = 0.0 + del train_dataset_group + + # function for saving/removing + def save_model(ckpt_name, model, steps, epoch_no, force_sync_upload=False): + os.makedirs(args.output_dir, exist_ok=True) + ckpt_file = os.path.join(args.output_dir, ckpt_name) + + print(f"\nsaving checkpoint: {ckpt_file}") + + state_dict = model_util.convert_controlnet_state_dict_to_sd(model.state_dict()) + + if save_dtype is not None: + for key in list(state_dict.keys()): + v = state_dict[key] + v = v.detach().clone().to("cpu").to(save_dtype) + state_dict[key] = v + + if os.path.splitext(ckpt_file)[1] == ".safetensors": + from safetensors.torch import save_file + + save_file(state_dict, ckpt_file) + else: + torch.save(state_dict, ckpt_file) + + if args.huggingface_repo_id is not None: + huggingface_util.upload( + args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload + ) + + def remove_model(old_ckpt_name): + old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) + if os.path.exists(old_ckpt_file): + print(f"removing old checkpoint: {old_ckpt_file}") + os.remove(old_ckpt_file) + + # training loop + for epoch in range(num_train_epochs): + if is_main_process: + print(f"\nepoch {epoch+1}/{num_train_epochs}") + current_epoch.value = epoch + 1 + + for step, batch in enumerate(train_dataloader): + current_step.value = global_step + with accelerator.accumulate(controlnet): + with torch.no_grad(): + if "latents" in batch and batch["latents"] is not None: + latents = batch["latents"].to(accelerator.device) + else: + # latentに変換 + latents = vae.encode( + batch["images"].to(dtype=weight_dtype) + ).latent_dist.sample() + latents = latents * 0.18215 + b_size = latents.shape[0] + + input_ids = batch["input_ids"].to(accelerator.device) + encoder_hidden_states = train_util.gethidden_states( + args, input_ids, tokenizer, text_encoder, weight_dtype + ) + + # Sample noise that we'll add to the latents + noise = torch.randn_like(latents, device=latents.device) + if args.noise_offset: + noise = apply_noise_offset( + latents, noise, args.noise_offset, args.adaptive_noise_scale + ) + elif args.multires_noise_iterations: + noise = pyramid_noise_like( + noise, + latents.device, + args.multires_noise_iterations, + args.multires_noise_discount, + ) + + # Sample a random timestep for each image + timesteps = torch.randint( + 0, + noise_scheduler.config.num_train_timesteps, + (b_size,), + device=latents.device, + ) + timesteps = timesteps.long() + # Add noise to the latents according to the noise magnitude at each timestep + # (this is the forward diffusion process) + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + + controlnet_image = batch["conditioning_images"].to(dtype=weight_dtype) + + with accelerator.autocast(): + down_block_res_samples, mid_block_res_sample = controlnet( + noisy_latents, + timesteps, + encoder_hidden_states=encoder_hidden_states, + controlnet_cond=controlnet_image, + return_dict=False, + ) + + # Predict the noise residual + noise_pred = unet( + noisy_latents, + timesteps, + encoder_hidden_states, + down_block_additional_residuals=[ + sample.to(dtype=weight_dtype) + for sample in down_block_res_samples + ], + mid_block_additional_residual=mid_block_res_sample.to( + dtype=weight_dtype + ), + ).sample + + if args.v_parameterization: + # v-parameterization training + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + target = noise + + loss = torch.nn.functional.mse_loss( + noise_pred.float(), target.float(), reduction="none" + ) + loss = loss.mean([1, 2, 3]) + + loss_weights = batch["loss_weights"] # 各sampleごとのweight + loss = loss * loss_weights + + if args.min_snr_gamma: + loss = apply_snr_weight( + loss, timesteps, noise_scheduler, args.min_snr_gamma + ) + + loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし + + accelerator.backward(loss) + if accelerator.sync_gradients and args.max_grad_norm != 0.0: + params_to_clip = controlnet.parameters() + accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) + + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad(set_to_none=True) + + # Checks if the accelerator has performed an optimization step behind the scenes + if accelerator.sync_gradients: + progress_bar.update(1) + global_step += 1 + + train_util.sample_images( + accelerator, + args, + None, + global_step, + accelerator.device, + vae, + tokenizer, + text_encoder, + unet, + ) + + # 指定ステップごとにモデルを保存 + if ( + args.save_every_n_steps is not None + and global_step % args.save_every_n_steps == 0 + ): + accelerator.wait_for_everyone() + if accelerator.is_main_process: + ckpt_name = train_util.get_step_ckpt_name( + args, "." + args.save_model_as, global_step + ) + save_model( + ckpt_name, unwrap_model(controlnet), global_step, epoch + ) + + if args.save_state: + train_util.save_and_remove_state_stepwise( + args, accelerator, global_step + ) + + remove_step_no = train_util.get_remove_step_no( + args, global_step + ) + if remove_step_no is not None: + remove_ckpt_name = train_util.get_step_ckpt_name( + args, "." + args.save_model_as, remove_step_no + ) + remove_model(remove_ckpt_name) + + current_loss = loss.detach().item() + if epoch == 0: + loss_list.append(current_loss) + else: + loss_total -= loss_list[step] + loss_list[step] = current_loss + loss_total += current_loss + avr_loss = loss_total / len(loss_list) + logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} + progress_bar.set_postfix(**logs) + + if args.logging_dir is not None: + logs = generate_step_logs(args, current_loss, avr_loss, lr_scheduler) + accelerator.log(logs, step=global_step) + + if global_step >= args.max_train_steps: + break + + if args.logging_dir is not None: + logs = {"loss/epoch": loss_total / len(loss_list)} + accelerator.log(logs, step=epoch + 1) + + accelerator.wait_for_everyone() + + # 指定エポックごとにモデルを保存 + if args.save_every_n_epochs is not None: + saving = (epoch + 1) % args.save_every_n_epochs == 0 and ( + epoch + 1 + ) < num_train_epochs + if is_main_process and saving: + ckpt_name = train_util.get_epoch_ckpt_name( + args, "." + args.save_model_as, epoch + 1 + ) + save_model(ckpt_name, unwrap_model(controlnet), global_step, epoch + 1) + + remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) + if remove_epoch_no is not None: + remove_ckpt_name = train_util.get_epoch_ckpt_name( + args, "." + args.save_model_as, remove_epoch_no + ) + remove_model(remove_ckpt_name) + + if args.save_state: + train_util.save_and_remove_state_on_epoch_end( + args, accelerator, epoch + 1 + ) + + train_util.sample_images( + accelerator, + args, + epoch + 1, + global_step, + accelerator.device, + vae, + tokenizer, + text_encoder, + unet, + ) + + # end of epoch + if is_main_process: + controlnet = unwrap_model(controlnet) + + accelerator.end_training() + + if is_main_process and args.save_state: + train_util.save_state_on_train_end(args, accelerator) + + del accelerator # この後メモリを使うのでこれは消す + + if is_main_process: + ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) + save_model( + ckpt_name, controlnet, global_step, num_train_epochs, force_sync_upload=True + ) + + print("model saved.") + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + + train_util.add_sd_models_arguments(parser) + train_util.add_dataset_arguments(parser, False, True, True) + train_util.add_training_arguments(parser, False) + train_util.add_optimizer_arguments(parser) + config_util.add_config_arguments(parser) + custom_train_functions.add_custom_train_arguments(parser) + + parser.add_argument( + "--controlnet_model_name_or_path", + type=str, + default=None, + help="controlnet model name or path / controlnetのモデル名またはパス", + ) + parser.add_argument( + "--conditioning_data_dir", + type=str, + default=None, + help="conditioning data directory / 条件付けデータのディレクトリ", + ) + + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + train(args) From 3bd00b88c2c13489fac9cc4a5ebf1f394d0f5df9 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 09:47:37 +0900 Subject: [PATCH 008/220] support for controlnet in sample output --- library/lpw_stable_diffusion.py | 85 ++++++++++++++++++++++++++++++++- library/model_util.py | 28 +++++++++-- library/train_util.py | 27 ++++++++--- train_controlnet.py | 47 +++++++++++------- 4 files changed, 159 insertions(+), 28 deletions(-) diff --git a/library/lpw_stable_diffusion.py b/library/lpw_stable_diffusion.py index 84e1ab151..88317e30a 100644 --- a/library/lpw_stable_diffusion.py +++ b/library/lpw_stable_diffusion.py @@ -6,7 +6,7 @@ from typing import Callable, List, Optional, Union import numpy as np -import PIL +import PIL.Image import torch from packaging import version from transformers import CLIPFeatureExtractor, CLIPTextModel, CLIPTokenizer @@ -426,6 +426,59 @@ def preprocess_mask(mask, scale_factor=8): return mask +def prepare_controlnet_image( + image: PIL.Image.Image, + width: int, + height: int, + batch_size: int, + num_images_per_prompt: int, + device: torch.device, + dtype: torch.dtype, + do_classifier_free_guidance: bool = False, + guess_mode: bool = False, +): + if not isinstance(image, torch.Tensor): + if isinstance(image, PIL.Image.Image): + image = [image] + + if isinstance(image[0], PIL.Image.Image): + images = [] + + for image_ in image: + image_ = image_.convert("RGB") + image_ = image_.resize( + (width, height), resample=PIL_INTERPOLATION["lanczos"] + ) + image_ = np.array(image_) + image_ = image_[None, :] + images.append(image_) + + image = images + + image = np.concatenate(image, axis=0) + image = np.array(image).astype(np.float32) / 255.0 + image = image.transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + elif isinstance(image[0], torch.Tensor): + image = torch.cat(image, dim=0) + + image_batch_size = image.shape[0] + + if image_batch_size == 1: + repeat_by = batch_size + else: + # image batch size is the same as prompt batch size + repeat_by = num_images_per_prompt + + image = image.repeat_interleave(repeat_by, dim=0) + + image = image.to(device=device, dtype=dtype) + + if do_classifier_free_guidance and not guess_mode: + image = torch.cat([image] * 2) + + return image + class StableDiffusionLongPromptWeightingPipeline(StableDiffusionPipeline): r""" Pipeline for text-to-image generation using Stable Diffusion without tokens length limit, and support parsing @@ -707,6 +760,8 @@ def __call__( max_embeddings_multiples: Optional[int] = 3, output_type: Optional[str] = "pil", return_dict: bool = True, + controlnet=None, + controlnet_image=None, callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, is_cancelled_callback: Optional[Callable[[], bool]] = None, callback_steps: int = 1, @@ -767,6 +822,11 @@ def __call__( return_dict (`bool`, *optional*, defaults to `True`): Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a plain tuple. + controlnet (`diffusers.ControlNetModel`, *optional*): + A controlnet model to be used for the inference. If not provided, controlnet will be disabled. + controlnet_image (`torch.FloatTensor` or `PIL.Image.Image`, *optional*): + `Image`, or tensor representing an image batch, to be used as the starting point for the controlnet + inference. callback (`Callable`, *optional*): A function that will be called every `callback_steps` steps during inference. The function will be called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. @@ -785,6 +845,9 @@ def __call__( list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work" (nsfw) content, according to the `safety_checker`. """ + if controlnet is not None and controlnet_image is None: + raise ValueError("controlnet_image must be provided if controlnet is not None.") + # 0. Default height and width to unet height = height or self.unet.config.sample_size * self.vae_scale_factor width = width or self.unet.config.sample_size * self.vae_scale_factor @@ -824,6 +887,10 @@ def __call__( else: mask = None + if controlnet_image is not None: + controlnet_image = prepare_controlnet_image(controlnet_image, width, height, batch_size, 1, self.device, controlnet.dtype, do_classifier_free_guidance, False) + + # 5. set timesteps self.scheduler.set_timesteps(num_inference_steps, device=device) timesteps, num_inference_steps = self.get_timesteps(num_inference_steps, strength, device, image is None) @@ -851,8 +918,22 @@ def __call__( latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + unet_additional_args = {} + if controlnet is not None: + down_block_res_samples, mid_block_res_sample = controlnet( + latent_model_input, + t, + encoder_hidden_states=text_embeddings, + controlnet_cond=controlnet_image, + conditioning_scale=1.0, + guess_mode=False, + return_dict=False, + ) + unet_additional_args['down_block_additional_residuals'] = down_block_res_samples + unet_additional_args['mid_block_additional_residual'] = mid_block_res_sample + # predict the noise residual - noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample + noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings, **unet_additional_args).sample # perform guidance if do_classifier_free_guidance: diff --git a/library/model_util.py b/library/model_util.py index bb1686537..0764a8811 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -731,8 +731,7 @@ def convert_unet_state_dict_to_sd(v2, unet_state_dict): return new_state_dict - -def convert_controlnet_state_dict_to_sd(controlnet_state_dict): +def controlnet_conversion_map(): unet_conversion_map = [ ("time_embed.0.weight", "time_embedding.linear_1.weight"), ("time_embed.0.bias", "time_embedding.linear_1.bias"), @@ -792,6 +791,12 @@ def convert_controlnet_state_dict_to_sd(controlnet_state_dict): sd_prefix = f"zero_convs.{i}.0." unet_conversion_map_layer.append((sd_prefix, hf_prefix)) + return unet_conversion_map, unet_conversion_map_resnet, unet_conversion_map_layer + + +def convert_controlnet_state_dict_to_sd(controlnet_state_dict): + unet_conversion_map, unet_conversion_map_resnet, unet_conversion_map_layer = controlnet_conversion_map() + mapping = {k: k for k in controlnet_state_dict.keys()} for sd_name, diffusers_name in unet_conversion_map: mapping[diffusers_name] = sd_name @@ -807,6 +812,23 @@ def convert_controlnet_state_dict_to_sd(controlnet_state_dict): new_state_dict = {v: controlnet_state_dict[k] for k, v in mapping.items()} return new_state_dict +def convert_controlnet_state_dict_to_diffusers(controlnet_state_dict): + unet_conversion_map, unet_conversion_map_resnet, unet_conversion_map_layer = controlnet_conversion_map() + + mapping = {k: k for k in controlnet_state_dict.keys()} + for sd_name, diffusers_name in unet_conversion_map: + mapping[sd_name] = diffusers_name + for k, v in mapping.items(): + for sd_part, diffusers_part in unet_conversion_map_layer: + v = v.replace(sd_part, diffusers_part) + mapping[k] = v + for k, v in mapping.items(): + if "resnets" in v: + for sd_part, diffusers_part in unet_conversion_map_resnet: + v = v.replace(sd_part, diffusers_part) + mapping[k] = v + new_state_dict = {v: controlnet_state_dict[k] for k, v in mapping.items()} + return new_state_dict # ================# # VAE Conversion # @@ -928,7 +950,7 @@ def load_checkpoint_with_text_encoder_conversion(ckpt_path, device="cpu"): # TODO dtype指定の動作が怪しいので確認する text_encoderを指定形式で作れるか未確認 -def load_models_from_stable_diffusion_checkpoint(v2, ckpt_path, device="cpu", dtype=None, unet_use_linear_projection_in_v2=False): +def load_models_from_stable_diffusion_checkpoint(v2, ckpt_path, device="cpu", dtype=None, unet_use_linear_projection_in_v2=True): _, state_dict = load_checkpoint_with_text_encoder_conversion(ckpt_path, device) # Convert the UNet2DConditionModel model. diff --git a/library/train_util.py b/library/train_util.py index 1921c2a43..81dffb1d9 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -1674,7 +1674,6 @@ def __getitem__(self, index): cond_img = self.trim_and_resize_if_required(subset, cond_img, image_info.bucket_reso, image_info.resized_size) cond_img = self.conditioning_image_transforms(cond_img) conditioning_images.append(cond_img) - conditioning_images = torch.stack(conditioning_images) example = {} example["loss_weights"] = torch.FloatTensor(loss_weights) @@ -1699,7 +1698,7 @@ def __getitem__(self, index): if self.debug_dataset: example["image_keys"] = bucket[image_index : image_index + self.batch_size] - example["conditioning_images"] = conditioning_images.to(memory_format=torch.contiguous_format).float() + example["conditioning_images"] = torch.stack(conditioning_images).to(memory_format=torch.contiguous_format).float() return example @@ -3138,13 +3137,13 @@ def prepare_dtype(args: argparse.Namespace): return weight_dtype, save_dtype -def _load_target_model(args: argparse.Namespace, weight_dtype, device="cpu"): +def _load_target_model(args: argparse.Namespace, weight_dtype, device="cpu", unet_use_linear_projection_in_v2=False): name_or_path = args.pretrained_model_name_or_path name_or_path = os.readlink(name_or_path) if os.path.islink(name_or_path) else name_or_path load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers if load_stable_diffusion_format: print(f"load StableDiffusion checkpoint: {name_or_path}") - text_encoder, vae, unet = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, name_or_path, device) + text_encoder, vae, unet = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, name_or_path, device, unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2) else: # Diffusers model is loaded to CPU print(f"load Diffusers pretrained models: {name_or_path}") @@ -3172,14 +3171,14 @@ def transform_if_model_is_DDP(text_encoder, unet, network=None): return (model.module if type(model) == DDP else model for model in [text_encoder, unet, network] if model is not None) -def load_target_model(args, weight_dtype, accelerator): +def load_target_model(args, weight_dtype, accelerator, unet_use_linear_projection_in_v2=False): # load models for each process for pi in range(accelerator.state.num_processes): if pi == accelerator.state.local_process_index: print(f"loading model for process {accelerator.state.local_process_index}/{accelerator.state.num_processes}") text_encoder, vae, unet, load_stable_diffusion_format = _load_target_model( - args, weight_dtype, accelerator.device if args.lowram else "cpu" + args, weight_dtype, accelerator.device if args.lowram else "cpu", unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2 ) # work on low-ram device @@ -3493,7 +3492,7 @@ def save_sd_model_on_train_end( def sample_images( - accelerator, args: argparse.Namespace, epoch, steps, device, vae, tokenizer, text_encoder, unet, prompt_replacement=None + accelerator, args: argparse.Namespace, epoch, steps, device, vae, tokenizer, text_encoder, unet, prompt_replacement=None, controlnet=None ): """ StableDiffusionLongPromptWeightingPipelineの改造版を使うようにしたので、clip skipおよびプロンプトの重みづけに対応した @@ -3609,6 +3608,7 @@ def sample_images( height = prompt.get("height", 512) scale = prompt.get("scale", 7.5) seed = prompt.get("seed") + controlnet_image = prompt.get("controlnet_image") prompt = prompt.get("prompt") else: # prompt = prompt.strip() @@ -3623,6 +3623,7 @@ def sample_images( width = height = 512 scale = 7.5 seed = None + controlnet_image = None for parg in prompt_args: try: m = re.match(r"w (\d+)", parg, re.IGNORECASE) @@ -3655,6 +3656,12 @@ def sample_images( negative_prompt = m.group(1) continue + m = re.match(r"cn (.+)", parg, re.IGNORECASE) + if m: # negative prompt + controlnet_image = m.group(1) + continue + + except ValueError as ex: print(f"Exception in parsing / 解析エラー: {parg}") print(ex) @@ -3668,6 +3675,10 @@ def sample_images( if negative_prompt is not None: negative_prompt = negative_prompt.replace(prompt_replacement[0], prompt_replacement[1]) + if controlnet_image is not None: + controlnet_image = Image.open(controlnet_image).convert("RGB") + controlnet_image = controlnet_image.resize((width, height), Image.LANCZOS) + height = max(64, height - height % 8) # round to divisible by 8 width = max(64, width - width % 8) # round to divisible by 8 print(f"prompt: {prompt}") @@ -3683,6 +3694,8 @@ def sample_images( num_inference_steps=sample_steps, guidance_scale=scale, negative_prompt=negative_prompt, + controlnet=controlnet, + controlnet_image=controlnet_image, ).images[0] ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) diff --git a/train_controlnet.py b/train_controlnet.py index 7bcaf03a1..263e8813b 100644 --- a/train_controlnet.py +++ b/train_controlnet.py @@ -1,5 +1,6 @@ import argparse import gc +import json import math import os import random @@ -11,6 +12,7 @@ from torch.nn.parallel import DistributedDataParallel as DDP from accelerate.utils import set_seed from diffusers import DDPMScheduler, ControlNetModel +from safetensors.torch import load_file import library.model_util as model_util import library.train_util as train_util @@ -26,9 +28,6 @@ pyramid_noise_like, apply_noise_offset, ) -from diffusers.pipelines.stable_diffusion.convert_from_ckpt import ( - download_controlnet_from_original_ckpt, -) # TODO 他のスクリプトと共通化する @@ -124,19 +123,24 @@ def train(args): # モデルを読み込む text_encoder, vae, unet, _ = train_util.load_target_model( - args, weight_dtype, accelerator + args, weight_dtype, accelerator, unet_use_linear_projection_in_v2=True ) + + controlnet = ControlNetModel.from_unet(unet) + if args.controlnet_model_name_or_path: - if os.path.isfile(args.controlnet_model_name_or_path): - controlnet = download_controlnet_from_original_ckpt( - args.controlnet_model_name_or_path - ) - else: - controlnet = ControlNetModel.from_pretrained( - args.controlnet_model_name_or_path - ) - else: - controlnet = ControlNetModel.from_unet(unet) + filename = args.controlnet_model_name_or_path + if os.path.isfile(filename): + if os.path.splitext(filename)[1] == ".safetensors": + state_dict = load_file(filename) + else: + state_dict = torch.load(filename) + state_dict = model_util.convert_controlnet_state_dict_to_diffusers(state_dict) + controlnet.load_state_dict(state_dict) + elif os.path.isdir(filename): + controlnet = ControlNetModel.from_pretrained(filename) + + # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) @@ -289,7 +293,9 @@ def train(args): ) if accelerator.is_main_process: accelerator.init_trackers( - "controlnet_train" if args.log_tracker_name is None else args.log_tracker_name + "controlnet_train" + if args.log_tracker_name is None + else args.log_tracker_name ) loss_list = [] @@ -350,7 +356,7 @@ def remove_model(old_ckpt_name): b_size = latents.shape[0] input_ids = batch["input_ids"].to(accelerator.device) - encoder_hidden_states = train_util.gethidden_states( + encoder_hidden_states = train_util.get_hidden_states( args, input_ids, tokenizer, text_encoder, weight_dtype ) @@ -450,6 +456,7 @@ def remove_model(old_ckpt_name): tokenizer, text_encoder, unet, + controlnet=controlnet, ) # 指定ステップごとにモデルを保存 @@ -537,6 +544,7 @@ def remove_model(old_ckpt_name): tokenizer, text_encoder, unet, + controlnet=controlnet, ) # end of epoch @@ -569,6 +577,13 @@ def setup_parser() -> argparse.ArgumentParser: config_util.add_config_arguments(parser) custom_train_functions.add_custom_train_arguments(parser) + parser.add_argument( + "--save_model_as", + type=str, + default="safetensors", + choices=[None, "ckpt", "pt", "safetensors"], + help="format to save the model (default is .safetensors) / モデル保存時の形式(デフォルトはsafetensors)", + ) parser.add_argument( "--controlnet_model_name_or_path", type=str, From 1e3daa247bbfe10957d54fb337e2ced8853a0d2d Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Thu, 1 Jun 2023 21:58:45 +0900 Subject: [PATCH 009/220] fix bucketing --- library/train_util.py | 55 +++++++++++++++++---------------------- train_controlnet.py | 60 ++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 63 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index 81dffb1d9..b5e6aa3fc 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -754,12 +754,14 @@ def load_image(self, image_path): img = np.array(image, np.uint8) return img - def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_size): + def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_size, cond_img = None): image_height, image_width = image.shape[0:2] if image_width != resized_size[0] or image_height != resized_size[1]: # リサイズする image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ + if exists(cond_img): + cond_img = cv2.resize(cond_img, resized_size, interpolation=cv2.INTER_AREA) image_height, image_width = image.shape[0:2] if image_width > reso[0]: @@ -767,15 +769,26 @@ def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_s p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) # print("w", trim_size, p) image = image[:, p : p + reso[0]] + if exists(cond_img): + cond_img = cond_img[:, p : p + reso[0]] if image_height > reso[1]: trim_size = image_height - reso[1] p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) # print("h", trim_size, p) image = image[p : p + reso[1]] + if exists(cond_img): + cond_img = cond_img[p : p + reso[1]] assert ( image.shape[0] == reso[1] and image.shape[1] == reso[0] ), f"internal error, illegal trimmed size: {image.shape}, {reso}" + + if exists(cond_img): + assert ( + cond_img.shape[0] == reso[1] and cond_img.shape[1] == reso[0] + ), f"internal error, illegal trimmed size: {cond_img.shape}, {reso}" + return image, cond_img + return image def is_latent_cacheable(self): @@ -1617,6 +1630,8 @@ def __getitem__(self, index): subset = self.image_to_subset[image_key] loss_weights.append(1.0) + assert hasattr(image_info, "cond_img_path"), f"conditioning image path is not found: {image_info.absolute_path}" + # image/latentsを処理する if image_info.latents is not None: # cache_latents=Trueの場合 latents = image_info.latents if not subset.flip_aug or random.random() < 0.5 else image_info.latents_flipped @@ -1628,10 +1643,11 @@ def __getitem__(self, index): else: # 画像を読み込み、必要ならcropする img = self.load_image(image_info.absolute_path) + cond_img = self.load_image(image_info.cond_img_path) im_h, im_w = img.shape[0:2] if self.enable_bucket: - img = self.trim_and_resize_if_required(subset, img, image_info.bucket_reso, image_info.resized_size) + img, cond_img = self.trim_and_resize_if_required(subset, img, image_info.bucket_reso, image_info.resized_size, cond_img=cond_img) else: im_h, im_w = img.shape[0:2] assert ( @@ -1649,41 +1665,18 @@ def __getitem__(self, index): images.append(image) latents_list.append(latents) - caption = self.process_caption(subset, image_info.caption) - if self.XTI_layers: - caption_layer = [] - for layer in self.XTI_layers: - token_strings_from = " ".join(self.token_strings) - token_strings_to = " ".join([f"{x}_{layer}" for x in self.token_strings]) - caption_ = caption.replace(token_strings_from, token_strings_to) - caption_layer.append(caption_) - captions.append(caption_layer) - else: - captions.append(caption) - if not self.token_padding_disabled: # this option might be omitted in future - if self.XTI_layers: - token_caption = self.get_input_ids(caption_layer) - else: - token_caption = self.get_input_ids(caption) - input_ids_list.append(token_caption) - - assert hasattr(image_info, "cond_img_path"), f"conditioning image path is not found: {image_info.absolute_path}" - - cond_img = self.load_image(image_info.cond_img_path) - if self.enable_bucket: - cond_img = self.trim_and_resize_if_required(subset, cond_img, image_info.bucket_reso, image_info.resized_size) cond_img = self.conditioning_image_transforms(cond_img) conditioning_images.append(cond_img) + caption = self.process_caption(subset, image_info.caption) + captions.append(caption) + token_caption = self.get_input_ids(caption) + input_ids_list.append(token_caption) + example = {} example["loss_weights"] = torch.FloatTensor(loss_weights) - if self.token_padding_disabled: - # padding=True means pad in the batch - example["input_ids"] = self.tokenizer(captions, padding=True, truncation=True, return_tensors="pt").input_ids - else: - # batch processing seems to be good - example["input_ids"] = torch.stack(input_ids_list) + example["input_ids"] = torch.stack(input_ids_list) if images[0] is not None: images = torch.stack(images) diff --git a/train_controlnet.py b/train_controlnet.py index 263e8813b..6e4e5bb82 100644 --- a/train_controlnet.py +++ b/train_controlnet.py @@ -141,7 +141,6 @@ def train(args): controlnet = ControlNetModel.from_pretrained(filename) - # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) @@ -168,11 +167,11 @@ def train(args): controlnet.enable_gradient_checkpointing() # 学習に必要なクラスを準備する - print("prepare optimizer, data loader etc.") + accelerator.print("prepare optimizer, data loader etc.") trainable_params = controlnet.parameters() - optimizer_name, optimizer_args, optimizer = train_util.get_optimizer( + _, _, optimizer = train_util.get_optimizer( args, trainable_params ) @@ -198,10 +197,9 @@ def train(args): / accelerator.num_processes / args.gradient_accumulation_steps ) - if is_main_process: - print( - f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" - ) + accelerator.print( + f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" + ) # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) @@ -216,7 +214,7 @@ def train(args): assert ( args.mixed_precision == "fp16" ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" - print("enable full fp16 training.") + accelerator.print("enable full fp16 training.") controlnet.to(weight_dtype) # acceleratorがなんかよろしくやってくれるらしい @@ -258,23 +256,21 @@ def train(args): # 学習する # TODO: find a way to handle total batch size when there are multiple datasets - - if is_main_process: - print("running training / 学習開始") - print( - f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}" - ) - print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - print(f" num epochs / epoch数: {num_train_epochs}") - print( - f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" - ) - # print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - print( - f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}" - ) - print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + accelerator.print("running training / 学習開始") + accelerator.print( + f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}" + ) + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print( + f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" + ) + # print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print( + f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}" + ) + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") progress_bar = tqdm( range(args.max_train_steps), @@ -303,11 +299,11 @@ def train(args): del train_dataset_group # function for saving/removing - def save_model(ckpt_name, model, steps, epoch_no, force_sync_upload=False): + def save_model(ckpt_name, model, force_sync_upload=False): os.makedirs(args.output_dir, exist_ok=True) ckpt_file = os.path.join(args.output_dir, ckpt_name) - print(f"\nsaving checkpoint: {ckpt_file}") + accelerator.print(f"\nsaving checkpoint: {ckpt_file}") state_dict = model_util.convert_controlnet_state_dict_to_sd(model.state_dict()) @@ -332,13 +328,13 @@ def save_model(ckpt_name, model, steps, epoch_no, force_sync_upload=False): def remove_model(old_ckpt_name): old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) if os.path.exists(old_ckpt_file): - print(f"removing old checkpoint: {old_ckpt_file}") + accelerator.print(f"removing old checkpoint: {old_ckpt_file}") os.remove(old_ckpt_file) # training loop for epoch in range(num_train_epochs): if is_main_process: - print(f"\nepoch {epoch+1}/{num_train_epochs}") + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") current_epoch.value = epoch + 1 for step, batch in enumerate(train_dataloader): @@ -470,7 +466,7 @@ def remove_model(old_ckpt_name): args, "." + args.save_model_as, global_step ) save_model( - ckpt_name, unwrap_model(controlnet), global_step, epoch + ckpt_name, unwrap_model(controlnet), ) if args.save_state: @@ -520,7 +516,7 @@ def remove_model(old_ckpt_name): ckpt_name = train_util.get_epoch_ckpt_name( args, "." + args.save_model_as, epoch + 1 ) - save_model(ckpt_name, unwrap_model(controlnet), global_step, epoch + 1) + save_model(ckpt_name, unwrap_model(controlnet)) remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) if remove_epoch_no is not None: @@ -561,7 +557,7 @@ def remove_model(old_ckpt_name): if is_main_process: ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) save_model( - ckpt_name, controlnet, global_step, num_train_epochs, force_sync_upload=True + ckpt_name, controlnet, force_sync_upload=True ) print("model saved.") From 5db792b10b7da7ff2d523e0083430dcbd5426a36 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 3 Jun 2023 19:24:47 +0900 Subject: [PATCH 010/220] initial commit for original U-Net --- gen_img_diffusers.py | 3 +- library/model_util.py | 3 +- library/original_unet.py | 1234 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 1238 insertions(+), 2 deletions(-) create mode 100644 library/original_unet.py diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 27bd7460d..4d8121ca1 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -78,7 +78,7 @@ HeunDiscreteScheduler, KDPM2DiscreteScheduler, KDPM2AncestralDiscreteScheduler, - UNet2DConditionModel, + # UNet2DConditionModel, StableDiffusionPipeline, ) from einops import rearrange @@ -95,6 +95,7 @@ from networks.lora import LoRANetwork import tools.original_control_net as original_control_net from tools.original_control_net import ControlNetInfo +from library.original_unet import UNet2DConditionModel from XTI_hijack import unet_forward_XTI, downblock_forward_XTI, upblock_forward_XTI diff --git a/library/model_util.py b/library/model_util.py index 26f72235d..0fbc65901 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -5,8 +5,9 @@ import os import torch from transformers import CLIPTextModel, CLIPTokenizer, CLIPTextConfig, logging -from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline, UNet2DConditionModel +from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline #, UNet2DConditionModel from safetensors.torch import load_file, save_file +from library.original_unet import UNet2DConditionModel # DiffUsers版StableDiffusionのモデルパラメータ NUM_TRAIN_TIMESTEPS = 1000 diff --git a/library/original_unet.py b/library/original_unet.py new file mode 100644 index 000000000..603239d57 --- /dev/null +++ b/library/original_unet.py @@ -0,0 +1,1234 @@ +# Diffusers 0.10.2からStable Diffusionに必要な部分だけを持ってくる +# コードの多くはDiffusersからコピーしている +# コードが冗長になる部分はコメント等を適宜削除する +# 制約として、モデルのstate_dictがDiffusers 0.10.2のものと同じ形式である必要がある + +# Copy from Diffusers 0.10.2 for Stable Diffusion. Most of the code is copied from Diffusers. +# Remove redundant code by deleting comments, etc. as appropriate +# As a constraint, the state_dict of the model must be in the same format as that of Diffusers 0.10.2 + +""" +v1.5とv2.1の相違点は +- attention_head_dimがintかlist[int]か +- cross_attention_dimが768か1024か +- use_linear_projection: trueがない(=False, 1.5)かあるか +- upcast_attentionがFalse(1.5)かTrue(2.1)か +- (以下は多分無視していい) +- sample_sizeが64か96か +- dual_cross_attentionがあるかないか +- num_class_embedsがあるかないか +- only_cross_attentionがあるかないか + +v1.5 +{ + "_class_name": "UNet2DConditionModel", + "_diffusers_version": "0.6.0", + "act_fn": "silu", + "attention_head_dim": 8, + "block_out_channels": [ + 320, + 640, + 1280, + 1280 + ], + "center_input_sample": false, + "cross_attention_dim": 768, + "down_block_types": [ + "CrossAttnDownBlock2D", + "CrossAttnDownBlock2D", + "CrossAttnDownBlock2D", + "DownBlock2D" + ], + "downsample_padding": 1, + "flip_sin_to_cos": true, + "freq_shift": 0, + "in_channels": 4, + "layers_per_block": 2, + "mid_block_scale_factor": 1, + "norm_eps": 1e-05, + "norm_num_groups": 32, + "out_channels": 4, + "sample_size": 64, + "up_block_types": [ + "UpBlock2D", + "CrossAttnUpBlock2D", + "CrossAttnUpBlock2D", + "CrossAttnUpBlock2D" + ] +} + +v2.1 +{ + "_class_name": "UNet2DConditionModel", + "_diffusers_version": "0.10.0.dev0", + "act_fn": "silu", + "attention_head_dim": [ + 5, + 10, + 20, + 20 + ], + "block_out_channels": [ + 320, + 640, + 1280, + 1280 + ], + "center_input_sample": false, + "cross_attention_dim": 1024, + "down_block_types": [ + "CrossAttnDownBlock2D", + "CrossAttnDownBlock2D", + "CrossAttnDownBlock2D", + "DownBlock2D" + ], + "downsample_padding": 1, + "dual_cross_attention": false, + "flip_sin_to_cos": true, + "freq_shift": 0, + "in_channels": 4, + "layers_per_block": 2, + "mid_block_scale_factor": 1, + "norm_eps": 1e-05, + "norm_num_groups": 32, + "num_class_embeds": null, + "only_cross_attention": false, + "out_channels": 4, + "sample_size": 96, + "up_block_types": [ + "UpBlock2D", + "CrossAttnUpBlock2D", + "CrossAttnUpBlock2D", + "CrossAttnUpBlock2D" + ], + "use_linear_projection": true, + "upcast_attention": true +} +""" + +import math +from typing import Dict, Optional, Tuple, Union +import torch +from torch import nn +from torch.nn import functional as F + +BLOCK_OUT_CHANNELS: Tuple[int] = (320, 640, 1280, 1280) +TIMESTEP_INPUT_DIM = BLOCK_OUT_CHANNELS[0] +TIME_EMBED_DIM = BLOCK_OUT_CHANNELS[0] * 4 +IN_CHANNELS: int = 4 +OUT_CHANNELS: int = 4 +LAYERS_PER_BLOCK: int = 2 +LAYERS_PER_BLOCK_UP: int = LAYERS_PER_BLOCK + 1 +TIME_EMBED_FLIP_SIN_TO_COS: bool = True +TIME_EMBED_FREQ_SHIFT: int = 0 +RESNET_GROUPS: int = 32 +RESNET_EPS: float = 1e-6 +TRANSFORMER_NORM_NUM_GROUPS = 32 + +DOWN_BLOCK_TYPES = ["CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "DownBlock2D"] +UP_BLOCK_TYPES = ["UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"] + + +def get_parameter_dtype(parameter: torch.nn.Module): + return next(parameter.parameters()).dtype + + +def get_timestep_embedding( + timesteps: torch.Tensor, + embedding_dim: int, + flip_sin_to_cos: bool = False, + downscale_freq_shift: float = 1, + scale: float = 1, + max_period: int = 10000, +): + """ + This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings. + + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param embedding_dim: the dimension of the output. :param max_period: controls the minimum frequency of the + embeddings. :return: an [N x dim] Tensor of positional embeddings. + """ + assert len(timesteps.shape) == 1, "Timesteps should be a 1d-array" + + half_dim = embedding_dim // 2 + exponent = -math.log(max_period) * torch.arange(start=0, end=half_dim, dtype=torch.float32, device=timesteps.device) + exponent = exponent / (half_dim - downscale_freq_shift) + + emb = torch.exp(exponent) + emb = timesteps[:, None].float() * emb[None, :] + + # scale embeddings + emb = scale * emb + + # concat sine and cosine embeddings + emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1) + + # flip sine and cosine embeddings + if flip_sin_to_cos: + emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1) + + # zero pad + if embedding_dim % 2 == 1: + emb = torch.nn.functional.pad(emb, (0, 1, 0, 0)) + return emb + + +class SampleOutput: + def __init__(self, sample): + self.sample = sample + + +class TimestepEmbedding(nn.Module): + def __init__(self, in_channels: int, time_embed_dim: int, act_fn: str = "silu", out_dim: int = None): + super().__init__() + + self.linear_1 = nn.Linear(in_channels, time_embed_dim) + self.act = None + if act_fn == "silu": + self.act = nn.SiLU() + elif act_fn == "mish": + self.act = nn.Mish() + + if out_dim is not None: + time_embed_dim_out = out_dim + else: + time_embed_dim_out = time_embed_dim + self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim_out) + + def forward(self, sample): + sample = self.linear_1(sample) + + if self.act is not None: + sample = self.act(sample) + + sample = self.linear_2(sample) + return sample + + +class Timesteps(nn.Module): + def __init__(self, num_channels: int, flip_sin_to_cos: bool, downscale_freq_shift: float): + super().__init__() + self.num_channels = num_channels + self.flip_sin_to_cos = flip_sin_to_cos + self.downscale_freq_shift = downscale_freq_shift + + def forward(self, timesteps): + t_emb = get_timestep_embedding( + timesteps, + self.num_channels, + flip_sin_to_cos=self.flip_sin_to_cos, + downscale_freq_shift=self.downscale_freq_shift, + ) + return t_emb + + +class ResnetBlock2D(nn.Module): + def __init__( + self, + in_channels, + out_channels, + ): + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + + self.norm1 = torch.nn.GroupNorm(num_groups=RESNET_GROUPS, num_channels=in_channels, eps=RESNET_EPS, affine=True) + + self.conv1 = torch.nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1) + + self.time_emb_proj = torch.nn.Linear(TIME_EMBED_DIM, out_channels) + + self.norm2 = torch.nn.GroupNorm(num_groups=RESNET_GROUPS, num_channels=out_channels, eps=RESNET_EPS, affine=True) + self.conv2 = torch.nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) + + # if non_linearity == "swish": + self.nonlinearity = lambda x: F.silu(x) + + self.use_in_shortcut = self.in_channels != self.out_channels + + self.conv_shortcut = None + if self.use_in_shortcut: + self.conv_shortcut = torch.nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0) + + def forward(self, input_tensor, temb): + hidden_states = input_tensor + + hidden_states = self.norm1(hidden_states) + hidden_states = self.nonlinearity(hidden_states) + + hidden_states = self.conv1(hidden_states) + + temb = self.time_emb_proj(self.nonlinearity(temb))[:, :, None, None] + hidden_states = hidden_states + temb + + hidden_states = self.norm2(hidden_states) + hidden_states = self.nonlinearity(hidden_states) + + hidden_states = self.conv2(hidden_states) + + if self.conv_shortcut is not None: + input_tensor = self.conv_shortcut(input_tensor) + + output_tensor = input_tensor + hidden_states + + return output_tensor + + +class DownBlock2D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + add_downsample=True, + ): + super().__init__() + + self.has_cross_attention = False + resnets = [] + + for i in range(LAYERS_PER_BLOCK): + in_channels = in_channels if i == 0 else out_channels + resnets.append( + ResnetBlock2D( + in_channels=in_channels, + out_channels=out_channels, + ) + ) + self.resnets = nn.ModuleList(resnets) + + if add_downsample: + self.downsamplers = [Downsample2D(out_channels, out_channels=out_channels)] + else: + self.downsamplers = None + + self.gradient_checkpointing = False + + def forward(self, hidden_states, temb=None): + output_states = () + + for resnet in self.resnets: + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb) + else: + hidden_states = resnet(hidden_states, temb) + + output_states += (hidden_states,) + + if self.downsamplers is not None: + for downsampler in self.downsamplers: + hidden_states = downsampler(hidden_states) + + output_states += (hidden_states,) + + return hidden_states, output_states + + +class Downsample2D(nn.Module): + def __init__(self, channels, out_channels): + super().__init__() + + self.channels = channels + self.out_channels = out_channels + + self.conv = nn.Conv2d(self.channels, self.out_channels, 3, stride=2, padding=1) + + def forward(self, hidden_states): + assert hidden_states.shape[1] == self.channels + hidden_states = self.conv(hidden_states) + + return hidden_states + + +class CrossAttention(nn.Module): + def __init__( + self, + query_dim: int, + cross_attention_dim: Optional[int] = None, + heads: int = 8, + dim_head: int = 64, + upcast_attention: bool = False, + ): + super().__init__() + inner_dim = dim_head * heads + cross_attention_dim = cross_attention_dim if cross_attention_dim is not None else query_dim + self.upcast_attention = upcast_attention + + self.scale = dim_head**-0.5 + self.heads = heads + + self.to_q = nn.Linear(query_dim, inner_dim, bias=False) + self.to_k = nn.Linear(cross_attention_dim, inner_dim, bias=False) + self.to_v = nn.Linear(cross_attention_dim, inner_dim, bias=False) + + self.to_out = nn.ModuleList([]) + self.to_out.append(nn.Linear(inner_dim, query_dim)) + # no dropout here + + def reshape_heads_to_batch_dim(self, tensor): + batch_size, seq_len, dim = tensor.shape + head_size = self.heads + tensor = tensor.reshape(batch_size, seq_len, head_size, dim // head_size) + tensor = tensor.permute(0, 2, 1, 3).reshape(batch_size * head_size, seq_len, dim // head_size) + return tensor + + def reshape_batch_dim_to_heads(self, tensor): + batch_size, seq_len, dim = tensor.shape + head_size = self.heads + tensor = tensor.reshape(batch_size // head_size, head_size, seq_len, dim) + tensor = tensor.permute(0, 2, 1, 3).reshape(batch_size // head_size, seq_len, dim * head_size) + return tensor + + def forward(self, hidden_states, context=None, mask=None): + query = self.to_q(hidden_states) + context = context if context is not None else hidden_states + key = self.to_k(context) + value = self.to_v(context) + + query = self.reshape_heads_to_batch_dim(query) + key = self.reshape_heads_to_batch_dim(key) + value = self.reshape_heads_to_batch_dim(value) + + hidden_states = self._attention(query, key, value) + + # linear proj + hidden_states = self.to_out[0](hidden_states) + # hidden_states = self.to_out[1](hidden_states) # no dropout + return hidden_states + + def _attention(self, query, key, value): + if self.upcast_attention: + query = query.float() + key = key.float() + + attention_scores = torch.baddbmm( + torch.empty(query.shape[0], query.shape[1], key.shape[1], dtype=query.dtype, device=query.device), + query, + key.transpose(-1, -2), + beta=0, + alpha=self.scale, + ) + attention_probs = attention_scores.softmax(dim=-1) + + # cast back to the original dtype + attention_probs = attention_probs.to(value.dtype) + + # compute attention output + hidden_states = torch.bmm(attention_probs, value) + + # reshape hidden_states + hidden_states = self.reshape_batch_dim_to_heads(hidden_states) + return hidden_states + + +# feedforward +class GEGLU(nn.Module): + r""" + A variant of the gated linear unit activation function from https://arxiv.org/abs/2002.05202. + + Parameters: + dim_in (`int`): The number of channels in the input. + dim_out (`int`): The number of channels in the output. + """ + + def __init__(self, dim_in: int, dim_out: int): + super().__init__() + self.proj = nn.Linear(dim_in, dim_out * 2) + + def gelu(self, gate): + if gate.device.type != "mps": + return F.gelu(gate) + # mps: gelu is not implemented for float16 + return F.gelu(gate.to(dtype=torch.float32)).to(dtype=gate.dtype) + + def forward(self, hidden_states): + hidden_states, gate = self.proj(hidden_states).chunk(2, dim=-1) + return hidden_states * self.gelu(gate) + + +class FeedForward(nn.Module): + def __init__( + self, + dim: int, + ): + super().__init__() + inner_dim = int(dim * 4) # mult is always 4 + + self.net = nn.ModuleList([]) + # project in + self.net.append(GEGLU(dim, inner_dim)) + # project dropout + self.net.append(nn.Identity()) # nn.Dropout(0)) # dummy for dropout with 0 + # project out + self.net.append(nn.Linear(inner_dim, dim)) + + def forward(self, hidden_states): + for module in self.net: + hidden_states = module(hidden_states) + return hidden_states + + +class BasicTransformerBlock(nn.Module): + def __init__( + self, dim: int, num_attention_heads: int, attention_head_dim: int, cross_attention_dim: int, upcast_attention: bool = False + ): + super().__init__() + + # 1. Self-Attn + self.attn1 = CrossAttention( + query_dim=dim, + cross_attention_dim=None, + heads=num_attention_heads, + dim_head=attention_head_dim, + upcast_attention=upcast_attention, + ) + self.ff = FeedForward(dim) + + # 2. Cross-Attn + self.attn2 = CrossAttention( + query_dim=dim, + cross_attention_dim=cross_attention_dim, + heads=num_attention_heads, + dim_head=attention_head_dim, + upcast_attention=upcast_attention, + ) + + self.norm1 = nn.LayerNorm(dim) + self.norm2 = nn.LayerNorm(dim) + + # 3. Feed-forward + self.norm3 = nn.LayerNorm(dim) + + def set_use_memory_efficient_attention_xformers(self, use_memory_efficient_attention_xformers: bool): + raise NotImplementedError("Memory efficient attention is not implemented for this model.") + + def forward(self, hidden_states, context=None, timestep=None): + # 1. Self-Attention + norm_hidden_states = self.norm1(hidden_states) + + hidden_states = self.attn1(norm_hidden_states) + hidden_states + + # 2. Cross-Attention + norm_hidden_states = self.norm2(hidden_states) + hidden_states = self.attn2(norm_hidden_states, context=context) + hidden_states + + # 3. Feed-forward + hidden_states = self.ff(self.norm3(hidden_states)) + hidden_states + + return hidden_states + + +class Transformer2DModel(nn.Module): + def __init__( + self, + num_attention_heads: int = 16, + attention_head_dim: int = 88, + in_channels: Optional[int] = None, + cross_attention_dim: Optional[int] = None, + use_linear_projection: bool = False, + upcast_attention: bool = False, + ): + super().__init__() + self.in_channels = in_channels + self.num_attention_heads = num_attention_heads + self.attention_head_dim = attention_head_dim + inner_dim = num_attention_heads * attention_head_dim + self.use_linear_projection = use_linear_projection + + self.norm = torch.nn.GroupNorm(num_groups=TRANSFORMER_NORM_NUM_GROUPS, num_channels=in_channels, eps=1e-6, affine=True) + + if use_linear_projection: + self.proj_in = nn.Linear(in_channels, inner_dim) + else: + self.proj_in = nn.Conv2d(in_channels, inner_dim, kernel_size=1, stride=1, padding=0) + + self.transformer_blocks = nn.ModuleList( + [ + BasicTransformerBlock( + inner_dim, + num_attention_heads, + attention_head_dim, + cross_attention_dim=cross_attention_dim, + upcast_attention=upcast_attention, + ) + ] + ) + + if use_linear_projection: + self.proj_out = nn.Linear(in_channels, inner_dim) + else: + self.proj_out = nn.Conv2d(inner_dim, in_channels, kernel_size=1, stride=1, padding=0) + + def forward(self, hidden_states, encoder_hidden_states=None, timestep=None, return_dict: bool = True): + # 1. Input + batch, _, height, weight = hidden_states.shape + residual = hidden_states + + hidden_states = self.norm(hidden_states) + if not self.use_linear_projection: + hidden_states = self.proj_in(hidden_states) + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * weight, inner_dim) + else: + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * weight, inner_dim) + hidden_states = self.proj_in(hidden_states) + + # 2. Blocks + for block in self.transformer_blocks: + hidden_states = block(hidden_states, context=encoder_hidden_states, timestep=timestep) + + # 3. Output + if not self.use_linear_projection: + hidden_states = hidden_states.reshape(batch, height, weight, inner_dim).permute(0, 3, 1, 2).contiguous() + hidden_states = self.proj_out(hidden_states) + else: + hidden_states = self.proj_out(hidden_states) + hidden_states = hidden_states.reshape(batch, height, weight, inner_dim).permute(0, 3, 1, 2).contiguous() + + output = hidden_states + residual + + if not return_dict: + return (output,) + + return SampleOutput(sample=output) + + +class CrossAttnDownBlock2D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + add_downsample=True, + cross_attention_dim=1280, + attn_num_head_channels=1, + use_linear_projection=False, + upcast_attention=False, + ): + super().__init__() + self.has_cross_attention = True + resnets = [] + attentions = [] + + self.attn_num_head_channels = attn_num_head_channels + + for i in range(LAYERS_PER_BLOCK): + in_channels = in_channels if i == 0 else out_channels + + resnets.append(ResnetBlock2D(in_channels=in_channels, out_channels=out_channels)) + attentions.append( + Transformer2DModel( + attn_num_head_channels, + out_channels // attn_num_head_channels, + in_channels=out_channels, + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + ) + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + + if add_downsample: + self.downsamplers = nn.ModuleList([Downsample2D(out_channels, out_channels)]) + else: + self.downsamplers = None + + self.gradient_checkpointing = False + + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): + output_states = () + + for resnet, attn in zip(self.resnets, self.attentions): + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module, return_dict=None): + def custom_forward(*inputs): + if return_dict is not None: + return module(*inputs, return_dict=return_dict) + else: + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb) + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(attn, return_dict=False), hidden_states, encoder_hidden_states + )[0] + else: + hidden_states = resnet(hidden_states, temb) + hidden_states = attn(hidden_states, encoder_hidden_states=encoder_hidden_states).sample + + output_states += (hidden_states,) + + if self.downsamplers is not None: + for downsampler in self.downsamplers: + hidden_states = downsampler(hidden_states) + + output_states += (hidden_states,) + + return hidden_states, output_states + + +class UNetMidBlock2DCrossAttn(nn.Module): + def __init__( + self, + in_channels: int, + attn_num_head_channels=1, + cross_attention_dim=1280, + use_linear_projection=False, + ): + super().__init__() + + self.has_cross_attention = True + self.attn_num_head_channels = attn_num_head_channels + + # Middle block has two resnets and one attention + resnets = [ + ResnetBlock2D( + in_channels=in_channels, + out_channels=in_channels, + ), + ResnetBlock2D( + in_channels=in_channels, + out_channels=in_channels, + ), + ] + attentions = [ + Transformer2DModel( + attn_num_head_channels, + in_channels // attn_num_head_channels, + in_channels=in_channels, + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + ) + ] + + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): + hidden_states = self.resnets[0](hidden_states, temb) + for attn, resnet in zip(self.attentions, self.resnets[1:]): + hidden_states = attn(hidden_states, encoder_hidden_states).sample + hidden_states = resnet(hidden_states, temb) + + return hidden_states + + +class Upsample2D(nn.Module): + def __init__(self, channels, out_channels): + super().__init__() + self.channels = channels + self.out_channels = out_channels + self.conv = nn.Conv2d(self.channels, self.out_channels, 3, padding=1) + + def forward(self, hidden_states, output_size): + assert hidden_states.shape[1] == self.channels + + # Cast to float32 to as 'upsample_nearest2d_out_frame' op does not support bfloat16 + # TODO(Suraj): Remove this cast once the issue is fixed in PyTorch + # https://github.com/pytorch/pytorch/issues/86679 + dtype = hidden_states.dtype + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(torch.float32) + + # upsample_nearest_nhwc fails with large batch sizes. see https://github.com/huggingface/diffusers/issues/984 + if hidden_states.shape[0] >= 64: + hidden_states = hidden_states.contiguous() + + # if `output_size` is passed we force the interpolation output size and do not make use of `scale_factor=2` + if output_size is None: + hidden_states = F.interpolate(hidden_states, scale_factor=2.0, mode="nearest") + else: + hidden_states = F.interpolate(hidden_states, size=output_size, mode="nearest") + + # If the input is bfloat16, we cast back to bfloat16 + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(dtype) + + hidden_states = self.conv(hidden_states) + + return hidden_states + + +class UpBlock2D(nn.Module): + def __init__( + self, + in_channels: int, + prev_output_channel: int, + out_channels: int, + add_upsample=True, + ): + super().__init__() + + self.has_cross_attention = False + resnets = [] + + for i in range(LAYERS_PER_BLOCK_UP): + res_skip_channels = in_channels if (i == LAYERS_PER_BLOCK_UP - 1) else out_channels + resnet_in_channels = prev_output_channel if i == 0 else out_channels + + resnets.append( + ResnetBlock2D( + in_channels=resnet_in_channels + res_skip_channels, + out_channels=out_channels, + ) + ) + + self.resnets = nn.ModuleList(resnets) + + if add_upsample: + self.upsamplers = nn.ModuleList([Upsample2D(out_channels, out_channels)]) + else: + self.upsamplers = None + + self.gradient_checkpointing = False + + def forward(self, hidden_states, res_hidden_states_tuple, temb=None, upsample_size=None): + for resnet in self.resnets: + # pop res hidden states + res_hidden_states = res_hidden_states_tuple[-1] + res_hidden_states_tuple = res_hidden_states_tuple[:-1] + hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1) + + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module): + def custom_forward(*inputs): + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb) + else: + hidden_states = resnet(hidden_states, temb) + + if self.upsamplers is not None: + for upsampler in self.upsamplers: + hidden_states = upsampler(hidden_states, upsample_size) + + return hidden_states + + +class CrossAttnUpBlock2D(nn.Module): + def __init__( + self, + in_channels: int, + out_channels: int, + prev_output_channel: int, + attn_num_head_channels=1, + cross_attention_dim=1280, + add_upsample=True, + use_linear_projection=False, + upcast_attention=False, + ): + super().__init__() + resnets = [] + attentions = [] + + self.has_cross_attention = True + self.attn_num_head_channels = attn_num_head_channels + + for i in range(LAYERS_PER_BLOCK_UP): + res_skip_channels = in_channels if (i == LAYERS_PER_BLOCK_UP - 1) else out_channels + resnet_in_channels = prev_output_channel if i == 0 else out_channels + + resnets.append( + ResnetBlock2D( + in_channels=resnet_in_channels + res_skip_channels, + out_channels=out_channels, + ) + ) + attentions.append( + Transformer2DModel( + attn_num_head_channels, + out_channels // attn_num_head_channels, + in_channels=out_channels, + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + ) + + self.attentions = nn.ModuleList(attentions) + self.resnets = nn.ModuleList(resnets) + + if add_upsample: + self.upsamplers = nn.ModuleList([Upsample2D(out_channels, out_channels)]) + else: + self.upsamplers = None + + self.gradient_checkpointing = False + + def forward( + self, + hidden_states, + res_hidden_states_tuple, + temb=None, + encoder_hidden_states=None, + upsample_size=None, + ): + for resnet, attn in zip(self.resnets, self.attentions): + # pop res hidden states + res_hidden_states = res_hidden_states_tuple[-1] + res_hidden_states_tuple = res_hidden_states_tuple[:-1] + hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1) + + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module, return_dict=None): + def custom_forward(*inputs): + if return_dict is not None: + return module(*inputs, return_dict=return_dict) + else: + return module(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb) + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(attn, return_dict=False), hidden_states, encoder_hidden_states + )[0] + else: + hidden_states = resnet(hidden_states, temb) + hidden_states = attn(hidden_states, encoder_hidden_states=encoder_hidden_states).sample + + if self.upsamplers is not None: + for upsampler in self.upsamplers: + hidden_states = upsampler(hidden_states, upsample_size) + + return hidden_states + + +def get_down_block( + down_block_type, + in_channels, + out_channels, + add_downsample, + attn_num_head_channels, + cross_attention_dim, + use_linear_projection, + upcast_attention, +): + if down_block_type == "DownBlock2D": + return DownBlock2D( + in_channels=in_channels, + out_channels=out_channels, + add_downsample=add_downsample, + ) + elif down_block_type == "CrossAttnDownBlock2D": + return CrossAttnDownBlock2D( + in_channels=in_channels, + out_channels=out_channels, + add_downsample=add_downsample, + cross_attention_dim=cross_attention_dim, + attn_num_head_channels=attn_num_head_channels, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + + +def get_up_block( + up_block_type, + in_channels, + out_channels, + prev_output_channel, + add_upsample, + attn_num_head_channels, + cross_attention_dim=None, + use_linear_projection=False, + upcast_attention=False, +): + if up_block_type == "UpBlock2D": + return UpBlock2D( + in_channels=in_channels, + prev_output_channel=prev_output_channel, + out_channels=out_channels, + add_upsample=add_upsample, + ) + elif up_block_type == "CrossAttnUpBlock2D": + return CrossAttnUpBlock2D( + in_channels=in_channels, + out_channels=out_channels, + prev_output_channel=prev_output_channel, + attn_num_head_channels=attn_num_head_channels, + cross_attention_dim=cross_attention_dim, + add_upsample=add_upsample, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + + +class UNet2DConditionModel(nn.Module): + _supports_gradient_checkpointing = True + + def __init__( + self, + sample_size: Optional[int] = None, + attention_head_dim: Union[int, Tuple[int]] = 8, + cross_attention_dim: int = 1280, + use_linear_projection: bool = False, + upcast_attention: bool = False, + **kwargs, + ): + super().__init__() + assert sample_size is not None, "sample_size must be specified" + print( + f"UNet2DConditionModel: {sample_size}, {attention_head_dim}, {cross_attention_dim}, {use_linear_projection}, {upcast_attention}" + ) + + # 外部からの参照用に定義しておく + self.in_channels = IN_CHANNELS + self.out_channels = OUT_CHANNELS + + self.sample_size = sample_size + + # input + self.conv_in = nn.Conv2d(IN_CHANNELS, BLOCK_OUT_CHANNELS[0], kernel_size=3, padding=(1, 1)) + + # time + self.time_proj = Timesteps(BLOCK_OUT_CHANNELS[0], TIME_EMBED_FLIP_SIN_TO_COS, TIME_EMBED_FREQ_SHIFT) + + self.time_embedding = TimestepEmbedding(TIMESTEP_INPUT_DIM, TIME_EMBED_DIM) + + self.down_blocks = nn.ModuleList([]) + self.mid_block = None + self.up_blocks = nn.ModuleList([]) + + if isinstance(attention_head_dim, int): + attention_head_dim = (attention_head_dim,) * 4 + + # down + output_channel = BLOCK_OUT_CHANNELS[0] + for i, down_block_type in enumerate(DOWN_BLOCK_TYPES): + input_channel = output_channel + output_channel = BLOCK_OUT_CHANNELS[i] + is_final_block = i == len(BLOCK_OUT_CHANNELS) - 1 + + down_block = get_down_block( + down_block_type, + in_channels=input_channel, + out_channels=output_channel, + add_downsample=not is_final_block, + attn_num_head_channels=attention_head_dim[i], + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + self.down_blocks.append(down_block) + + # mid + self.mid_block = UNetMidBlock2DCrossAttn( + in_channels=BLOCK_OUT_CHANNELS[-1], + attn_num_head_channels=attention_head_dim[-1], + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + ) + + # count how many layers upsample the images + self.num_upsamplers = 0 + + # up + reversed_block_out_channels = list(reversed(BLOCK_OUT_CHANNELS)) + reversed_attention_head_dim = list(reversed(attention_head_dim)) + output_channel = reversed_block_out_channels[0] + for i, up_block_type in enumerate(UP_BLOCK_TYPES): + is_final_block = i == len(BLOCK_OUT_CHANNELS) - 1 + + prev_output_channel = output_channel + output_channel = reversed_block_out_channels[i] + input_channel = reversed_block_out_channels[min(i + 1, len(BLOCK_OUT_CHANNELS) - 1)] + + # add upsample block for all BUT final layer + if not is_final_block: + add_upsample = True + self.num_upsamplers += 1 + else: + add_upsample = False + + up_block = get_up_block( + up_block_type, + in_channels=input_channel, + out_channels=output_channel, + prev_output_channel=prev_output_channel, + add_upsample=add_upsample, + attn_num_head_channels=reversed_attention_head_dim[i], + cross_attention_dim=cross_attention_dim, + use_linear_projection=use_linear_projection, + upcast_attention=upcast_attention, + ) + self.up_blocks.append(up_block) + prev_output_channel = output_channel + + # out + self.conv_norm_out = nn.GroupNorm(num_channels=BLOCK_OUT_CHANNELS[0], num_groups=RESNET_GROUPS, eps=RESNET_EPS) + self.conv_act = nn.SiLU() + self.conv_out = nn.Conv2d(BLOCK_OUT_CHANNELS[0], OUT_CHANNELS, kernel_size=3, padding=1) + + # region diffusers compatibility + @property + def dtype(self) -> torch.dtype: + """ + `torch.dtype`: The dtype of the module (assuming that all the module parameters have the same dtype). + """ + return get_parameter_dtype(self) + + def set_attention_slice(self, slice_size): + raise NotImplementedError("Attention slicing is not supported for this model.") + + def is_gradient_checkpointing(self) -> bool: + return any(hasattr(m, "gradient_checkpointing") and m.gradient_checkpointing for m in self.modules()) + + def enable_gradient_checkpointing(self): + self._set_gradient_checkpointing(self, value=True) + + def disable_gradient_checkpointing(self): + self._set_gradient_checkpointing(self, value=False) + + def set_use_memory_efficient_attention_xformers(self, valid: bool) -> None: + raise NotImplementedError("Memory efficient attention is not supported for this model.") + + def _set_gradient_checkpointing(self, module, value=False): + if isinstance(module, (CrossAttnDownBlock2D, DownBlock2D, CrossAttnUpBlock2D, UpBlock2D)): + module.gradient_checkpointing = value + + # endregion + + def forward( + self, + sample: torch.FloatTensor, + timestep: Union[torch.Tensor, float, int], + encoder_hidden_states: torch.Tensor, + class_labels: Optional[torch.Tensor] = None, + return_dict: bool = True, + ) -> Union[Dict, Tuple]: + r""" + Args: + sample (`torch.FloatTensor`): (batch, channel, height, width) noisy inputs tensor + timestep (`torch.FloatTensor` or `float` or `int`): (batch) timesteps + encoder_hidden_states (`torch.FloatTensor`): (batch, sequence_length, feature_dim) encoder hidden states + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a dict instead of a plain tuple. + + Returns: + `SampleOutput` or `tuple`: + `SampleOutput` if `return_dict` is True, otherwise a `tuple`. When returning a tuple, the first element is the sample tensor. + """ + # By default samples have to be AT least a multiple of the overall upsampling factor. + # The overall upsampling factor is equal to 2 ** (# num of upsampling layears). + # However, the upsampling interpolation output size can be forced to fit any upsampling size + # on the fly if necessary. + # デフォルトではサンプルは「2^アップサンプルの数」、つまり64の倍数である必要がある + # ただそれ以外のサイズにも対応できるように、必要ならアップサンプルのサイズを変更する + # 多分画質が悪くなるので、64で割り切れるようにしておくのが良い + default_overall_up_factor = 2**self.num_upsamplers + + # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor` + # 64で割り切れないときはupsamplerにサイズを伝える + forward_upsample_size = False + upsample_size = None + + if any(s % default_overall_up_factor != 0 for s in sample.shape[-2:]): + # logger.info("Forward upsample size to force interpolation output size.") + forward_upsample_size = True + + # 1. time + timesteps = timestep + timesteps = self.handle_unusual_timesteps(sample, timesteps) # 変な時だけ処理 + + t_emb = self.time_proj(timesteps) + + # timesteps does not contain any weights and will always return f32 tensors + # but time_embedding might actually be running in fp16. so we need to cast here. + # there might be better ways to encapsulate this. + # timestepsは重みを含まないので常にfloat32のテンソルを返す + # しかしtime_embeddingはfp16で動いているかもしれないので、ここでキャストする必要がある + # time_projでキャストしておけばいいんじゃね? + t_emb = t_emb.to(dtype=self.dtype) + emb = self.time_embedding(t_emb) + + # 2. pre-process + sample = self.conv_in(sample) + + # 3. down + down_block_res_samples = (sample,) + for downsample_block in self.down_blocks: + # downblockはforwardで必ずencoder_hidden_statesを受け取るようにしても良さそうだけど、 + # まあこちらのほうがわかりやすいかもしれない + if downsample_block.has_cross_attention: + sample, res_samples = downsample_block( + hidden_states=sample, + temb=emb, + encoder_hidden_states=encoder_hidden_states, + ) + else: + sample, res_samples = downsample_block(hidden_states=sample, temb=emb) + + down_block_res_samples += res_samples + + # 4. mid + sample = self.mid_block(sample, emb, encoder_hidden_states=encoder_hidden_states) + + # 5. up + for i, upsample_block in enumerate(self.up_blocks): + is_final_block = i == len(self.up_blocks) - 1 + + res_samples = down_block_res_samples[-len(upsample_block.resnets) :] + down_block_res_samples = down_block_res_samples[: -len(upsample_block.resnets)] # skip connection + + # if we have not reached the final block and need to forward the upsample size, we do it here + # 前述のように最後のブロック以外ではupsample_sizeを伝える + if not is_final_block and forward_upsample_size: + upsample_size = down_block_res_samples[-1].shape[2:] + + if upsample_block.has_cross_attention: + sample = upsample_block( + hidden_states=sample, + temb=emb, + res_hidden_states_tuple=res_samples, + encoder_hidden_states=encoder_hidden_states, + upsample_size=upsample_size, + ) + else: + sample = upsample_block( + hidden_states=sample, temb=emb, res_hidden_states_tuple=res_samples, upsample_size=upsample_size + ) + + # 6. post-process + sample = self.conv_norm_out(sample) + sample = self.conv_act(sample) + sample = self.conv_out(sample) + + if not return_dict: + return (sample,) + + return SampleOutput(sample=sample) + + def handle_unusual_timesteps(self, sample, timesteps): + r""" + timestampsがTensorでない場合、Tensorに変換する。またOnnx/Core MLと互換性のあるようにbatchサイズまでbroadcastする。 + """ + if not torch.is_tensor(timesteps): + # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can + # This would be a good case for the `match` statement (Python 3.10+) + is_mps = sample.device.type == "mps" + if isinstance(timesteps, float): + dtype = torch.float32 if is_mps else torch.float64 + else: + dtype = torch.int32 if is_mps else torch.int64 + timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device) + elif len(timesteps.shape) == 0: + timesteps = timesteps[None].to(sample.device) + + # broadcast to batch dimension in a way that's compatible with ONNX/Core ML + timesteps = timesteps.expand(sample.shape[0]) + + return timesteps From c0a7df9ee14c715134f0e1cfce0a6256d1b64014 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 3 Jun 2023 21:29:27 +0900 Subject: [PATCH 011/220] fix eps value, enable xformers, etc. --- gen_img_diffusers.py | 63 ++++++++++---------- library/original_unet.py | 122 +++++++++++++++++++++++++++++++++------ library/train_util.py | 66 +++++++++++---------- 3 files changed, 172 insertions(+), 79 deletions(-) diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 4d8121ca1..33b7a65cc 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -317,7 +317,7 @@ def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditio if mem_eff_attn: replace_unet_cross_attn_to_memory_efficient() elif xformers: - replace_unet_cross_attn_to_xformers() + replace_unet_cross_attn_to_xformers(unet) def replace_unet_cross_attn_to_memory_efficient(): @@ -357,50 +357,55 @@ def forward_flash_attn(self, x, context=None, mask=None): out = self.to_out[1](out) return out - diffusers.models.attention.CrossAttention.forward = forward_flash_attn + # diffusers.models.attention.CrossAttention.forward = forward_flash_attn + # TODO U-Net側に移す + from library.original_unet import CrossAttention + CrossAttention.forward = forward_flash_attn -def replace_unet_cross_attn_to_xformers(): +def replace_unet_cross_attn_to_xformers(unet:UNet2DConditionModel): print("CrossAttention.forward has been replaced to enable xformers and NAI style Hypernetwork") try: import xformers.ops except ImportError: raise ImportError("No xformers / xformersがインストールされていないようです") + + unet.set_use_memory_efficient_attention_xformers(True) - def forward_xformers(self, x, context=None, mask=None): - h = self.heads - q_in = self.to_q(x) + # def forward_xformers(self, x, context=None, mask=None): + # h = self.heads + # q_in = self.to_q(x) - context = default(context, x) - context = context.to(x.dtype) + # context = default(context, x) + # context = context.to(x.dtype) - if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - context_k, context_v = self.hypernetwork.forward(x, context) - context_k = context_k.to(x.dtype) - context_v = context_v.to(x.dtype) - else: - context_k = context - context_v = context + # if hasattr(self, "hypernetwork") and self.hypernetwork is not None: + # context_k, context_v = self.hypernetwork.forward(x, context) + # context_k = context_k.to(x.dtype) + # context_v = context_v.to(x.dtype) + # else: + # context_k = context + # context_v = context - k_in = self.to_k(context_k) - v_in = self.to_v(context_v) + # k_in = self.to_k(context_k) + # v_in = self.to_v(context_v) - q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) - del q_in, k_in, v_in + # q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) + # del q_in, k_in, v_in - q = q.contiguous() - k = k.contiguous() - v = v.contiguous() - out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる + # q = q.contiguous() + # k = k.contiguous() + # v = v.contiguous() + # out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる - out = rearrange(out, "b n h d -> b n (h d)", h=h) + # out = rearrange(out, "b n h d -> b n (h d)", h=h) - # diffusers 0.7.0~ - out = self.to_out[0](out) - out = self.to_out[1](out) - return out + # # diffusers 0.7.0~ + # out = self.to_out[0](out) + # out = self.to_out[1](out) + # return out - diffusers.models.attention.CrossAttention.forward = forward_xformers + # diffusers.models.attention.CrossAttention.forward = forward_xformers def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): diff --git a/library/original_unet.py b/library/original_unet.py index 603239d57..47b751c1f 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -1,10 +1,10 @@ # Diffusers 0.10.2からStable Diffusionに必要な部分だけを持ってくる +# 条件分岐等で不要な部分は削除している # コードの多くはDiffusersからコピーしている -# コードが冗長になる部分はコメント等を適宜削除する # 制約として、モデルのstate_dictがDiffusers 0.10.2のものと同じ形式である必要がある # Copy from Diffusers 0.10.2 for Stable Diffusion. Most of the code is copied from Diffusers. -# Remove redundant code by deleting comments, etc. as appropriate +# Unnecessary parts are deleted by condition branching. # As a constraint, the state_dict of the model must be in the same format as that of Diffusers 0.10.2 """ @@ -111,6 +111,7 @@ import torch from torch import nn from torch.nn import functional as F +from einops import rearrange BLOCK_OUT_CHANNELS: Tuple[int] = (320, 640, 1280, 1280) TIMESTEP_INPUT_DIM = BLOCK_OUT_CHANNELS[0] @@ -121,8 +122,8 @@ LAYERS_PER_BLOCK_UP: int = LAYERS_PER_BLOCK + 1 TIME_EMBED_FLIP_SIN_TO_COS: bool = True TIME_EMBED_FREQ_SHIFT: int = 0 -RESNET_GROUPS: int = 32 -RESNET_EPS: float = 1e-6 +NORM_GROUPS: int = 32 +NORM_EPS: float = 1e-5 TRANSFORMER_NORM_NUM_GROUPS = 32 DOWN_BLOCK_TYPES = ["CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "DownBlock2D"] @@ -233,13 +234,13 @@ def __init__( self.in_channels = in_channels self.out_channels = out_channels - self.norm1 = torch.nn.GroupNorm(num_groups=RESNET_GROUPS, num_channels=in_channels, eps=RESNET_EPS, affine=True) + self.norm1 = torch.nn.GroupNorm(num_groups=NORM_GROUPS, num_channels=in_channels, eps=NORM_EPS, affine=True) self.conv1 = torch.nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1) self.time_emb_proj = torch.nn.Linear(TIME_EMBED_DIM, out_channels) - self.norm2 = torch.nn.GroupNorm(num_groups=RESNET_GROUPS, num_channels=out_channels, eps=RESNET_EPS, affine=True) + self.norm2 = torch.nn.GroupNorm(num_groups=NORM_GROUPS, num_channels=out_channels, eps=NORM_EPS, affine=True) self.conv2 = torch.nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1) # if non_linearity == "swish": @@ -304,6 +305,9 @@ def __init__( self.gradient_checkpointing = False + def set_use_memory_efficient_attention_xformers(self, value): + pass + def forward(self, hidden_states, temb=None): output_states = () @@ -372,6 +376,11 @@ def __init__( self.to_out.append(nn.Linear(inner_dim, query_dim)) # no dropout here + self.use_memory_efficient_attention_xformers = False + + def set_use_memory_efficient_attention_xformers(self, value): + self.use_memory_efficient_attention_xformers = value + def reshape_heads_to_batch_dim(self, tensor): batch_size, seq_len, dim = tensor.shape head_size = self.heads @@ -387,6 +396,9 @@ def reshape_batch_dim_to_heads(self, tensor): return tensor def forward(self, hidden_states, context=None, mask=None): + if self.use_memory_efficient_attention_xformers: + return self.forward_memory_efficient_xformers(hidden_states, context, mask) + query = self.to_q(hidden_states) context = context if context is not None else hidden_states key = self.to_k(context) @@ -427,6 +439,30 @@ def _attention(self, query, key, value): hidden_states = self.reshape_batch_dim_to_heads(hidden_states) return hidden_states + # TODO support Hypernetworks + def forward_memory_efficient_xformers(self, x, context=None, mask=None): + import xformers.ops + + h = self.heads + q_in = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k_in = self.to_k(context) + v_in = self.to_v(context) + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) + del q_in, k_in, v_in + + q = q.contiguous() + k = k.contiguous() + v = v.contiguous() + out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる + + out = rearrange(out, "b n h d -> b n (h d)", h=h) + + out = self.to_out[0](out) + return out + # feedforward class GEGLU(nn.Module): @@ -506,8 +542,9 @@ def __init__( # 3. Feed-forward self.norm3 = nn.LayerNorm(dim) - def set_use_memory_efficient_attention_xformers(self, use_memory_efficient_attention_xformers: bool): - raise NotImplementedError("Memory efficient attention is not implemented for this model.") + def set_use_memory_efficient_attention_xformers(self, value: bool): + self.attn1.set_use_memory_efficient_attention_xformers(value) + self.attn2.set_use_memory_efficient_attention_xformers(value) def forward(self, hidden_states, context=None, timestep=None): # 1. Self-Attention @@ -566,6 +603,10 @@ def __init__( else: self.proj_out = nn.Conv2d(inner_dim, in_channels, kernel_size=1, stride=1, padding=0) + def set_use_memory_efficient_attention_xformers(self, value): + for transformer in self.transformer_blocks: + transformer.set_use_memory_efficient_attention_xformers(value) + def forward(self, hidden_states, encoder_hidden_states=None, timestep=None, return_dict: bool = True): # 1. Input batch, _, height, weight = hidden_states.shape @@ -643,6 +684,10 @@ def __init__( self.gradient_checkpointing = False + def set_use_memory_efficient_attention_xformers(self, value): + for attn in self.attentions: + attn.set_use_memory_efficient_attention_xformers(value) + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): output_states = () @@ -714,11 +759,37 @@ def __init__( self.attentions = nn.ModuleList(attentions) self.resnets = nn.ModuleList(resnets) + self.gradient_checkpointing = False + + def set_use_memory_efficient_attention_xformers(self, value): + for attn in self.attentions: + attn.set_use_memory_efficient_attention_xformers(value) + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): - hidden_states = self.resnets[0](hidden_states, temb) - for attn, resnet in zip(self.attentions, self.resnets[1:]): - hidden_states = attn(hidden_states, encoder_hidden_states).sample - hidden_states = resnet(hidden_states, temb) + for i, resnet in enumerate(self.resnets): + attn = None if i == 0 else self.attentions[i - 1] + + if self.training and self.gradient_checkpointing: + + def create_custom_forward(module, return_dict=None): + def custom_forward(*inputs): + if return_dict is not None: + return module(*inputs, return_dict=return_dict) + else: + return module(*inputs) + + return custom_forward + + if attn is not None: + hidden_states = torch.utils.checkpoint.checkpoint( + create_custom_forward(attn, return_dict=False), hidden_states, encoder_hidden_states + )[0] + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb) + else: + if attn is not None: + hidden_states = attn(hidden_states, encoder_hidden_states).sample + hidden_states = resnet(hidden_states, temb) return hidden_states @@ -792,6 +863,9 @@ def __init__( self.gradient_checkpointing = False + def set_use_memory_efficient_attention_xformers(self, value): + pass + def forward(self, hidden_states, res_hidden_states_tuple, temb=None, upsample_size=None): for resnet in self.resnets: # pop res hidden states @@ -868,6 +942,10 @@ def __init__( self.gradient_checkpointing = False + def set_use_memory_efficient_attention_xformers(self, value): + for attn in self.attentions: + attn.set_use_memory_efficient_attention_xformers(value) + def forward( self, hidden_states, @@ -991,6 +1069,8 @@ def __init__( self.sample_size = sample_size + # state_dictの書式が変わるのでmoduleの持ち方は変えられない + # input self.conv_in = nn.Conv2d(IN_CHANNELS, BLOCK_OUT_CHANNELS[0], kernel_size=3, padding=(1, 1)) @@ -1069,7 +1149,7 @@ def __init__( prev_output_channel = output_channel # out - self.conv_norm_out = nn.GroupNorm(num_channels=BLOCK_OUT_CHANNELS[0], num_groups=RESNET_GROUPS, eps=RESNET_EPS) + self.conv_norm_out = nn.GroupNorm(num_channels=BLOCK_OUT_CHANNELS[0], num_groups=NORM_GROUPS, eps=NORM_EPS) self.conv_act = nn.SiLU() self.conv_out = nn.Conv2d(BLOCK_OUT_CHANNELS[0], OUT_CHANNELS, kernel_size=3, padding=1) @@ -1088,16 +1168,20 @@ def is_gradient_checkpointing(self) -> bool: return any(hasattr(m, "gradient_checkpointing") and m.gradient_checkpointing for m in self.modules()) def enable_gradient_checkpointing(self): - self._set_gradient_checkpointing(self, value=True) + self.set_gradient_checkpointing(value=True) def disable_gradient_checkpointing(self): - self._set_gradient_checkpointing(self, value=False) + self.set_gradient_checkpointing(value=False) def set_use_memory_efficient_attention_xformers(self, valid: bool) -> None: - raise NotImplementedError("Memory efficient attention is not supported for this model.") - - def _set_gradient_checkpointing(self, module, value=False): - if isinstance(module, (CrossAttnDownBlock2D, DownBlock2D, CrossAttnUpBlock2D, UpBlock2D)): + modules = self.down_blocks + [self.mid_block] + self.up_blocks + for module in modules: + module.set_use_memory_efficient_attention_xformers(valid) + + def set_gradient_checkpointing(self, value=False): + modules = self.down_blocks + [self.mid_block] + self.up_blocks + for module in modules: + print(module.__class__.__name__, module.gradient_checkpointing, "->", value) module.gradient_checkpointing = value # endregion diff --git a/library/train_util.py b/library/train_util.py index 844faca75..b7cee937b 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -1792,7 +1792,7 @@ def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditio if mem_eff_attn: replace_unet_cross_attn_to_memory_efficient() elif xformers: - replace_unet_cross_attn_to_xformers() + replace_unet_cross_attn_to_xformers(unet) def replace_unet_cross_attn_to_memory_efficient(): @@ -1827,55 +1827,59 @@ def forward_flash_attn(self, x, context=None, mask=None): out = rearrange(out, "b h n d -> b n (h d)") - # diffusers 0.7.0~ わざわざ変えるなよ (;´Д`) out = self.to_out[0](out) - out = self.to_out[1](out) + # out = self.to_out[1](out) return out - diffusers.models.attention.CrossAttention.forward = forward_flash_attn + # diffusers.models.attention.CrossAttention.forward = forward_flash_attn + from library.original_unet import CrossAttention + CrossAttention.forward = forward_flash_attn -def replace_unet_cross_attn_to_xformers(): + +def replace_unet_cross_attn_to_xformers(unet): print("CrossAttention.forward has been replaced to enable xformers.") try: import xformers.ops except ImportError: raise ImportError("No xformers / xformersがインストールされていないようです") - def forward_xformers(self, x, context=None, mask=None): - h = self.heads - q_in = self.to_q(x) + unet.set_use_memory_efficient_attention_xformers(True) - context = default(context, x) - context = context.to(x.dtype) + # def forward_xformers(self, x, context=None, mask=None): + # h = self.heads + # q_in = self.to_q(x) - if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - context_k, context_v = self.hypernetwork.forward(x, context) - context_k = context_k.to(x.dtype) - context_v = context_v.to(x.dtype) - else: - context_k = context - context_v = context + # context = default(context, x) + # context = context.to(x.dtype) - k_in = self.to_k(context_k) - v_in = self.to_v(context_v) + # if hasattr(self, "hypernetwork") and self.hypernetwork is not None: + # context_k, context_v = self.hypernetwork.forward(x, context) + # context_k = context_k.to(x.dtype) + # context_v = context_v.to(x.dtype) + # else: + # context_k = context + # context_v = context - q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) - del q_in, k_in, v_in + # k_in = self.to_k(context_k) + # v_in = self.to_v(context_v) - q = q.contiguous() - k = k.contiguous() - v = v.contiguous() - out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる + # q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) + # del q_in, k_in, v_in - out = rearrange(out, "b n h d -> b n (h d)", h=h) + # q = q.contiguous() + # k = k.contiguous() + # v = v.contiguous() + # out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる - # diffusers 0.7.0~ - out = self.to_out[0](out) - out = self.to_out[1](out) - return out + # out = rearrange(out, "b n h d -> b n (h d)", h=h) + + # # diffusers 0.7.0~ + # out = self.to_out[0](out) + # out = self.to_out[1](out) + # return out - diffusers.models.attention.CrossAttention.forward = forward_xformers + # diffusers.models.attention.CrossAttention.forward = forward_xformers """ From dccdb8771c6facfb40087fc670e2698a2deb3bce Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 7 Jun 2023 08:12:52 +0900 Subject: [PATCH 012/220] support sample generation in training --- library/original_unet.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/library/original_unet.py b/library/original_unet.py index 47b751c1f..e89207279 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -107,6 +107,7 @@ """ import math +from types import SimpleNamespace from typing import Dict, Optional, Tuple, Union import torch from torch import nn @@ -134,6 +135,10 @@ def get_parameter_dtype(parameter: torch.nn.Module): return next(parameter.parameters()).dtype +def get_parameter_device(parameter: torch.nn.Module): + return next(parameter.parameters()).device + + def get_timestep_embedding( timesteps: torch.Tensor, embedding_dim: int, @@ -1068,6 +1073,7 @@ def __init__( self.out_channels = OUT_CHANNELS self.sample_size = sample_size + self.prepare_config() # state_dictの書式が変わるのでmoduleの持ち方は変えられない @@ -1154,13 +1160,19 @@ def __init__( self.conv_out = nn.Conv2d(BLOCK_OUT_CHANNELS[0], OUT_CHANNELS, kernel_size=3, padding=1) # region diffusers compatibility + def prepare_config(self): + self.config = SimpleNamespace() + @property def dtype(self) -> torch.dtype: - """ - `torch.dtype`: The dtype of the module (assuming that all the module parameters have the same dtype). - """ + # `torch.dtype`: The dtype of the module (assuming that all the module parameters have the same dtype). return get_parameter_dtype(self) + @property + def device(self) -> torch.device: + # `torch.device`: The device on which the module is (assuming that all the module parameters are on the same device). + return get_parameter_device(self) + def set_attention_slice(self, slice_size): raise NotImplementedError("Attention slicing is not supported for this model.") From cc274fb7fb0e5d081009feffe815d91af4ece02b Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 16:54:10 +0900 Subject: [PATCH 013/220] update diffusers ver, remove tensorflow --- requirements.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 801cf321b..7252f7456 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -accelerate==0.15.0 +accelerate==0.16.0 transformers==4.26.0 ftfy==6.1.1 albumentations==1.3.0 opencv-python==4.7.0.68 einops==0.6.0 -diffusers[torch]==0.10.2 +diffusers[torch]==0.17.0 pytorch-lightning==1.9.0 bitsandbytes==0.35.0 tensorboard==2.10.1 @@ -14,13 +14,12 @@ altair==4.2.2 easygui==0.98.3 toml==0.10.2 voluptuous==0.13.1 +huggingface-hub==0.13.3 # for BLIP captioning requests==2.28.2 timm==0.6.12 fairscale==0.4.13 # for WD14 captioning -# tensorflow<2.11 -tensorflow==2.10.1 -huggingface-hub==0.13.3 +# tensorflow==2.10.1 # for kohya_ss library . From 7f6b581ef82933bf5f1695b17676efeb64ce7b32 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 16:54:41 +0900 Subject: [PATCH 014/220] support memory efficient attn (not xformers) --- library/original_unet.py | 242 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 225 insertions(+), 17 deletions(-) diff --git a/library/original_unet.py b/library/original_unet.py index e89207279..0e64280b2 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -131,6 +131,187 @@ UP_BLOCK_TYPES = ["UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"] +# region memory effcient attention + +# FlashAttentionを使うCrossAttention +# based on https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/memory_efficient_attention_pytorch/flash_attention.py +# LICENSE MIT https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/LICENSE + +# constants + +EPSILON = 1e-6 + +# helper functions + + +def exists(val): + return val is not None + + +def default(val, d): + return val if exists(val) else d + + +# flash attention forwards and backwards + +# https://arxiv.org/abs/2205.14135 + + +class FlashAttentionFunction(torch.autograd.Function): + @staticmethod + @torch.no_grad() + def forward(ctx, q, k, v, mask, causal, q_bucket_size, k_bucket_size): + """Algorithm 2 in the paper""" + + device = q.device + dtype = q.dtype + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + o = torch.zeros_like(q) + all_row_sums = torch.zeros((*q.shape[:-1], 1), dtype=dtype, device=device) + all_row_maxes = torch.full((*q.shape[:-1], 1), max_neg_value, dtype=dtype, device=device) + + scale = q.shape[-1] ** -0.5 + + if not exists(mask): + mask = (None,) * math.ceil(q.shape[-2] / q_bucket_size) + else: + mask = rearrange(mask, "b n -> b 1 1 n") + mask = mask.split(q_bucket_size, dim=-1) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + mask, + all_row_sums.split(q_bucket_size, dim=-2), + all_row_maxes.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, row_mask, row_sums, row_maxes) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale + + if exists(row_mask): + attn_weights.masked_fill_(~row_mask, max_neg_value) + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( + q_start_index - k_start_index + 1 + ) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + block_row_maxes = attn_weights.amax(dim=-1, keepdims=True) + attn_weights -= block_row_maxes + exp_weights = torch.exp(attn_weights) + + if exists(row_mask): + exp_weights.masked_fill_(~row_mask, 0.0) + + block_row_sums = exp_weights.sum(dim=-1, keepdims=True).clamp(min=EPSILON) + + new_row_maxes = torch.maximum(block_row_maxes, row_maxes) + + exp_values = torch.einsum("... i j, ... j d -> ... i d", exp_weights, vc) + + exp_row_max_diff = torch.exp(row_maxes - new_row_maxes) + exp_block_row_max_diff = torch.exp(block_row_maxes - new_row_maxes) + + new_row_sums = exp_row_max_diff * row_sums + exp_block_row_max_diff * block_row_sums + + oc.mul_((row_sums / new_row_sums) * exp_row_max_diff).add_((exp_block_row_max_diff / new_row_sums) * exp_values) + + row_maxes.copy_(new_row_maxes) + row_sums.copy_(new_row_sums) + + ctx.args = (causal, scale, mask, q_bucket_size, k_bucket_size) + ctx.save_for_backward(q, k, v, o, all_row_sums, all_row_maxes) + + return o + + @staticmethod + @torch.no_grad() + def backward(ctx, do): + """Algorithm 4 in the paper""" + + causal, scale, mask, q_bucket_size, k_bucket_size = ctx.args + q, k, v, o, l, m = ctx.saved_tensors + + device = q.device + + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + dq = torch.zeros_like(q) + dk = torch.zeros_like(k) + dv = torch.zeros_like(v) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + do.split(q_bucket_size, dim=-2), + mask, + l.split(q_bucket_size, dim=-2), + m.split(q_bucket_size, dim=-2), + dq.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, doc, row_mask, lc, mc, dqc) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + dk.split(k_bucket_size, dim=-2), + dv.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( + q_start_index - k_start_index + 1 + ) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + exp_attn_weights = torch.exp(attn_weights - mc) + + if exists(row_mask): + exp_attn_weights.masked_fill_(~row_mask, 0.0) + + p = exp_attn_weights / lc + + dv_chunk = einsum("... i j, ... i d -> ... j d", p, doc) + dp = einsum("... i d, ... j d -> ... i j", doc, vc) + + D = (doc * oc).sum(dim=-1, keepdims=True) + ds = p * scale * (dp - D) + + dq_chunk = einsum("... i j, ... j d -> ... i d", ds, kc) + dk_chunk = einsum("... i j, ... i d -> ... j d", ds, qc) + + dqc.add_(dq_chunk) + dkc.add_(dk_chunk) + dvc.add_(dv_chunk) + + return dq, dk, dv, None, None, None, None + + +# endregion + + def get_parameter_dtype(parameter: torch.nn.Module): return next(parameter.parameters()).dtype @@ -310,7 +491,7 @@ def __init__( self.gradient_checkpointing = False - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): pass def forward(self, hidden_states, temb=None): @@ -382,9 +563,11 @@ def __init__( # no dropout here self.use_memory_efficient_attention_xformers = False + self.use_memory_efficient_attention_mem_eff = False - def set_use_memory_efficient_attention_xformers(self, value): - self.use_memory_efficient_attention_xformers = value + def set_use_memory_efficient_attention(self, xformers, mem_eff): + self.use_memory_efficient_attention_xformers = xformers + self.use_memory_efficient_attention_mem_eff = mem_eff def reshape_heads_to_batch_dim(self, tensor): batch_size, seq_len, dim = tensor.shape @@ -403,6 +586,8 @@ def reshape_batch_dim_to_heads(self, tensor): def forward(self, hidden_states, context=None, mask=None): if self.use_memory_efficient_attention_xformers: return self.forward_memory_efficient_xformers(hidden_states, context, mask) + if self.use_memory_efficient_attention_mem_eff: + return self.forward_memory_efficient_mem_eff(hidden_states, context, mask) query = self.to_q(hidden_states) context = context if context is not None else hidden_states @@ -468,6 +653,29 @@ def forward_memory_efficient_xformers(self, x, context=None, mask=None): out = self.to_out[0](out) return out + def forward_memory_efficient_mem_eff(self, x, context=None, mask=None): + flash_func = FlashAttentionFunction + + q_bucket_size = 512 + k_bucket_size = 1024 + + h = self.heads + q = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k = self.to_k(context) + v = self.to_v(context) + del context, x + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) + + out = flash_func.apply(q, k, v, mask, False, q_bucket_size, k_bucket_size) + + out = rearrange(out, "b h n d -> b n (h d)") + + out = self.to_out[0](out) + return out + # feedforward class GEGLU(nn.Module): @@ -547,9 +755,9 @@ def __init__( # 3. Feed-forward self.norm3 = nn.LayerNorm(dim) - def set_use_memory_efficient_attention_xformers(self, value: bool): - self.attn1.set_use_memory_efficient_attention_xformers(value) - self.attn2.set_use_memory_efficient_attention_xformers(value) + def set_use_memory_efficient_attention(self, xformers: bool, mem_eff: bool): + self.attn1.set_use_memory_efficient_attention(xformers, mem_eff) + self.attn2.set_use_memory_efficient_attention(xformers, mem_eff) def forward(self, hidden_states, context=None, timestep=None): # 1. Self-Attention @@ -608,9 +816,9 @@ def __init__( else: self.proj_out = nn.Conv2d(inner_dim, in_channels, kernel_size=1, stride=1, padding=0) - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): for transformer in self.transformer_blocks: - transformer.set_use_memory_efficient_attention_xformers(value) + transformer.set_use_memory_efficient_attention(xformers, mem_eff) def forward(self, hidden_states, encoder_hidden_states=None, timestep=None, return_dict: bool = True): # 1. Input @@ -689,9 +897,9 @@ def __init__( self.gradient_checkpointing = False - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: - attn.set_use_memory_efficient_attention_xformers(value) + attn.set_use_memory_efficient_attention(xformers, mem_eff) def forward(self, hidden_states, temb=None, encoder_hidden_states=None): output_states = () @@ -766,9 +974,9 @@ def __init__( self.gradient_checkpointing = False - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: - attn.set_use_memory_efficient_attention_xformers(value) + attn.set_use_memory_efficient_attention(xformers, mem_eff) def forward(self, hidden_states, temb=None, encoder_hidden_states=None): for i, resnet in enumerate(self.resnets): @@ -868,7 +1076,7 @@ def __init__( self.gradient_checkpointing = False - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): pass def forward(self, hidden_states, res_hidden_states_tuple, temb=None, upsample_size=None): @@ -947,9 +1155,9 @@ def __init__( self.gradient_checkpointing = False - def set_use_memory_efficient_attention_xformers(self, value): + def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: - attn.set_use_memory_efficient_attention_xformers(value) + attn.set_use_memory_efficient_attention(xformers, mem_eff) def forward( self, @@ -1185,10 +1393,10 @@ def enable_gradient_checkpointing(self): def disable_gradient_checkpointing(self): self.set_gradient_checkpointing(value=False) - def set_use_memory_efficient_attention_xformers(self, valid: bool) -> None: + def set_use_memory_efficient_attention(self, xformers: bool,mem_eff:bool) -> None: modules = self.down_blocks + [self.mid_block] + self.up_blocks for module in modules: - module.set_use_memory_efficient_attention_xformers(valid) + module.set_use_memory_efficient_attention(xformers,mem_eff) def set_gradient_checkpointing(self, value=False): modules = self.down_blocks + [self.mid_block] + self.up_blocks From 4e25c8f78e873224e753af6d0509bc9281acff65 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 16:57:17 +0900 Subject: [PATCH 015/220] fix to work with Diffusers 0.17.0 --- gen_img_diffusers.py | 381 ++++++-------------------------- library/lpw_stable_diffusion.py | 4 +- library/model_util.py | 24 +- library/train_util.py | 2 +- 4 files changed, 77 insertions(+), 334 deletions(-) diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 28f7323a3..34857af39 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -82,7 +82,6 @@ StableDiffusionPipeline, ) from einops import rearrange -from torch import einsum from tqdm import tqdm from torchvision import transforms from transformers import CLIPTextModel, CLIPTokenizer, CLIPModel, CLIPTextConfig @@ -96,6 +95,7 @@ import tools.original_control_net as original_control_net from tools.original_control_net import ControlNetInfo from library.original_unet import UNet2DConditionModel +from library.original_unet import FlashAttentionFunction from XTI_hijack import unet_forward_XTI, downblock_forward_XTI, upblock_forward_XTI @@ -136,344 +136,80 @@ 高速化のためのモジュール入れ替え """ -# FlashAttentionを使うCrossAttention -# based on https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/memory_efficient_attention_pytorch/flash_attention.py -# LICENSE MIT https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/LICENSE -# constants - -EPSILON = 1e-6 - -# helper functions - - -def exists(val): - return val is not None - - -def default(val, d): - return val if exists(val) else d - - -# flash attention forwards and backwards - -# https://arxiv.org/abs/2205.14135 - - -class FlashAttentionFunction(torch.autograd.Function): - @staticmethod - @torch.no_grad() - def forward(ctx, q, k, v, mask, causal, q_bucket_size, k_bucket_size): - """Algorithm 2 in the paper""" - - device = q.device - dtype = q.dtype - max_neg_value = -torch.finfo(q.dtype).max - qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) - - o = torch.zeros_like(q) - all_row_sums = torch.zeros((*q.shape[:-1], 1), dtype=dtype, device=device) - all_row_maxes = torch.full((*q.shape[:-1], 1), max_neg_value, dtype=dtype, device=device) - - scale = q.shape[-1] ** -0.5 - - if not exists(mask): - mask = (None,) * math.ceil(q.shape[-2] / q_bucket_size) - else: - mask = rearrange(mask, "b n -> b 1 1 n") - mask = mask.split(q_bucket_size, dim=-1) - - row_splits = zip( - q.split(q_bucket_size, dim=-2), - o.split(q_bucket_size, dim=-2), - mask, - all_row_sums.split(q_bucket_size, dim=-2), - all_row_maxes.split(q_bucket_size, dim=-2), - ) - - for ind, (qc, oc, row_mask, row_sums, row_maxes) in enumerate(row_splits): - q_start_index = ind * q_bucket_size - qk_len_diff - - col_splits = zip( - k.split(k_bucket_size, dim=-2), - v.split(k_bucket_size, dim=-2), - ) - - for k_ind, (kc, vc) in enumerate(col_splits): - k_start_index = k_ind * k_bucket_size - - attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale - - if exists(row_mask): - attn_weights.masked_fill_(~row_mask, max_neg_value) - - if causal and q_start_index < (k_start_index + k_bucket_size - 1): - causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( - q_start_index - k_start_index + 1 - ) - attn_weights.masked_fill_(causal_mask, max_neg_value) - - block_row_maxes = attn_weights.amax(dim=-1, keepdims=True) - attn_weights -= block_row_maxes - exp_weights = torch.exp(attn_weights) - - if exists(row_mask): - exp_weights.masked_fill_(~row_mask, 0.0) - - block_row_sums = exp_weights.sum(dim=-1, keepdims=True).clamp(min=EPSILON) - - new_row_maxes = torch.maximum(block_row_maxes, row_maxes) - - exp_values = einsum("... i j, ... j d -> ... i d", exp_weights, vc) - - exp_row_max_diff = torch.exp(row_maxes - new_row_maxes) - exp_block_row_max_diff = torch.exp(block_row_maxes - new_row_maxes) - - new_row_sums = exp_row_max_diff * row_sums + exp_block_row_max_diff * block_row_sums - - oc.mul_((row_sums / new_row_sums) * exp_row_max_diff).add_((exp_block_row_max_diff / new_row_sums) * exp_values) - - row_maxes.copy_(new_row_maxes) - row_sums.copy_(new_row_sums) - - ctx.args = (causal, scale, mask, q_bucket_size, k_bucket_size) - ctx.save_for_backward(q, k, v, o, all_row_sums, all_row_maxes) - - return o - - @staticmethod - @torch.no_grad() - def backward(ctx, do): - """Algorithm 4 in the paper""" - - causal, scale, mask, q_bucket_size, k_bucket_size = ctx.args - q, k, v, o, l, m = ctx.saved_tensors - - device = q.device - - max_neg_value = -torch.finfo(q.dtype).max - qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) - - dq = torch.zeros_like(q) - dk = torch.zeros_like(k) - dv = torch.zeros_like(v) - - row_splits = zip( - q.split(q_bucket_size, dim=-2), - o.split(q_bucket_size, dim=-2), - do.split(q_bucket_size, dim=-2), - mask, - l.split(q_bucket_size, dim=-2), - m.split(q_bucket_size, dim=-2), - dq.split(q_bucket_size, dim=-2), - ) - - for ind, (qc, oc, doc, row_mask, lc, mc, dqc) in enumerate(row_splits): - q_start_index = ind * q_bucket_size - qk_len_diff - - col_splits = zip( - k.split(k_bucket_size, dim=-2), - v.split(k_bucket_size, dim=-2), - dk.split(k_bucket_size, dim=-2), - dv.split(k_bucket_size, dim=-2), - ) - - for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): - k_start_index = k_ind * k_bucket_size - - attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale - - if causal and q_start_index < (k_start_index + k_bucket_size - 1): - causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( - q_start_index - k_start_index + 1 - ) - attn_weights.masked_fill_(causal_mask, max_neg_value) - - exp_attn_weights = torch.exp(attn_weights - mc) - - if exists(row_mask): - exp_attn_weights.masked_fill_(~row_mask, 0.0) - - p = exp_attn_weights / lc - - dv_chunk = einsum("... i j, ... i d -> ... j d", p, doc) - dp = einsum("... i d, ... j d -> ... i j", doc, vc) - - D = (doc * oc).sum(dim=-1, keepdims=True) - ds = p * scale * (dp - D) - - dq_chunk = einsum("... i j, ... j d -> ... i d", ds, kc) - dk_chunk = einsum("... i j, ... i d -> ... j d", ds, qc) +def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): + if mem_eff_attn: + print("Enable memory efficient attention for U-Net") - dqc.add_(dq_chunk) - dkc.add_(dk_chunk) - dvc.add_(dv_chunk) + # これはDiffusersのU-Netではなく自前のU-Netなので置き換えなくても良い + unet.set_use_memory_efficient_attention(False, True) + elif xformers: + print("Enable xformers for U-Net") + try: + import xformers.ops + except ImportError: + raise ImportError("No xformers / xformersがインストールされていないようです") - return dq, dk, dv, None, None, None, None + unet.set_use_memory_efficient_attention(True, False) # TODO common train_util.py -def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): +def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): if mem_eff_attn: - replace_unet_cross_attn_to_memory_efficient() + replace_vae_attn_to_memory_efficient() elif xformers: - replace_unet_cross_attn_to_xformers(unet) - + # とりあえずDiffusersのxformersを使う。AttentionがあるのはMidBlockのみ + replace_vae_attn_to_xformers() -def replace_unet_cross_attn_to_memory_efficient(): - print("CrossAttention.forward has been replaced to FlashAttention (not xformers) and NAI style Hypernetwork") - flash_func = FlashAttentionFunction +def replace_vae_attn_to_memory_efficient(): + print("VAE Attention.forward has been replaced to FlashAttention (not xformers)") + flash_func =FlashAttentionFunction - def forward_flash_attn(self, x, context=None, mask=None): + def forward_flash_attn(self, hidden_states, **kwargs): q_bucket_size = 512 k_bucket_size = 1024 - h = self.heads - q = self.to_q(x) + residual = hidden_states + batch, channel, height, width = hidden_states.shape - context = context if context is not None else x - context = context.to(x.dtype) + # norm + hidden_states = self.group_norm(hidden_states) - if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - context_k, context_v = self.hypernetwork.forward(x, context) - context_k = context_k.to(x.dtype) - context_v = context_v.to(x.dtype) - else: - context_k = context - context_v = context + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) - k = self.to_k(context_k) - v = self.to_v(context_v) - del context, x + # proj to q, k, v + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) - q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) + ) - out = flash_func.apply(q, k, v, mask, False, q_bucket_size, k_bucket_size) + out = flash_func.apply(query_proj, key_proj, value_proj, None, False, q_bucket_size, k_bucket_size) out = rearrange(out, "b h n d -> b n (h d)") - # diffusers 0.7.0~ - out = self.to_out[0](out) - out = self.to_out[1](out) - return out - - # diffusers.models.attention.CrossAttention.forward = forward_flash_attn - # TODO U-Net側に移す - from library.original_unet import CrossAttention - CrossAttention.forward = forward_flash_attn - - -def replace_unet_cross_attn_to_xformers(unet:UNet2DConditionModel): - print("CrossAttention.forward has been replaced to enable xformers and NAI style Hypernetwork") - try: - import xformers.ops - except ImportError: - raise ImportError("No xformers / xformersがインストールされていないようです") - - unet.set_use_memory_efficient_attention_xformers(True) - - # def forward_xformers(self, x, context=None, mask=None): - # h = self.heads - # q_in = self.to_q(x) - - # context = default(context, x) - # context = context.to(x.dtype) - - # if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - # context_k, context_v = self.hypernetwork.forward(x, context) - # context_k = context_k.to(x.dtype) - # context_v = context_v.to(x.dtype) - # else: - # context_k = context - # context_v = context - - # k_in = self.to_k(context_k) - # v_in = self.to_v(context_v) - - # q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) - # del q_in, k_in, v_in - - # q = q.contiguous() - # k = k.contiguous() - # v = v.contiguous() - # out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる - - # out = rearrange(out, "b n h d -> b n (h d)", h=h) - - # # diffusers 0.7.0~ - # out = self.to_out[0](out) - # out = self.to_out[1](out) - # return out - - # diffusers.models.attention.CrossAttention.forward = forward_xformers - - -def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): - if mem_eff_attn: - replace_vae_attn_to_memory_efficient() - elif xformers: - # とりあえずDiffusersのxformersを使う。AttentionがあるのはMidBlockのみ - print("Use Diffusers xformers for VAE") - vae.set_use_memory_efficient_attention_xformers(True) - - """ - # VAEがbfloat16でメモリ消費が大きい問題を解決する - upsamplers = [] - for block in vae.decoder.up_blocks: - if block.upsamplers is not None: - upsamplers.extend(block.upsamplers) - - def forward_upsample(_self, hidden_states, output_size=None): - assert hidden_states.shape[1] == _self.channels - if _self.use_conv_transpose: - return _self.conv(hidden_states) - - dtype = hidden_states.dtype - if dtype == torch.bfloat16: - assert output_size is None - # repeat_interleaveはすごく遅いが、回数はあまり呼ばれないので許容する - hidden_states = hidden_states.repeat_interleave(2, dim=-1) - hidden_states = hidden_states.repeat_interleave(2, dim=-2) - else: - if hidden_states.shape[0] >= 64: - hidden_states = hidden_states.contiguous() + # compute next hidden_states + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) - # if `output_size` is passed we force the interpolation output - # size and do not make use of `scale_factor=2` - if output_size is None: - hidden_states = torch.nn.functional.interpolate(hidden_states, scale_factor=2.0, mode="nearest") - else: - hidden_states = torch.nn.functional.interpolate(hidden_states, size=output_size, mode="nearest") + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) - if _self.use_conv: - if _self.name == "conv": - hidden_states = _self.conv(hidden_states) - else: - hidden_states = _self.Conv2d_0(hidden_states) + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states - # replace upsamplers - for upsampler in upsamplers: - # make new scope - def make_replacer(upsampler): - def forward(hidden_states, output_size=None): - return forward_upsample(upsampler, hidden_states, output_size) - - return forward - - upsampler.forward = make_replacer(upsampler) -""" - + diffusers.models.attention_processor.Attention.forward = forward_flash_attn -def replace_vae_attn_to_memory_efficient(): - print("AttentionBlock.forward has been replaced to FlashAttention (not xformers)") - flash_func = FlashAttentionFunction - - def forward_flash_attn(self, hidden_states): - print("forward_flash_attn") - q_bucket_size = 512 - k_bucket_size = 1024 +def replace_vae_attn_to_xformers(): + print("VAE: Attention.forward has been replaced to xformers") + import xformers.ops + + def forward_xformers(self, hidden_states, **kwargs): residual = hidden_states batch, channel, height, width = hidden_states.shape @@ -483,27 +219,34 @@ def forward_flash_attn(self, hidden_states): hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) # proj to q, k, v - query_proj = self.query(hidden_states) - key_proj = self.key(hidden_states) - value_proj = self.value(hidden_states) + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) query_proj, key_proj, value_proj = map( - lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.num_heads), (query_proj, key_proj, value_proj) + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) ) - out = flash_func.apply(query_proj, key_proj, value_proj, None, False, q_bucket_size, k_bucket_size) + query_proj = query_proj.contiguous() + key_proj = key_proj.contiguous() + value_proj = value_proj.contiguous() + out = xformers.ops.memory_efficient_attention(query_proj, key_proj, value_proj, attn_bias=None) out = rearrange(out, "b h n d -> b n (h d)") # compute next hidden_states - hidden_states = self.proj_attn(hidden_states) + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) # res connect and rescale hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states - diffusers.models.attention.AttentionBlock.forward = forward_flash_attn + diffusers.models.attention_processor.Attention.forward = forward_xformers # endregion diff --git a/library/lpw_stable_diffusion.py b/library/lpw_stable_diffusion.py index 3e04b8876..883707f75 100644 --- a/library/lpw_stable_diffusion.py +++ b/library/lpw_stable_diffusion.py @@ -464,7 +464,7 @@ def __init__( tokenizer: CLIPTokenizer, unet: UNet2DConditionModel, scheduler: SchedulerMixin, - clip_skip: int, + # clip_skip: int, safety_checker: StableDiffusionSafetyChecker, feature_extractor: CLIPFeatureExtractor, requires_safety_checker: bool = True, @@ -479,7 +479,7 @@ def __init__( feature_extractor=feature_extractor, requires_safety_checker=requires_safety_checker, ) - self.clip_skip = clip_skip + # self.clip_skip = clip_skip self.__init__additional__() # else: diff --git a/library/model_util.py b/library/model_util.py index 0fbc65901..ea1be5133 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -5,7 +5,7 @@ import os import torch from transformers import CLIPTextModel, CLIPTokenizer, CLIPTextConfig, logging -from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline #, UNet2DConditionModel +from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline # , UNet2DConditionModel from safetensors.torch import load_file, save_file from library.original_unet import UNet2DConditionModel @@ -127,17 +127,17 @@ def renew_vae_attention_paths(old_list, n_shave_prefix_segments=0): new_item = new_item.replace("norm.weight", "group_norm.weight") new_item = new_item.replace("norm.bias", "group_norm.bias") - new_item = new_item.replace("q.weight", "query.weight") - new_item = new_item.replace("q.bias", "query.bias") + new_item = new_item.replace("q.weight", "to_q.weight") + new_item = new_item.replace("q.bias", "to_q.bias") - new_item = new_item.replace("k.weight", "key.weight") - new_item = new_item.replace("k.bias", "key.bias") + new_item = new_item.replace("k.weight", "to_k.weight") + new_item = new_item.replace("k.bias", "to_k.bias") - new_item = new_item.replace("v.weight", "value.weight") - new_item = new_item.replace("v.bias", "value.bias") + new_item = new_item.replace("v.weight", "to_v.weight") + new_item = new_item.replace("v.bias", "to_v.bias") - new_item = new_item.replace("proj_out.weight", "proj_attn.weight") - new_item = new_item.replace("proj_out.bias", "proj_attn.bias") + new_item = new_item.replace("proj_out.weight", "to_out.0.weight") + new_item = new_item.replace("proj_out.bias", "to_out.0.bias") new_item = shave_segments(new_item, n_shave_prefix_segments=n_shave_prefix_segments) @@ -192,8 +192,8 @@ def assign_to_checkpoint( new_path = new_path.replace(replacement["old"], replacement["new"]) # proj_attn.weight has to be converted from conv 1D to linear - if "proj_attn.weight" in new_path: - checkpoint[new_path] = old_checkpoint[path["old"]][:, :, 0] + if ".attentions." in new_path and ".0.to_" in new_path and old_checkpoint[path["old"]].ndim > 2: + checkpoint[new_path] = old_checkpoint[path["old"]][:, :, 0, 0] else: checkpoint[new_path] = old_checkpoint[path["old"]] @@ -362,7 +362,7 @@ def convert_ldm_unet_checkpoint(v2, checkpoint, config): # SDのv2では1*1のconv2dがlinearに変わっている # 誤って Diffusers 側を conv2d のままにしてしまったので、変換必要 - if v2 and not config.get('use_linear_projection', False): + if v2 and not config.get("use_linear_projection", False): linear_transformer_to_conv(new_checkpoint) return new_checkpoint diff --git a/library/train_util.py b/library/train_util.py index b7cee937b..8aa7f9874 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3467,11 +3467,11 @@ def sample_images( unet=unet, tokenizer=tokenizer, scheduler=scheduler, - clip_skip=args.clip_skip, safety_checker=None, feature_extractor=None, requires_safety_checker=False, ) + pipeline.clip_skip = args.clip_skip # Pipelineのコンストラクタにckip_skipを追加できないので後から設定する pipeline.to(device) save_dir = args.output_dir + "/sample" From 035dd3a900ce9208c5d703c354ec839166b8f9cc Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 17:08:21 +0900 Subject: [PATCH 016/220] fix mem_eff_attn does not work --- library/original_unet.py | 10 ++-- library/train_util.py | 101 ++++----------------------------------- 2 files changed, 15 insertions(+), 96 deletions(-) diff --git a/library/original_unet.py b/library/original_unet.py index 0e64280b2..36318eb90 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -278,7 +278,7 @@ def backward(ctx, do): for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): k_start_index = k_ind * k_bucket_size - attn_weights = einsum("... i d, ... j d -> ... i j", qc, kc) * scale + attn_weights = torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale if causal and q_start_index < (k_start_index + k_bucket_size - 1): causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( @@ -293,14 +293,14 @@ def backward(ctx, do): p = exp_attn_weights / lc - dv_chunk = einsum("... i j, ... i d -> ... j d", p, doc) - dp = einsum("... i d, ... j d -> ... i j", doc, vc) + dv_chunk = torch.einsum("... i j, ... i d -> ... j d", p, doc) + dp = torch.einsum("... i d, ... j d -> ... i j", doc, vc) D = (doc * oc).sum(dim=-1, keepdims=True) ds = p * scale * (dp - D) - dq_chunk = einsum("... i j, ... j d -> ... i d", ds, kc) - dk_chunk = einsum("... i j, ... i d -> ... j d", ds, qc) + dq_chunk = torch.einsum("... i j, ... j d -> ... i d", ds, kc) + dk_chunk = torch.einsum("... i j, ... i d -> ... j d", ds, qc) dqc.add_(dq_chunk) dkc.add_(dk_chunk) diff --git a/library/train_util.py b/library/train_util.py index 8aa7f9874..7d7eb325d 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -63,6 +63,7 @@ from library.lpw_stable_diffusion import StableDiffusionLongPromptWeightingPipeline import library.model_util as model_util import library.huggingface_util as huggingface_util +from library.original_unet import UNet2DConditionModel # Tokenizer: checkpointから読み込むのではなくあらかじめ提供されているものを使う TOKENIZER_PATH = "openai/clip-vit-large-patch14" @@ -1787,100 +1788,18 @@ def backward(ctx, do): return dq, dk, dv, None, None, None, None -def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): - # unet is not used currently, but it is here for future use +def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers): if mem_eff_attn: - replace_unet_cross_attn_to_memory_efficient() + print("Enable memory efficient attention for U-Net") + unet.set_use_memory_efficient_attention(False, True) elif xformers: - replace_unet_cross_attn_to_xformers(unet) - - -def replace_unet_cross_attn_to_memory_efficient(): - print("CrossAttention.forward has been replaced to FlashAttention (not xformers)") - flash_func = FlashAttentionFunction - - def forward_flash_attn(self, x, context=None, mask=None): - q_bucket_size = 512 - k_bucket_size = 1024 - - h = self.heads - q = self.to_q(x) - - context = context if context is not None else x - context = context.to(x.dtype) - - if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - context_k, context_v = self.hypernetwork.forward(x, context) - context_k = context_k.to(x.dtype) - context_v = context_v.to(x.dtype) - else: - context_k = context - context_v = context - - k = self.to_k(context_k) - v = self.to_v(context_v) - del context, x - - q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) - - out = flash_func.apply(q, k, v, mask, False, q_bucket_size, k_bucket_size) - - out = rearrange(out, "b h n d -> b n (h d)") - - out = self.to_out[0](out) - # out = self.to_out[1](out) - return out - - # diffusers.models.attention.CrossAttention.forward = forward_flash_attn - from library.original_unet import CrossAttention - - CrossAttention.forward = forward_flash_attn - - -def replace_unet_cross_attn_to_xformers(unet): - print("CrossAttention.forward has been replaced to enable xformers.") - try: - import xformers.ops - except ImportError: - raise ImportError("No xformers / xformersがインストールされていないようです") - - unet.set_use_memory_efficient_attention_xformers(True) - - # def forward_xformers(self, x, context=None, mask=None): - # h = self.heads - # q_in = self.to_q(x) - - # context = default(context, x) - # context = context.to(x.dtype) - - # if hasattr(self, "hypernetwork") and self.hypernetwork is not None: - # context_k, context_v = self.hypernetwork.forward(x, context) - # context_k = context_k.to(x.dtype) - # context_v = context_v.to(x.dtype) - # else: - # context_k = context - # context_v = context - - # k_in = self.to_k(context_k) - # v_in = self.to_v(context_v) - - # q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) - # del q_in, k_in, v_in - - # q = q.contiguous() - # k = k.contiguous() - # v = v.contiguous() - # out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる - - # out = rearrange(out, "b n h d -> b n (h d)", h=h) - - # # diffusers 0.7.0~ - # out = self.to_out[0](out) - # out = self.to_out[1](out) - # return out - - # diffusers.models.attention.CrossAttention.forward = forward_xformers + print("Enable xformers for U-Net") + try: + import xformers.ops + except ImportError: + raise ImportError("No xformers / xformersがインストールされていないようです") + unet.set_use_memory_efficient_attention(True, False) """ def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): From 4b7b3bc04a5e0d6b74b4e92ade5bbacb3f095c9c Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 17:35:00 +0900 Subject: [PATCH 017/220] fix saved SD dict is invalid for VAE --- library/model_util.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/model_util.py b/library/model_util.py index ea1be5133..0773188c4 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -783,10 +783,10 @@ def convert_vae_state_dict(vae_state_dict): vae_conversion_map_attn = [ # (stable-diffusion, HF Diffusers) ("norm.", "group_norm."), - ("q.", "query."), - ("k.", "key."), - ("v.", "value."), - ("proj_out.", "proj_attn."), + ("q.", "to_q."), + ("k.", "to_k."), + ("v.", "to_v."), + ("proj_out.", "to_out.0."), ] mapping = {k: k for k in vae_state_dict.keys()} @@ -804,7 +804,7 @@ def convert_vae_state_dict(vae_state_dict): for k, v in new_state_dict.items(): for weight_name in weights_to_convert: if f"mid.attn_1.{weight_name}.weight" in k: - # print(f"Reshaping {k} for SD format") + # print(f"Reshaping {k} for SD format: shape {v.shape} -> {v.shape} x 1 x 1") new_state_dict[k] = reshape_weight_for_sd(v) return new_state_dict From 0315611b11c92ab7ad60ac82bf285d8461b78910 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 18:32:14 +0900 Subject: [PATCH 018/220] remove workaround for accelerator=0.15, fix XTI --- XTI_hijack.py | 248 ++++++++++++++++----------------- fine_tune.py | 14 +- library/train_util.py | 18 +-- train_db.py | 14 +- train_network.py | 8 +- train_textual_inversion.py | 14 +- train_textual_inversion_XTI.py | 34 +++-- 7 files changed, 172 insertions(+), 178 deletions(-) diff --git a/XTI_hijack.py b/XTI_hijack.py index f39cc8e7e..36b5d3f2b 100644 --- a/XTI_hijack.py +++ b/XTI_hijack.py @@ -2,132 +2,123 @@ from typing import Union, List, Optional, Dict, Any, Tuple from diffusers.models.unet_2d_condition import UNet2DConditionOutput -def unet_forward_XTI(self, - sample: torch.FloatTensor, - timestep: Union[torch.Tensor, float, int], - encoder_hidden_states: torch.Tensor, - class_labels: Optional[torch.Tensor] = None, - return_dict: bool = True, - ) -> Union[UNet2DConditionOutput, Tuple]: - r""" - Args: - sample (`torch.FloatTensor`): (batch, channel, height, width) noisy inputs tensor - timestep (`torch.FloatTensor` or `float` or `int`): (batch) timesteps - encoder_hidden_states (`torch.FloatTensor`): (batch, sequence_length, feature_dim) encoder hidden states - return_dict (`bool`, *optional*, defaults to `True`): - Whether or not to return a [`models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain tuple. - - Returns: - [`~models.unet_2d_condition.UNet2DConditionOutput`] or `tuple`: - [`~models.unet_2d_condition.UNet2DConditionOutput`] if `return_dict` is True, otherwise a `tuple`. When - returning a tuple, the first element is the sample tensor. - """ - # By default samples have to be AT least a multiple of the overall upsampling factor. - # The overall upsampling factor is equal to 2 ** (# num of upsampling layears). - # However, the upsampling interpolation output size can be forced to fit any upsampling size - # on the fly if necessary. - default_overall_up_factor = 2**self.num_upsamplers - - # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor` - forward_upsample_size = False - upsample_size = None - - if any(s % default_overall_up_factor != 0 for s in sample.shape[-2:]): - logger.info("Forward upsample size to force interpolation output size.") - forward_upsample_size = True - - # 0. center input if necessary - if self.config.center_input_sample: - sample = 2 * sample - 1.0 - - # 1. time - timesteps = timestep - if not torch.is_tensor(timesteps): - # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can - # This would be a good case for the `match` statement (Python 3.10+) - is_mps = sample.device.type == "mps" - if isinstance(timestep, float): - dtype = torch.float32 if is_mps else torch.float64 - else: - dtype = torch.int32 if is_mps else torch.int64 - timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device) - elif len(timesteps.shape) == 0: - timesteps = timesteps[None].to(sample.device) - - # broadcast to batch dimension in a way that's compatible with ONNX/Core ML - timesteps = timesteps.expand(sample.shape[0]) - - t_emb = self.time_proj(timesteps) - - # timesteps does not contain any weights and will always return f32 tensors - # but time_embedding might actually be running in fp16. so we need to cast here. - # there might be better ways to encapsulate this. - t_emb = t_emb.to(dtype=self.dtype) - emb = self.time_embedding(t_emb) - - if self.config.num_class_embeds is not None: - if class_labels is None: - raise ValueError("class_labels should be provided when num_class_embeds > 0") - class_emb = self.class_embedding(class_labels).to(dtype=self.dtype) - emb = emb + class_emb - - # 2. pre-process - sample = self.conv_in(sample) - - # 3. down - down_block_res_samples = (sample,) - down_i = 0 - for downsample_block in self.down_blocks: - if hasattr(downsample_block, "has_cross_attention") and downsample_block.has_cross_attention: - sample, res_samples = downsample_block( - hidden_states=sample, - temb=emb, - encoder_hidden_states=encoder_hidden_states[down_i:down_i+2], - ) - down_i += 2 - else: - sample, res_samples = downsample_block(hidden_states=sample, temb=emb) - - down_block_res_samples += res_samples - - # 4. mid - sample = self.mid_block(sample, emb, encoder_hidden_states=encoder_hidden_states[6]) - - # 5. up - up_i = 7 - for i, upsample_block in enumerate(self.up_blocks): - is_final_block = i == len(self.up_blocks) - 1 - - res_samples = down_block_res_samples[-len(upsample_block.resnets) :] - down_block_res_samples = down_block_res_samples[: -len(upsample_block.resnets)] - - # if we have not reached the final block and need to forward the - # upsample size, we do it here - if not is_final_block and forward_upsample_size: - upsample_size = down_block_res_samples[-1].shape[2:] - - if hasattr(upsample_block, "has_cross_attention") and upsample_block.has_cross_attention: - sample = upsample_block( - hidden_states=sample, - temb=emb, - res_hidden_states_tuple=res_samples, - encoder_hidden_states=encoder_hidden_states[up_i:up_i+3], - upsample_size=upsample_size, - ) - up_i += 3 - else: - sample = upsample_block( - hidden_states=sample, temb=emb, res_hidden_states_tuple=res_samples, upsample_size=upsample_size - ) - # 6. post-process - sample = self.conv_norm_out(sample) - sample = self.conv_act(sample) - sample = self.conv_out(sample) - - if not return_dict: - return (sample,) - - return UNet2DConditionOutput(sample=sample) +from library.original_unet import SampleOutput + + +def unet_forward_XTI( + self, + sample: torch.FloatTensor, + timestep: Union[torch.Tensor, float, int], + encoder_hidden_states: torch.Tensor, + class_labels: Optional[torch.Tensor] = None, + return_dict: bool = True, +) -> Union[Dict, Tuple]: + r""" + Args: + sample (`torch.FloatTensor`): (batch, channel, height, width) noisy inputs tensor + timestep (`torch.FloatTensor` or `float` or `int`): (batch) timesteps + encoder_hidden_states (`torch.FloatTensor`): (batch, sequence_length, feature_dim) encoder hidden states + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a dict instead of a plain tuple. + + Returns: + `SampleOutput` or `tuple`: + `SampleOutput` if `return_dict` is True, otherwise a `tuple`. When returning a tuple, the first element is the sample tensor. + """ + # By default samples have to be AT least a multiple of the overall upsampling factor. + # The overall upsampling factor is equal to 2 ** (# num of upsampling layears). + # However, the upsampling interpolation output size can be forced to fit any upsampling size + # on the fly if necessary. + # デフォルトではサンプルは「2^アップサンプルの数」、つまり64の倍数である必要がある + # ただそれ以外のサイズにも対応できるように、必要ならアップサンプルのサイズを変更する + # 多分画質が悪くなるので、64で割り切れるようにしておくのが良い + default_overall_up_factor = 2**self.num_upsamplers + + # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor` + # 64で割り切れないときはupsamplerにサイズを伝える + forward_upsample_size = False + upsample_size = None + + if any(s % default_overall_up_factor != 0 for s in sample.shape[-2:]): + # logger.info("Forward upsample size to force interpolation output size.") + forward_upsample_size = True + + # 1. time + timesteps = timestep + timesteps = self.handle_unusual_timesteps(sample, timesteps) # 変な時だけ処理 + + t_emb = self.time_proj(timesteps) + + # timesteps does not contain any weights and will always return f32 tensors + # but time_embedding might actually be running in fp16. so we need to cast here. + # there might be better ways to encapsulate this. + # timestepsは重みを含まないので常にfloat32のテンソルを返す + # しかしtime_embeddingはfp16で動いているかもしれないので、ここでキャストする必要がある + # time_projでキャストしておけばいいんじゃね? + t_emb = t_emb.to(dtype=self.dtype) + emb = self.time_embedding(t_emb) + + # 2. pre-process + sample = self.conv_in(sample) + + # 3. down + down_block_res_samples = (sample,) + down_i = 0 + for downsample_block in self.down_blocks: + # downblockはforwardで必ずencoder_hidden_statesを受け取るようにしても良さそうだけど、 + # まあこちらのほうがわかりやすいかもしれない + if downsample_block.has_cross_attention: + sample, res_samples = downsample_block( + hidden_states=sample, + temb=emb, + encoder_hidden_states=encoder_hidden_states[down_i : down_i + 2], + ) + down_i += 2 + else: + sample, res_samples = downsample_block(hidden_states=sample, temb=emb) + + down_block_res_samples += res_samples + + # 4. mid + sample = self.mid_block(sample, emb, encoder_hidden_states=encoder_hidden_states[6]) + + # 5. up + up_i = 7 + for i, upsample_block in enumerate(self.up_blocks): + is_final_block = i == len(self.up_blocks) - 1 + + res_samples = down_block_res_samples[-len(upsample_block.resnets) :] + down_block_res_samples = down_block_res_samples[: -len(upsample_block.resnets)] # skip connection + + # if we have not reached the final block and need to forward the upsample size, we do it here + # 前述のように最後のブロック以外ではupsample_sizeを伝える + if not is_final_block and forward_upsample_size: + upsample_size = down_block_res_samples[-1].shape[2:] + + if upsample_block.has_cross_attention: + sample = upsample_block( + hidden_states=sample, + temb=emb, + res_hidden_states_tuple=res_samples, + encoder_hidden_states=encoder_hidden_states[up_i : up_i + 3], + upsample_size=upsample_size, + ) + up_i += 3 + else: + sample = upsample_block( + hidden_states=sample, temb=emb, res_hidden_states_tuple=res_samples, upsample_size=upsample_size + ) + + # 6. post-process + sample = self.conv_norm_out(sample) + sample = self.conv_act(sample) + sample = self.conv_out(sample) + + if not return_dict: + return (sample,) + + return SampleOutput(sample=sample) + def downblock_forward_XTI( self, hidden_states, temb=None, encoder_hidden_states=None, attention_mask=None, cross_attention_kwargs=None @@ -166,6 +157,7 @@ def custom_forward(*inputs): return hidden_states, output_states + def upblock_forward_XTI( self, hidden_states, @@ -199,11 +191,11 @@ def custom_forward(*inputs): else: hidden_states = resnet(hidden_states, temb) hidden_states = attn(hidden_states, encoder_hidden_states=encoder_hidden_states[i]).sample - + i += 1 if self.upsamplers is not None: for upsampler in self.upsamplers: hidden_states = upsampler(hidden_states, upsample_size) - return hidden_states \ No newline at end of file + return hidden_states diff --git a/fine_tune.py b/fine_tune.py index 201d49525..881845c56 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -91,7 +91,7 @@ def train(args): # acceleratorを準備する print("prepare accelerator") - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) @@ -385,8 +385,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): epoch, num_train_epochs, global_step, - unwrap_model(text_encoder), - unwrap_model(unet), + accelerator.unwrap_model(text_encoder), + accelerator.unwrap_model(unet), vae, ) @@ -428,8 +428,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): epoch, num_train_epochs, global_step, - unwrap_model(text_encoder), - unwrap_model(unet), + accelerator.unwrap_model(text_encoder), + accelerator.unwrap_model(unet), vae, ) @@ -437,8 +437,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): is_main_process = accelerator.is_main_process if is_main_process: - unet = unwrap_model(unet) - text_encoder = unwrap_model(text_encoder) + unet = accelerator.unwrap_model(unet) + text_encoder = accelerator.unwrap_model(text_encoder) accelerator.end_training() diff --git a/library/train_util.py b/library/train_util.py index 7d7eb325d..3ae5d0f3f 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2904,23 +2904,9 @@ def prepare_accelerator(args: argparse.Namespace): gradient_accumulation_steps=args.gradient_accumulation_steps, mixed_precision=args.mixed_precision, log_with=log_with, - logging_dir=logging_dir, + project_dir=logging_dir, ) - - # accelerateの互換性問題を解決する - accelerator_0_15 = True - try: - accelerator.unwrap_model("dummy", True) - print("Using accelerator 0.15.0 or above.") - except TypeError: - accelerator_0_15 = False - - def unwrap_model(model): - if accelerator_0_15: - return accelerator.unwrap_model(model, True) - return accelerator.unwrap_model(model) - - return accelerator, unwrap_model + return accelerator def prepare_dtype(args: argparse.Namespace): diff --git a/train_db.py b/train_db.py index c81a092de..09f8d361d 100644 --- a/train_db.py +++ b/train_db.py @@ -95,7 +95,7 @@ def train(args): f"gradient_accumulation_stepsが{args.gradient_accumulation_steps}に設定されています。accelerateは複数モデル(U-NetおよびText Encoder)の学習時にgradient_accumulation_stepsをサポートしていないため結果は未知数です" ) - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) @@ -372,8 +372,8 @@ def train(args): epoch, num_train_epochs, global_step, - unwrap_model(text_encoder), - unwrap_model(unet), + accelerator.unwrap_model(text_encoder), + accelerator.unwrap_model(unet), vae, ) @@ -420,8 +420,8 @@ def train(args): epoch, num_train_epochs, global_step, - unwrap_model(text_encoder), - unwrap_model(unet), + accelerator.unwrap_model(text_encoder), + accelerator.unwrap_model(unet), vae, ) @@ -429,8 +429,8 @@ def train(args): is_main_process = accelerator.is_main_process if is_main_process: - unet = unwrap_model(unet) - text_encoder = unwrap_model(text_encoder) + unet = accelerator.unwrap_model(unet) + text_encoder = accelerator.unwrap_model(text_encoder) accelerator.end_training() diff --git a/train_network.py b/train_network.py index b62aef7ee..7c74ae5d4 100644 --- a/train_network.py +++ b/train_network.py @@ -150,7 +150,7 @@ def train(args): # acceleratorを準備する print("preparing accelerator") - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) is_main_process = accelerator.is_main_process # mixed precisionに対応した型を用意しておき適宜castする @@ -702,7 +702,7 @@ def remove_model(old_ckpt_name): accelerator.wait_for_everyone() if accelerator.is_main_process: ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) - save_model(ckpt_name, unwrap_model(network), global_step, epoch) + save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch) if args.save_state: train_util.save_and_remove_state_stepwise(args, accelerator, global_step) @@ -744,7 +744,7 @@ def remove_model(old_ckpt_name): saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs if is_main_process and saving: ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) - save_model(ckpt_name, unwrap_model(network), global_step, epoch + 1) + save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch + 1) remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) if remove_epoch_no is not None: @@ -762,7 +762,7 @@ def remove_model(old_ckpt_name): metadata["ss_training_finished_at"] = str(time.time()) if is_main_process: - network = unwrap_model(network) + network = accelerator.unwrap_model(network) accelerator.end_training() diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 8be0703d6..9dd846bd4 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -98,7 +98,7 @@ def train(args): # acceleratorを準備する print("prepare accelerator") - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) @@ -291,7 +291,7 @@ def train(args): index_no_updates = torch.arange(len(tokenizer)) < token_ids[0] # print(len(index_no_updates), torch.sum(index_no_updates)) - orig_embeds_params = unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() + orig_embeds_params = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() # Freeze all parameters except for the token embeddings in text encoder text_encoder.requires_grad_(True) @@ -440,7 +440,7 @@ def remove_model(old_ckpt_name): # Let's make sure we don't update any embedding weights besides the newly added token with torch.no_grad(): - unwrap_model(text_encoder).get_input_embeddings().weight[index_no_updates] = orig_embeds_params[ + accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[index_no_updates] = orig_embeds_params[ index_no_updates ] @@ -457,7 +457,9 @@ def remove_model(old_ckpt_name): if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: accelerator.wait_for_everyone() if accelerator.is_main_process: - updated_embs = unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() + updated_embs = ( + accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() + ) ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) save_model(ckpt_name, updated_embs, global_step, epoch) @@ -493,7 +495,7 @@ def remove_model(old_ckpt_name): accelerator.wait_for_everyone() - updated_embs = unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() + updated_embs = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() if args.save_every_n_epochs is not None: saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs @@ -517,7 +519,7 @@ def remove_model(old_ckpt_name): is_main_process = accelerator.is_main_process if is_main_process: - text_encoder = unwrap_model(text_encoder) + text_encoder = accelerator.unwrap_model(text_encoder) accelerator.end_training() diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index 7b734f283..1ea6dfc6e 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -11,6 +11,7 @@ from accelerate.utils import set_seed import diffusers from diffusers import DDPMScheduler +import library import library.train_util as train_util import library.huggingface_util as huggingface_util @@ -20,7 +21,14 @@ BlueprintGenerator, ) import library.custom_train_functions as custom_train_functions -from library.custom_train_functions import apply_snr_weight, prepare_scheduler_for_custom_training, pyramid_noise_like, apply_noise_offset, scale_v_prediction_loss_like_noise_prediction +from library.custom_train_functions import ( + apply_snr_weight, + prepare_scheduler_for_custom_training, + pyramid_noise_like, + apply_noise_offset, + scale_v_prediction_loss_like_noise_prediction, +) +import library.original_unet as original_unet from XTI_hijack import unet_forward_XTI, downblock_forward_XTI, upblock_forward_XTI imagenet_templates_small = [ @@ -98,7 +106,7 @@ def train(args): # acceleratorを準備する print("prepare accelerator") - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) @@ -257,9 +265,9 @@ def train(args): # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) - diffusers.models.UNet2DConditionModel.forward = unet_forward_XTI - diffusers.models.unet_2d_blocks.CrossAttnDownBlock2D.forward = downblock_forward_XTI - diffusers.models.unet_2d_blocks.CrossAttnUpBlock2D.forward = upblock_forward_XTI + original_unet.UNet2DConditionModel.forward = unet_forward_XTI + original_unet.CrossAttnDownBlock2D.forward = downblock_forward_XTI + original_unet.CrossAttnUpBlock2D.forward = upblock_forward_XTI # 学習を準備する if cache_latents: @@ -319,7 +327,7 @@ def train(args): index_no_updates = torch.arange(len(tokenizer)) < token_ids_XTI[0] # print(len(index_no_updates), torch.sum(index_no_updates)) - orig_embeds_params = unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() + orig_embeds_params = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() # Freeze all parameters except for the token embeddings in text encoder text_encoder.requires_grad_(True) @@ -473,7 +481,7 @@ def remove_model(old_ckpt_name): # Let's make sure we don't update any embedding weights besides the newly added token with torch.no_grad(): - unwrap_model(text_encoder).get_input_embeddings().weight[index_no_updates] = orig_embeds_params[ + accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[index_no_updates] = orig_embeds_params[ index_no_updates ] @@ -490,7 +498,13 @@ def remove_model(old_ckpt_name): if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: accelerator.wait_for_everyone() if accelerator.is_main_process: - updated_embs = unwrap_model(text_encoder).get_input_embeddings().weight[token_ids_XTI].data.detach().clone() + updated_embs = ( + accelerator.unwrap_model(text_encoder) + .get_input_embeddings() + .weight[token_ids_XTI] + .data.detach() + .clone() + ) ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) save_model(ckpt_name, updated_embs, global_step, epoch) @@ -526,7 +540,7 @@ def remove_model(old_ckpt_name): accelerator.wait_for_everyone() - updated_embs = unwrap_model(text_encoder).get_input_embeddings().weight[token_ids_XTI].data.detach().clone() + updated_embs = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids_XTI].data.detach().clone() if args.save_every_n_epochs is not None: saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs @@ -551,7 +565,7 @@ def remove_model(old_ckpt_name): is_main_process = accelerator.is_main_process if is_main_process: - text_encoder = unwrap_model(text_encoder) + text_encoder = accelerator.unwrap_model(text_encoder) accelerator.end_training() From 4d0c06e3975e03f4f4e7c648602824d272151297 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 18:54:50 +0900 Subject: [PATCH 019/220] support both 0.10.2 and 0.17.0 for Diffusers --- gen_img_diffusers.py | 84 ++++++++++++++++++++++++++++++++++++++++--- library/model_util.py | 66 +++++++++++++++++++++++++--------- 2 files changed, 129 insertions(+), 21 deletions(-) diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 34857af39..71daa9a19 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -161,9 +161,45 @@ def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xform # とりあえずDiffusersのxformersを使う。AttentionがあるのはMidBlockのみ replace_vae_attn_to_xformers() + def replace_vae_attn_to_memory_efficient(): print("VAE Attention.forward has been replaced to FlashAttention (not xformers)") - flash_func =FlashAttentionFunction + flash_func = FlashAttentionFunction + + def forward_flash_attn_0_14(self, hidden_states, **kwargs): + q_bucket_size = 512 + k_bucket_size = 1024 + + residual = hidden_states + batch, channel, height, width = hidden_states.shape + + # norm + hidden_states = self.group_norm(hidden_states) + + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) + + # proj to q, k, v + query_proj = self.query(hidden_states) + key_proj = self.key(hidden_states) + value_proj = self.value(hidden_states) + + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.num_heads), (query_proj, key_proj, value_proj) + ) + + out = flash_func.apply(query_proj, key_proj, value_proj, None, False, q_bucket_size, k_bucket_size) + + out = rearrange(out, "b h n d -> b n (h d)") + + # compute next hidden_states + # linear proj + hidden_states = self.proj_attn(hidden_states) + + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) + + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor + return hidden_states def forward_flash_attn(self, hidden_states, **kwargs): q_bucket_size = 512 @@ -202,13 +238,50 @@ def forward_flash_attn(self, hidden_states, **kwargs): hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states - diffusers.models.attention_processor.Attention.forward = forward_flash_attn + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_flash_attn_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_flash_attn def replace_vae_attn_to_xformers(): print("VAE: Attention.forward has been replaced to xformers") import xformers.ops - + + def forward_xformers_0_14(self, hidden_states, **kwargs): + residual = hidden_states + batch, channel, height, width = hidden_states.shape + + # norm + hidden_states = self.group_norm(hidden_states) + + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) + + # proj to q, k, v + query_proj = self.query(hidden_states) + key_proj = self.key(hidden_states) + value_proj = self.value(hidden_states) + + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.num_heads), (query_proj, key_proj, value_proj) + ) + + query_proj = query_proj.contiguous() + key_proj = key_proj.contiguous() + value_proj = value_proj.contiguous() + out = xformers.ops.memory_efficient_attention(query_proj, key_proj, value_proj, attn_bias=None) + + out = rearrange(out, "b h n d -> b n (h d)") + + # compute next hidden_states + hidden_states = self.proj_attn(hidden_states) + + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) + + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor + return hidden_states + def forward_xformers(self, hidden_states, **kwargs): residual = hidden_states batch, channel, height, width = hidden_states.shape @@ -246,7 +319,10 @@ def forward_xformers(self, hidden_states, **kwargs): hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states - diffusers.models.attention_processor.Attention.forward = forward_xformers + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_xformers_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_xformers # endregion diff --git a/library/model_util.py b/library/model_util.py index 0773188c4..7ca8f1942 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -4,6 +4,7 @@ import math import os import torch +import diffusers from transformers import CLIPTextModel, CLIPTokenizer, CLIPTextConfig, logging from diffusers import AutoencoderKL, DDIMScheduler, StableDiffusionPipeline # , UNet2DConditionModel from safetensors.torch import load_file, save_file @@ -127,17 +128,30 @@ def renew_vae_attention_paths(old_list, n_shave_prefix_segments=0): new_item = new_item.replace("norm.weight", "group_norm.weight") new_item = new_item.replace("norm.bias", "group_norm.bias") - new_item = new_item.replace("q.weight", "to_q.weight") - new_item = new_item.replace("q.bias", "to_q.bias") + if diffusers.__version__ < "0.15.0": + new_item = new_item.replace("q.weight", "query.weight") + new_item = new_item.replace("q.bias", "query.bias") - new_item = new_item.replace("k.weight", "to_k.weight") - new_item = new_item.replace("k.bias", "to_k.bias") + new_item = new_item.replace("k.weight", "key.weight") + new_item = new_item.replace("k.bias", "key.bias") - new_item = new_item.replace("v.weight", "to_v.weight") - new_item = new_item.replace("v.bias", "to_v.bias") + new_item = new_item.replace("v.weight", "value.weight") + new_item = new_item.replace("v.bias", "value.bias") - new_item = new_item.replace("proj_out.weight", "to_out.0.weight") - new_item = new_item.replace("proj_out.bias", "to_out.0.bias") + new_item = new_item.replace("proj_out.weight", "proj_attn.weight") + new_item = new_item.replace("proj_out.bias", "proj_attn.bias") + else: + new_item = new_item.replace("q.weight", "to_q.weight") + new_item = new_item.replace("q.bias", "to_q.bias") + + new_item = new_item.replace("k.weight", "to_k.weight") + new_item = new_item.replace("k.bias", "to_k.bias") + + new_item = new_item.replace("v.weight", "to_v.weight") + new_item = new_item.replace("v.bias", "to_v.bias") + + new_item = new_item.replace("proj_out.weight", "to_out.0.weight") + new_item = new_item.replace("proj_out.bias", "to_out.0.bias") new_item = shave_segments(new_item, n_shave_prefix_segments=n_shave_prefix_segments) @@ -192,7 +206,15 @@ def assign_to_checkpoint( new_path = new_path.replace(replacement["old"], replacement["new"]) # proj_attn.weight has to be converted from conv 1D to linear - if ".attentions." in new_path and ".0.to_" in new_path and old_checkpoint[path["old"]].ndim > 2: + reshaping = False + if diffusers.__version__ < "0.15.0": + if "proj_attn.weight" in new_path: + reshaping = True + else: + if ".attentions." in new_path and ".0.to_" in new_path and old_checkpoint[path["old"]].ndim > 2: + reshaping = True + + if reshaping: checkpoint[new_path] = old_checkpoint[path["old"]][:, :, 0, 0] else: checkpoint[new_path] = old_checkpoint[path["old"]] @@ -780,14 +802,24 @@ def convert_vae_state_dict(vae_state_dict): sd_mid_res_prefix = f"mid.block_{i+1}." vae_conversion_map.append((sd_mid_res_prefix, hf_mid_res_prefix)) - vae_conversion_map_attn = [ - # (stable-diffusion, HF Diffusers) - ("norm.", "group_norm."), - ("q.", "to_q."), - ("k.", "to_k."), - ("v.", "to_v."), - ("proj_out.", "to_out.0."), - ] + if diffusers.__version__ < "0.15.0": + vae_conversion_map_attn = [ + # (stable-diffusion, HF Diffusers) + ("norm.", "group_norm."), + ("q.", "query."), + ("k.", "key."), + ("v.", "value."), + ("proj_out.", "proj_attn."), + ] + else: + vae_conversion_map_attn = [ + # (stable-diffusion, HF Diffusers) + ("norm.", "group_norm."), + ("q.", "to_q."), + ("k.", "to_k."), + ("v.", "to_v."), + ("proj_out.", "to_out.0."), + ] mapping = {k: k for k in vae_state_dict.keys()} for k, v in mapping.items(): From 9e1683cf2b85438c3ddc54b9c545a12bcf670e6d Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 21:26:15 +0900 Subject: [PATCH 020/220] support sdpa --- README.md | 26 ++++++- fine_tune.py | 2 +- gen_img_diffusers.py | 120 ++++++++++++++++++--------------- library/original_unet.py | 61 ++++++++++++++++- library/train_util.py | 6 +- train_db.py | 2 +- train_network.py | 2 +- train_textual_inversion.py | 2 +- train_textual_inversion_XTI.py | 2 +- 9 files changed, 158 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 8234a89e4..634b9494e 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,6 @@ cp .\bitsandbytes_windows\main.py .\venv\Lib\site-packages\bitsandbytes\cuda_set accelerate config ``` -update: ``python -m venv venv`` is seemed to be safer than ``python -m venv --system-site-packages venv`` (some user have packages in global python). - Answers to accelerate config: ```txt @@ -94,6 +92,30 @@ note: Some user reports ``ValueError: fp16 mixed precision requires a GPU`` is o (Single GPU with id `0` will be used.) +### Experimental: Use PyTorch 2.0 + +In this case, you need to install PyTorch 2.0 and xformers 0.0.20. Instead of the above, please type the following: + +```powershell +git clone https://github.com/kohya-ss/sd-scripts.git +cd sd-scripts + +python -m venv venv +.\venv\Scripts\activate + +pip install torch==2.0.1+cu118 torchvision==0.15.2+cu118 --index-url https://download.pytorch.org/whl/cu118 +pip install --upgrade -r requirements.txt +pip install xformers==0.0.20 + +cp .\bitsandbytes_windows\*.dll .\venv\Lib\site-packages\bitsandbytes\ +cp .\bitsandbytes_windows\cextension.py .\venv\Lib\site-packages\bitsandbytes\cextension.py +cp .\bitsandbytes_windows\main.py .\venv\Lib\site-packages\bitsandbytes\cuda_setup\main.py + +accelerate config +``` + +Answers to accelerate config should be the same as above. + ### about PyTorch and xformers Other versions of PyTorch and xformers seem to have problems with training. diff --git a/fine_tune.py b/fine_tune.py index 881845c56..120f3d0f8 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -141,7 +141,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # Windows版のxformersはfloatで学習できないのでxformersを使わない設定も可能にしておく必要がある print("Disable Diffusers' xformers") set_diffusers_xformers_flag(unet, False) - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) # 学習を準備する if cache_latents: diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 71daa9a19..889b4c4cb 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -137,7 +137,7 @@ """ -def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): +def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers, sdpa): if mem_eff_attn: print("Enable memory efficient attention for U-Net") @@ -151,56 +151,26 @@ def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditio raise ImportError("No xformers / xformersがインストールされていないようです") unet.set_use_memory_efficient_attention(True, False) + elif sdpa: + print("Enable SDPA for U-Net") + unet.set_use_memory_efficient_attention(False, False) + unet.set_use_sdpa(True) # TODO common train_util.py -def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): +def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers, sdpa): if mem_eff_attn: replace_vae_attn_to_memory_efficient() elif xformers: - # とりあえずDiffusersのxformersを使う。AttentionがあるのはMidBlockのみ replace_vae_attn_to_xformers() + elif sdpa: + replace_vae_attn_to_sdpa() def replace_vae_attn_to_memory_efficient(): print("VAE Attention.forward has been replaced to FlashAttention (not xformers)") flash_func = FlashAttentionFunction - def forward_flash_attn_0_14(self, hidden_states, **kwargs): - q_bucket_size = 512 - k_bucket_size = 1024 - - residual = hidden_states - batch, channel, height, width = hidden_states.shape - - # norm - hidden_states = self.group_norm(hidden_states) - - hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) - - # proj to q, k, v - query_proj = self.query(hidden_states) - key_proj = self.key(hidden_states) - value_proj = self.value(hidden_states) - - query_proj, key_proj, value_proj = map( - lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.num_heads), (query_proj, key_proj, value_proj) - ) - - out = flash_func.apply(query_proj, key_proj, value_proj, None, False, q_bucket_size, k_bucket_size) - - out = rearrange(out, "b h n d -> b n (h d)") - - # compute next hidden_states - # linear proj - hidden_states = self.proj_attn(hidden_states) - - hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) - - # res connect and rescale - hidden_states = (hidden_states + residual) / self.rescale_output_factor - return hidden_states - def forward_flash_attn(self, hidden_states, **kwargs): q_bucket_size = 512 k_bucket_size = 1024 @@ -238,6 +208,15 @@ def forward_flash_attn(self, hidden_states, **kwargs): hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states + def forward_flash_attn_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_flash_attn(self, hidden_states, **kwargs) + if diffusers.__version__ < "0.15.0": diffusers.models.attention.AttentionBlock.forward = forward_flash_attn_0_14 else: @@ -248,7 +227,7 @@ def replace_vae_attn_to_xformers(): print("VAE: Attention.forward has been replaced to xformers") import xformers.ops - def forward_xformers_0_14(self, hidden_states, **kwargs): + def forward_xformers(self, hidden_states, **kwargs): residual = hidden_states batch, channel, height, width = hidden_states.shape @@ -258,12 +237,12 @@ def forward_xformers_0_14(self, hidden_states, **kwargs): hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) # proj to q, k, v - query_proj = self.query(hidden_states) - key_proj = self.key(hidden_states) - value_proj = self.value(hidden_states) + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) query_proj, key_proj, value_proj = map( - lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.num_heads), (query_proj, key_proj, value_proj) + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) ) query_proj = query_proj.contiguous() @@ -274,7 +253,10 @@ def forward_xformers_0_14(self, hidden_states, **kwargs): out = rearrange(out, "b h n d -> b n (h d)") # compute next hidden_states - hidden_states = self.proj_attn(hidden_states) + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) @@ -282,7 +264,25 @@ def forward_xformers_0_14(self, hidden_states, **kwargs): hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states - def forward_xformers(self, hidden_states, **kwargs): + def forward_xformers_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_xformers(self, hidden_states, **kwargs) + + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_xformers_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_xformers + + +def replace_vae_attn_to_sdpa(): + print("VAE: Attention.forward has been replaced to sdpa") + + def forward_sdpa(self, hidden_states, **kwargs): residual = hidden_states batch, channel, height, width = hidden_states.shape @@ -297,15 +297,14 @@ def forward_xformers(self, hidden_states, **kwargs): value_proj = self.to_v(hidden_states) query_proj, key_proj, value_proj = map( - lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) + lambda t: rearrange(t, "b n (h d) -> b n h d", h=self.heads), (query_proj, key_proj, value_proj) ) - query_proj = query_proj.contiguous() - key_proj = key_proj.contiguous() - value_proj = value_proj.contiguous() - out = xformers.ops.memory_efficient_attention(query_proj, key_proj, value_proj, attn_bias=None) + out = torch.nn.functional.scaled_dot_product_attention( + query_proj, key_proj, value_proj, attn_mask=None, dropout_p=0.0, is_causal=False + ) - out = rearrange(out, "b h n d -> b n (h d)") + out = rearrange(out, "b n h d -> b n (h d)") # compute next hidden_states # linear proj @@ -319,10 +318,19 @@ def forward_xformers(self, hidden_states, **kwargs): hidden_states = (hidden_states + residual) / self.rescale_output_factor return hidden_states + def forward_sdpa_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_sdpa(self, hidden_states, **kwargs) + if diffusers.__version__ < "0.15.0": - diffusers.models.attention.AttentionBlock.forward = forward_xformers_0_14 + diffusers.models.attention.AttentionBlock.forward = forward_sdpa_0_14 else: - diffusers.models.attention_processor.Attention.forward = forward_xformers + diffusers.models.attention_processor.Attention.forward = forward_sdpa # endregion @@ -2082,8 +2090,9 @@ def main(args): # xformers、Hypernetwork対応 if not args.diffusers_xformers: - replace_unet_modules(unet, not args.xformers, args.xformers) - replace_vae_modules(vae, not args.xformers, args.xformers) + mem_eff = not (args.xformers or args.sdpa) + replace_unet_modules(unet, mem_eff, args.xformers, args.sdpa) + replace_vae_modules(vae, mem_eff, args.xformers, args.sdpa) # tokenizerを読み込む print("loading tokenizer") @@ -3176,6 +3185,7 @@ def setup_parser() -> argparse.ArgumentParser: parser.add_argument("--fp16", action="store_true", help="use fp16 / fp16を指定し省メモリ化する") parser.add_argument("--bf16", action="store_true", help="use bfloat16 / bfloat16を指定し省メモリ化する") parser.add_argument("--xformers", action="store_true", help="use xformers / xformersを使用し高速化する") + parser.add_argument("--sdpa", action="store_true", help="use sdpa in PyTorch 2 / sdpa") parser.add_argument( "--diffusers_xformers", action="store_true", diff --git a/library/original_unet.py b/library/original_unet.py index 36318eb90..e22b16c0c 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -494,6 +494,9 @@ def __init__( def set_use_memory_efficient_attention(self, xformers, mem_eff): pass + def set_use_sdpa(self, sdpa): + pass + def forward(self, hidden_states, temb=None): output_states = () @@ -564,11 +567,15 @@ def __init__( self.use_memory_efficient_attention_xformers = False self.use_memory_efficient_attention_mem_eff = False + self.use_sdpa = False def set_use_memory_efficient_attention(self, xformers, mem_eff): self.use_memory_efficient_attention_xformers = xformers self.use_memory_efficient_attention_mem_eff = mem_eff + def set_use_sdpa(self, sdpa): + self.use_sdpa = sdpa + def reshape_heads_to_batch_dim(self, tensor): batch_size, seq_len, dim = tensor.shape head_size = self.heads @@ -588,6 +595,8 @@ def forward(self, hidden_states, context=None, mask=None): return self.forward_memory_efficient_xformers(hidden_states, context, mask) if self.use_memory_efficient_attention_mem_eff: return self.forward_memory_efficient_mem_eff(hidden_states, context, mask) + if self.use_sdpa: + return self.forward_sdpa(hidden_states, context, mask) query = self.to_q(hidden_states) context = context if context is not None else hidden_states @@ -676,6 +685,26 @@ def forward_memory_efficient_mem_eff(self, x, context=None, mask=None): out = self.to_out[0](out) return out + def forward_sdpa(self, x, context=None, mask=None): + import xformers.ops + + h = self.heads + q_in = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k_in = self.to_k(context) + v_in = self.to_v(context) + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q_in, k_in, v_in)) + del q_in, k_in, v_in + + out = F.scaled_dot_product_attention(q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False) + + out = rearrange(out, "b h n d -> b n (h d)", h=h) + + out = self.to_out[0](out) + return out + # feedforward class GEGLU(nn.Module): @@ -759,6 +788,10 @@ def set_use_memory_efficient_attention(self, xformers: bool, mem_eff: bool): self.attn1.set_use_memory_efficient_attention(xformers, mem_eff) self.attn2.set_use_memory_efficient_attention(xformers, mem_eff) + def set_use_sdpa(self, sdpa: bool): + self.attn1.set_use_sdpa(sdpa) + self.attn2.set_use_sdpa(sdpa) + def forward(self, hidden_states, context=None, timestep=None): # 1. Self-Attention norm_hidden_states = self.norm1(hidden_states) @@ -820,6 +853,10 @@ def set_use_memory_efficient_attention(self, xformers, mem_eff): for transformer in self.transformer_blocks: transformer.set_use_memory_efficient_attention(xformers, mem_eff) + def set_use_sdpa(self, sdpa): + for transformer in self.transformer_blocks: + transformer.set_use_sdpa(sdpa) + def forward(self, hidden_states, encoder_hidden_states=None, timestep=None, return_dict: bool = True): # 1. Input batch, _, height, weight = hidden_states.shape @@ -901,6 +938,10 @@ def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: attn.set_use_memory_efficient_attention(xformers, mem_eff) + def set_use_sdpa(self, sdpa): + for attn in self.attentions: + attn.set_use_sdpa(sdpa) + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): output_states = () @@ -978,6 +1019,10 @@ def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: attn.set_use_memory_efficient_attention(xformers, mem_eff) + def set_use_sdpa(self, sdpa): + for attn in self.attentions: + attn.set_use_sdpa(sdpa) + def forward(self, hidden_states, temb=None, encoder_hidden_states=None): for i, resnet in enumerate(self.resnets): attn = None if i == 0 else self.attentions[i - 1] @@ -1079,6 +1124,9 @@ def __init__( def set_use_memory_efficient_attention(self, xformers, mem_eff): pass + def set_use_sdpa(self, sdpa): + pass + def forward(self, hidden_states, res_hidden_states_tuple, temb=None, upsample_size=None): for resnet in self.resnets: # pop res hidden states @@ -1159,6 +1207,10 @@ def set_use_memory_efficient_attention(self, xformers, mem_eff): for attn in self.attentions: attn.set_use_memory_efficient_attention(xformers, mem_eff) + def set_use_sdpa(self, spda): + for attn in self.attentions: + attn.set_use_sdpa(spda) + def forward( self, hidden_states, @@ -1393,10 +1445,15 @@ def enable_gradient_checkpointing(self): def disable_gradient_checkpointing(self): self.set_gradient_checkpointing(value=False) - def set_use_memory_efficient_attention(self, xformers: bool,mem_eff:bool) -> None: + def set_use_memory_efficient_attention(self, xformers: bool, mem_eff: bool) -> None: + modules = self.down_blocks + [self.mid_block] + self.up_blocks + for module in modules: + module.set_use_memory_efficient_attention(xformers, mem_eff) + + def set_use_sdpa(self, sdpa: bool) -> None: modules = self.down_blocks + [self.mid_block] + self.up_blocks for module in modules: - module.set_use_memory_efficient_attention(xformers,mem_eff) + module.set_use_sdpa(sdpa) def set_gradient_checkpointing(self, value=False): modules = self.down_blocks + [self.mid_block] + self.up_blocks diff --git a/library/train_util.py b/library/train_util.py index 3ae5d0f3f..30380262c 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -1788,7 +1788,7 @@ def backward(ctx, do): return dq, dk, dv, None, None, None, None -def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers): +def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers, sdpa): if mem_eff_attn: print("Enable memory efficient attention for U-Net") unet.set_use_memory_efficient_attention(False, True) @@ -1800,6 +1800,9 @@ def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers): raise ImportError("No xformers / xformersがインストールされていないようです") unet.set_use_memory_efficient_attention(True, False) + elif sdpa: + print("Enable SDPA for U-Net") + unet.set_use_sdpa(True) """ def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): @@ -2048,6 +2051,7 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: help="use memory efficient attention for CrossAttention / CrossAttentionに省メモリ版attentionを使う", ) parser.add_argument("--xformers", action="store_true", help="use xformers for CrossAttention / CrossAttentionにxformersを使う") + parser.add_argument("--sdpa", action="store_true", help="use sdpa for CrossAttention (requires PyTorch 2.0) / CrossAttentionにsdpaを使う(PyTorch 2.0が必要)") parser.add_argument( "--vae", type=str, default=None, help="path to checkpoint of vae to replace / VAEを入れ替える場合、VAEのcheckpointファイルまたはディレクトリ" ) diff --git a/train_db.py b/train_db.py index 09f8d361d..895b8b249 100644 --- a/train_db.py +++ b/train_db.py @@ -119,7 +119,7 @@ def train(args): use_safetensors = args.use_safetensors or ("safetensors" in args.save_model_as.lower()) # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) # 学習を準備する if cache_latents: diff --git a/train_network.py b/train_network.py index 7c74ae5d4..9ea9bf9cf 100644 --- a/train_network.py +++ b/train_network.py @@ -160,7 +160,7 @@ def train(args): text_encoder, vae, unet, _ = train_util.load_target_model(args, weight_dtype, accelerator) # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) # 差分追加学習のためにモデルを読み込む import sys diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 9dd846bd4..4f31220d0 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -231,7 +231,7 @@ def train(args): ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) # 学習を準備する if cache_latents: diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index 1ea6dfc6e..69f618ccd 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -264,7 +264,7 @@ def train(args): ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) original_unet.UNet2DConditionModel.forward = unet_forward_XTI original_unet.CrossAttnDownBlock2D.forward = downblock_forward_XTI original_unet.CrossAttnUpBlock2D.forward = upblock_forward_XTI From 0dfffcd88ac46214ac8d5596c3060f87843f010f Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 11 Jun 2023 21:46:05 +0900 Subject: [PATCH 021/220] remove unnecessary import --- library/original_unet.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/original_unet.py b/library/original_unet.py index e22b16c0c..94d112902 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -686,8 +686,6 @@ def forward_memory_efficient_mem_eff(self, x, context=None, mask=None): return out def forward_sdpa(self, x, context=None, mask=None): - import xformers.ops - h = self.heads q_in = self.to_q(x) context = context if context is not None else x From 67f09b7d7ed247c14133feb584519428a396f329 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 12 Jun 2023 12:29:44 +0900 Subject: [PATCH 022/220] change ver no for Diffusers VAE changing --- library/model_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/model_util.py b/library/model_util.py index 7ca8f1942..d59f5ef46 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -128,7 +128,7 @@ def renew_vae_attention_paths(old_list, n_shave_prefix_segments=0): new_item = new_item.replace("norm.weight", "group_norm.weight") new_item = new_item.replace("norm.bias", "group_norm.bias") - if diffusers.__version__ < "0.15.0": + if diffusers.__version__ < "0.17.0": new_item = new_item.replace("q.weight", "query.weight") new_item = new_item.replace("q.bias", "query.bias") @@ -207,7 +207,7 @@ def assign_to_checkpoint( # proj_attn.weight has to be converted from conv 1D to linear reshaping = False - if diffusers.__version__ < "0.15.0": + if diffusers.__version__ < "0.17.0": if "proj_attn.weight" in new_path: reshaping = True else: @@ -802,7 +802,7 @@ def convert_vae_state_dict(vae_state_dict): sd_mid_res_prefix = f"mid.block_{i+1}." vae_conversion_map.append((sd_mid_res_prefix, hf_mid_res_prefix)) - if diffusers.__version__ < "0.15.0": + if diffusers.__version__ < "0.17.0": vae_conversion_map_attn = [ # (stable-diffusion, HF Diffusers) ("norm.", "group_norm."), From 449ad7502cb0f36cd8b94b2c7d98ec204af234a9 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 14 Jun 2023 22:26:05 +0900 Subject: [PATCH 023/220] use original unet for HF models, don't download TE --- gen_img_diffusers.py | 17 +++++++++++------ library/model_util.py | 29 +++++++++++++++++++++++++---- library/train_util.py | 17 ++++++++++++++++- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/gen_img_diffusers.py b/gen_img_diffusers.py index 889b4c4cb..2c36329e0 100644 --- a/gen_img_diffusers.py +++ b/gen_img_diffusers.py @@ -99,12 +99,6 @@ from XTI_hijack import unet_forward_XTI, downblock_forward_XTI, upblock_forward_XTI -# Tokenizer: checkpointから読み込むのではなくあらかじめ提供されているものを使う -TOKENIZER_PATH = "openai/clip-vit-large-patch14" -V2_STABLE_DIFFUSION_PATH = "stabilityai/stable-diffusion-2" # ここからtokenizerだけ使う - -DEFAULT_TOKEN_LENGTH = 75 - # scheduler: SCHEDULER_LINEAR_START = 0.00085 SCHEDULER_LINEAR_END = 0.0120 @@ -2066,6 +2060,17 @@ def main(args): tokenizer = loading_pipe.tokenizer del loading_pipe + # Diffusers U-Net to original U-Net + original_unet = UNet2DConditionModel( + unet.config.sample_size, + unet.config.attention_head_dim, + unet.config.cross_attention_dim, + unet.config.use_linear_projection, + unet.config.upcast_attention, + ) + original_unet.load_state_dict(unet.state_dict()) + unet = original_unet + # VAEを読み込む if args.vae is not None: vae = model_util.load_vae(args.vae, dtype) diff --git a/library/model_util.py b/library/model_util.py index d59f5ef46..63a395f82 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -933,10 +933,31 @@ def load_models_from_stable_diffusion_checkpoint(v2, ckpt_path, device="cpu", dt else: converted_text_encoder_checkpoint = convert_ldm_clip_checkpoint_v1(state_dict) - logging.set_verbosity_error() # don't show annoying warning - text_model = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14").to(device) - logging.set_verbosity_warning() - + # logging.set_verbosity_error() # don't show annoying warning + # text_model = CLIPTextModel.from_pretrained("openai/clip-vit-large-patch14").to(device) + # logging.set_verbosity_warning() + # print(f"config: {text_model.config}") + cfg = CLIPTextConfig( + vocab_size=49408, + hidden_size=768, + intermediate_size=3072, + num_hidden_layers=12, + num_attention_heads=12, + max_position_embeddings=77, + hidden_act="quick_gelu", + layer_norm_eps=1e-05, + dropout=0.0, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + model_type="clip_text_model", + projection_dim=768, + torch_dtype="float32", + ) + text_model = CLIPTextModel._from_config(cfg) info = text_model.load_state_dict(converted_text_encoder_checkpoint) print("loading text encoder:", info) diff --git a/library/train_util.py b/library/train_util.py index 30380262c..f13d72529 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -36,7 +36,6 @@ from torchvision import transforms from transformers import CLIPTokenizer import transformers -import diffusers from diffusers.optimization import SchedulerType, TYPE_TO_SCHEDULER_FUNCTION from diffusers import ( StableDiffusionPipeline, @@ -52,6 +51,7 @@ KDPM2DiscreteScheduler, KDPM2AncestralDiscreteScheduler, ) +from library.original_unet import UNet2DConditionModel from huggingface_hub import hf_hub_download import albumentations as albu import numpy as np @@ -2947,11 +2947,26 @@ def _load_target_model(args: argparse.Namespace, weight_dtype, device="cpu"): print( f"model is not found as a file or in Hugging Face, perhaps file name is wrong? / 指定したモデル名のファイル、またはHugging Faceのモデルが見つかりません。ファイル名が誤っているかもしれません: {name_or_path}" ) + raise ex text_encoder = pipe.text_encoder vae = pipe.vae unet = pipe.unet del pipe + # Diffusers U-Net to original U-Net + # TODO *.ckpt/*.safetensorsのv2と同じ形式にここで変換すると良さそう + # print(f"unet config: {unet.config}") + original_unet = UNet2DConditionModel( + unet.config.sample_size, + unet.config.attention_head_dim, + unet.config.cross_attention_dim, + unet.config.use_linear_projection, + unet.config.upcast_attention, + ) + original_unet.load_state_dict(unet.state_dict()) + unet = original_unet + print("U-Net converted to original U-Net") + # VAEを読み込む if args.vae is not None: vae = model_util.load_vae(args.vae, weight_dtype) From 1c09867b3e466cf0632228773e5eab6920426e7d Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 22 Jun 2023 08:38:44 +0900 Subject: [PATCH 024/220] update Diffusers, remove BLIP deps --- requirements.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 390567841..a6bc8de57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,10 @@ accelerate==0.19.0 transformers==4.29.2 -diffusers[torch]==0.16.1 +diffusers[torch]==0.17.1 ftfy==6.1.1 albumentations==1.3.0 opencv-python==4.7.0.68 einops==0.6.0 -diffusers[torch]==0.17.0 pytorch-lightning==1.9.0 bitsandbytes==0.35.0 tensorboard==2.10.1 @@ -17,9 +16,9 @@ toml==0.10.2 voluptuous==0.13.1 huggingface-hub==0.13.3 # for BLIP captioning -requests==2.28.2 -timm==0.6.12 -fairscale==0.4.13 +# requests==2.28.2 +# timm==0.6.12 +# fairscale==0.4.13 # for WD14 captioning # tensorflow==2.10.1 # for kohya_ss library From 5114e8daf14123f07710fd8eed6dd6baead9a572 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 22 Jun 2023 08:46:53 +0900 Subject: [PATCH 025/220] fix training scripts except controlnet not working --- fine_tune.py | 10 +++++++--- library/config_util.py | 3 ++- requirements.txt | 2 +- train_db.py | 2 +- train_network.py | 2 +- train_textual_inversion.py | 2 +- train_textual_inversion_XTI.py | 2 +- 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fine_tune.py b/fine_tune.py index 82e52ddaa..0afacdaf8 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -42,7 +42,7 @@ def train(args): # データセットを準備する if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(False, True, True)) + blueprint_generator = BlueprintGenerator(ConfigSanitizer(False, True, False, True)) if args.dataset_config is not None: print(f"Load dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) @@ -260,7 +260,9 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") accelerator.print(f" num epochs / epoch数: {num_train_epochs}") accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print( + f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + ) accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") @@ -395,7 +397,9 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): current_loss = loss.detach().item() # 平均なのでbatch sizeは関係ないはず if args.logging_dir is not None: logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} - if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy": # tracking d*lr value + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy" + ): # tracking d*lr value logs["lr/d*lr"] = ( lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] ) diff --git a/library/config_util.py b/library/config_util.py index ae17655ca..36c165a5c 100644 --- a/library/config_util.py +++ b/library/config_util.py @@ -584,6 +584,7 @@ def load_user_config(file: str) -> dict: parser = argparse.ArgumentParser() parser.add_argument("--support_dreambooth", action="store_true") parser.add_argument("--support_finetuning", action="store_true") + parser.add_argument("--support_controlnet", action="store_true") parser.add_argument("--support_dropout", action="store_true") parser.add_argument("dataset_config") config_args, remain = parser.parse_known_args() @@ -602,7 +603,7 @@ def load_user_config(file: str) -> dict: print("\n[user_config]") print(user_config) - sanitizer = ConfigSanitizer(config_args.support_dreambooth, config_args.support_finetuning, config_args.support_dropout) + sanitizer = ConfigSanitizer(config_args.support_dreambooth, config_args.support_finetuning, config_args.support_controlnet, config_args.support_dropout) sanitized_user_config = sanitizer.sanitize_user_config(user_config) print("\n[sanitized_user_config]") diff --git a/requirements.txt b/requirements.txt index a6bc8de57..74e06d216 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ altair==4.2.2 easygui==0.98.3 toml==0.10.2 voluptuous==0.13.1 -huggingface-hub==0.13.3 +huggingface-hub==0.14.1 # for BLIP captioning # requests==2.28.2 # timm==0.6.12 diff --git a/train_db.py b/train_db.py index ab094fddc..c8ddab1ee 100644 --- a/train_db.py +++ b/train_db.py @@ -45,7 +45,7 @@ def train(args): # データセットを準備する if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, False, True)) + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, False, False, True)) if args.dataset_config is not None: print(f"Load dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) diff --git a/train_network.py b/train_network.py index 12e52248a..7e930e8a8 100644 --- a/train_network.py +++ b/train_network.py @@ -92,7 +92,7 @@ def train(args): # データセットを準備する if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, True)) + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) if use_user_config: print(f"Loading dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 97f7435a8..bcf0f1964 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -151,7 +151,7 @@ def train(args): # データセットを準備する if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False)) + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, False)) if args.dataset_config is not None: accelerator.print(f"Load dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index 426799d16..3a87ede9f 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -189,7 +189,7 @@ def train(args): print(f"create embeddings for {args.num_vectors_per_token} tokens, for {args.token_string}") # データセットを準備する - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False)) + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, False)) if args.dataset_config is not None: print(f"Load dataset config from {args.dataset_config}") user_config = config_util.load_user_config(args.dataset_config) From 6a86de19275df56c56fa3415ebdfd79109a1b3be Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 24 Jun 2023 00:01:50 +0900 Subject: [PATCH 026/220] add sdxl unet --- library/sdxl_original_unet.py | 1149 +++++++++++++++++++++++++++++++++ 1 file changed, 1149 insertions(+) create mode 100644 library/sdxl_original_unet.py diff --git a/library/sdxl_original_unet.py b/library/sdxl_original_unet.py new file mode 100644 index 000000000..6556b12c5 --- /dev/null +++ b/library/sdxl_original_unet.py @@ -0,0 +1,1149 @@ +# Diffusersのコードをベースとした sd_xl_baseのU-Net +# state dictの形式をSDXLに合わせてある + +""" + target: sgm.modules.diffusionmodules.openaimodel.UNetModel + params: + adm_in_channels: 2816 + num_classes: sequential + use_checkpoint: True + in_channels: 4 + out_channels: 4 + model_channels: 320 + attention_resolutions: [4, 2] + num_res_blocks: 2 + channel_mult: [1, 2, 4] + num_head_channels: 64 + use_spatial_transformer: True + use_linear_in_transformer: True + transformer_depth: [1, 2, 10] # note: the first is unused (due to attn_res starting at 2) 32, 16, 8 --> 64, 32, 16 + context_dim: 2048 + spatial_transformer_attn_type: softmax-xformers + legacy: False +""" + +import math +from types import SimpleNamespace +from typing import Optional +import torch +import torch.utils.checkpoint +from torch import nn +from torch.nn import functional as F +from einops import rearrange + + +IN_CHANNELS: int = 4 +OUT_CHANNELS: int = 4 +ADM_IN_CHANNELS: int = 2816 +CONTEXT_DIM: int = 2048 +MODEL_CHANNELS: int = 320 +TIME_EMBED_DIM = 320 * 4 + + +# region memory effcient attention + +# FlashAttentionを使うCrossAttention +# based on https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/memory_efficient_attention_pytorch/flash_attention.py +# LICENSE MIT https://github.com/lucidrains/memory-efficient-attention-pytorch/blob/main/LICENSE + +# constants + +EPSILON = 1e-6 + +# helper functions + + +def exists(val): + return val is not None + + +def default(val, d): + return val if exists(val) else d + + +# flash attention forwards and backwards + +# https://arxiv.org/abs/2205.14135 + + +class FlashAttentionFunction(torch.autograd.Function): + @staticmethod + @torch.no_grad() + def forward(ctx, q, k, v, mask, causal, q_bucket_size, k_bucket_size): + """Algorithm 2 in the paper""" + + device = q.device + dtype = q.dtype + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + o = torch.zeros_like(q) + all_row_sums = torch.zeros((*q.shape[:-1], 1), dtype=dtype, device=device) + all_row_maxes = torch.full((*q.shape[:-1], 1), max_neg_value, dtype=dtype, device=device) + + scale = q.shape[-1] ** -0.5 + + if not exists(mask): + mask = (None,) * math.ceil(q.shape[-2] / q_bucket_size) + else: + mask = rearrange(mask, "b n -> b 1 1 n") + mask = mask.split(q_bucket_size, dim=-1) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + mask, + all_row_sums.split(q_bucket_size, dim=-2), + all_row_maxes.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, row_mask, row_sums, row_maxes) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale + + if exists(row_mask): + attn_weights.masked_fill_(~row_mask, max_neg_value) + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( + q_start_index - k_start_index + 1 + ) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + block_row_maxes = attn_weights.amax(dim=-1, keepdims=True) + attn_weights -= block_row_maxes + exp_weights = torch.exp(attn_weights) + + if exists(row_mask): + exp_weights.masked_fill_(~row_mask, 0.0) + + block_row_sums = exp_weights.sum(dim=-1, keepdims=True).clamp(min=EPSILON) + + new_row_maxes = torch.maximum(block_row_maxes, row_maxes) + + exp_values = torch.einsum("... i j, ... j d -> ... i d", exp_weights, vc) + + exp_row_max_diff = torch.exp(row_maxes - new_row_maxes) + exp_block_row_max_diff = torch.exp(block_row_maxes - new_row_maxes) + + new_row_sums = exp_row_max_diff * row_sums + exp_block_row_max_diff * block_row_sums + + oc.mul_((row_sums / new_row_sums) * exp_row_max_diff).add_((exp_block_row_max_diff / new_row_sums) * exp_values) + + row_maxes.copy_(new_row_maxes) + row_sums.copy_(new_row_sums) + + ctx.args = (causal, scale, mask, q_bucket_size, k_bucket_size) + ctx.save_for_backward(q, k, v, o, all_row_sums, all_row_maxes) + + return o + + @staticmethod + @torch.no_grad() + def backward(ctx, do): + """Algorithm 4 in the paper""" + + causal, scale, mask, q_bucket_size, k_bucket_size = ctx.args + q, k, v, o, l, m = ctx.saved_tensors + + device = q.device + + max_neg_value = -torch.finfo(q.dtype).max + qk_len_diff = max(k.shape[-2] - q.shape[-2], 0) + + dq = torch.zeros_like(q) + dk = torch.zeros_like(k) + dv = torch.zeros_like(v) + + row_splits = zip( + q.split(q_bucket_size, dim=-2), + o.split(q_bucket_size, dim=-2), + do.split(q_bucket_size, dim=-2), + mask, + l.split(q_bucket_size, dim=-2), + m.split(q_bucket_size, dim=-2), + dq.split(q_bucket_size, dim=-2), + ) + + for ind, (qc, oc, doc, row_mask, lc, mc, dqc) in enumerate(row_splits): + q_start_index = ind * q_bucket_size - qk_len_diff + + col_splits = zip( + k.split(k_bucket_size, dim=-2), + v.split(k_bucket_size, dim=-2), + dk.split(k_bucket_size, dim=-2), + dv.split(k_bucket_size, dim=-2), + ) + + for k_ind, (kc, vc, dkc, dvc) in enumerate(col_splits): + k_start_index = k_ind * k_bucket_size + + attn_weights = torch.einsum("... i d, ... j d -> ... i j", qc, kc) * scale + + if causal and q_start_index < (k_start_index + k_bucket_size - 1): + causal_mask = torch.ones((qc.shape[-2], kc.shape[-2]), dtype=torch.bool, device=device).triu( + q_start_index - k_start_index + 1 + ) + attn_weights.masked_fill_(causal_mask, max_neg_value) + + exp_attn_weights = torch.exp(attn_weights - mc) + + if exists(row_mask): + exp_attn_weights.masked_fill_(~row_mask, 0.0) + + p = exp_attn_weights / lc + + dv_chunk = torch.einsum("... i j, ... i d -> ... j d", p, doc) + dp = torch.einsum("... i d, ... j d -> ... i j", doc, vc) + + D = (doc * oc).sum(dim=-1, keepdims=True) + ds = p * scale * (dp - D) + + dq_chunk = torch.einsum("... i j, ... j d -> ... i d", ds, kc) + dk_chunk = torch.einsum("... i j, ... i d -> ... j d", ds, qc) + + dqc.add_(dq_chunk) + dkc.add_(dk_chunk) + dvc.add_(dv_chunk) + + return dq, dk, dv, None, None, None, None + + +# endregion + + +def get_parameter_dtype(parameter: torch.nn.Module): + return next(parameter.parameters()).dtype + + +def get_parameter_device(parameter: torch.nn.Module): + return next(parameter.parameters()).device + + +def get_timestep_embedding( + timesteps: torch.Tensor, + embedding_dim: int, + downscale_freq_shift: float = 1, + scale: float = 1, + max_period: int = 10000, +): + """ + This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings. + + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param embedding_dim: the dimension of the output. :param max_period: controls the minimum frequency of the + embeddings. :return: an [N x dim] Tensor of positional embeddings. + """ + assert len(timesteps.shape) == 1, "Timesteps should be a 1d-array" + + half_dim = embedding_dim // 2 + exponent = -math.log(max_period) * torch.arange(start=0, end=half_dim, dtype=torch.float32, device=timesteps.device) + exponent = exponent / (half_dim - downscale_freq_shift) + + emb = torch.exp(exponent) + emb = timesteps[:, None].float() * emb[None, :] + + # scale embeddings + emb = scale * emb + + # concat sine and cosine embeddings: flipped from Diffusers original ver because always flip_sin_to_cos=True + emb = torch.cat([torch.cos(emb), torch.sin(emb)], dim=-1) + + # zero pad + if embedding_dim % 2 == 1: + emb = torch.nn.functional.pad(emb, (0, 1, 0, 0)) + return emb + + +class GroupNorm32(nn.GroupNorm): + def forward(self, x): + if self.weight.dtype != torch.float32: + return super().forward(x) + return super().forward(x.float()).type(x.dtype) + + +class ResnetBlock2D(nn.Module): + def __init__( + self, + in_channels, + out_channels, + ): + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + + self.in_layers = nn.Sequential( + GroupNorm32(32, in_channels), + nn.SiLU(), + nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1), + ) + + self.emb_layers = nn.Sequential(nn.SiLU(), nn.Linear(TIME_EMBED_DIM, out_channels)) + + self.out_layers = nn.Sequential( + GroupNorm32(32, out_channels), + nn.SiLU(), + nn.Identity(), # to make state_dict compatible with original model + nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1), + ) + + if in_channels != out_channels: + self.skip_connection = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0) + else: + self.skip_connection = nn.Identity() + + self.gradient_checkpointing = False + + def forward_body(self, x, emb): + h = self.in_layers(x) + emb_out = self.emb_layers(emb).type(h.dtype) + h = h + emb_out[:, :, None, None] + h = self.out_layers(h) + x = self.skip_connection(x) + return x + h + + def forward(self, x, emb): + if self.training and self.gradient_checkpointing: + # print("ResnetBlock2D: gradient_checkpointing") + + def create_custom_forward(func): + def custom_forward(*inputs): + return func(*inputs) + + return custom_forward + + x = torch.utils.checkpoint.checkpoint(create_custom_forward(self.forward_body), x, emb) + else: + x = self.forward_body(x, emb) + + return x + + +class Downsample2D(nn.Module): + def __init__(self, channels, out_channels): + super().__init__() + + self.channels = channels + self.out_channels = out_channels + + self.op = nn.Conv2d(self.channels, self.out_channels, 3, stride=2, padding=1) + + self.gradient_checkpointing = False + + def forward_body(self, hidden_states): + assert hidden_states.shape[1] == self.channels + hidden_states = self.op(hidden_states) + + return hidden_states + + def forward(self, hidden_states): + if self.training and self.gradient_checkpointing: + # print("Downsample2D: gradient_checkpointing") + + def create_custom_forward(func): + def custom_forward(*inputs): + return func(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(self.forward_body), hidden_states) + else: + hidden_states = self.forward_body(hidden_states) + + return hidden_states + + +class CrossAttention(nn.Module): + def __init__( + self, + query_dim: int, + cross_attention_dim: Optional[int] = None, + heads: int = 8, + dim_head: int = 64, + upcast_attention: bool = False, + ): + super().__init__() + inner_dim = dim_head * heads + cross_attention_dim = cross_attention_dim if cross_attention_dim is not None else query_dim + self.upcast_attention = upcast_attention + + self.scale = dim_head**-0.5 + self.heads = heads + + self.to_q = nn.Linear(query_dim, inner_dim, bias=False) + self.to_k = nn.Linear(cross_attention_dim, inner_dim, bias=False) + self.to_v = nn.Linear(cross_attention_dim, inner_dim, bias=False) + + self.to_out = nn.ModuleList([]) + self.to_out.append(nn.Linear(inner_dim, query_dim)) + # no dropout here + + self.use_memory_efficient_attention_xformers = False + self.use_memory_efficient_attention_mem_eff = False + self.use_sdpa = False + + def set_use_memory_efficient_attention(self, xformers, mem_eff): + self.use_memory_efficient_attention_xformers = xformers + self.use_memory_efficient_attention_mem_eff = mem_eff + + def set_use_sdpa(self, sdpa): + self.use_sdpa = sdpa + + def reshape_heads_to_batch_dim(self, tensor): + batch_size, seq_len, dim = tensor.shape + head_size = self.heads + tensor = tensor.reshape(batch_size, seq_len, head_size, dim // head_size) + tensor = tensor.permute(0, 2, 1, 3).reshape(batch_size * head_size, seq_len, dim // head_size) + return tensor + + def reshape_batch_dim_to_heads(self, tensor): + batch_size, seq_len, dim = tensor.shape + head_size = self.heads + tensor = tensor.reshape(batch_size // head_size, head_size, seq_len, dim) + tensor = tensor.permute(0, 2, 1, 3).reshape(batch_size // head_size, seq_len, dim * head_size) + return tensor + + def forward(self, hidden_states, context=None, mask=None): + if self.use_memory_efficient_attention_xformers: + return self.forward_memory_efficient_xformers(hidden_states, context, mask) + if self.use_memory_efficient_attention_mem_eff: + return self.forward_memory_efficient_mem_eff(hidden_states, context, mask) + if self.use_sdpa: + return self.forward_sdpa(hidden_states, context, mask) + + query = self.to_q(hidden_states) + context = context if context is not None else hidden_states + key = self.to_k(context) + value = self.to_v(context) + + query = self.reshape_heads_to_batch_dim(query) + key = self.reshape_heads_to_batch_dim(key) + value = self.reshape_heads_to_batch_dim(value) + + hidden_states = self._attention(query, key, value) + + # linear proj + hidden_states = self.to_out[0](hidden_states) + # hidden_states = self.to_out[1](hidden_states) # no dropout + return hidden_states + + def _attention(self, query, key, value): + if self.upcast_attention: + query = query.float() + key = key.float() + + attention_scores = torch.baddbmm( + torch.empty(query.shape[0], query.shape[1], key.shape[1], dtype=query.dtype, device=query.device), + query, + key.transpose(-1, -2), + beta=0, + alpha=self.scale, + ) + attention_probs = attention_scores.softmax(dim=-1) + + # cast back to the original dtype + attention_probs = attention_probs.to(value.dtype) + + # compute attention output + hidden_states = torch.bmm(attention_probs, value) + + # reshape hidden_states + hidden_states = self.reshape_batch_dim_to_heads(hidden_states) + return hidden_states + + # TODO support Hypernetworks + def forward_memory_efficient_xformers(self, x, context=None, mask=None): + import xformers.ops + + h = self.heads + q_in = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k_in = self.to_k(context) + v_in = self.to_v(context) + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b n h d", h=h), (q_in, k_in, v_in)) + del q_in, k_in, v_in + + q = q.contiguous() + k = k.contiguous() + v = v.contiguous() + out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None) # 最適なのを選んでくれる + del q, k, v + + out = rearrange(out, "b n h d -> b n (h d)", h=h) + + out = self.to_out[0](out) + return out + + def forward_memory_efficient_mem_eff(self, x, context=None, mask=None): + flash_func = FlashAttentionFunction + + q_bucket_size = 512 + k_bucket_size = 1024 + + h = self.heads + q = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k = self.to_k(context) + v = self.to_v(context) + del context, x + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q, k, v)) + + out = flash_func.apply(q, k, v, mask, False, q_bucket_size, k_bucket_size) + + out = rearrange(out, "b h n d -> b n (h d)") + + out = self.to_out[0](out) + return out + + def forward_sdpa(self, x, context=None, mask=None): + h = self.heads + q_in = self.to_q(x) + context = context if context is not None else x + context = context.to(x.dtype) + k_in = self.to_k(context) + v_in = self.to_v(context) + + q, k, v = map(lambda t: rearrange(t, "b n (h d) -> b h n d", h=h), (q_in, k_in, v_in)) + del q_in, k_in, v_in + + out = F.scaled_dot_product_attention(q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False) + + out = rearrange(out, "b h n d -> b n (h d)", h=h) + + out = self.to_out[0](out) + return out + + +# feedforward +class GEGLU(nn.Module): + r""" + A variant of the gated linear unit activation function from https://arxiv.org/abs/2002.05202. + + Parameters: + dim_in (`int`): The number of channels in the input. + dim_out (`int`): The number of channels in the output. + """ + + def __init__(self, dim_in: int, dim_out: int): + super().__init__() + self.proj = nn.Linear(dim_in, dim_out * 2) + + def gelu(self, gate): + if gate.device.type != "mps": + return F.gelu(gate) + # mps: gelu is not implemented for float16 + return F.gelu(gate.to(dtype=torch.float32)).to(dtype=gate.dtype) + + def forward(self, hidden_states): + hidden_states, gate = self.proj(hidden_states).chunk(2, dim=-1) + return hidden_states * self.gelu(gate) + + +class FeedForward(nn.Module): + def __init__( + self, + dim: int, + ): + super().__init__() + inner_dim = int(dim * 4) # mult is always 4 + + self.net = nn.ModuleList([]) + # project in + self.net.append(GEGLU(dim, inner_dim)) + # project dropout + self.net.append(nn.Identity()) # nn.Dropout(0)) # dummy for dropout with 0 + # project out + self.net.append(nn.Linear(inner_dim, dim)) + + def forward(self, hidden_states): + for module in self.net: + hidden_states = module(hidden_states) + return hidden_states + + +class BasicTransformerBlock(nn.Module): + def __init__( + self, dim: int, num_attention_heads: int, attention_head_dim: int, cross_attention_dim: int, upcast_attention: bool = False + ): + super().__init__() + + self.gradient_checkpointing = False + + # 1. Self-Attn + self.attn1 = CrossAttention( + query_dim=dim, + cross_attention_dim=None, + heads=num_attention_heads, + dim_head=attention_head_dim, + upcast_attention=upcast_attention, + ) + self.ff = FeedForward(dim) + + # 2. Cross-Attn + self.attn2 = CrossAttention( + query_dim=dim, + cross_attention_dim=cross_attention_dim, + heads=num_attention_heads, + dim_head=attention_head_dim, + upcast_attention=upcast_attention, + ) + + self.norm1 = nn.LayerNorm(dim) + self.norm2 = nn.LayerNorm(dim) + + # 3. Feed-forward + self.norm3 = nn.LayerNorm(dim) + + def set_use_memory_efficient_attention(self, xformers: bool, mem_eff: bool): + self.attn1.set_use_memory_efficient_attention(xformers, mem_eff) + self.attn2.set_use_memory_efficient_attention(xformers, mem_eff) + + def set_use_sdpa(self, sdpa: bool): + self.attn1.set_use_sdpa(sdpa) + self.attn2.set_use_sdpa(sdpa) + + def forward_body(self, hidden_states, context=None, timestep=None): + # 1. Self-Attention + norm_hidden_states = self.norm1(hidden_states) + + hidden_states = self.attn1(norm_hidden_states) + hidden_states + + # 2. Cross-Attention + norm_hidden_states = self.norm2(hidden_states) + hidden_states = self.attn2(norm_hidden_states, context=context) + hidden_states + + # 3. Feed-forward + hidden_states = self.ff(self.norm3(hidden_states)) + hidden_states + + return hidden_states + + def forward(self, hidden_states, context=None, timestep=None): + if self.training and self.gradient_checkpointing: + # print("BasicTransformerBlock: checkpointing") + + def create_custom_forward(func): + def custom_forward(*inputs): + return func(*inputs) + + return custom_forward + + output = torch.utils.checkpoint.checkpoint(create_custom_forward(self.forward_body), hidden_states, context, timestep) + else: + output = self.forward_body(hidden_states, context, timestep) + + return output + + +class Transformer2DModel(nn.Module): + def __init__( + self, + num_attention_heads: int = 16, + attention_head_dim: int = 88, + in_channels: Optional[int] = None, + cross_attention_dim: Optional[int] = None, + use_linear_projection: bool = False, + upcast_attention: bool = False, + num_transformer_layers: int = 1, + ): + super().__init__() + self.in_channels = in_channels + self.num_attention_heads = num_attention_heads + self.attention_head_dim = attention_head_dim + inner_dim = num_attention_heads * attention_head_dim + self.use_linear_projection = use_linear_projection + + self.norm = torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True) + # self.norm = GroupNorm32(32, in_channels, eps=1e-6, affine=True) + + if use_linear_projection: + self.proj_in = nn.Linear(in_channels, inner_dim) + else: + self.proj_in = nn.Conv2d(in_channels, inner_dim, kernel_size=1, stride=1, padding=0) + + blocks = [] + for _ in range(num_transformer_layers): + blocks.append( + BasicTransformerBlock( + inner_dim, + num_attention_heads, + attention_head_dim, + cross_attention_dim=cross_attention_dim, + upcast_attention=upcast_attention, + ) + ) + + self.transformer_blocks = nn.ModuleList(blocks) + + if use_linear_projection: + self.proj_out = nn.Linear(in_channels, inner_dim) + else: + self.proj_out = nn.Conv2d(inner_dim, in_channels, kernel_size=1, stride=1, padding=0) + + self.gradient_checkpointing = False + + def set_use_memory_efficient_attention(self, xformers, mem_eff): + for transformer in self.transformer_blocks: + transformer.set_use_memory_efficient_attention(xformers, mem_eff) + + def set_use_sdpa(self, sdpa): + for transformer in self.transformer_blocks: + transformer.set_use_sdpa(sdpa) + + def forward(self, hidden_states, encoder_hidden_states=None, timestep=None): + # 1. Input + batch, _, height, weight = hidden_states.shape + residual = hidden_states + + hidden_states = self.norm(hidden_states) + if not self.use_linear_projection: + hidden_states = self.proj_in(hidden_states) + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * weight, inner_dim) + else: + inner_dim = hidden_states.shape[1] + hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * weight, inner_dim) + hidden_states = self.proj_in(hidden_states) + + # 2. Blocks + for block in self.transformer_blocks: + hidden_states = block(hidden_states, context=encoder_hidden_states, timestep=timestep) + + # 3. Output + if not self.use_linear_projection: + hidden_states = hidden_states.reshape(batch, height, weight, inner_dim).permute(0, 3, 1, 2).contiguous() + hidden_states = self.proj_out(hidden_states) + else: + hidden_states = self.proj_out(hidden_states) + hidden_states = hidden_states.reshape(batch, height, weight, inner_dim).permute(0, 3, 1, 2).contiguous() + + output = hidden_states + residual + + return output + + def forward_xxx(self, hidden_states, encoder_hidden_states=None, timestep=None): + if self.training and self.gradient_checkpointing: + # print("Transformer2DModel: Using gradient checkpointing") + + def create_custom_forward(func): + def custom_forward(*inputs): + return func(*inputs) + + return custom_forward + + output = torch.utils.checkpoint.checkpoint( + create_custom_forward(self.forward_body), hidden_states, encoder_hidden_states, timestep + ) + else: + output = self.forward_body(hidden_states, encoder_hidden_states, timestep) + + return output + + +class Upsample2D(nn.Module): + def __init__(self, channels, out_channels): + super().__init__() + self.channels = channels + self.out_channels = out_channels + self.conv = nn.Conv2d(self.channels, self.out_channels, 3, padding=1) + + self.gradient_checkpointing = False + + def forward_body(self, hidden_states, output_size=None): + assert hidden_states.shape[1] == self.channels + + # Cast to float32 to as 'upsample_nearest2d_out_frame' op does not support bfloat16 + # TODO(Suraj): Remove this cast once the issue is fixed in PyTorch + # https://github.com/pytorch/pytorch/issues/86679 + dtype = hidden_states.dtype + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(torch.float32) + + # upsample_nearest_nhwc fails with large batch sizes. see https://github.com/huggingface/diffusers/issues/984 + if hidden_states.shape[0] >= 64: + hidden_states = hidden_states.contiguous() + + # if `output_size` is passed we force the interpolation output size and do not make use of `scale_factor=2` + if output_size is None: + hidden_states = F.interpolate(hidden_states, scale_factor=2.0, mode="nearest") + else: + hidden_states = F.interpolate(hidden_states, size=output_size, mode="nearest") + + # If the input is bfloat16, we cast back to bfloat16 + if dtype == torch.bfloat16: + hidden_states = hidden_states.to(dtype) + + hidden_states = self.conv(hidden_states) + + return hidden_states + + def forward(self, hidden_states, output_size=None): + if self.training and self.gradient_checkpointing: + # print("Upsample2D: gradient_checkpointing") + + def create_custom_forward(func): + def custom_forward(*inputs): + return func(*inputs) + + return custom_forward + + hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(self.forward_body), hidden_states, output_size) + else: + hidden_states = self.forward_body(hidden_states, output_size) + + return hidden_states + + +class SdxlUNet2DConditionModel(nn.Module): + _supports_gradient_checkpointing = True + + def __init__( + self, + **kwargs, + ): + super().__init__() + + self.in_channels = IN_CHANNELS + self.out_channels = OUT_CHANNELS + self.model_channels = MODEL_CHANNELS + self.time_embed_dim = TIME_EMBED_DIM + self.adm_in_channels = ADM_IN_CHANNELS + + self.gradient_checkpointing = False + # self.sample_size = sample_size + + # time embedding + self.time_embed = nn.Sequential( + nn.Linear(self.model_channels, self.time_embed_dim), + nn.SiLU(), + nn.Linear(self.time_embed_dim, self.time_embed_dim), + ) + + # label embedding + self.label_emb = nn.Sequential( + nn.Sequential( + nn.Linear(self.adm_in_channels, self.time_embed_dim), + nn.SiLU(), + nn.Linear(self.time_embed_dim, self.time_embed_dim), + ) + ) + + # input + self.input_blocks = nn.ModuleList( + [ + nn.Sequential( + nn.Conv2d(self.in_channels, self.model_channels, kernel_size=3, padding=(1, 1)), + ) + ] + ) + + # level 0 + for i in range(2): + layers = [ + ResnetBlock2D( + in_channels=1 * self.model_channels, + out_channels=1 * self.model_channels, + ), + ] + self.input_blocks.append(nn.ModuleList(layers)) + + self.input_blocks.append( + nn.Sequential( + Downsample2D( + channels=1 * self.model_channels, + out_channels=1 * self.model_channels, + ), + ) + ) + + # level 1 + for i in range(2): + layers = [ + ResnetBlock2D( + in_channels=(1 if i == 0 else 2) * self.model_channels, + out_channels=2 * self.model_channels, + ), + Transformer2DModel( + num_attention_heads=2 * self.model_channels // 64, + attention_head_dim=64, + in_channels=2 * self.model_channels, + num_transformer_layers=2, + use_linear_projection=True, + cross_attention_dim=2048, + ), + ] + self.input_blocks.append(nn.ModuleList(layers)) + + self.input_blocks.append( + nn.Sequential( + Downsample2D( + channels=2 * self.model_channels, + out_channels=2 * self.model_channels, + ), + ) + ) + + # level 2 + for i in range(2): + layers = [ + ResnetBlock2D( + in_channels=(2 if i == 0 else 4) * self.model_channels, + out_channels=4 * self.model_channels, + ), + Transformer2DModel( + num_attention_heads=4 * self.model_channels // 64, + attention_head_dim=64, + in_channels=4 * self.model_channels, + num_transformer_layers=10, + use_linear_projection=True, + cross_attention_dim=2048, + ), + ] + self.input_blocks.append(nn.ModuleList(layers)) + + # mid + self.middle_block = nn.ModuleList( + [ + ResnetBlock2D( + in_channels=4 * self.model_channels, + out_channels=4 * self.model_channels, + ), + Transformer2DModel( + num_attention_heads=4 * self.model_channels // 64, + attention_head_dim=64, + in_channels=4 * self.model_channels, + num_transformer_layers=10, + use_linear_projection=True, + cross_attention_dim=2048, + ), + ResnetBlock2D( + in_channels=4 * self.model_channels, + out_channels=4 * self.model_channels, + ), + ] + ) + + # output + self.output_blocks = nn.ModuleList([]) + + # level 2 + for i in range(3): + layers = [ + ResnetBlock2D( + in_channels=4 * self.model_channels + (4 if i <= 1 else 2) * self.model_channels, + out_channels=4 * self.model_channels, + ), + Transformer2DModel( + num_attention_heads=4 * self.model_channels // 64, + attention_head_dim=64, + in_channels=4 * self.model_channels, + num_transformer_layers=10, + use_linear_projection=True, + cross_attention_dim=2048, + ), + ] + if i == 2: + layers.append( + Upsample2D( + channels=4 * self.model_channels, + out_channels=4 * self.model_channels, + ) + ) + + self.output_blocks.append(nn.ModuleList(layers)) + + # level 1 + for i in range(3): + layers = [ + ResnetBlock2D( + in_channels=2 * self.model_channels + (4 if i == 0 else (2 if i == 1 else 1)) * self.model_channels, + out_channels=2 * self.model_channels, + ), + Transformer2DModel( + num_attention_heads=2 * self.model_channels // 64, + attention_head_dim=64, + in_channels=2 * self.model_channels, + num_transformer_layers=2, + use_linear_projection=True, + cross_attention_dim=2048, + ), + ] + if i == 2: + layers.append( + Upsample2D( + channels=2 * self.model_channels, + out_channels=2 * self.model_channels, + ) + ) + + self.output_blocks.append(nn.ModuleList(layers)) + + # level 0 + for i in range(3): + layers = [ + ResnetBlock2D( + in_channels=1 * self.model_channels + (2 if i == 0 else 1) * self.model_channels, + out_channels=1 * self.model_channels, + ), + ] + + self.output_blocks.append(nn.ModuleList(layers)) + + # output + self.out = nn.ModuleList( + [GroupNorm32(32, self.model_channels), nn.SiLU(), nn.Conv2d(self.model_channels, self.out_channels, 3, padding=1)] + ) + + # region diffusers compatibility + def prepare_config(self): + self.config = SimpleNamespace() + + @property + def dtype(self) -> torch.dtype: + # `torch.dtype`: The dtype of the module (assuming that all the module parameters have the same dtype). + return get_parameter_dtype(self) + + @property + def device(self) -> torch.device: + # `torch.device`: The device on which the module is (assuming that all the module parameters are on the same device). + return get_parameter_device(self) + + def set_attention_slice(self, slice_size): + raise NotImplementedError("Attention slicing is not supported for this model.") + + def is_gradient_checkpointing(self) -> bool: + return any(hasattr(m, "gradient_checkpointing") and m.gradient_checkpointing for m in self.modules()) + + def enable_gradient_checkpointing(self): + self.gradient_checkpointing = True + self.set_gradient_checkpointing(value=True) + + def disable_gradient_checkpointing(self): + self.gradient_checkpointing = False + self.set_gradient_checkpointing(value=False) + + def set_use_memory_efficient_attention(self, xformers: bool, mem_eff: bool) -> None: + blocks = self.input_blocks + [self.middle_block] + self.output_blocks + for block in blocks: + for module in block: + if hasattr(module, "set_use_memory_efficient_attention"): + # print(module.__class__.__name__) + module.set_use_memory_efficient_attention(xformers, mem_eff) + + def set_use_sdpa(self, sdpa: bool) -> None: + blocks = self.input_blocks + [self.middle_block] + self.output_blocks + for block in blocks: + for module in block: + if hasattr(module, "set_use_sdpa"): + module.set_use_sdpa(sdpa) + + def set_gradient_checkpointing(self, value=False): + blocks = self.input_blocks + [self.middle_block] + self.output_blocks + for block in blocks: + for module in block.modules(): + if hasattr(module, "gradient_checkpointing"): + # print(module.__class__.__name__, module.gradient_checkpointing, "->", value) + module.gradient_checkpointing = value + + # endregion + + def forward(self, x, timesteps=None, context=None, y=None, **kwargs): + # broadcast timesteps to batch dimension + timesteps = timesteps.expand(x.shape[0]) + + hs = [] + t_emb = get_timestep_embedding(timesteps, self.model_channels) # , repeat_only=False) + t_emb = t_emb.to(x.dtype) + emb = self.time_embed(t_emb) + + assert y.shape[0] == x.shape[0] + assert x.dtype == y.dtype + # assert x.dtype == self.dtype + emb = emb + self.label_emb(y) + + def call_module(module, h, emb, context): + x = h + for layer in module: + # print(layer.__class__.__name__, x.dtype, emb.dtype, context.dtype if context is not None else None) + if isinstance(layer, ResnetBlock2D): + x = layer(x, emb) + elif isinstance(layer, Transformer2DModel): + x = layer(x, context) + else: + x = layer(x) + return x + + # h = x.type(self.dtype) + h = x + for module in self.input_blocks: + h = call_module(module, h, emb, context) + hs.append(h) + + h = call_module(self.middle_block, h, emb, context) + + for module in self.output_blocks: + h = torch.cat([h, hs.pop()], dim=1) + h = call_module(module, h, emb, context) + + h = h.type(x.dtype) + h = call_module(self.out, h, emb, context) + + return h + + +if __name__ == "__main__": + print("create unet") + unet = SdxlUNet2DConditionModel() + + unet.to("cuda") + unet.set_use_memory_efficient_attention(True, False) + unet.set_gradient_checkpointing(True) + unet.train() + + # 使用メモリ量確認用の疑似学習ループ + print("preparing optimizer") + + import bitsandbytes + import transformers + + # optimizer = bitsandbytes.adam.Adam8bit(unet.parameters(), lr=1e-3) # not working + # optimizer = bitsandbytes.optim.RMSprop8bit(unet.parameters(), lr=1e-3) # working at 23.5 GB with torch2 + # optimizer=bitsandbytes.optim.Adagrad8bit(unet.parameters(), lr=1e-3) # working at 23.5 GB with torch2 + # optimizer = torch.optim.SGD(unet.parameters(), lr=1e-3, nesterov=True, momentum=0.9) # not working + optimizer = transformers.optimization.Adafactor(unet.parameters(), relative_step=True) # working at 22.2GB with torch2 + + scaler = torch.cuda.amp.GradScaler(enabled=True) + + print("start training") + steps = 10 + batch_size = 1 + for step in range(steps): + print(f"step {step}") + + x = torch.randn(batch_size, 4, 128, 128).cuda() # 512x512 + t = torch.randint(low=0, high=10, size=(batch_size,), device="cuda") + ctx = torch.randn(batch_size, 77, 2048).cuda() + y = torch.randn(batch_size, ADM_IN_CHANNELS).cuda() + + with torch.cuda.amp.autocast(enabled=True): + output = unet(x, t, ctx, y) + target = torch.randn_like(output) + loss = torch.nn.functional.mse_loss(output, target) + + scaler.scale(loss).backward() + scaler.step(optimizer) + scaler.update() + optimizer.zero_grad(set_to_none=True) From 11e8c7d8ffa322ea8af50a4822afcbb4b094cccb Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 24 Jun 2023 09:35:33 +0900 Subject: [PATCH 027/220] fix to work controlnet training --- library/original_unet.py | 13 +++ train_controlnet.py | 215 +++++++++++++++++++-------------------- 2 files changed, 118 insertions(+), 110 deletions(-) diff --git a/library/original_unet.py b/library/original_unet.py index 94d112902..c0028ddc2 100644 --- a/library/original_unet.py +++ b/library/original_unet.py @@ -1468,6 +1468,8 @@ def forward( encoder_hidden_states: torch.Tensor, class_labels: Optional[torch.Tensor] = None, return_dict: bool = True, + down_block_additional_residuals: Optional[Tuple[torch.Tensor]] = None, + mid_block_additional_residual: Optional[torch.Tensor] = None, ) -> Union[Dict, Tuple]: r""" Args: @@ -1533,9 +1535,20 @@ def forward( down_block_res_samples += res_samples + # skip connectionにControlNetの出力を追加する + if down_block_additional_residuals is not None: + down_block_res_samples = list(down_block_res_samples) + for i in range(len(down_block_res_samples)): + down_block_res_samples[i] += down_block_additional_residuals[i] + down_block_res_samples = tuple(down_block_res_samples) + # 4. mid sample = self.mid_block(sample, emb, encoder_hidden_states=encoder_hidden_states) + # ControlNetの出力を追加する + if mid_block_additional_residual is not None: + sample += mid_block_additional_residual + # 5. up for i, upsample_block in enumerate(self.up_blocks): is_final_block = i == len(self.up_blocks) - 1 diff --git a/train_controlnet.py b/train_controlnet.py index 6e4e5bb82..39ac43e96 100644 --- a/train_controlnet.py +++ b/train_controlnet.py @@ -6,6 +6,7 @@ import random import time from multiprocessing import Value +from types import SimpleNamespace from tqdm import tqdm import torch @@ -39,17 +40,14 @@ def generate_step_logs(args: argparse.Namespace, current_loss, avr_loss, lr_sche } if args.optimizer_type.lower().startswith("DAdapt".lower()): - logs["lr/d*lr"] = ( - lr_scheduler.optimizers[-1].param_groups[0]["d"] - * lr_scheduler.optimizers[-1].param_groups[0]["lr"] - ) + logs["lr/d*lr"] = lr_scheduler.optimizers[-1].param_groups[0]["d"] * lr_scheduler.optimizers[-1].param_groups[0]["lr"] return logs def train(args): - session_id = random.randint(0, 2**32) - training_started_at = time.time() + # session_id = random.randint(0, 2**32) + # training_started_at = time.time() train_util.verify_training_args(args) train_util.prepare_dataset_args(args, True) @@ -88,15 +86,11 @@ def train(args): } blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer) - train_dataset_group = config_util.generate_dataset_group_by_blueprint( - blueprint.dataset_group - ) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) current_epoch = Value("i", 0) current_step = Value("i", 0) - ds_for_collater = ( - train_dataset_group if args.max_data_loader_n_workers == 0 else None - ) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) if args.debug_dataset: @@ -115,7 +109,7 @@ def train(args): # acceleratorを準備する print("prepare accelerator") - accelerator, unwrap_model = train_util.prepare_accelerator(args) + accelerator = train_util.prepare_accelerator(args) is_main_process = accelerator.is_main_process # mixed precisionに対応した型を用意しておき適宜castする @@ -126,6 +120,69 @@ def train(args): args, weight_dtype, accelerator, unet_use_linear_projection_in_v2=True ) + # DiffusersのControlNetが使用するデータを準備する + if args.v2: + unet.config = { + "act_fn": "silu", + "attention_head_dim": [5, 10, 20, 20], + "block_out_channels": [320, 640, 1280, 1280], + "center_input_sample": False, + "cross_attention_dim": 1024, + "down_block_types": ["CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "DownBlock2D"], + "downsample_padding": 1, + "dual_cross_attention": False, + "flip_sin_to_cos": True, + "freq_shift": 0, + "in_channels": 4, + "layers_per_block": 2, + "mid_block_scale_factor": 1, + "norm_eps": 1e-05, + "norm_num_groups": 32, + "num_class_embeds": None, + "only_cross_attention": False, + "out_channels": 4, + "sample_size": 96, + "up_block_types": ["UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"], + "use_linear_projection": True, + "upcast_attention": True, + "only_cross_attention": False, + "downsample_padding": 1, + "use_linear_projection": True, + "class_embed_type": None, + "num_class_embeds": None, + "resnet_time_scale_shift": "default", + "projection_class_embeddings_input_dim": None, + } + else: + unet.config = { + "act_fn": "silu", + "attention_head_dim": 8, + "block_out_channels": [320, 640, 1280, 1280], + "center_input_sample": False, + "cross_attention_dim": 768, + "down_block_types": ["CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "DownBlock2D"], + "downsample_padding": 1, + "flip_sin_to_cos": True, + "freq_shift": 0, + "in_channels": 4, + "layers_per_block": 2, + "mid_block_scale_factor": 1, + "norm_eps": 1e-05, + "norm_num_groups": 32, + "out_channels": 4, + "sample_size": 64, + "up_block_types": ["UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"], + "only_cross_attention": False, + "downsample_padding": 1, + "use_linear_projection": False, + "class_embed_type": None, + "num_class_embeds": None, + "upcast_attention": False, + "resnet_time_scale_shift": "default", + "projection_class_embeddings_input_dim": None, + } + unet.config = SimpleNamespace(**unet.config) + controlnet = ControlNetModel.from_unet(unet) if args.controlnet_model_name_or_path: @@ -140,9 +197,8 @@ def train(args): elif os.path.isdir(filename): controlnet = ControlNetModel.from_pretrained(filename) - # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers) + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) # 学習を準備する if cache_latents: @@ -171,15 +227,11 @@ def train(args): trainable_params = controlnet.parameters() - _, _, optimizer = train_util.get_optimizer( - args, trainable_params - ) + _, _, optimizer = train_util.get_optimizer(args, trainable_params) # dataloaderを準備する # DataLoaderのプロセス数:0はメインプロセスになる - n_workers = min( - args.max_data_loader_n_workers, os.cpu_count() - 1 - ) # cpu_count-1 ただし最大で指定された数まで + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで train_dataloader = torch.utils.data.DataLoader( train_dataset_group, @@ -193,21 +245,15 @@ def train(args): # 学習ステップ数を計算する if args.max_train_epochs is not None: args.max_train_steps = args.max_train_epochs * math.ceil( - len(train_dataloader) - / accelerator.num_processes - / args.gradient_accumulation_steps - ) - accelerator.print( - f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" + len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps ) + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") # データセット側にも学習ステップを送信 train_dataset_group.set_max_train_steps(args.max_train_steps) # lr schedulerを用意する - lr_scheduler = train_util.get_scheduler_fix( - args, optimizer, accelerator.num_processes - ) + lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする if args.full_fp16: @@ -245,31 +291,21 @@ def train(args): train_util.resume_from_local_or_hf_if_specified(accelerator, args) # epoch数を計算する - num_update_steps_per_epoch = math.ceil( - len(train_dataloader) / args.gradient_accumulation_steps - ) + num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): - args.save_every_n_epochs = ( - math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 - ) + args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 # 学習する # TODO: find a way to handle total batch size when there are multiple datasets accelerator.print("running training / 学習開始") - accelerator.print( - f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}" - ) + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") accelerator.print(f" num epochs / epoch数: {num_train_epochs}") - accelerator.print( - f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" - ) + accelerator.print(f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}") # print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - accelerator.print( - f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}" - ) + accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") progress_bar = tqdm( @@ -288,11 +324,7 @@ def train(args): clip_sample=False, ) if accelerator.is_main_process: - accelerator.init_trackers( - "controlnet_train" - if args.log_tracker_name is None - else args.log_tracker_name - ) + accelerator.init_trackers("controlnet_train" if args.log_tracker_name is None else args.log_tracker_name) loss_list = [] loss_total = 0.0 @@ -321,9 +353,7 @@ def save_model(ckpt_name, model, force_sync_upload=False): torch.save(state_dict, ckpt_file) if args.huggingface_repo_id is not None: - huggingface_util.upload( - args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload - ) + huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) def remove_model(old_ckpt_name): old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) @@ -345,23 +375,17 @@ def remove_model(old_ckpt_name): latents = batch["latents"].to(accelerator.device) else: # latentに変換 - latents = vae.encode( - batch["images"].to(dtype=weight_dtype) - ).latent_dist.sample() + latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() latents = latents * 0.18215 b_size = latents.shape[0] input_ids = batch["input_ids"].to(accelerator.device) - encoder_hidden_states = train_util.get_hidden_states( - args, input_ids, tokenizer, text_encoder, weight_dtype - ) + encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizer, text_encoder, weight_dtype) # Sample noise that we'll add to the latents noise = torch.randn_like(latents, device=latents.device) if args.noise_offset: - noise = apply_noise_offset( - latents, noise, args.noise_offset, args.adaptive_noise_scale - ) + noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) elif args.multires_noise_iterations: noise = pyramid_noise_like( noise, @@ -398,13 +422,8 @@ def remove_model(old_ckpt_name): noisy_latents, timesteps, encoder_hidden_states, - down_block_additional_residuals=[ - sample.to(dtype=weight_dtype) - for sample in down_block_res_samples - ], - mid_block_additional_residual=mid_block_res_sample.to( - dtype=weight_dtype - ), + down_block_additional_residuals=[sample.to(dtype=weight_dtype) for sample in down_block_res_samples], + mid_block_additional_residual=mid_block_res_sample.to(dtype=weight_dtype), ).sample if args.v_parameterization: @@ -413,18 +432,14 @@ def remove_model(old_ckpt_name): else: target = noise - loss = torch.nn.functional.mse_loss( - noise_pred.float(), target.float(), reduction="none" - ) + loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") loss = loss.mean([1, 2, 3]) loss_weights = batch["loss_weights"] # 各sampleごとのweight loss = loss * loss_weights if args.min_snr_gamma: - loss = apply_snr_weight( - loss, timesteps, noise_scheduler, args.min_snr_gamma - ) + loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし @@ -456,31 +471,21 @@ def remove_model(old_ckpt_name): ) # 指定ステップごとにモデルを保存 - if ( - args.save_every_n_steps is not None - and global_step % args.save_every_n_steps == 0 - ): + if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: accelerator.wait_for_everyone() if accelerator.is_main_process: - ckpt_name = train_util.get_step_ckpt_name( - args, "." + args.save_model_as, global_step - ) + ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) save_model( - ckpt_name, unwrap_model(controlnet), + ckpt_name, + accelerator.unwrap_model(controlnet), ) if args.save_state: - train_util.save_and_remove_state_stepwise( - args, accelerator, global_step - ) + train_util.save_and_remove_state_stepwise(args, accelerator, global_step) - remove_step_no = train_util.get_remove_step_no( - args, global_step - ) + remove_step_no = train_util.get_remove_step_no(args, global_step) if remove_step_no is not None: - remove_ckpt_name = train_util.get_step_ckpt_name( - args, "." + args.save_model_as, remove_step_no - ) + remove_ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, remove_step_no) remove_model(remove_ckpt_name) current_loss = loss.detach().item() @@ -509,26 +514,18 @@ def remove_model(old_ckpt_name): # 指定エポックごとにモデルを保存 if args.save_every_n_epochs is not None: - saving = (epoch + 1) % args.save_every_n_epochs == 0 and ( - epoch + 1 - ) < num_train_epochs + saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs if is_main_process and saving: - ckpt_name = train_util.get_epoch_ckpt_name( - args, "." + args.save_model_as, epoch + 1 - ) - save_model(ckpt_name, unwrap_model(controlnet)) + ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) + save_model(ckpt_name, accelerator.unwrap_model(controlnet)) remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) if remove_epoch_no is not None: - remove_ckpt_name = train_util.get_epoch_ckpt_name( - args, "." + args.save_model_as, remove_epoch_no - ) + remove_ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, remove_epoch_no) remove_model(remove_ckpt_name) if args.save_state: - train_util.save_and_remove_state_on_epoch_end( - args, accelerator, epoch + 1 - ) + train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) train_util.sample_images( accelerator, @@ -545,20 +542,18 @@ def remove_model(old_ckpt_name): # end of epoch if is_main_process: - controlnet = unwrap_model(controlnet) + controlnet = accelerator.unwrap_model(controlnet) accelerator.end_training() if is_main_process and args.save_state: train_util.save_state_on_train_end(args, accelerator) - del accelerator # この後メモリを使うのでこれは消す + # del accelerator # この後メモリを使うのでこれは消す→printで使うので消さずにおく if is_main_process: ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) - save_model( - ckpt_name, controlnet, force_sync_upload=True - ) + save_model(ckpt_name, controlnet, force_sync_upload=True) print("model saved.") From f7f762c67685398d4e2f6c2fe5472fe4ec5759c4 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 24 Jun 2023 11:52:26 +0900 Subject: [PATCH 028/220] add minimal inference code for sdxl --- library/sdxl_model_util.py | 309 +++++++++++++++++++++++++++++++++++++ requirements.txt | 4 +- sdxl_minimal_inference.py | 268 ++++++++++++++++++++++++++++++++ 3 files changed, 580 insertions(+), 1 deletion(-) create mode 100644 library/sdxl_model_util.py create mode 100644 sdxl_minimal_inference.py diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py new file mode 100644 index 000000000..fc64d21ea --- /dev/null +++ b/library/sdxl_model_util.py @@ -0,0 +1,309 @@ +import torch +from safetensors.torch import load_file, save_file +from transformers import CLIPTextModel, CLIPTextConfig +from diffusers import AutoencoderKL +from library import model_util +from library import sdxl_original_unet + + +def convert_sdxl_text_encoder_2_checkpoint(checkpoint, max_length): + SDXL_KEY_PREFIX = "conditioner.embedders.1.model." + + # SD2のと、基本的には同じ。text_projectionを後で使うので、それを追加で返す + # logit_scaleはcheckpointの保存時に使用する + def convert_key(key): + # common conversion + key = key.replace(SDXL_KEY_PREFIX + "transformer.", "text_model.encoder.") + key = key.replace(SDXL_KEY_PREFIX, "text_model.") + + if "resblocks" in key: + # resblocks conversion + key = key.replace(".resblocks.", ".layers.") + if ".ln_" in key: + key = key.replace(".ln_", ".layer_norm") + elif ".mlp." in key: + key = key.replace(".c_fc.", ".fc1.") + key = key.replace(".c_proj.", ".fc2.") + elif ".attn.out_proj" in key: + key = key.replace(".attn.out_proj.", ".self_attn.out_proj.") + elif ".attn.in_proj" in key: + key = None # 特殊なので後で処理する + else: + raise ValueError(f"unexpected key in SD: {key}") + elif ".positional_embedding" in key: + key = key.replace(".positional_embedding", ".embeddings.position_embedding.weight") + elif ".text_projection" in key: + key = None # 後で処理する + elif ".logit_scale" in key: + key = None # 後で処理する + elif ".token_embedding" in key: + key = key.replace(".token_embedding.weight", ".embeddings.token_embedding.weight") + elif ".ln_final" in key: + key = key.replace(".ln_final", ".final_layer_norm") + return key + + keys = list(checkpoint.keys()) + new_sd = {} + for key in keys: + new_key = convert_key(key) + if new_key is None: + continue + new_sd[new_key] = checkpoint[key] + + # attnの変換 + for key in keys: + if ".resblocks" in key and ".attn.in_proj_" in key: + # 三つに分割 + values = torch.chunk(checkpoint[key], 3) + + key_suffix = ".weight" if "weight" in key else ".bias" + key_pfx = key.replace(SDXL_KEY_PREFIX + "transformer.resblocks.", "text_model.encoder.layers.") + key_pfx = key_pfx.replace("_weight", "") + key_pfx = key_pfx.replace("_bias", "") + key_pfx = key_pfx.replace(".attn.in_proj", ".self_attn.") + new_sd[key_pfx + "q_proj" + key_suffix] = values[0] + new_sd[key_pfx + "k_proj" + key_suffix] = values[1] + new_sd[key_pfx + "v_proj" + key_suffix] = values[2] + + # original SD にはないので、position_idsを追加 + position_ids = torch.Tensor([list(range(max_length))]).to(torch.int64) + new_sd["text_model.embeddings.position_ids"] = position_ids + + # text projection, logit_scale はDiffusersには含まれないが、後で必要になるので返す + text_projection = checkpoint[SDXL_KEY_PREFIX + "text_projection"] + logit_scale = checkpoint[SDXL_KEY_PREFIX + "logit_scale"] + + return new_sd, text_projection, logit_scale + + +def load_models_from_sdxl_checkpoint(model_type, ckpt_path, map_location): + # model_type is reserved to future use + + # Load the state dict + if model_util.is_safetensors(ckpt_path): + checkpoint = None + state_dict = load_file(ckpt_path, device=map_location) + epoch = None + global_step = None + else: + checkpoint = torch.load(ckpt_path, map_location=map_location) + if "state_dict" in checkpoint: + state_dict = checkpoint["state_dict"] + epoch = checkpoint.get("epoch", 0) + global_step = checkpoint.get("global_step", 0) + else: + state_dict = checkpoint + epoch = 0 + global_step = 0 + checkpoint = None + + # U-Net + print("building U-Net") + unet = sdxl_original_unet.SdxlUNet2DConditionModel() + + print("loading U-Net from checkpoint") + unet_sd = {} + for k in list(state_dict.keys()): + if k.startswith("model.diffusion_model."): + unet_sd[k.replace("model.diffusion_model.", "")] = state_dict.pop(k) + info = unet.load_state_dict(unet_sd) + print("U-Net: ", info) + del unet_sd + + # Text Encoders + print("building text encoders") + + # Text Encoder 1 is same to SDXL + text_model1_cfg = CLIPTextConfig( + vocab_size=49408, + hidden_size=768, + intermediate_size=3072, + num_hidden_layers=12, + num_attention_heads=12, + max_position_embeddings=77, + hidden_act="quick_gelu", + layer_norm_eps=1e-05, + dropout=0.0, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + model_type="clip_text_model", + projection_dim=768, + # torch_dtype="float32", + # transformers_version="4.25.0.dev0", + ) + text_model1 = CLIPTextModel._from_config(text_model1_cfg) + + # Text Encoder 2 is different from SDXL. SDXL uses open clip, but we use the model from HuggingFace. + # Note: Tokenizer from HuggingFace is different from SDXL. We must use open clip's tokenizer. + text_model2_cfg = CLIPTextConfig( + vocab_size=49408, + hidden_size=1280, + intermediate_size=5120, + num_hidden_layers=32, + num_attention_heads=20, + max_position_embeddings=77, + hidden_act="gelu", + layer_norm_eps=1e-05, + dropout=0.0, + attention_dropout=0.0, + initializer_range=0.02, + initializer_factor=1.0, + pad_token_id=1, + bos_token_id=0, + eos_token_id=2, + model_type="clip_text_model", + projection_dim=1280, + # torch_dtype="float32", + # transformers_version="4.25.0.dev0", + ) + text_model2 = CLIPTextModel._from_config(text_model2_cfg) + + print("loading text encoders from checkpoint") + te1_sd = {} + te2_sd = {} + for k in list(state_dict.keys()): + if k.startswith("conditioner.embedders.0.transformer."): + te1_sd[k.replace("conditioner.embedders.0.transformer.", "")] = state_dict.pop(k) + elif k.startswith("conditioner.embedders.1.model."): + te2_sd[k] = state_dict.pop(k) + + info1 = text_model1.load_state_dict(te1_sd) + print("text encoder 1:", info1) + + converted_sd, text_projection, logit_scale = convert_sdxl_text_encoder_2_checkpoint(te2_sd, max_length=77) + info2 = text_model2.load_state_dict(converted_sd) + print("text encoder2:", info2) + + # prepare vae + print("building VAE") + vae_config = model_util.create_vae_diffusers_config() + vae = AutoencoderKL(**vae_config) # .to(device) + + print("loading VAE from checkpoint") + converted_vae_checkpoint = model_util.convert_ldm_vae_checkpoint(state_dict, vae_config) + info = vae.load_state_dict(converted_vae_checkpoint) + print("VAE:", info) + + ckpt_info = (epoch, global_step) if epoch is not None else None + return text_model1, text_model2, vae, unet, text_projection, logit_scale, ckpt_info + + +def convert_text_encoder_2_state_dict_to_sdxl(checkpoint, text_projection, logit_scale): + def convert_key(key): + # position_idsの除去 + if ".position_ids" in key: + return None + + # common + key = key.replace("text_model.encoder.", "transformer.") + key = key.replace("text_model.", "") + if "layers" in key: + # resblocks conversion + key = key.replace(".layers.", ".resblocks.") + if ".layer_norm" in key: + key = key.replace(".layer_norm", ".ln_") + elif ".mlp." in key: + key = key.replace(".fc1.", ".c_fc.") + key = key.replace(".fc2.", ".c_proj.") + elif ".self_attn.out_proj" in key: + key = key.replace(".self_attn.out_proj.", ".attn.out_proj.") + elif ".self_attn." in key: + key = None # 特殊なので後で処理する + else: + raise ValueError(f"unexpected key in DiffUsers model: {key}") + elif ".position_embedding" in key: + key = key.replace("embeddings.position_embedding.weight", "positional_embedding") + elif ".token_embedding" in key: + key = key.replace("embeddings.token_embedding.weight", "token_embedding.weight") + elif "final_layer_norm" in key: + key = key.replace("final_layer_norm", "ln_final") + return key + + keys = list(checkpoint.keys()) + new_sd = {} + for key in keys: + new_key = convert_key(key) + if new_key is None: + continue + new_sd[new_key] = checkpoint[key] + + # attnの変換 + for key in keys: + if "layers" in key and "q_proj" in key: + # 三つを結合 + key_q = key + key_k = key.replace("q_proj", "k_proj") + key_v = key.replace("q_proj", "v_proj") + + value_q = checkpoint[key_q] + value_k = checkpoint[key_k] + value_v = checkpoint[key_v] + value = torch.cat([value_q, value_k, value_v]) + + new_key = key.replace("text_model.encoder.layers.", "transformer.resblocks.") + new_key = new_key.replace(".self_attn.q_proj.", ".attn.in_proj_") + new_sd[new_key] = value + + new_sd["text_projection"] = text_projection + new_sd["logit_scale"] = logit_scale + + return new_sd + + +def save_stable_diffusion_checkpoint( + output_file, + text_encoder1, + text_encoder2, + unet, + epochs, + steps, + ckpt_info, + vae, + text_projection, + logit_scale, + save_dtype=None, +): + state_dict = {} + + def update_sd(prefix, sd): + for k, v in sd.items(): + key = prefix + k + if save_dtype is not None: + v = v.detach().clone().to("cpu").to(save_dtype) + state_dict[key] = v + + # Convert the UNet model + update_sd("model.diffusion_model.", unet.state_dict()) + + # Convert the text encoders + update_sd("conditioner.embedders.0.transformer.", text_encoder1.state_dict()) + + text_enc2_dict = convert_text_encoder_2_state_dict_to_sdxl(text_encoder2.state_dict(), text_projection, logit_scale) + update_sd("conditioner.embedders.1.model.", text_enc2_dict) + + # Convert the VAE + vae_dict = model_util.convert_vae_state_dict(vae.state_dict()) + update_sd("first_stage_model.", vae_dict) + + # Put together new checkpoint + key_count = len(state_dict.keys()) + new_ckpt = {"state_dict": state_dict} + + # epoch and global_step are sometimes not int + if ckpt_info is not None: + epochs += ckpt_info[0] + steps += ckpt_info[1] + + new_ckpt["epoch"] = epochs + new_ckpt["global_step"] = steps + + if model_util.is_safetensors(output_file): + save_file(state_dict, output_file) + else: + torch.save(new_ckpt, output_file) + + return key_count diff --git a/requirements.txt b/requirements.txt index 74e06d216..babd96e9f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,5 +21,7 @@ huggingface-hub==0.14.1 # fairscale==0.4.13 # for WD14 captioning # tensorflow==2.10.1 +# open clip for SDXL +open-clip-torch==2.20.0 # for kohya_ss library -. +-e . diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py new file mode 100644 index 000000000..f8e7d687b --- /dev/null +++ b/sdxl_minimal_inference.py @@ -0,0 +1,268 @@ +# 手元で推論を行うための最低限のコード。HuggingFace/DiffusersのCLIP、schedulerとVAEを使う +# Minimal code for performing inference at local. Use HuggingFace/Diffusers CLIP, scheduler and VAE + +import argparse +import datetime +import math +import os +import random +from einops import repeat +import numpy as np +import torch +from tqdm import tqdm +from transformers import CLIPTokenizer +from library import sdxl_model_util +from diffusers import EulerDiscreteScheduler +from PIL import Image +import open_clip + +# scheduler: このあたりの設定はSD1/2と同じでいいらしい +# scheduler: The settings around here seem to be the same as SD1/2 +SCHEDULER_LINEAR_START = 0.00085 +SCHEDULER_LINEAR_END = 0.0120 +SCHEDULER_TIMESTEPS = 1000 +SCHEDLER_SCHEDULE = "scaled_linear" + + +# Time EmbeddingはDiffusersからのコピー +# Time Embedding is copied from Diffusers + + +def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False): + """ + Create sinusoidal timestep embeddings. + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param dim: the dimension of the output. + :param max_period: controls the minimum frequency of the embeddings. + :return: an [N x dim] Tensor of positional embeddings. + """ + if not repeat_only: + half = dim // 2 + freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to( + device=timesteps.device + ) + args = timesteps[:, None].float() * freqs[None] + embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) + if dim % 2: + embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) + else: + embedding = repeat(timesteps, "b -> b d", d=dim) + return embedding + + +def get_timestep_embedding(x, outdim): + assert len(x.shape) == 2 + b, dims = x.shape[0], x.shape[1] + # x = rearrange(x, "b d -> (b d)") + x = torch.flatten(x) + emb = timestep_embedding(x, outdim) + # emb = rearrange(emb, "(b d) d2 -> b (d d2)", b=b, d=dims, d2=outdim) + emb = torch.reshape(emb, (b, dims * outdim)) + return emb + + +if __name__ == "__main__": + # 画像生成条件を変更する場合はここを変更 + + # SDXLの追加のvector embeddingへ渡す値 + target_height = 1024 + target_width = 1024 + original_height = target_height + original_width = target_width + crop_top = 0 + crop_left = 0 + + steps = 50 + guidance_scale = 7 + seed = None # 1 + + DEVICE = "cuda" + DTYPE = torch.float16 # bfloat16 may work + + parser = argparse.ArgumentParser() + parser.add_argument("--ckpt_path", type=str, required=True) + parser.add_argument("--prompt", type=str, default="A photo of a cat") + parser.add_argument("--negative_prompt", type=str, default="") + parser.add_argument("--output_dir", type=str, default=".") + args = parser.parse_args() + + # HuggingFaceのmodel id + text_encoder_1_name = "openai/clip-vit-large-patch14" + text_encoder_2_name = "laion/CLIP-ViT-bigG-14-laion2B-39B-b160k" + + # checkpointを読み込む。モデル変換についてはそちらの関数を参照 + # Load checkpoint. For model conversion, see this function + + # 本体RAMが少ない場合はGPUにロードするといいかも + # If the main RAM is small, it may be better to load it on the GPU + text_model1, text_model2, vae, unet, text_projection, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( + "sdxl_base_v0-9", args.ckpt_path, "cpu" + ) + + # Text Encoder 1はSDXL本体でもHuggingFaceのものを使っている + # In SDXL, Text Encoder 1 is also using HuggingFace's + + # Text Encoder 2はSDXL本体ではopen_clipを使っている + # それを使ってもいいが、SD2のDiffusers版に合わせる形で、HuggingFaceのものを使う + # 重みの変換コードはSD2とほぼ同じ + # In SDXL, Text Encoder 2 is using open_clip + # It's okay to use it, but to match the Diffusers version of SD2, use HuggingFace's + # The weight conversion code is almost the same as SD2 + + # VAEの構造はSDXLもSD1/2と同じだが、重みは異なるようだ。何より謎のscale値が違う + # fp16でNaNが出やすいようだ + # The structure of VAE is the same as SD1/2, but the weights seem to be different. Above all, the mysterious scale value is different. + # NaN seems to be more likely to occur in fp16 + + unet.to(DEVICE, dtype=DTYPE) + unet.eval() + + if DTYPE == torch.float16: + print("use float32 for vae") + vae.to(DEVICE, torch.float32) # avoid black image, same as no-half-vae + else: + vae.to(DEVICE, DTYPE) + vae.eval() + + text_model1.to(DEVICE, dtype=DTYPE) + text_model1.eval() + text_model2.to(DEVICE, dtype=DTYPE) + text_model2.eval() + + text_projection = text_projection.to(DEVICE, dtype=DTYPE) + + unet.set_use_memory_efficient_attention(True, False) + + # prepare embedding + with torch.no_grad(): + # vector + emb1 = get_timestep_embedding(torch.FloatTensor([original_height, original_width]).unsqueeze(0), 256) + emb2 = get_timestep_embedding(torch.FloatTensor([crop_top, crop_left]).unsqueeze(0), 256) + emb3 = get_timestep_embedding(torch.FloatTensor([target_height, target_width]).unsqueeze(0), 256) + # print("emb1", emb1.shape) + c_vector = torch.cat([emb1, emb2, emb3], dim=1).to(DEVICE, dtype=DTYPE) + uc_vector = c_vector.clone().to(DEVICE, dtype=DTYPE) # ちょっとここ正しいかどうかわからない I'm not sure if this is right + + # crossattn + tokenizer1 = CLIPTokenizer.from_pretrained(text_encoder_1_name) + tokenizer2 = lambda x: open_clip.tokenize(x, context_length=77) + + # Text Encoderを二つ呼ぶ関数 Function to call two Text Encoders + def call_text_encoder(text): + # text encoder 1 + batch_encoding = tokenizer1( + text, + truncation=True, + return_length=True, + return_overflowing_tokens=False, + padding="max_length", + return_tensors="pt", + ) + tokens = batch_encoding["input_ids"].to(DEVICE) + + enc_out = text_model1(tokens, output_hidden_states=True, return_dict=True) + text_embedding1 = enc_out["hidden_states"][11] + # text_embedding = pipe.text_encoder.text_model.final_layer_norm(text_embedding) # layer normは通さないらしい + + # text encoder 2 + tokens = tokenizer2(text).to(DEVICE) + + enc_out = text_model2(tokens, output_hidden_states=True, return_dict=True) + text_embedding2_penu = enc_out["hidden_states"][-2] + # print("hidden_states2", text_embedding2_penu.shape) + text_embedding2_pool = enc_out["pooler_output"] + text_embedding2_pool = text_embedding2_pool @ text_projection.to(text_embedding2_pool.dtype) + + # 連結して終了 concat and finish + text_embedding = torch.cat([text_embedding1, text_embedding2_penu], dim=2) + return text_embedding, text_embedding2_pool + + # cond + c_ctx, c_ctx_pool = call_text_encoder(args.prompt) + # print(c_ctx.shape, c_ctx_p.shape, c_vector.shape) + c_vector = torch.cat([c_ctx_pool, c_vector], dim=1) + + # uncond + uc_ctx, uc_ctx_pool = call_text_encoder(args.negative_prompt) + uc_vector = torch.cat([uc_ctx_pool, uc_vector], dim=1) + + text_embeddings = torch.cat([uc_ctx, c_ctx]) + vector_embeddings = torch.cat([uc_vector, c_vector]) + + # メモリ使用量を減らすにはここでText Encoderを削除するかCPUへ移動する + + # scheduler + scheduler = EulerDiscreteScheduler( + num_train_timesteps=SCHEDULER_TIMESTEPS, + beta_start=SCHEDULER_LINEAR_START, + beta_end=SCHEDULER_LINEAR_END, + beta_schedule=SCHEDLER_SCHEDULE, + ) + + if seed is not None: + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + + # # random generator for initial noise + # generator = torch.Generator(device="cuda").manual_seed(seed) + generator = None + else: + generator = None + + # get the initial random noise unless the user supplied it + # SDXLはCPUでlatentsを作成しているので一応合わせておく、Diffusersはtarget deviceでlatentsを作成している + # SDXL creates latents in CPU, Diffusers creates latents in target device + latents_shape = (1, 4, target_height // 8, target_width // 8) + latents = torch.randn( + latents_shape, + generator=generator, + device="cpu", + dtype=torch.float32, + ).to(DEVICE, dtype=DTYPE) + + # scale the initial noise by the standard deviation required by the scheduler + latents = latents * scheduler.init_noise_sigma + + # set timesteps + scheduler.set_timesteps(steps, DEVICE) + + # このへんはDiffusersからのコピペ + # Copy from Diffusers + timesteps = scheduler.timesteps.to(DEVICE) # .to(DTYPE) + num_latent_input = 2 + for i, t in enumerate(tqdm(timesteps)): + # expand the latents if we are doing classifier free guidance + latent_model_input = latents.repeat((num_latent_input, 1, 1, 1)) + latent_model_input = scheduler.scale_model_input(latent_model_input, t) + + noise_pred = unet(latent_model_input, t, text_embeddings, vector_embeddings) + + noise_pred_uncond, noise_pred_text = noise_pred.chunk(num_latent_input) # uncond by negative prompt + noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) + + # compute the previous noisy sample x_t -> x_t-1 + # latents = scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample + latents = scheduler.step(noise_pred, t, latents).prev_sample + + # latents = 1 / 0.18215 * latents + latents = 1 / 0.13025 * latents + latents = latents.to(torch.float32) + image = vae.decode(latents).sample + image = (image / 2 + 0.5).clamp(0, 1) + + # we always cast to float32 as this does not cause significant overhead and is compatible with bfloa16 + image = image.cpu().permute(0, 2, 3, 1).float().numpy() + + # image = self.numpy_to_pil(image) + image = (image * 255).round().astype("uint8") + image = [Image.fromarray(im) for im in image] + + # 保存して終了 save and finish + timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + for i, img in enumerate(image): + img.save(os.path.join(args.output_dir, f"image_{timestamp}_{i:03d}.png")) + + print("Done!") From 9e9df2b5017c4dded9a7be1f46e916df248dd5c1 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 24 Jun 2023 17:56:02 +0900 Subject: [PATCH 029/220] update dataset to return size, refactor ctrlnet ds --- library/config_util.py | 2 +- library/sdxl_original_unet.py | 10 +- library/train_util.py | 633 ++++++++++++++++++---------------- 3 files changed, 337 insertions(+), 308 deletions(-) diff --git a/library/config_util.py b/library/config_util.py index 36c165a5c..dd81ae660 100644 --- a/library/config_util.py +++ b/library/config_util.py @@ -79,7 +79,7 @@ class ControlNetSubsetParams(BaseSubsetParams): @dataclass class BaseDatasetParams: - tokenizer: CLIPTokenizer = None + tokenizer: Union[CLIPTokenizer, List[CLIPTokenizer]] = None max_token_length: int = None resolution: Optional[Tuple[int, int]] = None debug_dataset: bool = False diff --git a/library/sdxl_original_unet.py b/library/sdxl_original_unet.py index 6556b12c5..fd37432f7 100644 --- a/library/sdxl_original_unet.py +++ b/library/sdxl_original_unet.py @@ -1116,13 +1116,15 @@ def call_module(module, h, emb, context): # 使用メモリ量確認用の疑似学習ループ print("preparing optimizer") - import bitsandbytes - import transformers + # optimizer = torch.optim.SGD(unet.parameters(), lr=1e-3, nesterov=True, momentum=0.9) # not working + # import bitsandbytes # optimizer = bitsandbytes.adam.Adam8bit(unet.parameters(), lr=1e-3) # not working # optimizer = bitsandbytes.optim.RMSprop8bit(unet.parameters(), lr=1e-3) # working at 23.5 GB with torch2 # optimizer=bitsandbytes.optim.Adagrad8bit(unet.parameters(), lr=1e-3) # working at 23.5 GB with torch2 - # optimizer = torch.optim.SGD(unet.parameters(), lr=1e-3, nesterov=True, momentum=0.9) # not working + + import transformers + optimizer = transformers.optimization.Adafactor(unet.parameters(), relative_step=True) # working at 22.2GB with torch2 scaler = torch.cuda.amp.GradScaler(enabled=True) @@ -1133,7 +1135,7 @@ def call_module(module, h, emb, context): for step in range(steps): print(f"step {step}") - x = torch.randn(batch_size, 4, 128, 128).cuda() # 512x512 + x = torch.randn(batch_size, 4, 128, 128).cuda() # 1024x1024 t = torch.randint(low=0, high=10, size=(batch_size,), device="cuda") ctx = torch.randn(batch_size, 77, 2048).cuda() y = torch.randn(batch_size, ADM_IN_CHANNELS).cuda() diff --git a/library/train_util.py b/library/train_util.py index 89ad683bc..533bf0a9f 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -103,6 +103,9 @@ def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, self.latents_flipped: torch.Tensor = None self.latents_npz: str = None self.latents_npz_flipped: str = None + self.latents_original_size: Tuple[int, int] = None # original image size, not latents size + self.latents_crop_left_top: Tuple[int, int] = None # original image crop left top, not latents crop left top + self.cond_img_path: str = None class BucketManager: @@ -171,6 +174,7 @@ def round_to_steps(self, x): def select_bucket(self, image_width, image_height): aspect_ratio = image_width / image_height if not self.no_upscale: + # 拡大および縮小を行う # 同じaspect ratioがあるかもしれないので(fine tuningで、no_upscale=Trueで前処理した場合)、解像度が同じものを優先する reso = (image_width, image_height) if reso in self.predefined_resos_set: @@ -189,6 +193,7 @@ def select_bucket(self, image_width, image_height): resized_size = (int(image_width * scale + 0.5), int(image_height * scale + 0.5)) # print("use predef", image_width, image_height, reso, resized_size) else: + # 縮小のみを行う if image_width * image_height > self.max_area: # 画像が大きすぎるのでアスペクト比を保ったまま縮小することを前提にbucketを決める resized_width = math.sqrt(self.max_area * aspect_ratio) @@ -238,41 +243,40 @@ class BucketBatchIndex(NamedTuple): class AugHelper: def __init__(self): # prepare all possible augmentators - color_aug_method = albu.OneOf( + self.color_aug_method = albu.OneOf( [ albu.HueSaturationValue(8, 0, 0, p=0.5), albu.RandomGamma((95, 105), p=0.5), ], p=0.33, ) - flip_aug_method = albu.HorizontalFlip(p=0.5) # key: (use_color_aug, use_flip_aug) - self.augmentors = { - (True, True): albu.Compose( - [ - color_aug_method, - flip_aug_method, - ], - p=1.0, - ), - (True, False): albu.Compose( - [ - color_aug_method, - ], - p=1.0, - ), - (False, True): albu.Compose( - [ - flip_aug_method, - ], - p=1.0, - ), - (False, False): None, - } - - def get_augmentor(self, use_color_aug: bool, use_flip_aug: bool) -> Optional[albu.Compose]: - return self.augmentors[(use_color_aug, use_flip_aug)] + # self.augmentors = { + # (True, True): albu.Compose( + # [ + # color_aug_method, + # flip_aug_method, + # ], + # p=1.0, + # ), + # (True, False): albu.Compose( + # [ + # color_aug_method, + # ], + # p=1.0, + # ), + # (False, True): albu.Compose( + # [ + # flip_aug_method, + # ], + # p=1.0, + # ), + # (False, False): None, + # } + + def get_augmentor(self, use_color_aug: bool) -> Optional[albu.Compose]: + return self.color_aug_method if use_color_aug else None class BaseSubset: @@ -454,10 +458,16 @@ def __eq__(self, other) -> bool: class BaseDataset(torch.utils.data.Dataset): def __init__( - self, tokenizer: CLIPTokenizer, max_token_length: int, resolution: Optional[Tuple[int, int]], debug_dataset: bool + self, + tokenizer: Union[CLIPTokenizer, List[CLIPTokenizer]], + max_token_length: int, + resolution: Optional[Tuple[int, int]], + debug_dataset: bool, ) -> None: super().__init__() - self.tokenizer = tokenizer + + self.tokenizers = tokenizer if isinstance(tokenizer, list) else [tokenizer] + self.max_token_length = max_token_length # width/height is used when enable_bucket==False self.width, self.height = (None, None) if resolution is None else resolution @@ -478,7 +488,7 @@ def __init__( self.bucket_no_upscale = None self.bucket_info = None # for metadata - self.tokenizer_max_length = self.tokenizer.model_max_length if max_token_length is None else max_token_length + 2 + self.tokenizer_max_length = self.tokenizers[0].model_max_length if max_token_length is None else max_token_length + 2 self.current_epoch: int = 0 # インスタンスがepochごとに新しく作られるようなので外側から渡さないとダメ @@ -594,48 +604,49 @@ def dropout_tags(tokens): return caption - def get_input_ids(self, caption): - input_ids = self.tokenizer( + def get_input_ids(self, caption, tokenizer=None): + if tokenizer is None: + tokenizer = self.tokenizers[0] + + input_ids = tokenizer( caption, padding="max_length", truncation=True, max_length=self.tokenizer_max_length, return_tensors="pt" ).input_ids - if self.tokenizer_max_length > self.tokenizer.model_max_length: + if self.tokenizer_max_length > tokenizer.model_max_length: input_ids = input_ids.squeeze(0) iids_list = [] - if self.tokenizer.pad_token_id == self.tokenizer.eos_token_id: + if tokenizer.pad_token_id == tokenizer.eos_token_id: # v1 # 77以上の時は " .... " でトータル227とかになっているので、"..."の三連に変換する # 1111氏のやつは , で区切る、とかしているようだが とりあえず単純に for i in range( - 1, self.tokenizer_max_length - self.tokenizer.model_max_length + 2, self.tokenizer.model_max_length - 2 + 1, self.tokenizer_max_length - tokenizer.model_max_length + 2, tokenizer.model_max_length - 2 ): # (1, 152, 75) ids_chunk = ( input_ids[0].unsqueeze(0), - input_ids[i : i + self.tokenizer.model_max_length - 2], + input_ids[i : i + tokenizer.model_max_length - 2], input_ids[-1].unsqueeze(0), ) ids_chunk = torch.cat(ids_chunk) iids_list.append(ids_chunk) else: - # v2 + # v2 or SDXL # 77以上の時は " .... ..." でトータル227とかになっているので、"... ..."の三連に変換する - for i in range( - 1, self.tokenizer_max_length - self.tokenizer.model_max_length + 2, self.tokenizer.model_max_length - 2 - ): + for i in range(1, self.tokenizer_max_length - tokenizer.model_max_length + 2, tokenizer.model_max_length - 2): ids_chunk = ( input_ids[0].unsqueeze(0), # BOS - input_ids[i : i + self.tokenizer.model_max_length - 2], + input_ids[i : i + tokenizer.model_max_length - 2], input_ids[-1].unsqueeze(0), ) # PAD or EOS ids_chunk = torch.cat(ids_chunk) # 末尾が または の場合は、何もしなくてよい # 末尾が x の場合は末尾を に変える(x なら結果的に変化なし) - if ids_chunk[-2] != self.tokenizer.eos_token_id and ids_chunk[-2] != self.tokenizer.pad_token_id: - ids_chunk[-1] = self.tokenizer.eos_token_id + if ids_chunk[-2] != tokenizer.eos_token_id and ids_chunk[-2] != tokenizer.pad_token_id: + ids_chunk[-1] = tokenizer.eos_token_id # 先頭が ... の場合は ... に変える - if ids_chunk[1] == self.tokenizer.pad_token_id: - ids_chunk[1] = self.tokenizer.eos_token_id + if ids_chunk[1] == tokenizer.pad_token_id: + ids_chunk[1] = tokenizer.eos_token_id iids_list.append(ids_chunk) @@ -755,46 +766,58 @@ def load_image(self, image_path): img = np.array(image, np.uint8) return img - def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_size, cond_img = None): + def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_size): image_height, image_width = image.shape[0:2] if image_width != resized_size[0] or image_height != resized_size[1]: # リサイズする image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ - if exists(cond_img): - cond_img = cv2.resize(cond_img, resized_size, interpolation=cv2.INTER_AREA) image_height, image_width = image.shape[0:2] + original_size = (image_width, image_height) + + crop_left_top = (0, 0) if image_width > reso[0]: trim_size = image_width - reso[0] p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) # print("w", trim_size, p) image = image[:, p : p + reso[0]] - if exists(cond_img): - cond_img = cond_img[:, p : p + reso[0]] + crop_left_top = (p, 0) if image_height > reso[1]: trim_size = image_height - reso[1] p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) # print("h", trim_size, p) image = image[p : p + reso[1]] - if exists(cond_img): - cond_img = cond_img[p : p + reso[1]] + crop_left_top = (crop_left_top[0], p) assert ( image.shape[0] == reso[1] and image.shape[1] == reso[0] ), f"internal error, illegal trimmed size: {image.shape}, {reso}" - - if exists(cond_img): - assert ( - cond_img.shape[0] == reso[1] and cond_img.shape[1] == reso[0] - ), f"internal error, illegal trimmed size: {cond_img.shape}, {reso}" - return image, cond_img - - return image + return image, original_size, crop_left_top def is_latent_cacheable(self): return all([not subset.color_aug and not subset.random_crop for subset in self.subsets]) + def is_disk_cached_latents_is_expected(self, reso, npz_path, flipped_npz_path): + expected_latents_size = (reso[1] // 8, reso[0] // 8) # bucket_resoはWxHなので注意 + + for npath in [npz_path, flipped_npz_path]: + if npath is None: + continue + if not os.path.exists(npath): + return False + + npz = np.load(npath) + if "latents" not in npz or "original_size" not in npz or "crop_left_top" not in npz: # old ver? + return False + + cached_latents = npz["latents"] + + if cached_latents.shape[1:3] != expected_latents_size: + return False + + return True + def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_process=True): # ちょっと速くした print("caching latents.") @@ -811,38 +834,26 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc subset = self.image_to_subset[info.image_key] if info.latents_npz is not None: - info.latents = self.load_latents_from_npz(info, False) + info.latents, info.latents_original_size, info.latents_crop_left_top = self.load_latents_from_npz(info, False) info.latents = torch.FloatTensor(info.latents) - # might be None, but that's ok because check is done in dataset - info.latents_flipped = self.load_latents_from_npz(info, True) + info.latents_flipped, _, _ = self.load_latents_from_npz(info, True) # might be None if info.latents_flipped is not None: info.latents_flipped = torch.FloatTensor(info.latents_flipped) continue # check disk cache exists and size of latents if cache_to_disk: - # TODO: refactor to unify with FineTuningDataset info.latents_npz = os.path.splitext(info.absolute_path)[0] + ".npz" info.latents_npz_flipped = os.path.splitext(info.absolute_path)[0] + "_flip.npz" if not is_main_process: continue - cache_available = False - expected_latents_size = (info.bucket_reso[1] // 8, info.bucket_reso[0] // 8) # bucket_resoはWxHなので注意 - if os.path.exists(info.latents_npz): - cached_latents = np.load(info.latents_npz)["arr_0"] - if cached_latents.shape[1:3] == expected_latents_size: - cache_available = True - - if subset.flip_aug: - cache_available = False - if os.path.exists(info.latents_npz_flipped): - cached_latents_flipped = np.load(info.latents_npz_flipped)["arr_0"] - if cached_latents_flipped.shape[1:3] == expected_latents_size: - cache_available = True - - if cache_available: + cache_available = self.is_disk_cached_latents_is_expected( + info.bucket_reso, info.latents_npz, info.latents_npz_flipped if self.flip_aug else None + ) + + if cache_available: # do not add to batch continue # if last member of batch has different resolution, flush the batch @@ -868,10 +879,15 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc images = [] for info in batch: image = self.load_image(info.absolute_path) - image = self.trim_and_resize_if_required(subset, image, info.bucket_reso, info.resized_size) + image, original_size, crop_left_top = self.trim_and_resize_if_required( + subset, image, info.bucket_reso, info.resized_size + ) image = self.image_transforms(image) images.append(image) + info.latents_original_size = original_size + info.latents_crop_left_top = crop_left_top + img_tensors = torch.stack(images, dim=0) img_tensors = img_tensors.to(device=vae.device, dtype=vae.dtype) @@ -879,7 +895,12 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc for info, latent in zip(batch, latents): if cache_to_disk: - np.savez(info.latents_npz, latent.float().numpy()) + np.savez( + info.latents_npz, + latents=latent.float().numpy(), + original_size=np.array(info.latents_original_size), + crop_left_top=np.array(info.latents_crop_left_top), + ) else: info.latents = latent @@ -888,7 +909,12 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") for info, latent in zip(batch, latents): if cache_to_disk: - np.savez(info.latents_npz_flipped, latent.float().numpy()) + np.savez( + info.latents_npz_flipped, + latents=latent.float().numpy(), + original_size=np.array(info.latents_original_size), + crop_left_top=np.array(info.latents_crop_left_top), # reverse horizontally when use flipped latents + ) else: info.latents_flipped = latent @@ -961,8 +987,13 @@ def crop_target(self, subset: BaseSubset, image, face_cx, face_cy, face_w, face_ def load_latents_from_npz(self, image_info: ImageInfo, flipped): npz_file = image_info.latents_npz_flipped if flipped else image_info.latents_npz if npz_file is None: - return None - return np.load(npz_file)["arr_0"] + return None, None, None + + npz = np.load(npz_file) + latents = npz["latents"] + original_size = npz["original_size"].tolist() + crop_left_top = npz["crop_left_top"].tolist() + return latents, original_size, crop_left_top def __len__(self): return self._length @@ -975,21 +1006,35 @@ def __getitem__(self, index): loss_weights = [] captions = [] input_ids_list = [] + input_ids2_list = [] latents_list = [] images = [] + original_sizes_hw = [] + crop_top_lefts = [] + target_sizes_hw = [] + flippeds = [] # 変数名が微妙 for image_key in bucket[image_index : image_index + bucket_batch_size]: image_info = self.image_data[image_key] subset = self.image_to_subset[image_key] loss_weights.append(self.prior_loss_weight if image_info.is_reg else 1.0) + flipped = subset.flip_aug and random.random() < 0.5 # not flipped or flipped with 50% chance + # image/latentsを処理する if image_info.latents is not None: # cache_latents=Trueの場合 - latents = image_info.latents if not subset.flip_aug or random.random() < 0.5 else image_info.latents_flipped + original_size = image_info.latents_original_size + crop_left_top = image_info.latents_crop_left_top # calc values later if flipped + if not flipped: + latents = image_info.latents + else: + latents = image_info.latents_flipped + image = None elif image_info.latents_npz is not None: # FineTuningDatasetまたはcache_latents_to_disk=Trueの場合 - latents = self.load_latents_from_npz(image_info, subset.flip_aug and random.random() >= 0.5) + latents, original_size, crop_left_top = self.load_latents_from_npz(image_info, flipped) latents = torch.FloatTensor(latents) + image = None else: # 画像を読み込み、必要ならcropする @@ -997,7 +1042,9 @@ def __getitem__(self, index): im_h, im_w = img.shape[0:2] if self.enable_bucket: - img = self.trim_and_resize_if_required(subset, img, image_info.bucket_reso, image_info.resized_size) + img, original_size, crop_left_top = self.trim_and_resize_if_required( + subset, img, image_info.bucket_reso, image_info.resized_size + ) else: if face_cx > 0: # 顔位置情報あり img = self.crop_target(subset, img, face_cx, face_cy, face_w, face_h) @@ -1017,17 +1064,33 @@ def __getitem__(self, index): im_h == self.height and im_w == self.width ), f"image size is small / 画像サイズが小さいようです: {image_info.absolute_path}" + original_size = [im_w, im_h] + crop_left_top = [0, 0] + # augmentation - aug = self.aug_helper.get_augmentor(subset.color_aug, subset.flip_aug) + aug = self.aug_helper.get_augmentor(subset.color_aug) if aug is not None: img = aug(image=img)["image"] + if flipped: + img = img[:, ::-1, :].copy() # copy to avoid negative stride problem + latents = None image = self.image_transforms(img) # -1.0~1.0のtorch.Tensorになる images.append(image) latents_list.append(latents) + target_size = (image.shape[2], image.shape[1]) if image is not None else (latents.shape[2] * 8, latents.shape[1] * 8) + + if flipped: + crop_left_top = (original_size[0] - crop_left_top[0] - target_size[0], crop_left_top[1]) + + original_sizes_hw.append((original_size[1], original_size[0])) + crop_top_lefts.append((crop_left_top[1], crop_left_top[0])) + target_sizes_hw.append((target_size[1], target_size[0])) + flippeds.append(flipped) + caption = self.process_caption(subset, image_info.caption) if self.XTI_layers: caption_layer = [] @@ -1039,22 +1102,33 @@ def __getitem__(self, index): captions.append(caption_layer) else: captions.append(caption) + if not self.token_padding_disabled: # this option might be omitted in future if self.XTI_layers: - token_caption = self.get_input_ids(caption_layer) + token_caption = self.get_input_ids(caption_layer, self.tokenizers[0]) else: - token_caption = self.get_input_ids(caption) + token_caption = self.get_input_ids(caption, self.tokenizers[0]) input_ids_list.append(token_caption) + if len(self.tokenizers) > 1: + if self.XTI_layers: + token_caption2 = self.get_input_ids(caption_layer, self.tokenizers[1]) + else: + token_caption2 = self.get_input_ids(caption, self.tokenizers[1]) + input_ids2_list.append(token_caption2) + example = {} example["loss_weights"] = torch.FloatTensor(loss_weights) if self.token_padding_disabled: # padding=True means pad in the batch - example["input_ids"] = self.tokenizer(captions, padding=True, truncation=True, return_tensors="pt").input_ids + example["input_ids"] = self.tokenizer[0](captions, padding=True, truncation=True, return_tensors="pt").input_ids + if len(self.tokenizers) > 1: + # following may not work in SDXL, keep the line for future update + example["input_ids2"] = self.tokenizer[1](captions, padding=True, truncation=True, return_tensors="pt").input_ids else: - # batch processing seems to be good example["input_ids"] = torch.stack(input_ids_list) + example["input_ids2"] = torch.stack(input_ids2_list) if len(self.tokenizers) > 1 else None if images[0] is not None: images = torch.stack(images) @@ -1066,6 +1140,11 @@ def __getitem__(self, index): example["latents"] = torch.stack(latents_list) if latents_list[0] is not None else None example["captions"] = captions + example["original_sizes_hw"] = torch.stack([torch.LongTensor(x) for x in original_sizes_hw]) + example["crop_top_lefts"] = torch.stack([torch.LongTensor(x) for x in crop_top_lefts]) + example["target_sizes_hw"] = torch.stack([torch.LongTensor(x) for x in target_sizes_hw]) + example["flippeds"] = flippeds + if self.debug_dataset: example["image_keys"] = bucket[image_index : image_index + self.batch_size] return example @@ -1462,151 +1541,86 @@ def __init__( max_bucket_reso: int, bucket_reso_steps: int, bucket_no_upscale: bool, - debug_dataset) -> None: + debug_dataset, + ) -> None: super().__init__(tokenizer, max_token_length, resolution, debug_dataset) - self.conditioning_image_data: Dict[str, ImageInfo] = {} - assert resolution is not None, f"resolution is required / resolution(解像度)指定は必須です" + db_subsets = [] + for subset in subsets: + db_subset = DreamBoothSubset( + subset.image_dir, + False, + None, + subset.caption_extension, + subset.num_repeats, + subset.shuffle_caption, + subset.keep_tokens, + subset.color_aug, + subset.flip_aug, + subset.face_crop_aug_range, + subset.random_crop, + subset.caption_dropout_rate, + subset.caption_dropout_every_n_epochs, + subset.caption_tag_dropout_rate, + subset.token_warmup_min, + subset.token_warmup_step, + ) + db_subsets.append(db_subset) + + self.dreambooth_dataset_delegate = DreamBoothDataset( + db_subsets, + batch_size, + tokenizer, + max_token_length, + resolution, + enable_bucket, + min_bucket_reso, + max_bucket_reso, + bucket_reso_steps, + bucket_no_upscale, + 1.0, + debug_dataset, + ) + # config_util等から参照される値をいれておく(若干微妙なのでなんとかしたい) + self.image_data = self.dreambooth_dataset_delegate.image_data self.batch_size = batch_size - self.size = min(self.width, self.height) # 短いほう - self.latents_cache = None - - self.num_reg_images = 0 - - self.enable_bucket = enable_bucket - if self.enable_bucket: - assert ( - min(resolution) >= min_bucket_reso - ), f"min_bucket_reso must be equal or less than resolution / min_bucket_resoは最小解像度より大きくできません。解像度を大きくするかmin_bucket_resoを小さくしてください" - assert ( - max(resolution) <= max_bucket_reso - ), f"max_bucket_reso must be equal or greater than resolution / max_bucket_resoは最大解像度より小さくできません。解像度を小さくするかmin_bucket_resoを大きくしてください" - self.min_bucket_reso = min_bucket_reso - self.max_bucket_reso = max_bucket_reso - self.bucket_reso_steps = bucket_reso_steps - self.bucket_no_upscale = bucket_no_upscale - else: - self.min_bucket_reso = None - self.max_bucket_reso = None - self.bucket_reso_steps = None # この情報は使われない - self.bucket_no_upscale = False - - def read_caption(img_path, caption_extension): - # captionの候補ファイル名を作る - base_name = os.path.splitext(img_path)[0] - base_name_face_det = base_name - tokens = base_name.split("_") - if len(tokens) >= 5: - base_name_face_det = "_".join(tokens[:-4]) - cap_paths = [base_name + caption_extension, base_name_face_det + caption_extension] - - caption = None - for cap_path in cap_paths: - if os.path.isfile(cap_path): - with open(cap_path, "rt", encoding="utf-8") as f: - try: - lines = f.readlines() - except UnicodeDecodeError as e: - print(f"illegal char in file (not UTF-8) / ファイルにUTF-8以外の文字があります: {cap_path}") - raise e - assert len(lines) > 0, f"caption file is empty / キャプションファイルが空です: {cap_path}" - caption = lines[0].strip() + self.num_train_images = self.dreambooth_dataset_delegate.num_train_images + self.num_reg_images = self.dreambooth_dataset_delegate.num_reg_images + + # assert all conditioning data exists + missing_imgs = [] + cond_imgs_with_img = set() + for image_key, info in self.dreambooth_dataset_delegate.image_data.items(): + db_subset = self.dreambooth_dataset_delegate.image_to_subset[image_key] + subset = None + for s in subsets: + if s.image_dir == db_subset.image_dir: + subset = s break - return caption + assert subset is not None, "internal error: subset not found" - def load_controlnet_dir(subset: ControlNetSubset): - if not os.path.isdir(subset.image_dir): - print(f"not directory: {subset.image_dir}") - return [], [] if not os.path.isdir(subset.conditioning_data_dir): print(f"not directory: {subset.conditioning_data_dir}") - return [], [] - - img_paths = glob_images(subset.image_dir, "*") - conditioning_img_paths = glob_images(subset.conditioning_data_dir, "*") - img_paths = sorted(img_paths) - conditioning_img_paths = sorted(conditioning_img_paths) - print(f"found directory {subset.image_dir} contains {len(img_paths)} image files") - print(f"found directory {subset.conditioning_data_dir} contains {len(conditioning_img_paths)} image files") - - img_basenames = [os.path.basename(img) for img in img_paths] - conditioning_img_basenames = [os.path.basename(img) for img in conditioning_img_paths] - missing_imgs = [] - extra_imgs = [] - - for img in img_basenames: - if img not in conditioning_img_basenames: - missing_imgs.append(img) - for img in conditioning_img_basenames: - if img not in img_basenames: - extra_imgs.append(img) - - assert len(missing_imgs) == 0, f"missing conditioning data for {len(missing_imgs)} images: {missing_imgs}" - assert len(extra_imgs) == 0, f"extra conditioning data for {len(extra_imgs)} images: {extra_imgs}" - - - # 画像ファイルごとにプロンプトを読み込み、もしあればそちらを使う - captions = [] - missing_captions = [] - for img_path in img_paths: - cap_for_img = read_caption(img_path, subset.caption_extension) - if cap_for_img is None: - print(f"neither caption file nor class tokens are found. use empty caption for {img_path} / キャプションファイルもclass tokenも見つかりませんでした。空のキャプションを使用します: {img_path}") - captions.append("") - missing_captions.append(img_path) - else: - captions.append(cap_for_img) - - self.set_tag_frequency(os.path.basename(subset.image_dir), captions) # タグ頻度を記録 - - if missing_captions: - number_of_missing_captions = len(missing_captions) - number_of_missing_captions_to_show = 5 - remaining_missing_captions = number_of_missing_captions - number_of_missing_captions_to_show - - print( - f"No caption file found for {number_of_missing_captions} images. Training will continue without captions for these images. If class token exists, it will be used. / {number_of_missing_captions}枚の画像にキャプションファイルが見つかりませんでした。これらの画像についてはキャプションなしで学習を続行します。class tokenが存在する場合はそれを使います。" - ) - for i, missing_caption in enumerate(missing_captions): - if i >= number_of_missing_captions_to_show: - print(missing_caption + f"... and {remaining_missing_captions} more") - break - print(missing_caption) - return img_paths, conditioning_img_paths, captions - - print("prepare images.") - num_train_images = 0 - for subset in subsets: - if subset.num_repeats < 1: - print( - f"ignore subset with image_dir='{subset.image_dir}': num_repeats is less than 1 / num_repeatsが1を下回っているためサブセットを無視します: {subset.num_repeats}" - ) - continue - - if subset in self.subsets: - print( - f"ignore duplicated subset with image_dir='{subset.image_dir}': use the first one / 既にサブセットが登録されているため、重複した後発のサブセットを無視します" - ) continue - img_paths, conditioning_img_paths, captions = load_controlnet_dir(subset) - if len(img_paths) < 1: - print(f"ignore subset with image_dir='{subset.image_dir}': no images found / 画像が見つからないためサブセットを無視します") - continue + img_basename = os.path.basename(info.absolute_path) + ctrl_img_path = os.path.join(subset.conditioning_data_dir, img_basename) + if not os.path.exists(ctrl_img_path): + missing_imgs.append(img_basename) - num_train_images += subset.num_repeats * len(img_paths) + info.cond_img_path = ctrl_img_path + cond_imgs_with_img.add(ctrl_img_path) - for img_path, cond_img_path, caption in zip(img_paths, conditioning_img_paths, captions): - info = ImageInfo(img_path, subset.num_repeats, caption, False, img_path) - setattr(info, "cond_img_path", cond_img_path) - self.register_image(info, subset) - - subset.img_count = len(img_paths) - self.subsets.append(subset) + extra_imgs = [] + for subset in subsets: + conditioning_img_paths = glob_images(subset.conditioning_data_dir, "*") + extra_imgs.extend( + [cond_img_path for cond_img_path in conditioning_img_paths if cond_img_path not in cond_imgs_with_img] + ) - print(f"{num_train_images} train images with repeating.") - self.num_train_images = num_train_images + assert len(missing_imgs) == 0, f"missing conditioning data for {len(missing_imgs)} images: {missing_imgs}" + assert len(extra_imgs) == 0, f"extra conditioning data for {len(extra_imgs)} images: {extra_imgs}" self.conditioning_image_transforms = transforms.Compose( [ @@ -1614,88 +1628,58 @@ def load_controlnet_dir(subset: ControlNetSubset): ] ) - def __getitem__(self, index): - bucket = self.bucket_manager.buckets[self.buckets_indices[index].bucket_index] - bucket_batch_size = self.buckets_indices[index].bucket_batch_size - image_index = self.buckets_indices[index].batch_index * bucket_batch_size - - loss_weights = [] - captions = [] - input_ids_list = [] - latents_list = [] - images = [] - conditioning_images = [] - - for image_key in bucket[image_index : image_index + bucket_batch_size]: - image_info = self.image_data[image_key] - subset = self.image_to_subset[image_key] - loss_weights.append(1.0) + def make_buckets(self): + self.dreambooth_dataset_delegate.make_buckets() + self.bucket_manager = self.dreambooth_dataset_delegate.bucket_manager + self.buckets_indices = self.dreambooth_dataset_delegate.buckets_indices - assert hasattr(image_info, "cond_img_path"), f"conditioning image path is not found: {image_info.absolute_path}" + def __len__(self): + return self.dreambooth_dataset_delegate.__len__() - # image/latentsを処理する - if image_info.latents is not None: # cache_latents=Trueの場合 - latents = image_info.latents if not subset.flip_aug or random.random() < 0.5 else image_info.latents_flipped - image = None - elif image_info.latents_npz is not None: # FineTuningDatasetまたはcache_latents_to_disk=Trueの場合 - latents = self.load_latents_from_npz(image_info, subset.flip_aug and random.random() >= 0.5) - latents = torch.FloatTensor(latents) - image = None - else: - # 画像を読み込み、必要ならcropする - img = self.load_image(image_info.absolute_path) - cond_img = self.load_image(image_info.cond_img_path) - im_h, im_w = img.shape[0:2] + def __getitem__(self, index): + example = self.dreambooth_dataset_delegate[index] - if self.enable_bucket: - img, cond_img = self.trim_and_resize_if_required(subset, img, image_info.bucket_reso, image_info.resized_size, cond_img=cond_img) - else: - im_h, im_w = img.shape[0:2] - assert ( - im_h == self.height and im_w == self.width - ), f"image size is small / 画像サイズが小さいようです: {image_info.absolute_path}" + bucket = self.dreambooth_dataset_delegate.bucket_manager.buckets[ + self.dreambooth_dataset_delegate.buckets_indices[index].bucket_index + ] + bucket_batch_size = self.dreambooth_dataset_delegate.buckets_indices[index].bucket_batch_size + image_index = self.dreambooth_dataset_delegate.buckets_indices[index].batch_index * bucket_batch_size - # augmentation - aug = self.aug_helper.get_augmentor(subset.color_aug, subset.flip_aug) - if aug is not None: - img = aug(image=img)["image"] + conditioning_images = [] - latents = None - image = self.image_transforms(img) # -1.0~1.0のtorch.Tensorになる + for i, image_key in enumerate(bucket[image_index : image_index + bucket_batch_size]): + image_info = self.dreambooth_dataset_delegate.image_data[image_key] + + target_size_hw = example["target_sizes_hw"][i] + original_size_hw = example["original_sizes_hw"][i] + crop_top_left = example["crop_top_lefts"][i] + flipped = example["flippeds"][i] + cond_img = self.load_image(image_info.cond_img_path) + + if self.dreambooth_dataset_delegate.enable_bucket: + cond_img = cv2.resize(cond_img, image_info.resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ + assert ( + cond_img.shape[0] == original_size_hw[0] and cond_img.shape[1] == original_size_hw[1] + ), f"size of conditioning image is not match / 画像サイズが合いません: {image_info.absolute_path}" + ct, cl = crop_top_left + h, w = target_size_hw + cond_img = cond_img[ct : ct + h, cl : cl + w] + else: + assert ( + cond_img.shape[0] == self.height and cond_img.shape[1] == self.width + ), f"image size is small / 画像サイズが小さいようです: {image_info.absolute_path}" - images.append(image) - latents_list.append(latents) + if flipped: + cond_img = cond_img[:, ::-1, :].copy() # copy to avoid negative stride cond_img = self.conditioning_image_transforms(cond_img) conditioning_images.append(cond_img) - caption = self.process_caption(subset, image_info.caption) - captions.append(caption) - token_caption = self.get_input_ids(caption) - input_ids_list.append(token_caption) - - example = {} - example["loss_weights"] = torch.FloatTensor(loss_weights) - - example["input_ids"] = torch.stack(input_ids_list) - - if images[0] is not None: - images = torch.stack(images) - images = images.to(memory_format=torch.contiguous_format).float() - else: - images = None - example["images"] = images - - example["latents"] = torch.stack(latents_list) if latents_list[0] is not None else None - example["captions"] = captions - - if self.debug_dataset: - example["image_keys"] = bucket[image_index : image_index + self.batch_size] - example["conditioning_images"] = torch.stack(conditioning_images).to(memory_format=torch.contiguous_format).float() return example + # behave as Dataset mock class DatasetGroup(torch.utils.data.ConcatDataset): def __init__(self, datasets: Sequence[Union[DreamBoothDataset, FineTuningDataset]]): @@ -1773,18 +1757,42 @@ def debug_dataset(train_dataset, show_input_ids=False): example = train_dataset[idx] if example["latents"] is not None: print(f"sample has latents from npz file: {example['latents'].size()}") - for j, (ik, cap, lw, iid) in enumerate( - zip(example["image_keys"], example["captions"], example["loss_weights"], example["input_ids"]) + for j, (ik, cap, lw, iid, orgsz, crptl, trgsz, flpdz) in enumerate( + zip( + example["image_keys"], + example["captions"], + example["loss_weights"], + example["input_ids"], + example["original_sizes_hw"], + example["crop_top_lefts"], + example["target_sizes_hw"], + example["flippeds"], + ) ): - print(f'{ik}, size: {train_dataset.image_data[ik].image_size}, loss weight: {lw}, caption: "{cap}"') + print( + f'{ik}, size: {train_dataset.image_data[ik].image_size}, loss weight: {lw}, caption: "{cap}", original size: {orgsz}, crop left top: {crptl}, target size: {trgsz}, flipped: {flpdz}' + ) + if show_input_ids: print(f"input ids: {iid}") + if "input_ids2" in example: + print(f"input ids2: {example['input_ids2'][j]}") if example["images"] is not None: im = example["images"][j] print(f"image size: {im.size()}") im = ((im.numpy() + 1.0) * 127.5).astype(np.uint8) im = np.transpose(im, (1, 2, 0)) # c,H,W -> H,W,c im = im[:, :, ::-1] # RGB -> BGR (OpenCV) + + if "conditioning_images" in example: + cond_img = example["conditioning_images"][j] + print(f"conditioning image size: {cond_img.size()}") + cond_img = (cond_img.numpy() * 255.0).astype(np.uint8) + cond_img = np.transpose(cond_img, (1, 2, 0)) + cond_img = cond_img[:, :, ::-1] + if os.name == "nt": + cv2.imshow("cond_img", cond_img) + if os.name == "nt": # only windows cv2.imshow("img", im) k = cv2.waitKey() @@ -2011,7 +2019,6 @@ def get_git_revision_hash() -> str: return "(unknown)" - # def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers): # replace_attentions_for_hypernetwork() # # unet is not used currently, but it is here for future use @@ -2063,8 +2070,9 @@ def get_git_revision_hash() -> str: # out = self.to_out[1](out) # return out + # diffusers.models.attention.CrossAttention.forward = forward_xformers -def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers, sdpa): +def replace_unet_modules(unet: UNet2DConditionModel, mem_eff_attn, xformers, sdpa): if mem_eff_attn: print("Enable memory efficient attention for U-Net") unet.set_use_memory_efficient_attention(False, True) @@ -2080,6 +2088,7 @@ def replace_unet_modules(unet:UNet2DConditionModel, mem_eff_attn, xformers, sdpa print("Enable SDPA for U-Net") unet.set_use_sdpa(True) + """ def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers): # vae is not used currently, but it is here for future use @@ -2327,7 +2336,11 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: help="use memory efficient attention for CrossAttention / CrossAttentionに省メモリ版attentionを使う", ) parser.add_argument("--xformers", action="store_true", help="use xformers for CrossAttention / CrossAttentionにxformersを使う") - parser.add_argument("--sdpa", action="store_true", help="use sdpa for CrossAttention (requires PyTorch 2.0) / CrossAttentionにsdpaを使う(PyTorch 2.0が必要)") + parser.add_argument( + "--sdpa", + action="store_true", + help="use sdpa for CrossAttention (requires PyTorch 2.0) / CrossAttentionにsdpaを使う(PyTorch 2.0が必要)", + ) parser.add_argument( "--vae", type=str, default=None, help="path to checkpoint of vae to replace / VAEを入れ替える場合、VAEのcheckpointファイルまたはディレクトリ" ) @@ -3231,7 +3244,9 @@ def _load_target_model(args: argparse.Namespace, weight_dtype, device="cpu", une load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers if load_stable_diffusion_format: print(f"load StableDiffusion checkpoint: {name_or_path}") - text_encoder, vae, unet = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, name_or_path, device, unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2) + text_encoder, vae, unet = model_util.load_models_from_stable_diffusion_checkpoint( + args.v2, name_or_path, device, unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2 + ) else: # Diffusers model is loaded to CPU print(f"load Diffusers pretrained models: {name_or_path}") @@ -3281,7 +3296,10 @@ def load_target_model(args, weight_dtype, accelerator, unet_use_linear_projectio print(f"loading model for process {accelerator.state.local_process_index}/{accelerator.state.num_processes}") text_encoder, vae, unet, load_stable_diffusion_format = _load_target_model( - args, weight_dtype, accelerator.device if args.lowram else "cpu", unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2 + args, + weight_dtype, + accelerator.device if args.lowram else "cpu", + unet_use_linear_projection_in_v2=unet_use_linear_projection_in_v2, ) # work on low-ram device @@ -3595,7 +3613,17 @@ def save_sd_model_on_train_end( def sample_images( - accelerator, args: argparse.Namespace, epoch, steps, device, vae, tokenizer, text_encoder, unet, prompt_replacement=None, controlnet=None + accelerator, + args: argparse.Namespace, + epoch, + steps, + device, + vae, + tokenizer, + text_encoder, + unet, + prompt_replacement=None, + controlnet=None, ): """ StableDiffusionLongPromptWeightingPipelineの改造版を使うようにしたので、clip skipおよびプロンプトの重みづけに対応した @@ -3690,7 +3718,7 @@ def sample_images( requires_safety_checker=False, clip_skip=args.clip_skip, ) - pipeline.clip_skip = args.clip_skip # Pipelineのコンストラクタにckip_skipを追加できないので後から設定する + pipeline.clip_skip = args.clip_skip # Pipelineのコンストラクタにckip_skipを追加できないので後から設定する pipeline.to(device) save_dir = args.output_dir + "/sample" @@ -3765,7 +3793,6 @@ def sample_images( controlnet_image = m.group(1) continue - except ValueError as ex: print(f"Exception in parsing / 解析エラー: {parg}") print(ex) From 747af145ed32eb85205dca144a4e49f25032d130 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 08:07:24 +0900 Subject: [PATCH 030/220] add sdxl fine-tuning and LoRA --- library/model_util.py | 10 + library/sdxl_model_util.py | 8 +- library/sdxl_original_unet.py | 12 +- library/sdxl_train_util.py | 384 +++++++++ library/train_util.py | 103 ++- networks/lora.py | 90 +- networks/sdxl_merge_lora.py | 258 ++++++ sdxl_minimal_inference.py | 29 +- sdxl_train.py | 605 ++++++++++++++ sdxl_train_network.py | 172 ++++ train_network.py | 1445 ++++++++++++++++++--------------- 11 files changed, 2402 insertions(+), 714 deletions(-) create mode 100644 library/sdxl_train_util.py create mode 100644 networks/sdxl_merge_lora.py create mode 100644 sdxl_train.py create mode 100644 sdxl_train_network.py diff --git a/library/model_util.py b/library/model_util.py index fce08be8b..938b76929 100644 --- a/library/model_util.py +++ b/library/model_util.py @@ -1061,6 +1061,16 @@ def load_models_from_stable_diffusion_checkpoint(v2, ckpt_path, device="cpu", dt return text_model, vae, unet +def get_model_version_str_for_sd1_sd2(v2, v_parameterization): + # only for reference + version_str = "sd" + if v2: + version_str += "_v2" + else: + version_str += "_v1" + if v_parameterization: + version_str += "_v" + return version_str def convert_text_encoder_state_dict_to_sd_v2(checkpoint, make_dummy_weights=False): def convert_key(key): diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index fc64d21ea..c554782b7 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -6,6 +6,10 @@ from library import sdxl_original_unet +VAE_SCALE_FACTOR = 0.13025 +MODEL_VERSION_SDXL_BASE_V0_9 = "sdxl_base_v0-9" + + def convert_sdxl_text_encoder_2_checkpoint(checkpoint, max_length): SDXL_KEY_PREFIX = "conditioner.embedders.1.model." @@ -76,8 +80,8 @@ def convert_key(key): return new_sd, text_projection, logit_scale -def load_models_from_sdxl_checkpoint(model_type, ckpt_path, map_location): - # model_type is reserved to future use +def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): + # model_version is reserved for future use # Load the state dict if model_util.is_safetensors(ckpt_path): diff --git a/library/sdxl_original_unet.py b/library/sdxl_original_unet.py index fd37432f7..8ba1c988b 100644 --- a/library/sdxl_original_unet.py +++ b/library/sdxl_original_unet.py @@ -1069,8 +1069,8 @@ def forward(self, x, timesteps=None, context=None, y=None, **kwargs): t_emb = t_emb.to(x.dtype) emb = self.time_embed(t_emb) - assert y.shape[0] == x.shape[0] - assert x.dtype == y.dtype + assert x.shape[0] == y.shape[0], f"batch size mismatch: {x.shape[0]} != {y.shape[0]}" + assert x.dtype == y.dtype, f"dtype mismatch: {x.dtype} != {y.dtype}" # assert x.dtype == self.dtype emb = emb + self.label_emb(y) @@ -1105,6 +1105,8 @@ def call_module(module, h, emb, context): if __name__ == "__main__": + import time + print("create unet") unet = SdxlUNet2DConditionModel() @@ -1132,8 +1134,11 @@ def call_module(module, h, emb, context): print("start training") steps = 10 batch_size = 1 + for step in range(steps): print(f"step {step}") + if step == 1: + time_start = time.perf_counter() x = torch.randn(batch_size, 4, 128, 128).cuda() # 1024x1024 t = torch.randint(low=0, high=10, size=(batch_size,), device="cuda") @@ -1149,3 +1154,6 @@ def call_module(module, h, emb, context): scaler.step(optimizer) scaler.update() optimizer.zero_grad(set_to_none=True) + + time_end = time.perf_counter() + print(f"elapsed time: {time_end - time_start} [sec] for last {steps - 1} steps") diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py new file mode 100644 index 000000000..e10488c03 --- /dev/null +++ b/library/sdxl_train_util.py @@ -0,0 +1,384 @@ +import argparse +import gc +import math +import os +from types import SimpleNamespace +from typing import Any +import torch +from tqdm import tqdm +from transformers import CLIPTokenizer +import open_clip +from library import model_util, sdxl_model_util, train_util + +TOKENIZER_PATH = "openai/clip-vit-large-patch14" + +DEFAULT_NOISE_OFFSET = 0.0357 + + +# TODO: separate checkpoint for each U-Net/Text Encoder/VAE +def load_target_model(args, accelerator, model_version: str, weight_dtype): + # load models for each process + for pi in range(accelerator.state.num_processes): + if pi == accelerator.state.local_process_index: + print(f"loading model for process {accelerator.state.local_process_index}/{accelerator.state.num_processes}") + + ( + load_stable_diffusion_format, + text_encoder1, + text_encoder2, + vae, + unet, + text_projection, + logit_scale, + ckpt_info, + ) = _load_target_model(args, model_version, weight_dtype, accelerator.device if args.lowram else "cpu") + + # work on low-ram device + if args.lowram: + text_encoder1.to(accelerator.device) + text_encoder2.to(accelerator.device) + unet.to(accelerator.device) + vae.to(accelerator.device) + + gc.collect() + torch.cuda.empty_cache() + accelerator.wait_for_everyone() + + text_encoder1, text_encoder2, unet = train_util.transform_models_if_DDP([text_encoder1, text_encoder2, unet]) + + return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, text_projection, logit_scale, ckpt_info + + +def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtype, device="cpu"): + # only supports StableDiffusion + name_or_path = args.pretrained_model_name_or_path + name_or_path = os.readlink(name_or_path) if os.path.islink(name_or_path) else name_or_path + load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers + assert ( + load_stable_diffusion_format + ), f"only supports StableDiffusion format for SDXL / SDXLではStableDiffusion形式のみサポートしています: {name_or_path}" + + print(f"load StableDiffusion checkpoint: {name_or_path}") + ( + text_encoder1, + text_encoder2, + vae, + unet, + text_projection, + logit_scale, + ckpt_info, + ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) + + # VAEを読み込む + if args.vae is not None: + vae = model_util.load_vae(args.vae, weight_dtype) + print("additional VAE loaded") + + return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, text_projection, logit_scale, ckpt_info + + +class WrapperTokenizer: + # open clipのtokenizerをHuggingFaceのtokenizerと同じ形で使えるようにする + def __init__(self): + open_clip_tokenizer = open_clip.tokenizer._tokenizer + self.model_max_length = 77 + self.bos_token_id = open_clip_tokenizer.all_special_ids[0] + self.eos_token_id = open_clip_tokenizer.all_special_ids[1] + self.pad_token_id = 0 # 結果から推定している + + def __call__(self, *args: Any, **kwds: Any) -> Any: + return self.tokenize(*args, **kwds) + + def tokenize(self, text, padding, truncation, max_length, return_tensors): + assert padding == "max_length" + assert truncation == True + assert return_tensors == "pt" + input_ids = open_clip.tokenize(text, context_length=max_length) + return SimpleNamespace(**{"input_ids": input_ids}) + + +def load_tokenizers(args: argparse.Namespace): + print("prepare tokenizers") + original_path = TOKENIZER_PATH + + tokenizer1: CLIPTokenizer = None + if args.tokenizer_cache_dir: + local_tokenizer_path = os.path.join(args.tokenizer_cache_dir, original_path.replace("/", "_")) + if os.path.exists(local_tokenizer_path): + print(f"load tokenizer from cache: {local_tokenizer_path}") + tokenizer1 = CLIPTokenizer.from_pretrained(local_tokenizer_path) + + if tokenizer1 is None: + tokenizer1 = CLIPTokenizer.from_pretrained(original_path) + + if args.tokenizer_cache_dir and not os.path.exists(local_tokenizer_path): + print(f"save Tokenizer to cache: {local_tokenizer_path}") + tokenizer1.save_pretrained(local_tokenizer_path) + + if hasattr(args, "max_token_length") and args.max_token_length is not None: + print(f"update token length: {args.max_token_length}") + + # tokenizer2 is from open_clip + # TODO caching + tokenizer2 = WrapperTokenizer() + + return [tokenizer1, tokenizer2] + + +def get_hidden_states( + args: argparse.Namespace, input_ids1, input_ids2, tokenizer1, tokenizer2, text_encoder1, text_encoder2, weight_dtype=None +): + input_ids1 = input_ids1.reshape((-1, tokenizer1.model_max_length)) # batch_size*n, 77 + input_ids2 = input_ids2.reshape((-1, tokenizer2.model_max_length)) # batch_size*n, 77 + + # text_encoder1 + enc_out = text_encoder1(input_ids1, output_hidden_states=True, return_dict=True) + hidden_states1 = enc_out["hidden_states"][11] + + # text_encoder2 + enc_out = text_encoder2(input_ids2, output_hidden_states=True, return_dict=True) + hidden_states2 = enc_out["hidden_states"][-2] # penuultimate layer + pool2 = enc_out["pooler_output"] + + if args.max_token_length is not None: + # bs*3, 77, 768 or 1024 + # encoder1: ... の三連を ... へ戻す + states_list = [hidden_states1[:, 0].unsqueeze(1)] # + for i in range(1, args.max_token_length, tokenizer1.model_max_length): + states_list.append(hidden_states1[:, i : i + tokenizer1.model_max_length - 2]) # の後から の前まで + states_list.append(hidden_states1[:, -1].unsqueeze(1)) # + hidden_states1 = torch.cat(states_list, dim=1) + + # v2: ... ... の三連を ... ... へ戻す 正直この実装でいいのかわからん + states_list = [hidden_states2[:, 0].unsqueeze(1)] # + for i in range(1, args.max_token_length, tokenizer2.model_max_length): + chunk = hidden_states2[:, i : i + tokenizer2.model_max_length - 2] # の後から 最後の前まで + if i > 0: + for j in range(len(chunk)): + if input_ids2[j, 1] == tokenizer2.eos_token: # 空、つまり ...のパターン + chunk[j, 0] = chunk[j, 1] # 次の の値をコピーする + states_list.append(chunk) # の後から の前まで + states_list.append(hidden_states2[:, -1].unsqueeze(1)) # のどちらか + hidden_states2 = torch.cat(states_list, dim=1) + + if weight_dtype is not None: + # this is required for additional network training + hidden_states1 = hidden_states1.to(weight_dtype) + hidden_states2 = hidden_states2.to(weight_dtype) + + return hidden_states1, hidden_states2, pool2 + + +def timestep_embedding(timesteps, dim, max_period=10000): + """ + Create sinusoidal timestep embeddings. + :param timesteps: a 1-D Tensor of N indices, one per batch element. + These may be fractional. + :param dim: the dimension of the output. + :param max_period: controls the minimum frequency of the embeddings. + :return: an [N x dim] Tensor of positional embeddings. + """ + half = dim // 2 + freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to( + device=timesteps.device + ) + args = timesteps[:, None].float() * freqs[None] + embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) + if dim % 2: + embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) + return embedding + + +def get_timestep_embedding(x, outdim): + assert len(x.shape) == 2 + b, dims = x.shape[0], x.shape[1] + x = torch.flatten(x) + emb = timestep_embedding(x, outdim) + emb = torch.reshape(emb, (b, dims * outdim)) + return emb + + +def get_size_embeddings(orig_size, crop_size, target_size, device): + emb1 = get_timestep_embedding(orig_size, 256) + emb2 = get_timestep_embedding(crop_size, 256) + emb3 = get_timestep_embedding(target_size, 256) + vector = torch.cat([emb1, emb2, emb3], dim=1).to(device) + return vector + + +def save_sd_model_on_train_end( + args: argparse.Namespace, + src_path: str, + save_stable_diffusion_format: bool, + use_safetensors: bool, + save_dtype: torch.dtype, + epoch: int, + global_step: int, + text_encoder1, + text_encoder2, + unet, + vae, + text_projection, + logit_scale, + ckpt_info, +): + def sd_saver(ckpt_file, epoch_no, global_step): + sdxl_model_util.save_stable_diffusion_checkpoint( + ckpt_file, + text_encoder1, + text_encoder2, + unet, + epoch_no, + global_step, + ckpt_info, + vae, + text_projection, + logit_scale, + save_dtype, + ) + + def diffusers_saver(out_dir): + raise NotImplementedError("diffusers_saver is not implemented") + + train_util.save_sd_model_on_train_end_common( + args, save_stable_diffusion_format, use_safetensors, epoch, global_step, sd_saver, diffusers_saver + ) + + +# epochとstepの保存、メタデータにepoch/stepが含まれ引数が同じになるため、統合している +# on_epoch_end: Trueならepoch終了時、Falseならstep経過時 +def save_sd_model_on_epoch_end_or_stepwise( + args: argparse.Namespace, + on_epoch_end: bool, + accelerator, + src_path, + save_stable_diffusion_format: bool, + use_safetensors: bool, + save_dtype: torch.dtype, + epoch: int, + num_train_epochs: int, + global_step: int, + text_encoder1, + text_encoder2, + unet, + vae, + text_projection, + logit_scale, + ckpt_info, +): + def sd_saver(ckpt_file, epoch_no, global_step): + sdxl_model_util.save_stable_diffusion_checkpoint( + ckpt_file, + text_encoder1, + text_encoder2, + unet, + epoch_no, + global_step, + ckpt_info, + vae, + text_projection, + logit_scale, + save_dtype, + ) + + def diffusers_saver(out_dir): + raise NotImplementedError("diffusers_saver is not implemented") + + train_util.save_sd_model_on_epoch_end_or_stepwise_common( + args, + on_epoch_end, + accelerator, + save_stable_diffusion_format, + use_safetensors, + epoch, + num_train_epochs, + global_step, + sd_saver, + diffusers_saver, + ) + + +# TextEncoderの出力をキャッシュする +# weight_dtypeを指定するとText Encoderそのもの、およひ出力がweight_dtypeになる +def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, data_loader, weight_dtype): + print("caching text encoder outputs") + + tokenizer1, tokenizer2 = tokenizers + text_encoder1, text_encoder2 = text_encoders + text_encoder1.to(accelerator.device) + text_encoder2.to(accelerator.device) + if weight_dtype is not None: + text_encoder1.to(dtype=weight_dtype) + text_encoder2.to(dtype=weight_dtype) + + text_encoder1_cache = {} + text_encoder2_cache = {} + for batch in tqdm(data_loader): + input_ids1_batch = batch["input_ids"] + input_ids2_batch = batch["input_ids2"] + + # split batch to avoid OOM + # TODO specify batch size by args + for input_ids1, input_ids2 in zip(input_ids1_batch.split(1), input_ids2_batch.split(1)): + # remove input_ids already in cache + input_ids1 = input_ids1.squeeze(0) + input_ids2 = input_ids2.squeeze(0) + input_ids1 = [i for i in input_ids1 if i not in text_encoder1_cache] + input_ids2 = [i for i in input_ids2 if i not in text_encoder2_cache] + assert len(input_ids1) == len(input_ids2) + if len(input_ids1) == 0: + continue + input_ids1 = torch.stack(input_ids1).to(accelerator.device) + input_ids2 = torch.stack(input_ids2).to(accelerator.device) + + with torch.no_grad(): + encoder_hidden_states1, encoder_hidden_states2, pool2 = get_hidden_states( + args, + input_ids1, + input_ids2, + tokenizer1, + tokenizer2, + text_encoder1, + text_encoder2, + None if not args.full_fp16 else weight_dtype, + ) + encoder_hidden_states1 = encoder_hidden_states1.detach().to("cpu") + encoder_hidden_states2 = encoder_hidden_states2.detach().to("cpu") + pool2 = pool2.to("cpu") + for input_id1, input_id2, hidden_states1, hidden_states2, p2 in zip( + input_ids1, input_ids2, encoder_hidden_states1, encoder_hidden_states2, pool2 + ): + text_encoder1_cache[tuple(input_id1.tolist())] = hidden_states1 + text_encoder2_cache[tuple(input_id2.tolist())] = (hidden_states2, p2) + return text_encoder1_cache, text_encoder2_cache + + +def add_sdxl_training_arguments(parser: argparse.ArgumentParser): + parser.add_argument( + "--cache_text_encoder_outputs", action="store_true", help="cache text encoder outputs / text encoderの出力をキャッシュする" + ) + + +def verify_sdxl_training_args(args: argparse.Namespace): + assert ( + not args.v2 and not args.v_parameterization + ), "v2 or v_parameterization cannot be enabled in SDXL training / SDXL学習ではv2とv_parameterizationを有効にすることはできません" + if args.clip_skip is not None: + print("clip_skip will be unexpected / SDXL学習ではclip_skipは動作しません") + + if args.multires_noise_iterations: + print( + f"Warning: SDXL has been trained with noise_offset={DEFAULT_NOISE_OFFSET}, but noise_offset is disabled due to multires_noise_iterations / SDXLはnoise_offset={DEFAULT_NOISE_OFFSET}で学習されていますが、multires_noise_iterationsが有効になっているためnoise_offsetは無効になります" + ) + else: + if args.noise_offset is None: + args.noise_offset = DEFAULT_NOISE_OFFSET + elif args.noise_offset != DEFAULT_NOISE_OFFSET: + print( + f"Waring: SDXL has been trained with noise_offset={DEFAULT_NOISE_OFFSET} / SDXLはnoise_offset={DEFAULT_NOISE_OFFSET}で学習されています" + ) + print(f"noise_offset is set to {args.noise_offset} / noise_offsetが{args.noise_offset}に設定されました") + + assert ( + not args.weighted_captions + ), "weighted_captions cannot be enabled in SDXL training currently / SDXL学習では今のところweighted_captionsを有効にすることはできません" diff --git a/library/train_util.py b/library/train_util.py index 533bf0a9f..e609705e2 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -798,6 +798,19 @@ def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_s def is_latent_cacheable(self): return all([not subset.color_aug and not subset.random_crop for subset in self.subsets]) + def is_text_encoder_output_cacheable(self): + return all( + [ + not ( + subset.caption_dropout_rate > 0 + or subset.shuffle_caption + or subset.token_warmup_step > 0 + or subset.caption_tag_dropout_rate > 0 + ) + for subset in self.subsets + ] + ) + def is_disk_cached_latents_is_expected(self, reso, npz_path, flipped_npz_path): expected_latents_size = (reso[1] // 8, reso[0] // 8) # bucket_resoはWxHなので注意 @@ -850,7 +863,7 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc continue cache_available = self.is_disk_cached_latents_is_expected( - info.bucket_reso, info.latents_npz, info.latents_npz_flipped if self.flip_aug else None + info.bucket_reso, info.latents_npz, info.latents_npz_flipped if subset.flip_aug else None ) if cache_available: # do not add to batch @@ -1719,6 +1732,9 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc def is_latent_cacheable(self) -> bool: return all([dataset.is_latent_cacheable() for dataset in self.datasets]) + def is_text_encoder_output_cacheable(self) -> bool: + return all([dataset.is_text_encoder_output_cacheable() for dataset in self.datasets]) + def set_current_epoch(self, epoch): for dataset in self.datasets: dataset.set_current_epoch(epoch) @@ -3284,11 +3300,17 @@ def _load_target_model(args: argparse.Namespace, weight_dtype, device="cpu", une return text_encoder, vae, unet, load_stable_diffusion_format +# TODO remove this function in the future def transform_if_model_is_DDP(text_encoder, unet, network=None): # Transform text_encoder, unet and network from DistributedDataParallel return (model.module if type(model) == DDP else model for model in [text_encoder, unet, network] if model is not None) +def transform_models_if_DDP(models): + # Transform text_encoder, unet and network from DistributedDataParallel + return [model.module if type(model) == DDP else model for model in models if model is not None] + + def load_target_model(args, weight_dtype, accelerator, unet_use_linear_projection_in_v2=False): # load models for each process for pi in range(accelerator.state.num_processes): @@ -3430,6 +3452,42 @@ def save_sd_model_on_epoch_end_or_stepwise( text_encoder, unet, vae, +): + def sd_saver(ckpt_file, epoch_no, global_step): + model_util.save_stable_diffusion_checkpoint( + args.v2, ckpt_file, text_encoder, unet, src_path, epoch_no, global_step, save_dtype, vae + ) + + def diffusers_saver(out_dir): + model_util.save_diffusers_checkpoint( + args.v2, out_dir, text_encoder, unet, src_path, vae=vae, use_safetensors=use_safetensors + ) + + save_sd_model_on_epoch_end_or_stepwise_common( + args, + on_epoch_end, + accelerator, + save_stable_diffusion_format, + use_safetensors, + epoch, + num_train_epochs, + global_step, + sd_saver, + diffusers_saver, + ) + + +def save_sd_model_on_epoch_end_or_stepwise_common( + args: argparse.Namespace, + on_epoch_end: bool, + accelerator, + save_stable_diffusion_format: bool, + use_safetensors: bool, + epoch: int, + num_train_epochs: int, + global_step: int, + sd_saver, + diffusers_saver, ): if on_epoch_end: epoch_no = epoch + 1 @@ -3457,9 +3515,7 @@ def save_sd_model_on_epoch_end_or_stepwise( ckpt_file = os.path.join(args.output_dir, ckpt_name) print(f"\nsaving checkpoint: {ckpt_file}") - model_util.save_stable_diffusion_checkpoint( - args.v2, ckpt_file, text_encoder, unet, src_path, epoch_no, global_step, save_dtype, vae - ) + sd_saver(ckpt_file, epoch_no, global_step) if args.huggingface_repo_id is not None: huggingface_util.upload(args, ckpt_file, "/" + ckpt_name) @@ -3483,9 +3539,8 @@ def save_sd_model_on_epoch_end_or_stepwise( out_dir = os.path.join(args.output_dir, STEP_DIFFUSERS_DIR_NAME.format(model_name, global_step)) print(f"\nsaving model: {out_dir}") - model_util.save_diffusers_checkpoint( - args.v2, out_dir, text_encoder, unet, src_path, vae=vae, use_safetensors=use_safetensors - ) + diffusers_saver(out_dir) + if args.huggingface_repo_id is not None: huggingface_util.upload(args, out_dir, "/" + model_name) @@ -3578,6 +3633,30 @@ def save_sd_model_on_train_end( text_encoder, unet, vae, +): + def sd_saver(ckpt_file, epoch_no, global_step): + model_util.save_stable_diffusion_checkpoint( + args.v2, ckpt_file, text_encoder, unet, src_path, epoch_no, global_step, save_dtype, vae + ) + + def diffusers_saver(out_dir): + model_util.save_diffusers_checkpoint( + args.v2, out_dir, text_encoder, unet, src_path, vae=vae, use_safetensors=use_safetensors + ) + + save_sd_model_on_train_end_common( + args, save_stable_diffusion_format, use_safetensors, epoch, global_step, sd_saver, diffusers_saver + ) + + +def save_sd_model_on_train_end_common( + args: argparse.Namespace, + save_stable_diffusion_format: bool, + use_safetensors: bool, + epoch: int, + global_step: int, + sd_saver, + diffusers_saver, ): model_name = default_if_none(args.output_name, DEFAULT_LAST_OUTPUT_NAME) @@ -3588,9 +3667,8 @@ def save_sd_model_on_train_end( ckpt_file = os.path.join(args.output_dir, ckpt_name) print(f"save trained model as StableDiffusion checkpoint to {ckpt_file}") - model_util.save_stable_diffusion_checkpoint( - args.v2, ckpt_file, text_encoder, unet, src_path, epoch, global_step, save_dtype, vae - ) + sd_saver(ckpt_file, epoch, global_step) + if args.huggingface_repo_id is not None: huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=True) else: @@ -3598,9 +3676,8 @@ def save_sd_model_on_train_end( os.makedirs(out_dir, exist_ok=True) print(f"save trained model as Diffusers to {out_dir}") - model_util.save_diffusers_checkpoint( - args.v2, out_dir, text_encoder, unet, src_path, vae=vae, use_safetensors=use_safetensors - ) + diffusers_saver(out_dir) + if args.huggingface_repo_id is not None: huggingface_util.upload(args, out_dir, "/" + model_name, force_sync_upload=True) diff --git a/networks/lora.py b/networks/lora.py index 10c5a07f4..b6788b995 100644 --- a/networks/lora.py +++ b/networks/lora.py @@ -5,7 +5,9 @@ import math import os -from typing import List, Tuple, Union +from typing import Dict, List, Optional, Tuple, Type, Union +from diffusers import AutoencoderKL +from transformers import CLIPTextModel import numpy as np import torch import re @@ -400,7 +402,16 @@ def parse_block_lr_kwargs(nw_kwargs): return down_lr_weight, mid_lr_weight, up_lr_weight -def create_network(multiplier, network_dim, network_alpha, vae, text_encoder, unet, neuron_dropout=None, **kwargs): +def create_network( + multiplier: float, + network_dim: Optional[int], + network_alpha: Optional[float], + vae: AutoencoderKL, + text_encoder: Union[CLIPTextModel, List[CLIPTextModel]], + unet, + neuron_dropout: Optional[float] = None, + **kwargs, +): if network_dim is None: network_dim = 4 # default if network_alpha is None: @@ -719,33 +730,36 @@ def create_network_from_weights(multiplier, file, vae, text_encoder, unet, weigh class LoRANetwork(torch.nn.Module): NUM_OF_BLOCKS = 12 # フルモデル相当でのup,downの層の数 - # is it possible to apply conv_in and conv_out? -> yes, newer LoCon supports it (^^;) UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel"] UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 = ["ResnetBlock2D", "Downsample2D", "Upsample2D"] TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"] LORA_PREFIX_UNET = "lora_unet" LORA_PREFIX_TEXT_ENCODER = "lora_te" + + # SDXL: must starts with LORA_PREFIX_TEXT_ENCODER + LORA_PREFIX_TEXT_ENCODER1 = "lora_te1" + LORA_PREFIX_TEXT_ENCODER2 = "lora_te2" def __init__( self, - text_encoder, + text_encoder: Union[List[CLIPTextModel], CLIPTextModel], unet, - multiplier=1.0, - lora_dim=4, - alpha=1, - dropout=None, - rank_dropout=None, - module_dropout=None, - conv_lora_dim=None, - conv_alpha=None, - block_dims=None, - block_alphas=None, - conv_block_dims=None, - conv_block_alphas=None, - modules_dim=None, - modules_alpha=None, - module_class=LoRAModule, - varbose=False, + multiplier: float = 1.0, + lora_dim: int = 4, + alpha: float = 1, + dropout: Optional[float] = None, + rank_dropout: Optional[float] = None, + module_dropout: Optional[float] = None, + conv_lora_dim: Optional[int] = None, + conv_alpha: Optional[float] = None, + block_dims: Optional[List[int]] = None, + block_alphas: Optional[List[float]] = None, + conv_block_dims: Optional[List[int]] = None, + conv_block_alphas: Optional[List[float]] = None, + modules_dim: Optional[Dict[str, int]] = None, + modules_alpha: Optional[Dict[str, int]] = None, + module_class: Type[object] = LoRAModule, + varbose: Optional[bool] = False, ) -> None: """ LoRA network: すごく引数が多いが、パターンは以下の通り @@ -783,8 +797,21 @@ def __init__( print(f"apply LoRA to Conv2d with kernel size (3,3). dim (rank): {self.conv_lora_dim}, alpha: {self.conv_alpha}") # create module instances - def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules) -> List[LoRAModule]: - prefix = LoRANetwork.LORA_PREFIX_UNET if is_unet else LoRANetwork.LORA_PREFIX_TEXT_ENCODER + def create_modules( + is_unet: bool, + text_encoder_idx: Optional[int], # None, 1, 2 + root_module: torch.nn.Module, + target_replace_modules: List[torch.nn.Module], + ) -> List[LoRAModule]: + prefix = ( + self.LORA_PREFIX_UNET + if is_unet + else ( + self.LORA_PREFIX_TEXT_ENCODER + if text_encoder_idx is None + else (self.LORA_PREFIX_TEXT_ENCODER1 if text_encoder_idx == 1 else self.LORA_PREFIX_TEXT_ENCODER2) + ) + ) loras = [] skipped = [] for name, module in root_module.named_modules(): @@ -800,11 +827,14 @@ def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules dim = None alpha = None + if modules_dim is not None: + # モジュール指定あり if lora_name in modules_dim: dim = modules_dim[lora_name] alpha = modules_alpha[lora_name] elif is_unet and block_dims is not None: + # U-Netでblock_dims指定あり block_idx = get_block_index(lora_name) if is_linear or is_conv2d_1x1: dim = block_dims[block_idx] @@ -813,6 +843,7 @@ def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules dim = conv_block_dims[block_idx] alpha = conv_block_alphas[block_idx] else: + # 通常、すべて対象とする if is_linear or is_conv2d_1x1: dim = self.lora_dim alpha = self.alpha @@ -821,6 +852,7 @@ def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules alpha = self.conv_alpha if dim is None or dim == 0: + # skipした情報を出力 if is_linear or is_conv2d_1x1 or (self.conv_lora_dim is not None or conv_block_dims is not None): skipped.append(lora_name) continue @@ -838,7 +870,16 @@ def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules loras.append(lora) return loras, skipped - self.text_encoder_loras, skipped_te = create_modules(False, text_encoder, LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE) + text_encoders = text_encoder if type(text_encoder) == list else [text_encoder] + + # create LoRA for text encoder + # 毎回すべてのモジュールを作るのは無駄なので要検討 + self.text_encoder_loras = [] + skipped_te = [] + for i, text_encoder in enumerate(text_encoders): + text_encoder_loras, skipped = create_modules(False, i + 1, text_encoder, LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE) + self.text_encoder_loras.extend(text_encoder_loras) + skipped_te += skipped print(f"create LoRA for Text Encoder: {len(self.text_encoder_loras)} modules.") # extend U-Net target modules if conv2d 3x3 is enabled, or load from weights @@ -846,7 +887,7 @@ def create_modules(is_unet, root_module: torch.nn.Module, target_replace_modules if modules_dim is not None or self.conv_lora_dim is not None or conv_block_dims is not None: target_modules += LoRANetwork.UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 - self.unet_loras, skipped_un = create_modules(True, unet, target_modules) + self.unet_loras, skipped_un = create_modules(True, None, unet, target_modules) print(f"create LoRA for U-Net: {len(self.unet_loras)} modules.") skipped = skipped_te + skipped_un @@ -961,6 +1002,7 @@ def get_lr_weight(self, lora: LoRAModule) -> float: return lr_weight + # 二つのText Encoderに別々の学習率を設定できるようにするといいかも def prepare_optimizer_params(self, text_encoder_lr, unet_lr, default_lr): self.requires_grad_(True) all_params = [] diff --git a/networks/sdxl_merge_lora.py b/networks/sdxl_merge_lora.py new file mode 100644 index 000000000..0fc3f9c59 --- /dev/null +++ b/networks/sdxl_merge_lora.py @@ -0,0 +1,258 @@ +import math +import argparse +import os +import torch +from safetensors.torch import load_file, save_file +from tqdm import tqdm +from library import sdxl_model_util +import library.model_util as model_util +import lora + + +def load_state_dict(file_name, dtype): + if os.path.splitext(file_name)[1] == ".safetensors": + sd = load_file(file_name) + else: + sd = torch.load(file_name, map_location="cpu") + for key in list(sd.keys()): + if type(sd[key]) == torch.Tensor: + sd[key] = sd[key].to(dtype) + return sd + + +def save_to_file(file_name, model, state_dict, dtype): + if dtype is not None: + for key in list(state_dict.keys()): + if type(state_dict[key]) == torch.Tensor: + state_dict[key] = state_dict[key].to(dtype) + + if os.path.splitext(file_name)[1] == ".safetensors": + save_file(model, file_name) + else: + torch.save(model, file_name) + + +def merge_to_sd_model(text_encoder1, text_encoder2, unet, models, ratios, merge_dtype): + text_encoder1.to(merge_dtype) + text_encoder1.to(merge_dtype) + unet.to(merge_dtype) + + # create module map + name_to_module = {} + for i, root_module in enumerate([text_encoder1, text_encoder2, unet]): + if i <= 1: + if i == 0: + prefix = lora.LoRANetwork.LORA_PREFIX_TEXT_ENCODER1 + else: + prefix = lora.LoRANetwork.LORA_PREFIX_TEXT_ENCODER2 + target_replace_modules = lora.LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE + else: + prefix = lora.LoRANetwork.LORA_PREFIX_UNET + target_replace_modules = ( + lora.LoRANetwork.UNET_TARGET_REPLACE_MODULE + lora.LoRANetwork.UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 + ) + + for name, module in root_module.named_modules(): + if module.__class__.__name__ in target_replace_modules: + for child_name, child_module in module.named_modules(): + if child_module.__class__.__name__ == "Linear" or child_module.__class__.__name__ == "Conv2d": + lora_name = prefix + "." + name + "." + child_name + lora_name = lora_name.replace(".", "_") + name_to_module[lora_name] = child_module + + for model, ratio in zip(models, ratios): + print(f"loading: {model}") + lora_sd = load_state_dict(model, merge_dtype) + + print(f"merging...") + for key in tqdm(lora_sd.keys()): + if "lora_down" in key: + up_key = key.replace("lora_down", "lora_up") + alpha_key = key[: key.index("lora_down")] + "alpha" + + # find original module for this lora + module_name = ".".join(key.split(".")[:-2]) # remove trailing ".lora_down.weight" + if module_name not in name_to_module: + print(f"no module found for LoRA weight: {key}") + continue + module = name_to_module[module_name] + # print(f"apply {key} to {module}") + + down_weight = lora_sd[key] + up_weight = lora_sd[up_key] + + dim = down_weight.size()[0] + alpha = lora_sd.get(alpha_key, dim) + scale = alpha / dim + + # W <- W + U * D + weight = module.weight + # print(module_name, down_weight.size(), up_weight.size()) + if len(weight.size()) == 2: + # linear + weight = weight + ratio * (up_weight @ down_weight) * scale + elif down_weight.size()[2:4] == (1, 1): + # conv2d 1x1 + weight = ( + weight + + ratio + * (up_weight.squeeze(3).squeeze(2) @ down_weight.squeeze(3).squeeze(2)).unsqueeze(2).unsqueeze(3) + * scale + ) + else: + # conv2d 3x3 + conved = torch.nn.functional.conv2d(down_weight.permute(1, 0, 2, 3), up_weight).permute(1, 0, 2, 3) + # print(conved.size(), weight.size(), module.stride, module.padding) + weight = weight + ratio * conved * scale + + module.weight = torch.nn.Parameter(weight) + + +def merge_lora_models(models, ratios, merge_dtype): + base_alphas = {} # alpha for merged model + base_dims = {} + + merged_sd = {} + for model, ratio in zip(models, ratios): + print(f"loading: {model}") + lora_sd = load_state_dict(model, merge_dtype) + + # get alpha and dim + alphas = {} # alpha for current model + dims = {} # dims for current model + for key in lora_sd.keys(): + if "alpha" in key: + lora_module_name = key[: key.rfind(".alpha")] + alpha = float(lora_sd[key].detach().numpy()) + alphas[lora_module_name] = alpha + if lora_module_name not in base_alphas: + base_alphas[lora_module_name] = alpha + elif "lora_down" in key: + lora_module_name = key[: key.rfind(".lora_down")] + dim = lora_sd[key].size()[0] + dims[lora_module_name] = dim + if lora_module_name not in base_dims: + base_dims[lora_module_name] = dim + + for lora_module_name in dims.keys(): + if lora_module_name not in alphas: + alpha = dims[lora_module_name] + alphas[lora_module_name] = alpha + if lora_module_name not in base_alphas: + base_alphas[lora_module_name] = alpha + + print(f"dim: {list(set(dims.values()))}, alpha: {list(set(alphas.values()))}") + + # merge + print(f"merging...") + for key in tqdm(lora_sd.keys()): + if "alpha" in key: + continue + + lora_module_name = key[: key.rfind(".lora_")] + + base_alpha = base_alphas[lora_module_name] + alpha = alphas[lora_module_name] + + scale = math.sqrt(alpha / base_alpha) * ratio + + if key in merged_sd: + assert ( + merged_sd[key].size() == lora_sd[key].size() + ), f"weights shape mismatch merging v1 and v2, different dims? / 重みのサイズが合いません。v1とv2、または次元数の異なるモデルはマージできません" + merged_sd[key] = merged_sd[key] + lora_sd[key] * scale + else: + merged_sd[key] = lora_sd[key] * scale + + # set alpha to sd + for lora_module_name, alpha in base_alphas.items(): + key = lora_module_name + ".alpha" + merged_sd[key] = torch.tensor(alpha) + + print("merged model") + print(f"dim: {list(set(base_dims.values()))}, alpha: {list(set(base_alphas.values()))}") + + return merged_sd + + +def merge(args): + assert len(args.models) == len(args.ratios), f"number of models must be equal to number of ratios / モデルの数と重みの数は合わせてください" + + def str_to_dtype(p): + if p == "float": + return torch.float + if p == "fp16": + return torch.float16 + if p == "bf16": + return torch.bfloat16 + return None + + merge_dtype = str_to_dtype(args.precision) + save_dtype = str_to_dtype(args.save_precision) + if save_dtype is None: + save_dtype = merge_dtype + + if args.sd_model is not None: + print(f"loading SD model: {args.sd_model}") + + ( + text_model1, + text_model2, + vae, + unet, + text_projection, + logit_scale, + ckpt_info, + ) = sdxl_model_util.load_models_from_sdxl_checkpoint(sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.sd_model, "cpu") + + merge_to_sd_model(text_model2, text_model2, unet, args.models, args.ratios, merge_dtype) + + print(f"saving SD model to: {args.save_to}") + sdxl_model_util.save_stable_diffusion_checkpoint( + args.save_to, text_model1, text_model2, unet, 0, 0, ckpt_info, vae, text_projection, logit_scale, save_dtype + ) + else: + state_dict = merge_lora_models(args.models, args.ratios, merge_dtype) + + print(f"saving model to: {args.save_to}") + save_to_file(args.save_to, state_dict, state_dict, save_dtype) + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + parser.add_argument( + "--save_precision", + type=str, + default=None, + choices=[None, "float", "fp16", "bf16"], + help="precision in saving, same to merging if omitted / 保存時に精度を変更して保存する、省略時はマージ時の精度と同じ", + ) + parser.add_argument( + "--precision", + type=str, + default="float", + choices=["float", "fp16", "bf16"], + help="precision in merging (float is recommended) / マージの計算時の精度(floatを推奨)", + ) + parser.add_argument( + "--sd_model", + type=str, + default=None, + help="Stable Diffusion model to load: ckpt or safetensors file, merge LoRA models if omitted / 読み込むモデル、ckptまたはsafetensors。省略時はLoRAモデル同士をマージする", + ) + parser.add_argument( + "--save_to", type=str, default=None, help="destination file name: ckpt or safetensors file / 保存先のファイル名、ckptまたはsafetensors" + ) + parser.add_argument( + "--models", type=str, nargs="*", help="LoRA models to merge: ckpt or safetensors file / マージするLoRAモデル、ckptまたはsafetensors" + ) + parser.add_argument("--ratios", type=float, nargs="*", help="ratios for each model / それぞれのLoRAモデルの比率") + + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + merge(args) diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index f8e7d687b..2f3670df5 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -11,10 +11,13 @@ import torch from tqdm import tqdm from transformers import CLIPTokenizer -from library import sdxl_model_util from diffusers import EulerDiscreteScheduler from PIL import Image import open_clip +from safetensors.torch import load_file + +from library import model_util, sdxl_model_util +import networks.lora as lora # scheduler: このあたりの設定はSD1/2と同じでいいらしい # scheduler: The settings around here seem to be the same as SD1/2 @@ -85,6 +88,13 @@ def get_timestep_embedding(x, outdim): parser.add_argument("--prompt", type=str, default="A photo of a cat") parser.add_argument("--negative_prompt", type=str, default="") parser.add_argument("--output_dir", type=str, default=".") + parser.add_argument( + "--lora_weights", + type=str, + nargs="*", + default=[], + help="LoRA weights, only supports networks.lora, each arguement is a `path;multiplier` (semi-colon separated)", + ) args = parser.parse_args() # HuggingFaceのmodel id @@ -97,7 +107,7 @@ def get_timestep_embedding(x, outdim): # 本体RAMが少ない場合はGPUにロードするといいかも # If the main RAM is small, it may be better to load it on the GPU text_model1, text_model2, vae, unet, text_projection, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( - "sdxl_base_v0-9", args.ckpt_path, "cpu" + sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.ckpt_path, "cpu" ) # Text Encoder 1はSDXL本体でもHuggingFaceのものを使っている @@ -134,6 +144,19 @@ def get_timestep_embedding(x, outdim): unet.set_use_memory_efficient_attention(True, False) + # LoRA + for weights_file in args.lora_weights: + if ";" in weights_file: + weights_file, multiplier = weights_file.split(";") + multiplier = float(multiplier) + else: + multiplier = 1.0 + + lora_model, weights_sd = lora.create_network_from_weights( + multiplier, weights_file, vae, [text_model1, text_model2], unet, None, True + ) + lora_model.merge_to([text_model1, text_model2], unet, weights_sd, DTYPE, DEVICE) + # prepare embedding with torch.no_grad(): # vector @@ -248,7 +271,7 @@ def call_text_encoder(text): latents = scheduler.step(noise_pred, t, latents).prev_sample # latents = 1 / 0.18215 * latents - latents = 1 / 0.13025 * latents + latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents latents = latents.to(torch.float32) image = vae.decode(latents).sample image = (image / 2 + 0.5).clamp(0, 1) diff --git a/sdxl_train.py b/sdxl_train.py new file mode 100644 index 000000000..2683038b5 --- /dev/null +++ b/sdxl_train.py @@ -0,0 +1,605 @@ +# training with captions + +import argparse +import gc +import math +import os +from multiprocessing import Value + +from tqdm import tqdm +import torch +from accelerate.utils import set_seed +from diffusers import DDPMScheduler +from library import sdxl_model_util + +import library.train_util as train_util +import library.config_util as config_util +import library.sdxl_train_util as sdxl_train_util +from library.config_util import ( + ConfigSanitizer, + BlueprintGenerator, +) +import library.custom_train_functions as custom_train_functions +from library.custom_train_functions import ( + apply_snr_weight, + prepare_scheduler_for_custom_training, + pyramid_noise_like, + apply_noise_offset, + scale_v_prediction_loss_like_noise_prediction, +) +from library.sdxl_original_unet import SdxlUNet2DConditionModel + + +def train(args): + train_util.verify_training_args(args) + train_util.prepare_dataset_args(args, True) + sdxl_train_util.verify_sdxl_training_args(args) + + assert not args.weighted_captions, "weighted_captions is not supported currently / weighted_captionsは現在サポートされていません" + assert ( + not args.train_text_encoder or not args.cache_text_encoder_outputs + ), "cache_text_encoder_outputs is not supported when training text encoder / text encoderを学習するときはcache_text_encoder_outputsはサポートされていません" + + cache_latents = args.cache_latents + + if args.seed is not None: + set_seed(args.seed) # 乱数系列を初期化する + + tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) + + # データセットを準備する + if args.dataset_class is None: + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) + if args.dataset_config is not None: + print(f"Load dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "in_json"] + if any(getattr(args, attr) is not None for attr in ignored): + print( + "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=[tokenizer1, tokenizer2]) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) + else: + train_dataset_group = train_util.load_arbitrary_dataset(args, [tokenizer1, tokenizer2]) + + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + if args.debug_dataset: + train_util.debug_dataset(train_dataset_group, True) + return + if len(train_dataset_group) == 0: + print( + "No data found. Please verify the metadata file and train_data_dir option. / 画像がありません。メタデータおよびtrain_data_dirオプションを確認してください。" + ) + return + + if cache_latents: + assert ( + train_dataset_group.is_latent_cacheable() + ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" + + if args.cache_text_encoder_outputs: + assert ( + train_dataset_group.is_text_encoder_output_cacheable() + ), "when caching text encoder output, either caption_dropout_rate, shuffle_caption, token_warmup_step or caption_tag_dropout_rate cannot be used / text encoderの出力をキャッシュするときはcaption_dropout_rate, shuffle_caption, token_warmup_step, caption_tag_dropout_rateは使えません" + + # acceleratorを準備する + print("prepare accelerator") + accelerator = train_util.prepare_accelerator(args) + + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, save_dtype = train_util.prepare_dtype(args) + + # モデルを読み込む + ( + load_stable_diffusion_format, + text_encoder1, + text_encoder2, + vae, + unet, + text_projection, + logit_scale, + ckpt_info, + ) = sdxl_train_util.load_target_model(args, accelerator, "sdxl", weight_dtype) + text_projection = text_projection.to(accelerator.device, dtype=weight_dtype) + logit_scale = logit_scale.to(accelerator.device, dtype=weight_dtype) + + # verify load/save model formats + if load_stable_diffusion_format: + src_stable_diffusion_ckpt = args.pretrained_model_name_or_path + src_diffusers_model_path = None + else: + src_stable_diffusion_ckpt = None + src_diffusers_model_path = args.pretrained_model_name_or_path + + if args.save_model_as is None: + save_stable_diffusion_format = load_stable_diffusion_format + use_safetensors = args.use_safetensors + else: + save_stable_diffusion_format = args.save_model_as.lower() == "ckpt" or args.save_model_as.lower() == "safetensors" + use_safetensors = args.use_safetensors or ("safetensors" in args.save_model_as.lower()) + assert save_stable_diffusion_format, "save_model_as must be ckpt or safetensors / save_model_asはckptかsafetensorsである必要があります" + + # Diffusers版のxformers使用フラグを設定する関数 + def set_diffusers_xformers_flag(model, valid): + def fn_recursive_set_mem_eff(module: torch.nn.Module): + if hasattr(module, "set_use_memory_efficient_attention_xformers"): + module.set_use_memory_efficient_attention_xformers(valid) + + for child in module.children(): + fn_recursive_set_mem_eff(child) + + fn_recursive_set_mem_eff(model) + + # モデルに xformers とか memory efficient attention を組み込む + if args.diffusers_xformers: + # もうU-Netを独自にしたので動かないけどVAEのxformersは動くはず + accelerator.print("Use xformers by Diffusers") + # set_diffusers_xformers_flag(unet, True) + set_diffusers_xformers_flag(vae, True) + else: + # Windows版のxformersはfloatで学習できなかったりxformersを使わない設定も可能にしておく必要がある + accelerator.print("Disable Diffusers' xformers") + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) + vae.set_use_memory_efficient_attention_xformers(args.xformers) + + # 学習を準備する + if cache_latents: + # vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=torch.float32) # VAE in float to avoid NaN + vae.requires_grad_(False) + vae.eval() + with torch.no_grad(): + train_dataset_group.cache_latents(vae, args.vae_batch_size, args.cache_latents_to_disk, accelerator.is_main_process) + vae.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + gc.collect() + + accelerator.wait_for_everyone() + + # 学習を準備する:モデルを適切な状態にする + training_models = [] + if args.gradient_checkpointing: + unet.enable_gradient_checkpointing() + training_models.append(unet) + + if args.train_text_encoder: + # TODO each option for two text encoders? + accelerator.print("enable text encoder training") + if args.gradient_checkpointing: + text_encoder1.gradient_checkpointing_enable() + text_encoder2.gradient_checkpointing_enable() + training_models.append(text_encoder1) + training_models.append(text_encoder2) + else: + text_encoder1.requires_grad_(False) + text_encoder2.requires_grad_(False) + text_encoder1.eval() + text_encoder2.eval() + + if not cache_latents: + vae.requires_grad_(False) + vae.eval() + vae.to(accelerator.device, dtype=weight_dtype) + + for m in training_models: + m.requires_grad_(True) + params = [] + for m in training_models: + params.extend(m.parameters()) + params_to_optimize = params + + # calculate number of trainable parameters + n_params = 0 + for p in params: + n_params += p.numel() + accelerator.print(f"number of models: {len(training_models)}") + accelerator.print(f"number of trainable parameters: {n_params}") + + # 学習に必要なクラスを準備する + accelerator.print("prepare optimizer, data loader etc.") + _, _, optimizer = train_util.get_optimizer(args, trainable_params=params_to_optimize) + + # dataloaderを準備する + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, + ) + + # 学習ステップ数を計算する + if args.max_train_epochs is not None: + args.max_train_steps = args.max_train_epochs * math.ceil( + len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps + ) + accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + + # データセット側にも学習ステップを送信 + train_dataset_group.set_max_train_steps(args.max_train_steps) + + # lr schedulerを用意する + lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) + + # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする + if args.full_fp16: + assert ( + args.mixed_precision == "fp16" + ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" + accelerator.print("enable full fp16 training.") + unet.to(weight_dtype) + text_encoder1.to(weight_dtype) + text_encoder2.to(weight_dtype) + + # acceleratorがなんかよろしくやってくれるらしい + if args.train_text_encoder: + unet, text_encoder1, text_encoder2, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + unet, text_encoder1, text_encoder2, optimizer, train_dataloader, lr_scheduler + ) + + # transform DDP after prepare + text_encoder1, text_encoder2, unet = train_util.transform_models_if_DDP([text_encoder1, text_encoder2, unet]) + else: + unet, optimizer, train_dataloader, lr_scheduler = accelerator.prepare(unet, optimizer, train_dataloader, lr_scheduler) + (unet,) = train_util.transform_models_if_DDP([unet]) + text_encoder1.to(weight_dtype) + text_encoder2.to(weight_dtype) + text_encoder1.eval() + text_encoder2.eval() + + # TextEncoderの出力をキャッシュする + if args.cache_text_encoder_outputs: + text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( + args, accelerator, (tokenizer1, tokenizer2), (text_encoder1, text_encoder2), train_dataloader, None + ) + accelerator.wait_for_everyone() + text_encoder1.to("cpu") + text_encoder2.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + else: + text_encoder1_cache = None + text_encoder2_cache = None + text_encoder1.to(accelerator.device) + text_encoder2.to(accelerator.device) + + # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする + if args.full_fp16: + train_util.patch_accelerator_for_fp16_training(accelerator) + + # resumeする + train_util.resume_from_local_or_hf_if_specified(accelerator, args) + + # epoch数を計算する + num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) + num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) + if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): + args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 + + # 学習する + total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps + accelerator.print("running training / 学習開始") + accelerator.print(f" num examples / サンプル数: {train_dataset_group.num_train_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") + accelerator.print( + f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + ) + accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + + progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") + global_step = 0 + + noise_scheduler = DDPMScheduler( + beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False + ) + prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + + if accelerator.is_main_process: + accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) + + for epoch in range(num_train_epochs): + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") + current_epoch.value = epoch + 1 + + for m in training_models: + m.train() + + loss_total = 0 + for step, batch in enumerate(train_dataloader): + current_step.value = global_step + # with accelerator.accumulate(training_models[0]): # 複数モデルに対応していない模様だがとりあえずこうしておく + if True: + if "latents" in batch and batch["latents"] is not None: + latents = batch["latents"].to(accelerator.device).to(dtype=weight_dtype) + else: + with torch.no_grad(): + # latentに変換 + # latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() + latents = vae.encode(batch["images"].to(torch.float32)).latent_dist.sample().to(weight_dtype) + latents = latents * sdxl_model_util.VAE_SCALE_FACTOR + b_size = latents.shape[0] + + input_ids1 = batch["input_ids"] + input_ids2 = batch["input_ids2"] + if not args.cache_text_encoder_outputs: + with torch.set_grad_enabled(args.train_text_encoder): + # Get the text embedding for conditioning + # TODO support weighted captions + # if args.weighted_captions: + # encoder_hidden_states = get_weighted_text_embeddings( + # tokenizer, + # text_encoder, + # batch["captions"], + # accelerator.device, + # args.max_token_length // 75 if args.max_token_length else 1, + # clip_skip=args.clip_skip, + # ) + # else: + input_ids1 = input_ids1.to(accelerator.device) + input_ids2 = input_ids2.to(accelerator.device) + encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( + args, + input_ids1, + input_ids2, + tokenizer1, + tokenizer2, + text_encoder1, + text_encoder2, + None if not args.full_fp16 else weight_dtype, + ) + pool2 = pool2 @ text_projection.to(pool2.dtype) + else: + encoder_hidden_states1 = [] + encoder_hidden_states2 = [] + pool2 = [] + for input_id1, input_id2 in zip(input_ids1, input_ids2): + input_id1 = input_id1.squeeze(0) + input_id2 = input_id2.squeeze(0) + encoder_hidden_states1.append(text_encoder1_cache[tuple(input_id1.tolist())]) + hidden_states2, p2 = text_encoder2_cache[tuple(input_id2.tolist())] + encoder_hidden_states2.append(hidden_states2) + pool2.append(p2) + encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) + encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) + pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) + + pool2 = pool2 @ text_projection.to(pool2.dtype) + + # get size embeddings + orig_size = batch["original_sizes_hw"] + crop_size = batch["crop_top_lefts"] + target_size = batch["target_sizes_hw"] + embs = sdxl_train_util.get_size_embeddings(orig_size, crop_size, target_size, accelerator.device).to(weight_dtype) + + # concat embeddings + vector_embedding = torch.cat([pool2, embs], dim=1).to(weight_dtype) + text_embedding = torch.cat([encoder_hidden_states1, encoder_hidden_states2], dim=2).to(weight_dtype) + + # Sample noise that we'll add to the latents + noise = torch.randn_like(latents, device=latents.device) + if args.noise_offset: + noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) + elif args.multires_noise_iterations: + noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) + + # Sample a random timestep for each image + timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) + timesteps = timesteps.long() + + # Add noise to the latents according to the noise magnitude at each timestep + # (this is the forward diffusion process) + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + + noisy_latents = noisy_latents.to(weight_dtype) # TODO check why noisy_latents is not weight_dtype + + # Predict the noise residual + with accelerator.autocast(): + noise_pred = unet(noisy_latents, timesteps, text_embedding, vector_embedding) + + target = noise + + if args.min_snr_gamma: + # do not mean over batch dimension for snr weight or scale v-pred loss + loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") + loss = loss.mean([1, 2, 3]) + + if args.min_snr_gamma: + loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) + + loss = loss.mean() # mean over batch dimension + else: + loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="mean") + + accelerator.backward(loss) + if accelerator.sync_gradients and args.max_grad_norm != 0.0: + params_to_clip = [] + for m in training_models: + params_to_clip.extend(m.parameters()) + accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) + + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad(set_to_none=True) + + # Checks if the accelerator has performed an optimization step behind the scenes + if accelerator.sync_gradients: + progress_bar.update(1) + global_step += 1 + + # sdxl_train_util.sample_images( + # accelerator, + # args, + # None, + # global_step, + # accelerator.device, + # vae, + # tokenizer1, + # tokenizer2, + # text_encoder1, + # text_encoder2, + # unet, + # ) + + # 指定ステップごとにモデルを保存 + if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: + accelerator.wait_for_everyone() + if accelerator.is_main_process: + src_path = src_stable_diffusion_ckpt if save_stable_diffusion_format else src_diffusers_model_path + sdxl_train_util.save_sd_model_on_epoch_end_or_stepwise( + args, + False, + accelerator, + src_path, + save_stable_diffusion_format, + use_safetensors, + save_dtype, + epoch, + num_train_epochs, + global_step, + accelerator.unwrap_model(text_encoder1), + accelerator.unwrap_model(text_encoder2), + accelerator.unwrap_model(unet), + vae, + text_projection, + logit_scale, + ckpt_info, + ) + + current_loss = loss.detach().item() # 平均なのでbatch sizeは関係ないはず + if args.logging_dir is not None: + logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy" + ): # tracking d*lr value + logs["lr/d*lr"] = ( + lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] + ) + accelerator.log(logs, step=global_step) + + # TODO moving averageにする + loss_total += current_loss + avr_loss = loss_total / (step + 1) + logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} + progress_bar.set_postfix(**logs) + + if global_step >= args.max_train_steps: + break + + if args.logging_dir is not None: + logs = {"loss/epoch": loss_total / len(train_dataloader)} + accelerator.log(logs, step=epoch + 1) + + accelerator.wait_for_everyone() + + if args.save_every_n_epochs is not None: + if accelerator.is_main_process: + src_path = src_stable_diffusion_ckpt if save_stable_diffusion_format else src_diffusers_model_path + sdxl_train_util.save_sd_model_on_epoch_end_or_stepwise( + args, + True, + accelerator, + src_path, + save_stable_diffusion_format, + use_safetensors, + save_dtype, + epoch, + num_train_epochs, + global_step, + accelerator.unwrap_model(text_encoder1), + accelerator.unwrap_model(text_encoder2), + accelerator.unwrap_model(unet), + vae, + text_projection, + logit_scale, + ckpt_info, + ) + + # train_util.sample_images(accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet) + + is_main_process = accelerator.is_main_process + # if is_main_process: + unet = accelerator.unwrap_model(unet) + text_encoder1 = accelerator.unwrap_model(text_encoder1) + text_encoder2 = accelerator.unwrap_model(text_encoder2) + + accelerator.end_training() + + if args.save_state: # and is_main_process: + train_util.save_state_on_train_end(args, accelerator) + + del accelerator # この後メモリを使うのでこれは消す + + if is_main_process: + src_path = src_stable_diffusion_ckpt if save_stable_diffusion_format else src_diffusers_model_path + sdxl_train_util.save_sd_model_on_train_end( + args, + src_path, + save_stable_diffusion_format, + use_safetensors, + save_dtype, + epoch, + global_step, + text_encoder1, + text_encoder2, + unet, + vae, + text_projection, + logit_scale, + ckpt_info, + ) + print("model saved.") + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + + train_util.add_sd_models_arguments(parser) + train_util.add_dataset_arguments(parser, True, True, True) + train_util.add_training_arguments(parser, False) + train_util.add_sd_saving_arguments(parser) + train_util.add_optimizer_arguments(parser) + config_util.add_config_arguments(parser) + custom_train_functions.add_custom_train_arguments(parser) + sdxl_train_util.add_sdxl_training_arguments(parser) + + parser.add_argument("--diffusers_xformers", action="store_true", help="use xformers by diffusers / Diffusersでxformersを使用する") + parser.add_argument("--train_text_encoder", action="store_true", help="train text encoder / text encoderも学習する") + + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + train(args) diff --git a/sdxl_train_network.py b/sdxl_train_network.py new file mode 100644 index 000000000..1bd4cb742 --- /dev/null +++ b/sdxl_train_network.py @@ -0,0 +1,172 @@ +import argparse +import torch +from library import sdxl_model_util, sdxl_train_util, train_util +import train_network + + +class SdxlNetworkTrainer(train_network.NetworkTrainer): + def __init__(self): + super().__init__() + self.vae_scale_factor = sdxl_model_util.VAE_SCALE_FACTOR + + def assert_extra_args(self, args, train_dataset_group): + super().assert_extra_args(args) + sdxl_train_util.verify_sdxl_training_args(args) + + if args.cache_text_encoder_outputs: + assert ( + train_dataset_group.is_text_encoder_output_cacheable() + ), "when caching Text Encoder output, either caption_dropout_rate, shuffle_caption, token_warmup_step or caption_tag_dropout_rate cannot be used / Text Encoderの出力をキャッシュするときはcaption_dropout_rate, shuffle_caption, token_warmup_step, caption_tag_dropout_rateは使えません" + + assert ( + args.network_train_unet_only or not args.cache_text_encoder_outputs + ), "network for Text Encoder cannot be trained with caching Text Encoder outputs / Text Encoderの出力をキャッシュしながらText Encoderのネットワークを学習することはできません" + + def load_target_model(self, args, weight_dtype, accelerator): + ( + load_stable_diffusion_format, + text_encoder1, + text_encoder2, + vae, + unet, + text_projection, + logit_scale, + ckpt_info, + ) = sdxl_train_util.load_target_model(args, accelerator, sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, weight_dtype) + + self.load_stable_diffusion_format = load_stable_diffusion_format + self.text_projection = text_projection.to(accelerator.device, dtype=weight_dtype) + self.logit_scale = logit_scale + self.ckpt_info = ckpt_info + + return sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, [text_encoder1, text_encoder2], vae, unet + + def load_tokenizer(self, args): + tokenizer = sdxl_train_util.load_tokenizers(args) + return tokenizer + + def is_text_encoder_outputs_cached(self, args): + return args.cache_text_encoder_outputs + + def cache_text_encoder_outputs_if_needed( + self, args, accelerator, unet, vae, tokenizers, text_encoders, data_loader, weight_dtype + ): + if args.cache_text_encoder_outputs: + if not args.lowram: + # メモリ消費を減らす + print("move vae and unet to cpu to save memory") + org_vae_device = vae.device + org_unet_device = unet.device + vae.to("cpu") + unet.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + + text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( + args, accelerator, tokenizers, text_encoders, data_loader, weight_dtype + ) + accelerator.wait_for_everyone() + text_encoders[0].to("cpu") + text_encoders[1].to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + + self.text_encoder1_cache = text_encoder1_cache + self.text_encoder2_cache = text_encoder2_cache + + if not args.lowram: + print("move vae and unet back to original device") + vae.to(org_vae_device) + unet.to(org_unet_device) + else: + self.text_encoder1_cache = None + self.text_encoder2_cache = None + + # Text Encoderから毎回出力を取得するので、GPUに乗せておく + text_encoders[0].to(accelerator.device) + text_encoders[1].to(accelerator.device) + + def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): + input_ids1 = batch["input_ids"] + input_ids2 = batch["input_ids2"] + if not args.cache_text_encoder_outputs: + with torch.enable_grad(): + # Get the text embedding for conditioning + # TODO support weighted captions + # if args.weighted_captions: + # encoder_hidden_states = get_weighted_text_embeddings( + # tokenizer, + # text_encoder, + # batch["captions"], + # accelerator.device, + # args.max_token_length // 75 if args.max_token_length else 1, + # clip_skip=args.clip_skip, + # ) + # else: + input_ids1 = input_ids1.to(accelerator.device) + input_ids2 = input_ids2.to(accelerator.device) + encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( + args, + input_ids1, + input_ids2, + tokenizers[0], + tokenizers[1], + text_encoders[0], + text_encoders[1], + None if not args.full_fp16 else weight_dtype, + ) + pool2 = pool2 @ self.text_projection.to(pool2.dtype) + else: + encoder_hidden_states1 = [] + encoder_hidden_states2 = [] + pool2 = [] + for input_id1, input_id2 in zip(input_ids1, input_ids2): + input_id1 = input_id1.squeeze(0) + input_id2 = input_id2.squeeze(0) + encoder_hidden_states1.append(self.text_encoder1_cache[tuple(input_id1.tolist())]) + hidden_states2, p2 = self.text_encoder2_cache[tuple(input_id2.tolist())] + encoder_hidden_states2.append(hidden_states2) + pool2.append(p2) + encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) + encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) + pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) + + pool2 = pool2 @ self.text_projection.to(weight_dtype) + + return encoder_hidden_states1, encoder_hidden_states2, pool2 + + def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_conds, batch, weight_dtype): + noisy_latents = noisy_latents.to(weight_dtype) # TODO check why noisy_latents is not weight_dtype + + # get size embeddings + orig_size = batch["original_sizes_hw"] + crop_size = batch["crop_top_lefts"] + target_size = batch["target_sizes_hw"] + embs = sdxl_train_util.get_size_embeddings(orig_size, crop_size, target_size, accelerator.device).to(weight_dtype) + + # concat embeddings + encoder_hidden_states1, encoder_hidden_states2, pool2 = text_conds + vector_embedding = torch.cat([pool2, embs], dim=1).to(weight_dtype) + text_embedding = torch.cat([encoder_hidden_states1, encoder_hidden_states2], dim=2).to(weight_dtype) + + noise_pred = unet(noisy_latents, timesteps, text_embedding, vector_embedding) + return noise_pred + + def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet): + print("sample_images is not implemented") + + +def setup_parser() -> argparse.ArgumentParser: + parser = train_network.setup_parser() + sdxl_train_util.add_sdxl_training_arguments(parser) + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + trainer = SdxlNetworkTrainer() + trainer.train(args) diff --git a/train_network.py b/train_network.py index 7e930e8a8..e2920db4b 100644 --- a/train_network.py +++ b/train_network.py @@ -3,6 +3,7 @@ import gc import math import os +import sys import random import time import json @@ -12,6 +13,7 @@ import torch from accelerate.utils import set_seed from diffusers import DDPMScheduler +from library import model_util import library.train_util as train_util from library.train_util import ( @@ -34,753 +36,855 @@ ) -# TODO 他のスクリプトと共通化する -def generate_step_logs( - args: argparse.Namespace, current_loss, avr_loss, lr_scheduler, keys_scaled=None, mean_norm=None, maximum_norm=None -): - logs = {"loss/current": current_loss, "loss/average": avr_loss} +class NetworkTrainer: + def __init__(self): + self.vae_scale_factor = 0.18215 - if keys_scaled is not None: - logs["max_norm/keys_scaled"] = keys_scaled - logs["max_norm/average_key_norm"] = mean_norm - logs["max_norm/max_key_norm"] = maximum_norm + # TODO 他のスクリプトと共通化する + def generate_step_logs( + self, args: argparse.Namespace, current_loss, avr_loss, lr_scheduler, keys_scaled=None, mean_norm=None, maximum_norm=None + ): + logs = {"loss/current": current_loss, "loss/average": avr_loss} - lrs = lr_scheduler.get_last_lr() + if keys_scaled is not None: + logs["max_norm/keys_scaled"] = keys_scaled + logs["max_norm/average_key_norm"] = mean_norm + logs["max_norm/max_key_norm"] = maximum_norm - if args.network_train_text_encoder_only or len(lrs) <= 2: # not block lr (or single block) - if args.network_train_unet_only: - logs["lr/unet"] = float(lrs[0]) - elif args.network_train_text_encoder_only: - logs["lr/textencoder"] = float(lrs[0]) - else: - logs["lr/textencoder"] = float(lrs[0]) - logs["lr/unet"] = float(lrs[-1]) # may be same to textencoder - - if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower(): # tracking d*lr value of unet. - logs["lr/d*lr"] = lr_scheduler.optimizers[-1].param_groups[0]["d"] * lr_scheduler.optimizers[-1].param_groups[0]["lr"] - else: - idx = 0 - if not args.network_train_unet_only: - logs["lr/textencoder"] = float(lrs[0]) - idx = 1 - - for i in range(idx, len(lrs)): - logs[f"lr/group{i}"] = float(lrs[i]) - if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower(): - logs[f"lr/d*lr/group{i}"] = ( - lr_scheduler.optimizers[-1].param_groups[i]["d"] * lr_scheduler.optimizers[-1].param_groups[i]["lr"] + lrs = lr_scheduler.get_last_lr() + + if args.network_train_text_encoder_only or len(lrs) <= 2: # not block lr (or single block) + if args.network_train_unet_only: + logs["lr/unet"] = float(lrs[0]) + elif args.network_train_text_encoder_only: + logs["lr/textencoder"] = float(lrs[0]) + else: + logs["lr/textencoder"] = float(lrs[0]) + logs["lr/unet"] = float(lrs[-1]) # may be same to textencoder + + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower() + ): # tracking d*lr value of unet. + logs["lr/d*lr"] = ( + lr_scheduler.optimizers[-1].param_groups[0]["d"] * lr_scheduler.optimizers[-1].param_groups[0]["lr"] ) + else: + idx = 0 + if not args.network_train_unet_only: + logs["lr/textencoder"] = float(lrs[0]) + idx = 1 + + for i in range(idx, len(lrs)): + logs[f"lr/group{i}"] = float(lrs[i]) + if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower(): + logs[f"lr/d*lr/group{i}"] = ( + lr_scheduler.optimizers[-1].param_groups[i]["d"] * lr_scheduler.optimizers[-1].param_groups[i]["lr"] + ) - return logs + return logs + + def assert_extra_args(self, args): + pass + + def load_target_model(self, args, weight_dtype, accelerator): + text_encoder, vae, unet, _ = train_util.load_target_model(args, weight_dtype, accelerator) + return model_util.get_model_version_str_for_sd1_sd2(args.v2, args.v_parameterization), text_encoder, vae, unet + + def load_tokenizer(self, args): + tokenizer = train_util.load_tokenizer(args) + return tokenizer + + def is_text_encoder_outputs_cached(self, args): + return False + + def cache_text_encoder_outputs_if_needed( + self, args, accelerator, uner, vae, tokenizers, text_encoders, data_loader, weight_dtype + ): + for t_enc in text_encoders: + t_enc.to(accelerator.device) + + def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): + input_ids = batch["input_ids"].to(accelerator.device) + encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizers[0], text_encoders[0], weight_dtype) + return encoder_hidden_states + + def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_conds, batch, weight_dtype): + noise_pred = unet(noisy_latents, timesteps, text_conds).sample + return noise_pred + + def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet): + train_util.sample_images(accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet) + + def train(self, args): + session_id = random.randint(0, 2**32) + training_started_at = time.time() + train_util.verify_training_args(args) + train_util.prepare_dataset_args(args, True) + + cache_latents = args.cache_latents + use_dreambooth_method = args.in_json is None + use_user_config = args.dataset_config is not None + + if args.seed is None: + args.seed = random.randint(0, 2**32) + set_seed(args.seed) + + # tokenizerは単体またはリスト、tokenizersは必ずリスト:既存のコードとの互換性のため + tokenizer = self.load_tokenizer(args) + tokenizers = tokenizer if isinstance(tokenizer, list) else [tokenizer] + + # データセットを準備する + if args.dataset_class is None: + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) + if use_user_config: + print(f"Loading dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "reg_data_dir", "in_json"] + if any(getattr(args, attr) is not None for attr in ignored): + print( + "ignoring the following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + if use_dreambooth_method: + print("Using DreamBooth method.") + user_config = { + "datasets": [ + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } + ] + } + else: + print("Training with captions.") + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) + else: + # use arbitrary dataset class + train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizer) + + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + if args.debug_dataset: + train_util.debug_dataset(train_dataset_group) + return + if len(train_dataset_group) == 0: + print( + "No data found. Please verify arguments (train_data_dir must be the parent of folders with images) / 画像がありません。引数指定を確認してください(train_data_dirには画像があるフォルダではなく、画像があるフォルダの親フォルダを指定する必要があります)" + ) + return + if cache_latents: + assert ( + train_dataset_group.is_latent_cacheable() + ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" -def train(args): - session_id = random.randint(0, 2**32) - training_started_at = time.time() - train_util.verify_training_args(args) - train_util.prepare_dataset_args(args, True) + self.assert_extra_args(args, train_dataset_group) - cache_latents = args.cache_latents - use_dreambooth_method = args.in_json is None - use_user_config = args.dataset_config is not None + # acceleratorを準備する + print("preparing accelerator") + accelerator = train_util.prepare_accelerator(args) + is_main_process = accelerator.is_main_process - if args.seed is None: - args.seed = random.randint(0, 2**32) - set_seed(args.seed) + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, save_dtype = train_util.prepare_dtype(args) - tokenizer = train_util.load_tokenizer(args) + # モデルを読み込む + model_version, text_encoder, vae, unet = self.load_target_model(args, weight_dtype, accelerator) - # データセットを準備する - if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) - if use_user_config: - print(f"Loading dataset config from {args.dataset_config}") - user_config = config_util.load_user_config(args.dataset_config) - ignored = ["train_data_dir", "reg_data_dir", "in_json"] - if any(getattr(args, attr) is not None for attr in ignored): - print( - "ignoring the following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( - ", ".join(ignored) - ) + # text_encoder is List[CLIPTextModel] or CLIPTextModel + text_encoders = text_encoder if isinstance(text_encoder, list) else [text_encoder] + + # モデルに xformers とか memory efficient attention を組み込む + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) + + # 差分追加学習のためにモデルを読み込む + sys.path.append(os.path.dirname(__file__)) + accelerator.print("import network module:", args.network_module) + network_module = importlib.import_module(args.network_module) + + if args.base_weights is not None: + # base_weights が指定されている場合は、指定された重みを読み込みマージする + for i, weight_path in enumerate(args.base_weights): + if args.base_weights_multiplier is None or len(args.base_weights_multiplier) <= i: + multiplier = 1.0 + else: + multiplier = args.base_weights_multiplier[i] + + accelerator.print(f"merging module: {weight_path} with multiplier {multiplier}") + + module, weights_sd = network_module.create_network_from_weights( + multiplier, weight_path, vae, text_encoder, unet, for_inference=True ) + module.merge_to(text_encoder, unet, weights_sd, weight_dtype, accelerator.device if args.lowram else "cpu") + + accelerator.print(f"all weights merged: {', '.join(args.base_weights)}") + + # 学習を準備する + if cache_latents: + vae.to(accelerator.device, dtype=weight_dtype) + vae.requires_grad_(False) + vae.eval() + with torch.no_grad(): + train_dataset_group.cache_latents(vae, args.vae_batch_size, args.cache_latents_to_disk, accelerator.is_main_process) + vae.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + gc.collect() + + accelerator.wait_for_everyone() + + # prepare network + net_kwargs = {} + if args.network_args is not None: + for net_arg in args.network_args: + key, value = net_arg.split("=") + net_kwargs[key] = value + + # if a new network is added in future, add if ~ then blocks for each network (;'∀') + if args.dim_from_weights: + network, _ = network_module.create_network_from_weights(1, args.network_weights, vae, text_encoder, unet, **net_kwargs) else: - if use_dreambooth_method: - print("Using DreamBooth method.") - user_config = { - "datasets": [ - { - "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( - args.train_data_dir, args.reg_data_dir - ) - } - ] - } - else: - print("Training with captions.") - user_config = { - "datasets": [ - { - "subsets": [ - { - "image_dir": args.train_data_dir, - "metadata_file": args.in_json, - } - ] - } - ] - } + # LyCORIS will work with this... + network = network_module.create_network( + 1.0, + args.network_dim, + args.network_alpha, + vae, + text_encoder, + unet, + neuron_dropout=args.network_dropout, + **net_kwargs, + ) + if network is None: + return + + if hasattr(network, "prepare_network"): + network.prepare_network(args) + if args.scale_weight_norms and not hasattr(network, "apply_max_norm_regularization"): + print( + "warning: scale_weight_norms is specified but the network does not support it / scale_weight_normsが指定されていますが、ネットワークが対応していません" + ) + args.scale_weight_norms = False + + train_unet = not args.network_train_text_encoder_only + train_text_encoder = not args.network_train_unet_only and not self.is_text_encoder_outputs_cached(args) + network.apply_to(text_encoder, unet, train_text_encoder, train_unet) + + if args.network_weights is not None: + info = network.load_weights(args.network_weights) + accelerator.print(f"load network weights from {args.network_weights}: {info}") + + if args.gradient_checkpointing: + unet.enable_gradient_checkpointing() + for t_enc in text_encoders: + t_enc.gradient_checkpointing_enable() + del t_enc + network.enable_gradient_checkpointing() # may have no effect + + # 学習に必要なクラスを準備する + accelerator.print("prepare optimizer, data loader etc.") + + # 後方互換性を確保するよ + try: + trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr, args.learning_rate) + except TypeError: + accelerator.print( + "Deprecated: use prepare_optimizer_params(text_encoder_lr, unet_lr, learning_rate) instead of prepare_optimizer_params(text_encoder_lr, unet_lr)" + ) + trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr) - blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer) - train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) - else: - # use arbitrary dataset class - train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizer) - - current_epoch = Value("i", 0) - current_step = Value("i", 0) - ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None - collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) - - if args.debug_dataset: - train_util.debug_dataset(train_dataset_group) - return - if len(train_dataset_group) == 0: - print( - "No data found. Please verify arguments (train_data_dir must be the parent of folders with images) / 画像がありません。引数指定を確認してください(train_data_dirには画像があるフォルダではなく、画像があるフォルダの親フォルダを指定する必要があります)" + optimizer_name, optimizer_args, optimizer = train_util.get_optimizer(args, trainable_params) + + # dataloaderを準備する + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, ) - return - if cache_latents: - assert ( - train_dataset_group.is_latent_cacheable() - ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" + # 学習ステップ数を計算する + if args.max_train_epochs is not None: + args.max_train_steps = args.max_train_epochs * math.ceil( + len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps + ) + accelerator.print( + f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" + ) - # acceleratorを準備する - print("preparing accelerator") - accelerator = train_util.prepare_accelerator(args) - is_main_process = accelerator.is_main_process + # データセット側にも学習ステップを送信 + train_dataset_group.set_max_train_steps(args.max_train_steps) + + # lr schedulerを用意する + lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) + + # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする + if args.full_fp16: + assert ( + args.mixed_precision == "fp16" + ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" + accelerator.print("enable full fp16 training.") + network.to(weight_dtype) + + # acceleratorがなんかよろしくやってくれるらしい + # TODO めちゃくちゃ冗長なのでコードを整理する + if train_unet and train_text_encoder: + if len(text_encoders) > 1: + unet, t_enc1, t_enc2, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + unet, text_encoders[0], text_encoders[1], network, optimizer, train_dataloader, lr_scheduler + ) + text_encoder = text_encoders = [t_enc1, t_enc2] + del t_enc1, t_enc2 + else: + unet, text_encoder, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + unet, text_encoder, network, optimizer, train_dataloader, lr_scheduler + ) + text_encoders = [text_encoder] + elif train_unet: + unet, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + unet, network, optimizer, train_dataloader, lr_scheduler + ) + elif train_text_encoder: + if len(text_encoders) > 1: + t_enc1, t_enc2, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + text_encoders[0], text_encoders[1], network, optimizer, train_dataloader, lr_scheduler + ) + text_encoder = text_encoders = [t_enc1, t_enc2] + del t_enc1, t_enc2 + else: + text_encoder, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + text_encoder, network, optimizer, train_dataloader, lr_scheduler + ) + text_encoders = [text_encoder] + else: + network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + network, optimizer, train_dataloader, lr_scheduler + ) - # mixed precisionに対応した型を用意しておき適宜castする - weight_dtype, save_dtype = train_util.prepare_dtype(args) + # transform DDP after prepare (train_network here only) + text_encoders = train_util.transform_models_if_DDP(text_encoders) + unet, network = train_util.transform_models_if_DDP([unet, network]) - # モデルを読み込む - text_encoder, vae, unet, _ = train_util.load_target_model(args, weight_dtype, accelerator) + unet.requires_grad_(False) + unet.to(accelerator.device, dtype=weight_dtype) + for t_enc in text_encoders: + t_enc.requires_grad_(False) - # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) + if args.gradient_checkpointing: + # according to TI example in Diffusers, train is required + unet.train() + for t_enc in text_encoders: + t_enc.train() - # 差分追加学習のためにモデルを読み込む - import sys + # set top parameter requires_grad = True for gradient checkpointing works + t_enc.text_model.embeddings.requires_grad_(True) + else: + unet.eval() + for t_enc in text_encoders: + t_enc.eval() - sys.path.append(os.path.dirname(__file__)) - accelerator.print("import network module:", args.network_module) - network_module = importlib.import_module(args.network_module) + del t_enc - if args.base_weights is not None: - # base_weights が指定されている場合は、指定された重みを読み込みマージする - for i, weight_path in enumerate(args.base_weights): - if args.base_weights_multiplier is None or len(args.base_weights_multiplier) <= i: - multiplier = 1.0 - else: - multiplier = args.base_weights_multiplier[i] + network.prepare_grad_etc(text_encoder, unet) - accelerator.print(f"merging module: {weight_path} with multiplier {multiplier}") + if not cache_latents: # キャッシュしない場合はVAEを使うのでVAEを準備する + vae.requires_grad_(False) + vae.eval() + vae.to(accelerator.device, dtype=weight_dtype) - module, weights_sd = network_module.create_network_from_weights( - multiplier, weight_path, vae, text_encoder, unet, for_inference=True - ) - module.merge_to(text_encoder, unet, weights_sd, weight_dtype, accelerator.device if args.lowram else "cpu") - - accelerator.print(f"all weights merged: {', '.join(args.base_weights)}") - - # 学習を準備する - if cache_latents: - vae.to(accelerator.device, dtype=weight_dtype) - vae.requires_grad_(False) - vae.eval() - with torch.no_grad(): - train_dataset_group.cache_latents(vae, args.vae_batch_size, args.cache_latents_to_disk, accelerator.is_main_process) - vae.to("cpu") - if torch.cuda.is_available(): - torch.cuda.empty_cache() - gc.collect() - - accelerator.wait_for_everyone() - - # prepare network - net_kwargs = {} - if args.network_args is not None: - for net_arg in args.network_args: - key, value = net_arg.split("=") - net_kwargs[key] = value - - # if a new network is added in future, add if ~ then blocks for each network (;'∀') - if args.dim_from_weights: - network, _ = network_module.create_network_from_weights(1, args.network_weights, vae, text_encoder, unet, **net_kwargs) - else: - # LyCORIS will work with this... - network = network_module.create_network( - 1.0, args.network_dim, args.network_alpha, vae, text_encoder, unet, neuron_dropout=args.network_dropout, **net_kwargs + # 必要ならテキストエンコーダーの出力をキャッシュする: Text Encoderはcpuまたはgpuへ移される + self.cache_text_encoder_outputs_if_needed( + args, accelerator, unet, vae, tokenizers, text_encoders, train_dataloader, weight_dtype ) - if network is None: - return - - if hasattr(network, "prepare_network"): - network.prepare_network(args) - if args.scale_weight_norms and not hasattr(network, "apply_max_norm_regularization"): - print( - "warning: scale_weight_norms is specified but the network does not support it / scale_weight_normsが指定されていますが、ネットワークが対応していません" - ) - args.scale_weight_norms = False - train_unet = not args.network_train_text_encoder_only - train_text_encoder = not args.network_train_unet_only - network.apply_to(text_encoder, unet, train_text_encoder, train_unet) + # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする + if args.full_fp16: + train_util.patch_accelerator_for_fp16_training(accelerator) - if args.network_weights is not None: - info = network.load_weights(args.network_weights) - accelerator.print(f"load network weights from {args.network_weights}: {info}") + # resumeする + train_util.resume_from_local_or_hf_if_specified(accelerator, args) - if args.gradient_checkpointing: - unet.enable_gradient_checkpointing() - text_encoder.gradient_checkpointing_enable() - network.enable_gradient_checkpointing() # may have no effect + # epoch数を計算する + num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) + num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) + if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): + args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 - # 学習に必要なクラスを準備する - accelerator.print("prepare optimizer, data loader etc.") + # 学習する + # TODO: find a way to handle total batch size when there are multiple datasets + total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - # 後方互換性を確保するよ - try: - trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr, args.learning_rate) - except TypeError: + accelerator.print("running training / 学習開始") + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") accelerator.print( - "Deprecated: use prepare_optimizer_params(text_encoder_lr, unet_lr, learning_rate) instead of prepare_optimizer_params(text_encoder_lr, unet_lr)" + f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" ) - trainable_params = network.prepare_optimizer_params(args.text_encoder_lr, args.unet_lr) + # accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + + # TODO refactor metadata creation and move to util + metadata = { + "ss_session_id": session_id, # random integer indicating which group of epochs the model came from + "ss_training_started_at": training_started_at, # unix timestamp + "ss_output_name": args.output_name, + "ss_learning_rate": args.learning_rate, + "ss_text_encoder_lr": args.text_encoder_lr, + "ss_unet_lr": args.unet_lr, + "ss_num_train_images": train_dataset_group.num_train_images, + "ss_num_reg_images": train_dataset_group.num_reg_images, + "ss_num_batches_per_epoch": len(train_dataloader), + "ss_num_epochs": num_train_epochs, + "ss_gradient_checkpointing": args.gradient_checkpointing, + "ss_gradient_accumulation_steps": args.gradient_accumulation_steps, + "ss_max_train_steps": args.max_train_steps, + "ss_lr_warmup_steps": args.lr_warmup_steps, + "ss_lr_scheduler": args.lr_scheduler, + "ss_network_module": args.network_module, + "ss_network_dim": args.network_dim, # None means default because another network than LoRA may have another default dim + "ss_network_alpha": args.network_alpha, # some networks may not have alpha + "ss_network_dropout": args.network_dropout, # some networks may not have dropout + "ss_mixed_precision": args.mixed_precision, + "ss_full_fp16": bool(args.full_fp16), + "ss_v2": bool(args.v2), + "ss_base_model_version": model_version, + "ss_clip_skip": args.clip_skip, + "ss_max_token_length": args.max_token_length, + "ss_cache_latents": bool(args.cache_latents), + "ss_seed": args.seed, + "ss_lowram": args.lowram, + "ss_noise_offset": args.noise_offset, + "ss_multires_noise_iterations": args.multires_noise_iterations, + "ss_multires_noise_discount": args.multires_noise_discount, + "ss_adaptive_noise_scale": args.adaptive_noise_scale, + "ss_training_comment": args.training_comment, # will not be updated after training + "ss_sd_scripts_commit_hash": train_util.get_git_revision_hash(), + "ss_optimizer": optimizer_name + (f"({optimizer_args})" if len(optimizer_args) > 0 else ""), + "ss_max_grad_norm": args.max_grad_norm, + "ss_caption_dropout_rate": args.caption_dropout_rate, + "ss_caption_dropout_every_n_epochs": args.caption_dropout_every_n_epochs, + "ss_caption_tag_dropout_rate": args.caption_tag_dropout_rate, + "ss_face_crop_aug_range": args.face_crop_aug_range, + "ss_prior_loss_weight": args.prior_loss_weight, + "ss_min_snr_gamma": args.min_snr_gamma, + "ss_scale_weight_norms": args.scale_weight_norms, + } - optimizer_name, optimizer_args, optimizer = train_util.get_optimizer(args, trainable_params) + if use_user_config: + # save metadata of multiple datasets + # NOTE: pack "ss_datasets" value as json one time + # or should also pack nested collections as json? + datasets_metadata = [] + tag_frequency = {} # merge tag frequency for metadata editor + dataset_dirs_info = {} # merge subset dirs for metadata editor + + for dataset in train_dataset_group.datasets: + is_dreambooth_dataset = isinstance(dataset, DreamBoothDataset) + dataset_metadata = { + "is_dreambooth": is_dreambooth_dataset, + "batch_size_per_device": dataset.batch_size, + "num_train_images": dataset.num_train_images, # includes repeating + "num_reg_images": dataset.num_reg_images, + "resolution": (dataset.width, dataset.height), + "enable_bucket": bool(dataset.enable_bucket), + "min_bucket_reso": dataset.min_bucket_reso, + "max_bucket_reso": dataset.max_bucket_reso, + "tag_frequency": dataset.tag_frequency, + "bucket_info": dataset.bucket_info, + } - # dataloaderを準備する - # DataLoaderのプロセス数:0はメインプロセスになる - n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + subsets_metadata = [] + for subset in dataset.subsets: + subset_metadata = { + "img_count": subset.img_count, + "num_repeats": subset.num_repeats, + "color_aug": bool(subset.color_aug), + "flip_aug": bool(subset.flip_aug), + "random_crop": bool(subset.random_crop), + "shuffle_caption": bool(subset.shuffle_caption), + "keep_tokens": subset.keep_tokens, + } + + image_dir_or_metadata_file = None + if subset.image_dir: + image_dir = os.path.basename(subset.image_dir) + subset_metadata["image_dir"] = image_dir + image_dir_or_metadata_file = image_dir + + if is_dreambooth_dataset: + subset_metadata["class_tokens"] = subset.class_tokens + subset_metadata["is_reg"] = subset.is_reg + if subset.is_reg: + image_dir_or_metadata_file = None # not merging reg dataset + else: + metadata_file = os.path.basename(subset.metadata_file) + subset_metadata["metadata_file"] = metadata_file + image_dir_or_metadata_file = metadata_file # may overwrite + + subsets_metadata.append(subset_metadata) + + # merge dataset dir: not reg subset only + # TODO update additional-network extension to show detailed dataset config from metadata + if image_dir_or_metadata_file is not None: + # datasets may have a certain dir multiple times + v = image_dir_or_metadata_file + i = 2 + while v in dataset_dirs_info: + v = image_dir_or_metadata_file + f" ({i})" + i += 1 + image_dir_or_metadata_file = v + + dataset_dirs_info[image_dir_or_metadata_file] = { + "n_repeats": subset.num_repeats, + "img_count": subset.img_count, + } - train_dataloader = torch.utils.data.DataLoader( - train_dataset_group, - batch_size=1, - shuffle=True, - collate_fn=collater, - num_workers=n_workers, - persistent_workers=args.persistent_data_loader_workers, - ) + dataset_metadata["subsets"] = subsets_metadata + datasets_metadata.append(dataset_metadata) + + # merge tag frequency: + for ds_dir_name, ds_freq_for_dir in dataset.tag_frequency.items(): + # あるディレクトリが複数のdatasetで使用されている場合、一度だけ数える + # もともと繰り返し回数を指定しているので、キャプション内でのタグの出現回数と、それが学習で何度使われるかは一致しない + # なので、ここで複数datasetの回数を合算してもあまり意味はない + if ds_dir_name in tag_frequency: + continue + tag_frequency[ds_dir_name] = ds_freq_for_dir + + metadata["ss_datasets"] = json.dumps(datasets_metadata) + metadata["ss_tag_frequency"] = json.dumps(tag_frequency) + metadata["ss_dataset_dirs"] = json.dumps(dataset_dirs_info) + else: + # conserving backward compatibility when using train_dataset_dir and reg_dataset_dir + assert ( + len(train_dataset_group.datasets) == 1 + ), f"There should be a single dataset but {len(train_dataset_group.datasets)} found. This seems to be a bug. / データセットは1個だけ存在するはずですが、実際には{len(train_dataset_group.datasets)}個でした。プログラムのバグかもしれません。" - # 学習ステップ数を計算する - if args.max_train_epochs is not None: - args.max_train_steps = args.max_train_epochs * math.ceil( - len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps - ) - accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") - - # データセット側にも学習ステップを送信 - train_dataset_group.set_max_train_steps(args.max_train_steps) - - # lr schedulerを用意する - lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) - - # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする - if args.full_fp16: - assert ( - args.mixed_precision == "fp16" - ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" - accelerator.print("enable full fp16 training.") - network.to(weight_dtype) - - # acceleratorがなんかよろしくやってくれるらしい - if train_unet and train_text_encoder: - unet, text_encoder, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( - unet, text_encoder, network, optimizer, train_dataloader, lr_scheduler - ) - elif train_unet: - unet, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( - unet, network, optimizer, train_dataloader, lr_scheduler - ) - elif train_text_encoder: - text_encoder, network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( - text_encoder, network, optimizer, train_dataloader, lr_scheduler - ) - else: - network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare(network, optimizer, train_dataloader, lr_scheduler) - - # transform DDP after prepare (train_network here only) - text_encoder, unet, network = train_util.transform_if_model_is_DDP(text_encoder, unet, network) - - unet.requires_grad_(False) - unet.to(accelerator.device, dtype=weight_dtype) - text_encoder.requires_grad_(False) - text_encoder.to(accelerator.device) - if args.gradient_checkpointing: # according to TI example in Diffusers, train is required - unet.train() - text_encoder.train() - - # set top parameter requires_grad = True for gradient checkpointing works - text_encoder.text_model.embeddings.requires_grad_(True) - else: - unet.eval() - text_encoder.eval() - - network.prepare_grad_etc(text_encoder, unet) - - if not cache_latents: # キャッシュしない場合はVAEを使うのでVAEを準備する - vae.requires_grad_(False) - vae.eval() - vae.to(accelerator.device, dtype=weight_dtype) - - # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする - if args.full_fp16: - train_util.patch_accelerator_for_fp16_training(accelerator) - - # resumeする - train_util.resume_from_local_or_hf_if_specified(accelerator, args) - - # epoch数を計算する - num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) - num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) - if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): - args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 - - # 学習する - # TODO: find a way to handle total batch size when there are multiple datasets - total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - - accelerator.print("running training / 学習開始") - accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") - accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - accelerator.print(f" num epochs / epoch数: {num_train_epochs}") - accelerator.print(f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}") - # accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") - accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") - - # TODO refactor metadata creation and move to util - metadata = { - "ss_session_id": session_id, # random integer indicating which group of epochs the model came from - "ss_training_started_at": training_started_at, # unix timestamp - "ss_output_name": args.output_name, - "ss_learning_rate": args.learning_rate, - "ss_text_encoder_lr": args.text_encoder_lr, - "ss_unet_lr": args.unet_lr, - "ss_num_train_images": train_dataset_group.num_train_images, - "ss_num_reg_images": train_dataset_group.num_reg_images, - "ss_num_batches_per_epoch": len(train_dataloader), - "ss_num_epochs": num_train_epochs, - "ss_gradient_checkpointing": args.gradient_checkpointing, - "ss_gradient_accumulation_steps": args.gradient_accumulation_steps, - "ss_max_train_steps": args.max_train_steps, - "ss_lr_warmup_steps": args.lr_warmup_steps, - "ss_lr_scheduler": args.lr_scheduler, - "ss_network_module": args.network_module, - "ss_network_dim": args.network_dim, # None means default because another network than LoRA may have another default dim - "ss_network_alpha": args.network_alpha, # some networks may not have alpha - "ss_network_dropout": args.network_dropout, # some networks may not have dropout - "ss_mixed_precision": args.mixed_precision, - "ss_full_fp16": bool(args.full_fp16), - "ss_v2": bool(args.v2), - "ss_clip_skip": args.clip_skip, - "ss_max_token_length": args.max_token_length, - "ss_cache_latents": bool(args.cache_latents), - "ss_seed": args.seed, - "ss_lowram": args.lowram, - "ss_noise_offset": args.noise_offset, - "ss_multires_noise_iterations": args.multires_noise_iterations, - "ss_multires_noise_discount": args.multires_noise_discount, - "ss_adaptive_noise_scale": args.adaptive_noise_scale, - "ss_training_comment": args.training_comment, # will not be updated after training - "ss_sd_scripts_commit_hash": train_util.get_git_revision_hash(), - "ss_optimizer": optimizer_name + (f"({optimizer_args})" if len(optimizer_args) > 0 else ""), - "ss_max_grad_norm": args.max_grad_norm, - "ss_caption_dropout_rate": args.caption_dropout_rate, - "ss_caption_dropout_every_n_epochs": args.caption_dropout_every_n_epochs, - "ss_caption_tag_dropout_rate": args.caption_tag_dropout_rate, - "ss_face_crop_aug_range": args.face_crop_aug_range, - "ss_prior_loss_weight": args.prior_loss_weight, - "ss_min_snr_gamma": args.min_snr_gamma, - "ss_scale_weight_norms": args.scale_weight_norms, - } - - if use_user_config: - # save metadata of multiple datasets - # NOTE: pack "ss_datasets" value as json one time - # or should also pack nested collections as json? - datasets_metadata = [] - tag_frequency = {} # merge tag frequency for metadata editor - dataset_dirs_info = {} # merge subset dirs for metadata editor - - for dataset in train_dataset_group.datasets: - is_dreambooth_dataset = isinstance(dataset, DreamBoothDataset) - dataset_metadata = { - "is_dreambooth": is_dreambooth_dataset, - "batch_size_per_device": dataset.batch_size, - "num_train_images": dataset.num_train_images, # includes repeating - "num_reg_images": dataset.num_reg_images, - "resolution": (dataset.width, dataset.height), - "enable_bucket": bool(dataset.enable_bucket), - "min_bucket_reso": dataset.min_bucket_reso, - "max_bucket_reso": dataset.max_bucket_reso, - "tag_frequency": dataset.tag_frequency, - "bucket_info": dataset.bucket_info, - } - - subsets_metadata = [] - for subset in dataset.subsets: - subset_metadata = { - "img_count": subset.img_count, - "num_repeats": subset.num_repeats, - "color_aug": bool(subset.color_aug), - "flip_aug": bool(subset.flip_aug), - "random_crop": bool(subset.random_crop), - "shuffle_caption": bool(subset.shuffle_caption), - "keep_tokens": subset.keep_tokens, - } + dataset = train_dataset_group.datasets[0] - image_dir_or_metadata_file = None - if subset.image_dir: - image_dir = os.path.basename(subset.image_dir) - subset_metadata["image_dir"] = image_dir - image_dir_or_metadata_file = image_dir - - if is_dreambooth_dataset: - subset_metadata["class_tokens"] = subset.class_tokens - subset_metadata["is_reg"] = subset.is_reg - if subset.is_reg: - image_dir_or_metadata_file = None # not merging reg dataset - else: - metadata_file = os.path.basename(subset.metadata_file) - subset_metadata["metadata_file"] = metadata_file - image_dir_or_metadata_file = metadata_file # may overwrite - - subsets_metadata.append(subset_metadata) - - # merge dataset dir: not reg subset only - # TODO update additional-network extension to show detailed dataset config from metadata - if image_dir_or_metadata_file is not None: - # datasets may have a certain dir multiple times - v = image_dir_or_metadata_file - i = 2 - while v in dataset_dirs_info: - v = image_dir_or_metadata_file + f" ({i})" - i += 1 - image_dir_or_metadata_file = v - - dataset_dirs_info[image_dir_or_metadata_file] = {"n_repeats": subset.num_repeats, "img_count": subset.img_count} - - dataset_metadata["subsets"] = subsets_metadata - datasets_metadata.append(dataset_metadata) - - # merge tag frequency: - for ds_dir_name, ds_freq_for_dir in dataset.tag_frequency.items(): - # あるディレクトリが複数のdatasetで使用されている場合、一度だけ数える - # もともと繰り返し回数を指定しているので、キャプション内でのタグの出現回数と、それが学習で何度使われるかは一致しない - # なので、ここで複数datasetの回数を合算してもあまり意味はない - if ds_dir_name in tag_frequency: - continue - tag_frequency[ds_dir_name] = ds_freq_for_dir - - metadata["ss_datasets"] = json.dumps(datasets_metadata) - metadata["ss_tag_frequency"] = json.dumps(tag_frequency) - metadata["ss_dataset_dirs"] = json.dumps(dataset_dirs_info) - else: - # conserving backward compatibility when using train_dataset_dir and reg_dataset_dir - assert ( - len(train_dataset_group.datasets) == 1 - ), f"There should be a single dataset but {len(train_dataset_group.datasets)} found. This seems to be a bug. / データセットは1個だけ存在するはずですが、実際には{len(train_dataset_group.datasets)}個でした。プログラムのバグかもしれません。" - - dataset = train_dataset_group.datasets[0] - - dataset_dirs_info = {} - reg_dataset_dirs_info = {} - if use_dreambooth_method: - for subset in dataset.subsets: - info = reg_dataset_dirs_info if subset.is_reg else dataset_dirs_info - info[os.path.basename(subset.image_dir)] = {"n_repeats": subset.num_repeats, "img_count": subset.img_count} - else: - for subset in dataset.subsets: - dataset_dirs_info[os.path.basename(subset.metadata_file)] = { - "n_repeats": subset.num_repeats, - "img_count": subset.img_count, + dataset_dirs_info = {} + reg_dataset_dirs_info = {} + if use_dreambooth_method: + for subset in dataset.subsets: + info = reg_dataset_dirs_info if subset.is_reg else dataset_dirs_info + info[os.path.basename(subset.image_dir)] = {"n_repeats": subset.num_repeats, "img_count": subset.img_count} + else: + for subset in dataset.subsets: + dataset_dirs_info[os.path.basename(subset.metadata_file)] = { + "n_repeats": subset.num_repeats, + "img_count": subset.img_count, + } + + metadata.update( + { + "ss_batch_size_per_device": args.train_batch_size, + "ss_total_batch_size": total_batch_size, + "ss_resolution": args.resolution, + "ss_color_aug": bool(args.color_aug), + "ss_flip_aug": bool(args.flip_aug), + "ss_random_crop": bool(args.random_crop), + "ss_shuffle_caption": bool(args.shuffle_caption), + "ss_enable_bucket": bool(dataset.enable_bucket), + "ss_bucket_no_upscale": bool(dataset.bucket_no_upscale), + "ss_min_bucket_reso": dataset.min_bucket_reso, + "ss_max_bucket_reso": dataset.max_bucket_reso, + "ss_keep_tokens": args.keep_tokens, + "ss_dataset_dirs": json.dumps(dataset_dirs_info), + "ss_reg_dataset_dirs": json.dumps(reg_dataset_dirs_info), + "ss_tag_frequency": json.dumps(dataset.tag_frequency), + "ss_bucket_info": json.dumps(dataset.bucket_info), } + ) - metadata.update( - { - "ss_batch_size_per_device": args.train_batch_size, - "ss_total_batch_size": total_batch_size, - "ss_resolution": args.resolution, - "ss_color_aug": bool(args.color_aug), - "ss_flip_aug": bool(args.flip_aug), - "ss_random_crop": bool(args.random_crop), - "ss_shuffle_caption": bool(args.shuffle_caption), - "ss_enable_bucket": bool(dataset.enable_bucket), - "ss_bucket_no_upscale": bool(dataset.bucket_no_upscale), - "ss_min_bucket_reso": dataset.min_bucket_reso, - "ss_max_bucket_reso": dataset.max_bucket_reso, - "ss_keep_tokens": args.keep_tokens, - "ss_dataset_dirs": json.dumps(dataset_dirs_info), - "ss_reg_dataset_dirs": json.dumps(reg_dataset_dirs_info), - "ss_tag_frequency": json.dumps(dataset.tag_frequency), - "ss_bucket_info": json.dumps(dataset.bucket_info), - } + # add extra args + if args.network_args: + metadata["ss_network_args"] = json.dumps(net_kwargs) + + # model name and hash + if args.pretrained_model_name_or_path is not None: + sd_model_name = args.pretrained_model_name_or_path + if os.path.exists(sd_model_name): + metadata["ss_sd_model_hash"] = train_util.model_hash(sd_model_name) + metadata["ss_new_sd_model_hash"] = train_util.calculate_sha256(sd_model_name) + sd_model_name = os.path.basename(sd_model_name) + metadata["ss_sd_model_name"] = sd_model_name + + if args.vae is not None: + vae_name = args.vae + if os.path.exists(vae_name): + metadata["ss_vae_hash"] = train_util.model_hash(vae_name) + metadata["ss_new_vae_hash"] = train_util.calculate_sha256(vae_name) + vae_name = os.path.basename(vae_name) + metadata["ss_vae_name"] = vae_name + + metadata = {k: str(v) for k, v in metadata.items()} + + # make minimum metadata for filtering + minimum_keys = [ + "ss_v2", + "ss_base_model_version", + "ss_network_module", + "ss_network_dim", + "ss_network_alpha", + "ss_network_args", + ] + minimum_metadata = {} + for key in minimum_keys: + if key in metadata: + minimum_metadata[key] = metadata[key] + + progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") + global_step = 0 + + noise_scheduler = DDPMScheduler( + beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) + prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) - # add extra args - if args.network_args: - metadata["ss_network_args"] = json.dumps(net_kwargs) - - # model name and hash - if args.pretrained_model_name_or_path is not None: - sd_model_name = args.pretrained_model_name_or_path - if os.path.exists(sd_model_name): - metadata["ss_sd_model_hash"] = train_util.model_hash(sd_model_name) - metadata["ss_new_sd_model_hash"] = train_util.calculate_sha256(sd_model_name) - sd_model_name = os.path.basename(sd_model_name) - metadata["ss_sd_model_name"] = sd_model_name - - if args.vae is not None: - vae_name = args.vae - if os.path.exists(vae_name): - metadata["ss_vae_hash"] = train_util.model_hash(vae_name) - metadata["ss_new_vae_hash"] = train_util.calculate_sha256(vae_name) - vae_name = os.path.basename(vae_name) - metadata["ss_vae_name"] = vae_name - - metadata = {k: str(v) for k, v in metadata.items()} - - # make minimum metadata for filtering - minimum_keys = ["ss_network_module", "ss_network_dim", "ss_network_alpha", "ss_network_args"] - minimum_metadata = {} - for key in minimum_keys: - if key in metadata: - minimum_metadata[key] = metadata[key] - - progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") - global_step = 0 - - noise_scheduler = DDPMScheduler( - beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False - ) - prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if accelerator.is_main_process: + accelerator.init_trackers("network_train" if args.log_tracker_name is None else args.log_tracker_name) - if accelerator.is_main_process: - accelerator.init_trackers("network_train" if args.log_tracker_name is None else args.log_tracker_name) + loss_list = [] + loss_total = 0.0 + del train_dataset_group - loss_list = [] - loss_total = 0.0 - del train_dataset_group + # callback for step start + if hasattr(network, "on_step_start"): + on_step_start = network.on_step_start + else: + on_step_start = lambda *args, **kwargs: None + + # function for saving/removing + def save_model(ckpt_name, unwrapped_nw, steps, epoch_no, force_sync_upload=False): + os.makedirs(args.output_dir, exist_ok=True) + ckpt_file = os.path.join(args.output_dir, ckpt_name) + + accelerator.print(f"\nsaving checkpoint: {ckpt_file}") + metadata["ss_training_finished_at"] = str(time.time()) + metadata["ss_steps"] = str(steps) + metadata["ss_epoch"] = str(epoch_no) + + unwrapped_nw.save_weights(ckpt_file, save_dtype, minimum_metadata if args.no_metadata else metadata) + if args.huggingface_repo_id is not None: + huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) + + def remove_model(old_ckpt_name): + old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) + if os.path.exists(old_ckpt_file): + accelerator.print(f"removing old checkpoint: {old_ckpt_file}") + os.remove(old_ckpt_file) + + # training loop + for epoch in range(num_train_epochs): + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") + current_epoch.value = epoch + 1 + + metadata["ss_epoch"] = str(epoch + 1) + + network.on_epoch_start(text_encoder, unet) + + for step, batch in enumerate(train_dataloader): + current_step.value = global_step + with accelerator.accumulate(network): + on_step_start(text_encoder, unet) + + with torch.no_grad(): + if "latents" in batch and batch["latents"] is not None: + latents = batch["latents"].to(accelerator.device) + else: + # latentに変換 + latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() + latents = latents * self.vae_scale_factor + b_size = latents.shape[0] + + with torch.set_grad_enabled(train_text_encoder): + # Get the text embedding for conditioning + if args.weighted_captions: + text_encoder_conds = get_weighted_text_embeddings( + tokenizer, + text_encoder, + batch["captions"], + accelerator.device, + args.max_token_length // 75 if args.max_token_length else 1, + clip_skip=args.clip_skip, + ) + else: + text_encoder_conds = self.get_text_cond( + args, accelerator, batch, tokenizers, text_encoders, weight_dtype + ) - # callback for step start - if hasattr(network, "on_step_start"): - on_step_start = network.on_step_start - else: - on_step_start = lambda *args, **kwargs: None + # Sample noise that we'll add to the latents + noise = torch.randn_like(latents, device=latents.device) + if args.noise_offset: + noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) + elif args.multires_noise_iterations: + noise = pyramid_noise_like( + noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount + ) - # function for saving/removing - def save_model(ckpt_name, unwrapped_nw, steps, epoch_no, force_sync_upload=False): - os.makedirs(args.output_dir, exist_ok=True) - ckpt_file = os.path.join(args.output_dir, ckpt_name) + # Sample a random timestep for each image + timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) + timesteps = timesteps.long() + # Add noise to the latents according to the noise magnitude at each timestep + # (this is the forward diffusion process) + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + + # Predict the noise residual + with accelerator.autocast(): + noise_pred = self.call_unet( + args, accelerator, unet, noisy_latents, timesteps, text_encoder_conds, batch, weight_dtype + ) - accelerator.print(f"\nsaving checkpoint: {ckpt_file}") - metadata["ss_training_finished_at"] = str(time.time()) - metadata["ss_steps"] = str(steps) - metadata["ss_epoch"] = str(epoch_no) + if args.v_parameterization: + # v-parameterization training + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + target = noise - unwrapped_nw.save_weights(ckpt_file, save_dtype, minimum_metadata if args.no_metadata else metadata) - if args.huggingface_repo_id is not None: - huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) + loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") + loss = loss.mean([1, 2, 3]) - def remove_model(old_ckpt_name): - old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) - if os.path.exists(old_ckpt_file): - accelerator.print(f"removing old checkpoint: {old_ckpt_file}") - os.remove(old_ckpt_file) + loss_weights = batch["loss_weights"] # 各sampleごとのweight + loss = loss * loss_weights - # training loop - for epoch in range(num_train_epochs): - accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") - current_epoch.value = epoch + 1 + if args.min_snr_gamma: + loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) + if args.scale_v_pred_loss_like_noise_pred: + loss = scale_v_prediction_loss_like_noise_prediction(loss, timesteps, noise_scheduler) - metadata["ss_epoch"] = str(epoch + 1) + loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし - network.on_epoch_start(text_encoder, unet) + accelerator.backward(loss) + if accelerator.sync_gradients and args.max_grad_norm != 0.0: + params_to_clip = network.get_trainable_params() + accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) - for step, batch in enumerate(train_dataloader): - current_step.value = global_step - with accelerator.accumulate(network): - on_step_start(text_encoder, unet) + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad(set_to_none=True) - with torch.no_grad(): - if "latents" in batch and batch["latents"] is not None: - latents = batch["latents"].to(accelerator.device) - else: - # latentに変換 - latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() - latents = latents * 0.18215 - b_size = latents.shape[0] - - with torch.set_grad_enabled(train_text_encoder): - # Get the text embedding for conditioning - if args.weighted_captions: - encoder_hidden_states = get_weighted_text_embeddings( - tokenizer, - text_encoder, - batch["captions"], - accelerator.device, - args.max_token_length // 75 if args.max_token_length else 1, - clip_skip=args.clip_skip, - ) - else: - input_ids = batch["input_ids"].to(accelerator.device) - encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizer, text_encoder, weight_dtype) - - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) - - # Predict the noise residual - with accelerator.autocast(): - noise_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample - - if args.v_parameterization: - # v-parameterization training - target = noise_scheduler.get_velocity(latents, noise, timesteps) + if args.scale_weight_norms: + keys_scaled, mean_norm, maximum_norm = network.apply_max_norm_regularization( + args.scale_weight_norms, accelerator.device + ) + max_mean_logs = {"Keys Scaled": keys_scaled, "Average key norm": mean_norm} else: - target = noise - - loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") - loss = loss.mean([1, 2, 3]) - - loss_weights = batch["loss_weights"] # 各sampleごとのweight - loss = loss * loss_weights - - if args.min_snr_gamma: - loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) - if args.scale_v_pred_loss_like_noise_pred: - loss = scale_v_prediction_loss_like_noise_prediction(loss, timesteps, noise_scheduler) - - loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし + keys_scaled, mean_norm, maximum_norm = None, None, None - accelerator.backward(loss) - if accelerator.sync_gradients and args.max_grad_norm != 0.0: - params_to_clip = network.get_trainable_params() - accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) + # Checks if the accelerator has performed an optimization step behind the scenes + if accelerator.sync_gradients: + progress_bar.update(1) + global_step += 1 - optimizer.step() - lr_scheduler.step() - optimizer.zero_grad(set_to_none=True) + self.sample_images(accelerator, args, None, global_step, accelerator.device, vae, tokenizer, text_encoder, unet) - if args.scale_weight_norms: - keys_scaled, mean_norm, maximum_norm = network.apply_max_norm_regularization( - args.scale_weight_norms, accelerator.device - ) - max_mean_logs = {"Keys Scaled": keys_scaled, "Average key norm": mean_norm} - else: - keys_scaled, mean_norm, maximum_norm = None, None, None - - # Checks if the accelerator has performed an optimization step behind the scenes - if accelerator.sync_gradients: - progress_bar.update(1) - global_step += 1 + # 指定ステップごとにモデルを保存 + if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: + accelerator.wait_for_everyone() + if accelerator.is_main_process: + ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) + save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch) - train_util.sample_images( - accelerator, args, None, global_step, accelerator.device, vae, tokenizer, text_encoder, unet - ) + if args.save_state: + train_util.save_and_remove_state_stepwise(args, accelerator, global_step) - # 指定ステップごとにモデルを保存 - if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: - accelerator.wait_for_everyone() - if accelerator.is_main_process: - ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) - save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch) + remove_step_no = train_util.get_remove_step_no(args, global_step) + if remove_step_no is not None: + remove_ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, remove_step_no) + remove_model(remove_ckpt_name) - if args.save_state: - train_util.save_and_remove_state_stepwise(args, accelerator, global_step) + current_loss = loss.detach().item() + if epoch == 0: + loss_list.append(current_loss) + else: + loss_total -= loss_list[step] + loss_list[step] = current_loss + loss_total += current_loss + avr_loss = loss_total / len(loss_list) + logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} + progress_bar.set_postfix(**logs) - remove_step_no = train_util.get_remove_step_no(args, global_step) - if remove_step_no is not None: - remove_ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, remove_step_no) - remove_model(remove_ckpt_name) + if args.scale_weight_norms: + progress_bar.set_postfix(**{**max_mean_logs, **logs}) - current_loss = loss.detach().item() - if epoch == 0: - loss_list.append(current_loss) - else: - loss_total -= loss_list[step] - loss_list[step] = current_loss - loss_total += current_loss - avr_loss = loss_total / len(loss_list) - logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} - progress_bar.set_postfix(**logs) + if args.logging_dir is not None: + logs = self.generate_step_logs(args, current_loss, avr_loss, lr_scheduler, keys_scaled, mean_norm, maximum_norm) + accelerator.log(logs, step=global_step) - if args.scale_weight_norms: - progress_bar.set_postfix(**{**max_mean_logs, **logs}) + if global_step >= args.max_train_steps: + break if args.logging_dir is not None: - logs = generate_step_logs(args, current_loss, avr_loss, lr_scheduler, keys_scaled, mean_norm, maximum_norm) - accelerator.log(logs, step=global_step) + logs = {"loss/epoch": loss_total / len(loss_list)} + accelerator.log(logs, step=epoch + 1) - if global_step >= args.max_train_steps: - break + accelerator.wait_for_everyone() - if args.logging_dir is not None: - logs = {"loss/epoch": loss_total / len(loss_list)} - accelerator.log(logs, step=epoch + 1) + # 指定エポックごとにモデルを保存 + if args.save_every_n_epochs is not None: + saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs + if is_main_process and saving: + ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) + save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch + 1) - accelerator.wait_for_everyone() + remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) + if remove_epoch_no is not None: + remove_ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, remove_epoch_no) + remove_model(remove_ckpt_name) - # 指定エポックごとにモデルを保存 - if args.save_every_n_epochs is not None: - saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs - if is_main_process and saving: - ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) - save_model(ckpt_name, accelerator.unwrap_model(network), global_step, epoch + 1) + if args.save_state: + train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) - remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) - if remove_epoch_no is not None: - remove_ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, remove_epoch_no) - remove_model(remove_ckpt_name) - - if args.save_state: - train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) - - train_util.sample_images(accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet) - - # end of epoch + self.sample_images( + accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet + ) - # metadata["ss_epoch"] = str(num_train_epochs) - metadata["ss_training_finished_at"] = str(time.time()) + # end of epoch - if is_main_process: - network = accelerator.unwrap_model(network) + # metadata["ss_epoch"] = str(num_train_epochs) + metadata["ss_training_finished_at"] = str(time.time()) - accelerator.end_training() + if is_main_process: + network = accelerator.unwrap_model(network) - if is_main_process and args.save_state: - train_util.save_state_on_train_end(args, accelerator) + accelerator.end_training() - del accelerator # この後メモリを使うのでこれは消す + if is_main_process and args.save_state: + train_util.save_state_on_train_end(args, accelerator) - if is_main_process: - ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) - save_model(ckpt_name, network, global_step, num_train_epochs, force_sync_upload=True) + if is_main_process: + ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) + save_model(ckpt_name, network, global_step, num_train_epochs, force_sync_upload=True) - print("model saved.") + print("model saved.") def setup_parser() -> argparse.ArgumentParser: @@ -866,4 +970,5 @@ def setup_parser() -> argparse.ArgumentParser: args = parser.parse_args() args = train_util.read_config_from_file(args, parser) - train(args) + trainer = NetworkTrainer() + trainer.train(args) From 56ca5dfa1504876b204881895d2dd4d108484c0b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 20:37:14 +0900 Subject: [PATCH 031/220] fix warning messages are shown every step --- sdxl_train_network.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdxl_train_network.py b/sdxl_train_network.py index 1bd4cb742..306c0f0f2 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -8,6 +8,7 @@ class SdxlNetworkTrainer(train_network.NetworkTrainer): def __init__(self): super().__init__() self.vae_scale_factor = sdxl_model_util.VAE_SCALE_FACTOR + self.sampling_warning_showed = False def assert_extra_args(self, args, train_dataset_group): super().assert_extra_args(args) @@ -153,7 +154,9 @@ def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_cond return noise_pred def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet): - print("sample_images is not implemented") + if not self.sampling_warning_showed: + print("sample_images is not implemented") + self.sampling_warning_showed = True def setup_parser() -> argparse.ArgumentParser: From 2c461e4ad39f00189114671d8a3fcdd748e6447d Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 20:38:09 +0900 Subject: [PATCH 032/220] Add no_half_vae for SDXL training, add nan check --- library/train_util.py | 5 +++++ sdxl_train.py | 19 ++++++++++++++----- train_network.py | 22 ++++++++++++++++------ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index e609705e2..c27e1b273 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -906,6 +906,11 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") + # check NaN + for info, latents1 in zip(batch, latents): + if torch.isnan(latents1).any(): + raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") + for info, latent in zip(batch, latents): if cache_to_disk: np.savez( diff --git a/sdxl_train.py b/sdxl_train.py index 2683038b5..562407445 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -109,6 +109,7 @@ def train(args): # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) + vae_dtype = torch.float32 if args.no_half_vae else weight_dtype # モデルを読み込む ( @@ -165,8 +166,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # 学習を準備する if cache_latents: - # vae.to(accelerator.device, dtype=weight_dtype) - vae.to(accelerator.device, dtype=torch.float32) # VAE in float to avoid NaN + vae.to(accelerator.device, dtype=vae_dtype) vae.requires_grad_(False) vae.eval() with torch.no_grad(): @@ -201,7 +201,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): if not cache_latents: vae.requires_grad_(False) vae.eval() - vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=vae_dtype) for m in training_models: m.requires_grad_(True) @@ -342,8 +342,12 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): else: with torch.no_grad(): # latentに変換 - # latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() - latents = vae.encode(batch["images"].to(torch.float32)).latent_dist.sample().to(weight_dtype) + latents = vae.encode(batch["images"].to(vae_dtype)).latent_dist.sample().to(weight_dtype) + + # NaNが含まれていれば警告を表示し0に置き換える + if torch.any(torch.isnan(latents)): + accelerator.print("NaN found in latents, replacing with zeros") + latents = torch.where(torch.isnan(latents), torch.zeros_like(latents), latents) latents = latents * sdxl_model_util.VAE_SCALE_FACTOR b_size = latents.shape[0] @@ -592,6 +596,11 @@ def setup_parser() -> argparse.ArgumentParser: parser.add_argument("--diffusers_xformers", action="store_true", help="use xformers by diffusers / Diffusersでxformersを使用する") parser.add_argument("--train_text_encoder", action="store_true", help="train text encoder / text encoderも学習する") + parser.add_argument( + "--no_half_vae", + action="store_true", + help="do not use fp16/bf16 VAE in mixed precision (use float VAE) / mixed precisionでも fp16/bf16 VAEを使わずfloat VAEを使う", + ) return parser diff --git a/train_network.py b/train_network.py index e2920db4b..2bb94b1ec 100644 --- a/train_network.py +++ b/train_network.py @@ -207,6 +207,7 @@ def train(self, args): # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) + vae_dtype = torch.float32 if args.no_half_vae else weight_dtype # モデルを読み込む model_version, text_encoder, vae, unet = self.load_target_model(args, weight_dtype, accelerator) @@ -216,6 +217,7 @@ def train(self, args): # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) + vae.set_use_memory_efficient_attention_xformers(args.xformers) # 差分追加学習のためにモデルを読み込む sys.path.append(os.path.dirname(__file__)) @@ -241,7 +243,7 @@ def train(self, args): # 学習を準備する if cache_latents: - vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=vae_dtype) vae.requires_grad_(False) vae.eval() with torch.no_grad(): @@ -415,7 +417,7 @@ def train(self, args): if not cache_latents: # キャッシュしない場合はVAEを使うのでVAEを準備する vae.requires_grad_(False) vae.eval() - vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=vae_dtype) # 必要ならテキストエンコーダーの出力をキャッシュする: Text Encoderはcpuまたはgpuへ移される self.cache_text_encoder_outputs_if_needed( @@ -721,7 +723,12 @@ def remove_model(old_ckpt_name): latents = batch["latents"].to(accelerator.device) else: # latentに変換 - latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() + latents = vae.encode(batch["images"].to(dtype=vae_dtype)).latent_dist.sample() + + # NaNが含まれていれば警告を表示し0に置き換える + if torch.any(torch.isnan(latents)): + accelerator.print("NaN found in latents, replacing with zeros") + latents = torch.where(torch.isnan(latents), torch.zeros_like(latents), latents) latents = latents * self.vae_scale_factor b_size = latents.shape[0] @@ -863,9 +870,7 @@ def remove_model(old_ckpt_name): if args.save_state: train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) - self.sample_images( - accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet - ) + self.sample_images(accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet) # end of epoch @@ -961,6 +966,11 @@ def setup_parser() -> argparse.ArgumentParser: nargs="*", help="multiplier for network weights to merge into the model before training / 学習前にあらかじめモデルにマージするnetworkの重みの倍率", ) + parser.add_argument( + "--no_half_vae", + action="store_true", + help="do not use fp16/bf16 VAE in mixed precision (use float VAE) / mixed precisionでも fp16/bf16 VAEを使わずfloat VAEを使う", + ) return parser From 9ebebb22db31106d293f2eae0592f8f2f157a05a Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 20:43:34 +0900 Subject: [PATCH 033/220] fix typos --- library/sdxl_train_util.py | 2 +- train_network.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index e10488c03..0eaee4eb7 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -375,7 +375,7 @@ def verify_sdxl_training_args(args: argparse.Namespace): args.noise_offset = DEFAULT_NOISE_OFFSET elif args.noise_offset != DEFAULT_NOISE_OFFSET: print( - f"Waring: SDXL has been trained with noise_offset={DEFAULT_NOISE_OFFSET} / SDXLはnoise_offset={DEFAULT_NOISE_OFFSET}で学習されています" + f"Warning: SDXL has been trained with noise_offset={DEFAULT_NOISE_OFFSET} / SDXLはnoise_offset={DEFAULT_NOISE_OFFSET}で学習されています" ) print(f"noise_offset is set to {args.noise_offset} / noise_offsetが{args.noise_offset}に設定されました") diff --git a/train_network.py b/train_network.py index 2bb94b1ec..1a3c19e2e 100644 --- a/train_network.py +++ b/train_network.py @@ -98,7 +98,7 @@ def is_text_encoder_outputs_cached(self, args): return False def cache_text_encoder_outputs_if_needed( - self, args, accelerator, uner, vae, tokenizers, text_encoders, data_loader, weight_dtype + self, args, accelerator, unet, vae, tokenizers, text_encoders, data_loader, weight_dtype ): for t_enc in text_encoders: t_enc.to(accelerator.device) From 31018d57b6c02dc6772ab0f7a14410e71708dbd6 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 21:18:22 +0900 Subject: [PATCH 034/220] update for sdxl --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 1a0ef579e..265c9af93 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,38 @@ This repository contains the scripts for: __Stable Diffusion web UI now seems to support LoRA trained by ``sd-scripts``.__ Thank you for great work!!! +## About SDXL training + +The feature of SDXL training is now available in sdxl branch as an experimental feature. + +Summary of the feature: + +- `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`. +- `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. +- Both scripts has following additional options: + - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. + - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. + +### Tips for SDXL training + +- The default resolution of SDXL is 1024x1024. +- The fine-tuning can be done with 24GB GPU memory with the batch size of 1. + - Train U-Net only. + - Use gradient checkpointing. + - Use `--cache_text_encoder_outputs` option and caching latents. + - Use Adafactor optimizer. RMSprop 8bit or Adagrad 8bit may work. AdamW 8bit doesn't seem to work. +- The LoRA training can be done with 12GB GPU memory. +- `--train_unet_only` option is highly recommended for SDXL LoRA. Because SDXL has two text encoders, the result of the training will be unexpected. + +Example of the optimizer settings for Adafactor with the fixed learning rate: +``` +optimizer_type = "adafactor" +optimizer_args = [ "scale_parameter=False", "relative_step=False", "warmup_init=False" ] +lr_scheduler = "constant_with_warmup" +lr_warmup_steps = 100 +learning_rate = 4e-7 # SDXL original learning rate +``` + ## About requirements.txt These files do not contain requirements for PyTorch. Because the versions of them depend on your environment. Please install PyTorch at first (see installation guide below.) From b0dfbe70864d95099e53b9bf131ee2112b2ec8f5 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 21:20:49 +0900 Subject: [PATCH 035/220] update readme --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 265c9af93..df059120c 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ Summary of the feature: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. +`requirements.txt` is updated to support SDXL training. + ### Tips for SDXL training - The default resolution of SDXL is 1024x1024. @@ -40,6 +42,7 @@ Summary of the feature: - Use Adafactor optimizer. RMSprop 8bit or Adagrad 8bit may work. AdamW 8bit doesn't seem to work. - The LoRA training can be done with 12GB GPU memory. - `--train_unet_only` option is highly recommended for SDXL LoRA. Because SDXL has two text encoders, the result of the training will be unexpected. +- PyTorch 2 seems to use slightly less GPU memory than PyTorch 1. Example of the optimizer settings for Adafactor with the fixed learning rate: ``` @@ -54,7 +57,7 @@ learning_rate = 4e-7 # SDXL original learning rate These files do not contain requirements for PyTorch. Because the versions of them depend on your environment. Please install PyTorch at first (see installation guide below.) -The scripts are tested with PyTorch 1.12.1 and 1.13.0, Diffusers 0.10.2. +The scripts are tested with PyTorch 1.12.1 and 2.0.1, Diffusers 0.17.1. ## Links to how-to-use documents From 753c63e11ba0bac503032d85ebc61a99bbc71e3e Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 26 Jun 2023 21:24:28 +0900 Subject: [PATCH 036/220] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df059120c..cf3de20e8 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: -- `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`. +- `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. From a751dc25d679995dd3815f1c1899250c2e3096f5 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 27 Jun 2023 20:48:06 +0900 Subject: [PATCH 037/220] use CLIPTextModelWithProjection --- library/sdxl_model_util.py | 25 ++++--- library/sdxl_train_util.py | 12 +--- networks/sdxl_merge_lora.py | 3 +- sdxl_minimal_inference.py | 126 +++++++++++++++++++++--------------- sdxl_train.py | 8 --- sdxl_train_network.py | 5 -- 6 files changed, 90 insertions(+), 89 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index c554782b7..681c9b218 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -1,6 +1,6 @@ import torch from safetensors.torch import load_file, save_file -from transformers import CLIPTextModel, CLIPTextConfig +from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection from diffusers import AutoencoderKL from library import model_util from library import sdxl_original_unet @@ -13,7 +13,7 @@ def convert_sdxl_text_encoder_2_checkpoint(checkpoint, max_length): SDXL_KEY_PREFIX = "conditioner.embedders.1.model." - # SD2のと、基本的には同じ。text_projectionを後で使うので、それを追加で返す + # SD2のと、基本的には同じ。logit_scaleを後で使うので、それを追加で返す # logit_scaleはcheckpointの保存時に使用する def convert_key(key): # common conversion @@ -37,7 +37,7 @@ def convert_key(key): elif ".positional_embedding" in key: key = key.replace(".positional_embedding", ".embeddings.position_embedding.weight") elif ".text_projection" in key: - key = None # 後で処理する + key = key.replace("text_model.text_projection", "text_projection.weight") elif ".logit_scale" in key: key = None # 後で処理する elif ".token_embedding" in key: @@ -73,11 +73,10 @@ def convert_key(key): position_ids = torch.Tensor([list(range(max_length))]).to(torch.int64) new_sd["text_model.embeddings.position_ids"] = position_ids - # text projection, logit_scale はDiffusersには含まれないが、後で必要になるので返す - text_projection = checkpoint[SDXL_KEY_PREFIX + "text_projection"] + # logit_scale はDiffusersには含まれないが、保存時に戻したいので別途返す logit_scale = checkpoint[SDXL_KEY_PREFIX + "logit_scale"] - return new_sd, text_projection, logit_scale + return new_sd, logit_scale def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): @@ -164,7 +163,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): # torch_dtype="float32", # transformers_version="4.25.0.dev0", ) - text_model2 = CLIPTextModel._from_config(text_model2_cfg) + text_model2 = CLIPTextModelWithProjection(text_model2_cfg) print("loading text encoders from checkpoint") te1_sd = {} @@ -178,7 +177,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): info1 = text_model1.load_state_dict(te1_sd) print("text encoder 1:", info1) - converted_sd, text_projection, logit_scale = convert_sdxl_text_encoder_2_checkpoint(te2_sd, max_length=77) + converted_sd, logit_scale = convert_sdxl_text_encoder_2_checkpoint(te2_sd, max_length=77) info2 = text_model2.load_state_dict(converted_sd) print("text encoder2:", info2) @@ -193,10 +192,10 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): print("VAE:", info) ckpt_info = (epoch, global_step) if epoch is not None else None - return text_model1, text_model2, vae, unet, text_projection, logit_scale, ckpt_info + return text_model1, text_model2, vae, unet, logit_scale, ckpt_info -def convert_text_encoder_2_state_dict_to_sdxl(checkpoint, text_projection, logit_scale): +def convert_text_encoder_2_state_dict_to_sdxl(checkpoint, logit_scale): def convert_key(key): # position_idsの除去 if ".position_ids" in key: @@ -223,6 +222,8 @@ def convert_key(key): key = key.replace("embeddings.position_embedding.weight", "positional_embedding") elif ".token_embedding" in key: key = key.replace("embeddings.token_embedding.weight", "token_embedding.weight") + elif "text_projection" in key: # no dot in key + key = key.replace("text_projection.weight", "text_projection") elif "final_layer_norm" in key: key = key.replace("final_layer_norm", "ln_final") return key @@ -252,7 +253,6 @@ def convert_key(key): new_key = new_key.replace(".self_attn.q_proj.", ".attn.in_proj_") new_sd[new_key] = value - new_sd["text_projection"] = text_projection new_sd["logit_scale"] = logit_scale return new_sd @@ -267,7 +267,6 @@ def save_stable_diffusion_checkpoint( steps, ckpt_info, vae, - text_projection, logit_scale, save_dtype=None, ): @@ -286,7 +285,7 @@ def update_sd(prefix, sd): # Convert the text encoders update_sd("conditioner.embedders.0.transformer.", text_encoder1.state_dict()) - text_enc2_dict = convert_text_encoder_2_state_dict_to_sdxl(text_encoder2.state_dict(), text_projection, logit_scale) + text_enc2_dict = convert_text_encoder_2_state_dict_to_sdxl(text_encoder2.state_dict(), logit_scale) update_sd("conditioner.embedders.1.model.", text_enc2_dict) # Convert the VAE diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 0eaee4eb7..46756b865 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -28,7 +28,6 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): text_encoder2, vae, unet, - text_projection, logit_scale, ckpt_info, ) = _load_target_model(args, model_version, weight_dtype, accelerator.device if args.lowram else "cpu") @@ -46,7 +45,7 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): text_encoder1, text_encoder2, unet = train_util.transform_models_if_DDP([text_encoder1, text_encoder2, unet]) - return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, text_projection, logit_scale, ckpt_info + return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, logit_scale, ckpt_info def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtype, device="cpu"): @@ -64,7 +63,6 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp text_encoder2, vae, unet, - text_projection, logit_scale, ckpt_info, ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) @@ -74,7 +72,7 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp vae = model_util.load_vae(args.vae, weight_dtype) print("additional VAE loaded") - return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, text_projection, logit_scale, ckpt_info + return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, logit_scale, ckpt_info class WrapperTokenizer: @@ -138,7 +136,7 @@ def get_hidden_states( # text_encoder2 enc_out = text_encoder2(input_ids2, output_hidden_states=True, return_dict=True) hidden_states2 = enc_out["hidden_states"][-2] # penuultimate layer - pool2 = enc_out["pooler_output"] + pool2 = enc_out["text_embeds"] if args.max_token_length is not None: # bs*3, 77, 768 or 1024 @@ -218,7 +216,6 @@ def save_sd_model_on_train_end( text_encoder2, unet, vae, - text_projection, logit_scale, ckpt_info, ): @@ -232,7 +229,6 @@ def sd_saver(ckpt_file, epoch_no, global_step): global_step, ckpt_info, vae, - text_projection, logit_scale, save_dtype, ) @@ -262,7 +258,6 @@ def save_sd_model_on_epoch_end_or_stepwise( text_encoder2, unet, vae, - text_projection, logit_scale, ckpt_info, ): @@ -276,7 +271,6 @@ def sd_saver(ckpt_file, epoch_no, global_step): global_step, ckpt_info, vae, - text_projection, logit_scale, save_dtype, ) diff --git a/networks/sdxl_merge_lora.py b/networks/sdxl_merge_lora.py index 0fc3f9c59..d75da7d76 100644 --- a/networks/sdxl_merge_lora.py +++ b/networks/sdxl_merge_lora.py @@ -200,7 +200,6 @@ def str_to_dtype(p): text_model2, vae, unet, - text_projection, logit_scale, ckpt_info, ) = sdxl_model_util.load_models_from_sdxl_checkpoint(sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.sd_model, "cpu") @@ -209,7 +208,7 @@ def str_to_dtype(p): print(f"saving SD model to: {args.save_to}") sdxl_model_util.save_stable_diffusion_checkpoint( - args.save_to, text_model1, text_model2, unet, 0, 0, ckpt_info, vae, text_projection, logit_scale, save_dtype + args.save_to, text_model1, text_model2, unet, 0, 0, ckpt_info, vae, logit_scale, save_dtype ) else: state_dict = merge_lora_models(args.models, args.ratios, merge_dtype) diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index 2f3670df5..138d2856e 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -66,9 +66,9 @@ def get_timestep_embedding(x, outdim): if __name__ == "__main__": - # 画像生成条件を変更する場合はここを変更 + # 画像生成条件を変更する場合はここを変更 / change here to change image generation conditions - # SDXLの追加のvector embeddingへ渡す値 + # SDXLの追加のvector embeddingへ渡す値 / Values to pass to additional vector embedding of SDXL target_height = 1024 target_width = 1024 original_height = target_height @@ -95,6 +95,7 @@ def get_timestep_embedding(x, outdim): default=[], help="LoRA weights, only supports networks.lora, each arguement is a `path;multiplier` (semi-colon separated)", ) + parser.add_argument("--interactive", action="store_true") args = parser.parse_args() # HuggingFaceのmodel id @@ -106,7 +107,7 @@ def get_timestep_embedding(x, outdim): # 本体RAMが少ない場合はGPUにロードするといいかも # If the main RAM is small, it may be better to load it on the GPU - text_model1, text_model2, vae, unet, text_projection, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( + text_model1, text_model2, vae, unet, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.ckpt_path, "cpu" ) @@ -140,9 +141,12 @@ def get_timestep_embedding(x, outdim): text_model2.to(DEVICE, dtype=DTYPE) text_model2.eval() - text_projection = text_projection.to(DEVICE, dtype=DTYPE) - unet.set_use_memory_efficient_attention(True, False) + vae.set_use_memory_efficient_attention_xformers(True) + + # Tokenizers + tokenizer1 = CLIPTokenizer.from_pretrained(text_encoder_1_name) + tokenizer2 = lambda x: open_clip.tokenize(x, context_length=77) # LoRA for weights_file in args.lora_weights: @@ -157,19 +161,27 @@ def get_timestep_embedding(x, outdim): ) lora_model.merge_to([text_model1, text_model2], unet, weights_sd, DTYPE, DEVICE) - # prepare embedding - with torch.no_grad(): - # vector - emb1 = get_timestep_embedding(torch.FloatTensor([original_height, original_width]).unsqueeze(0), 256) - emb2 = get_timestep_embedding(torch.FloatTensor([crop_top, crop_left]).unsqueeze(0), 256) - emb3 = get_timestep_embedding(torch.FloatTensor([target_height, target_width]).unsqueeze(0), 256) - # print("emb1", emb1.shape) - c_vector = torch.cat([emb1, emb2, emb3], dim=1).to(DEVICE, dtype=DTYPE) - uc_vector = c_vector.clone().to(DEVICE, dtype=DTYPE) # ちょっとここ正しいかどうかわからない I'm not sure if this is right + # scheduler + scheduler = EulerDiscreteScheduler( + num_train_timesteps=SCHEDULER_TIMESTEPS, + beta_start=SCHEDULER_LINEAR_START, + beta_end=SCHEDULER_LINEAR_END, + beta_schedule=SCHEDLER_SCHEDULE, + ) + + def generate_image(text, negative_text, seed=None): + # 将来的にサイズ情報も変えられるようにする / Make it possible to change the size information in the future + # prepare embedding + with torch.no_grad(): + # vector + emb1 = get_timestep_embedding(torch.FloatTensor([original_height, original_width]).unsqueeze(0), 256) + emb2 = get_timestep_embedding(torch.FloatTensor([crop_top, crop_left]).unsqueeze(0), 256) + emb3 = get_timestep_embedding(torch.FloatTensor([target_height, target_width]).unsqueeze(0), 256) + # print("emb1", emb1.shape) + c_vector = torch.cat([emb1, emb2, emb3], dim=1).to(DEVICE, dtype=DTYPE) + uc_vector = c_vector.clone().to(DEVICE, dtype=DTYPE) # ちょっとここ正しいかどうかわからない I'm not sure if this is right - # crossattn - tokenizer1 = CLIPTokenizer.from_pretrained(text_encoder_1_name) - tokenizer2 = lambda x: open_clip.tokenize(x, context_length=77) + # crossattn # Text Encoderを二つ呼ぶ関数 Function to call two Text Encoders def call_text_encoder(text): @@ -184,30 +196,31 @@ def call_text_encoder(text): ) tokens = batch_encoding["input_ids"].to(DEVICE) - enc_out = text_model1(tokens, output_hidden_states=True, return_dict=True) - text_embedding1 = enc_out["hidden_states"][11] - # text_embedding = pipe.text_encoder.text_model.final_layer_norm(text_embedding) # layer normは通さないらしい + with torch.no_grad(): + enc_out = text_model1(tokens, output_hidden_states=True, return_dict=True) + text_embedding1 = enc_out["hidden_states"][11] + # text_embedding = pipe.text_encoder.text_model.final_layer_norm(text_embedding) # layer normは通さないらしい # text encoder 2 - tokens = tokenizer2(text).to(DEVICE) + with torch.no_grad(): + tokens = tokenizer2(text).to(DEVICE) - enc_out = text_model2(tokens, output_hidden_states=True, return_dict=True) - text_embedding2_penu = enc_out["hidden_states"][-2] - # print("hidden_states2", text_embedding2_penu.shape) - text_embedding2_pool = enc_out["pooler_output"] - text_embedding2_pool = text_embedding2_pool @ text_projection.to(text_embedding2_pool.dtype) + enc_out = text_model2(tokens, output_hidden_states=True, return_dict=True) + text_embedding2_penu = enc_out["hidden_states"][-2] + # print("hidden_states2", text_embedding2_penu.shape) + text_embedding2_pool = enc_out["text_embeds"] # 連結して終了 concat and finish text_embedding = torch.cat([text_embedding1, text_embedding2_penu], dim=2) return text_embedding, text_embedding2_pool # cond - c_ctx, c_ctx_pool = call_text_encoder(args.prompt) + c_ctx, c_ctx_pool = call_text_encoder(prompt) # print(c_ctx.shape, c_ctx_p.shape, c_vector.shape) c_vector = torch.cat([c_ctx_pool, c_vector], dim=1) # uncond - uc_ctx, uc_ctx_pool = call_text_encoder(args.negative_prompt) + uc_ctx, uc_ctx_pool = call_text_encoder(negative_prompt) uc_vector = torch.cat([uc_ctx_pool, uc_vector], dim=1) text_embeddings = torch.cat([uc_ctx, c_ctx]) @@ -215,14 +228,6 @@ def call_text_encoder(text): # メモリ使用量を減らすにはここでText Encoderを削除するかCPUへ移動する - # scheduler - scheduler = EulerDiscreteScheduler( - num_train_timesteps=SCHEDULER_TIMESTEPS, - beta_start=SCHEDULER_LINEAR_START, - beta_end=SCHEDULER_LINEAR_END, - beta_schedule=SCHEDLER_SCHEDULE, - ) - if seed is not None: random.seed(seed) np.random.seed(seed) @@ -256,25 +261,26 @@ def call_text_encoder(text): # Copy from Diffusers timesteps = scheduler.timesteps.to(DEVICE) # .to(DTYPE) num_latent_input = 2 - for i, t in enumerate(tqdm(timesteps)): - # expand the latents if we are doing classifier free guidance - latent_model_input = latents.repeat((num_latent_input, 1, 1, 1)) - latent_model_input = scheduler.scale_model_input(latent_model_input, t) + with torch.no_grad(): + for i, t in enumerate(tqdm(timesteps)): + # expand the latents if we are doing classifier free guidance + latent_model_input = latents.repeat((num_latent_input, 1, 1, 1)) + latent_model_input = scheduler.scale_model_input(latent_model_input, t) - noise_pred = unet(latent_model_input, t, text_embeddings, vector_embeddings) + noise_pred = unet(latent_model_input, t, text_embeddings, vector_embeddings) - noise_pred_uncond, noise_pred_text = noise_pred.chunk(num_latent_input) # uncond by negative prompt - noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) + noise_pred_uncond, noise_pred_text = noise_pred.chunk(num_latent_input) # uncond by negative prompt + noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - # compute the previous noisy sample x_t -> x_t-1 - # latents = scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample - latents = scheduler.step(noise_pred, t, latents).prev_sample + # compute the previous noisy sample x_t -> x_t-1 + # latents = scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample + latents = scheduler.step(noise_pred, t, latents).prev_sample - # latents = 1 / 0.18215 * latents - latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents - latents = latents.to(torch.float32) - image = vae.decode(latents).sample - image = (image / 2 + 0.5).clamp(0, 1) + # latents = 1 / 0.18215 * latents + latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents + latents = latents.to(torch.float32) + image = vae.decode(latents).sample + image = (image / 2 + 0.5).clamp(0, 1) # we always cast to float32 as this does not cause significant overhead and is compatible with bfloa16 image = image.cpu().permute(0, 2, 3, 1).float().numpy() @@ -288,4 +294,20 @@ def call_text_encoder(text): for i, img in enumerate(image): img.save(os.path.join(args.output_dir, f"image_{timestamp}_{i:03d}.png")) - print("Done!") + if not args.interactive: + generate_image(args.prompt, args.negative_prompt, args.seed) + else: + # loop for interactive + while True: + prompt = input("prompt: ") + if prompt == "": + break + negative_prompt = input("negative prompt: ") + seed = input("seed: ") + if seed == "": + seed = None + else: + seed = int(seed) + generate_image(prompt, negative_prompt, seed) + + print("Done!") diff --git a/sdxl_train.py b/sdxl_train.py index 562407445..f640580af 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -118,11 +118,9 @@ def train(args): text_encoder2, vae, unet, - text_projection, logit_scale, ckpt_info, ) = sdxl_train_util.load_target_model(args, accelerator, "sdxl", weight_dtype) - text_projection = text_projection.to(accelerator.device, dtype=weight_dtype) logit_scale = logit_scale.to(accelerator.device, dtype=weight_dtype) # verify load/save model formats @@ -379,7 +377,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): text_encoder2, None if not args.full_fp16 else weight_dtype, ) - pool2 = pool2 @ text_projection.to(pool2.dtype) else: encoder_hidden_states1 = [] encoder_hidden_states2 = [] @@ -395,8 +392,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) - pool2 = pool2 @ text_projection.to(pool2.dtype) - # get size embeddings orig_size = batch["original_sizes_hw"] crop_size = batch["crop_top_lefts"] @@ -492,7 +487,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): accelerator.unwrap_model(text_encoder2), accelerator.unwrap_model(unet), vae, - text_projection, logit_scale, ckpt_info, ) @@ -541,7 +535,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): accelerator.unwrap_model(text_encoder2), accelerator.unwrap_model(unet), vae, - text_projection, logit_scale, ckpt_info, ) @@ -575,7 +568,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): text_encoder2, unet, vae, - text_projection, logit_scale, ckpt_info, ) diff --git a/sdxl_train_network.py b/sdxl_train_network.py index 306c0f0f2..fb445fb7d 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -30,13 +30,11 @@ def load_target_model(self, args, weight_dtype, accelerator): text_encoder2, vae, unet, - text_projection, logit_scale, ckpt_info, ) = sdxl_train_util.load_target_model(args, accelerator, sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, weight_dtype) self.load_stable_diffusion_format = load_stable_diffusion_format - self.text_projection = text_projection.to(accelerator.device, dtype=weight_dtype) self.logit_scale = logit_scale self.ckpt_info = ckpt_info @@ -116,7 +114,6 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei text_encoders[1], None if not args.full_fp16 else weight_dtype, ) - pool2 = pool2 @ self.text_projection.to(pool2.dtype) else: encoder_hidden_states1 = [] encoder_hidden_states2 = [] @@ -132,8 +129,6 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) - pool2 = pool2 @ self.text_projection.to(weight_dtype) - return encoder_hidden_states1, encoder_hidden_states2, pool2 def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_conds, batch, weight_dtype): From 07d5c710908751f5e675315b4a18fe5247e92316 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 27 Jun 2023 23:24:56 +0900 Subject: [PATCH 038/220] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cf3de20e8..e2812e449 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. + - __`prepare_buckets_latents.py` does not support SDXL fine-tuning. Please use DreamBooth dataset, or the metadata without bucketing.__ - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. From 71a6d49d0663fbdeacab11c1050c33384695122b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 28 Jun 2023 07:50:53 +0900 Subject: [PATCH 039/220] fix to work train_network with fine-tuning dataset --- library/config_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/config_util.py b/library/config_util.py index dd81ae660..c357c70ea 100644 --- a/library/config_util.py +++ b/library/config_util.py @@ -262,11 +262,11 @@ def __init__(self, support_dreambooth: bool, support_finetuning: bool, support_c {"subsets": [self.cn_subset_schema]}, ) - if support_dreambooth and support_finetuning and support_controlnet: + if support_dreambooth and support_finetuning: def validate_flex_dataset(dataset_config: dict): subsets_config = dataset_config.get("subsets", []) - if all(["conditioning_data_dir" in subset for subset in subsets_config]): + if support_controlnet and all(["conditioning_data_dir" in subset for subset in subsets_config]): return Schema(self.cn_dataset_schema)(dataset_config) # check dataset meets FT style # NOTE: all FT subsets should have "metadata_file" @@ -347,6 +347,7 @@ def __init__(self, sanitizer: ConfigSanitizer): # runtime_params is for parameters which is only configurable on runtime, such as tokenizer def generate(self, user_config: dict, argparse_namespace: argparse.Namespace, **runtime_params) -> Blueprint: + print(user_config) sanitized_user_config = self.sanitizer.sanitize_user_config(user_config) sanitized_argparse_namespace = self.sanitizer.sanitize_argparse_namespace(argparse_namespace) From 8521ab79901608948fd34bcc6a12f850fcb38465 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 28 Jun 2023 13:09:02 +0900 Subject: [PATCH 040/220] fix to work --- sdxl_minimal_inference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index 138d2856e..02a4af9c2 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -169,7 +169,7 @@ def get_timestep_embedding(x, outdim): beta_schedule=SCHEDLER_SCHEDULE, ) - def generate_image(text, negative_text, seed=None): + def generate_image(prompt, negative_prompt, seed=None): # 将来的にサイズ情報も変えられるようにする / Make it possible to change the size information in the future # prepare embedding with torch.no_grad(): @@ -295,7 +295,7 @@ def call_text_encoder(text): img.save(os.path.join(args.output_dir, f"image_{timestamp}_{i:03d}.png")) if not args.interactive: - generate_image(args.prompt, args.negative_prompt, args.seed) + generate_image(args.prompt, args.negative_prompt, seed) else: # loop for interactive while True: From d395bc064743a6e7cfdf345b6e607908710a69dc Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 29 Jun 2023 13:02:19 +0900 Subject: [PATCH 041/220] fix max_token_length not works for sdxl --- library/sdxl_train_util.py | 51 +++++++++++++++++++++----------------- library/train_util.py | 1 + sdxl_train.py | 8 +++--- sdxl_train_network.py | 10 ++++---- train_network.py | 2 +- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 46756b865..e3b502c26 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -126,6 +126,8 @@ def load_tokenizers(args: argparse.Namespace): def get_hidden_states( args: argparse.Namespace, input_ids1, input_ids2, tokenizer1, tokenizer2, text_encoder1, text_encoder2, weight_dtype=None ): + # input_ids: b,n,77 -> b*n, 77 + b_size = input_ids1.size()[0] input_ids1 = input_ids1.reshape((-1, tokenizer1.model_max_length)) # batch_size*n, 77 input_ids2 = input_ids2.reshape((-1, tokenizer2.model_max_length)) # batch_size*n, 77 @@ -138,6 +140,11 @@ def get_hidden_states( hidden_states2 = enc_out["hidden_states"][-2] # penuultimate layer pool2 = enc_out["text_embeds"] + # b*n, 77, 768 or 1280 -> b, n*77, 768 or 1280 + n_size = 1 if args.max_token_length is None else args.max_token_length // 75 + hidden_states1 = hidden_states1.reshape((b_size, -1, hidden_states1.shape[-1])) + hidden_states2 = hidden_states2.reshape((b_size, -1, hidden_states2.shape[-1])) + if args.max_token_length is not None: # bs*3, 77, 768 or 1024 # encoder1: ... の三連を ... へ戻す @@ -151,14 +158,19 @@ def get_hidden_states( states_list = [hidden_states2[:, 0].unsqueeze(1)] # for i in range(1, args.max_token_length, tokenizer2.model_max_length): chunk = hidden_states2[:, i : i + tokenizer2.model_max_length - 2] # の後から 最後の前まで - if i > 0: - for j in range(len(chunk)): - if input_ids2[j, 1] == tokenizer2.eos_token: # 空、つまり ...のパターン - chunk[j, 0] = chunk[j, 1] # 次の の値をコピーする + # this causes an error: + # RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation + # if i > 1: + # for j in range(len(chunk)): # batch_size + # if input_ids2[n_index + j * n_size, 1] == tokenizer2.eos_token_id: # 空、つまり ...のパターン + # chunk[j, 0] = chunk[j, 1] # 次の の値をコピーする states_list.append(chunk) # の後から の前まで states_list.append(hidden_states2[:, -1].unsqueeze(1)) # のどちらか hidden_states2 = torch.cat(states_list, dim=1) + # pool はnの最初のものを使う + pool2 = pool2[::n_size] + if weight_dtype is not None: # this is required for additional network training hidden_states1 = hidden_states1.to(weight_dtype) @@ -313,37 +325,30 @@ def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, dat # split batch to avoid OOM # TODO specify batch size by args - for input_ids1, input_ids2 in zip(input_ids1_batch.split(1), input_ids2_batch.split(1)): + for input_id1, input_id2 in zip(input_ids1_batch.split(1), input_ids2_batch.split(1)): # remove input_ids already in cache - input_ids1 = input_ids1.squeeze(0) - input_ids2 = input_ids2.squeeze(0) - input_ids1 = [i for i in input_ids1 if i not in text_encoder1_cache] - input_ids2 = [i for i in input_ids2 if i not in text_encoder2_cache] - assert len(input_ids1) == len(input_ids2) - if len(input_ids1) == 0: + input_id1_cache_key = tuple(input_id1.flatten().tolist()) + input_id2_cache_key = tuple(input_id2.flatten().tolist()) + if input_id1_cache_key in text_encoder1_cache: + assert input_id2_cache_key in text_encoder2_cache continue - input_ids1 = torch.stack(input_ids1).to(accelerator.device) - input_ids2 = torch.stack(input_ids2).to(accelerator.device) with torch.no_grad(): encoder_hidden_states1, encoder_hidden_states2, pool2 = get_hidden_states( args, - input_ids1, - input_ids2, + input_id1, + input_id2, tokenizer1, tokenizer2, text_encoder1, text_encoder2, None if not args.full_fp16 else weight_dtype, ) - encoder_hidden_states1 = encoder_hidden_states1.detach().to("cpu") - encoder_hidden_states2 = encoder_hidden_states2.detach().to("cpu") - pool2 = pool2.to("cpu") - for input_id1, input_id2, hidden_states1, hidden_states2, p2 in zip( - input_ids1, input_ids2, encoder_hidden_states1, encoder_hidden_states2, pool2 - ): - text_encoder1_cache[tuple(input_id1.tolist())] = hidden_states1 - text_encoder2_cache[tuple(input_id2.tolist())] = (hidden_states2, p2) + encoder_hidden_states1 = encoder_hidden_states1.detach().to("cpu").squeeze(0) # n*75+2,768 + encoder_hidden_states2 = encoder_hidden_states2.detach().to("cpu").squeeze(0) # n*75+2,1280 + pool2 = pool2.detach().to("cpu").squeeze(0) # 1280 + text_encoder1_cache[input_id1_cache_key] = encoder_hidden_states1 + text_encoder2_cache[input_id2_cache_key] = (encoder_hidden_states2, pool2) return text_encoder1_cache, text_encoder2_cache diff --git a/library/train_util.py b/library/train_util.py index c27e1b273..43f553533 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3358,6 +3358,7 @@ def get_hidden_states(args: argparse.Namespace, input_ids, tokenizer, text_encod if input_ids.size()[-1] != tokenizer.model_max_length: return text_encoder(input_ids)[0] + # input_ids: b,n,77 b_size = input_ids.size()[0] input_ids = input_ids.reshape((-1, tokenizer.model_max_length)) # batch_size*3, 77 diff --git a/sdxl_train.py b/sdxl_train.py index f640580af..66b3c76d5 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -382,10 +382,10 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): encoder_hidden_states2 = [] pool2 = [] for input_id1, input_id2 in zip(input_ids1, input_ids2): - input_id1 = input_id1.squeeze(0) - input_id2 = input_id2.squeeze(0) - encoder_hidden_states1.append(text_encoder1_cache[tuple(input_id1.tolist())]) - hidden_states2, p2 = text_encoder2_cache[tuple(input_id2.tolist())] + input_id1_cache_key = tuple(input_id1.squeeze(0).flatten().tolist()) + input_id2_cache_key = tuple(input_id2.squeeze(0).flatten().tolist()) + encoder_hidden_states1.append(text_encoder1_cache[input_id1_cache_key]) + hidden_states2, p2 = text_encoder2_cache[input_id2_cache_key] encoder_hidden_states2.append(hidden_states2) pool2.append(p2) encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) diff --git a/sdxl_train_network.py b/sdxl_train_network.py index fb445fb7d..8f52fe5d2 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -11,7 +11,7 @@ def __init__(self): self.sampling_warning_showed = False def assert_extra_args(self, args, train_dataset_group): - super().assert_extra_args(args) + super().assert_extra_args(args, train_dataset_group) sdxl_train_util.verify_sdxl_training_args(args) if args.cache_text_encoder_outputs: @@ -119,10 +119,10 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei encoder_hidden_states2 = [] pool2 = [] for input_id1, input_id2 in zip(input_ids1, input_ids2): - input_id1 = input_id1.squeeze(0) - input_id2 = input_id2.squeeze(0) - encoder_hidden_states1.append(self.text_encoder1_cache[tuple(input_id1.tolist())]) - hidden_states2, p2 = self.text_encoder2_cache[tuple(input_id2.tolist())] + input_id1_cache_key = tuple(input_id1.flatten().tolist()) + input_id2_cache_key = tuple(input_id2.flatten().tolist()) + encoder_hidden_states1.append(self.text_encoder1_cache[input_id1_cache_key]) + hidden_states2, p2 = self.text_encoder2_cache[input_id2_cache_key] encoder_hidden_states2.append(hidden_states2) pool2.append(p2) encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) diff --git a/train_network.py b/train_network.py index 1a3c19e2e..e42225f1a 100644 --- a/train_network.py +++ b/train_network.py @@ -83,7 +83,7 @@ def generate_step_logs( return logs - def assert_extra_args(self, args): + def assert_extra_args(self, args, train_dataset_group): pass def load_target_model(self, args, weight_dtype, accelerator): From 38e21f5c1ab590dddf844d5314a37a89a7e1594d Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 29 Jun 2023 13:03:00 +0900 Subject: [PATCH 042/220] update transfomer to fix sdxl text model with bf16 --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index babd96e9f..86c48a19c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ accelerate==0.19.0 -transformers==4.29.2 +transformers==4.30.2 diffusers[torch]==0.17.1 ftfy==6.1.1 albumentations==1.3.0 @@ -8,7 +8,7 @@ einops==0.6.0 pytorch-lightning==1.9.0 bitsandbytes==0.35.0 tensorboard==2.10.1 -safetensors==0.2.6 +safetensors==0.3.1 # gradio==3.16.2 altair==4.2.2 easygui==0.98.3 From 227a62e4c4d3c3c5269a244328609ce2da96ebda Mon Sep 17 00:00:00 2001 From: Kohya S Date: Fri, 30 Jun 2023 07:40:22 +0900 Subject: [PATCH 043/220] fix to work with dreambooth ds without toml --- sdxl_train.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/sdxl_train.py b/sdxl_train.py index 66b3c76d5..35934c385 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -41,6 +41,7 @@ def train(args): ), "cache_text_encoder_outputs is not supported when training text encoder / text encoderを学習するときはcache_text_encoder_outputsはサポートされていません" cache_latents = args.cache_latents + use_dreambooth_method = args.in_json is None if args.seed is not None: set_seed(args.seed) # 乱数系列を初期化する @@ -61,18 +62,31 @@ def train(args): ) ) else: - user_config = { - "datasets": [ - { - "subsets": [ - { - "image_dir": args.train_data_dir, - "metadata_file": args.in_json, - } - ] - } - ] - } + if use_dreambooth_method: + print("Using DreamBooth method.") + user_config = { + "datasets": [ + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } + ] + } + else: + print("Training with captions.") + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } blueprint = blueprint_generator.generate(user_config, args, tokenizer=[tokenizer1, tokenizer2]) train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) From 64cf92284130193b61efc09ed5446afe7f2f6eff Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 2 Jul 2023 16:42:19 +0900 Subject: [PATCH 044/220] add feature to sample images during sdxl training --- library/sdxl_lpw_stable_diffusion.py | 1346 ++++++++++++++++++++++++++ library/sdxl_train_util.py | 26 +- library/train_util.py | 12 +- sdxl_train.py | 41 +- sdxl_train_network.py | 9 +- 5 files changed, 1402 insertions(+), 32 deletions(-) create mode 100644 library/sdxl_lpw_stable_diffusion.py diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py new file mode 100644 index 000000000..786b8119a --- /dev/null +++ b/library/sdxl_lpw_stable_diffusion.py @@ -0,0 +1,1346 @@ +# copy from https://github.com/huggingface/diffusers/blob/main/examples/community/lpw_stable_diffusion.py +# and modify to support SD2.x + +import inspect +import re +from typing import Callable, List, Optional, Union + +import numpy as np +import PIL.Image +import torch +from packaging import version +from tqdm import tqdm +from transformers import CLIPFeatureExtractor, CLIPTextModel, CLIPTokenizer + +from diffusers import SchedulerMixin, StableDiffusionPipeline +from diffusers.models import AutoencoderKL, UNet2DConditionModel +from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput, StableDiffusionSafetyChecker +from diffusers.utils import logging +from PIL import Image + +from library import sdxl_model_util, sdxl_train_util + + +try: + from diffusers.utils import PIL_INTERPOLATION +except ImportError: + if version.parse(version.parse(PIL.__version__).base_version) >= version.parse("9.1.0"): + PIL_INTERPOLATION = { + "linear": PIL.Image.Resampling.BILINEAR, + "bilinear": PIL.Image.Resampling.BILINEAR, + "bicubic": PIL.Image.Resampling.BICUBIC, + "lanczos": PIL.Image.Resampling.LANCZOS, + "nearest": PIL.Image.Resampling.NEAREST, + } + else: + PIL_INTERPOLATION = { + "linear": PIL.Image.LINEAR, + "bilinear": PIL.Image.BILINEAR, + "bicubic": PIL.Image.BICUBIC, + "lanczos": PIL.Image.LANCZOS, + "nearest": PIL.Image.NEAREST, + } +# ------------------------------------------------------------------------------ + +logger = logging.get_logger(__name__) # pylint: disable=invalid-name + +re_attention = re.compile( + r""" +\\\(| +\\\)| +\\\[| +\\]| +\\\\| +\\| +\(| +\[| +:([+-]?[.\d]+)\)| +\)| +]| +[^\\()\[\]:]+| +: +""", + re.X, +) + + +def parse_prompt_attention(text): + """ + Parses a string with attention tokens and returns a list of pairs: text and its associated weight. + Accepted tokens are: + (abc) - increases attention to abc by a multiplier of 1.1 + (abc:3.12) - increases attention to abc by a multiplier of 3.12 + [abc] - decreases attention to abc by a multiplier of 1.1 + \( - literal character '(' + \[ - literal character '[' + \) - literal character ')' + \] - literal character ']' + \\ - literal character '\' + anything else - just text + >>> parse_prompt_attention('normal text') + [['normal text', 1.0]] + >>> parse_prompt_attention('an (important) word') + [['an ', 1.0], ['important', 1.1], [' word', 1.0]] + >>> parse_prompt_attention('(unbalanced') + [['unbalanced', 1.1]] + >>> parse_prompt_attention('\(literal\]') + [['(literal]', 1.0]] + >>> parse_prompt_attention('(unnecessary)(parens)') + [['unnecessaryparens', 1.1]] + >>> parse_prompt_attention('a (((house:1.3)) [on] a (hill:0.5), sun, (((sky))).') + [['a ', 1.0], + ['house', 1.5730000000000004], + [' ', 1.1], + ['on', 1.0], + [' a ', 1.1], + ['hill', 0.55], + [', sun, ', 1.1], + ['sky', 1.4641000000000006], + ['.', 1.1]] + """ + + res = [] + round_brackets = [] + square_brackets = [] + + round_bracket_multiplier = 1.1 + square_bracket_multiplier = 1 / 1.1 + + def multiply_range(start_position, multiplier): + for p in range(start_position, len(res)): + res[p][1] *= multiplier + + for m in re_attention.finditer(text): + text = m.group(0) + weight = m.group(1) + + if text.startswith("\\"): + res.append([text[1:], 1.0]) + elif text == "(": + round_brackets.append(len(res)) + elif text == "[": + square_brackets.append(len(res)) + elif weight is not None and len(round_brackets) > 0: + multiply_range(round_brackets.pop(), float(weight)) + elif text == ")" and len(round_brackets) > 0: + multiply_range(round_brackets.pop(), round_bracket_multiplier) + elif text == "]" and len(square_brackets) > 0: + multiply_range(square_brackets.pop(), square_bracket_multiplier) + else: + res.append([text, 1.0]) + + for pos in round_brackets: + multiply_range(pos, round_bracket_multiplier) + + for pos in square_brackets: + multiply_range(pos, square_bracket_multiplier) + + if len(res) == 0: + res = [["", 1.0]] + + # merge runs of identical weights + i = 0 + while i + 1 < len(res): + if res[i][1] == res[i + 1][1]: + res[i][0] += res[i + 1][0] + res.pop(i + 1) + else: + i += 1 + + return res + + +def get_prompts_with_weights(pipe: StableDiffusionPipeline, prompt: List[str], max_length: int): + r""" + Tokenize a list of prompts and return its tokens with weights of each token. + + No padding, starting or ending token is included. + """ + tokens = [] + weights = [] + truncated = False + for text in prompt: + texts_and_weights = parse_prompt_attention(text) + text_token = [] + text_weight = [] + for word, weight in texts_and_weights: + # tokenize and discard the starting and the ending token + token = pipe.tokenizer(word).input_ids[1:-1] + text_token += token + # copy the weight by length of token + text_weight += [weight] * len(token) + # stop if the text is too long (longer than truncation limit) + if len(text_token) > max_length: + truncated = True + break + # truncate + if len(text_token) > max_length: + truncated = True + text_token = text_token[:max_length] + text_weight = text_weight[:max_length] + tokens.append(text_token) + weights.append(text_weight) + if truncated: + logger.warning("Prompt was truncated. Try to shorten the prompt or increase max_embeddings_multiples") + return tokens, weights + + +def pad_tokens_and_weights(tokens, weights, max_length, bos, eos, no_boseos_middle=True, chunk_length=77): + r""" + Pad the tokens (with starting and ending tokens) and weights (with 1.0) to max_length. + """ + max_embeddings_multiples = (max_length - 2) // (chunk_length - 2) + weights_length = max_length if no_boseos_middle else max_embeddings_multiples * chunk_length + for i in range(len(tokens)): + tokens[i] = [bos] + tokens[i] + [eos] * (max_length - 1 - len(tokens[i])) + if no_boseos_middle: + weights[i] = [1.0] + weights[i] + [1.0] * (max_length - 1 - len(weights[i])) + else: + w = [] + if len(weights[i]) == 0: + w = [1.0] * weights_length + else: + for j in range(max_embeddings_multiples): + w.append(1.0) # weight for starting token in this chunk + w += weights[i][j * (chunk_length - 2) : min(len(weights[i]), (j + 1) * (chunk_length - 2))] + w.append(1.0) # weight for ending token in this chunk + w += [1.0] * (weights_length - len(w)) + weights[i] = w[:] + + return tokens, weights + + +def get_hidden_states(text_encoder, input_ids, is_sdxl_text_encoder2: bool, device): + if not is_sdxl_text_encoder2: + # text_encoder1: same as SD1/2 + enc_out = text_encoder(input_ids.to(text_encoder.device), output_hidden_states=True, return_dict=True) + hidden_states = enc_out["hidden_states"][11] + pool = None + else: + # text_encoder2 + enc_out = text_encoder(input_ids.to(text_encoder.device), output_hidden_states=True, return_dict=True) + hidden_states = enc_out["hidden_states"][-2] # penuultimate layer + pool = enc_out["text_embeds"] + hidden_states = hidden_states.to(device) + if pool is not None: + pool = pool.to(device) + return hidden_states, pool + + +def get_unweighted_text_embeddings( + pipe: StableDiffusionPipeline, + text_input: torch.Tensor, + chunk_length: int, + clip_skip: int, + eos: int, + pad: int, + is_sdxl_text_encoder2: bool, + no_boseos_middle: Optional[bool] = True, +): + """ + When the length of tokens is a multiple of the capacity of the text encoder, + it should be split into chunks and sent to the text encoder individually. + """ + max_embeddings_multiples = (text_input.shape[1] - 2) // (chunk_length - 2) + text_pool = None + if max_embeddings_multiples > 1: + text_embeddings = [] + for i in range(max_embeddings_multiples): + # extract the i-th chunk + text_input_chunk = text_input[:, i * (chunk_length - 2) : (i + 1) * (chunk_length - 2) + 2].clone() + + # cover the head and the tail by the starting and the ending tokens + text_input_chunk[:, 0] = text_input[0, 0] + if pad == eos: # v1 + text_input_chunk[:, -1] = text_input[0, -1] + else: # v2 + for j in range(len(text_input_chunk)): + if text_input_chunk[j, -1] != eos and text_input_chunk[j, -1] != pad: # 最後に普通の文字がある + text_input_chunk[j, -1] = eos + if text_input_chunk[j, 1] == pad: # BOSだけであとはPAD + text_input_chunk[j, 1] = eos + + text_embedding, current_text_pool = get_hidden_states( + pipe.text_encoder, text_input_chunk, is_sdxl_text_encoder2, pipe.device + ) + if text_pool is None: + text_pool = current_text_pool + + if no_boseos_middle: + if i == 0: + # discard the ending token + text_embedding = text_embedding[:, :-1] + elif i == max_embeddings_multiples - 1: + # discard the starting token + text_embedding = text_embedding[:, 1:] + else: + # discard both starting and ending tokens + text_embedding = text_embedding[:, 1:-1] + + text_embeddings.append(text_embedding) + text_embeddings = torch.concat(text_embeddings, axis=1) + else: + text_embeddings, text_pool = get_hidden_states(pipe.text_encoder, text_input, is_sdxl_text_encoder2, pipe.device) + return text_embeddings, text_pool + + +def get_weighted_text_embeddings( + pipe: StableDiffusionPipeline, + prompt: Union[str, List[str]], + uncond_prompt: Optional[Union[str, List[str]]] = None, + max_embeddings_multiples: Optional[int] = 3, + no_boseos_middle: Optional[bool] = False, + skip_parsing: Optional[bool] = False, + skip_weighting: Optional[bool] = False, + clip_skip=None, + is_sdxl_text_encoder2=False, +): + r""" + Prompts can be assigned with local weights using brackets. For example, + prompt 'A (very beautiful) masterpiece' highlights the words 'very beautiful', + and the embedding tokens corresponding to the words get multiplied by a constant, 1.1. + + Also, to regularize of the embedding, the weighted embedding would be scaled to preserve the original mean. + + Args: + pipe (`StableDiffusionPipeline`): + Pipe to provide access to the tokenizer and the text encoder. + prompt (`str` or `List[str]`): + The prompt or prompts to guide the image generation. + uncond_prompt (`str` or `List[str]`): + The unconditional prompt or prompts for guide the image generation. If unconditional prompt + is provided, the embeddings of prompt and uncond_prompt are concatenated. + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + no_boseos_middle (`bool`, *optional*, defaults to `False`): + If the length of text token is multiples of the capacity of text encoder, whether reserve the starting and + ending token in each of the chunk in the middle. + skip_parsing (`bool`, *optional*, defaults to `False`): + Skip the parsing of brackets. + skip_weighting (`bool`, *optional*, defaults to `False`): + Skip the weighting. When the parsing is skipped, it is forced True. + """ + max_length = (pipe.tokenizer.model_max_length - 2) * max_embeddings_multiples + 2 + if isinstance(prompt, str): + prompt = [prompt] + + if not skip_parsing: + prompt_tokens, prompt_weights = get_prompts_with_weights(pipe, prompt, max_length - 2) + if uncond_prompt is not None: + if isinstance(uncond_prompt, str): + uncond_prompt = [uncond_prompt] + uncond_tokens, uncond_weights = get_prompts_with_weights(pipe, uncond_prompt, max_length - 2) + else: + prompt_tokens = [token[1:-1] for token in pipe.tokenizer(prompt, max_length=max_length, truncation=True).input_ids] + prompt_weights = [[1.0] * len(token) for token in prompt_tokens] + if uncond_prompt is not None: + if isinstance(uncond_prompt, str): + uncond_prompt = [uncond_prompt] + uncond_tokens = [ + token[1:-1] for token in pipe.tokenizer(uncond_prompt, max_length=max_length, truncation=True).input_ids + ] + uncond_weights = [[1.0] * len(token) for token in uncond_tokens] + + # round up the longest length of tokens to a multiple of (model_max_length - 2) + max_length = max([len(token) for token in prompt_tokens]) + if uncond_prompt is not None: + max_length = max(max_length, max([len(token) for token in uncond_tokens])) + + max_embeddings_multiples = min( + max_embeddings_multiples, + (max_length - 1) // (pipe.tokenizer.model_max_length - 2) + 1, + ) + max_embeddings_multiples = max(1, max_embeddings_multiples) + max_length = (pipe.tokenizer.model_max_length - 2) * max_embeddings_multiples + 2 + + # pad the length of tokens and weights + bos = pipe.tokenizer.bos_token_id + eos = pipe.tokenizer.eos_token_id + pad = pipe.tokenizer.pad_token_id + prompt_tokens, prompt_weights = pad_tokens_and_weights( + prompt_tokens, + prompt_weights, + max_length, + bos, + eos, + no_boseos_middle=no_boseos_middle, + chunk_length=pipe.tokenizer.model_max_length, + ) + prompt_tokens = torch.tensor(prompt_tokens, dtype=torch.long, device=pipe.device) + if uncond_prompt is not None: + uncond_tokens, uncond_weights = pad_tokens_and_weights( + uncond_tokens, + uncond_weights, + max_length, + bos, + eos, + no_boseos_middle=no_boseos_middle, + chunk_length=pipe.tokenizer.model_max_length, + ) + uncond_tokens = torch.tensor(uncond_tokens, dtype=torch.long, device=pipe.device) + + # get the embeddings + text_embeddings, text_pool = get_unweighted_text_embeddings( + pipe, + prompt_tokens, + pipe.tokenizer.model_max_length, + clip_skip, + eos, + pad, + is_sdxl_text_encoder2, + no_boseos_middle=no_boseos_middle, + ) + prompt_weights = torch.tensor(prompt_weights, dtype=text_embeddings.dtype, device=pipe.device) + + if uncond_prompt is not None: + uncond_embeddings, uncond_pool = get_unweighted_text_embeddings( + pipe, + uncond_tokens, + pipe.tokenizer.model_max_length, + clip_skip, + eos, + pad, + is_sdxl_text_encoder2, + no_boseos_middle=no_boseos_middle, + ) + uncond_weights = torch.tensor(uncond_weights, dtype=uncond_embeddings.dtype, device=pipe.device) + + # assign weights to the prompts and normalize in the sense of mean + # TODO: should we normalize by chunk or in a whole (current implementation)? + if (not skip_parsing) and (not skip_weighting): + previous_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype) + text_embeddings *= prompt_weights.unsqueeze(-1) + current_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype) + text_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1) + if uncond_prompt is not None: + previous_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype) + uncond_embeddings *= uncond_weights.unsqueeze(-1) + current_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype) + uncond_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1) + + if uncond_prompt is not None: + return text_embeddings, text_pool, uncond_embeddings, uncond_pool + return text_embeddings, text_pool, None, None + + +def preprocess_image(image): + w, h = image.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + image = image.resize((w, h), resample=PIL_INTERPOLATION["lanczos"]) + image = np.array(image).astype(np.float32) / 255.0 + image = image[None].transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + return 2.0 * image - 1.0 + + +def preprocess_mask(mask, scale_factor=8): + mask = mask.convert("L") + w, h = mask.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + mask = mask.resize((w // scale_factor, h // scale_factor), resample=PIL_INTERPOLATION["nearest"]) + mask = np.array(mask).astype(np.float32) / 255.0 + mask = np.tile(mask, (4, 1, 1)) + mask = mask[None].transpose(0, 1, 2, 3) # what does this step do? + mask = 1 - mask # repaint white, keep black + mask = torch.from_numpy(mask) + return mask + + +def prepare_controlnet_image( + image: PIL.Image.Image, + width: int, + height: int, + batch_size: int, + num_images_per_prompt: int, + device: torch.device, + dtype: torch.dtype, + do_classifier_free_guidance: bool = False, + guess_mode: bool = False, +): + if not isinstance(image, torch.Tensor): + if isinstance(image, PIL.Image.Image): + image = [image] + + if isinstance(image[0], PIL.Image.Image): + images = [] + + for image_ in image: + image_ = image_.convert("RGB") + image_ = image_.resize((width, height), resample=PIL_INTERPOLATION["lanczos"]) + image_ = np.array(image_) + image_ = image_[None, :] + images.append(image_) + + image = images + + image = np.concatenate(image, axis=0) + image = np.array(image).astype(np.float32) / 255.0 + image = image.transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + elif isinstance(image[0], torch.Tensor): + image = torch.cat(image, dim=0) + + image_batch_size = image.shape[0] + + if image_batch_size == 1: + repeat_by = batch_size + else: + # image batch size is the same as prompt batch size + repeat_by = num_images_per_prompt + + image = image.repeat_interleave(repeat_by, dim=0) + + image = image.to(device=device, dtype=dtype) + + if do_classifier_free_guidance and not guess_mode: + image = torch.cat([image] * 2) + + return image + + +class SdxlStableDiffusionLongPromptWeightingPipeline: + r""" + Pipeline for text-to-image generation using Stable Diffusion without tokens length limit, and support parsing + weighting in prompt. + + This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the + library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.) + + Args: + vae ([`AutoencoderKL`]): + Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations. + text_encoder ([`CLIPTextModel`]): + Frozen text-encoder. Stable Diffusion uses the text portion of + [CLIP](https://huggingface.co/docs/transformers/model_doc/clip#transformers.CLIPTextModel), specifically + the [clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14) variant. + tokenizer (`CLIPTokenizer`): + Tokenizer of class + [CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer). + unet ([`UNet2DConditionModel`]): Conditional U-Net architecture to denoise the encoded image latents. + scheduler ([`SchedulerMixin`]): + A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of + [`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`]. + safety_checker ([`StableDiffusionSafetyChecker`]): + Classification module that estimates whether generated images could be considered offensive or harmful. + Please, refer to the [model card](https://huggingface.co/CompVis/stable-diffusion-v1-4) for details. + feature_extractor ([`CLIPFeatureExtractor`]): + Model that extracts features from generated images to be used as inputs for the `safety_checker`. + """ + + # if version.parse(version.parse(diffusers.__version__).base_version) >= version.parse("0.9.0"): + + def __init__( + self, + vae: AutoencoderKL, + text_encoder: List[CLIPTextModel], + tokenizer: List[CLIPTokenizer], + unet: UNet2DConditionModel, + scheduler: SchedulerMixin, + # clip_skip: int, + safety_checker: StableDiffusionSafetyChecker, + feature_extractor: CLIPFeatureExtractor, + requires_safety_checker: bool = True, + clip_skip: int = 1, + ): + # clip skip is ignored currently + self.tokenizer = tokenizer[0] + self.text_encoder = text_encoder[0] + self.unet = unet + self.scheduler = scheduler + self.safety_checker = safety_checker + self.feature_extractor = feature_extractor + self.requires_safety_checker = requires_safety_checker + self.vae = vae + self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) + self.progress_bar = lambda x: tqdm(x, leave=False) + + self.clip_skip = clip_skip + self.tokenizers = tokenizer + self.text_encoders = text_encoder + + # self.__init__additional__() + + # def __init__additional__(self): + # if not hasattr(self, "vae_scale_factor"): + # setattr(self, "vae_scale_factor", 2 ** (len(self.vae.config.block_out_channels) - 1)) + + def to(self, device=None, dtype=None): + if device is not None: + self.device = device + # self.vae.to(device=self.device) + if dtype is not None: + self.dtype = dtype + + # do not move Text Encoders to device, because Text Encoder should be on CPU + + @property + def _execution_device(self): + r""" + Returns the device on which the pipeline's models will be executed. After calling + `pipeline.enable_sequential_cpu_offload()` the execution device can only be inferred from Accelerate's module + hooks. + """ + if self.device != torch.device("meta") or not hasattr(self.unet, "_hf_hook"): + return self.device + for module in self.unet.modules(): + if ( + hasattr(module, "_hf_hook") + and hasattr(module._hf_hook, "execution_device") + and module._hf_hook.execution_device is not None + ): + return torch.device(module._hf_hook.execution_device) + return self.device + + def _encode_prompt( + self, + prompt, + device, + num_images_per_prompt, + do_classifier_free_guidance, + negative_prompt, + max_embeddings_multiples, + is_sdxl_text_encoder2, + ): + r""" + Encodes the prompt into text encoder hidden states. + + Args: + prompt (`str` or `list(int)`): + prompt to be encoded + device: (`torch.device`): + torch device + num_images_per_prompt (`int`): + number of images that should be generated per prompt + do_classifier_free_guidance (`bool`): + whether to use classifier free guidance or not + negative_prompt (`str` or `List[str]`): + The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored + if `guidance_scale` is less than `1`). + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + """ + batch_size = len(prompt) if isinstance(prompt, list) else 1 + + if negative_prompt is None: + negative_prompt = [""] * batch_size + elif isinstance(negative_prompt, str): + negative_prompt = [negative_prompt] * batch_size + if batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + + text_embeddings, text_pool, uncond_embeddings, uncond_pool = get_weighted_text_embeddings( + pipe=self, + prompt=prompt, + uncond_prompt=negative_prompt if do_classifier_free_guidance else None, + max_embeddings_multiples=max_embeddings_multiples, + clip_skip=self.clip_skip, + is_sdxl_text_encoder2=is_sdxl_text_encoder2, + ) + bs_embed, seq_len, _ = text_embeddings.shape + text_embeddings = text_embeddings.repeat(1, num_images_per_prompt, 1) # ?? + text_embeddings = text_embeddings.view(bs_embed * num_images_per_prompt, seq_len, -1) + if text_pool is not None: + text_pool = text_pool.repeat(1, num_images_per_prompt) + text_pool = text_pool.view(bs_embed * num_images_per_prompt, -1) + + if do_classifier_free_guidance: + bs_embed, seq_len, _ = uncond_embeddings.shape + uncond_embeddings = uncond_embeddings.repeat(1, num_images_per_prompt, 1) + uncond_embeddings = uncond_embeddings.view(bs_embed * num_images_per_prompt, seq_len, -1) + if uncond_pool is not None: + uncond_pool = uncond_pool.repeat(1, num_images_per_prompt) + uncond_pool = uncond_pool.view(bs_embed * num_images_per_prompt, -1) + + text_embeddings = torch.cat([uncond_embeddings, text_embeddings]) + if text_pool is not None: + text_pool = torch.cat([uncond_pool, text_pool]) + + return text_embeddings, text_pool + + def check_inputs(self, prompt, height, width, strength, callback_steps): + if not isinstance(prompt, str) and not isinstance(prompt, list): + raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") + + if strength < 0 or strength > 1: + raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}") + + if height % 8 != 0 or width % 8 != 0: + print(height, width) + raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") + + if (callback_steps is None) or ( + callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0) + ): + raise ValueError( + f"`callback_steps` has to be a positive integer but is {callback_steps} of type" f" {type(callback_steps)}." + ) + + def get_timesteps(self, num_inference_steps, strength, device, is_text2img): + if is_text2img: + return self.scheduler.timesteps.to(device), num_inference_steps + else: + # get the original timestep using init_timestep + offset = self.scheduler.config.get("steps_offset", 0) + init_timestep = int(num_inference_steps * strength) + offset + init_timestep = min(init_timestep, num_inference_steps) + + t_start = max(num_inference_steps - init_timestep + offset, 0) + timesteps = self.scheduler.timesteps[t_start:].to(device) + return timesteps, num_inference_steps - t_start + + def run_safety_checker(self, image, device, dtype): + if self.safety_checker is not None: + safety_checker_input = self.feature_extractor(self.numpy_to_pil(image), return_tensors="pt").to(device) + image, has_nsfw_concept = self.safety_checker(images=image, clip_input=safety_checker_input.pixel_values.to(dtype)) + else: + has_nsfw_concept = None + return image, has_nsfw_concept + + def decode_latents(self, latents): + with torch.no_grad(): + latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents + + # print("post_quant_conv dtype:", self.vae.post_quant_conv.weight.dtype) # torch.float32 + # x = torch.nn.functional.conv2d(latents, self.vae.post_quant_conv.weight.detach(), stride=1, padding=0) + # print("latents dtype:", latents.dtype, "x dtype:", x.dtype) # torch.float32, torch.float16 + # self.vae.to("cpu") + # self.vae.set_use_memory_efficient_attention_xformers(False) + # image = self.vae.decode(latents.to("cpu")).sample + + print("default dtype:", torch.get_default_dtype()) + assert latents.dtype == torch.float32 + assert self.vae.post_quant_conv.weight.dtype == torch.float32 + print("device:", latents.device, "latents dtype:", latents.dtype, "weight dtype:", self.vae.post_quant_conv.weight.dtype) + w = torch.randn_like(self.vae.post_quant_conv.weight, dtype=torch.float32, device=latents.device) + x = torch.randn_like(latents, dtype=torch.float32, device=latents.device) + x = torch.nn.functional.conv2d(x, w) + print("result dtype:", x.dtype) # float16 !! + w = torch.randn_like(self.vae.post_quant_conv.weight, dtype=torch.float32, device="cpu") + x = torch.randn_like(latents, dtype=torch.float32, device="cpu") + x = torch.nn.functional.conv2d(x, w) + print("result dtype:", x.dtype) # float32 + + image = self.vae.decode(latents).sample + image = (image / 2 + 0.5).clamp(0, 1) + # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16 + image = image.cpu().permute(0, 2, 3, 1).float().numpy() + return image + + def prepare_extra_step_kwargs(self, generator, eta): + # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature + # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. + # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502 + # and should be between [0, 1] + + accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()) + extra_step_kwargs = {} + if accepts_eta: + extra_step_kwargs["eta"] = eta + + # check if the scheduler accepts generator + accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys()) + if accepts_generator: + extra_step_kwargs["generator"] = generator + return extra_step_kwargs + + def prepare_latents(self, image, timestep, batch_size, height, width, dtype, device, generator, latents=None): + if image is None: + shape = ( + batch_size, + self.unet.in_channels, + height // self.vae_scale_factor, + width // self.vae_scale_factor, + ) + + if latents is None: + if device.type == "mps": + # randn does not work reproducibly on mps + latents = torch.randn(shape, generator=generator, device="cpu", dtype=dtype).to(device) + else: + latents = torch.randn(shape, generator=generator, device=device, dtype=dtype) + else: + if latents.shape != shape: + raise ValueError(f"Unexpected latents shape, got {latents.shape}, expected {shape}") + latents = latents.to(device) + + # scale the initial noise by the standard deviation required by the scheduler + latents = latents * self.scheduler.init_noise_sigma + return latents, None, None + else: + init_latent_dist = self.vae.encode(image).latent_dist + init_latents = init_latent_dist.sample(generator=generator) + init_latents = sdxl_model_util.VAE_SCALE_FACTOR * init_latents + init_latents = torch.cat([init_latents] * batch_size, dim=0) + init_latents_orig = init_latents + shape = init_latents.shape + + # add noise to latents using the timesteps + if device.type == "mps": + noise = torch.randn(shape, generator=generator, device="cpu", dtype=dtype).to(device) + else: + noise = torch.randn(shape, generator=generator, device=device, dtype=dtype) + latents = self.scheduler.add_noise(init_latents, noise, timestep) + return latents, init_latents_orig, noise + + @torch.no_grad() + def __call__( + self, + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + image: Union[torch.FloatTensor, PIL.Image.Image] = None, + mask_image: Union[torch.FloatTensor, PIL.Image.Image] = None, + height: int = 512, + width: int = 512, + num_inference_steps: int = 50, + guidance_scale: float = 7.5, + strength: float = 0.8, + num_images_per_prompt: Optional[int] = 1, + eta: float = 0.0, + generator: Optional[torch.Generator] = None, + latents: Optional[torch.FloatTensor] = None, + max_embeddings_multiples: Optional[int] = 3, + output_type: Optional[str] = "pil", + return_dict: bool = True, + controlnet=None, + controlnet_image=None, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + r""" + Function invoked when calling the pipeline for generation. + + Args: + prompt (`str` or `List[str]`): + The prompt or prompts to guide the image generation. + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored + if `guidance_scale` is less than `1`). + image (`torch.FloatTensor` or `PIL.Image.Image`): + `Image`, or tensor representing an image batch, that will be used as the starting point for the + process. + mask_image (`torch.FloatTensor` or `PIL.Image.Image`): + `Image`, or tensor representing an image batch, to mask `image`. White pixels in the mask will be + replaced by noise and therefore repainted, while black pixels will be preserved. If `mask_image` is a + PIL image, it will be converted to a single channel (luminance) before use. If it's a tensor, it should + contain one color channel (L) instead of 3, so the expected shape would be `(B, H, W, 1)`. + height (`int`, *optional*, defaults to 512): + The height in pixels of the generated image. + width (`int`, *optional*, defaults to 512): + The width in pixels of the generated image. + num_inference_steps (`int`, *optional*, defaults to 50): + The number of denoising steps. More denoising steps usually lead to a higher quality image at the + expense of slower inference. + guidance_scale (`float`, *optional*, defaults to 7.5): + Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). + `guidance_scale` is defined as `w` of equation 2. of [Imagen + Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > + 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, + usually at the expense of lower image quality. + strength (`float`, *optional*, defaults to 0.8): + Conceptually, indicates how much to transform the reference `image`. Must be between 0 and 1. + `image` will be used as a starting point, adding more noise to it the larger the `strength`. The + number of denoising steps depends on the amount of noise initially added. When `strength` is 1, added + noise will be maximum and the denoising process will run for the full number of iterations specified in + `num_inference_steps`. A value of 1, therefore, essentially ignores `image`. + num_images_per_prompt (`int`, *optional*, defaults to 1): + The number of images to generate per prompt. + eta (`float`, *optional*, defaults to 0.0): + Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to + [`schedulers.DDIMScheduler`], will be ignored for others. + generator (`torch.Generator`, *optional*): + A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation + deterministic. + latents (`torch.FloatTensor`, *optional*): + Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image + generation. Can be used to tweak the same generation with different prompts. If not provided, a latents + tensor will ge generated by sampling using the supplied random `generator`. + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + output_type (`str`, *optional*, defaults to `"pil"`): + The output format of the generate image. Choose between + [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a + plain tuple. + controlnet (`diffusers.ControlNetModel`, *optional*): + A controlnet model to be used for the inference. If not provided, controlnet will be disabled. + controlnet_image (`torch.FloatTensor` or `PIL.Image.Image`, *optional*): + `Image`, or tensor representing an image batch, to be used as the starting point for the controlnet + inference. + callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. The function will be + called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. + is_cancelled_callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. If the function returns + `True`, the inference will be cancelled. + callback_steps (`int`, *optional*, defaults to 1): + The frequency at which the `callback` function will be called. If not specified, the callback will be + called at every step. + + Returns: + `None` if cancelled by `is_cancelled_callback`, + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple. + When returning a tuple, the first element is a list with the generated images, and the second element is a + list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work" + (nsfw) content, according to the `safety_checker`. + """ + if controlnet is not None and controlnet_image is None: + raise ValueError("controlnet_image must be provided if controlnet is not None.") + + # 0. Default height and width to unet + height = height or self.unet.config.sample_size * self.vae_scale_factor + width = width or self.unet.config.sample_size * self.vae_scale_factor + + # 1. Check inputs. Raise error if not correct + self.check_inputs(prompt, height, width, strength, callback_steps) + + # 2. Define call parameters + batch_size = 1 if isinstance(prompt, str) else len(prompt) + device = self._execution_device + # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) + # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` + # corresponds to doing no classifier free guidance. + do_classifier_free_guidance = guidance_scale > 1.0 + + # 3. Encode input prompt + # 実装を簡単にするためにtokenzer/text encoderを切り替えて二回呼び出す + # To simplify the implementation, switch the tokenzer/text encoder and call it twice + text_embeddings_list = [] + text_pools = [] + for i in range(len(self.tokenizers)): + self.tokenizer = self.tokenizers[i] + self.text_encoder = self.text_encoders[i] + + text_embeddings, text_pool = self._encode_prompt( + prompt, + device, + num_images_per_prompt, + do_classifier_free_guidance, + negative_prompt, + max_embeddings_multiples, + is_sdxl_text_encoder2=i == 1, + ) + text_embeddings_list.append(text_embeddings) + text_pools.append(text_pool) + + dtype = text_embeddings_list[0].dtype + + # 4. Preprocess image and mask + if isinstance(image, PIL.Image.Image): + image = preprocess_image(image) + if image is not None: + image = image.to(device=self.device, dtype=dtype) + if isinstance(mask_image, PIL.Image.Image): + mask_image = preprocess_mask(mask_image, self.vae_scale_factor) + if mask_image is not None: + mask = mask_image.to(device=self.device, dtype=dtype) + mask = torch.cat([mask] * batch_size * num_images_per_prompt) + else: + mask = None + + # ControlNet is not working yet in SDXL, but keep the code here for future use + if controlnet_image is not None: + controlnet_image = prepare_controlnet_image( + controlnet_image, width, height, batch_size, 1, self.device, controlnet.dtype, do_classifier_free_guidance, False + ) + + # 5. set timesteps + self.scheduler.set_timesteps(num_inference_steps, device=device) + timesteps, num_inference_steps = self.get_timesteps(num_inference_steps, strength, device, image is None) + latent_timestep = timesteps[:1].repeat(batch_size * num_images_per_prompt) + + # 6. Prepare latent variables + latents, init_latents_orig, noise = self.prepare_latents( + image, + latent_timestep, + batch_size * num_images_per_prompt, + height, + width, + dtype, + device, + generator, + latents, + ) + + # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline + extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta) + + # create size embs and concat embeddings for SDXL + orig_size = torch.tensor([height, width]).repeat(batch_size * num_images_per_prompt, 1).to(dtype) + crop_size = torch.zeros_like(orig_size) + target_size = orig_size + embs = sdxl_train_util.get_size_embeddings(orig_size, crop_size, target_size, device).to(dtype) + if do_classifier_free_guidance: + embs = torch.cat([embs] * 2) + + vector_embedding = torch.cat([text_pools[1], embs], dim=1).to(dtype) + text_embedding = torch.cat(text_embeddings_list, dim=2).to(dtype) + + # 8. Denoising loop + for i, t in enumerate(self.progress_bar(timesteps)): + # expand the latents if we are doing classifier free guidance + latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + + unet_additional_args = {} + if controlnet is not None: + down_block_res_samples, mid_block_res_sample = controlnet( + latent_model_input, + t, + encoder_hidden_states=text_embeddings, + controlnet_cond=controlnet_image, + conditioning_scale=1.0, + guess_mode=False, + return_dict=False, + ) + unet_additional_args["down_block_additional_residuals"] = down_block_res_samples + unet_additional_args["mid_block_additional_residual"] = mid_block_res_sample + + # predict the noise residual + noise_pred = self.unet(latent_model_input, t, text_embedding, vector_embedding) + + # perform guidance + if do_classifier_free_guidance: + noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) + noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) + + # compute the previous noisy sample x_t -> x_t-1 + latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample + + if mask is not None: + # masking + init_latents_proper = self.scheduler.add_noise(init_latents_orig, noise, torch.tensor([t])) + latents = (init_latents_proper * mask) + (latents * (1 - mask)) + + # call the callback, if provided + if i % callback_steps == 0: + if callback is not None: + callback(i, t, latents) + if is_cancelled_callback is not None and is_cancelled_callback(): + return None + + # 9. Post-processing + image = self.decode_latents(latents.to(torch.float32)) + + # 10. Run safety checker + image, has_nsfw_concept = image, None # self.run_safety_checker(image, device, text_embeddings.dtype) + + # 11. Convert to PIL + if output_type == "pil": + image = self.numpy_to_pil(image) + + if not return_dict: + return image, has_nsfw_concept + + return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept) + + # copy from pil_utils.py + def numpy_to_pil(self, images: np.ndarray) -> Image.Image: + """ + Convert a numpy image or a batch of images to a PIL image. + """ + if images.ndim == 3: + images = images[None, ...] + images = (images * 255).round().astype("uint8") + if images.shape[-1] == 1: + # special case for grayscale (single channel) images + pil_images = [Image.fromarray(image.squeeze(), mode="L") for image in images] + else: + pil_images = [Image.fromarray(image) for image in images] + + return pil_images + + def text2img( + self, + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + height: int = 512, + width: int = 512, + num_inference_steps: int = 50, + guidance_scale: float = 7.5, + num_images_per_prompt: Optional[int] = 1, + eta: float = 0.0, + generator: Optional[torch.Generator] = None, + latents: Optional[torch.FloatTensor] = None, + max_embeddings_multiples: Optional[int] = 3, + output_type: Optional[str] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + r""" + Function for text-to-image generation. + Args: + prompt (`str` or `List[str]`): + The prompt or prompts to guide the image generation. + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored + if `guidance_scale` is less than `1`). + height (`int`, *optional*, defaults to 512): + The height in pixels of the generated image. + width (`int`, *optional*, defaults to 512): + The width in pixels of the generated image. + num_inference_steps (`int`, *optional*, defaults to 50): + The number of denoising steps. More denoising steps usually lead to a higher quality image at the + expense of slower inference. + guidance_scale (`float`, *optional*, defaults to 7.5): + Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). + `guidance_scale` is defined as `w` of equation 2. of [Imagen + Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > + 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, + usually at the expense of lower image quality. + num_images_per_prompt (`int`, *optional*, defaults to 1): + The number of images to generate per prompt. + eta (`float`, *optional*, defaults to 0.0): + Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to + [`schedulers.DDIMScheduler`], will be ignored for others. + generator (`torch.Generator`, *optional*): + A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation + deterministic. + latents (`torch.FloatTensor`, *optional*): + Pre-generated noisy latents, sampled from a Gaussian distribution, to be used as inputs for image + generation. Can be used to tweak the same generation with different prompts. If not provided, a latents + tensor will ge generated by sampling using the supplied random `generator`. + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + output_type (`str`, *optional*, defaults to `"pil"`): + The output format of the generate image. Choose between + [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a + plain tuple. + callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. The function will be + called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. + is_cancelled_callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. If the function returns + `True`, the inference will be cancelled. + callback_steps (`int`, *optional*, defaults to 1): + The frequency at which the `callback` function will be called. If not specified, the callback will be + called at every step. + Returns: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple. + When returning a tuple, the first element is a list with the generated images, and the second element is a + list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work" + (nsfw) content, according to the `safety_checker`. + """ + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + height=height, + width=width, + num_inference_steps=num_inference_steps, + guidance_scale=guidance_scale, + num_images_per_prompt=num_images_per_prompt, + eta=eta, + generator=generator, + latents=latents, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + ) + + def img2img( + self, + image: Union[torch.FloatTensor, PIL.Image.Image], + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + strength: float = 0.8, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 7.5, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, + generator: Optional[torch.Generator] = None, + max_embeddings_multiples: Optional[int] = 3, + output_type: Optional[str] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + r""" + Function for image-to-image generation. + Args: + image (`torch.FloatTensor` or `PIL.Image.Image`): + `Image`, or tensor representing an image batch, that will be used as the starting point for the + process. + prompt (`str` or `List[str]`): + The prompt or prompts to guide the image generation. + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored + if `guidance_scale` is less than `1`). + strength (`float`, *optional*, defaults to 0.8): + Conceptually, indicates how much to transform the reference `image`. Must be between 0 and 1. + `image` will be used as a starting point, adding more noise to it the larger the `strength`. The + number of denoising steps depends on the amount of noise initially added. When `strength` is 1, added + noise will be maximum and the denoising process will run for the full number of iterations specified in + `num_inference_steps`. A value of 1, therefore, essentially ignores `image`. + num_inference_steps (`int`, *optional*, defaults to 50): + The number of denoising steps. More denoising steps usually lead to a higher quality image at the + expense of slower inference. This parameter will be modulated by `strength`. + guidance_scale (`float`, *optional*, defaults to 7.5): + Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). + `guidance_scale` is defined as `w` of equation 2. of [Imagen + Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > + 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, + usually at the expense of lower image quality. + num_images_per_prompt (`int`, *optional*, defaults to 1): + The number of images to generate per prompt. + eta (`float`, *optional*, defaults to 0.0): + Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to + [`schedulers.DDIMScheduler`], will be ignored for others. + generator (`torch.Generator`, *optional*): + A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation + deterministic. + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + output_type (`str`, *optional*, defaults to `"pil"`): + The output format of the generate image. Choose between + [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a + plain tuple. + callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. The function will be + called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. + is_cancelled_callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. If the function returns + `True`, the inference will be cancelled. + callback_steps (`int`, *optional*, defaults to 1): + The frequency at which the `callback` function will be called. If not specified, the callback will be + called at every step. + Returns: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple. + When returning a tuple, the first element is a list with the generated images, and the second element is a + list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work" + (nsfw) content, according to the `safety_checker`. + """ + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + image=image, + num_inference_steps=num_inference_steps, + guidance_scale=guidance_scale, + strength=strength, + num_images_per_prompt=num_images_per_prompt, + eta=eta, + generator=generator, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + ) + + def inpaint( + self, + image: Union[torch.FloatTensor, PIL.Image.Image], + mask_image: Union[torch.FloatTensor, PIL.Image.Image], + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + strength: float = 0.8, + num_inference_steps: Optional[int] = 50, + guidance_scale: Optional[float] = 7.5, + num_images_per_prompt: Optional[int] = 1, + eta: Optional[float] = 0.0, + generator: Optional[torch.Generator] = None, + max_embeddings_multiples: Optional[int] = 3, + output_type: Optional[str] = "pil", + return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: int = 1, + ): + r""" + Function for inpaint. + Args: + image (`torch.FloatTensor` or `PIL.Image.Image`): + `Image`, or tensor representing an image batch, that will be used as the starting point for the + process. This is the image whose masked region will be inpainted. + mask_image (`torch.FloatTensor` or `PIL.Image.Image`): + `Image`, or tensor representing an image batch, to mask `image`. White pixels in the mask will be + replaced by noise and therefore repainted, while black pixels will be preserved. If `mask_image` is a + PIL image, it will be converted to a single channel (luminance) before use. If it's a tensor, it should + contain one color channel (L) instead of 3, so the expected shape would be `(B, H, W, 1)`. + prompt (`str` or `List[str]`): + The prompt or prompts to guide the image generation. + negative_prompt (`str` or `List[str]`, *optional*): + The prompt or prompts not to guide the image generation. Ignored when not using guidance (i.e., ignored + if `guidance_scale` is less than `1`). + strength (`float`, *optional*, defaults to 0.8): + Conceptually, indicates how much to inpaint the masked area. Must be between 0 and 1. When `strength` + is 1, the denoising process will be run on the masked area for the full number of iterations specified + in `num_inference_steps`. `image` will be used as a reference for the masked area, adding more + noise to that region the larger the `strength`. If `strength` is 0, no inpainting will occur. + num_inference_steps (`int`, *optional*, defaults to 50): + The reference number of denoising steps. More denoising steps usually lead to a higher quality image at + the expense of slower inference. This parameter will be modulated by `strength`, as explained above. + guidance_scale (`float`, *optional*, defaults to 7.5): + Guidance scale as defined in [Classifier-Free Diffusion Guidance](https://arxiv.org/abs/2207.12598). + `guidance_scale` is defined as `w` of equation 2. of [Imagen + Paper](https://arxiv.org/pdf/2205.11487.pdf). Guidance scale is enabled by setting `guidance_scale > + 1`. Higher guidance scale encourages to generate images that are closely linked to the text `prompt`, + usually at the expense of lower image quality. + num_images_per_prompt (`int`, *optional*, defaults to 1): + The number of images to generate per prompt. + eta (`float`, *optional*, defaults to 0.0): + Corresponds to parameter eta (η) in the DDIM paper: https://arxiv.org/abs/2010.02502. Only applies to + [`schedulers.DDIMScheduler`], will be ignored for others. + generator (`torch.Generator`, *optional*): + A [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make generation + deterministic. + max_embeddings_multiples (`int`, *optional*, defaults to `3`): + The max multiple length of prompt embeddings compared to the max output length of text encoder. + output_type (`str`, *optional*, defaults to `"pil"`): + The output format of the generate image. Choose between + [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` or `np.array`. + return_dict (`bool`, *optional*, defaults to `True`): + Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a + plain tuple. + callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. The function will be + called with the following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`. + is_cancelled_callback (`Callable`, *optional*): + A function that will be called every `callback_steps` steps during inference. If the function returns + `True`, the inference will be cancelled. + callback_steps (`int`, *optional*, defaults to 1): + The frequency at which the `callback` function will be called. If not specified, the callback will be + called at every step. + Returns: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`: + [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] if `return_dict` is True, otherwise a `tuple. + When returning a tuple, the first element is a list with the generated images, and the second element is a + list of `bool`s denoting whether the corresponding generated image likely represents "not-safe-for-work" + (nsfw) content, according to the `safety_checker`. + """ + return self.__call__( + prompt=prompt, + negative_prompt=negative_prompt, + image=image, + mask_image=mask_image, + num_inference_steps=num_inference_steps, + guidance_scale=guidance_scale, + strength=strength, + num_images_per_prompt=num_images_per_prompt, + eta=eta, + generator=generator, + max_embeddings_multiples=max_embeddings_multiples, + output_type=output_type, + return_dict=return_dict, + callback=callback, + is_cancelled_callback=is_cancelled_callback, + callback_steps=callback_steps, + ) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index e3b502c26..f4b2c1739 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -9,6 +9,7 @@ from transformers import CLIPTokenizer import open_clip from library import model_util, sdxl_model_util, train_util +from library.sdxl_lpw_stable_diffusion import SdxlStableDiffusionLongPromptWeightingPipeline TOKENIZER_PATH = "openai/clip-vit-large-patch14" @@ -87,14 +88,23 @@ def __init__(self): def __call__(self, *args: Any, **kwds: Any) -> Any: return self.tokenize(*args, **kwds) - def tokenize(self, text, padding, truncation, max_length, return_tensors): - assert padding == "max_length" - assert truncation == True - assert return_tensors == "pt" - input_ids = open_clip.tokenize(text, context_length=max_length) + def tokenize(self, text, padding=False, truncation=None, max_length=None, return_tensors=None): + if padding == "max_length": + # for training + assert max_length is not None + assert truncation == True + assert return_tensors == "pt" + input_ids = open_clip.tokenize(text, context_length=max_length) + return SimpleNamespace(**{"input_ids": input_ids}) + + # for weighted prompt + input_ids = open_clip.tokenize(text, context_length=self.model_max_length) + + # find eos + eos_index = (input_ids == self.eos_token_id).nonzero()[0].max() # max index of each batch + input_ids = input_ids[:, : eos_index + 1] # include eos return SimpleNamespace(**{"input_ids": input_ids}) - def load_tokenizers(args: argparse.Namespace): print("prepare tokenizers") original_path = TOKENIZER_PATH @@ -381,3 +391,7 @@ def verify_sdxl_training_args(args: argparse.Namespace): assert ( not args.weighted_captions ), "weighted_captions cannot be enabled in SDXL training currently / SDXL学習では今のところweighted_captionsを有効にすることはできません" + + +def sample_images(*args, **kwargs): + return train_util.sample_images_common(SdxlStableDiffusionLongPromptWeightingPipeline, *args, **kwargs) diff --git a/library/train_util.py b/library/train_util.py index 43f553533..ebb89da54 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3695,7 +3695,12 @@ def save_sd_model_on_train_end_common( SCHEDLER_SCHEDULE = "scaled_linear" -def sample_images( +def sample_images(*args, **kwargs): + return sample_images_common(StableDiffusionLongPromptWeightingPipeline, *args, **kwargs) + + +def sample_images_common( + pipe_class, accelerator, args: argparse.Namespace, epoch, @@ -3790,7 +3795,7 @@ def sample_images( # print("set clip_sample to True") scheduler.config.clip_sample = True - pipeline = StableDiffusionLongPromptWeightingPipeline( + pipeline = pipe_class( text_encoder=text_encoder, vae=vae, unet=unet, @@ -3801,9 +3806,8 @@ def sample_images( requires_safety_checker=False, clip_skip=args.clip_skip, ) - pipeline.clip_skip = args.clip_skip # Pipelineのコンストラクタにckip_skipを追加できないので後から設定する pipeline.to(device) - + save_dir = args.output_dir + "/sample" os.makedirs(save_dir, exist_ok=True) diff --git a/sdxl_train.py b/sdxl_train.py index 35934c385..e9548ca34 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -290,8 +290,9 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): args, accelerator, (tokenizer1, tokenizer2), (text_encoder1, text_encoder2), train_dataloader, None ) accelerator.wait_for_everyone() - text_encoder1.to("cpu") - text_encoder2.to("cpu") + # Text Encoder doesn't work on CPU with fp16 + text_encoder1.to("cpu", dtype=torch.float32) + text_encoder2.to("cpu", dtype=torch.float32) if torch.cuda.is_available(): torch.cuda.empty_cache() else: @@ -467,19 +468,17 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): progress_bar.update(1) global_step += 1 - # sdxl_train_util.sample_images( - # accelerator, - # args, - # None, - # global_step, - # accelerator.device, - # vae, - # tokenizer1, - # tokenizer2, - # text_encoder1, - # text_encoder2, - # unet, - # ) + sdxl_train_util.sample_images( + accelerator, + args, + None, + global_step, + accelerator.device, + vae, + [tokenizer1, tokenizer2], + [text_encoder1, text_encoder2], + unet, + ) # 指定ステップごとにモデルを保存 if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: @@ -553,7 +552,17 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): ckpt_info, ) - # train_util.sample_images(accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet) + sdxl_train_util.sample_images( + accelerator, + args, + epoch + 1, + global_step, + accelerator.device, + vae, + [tokenizer1, tokenizer2], + [text_encoder1, text_encoder2], + unet, + ) is_main_process = accelerator.is_main_process # if is_main_process: diff --git a/sdxl_train_network.py b/sdxl_train_network.py index 8f52fe5d2..ec15ce4bd 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -8,7 +8,6 @@ class SdxlNetworkTrainer(train_network.NetworkTrainer): def __init__(self): super().__init__() self.vae_scale_factor = sdxl_model_util.VAE_SCALE_FACTOR - self.sampling_warning_showed = False def assert_extra_args(self, args, train_dataset_group): super().assert_extra_args(args, train_dataset_group) @@ -65,8 +64,8 @@ def cache_text_encoder_outputs_if_needed( args, accelerator, tokenizers, text_encoders, data_loader, weight_dtype ) accelerator.wait_for_everyone() - text_encoders[0].to("cpu") - text_encoders[1].to("cpu") + text_encoders[0].to("cpu", dtype=torch.float32) # Text Encoder doesn't work with fp16 on CPU + text_encoders[1].to("cpu", dtype=torch.float32) if torch.cuda.is_available(): torch.cuda.empty_cache() @@ -149,9 +148,7 @@ def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_cond return noise_pred def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet): - if not self.sampling_warning_showed: - print("sample_images is not implemented") - self.sampling_warning_showed = True + sdxl_train_util.sample_images(accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet) def setup_parser() -> argparse.ArgumentParser: From 97611e89cab7137b994defd65a1e2ba29c0567e5 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 2 Jul 2023 16:49:11 +0900 Subject: [PATCH 045/220] remove debug code --- library/sdxl_lpw_stable_diffusion.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index 786b8119a..e806bc61e 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -711,19 +711,6 @@ def decode_latents(self, latents): # self.vae.set_use_memory_efficient_attention_xformers(False) # image = self.vae.decode(latents.to("cpu")).sample - print("default dtype:", torch.get_default_dtype()) - assert latents.dtype == torch.float32 - assert self.vae.post_quant_conv.weight.dtype == torch.float32 - print("device:", latents.device, "latents dtype:", latents.dtype, "weight dtype:", self.vae.post_quant_conv.weight.dtype) - w = torch.randn_like(self.vae.post_quant_conv.weight, dtype=torch.float32, device=latents.device) - x = torch.randn_like(latents, dtype=torch.float32, device=latents.device) - x = torch.nn.functional.conv2d(x, w) - print("result dtype:", x.dtype) # float16 !! - w = torch.randn_like(self.vae.post_quant_conv.weight, dtype=torch.float32, device="cpu") - x = torch.randn_like(latents, dtype=torch.float32, device="cpu") - x = torch.nn.functional.conv2d(x, w) - print("result dtype:", x.dtype) # float32 - image = self.vae.decode(latents).sample image = (image / 2 + 0.5).clamp(0, 1) # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16 From 5863676ccbada0887529a99dcb9d879149b199e5 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 2 Jul 2023 16:49:18 +0900 Subject: [PATCH 046/220] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2812e449..efa4d1ee2 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ Summary of the feature: - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. +- The image generation during training is now available. However, the VAE for SDXL seems to produce NaNs in some cases when using `fp16`. The images will be black. Currently, the NaNs cannot be avoided even with `--no_half_vae` option. It works with `bf16` or without mixed precision. +- `--weighted_captions` option is not supported yet. `requirements.txt` is updated to support SDXL training. From ea182461d38b93acecd81671bcb83e7bf9de43aa Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 3 Jul 2023 20:44:42 +0900 Subject: [PATCH 047/220] add min/max_timestep --- fine_tune.py | 17 +++----------- library/train_util.py | 42 +++++++++++++++++++++++++++++++++- sdxl_train.py | 17 +++----------- train_db.py | 27 ++++++++-------------- train_network.py | 20 ++++------------ train_textual_inversion.py | 31 ++++++++++++------------- train_textual_inversion_XTI.py | 17 +++----------- 7 files changed, 78 insertions(+), 93 deletions(-) diff --git a/fine_tune.py b/fine_tune.py index b739a86a7..58a6cda0e 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -314,20 +314,9 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): args, input_ids, tokenizer, text_encoder, None if not args.full_fp16 else weight_dtype ) - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) # Predict the noise residual with accelerator.autocast(): diff --git a/library/train_util.py b/library/train_util.py index ebb89da54..1d6163765 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -51,6 +51,7 @@ KDPM2DiscreteScheduler, KDPM2AncestralDiscreteScheduler, ) +from library import custom_train_functions from library.original_unet import UNet2DConditionModel from huggingface_hub import hf_hub_download import albumentations as albu @@ -2460,6 +2461,19 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: default=None, help="add `latent mean absolute value * this value` to noise_offset (disabled if None, default) / latentの平均値の絶対値 * この値をnoise_offsetに加算する(Noneの場合は無効、デフォルト)", ) + parser.add_argument( + "--min_timestep", + type=int, + default=None, + help="set minimum time step for U-Net training (0~999, default is 0) / U-Net学習時のtime stepの最小値を設定する(0~999で指定、省略時はデフォルト値(0)) ", + ) + parser.add_argument( + "--max_timestep", + type=int, + default=None, + help="set maximum time step for U-Net training (1~1000, default is 1000) / U-Net学習時のtime stepの最大値を設定する(1~1000で指定、省略時はデフォルト値(1000))", + ) + parser.add_argument( "--lowram", action="store_true", @@ -3688,6 +3702,32 @@ def save_sd_model_on_train_end_common( huggingface_util.upload(args, out_dir, "/" + model_name, force_sync_upload=True) +def get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents): + # Sample noise that we'll add to the latents + noise = torch.randn_like(latents, device=latents.device) + if args.noise_offset: + noise = custom_train_functions.apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) + elif args.multires_noise_iterations: + noise = custom_train_functions.pyramid_noise_like( + noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount + ) + + # Sample a random timestep for each image + b_size = latents.shape[0] + min_timestep = 0 if args.min_timestep is None else args.min_timestep + max_timestep = noise_scheduler.config.num_train_timesteps if args.max_timestep is None else args.max_timestep + print(b_size, min_timestep, max_timestep) + + timesteps = torch.randint(min_timestep, max_timestep, (b_size,), device=latents.device) + timesteps = timesteps.long() + + # Add noise to the latents according to the noise magnitude at each timestep + # (this is the forward diffusion process) + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + + return noise, noisy_latents, timesteps + + # scheduler: SCHEDULER_LINEAR_START = 0.00085 SCHEDULER_LINEAR_END = 0.0120 @@ -3807,7 +3847,7 @@ def sample_images_common( clip_skip=args.clip_skip, ) pipeline.to(device) - + save_dir = args.output_dir + "/sample" os.makedirs(save_dir, exist_ok=True) diff --git a/sdxl_train.py b/sdxl_train.py index e9548ca34..1e8b04fb2 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -417,20 +417,9 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): vector_embedding = torch.cat([pool2, embs], dim=1).to(weight_dtype) text_embedding = torch.cat([encoder_hidden_states1, encoder_hidden_states2], dim=2).to(weight_dtype) - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) noisy_latents = noisy_latents.to(weight_dtype) # TODO check why noisy_latents is not weight_dtype diff --git a/train_db.py b/train_db.py index c8ddab1ee..439f4b9d9 100644 --- a/train_db.py +++ b/train_db.py @@ -233,7 +233,9 @@ def train(args): accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") accelerator.print(f" num epochs / epoch数: {num_train_epochs}") accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print( + f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + ) accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") @@ -279,15 +281,6 @@ def train(args): latents = latents * 0.18215 b_size = latents.shape[0] - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - # elif args.perlin_noise: - # noise = perlin_noise(noise, latents.device, args.perlin_noise) # only shape of noise is used currently - # Get the text embedding for conditioning with torch.set_grad_enabled(global_step < args.stop_text_encoder_training): if args.weighted_captions: @@ -305,13 +298,9 @@ def train(args): args, input_ids, tokenizer, text_encoder, None if not args.full_fp16 else weight_dtype ) - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) # Predict the noise residual with accelerator.autocast(): @@ -381,7 +370,9 @@ def train(args): current_loss = loss.detach().item() if args.logging_dir is not None: logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} - if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower(): # tracking d*lr value + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower() + ): # tracking d*lr value logs["lr/d*lr"] = ( lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] ) diff --git a/train_network.py b/train_network.py index e42225f1a..3c9515b55 100644 --- a/train_network.py +++ b/train_network.py @@ -748,21 +748,11 @@ def remove_model(old_ckpt_name): args, accelerator, batch, tokenizers, text_encoders, weight_dtype ) - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like( - noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount - ) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps( + args, noise_scheduler, latents + ) # Predict the noise residual with accelerator.autocast(): diff --git a/train_textual_inversion.py b/train_textual_inversion.py index bcf0f1964..ecfaeb4fa 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -168,7 +168,11 @@ def train(args): accelerator.print("Use DreamBooth method.") user_config = { "datasets": [ - {"subsets": config_util.generate_dreambooth_subsets_config_by_subdirs(args.train_data_dir, args.reg_data_dir)} + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } ] } else: @@ -334,7 +338,9 @@ def train(args): accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") accelerator.print(f" num epochs / epoch数: {num_train_epochs}") accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - accelerator.print(f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}") + accelerator.print( + f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + ) accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") @@ -391,20 +397,9 @@ def remove_model(old_ckpt_name): # use float instead of fp16/bf16 because text encoder is float encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizer, text_encoder, torch.float) - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) # Predict the noise residual with accelerator.autocast(): @@ -475,7 +470,9 @@ def remove_model(old_ckpt_name): current_loss = loss.detach().item() if args.logging_dir is not None: logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} - if args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower(): # tracking d*lr value + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower() + ): # tracking d*lr value logs["lr/d*lr"] = ( lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] ) diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index 3a87ede9f..a08c3a824 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -435,20 +435,9 @@ def remove_model(old_ckpt_name): ] ) - # Sample noise that we'll add to the latents - noise = torch.randn_like(latents, device=latents.device) - if args.noise_offset: - noise = apply_noise_offset(latents, noise, args.noise_offset, args.adaptive_noise_scale) - elif args.multires_noise_iterations: - noise = pyramid_noise_like(noise, latents.device, args.multires_noise_iterations, args.multires_noise_discount) - - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (b_size,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) # Predict the noise residual with accelerator.autocast(): From 2febbfe4b025ce238471b53a569986a9cfa2469a Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 3 Jul 2023 20:58:35 +0900 Subject: [PATCH 048/220] add error message for old npz --- library/train_util.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/train_util.py b/library/train_util.py index 1d6163765..534771ad5 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -1009,6 +1009,10 @@ def load_latents_from_npz(self, image_info: ImageInfo, flipped): return None, None, None npz = np.load(npz_file) + if "latents" not in npz: + print(f"error: npz is old format. please re-generate {npz_file}") + return None, None, None + latents = npz["latents"] original_size = npz["original_size"].tolist() crop_left_top = npz["crop_left_top"].tolist() From 6aa62b9b667ed06cb7b600f905b2fc64eaaa12e6 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 3 Jul 2023 21:06:58 +0900 Subject: [PATCH 049/220] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index efa4d1ee2..53685c3f2 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ Summary of the feature: - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. - The image generation during training is now available. However, the VAE for SDXL seems to produce NaNs in some cases when using `fp16`. The images will be black. Currently, the NaNs cannot be avoided even with `--no_half_vae` option. It works with `bf16` or without mixed precision. - `--weighted_captions` option is not supported yet. +- `--min_timestep` and `--max_timestep` options are added to each training script. These options can be used to train U-Net with different timesteps. The default values are 0 and 1000. `requirements.txt` is updated to support SDXL training. From 3b35547da0cc258fc41097e8926a8d66cde5fd66 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 4 Jul 2023 21:30:37 +0900 Subject: [PATCH 050/220] fix dtype for vae --- sdxl_minimal_inference.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index 02a4af9c2..25b8e51bf 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -129,11 +129,11 @@ def get_timestep_embedding(x, outdim): unet.to(DEVICE, dtype=DTYPE) unet.eval() + vae_dtype = DTYPE if DTYPE == torch.float16: print("use float32 for vae") - vae.to(DEVICE, torch.float32) # avoid black image, same as no-half-vae - else: - vae.to(DEVICE, DTYPE) + vae_dtype = torch.float32 + vae.to(DEVICE, dtype=vae_dtype) vae.eval() text_model1.to(DEVICE, dtype=DTYPE) @@ -278,7 +278,7 @@ def call_text_encoder(text): # latents = 1 / 0.18215 * latents latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents - latents = latents.to(torch.float32) + latents = latents.to(vae_dtype) image = vae.decode(latents).sample image = (image / 2 + 0.5).clamp(0, 1) From ce46aa0c3b2aa551ad6d9bbd40db378e32778784 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 4 Jul 2023 21:34:18 +0900 Subject: [PATCH 051/220] remove debug print --- library/config_util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/library/config_util.py b/library/config_util.py index c357c70ea..3604ea576 100644 --- a/library/config_util.py +++ b/library/config_util.py @@ -347,7 +347,6 @@ def __init__(self, sanitizer: ConfigSanitizer): # runtime_params is for parameters which is only configurable on runtime, such as tokenizer def generate(self, user_config: dict, argparse_namespace: argparse.Namespace, **runtime_params) -> Blueprint: - print(user_config) sanitized_user_config = self.sanitizer.sanitize_user_config(user_config) sanitized_argparse_namespace = self.sanitizer.sanitize_argparse_namespace(argparse_namespace) From 3060eb5bafbb4c9c1092fb55d0b7c044b46c045b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 5 Jul 2023 21:44:46 +0900 Subject: [PATCH 052/220] remove debug print --- library/train_util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/library/train_util.py b/library/train_util.py index 534771ad5..9ab1f538d 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3720,7 +3720,6 @@ def get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents): b_size = latents.shape[0] min_timestep = 0 if args.min_timestep is None else args.min_timestep max_timestep = noise_scheduler.config.num_train_timesteps if args.max_timestep is None else args.max_timestep - print(b_size, min_timestep, max_timestep) timesteps = torch.randint(min_timestep, max_timestep, (b_size,), device=latents.device) timesteps = timesteps.long() From 3d0375daa61e10ab9b42c0b04ca86c109d0b2fa7 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 5 Jul 2023 21:45:30 +0900 Subject: [PATCH 053/220] fix to work sdxl state dict without logit_scale --- library/sdxl_model_util.py | 7 ++++--- sdxl_train.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 681c9b218..c7b9f9667 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -74,7 +74,7 @@ def convert_key(key): new_sd["text_model.embeddings.position_ids"] = position_ids # logit_scale はDiffusersには含まれないが、保存時に戻したいので別途返す - logit_scale = checkpoint[SDXL_KEY_PREFIX + "logit_scale"] + logit_scale = checkpoint.get(SDXL_KEY_PREFIX + "logit_scale", None) return new_sd, logit_scale @@ -222,7 +222,7 @@ def convert_key(key): key = key.replace("embeddings.position_embedding.weight", "positional_embedding") elif ".token_embedding" in key: key = key.replace("embeddings.token_embedding.weight", "token_embedding.weight") - elif "text_projection" in key: # no dot in key + elif "text_projection" in key: # no dot in key key = key.replace("text_projection.weight", "text_projection") elif "final_layer_norm" in key: key = key.replace("final_layer_norm", "ln_final") @@ -253,7 +253,8 @@ def convert_key(key): new_key = new_key.replace(".self_attn.q_proj.", ".attn.in_proj_") new_sd[new_key] = value - new_sd["logit_scale"] = logit_scale + if logit_scale is not None: + new_sd["logit_scale"] = logit_scale return new_sd diff --git a/sdxl_train.py b/sdxl_train.py index 1e8b04fb2..9cf20252d 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -135,7 +135,7 @@ def train(args): logit_scale, ckpt_info, ) = sdxl_train_util.load_target_model(args, accelerator, "sdxl", weight_dtype) - logit_scale = logit_scale.to(accelerator.device, dtype=weight_dtype) + # logit_scale = logit_scale.to(accelerator.device, dtype=weight_dtype) # verify load/save model formats if load_stable_diffusion_format: From 4a34e5804e13936ee07a14cf9ebf47b2d4e0a7bb Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 5 Jul 2023 21:55:43 +0900 Subject: [PATCH 054/220] fix to work with .ckpt from comfyui --- library/sdxl_model_util.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index c7b9f9667..b9533af10 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -44,6 +44,9 @@ def convert_key(key): key = key.replace(".token_embedding.weight", ".embeddings.token_embedding.weight") elif ".ln_final" in key: key = key.replace(".ln_final", ".final_layer_norm") + # ckpt from comfy has this key: text_model.encoder.text_model.embeddings.position_ids + elif ".embeddings.position_ids" in key: + key = None # remove this key: make position_ids by ourselves return key keys = list(checkpoint.keys()) From 288efddf2f6b8392dd74a0494b631c4d3b28304a Mon Sep 17 00:00:00 2001 From: Kohya S <52813779+kohya-ss@users.noreply.github.com> Date: Thu, 6 Jul 2023 07:43:30 +0900 Subject: [PATCH 055/220] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53685c3f2..7df0ec53c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Summary of the feature: - Use `--cache_text_encoder_outputs` option and caching latents. - Use Adafactor optimizer. RMSprop 8bit or Adagrad 8bit may work. AdamW 8bit doesn't seem to work. - The LoRA training can be done with 12GB GPU memory. -- `--train_unet_only` option is highly recommended for SDXL LoRA. Because SDXL has two text encoders, the result of the training will be unexpected. +- `--network_train_unet_only` option is highly recommended for SDXL LoRA. Because SDXL has two text encoders, the result of the training will be unexpected. - PyTorch 2 seems to use slightly less GPU memory than PyTorch 1. Example of the optimizer settings for Adafactor with the fixed learning rate: From cc3d40ca44a78aa99493581ad4681493f2775e7b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Fri, 7 Jul 2023 21:16:41 +0900 Subject: [PATCH 056/220] support sdxl in prepare scipt --- finetune/prepare_buckets_latents.py | 46 +++++++++++++----- library/train_util.py | 75 +++++++++++++++++------------ 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/finetune/prepare_buckets_latents.py b/finetune/prepare_buckets_latents.py index fd289d1d3..6bb1c32fe 100644 --- a/finetune/prepare_buckets_latents.py +++ b/finetune/prepare_buckets_latents.py @@ -34,12 +34,18 @@ def collate_fn_remove_corrupted(batch): return batch -def get_latents(vae, images, weight_dtype): - img_tensors = [IMAGE_TRANSFORMS(image) for image in images] +def get_latents(vae, key_and_images, weight_dtype): + img_tensors = [IMAGE_TRANSFORMS(image) for _, image in key_and_images] img_tensors = torch.stack(img_tensors) img_tensors = img_tensors.to(DEVICE, weight_dtype) with torch.no_grad(): - latents = vae.encode(img_tensors).latent_dist.sample().float().to("cpu").numpy() + latents = vae.encode(img_tensors).latent_dist.sample() + + # check NaN + for (key, _), latents1 in zip(key_and_images, latents): + if torch.isnan(latents1).any(): + raise ValueError(f"NaN detected in latents of {key}") + return latents @@ -107,24 +113,26 @@ def main(args): def process_batch(is_last): for bucket in bucket_manager.buckets: if (is_last and len(bucket) > 0) or len(bucket) >= args.batch_size: - latents = get_latents(vae, [img for _, img in bucket], weight_dtype) + latents = get_latents(vae, [(key, img) for key, img, _, _ in bucket], weight_dtype) assert ( latents.shape[2] == bucket[0][1].shape[0] // 8 and latents.shape[3] == bucket[0][1].shape[1] // 8 ), f"latent shape {latents.shape}, {bucket[0][1].shape}" - for (image_key, _), latent in zip(bucket, latents): + for (image_key, _, original_size, crop_left_top), latent in zip(bucket, latents): npz_file_name = get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, False, args.recursive) - np.savez(npz_file_name, latent) + train_util.save_latents_to_disk(npz_file_name, latent, original_size, crop_left_top) # flip if args.flip_aug: - latents = get_latents(vae, [img[:, ::-1].copy() for _, img in bucket], weight_dtype) # copyがないとTensor変換できない + latents = get_latents( + vae, [(key, img[:, ::-1].copy()) for key, img, _, _ in bucket], weight_dtype + ) # copyがないとTensor変換できない - for (image_key, _), latent in zip(bucket, latents): + for (image_key, _, original_size, crop_left_top), latent in zip(bucket, latents): npz_file_name = get_npz_filename_wo_ext( args.train_data_dir, image_key, args.full_path, True, args.recursive ) - np.savez(npz_file_name, latent) + train_util.save_latents_to_disk(npz_file_name, latent, original_size, crop_left_top) else: # remove existing flipped npz for image_key, _ in bucket: @@ -194,7 +202,7 @@ def process_batch(is_last): resized_size[0] >= reso[0] and resized_size[1] >= reso[1] ), f"internal error resized size is small: {resized_size}, {reso}" - # 既に存在するファイルがあればshapeを確認して同じならskipする + # 既に存在するファイルがあればshape等を確認して同じならskipする if args.skip_existing: npz_files = [get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, False, args.recursive) + ".npz"] if args.flip_aug: @@ -208,8 +216,12 @@ def process_batch(is_last): found = False break - dat = np.load(npz_file)["arr_0"] - if dat.shape[1] != reso[1] // 8 or dat.shape[2] != reso[0] // 8: # latentsのshapeを確認 + latents, _, _ = train_util.load_latents_from_disk(npz_file) + if latents is None: # old version + found = False + break + + if latents.shape[1] != reso[1] // 8 or latents.shape[2] != reso[0] // 8: # latentsのshapeを確認 found = False break if found: @@ -221,13 +233,21 @@ def process_batch(is_last): if resized_size[0] != image.shape[1] or resized_size[1] != image.shape[0]: # リサイズ処理が必要? image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) + trim_left = 0 if resized_size[0] > reso[0]: trim_size = resized_size[0] - reso[0] image = image[:, trim_size // 2 : trim_size // 2 + reso[0]] + trim_left = trim_size // 2 + trim_top = 0 if resized_size[1] > reso[1]: trim_size = resized_size[1] - reso[1] image = image[trim_size // 2 : trim_size // 2 + reso[1]] + trim_top = trim_size // 2 + + original_size_wh = (resized_size[0], resized_size[1]) + # target_size_wh = (reso[0], reso[1]) + crop_left_top = (trim_left, trim_top) assert ( image.shape[0] == reso[1] and image.shape[1] == reso[0] @@ -237,7 +257,7 @@ def process_batch(is_last): # cv2.imwrite(f"r:\\test\\img_{len(img_ar_errors)}.jpg", image[:, :, ::-1]) # バッチへ追加 - bucket_manager.add_image(reso, (image_key, image)) + bucket_manager.add_image(reso, (image_key, image, original_size_wh, crop_left_top)) # バッチを推論するか判定して推論する process_batch(False) diff --git a/library/train_util.py b/library/train_util.py index 9ab1f538d..62cd145e1 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -124,11 +124,11 @@ def __init__(self, no_upscale, max_reso, min_size, max_size, reso_steps) -> None self.resos = [] self.reso_to_id = {} - self.buckets = [] # 前処理時は (image_key, image)、学習時は image_key + self.buckets = [] # 前処理時は (image_key, image, original size, crop left/top)、学習時は image_key - def add_image(self, reso, image): + def add_image(self, reso, image_or_info): bucket_id = self.reso_to_id[reso] - self.buckets[bucket_id].append(image) + self.buckets[bucket_id].append(image_or_info) def shuffle(self): for bucket in self.buckets: @@ -767,7 +767,10 @@ def load_image(self, image_path): img = np.array(image, np.uint8) return img - def trim_and_resize_if_required(self, subset: BaseSubset, image, reso, resized_size): + # 画像を読み込む。戻り値はnumpy.ndarray,(original width, original height),(crop left, crop top) + def trim_and_resize_if_required( + self, subset: BaseSubset, image, reso, resized_size + ) -> Tuple[np.ndarray, Tuple[int, int], Tuple[int, int]]: image_height, image_width = image.shape[0:2] if image_width != resized_size[0] or image_height != resized_size[1]: @@ -907,19 +910,13 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") - # check NaN - for info, latents1 in zip(batch, latents): - if torch.isnan(latents1).any(): + for info, latent in zip(batch, latents): + # check NaN + if torch.isnan(latents).any(): raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") - for info, latent in zip(batch, latents): if cache_to_disk: - np.savez( - info.latents_npz, - latents=latent.float().numpy(), - original_size=np.array(info.latents_original_size), - crop_left_top=np.array(info.latents_crop_left_top), - ) + save_latents_to_disk(info.latents_npz, latent, info.latents_original_size, info.latents_crop_left_top) else: info.latents = latent @@ -927,12 +924,14 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc img_tensors = torch.flip(img_tensors, dims=[3]) latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") for info, latent in zip(batch, latents): + # check NaN + if torch.isnan(latents).any(): + raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") + if cache_to_disk: - np.savez( - info.latents_npz_flipped, - latents=latent.float().numpy(), - original_size=np.array(info.latents_original_size), - crop_left_top=np.array(info.latents_crop_left_top), # reverse horizontally when use flipped latents + # crop_left_top is reversed when making batch + save_latents_to_disk( + info.latents_npz_flipped, latent, info.latents_original_size, info.latents_crop_left_top ) else: info.latents_flipped = latent @@ -1005,18 +1004,7 @@ def crop_target(self, subset: BaseSubset, image, face_cx, face_cy, face_w, face_ def load_latents_from_npz(self, image_info: ImageInfo, flipped): npz_file = image_info.latents_npz_flipped if flipped else image_info.latents_npz - if npz_file is None: - return None, None, None - - npz = np.load(npz_file) - if "latents" not in npz: - print(f"error: npz is old format. please re-generate {npz_file}") - return None, None, None - - latents = npz["latents"] - original_size = npz["original_size"].tolist() - crop_left_top = npz["crop_left_top"].tolist() - return latents, original_size, crop_left_top + return load_latents_from_disk(npz_file) def __len__(self): return self._length @@ -1762,6 +1750,31 @@ def disable_token_padding(self): dataset.disable_token_padding() +# 戻り値は、latents_tensor, (original_size width, original_size height), (crop left, crop top) +def load_latents_from_disk(npz_path) -> Tuple[Optional[torch.Tensor], Optional[List[int]], Optional[List[int]]]: + if npz_path is None: # flipped doesn't exist + return None, None, None + + npz = np.load(npz_path) + if "latents" not in npz: + print(f"error: npz is old format. please re-generate {npz_path}") + return None, None, None + + latents = npz["latents"] + original_size = npz["original_size"].tolist() + crop_left_top = npz["crop_left_top"].tolist() + return latents, original_size, crop_left_top + + +def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_left_top): + np.savez( + npz_path, + latents=latents_tensor.float().cpu().numpy(), + original_size=np.array(original_size), + crop_left_top=np.array(crop_left_top), + ) + + def debug_dataset(train_dataset, show_input_ids=False): print(f"Total dataset length (steps) / データセットの長さ(ステップ数): {len(train_dataset)}") print("`S` for next step, `E` for next epoch no. , Escape for exit. / Sキーで次のステップ、Eキーで次のエポック、Escキーで中断、終了します") From c1d62383c6316a0c0efa92928384eb0873dfa3c1 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Fri, 7 Jul 2023 21:17:56 +0900 Subject: [PATCH 057/220] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7df0ec53c..234301705 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - - __`prepare_buckets_latents.py` does not support SDXL fine-tuning. Please use DreamBooth dataset, or the metadata without bucketing.__ + - `prepare_buckets_latents.py` now supports SDXL fine-tuning. - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. @@ -39,7 +39,7 @@ Summary of the feature: ### Tips for SDXL training - The default resolution of SDXL is 1024x1024. -- The fine-tuning can be done with 24GB GPU memory with the batch size of 1. +- The fine-tuning can be done with 24GB GPU memory with the batch size of 1. For 24GB GPU, the following options are recommended: - Train U-Net only. - Use gradient checkpointing. - Use `--cache_text_encoder_outputs` option and caching latents. From 66c03be45f30441cc01aaf7496c1339007de4cf1 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 8 Jul 2023 09:56:38 +0900 Subject: [PATCH 058/220] Fix TE key names for SD1/2 LoRA are invalid --- networks/lora.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/networks/lora.py b/networks/lora.py index b6788b995..cd73cbe7c 100644 --- a/networks/lora.py +++ b/networks/lora.py @@ -735,7 +735,7 @@ class LoRANetwork(torch.nn.Module): TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"] LORA_PREFIX_UNET = "lora_unet" LORA_PREFIX_TEXT_ENCODER = "lora_te" - + # SDXL: must starts with LORA_PREFIX_TEXT_ENCODER LORA_PREFIX_TEXT_ENCODER1 = "lora_te1" LORA_PREFIX_TEXT_ENCODER2 = "lora_te2" @@ -877,7 +877,14 @@ def create_modules( self.text_encoder_loras = [] skipped_te = [] for i, text_encoder in enumerate(text_encoders): - text_encoder_loras, skipped = create_modules(False, i + 1, text_encoder, LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE) + if len(text_encoders) > 1: + index = i + 1 + print(f"create LoRA for Text Encoder {index}:") + else: + index = None + print(f"create LoRA for Text Encoder:") + + text_encoder_loras, skipped = create_modules(False, index, text_encoder, LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE) self.text_encoder_loras.extend(text_encoder_loras) skipped_te += skipped print(f"create LoRA for Text Encoder: {len(self.text_encoder_loras)} modules.") From d599394f6086b7291535e510e67b30c18fef4c07 Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Sat, 8 Jul 2023 15:47:56 +0900 Subject: [PATCH 059/220] support avif --- library/train_util.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/train_util.py b/library/train_util.py index 62cd145e1..a3017694c 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -89,6 +89,12 @@ IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp", ".bmp", ".PNG", ".JPG", ".JPEG", ".WEBP", ".BMP"] +try: + import pillow_avif + IMAGE_EXTENSIONS.extend([".avif", ".AVIF"]) +except: + pass + class ImageInfo: def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, absolute_path: str) -> None: From fe7ede5af33e9d4fecc22ee454f06e28c4bcff74 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 9 Jul 2023 13:33:16 +0900 Subject: [PATCH 060/220] fix wrapper tokenizer not work for weighted prompt --- library/sdxl_train_util.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index f4b2c1739..c67a70431 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -98,13 +98,16 @@ def tokenize(self, text, padding=False, truncation=None, max_length=None, return return SimpleNamespace(**{"input_ids": input_ids}) # for weighted prompt - input_ids = open_clip.tokenize(text, context_length=self.model_max_length) + assert isinstance(text, str), f"input must be str: {text}" + + input_ids = open_clip.tokenize(text, context_length=self.model_max_length)[0] # tokenizer returns list # find eos - eos_index = (input_ids == self.eos_token_id).nonzero()[0].max() # max index of each batch - input_ids = input_ids[:, : eos_index + 1] # include eos + eos_index = (input_ids == self.eos_token_id).nonzero().max() + input_ids = input_ids[: eos_index + 1] # include eos return SimpleNamespace(**{"input_ids": input_ids}) + def load_tokenizers(args: argparse.Namespace): print("prepare tokenizers") original_path = TOKENIZER_PATH From 1d25703ac32abe8752d12e58e2637883dc6919bb Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 9 Jul 2023 13:33:26 +0900 Subject: [PATCH 061/220] add generation script --- library/sdxl_model_util.py | 2 +- sdxl_gen_img.py | 2547 ++++++++++++++++++++++++++++++++++++ 2 files changed, 2548 insertions(+), 1 deletion(-) create mode 100644 sdxl_gen_img.py diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index b9533af10..ae764b17f 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -182,7 +182,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): converted_sd, logit_scale = convert_sdxl_text_encoder_2_checkpoint(te2_sd, max_length=77) info2 = text_model2.load_state_dict(converted_sd) - print("text encoder2:", info2) + print("text encoder 2:", info2) # prepare vae print("building VAE") diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py new file mode 100644 index 000000000..8f1c17d60 --- /dev/null +++ b/sdxl_gen_img.py @@ -0,0 +1,2547 @@ +import itertools +import json +from typing import Any, List, NamedTuple, Optional, Tuple, Union, Callable +import glob +import importlib +import inspect +import time +import zipfile +from diffusers.utils import deprecate +from diffusers.configuration_utils import FrozenDict +import argparse +import math +import os +import random +import re + +import diffusers +import numpy as np +import torch +import torchvision +from diffusers import ( + AutoencoderKL, + DDPMScheduler, + EulerAncestralDiscreteScheduler, + DPMSolverMultistepScheduler, + DPMSolverSinglestepScheduler, + LMSDiscreteScheduler, + PNDMScheduler, + DDIMScheduler, + EulerDiscreteScheduler, + HeunDiscreteScheduler, + KDPM2DiscreteScheduler, + KDPM2AncestralDiscreteScheduler, + # UNet2DConditionModel, + StableDiffusionPipeline, +) +from einops import rearrange +from tqdm import tqdm +from torchvision import transforms +from transformers import CLIPTextModel, CLIPTokenizer, CLIPModel, CLIPTextConfig +import PIL +from PIL import Image +from PIL.PngImagePlugin import PngInfo + +import library.model_util as model_util +import library.train_util as train_util +import library.sdxl_model_util as sdxl_model_util +import library.sdxl_train_util as sdxl_train_util +from networks.lora import LoRANetwork +import tools.original_control_net as original_control_net +from tools.original_control_net import ControlNetInfo +from library.sdxl_original_unet import SdxlUNet2DConditionModel +from library.original_unet import FlashAttentionFunction + +# scheduler: +SCHEDULER_LINEAR_START = 0.00085 +SCHEDULER_LINEAR_END = 0.0120 +SCHEDULER_TIMESTEPS = 1000 +SCHEDLER_SCHEDULE = "scaled_linear" + +# その他の設定 +LATENT_CHANNELS = 4 +DOWNSAMPLING_FACTOR = 8 + +# region モジュール入れ替え部 +""" +高速化のためのモジュール入れ替え +""" + + +def replace_unet_modules(unet: diffusers.models.unet_2d_condition.UNet2DConditionModel, mem_eff_attn, xformers, sdpa): + if mem_eff_attn: + print("Enable memory efficient attention for U-Net") + + # これはDiffusersのU-Netではなく自前のU-Netなので置き換えなくても良い + unet.set_use_memory_efficient_attention(False, True) + elif xformers: + print("Enable xformers for U-Net") + try: + import xformers.ops + except ImportError: + raise ImportError("No xformers / xformersがインストールされていないようです") + + unet.set_use_memory_efficient_attention(True, False) + elif sdpa: + print("Enable SDPA for U-Net") + unet.set_use_memory_efficient_attention(False, False) + unet.set_use_sdpa(True) + + +# TODO common train_util.py +def replace_vae_modules(vae: diffusers.models.AutoencoderKL, mem_eff_attn, xformers, sdpa): + if mem_eff_attn: + replace_vae_attn_to_memory_efficient() + elif xformers: + replace_vae_attn_to_xformers() + elif sdpa: + replace_vae_attn_to_sdpa() + + +def replace_vae_attn_to_memory_efficient(): + print("VAE Attention.forward has been replaced to FlashAttention (not xformers)") + flash_func = FlashAttentionFunction + + def forward_flash_attn(self, hidden_states, **kwargs): + q_bucket_size = 512 + k_bucket_size = 1024 + + residual = hidden_states + batch, channel, height, width = hidden_states.shape + + # norm + hidden_states = self.group_norm(hidden_states) + + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) + + # proj to q, k, v + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) + + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) + ) + + out = flash_func.apply(query_proj, key_proj, value_proj, None, False, q_bucket_size, k_bucket_size) + + out = rearrange(out, "b h n d -> b n (h d)") + + # compute next hidden_states + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) + + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) + + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor + return hidden_states + + def forward_flash_attn_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_flash_attn(self, hidden_states, **kwargs) + + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_flash_attn_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_flash_attn + + +def replace_vae_attn_to_xformers(): + print("VAE: Attention.forward has been replaced to xformers") + import xformers.ops + + def forward_xformers(self, hidden_states, **kwargs): + residual = hidden_states + batch, channel, height, width = hidden_states.shape + + # norm + hidden_states = self.group_norm(hidden_states) + + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) + + # proj to q, k, v + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) + + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b h n d", h=self.heads), (query_proj, key_proj, value_proj) + ) + + query_proj = query_proj.contiguous() + key_proj = key_proj.contiguous() + value_proj = value_proj.contiguous() + out = xformers.ops.memory_efficient_attention(query_proj, key_proj, value_proj, attn_bias=None) + + out = rearrange(out, "b h n d -> b n (h d)") + + # compute next hidden_states + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) + + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) + + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor + return hidden_states + + def forward_xformers_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_xformers(self, hidden_states, **kwargs) + + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_xformers_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_xformers + + +def replace_vae_attn_to_sdpa(): + print("VAE: Attention.forward has been replaced to sdpa") + + def forward_sdpa(self, hidden_states, **kwargs): + residual = hidden_states + batch, channel, height, width = hidden_states.shape + + # norm + hidden_states = self.group_norm(hidden_states) + + hidden_states = hidden_states.view(batch, channel, height * width).transpose(1, 2) + + # proj to q, k, v + query_proj = self.to_q(hidden_states) + key_proj = self.to_k(hidden_states) + value_proj = self.to_v(hidden_states) + + query_proj, key_proj, value_proj = map( + lambda t: rearrange(t, "b n (h d) -> b n h d", h=self.heads), (query_proj, key_proj, value_proj) + ) + + out = torch.nn.functional.scaled_dot_product_attention( + query_proj, key_proj, value_proj, attn_mask=None, dropout_p=0.0, is_causal=False + ) + + out = rearrange(out, "b n h d -> b n (h d)") + + # compute next hidden_states + # linear proj + hidden_states = self.to_out[0](hidden_states) + # dropout + hidden_states = self.to_out[1](hidden_states) + + hidden_states = hidden_states.transpose(-1, -2).reshape(batch, channel, height, width) + + # res connect and rescale + hidden_states = (hidden_states + residual) / self.rescale_output_factor + return hidden_states + + def forward_sdpa_0_14(self, hidden_states, **kwargs): + if not hasattr(self, "to_q"): + self.to_q = self.query + self.to_k = self.key + self.to_v = self.value + self.to_out = [self.proj_attn, torch.nn.Identity()] + self.heads = self.num_heads + return forward_sdpa(self, hidden_states, **kwargs) + + if diffusers.__version__ < "0.15.0": + diffusers.models.attention.AttentionBlock.forward = forward_sdpa_0_14 + else: + diffusers.models.attention_processor.Attention.forward = forward_sdpa + + +# endregion + +# region 画像生成の本体:lpw_stable_diffusion.py (ASL)からコピーして修正 +# https://github.com/huggingface/diffusers/blob/main/examples/community/lpw_stable_diffusion.py +# Pipelineだけ独立して使えないのと機能追加するのとでコピーして修正 + + +class PipelineLike: + def __init__( + self, + device, + vae: AutoencoderKL, + text_encoders: List[CLIPTextModel], + tokenizers: List[CLIPTokenizer], + unet: SdxlUNet2DConditionModel, + scheduler: Union[DDIMScheduler, PNDMScheduler, LMSDiscreteScheduler], + clip_skip: int, + ): + super().__init__() + self.device = device + self.clip_skip = clip_skip + + if hasattr(scheduler.config, "steps_offset") and scheduler.config.steps_offset != 1: + deprecation_message = ( + f"The configuration file of this scheduler: {scheduler} is outdated. `steps_offset`" + f" should be set to 1 instead of {scheduler.config.steps_offset}. Please make sure " + "to update the config accordingly as leaving `steps_offset` might led to incorrect results" + " in future versions. If you have downloaded this checkpoint from the Hugging Face Hub," + " it would be very nice if you could open a Pull request for the `scheduler/scheduler_config.json`" + " file" + ) + deprecate("steps_offset!=1", "1.0.0", deprecation_message, standard_warn=False) + new_config = dict(scheduler.config) + new_config["steps_offset"] = 1 + scheduler._internal_dict = FrozenDict(new_config) + + if hasattr(scheduler.config, "clip_sample") and scheduler.config.clip_sample is True: + deprecation_message = ( + f"The configuration file of this scheduler: {scheduler} has not set the configuration `clip_sample`." + " `clip_sample` should be set to False in the configuration file. Please make sure to update the" + " config accordingly as not setting `clip_sample` in the config might lead to incorrect results in" + " future versions. If you have downloaded this checkpoint from the Hugging Face Hub, it would be very" + " nice if you could open a Pull request for the `scheduler/scheduler_config.json` file" + ) + deprecate("clip_sample not set", "1.0.0", deprecation_message, standard_warn=False) + new_config = dict(scheduler.config) + new_config["clip_sample"] = False + scheduler._internal_dict = FrozenDict(new_config) + + self.vae = vae + self.text_encoders = text_encoders + self.tokenizers = tokenizers + self.unet: SdxlUNet2DConditionModel = unet + self.scheduler = scheduler + self.safety_checker = None + + # Textual Inversion # not tested yet + self.token_replacements_list = [] + for _ in range(len(self.text_encoders)): + self.token_replacements_list.append({}) + + # ControlNet # not supported yet + self.control_nets: List[ControlNetInfo] = [] + self.control_net_enabled = True # control_netsが空ならTrueでもFalseでもControlNetは動作しない + + # Textual Inversion + def add_token_replacement(self, text_encoder_index, target_token_id, rep_token_ids): + self.token_replacements_list[text_encoder_index][target_token_id] = rep_token_ids + + def set_enable_control_net(self, en: bool): + self.control_net_enabled = en + + def get_token_replacer(self, tokenizer): + tokenizer_index = self.tokenizers.index(tokenizer) + token_replacements = self.token_replacements_list[tokenizer_index] + + def replace_tokens(tokens): + new_tokens = [] + for token in tokens: + if token in token_replacements: + replacement = token_replacements[token] + new_tokens.extend(replacement) + else: + new_tokens.append(token) + return new_tokens + + return replace_tokens + + def set_control_nets(self, ctrl_nets): + self.control_nets = ctrl_nets + + @torch.no_grad() + def __call__( + self, + prompt: Union[str, List[str]], + negative_prompt: Optional[Union[str, List[str]]] = None, + init_image: Union[torch.FloatTensor, PIL.Image.Image, List[PIL.Image.Image]] = None, + mask_image: Union[torch.FloatTensor, PIL.Image.Image, List[PIL.Image.Image]] = None, + height: int = 1024, + width: int = 1024, + original_height: int = None, + original_width: int = None, + crop_top: int = 0, + crop_left: int = 0, + num_inference_steps: int = 50, + guidance_scale: float = 7.5, + negative_scale: float = None, + strength: float = 0.8, + # num_images_per_prompt: Optional[int] = 1, + eta: float = 0.0, + generator: Optional[torch.Generator] = None, + latents: Optional[torch.FloatTensor] = None, + max_embeddings_multiples: Optional[int] = 3, + output_type: Optional[str] = "pil", + vae_batch_size: float = None, + return_latents: bool = False, + # return_dict: bool = True, + callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None, + is_cancelled_callback: Optional[Callable[[], bool]] = None, + callback_steps: Optional[int] = 1, + img2img_noise=None, + **kwargs, + ): + # TODO support secondary prompt + num_images_per_prompt = 1 # fixed because already prompt is repeated + + if isinstance(prompt, str): + batch_size = 1 + prompt = [prompt] + elif isinstance(prompt, list): + batch_size = len(prompt) + else: + raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") + reginonal_network = " AND " in prompt[0] + + vae_batch_size = ( + batch_size + if vae_batch_size is None + else (int(vae_batch_size) if vae_batch_size >= 1 else max(1, int(batch_size * vae_batch_size))) + ) + + if strength < 0 or strength > 1: + raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}") + + if height % 8 != 0 or width % 8 != 0: + raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") + + if (callback_steps is None) or ( + callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0) + ): + raise ValueError( + f"`callback_steps` has to be a positive integer but is {callback_steps} of type" f" {type(callback_steps)}." + ) + + # get prompt text embeddings + + # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2) + # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1` + # corresponds to doing no classifier free guidance. + do_classifier_free_guidance = guidance_scale > 1.0 + + if not do_classifier_free_guidance and negative_scale is not None: + print(f"negative_scale is ignored if guidance scalle <= 1.0") + negative_scale = None + + # get unconditional embeddings for classifier free guidance + if negative_prompt is None: + negative_prompt = [""] * batch_size + elif isinstance(negative_prompt, str): + negative_prompt = [negative_prompt] * batch_size + if batch_size != len(negative_prompt): + raise ValueError( + f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" + f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" + " the batch size of `prompt`." + ) + + tes_text_embs = [] + tes_uncond_embs = [] + tes_real_uncond_embs = [] + # use last pool + for tokenizer, text_encoder in zip(self.tokenizers, self.text_encoders): + token_replacer = self.get_token_replacer(tokenizer) + + text_embeddings, text_pool, uncond_embeddings, uncond_pool, _ = get_weighted_text_embeddings( + tokenizer, + text_encoder, + prompt=prompt, + uncond_prompt=negative_prompt if do_classifier_free_guidance else None, + max_embeddings_multiples=max_embeddings_multiples, + clip_skip=self.clip_skip, + token_replacer=token_replacer, + device=self.device, + **kwargs, + ) + tes_text_embs.append(text_embeddings) + tes_uncond_embs.append(uncond_embeddings) + + if negative_scale is not None: + _, real_uncond_embeddings, _ = get_weighted_text_embeddings( + token_replacer, + prompt=prompt, # こちらのトークン長に合わせてuncondを作るので75トークン超で必須 + uncond_prompt=[""] * batch_size, + max_embeddings_multiples=max_embeddings_multiples, + clip_skip=self.clip_skip, + token_replacer=token_replacer, + device=self.device, + **kwargs, + ) + tes_real_uncond_embs.append(real_uncond_embeddings) + + # concat text encoder outputs + text_embeddings = tes_text_embs[0] + uncond_embeddings = tes_uncond_embs[0] + for i in range(1, len(tes_text_embs)): + text_embeddings = torch.cat([text_embeddings, tes_text_embs[i]], dim=2) # n,77,2048 + uncond_embeddings = torch.cat([uncond_embeddings, tes_uncond_embs[i]], dim=2) # n,77,2048 + + if do_classifier_free_guidance: + if negative_scale is None: + text_embeddings = torch.cat([uncond_embeddings, text_embeddings]) + else: + text_embeddings = torch.cat([uncond_embeddings, text_embeddings, real_uncond_embeddings]) + + if self.control_nets: + if isinstance(clip_guide_images, PIL.Image.Image): + clip_guide_images = [clip_guide_images] + + # ControlNetのhintにguide imageを流用する + # 前処理はControlNet側で行う + + # create size embs + if original_height is None: + original_height = height + if original_width is None: + original_width = width + if crop_top is None: + crop_top = 0 + if crop_left is None: + crop_left = 0 + emb1 = sdxl_train_util.get_timestep_embedding(torch.FloatTensor([original_height, original_width]).unsqueeze(0), 256) + emb2 = sdxl_train_util.get_timestep_embedding(torch.FloatTensor([crop_top, crop_left]).unsqueeze(0), 256) + emb3 = sdxl_train_util.get_timestep_embedding(torch.FloatTensor([height, width]).unsqueeze(0), 256) + c_vector = torch.cat([emb1, emb2, emb3], dim=1).to(self.device, dtype=text_embeddings.dtype) + uc_vector = c_vector.clone().to(self.device, dtype=text_embeddings.dtype) + + c_vector = torch.cat([text_pool, c_vector], dim=1) + uc_vector = torch.cat([uncond_pool, uc_vector], dim=1) + + vector_embeddings = torch.cat([uc_vector, c_vector]) + + # set timesteps + self.scheduler.set_timesteps(num_inference_steps, self.device) + + latents_dtype = text_embeddings.dtype + init_latents_orig = None + mask = None + + if init_image is None: + # get the initial random noise unless the user supplied it + + # Unlike in other pipelines, latents need to be generated in the target device + # for 1-to-1 results reproducibility with the CompVis implementation. + # However this currently doesn't work in `mps`. + latents_shape = ( + batch_size * num_images_per_prompt, + self.unet.in_channels, + height // 8, + width // 8, + ) + + if latents is None: + if self.device.type == "mps": + # randn does not exist on mps + latents = torch.randn( + latents_shape, + generator=generator, + device="cpu", + dtype=latents_dtype, + ).to(self.device) + else: + latents = torch.randn( + latents_shape, + generator=generator, + device=self.device, + dtype=latents_dtype, + ) + else: + if latents.shape != latents_shape: + raise ValueError(f"Unexpected latents shape, got {latents.shape}, expected {latents_shape}") + latents = latents.to(self.device) + + timesteps = self.scheduler.timesteps.to(self.device) + + # scale the initial noise by the standard deviation required by the scheduler + latents = latents * self.scheduler.init_noise_sigma + else: + # image to tensor + if isinstance(init_image, PIL.Image.Image): + init_image = [init_image] + if isinstance(init_image[0], PIL.Image.Image): + init_image = [preprocess_image(im) for im in init_image] + init_image = torch.cat(init_image) + if isinstance(init_image, list): + init_image = torch.stack(init_image) + + # mask image to tensor + if mask_image is not None: + if isinstance(mask_image, PIL.Image.Image): + mask_image = [mask_image] + if isinstance(mask_image[0], PIL.Image.Image): + mask_image = torch.cat([preprocess_mask(im) for im in mask_image]) # H*W, 0 for repaint + + # encode the init image into latents and scale the latents + init_image = init_image.to(device=self.device, dtype=latents_dtype) + if init_image.size()[-2:] == (height // 8, width // 8): + init_latents = init_image + else: + if vae_batch_size >= batch_size: + init_latent_dist = self.vae.encode(init_image.to(self.vae.dtype)).latent_dist + init_latents = init_latent_dist.sample(generator=generator) + else: + if torch.cuda.is_available(): + torch.cuda.empty_cache() + init_latents = [] + for i in tqdm(range(0, min(batch_size, len(init_image)), vae_batch_size)): + init_latent_dist = self.vae.encode( + (init_image[i : i + vae_batch_size] if vae_batch_size > 1 else init_image[i].unsqueeze(0)).to( + self.vae.dtype + ) + ).latent_dist + init_latents.append(init_latent_dist.sample(generator=generator)) + init_latents = torch.cat(init_latents) + + init_latents = sdxl_model_util.VAE_SCALE_FACTOR * init_latents + + if len(init_latents) == 1: + init_latents = init_latents.repeat((batch_size, 1, 1, 1)) + init_latents_orig = init_latents + + # preprocess mask + if mask_image is not None: + mask = mask_image.to(device=self.device, dtype=latents_dtype) + if len(mask) == 1: + mask = mask.repeat((batch_size, 1, 1, 1)) + + # check sizes + if not mask.shape == init_latents.shape: + raise ValueError("The mask and init_image should be the same size!") + + # get the original timestep using init_timestep + offset = self.scheduler.config.get("steps_offset", 0) + init_timestep = int(num_inference_steps * strength) + offset + init_timestep = min(init_timestep, num_inference_steps) + + timesteps = self.scheduler.timesteps[-init_timestep] + timesteps = torch.tensor([timesteps] * batch_size * num_images_per_prompt, device=self.device) + + # add noise to latents using the timesteps + latents = self.scheduler.add_noise(init_latents, img2img_noise, timesteps) + + t_start = max(num_inference_steps - init_timestep + offset, 0) + timesteps = self.scheduler.timesteps[t_start:].to(self.device) + + # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature + # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers. + # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502 + # and should be between [0, 1] + accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()) + extra_step_kwargs = {} + if accepts_eta: + extra_step_kwargs["eta"] = eta + + num_latent_input = (3 if negative_scale is not None else 2) if do_classifier_free_guidance else 1 + + if self.control_nets: + guided_hints = original_control_net.get_guided_hints(self.control_nets, num_latent_input, batch_size, clip_guide_images) + + for i, t in enumerate(tqdm(timesteps)): + # expand the latents if we are doing classifier free guidance + latent_model_input = latents.repeat((num_latent_input, 1, 1, 1)) + latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) + + # predict the noise residual + if self.control_nets and self.control_net_enabled: + if reginonal_network: + num_sub_and_neg_prompts = len(text_embeddings) // batch_size + text_emb_last = text_embeddings[num_sub_and_neg_prompts - 2 :: num_sub_and_neg_prompts] # last subprompt + else: + text_emb_last = text_embeddings + + # not working yet + noise_pred = original_control_net.call_unet_and_control_net( + i, + num_latent_input, + self.unet, + self.control_nets, + guided_hints, + i / len(timesteps), + latent_model_input, + t, + text_emb_last, + ).sample + else: + noise_pred = self.unet(latent_model_input, t, text_embeddings, vector_embeddings) + + # perform guidance + if do_classifier_free_guidance: + if negative_scale is None: + noise_pred_uncond, noise_pred_text = noise_pred.chunk(num_latent_input) # uncond by negative prompt + noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) + else: + noise_pred_negative, noise_pred_text, noise_pred_uncond = noise_pred.chunk( + num_latent_input + ) # uncond is real uncond + noise_pred = ( + noise_pred_uncond + + guidance_scale * (noise_pred_text - noise_pred_uncond) + - negative_scale * (noise_pred_negative - noise_pred_uncond) + ) + + # compute the previous noisy sample x_t -> x_t-1 + latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs).prev_sample + + if mask is not None: + # masking + init_latents_proper = self.scheduler.add_noise(init_latents_orig, img2img_noise, torch.tensor([t])) + latents = (init_latents_proper * mask) + (latents * (1 - mask)) + + # call the callback, if provided + if i % callback_steps == 0: + if callback is not None: + callback(i, t, latents) + if is_cancelled_callback is not None and is_cancelled_callback(): + return None + + if return_latents: + return (latents, False) + + latents = 1 / sdxl_model_util.VAE_SCALE_FACTOR * latents + if vae_batch_size >= batch_size: + image = self.vae.decode(latents.to(self.vae.dtype)).sample + else: + if torch.cuda.is_available(): + torch.cuda.empty_cache() + images = [] + for i in tqdm(range(0, batch_size, vae_batch_size)): + images.append( + self.vae.decode( + (latents[i : i + vae_batch_size] if vae_batch_size > 1 else latents[i].unsqueeze(0)).to(self.vae.dtype) + ).sample + ) + image = torch.cat(images) + + image = (image / 2 + 0.5).clamp(0, 1) + + # we always cast to float32 as this does not cause significant overhead and is compatible with bfloa16 + image = image.cpu().permute(0, 2, 3, 1).float().numpy() + + if output_type == "pil": + # image = self.numpy_to_pil(image) + image = (image * 255).round().astype("uint8") + image = [Image.fromarray(im) for im in image] + + return image + + # return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept) + + +re_attention = re.compile( + r""" +\\\(| +\\\)| +\\\[| +\\]| +\\\\| +\\| +\(| +\[| +:([+-]?[.\d]+)\)| +\)| +]| +[^\\()\[\]:]+| +: +""", + re.X, +) + + +def parse_prompt_attention(text): + """ + Parses a string with attention tokens and returns a list of pairs: text and its associated weight. + Accepted tokens are: + (abc) - increases attention to abc by a multiplier of 1.1 + (abc:3.12) - increases attention to abc by a multiplier of 3.12 + [abc] - decreases attention to abc by a multiplier of 1.1 + \( - literal character '(' + \[ - literal character '[' + \) - literal character ')' + \] - literal character ']' + \\ - literal character '\' + anything else - just text + >>> parse_prompt_attention('normal text') + [['normal text', 1.0]] + >>> parse_prompt_attention('an (important) word') + [['an ', 1.0], ['important', 1.1], [' word', 1.0]] + >>> parse_prompt_attention('(unbalanced') + [['unbalanced', 1.1]] + >>> parse_prompt_attention('\(literal\]') + [['(literal]', 1.0]] + >>> parse_prompt_attention('(unnecessary)(parens)') + [['unnecessaryparens', 1.1]] + >>> parse_prompt_attention('a (((house:1.3)) [on] a (hill:0.5), sun, (((sky))).') + [['a ', 1.0], + ['house', 1.5730000000000004], + [' ', 1.1], + ['on', 1.0], + [' a ', 1.1], + ['hill', 0.55], + [', sun, ', 1.1], + ['sky', 1.4641000000000006], + ['.', 1.1]] + """ + + res = [] + round_brackets = [] + square_brackets = [] + + round_bracket_multiplier = 1.1 + square_bracket_multiplier = 1 / 1.1 + + def multiply_range(start_position, multiplier): + for p in range(start_position, len(res)): + res[p][1] *= multiplier + + # keep break as separate token + text = text.replace("BREAK", "\\BREAK\\") + + for m in re_attention.finditer(text): + text = m.group(0) + weight = m.group(1) + + if text.startswith("\\"): + res.append([text[1:], 1.0]) + elif text == "(": + round_brackets.append(len(res)) + elif text == "[": + square_brackets.append(len(res)) + elif weight is not None and len(round_brackets) > 0: + multiply_range(round_brackets.pop(), float(weight)) + elif text == ")" and len(round_brackets) > 0: + multiply_range(round_brackets.pop(), round_bracket_multiplier) + elif text == "]" and len(square_brackets) > 0: + multiply_range(square_brackets.pop(), square_bracket_multiplier) + else: + res.append([text, 1.0]) + + for pos in round_brackets: + multiply_range(pos, round_bracket_multiplier) + + for pos in square_brackets: + multiply_range(pos, square_bracket_multiplier) + + if len(res) == 0: + res = [["", 1.0]] + + # merge runs of identical weights + i = 0 + while i + 1 < len(res): + if res[i][1] == res[i + 1][1] and res[i][0].strip() != "BREAK" and res[i + 1][0].strip() != "BREAK": + res[i][0] += res[i + 1][0] + res.pop(i + 1) + else: + i += 1 + + return res + + +def get_prompts_with_weights(tokenizer: CLIPTokenizer, token_replacer, prompt: List[str], max_length: int): + r""" + Tokenize a list of prompts and return its tokens with weights of each token. + No padding, starting or ending token is included. + """ + tokens = [] + weights = [] + truncated = False + + for text in prompt: + texts_and_weights = parse_prompt_attention(text) + text_token = [] + text_weight = [] + for word, weight in texts_and_weights: + if word.strip() == "BREAK": + # pad until next multiple of tokenizer's max token length + pad_len = tokenizer.model_max_length - (len(text_token) % tokenizer.model_max_length) + print(f"BREAK pad_len: {pad_len}") + for i in range(pad_len): + # v2のときEOSをつけるべきかどうかわからないぜ + # if i == 0: + # text_token.append(tokenizer.eos_token_id) + # else: + text_token.append(tokenizer.pad_token_id) + text_weight.append(1.0) + continue + + # tokenize and discard the starting and the ending token + token = tokenizer(word).input_ids[1:-1] + + token = token_replacer(token) # for Textual Inversion + + text_token += token + # copy the weight by length of token + text_weight += [weight] * len(token) + # stop if the text is too long (longer than truncation limit) + if len(text_token) > max_length: + truncated = True + break + # truncate + if len(text_token) > max_length: + truncated = True + text_token = text_token[:max_length] + text_weight = text_weight[:max_length] + tokens.append(text_token) + weights.append(text_weight) + if truncated: + print("warning: Prompt was truncated. Try to shorten the prompt or increase max_embeddings_multiples") + return tokens, weights + + +def pad_tokens_and_weights(tokens, weights, max_length, bos, eos, pad, no_boseos_middle=True, chunk_length=77): + r""" + Pad the tokens (with starting and ending tokens) and weights (with 1.0) to max_length. + """ + max_embeddings_multiples = (max_length - 2) // (chunk_length - 2) + weights_length = max_length if no_boseos_middle else max_embeddings_multiples * chunk_length + for i in range(len(tokens)): + tokens[i] = [bos] + tokens[i] + [eos] + [pad] * (max_length - 2 - len(tokens[i])) + if no_boseos_middle: + weights[i] = [1.0] + weights[i] + [1.0] * (max_length - 1 - len(weights[i])) + else: + w = [] + if len(weights[i]) == 0: + w = [1.0] * weights_length + else: + for j in range(max_embeddings_multiples): + w.append(1.0) # weight for starting token in this chunk + w += weights[i][j * (chunk_length - 2) : min(len(weights[i]), (j + 1) * (chunk_length - 2))] + w.append(1.0) # weight for ending token in this chunk + w += [1.0] * (weights_length - len(w)) + weights[i] = w[:] + + return tokens, weights + + +def get_unweighted_text_embeddings( + text_encoder: CLIPTextModel, + text_input: torch.Tensor, + chunk_length: int, + clip_skip: int, + eos: int, + pad: int, + no_boseos_middle: Optional[bool] = True, +): + """ + When the length of tokens is a multiple of the capacity of the text encoder, + it should be split into chunks and sent to the text encoder individually. + """ + max_embeddings_multiples = (text_input.shape[1] - 2) // (chunk_length - 2) + if max_embeddings_multiples > 1: + text_embeddings = [] + pool = None + for i in range(max_embeddings_multiples): + # extract the i-th chunk + text_input_chunk = text_input[:, i * (chunk_length - 2) : (i + 1) * (chunk_length - 2) + 2].clone() + + # cover the head and the tail by the starting and the ending tokens + text_input_chunk[:, 0] = text_input[0, 0] + if pad == eos: # v1 + text_input_chunk[:, -1] = text_input[0, -1] + else: # v2 + for j in range(len(text_input_chunk)): + if text_input_chunk[j, -1] != eos and text_input_chunk[j, -1] != pad: # 最後に普通の文字がある + text_input_chunk[j, -1] = eos + if text_input_chunk[j, 1] == pad: # BOSだけであとはPAD + text_input_chunk[j, 1] = eos + + # -2 is same for Text Encoder 1 and 2 + enc_out = text_encoder(text_input_chunk, output_hidden_states=True, return_dict=True) + text_embedding = enc_out["hidden_states"][-2] + if pool is None: + pool = enc_out["text_embeds"] # use 1st chunk + + if no_boseos_middle: + if i == 0: + # discard the ending token + text_embedding = text_embedding[:, :-1] + elif i == max_embeddings_multiples - 1: + # discard the starting token + text_embedding = text_embedding[:, 1:] + else: + # discard both starting and ending tokens + text_embedding = text_embedding[:, 1:-1] + + text_embeddings.append(text_embedding) + text_embeddings = torch.concat(text_embeddings, axis=1) + else: + enc_out = text_encoder(text_input, output_hidden_states=True, return_dict=True) + text_embeddings = enc_out["hidden_states"][-2] + pool = enc_out.get("text_embeds", None) # text encoder 1 doesn't return this + return text_embeddings, pool + + +def get_weighted_text_embeddings( + tokenizer: CLIPTokenizer, + text_encoder: CLIPTextModel, + prompt: Union[str, List[str]], + uncond_prompt: Optional[Union[str, List[str]]] = None, + max_embeddings_multiples: Optional[int] = 1, + no_boseos_middle: Optional[bool] = False, + skip_parsing: Optional[bool] = False, + skip_weighting: Optional[bool] = False, + clip_skip=None, + token_replacer=None, + device=None, + **kwargs, +): + max_length = (tokenizer.model_max_length - 2) * max_embeddings_multiples + 2 + if isinstance(prompt, str): + prompt = [prompt] + + # split the prompts with "AND". each prompt must have the same number of splits + new_prompts = [] + for p in prompt: + new_prompts.extend(p.split(" AND ")) + prompt = new_prompts + + if not skip_parsing: + prompt_tokens, prompt_weights = get_prompts_with_weights(tokenizer, token_replacer, prompt, max_length - 2) + if uncond_prompt is not None: + if isinstance(uncond_prompt, str): + uncond_prompt = [uncond_prompt] + uncond_tokens, uncond_weights = get_prompts_with_weights(tokenizer, token_replacer, uncond_prompt, max_length - 2) + else: + prompt_tokens = [token[1:-1] for token in tokenizer(prompt, max_length=max_length, truncation=True).input_ids] + prompt_weights = [[1.0] * len(token) for token in prompt_tokens] + if uncond_prompt is not None: + if isinstance(uncond_prompt, str): + uncond_prompt = [uncond_prompt] + uncond_tokens = [token[1:-1] for token in tokenizer(uncond_prompt, max_length=max_length, truncation=True).input_ids] + uncond_weights = [[1.0] * len(token) for token in uncond_tokens] + + # round up the longest length of tokens to a multiple of (model_max_length - 2) + max_length = max([len(token) for token in prompt_tokens]) + if uncond_prompt is not None: + max_length = max(max_length, max([len(token) for token in uncond_tokens])) + + max_embeddings_multiples = min( + max_embeddings_multiples, + (max_length - 1) // (tokenizer.model_max_length - 2) + 1, + ) + max_embeddings_multiples = max(1, max_embeddings_multiples) + max_length = (tokenizer.model_max_length - 2) * max_embeddings_multiples + 2 + + # pad the length of tokens and weights + bos = tokenizer.bos_token_id + eos = tokenizer.eos_token_id + pad = tokenizer.pad_token_id + prompt_tokens, prompt_weights = pad_tokens_and_weights( + prompt_tokens, + prompt_weights, + max_length, + bos, + eos, + pad, + no_boseos_middle=no_boseos_middle, + chunk_length=tokenizer.model_max_length, + ) + prompt_tokens = torch.tensor(prompt_tokens, dtype=torch.long, device=device) + if uncond_prompt is not None: + uncond_tokens, uncond_weights = pad_tokens_and_weights( + uncond_tokens, + uncond_weights, + max_length, + bos, + eos, + pad, + no_boseos_middle=no_boseos_middle, + chunk_length=tokenizer.model_max_length, + ) + uncond_tokens = torch.tensor(uncond_tokens, dtype=torch.long, device=device) + + # get the embeddings + text_embeddings, text_pool = get_unweighted_text_embeddings( + text_encoder, + prompt_tokens, + tokenizer.model_max_length, + clip_skip, + eos, + pad, + no_boseos_middle=no_boseos_middle, + ) + prompt_weights = torch.tensor(prompt_weights, dtype=text_embeddings.dtype, device=device) + if uncond_prompt is not None: + uncond_embeddings, uncond_pool = get_unweighted_text_embeddings( + text_encoder, + uncond_tokens, + tokenizer.model_max_length, + clip_skip, + eos, + pad, + no_boseos_middle=no_boseos_middle, + ) + uncond_weights = torch.tensor(uncond_weights, dtype=uncond_embeddings.dtype, device=device) + + # assign weights to the prompts and normalize in the sense of mean + # TODO: should we normalize by chunk or in a whole (current implementation)? + # →全体でいいんじゃないかな + if (not skip_parsing) and (not skip_weighting): + previous_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype) + text_embeddings *= prompt_weights.unsqueeze(-1) + current_mean = text_embeddings.float().mean(axis=[-2, -1]).to(text_embeddings.dtype) + text_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1) + if uncond_prompt is not None: + previous_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype) + uncond_embeddings *= uncond_weights.unsqueeze(-1) + current_mean = uncond_embeddings.float().mean(axis=[-2, -1]).to(uncond_embeddings.dtype) + uncond_embeddings *= (previous_mean / current_mean).unsqueeze(-1).unsqueeze(-1) + + if uncond_prompt is not None: + return text_embeddings, text_pool, uncond_embeddings, uncond_pool, prompt_tokens + return text_embeddings, text_pool, None, None, prompt_tokens + + +def preprocess_image(image): + w, h = image.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + image = image.resize((w, h), resample=PIL.Image.LANCZOS) + image = np.array(image).astype(np.float32) / 255.0 + image = image[None].transpose(0, 3, 1, 2) + image = torch.from_numpy(image) + return 2.0 * image - 1.0 + + +def preprocess_mask(mask): + mask = mask.convert("L") + w, h = mask.size + w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 + mask = mask.resize((w // 8, h // 8), resample=PIL.Image.BILINEAR) # LANCZOS) + mask = np.array(mask).astype(np.float32) / 255.0 + mask = np.tile(mask, (4, 1, 1)) + mask = mask[None].transpose(0, 1, 2, 3) # what does this step do? + mask = 1 - mask # repaint white, keep black + mask = torch.from_numpy(mask) + return mask + + +# regular expression for dynamic prompt: +# starts and ends with "{" and "}" +# contains at least one variant divided by "|" +# optional framgments divided by "$$" at start +# if the first fragment is "E" or "e", enumerate all variants +# if the second fragment is a number or two numbers, repeat the variants in the range +# if the third fragment is a string, use it as a separator + +RE_DYNAMIC_PROMPT = re.compile(r"\{((e|E)\$\$)?(([\d\-]+)\$\$)?(([^\|\}]+?)\$\$)?(.+?((\|).+?)*?)\}") + + +def handle_dynamic_prompt_variants(prompt, repeat_count): + founds = list(RE_DYNAMIC_PROMPT.finditer(prompt)) + if not founds: + return [prompt] + + # make each replacement for each variant + enumerating = False + replacers = [] + for found in founds: + # if "e$$" is found, enumerate all variants + found_enumerating = found.group(2) is not None + enumerating = enumerating or found_enumerating + + separator = ", " if found.group(6) is None else found.group(6) + variants = found.group(7).split("|") + + # parse count range + count_range = found.group(4) + if count_range is None: + count_range = [1, 1] + else: + count_range = count_range.split("-") + if len(count_range) == 1: + count_range = [int(count_range[0]), int(count_range[0])] + elif len(count_range) == 2: + count_range = [int(count_range[0]), int(count_range[1])] + else: + print(f"invalid count range: {count_range}") + count_range = [1, 1] + if count_range[0] > count_range[1]: + count_range = [count_range[1], count_range[0]] + if count_range[0] < 0: + count_range[0] = 0 + if count_range[1] > len(variants): + count_range[1] = len(variants) + + if found_enumerating: + # make function to enumerate all combinations + def make_replacer_enum(vari, cr, sep): + def replacer(): + values = [] + for count in range(cr[0], cr[1] + 1): + for comb in itertools.combinations(vari, count): + values.append(sep.join(comb)) + return values + + return replacer + + replacers.append(make_replacer_enum(variants, count_range, separator)) + else: + # make function to choose random combinations + def make_replacer_single(vari, cr, sep): + def replacer(): + count = random.randint(cr[0], cr[1]) + comb = random.sample(vari, count) + return [sep.join(comb)] + + return replacer + + replacers.append(make_replacer_single(variants, count_range, separator)) + + # make each prompt + if not enumerating: + # if not enumerating, repeat the prompt, replace each variant randomly + prompts = [] + for _ in range(repeat_count): + current = prompt + for found, replacer in zip(founds, replacers): + current = current.replace(found.group(0), replacer()[0], 1) + prompts.append(current) + else: + # if enumerating, iterate all combinations for previous prompts + prompts = [prompt] + + for found, replacer in zip(founds, replacers): + if found.group(2) is not None: + # make all combinations for existing prompts + new_prompts = [] + for current in prompts: + replecements = replacer() + for replecement in replecements: + new_prompts.append(current.replace(found.group(0), replecement, 1)) + prompts = new_prompts + + for found, replacer in zip(founds, replacers): + # make random selection for existing prompts + if found.group(2) is None: + for i in range(len(prompts)): + prompts[i] = prompts[i].replace(found.group(0), replacer()[0], 1) + + return prompts + + +# endregion + + +# def load_clip_l14_336(dtype): +# print(f"loading CLIP: {CLIP_ID_L14_336}") +# text_encoder = CLIPTextModel.from_pretrained(CLIP_ID_L14_336, torch_dtype=dtype) +# return text_encoder + + +class BatchDataBase(NamedTuple): + # バッチ分割が必要ないデータ + step: int + prompt: str + negative_prompt: str + seed: int + init_image: Any + mask_image: Any + clip_prompt: str + guide_image: Any + + +class BatchDataExt(NamedTuple): + # バッチ分割が必要なデータ + width: int + height: int + original_width: int + original_height: int + crop_left: int + crop_top: int + steps: int + scale: float + negative_scale: float + strength: float + network_muls: Tuple[float] + num_sub_prompts: int + + +class BatchData(NamedTuple): + return_latents: bool + base: BatchDataBase + ext: BatchDataExt + + +def main(args): + if args.fp16: + dtype = torch.float16 + elif args.bf16: + dtype = torch.bfloat16 + else: + dtype = torch.float32 + + highres_fix = args.highres_fix_scale is not None + # assert not highres_fix or args.image_path is None, f"highres_fix doesn't work with img2img / highres_fixはimg2imgと同時に使えません" + + # モデルを読み込む + if not os.path.isfile(args.ckpt): # ファイルがないならパターンで探し、一つだけ該当すればそれを使う + files = glob.glob(args.ckpt) + if len(files) == 1: + args.ckpt = files[0] + + use_stable_diffusion_format = os.path.isfile(args.ckpt) + assert use_stable_diffusion_format, "Diffusers pretrained models are not supported yet" + print("load StableDiffusion checkpoint") + text_encoder1, text_encoder2, vae, unet, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( + sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.ckpt, "cpu" + ) + # else: + # print("load Diffusers pretrained models") + # TODO use Diffusers 0.18.1 and support SDXL pipeline + # raise NotImplementedError("Diffusers pretrained models are not supported yet") + # loading_pipe = StableDiffusionXLPipeline.from_pretrained(args.ckpt, safety_checker=None, torch_dtype=dtype) + # text_encoder = loading_pipe.text_encoder + # vae = loading_pipe.vae + # unet = loading_pipe.unet + # tokenizer = loading_pipe.tokenizer + # del loading_pipe + + # # Diffusers U-Net to original U-Net + # original_unet = SdxlUNet2DConditionModel( + # unet.config.sample_size, + # unet.config.attention_head_dim, + # unet.config.cross_attention_dim, + # unet.config.use_linear_projection, + # unet.config.upcast_attention, + # ) + # original_unet.load_state_dict(unet.state_dict()) + # unet = original_unet + + # VAEを読み込む + if args.vae is not None: + vae = model_util.load_vae(args.vae, dtype) + print("additional VAE loaded") + + # xformers、Hypernetwork対応 + if not args.diffusers_xformers: + mem_eff = not (args.xformers or args.sdpa) + replace_unet_modules(unet, mem_eff, args.xformers, args.sdpa) + replace_vae_modules(vae, mem_eff, args.xformers, args.sdpa) + + # tokenizerを読み込む + print("loading tokenizer") + if use_stable_diffusion_format: + tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) + + # schedulerを用意する + sched_init_args = {} + scheduler_num_noises_per_step = 1 + if args.sampler == "ddim": + scheduler_cls = DDIMScheduler + scheduler_module = diffusers.schedulers.scheduling_ddim + elif args.sampler == "ddpm": # ddpmはおかしくなるのでoptionから外してある + scheduler_cls = DDPMScheduler + scheduler_module = diffusers.schedulers.scheduling_ddpm + elif args.sampler == "pndm": + scheduler_cls = PNDMScheduler + scheduler_module = diffusers.schedulers.scheduling_pndm + elif args.sampler == "lms" or args.sampler == "k_lms": + scheduler_cls = LMSDiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_lms_discrete + elif args.sampler == "euler" or args.sampler == "k_euler": + scheduler_cls = EulerDiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_euler_discrete + elif args.sampler == "euler_a" or args.sampler == "k_euler_a": + scheduler_cls = EulerAncestralDiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_euler_ancestral_discrete + elif args.sampler == "dpmsolver" or args.sampler == "dpmsolver++": + scheduler_cls = DPMSolverMultistepScheduler + sched_init_args["algorithm_type"] = args.sampler + scheduler_module = diffusers.schedulers.scheduling_dpmsolver_multistep + elif args.sampler == "dpmsingle": + scheduler_cls = DPMSolverSinglestepScheduler + scheduler_module = diffusers.schedulers.scheduling_dpmsolver_singlestep + elif args.sampler == "heun": + scheduler_cls = HeunDiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_heun_discrete + elif args.sampler == "dpm_2" or args.sampler == "k_dpm_2": + scheduler_cls = KDPM2DiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_k_dpm_2_discrete + elif args.sampler == "dpm_2_a" or args.sampler == "k_dpm_2_a": + scheduler_cls = KDPM2AncestralDiscreteScheduler + scheduler_module = diffusers.schedulers.scheduling_k_dpm_2_ancestral_discrete + scheduler_num_noises_per_step = 2 + + # samplerの乱数をあらかじめ指定するための処理 + + # replace randn + class NoiseManager: + def __init__(self): + self.sampler_noises = None + self.sampler_noise_index = 0 + + def reset_sampler_noises(self, noises): + self.sampler_noise_index = 0 + self.sampler_noises = noises + + def randn(self, shape, device=None, dtype=None, layout=None, generator=None): + # print("replacing", shape, len(self.sampler_noises), self.sampler_noise_index) + if self.sampler_noises is not None and self.sampler_noise_index < len(self.sampler_noises): + noise = self.sampler_noises[self.sampler_noise_index] + if shape != noise.shape: + noise = None + else: + noise = None + + if noise == None: + print(f"unexpected noise request: {self.sampler_noise_index}, {shape}") + noise = torch.randn(shape, dtype=dtype, device=device, generator=generator) + + self.sampler_noise_index += 1 + return noise + + class TorchRandReplacer: + def __init__(self, noise_manager): + self.noise_manager = noise_manager + + def __getattr__(self, item): + if item == "randn": + return self.noise_manager.randn + if hasattr(torch, item): + return getattr(torch, item) + raise AttributeError("'{}' object has no attribute '{}'".format(type(self).__name__, item)) + + noise_manager = NoiseManager() + if scheduler_module is not None: + scheduler_module.torch = TorchRandReplacer(noise_manager) + + scheduler = scheduler_cls( + num_train_timesteps=SCHEDULER_TIMESTEPS, + beta_start=SCHEDULER_LINEAR_START, + beta_end=SCHEDULER_LINEAR_END, + beta_schedule=SCHEDLER_SCHEDULE, + **sched_init_args, + ) + + # clip_sample=Trueにする + if hasattr(scheduler.config, "clip_sample") and scheduler.config.clip_sample is False: + print("set clip_sample to True") + scheduler.config.clip_sample = True + + # deviceを決定する + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # "mps"を考量してない + + # custom pipelineをコピったやつを生成する + if args.vae_slices: + from library.slicing_vae import SlicingAutoencoderKL + + sli_vae = SlicingAutoencoderKL( + act_fn="silu", + block_out_channels=(128, 256, 512, 512), + down_block_types=["DownEncoderBlock2D", "DownEncoderBlock2D", "DownEncoderBlock2D", "DownEncoderBlock2D"], + in_channels=3, + latent_channels=4, + layers_per_block=2, + norm_num_groups=32, + out_channels=3, + sample_size=512, + up_block_types=["UpDecoderBlock2D", "UpDecoderBlock2D", "UpDecoderBlock2D", "UpDecoderBlock2D"], + num_slices=args.vae_slices, + ) + sli_vae.load_state_dict(vae.state_dict()) # vaeのパラメータをコピーする + vae = sli_vae + del sli_vae + + vae_dtype = dtype + if args.no_half_vae: + print("set vae_dtype to float32") + vae_dtype = torch.float32 + vae.to(vae_dtype).to(device) + + text_encoder1.to(dtype).to(device) + text_encoder2.to(dtype).to(device) + unet.to(dtype).to(device) + + # networkを組み込む + if args.network_module: + networks = [] + network_default_muls = [] + network_pre_calc = args.network_pre_calc + + for i, network_module in enumerate(args.network_module): + print("import network module:", network_module) + imported_module = importlib.import_module(network_module) + + network_mul = 1.0 if args.network_mul is None or len(args.network_mul) <= i else args.network_mul[i] + network_default_muls.append(network_mul) + + net_kwargs = {} + if args.network_args and i < len(args.network_args): + network_args = args.network_args[i] + # TODO escape special chars + network_args = network_args.split(";") + for net_arg in network_args: + key, value = net_arg.split("=") + net_kwargs[key] = value + + if args.network_weights and i < len(args.network_weights): + network_weight = args.network_weights[i] + print("load network weights from:", network_weight) + + if model_util.is_safetensors(network_weight) and args.network_show_meta: + from safetensors.torch import safe_open + + with safe_open(network_weight, framework="pt") as f: + metadata = f.metadata() + if metadata is not None: + print(f"metadata for: {network_weight}: {metadata}") + + network, weights_sd = imported_module.create_network_from_weights( + network_mul, network_weight, vae, [text_encoder1, text_encoder2], unet, for_inference=True, **net_kwargs + ) + else: + raise ValueError("No weight. Weight is required.") + if network is None: + return + + mergeable = network.is_mergeable() + if args.network_merge and not mergeable: + print("network is not mergiable. ignore merge option.") + + if not args.network_merge or not mergeable: + network.apply_to([text_encoder1, text_encoder2], unet) + info = network.load_state_dict(weights_sd, False) # network.load_weightsを使うようにするとよい + print(f"weights are loaded: {info}") + + if args.opt_channels_last: + network.to(memory_format=torch.channels_last) + network.to(dtype).to(device) + + if network_pre_calc: + print("backup original weights") + network.backup_weights() + + networks.append(network) + else: + network.merge_to([text_encoder1, text_encoder2], unet, weights_sd, dtype, device) + + else: + networks = [] + + # upscalerの指定があれば取得する + upscaler = None + if args.highres_fix_upscaler: + print("import upscaler module:", args.highres_fix_upscaler) + imported_module = importlib.import_module(args.highres_fix_upscaler) + + us_kwargs = {} + if args.highres_fix_upscaler_args: + for net_arg in args.highres_fix_upscaler_args.split(";"): + key, value = net_arg.split("=") + us_kwargs[key] = value + + print("create upscaler") + upscaler = imported_module.create_upscaler(**us_kwargs) + upscaler.to(dtype).to(device) + + # ControlNetの処理 + control_nets: List[ControlNetInfo] = [] + if args.control_net_models: + for i, model in enumerate(args.control_net_models): + prep_type = None if not args.control_net_preps or len(args.control_net_preps) <= i else args.control_net_preps[i] + weight = 1.0 if not args.control_net_weights or len(args.control_net_weights) <= i else args.control_net_weights[i] + ratio = 1.0 if not args.control_net_ratios or len(args.control_net_ratios) <= i else args.control_net_ratios[i] + + ctrl_unet, ctrl_net = original_control_net.load_control_net(False, unet, model) + prep = original_control_net.load_preprocess(prep_type) + control_nets.append(ControlNetInfo(ctrl_unet, ctrl_net, prep, weight, ratio)) + + if args.opt_channels_last: + print(f"set optimizing: channels last") + text_encoder1.to(memory_format=torch.channels_last) + text_encoder2.to(memory_format=torch.channels_last) + vae.to(memory_format=torch.channels_last) + unet.to(memory_format=torch.channels_last) + if networks: + for network in networks: + network.to(memory_format=torch.channels_last) + + for cn in control_nets: + cn.unet.to(memory_format=torch.channels_last) + cn.net.to(memory_format=torch.channels_last) + + pipe = PipelineLike( + device, + vae, + [text_encoder1, text_encoder2], + [tokenizer1, tokenizer2], + unet, + scheduler, + args.clip_skip, + ) + pipe.set_control_nets(control_nets) + print("pipeline is ready.") + + if args.diffusers_xformers: + pipe.enable_xformers_memory_efficient_attention() + + # Textual Inversionを処理する + if args.textual_inversion_embeddings: + token_ids_embeds1 = [] + token_ids_embeds2 = [] + for embeds_file in args.textual_inversion_embeddings: + if model_util.is_safetensors(embeds_file): + from safetensors.torch import load_file + + data = load_file(embeds_file) + else: + data = torch.load(embeds_file, map_location="cpu") + + if "string_to_param" in data: + data = data["string_to_param"] + embeds1 = data["clip_l"] + embeds2 = data["clip_g"] + + num_vectors_per_token = embeds1.size()[0] + token_string = os.path.splitext(os.path.basename(embeds_file))[0] + token_strings = [token_string] + [f"{token_string}{i+1}" for i in range(num_vectors_per_token - 1)] + + # add new word to tokenizer, count is num_vectors_per_token + num_added_tokens1 = tokenizer1.add_tokens(token_strings) + num_added_tokens2 = tokenizer2.add_tokens(token_strings) # not working now + assert ( + num_added_tokens1 == num_vectors_per_token and num_added_tokens2 == num_vectors_per_token + ), f"tokenizer has same word to token string (filename). please rename the file / 指定した名前(ファイル名)のトークンが既に存在します。ファイルをリネームしてください: {embeds_file}" + + token_ids1 = tokenizer1.convert_tokens_to_ids(token_strings) + token_ids2 = tokenizer2.convert_tokens_to_ids(token_strings) + print(f"Textual Inversion embeddings `{token_string}` loaded. Tokens are added: {token_ids1} and {token_ids2}") + assert ( + min(token_ids1) == token_ids1[0] and token_ids1[-1] == token_ids1[0] + len(token_ids1) - 1 + ), f"token ids1 is not ordered" + assert ( + min(token_ids2) == token_ids2[0] and token_ids2[-1] == token_ids2[0] + len(token_ids2) - 1 + ), f"token ids2 is not ordered" + assert len(tokenizer1) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer1)}" + assert len(tokenizer2) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer2)}" + + if num_vectors_per_token > 1: + pipe.add_token_replacement(0, token_ids1[0], token_ids1) + pipe.add_token_replacement(1, token_ids2[0], token_ids2) + + token_ids_embeds1.append((token_ids1, embeds1)) + token_ids_embeds2.append((token_ids2, embeds2)) + + text_encoder1.resize_token_embeddings(len(tokenizer1)) + text_encoder2.resize_token_embeddings(len(tokenizer2)) + token_embeds1 = text_encoder1.get_input_embeddings().weight.data + token_embeds2 = text_encoder2.get_input_embeddings().weight.data + for token_ids, embeds in token_ids_embeds1: + for token_id, embed in zip(token_ids, embeds): + token_embeds1[token_id] = embed + for token_ids, embeds in token_ids_embeds2: + for token_id, embed in zip(token_ids, embeds): + token_embeds2[token_id] = embed + + # promptを取得する + if args.from_file is not None: + print(f"reading prompts from {args.from_file}") + with open(args.from_file, "r", encoding="utf-8") as f: + prompt_list = f.read().splitlines() + prompt_list = [d for d in prompt_list if len(d.strip()) > 0] + elif args.prompt is not None: + prompt_list = [args.prompt] + else: + prompt_list = [] + + if args.interactive: + args.n_iter = 1 + + # img2imgの前処理、画像の読み込みなど + def load_images(path): + if os.path.isfile(path): + paths = [path] + else: + paths = ( + glob.glob(os.path.join(path, "*.png")) + + glob.glob(os.path.join(path, "*.jpg")) + + glob.glob(os.path.join(path, "*.jpeg")) + + glob.glob(os.path.join(path, "*.webp")) + ) + paths.sort() + + images = [] + for p in paths: + image = Image.open(p) + if image.mode != "RGB": + print(f"convert image to RGB from {image.mode}: {p}") + image = image.convert("RGB") + images.append(image) + + return images + + def resize_images(imgs, size): + resized = [] + for img in imgs: + r_img = img.resize(size, Image.Resampling.LANCZOS) + if hasattr(img, "filename"): # filename属性がない場合があるらしい + r_img.filename = img.filename + resized.append(r_img) + return resized + + if args.image_path is not None: + print(f"load image for img2img: {args.image_path}") + init_images = load_images(args.image_path) + assert len(init_images) > 0, f"No image / 画像がありません: {args.image_path}" + print(f"loaded {len(init_images)} images for img2img") + else: + init_images = None + + if args.mask_path is not None: + print(f"load mask for inpainting: {args.mask_path}") + mask_images = load_images(args.mask_path) + assert len(mask_images) > 0, f"No mask image / マスク画像がありません: {args.image_path}" + print(f"loaded {len(mask_images)} mask images for inpainting") + else: + mask_images = None + + # promptがないとき、画像のPngInfoから取得する + if init_images is not None and len(prompt_list) == 0 and not args.interactive: + print("get prompts from images' meta data") + for img in init_images: + if "prompt" in img.text: + prompt = img.text["prompt"] + if "negative-prompt" in img.text: + prompt += " --n " + img.text["negative-prompt"] + prompt_list.append(prompt) + + # プロンプトと画像を一致させるため指定回数だけ繰り返す(画像を増幅する) + l = [] + for im in init_images: + l.extend([im] * args.images_per_prompt) + init_images = l + + if mask_images is not None: + l = [] + for im in mask_images: + l.extend([im] * args.images_per_prompt) + mask_images = l + + # 画像サイズにオプション指定があるときはリサイズする + if args.W is not None and args.H is not None: + # highres fix を考慮に入れる + w, h = args.W, args.H + if highres_fix: + w = int(w * args.highres_fix_scale + 0.5) + h = int(h * args.highres_fix_scale + 0.5) + + if init_images is not None: + print(f"resize img2img source images to {w}*{h}") + init_images = resize_images(init_images, (w, h)) + if mask_images is not None: + print(f"resize img2img mask images to {w}*{h}") + mask_images = resize_images(mask_images, (w, h)) + + regional_network = False + if networks and mask_images: + # mask を領域情報として流用する、現在は一回のコマンド呼び出しで1枚だけ対応 + regional_network = True + print("use mask as region") + + size = None + for i, network in enumerate(networks): + if i < 3: + np_mask = np.array(mask_images[0]) + np_mask = np_mask[:, :, i] + size = np_mask.shape + else: + np_mask = np.full(size, 255, dtype=np.uint8) + mask = torch.from_numpy(np_mask.astype(np.float32) / 255.0) + network.set_region(i, i == len(networks) - 1, mask) + mask_images = None + + prev_image = None # for VGG16 guided + if args.guide_image_path is not None: + print(f"load image for ControlNet guidance: {args.guide_image_path}") + guide_images = [] + for p in args.guide_image_path: + guide_images.extend(load_images(p)) + + print(f"loaded {len(guide_images)} guide images for guidance") + if len(guide_images) == 0: + print(f"No guide image, use previous generated image. / ガイド画像がありません。直前に生成した画像を使います: {args.image_path}") + guide_images = None + else: + guide_images = None + + # seed指定時はseedを決めておく + if args.seed is not None: + # dynamic promptを使うと足りなくなる→images_per_promptを適当に大きくしておいてもらう + random.seed(args.seed) + predefined_seeds = [random.randint(0, 0x7FFFFFFF) for _ in range(args.n_iter * len(prompt_list) * args.images_per_prompt)] + if len(predefined_seeds) == 1: + predefined_seeds[0] = args.seed + else: + predefined_seeds = None + + # デフォルト画像サイズを設定する:img2imgではこれらの値は無視される(またはW*Hにリサイズ済み) + if args.W is None: + args.W = 1024 + if args.H is None: + args.H = 1024 + + # 画像生成のループ + os.makedirs(args.outdir, exist_ok=True) + max_embeddings_multiples = 1 if args.max_embeddings_multiples is None else args.max_embeddings_multiples + + for gen_iter in range(args.n_iter): + print(f"iteration {gen_iter+1}/{args.n_iter}") + iter_seed = random.randint(0, 0x7FFFFFFF) + + # バッチ処理の関数 + def process_batch(batch: List[BatchData], highres_fix, highres_1st=False): + batch_size = len(batch) + + # highres_fixの処理 + if highres_fix and not highres_1st: + # 1st stageのバッチを作成して呼び出す:サイズを小さくして呼び出す + is_1st_latent = upscaler.support_latents() if upscaler else args.highres_fix_latents_upscaling + + print("process 1st stage") + batch_1st = [] + for _, base, ext in batch: + + def scale_and_round(x): + if x is None: + return None + return int(x * args.highres_fix_scale + 0.5) + + width_1st = scale_and_round(ext.width) + height_1st = scale_and_round(ext.height) + width_1st = width_1st - width_1st % 32 + height_1st = height_1st - height_1st % 32 + + original_width_1st = scale_and_round(ext.original_width) + original_height_1st = scale_and_round(ext.original_height) + crop_left_1st = scale_and_round(ext.crop_left) + crop_top_1st = scale_and_round(ext.crop_top) + + strength_1st = ext.strength if args.highres_fix_strength is None else args.highres_fix_strength + + ext_1st = BatchDataExt( + width_1st, + height_1st, + original_width_1st, + original_height_1st, + crop_left_1st, + crop_top_1st, + args.highres_fix_steps, + ext.scale, + ext.negative_scale, + strength_1st, + ext.network_muls, + ext.num_sub_prompts, + ) + batch_1st.append(BatchData(is_1st_latent, base, ext_1st)) + + pipe.set_enable_control_net(True) # 1st stageではControlNetを有効にする + images_1st = process_batch(batch_1st, True, True) + + # 2nd stageのバッチを作成して以下処理する + print("process 2nd stage") + width_2nd, height_2nd = batch[0].ext.width, batch[0].ext.height + + if upscaler: + # upscalerを使って画像を拡大する + lowreso_imgs = None if is_1st_latent else images_1st + lowreso_latents = None if not is_1st_latent else images_1st + + # 戻り値はPIL.Image.Imageかtorch.Tensorのlatents + batch_size = len(images_1st) + vae_batch_size = ( + batch_size + if args.vae_batch_size is None + else (max(1, int(batch_size * args.vae_batch_size)) if args.vae_batch_size < 1 else args.vae_batch_size) + ) + vae_batch_size = int(vae_batch_size) + images_1st = upscaler.upscale( + vae, lowreso_imgs, lowreso_latents, dtype, width_2nd, height_2nd, batch_size, vae_batch_size + ) + + elif args.highres_fix_latents_upscaling: + # latentを拡大する + org_dtype = images_1st.dtype + if images_1st.dtype == torch.bfloat16: + images_1st = images_1st.to(torch.float) # interpolateがbf16をサポートしていない + images_1st = torch.nn.functional.interpolate( + images_1st, (batch[0].ext.height // 8, batch[0].ext.width // 8), mode="bilinear" + ) # , antialias=True) + images_1st = images_1st.to(org_dtype) + + else: + # 画像をLANCZOSで拡大する + images_1st = [image.resize((width_2nd, height_2nd), resample=PIL.Image.LANCZOS) for image in images_1st] + + batch_2nd = [] + for i, (bd, image) in enumerate(zip(batch, images_1st)): + bd_2nd = BatchData(False, BatchDataBase(*bd.base[0:3], bd.base.seed + 1, image, None, *bd.base[6:]), bd.ext) + batch_2nd.append(bd_2nd) + batch = batch_2nd + + if args.highres_fix_disable_control_net: + pipe.set_enable_control_net(False) # オプション指定時、2nd stageではControlNetを無効にする + + # このバッチの情報を取り出す + ( + return_latents, + (step_first, _, _, _, init_image, mask_image, _, guide_image), + ( + width, + height, + original_width, + original_height, + crop_left, + crop_top, + steps, + scale, + negative_scale, + strength, + network_muls, + num_sub_prompts, + ), + ) = batch[0] + noise_shape = (LATENT_CHANNELS, height // DOWNSAMPLING_FACTOR, width // DOWNSAMPLING_FACTOR) + + prompts = [] + negative_prompts = [] + start_code = torch.zeros((batch_size, *noise_shape), device=device, dtype=dtype) + noises = [ + torch.zeros((batch_size, *noise_shape), device=device, dtype=dtype) + for _ in range(steps * scheduler_num_noises_per_step) + ] + seeds = [] + clip_prompts = [] + + if init_image is not None: # img2img? + i2i_noises = torch.zeros((batch_size, *noise_shape), device=device, dtype=dtype) + init_images = [] + + if mask_image is not None: + mask_images = [] + else: + mask_images = None + else: + i2i_noises = None + init_images = None + mask_images = None + + if guide_image is not None: # CLIP image guided? + guide_images = [] + else: + guide_images = None + + # バッチ内の位置に関わらず同じ乱数を使うためにここで乱数を生成しておく。あわせてimage/maskがbatch内で同一かチェックする + all_images_are_same = True + all_masks_are_same = True + all_guide_images_are_same = True + for i, (_, (_, prompt, negative_prompt, seed, init_image, mask_image, clip_prompt, guide_image), _) in enumerate(batch): + prompts.append(prompt) + negative_prompts.append(negative_prompt) + seeds.append(seed) + clip_prompts.append(clip_prompt) + + if init_image is not None: + init_images.append(init_image) + if i > 0 and all_images_are_same: + all_images_are_same = init_images[-2] is init_image + + if mask_image is not None: + mask_images.append(mask_image) + if i > 0 and all_masks_are_same: + all_masks_are_same = mask_images[-2] is mask_image + + if guide_image is not None: + if type(guide_image) is list: + guide_images.extend(guide_image) + all_guide_images_are_same = False + else: + guide_images.append(guide_image) + if i > 0 and all_guide_images_are_same: + all_guide_images_are_same = guide_images[-2] is guide_image + + # make start code + torch.manual_seed(seed) + start_code[i] = torch.randn(noise_shape, device=device, dtype=dtype) + + # make each noises + for j in range(steps * scheduler_num_noises_per_step): + noises[j][i] = torch.randn(noise_shape, device=device, dtype=dtype) + + if i2i_noises is not None: # img2img noise + i2i_noises[i] = torch.randn(noise_shape, device=device, dtype=dtype) + + noise_manager.reset_sampler_noises(noises) + + # すべての画像が同じなら1枚だけpipeに渡すことでpipe側で処理を高速化する + if init_images is not None and all_images_are_same: + init_images = init_images[0] + if mask_images is not None and all_masks_are_same: + mask_images = mask_images[0] + if guide_images is not None and all_guide_images_are_same: + guide_images = guide_images[0] + + # ControlNet使用時はguide imageをリサイズする + if control_nets: + # TODO resampleのメソッド + guide_images = guide_images if type(guide_images) == list else [guide_images] + guide_images = [i.resize((width, height), resample=PIL.Image.LANCZOS) for i in guide_images] + if len(guide_images) == 1: + guide_images = guide_images[0] + + # generate + if networks: + # 追加ネットワークの処理 + shared = {} + for n, m in zip(networks, network_muls if network_muls else network_default_muls): + n.set_multiplier(m) + if regional_network: + n.set_current_generation(batch_size, num_sub_prompts, width, height, shared) + + if not regional_network and network_pre_calc: + for n in networks: + n.restore_weights() + for n in networks: + n.pre_calculation() + print("pre-calculation... done") + + images = pipe( + prompts, + negative_prompts, + init_images, + mask_images, + height, + width, + original_height, + original_width, + crop_top, + crop_left, + steps, + scale, + negative_scale, + strength, + latents=start_code, + output_type="pil", + max_embeddings_multiples=max_embeddings_multiples, + img2img_noise=i2i_noises, + vae_batch_size=args.vae_batch_size, + return_latents=return_latents, + clip_prompts=clip_prompts, + clip_guide_images=guide_images, + ) + if highres_1st and not args.highres_fix_save_1st: # return images or latents + return images + + # save image + highres_prefix = ("0" if highres_1st else "1") if highres_fix else "" + ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) + for i, (image, prompt, negative_prompts, seed, clip_prompt) in enumerate( + zip(images, prompts, negative_prompts, seeds, clip_prompts) + ): + metadata = PngInfo() + metadata.add_text("prompt", prompt) + metadata.add_text("seed", str(seed)) + metadata.add_text("sampler", args.sampler) + metadata.add_text("steps", str(steps)) + metadata.add_text("scale", str(scale)) + if negative_prompt is not None: + metadata.add_text("negative-prompt", negative_prompt) + if negative_scale is not None: + metadata.add_text("negative-scale", str(negative_scale)) + if clip_prompt is not None: + metadata.add_text("clip-prompt", clip_prompt) + metadata.add_text("original-height", str(original_height)) + metadata.add_text("original-width", str(original_width)) + metadata.add_text("crop-top", str(crop_top)) + metadata.add_text("crop-left", str(crop_left)) + + if args.use_original_file_name and init_images is not None: + if type(init_images) is list: + fln = os.path.splitext(os.path.basename(init_images[i % len(init_images)].filename))[0] + ".png" + else: + fln = os.path.splitext(os.path.basename(init_images.filename))[0] + ".png" + elif args.sequential_file_name: + fln = f"im_{highres_prefix}{step_first + i + 1:06d}.png" + else: + fln = f"im_{ts_str}_{highres_prefix}{i:03d}_{seed}.png" + + image.save(os.path.join(args.outdir, fln), pnginfo=metadata) + + if not args.no_preview and not highres_1st and args.interactive: + try: + import cv2 + + for prompt, image in zip(prompts, images): + cv2.imshow(prompt[:128], np.array(image)[:, :, ::-1]) # プロンプトが長いと死ぬ + cv2.waitKey() + cv2.destroyAllWindows() + except ImportError: + print("opencv-python is not installed, cannot preview / opencv-pythonがインストールされていないためプレビューできません") + + return images + + # 画像生成のプロンプトが一周するまでのループ + prompt_index = 0 + global_step = 0 + batch_data = [] + while args.interactive or prompt_index < len(prompt_list): + if len(prompt_list) == 0: + # interactive + valid = False + while not valid: + print("\nType prompt:") + try: + raw_prompt = input() + except EOFError: + break + + valid = len(raw_prompt.strip().split(" --")[0].strip()) > 0 + if not valid: # EOF, end app + break + else: + raw_prompt = prompt_list[prompt_index] + + # sd-dynamic-prompts like variants: + # count is 1 (not dynamic) or images_per_prompt (no enumeration) or arbitrary (enumeration) + raw_prompts = handle_dynamic_prompt_variants(raw_prompt, args.images_per_prompt) + + # repeat prompt + for pi in range(args.images_per_prompt if len(raw_prompts) == 1 else len(raw_prompts)): + raw_prompt = raw_prompts[pi] if len(raw_prompts) > 1 else raw_prompts[0] + + if pi == 0 or len(raw_prompts) > 1: + # parse prompt: if prompt is not changed, skip parsing + width = args.W + height = args.H + original_width = args.original_width + original_height = args.original_height + crop_top = args.crop_top + crop_left = args.crop_left + scale = args.scale + negative_scale = args.negative_scale + steps = args.steps + seed = None + seeds = None + strength = 0.8 if args.strength is None else args.strength + negative_prompt = "" + clip_prompt = None + network_muls = None + + prompt_args = raw_prompt.strip().split(" --") + prompt = prompt_args[0] + print(f"prompt {prompt_index+1}/{len(prompt_list)}: {prompt}") + + for parg in prompt_args[1:]: + try: + m = re.match(r"w (\d+)", parg, re.IGNORECASE) + if m: + width = int(m.group(1)) + print(f"width: {width}") + continue + + m = re.match(r"h (\d+)", parg, re.IGNORECASE) + if m: + height = int(m.group(1)) + print(f"height: {height}") + continue + + m = re.match(r"ow (\d+)", parg, re.IGNORECASE) + if m: + original_width = int(m.group(1)) + print(f"original width: {width}") + continue + + m = re.match(r"oh (\d+)", parg, re.IGNORECASE) + if m: + original_height = int(m.group(1)) + print(f"original height: {height}") + continue + + m = re.match(r"ct (\d+)", parg, re.IGNORECASE) + if m: + crop_top = int(m.group(1)) + print(f"crop top: {crop_top}") + continue + + m = re.match(r"cl (\d+)", parg, re.IGNORECASE) + if m: + crop_left = int(m.group(1)) + print(f"crop left: {crop_left}") + continue + + m = re.match(r"s (\d+)", parg, re.IGNORECASE) + if m: # steps + steps = max(1, min(1000, int(m.group(1)))) + print(f"steps: {steps}") + continue + + m = re.match(r"d ([\d,]+)", parg, re.IGNORECASE) + if m: # seed + seeds = [int(d) for d in m.group(1).split(",")] + print(f"seeds: {seeds}") + continue + + m = re.match(r"l ([\d\.]+)", parg, re.IGNORECASE) + if m: # scale + scale = float(m.group(1)) + print(f"scale: {scale}") + continue + + m = re.match(r"nl ([\d\.]+|none|None)", parg, re.IGNORECASE) + if m: # negative scale + if m.group(1).lower() == "none": + negative_scale = None + else: + negative_scale = float(m.group(1)) + print(f"negative scale: {negative_scale}") + continue + + m = re.match(r"t ([\d\.]+)", parg, re.IGNORECASE) + if m: # strength + strength = float(m.group(1)) + print(f"strength: {strength}") + continue + + m = re.match(r"n (.+)", parg, re.IGNORECASE) + if m: # negative prompt + negative_prompt = m.group(1) + print(f"negative prompt: {negative_prompt}") + continue + + m = re.match(r"c (.+)", parg, re.IGNORECASE) + if m: # clip prompt + clip_prompt = m.group(1) + print(f"clip prompt: {clip_prompt}") + continue + + m = re.match(r"am ([\d\.\-,]+)", parg, re.IGNORECASE) + if m: # network multiplies + network_muls = [float(v) for v in m.group(1).split(",")] + while len(network_muls) < len(networks): + network_muls.append(network_muls[-1]) + print(f"network mul: {network_muls}") + continue + + except ValueError as ex: + print(f"Exception in parsing / 解析エラー: {parg}") + print(ex) + + # prepare seed + if seeds is not None: # given in prompt + # 数が足りないなら前のをそのまま使う + if len(seeds) > 0: + seed = seeds.pop(0) + else: + if predefined_seeds is not None: + if len(predefined_seeds) > 0: + seed = predefined_seeds.pop(0) + else: + print("predefined seeds are exhausted") + seed = None + elif args.iter_same_seed: + seeds = iter_seed + else: + seed = None # 前のを消す + + if seed is None: + seed = random.randint(0, 0x7FFFFFFF) + if args.interactive: + print(f"seed: {seed}") + + # prepare init image, guide image and mask + init_image = mask_image = guide_image = None + + # 同一イメージを使うとき、本当はlatentに変換しておくと無駄がないが面倒なのでとりあえず毎回処理する + if init_images is not None: + init_image = init_images[global_step % len(init_images)] + + # img2imgの場合は、基本的に元画像のサイズで生成する。highres fixの場合はargs.W, args.Hとscaleに従いリサイズ済みなので無視する + # 32単位に丸めたやつにresizeされるので踏襲する + if not highres_fix: + width, height = init_image.size + width = width - width % 32 + height = height - height % 32 + if width != init_image.size[0] or height != init_image.size[1]: + print( + f"img2img image size is not divisible by 32 so aspect ratio is changed / img2imgの画像サイズが32で割り切れないためリサイズされます。画像が歪みます" + ) + + if mask_images is not None: + mask_image = mask_images[global_step % len(mask_images)] + + if guide_images is not None: + if control_nets: # 複数件の場合あり + c = len(control_nets) + p = global_step % (len(guide_images) // c) + guide_image = guide_images[p * c : p * c + c] + else: + guide_image = guide_images[global_step % len(guide_images)] + + if regional_network: + num_sub_prompts = len(prompt.split(" AND ")) + assert ( + len(networks) <= num_sub_prompts + ), "Number of networks must be less than or equal to number of sub prompts." + else: + num_sub_prompts = None + + b1 = BatchData( + False, + BatchDataBase(global_step, prompt, negative_prompt, seed, init_image, mask_image, clip_prompt, guide_image), + BatchDataExt( + width, + height, + original_width, + original_height, + crop_left, + crop_top, + steps, + scale, + negative_scale, + strength, + tuple(network_muls) if network_muls else None, + num_sub_prompts, + ), + ) + if len(batch_data) > 0 and batch_data[-1].ext != b1.ext: # バッチ分割必要? + process_batch(batch_data, highres_fix) + batch_data.clear() + + batch_data.append(b1) + if len(batch_data) == args.batch_size: + prev_image = process_batch(batch_data, highres_fix)[0] + batch_data.clear() + + global_step += 1 + + prompt_index += 1 + + if len(batch_data) > 0: + process_batch(batch_data, highres_fix) + batch_data.clear() + + print("done!") + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + + parser.add_argument("--prompt", type=str, default=None, help="prompt / プロンプト") + parser.add_argument( + "--from_file", type=str, default=None, help="if specified, load prompts from this file / 指定時はプロンプトをファイルから読み込む" + ) + parser.add_argument( + "--interactive", action="store_true", help="interactive mode (generates one image) / 対話モード(生成される画像は1枚になります)" + ) + parser.add_argument( + "--no_preview", action="store_true", help="do not show generated image in interactive mode / 対話モードで画像を表示しない" + ) + parser.add_argument( + "--image_path", type=str, default=None, help="image to inpaint or to generate from / img2imgまたはinpaintを行う元画像" + ) + parser.add_argument("--mask_path", type=str, default=None, help="mask in inpainting / inpaint時のマスク") + parser.add_argument("--strength", type=float, default=None, help="img2img strength / img2img時のstrength") + parser.add_argument("--images_per_prompt", type=int, default=1, help="number of images per prompt / プロンプトあたりの出力枚数") + parser.add_argument("--outdir", type=str, default="outputs", help="dir to write results to / 生成画像の出力先") + parser.add_argument("--sequential_file_name", action="store_true", help="sequential output file name / 生成画像のファイル名を連番にする") + parser.add_argument( + "--use_original_file_name", + action="store_true", + help="prepend original file name in img2img / img2imgで元画像のファイル名を生成画像のファイル名の先頭に付ける", + ) + # parser.add_argument("--ddim_eta", type=float, default=0.0, help="ddim eta (eta=0.0 corresponds to deterministic sampling", ) + parser.add_argument("--n_iter", type=int, default=1, help="sample this often / 繰り返し回数") + parser.add_argument("--H", type=int, default=None, help="image height, in pixel space / 生成画像高さ") + parser.add_argument("--W", type=int, default=None, help="image width, in pixel space / 生成画像幅") + parser.add_argument( + "--original_height", type=int, default=None, help="original height for SDXL conditioning / SDXLの条件付けに用いるoriginal heightの値" + ) + parser.add_argument( + "--original_width", type=int, default=None, help="original width for SDXL conditioning / SDXLの条件付けに用いるoriginal widthの値" + ) + parser.add_argument("--crop_top", type=int, default=None, help="crop top for SDXL conditioning / SDXLの条件付けに用いるcrop topの値") + parser.add_argument("--crop_left", type=int, default=None, help="crop left for SDXL conditioning / SDXLの条件付けに用いるcrop leftの値") + parser.add_argument("--batch_size", type=int, default=1, help="batch size / バッチサイズ") + parser.add_argument( + "--vae_batch_size", + type=float, + default=None, + help="batch size for VAE, < 1.0 for ratio / VAE処理時のバッチサイズ、1未満の値の場合は通常バッチサイズの比率", + ) + parser.add_argument( + "--vae_slices", + type=int, + default=None, + help="number of slices to split image into for VAE to reduce VRAM usage, None for no splitting (default), slower if specified. 16 or 32 recommended / VAE処理時にVRAM使用量削減のため画像を分割するスライス数、Noneの場合は分割しない(デフォルト)、指定すると遅くなる。16か32程度を推奨", + ) + parser.add_argument("--no_half_vae", action="store_true", help="do not use fp16/bf16 precision for VAE / VAE処理時にfp16/bf16を使わない") + parser.add_argument("--steps", type=int, default=50, help="number of ddim sampling steps / サンプリングステップ数") + parser.add_argument( + "--sampler", + type=str, + default="ddim", + choices=[ + "ddim", + "pndm", + "lms", + "euler", + "euler_a", + "heun", + "dpm_2", + "dpm_2_a", + "dpmsolver", + "dpmsolver++", + "dpmsingle", + "k_lms", + "k_euler", + "k_euler_a", + "k_dpm_2", + "k_dpm_2_a", + ], + help=f"sampler (scheduler) type / サンプラー(スケジューラ)の種類", + ) + parser.add_argument( + "--scale", + type=float, + default=7.5, + help="unconditional guidance scale: eps = eps(x, empty) + scale * (eps(x, cond) - eps(x, empty)) / guidance scale", + ) + parser.add_argument("--ckpt", type=str, default=None, help="path to checkpoint of model / モデルのcheckpointファイルまたはディレクトリ") + parser.add_argument( + "--vae", type=str, default=None, help="path to checkpoint of vae to replace / VAEを入れ替える場合、VAEのcheckpointファイルまたはディレクトリ" + ) + parser.add_argument( + "--tokenizer_cache_dir", + type=str, + default=None, + help="directory for caching Tokenizer (for offline training) / Tokenizerをキャッシュするディレクトリ(ネット接続なしでの学習のため)", + ) + # parser.add_argument("--replace_clip_l14_336", action='store_true', + # help="Replace CLIP (Text Encoder) to l/14@336 / CLIP(Text Encoder)をl/14@336に入れ替える") + parser.add_argument( + "--seed", + type=int, + default=None, + help="seed, or seed of seeds in multiple generation / 1枚生成時のseed、または複数枚生成時の乱数seedを決めるためのseed", + ) + parser.add_argument( + "--iter_same_seed", + action="store_true", + help="use same seed for all prompts in iteration if no seed specified / 乱数seedの指定がないとき繰り返し内はすべて同じseedを使う(プロンプト間の差異の比較用)", + ) + parser.add_argument("--fp16", action="store_true", help="use fp16 / fp16を指定し省メモリ化する") + parser.add_argument("--bf16", action="store_true", help="use bfloat16 / bfloat16を指定し省メモリ化する") + parser.add_argument("--xformers", action="store_true", help="use xformers / xformersを使用し高速化する") + parser.add_argument("--sdpa", action="store_true", help="use sdpa in PyTorch 2 / sdpa") + parser.add_argument( + "--diffusers_xformers", + action="store_true", + help="use xformers by diffusers (Hypernetworks doesn't work) / Diffusersでxformersを使用する(Hypernetwork利用不可)", + ) + parser.add_argument( + "--opt_channels_last", action="store_true", help="set channels last option to model / モデルにchannels lastを指定し最適化する" + ) + parser.add_argument( + "--network_module", type=str, default=None, nargs="*", help="additional network module to use / 追加ネットワークを使う時そのモジュール名" + ) + parser.add_argument( + "--network_weights", type=str, default=None, nargs="*", help="additional network weights to load / 追加ネットワークの重み" + ) + parser.add_argument("--network_mul", type=float, default=None, nargs="*", help="additional network multiplier / 追加ネットワークの効果の倍率") + parser.add_argument( + "--network_args", type=str, default=None, nargs="*", help="additional argmuments for network (key=value) / ネットワークへの追加の引数" + ) + parser.add_argument("--network_show_meta", action="store_true", help="show metadata of network model / ネットワークモデルのメタデータを表示する") + parser.add_argument("--network_merge", action="store_true", help="merge network weights to original model / ネットワークの重みをマージする") + parser.add_argument( + "--network_pre_calc", action="store_true", help="pre-calculate network for generation / ネットワークのあらかじめ計算して生成する" + ) + parser.add_argument( + "--textual_inversion_embeddings", + type=str, + default=None, + nargs="*", + help="Embeddings files of Textual Inversion / Textual Inversionのembeddings", + ) + parser.add_argument("--clip_skip", type=int, default=None, help="layer number from bottom to use in CLIP / CLIPの後ろからn層目の出力を使う") + parser.add_argument( + "--max_embeddings_multiples", + type=int, + default=None, + help="max embeding multiples, max token length is 75 * multiples / トークン長をデフォルトの何倍とするか 75*この値 がトークン長となる", + ) + parser.add_argument( + "--guide_image_path", type=str, default=None, nargs="*", help="image to CLIP guidance / CLIP guided SDでガイドに使う画像" + ) + parser.add_argument( + "--highres_fix_scale", + type=float, + default=None, + help="enable highres fix, reso scale for 1st stage / highres fixを有効にして最初の解像度をこのscaleにする", + ) + parser.add_argument( + "--highres_fix_steps", type=int, default=28, help="1st stage steps for highres fix / highres fixの最初のステージのステップ数" + ) + parser.add_argument( + "--highres_fix_strength", + type=float, + default=None, + help="1st stage img2img strength for highres fix / highres fixの最初のステージのimg2img時のstrength、省略時はstrengthと同じ", + ) + parser.add_argument( + "--highres_fix_save_1st", action="store_true", help="save 1st stage images for highres fix / highres fixの最初のステージの画像を保存する" + ) + parser.add_argument( + "--highres_fix_latents_upscaling", + action="store_true", + help="use latents upscaling for highres fix / highres fixでlatentで拡大する", + ) + parser.add_argument( + "--highres_fix_upscaler", type=str, default=None, help="upscaler module for highres fix / highres fixで使うupscalerのモジュール名" + ) + parser.add_argument( + "--highres_fix_upscaler_args", + type=str, + default=None, + help="additional argmuments for upscaler (key=value) / upscalerへの追加の引数", + ) + parser.add_argument( + "--highres_fix_disable_control_net", + action="store_true", + help="disable ControlNet for highres fix / highres fixでControlNetを使わない", + ) + + parser.add_argument( + "--negative_scale", type=float, default=None, help="set another guidance scale for negative prompt / ネガティブプロンプトのscaleを指定する" + ) + + parser.add_argument( + "--control_net_models", type=str, default=None, nargs="*", help="ControlNet models to use / 使用するControlNetのモデル名" + ) + parser.add_argument( + "--control_net_preps", type=str, default=None, nargs="*", help="ControlNet preprocess to use / 使用するControlNetのプリプロセス名" + ) + parser.add_argument("--control_net_weights", type=float, default=None, nargs="*", help="ControlNet weights / ControlNetの重み") + parser.add_argument( + "--control_net_ratios", + type=float, + default=None, + nargs="*", + help="ControlNet guidance ratio for steps / ControlNetでガイドするステップ比率", + ) + # parser.add_argument( + # "--control_net_image_path", type=str, default=None, nargs="*", help="image for ControlNet guidance / ControlNetでガイドに使う画像" + # ) + + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + main(args) From 8371a7a3aadb12dd1f6ea8edb3d9caa6066154f9 Mon Sep 17 00:00:00 2001 From: ykume Date: Sun, 9 Jul 2023 13:38:48 +0900 Subject: [PATCH 062/220] update readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 234301705..503427a5a 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Summary of the feature: - The image generation during training is now available. However, the VAE for SDXL seems to produce NaNs in some cases when using `fp16`. The images will be black. Currently, the NaNs cannot be avoided even with `--no_half_vae` option. It works with `bf16` or without mixed precision. - `--weighted_captions` option is not supported yet. - `--min_timestep` and `--max_timestep` options are added to each training script. These options can be used to train U-Net with different timesteps. The default values are 0 and 1000. +- `sdxl_gen_img.py` is added. This script can be used to generate images with SDXL, including LoRA. See the help message for the usage. `requirements.txt` is updated to support SDXL training. @@ -47,6 +48,7 @@ Summary of the feature: - The LoRA training can be done with 12GB GPU memory. - `--network_train_unet_only` option is highly recommended for SDXL LoRA. Because SDXL has two text encoders, the result of the training will be unexpected. - PyTorch 2 seems to use slightly less GPU memory than PyTorch 1. +- `--bucket_reso_steps` can be set to 32 instead of the default value 64. Smaller values than 32 will not work for SDXL training. Example of the optimizer settings for Adafactor with the fixed learning rate: ``` @@ -57,6 +59,12 @@ lr_warmup_steps = 100 learning_rate = 4e-7 # SDXL original learning rate ``` +### TODO + +- [ ] Support Textual Inversion training. +- [ ] Support `--weighted_captions` option. +- [ ] Change `--output_config` option to continue the training. + ## About requirements.txt These files do not contain requirements for PyTorch. Because the versions of them depend on your environment. Please install PyTorch at first (see installation guide below.) From 5f348579d115e289422732b92fad3d5228deeb35 Mon Sep 17 00:00:00 2001 From: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Date: Sun, 9 Jul 2023 12:46:35 +0800 Subject: [PATCH 063/220] Update sdxl_train.py --- sdxl_train.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdxl_train.py b/sdxl_train.py index 9cf20252d..06cbc5710 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -267,6 +267,14 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): unet.to(weight_dtype) text_encoder1.to(weight_dtype) text_encoder2.to(weight_dtype) + elif args.full_bf16: + assert ( + args.mixed_precision == "bf16" + ), "full_bf16 requires mixed precision='bf16' / full_bf16を使う場合はmixed_precision='bf16'を指定してください。" + accelerator.print("enable full bf16 training.") + unet.to(weight_dtype) + text_encoder1.to(weight_dtype) + text_encoder2.to(weight_dtype) # acceleratorがなんかよろしくやってくれるらしい if args.train_text_encoder: From d974959738d89b6d62e7dc60c6e10ee0d8f8ff4c Mon Sep 17 00:00:00 2001 From: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Date: Sun, 9 Jul 2023 12:47:26 +0800 Subject: [PATCH 064/220] Update train_util.py for full_bf16 support --- library/train_util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/library/train_util.py b/library/train_util.py index 62cd145e1..b9b4eecf8 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2416,6 +2416,7 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: "--mixed_precision", type=str, default="no", choices=["no", "fp16", "bf16"], help="use mixed precision / 混合精度を使う場合、その精度" ) parser.add_argument("--full_fp16", action="store_true", help="fp16 training including gradients / 勾配も含めてfp16で学習する") + parser.add_argument("--full_bf16", action="store_true", help="bf16 training including gradients / 勾配も含めてbf16で学習する") parser.add_argument( "--clip_skip", type=int, From 0416f26a76c39911afe7aae09f2e628e02922a1c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 9 Jul 2023 16:02:56 +0900 Subject: [PATCH 065/220] support multi gpu in caching text encoder outputs --- README.md | 6 +++++- library/sdxl_train_util.py | 8 ++++---- sdxl_train.py | 26 ++++++++++++++++---------- sdxl_train_network.py | 4 ++-- train_network.py | 10 +++++----- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 503427a5a..8a47ee3b5 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,10 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - - `prepare_buckets_latents.py` now supports SDXL fine-tuning. + - `--full_bf16` option is added. This option enables the full bfloat16 training. This option is useful to reduce the GPU memory usage. + - However, bitsandbytes==0.35 doesn't seem to support this. Please use a newer version of bitsandbytes or another optimizer. + - I cannot find bitsandbytes>0.35.0 that works correctly on Windows. +- `prepare_buckets_latents.py` now supports SDXL fine-tuning. - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. @@ -64,6 +67,7 @@ learning_rate = 4e-7 # SDXL original learning rate - [ ] Support Textual Inversion training. - [ ] Support `--weighted_captions` option. - [ ] Change `--output_config` option to continue the training. +- [ ] Extend `--full_bf16` for all the scripts. ## About requirements.txt diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index c67a70431..675aac3da 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -319,7 +319,7 @@ def diffusers_saver(out_dir): # TextEncoderの出力をキャッシュする # weight_dtypeを指定するとText Encoderそのもの、およひ出力がweight_dtypeになる -def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, data_loader, weight_dtype): +def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, dataset, weight_dtype): print("caching text encoder outputs") tokenizer1, tokenizer2 = tokenizers @@ -332,9 +332,9 @@ def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, dat text_encoder1_cache = {} text_encoder2_cache = {} - for batch in tqdm(data_loader): - input_ids1_batch = batch["input_ids"] - input_ids2_batch = batch["input_ids2"] + for batch in tqdm(dataset): + input_ids1_batch = batch["input_ids"].to(accelerator.device) + input_ids2_batch = batch["input_ids2"].to(accelerator.device) # split batch to avoid OOM # TODO specify batch size by args diff --git a/sdxl_train.py b/sdxl_train.py index 06cbc5710..dd5b74dda 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -204,12 +204,25 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): text_encoder2.gradient_checkpointing_enable() training_models.append(text_encoder1) training_models.append(text_encoder2) + + text_encoder1_cache = None + text_encoder2_cache = None + + # set require_grad=True later else: text_encoder1.requires_grad_(False) text_encoder2.requires_grad_(False) text_encoder1.eval() text_encoder2.eval() + # TextEncoderの出力をキャッシュする + if args.cache_text_encoder_outputs: + # Text Encodes are eval and no grad + text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( + args, accelerator, (tokenizer1, tokenizer2), (text_encoder1, text_encoder2), train_dataset_group, None + ) + accelerator.wait_for_everyone() + if not cache_latents: vae.requires_grad_(False) vae.eval() @@ -289,23 +302,16 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): (unet,) = train_util.transform_models_if_DDP([unet]) text_encoder1.to(weight_dtype) text_encoder2.to(weight_dtype) - text_encoder1.eval() - text_encoder2.eval() - # TextEncoderの出力をキャッシュする + # TextEncoderの出力をキャッシュするときにはCPUへ移動する if args.cache_text_encoder_outputs: - text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( - args, accelerator, (tokenizer1, tokenizer2), (text_encoder1, text_encoder2), train_dataloader, None - ) - accelerator.wait_for_everyone() - # Text Encoder doesn't work on CPU with fp16 + # move Text Encoders for sampling images. Text Encoder doesn't work on CPU with fp16 text_encoder1.to("cpu", dtype=torch.float32) text_encoder2.to("cpu", dtype=torch.float32) if torch.cuda.is_available(): torch.cuda.empty_cache() else: - text_encoder1_cache = None - text_encoder2_cache = None + # make sure Text Encoders are on GPU text_encoder1.to(accelerator.device) text_encoder2.to(accelerator.device) diff --git a/sdxl_train_network.py b/sdxl_train_network.py index ec15ce4bd..0c3c0cc5b 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -47,7 +47,7 @@ def is_text_encoder_outputs_cached(self, args): return args.cache_text_encoder_outputs def cache_text_encoder_outputs_if_needed( - self, args, accelerator, unet, vae, tokenizers, text_encoders, data_loader, weight_dtype + self, args, accelerator, unet, vae, tokenizers, text_encoders, dataset, weight_dtype ): if args.cache_text_encoder_outputs: if not args.lowram: @@ -61,7 +61,7 @@ def cache_text_encoder_outputs_if_needed( torch.cuda.empty_cache() text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( - args, accelerator, tokenizers, text_encoders, data_loader, weight_dtype + args, accelerator, tokenizers, text_encoders, dataset, weight_dtype ) accelerator.wait_for_everyone() text_encoders[0].to("cpu", dtype=torch.float32) # Text Encoder doesn't work with fp16 on CPU diff --git a/train_network.py b/train_network.py index 3c9515b55..f7ee451b1 100644 --- a/train_network.py +++ b/train_network.py @@ -255,6 +255,11 @@ def train(self, args): accelerator.wait_for_everyone() + # 必要ならテキストエンコーダーの出力をキャッシュする: Text Encoderはcpuまたはgpuへ移される + self.cache_text_encoder_outputs_if_needed( + args, accelerator, unet, vae, tokenizers, text_encoders, train_dataset_group, weight_dtype + ) + # prepare network net_kwargs = {} if args.network_args is not None: @@ -419,11 +424,6 @@ def train(self, args): vae.eval() vae.to(accelerator.device, dtype=vae_dtype) - # 必要ならテキストエンコーダーの出力をキャッシュする: Text Encoderはcpuまたはgpuへ移される - self.cache_text_encoder_outputs_if_needed( - args, accelerator, unet, vae, tokenizers, text_encoders, train_dataloader, weight_dtype - ) - # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする if args.full_fp16: train_util.patch_accelerator_for_fp16_training(accelerator) From a380502c01a9d99281f9ea0d7486ac2b03c7147c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 9 Jul 2023 18:13:49 +0900 Subject: [PATCH 066/220] fix pad token is not handled --- library/sdxl_lpw_stable_diffusion.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index e806bc61e..10038e6a7 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -185,14 +185,14 @@ def get_prompts_with_weights(pipe: StableDiffusionPipeline, prompt: List[str], m return tokens, weights -def pad_tokens_and_weights(tokens, weights, max_length, bos, eos, no_boseos_middle=True, chunk_length=77): +def pad_tokens_and_weights(tokens, weights, max_length, bos, eos, pad, no_boseos_middle=True, chunk_length=77): r""" Pad the tokens (with starting and ending tokens) and weights (with 1.0) to max_length. """ max_embeddings_multiples = (max_length - 2) // (chunk_length - 2) weights_length = max_length if no_boseos_middle else max_embeddings_multiples * chunk_length for i in range(len(tokens)): - tokens[i] = [bos] + tokens[i] + [eos] * (max_length - 1 - len(tokens[i])) + tokens[i] = [bos] + tokens[i] + [eos] + [pad] * (max_length - 2 - len(tokens[i])) if no_boseos_middle: weights[i] = [1.0] + weights[i] + [1.0] * (max_length - 1 - len(weights[i])) else: @@ -363,6 +363,7 @@ def get_weighted_text_embeddings( max_length, bos, eos, + pad, no_boseos_middle=no_boseos_middle, chunk_length=pipe.tokenizer.model_max_length, ) @@ -374,6 +375,7 @@ def get_weighted_text_embeddings( max_length, bos, eos, + pad, no_boseos_middle=no_boseos_middle, chunk_length=pipe.tokenizer.model_max_length, ) @@ -711,7 +713,7 @@ def decode_latents(self, latents): # self.vae.set_use_memory_efficient_attention_xformers(False) # image = self.vae.decode(latents.to("cpu")).sample - image = self.vae.decode(latents).sample + image = self.vae.decode(latents.to(self.vae.dtype)).sample image = (image / 2 + 0.5).clamp(0, 1) # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16 image = image.cpu().permute(0, 2, 3, 1).float().numpy() From 77ec70d145deb30cba0a9d972d9aee762fbb7268 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 9 Jul 2023 19:00:38 +0900 Subject: [PATCH 067/220] fix conditioning --- library/sdxl_lpw_stable_diffusion.py | 36 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index 10038e6a7..7ab609d81 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -285,7 +285,7 @@ def get_unweighted_text_embeddings( def get_weighted_text_embeddings( - pipe: StableDiffusionPipeline, + pipe, # : SdxlStableDiffusionLongPromptWeightingPipeline, prompt: Union[str, List[str]], uncond_prompt: Optional[Union[str, List[str]]] = None, max_embeddings_multiples: Optional[int] = 3, @@ -657,11 +657,9 @@ def _encode_prompt( uncond_pool = uncond_pool.repeat(1, num_images_per_prompt) uncond_pool = uncond_pool.view(bs_embed * num_images_per_prompt, -1) - text_embeddings = torch.cat([uncond_embeddings, text_embeddings]) - if text_pool is not None: - text_pool = torch.cat([uncond_pool, text_pool]) + return text_embeddings, text_pool, uncond_embeddings, uncond_pool - return text_embeddings, text_pool + return text_embeddings, text_pool, None, None def check_inputs(self, prompt, height, width, strength, callback_steps): if not isinstance(prompt, str) and not isinstance(prompt, list): @@ -671,7 +669,6 @@ def check_inputs(self, prompt, height, width, strength, callback_steps): raise ValueError(f"The value of strength should in [0.0, 1.0] but is {strength}") if height % 8 != 0 or width % 8 != 0: - print(height, width) raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.") if (callback_steps is None) or ( @@ -901,12 +898,14 @@ def __call__( # 実装を簡単にするためにtokenzer/text encoderを切り替えて二回呼び出す # To simplify the implementation, switch the tokenzer/text encoder and call it twice text_embeddings_list = [] - text_pools = [] + text_pool = None + uncond_embeddings_list = [] + uncond_pool = None for i in range(len(self.tokenizers)): self.tokenizer = self.tokenizers[i] self.text_encoder = self.text_encoders[i] - text_embeddings, text_pool = self._encode_prompt( + text_embeddings, tp1, uncond_embeddings, up1 = self._encode_prompt( prompt, device, num_images_per_prompt, @@ -916,7 +915,12 @@ def __call__( is_sdxl_text_encoder2=i == 1, ) text_embeddings_list.append(text_embeddings) - text_pools.append(text_pool) + uncond_embeddings_list.append(uncond_embeddings) + + if tp1 is not None: + text_pool = tp1 + if up1 is not None: + uncond_pool = up1 dtype = text_embeddings_list[0].dtype @@ -965,11 +969,19 @@ def __call__( crop_size = torch.zeros_like(orig_size) target_size = orig_size embs = sdxl_train_util.get_size_embeddings(orig_size, crop_size, target_size, device).to(dtype) + + # make conditionings if do_classifier_free_guidance: - embs = torch.cat([embs] * 2) + text_embeddings = torch.cat(text_embeddings_list, dim=2) + uncond_embeddings = torch.cat(uncond_embeddings_list, dim=2) + text_embedding = torch.cat([text_embeddings, uncond_embeddings]).to(dtype) - vector_embedding = torch.cat([text_pools[1], embs], dim=1).to(dtype) - text_embedding = torch.cat(text_embeddings_list, dim=2).to(dtype) + cond_vector = torch.cat([text_pool, embs], dim=1) + uncond_vector = torch.cat([uncond_pool, embs], dim=1) + vector_embedding = torch.cat([cond_vector, uncond_vector]).to(dtype) + else: + text_embedding = torch.cat(text_embeddings_list, dim=2).to(dtype) + vector_embedding = torch.cat([text_pool, embs], dim=1).to(dtype) # 8. Denoising loop for i, t in enumerate(self.progress_bar(timesteps)): From c2ceb6de5fc861513582642edf87834a01ce84a2 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 9 Jul 2023 21:14:12 +0900 Subject: [PATCH 068/220] fix uncond/cond order --- library/sdxl_lpw_stable_diffusion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index 7ab609d81..d44b3cf8c 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -974,11 +974,11 @@ def __call__( if do_classifier_free_guidance: text_embeddings = torch.cat(text_embeddings_list, dim=2) uncond_embeddings = torch.cat(uncond_embeddings_list, dim=2) - text_embedding = torch.cat([text_embeddings, uncond_embeddings]).to(dtype) + text_embedding = torch.cat([uncond_embeddings, text_embeddings]).to(dtype) cond_vector = torch.cat([text_pool, embs], dim=1) uncond_vector = torch.cat([uncond_pool, embs], dim=1) - vector_embedding = torch.cat([cond_vector, uncond_vector]).to(dtype) + vector_embedding = torch.cat([uncond_vector, cond_vector]).to(dtype) else: text_embedding = torch.cat(text_embeddings_list, dim=2).to(dtype) vector_embedding = torch.cat([text_pool, embs], dim=1).to(dtype) From 5c80117fbdcbb3f6470a95c9602323f9e28dd5e2 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 9 Jul 2023 21:37:46 +0900 Subject: [PATCH 069/220] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a47ee3b5..bf1d61c6e 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ learning_rate = 4e-7 # SDXL original learning rate ### TODO - [ ] Support Textual Inversion training. +- [ ] Support conversion of Diffusers SDXL models. - [ ] Support `--weighted_captions` option. - [ ] Change `--output_config` option to continue the training. - [ ] Extend `--full_bf16` for all the scripts. From b6e328ea8f22b03355ebd86ebc5190e0477864f4 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 10 Jul 2023 08:46:15 +0900 Subject: [PATCH 070/220] don't hold latent on memory for finetuning dataset --- library/train_util.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index 746a7f9dd..809f0af03 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -91,6 +91,7 @@ try: import pillow_avif + IMAGE_EXTENSIONS.extend([".avif", ".AVIF"]) except: pass @@ -853,16 +854,11 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc # split by resolution batches = [] batch = [] - for info in image_infos: + print("checking cache validity...") + for info in tqdm(image_infos): subset = self.image_to_subset[info.image_key] - if info.latents_npz is not None: - info.latents, info.latents_original_size, info.latents_crop_left_top = self.load_latents_from_npz(info, False) - info.latents = torch.FloatTensor(info.latents) - - info.latents_flipped, _, _ = self.load_latents_from_npz(info, True) # might be None - if info.latents_flipped is not None: - info.latents_flipped = torch.FloatTensor(info.latents_flipped) + if info.latents_npz is not None: # fine tuning dataset continue # check disk cache exists and size of latents From f54b784d88246a7b3f60a46c3782f29cd892d0c7 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 10 Jul 2023 22:04:02 +0900 Subject: [PATCH 071/220] support textual inversion training --- README.md | 30 +- library/sdxl_train_util.py | 41 +- sdxl_gen_img.py | 33 +- sdxl_train_textual_inversion.py | 142 +++++ train_textual_inversion.py | 1031 +++++++++++++++++-------------- 5 files changed, 809 insertions(+), 468 deletions(-) create mode 100644 sdxl_train_textual_inversion.py diff --git a/README.md b/README.md index bf1d61c6e..4e4150b60 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,31 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - - `--full_bf16` option is added. This option enables the full bfloat16 training. This option is useful to reduce the GPU memory usage. + - `--full_bf16` option is added. Thanks to KohakuBlueleaf! + - This option enables the full bfloat16 training (includes gradients). This option is useful to reduce the GPU memory usage. - However, bitsandbytes==0.35 doesn't seem to support this. Please use a newer version of bitsandbytes or another optimizer. - I cannot find bitsandbytes>0.35.0 that works correctly on Windows. + - In addition, the full bfloat16 training might be unstable. Please use it at your own risk. - `prepare_buckets_latents.py` now supports SDXL fine-tuning. - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. - The image generation during training is now available. However, the VAE for SDXL seems to produce NaNs in some cases when using `fp16`. The images will be black. Currently, the NaNs cannot be avoided even with `--no_half_vae` option. It works with `bf16` or without mixed precision. -- `--weighted_captions` option is not supported yet. + +- `--weighted_captions` option is not supported yet for both scripts. - `--min_timestep` and `--max_timestep` options are added to each training script. These options can be used to train U-Net with different timesteps. The default values are 0 and 1000. + +- `sdxl_train_textual_inversion.py` is a script for Textual Inversion training for SDXL. The usage is almost the same as `train_textual_inversion.py`. + - `--cache_text_encoder_outputs` is not supported. + - `token_string` must be alphabet only currently, due to the limitation of the open-clip tokenizer. + - There are two options for captions: + 1. Training with captions. All captions must include the token string. The token string is replaced with multiple tokens. + 2. Use `--use_object_template` or `--use_style_template` option. The captions are generated from the template. The existing captions are ignored. + - See below for the format of the embeddings. + - `sdxl_gen_img.py` is added. This script can be used to generate images with SDXL, including LoRA. See the help message for the usage. + - Textual Inversion is supported, but the name for the embeds in the caption becomes alphabet only. For example, `neg_hand_v1.safetensors` can be activated with `neghandv`. `requirements.txt` is updated to support SDXL training. @@ -54,7 +67,7 @@ Summary of the feature: - `--bucket_reso_steps` can be set to 32 instead of the default value 64. Smaller values than 32 will not work for SDXL training. Example of the optimizer settings for Adafactor with the fixed learning rate: -``` +```toml optimizer_type = "adafactor" optimizer_args = [ "scale_parameter=False", "relative_step=False", "warmup_init=False" ] lr_scheduler = "constant_with_warmup" @@ -62,13 +75,22 @@ lr_warmup_steps = 100 learning_rate = 4e-7 # SDXL original learning rate ``` +### Format of Textual Inversion embeddings + +```python +from safetensors.torch import save_file + +state_dict = {"clip_g": embs_for_text_encoder_1280, "clip_l": embs_for_text_encoder_768} +save_file(state_dict, file) +``` + ### TODO -- [ ] Support Textual Inversion training. - [ ] Support conversion of Diffusers SDXL models. - [ ] Support `--weighted_captions` option. - [ ] Change `--output_config` option to continue the training. - [ ] Extend `--full_bf16` for all the scripts. +- [x] Support Textual Inversion training. ## About requirements.txt diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 675aac3da..0ce097158 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -78,12 +78,13 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp class WrapperTokenizer: # open clipのtokenizerをHuggingFaceのtokenizerと同じ形で使えるようにする + # make open clip tokenizer compatible with HuggingFace tokenizer def __init__(self): open_clip_tokenizer = open_clip.tokenizer._tokenizer self.model_max_length = 77 self.bos_token_id = open_clip_tokenizer.all_special_ids[0] self.eos_token_id = open_clip_tokenizer.all_special_ids[1] - self.pad_token_id = 0 # 結果から推定している + self.pad_token_id = 0 # 結果から推定している assumption from result def __call__(self, *args: Any, **kwds: Any) -> Any: return self.tokenize(*args, **kwds) @@ -107,6 +108,42 @@ def tokenize(self, text, padding=False, truncation=None, max_length=None, return input_ids = input_ids[: eos_index + 1] # include eos return SimpleNamespace(**{"input_ids": input_ids}) + # for Textual Inversion + # わりと面倒くさいな……これWeb UIとかでどうするんだろう / this is a bit annoying... how to do this in Web UI? + + def encode(self, text, add_special_tokens=False): + assert not add_special_tokens + input_ids = open_clip.tokenizer._tokenizer.encode(text) + return input_ids + + def add_tokens(self, new_tokens): + tokens_to_add = [] + for token in new_tokens: + token = token.lower() + if token + "" not in open_clip.tokenizer._tokenizer.encoder: + tokens_to_add.append(token) + + # open clipのtokenizerに直接追加する / add tokens to open clip tokenizer + for token in tokens_to_add: + open_clip.tokenizer._tokenizer.encoder[token + ""] = len(open_clip.tokenizer._tokenizer.encoder) + open_clip.tokenizer._tokenizer.decoder[len(open_clip.tokenizer._tokenizer.decoder)] = token + "" + open_clip.tokenizer._tokenizer.vocab_size += 1 + + # open clipのtokenizerのcacheに直接設定することで、bpeとかいうやつに含まれていなくてもtokenizeできるようにする + # めちゃくちゃ乱暴なので、open clipのtokenizerの仕様が変わったら動かなくなる + # set cache of open clip tokenizer directly to enable tokenization even if the token is not included in bpe + # this is very rough, so it will not work if the specification of open clip tokenizer changes + open_clip.tokenizer._tokenizer.cache[token] = token + "" + + return len(tokens_to_add) + + def convert_tokens_to_ids(self, tokens): + input_ids = [open_clip.tokenizer._tokenizer.encoder[token + ""] for token in tokens] + return input_ids + + def __len__(self): + return open_clip.tokenizer._tokenizer.vocab_size + def load_tokenizers(args: argparse.Namespace): print("prepare tokenizers") @@ -392,7 +429,7 @@ def verify_sdxl_training_args(args: argparse.Namespace): print(f"noise_offset is set to {args.noise_offset} / noise_offsetが{args.noise_offset}に設定されました") assert ( - not args.weighted_captions + not hasattr(args, "weighted_captions") or not args.weighted_captions ), "weighted_captions cannot be enabled in SDXL training currently / SDXL学習では今のところweighted_captionsを有効にすることはできません" diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py index 8f1c17d60..1e20595cc 100644 --- a/sdxl_gen_img.py +++ b/sdxl_gen_img.py @@ -320,7 +320,7 @@ def __init__( self.scheduler = scheduler self.safety_checker = None - # Textual Inversion # not tested yet + # Textual Inversion self.token_replacements_list = [] for _ in range(len(self.text_encoders)): self.token_replacements_list.append({}) @@ -341,6 +341,10 @@ def get_token_replacer(self, tokenizer): token_replacements = self.token_replacements_list[tokenizer_index] def replace_tokens(tokens): + # print("replace_tokens", tokens, "=>", token_replacements) + if isinstance(tokens, torch.Tensor): + tokens = tokens.tolist() + new_tokens = [] for token in tokens: if token in token_replacements: @@ -1594,19 +1598,26 @@ def __getattr__(self, item): if "string_to_param" in data: data = data["string_to_param"] - embeds1 = data["clip_l"] - embeds2 = data["clip_g"] + + embeds1 = data["clip_l"] # text encoder 1 + embeds2 = data["clip_g"] # text encoder 2 num_vectors_per_token = embeds1.size()[0] token_string = os.path.splitext(os.path.basename(embeds_file))[0] - token_strings = [token_string] + [f"{token_string}{i+1}" for i in range(num_vectors_per_token - 1)] + + # remove non-alphabet characters to avoid splitting by tokenizer + # TODO make random alphabet string + token_string = "".join([c for c in token_string if c.isalpha()]) + + token_strings = [token_string] + [f"{token_string}{chr(ord('a') + i)}" for i in range(num_vectors_per_token - 1)] # add new word to tokenizer, count is num_vectors_per_token num_added_tokens1 = tokenizer1.add_tokens(token_strings) - num_added_tokens2 = tokenizer2.add_tokens(token_strings) # not working now - assert ( - num_added_tokens1 == num_vectors_per_token and num_added_tokens2 == num_vectors_per_token - ), f"tokenizer has same word to token string (filename). please rename the file / 指定した名前(ファイル名)のトークンが既に存在します。ファイルをリネームしてください: {embeds_file}" + num_added_tokens2 = tokenizer2.add_tokens(token_strings) + assert num_added_tokens1 == num_vectors_per_token and num_added_tokens2 == num_vectors_per_token, ( + f"tokenizer has same word to token string (filename). characters except alphabet are removed: {embeds_file}" + + f" / 指定した名前(ファイル名)のトークンが既に存在します。アルファベット以外の文字は削除されます: {embeds_file}" + ) token_ids1 = tokenizer1.convert_tokens_to_ids(token_strings) token_ids2 = tokenizer2.convert_tokens_to_ids(token_strings) @@ -1617,11 +1628,11 @@ def __getattr__(self, item): assert ( min(token_ids2) == token_ids2[0] and token_ids2[-1] == token_ids2[0] + len(token_ids2) - 1 ), f"token ids2 is not ordered" - assert len(tokenizer1) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer1)}" - assert len(tokenizer2) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer2)}" + assert len(tokenizer1) - 1 == token_ids1[-1], f"token ids 1 is not end of tokenize: {len(tokenizer1)}" + assert len(tokenizer2) - 1 == token_ids2[-1], f"token ids 2 is not end of tokenize: {len(tokenizer2)}" if num_vectors_per_token > 1: - pipe.add_token_replacement(0, token_ids1[0], token_ids1) + pipe.add_token_replacement(0, token_ids1[0], token_ids1) # hoge -> hoge, hogea, hogeb, ... pipe.add_token_replacement(1, token_ids2[0], token_ids2) token_ids_embeds1.append((token_ids1, embeds1)) diff --git a/sdxl_train_textual_inversion.py b/sdxl_train_textual_inversion.py new file mode 100644 index 000000000..9df370927 --- /dev/null +++ b/sdxl_train_textual_inversion.py @@ -0,0 +1,142 @@ +import argparse +import os + +import regex +import torch +import open_clip +from library import sdxl_model_util, sdxl_train_util, train_util + +import train_textual_inversion + + +class SdxlTextualInversionTrainer(train_textual_inversion.TextualInversionTrainer): + def __init__(self): + super().__init__() + self.vae_scale_factor = sdxl_model_util.VAE_SCALE_FACTOR + + def assert_extra_args(self, args, train_dataset_group): + super().assert_extra_args(args, train_dataset_group) + sdxl_train_util.verify_sdxl_training_args(args) + + def load_target_model(self, args, weight_dtype, accelerator): + ( + load_stable_diffusion_format, + text_encoder1, + text_encoder2, + vae, + unet, + logit_scale, + ckpt_info, + ) = sdxl_train_util.load_target_model(args, accelerator, sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, weight_dtype) + + self.load_stable_diffusion_format = load_stable_diffusion_format + self.logit_scale = logit_scale + self.ckpt_info = ckpt_info + + return sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, [text_encoder1, text_encoder2], vae, unet + + def load_tokenizer(self, args): + tokenizer = sdxl_train_util.load_tokenizers(args) + return tokenizer + + def assert_token_string(self, token_string, tokenizers): + # tokenizer 1 is seems to be ok + + # count words for token string: regular expression from open_clip + pat = regex.compile(r"""'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", regex.IGNORECASE) + words = regex.findall(pat, token_string) + word_count = len(words) + assert word_count == 1, ( + f"token string {token_string} contain {word_count} words, please don't use digits, punctuation, or special characters" + + f" / トークン文字列 {token_string} には{word_count}個の単語が含まれています。数字、句読点、特殊文字は使用しないでください" + ) + + def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): + input_ids1 = batch["input_ids"] + input_ids2 = batch["input_ids2"] + with torch.enable_grad(): + input_ids1 = input_ids1.to(accelerator.device) + input_ids2 = input_ids2.to(accelerator.device) + encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( + args, + input_ids1, + input_ids2, + tokenizers[0], + tokenizers[1], + text_encoders[0], + text_encoders[1], + None if not args.full_fp16 else weight_dtype, + ) + return encoder_hidden_states1, encoder_hidden_states2, pool2 + + def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_conds, batch, weight_dtype): + noisy_latents = noisy_latents.to(weight_dtype) # TODO check why noisy_latents is not weight_dtype + + # get size embeddings + orig_size = batch["original_sizes_hw"] + crop_size = batch["crop_top_lefts"] + target_size = batch["target_sizes_hw"] + embs = sdxl_train_util.get_size_embeddings(orig_size, crop_size, target_size, accelerator.device).to(weight_dtype) + + # concat embeddings + encoder_hidden_states1, encoder_hidden_states2, pool2 = text_conds + vector_embedding = torch.cat([pool2, embs], dim=1).to(weight_dtype) + text_embedding = torch.cat([encoder_hidden_states1, encoder_hidden_states2], dim=2).to(weight_dtype) + + noise_pred = unet(noisy_latents, timesteps, text_embedding, vector_embedding) + return noise_pred + + def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet, prompt_replacement): + sdxl_train_util.sample_images( + accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet, prompt_replacement + ) + + def save_weights(self, file, updated_embs, save_dtype): + state_dict = {"clip_l": updated_embs[0], "clip_g": updated_embs[1]} + + if save_dtype is not None: + for key in list(state_dict.keys()): + v = state_dict[key] + v = v.detach().clone().to("cpu").to(save_dtype) + state_dict[key] = v + + if os.path.splitext(file)[1] == ".safetensors": + from safetensors.torch import save_file + + save_file(state_dict, file) + else: + torch.save(state_dict, file) + + def load_weights(self, file): + if os.path.splitext(file)[1] == ".safetensors": + from safetensors.torch import load_file + + data = load_file(file) + else: + data = torch.load(file, map_location="cpu") + + emb_l = data.get("clib_l", None) # ViT-L text encoder 1 + emb_g = data.get("clib_g", None) # BiG-G text encoder 2 + + assert ( + emb_l is not None or emb_g is not None + ), f"weight file does not contains weights for text encoder 1 or 2 / 重みファイルにテキストエンコーダー1または2の重みが含まれていません: {file}" + + return [emb_l, emb_g] + + +def setup_parser() -> argparse.ArgumentParser: + parser = train_textual_inversion.setup_parser() + # don't add sdxl_train_util.add_sdxl_training_arguments(parser): because it only adds text encoder caching + # sdxl_train_util.add_sdxl_training_arguments(parser) + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + trainer = SdxlTextualInversionTrainer() + trainer.train(args) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index ecfaeb4fa..09294048f 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -8,6 +8,7 @@ import torch from accelerate.utils import set_seed from diffusers import DDPMScheduler +from library import model_util import library.train_util as train_util import library.huggingface_util as huggingface_util @@ -20,8 +21,6 @@ from library.custom_train_functions import ( apply_snr_weight, prepare_scheduler_for_custom_training, - pyramid_noise_like, - apply_noise_offset, scale_v_prediction_loss_like_noise_prediction, ) @@ -78,503 +77,632 @@ ] -def train(args): - if args.output_name is None: - args.output_name = args.token_string - use_template = args.use_object_template or args.use_style_template +class TextualInversionTrainer: + def __init__(self): + self.vae_scale_factor = 0.18215 - train_util.verify_training_args(args) - train_util.prepare_dataset_args(args, True) + def assert_extra_args(self, args, train_dataset_group): + pass - cache_latents = args.cache_latents + def load_target_model(self, args, weight_dtype, accelerator): + text_encoder, vae, unet, _ = train_util.load_target_model(args, weight_dtype, accelerator) + return model_util.get_model_version_str_for_sd1_sd2(args.v2, args.v_parameterization), text_encoder, vae, unet - if args.seed is not None: - set_seed(args.seed) + def load_tokenizer(self, args): + tokenizer = train_util.load_tokenizer(args) + return tokenizer - tokenizer = train_util.load_tokenizer(args) + def assert_token_string(self, token_string, tokenizers): + pass + + def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): + with torch.enable_grad(): + input_ids = batch["input_ids"].to(accelerator.device) + encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizers[0], text_encoders[0], None) + return encoder_hidden_states - # acceleratorを準備する - print("prepare accelerator") - accelerator = train_util.prepare_accelerator(args) + def call_unet(self, args, accelerator, unet, noisy_latents, timesteps, text_conds, batch, weight_dtype): + noise_pred = unet(noisy_latents, timesteps, text_conds).sample + return noise_pred - # mixed precisionに対応した型を用意しておき適宜castする - weight_dtype, save_dtype = train_util.prepare_dtype(args) + def sample_images(self, accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet, prompt_replacement): + train_util.sample_images( + accelerator, args, epoch, global_step, device, vae, tokenizer, text_encoder, unet, prompt_replacement + ) - # モデルを読み込む - text_encoder, vae, unet, _ = train_util.load_target_model(args, weight_dtype, accelerator) + def save_weights(self, file, updated_embs, save_dtype): + state_dict = {"emb_params": updated_embs[0]} - # Convert the init_word to token_id - if args.init_word is not None: - init_token_ids = tokenizer.encode(args.init_word, add_special_tokens=False) - if len(init_token_ids) > 1 and len(init_token_ids) != args.num_vectors_per_token: - accelerator.print( - f"token length for init words is not same to num_vectors_per_token, init words is repeated or truncated / 初期化単語のトークン長がnum_vectors_per_tokenと合わないため、繰り返しまたは切り捨てが発生します: length {len(init_token_ids)}" - ) - else: - init_token_ids = None - - # add new word to tokenizer, count is num_vectors_per_token - token_strings = [args.token_string] + [f"{args.token_string}{i+1}" for i in range(args.num_vectors_per_token - 1)] - num_added_tokens = tokenizer.add_tokens(token_strings) - assert ( - num_added_tokens == args.num_vectors_per_token - ), f"tokenizer has same word to token string. please use another one / 指定したargs.token_stringは既に存在します。別の単語を使ってください: {args.token_string}" - - token_ids = tokenizer.convert_tokens_to_ids(token_strings) - accelerator.print(f"tokens are added: {token_ids}") - assert min(token_ids) == token_ids[0] and token_ids[-1] == token_ids[0] + len(token_ids) - 1, f"token ids is not ordered" - assert len(tokenizer) - 1 == token_ids[-1], f"token ids is not end of tokenize: {len(tokenizer)}" - - # Resize the token embeddings as we are adding new special tokens to the tokenizer - text_encoder.resize_token_embeddings(len(tokenizer)) - - # Initialise the newly added placeholder token with the embeddings of the initializer token - token_embeds = text_encoder.get_input_embeddings().weight.data - if init_token_ids is not None: - for i, token_id in enumerate(token_ids): - token_embeds[token_id] = token_embeds[init_token_ids[i % len(init_token_ids)]] - # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) - - # load weights - if args.weights is not None: - embeddings = load_weights(args.weights) - assert len(token_ids) == len( - embeddings - ), f"num_vectors_per_token is mismatch for weights / 指定した重みとnum_vectors_per_tokenの値が異なります: {len(embeddings)}" - # accelerator.print(token_ids, embeddings.size()) - for token_id, embedding in zip(token_ids, embeddings): - token_embeds[token_id] = embedding - # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) - accelerator.print(f"weighs loaded") - - accelerator.print(f"create embeddings for {args.num_vectors_per_token} tokens, for {args.token_string}") - - # データセットを準備する - if args.dataset_class is None: - blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, False)) - if args.dataset_config is not None: - accelerator.print(f"Load dataset config from {args.dataset_config}") - user_config = config_util.load_user_config(args.dataset_config) - ignored = ["train_data_dir", "reg_data_dir", "in_json"] - if any(getattr(args, attr) is not None for attr in ignored): - accelerator.print( - "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( - ", ".join(ignored) - ) - ) - else: - use_dreambooth_method = args.in_json is None - if use_dreambooth_method: - accelerator.print("Use DreamBooth method.") - user_config = { - "datasets": [ - { - "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( - args.train_data_dir, args.reg_data_dir - ) - } - ] - } - else: - print("Train with captions.") - user_config = { - "datasets": [ - { - "subsets": [ - { - "image_dir": args.train_data_dir, - "metadata_file": args.in_json, - } - ] - } - ] - } - - blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer) - train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) - else: - train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizer) - - current_epoch = Value("i", 0) - current_step = Value("i", 0) - ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None - collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) - - # make captions: tokenstring tokenstring1 tokenstring2 ...tokenstringn という文字列に書き換える超乱暴な実装 - if use_template: - accelerator.print("use template for training captions. is object: {args.use_object_template}") - templates = imagenet_templates_small if args.use_object_template else imagenet_style_templates_small - replace_to = " ".join(token_strings) - captions = [] - for tmpl in templates: - captions.append(tmpl.format(replace_to)) - train_dataset_group.add_replacement("", captions) - - if args.num_vectors_per_token > 1: - prompt_replacement = (args.token_string, replace_to) - else: - prompt_replacement = None - else: - if args.num_vectors_per_token > 1: - replace_to = " ".join(token_strings) - train_dataset_group.add_replacement(args.token_string, replace_to) - prompt_replacement = (args.token_string, replace_to) - else: - prompt_replacement = None - - if args.debug_dataset: - train_util.debug_dataset(train_dataset_group, show_input_ids=True) - return - if len(train_dataset_group) == 0: - accelerator.print("No data found. Please verify arguments / 画像がありません。引数指定を確認してください") - return - - if cache_latents: - assert ( - train_dataset_group.is_latent_cacheable() - ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" - - # モデルに xformers とか memory efficient attention を組み込む - train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) - - # 学習を準備する - if cache_latents: - vae.to(accelerator.device, dtype=weight_dtype) - vae.requires_grad_(False) - vae.eval() - with torch.no_grad(): - train_dataset_group.cache_latents(vae, args.vae_batch_size, args.cache_latents_to_disk, accelerator.is_main_process) - vae.to("cpu") - if torch.cuda.is_available(): - torch.cuda.empty_cache() - gc.collect() - - accelerator.wait_for_everyone() - - if args.gradient_checkpointing: - unet.enable_gradient_checkpointing() - text_encoder.gradient_checkpointing_enable() - - # 学習に必要なクラスを準備する - accelerator.print("prepare optimizer, data loader etc.") - trainable_params = text_encoder.get_input_embeddings().parameters() - _, _, optimizer = train_util.get_optimizer(args, trainable_params) - - # dataloaderを準備する - # DataLoaderのプロセス数:0はメインプロセスになる - n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで - train_dataloader = torch.utils.data.DataLoader( - train_dataset_group, - batch_size=1, - shuffle=True, - collate_fn=collater, - num_workers=n_workers, - persistent_workers=args.persistent_data_loader_workers, - ) + if save_dtype is not None: + for key in list(state_dict.keys()): + v = state_dict[key] + v = v.detach().clone().to("cpu").to(save_dtype) + state_dict[key] = v - # 学習ステップ数を計算する - if args.max_train_epochs is not None: - args.max_train_steps = args.max_train_epochs * math.ceil( - len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps - ) - accelerator.print(f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}") + if os.path.splitext(file)[1] == ".safetensors": + from safetensors.torch import save_file - # データセット側にも学習ステップを送信 - train_dataset_group.set_max_train_steps(args.max_train_steps) + save_file(state_dict, file) + else: + torch.save(state_dict, file) # can be loaded in Web UI - # lr schedulerを用意する - lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) + def load_weights(self, file): + if os.path.splitext(file)[1] == ".safetensors": + from safetensors.torch import load_file - # acceleratorがなんかよろしくやってくれるらしい - text_encoder, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( - text_encoder, optimizer, train_dataloader, lr_scheduler - ) + data = load_file(file) + else: + # compatible to Web UI's file format + data = torch.load(file, map_location="cpu") + if type(data) != dict: + raise ValueError(f"weight file is not dict / 重みファイルがdict形式ではありません: {file}") - # transform DDP after prepare - text_encoder, unet = train_util.transform_if_model_is_DDP(text_encoder, unet) - - index_no_updates = torch.arange(len(tokenizer)) < token_ids[0] - # accelerator.print(len(index_no_updates), torch.sum(index_no_updates)) - orig_embeds_params = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() - - # Freeze all parameters except for the token embeddings in text encoder - text_encoder.requires_grad_(True) - text_encoder.text_model.encoder.requires_grad_(False) - text_encoder.text_model.final_layer_norm.requires_grad_(False) - text_encoder.text_model.embeddings.position_embedding.requires_grad_(False) - # text_encoder.text_model.embeddings.token_embedding.requires_grad_(True) - - unet.requires_grad_(False) - unet.to(accelerator.device, dtype=weight_dtype) - if args.gradient_checkpointing: # according to TI example in Diffusers, train is required - unet.train() - else: - unet.eval() - - if not cache_latents: - vae.requires_grad_(False) - vae.eval() - vae.to(accelerator.device, dtype=weight_dtype) - - # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする - if args.full_fp16: - train_util.patch_accelerator_for_fp16_training(accelerator) - text_encoder.to(weight_dtype) - - # resumeする - train_util.resume_from_local_or_hf_if_specified(accelerator, args) - - # epoch数を計算する - num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) - num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) - if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): - args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 - - # 学習する - total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps - accelerator.print("running training / 学習開始") - accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") - accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") - accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") - accelerator.print(f" num epochs / epoch数: {num_train_epochs}") - accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") - accelerator.print( - f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" - ) - accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") - accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") + if "string_to_param" in data: # textual inversion embeddings + data = data["string_to_param"] + if hasattr(data, "_parameters"): # support old PyTorch? + data = getattr(data, "_parameters") - progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") - global_step = 0 + emb = next(iter(data.values())) + if type(emb) != torch.Tensor: + raise ValueError(f"weight file does not contains Tensor / 重みファイルのデータがTensorではありません: {file}") - noise_scheduler = DDPMScheduler( - beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False - ) - prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) - - if accelerator.is_main_process: - accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) - - # function for saving/removing - def save_model(ckpt_name, embs, steps, epoch_no, force_sync_upload=False): - os.makedirs(args.output_dir, exist_ok=True) - ckpt_file = os.path.join(args.output_dir, ckpt_name) - - accelerator.print(f"\nsaving checkpoint: {ckpt_file}") - save_weights(ckpt_file, embs, save_dtype) - if args.huggingface_repo_id is not None: - huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) - - def remove_model(old_ckpt_name): - old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) - if os.path.exists(old_ckpt_file): - accelerator.print(f"removing old checkpoint: {old_ckpt_file}") - os.remove(old_ckpt_file) - - # training loop - for epoch in range(num_train_epochs): - accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") - current_epoch.value = epoch + 1 - - text_encoder.train() - - loss_total = 0 - - for step, batch in enumerate(train_dataloader): - current_step.value = global_step - with accelerator.accumulate(text_encoder): - with torch.no_grad(): - if "latents" in batch and batch["latents"] is not None: - latents = batch["latents"].to(accelerator.device) - else: - # latentに変換 - latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() - latents = latents * 0.18215 - b_size = latents.shape[0] - - # Get the text embedding for conditioning - input_ids = batch["input_ids"].to(accelerator.device) - # use float instead of fp16/bf16 because text encoder is float - encoder_hidden_states = train_util.get_hidden_states(args, input_ids, tokenizer, text_encoder, torch.float) - - # Sample noise, sample a random timestep for each image, and add noise to the latents, - # with noise offset and/or multires noise if specified - noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps(args, noise_scheduler, latents) - - # Predict the noise residual - with accelerator.autocast(): - noise_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample - - if args.v_parameterization: - # v-parameterization training - target = noise_scheduler.get_velocity(latents, noise, timesteps) - else: - target = noise - - loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") - loss = loss.mean([1, 2, 3]) - - loss_weights = batch["loss_weights"] # 各sampleごとのweight - loss = loss * loss_weights - - if args.min_snr_gamma: - loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) - if args.scale_v_pred_loss_like_noise_pred: - loss = scale_v_prediction_loss_like_noise_prediction(loss, timesteps, noise_scheduler) - - loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし - - accelerator.backward(loss) - if accelerator.sync_gradients and args.max_grad_norm != 0.0: - params_to_clip = text_encoder.get_input_embeddings().parameters() - accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) - - optimizer.step() - lr_scheduler.step() - optimizer.zero_grad(set_to_none=True) - - # Let's make sure we don't update any embedding weights besides the newly added token - with torch.no_grad(): - accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[index_no_updates] = orig_embeds_params[ - index_no_updates - ] - - # Checks if the accelerator has performed an optimization step behind the scenes - if accelerator.sync_gradients: - progress_bar.update(1) - global_step += 1 - - train_util.sample_images( - accelerator, args, None, global_step, accelerator.device, vae, tokenizer, text_encoder, unet, prompt_replacement - ) - - # 指定ステップごとにモデルを保存 - if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: - accelerator.wait_for_everyone() - if accelerator.is_main_process: - updated_embs = ( - accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() - ) + if len(emb.size()) == 1: + emb = emb.unsqueeze(0) - ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) - save_model(ckpt_name, updated_embs, global_step, epoch) + return [emb] - if args.save_state: - train_util.save_and_remove_state_stepwise(args, accelerator, global_step) + def train(self, args): + if args.output_name is None: + args.output_name = args.token_string + use_template = args.use_object_template or args.use_style_template - remove_step_no = train_util.get_remove_step_no(args, global_step) - if remove_step_no is not None: - remove_ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, remove_step_no) - remove_model(remove_ckpt_name) + train_util.verify_training_args(args) + train_util.prepare_dataset_args(args, True) - current_loss = loss.detach().item() - if args.logging_dir is not None: - logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} - if ( - args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower() - ): # tracking d*lr value - logs["lr/d*lr"] = ( - lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] - ) - accelerator.log(logs, step=global_step) + cache_latents = args.cache_latents - loss_total += current_loss - avr_loss = loss_total / (step + 1) - logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} - progress_bar.set_postfix(**logs) + if args.seed is not None: + set_seed(args.seed) - if global_step >= args.max_train_steps: - break + tokenizer_or_list = self.load_tokenizer(args) # list of tokenizer or tokenizer + tokenizers = tokenizer_or_list if isinstance(tokenizer_or_list, list) else [tokenizer_or_list] - if args.logging_dir is not None: - logs = {"loss/epoch": loss_total / len(train_dataloader)} - accelerator.log(logs, step=epoch + 1) + # acceleratorを準備する + print("prepare accelerator") + accelerator = train_util.prepare_accelerator(args) - accelerator.wait_for_everyone() + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, save_dtype = train_util.prepare_dtype(args) - updated_embs = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() + # モデルを読み込む + model_version, text_encoder_or_list, vae, unet = self.load_target_model(args, weight_dtype, accelerator) + text_encoders = [text_encoder_or_list] if not isinstance(text_encoder_or_list, list) else text_encoder_or_list - if args.save_every_n_epochs is not None: - saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs - if accelerator.is_main_process and saving: - ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) - save_model(ckpt_name, updated_embs, epoch + 1, global_step) + if len(text_encoders) > 1 and args.gradient_accumulation_steps > 1: + accelerator.print( + "accelerate doesn't seem to support gradient_accumulation_steps for multiple models (text encoders) / " + + "accelerateでは複数のモデル(テキストエンコーダー)のgradient_accumulation_stepsはサポートされていないようです" + ) - remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) - if remove_epoch_no is not None: - remove_ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, remove_epoch_no) - remove_model(remove_ckpt_name) + # Convert the init_word to token_id + init_token_ids_list = [] + if args.init_word is not None: + for i, tokenizer in enumerate(tokenizers): + init_token_ids = tokenizer.encode(args.init_word, add_special_tokens=False) + if len(init_token_ids) > 1 and len(init_token_ids) != args.num_vectors_per_token: + accelerator.print( + f"token length for init words is not same to num_vectors_per_token, init words is repeated or truncated / " + + f"初期化単語のトークン長がnum_vectors_per_tokenと合わないため、繰り返しまたは切り捨てが発生します: tokenizer {i+1}, length {len(init_token_ids)}" + ) + init_token_ids_list.append(init_token_ids) + else: + init_token_ids_list = [None] * len(tokenizers) + + # tokenizerに新しい単語を追加する。追加する単語の数はnum_vectors_per_token + # add new word to tokenizer, count is num_vectors_per_token + + # token_stringが hoge の場合、"hoge", "hogea", "hogeb", ... が追加される + # 当初は "hoge", "hoge1", "hoge2", ... としていたが、open clipのtokenizerは数字を含む単語を分割してしまうため(;^ω^)、a, b, ... とした + + # if token_string is hoge, "hoge", "hogea", "hogeb", ... are added + # originally, "hoge", "hoge1", "hoge2", ... were used, but open clip's tokenizer splits words including numbers (;^ω^), so a, b, ... are used + + self.assert_token_string(args.token_string, tokenizers) + + token_strings = [args.token_string] + [ + f"{args.token_string}{chr(ord('a') + i)}" for i in range(args.num_vectors_per_token - 1) + ] + token_ids_list = [] + token_embeds_list = [] + for i, (tokenizer, text_encoder, init_token_ids) in enumerate(zip(tokenizers, text_encoders, init_token_ids_list)): + num_added_tokens = tokenizer.add_tokens(token_strings) + assert ( + num_added_tokens == args.num_vectors_per_token + ), f"tokenizer has same word to token string. please use another one / 指定したargs.token_stringは既に存在します。別の単語を使ってください: tokenizer {i+1}, {args.token_string}" + + token_ids = tokenizer.convert_tokens_to_ids(token_strings) + accelerator.print(f"tokens are added for tokenizer {i+1}: {token_ids}") + assert ( + min(token_ids) == token_ids[0] and token_ids[-1] == token_ids[0] + len(token_ids) - 1 + ), f"token ids is not ordered : tokenizer {i+1}, {token_ids}" + assert ( + len(tokenizer) - 1 == token_ids[-1] + ), f"token ids is not end of tokenize: tokenizer {i+1}, {token_ids}, {len(tokenizer)}" + token_ids_list.append(token_ids) + + # Resize the token embeddings as we are adding new special tokens to the tokenizer + text_encoder.resize_token_embeddings(len(tokenizer)) + + # Initialise the newly added placeholder token with the embeddings of the initializer token + token_embeds = text_encoder.get_input_embeddings().weight.data + if init_token_ids is not None: + for i, token_id in enumerate(token_ids): + token_embeds[token_id] = token_embeds[init_token_ids[i % len(init_token_ids)]] + # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) + token_embeds_list.append(token_embeds) + + # load weights + if args.weights is not None: + embeddings_list = self.load_weights(args.weights) + assert len(token_ids) == len( + embeddings_list[0] + ), f"num_vectors_per_token is mismatch for weights / 指定した重みとnum_vectors_per_tokenの値が異なります: {len(embeddings)}" + # accelerator.print(token_ids, embeddings.size()) + for token_ids, embeddings, token_embeds in zip(token_ids_list, embeddings_list, token_embeds_list): + for token_id, embedding in zip(token_ids, embeddings): + token_embeds[token_id] = embedding + # accelerator.print(token_id, token_embeds[token_id].mean(), token_embeds[token_id].min()) + accelerator.print(f"weighs loaded") + + accelerator.print(f"create embeddings for {args.num_vectors_per_token} tokens, for {args.token_string}") + + # データセットを準備する + if args.dataset_class is None: + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, False)) + if args.dataset_config is not None: + accelerator.print(f"Load dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "reg_data_dir", "in_json"] + if any(getattr(args, attr) is not None for attr in ignored): + accelerator.print( + "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + use_dreambooth_method = args.in_json is None + if use_dreambooth_method: + accelerator.print("Use DreamBooth method.") + user_config = { + "datasets": [ + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } + ] + } + else: + print("Train with captions.") + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizer_or_list) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) + else: + train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizer_or_list) - if args.save_state: - train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) + self.assert_extra_args(args, train_dataset_group) - train_util.sample_images( - accelerator, args, epoch + 1, global_step, accelerator.device, vae, tokenizer, text_encoder, unet, prompt_replacement + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + # make captions: tokenstring tokenstring1 tokenstring2 ...tokenstringn という文字列に書き換える超乱暴な実装 + if use_template: + accelerator.print("use template for training captions. is object: {args.use_object_template}") + templates = imagenet_templates_small if args.use_object_template else imagenet_style_templates_small + replace_to = " ".join(token_strings) + captions = [] + for tmpl in templates: + captions.append(tmpl.format(replace_to)) + train_dataset_group.add_replacement("", captions) + + # サンプル生成用 + if args.num_vectors_per_token > 1: + prompt_replacement = (args.token_string, replace_to) + else: + prompt_replacement = None + else: + # サンプル生成用 + if args.num_vectors_per_token > 1: + replace_to = " ".join(token_strings) + train_dataset_group.add_replacement(args.token_string, replace_to) + prompt_replacement = (args.token_string, replace_to) + else: + prompt_replacement = None + + if args.debug_dataset: + train_util.debug_dataset(train_dataset_group, show_input_ids=True) + return + if len(train_dataset_group) == 0: + accelerator.print("No data found. Please verify arguments / 画像がありません。引数指定を確認してください") + return + + if cache_latents: + assert ( + train_dataset_group.is_latent_cacheable() + ), "when caching latents, either color_aug or random_crop cannot be used / latentをキャッシュするときはcolor_augとrandom_cropは使えません" + + # モデルに xformers とか memory efficient attention を組み込む + train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) + vae.set_use_memory_efficient_attention_xformers(args.xformers) + + # 学習を準備する + if cache_latents: + vae.to(accelerator.device, dtype=weight_dtype) + vae.requires_grad_(False) + vae.eval() + with torch.no_grad(): + train_dataset_group.cache_latents(vae, args.vae_batch_size, args.cache_latents_to_disk, accelerator.is_main_process) + vae.to("cpu") + if torch.cuda.is_available(): + torch.cuda.empty_cache() + gc.collect() + + accelerator.wait_for_everyone() + + if args.gradient_checkpointing: + unet.enable_gradient_checkpointing() + for text_encoder in text_encoders: + text_encoder.gradient_checkpointing_enable() + + # 学習に必要なクラスを準備する + accelerator.print("prepare optimizer, data loader etc.") + trainable_params = [] + for text_encoder in text_encoders: + trainable_params += text_encoder.get_input_embeddings().parameters() + _, _, optimizer = train_util.get_optimizer(args, trainable_params) + + # dataloaderを準備する + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, ) - # end of epoch + # 学習ステップ数を計算する + if args.max_train_epochs is not None: + args.max_train_steps = args.max_train_epochs * math.ceil( + len(train_dataloader) / accelerator.num_processes / args.gradient_accumulation_steps + ) + accelerator.print( + f"override steps. steps for {args.max_train_epochs} epochs is / 指定エポックまでのステップ数: {args.max_train_steps}" + ) - is_main_process = accelerator.is_main_process - if is_main_process: - text_encoder = accelerator.unwrap_model(text_encoder) + # データセット側にも学習ステップを送信 + train_dataset_group.set_max_train_steps(args.max_train_steps) - accelerator.end_training() + # lr schedulerを用意する + lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) - if args.save_state and is_main_process: - train_util.save_state_on_train_end(args, accelerator) + # acceleratorがなんかよろしくやってくれるらしい + if len(text_encoders) == 1: + text_encoder_or_list, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + text_encoder_or_list, optimizer, train_dataloader, lr_scheduler + ) + # transform DDP after prepare + text_encoder_or_list, unet = train_util.transform_if_model_is_DDP(text_encoder_or_list, unet) - updated_embs = text_encoder.get_input_embeddings().weight[token_ids].data.detach().clone() + elif len(text_encoders) == 2: + text_encoder1, text_encoder2, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( + text_encoders[0], text_encoders[1], optimizer, train_dataloader, lr_scheduler + ) + # transform DDP after prepare + text_encoder1, text_encoder2, unet = train_util.transform_if_model_is_DDP(text_encoder1, text_encoder2, unet) - del accelerator # この後メモリを使うのでこれは消す + text_encoder_or_list = text_encoders = [text_encoder1, text_encoder2] - if is_main_process: - ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) - save_model(ckpt_name, updated_embs, global_step, num_train_epochs, force_sync_upload=True) + else: + raise NotImplementedError() + + index_no_updates_list = [] + orig_embeds_params_list = [] + for tokenizer, token_ids, text_encoder in zip(tokenizers, token_ids_list, text_encoders): + index_no_updates = torch.arange(len(tokenizer)) < token_ids[0] + index_no_updates_list.append(index_no_updates) + + # accelerator.print(len(index_no_updates), torch.sum(index_no_updates)) + orig_embeds_params = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight.data.detach().clone() + orig_embeds_params_list.append(orig_embeds_params) + + # Freeze all parameters except for the token embeddings in text encoder + text_encoder.requires_grad_(True) + text_encoder.text_model.encoder.requires_grad_(False) + text_encoder.text_model.final_layer_norm.requires_grad_(False) + text_encoder.text_model.embeddings.position_embedding.requires_grad_(False) + # text_encoder.text_model.embeddings.token_embedding.requires_grad_(True) + + unet.requires_grad_(False) + unet.to(accelerator.device, dtype=weight_dtype) + if args.gradient_checkpointing: # according to TI example in Diffusers, train is required + # TODO U-Netをオリジナルに置き換えたのでいらないはずなので、後で確認して消す + unet.train() + else: + unet.eval() + + if not cache_latents: + vae.requires_grad_(False) + vae.eval() + vae.to(accelerator.device, dtype=weight_dtype) + + # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする + if args.full_fp16: + train_util.patch_accelerator_for_fp16_training(accelerator) + for text_encoder in text_encoders: + text_encoder.to(weight_dtype) + if args.full_bf16: + for text_encoder in text_encoders: + text_encoder.to(weight_dtype) + + # resumeする + train_util.resume_from_local_or_hf_if_specified(accelerator, args) + + # epoch数を計算する + num_update_steps_per_epoch = math.ceil(len(train_dataloader) / args.gradient_accumulation_steps) + num_train_epochs = math.ceil(args.max_train_steps / num_update_steps_per_epoch) + if (args.save_n_epoch_ratio is not None) and (args.save_n_epoch_ratio > 0): + args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 + + # 学習する + total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps + accelerator.print("running training / 学習開始") + accelerator.print(f" num train images * repeats / 学習画像の数×繰り返し回数: {train_dataset_group.num_train_images}") + accelerator.print(f" num reg images / 正則化画像の数: {train_dataset_group.num_reg_images}") + accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") + accelerator.print(f" num epochs / epoch数: {num_train_epochs}") + accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") + accelerator.print( + f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + ) + accelerator.print(f" gradient ccumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") + accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") - print("model saved.") + progress_bar = tqdm(range(args.max_train_steps), smoothing=0, disable=not accelerator.is_local_main_process, desc="steps") + global_step = 0 + noise_scheduler = DDPMScheduler( + beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False + ) + prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + + if accelerator.is_main_process: + accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) + + # function for saving/removing + def save_model(ckpt_name, embs_list, steps, epoch_no, force_sync_upload=False): + os.makedirs(args.output_dir, exist_ok=True) + ckpt_file = os.path.join(args.output_dir, ckpt_name) + + accelerator.print(f"\nsaving checkpoint: {ckpt_file}") + self.save_weights(ckpt_file, embs_list, save_dtype) + if args.huggingface_repo_id is not None: + huggingface_util.upload(args, ckpt_file, "/" + ckpt_name, force_sync_upload=force_sync_upload) + + def remove_model(old_ckpt_name): + old_ckpt_file = os.path.join(args.output_dir, old_ckpt_name) + if os.path.exists(old_ckpt_file): + accelerator.print(f"removing old checkpoint: {old_ckpt_file}") + os.remove(old_ckpt_file) + + # training loop + for epoch in range(num_train_epochs): + accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") + current_epoch.value = epoch + 1 + + for text_encoder in text_encoders: + text_encoder.train() + + loss_total = 0 + + for step, batch in enumerate(train_dataloader): + current_step.value = global_step + with accelerator.accumulate(text_encoders[0]): + with torch.no_grad(): + if "latents" in batch and batch["latents"] is not None: + latents = batch["latents"].to(accelerator.device) + else: + # latentに変換 + latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() + latents = latents * self.vae_scale_factor + + # Get the text embedding for conditioning + text_encoder_conds = self.get_text_cond(args, accelerator, batch, tokenizers, text_encoders, weight_dtype) + + # Sample noise, sample a random timestep for each image, and add noise to the latents, + # with noise offset and/or multires noise if specified + noise, noisy_latents, timesteps = train_util.get_noise_noisy_latents_and_timesteps( + args, noise_scheduler, latents + ) -def save_weights(file, updated_embs, save_dtype): - state_dict = {"emb_params": updated_embs} + # Predict the noise residual + with accelerator.autocast(): + noise_pred = self.call_unet( + args, accelerator, unet, noisy_latents, timesteps, text_encoder_conds, batch, weight_dtype + ) - if save_dtype is not None: - for key in list(state_dict.keys()): - v = state_dict[key] - v = v.detach().clone().to("cpu").to(save_dtype) - state_dict[key] = v + if args.v_parameterization: + # v-parameterization training + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + target = noise + + loss = torch.nn.functional.mse_loss(noise_pred.float(), target.float(), reduction="none") + loss = loss.mean([1, 2, 3]) + + loss_weights = batch["loss_weights"] # 各sampleごとのweight + loss = loss * loss_weights + + if args.min_snr_gamma: + loss = apply_snr_weight(loss, timesteps, noise_scheduler, args.min_snr_gamma) + if args.scale_v_pred_loss_like_noise_pred: + loss = scale_v_prediction_loss_like_noise_prediction(loss, timesteps, noise_scheduler) + + loss = loss.mean() # 平均なのでbatch_sizeで割る必要なし + + accelerator.backward(loss) + if accelerator.sync_gradients and args.max_grad_norm != 0.0: + params_to_clip = text_encoder.get_input_embeddings().parameters() + accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) + + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad(set_to_none=True) + + # Let's make sure we don't update any embedding weights besides the newly added token + with torch.no_grad(): + for text_encoder, orig_embeds_params, index_no_updates in zip( + text_encoders, orig_embeds_params_list, index_no_updates_list + ): + accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[ + index_no_updates + ] = orig_embeds_params[index_no_updates] + + # Checks if the accelerator has performed an optimization step behind the scenes + if accelerator.sync_gradients: + progress_bar.update(1) + global_step += 1 + + self.sample_images( + accelerator, + args, + None, + global_step, + accelerator.device, + vae, + tokenizer_or_list, + text_encoder_or_list, + unet, + prompt_replacement, + ) + + # 指定ステップごとにモデルを保存 + if args.save_every_n_steps is not None and global_step % args.save_every_n_steps == 0: + accelerator.wait_for_everyone() + if accelerator.is_main_process: + updated_embs_list = [] + for text_encoder, token_ids in zip(text_encoders, token_ids_list): + updated_embs = ( + accelerator.unwrap_model(text_encoder) + .get_input_embeddings() + .weight[token_ids] + .data.detach() + .clone() + ) + updated_embs_list.append(updated_embs) + + ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, global_step) + save_model(ckpt_name, updated_embs_list, global_step, epoch) + + if args.save_state: + train_util.save_and_remove_state_stepwise(args, accelerator, global_step) + + remove_step_no = train_util.get_remove_step_no(args, global_step) + if remove_step_no is not None: + remove_ckpt_name = train_util.get_step_ckpt_name(args, "." + args.save_model_as, remove_step_no) + remove_model(remove_ckpt_name) + + current_loss = loss.detach().item() + if args.logging_dir is not None: + logs = {"loss": current_loss, "lr": float(lr_scheduler.get_last_lr()[0])} + if ( + args.optimizer_type.lower().startswith("DAdapt".lower()) or args.optimizer_type.lower() == "Prodigy".lower() + ): # tracking d*lr value + logs["lr/d*lr"] = ( + lr_scheduler.optimizers[0].param_groups[0]["d"] * lr_scheduler.optimizers[0].param_groups[0]["lr"] + ) + accelerator.log(logs, step=global_step) - if os.path.splitext(file)[1] == ".safetensors": - from safetensors.torch import save_file + loss_total += current_loss + avr_loss = loss_total / (step + 1) + logs = {"loss": avr_loss} # , "lr": lr_scheduler.get_last_lr()[0]} + progress_bar.set_postfix(**logs) - save_file(state_dict, file) - else: - torch.save(state_dict, file) # can be loaded in Web UI + if global_step >= args.max_train_steps: + break + + if args.logging_dir is not None: + logs = {"loss/epoch": loss_total / len(train_dataloader)} + accelerator.log(logs, step=epoch + 1) + + accelerator.wait_for_everyone() + + updated_embs_list = [] + for text_encoder, token_ids in zip(text_encoders, token_ids_list): + updated_embs = accelerator.unwrap_model(text_encoder).get_input_embeddings().weight[token_ids].data.detach().clone() + updated_embs_list.append(updated_embs) + + if args.save_every_n_epochs is not None: + saving = (epoch + 1) % args.save_every_n_epochs == 0 and (epoch + 1) < num_train_epochs + if accelerator.is_main_process and saving: + ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, epoch + 1) + save_model(ckpt_name, updated_embs_list, epoch + 1, global_step) + + remove_epoch_no = train_util.get_remove_epoch_no(args, epoch + 1) + if remove_epoch_no is not None: + remove_ckpt_name = train_util.get_epoch_ckpt_name(args, "." + args.save_model_as, remove_epoch_no) + remove_model(remove_ckpt_name) + + if args.save_state: + train_util.save_and_remove_state_on_epoch_end(args, accelerator, epoch + 1) + + self.sample_images( + accelerator, + args, + epoch + 1, + global_step, + accelerator.device, + vae, + tokenizer_or_list, + text_encoder_or_list, + unet, + prompt_replacement, + ) + # end of epoch -def load_weights(file): - if os.path.splitext(file)[1] == ".safetensors": - from safetensors.torch import load_file + is_main_process = accelerator.is_main_process + if is_main_process: + text_encoder = accelerator.unwrap_model(text_encoder) - data = load_file(file) - else: - # compatible to Web UI's file format - data = torch.load(file, map_location="cpu") - if type(data) != dict: - raise ValueError(f"weight file is not dict / 重みファイルがdict形式ではありません: {file}") + accelerator.end_training() - if "string_to_param" in data: # textual inversion embeddings - data = data["string_to_param"] - if hasattr(data, "_parameters"): # support old PyTorch? - data = getattr(data, "_parameters") + if args.save_state and is_main_process: + train_util.save_state_on_train_end(args, accelerator) - emb = next(iter(data.values())) - if type(emb) != torch.Tensor: - raise ValueError(f"weight file does not contains Tensor / 重みファイルのデータがTensorではありません: {file}") + updated_embs = text_encoder.get_input_embeddings().weight[token_ids].data.detach().clone() - if len(emb.size()) == 1: - emb = emb.unsqueeze(0) + if is_main_process: + ckpt_name = train_util.get_last_ckpt_name(args, "." + args.save_model_as) + save_model(ckpt_name, updated_embs_list, global_step, num_train_epochs, force_sync_upload=True) - return emb + print("model saved.") def setup_parser() -> argparse.ArgumentParser: @@ -626,4 +754,5 @@ def setup_parser() -> argparse.ArgumentParser: args = parser.parse_args() args = train_util.read_config_from_file(args, parser) - train(args) + trainer = TextualInversionTrainer() + trainer.train(args) From 68ca0ea995434a331209fbc34938e1bbe7ccb083 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 10 Jul 2023 22:28:26 +0900 Subject: [PATCH 072/220] Fix to show template type --- train_textual_inversion.py | 4 ++-- train_textual_inversion_XTI.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 09294048f..1f085643b 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -94,7 +94,7 @@ def load_tokenizer(self, args): def assert_token_string(self, token_string, tokenizers): pass - + def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): with torch.enable_grad(): input_ids = batch["input_ids"].to(accelerator.device) @@ -311,7 +311,7 @@ def train(self, args): # make captions: tokenstring tokenstring1 tokenstring2 ...tokenstringn という文字列に書き換える超乱暴な実装 if use_template: - accelerator.print("use template for training captions. is object: {args.use_object_template}") + accelerator.print(f"use template for training captions. is object: {args.use_object_template}") templates = imagenet_templates_small if args.use_object_template else imagenet_style_templates_small replace_to = " ".join(token_strings) captions = [] diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index a08c3a824..0e91c71c3 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -234,7 +234,7 @@ def train(args): # make captions: tokenstring tokenstring1 tokenstring2 ...tokenstringn という文字列に書き換える超乱暴な実装 if use_template: - print("use template for training captions. is object: {args.use_object_template}") + print(f"use template for training captions. is object: {args.use_object_template}") templates = imagenet_templates_small if args.use_object_template else imagenet_style_templates_small replace_to = " ".join(token_strings) captions = [] From b841dd78fe1508207e09b6c581ee8d26654d899e Mon Sep 17 00:00:00 2001 From: ddPn08 Date: Sun, 9 Jul 2023 16:31:38 +0900 Subject: [PATCH 073/220] make tracker init_kwargs configurable --- fine_tune.py | 6 +++++- library/train_util.py | 6 ++++++ sdxl_train.py | 6 +++++- train_controlnet.py | 6 +++++- train_db.py | 6 +++++- train_network.py | 6 +++++- train_textual_inversion.py | 6 +++++- train_textual_inversion_XTI.py | 5 ++++- 8 files changed, 40 insertions(+), 7 deletions(-) diff --git a/fine_tune.py b/fine_tune.py index 58a6cda0e..a3df178b6 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -6,6 +6,7 @@ import math import os from multiprocessing import Value +import toml from tqdm import tqdm import torch @@ -275,7 +276,10 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) for epoch in range(num_train_epochs): accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") diff --git a/library/train_util.py b/library/train_util.py index 809f0af03..84807a2a2 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2445,6 +2445,12 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: default=None, help="name of tracker to use for logging, default is script-specific default name / ログ出力に使用するtrackerの名前、省略時はスクリプトごとのデフォルト名", ) + parser.add_argument( + "--log_tracker_config", + type=str, + default=None, + help="path to tracker config file to use for logging / ログ出力に使用するtrackerの設定ファイルのパス", + ) parser.add_argument( "--wandb_api_key", type=str, diff --git a/sdxl_train.py b/sdxl_train.py index dd5b74dda..a7a92c2a3 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -5,6 +5,7 @@ import math import os from multiprocessing import Value +import toml from tqdm import tqdm import torch @@ -350,7 +351,10 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) for epoch in range(num_train_epochs): accelerator.print(f"\nepoch {epoch+1}/{num_train_epochs}") diff --git a/train_controlnet.py b/train_controlnet.py index 39ac43e96..988304f62 100644 --- a/train_controlnet.py +++ b/train_controlnet.py @@ -7,6 +7,7 @@ import time from multiprocessing import Value from types import SimpleNamespace +import toml from tqdm import tqdm import torch @@ -324,7 +325,10 @@ def train(args): clip_sample=False, ) if accelerator.is_main_process: - accelerator.init_trackers("controlnet_train" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("controlnet_train" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) loss_list = [] loss_total = 0.0 diff --git a/train_db.py b/train_db.py index 439f4b9d9..13fd651b1 100644 --- a/train_db.py +++ b/train_db.py @@ -7,6 +7,7 @@ import math import os from multiprocessing import Value +import toml from tqdm import tqdm import torch @@ -248,7 +249,10 @@ def train(args): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("dreambooth" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("dreambooth" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) loss_list = [] loss_total = 0.0 diff --git a/train_network.py b/train_network.py index f7ee451b1..b500ae7e1 100644 --- a/train_network.py +++ b/train_network.py @@ -8,6 +8,7 @@ import time import json from multiprocessing import Value +import toml from tqdm import tqdm import torch @@ -672,7 +673,10 @@ def train(self, args): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("network_train" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("network_train" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) loss_list = [] loss_total = 0.0 diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 09294048f..0ceab18ae 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -3,6 +3,7 @@ import math import os from multiprocessing import Value +import toml from tqdm import tqdm import torch @@ -493,7 +494,10 @@ def train(self, args): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) # function for saving/removing def save_model(ckpt_name, embs_list, steps, epoch_no, force_sync_upload=False): diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index a08c3a824..33fef9432 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -386,7 +386,10 @@ def train(args): prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) if accelerator.is_main_process: - accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) + init_kwargs = {} + if args.log_tracker_config is not None: + init_kwargs = toml.load(args.log_tracker_config) + accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name, init_kwargs=init_kwargs) # function for saving/removing def save_model(ckpt_name, embs, steps, epoch_no, force_sync_upload=False): From 2e67d74df46df88a9e9b3cae59373b7053b7a40c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 11 Jul 2023 22:19:14 +0900 Subject: [PATCH 074/220] add no_half_vae option --- train_textual_inversion.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 1f085643b..cbfd48ce7 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -173,6 +173,7 @@ def train(self, args): # mixed precisionに対応した型を用意しておき適宜castする weight_dtype, save_dtype = train_util.prepare_dtype(args) + vae_dtype = torch.float32 if args.no_half_vae else weight_dtype # モデルを読み込む model_version, text_encoder_or_list, vae, unet = self.load_target_model(args, weight_dtype, accelerator) @@ -351,7 +352,7 @@ def train(self, args): # 学習を準備する if cache_latents: - vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=vae_dtype) vae.requires_grad_(False) vae.eval() with torch.no_grad(): @@ -447,10 +448,10 @@ def train(self, args): else: unet.eval() - if not cache_latents: + if not cache_latents: # キャッシュしない場合はVAEを使うのでVAEを準備する vae.requires_grad_(False) vae.eval() - vae.to(accelerator.device, dtype=weight_dtype) + vae.to(accelerator.device, dtype=vae_dtype) # 実験的機能:勾配も含めたfp16学習を行う PyTorchにパッチを当ててfp16でのgrad scaleを有効にする if args.full_fp16: @@ -529,7 +530,7 @@ def remove_model(old_ckpt_name): latents = batch["latents"].to(accelerator.device) else: # latentに変換 - latents = vae.encode(batch["images"].to(dtype=weight_dtype)).latent_dist.sample() + latents = vae.encode(batch["images"].to(dtype=vae_dtype)).latent_dist.sample() latents = latents * self.vae_scale_factor # Get the text embedding for conditioning @@ -744,6 +745,11 @@ def setup_parser() -> argparse.ArgumentParser: action="store_true", help="ignore caption and use default templates for stype / キャプションは使わずデフォルトのスタイル用テンプレートで学習する", ) + parser.add_argument( + "--no_half_vae", + action="store_true", + help="do not use fp16/bf16 VAE in mixed precision (use float VAE) / mixed precisionでも fp16/bf16 VAEを使わずfloat VAEを使う", + ) return parser From 814996b14f39fb7144c37089a20e05c120dceeaa Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 11 Jul 2023 23:18:35 +0900 Subject: [PATCH 075/220] fix NaN in sampling image --- library/sdxl_lpw_stable_diffusion.py | 2 +- library/train_util.py | 232 +++++++++++++-------------- 2 files changed, 117 insertions(+), 117 deletions(-) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index d44b3cf8c..99b0bc8d5 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -922,7 +922,7 @@ def __call__( if up1 is not None: uncond_pool = up1 - dtype = text_embeddings_list[0].dtype + dtype = self.unet.dtype # 4. Preprocess image and mask if isinstance(image, PIL.Image.Image): diff --git a/library/train_util.py b/library/train_util.py index 809f0af03..9438a1895 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3874,127 +3874,127 @@ def sample_images_common( cuda_rng_state = torch.cuda.get_rng_state() if torch.cuda.is_available() else None with torch.no_grad(): - with accelerator.autocast(): - for i, prompt in enumerate(prompts): - if not accelerator.is_main_process: - continue + # with accelerator.autocast(): + for i, prompt in enumerate(prompts): + if not accelerator.is_main_process: + continue - if isinstance(prompt, dict): - negative_prompt = prompt.get("negative_prompt") - sample_steps = prompt.get("sample_steps", 30) - width = prompt.get("width", 512) - height = prompt.get("height", 512) - scale = prompt.get("scale", 7.5) - seed = prompt.get("seed") - controlnet_image = prompt.get("controlnet_image") - prompt = prompt.get("prompt") - else: - # prompt = prompt.strip() - # if len(prompt) == 0 or prompt[0] == "#": - # continue - - # subset of gen_img_diffusers - prompt_args = prompt.split(" --") - prompt = prompt_args[0] - negative_prompt = None - sample_steps = 30 - width = height = 512 - scale = 7.5 - seed = None - controlnet_image = None - for parg in prompt_args: - try: - m = re.match(r"w (\d+)", parg, re.IGNORECASE) - if m: - width = int(m.group(1)) - continue - - m = re.match(r"h (\d+)", parg, re.IGNORECASE) - if m: - height = int(m.group(1)) - continue - - m = re.match(r"d (\d+)", parg, re.IGNORECASE) - if m: - seed = int(m.group(1)) - continue - - m = re.match(r"s (\d+)", parg, re.IGNORECASE) - if m: # steps - sample_steps = max(1, min(1000, int(m.group(1)))) - continue - - m = re.match(r"l ([\d\.]+)", parg, re.IGNORECASE) - if m: # scale - scale = float(m.group(1)) - continue - - m = re.match(r"n (.+)", parg, re.IGNORECASE) - if m: # negative prompt - negative_prompt = m.group(1) - continue - - m = re.match(r"cn (.+)", parg, re.IGNORECASE) - if m: # negative prompt - controlnet_image = m.group(1) - continue - - except ValueError as ex: - print(f"Exception in parsing / 解析エラー: {parg}") - print(ex) - - if seed is not None: - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - - if prompt_replacement is not None: - prompt = prompt.replace(prompt_replacement[0], prompt_replacement[1]) - if negative_prompt is not None: - negative_prompt = negative_prompt.replace(prompt_replacement[0], prompt_replacement[1]) - - if controlnet_image is not None: - controlnet_image = Image.open(controlnet_image).convert("RGB") - controlnet_image = controlnet_image.resize((width, height), Image.LANCZOS) - - height = max(64, height - height % 8) # round to divisible by 8 - width = max(64, width - width % 8) # round to divisible by 8 - print(f"prompt: {prompt}") - print(f"negative_prompt: {negative_prompt}") - print(f"height: {height}") - print(f"width: {width}") - print(f"sample_steps: {sample_steps}") - print(f"scale: {scale}") - image = pipeline( - prompt=prompt, - height=height, - width=width, - num_inference_steps=sample_steps, - guidance_scale=scale, - negative_prompt=negative_prompt, - controlnet=controlnet, - controlnet_image=controlnet_image, - ).images[0] - - ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) - num_suffix = f"e{epoch:06d}" if epoch is not None else f"{steps:06d}" - seed_suffix = "" if seed is None else f"_{seed}" - img_filename = ( - f"{'' if args.output_name is None else args.output_name + '_'}{ts_str}_{num_suffix}_{i:02d}{seed_suffix}.png" - ) + if isinstance(prompt, dict): + negative_prompt = prompt.get("negative_prompt") + sample_steps = prompt.get("sample_steps", 30) + width = prompt.get("width", 512) + height = prompt.get("height", 512) + scale = prompt.get("scale", 7.5) + seed = prompt.get("seed") + controlnet_image = prompt.get("controlnet_image") + prompt = prompt.get("prompt") + else: + # prompt = prompt.strip() + # if len(prompt) == 0 or prompt[0] == "#": + # continue + + # subset of gen_img_diffusers + prompt_args = prompt.split(" --") + prompt = prompt_args[0] + negative_prompt = None + sample_steps = 30 + width = height = 512 + scale = 7.5 + seed = None + controlnet_image = None + for parg in prompt_args: + try: + m = re.match(r"w (\d+)", parg, re.IGNORECASE) + if m: + width = int(m.group(1)) + continue + + m = re.match(r"h (\d+)", parg, re.IGNORECASE) + if m: + height = int(m.group(1)) + continue + + m = re.match(r"d (\d+)", parg, re.IGNORECASE) + if m: + seed = int(m.group(1)) + continue + + m = re.match(r"s (\d+)", parg, re.IGNORECASE) + if m: # steps + sample_steps = max(1, min(1000, int(m.group(1)))) + continue + + m = re.match(r"l ([\d\.]+)", parg, re.IGNORECASE) + if m: # scale + scale = float(m.group(1)) + continue + + m = re.match(r"n (.+)", parg, re.IGNORECASE) + if m: # negative prompt + negative_prompt = m.group(1) + continue + + m = re.match(r"cn (.+)", parg, re.IGNORECASE) + if m: # negative prompt + controlnet_image = m.group(1) + continue + + except ValueError as ex: + print(f"Exception in parsing / 解析エラー: {parg}") + print(ex) + + if seed is not None: + torch.manual_seed(seed) + torch.cuda.manual_seed(seed) + + if prompt_replacement is not None: + prompt = prompt.replace(prompt_replacement[0], prompt_replacement[1]) + if negative_prompt is not None: + negative_prompt = negative_prompt.replace(prompt_replacement[0], prompt_replacement[1]) + + if controlnet_image is not None: + controlnet_image = Image.open(controlnet_image).convert("RGB") + controlnet_image = controlnet_image.resize((width, height), Image.LANCZOS) + + height = max(64, height - height % 8) # round to divisible by 8 + width = max(64, width - width % 8) # round to divisible by 8 + print(f"prompt: {prompt}") + print(f"negative_prompt: {negative_prompt}") + print(f"height: {height}") + print(f"width: {width}") + print(f"sample_steps: {sample_steps}") + print(f"scale: {scale}") + image = pipeline( + prompt=prompt, + height=height, + width=width, + num_inference_steps=sample_steps, + guidance_scale=scale, + negative_prompt=negative_prompt, + controlnet=controlnet, + controlnet_image=controlnet_image, + ).images[0] + + ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) + num_suffix = f"e{epoch:06d}" if epoch is not None else f"{steps:06d}" + seed_suffix = "" if seed is None else f"_{seed}" + img_filename = ( + f"{'' if args.output_name is None else args.output_name + '_'}{ts_str}_{num_suffix}_{i:02d}{seed_suffix}.png" + ) - image.save(os.path.join(save_dir, img_filename)) + image.save(os.path.join(save_dir, img_filename)) - # wandb有効時のみログを送信 + # wandb有効時のみログを送信 + try: + wandb_tracker = accelerator.get_tracker("wandb") try: - wandb_tracker = accelerator.get_tracker("wandb") - try: - import wandb - except ImportError: # 事前に一度確認するのでここはエラー出ないはず - raise ImportError("No wandb / wandb がインストールされていないようです") + import wandb + except ImportError: # 事前に一度確認するのでここはエラー出ないはず + raise ImportError("No wandb / wandb がインストールされていないようです") - wandb_tracker.log({f"sample_{i}": wandb.Image(image)}) - except: # wandb 無効時 - pass + wandb_tracker.log({f"sample_{i}": wandb.Image(image)}) + except: # wandb 無効時 + pass # clear pipeline and cache to reduce vram usage del pipeline From 3c67e595b8b74ba9b652afd4e5acbc2eca9d5c4c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 12 Jul 2023 21:35:57 +0900 Subject: [PATCH 076/220] fix gradient accumulation doesn't work --- sdxl_train.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdxl_train.py b/sdxl_train.py index dd5b74dda..677bd466d 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -362,8 +362,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): loss_total = 0 for step, batch in enumerate(train_dataloader): current_step.value = global_step - # with accelerator.accumulate(training_models[0]): # 複数モデルに対応していない模様だがとりあえずこうしておく - if True: + with accelerator.accumulate(training_models[0]): # 複数モデルに対応していない模様だがとりあえずこうしておく if "latents" in batch and batch["latents"] is not None: latents = batch["latents"].to(accelerator.device).to(dtype=weight_dtype) else: From 8df948565a3e50a0322e6eb1443e50e916ebba47 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 12 Jul 2023 21:53:02 +0900 Subject: [PATCH 077/220] remove unnecessary code --- library/sdxl_original_unet.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/library/sdxl_original_unet.py b/library/sdxl_original_unet.py index 8ba1c988b..6ea4bc332 100644 --- a/library/sdxl_original_unet.py +++ b/library/sdxl_original_unet.py @@ -734,24 +734,6 @@ def forward(self, hidden_states, encoder_hidden_states=None, timestep=None): return output - def forward_xxx(self, hidden_states, encoder_hidden_states=None, timestep=None): - if self.training and self.gradient_checkpointing: - # print("Transformer2DModel: Using gradient checkpointing") - - def create_custom_forward(func): - def custom_forward(*inputs): - return func(*inputs) - - return custom_forward - - output = torch.utils.checkpoint.checkpoint( - create_custom_forward(self.forward_body), hidden_states, encoder_hidden_states, timestep - ) - else: - output = self.forward_body(hidden_states, encoder_hidden_states, timestep) - - return output - class Upsample2D(nn.Module): def __init__(self, channels, out_channels): From 8fa5fb28165a483a87508d8b101e37126b0f0543 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 12 Jul 2023 21:57:14 +0900 Subject: [PATCH 078/220] support diffusers format for SDXL --- library/sdxl_model_util.py | 225 ++++++++++++++++++++++++++++++++++++- library/sdxl_train_util.py | 84 +++++++++++--- requirements.txt | 2 +- sdxl_train.py | 4 +- 4 files changed, 291 insertions(+), 24 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index ae764b17f..41a05e950 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -1,7 +1,7 @@ import torch from safetensors.torch import load_file, save_file -from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection -from diffusers import AutoencoderKL +from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection, CLIPTokenizer +from diffusers import AutoencoderKL, EulerDiscreteScheduler, StableDiffusionXLPipeline, UNet2DConditionModel from library import model_util from library import sdxl_original_unet @@ -9,6 +9,57 @@ VAE_SCALE_FACTOR = 0.13025 MODEL_VERSION_SDXL_BASE_V0_9 = "sdxl_base_v0-9" +# Diffusersの設定を読み込むための参照モデル +DIFFUSERS_REF_MODEL_ID_SDXL = "stabilityai/stable-diffusion-xl-base-0.9" # アクセス権が必要 + +DIFFUSERS_SDXL_UNET_CONFIG = { + "act_fn": "silu", + "addition_embed_type": "text_time", + "addition_embed_type_num_heads": 64, + "addition_time_embed_dim": 256, + "attention_head_dim": [5, 10, 20], + "block_out_channels": [320, 640, 1280], + "center_input_sample": False, + "class_embed_type": None, + "class_embeddings_concat": False, + "conv_in_kernel": 3, + "conv_out_kernel": 3, + "cross_attention_dim": 2048, + "cross_attention_norm": None, + "down_block_types": ["DownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D"], + "downsample_padding": 1, + "dual_cross_attention": False, + "encoder_hid_dim": None, + "encoder_hid_dim_type": None, + "flip_sin_to_cos": True, + "freq_shift": 0, + "in_channels": 4, + "layers_per_block": 2, + "mid_block_only_cross_attention": None, + "mid_block_scale_factor": 1, + "mid_block_type": "UNetMidBlock2DCrossAttn", + "norm_eps": 1e-05, + "norm_num_groups": 32, + "num_attention_heads": None, + "num_class_embeds": None, + "only_cross_attention": False, + "out_channels": 4, + "projection_class_embeddings_input_dim": 2816, + "resnet_out_scale_factor": 1.0, + "resnet_skip_time_act": False, + "resnet_time_scale_shift": "default", + "sample_size": 128, + "time_cond_proj_dim": None, + "time_embedding_act_fn": None, + "time_embedding_dim": None, + "time_embedding_type": "positional", + "timestep_post_act": None, + "transformer_layers_per_block": [1, 2, 10], + "up_block_types": ["CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "UpBlock2D"], + "upcast_attention": False, + "use_linear_projection": True, +} + def convert_sdxl_text_encoder_2_checkpoint(checkpoint, max_length): SDXL_KEY_PREFIX = "conditioner.embedders.1.model." @@ -119,7 +170,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): # Text Encoders print("building text encoders") - # Text Encoder 1 is same to SDXL + # Text Encoder 1 is same to Stability AI's SDXL text_model1_cfg = CLIPTextConfig( vocab_size=49408, hidden_size=768, @@ -143,7 +194,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): ) text_model1 = CLIPTextModel._from_config(text_model1_cfg) - # Text Encoder 2 is different from SDXL. SDXL uses open clip, but we use the model from HuggingFace. + # Text Encoder 2 is different from Stability AI's SDXL. SDXL uses open clip, but we use the model from HuggingFace. # Note: Tokenizer from HuggingFace is different from SDXL. We must use open clip's tokenizer. text_model2_cfg = CLIPTextConfig( vocab_size=49408, @@ -198,6 +249,122 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): return text_model1, text_model2, vae, unet, logit_scale, ckpt_info +def make_unet_conversion_map(): + unet_conversion_map_layer = [] + + for i in range(3): # num_blocks is 3 in sdxl + # loop over downblocks/upblocks + for j in range(2): + # loop over resnets/attentions for downblocks + hf_down_res_prefix = f"down_blocks.{i}.resnets.{j}." + sd_down_res_prefix = f"input_blocks.{3*i + j + 1}.0." + unet_conversion_map_layer.append((sd_down_res_prefix, hf_down_res_prefix)) + + if i < 3: + # no attention layers in down_blocks.3 + hf_down_atn_prefix = f"down_blocks.{i}.attentions.{j}." + sd_down_atn_prefix = f"input_blocks.{3*i + j + 1}.1." + unet_conversion_map_layer.append((sd_down_atn_prefix, hf_down_atn_prefix)) + + for j in range(3): + # loop over resnets/attentions for upblocks + hf_up_res_prefix = f"up_blocks.{i}.resnets.{j}." + sd_up_res_prefix = f"output_blocks.{3*i + j}.0." + unet_conversion_map_layer.append((sd_up_res_prefix, hf_up_res_prefix)) + + # if i > 0: commentout for sdxl + # no attention layers in up_blocks.0 + hf_up_atn_prefix = f"up_blocks.{i}.attentions.{j}." + sd_up_atn_prefix = f"output_blocks.{3*i + j}.1." + unet_conversion_map_layer.append((sd_up_atn_prefix, hf_up_atn_prefix)) + + if i < 3: + # no downsample in down_blocks.3 + hf_downsample_prefix = f"down_blocks.{i}.downsamplers.0.conv." + sd_downsample_prefix = f"input_blocks.{3*(i+1)}.0.op." + unet_conversion_map_layer.append((sd_downsample_prefix, hf_downsample_prefix)) + + # no upsample in up_blocks.3 + hf_upsample_prefix = f"up_blocks.{i}.upsamplers.0." + sd_upsample_prefix = f"output_blocks.{3*i + 2}.{2}." # change for sdxl + unet_conversion_map_layer.append((sd_upsample_prefix, hf_upsample_prefix)) + + hf_mid_atn_prefix = "mid_block.attentions.0." + sd_mid_atn_prefix = "middle_block.1." + unet_conversion_map_layer.append((sd_mid_atn_prefix, hf_mid_atn_prefix)) + + for j in range(2): + hf_mid_res_prefix = f"mid_block.resnets.{j}." + sd_mid_res_prefix = f"middle_block.{2*j}." + unet_conversion_map_layer.append((sd_mid_res_prefix, hf_mid_res_prefix)) + + unet_conversion_map_resnet = [ + # (stable-diffusion, HF Diffusers) + ("in_layers.0.", "norm1."), + ("in_layers.2.", "conv1."), + ("out_layers.0.", "norm2."), + ("out_layers.3.", "conv2."), + ("emb_layers.1.", "time_emb_proj."), + ("skip_connection.", "conv_shortcut."), + ] + + unet_conversion_map = [] + for sd, hf in unet_conversion_map_layer: + if "resnets" in hf: + for sd_res, hf_res in unet_conversion_map_resnet: + unet_conversion_map.append((sd + sd_res, hf + hf_res)) + else: + unet_conversion_map.append((sd, hf)) + + for j in range(2): + hf_time_embed_prefix = f"time_embedding.linear_{j+1}." + sd_time_embed_prefix = f"time_embed.{j*2}." + unet_conversion_map.append((sd_time_embed_prefix, hf_time_embed_prefix)) + + for j in range(2): + hf_label_embed_prefix = f"add_embedding.linear_{j+1}." + sd_label_embed_prefix = f"label_emb.0.{j*2}." + unet_conversion_map.append((sd_label_embed_prefix, hf_label_embed_prefix)) + + unet_conversion_map.append(("input_blocks.0.0.", "conv_in.")) + unet_conversion_map.append(("out.0.", "conv_norm_out.")) + unet_conversion_map.append(("out.2.", "conv_out.")) + + return unet_conversion_map + + +def convert_diffusers_unet_state_dict_to_sdxl(du_sd): + unet_conversion_map = make_unet_conversion_map() + + conversion_map = {hf: sd for sd, hf in unet_conversion_map} + return convert_unet_state_dict(du_sd, conversion_map) + + +def convert_unet_state_dict(src_sd, conversion_map): + converted_sd = {} + for src_key, value in src_sd.items(): + # さすがに全部回すのは時間がかかるので右から要素を削りつつprefixを探す + src_key_fragments = src_key.split(".")[:-1] # remove weight/bias + while len(src_key_fragments) > 0: + src_key_prefix = ".".join(src_key_fragments) + "." + if src_key_prefix in conversion_map: + converted_prefix = conversion_map[src_key_prefix] + converted_key = converted_prefix + src_key[len(src_key_prefix) :] + converted_sd[converted_key] = value + break + src_key_fragments.pop(-1) + assert len(src_key_fragments) > 0, f"key {src_key} not found in conversion map" + + return converted_sd + + +def convert_sdxl_unet_state_dict_to_diffusers(sd): + unet_conversion_map = make_unet_conversion_map() + + conversion_dict = {sd: hf for sd, hf in unet_conversion_map} + return convert_unet_state_dict(sd, conversion_dict) + + def convert_text_encoder_2_state_dict_to_sdxl(checkpoint, logit_scale): def convert_key(key): # position_idsの除去 @@ -314,3 +481,53 @@ def update_sd(prefix, sd): torch.save(new_ckpt, output_file) return key_count + + +def save_diffusers_checkpoint( + output_dir, text_encoder1, text_encoder2, unet, pretrained_model_name_or_path, vae=None, use_safetensors=False, save_dtype=None +): + # convert U-Net + unet_sd = unet.state_dict() + du_unet_sd = convert_sdxl_unet_state_dict_to_diffusers(unet_sd) + + diffusers_unet = UNet2DConditionModel(**DIFFUSERS_SDXL_UNET_CONFIG) + if save_dtype is not None: + diffusers_unet.to(save_dtype) + diffusers_unet.load_state_dict(du_unet_sd) + + # create pipeline to save + if pretrained_model_name_or_path is None: + pretrained_model_name_or_path = DIFFUSERS_REF_MODEL_ID_SDXL + + scheduler = EulerDiscreteScheduler.from_pretrained(pretrained_model_name_or_path, subfolder="scheduler") + tokenizer1 = CLIPTokenizer.from_pretrained(pretrained_model_name_or_path, subfolder="tokenizer") + tokenizer2 = CLIPTokenizer.from_pretrained(pretrained_model_name_or_path, subfolder="tokenizer_2") + if vae is None: + vae = AutoencoderKL.from_pretrained(pretrained_model_name_or_path, subfolder="vae") + + # prevent local path from being saved + def remove_name_or_path(model): + if hasattr(model, "config"): + model.config._name_or_path = None + model.config._name_or_path = None + + remove_name_or_path(diffusers_unet) + remove_name_or_path(text_encoder1) + remove_name_or_path(text_encoder2) + remove_name_or_path(scheduler) + remove_name_or_path(tokenizer1) + remove_name_or_path(tokenizer2) + remove_name_or_path(vae) + + pipeline = StableDiffusionXLPipeline( + unet=diffusers_unet, + text_encoder=text_encoder1, + text_encoder_2=text_encoder2, + vae=vae, + scheduler=scheduler, + tokenizer=tokenizer1, + tokenizer_2=tokenizer2, + ) + if save_dtype is not None: + pipeline.to(None, save_dtype) + pipeline.save_pretrained(output_dir, safe_serialization=use_safetensors) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 0ce097158..a14807774 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -8,7 +8,8 @@ from tqdm import tqdm from transformers import CLIPTokenizer import open_clip -from library import model_util, sdxl_model_util, train_util +from diffusers import StableDiffusionXLPipeline +from library import model_util, sdxl_model_util, train_util, sdxl_original_unet from library.sdxl_lpw_stable_diffusion import SdxlStableDiffusionLongPromptWeightingPipeline TOKENIZER_PATH = "openai/clip-vit-large-patch14" @@ -50,23 +51,54 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtype, device="cpu"): - # only supports StableDiffusion name_or_path = args.pretrained_model_name_or_path name_or_path = os.readlink(name_or_path) if os.path.islink(name_or_path) else name_or_path load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers - assert ( - load_stable_diffusion_format - ), f"only supports StableDiffusion format for SDXL / SDXLではStableDiffusion形式のみサポートしています: {name_or_path}" - - print(f"load StableDiffusion checkpoint: {name_or_path}") - ( - text_encoder1, - text_encoder2, - vae, - unet, - logit_scale, - ckpt_info, - ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) + + if load_stable_diffusion_format: + print(f"load StableDiffusion checkpoint: {name_or_path}") + ( + text_encoder1, + text_encoder2, + vae, + unet, + logit_scale, + ckpt_info, + ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) + else: + # Diffusers model is loaded to CPU + variant = "fp16" if weight_dtype == torch.float16 else None + print(f"load Diffusers pretrained models: {name_or_path}, variant={variant}") + try: + try: + pipe = StableDiffusionXLPipeline.from_pretrained(name_or_path, variant=variant, tokenizer=None) + except EnvironmentError as ex: + if variant is not None: + print("try to load fp32 model") + pipe = StableDiffusionXLPipeline.from_pretrained(name_or_path, variant=None, tokenizer=None) + else: + raise ex + except EnvironmentError as ex: + print( + f"model is not found as a file or in Hugging Face, perhaps file name is wrong? / 指定したモデル名のファイル、またはHugging Faceのモデルが見つかりません。ファイル名が誤っているかもしれません: {name_or_path}" + ) + raise ex + + text_encoder1 = pipe.text_encoder + text_encoder2 = pipe.text_encoder_2 + vae = pipe.vae + unet = pipe.unet + del pipe + + # Diffusers U-Net to original U-Net + original_unet = sdxl_original_unet.SdxlUNet2DConditionModel() + state_dict = sdxl_model_util.convert_diffusers_unet_state_dict_to_sdxl(unet.state_dict()) + original_unet.load_state_dict(state_dict) + unet = original_unet + print("U-Net converted to original U-Net") + + logit_scale = None + ckpt_info = None # VAEを読み込む if args.vae is not None: @@ -296,7 +328,16 @@ def sd_saver(ckpt_file, epoch_no, global_step): ) def diffusers_saver(out_dir): - raise NotImplementedError("diffusers_saver is not implemented") + sdxl_model_util.save_diffusers_checkpoint( + out_dir, + text_encoder1, + text_encoder2, + unet, + src_path, + vae, + use_safetensors=use_safetensors, + save_dtype=save_dtype, + ) train_util.save_sd_model_on_train_end_common( args, save_stable_diffusion_format, use_safetensors, epoch, global_step, sd_saver, diffusers_saver @@ -338,7 +379,16 @@ def sd_saver(ckpt_file, epoch_no, global_step): ) def diffusers_saver(out_dir): - raise NotImplementedError("diffusers_saver is not implemented") + sdxl_model_util.save_diffusers_checkpoint( + out_dir, + text_encoder1, + text_encoder2, + unet, + src_path, + vae, + use_safetensors=use_safetensors, + save_dtype=save_dtype, + ) train_util.save_sd_model_on_epoch_end_or_stepwise_common( args, diff --git a/requirements.txt b/requirements.txt index 86c48a19c..da9ed9427 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ accelerate==0.19.0 transformers==4.30.2 -diffusers[torch]==0.17.1 +diffusers[torch]==0.18.2 ftfy==6.1.1 albumentations==1.3.0 opencv-python==4.7.0.68 diff --git a/sdxl_train.py b/sdxl_train.py index 677bd466d..935992bf9 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -171,7 +171,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # set_diffusers_xformers_flag(unet, True) set_diffusers_xformers_flag(vae, True) else: - # Windows版のxformersはfloatで学習できなかったりxformersを使わない設定も可能にしておく必要がある + # Windows版のxformersはfloatで学習できなかったりするのでxformersを使わない設定も可能にしておく必要がある accelerator.print("Disable Diffusers' xformers") train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) vae.set_use_memory_efficient_attention_xformers(args.xformers) @@ -271,7 +271,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # lr schedulerを用意する lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) - # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする + # 実験的機能:勾配も含めたfp16/bf16学習を行う モデル全体をfp16にする if args.full_fp16: assert ( args.mixed_precision == "fp16" From a7ce2633f3a9eb9488714ceade0e7009874cef9a Mon Sep 17 00:00:00 2001 From: kaibioinfo Date: Wed, 12 Jul 2023 15:06:20 +0200 Subject: [PATCH 079/220] fix typo in sdxl_train_textual_inversion bug appears when continue training on an existing TI --- sdxl_train_textual_inversion.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdxl_train_textual_inversion.py b/sdxl_train_textual_inversion.py index 9df370927..942d9e74e 100644 --- a/sdxl_train_textual_inversion.py +++ b/sdxl_train_textual_inversion.py @@ -115,8 +115,8 @@ def load_weights(self, file): else: data = torch.load(file, map_location="cpu") - emb_l = data.get("clib_l", None) # ViT-L text encoder 1 - emb_g = data.get("clib_g", None) # BiG-G text encoder 2 + emb_l = data.get("clip_l", None) # ViT-L text encoder 1 + emb_g = data.get("clip_g", None) # BiG-G text encoder 2 assert ( emb_l is not None or emb_g is not None From cdffd19f61d8b6d8c22f2778a4e3eb3bd44aeb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Forst=C3=A9n?= Date: Thu, 13 Jul 2023 12:45:28 +0300 Subject: [PATCH 080/220] Cast weights to correct precision before transferring them to GPU --- train_network.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/train_network.py b/train_network.py index f7ee451b1..e4c00524f 100644 --- a/train_network.py +++ b/train_network.py @@ -358,6 +358,11 @@ def train(self, args): accelerator.print("enable full fp16 training.") network.to(weight_dtype) + unet.requires_grad_(False) + unet.to(dtype=weight_dtype) + for t_enc in text_encoders: + t_enc.requires_grad_(False) + # acceleratorがなんかよろしくやってくれるらしい # TODO めちゃくちゃ冗長なのでコードを整理する if train_unet and train_text_encoder: @@ -397,11 +402,6 @@ def train(self, args): text_encoders = train_util.transform_models_if_DDP(text_encoders) unet, network = train_util.transform_models_if_DDP([unet, network]) - unet.requires_grad_(False) - unet.to(accelerator.device, dtype=weight_dtype) - for t_enc in text_encoders: - t_enc.requires_grad_(False) - if args.gradient_checkpointing: # according to TI example in Diffusers, train is required unet.train() From 3bb80ebf20e8d1cc2f2d29789d258f8ca75976e0 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 13 Jul 2023 19:02:34 +0900 Subject: [PATCH 081/220] fix sampling gen fails in lora training --- library/sdxl_lpw_stable_diffusion.py | 1 + 1 file changed, 1 insertion(+) diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index 99b0bc8d5..a65a1d967 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -1005,6 +1005,7 @@ def __call__( # predict the noise residual noise_pred = self.unet(latent_model_input, t, text_embedding, vector_embedding) + noise_pred = noise_pred.to(dtype) # U-Net changes dtype in LoRA training # perform guidance if do_classifier_free_guidance: From b4a3824ce4b98369129339c2502b5200e955b18a Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 13 Jul 2023 20:49:26 +0900 Subject: [PATCH 082/220] change tokenizer from open clip to transformers --- library/sdxl_train_util.py | 106 ++++++-------------------------- sdxl_gen_img.py | 10 +-- sdxl_train_textual_inversion.py | 12 ---- train_textual_inversion.py | 15 ++--- 4 files changed, 27 insertions(+), 116 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index a14807774..4fc14bf2e 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -12,7 +12,8 @@ from library import model_util, sdxl_model_util, train_util, sdxl_original_unet from library.sdxl_lpw_stable_diffusion import SdxlStableDiffusionLongPromptWeightingPipeline -TOKENIZER_PATH = "openai/clip-vit-large-patch14" +TOKENIZER1_PATH = "openai/clip-vit-large-patch14" +TOKENIZER2_PATH = "laion/CLIP-ViT-bigG-14-laion2B-39B-b160k" DEFAULT_NOISE_OFFSET = 0.0357 @@ -108,101 +109,32 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, logit_scale, ckpt_info -class WrapperTokenizer: - # open clipのtokenizerをHuggingFaceのtokenizerと同じ形で使えるようにする - # make open clip tokenizer compatible with HuggingFace tokenizer - def __init__(self): - open_clip_tokenizer = open_clip.tokenizer._tokenizer - self.model_max_length = 77 - self.bos_token_id = open_clip_tokenizer.all_special_ids[0] - self.eos_token_id = open_clip_tokenizer.all_special_ids[1] - self.pad_token_id = 0 # 結果から推定している assumption from result - - def __call__(self, *args: Any, **kwds: Any) -> Any: - return self.tokenize(*args, **kwds) - - def tokenize(self, text, padding=False, truncation=None, max_length=None, return_tensors=None): - if padding == "max_length": - # for training - assert max_length is not None - assert truncation == True - assert return_tensors == "pt" - input_ids = open_clip.tokenize(text, context_length=max_length) - return SimpleNamespace(**{"input_ids": input_ids}) - - # for weighted prompt - assert isinstance(text, str), f"input must be str: {text}" - - input_ids = open_clip.tokenize(text, context_length=self.model_max_length)[0] # tokenizer returns list - - # find eos - eos_index = (input_ids == self.eos_token_id).nonzero().max() - input_ids = input_ids[: eos_index + 1] # include eos - return SimpleNamespace(**{"input_ids": input_ids}) - - # for Textual Inversion - # わりと面倒くさいな……これWeb UIとかでどうするんだろう / this is a bit annoying... how to do this in Web UI? - - def encode(self, text, add_special_tokens=False): - assert not add_special_tokens - input_ids = open_clip.tokenizer._tokenizer.encode(text) - return input_ids - - def add_tokens(self, new_tokens): - tokens_to_add = [] - for token in new_tokens: - token = token.lower() - if token + "" not in open_clip.tokenizer._tokenizer.encoder: - tokens_to_add.append(token) - - # open clipのtokenizerに直接追加する / add tokens to open clip tokenizer - for token in tokens_to_add: - open_clip.tokenizer._tokenizer.encoder[token + ""] = len(open_clip.tokenizer._tokenizer.encoder) - open_clip.tokenizer._tokenizer.decoder[len(open_clip.tokenizer._tokenizer.decoder)] = token + "" - open_clip.tokenizer._tokenizer.vocab_size += 1 - - # open clipのtokenizerのcacheに直接設定することで、bpeとかいうやつに含まれていなくてもtokenizeできるようにする - # めちゃくちゃ乱暴なので、open clipのtokenizerの仕様が変わったら動かなくなる - # set cache of open clip tokenizer directly to enable tokenization even if the token is not included in bpe - # this is very rough, so it will not work if the specification of open clip tokenizer changes - open_clip.tokenizer._tokenizer.cache[token] = token + "" - - return len(tokens_to_add) - - def convert_tokens_to_ids(self, tokens): - input_ids = [open_clip.tokenizer._tokenizer.encoder[token + ""] for token in tokens] - return input_ids - - def __len__(self): - return open_clip.tokenizer._tokenizer.vocab_size - - def load_tokenizers(args: argparse.Namespace): print("prepare tokenizers") - original_path = TOKENIZER_PATH - tokenizer1: CLIPTokenizer = None - if args.tokenizer_cache_dir: - local_tokenizer_path = os.path.join(args.tokenizer_cache_dir, original_path.replace("/", "_")) - if os.path.exists(local_tokenizer_path): - print(f"load tokenizer from cache: {local_tokenizer_path}") - tokenizer1 = CLIPTokenizer.from_pretrained(local_tokenizer_path) + original_paths = [TOKENIZER1_PATH, TOKENIZER2_PATH] + tokeniers = [] + for original_path in original_paths: + tokenizer: CLIPTokenizer = None + if args.tokenizer_cache_dir: + local_tokenizer_path = os.path.join(args.tokenizer_cache_dir, original_path.replace("/", "_")) + if os.path.exists(local_tokenizer_path): + print(f"load tokenizer from cache: {local_tokenizer_path}") + tokenizer = CLIPTokenizer.from_pretrained(local_tokenizer_path) - if tokenizer1 is None: - tokenizer1 = CLIPTokenizer.from_pretrained(original_path) + if tokenizer is None: + tokenizer = CLIPTokenizer.from_pretrained(original_path) - if args.tokenizer_cache_dir and not os.path.exists(local_tokenizer_path): - print(f"save Tokenizer to cache: {local_tokenizer_path}") - tokenizer1.save_pretrained(local_tokenizer_path) + if args.tokenizer_cache_dir and not os.path.exists(local_tokenizer_path): + print(f"save Tokenizer to cache: {local_tokenizer_path}") + tokenizer.save_pretrained(local_tokenizer_path) + + tokeniers.append(tokenizer) if hasattr(args, "max_token_length") and args.max_token_length is not None: print(f"update token length: {args.max_token_length}") - # tokenizer2 is from open_clip - # TODO caching - tokenizer2 = WrapperTokenizer() - - return [tokenizer1, tokenizer2] + return tokeniers def get_hidden_states( diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py index 1e20595cc..cc9e8a280 100644 --- a/sdxl_gen_img.py +++ b/sdxl_gen_img.py @@ -1605,18 +1605,14 @@ def __getattr__(self, item): num_vectors_per_token = embeds1.size()[0] token_string = os.path.splitext(os.path.basename(embeds_file))[0] - # remove non-alphabet characters to avoid splitting by tokenizer - # TODO make random alphabet string - token_string = "".join([c for c in token_string if c.isalpha()]) - - token_strings = [token_string] + [f"{token_string}{chr(ord('a') + i)}" for i in range(num_vectors_per_token - 1)] + token_strings = [token_string] + [f"{token_string}{i+1}" for i in range(num_vectors_per_token - 1)] # add new word to tokenizer, count is num_vectors_per_token num_added_tokens1 = tokenizer1.add_tokens(token_strings) num_added_tokens2 = tokenizer2.add_tokens(token_strings) assert num_added_tokens1 == num_vectors_per_token and num_added_tokens2 == num_vectors_per_token, ( - f"tokenizer has same word to token string (filename). characters except alphabet are removed: {embeds_file}" - + f" / 指定した名前(ファイル名)のトークンが既に存在します。アルファベット以外の文字は削除されます: {embeds_file}" + f"tokenizer has same word to token string (filename): {embeds_file}" + + f" / 指定した名前(ファイル名)のトークンが既に存在します: {embeds_file}" ) token_ids1 = tokenizer1.convert_tokens_to_ids(token_strings) diff --git a/sdxl_train_textual_inversion.py b/sdxl_train_textual_inversion.py index 9df370927..2616a22c6 100644 --- a/sdxl_train_textual_inversion.py +++ b/sdxl_train_textual_inversion.py @@ -39,18 +39,6 @@ def load_tokenizer(self, args): tokenizer = sdxl_train_util.load_tokenizers(args) return tokenizer - def assert_token_string(self, token_string, tokenizers): - # tokenizer 1 is seems to be ok - - # count words for token string: regular expression from open_clip - pat = regex.compile(r"""'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", regex.IGNORECASE) - words = regex.findall(pat, token_string) - word_count = len(words) - assert word_count == 1, ( - f"token string {token_string} contain {word_count} words, please don't use digits, punctuation, or special characters" - + f" / トークン文字列 {token_string} には{word_count}個の単語が含まれています。数字、句読点、特殊文字は使用しないでください" - ) - def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): input_ids1 = batch["input_ids"] input_ids2 = batch["input_ids2"] diff --git a/train_textual_inversion.py b/train_textual_inversion.py index cbfd48ce7..7be8ba809 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -8,6 +8,7 @@ import torch from accelerate.utils import set_seed from diffusers import DDPMScheduler +from transformers import CLIPTokenizer from library import model_util import library.train_util as train_util @@ -92,7 +93,7 @@ def load_tokenizer(self, args): tokenizer = train_util.load_tokenizer(args) return tokenizer - def assert_token_string(self, token_string, tokenizers): + def assert_token_string(self, token_string, tokenizers: CLIPTokenizer): pass def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): @@ -200,19 +201,13 @@ def train(self, args): init_token_ids_list = [None] * len(tokenizers) # tokenizerに新しい単語を追加する。追加する単語の数はnum_vectors_per_token + # token_stringが hoge の場合、"hoge", "hoge1", "hoge2", ... が追加される # add new word to tokenizer, count is num_vectors_per_token - - # token_stringが hoge の場合、"hoge", "hogea", "hogeb", ... が追加される - # 当初は "hoge", "hoge1", "hoge2", ... としていたが、open clipのtokenizerは数字を含む単語を分割してしまうため(;^ω^)、a, b, ... とした - - # if token_string is hoge, "hoge", "hogea", "hogeb", ... are added - # originally, "hoge", "hoge1", "hoge2", ... were used, but open clip's tokenizer splits words including numbers (;^ω^), so a, b, ... are used + # if token_string is hoge, "hoge", "hoge1", "hoge2", ... are added self.assert_token_string(args.token_string, tokenizers) - token_strings = [args.token_string] + [ - f"{args.token_string}{chr(ord('a') + i)}" for i in range(args.num_vectors_per_token - 1) - ] + token_strings = [args.token_string] + [f"{args.token_string}{i+1}" for i in range(args.num_vectors_per_token - 1)] token_ids_list = [] token_embeds_list = [] for i, (tokenizer, text_encoder, init_token_ids) in enumerate(zip(tokenizers, text_encoders, init_token_ids_list)): From 9de357e3739967284bca0dc4b1c7636b0ac31950 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Fri, 14 Jul 2023 12:27:19 +0900 Subject: [PATCH 083/220] fix tokenizer 2 is not same as open clip tokenizer --- library/sdxl_train_util.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 4fc14bf2e..a93ef502a 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -114,7 +114,7 @@ def load_tokenizers(args: argparse.Namespace): original_paths = [TOKENIZER1_PATH, TOKENIZER2_PATH] tokeniers = [] - for original_path in original_paths: + for i, original_path in enumerate(original_paths): tokenizer: CLIPTokenizer = None if args.tokenizer_cache_dir: local_tokenizer_path = os.path.join(args.tokenizer_cache_dir, original_path.replace("/", "_")) @@ -129,6 +129,9 @@ def load_tokenizers(args: argparse.Namespace): print(f"save Tokenizer to cache: {local_tokenizer_path}") tokenizer.save_pretrained(local_tokenizer_path) + if i == 1: + tokenizer.pad_token_id = 0 # fix pad token id to make same as open clip tokenizer + tokeniers.append(tokenizer) if hasattr(args, "max_token_length") and args.max_token_length is not None: From 81fa54837f538a2c9d294d1aa66a45421edeeaee Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 15 Jul 2023 11:21:14 +0900 Subject: [PATCH 084/220] fix sampling in multi GPU training --- library/lpw_stable_diffusion.py | 33 +++++++++++----------------- library/sdxl_lpw_stable_diffusion.py | 21 ++++++------------ library/train_util.py | 23 ++++++++++--------- 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/library/lpw_stable_diffusion.py b/library/lpw_stable_diffusion.py index 2605c8642..9dce91a76 100644 --- a/library/lpw_stable_diffusion.py +++ b/library/lpw_stable_diffusion.py @@ -446,9 +446,7 @@ def prepare_controlnet_image( for image_ in image: image_ = image_.convert("RGB") - image_ = image_.resize( - (width, height), resample=PIL_INTERPOLATION["lanczos"] - ) + image_ = image_.resize((width, height), resample=PIL_INTERPOLATION["lanczos"]) image_ = np.array(image_) image_ = image_[None, :] images.append(image_) @@ -479,6 +477,7 @@ def prepare_controlnet_image( return image + class StableDiffusionLongPromptWeightingPipeline(StableDiffusionPipeline): r""" Pipeline for text-to-image generation using Stable Diffusion without tokens length limit, and support parsing @@ -889,8 +888,9 @@ def __call__( mask = None if controlnet_image is not None: - controlnet_image = prepare_controlnet_image(controlnet_image, width, height, batch_size, 1, self.device, controlnet.dtype, do_classifier_free_guidance, False) - + controlnet_image = prepare_controlnet_image( + controlnet_image, width, height, batch_size, 1, self.device, controlnet.dtype, do_classifier_free_guidance, False + ) # 5. set timesteps self.scheduler.set_timesteps(num_inference_steps, device=device) @@ -930,8 +930,8 @@ def __call__( guess_mode=False, return_dict=False, ) - unet_additional_args['down_block_additional_residuals'] = down_block_res_samples - unet_additional_args['mid_block_additional_residual'] = mid_block_res_sample + unet_additional_args["down_block_additional_residuals"] = down_block_res_samples + unet_additional_args["mid_block_additional_residual"] = mid_block_res_sample # predict the noise residual noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings, **unet_additional_args).sample @@ -956,20 +956,13 @@ def __call__( if is_cancelled_callback is not None and is_cancelled_callback(): return None - # 9. Post-processing - image = self.decode_latents(latents) - - # 10. Run safety checker - image, has_nsfw_concept = self.run_safety_checker(image, device, text_embeddings.dtype) - - # 11. Convert to PIL - if output_type == "pil": - image = self.numpy_to_pil(image) - - if not return_dict: - return image, has_nsfw_concept + return latents - return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept) + def latents_to_image(self, latents): + # 9. Post-processing + image = self.decode_latents(latents.to(self.vae.dtype)) + image = self.numpy_to_pil(image) + return image def text2img( self, diff --git a/library/sdxl_lpw_stable_diffusion.py b/library/sdxl_lpw_stable_diffusion.py index a65a1d967..7f88469f8 100644 --- a/library/sdxl_lpw_stable_diffusion.py +++ b/library/sdxl_lpw_stable_diffusion.py @@ -1005,7 +1005,7 @@ def __call__( # predict the noise residual noise_pred = self.unet(latent_model_input, t, text_embedding, vector_embedding) - noise_pred = noise_pred.to(dtype) # U-Net changes dtype in LoRA training + noise_pred = noise_pred.to(dtype) # U-Net changes dtype in LoRA training # perform guidance if do_classifier_free_guidance: @@ -1027,20 +1027,13 @@ def __call__( if is_cancelled_callback is not None and is_cancelled_callback(): return None - # 9. Post-processing - image = self.decode_latents(latents.to(torch.float32)) - - # 10. Run safety checker - image, has_nsfw_concept = image, None # self.run_safety_checker(image, device, text_embeddings.dtype) - - # 11. Convert to PIL - if output_type == "pil": - image = self.numpy_to_pil(image) + return latents - if not return_dict: - return image, has_nsfw_concept - - return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept) + def latents_to_image(self, latents): + # 9. Post-processing + image = self.decode_latents(latents.to(self.vae.dtype)) + image = self.numpy_to_pil(image) + return image # copy from pil_utils.py def numpy_to_pil(self, images: np.ndarray) -> Image.Image: diff --git a/library/train_util.py b/library/train_util.py index 9438a1895..15c58cc8c 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3964,16 +3964,19 @@ def sample_images_common( print(f"width: {width}") print(f"sample_steps: {sample_steps}") print(f"scale: {scale}") - image = pipeline( - prompt=prompt, - height=height, - width=width, - num_inference_steps=sample_steps, - guidance_scale=scale, - negative_prompt=negative_prompt, - controlnet=controlnet, - controlnet_image=controlnet_image, - ).images[0] + with accelerator.autocast(): + latents = pipeline( + prompt=prompt, + height=height, + width=width, + num_inference_steps=sample_steps, + guidance_scale=scale, + negative_prompt=negative_prompt, + controlnet=controlnet, + controlnet_image=controlnet_image, + ) + + image = pipeline.latents_to_image(latents)[0] ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) num_suffix = f"e{epoch:06d}" if epoch is not None else f"{steps:06d}" From 94c151aea33917ed1a0e938b9f571f83c1e17165 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 15 Jul 2023 18:28:33 +0900 Subject: [PATCH 085/220] refactor caching latents (flip in same npz, etc) --- finetune/prepare_buckets_latents.py | 114 +--------- library/train_util.py | 341 +++++++++++++++++----------- tools/cache_latents.py | 193 ++++++++++++++++ 3 files changed, 409 insertions(+), 239 deletions(-) create mode 100644 tools/cache_latents.py diff --git a/finetune/prepare_buckets_latents.py b/finetune/prepare_buckets_latents.py index 6bb1c32fe..1dde22942 100644 --- a/finetune/prepare_buckets_latents.py +++ b/finetune/prepare_buckets_latents.py @@ -34,22 +34,7 @@ def collate_fn_remove_corrupted(batch): return batch -def get_latents(vae, key_and_images, weight_dtype): - img_tensors = [IMAGE_TRANSFORMS(image) for _, image in key_and_images] - img_tensors = torch.stack(img_tensors) - img_tensors = img_tensors.to(DEVICE, weight_dtype) - with torch.no_grad(): - latents = vae.encode(img_tensors).latent_dist.sample() - - # check NaN - for (key, _), latents1 in zip(key_and_images, latents): - if torch.isnan(latents1).any(): - raise ValueError(f"NaN detected in latents of {key}") - - return latents - - -def get_npz_filename_wo_ext(data_dir, image_key, is_full_path, flip, recursive): +def get_npz_filename(data_dir, image_key, is_full_path, recursive): if is_full_path: base_name = os.path.splitext(os.path.basename(image_key))[0] relative_path = os.path.relpath(os.path.dirname(image_key), data_dir) @@ -57,13 +42,10 @@ def get_npz_filename_wo_ext(data_dir, image_key, is_full_path, flip, recursive): base_name = image_key relative_path = "" - if flip: - base_name += "_flip" - if recursive and relative_path: - return os.path.join(data_dir, relative_path, base_name) + return os.path.join(data_dir, relative_path, base_name) + ".npz" else: - return os.path.join(data_dir, base_name) + return os.path.join(data_dir, base_name) + ".npz" def main(args): @@ -113,36 +95,7 @@ def main(args): def process_batch(is_last): for bucket in bucket_manager.buckets: if (is_last and len(bucket) > 0) or len(bucket) >= args.batch_size: - latents = get_latents(vae, [(key, img) for key, img, _, _ in bucket], weight_dtype) - assert ( - latents.shape[2] == bucket[0][1].shape[0] // 8 and latents.shape[3] == bucket[0][1].shape[1] // 8 - ), f"latent shape {latents.shape}, {bucket[0][1].shape}" - - for (image_key, _, original_size, crop_left_top), latent in zip(bucket, latents): - npz_file_name = get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, False, args.recursive) - train_util.save_latents_to_disk(npz_file_name, latent, original_size, crop_left_top) - - # flip - if args.flip_aug: - latents = get_latents( - vae, [(key, img[:, ::-1].copy()) for key, img, _, _ in bucket], weight_dtype - ) # copyがないとTensor変換できない - - for (image_key, _, original_size, crop_left_top), latent in zip(bucket, latents): - npz_file_name = get_npz_filename_wo_ext( - args.train_data_dir, image_key, args.full_path, True, args.recursive - ) - train_util.save_latents_to_disk(npz_file_name, latent, original_size, crop_left_top) - else: - # remove existing flipped npz - for image_key, _ in bucket: - npz_file_name = ( - get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, True, args.recursive) + ".npz" - ) - if os.path.isfile(npz_file_name): - print(f"remove existing flipped npz / 既存のflipされたnpzファイルを削除します: {npz_file_name}") - os.remove(npz_file_name) - + train_util.cache_batch_latents(vae, True, bucket, args.flip_aug, False) bucket.clear() # 読み込みの高速化のためにDataLoaderを使うオプション @@ -203,61 +156,18 @@ def process_batch(is_last): ), f"internal error resized size is small: {resized_size}, {reso}" # 既に存在するファイルがあればshape等を確認して同じならskipする + npz_file_name = get_npz_filename(args.train_data_dir, image_key, args.full_path, args.recursive) if args.skip_existing: - npz_files = [get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, False, args.recursive) + ".npz"] - if args.flip_aug: - npz_files.append( - get_npz_filename_wo_ext(args.train_data_dir, image_key, args.full_path, True, args.recursive) + ".npz" - ) - - found = True - for npz_file in npz_files: - if not os.path.exists(npz_file): - found = False - break - - latents, _, _ = train_util.load_latents_from_disk(npz_file) - if latents is None: # old version - found = False - break - - if latents.shape[1] != reso[1] // 8 or latents.shape[2] != reso[0] // 8: # latentsのshapeを確認 - found = False - break - if found: + if train_util.is_disk_cached_latents_is_expected(reso, npz_file_name, args.flip_aug): continue - # 画像をリサイズしてトリミングする - # PILにinter_areaがないのでcv2で…… - image = np.array(image) - if resized_size[0] != image.shape[1] or resized_size[1] != image.shape[0]: # リサイズ処理が必要? - image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) - - trim_left = 0 - if resized_size[0] > reso[0]: - trim_size = resized_size[0] - reso[0] - image = image[:, trim_size // 2 : trim_size // 2 + reso[0]] - trim_left = trim_size // 2 - - trim_top = 0 - if resized_size[1] > reso[1]: - trim_size = resized_size[1] - reso[1] - image = image[trim_size // 2 : trim_size // 2 + reso[1]] - trim_top = trim_size // 2 - - original_size_wh = (resized_size[0], resized_size[1]) - # target_size_wh = (reso[0], reso[1]) - crop_left_top = (trim_left, trim_top) - - assert ( - image.shape[0] == reso[1] and image.shape[1] == reso[0] - ), f"internal error, illegal trimmed size: {image.shape}, {reso}" - - # # debug - # cv2.imwrite(f"r:\\test\\img_{len(img_ar_errors)}.jpg", image[:, :, ::-1]) - # バッチへ追加 - bucket_manager.add_image(reso, (image_key, image, original_size_wh, crop_left_top)) + image_info = train_util.ImageInfo(image_key, 1, "", False, image_path) + image_info.latents_npz = npz_file_name + image_info.bucket_reso = reso + image_info.resized_size = resized_size + image_info.image = image + bucket_manager.add_image(reso, image_info) # バッチを推論するか判定して推論する process_batch(False) diff --git a/library/train_util.py b/library/train_util.py index 15c58cc8c..bf3332992 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -50,6 +50,7 @@ HeunDiscreteScheduler, KDPM2DiscreteScheduler, KDPM2AncestralDiscreteScheduler, + AutoencoderKL, ) from library import custom_train_functions from library.original_unet import UNet2DConditionModel @@ -96,6 +97,13 @@ except: pass +IMAGE_TRANSFORMS = transforms.Compose( + [ + transforms.ToTensor(), + transforms.Normalize([0.5], [0.5]), + ] +) + class ImageInfo: def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, absolute_path: str) -> None: @@ -110,10 +118,10 @@ def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, self.latents: torch.Tensor = None self.latents_flipped: torch.Tensor = None self.latents_npz: str = None - self.latents_npz_flipped: str = None self.latents_original_size: Tuple[int, int] = None # original image size, not latents size self.latents_crop_left_top: Tuple[int, int] = None # original image crop left top, not latents crop left top self.cond_img_path: str = None + self.image: Optional[Image.Image] = None # optional, original PIL Image class BucketManager: @@ -507,21 +515,22 @@ def __init__( # augmentation self.aug_helper = AugHelper() - self.image_transforms = transforms.Compose( - [ - transforms.ToTensor(), - transforms.Normalize([0.5], [0.5]), - ] - ) + self.image_transforms = IMAGE_TRANSFORMS self.image_data: Dict[str, ImageInfo] = {} self.image_to_subset: Dict[str, Union[DreamBoothSubset, FineTuningSubset]] = {} self.replacements = {} + # caching + self.caching_mode = None # None, 'latents', 'text' + def set_seed(self, seed): self.seed = seed + def set_caching_mode(self, mode): + self.caching_mode = mode + def set_current_epoch(self, epoch): if not self.current_epoch == epoch: # epochが切り替わったらバケツをシャッフルする self.shuffle_buckets() @@ -767,45 +776,6 @@ def shuffle_buckets(self): random.shuffle(self.buckets_indices) self.bucket_manager.shuffle() - def load_image(self, image_path): - image = Image.open(image_path) - if not image.mode == "RGB": - image = image.convert("RGB") - img = np.array(image, np.uint8) - return img - - # 画像を読み込む。戻り値はnumpy.ndarray,(original width, original height),(crop left, crop top) - def trim_and_resize_if_required( - self, subset: BaseSubset, image, reso, resized_size - ) -> Tuple[np.ndarray, Tuple[int, int], Tuple[int, int]]: - image_height, image_width = image.shape[0:2] - - if image_width != resized_size[0] or image_height != resized_size[1]: - # リサイズする - image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ - - image_height, image_width = image.shape[0:2] - original_size = (image_width, image_height) - - crop_left_top = (0, 0) - if image_width > reso[0]: - trim_size = image_width - reso[0] - p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) - # print("w", trim_size, p) - image = image[:, p : p + reso[0]] - crop_left_top = (p, 0) - if image_height > reso[1]: - trim_size = image_height - reso[1] - p = trim_size // 2 if not subset.random_crop else random.randint(0, trim_size) - # print("h", trim_size, p) - image = image[p : p + reso[1]] - crop_left_top = (crop_left_top[0], p) - - assert ( - image.shape[0] == reso[1] and image.shape[1] == reso[0] - ), f"internal error, illegal trimmed size: {image.shape}, {reso}" - return image, original_size, crop_left_top - def is_latent_cacheable(self): return all([not subset.color_aug and not subset.random_crop for subset in self.subsets]) @@ -822,26 +792,6 @@ def is_text_encoder_output_cacheable(self): ] ) - def is_disk_cached_latents_is_expected(self, reso, npz_path, flipped_npz_path): - expected_latents_size = (reso[1] // 8, reso[0] // 8) # bucket_resoはWxHなので注意 - - for npath in [npz_path, flipped_npz_path]: - if npath is None: - continue - if not os.path.exists(npath): - return False - - npz = np.load(npath) - if "latents" not in npz or "original_size" not in npz or "crop_left_top" not in npz: # old ver? - return False - - cached_latents = npz["latents"] - - if cached_latents.shape[1:3] != expected_latents_size: - return False - - return True - def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_process=True): # ちょっと速くした print("caching latents.") @@ -864,13 +814,10 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc # check disk cache exists and size of latents if cache_to_disk: info.latents_npz = os.path.splitext(info.absolute_path)[0] + ".npz" - info.latents_npz_flipped = os.path.splitext(info.absolute_path)[0] + "_flip.npz" - if not is_main_process: + if not is_main_process: # store to info only continue - cache_available = self.is_disk_cached_latents_is_expected( - info.bucket_reso, info.latents_npz, info.latents_npz_flipped if subset.flip_aug else None - ) + cache_available = is_disk_cached_latents_is_expected(info.bucket_reso, info.latents_npz, subset.flip_aug) if cache_available: # do not add to batch continue @@ -890,60 +837,19 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc if len(batch) > 0: batches.append(batch) - if cache_to_disk and not is_main_process: # don't cache latents in non-main process, set to info only + if cache_to_disk and not is_main_process: # if cache to disk, don't cache latents in non-main process, set to info only return - # iterate batches + # iterate batches: batch doesn't have image, image will be loaded in cache_batch_latents and discarded for batch in tqdm(batches, smoothing=1, total=len(batches)): - images = [] - for info in batch: - image = self.load_image(info.absolute_path) - image, original_size, crop_left_top = self.trim_and_resize_if_required( - subset, image, info.bucket_reso, info.resized_size - ) - image = self.image_transforms(image) - images.append(image) - - info.latents_original_size = original_size - info.latents_crop_left_top = crop_left_top - - img_tensors = torch.stack(images, dim=0) - img_tensors = img_tensors.to(device=vae.device, dtype=vae.dtype) - - latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") - - for info, latent in zip(batch, latents): - # check NaN - if torch.isnan(latents).any(): - raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") - - if cache_to_disk: - save_latents_to_disk(info.latents_npz, latent, info.latents_original_size, info.latents_crop_left_top) - else: - info.latents = latent - - if subset.flip_aug: - img_tensors = torch.flip(img_tensors, dims=[3]) - latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") - for info, latent in zip(batch, latents): - # check NaN - if torch.isnan(latents).any(): - raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") - - if cache_to_disk: - # crop_left_top is reversed when making batch - save_latents_to_disk( - info.latents_npz_flipped, latent, info.latents_original_size, info.latents_crop_left_top - ) - else: - info.latents_flipped = latent + cache_batch_latents(vae, cache_to_disk, batch, subset.flip_aug, subset.random_crop) def get_image_size(self, image_path): image = Image.open(image_path) return image.size def load_image_with_face_info(self, subset: BaseSubset, image_path: str): - img = self.load_image(image_path) + img = load_image(image_path) face_cx = face_cy = face_w = face_h = 0 if subset.face_crop_aug_range is not None: @@ -1004,10 +910,6 @@ def crop_target(self, subset: BaseSubset, image, face_cx, face_cy, face_w, face_ return image - def load_latents_from_npz(self, image_info: ImageInfo, flipped): - npz_file = image_info.latents_npz_flipped if flipped else image_info.latents_npz - return load_latents_from_disk(npz_file) - def __len__(self): return self._length @@ -1016,6 +918,9 @@ def __getitem__(self, index): bucket_batch_size = self.buckets_indices[index].bucket_batch_size image_index = self.buckets_indices[index].batch_index * bucket_batch_size + if self.caching_mode is not None: # return batch for latents/text encoder outputs caching + return self.get_item_for_caching(bucket, bucket_batch_size, image_index) + loss_weights = [] captions = [] input_ids_list = [] @@ -1045,7 +950,10 @@ def __getitem__(self, index): image = None elif image_info.latents_npz is not None: # FineTuningDatasetまたはcache_latents_to_disk=Trueの場合 - latents, original_size, crop_left_top = self.load_latents_from_npz(image_info, flipped) + latents, original_size, crop_left_top, flipped_latents = load_latents_from_disk(image_info.latents_npz) + if flipped: + latents = flipped_latents + del flipped_latents latents = torch.FloatTensor(latents) image = None @@ -1055,8 +963,8 @@ def __getitem__(self, index): im_h, im_w = img.shape[0:2] if self.enable_bucket: - img, original_size, crop_left_top = self.trim_and_resize_if_required( - subset, img, image_info.bucket_reso, image_info.resized_size + img, original_size, crop_left_top = trim_and_resize_if_required( + subset.random_crop, img, image_info.bucket_reso, image_info.resized_size ) else: if face_cx > 0: # 顔位置情報あり @@ -1162,6 +1070,53 @@ def __getitem__(self, index): example["image_keys"] = bucket[image_index : image_index + self.batch_size] return example + def get_item_for_caching(self, bucket, bucket_batch_size, image_index): + captions = [] + images = [] + absolute_paths = [] + resized_sizes = [] + bucket_reso = None + flip_aug = None + random_crop = None + + for image_key in bucket[image_index : image_index + bucket_batch_size]: + image_info = self.image_data[image_key] + subset = self.image_to_subset[image_key] + + if flip_aug is None: + flip_aug = subset.flip_aug + random_crop = subset.random_crop + bucket_reso = image_info.bucket_reso + else: + assert flip_aug == subset.flip_aug, "flip_aug must be same in a batch" + assert random_crop == subset.random_crop, "random_crop must be same in a batch" + assert bucket_reso == image_info.bucket_reso, "bucket_reso must be same in a batch" + + caption = image_info.caption # TODO cache some patterns of droping, shuffling, etc. + if self.caching_mode == "latents": + image = load_image(image_info.absolute_path) + else: + image = None + + captions.append(caption) + images.append(image) + absolute_paths.append(image_info.absolute_path) + resized_sizes.append(image_info.resized_size) + + example = {} + + if images[0] is None: + images = None + example["images"] = images + + example["captions"] = captions + example["absolute_paths"] = absolute_paths + example["resized_sizes"] = resized_sizes + example["flip_aug"] = flip_aug + example["random_crop"] = random_crop + example["bucket_reso"] = bucket_reso + return example + class DreamBoothDataset(BaseDataset): def __init__( @@ -1635,11 +1590,7 @@ def __init__( assert len(missing_imgs) == 0, f"missing conditioning data for {len(missing_imgs)} images: {missing_imgs}" assert len(extra_imgs) == 0, f"extra conditioning data for {len(extra_imgs)} images: {extra_imgs}" - self.conditioning_image_transforms = transforms.Compose( - [ - transforms.ToTensor(), - ] - ) + self.conditioning_image_transforms = IMAGE_TRANSFORMS def make_buckets(self): self.dreambooth_dataset_delegate.make_buckets() @@ -1667,7 +1618,7 @@ def __getitem__(self, index): original_size_hw = example["original_sizes_hw"][i] crop_top_left = example["crop_top_lefts"][i] flipped = example["flippeds"][i] - cond_img = self.load_image(image_info.cond_img_path) + cond_img = load_image(image_info.cond_img_path) if self.dreambooth_dataset_delegate.enable_bucket: cond_img = cv2.resize(cond_img, image_info.resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ @@ -1729,6 +1680,10 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc print(f"[Dataset {i}]") dataset.cache_latents(vae, vae_batch_size, cache_to_disk, is_main_process) + def set_caching_mode(self, caching_mode): + for dataset in self.datasets: + dataset.set_caching_mode(caching_mode) + def is_latent_cacheable(self) -> bool: return all([dataset.is_latent_cacheable() for dataset in self.datasets]) @@ -1752,28 +1707,53 @@ def disable_token_padding(self): dataset.disable_token_padding() -# 戻り値は、latents_tensor, (original_size width, original_size height), (crop left, crop top) -def load_latents_from_disk(npz_path) -> Tuple[Optional[torch.Tensor], Optional[List[int]], Optional[List[int]]]: - if npz_path is None: # flipped doesn't exist - return None, None, None +def is_disk_cached_latents_is_expected(reso, npz_path: str, flip_aug: bool): + expected_latents_size = (reso[1] // 8, reso[0] // 8) # bucket_resoはWxHなので注意 + + if not os.path.exists(npz_path): + return False + + npz = np.load(npz_path) + if "latents" not in npz or "original_size" not in npz or "crop_left_top" not in npz: # old ver? + return False + if npz["latents"].shape[1:3] != expected_latents_size: + return False + + if flip_aug: + if "latents_flipped" not in npz: + return False + if npz["latents_flipped"].shape[1:3] != expected_latents_size: + return False + + return True + +# 戻り値は、latents_tensor, (original_size width, original_size height), (crop left, crop top) +def load_latents_from_disk( + npz_path, +) -> Tuple[Optional[torch.Tensor], Optional[List[int]], Optional[List[int]], Optional[torch.Tensor]]: npz = np.load(npz_path) if "latents" not in npz: print(f"error: npz is old format. please re-generate {npz_path}") - return None, None, None + return None, None, None, None latents = npz["latents"] original_size = npz["original_size"].tolist() crop_left_top = npz["crop_left_top"].tolist() - return latents, original_size, crop_left_top + flipped_latents = npz["latents_flipped"] if "latents_flipped" in npz else None + return latents, original_size, crop_left_top, flipped_latents -def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_left_top): +def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_left_top, flipped_latents_tensor=None): + kwargs = {} + if flipped_latents_tensor is not None: + kwargs["latents_flipped"] = flipped_latents_tensor.float().cpu().numpy() np.savez( npz_path, latents=latents_tensor.float().cpu().numpy(), original_size=np.array(original_size), crop_left_top=np.array(crop_left_top), + **kwargs, ) @@ -1948,6 +1928,93 @@ def load_arbitrary_dataset(args, tokenizer) -> MinimalDataset: return train_dataset_group +def load_image(image_path): + image = Image.open(image_path) + if not image.mode == "RGB": + image = image.convert("RGB") + img = np.array(image, np.uint8) + return img + + +# 画像を読み込む。戻り値はnumpy.ndarray,(original width, original height),(crop left, crop top) +def trim_and_resize_if_required( + random_crop: bool, image: Image.Image, reso, resized_size: Tuple[int, int] +) -> Tuple[np.ndarray, Tuple[int, int], Tuple[int, int]]: + image_height, image_width = image.shape[0:2] + + if image_width != resized_size[0] or image_height != resized_size[1]: + # リサイズする + image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ + + image_height, image_width = image.shape[0:2] + original_size = (image_width, image_height) + + crop_left_top = (0, 0) + if image_width > reso[0]: + trim_size = image_width - reso[0] + p = trim_size // 2 if not random_crop else random.randint(0, trim_size) + # print("w", trim_size, p) + image = image[:, p : p + reso[0]] + crop_left_top = (p, 0) + if image_height > reso[1]: + trim_size = image_height - reso[1] + p = trim_size // 2 if not random_crop else random.randint(0, trim_size) + # print("h", trim_size, p) + image = image[p : p + reso[1]] + crop_left_top = (crop_left_top[0], p) + + assert image.shape[0] == reso[1] and image.shape[1] == reso[0], f"internal error, illegal trimmed size: {image.shape}, {reso}" + return image, original_size, crop_left_top + + +def cache_batch_latents( + vae: AutoencoderKL, cache_to_disk: bool, image_infos: List[ImageInfo], flip_aug: bool, random_crop: bool +) -> None: + r""" + requires image_infos to have: absolute_path, bucket_reso, resized_size, latents_npz + optionally requires image_infos to have: image + if cache_to_disk is True, set info.latents_npz + flipped latents is also saved if flip_aug is True + if cache_to_disk is False, set info.latents + latents_flipped is also set if flip_aug is True + latents_original_size and latents_crop_left_top are also set + """ + images = [] + for info in image_infos: + image = load_image(info.absolute_path) if info.image is None else np.array(info.image, np.uint8) + image, original_size, crop_left_top = trim_and_resize_if_required(random_crop, image, info.bucket_reso, info.resized_size) + image = IMAGE_TRANSFORMS(image) + images.append(image) + + info.latents_original_size = original_size + info.latents_crop_left_top = crop_left_top + + img_tensors = torch.stack(images, dim=0) + img_tensors = img_tensors.to(device=vae.device, dtype=vae.dtype) + + with torch.no_grad(): + latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") + + if flip_aug: + img_tensors = torch.flip(img_tensors, dims=[3]) + with torch.no_grad(): + flipped_latents = vae.encode(img_tensors).latent_dist.sample().to("cpu") + else: + flipped_latents = [None] * len(latents) + + for info, latent, flipped_latent in zip(image_infos, latents, flipped_latents): + # check NaN + if torch.isnan(latents).any() or (flipped_latent is not None and torch.isnan(flipped_latent).any()): + raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") + + if cache_to_disk: + save_latents_to_disk(info.latents_npz, latent, info.latents_original_size, info.latents_crop_left_top, flipped_latent) + else: + info.latents = latent + if flip_aug: + info.latents_flipped = flipped_latent + + # endregion # region モジュール入れ替え部 @@ -3975,7 +4042,7 @@ def sample_images_common( controlnet=controlnet, controlnet_image=controlnet_image, ) - + image = pipeline.latents_to_image(latents)[0] ts_str = time.strftime("%Y%m%d%H%M%S", time.localtime()) diff --git a/tools/cache_latents.py b/tools/cache_latents.py new file mode 100644 index 000000000..d403d5594 --- /dev/null +++ b/tools/cache_latents.py @@ -0,0 +1,193 @@ +# latentsのdiskへの事前キャッシュを行う / cache latents to disk + +import argparse +import math +from multiprocessing import Value +import os + +from accelerate.utils import set_seed +import torch +from tqdm import tqdm + +from library import config_util +from library import train_util +from library import sdxl_train_util +from library.config_util import ( + ConfigSanitizer, + BlueprintGenerator, +) + + +def cache_to_disk(args: argparse.Namespace) -> None: + train_util.prepare_dataset_args(args, True) + + # check cache latents arg + assert args.cache_latents_to_disk, "cache_latents_to_disk must be True / cache_latents_to_diskはTrueである必要があります" + + use_dreambooth_method = args.in_json is None + + if args.seed is not None: + set_seed(args.seed) # 乱数系列を初期化する + + # tokenizerを準備する:datasetを動かすために必要 + if args.sdxl: + tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) + tokenizers = [tokenizer1, tokenizer2] + else: + tokenizer = train_util.load_tokenizer(args) + tokenizers = [tokenizer] + + # データセットを準備する + if args.dataset_class is None: + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) + if args.dataset_config is not None: + print(f"Load dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "in_json"] + if any(getattr(args, attr) is not None for attr in ignored): + print( + "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + if use_dreambooth_method: + print("Using DreamBooth method.") + user_config = { + "datasets": [ + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } + ] + } + else: + print("Training with captions.") + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizers) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) + else: + train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizers) + + # datasetのcache_latentsを呼ばなければ、生の画像が返る + + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + # acceleratorを準備する + print("prepare accelerator") + accelerator = train_util.prepare_accelerator(args) + + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, _ = train_util.prepare_dtype(args) + vae_dtype = torch.float32 if args.no_half_vae else weight_dtype + + # モデルを読み込む + print("load model") + if args.sdxl: + (_, _, _, vae, _, _, _) = sdxl_train_util.load_target_model(args, accelerator, "sdxl", weight_dtype) + else: + _, vae, _, _ = train_util.load_target_model(args, weight_dtype, accelerator) + + vae.set_use_memory_efficient_attention_xformers(args.xformers) + vae.to(accelerator.device, dtype=vae_dtype) + vae.requires_grad_(False) + vae.eval() + + # dataloaderを準備する + train_dataset_group.set_caching_mode("latents") + + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, + ) + + # acceleratorを使ってモデルを準備する:マルチGPUで使えるようになるはず + train_dataloader = accelerator.prepare(train_dataloader) + + # データ取得のためのループ + for batch in tqdm(train_dataloader): + b_size = len(batch["images"]) + vae_batch_size = b_size if args.vae_batch_size is None else args.vae_batch_size + flip_aug = batch["flip_aug"] + random_crop = batch["random_crop"] + bucket_reso = batch["bucket_reso"] + + # バッチを分割して処理する + for i in range(0, b_size, vae_batch_size): + images = batch["images"][i : i + vae_batch_size] + absolute_paths = batch["absolute_paths"][i : i + vae_batch_size] + resized_sizes = batch["resized_sizes"][i : i + vae_batch_size] + + image_infos = [] + for i, (image, absolute_path, resized_size) in enumerate(zip(images, absolute_paths, resized_sizes)): + image_info = train_util.ImageInfo(absolute_path, 1, "dummy", False, absolute_path) + image_info.image = image + image_info.bucket_reso = bucket_reso + image_info.resized_size = resized_size + image_info.latents_npz = os.path.splitext(absolute_path)[0] + ".npz" + + if args.skip_existing: + if train_util.is_disk_cached_latents_is_expected(image_info.bucket_reso, image_info.latents_npz, flip_aug): + print(f"Skipping {image_info.latents_npz} because it already exists.") + continue + + image_infos.append(image_info) + + if len(image_infos) > 0: + train_util.cache_batch_latents(vae, True, image_infos, flip_aug, random_crop) + + accelerator.wait_for_everyone() + accelerator.print(f"Finished caching latents for {len(train_dataset_group)} batches.") + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + + train_util.add_sd_models_arguments(parser) + train_util.add_training_arguments(parser, True) + train_util.add_dataset_arguments(parser, True, True, True) + config_util.add_config_arguments(parser) + parser.add_argument("--sdxl", action="store_true", help="Use SDXL model / SDXLモデルを使用する") + parser.add_argument( + "--no_half_vae", + action="store_true", + help="do not use fp16/bf16 VAE in mixed precision (use float VAE) / mixed precisionでも fp16/bf16 VAEを使わずfloat VAEを使う", + ) + parser.add_argument( + "--skip_existing", + action="store_true", + help="skip images if npz already exists (both normal and flipped exists if flip_aug is enabled) / npzが既に存在する画像をスキップする(flip_aug有効時は通常、反転の両方が存在する画像をスキップ)", + ) + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + cache_to_disk(args) From 62dd99bee5e8601058fea73752401407c52f86d0 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 15 Jul 2023 18:34:13 +0900 Subject: [PATCH 086/220] update readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 4e4150b60..7af3f8341 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,12 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: +- `tools/cache_latents.py` is added. This script can be used to cache the latents in advance. + - The options are almost the same as `sdxl_train.py'. See the help message for the usage. + - Please launch the script as follows: + `accelerate launch --num_cpu_threads_per_process 1 tools/cache_latents.py ...` + - This script should work with multi-GPU, but it is not tested in my environment. + - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - `--full_bf16` option is added. Thanks to KohakuBlueleaf! - This option enables the full bfloat16 training (includes gradients). This option is useful to reduce the GPU memory usage. From 516f64f4d967992fd2061b0fcd2d83ec4baa8b48 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 16 Jul 2023 14:53:47 +0900 Subject: [PATCH 087/220] add caching to disk for text encoder outputs --- library/sdxl_train_util.py | 68 ++----- library/train_util.py | 291 +++++++++++++++++++++++++--- sdxl_train.py | 60 +++--- sdxl_train_network.py | 65 ++++--- sdxl_train_textual_inversion.py | 4 +- tools/cache_text_encoder_outputs.py | 191 ++++++++++++++++++ 6 files changed, 537 insertions(+), 142 deletions(-) create mode 100644 tools/cache_text_encoder_outputs.py diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index a93ef502a..48785ca6f 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -140,62 +140,6 @@ def load_tokenizers(args: argparse.Namespace): return tokeniers -def get_hidden_states( - args: argparse.Namespace, input_ids1, input_ids2, tokenizer1, tokenizer2, text_encoder1, text_encoder2, weight_dtype=None -): - # input_ids: b,n,77 -> b*n, 77 - b_size = input_ids1.size()[0] - input_ids1 = input_ids1.reshape((-1, tokenizer1.model_max_length)) # batch_size*n, 77 - input_ids2 = input_ids2.reshape((-1, tokenizer2.model_max_length)) # batch_size*n, 77 - - # text_encoder1 - enc_out = text_encoder1(input_ids1, output_hidden_states=True, return_dict=True) - hidden_states1 = enc_out["hidden_states"][11] - - # text_encoder2 - enc_out = text_encoder2(input_ids2, output_hidden_states=True, return_dict=True) - hidden_states2 = enc_out["hidden_states"][-2] # penuultimate layer - pool2 = enc_out["text_embeds"] - - # b*n, 77, 768 or 1280 -> b, n*77, 768 or 1280 - n_size = 1 if args.max_token_length is None else args.max_token_length // 75 - hidden_states1 = hidden_states1.reshape((b_size, -1, hidden_states1.shape[-1])) - hidden_states2 = hidden_states2.reshape((b_size, -1, hidden_states2.shape[-1])) - - if args.max_token_length is not None: - # bs*3, 77, 768 or 1024 - # encoder1: ... の三連を ... へ戻す - states_list = [hidden_states1[:, 0].unsqueeze(1)] # - for i in range(1, args.max_token_length, tokenizer1.model_max_length): - states_list.append(hidden_states1[:, i : i + tokenizer1.model_max_length - 2]) # の後から の前まで - states_list.append(hidden_states1[:, -1].unsqueeze(1)) # - hidden_states1 = torch.cat(states_list, dim=1) - - # v2: ... ... の三連を ... ... へ戻す 正直この実装でいいのかわからん - states_list = [hidden_states2[:, 0].unsqueeze(1)] # - for i in range(1, args.max_token_length, tokenizer2.model_max_length): - chunk = hidden_states2[:, i : i + tokenizer2.model_max_length - 2] # の後から 最後の前まで - # this causes an error: - # RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation - # if i > 1: - # for j in range(len(chunk)): # batch_size - # if input_ids2[n_index + j * n_size, 1] == tokenizer2.eos_token_id: # 空、つまり ...のパターン - # chunk[j, 0] = chunk[j, 1] # 次の の値をコピーする - states_list.append(chunk) # の後から の前まで - states_list.append(hidden_states2[:, -1].unsqueeze(1)) # のどちらか - hidden_states2 = torch.cat(states_list, dim=1) - - # pool はnの最初のものを使う - pool2 = pool2[::n_size] - - if weight_dtype is not None: - # this is required for additional network training - hidden_states1 = hidden_states1.to(weight_dtype) - hidden_states2 = hidden_states2.to(weight_dtype) - - return hidden_states1, hidden_states2, pool2 - - def timestep_embedding(timesteps, dim, max_period=10000): """ Create sinusoidal timestep embeddings. @@ -391,6 +335,11 @@ def add_sdxl_training_arguments(parser: argparse.ArgumentParser): parser.add_argument( "--cache_text_encoder_outputs", action="store_true", help="cache text encoder outputs / text encoderの出力をキャッシュする" ) + parser.add_argument( + "--cache_text_encoder_outputs_to_disk", + action="store_true", + help="cache text encoder outputs to disk / text encoderの出力をディスクにキャッシュする", + ) def verify_sdxl_training_args(args: argparse.Namespace): @@ -417,6 +366,13 @@ def verify_sdxl_training_args(args: argparse.Namespace): not hasattr(args, "weighted_captions") or not args.weighted_captions ), "weighted_captions cannot be enabled in SDXL training currently / SDXL学習では今のところweighted_captionsを有効にすることはできません" + if args.cache_text_encoder_outputs_to_disk and not args.cache_text_encoder_outputs: + args.cache_text_encoder_outputs = True + print( + "cache_text_encoder_outputs is enabled because cache_text_encoder_outputs_to_disk is enabled / " + + "cache_text_encoder_outputs_to_diskが有効になっているためcache_text_encoder_outputsが有効になりました" + ) + def sample_images(*args, **kwargs): return train_util.sample_images_common(SdxlStableDiffusionLongPromptWeightingPipeline, *args, **kwargs) diff --git a/library/train_util.py b/library/train_util.py index bf3332992..c36651e2d 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -104,6 +104,8 @@ ] ) +TEXT_ENCODER_OUTPUTS_CACHE_SUFFIX = "_te_outputs.npz" + class ImageInfo: def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, absolute_path: str) -> None: @@ -122,6 +124,11 @@ def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, self.latents_crop_left_top: Tuple[int, int] = None # original image crop left top, not latents crop left top self.cond_img_path: str = None self.image: Optional[Image.Image] = None # optional, original PIL Image + # SDXL, optional + self.text_encoder_outputs_npz: Optional[str] = None + self.text_encoder_outputs1: Optional[torch.Tensor] = None + self.text_encoder_outputs2: Optional[torch.Tensor] = None + self.text_encoder_pool2: Optional[torch.Tensor] = None class BucketManager: @@ -793,7 +800,7 @@ def is_text_encoder_output_cacheable(self): ) def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_process=True): - # ちょっと速くした + # マルチGPUには対応していないので、そちらはtools/cache_latents.pyを使うこと print("caching latents.") image_infos = list(self.image_data.values()) @@ -841,9 +848,73 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc return # iterate batches: batch doesn't have image, image will be loaded in cache_batch_latents and discarded + print("caching latents...") for batch in tqdm(batches, smoothing=1, total=len(batches)): cache_batch_latents(vae, cache_to_disk, batch, subset.flip_aug, subset.random_crop) + # weight_dtypeを指定するとText Encoderそのもの、およひ出力がweight_dtypeになる + # SDXLでのみ有効だが、datasetのメソッドとする必要があるので、sdxl_train_util.pyではなくこちらに実装する + # SD1/2に対応するにはv2のフラグを持つ必要があるので後回し + def cache_text_encoder_outputs( + self, tokenizers, text_encoders, device, weight_dtype, cache_to_disk=False, is_main_process=True + ): + assert len(tokenizers) == 2, "only support SDXL" + + # latentsのキャッシュと同様に、ディスクへのキャッシュに対応する + # またマルチGPUには対応していないので、そちらはtools/cache_latents.pyを使うこと + print("caching text encoder outputs.") + image_infos = list(self.image_data.values()) + + print("checking cache existence...") + image_infos_to_cache = [] + for info in tqdm(image_infos): + # subset = self.image_to_subset[info.image_key] + if cache_to_disk: + te_out_npz = os.path.splitext(info.absolute_path)[0] + TEXT_ENCODER_OUTPUTS_CACHE_SUFFIX + info.text_encoder_outputs_npz = te_out_npz + + if not is_main_process: # store to info only + continue + + if os.path.exists(te_out_npz): + continue + + image_infos_to_cache.append(info) + + if cache_to_disk and not is_main_process: # if cache to disk, don't cache latents in non-main process, set to info only + return + + # prepare tokenizers and text encoders + for text_encoder in text_encoders: + text_encoder.to(device) + if weight_dtype is not None: + text_encoder.to(dtype=weight_dtype) + + # create batch + batch = [] + batches = [] + for info in image_infos_to_cache: + input_ids1 = self.get_input_ids(info.caption, tokenizers[0]) + input_ids2 = self.get_input_ids(info.caption, tokenizers[1]) + batch.append((info, input_ids1, input_ids2)) + + if len(batch) >= self.batch_size: + batches.append(batch) + batch = [] + + if len(batch) > 0: + batches.append(batch) + + # iterate batches: call text encoder and cache outputs for memory or disk + print("caching text encoder outputs...") + for batch in tqdm(batches): + infos, input_ids1, input_ids2 = zip(*batch) + input_ids1 = torch.stack(input_ids1, dim=0) + input_ids2 = torch.stack(input_ids2, dim=0) + cache_batch_text_encoder_outputs( + infos, tokenizers, text_encoders, self.max_token_length, cache_to_disk, input_ids1, input_ids2, weight_dtype + ) + def get_image_size(self, image_path): image = Image.open(image_path) return image.size @@ -931,6 +1002,9 @@ def __getitem__(self, index): crop_top_lefts = [] target_sizes_hw = [] flippeds = [] # 変数名が微妙 + text_encoder_outputs1_list = [] + text_encoder_outputs2_list = [] + text_encoder_pool2_list = [] for image_key in bucket[image_index : image_index + bucket_batch_size]: image_info = self.image_data[image_key] @@ -1012,44 +1086,76 @@ def __getitem__(self, index): target_sizes_hw.append((target_size[1], target_size[0])) flippeds.append(flipped) - caption = self.process_caption(subset, image_info.caption) - if self.XTI_layers: - caption_layer = [] - for layer in self.XTI_layers: - token_strings_from = " ".join(self.token_strings) - token_strings_to = " ".join([f"{x}_{layer}" for x in self.token_strings]) - caption_ = caption.replace(token_strings_from, token_strings_to) - caption_layer.append(caption_) - captions.append(caption_layer) - else: + # captionとtext encoder outputを処理する + caption = image_info.caption # default + if image_info.text_encoder_outputs1 is not None: + text_encoder_outputs1_list.append(image_info.text_encoder_outputs1) + text_encoder_outputs2_list.append(image_info.text_encoder_outputs2) + text_encoder_pool2_list.append(image_info.text_encoder_pool2) captions.append(caption) - - if not self.token_padding_disabled: # this option might be omitted in future + elif image_info.text_encoder_outputs_npz is not None: + text_encoder_outputs1, text_encoder_outputs2, text_encoder_pool2 = load_text_encoder_outputs_from_disk( + image_info.text_encoder_outputs_npz + ) + text_encoder_outputs1_list.append(text_encoder_outputs1) + text_encoder_outputs2_list.append(text_encoder_outputs2) + text_encoder_pool2_list.append(text_encoder_pool2) + captions.append(caption) + else: + caption = self.process_caption(subset, image_info.caption) if self.XTI_layers: - token_caption = self.get_input_ids(caption_layer, self.tokenizers[0]) + caption_layer = [] + for layer in self.XTI_layers: + token_strings_from = " ".join(self.token_strings) + token_strings_to = " ".join([f"{x}_{layer}" for x in self.token_strings]) + caption_ = caption.replace(token_strings_from, token_strings_to) + caption_layer.append(caption_) + captions.append(caption_layer) else: - token_caption = self.get_input_ids(caption, self.tokenizers[0]) - input_ids_list.append(token_caption) + captions.append(caption) - if len(self.tokenizers) > 1: + if not self.token_padding_disabled: # this option might be omitted in future if self.XTI_layers: - token_caption2 = self.get_input_ids(caption_layer, self.tokenizers[1]) + token_caption = self.get_input_ids(caption_layer, self.tokenizers[0]) else: - token_caption2 = self.get_input_ids(caption, self.tokenizers[1]) - input_ids2_list.append(token_caption2) + token_caption = self.get_input_ids(caption, self.tokenizers[0]) + input_ids_list.append(token_caption) + + if len(self.tokenizers) > 1: + if self.XTI_layers: + token_caption2 = self.get_input_ids(caption_layer, self.tokenizers[1]) + else: + token_caption2 = self.get_input_ids(caption, self.tokenizers[1]) + input_ids2_list.append(token_caption2) example = {} example["loss_weights"] = torch.FloatTensor(loss_weights) - if self.token_padding_disabled: - # padding=True means pad in the batch - example["input_ids"] = self.tokenizer[0](captions, padding=True, truncation=True, return_tensors="pt").input_ids - if len(self.tokenizers) > 1: - # following may not work in SDXL, keep the line for future update - example["input_ids2"] = self.tokenizer[1](captions, padding=True, truncation=True, return_tensors="pt").input_ids + if len(text_encoder_outputs1_list) == 0: + if self.token_padding_disabled: + # padding=True means pad in the batch + example["input_ids"] = self.tokenizer[0](captions, padding=True, truncation=True, return_tensors="pt").input_ids + if len(self.tokenizers) > 1: + example["input_ids2"] = self.tokenizer[1]( + captions, padding=True, truncation=True, return_tensors="pt" + ).input_ids + else: + example["input_ids2"] = None + else: + example["input_ids"] = torch.stack(input_ids_list) + example["input_ids2"] = torch.stack(input_ids2_list) if len(self.tokenizers) > 1 else None + example["text_encoder_outputs1_list"] = None + example["text_encoder_outputs2_list"] = None + example["text_encoder_pool2_list"] = None else: - example["input_ids"] = torch.stack(input_ids_list) - example["input_ids2"] = torch.stack(input_ids2_list) if len(self.tokenizers) > 1 else None + example["input_ids"] = None + example["input_ids2"] = None + # # for assertion + # example["input_ids"] = torch.stack([self.get_input_ids(cap, self.tokenizers[0]) for cap in captions]) + # example["input_ids2"] = torch.stack([self.get_input_ids(cap, self.tokenizers[1]) for cap in captions]) + example["text_encoder_outputs1_list"] = torch.stack(text_encoder_outputs1_list) + example["text_encoder_outputs2_list"] = torch.stack(text_encoder_outputs2_list) + example["text_encoder_pool2_list"] = torch.stack(text_encoder_pool2_list) if images[0] is not None: images = torch.stack(images) @@ -1073,6 +1179,8 @@ def __getitem__(self, index): def get_item_for_caching(self, bucket, bucket_batch_size, image_index): captions = [] images = [] + input_ids1_list = [] + input_ids2_list = [] absolute_paths = [] resized_sizes = [] bucket_reso = None @@ -1092,14 +1200,24 @@ def get_item_for_caching(self, bucket, bucket_batch_size, image_index): assert random_crop == subset.random_crop, "random_crop must be same in a batch" assert bucket_reso == image_info.bucket_reso, "bucket_reso must be same in a batch" - caption = image_info.caption # TODO cache some patterns of droping, shuffling, etc. + caption = image_info.caption # TODO cache some patterns of dropping, shuffling, etc. + if self.caching_mode == "latents": image = load_image(image_info.absolute_path) else: image = None + if self.caching_mode == "text": + input_ids1 = self.get_input_ids(caption, self.tokenizers[0]) + input_ids2 = self.get_input_ids(caption, self.tokenizers[1]) + else: + input_ids1 = None + input_ids2 = None + captions.append(caption) images.append(image) + input_ids1_list.append(input_ids1) + input_ids2_list.append(input_ids2) absolute_paths.append(image_info.absolute_path) resized_sizes.append(image_info.resized_size) @@ -1110,6 +1228,8 @@ def get_item_for_caching(self, bucket, bucket_batch_size, image_index): example["images"] = images example["captions"] = captions + example["input_ids1_list"] = input_ids1_list + example["input_ids2_list"] = input_ids2_list example["absolute_paths"] = absolute_paths example["resized_sizes"] = resized_sizes example["flip_aug"] = flip_aug @@ -1680,6 +1800,13 @@ def cache_latents(self, vae, vae_batch_size=1, cache_to_disk=False, is_main_proc print(f"[Dataset {i}]") dataset.cache_latents(vae, vae_batch_size, cache_to_disk, is_main_process) + def cache_text_encoder_outputs( + self, tokenizers, text_encoders, device, weight_dtype, cache_to_disk=False, is_main_process=True + ): + for i, dataset in enumerate(self.datasets): + print(f"[Dataset {i}]") + dataset.cache_text_encoder_outputs(tokenizers, text_encoders, device, weight_dtype, cache_to_disk, is_main_process) + def set_caching_mode(self, caching_mode): for dataset in self.datasets: dataset.set_caching_mode(caching_mode) @@ -1982,6 +2109,7 @@ def cache_batch_latents( images = [] for info in image_infos: image = load_image(info.absolute_path) if info.image is None else np.array(info.image, np.uint8) + # TODO 画像のメタデータが壊れていて、メタデータから割り当てたbucketと実際の画像サイズが一致しない場合があるのでチェック追加要 image, original_size, crop_left_top = trim_and_resize_if_required(random_crop, image, info.bucket_reso, info.resized_size) image = IMAGE_TRANSFORMS(image) images.append(image) @@ -2015,6 +2143,55 @@ def cache_batch_latents( info.latents_flipped = flipped_latent +def cache_batch_text_encoder_outputs( + image_infos, tokenizers, text_encoders, max_token_length, cache_to_disk, input_ids1, input_ids2, dtype +): + input_ids1 = input_ids1.to(text_encoders[0].device) + input_ids2 = input_ids2.to(text_encoders[1].device) + + with torch.no_grad(): + b_hidden_state1, b_hidden_state2, b_pool2 = get_hidden_states_sdxl( + max_token_length, + input_ids1, + input_ids2, + tokenizers[0], + tokenizers[1], + text_encoders[0], + text_encoders[1], + dtype, + ) + + # ここでcpuに移動しておかないと、上書きされてしまう + b_hidden_state1 = b_hidden_state1.detach().to("cpu") # b,n*75+2,768 + b_hidden_state2 = b_hidden_state2.detach().to("cpu") # b,n*75+2,1280 + b_pool2 = b_pool2.detach().to("cpu") # b,1280 + + for info, hidden_state1, hidden_state2, pool2 in zip(image_infos, b_hidden_state1, b_hidden_state2, b_pool2): + if cache_to_disk: + save_text_encoder_outputs_to_disk(info.text_encoder_outputs_npz, hidden_state1, hidden_state2, pool2) + else: + info.text_encoder_outputs1 = hidden_state1 + info.text_encoder_outputs2 = hidden_state2 + info.text_encoder_pool2 = pool2 + + +def save_text_encoder_outputs_to_disk(npz_path, hidden_state1, hidden_state2, pool2): + np.savez( + npz_path, + hidden_state1=hidden_state1.cpu().float().numpy(), + hidden_state2=hidden_state2.cpu().float().numpy(), + pool2=pool2.cpu().float().numpy(), + ) + + +def load_text_encoder_outputs_from_disk(npz_path): + with np.load(npz_path) as f: + hidden_state1 = torch.from_numpy(f["hidden_state1"]) + hidden_state2 = torch.from_numpy(f["hidden_state2"]) if "hidden_state2" in f else None + pool2 = torch.from_numpy(f["pool2"]) if "pool2" in f else None + return hidden_state1, hidden_state2, pool2 + + # endregion # region モジュール入れ替え部 @@ -3501,6 +3678,62 @@ def get_hidden_states(args: argparse.Namespace, input_ids, tokenizer, text_encod return encoder_hidden_states +def get_hidden_states_sdxl( + max_token_length, input_ids1, input_ids2, tokenizer1, tokenizer2, text_encoder1, text_encoder2, weight_dtype=None +): + # input_ids: b,n,77 -> b*n, 77 + b_size = input_ids1.size()[0] + input_ids1 = input_ids1.reshape((-1, tokenizer1.model_max_length)) # batch_size*n, 77 + input_ids2 = input_ids2.reshape((-1, tokenizer2.model_max_length)) # batch_size*n, 77 + + # text_encoder1 + enc_out = text_encoder1(input_ids1, output_hidden_states=True, return_dict=True) + hidden_states1 = enc_out["hidden_states"][11] + + # text_encoder2 + enc_out = text_encoder2(input_ids2, output_hidden_states=True, return_dict=True) + hidden_states2 = enc_out["hidden_states"][-2] # penuultimate layer + pool2 = enc_out["text_embeds"] + + # b*n, 77, 768 or 1280 -> b, n*77, 768 or 1280 + n_size = 1 if max_token_length is None else max_token_length // 75 + hidden_states1 = hidden_states1.reshape((b_size, -1, hidden_states1.shape[-1])) + hidden_states2 = hidden_states2.reshape((b_size, -1, hidden_states2.shape[-1])) + + if max_token_length is not None: + # bs*3, 77, 768 or 1024 + # encoder1: ... の三連を ... へ戻す + states_list = [hidden_states1[:, 0].unsqueeze(1)] # + for i in range(1, max_token_length, tokenizer1.model_max_length): + states_list.append(hidden_states1[:, i : i + tokenizer1.model_max_length - 2]) # の後から の前まで + states_list.append(hidden_states1[:, -1].unsqueeze(1)) # + hidden_states1 = torch.cat(states_list, dim=1) + + # v2: ... ... の三連を ... ... へ戻す 正直この実装でいいのかわからん + states_list = [hidden_states2[:, 0].unsqueeze(1)] # + for i in range(1, max_token_length, tokenizer2.model_max_length): + chunk = hidden_states2[:, i : i + tokenizer2.model_max_length - 2] # の後から 最後の前まで + # this causes an error: + # RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation + # if i > 1: + # for j in range(len(chunk)): # batch_size + # if input_ids2[n_index + j * n_size, 1] == tokenizer2.eos_token_id: # 空、つまり ...のパターン + # chunk[j, 0] = chunk[j, 1] # 次の の値をコピーする + states_list.append(chunk) # の後から の前まで + states_list.append(hidden_states2[:, -1].unsqueeze(1)) # のどちらか + hidden_states2 = torch.cat(states_list, dim=1) + + # pool はnの最初のものを使う + pool2 = pool2[::n_size] + + if weight_dtype is not None: + # this is required for additional network training + hidden_states1 = hidden_states1.to(weight_dtype) + hidden_states2 = hidden_states2.to(weight_dtype) + + return hidden_states1, hidden_states2, pool2 + + def default_if_none(value, default): return default if value is None else value diff --git a/sdxl_train.py b/sdxl_train.py index 935992bf9..8459671c1 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -204,10 +204,6 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): text_encoder2.gradient_checkpointing_enable() training_models.append(text_encoder1) training_models.append(text_encoder2) - - text_encoder1_cache = None - text_encoder2_cache = None - # set require_grad=True later else: text_encoder1.requires_grad_(False) @@ -218,9 +214,15 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # TextEncoderの出力をキャッシュする if args.cache_text_encoder_outputs: # Text Encodes are eval and no grad - text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( - args, accelerator, (tokenizer1, tokenizer2), (text_encoder1, text_encoder2), train_dataset_group, None - ) + with torch.no_grad(): + train_dataset_group.cache_text_encoder_outputs( + (tokenizer1, tokenizer2), + (text_encoder1, text_encoder2), + accelerator.device, + None, + args.cache_text_encoder_outputs_to_disk, + accelerator.is_main_process, + ) accelerator.wait_for_everyone() if not cache_latents: @@ -375,11 +377,10 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): accelerator.print("NaN found in latents, replacing with zeros") latents = torch.where(torch.isnan(latents), torch.zeros_like(latents), latents) latents = latents * sdxl_model_util.VAE_SCALE_FACTOR - b_size = latents.shape[0] - input_ids1 = batch["input_ids"] - input_ids2 = batch["input_ids2"] - if not args.cache_text_encoder_outputs: + if "text_encoder_outputs1_list" not in batch or batch["text_encoder_outputs1_list"] is None: + input_ids1 = batch["input_ids"] + input_ids2 = batch["input_ids2"] with torch.set_grad_enabled(args.train_text_encoder): # Get the text embedding for conditioning # TODO support weighted captions @@ -395,8 +396,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # else: input_ids1 = input_ids1.to(accelerator.device) input_ids2 = input_ids2.to(accelerator.device) - encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( - args, + encoder_hidden_states1, encoder_hidden_states2, pool2 = train_util.get_hidden_states_sdxl( + args.max_token_length, input_ids1, input_ids2, tokenizer1, @@ -406,19 +407,26 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): None if not args.full_fp16 else weight_dtype, ) else: - encoder_hidden_states1 = [] - encoder_hidden_states2 = [] - pool2 = [] - for input_id1, input_id2 in zip(input_ids1, input_ids2): - input_id1_cache_key = tuple(input_id1.squeeze(0).flatten().tolist()) - input_id2_cache_key = tuple(input_id2.squeeze(0).flatten().tolist()) - encoder_hidden_states1.append(text_encoder1_cache[input_id1_cache_key]) - hidden_states2, p2 = text_encoder2_cache[input_id2_cache_key] - encoder_hidden_states2.append(hidden_states2) - pool2.append(p2) - encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) - encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) - pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) + encoder_hidden_states1 = batch["text_encoder_outputs1_list"].to(accelerator.device).to(weight_dtype) + encoder_hidden_states2 = batch["text_encoder_outputs2_list"].to(accelerator.device).to(weight_dtype) + pool2 = batch["text_encoder_pool2_list"].to(accelerator.device).to(weight_dtype) + + # # verify that the text encoder outputs are correct + # ehs1, ehs2, p2 = train_util.get_hidden_states_sdxl( + # args.max_token_length, + # batch["input_ids"].to(text_encoder1.device), + # batch["input_ids2"].to(text_encoder1.device), + # tokenizer1, + # tokenizer2, + # text_encoder1, + # text_encoder2, + # None if not args.full_fp16 else weight_dtype, + # ) + # b_size = encoder_hidden_states1.shape[0] + # assert ((encoder_hidden_states1.to("cpu") - ehs1.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # assert ((encoder_hidden_states2.to("cpu") - ehs2.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # assert ((pool2.to("cpu") - p2.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # print("text encoder outputs verified") # get size embeddings orig_size = batch["original_sizes_hw"] diff --git a/sdxl_train_network.py b/sdxl_train_network.py index 0c3c0cc5b..dc2225346 100644 --- a/sdxl_train_network.py +++ b/sdxl_train_network.py @@ -47,7 +47,7 @@ def is_text_encoder_outputs_cached(self, args): return args.cache_text_encoder_outputs def cache_text_encoder_outputs_if_needed( - self, args, accelerator, unet, vae, tokenizers, text_encoders, dataset, weight_dtype + self, args, accelerator, unet, vae, tokenizers, text_encoders, dataset: train_util.DatasetGroup, weight_dtype ): if args.cache_text_encoder_outputs: if not args.lowram: @@ -60,34 +60,33 @@ def cache_text_encoder_outputs_if_needed( if torch.cuda.is_available(): torch.cuda.empty_cache() - text_encoder1_cache, text_encoder2_cache = sdxl_train_util.cache_text_encoder_outputs( - args, accelerator, tokenizers, text_encoders, dataset, weight_dtype + dataset.cache_text_encoder_outputs( + tokenizers, + text_encoders, + accelerator.device, + weight_dtype, + args.cache_text_encoder_outputs_to_disk, + accelerator.is_main_process, ) - accelerator.wait_for_everyone() - text_encoders[0].to("cpu", dtype=torch.float32) # Text Encoder doesn't work with fp16 on CPU + + text_encoders[0].to("cpu", dtype=torch.float32) # Text Encoder doesn't work with fp16 on CPU text_encoders[1].to("cpu", dtype=torch.float32) if torch.cuda.is_available(): torch.cuda.empty_cache() - self.text_encoder1_cache = text_encoder1_cache - self.text_encoder2_cache = text_encoder2_cache - if not args.lowram: print("move vae and unet back to original device") vae.to(org_vae_device) unet.to(org_unet_device) else: - self.text_encoder1_cache = None - self.text_encoder2_cache = None - # Text Encoderから毎回出力を取得するので、GPUに乗せておく text_encoders[0].to(accelerator.device) text_encoders[1].to(accelerator.device) def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, weight_dtype): - input_ids1 = batch["input_ids"] - input_ids2 = batch["input_ids2"] - if not args.cache_text_encoder_outputs: + if "text_encoder_outputs1_list" not in batch or batch["text_encoder_outputs1_list"] is None: + input_ids1 = batch["input_ids"] + input_ids2 = batch["input_ids2"] with torch.enable_grad(): # Get the text embedding for conditioning # TODO support weighted captions @@ -103,8 +102,8 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei # else: input_ids1 = input_ids1.to(accelerator.device) input_ids2 = input_ids2.to(accelerator.device) - encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( - args, + encoder_hidden_states1, encoder_hidden_states2, pool2 = train_util.get_hidden_states_sdxl( + args.max_token_length, input_ids1, input_ids2, tokenizers[0], @@ -114,19 +113,27 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei None if not args.full_fp16 else weight_dtype, ) else: - encoder_hidden_states1 = [] - encoder_hidden_states2 = [] - pool2 = [] - for input_id1, input_id2 in zip(input_ids1, input_ids2): - input_id1_cache_key = tuple(input_id1.flatten().tolist()) - input_id2_cache_key = tuple(input_id2.flatten().tolist()) - encoder_hidden_states1.append(self.text_encoder1_cache[input_id1_cache_key]) - hidden_states2, p2 = self.text_encoder2_cache[input_id2_cache_key] - encoder_hidden_states2.append(hidden_states2) - pool2.append(p2) - encoder_hidden_states1 = torch.stack(encoder_hidden_states1).to(accelerator.device).to(weight_dtype) - encoder_hidden_states2 = torch.stack(encoder_hidden_states2).to(accelerator.device).to(weight_dtype) - pool2 = torch.stack(pool2).to(accelerator.device).to(weight_dtype) + encoder_hidden_states1 = batch["text_encoder_outputs1_list"].to(accelerator.device).to(weight_dtype) + encoder_hidden_states2 = batch["text_encoder_outputs2_list"].to(accelerator.device).to(weight_dtype) + pool2 = batch["text_encoder_pool2_list"].to(accelerator.device).to(weight_dtype) + + # # verify that the text encoder outputs are correct + # ehs1, ehs2, p2 = train_util.get_hidden_states_sdxl( + # args.max_token_length, + # batch["input_ids"].to(text_encoders[0].device), + # batch["input_ids2"].to(text_encoders[0].device), + # tokenizers[0], + # tokenizers[1], + # text_encoders[0], + # text_encoders[1], + # None if not args.full_fp16 else weight_dtype, + # ) + # b_size = encoder_hidden_states1.shape[0] + # assert ((encoder_hidden_states1.to("cpu") - ehs1.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # assert ((encoder_hidden_states2.to("cpu") - ehs2.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # assert ((pool2.to("cpu") - p2.to(dtype=weight_dtype)).abs().max() > 1e-2).sum() <= b_size * 2 + # print("text encoder outputs verified") + return encoder_hidden_states1, encoder_hidden_states2, pool2 diff --git a/sdxl_train_textual_inversion.py b/sdxl_train_textual_inversion.py index 2616a22c6..c649c9f49 100644 --- a/sdxl_train_textual_inversion.py +++ b/sdxl_train_textual_inversion.py @@ -45,8 +45,8 @@ def get_text_cond(self, args, accelerator, batch, tokenizers, text_encoders, wei with torch.enable_grad(): input_ids1 = input_ids1.to(accelerator.device) input_ids2 = input_ids2.to(accelerator.device) - encoder_hidden_states1, encoder_hidden_states2, pool2 = sdxl_train_util.get_hidden_states( - args, + encoder_hidden_states1, encoder_hidden_states2, pool2 = train_util.get_hidden_states_sdxl( + args.max_token_length, input_ids1, input_ids2, tokenizers[0], diff --git a/tools/cache_text_encoder_outputs.py b/tools/cache_text_encoder_outputs.py new file mode 100644 index 000000000..2110e7261 --- /dev/null +++ b/tools/cache_text_encoder_outputs.py @@ -0,0 +1,191 @@ +# text encoder出力のdiskへの事前キャッシュを行う / cache text encoder outputs to disk in advance + +import argparse +import math +from multiprocessing import Value +import os + +from accelerate.utils import set_seed +import torch +from tqdm import tqdm + +from library import config_util +from library import train_util +from library import sdxl_train_util +from library.config_util import ( + ConfigSanitizer, + BlueprintGenerator, +) + + +def cache_to_disk(args: argparse.Namespace) -> None: + train_util.prepare_dataset_args(args, True) + + # check cache arg + assert ( + args.cache_text_encoder_outputs_to_disk + ), "cache_text_encoder_outputs_to_disk must be True / cache_text_encoder_outputs_to_diskはTrueである必要があります" + + # できるだけ準備はしておくが今のところSDXLのみしか動かない + assert ( + args.sdxl + ), "cache_text_encoder_outputs_to_disk is only available for SDXL / cache_text_encoder_outputs_to_diskはSDXLのみ利用可能です" + + use_dreambooth_method = args.in_json is None + + if args.seed is not None: + set_seed(args.seed) # 乱数系列を初期化する + + # tokenizerを準備する:datasetを動かすために必要 + if args.sdxl: + tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) + tokenizers = [tokenizer1, tokenizer2] + else: + tokenizer = train_util.load_tokenizer(args) + tokenizers = [tokenizer] + + # データセットを準備する + if args.dataset_class is None: + blueprint_generator = BlueprintGenerator(ConfigSanitizer(True, True, False, True)) + if args.dataset_config is not None: + print(f"Load dataset config from {args.dataset_config}") + user_config = config_util.load_user_config(args.dataset_config) + ignored = ["train_data_dir", "in_json"] + if any(getattr(args, attr) is not None for attr in ignored): + print( + "ignore following options because config file is found: {0} / 設定ファイルが利用されるため以下のオプションは無視されます: {0}".format( + ", ".join(ignored) + ) + ) + else: + if use_dreambooth_method: + print("Using DreamBooth method.") + user_config = { + "datasets": [ + { + "subsets": config_util.generate_dreambooth_subsets_config_by_subdirs( + args.train_data_dir, args.reg_data_dir + ) + } + ] + } + else: + print("Training with captions.") + user_config = { + "datasets": [ + { + "subsets": [ + { + "image_dir": args.train_data_dir, + "metadata_file": args.in_json, + } + ] + } + ] + } + + blueprint = blueprint_generator.generate(user_config, args, tokenizer=tokenizers) + train_dataset_group = config_util.generate_dataset_group_by_blueprint(blueprint.dataset_group) + else: + train_dataset_group = train_util.load_arbitrary_dataset(args, tokenizers) + + current_epoch = Value("i", 0) + current_step = Value("i", 0) + ds_for_collater = train_dataset_group if args.max_data_loader_n_workers == 0 else None + collater = train_util.collater_class(current_epoch, current_step, ds_for_collater) + + # acceleratorを準備する + print("prepare accelerator") + accelerator = train_util.prepare_accelerator(args) + + # mixed precisionに対応した型を用意しておき適宜castする + weight_dtype, _ = train_util.prepare_dtype(args) + + # モデルを読み込む + print("load model") + if args.sdxl: + (_, text_encoder1, text_encoder2, _, _, _, _) = sdxl_train_util.load_target_model(args, accelerator, "sdxl", weight_dtype) + text_encoders = [text_encoder1, text_encoder2] + else: + text_encoder1, _, _, _ = train_util.load_target_model(args, weight_dtype, accelerator) + text_encoders = [text_encoder1] + + for text_encoder in text_encoders: + text_encoder.to(accelerator.device, dtype=weight_dtype) + text_encoder.requires_grad_(False) + text_encoder.eval() + + # dataloaderを準備する + train_dataset_group.set_caching_mode("text") + + # DataLoaderのプロセス数:0はメインプロセスになる + n_workers = min(args.max_data_loader_n_workers, os.cpu_count() - 1) # cpu_count-1 ただし最大で指定された数まで + + train_dataloader = torch.utils.data.DataLoader( + train_dataset_group, + batch_size=1, + shuffle=True, + collate_fn=collater, + num_workers=n_workers, + persistent_workers=args.persistent_data_loader_workers, + ) + + # acceleratorを使ってモデルを準備する:マルチGPUで使えるようになるはず + train_dataloader = accelerator.prepare(train_dataloader) + + # データ取得のためのループ + for batch in tqdm(train_dataloader): + absolute_paths = batch["absolute_paths"] + input_ids1_list = batch["input_ids1_list"] + input_ids2_list = batch["input_ids2_list"] + + image_infos = [] + for absolute_path, input_ids1, input_ids2 in zip(absolute_paths, input_ids1_list, input_ids2_list): + image_info = train_util.ImageInfo(absolute_path, 1, "dummy", False, absolute_path) + image_info.text_encoder_outputs_npz = os.path.splitext(absolute_path)[0] + train_util.TEXT_ENCODER_OUTPUTS_CACHE_SUFFIX + image_info + + if args.skip_existing: + if os.path.exists(image_info.text_encoder_outputs_npz): + print(f"Skipping {image_info.text_encoder_outputs_npz} because it already exists.") + continue + + image_info.input_ids1 = input_ids1 + image_info.input_ids2 = input_ids2 + image_infos.append(image_info) + + if len(image_infos) > 0: + b_input_ids1 = torch.stack([image_info.input_ids1 for image_info in image_infos]) + b_input_ids2 = torch.stack([image_info.input_ids2 for image_info in image_infos]) + train_util.cache_batch_text_encoder_outputs( + image_infos, tokenizers, text_encoders, args.max_token_length, True, b_input_ids1, b_input_ids2, weight_dtype + ) + + accelerator.wait_for_everyone() + accelerator.print(f"Finished caching latents for {len(train_dataset_group)} batches.") + + +def setup_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + + train_util.add_sd_models_arguments(parser) + train_util.add_training_arguments(parser, True) + train_util.add_dataset_arguments(parser, True, True, True) + config_util.add_config_arguments(parser) + sdxl_train_util.add_sdxl_training_arguments(parser) + parser.add_argument("--sdxl", action="store_true", help="Use SDXL model / SDXLモデルを使用する") + parser.add_argument( + "--skip_existing", + action="store_true", + help="skip images if npz already exists (both normal and flipped exists if flip_aug is enabled) / npzが既に存在する画像をスキップする(flip_aug有効時は通常、反転の両方が存在する画像をスキップ)", + ) + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + args = train_util.read_config_from_file(args, parser) + + cache_to_disk(args) From 3db97f88979a7bbd08902c977cd44a36199288f6 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 16 Jul 2023 15:14:49 +0900 Subject: [PATCH 088/220] update readme --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7af3f8341..f725db35f 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,15 @@ The feature of SDXL training is now available in sdxl branch as an experimental Summary of the feature: -- `tools/cache_latents.py` is added. This script can be used to cache the latents in advance. +- `tools/cache_latents.py` is added. This script can be used to cache the latents to disk in advance. - The options are almost the same as `sdxl_train.py'. See the help message for the usage. - Please launch the script as follows: `accelerate launch --num_cpu_threads_per_process 1 tools/cache_latents.py ...` - This script should work with multi-GPU, but it is not tested in my environment. +- `tools/cache_text_encoder_outputs.py` is added. This script can be used to cache the text encoder outputs to disk in advance. + - The options are almost the same as `cache_latents.py' and `sdxl_train.py'. See the help message for the usage. + - `sdxl_train.py` is a script for SDXL fine-tuning. The usage is almost the same as `fine_tune.py`, but it also supports DreamBooth dataset. - `--full_bf16` option is added. Thanks to KohakuBlueleaf! - This option enables the full bfloat16 training (includes gradients). This option is useful to reduce the GPU memory usage. @@ -39,9 +42,9 @@ Summary of the feature: - `prepare_buckets_latents.py` now supports SDXL fine-tuning. - `sdxl_train_network.py` is a script for LoRA training for SDXL. The usage is almost the same as `train_network.py`. - Both scripts has following additional options: - - `--cache_text_encoder_outputs`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. + - `--cache_text_encoder_outputs` and `--cache_text_encoder_outputs_to_disk`: Cache the outputs of the text encoders. This option is useful to reduce the GPU memory usage. This option cannot be used with options for shuffling or dropping the captions. - `--no_half_vae`: Disable the half-precision (mixed-precision) VAE. VAE for SDXL seems to produce NaNs in some cases. This option is useful to avoid the NaNs. -- The image generation during training is now available. However, the VAE for SDXL seems to produce NaNs in some cases when using `fp16`. The images will be black. Currently, the NaNs cannot be avoided even with `--no_half_vae` option. It works with `bf16` or without mixed precision. +- The image generation during training is now available. `--no_half_vae` option also works to avoid black images. - `--weighted_captions` option is not supported yet for both scripts. - `--min_timestep` and `--max_timestep` options are added to each training script. These options can be used to train U-Net with different timesteps. The default values are 0 and 1000. From 41d195715d00d8db42335ab4ffef2a2e07fb97ff Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 16 Jul 2023 15:56:29 +0900 Subject: [PATCH 089/220] fix scheduler steps with gradient accumulation --- library/train_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/train_util.py b/library/train_util.py index c36651e2d..a4021c4fa 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -3348,7 +3348,7 @@ def get_scheduler_fix(args, optimizer: Optimizer, num_processes: int): """ name = args.lr_scheduler num_warmup_steps: Optional[int] = args.lr_warmup_steps - num_training_steps = args.max_train_steps * num_processes * args.gradient_accumulation_steps + num_training_steps = args.max_train_steps * num_processes # * args.gradient_accumulation_steps num_cycles = args.lr_scheduler_num_cycles power = args.lr_scheduler_power From 39e62b948e4a5da26225ad1d5d1a9670e134f2b5 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 16 Jul 2023 19:57:21 +0900 Subject: [PATCH 090/220] add lora for Diffusers --- networks/lora_diffusers.py | 586 +++++++++++++++++++++++++++++++++++++ 1 file changed, 586 insertions(+) create mode 100644 networks/lora_diffusers.py diff --git a/networks/lora_diffusers.py b/networks/lora_diffusers.py new file mode 100644 index 000000000..c17b6e3a8 --- /dev/null +++ b/networks/lora_diffusers.py @@ -0,0 +1,586 @@ +# Diffusersで動くLoRA。このファイル単独で完結する。 +# LoRA module for Diffusers. This file works independently. + +import bisect +import math +import random +from typing import Any, Dict, List, Mapping, Optional, Union +from diffusers import UNet2DConditionModel +import numpy as np +from tqdm import tqdm +from transformers import CLIPTextModel +import torch + + +def make_unet_conversion_map() -> Dict[str, str]: + unet_conversion_map_layer = [] + + for i in range(3): # num_blocks is 3 in sdxl + # loop over downblocks/upblocks + for j in range(2): + # loop over resnets/attentions for downblocks + hf_down_res_prefix = f"down_blocks.{i}.resnets.{j}." + sd_down_res_prefix = f"input_blocks.{3*i + j + 1}.0." + unet_conversion_map_layer.append((sd_down_res_prefix, hf_down_res_prefix)) + + if i < 3: + # no attention layers in down_blocks.3 + hf_down_atn_prefix = f"down_blocks.{i}.attentions.{j}." + sd_down_atn_prefix = f"input_blocks.{3*i + j + 1}.1." + unet_conversion_map_layer.append((sd_down_atn_prefix, hf_down_atn_prefix)) + + for j in range(3): + # loop over resnets/attentions for upblocks + hf_up_res_prefix = f"up_blocks.{i}.resnets.{j}." + sd_up_res_prefix = f"output_blocks.{3*i + j}.0." + unet_conversion_map_layer.append((sd_up_res_prefix, hf_up_res_prefix)) + + # if i > 0: commentout for sdxl + # no attention layers in up_blocks.0 + hf_up_atn_prefix = f"up_blocks.{i}.attentions.{j}." + sd_up_atn_prefix = f"output_blocks.{3*i + j}.1." + unet_conversion_map_layer.append((sd_up_atn_prefix, hf_up_atn_prefix)) + + if i < 3: + # no downsample in down_blocks.3 + hf_downsample_prefix = f"down_blocks.{i}.downsamplers.0.conv." + sd_downsample_prefix = f"input_blocks.{3*(i+1)}.0.op." + unet_conversion_map_layer.append((sd_downsample_prefix, hf_downsample_prefix)) + + # no upsample in up_blocks.3 + hf_upsample_prefix = f"up_blocks.{i}.upsamplers.0." + sd_upsample_prefix = f"output_blocks.{3*i + 2}.{2}." # change for sdxl + unet_conversion_map_layer.append((sd_upsample_prefix, hf_upsample_prefix)) + + hf_mid_atn_prefix = "mid_block.attentions.0." + sd_mid_atn_prefix = "middle_block.1." + unet_conversion_map_layer.append((sd_mid_atn_prefix, hf_mid_atn_prefix)) + + for j in range(2): + hf_mid_res_prefix = f"mid_block.resnets.{j}." + sd_mid_res_prefix = f"middle_block.{2*j}." + unet_conversion_map_layer.append((sd_mid_res_prefix, hf_mid_res_prefix)) + + unet_conversion_map_resnet = [ + # (stable-diffusion, HF Diffusers) + ("in_layers.0.", "norm1."), + ("in_layers.2.", "conv1."), + ("out_layers.0.", "norm2."), + ("out_layers.3.", "conv2."), + ("emb_layers.1.", "time_emb_proj."), + ("skip_connection.", "conv_shortcut."), + ] + + unet_conversion_map = [] + for sd, hf in unet_conversion_map_layer: + if "resnets" in hf: + for sd_res, hf_res in unet_conversion_map_resnet: + unet_conversion_map.append((sd + sd_res, hf + hf_res)) + else: + unet_conversion_map.append((sd, hf)) + + for j in range(2): + hf_time_embed_prefix = f"time_embedding.linear_{j+1}." + sd_time_embed_prefix = f"time_embed.{j*2}." + unet_conversion_map.append((sd_time_embed_prefix, hf_time_embed_prefix)) + + for j in range(2): + hf_label_embed_prefix = f"add_embedding.linear_{j+1}." + sd_label_embed_prefix = f"label_emb.0.{j*2}." + unet_conversion_map.append((sd_label_embed_prefix, hf_label_embed_prefix)) + + unet_conversion_map.append(("input_blocks.0.0.", "conv_in.")) + unet_conversion_map.append(("out.0.", "conv_norm_out.")) + unet_conversion_map.append(("out.2.", "conv_out.")) + + sd_hf_conversion_map = {sd.replace(".", "_")[:-1]: hf.replace(".", "_")[:-1] for sd, hf in unet_conversion_map} + return sd_hf_conversion_map + + +UNET_CONVERSION_MAP = make_unet_conversion_map() + + +class LoRAModule(torch.nn.Module): + """ + replaces forward method of the original Linear, instead of replacing the original Linear module. + """ + + def __init__( + self, + lora_name, + org_module: torch.nn.Module, + multiplier=1.0, + lora_dim=4, + alpha=1, + ): + """if alpha == 0 or None, alpha is rank (no scaling).""" + super().__init__() + self.lora_name = lora_name + + if org_module.__class__.__name__ == "Conv2d": + in_dim = org_module.in_channels + out_dim = org_module.out_channels + else: + in_dim = org_module.in_features + out_dim = org_module.out_features + + self.lora_dim = lora_dim + + if org_module.__class__.__name__ == "Conv2d": + kernel_size = org_module.kernel_size + stride = org_module.stride + padding = org_module.padding + self.lora_down = torch.nn.Conv2d(in_dim, self.lora_dim, kernel_size, stride, padding, bias=False) + self.lora_up = torch.nn.Conv2d(self.lora_dim, out_dim, (1, 1), (1, 1), bias=False) + else: + self.lora_down = torch.nn.Linear(in_dim, self.lora_dim, bias=False) + self.lora_up = torch.nn.Linear(self.lora_dim, out_dim, bias=False) + + if type(alpha) == torch.Tensor: + alpha = alpha.detach().float().numpy() # without casting, bf16 causes error + alpha = self.lora_dim if alpha is None or alpha == 0 else alpha + self.scale = alpha / self.lora_dim + self.register_buffer("alpha", torch.tensor(alpha)) # 勾配計算に含めない / not included in gradient calculation + + # same as microsoft's + torch.nn.init.kaiming_uniform_(self.lora_down.weight, a=math.sqrt(5)) + torch.nn.init.zeros_(self.lora_up.weight) + + self.multiplier = multiplier + self.org_module = [org_module] + self.enabled = True + self.network: LoRANetwork = None + self.org_forward = None + + # override org_module's forward method + def apply_to(self, multiplier=None): + if multiplier is not None: + self.multiplier = multiplier + if self.org_forward is None: + self.org_forward = self.org_module[0].forward + self.org_module[0].forward = self.forward + + # restore org_module's forward method + def unapply_to(self): + if self.org_forward is not None: + self.org_module[0].forward = self.org_forward + + # forward with lora + def forward(self, x): + if not self.enabled: + return self.org_forward(x) + return self.org_forward(x) + self.lora_up(self.lora_down(x)) * self.multiplier * self.scale + + def set_network(self, network): + self.network = network + + # merge lora weight to org weight + def merge_to(self, multiplier=1.0): + # get lora weight + lora_weight = self.get_weight(multiplier) + + # get org weight + org_sd = self.org_module[0].state_dict() + org_weight = org_sd["weight"] + weight = org_weight + lora_weight.to(org_weight.device, dtype=org_weight.dtype) + + # set weight to org_module + org_sd["weight"] = weight + self.org_module[0].load_state_dict(org_sd) + + # restore org weight from lora weight + def restore_from(self, multiplier=1.0): + # get lora weight + lora_weight = self.get_weight(multiplier) + + # get org weight + org_sd = self.org_module[0].state_dict() + org_weight = org_sd["weight"] + weight = org_weight - lora_weight.to(org_weight.device, dtype=org_weight.dtype) + + # set weight to org_module + org_sd["weight"] = weight + self.org_module[0].load_state_dict(org_sd) + + # return lora weight + def get_weight(self, multiplier=None): + if multiplier is None: + multiplier = self.multiplier + + # get up/down weight from module + up_weight = self.lora_up.weight.to(torch.float) + down_weight = self.lora_down.weight.to(torch.float) + + # pre-calculated weight + if len(down_weight.size()) == 2: + # linear + weight = self.multiplier * (up_weight @ down_weight) * self.scale + elif down_weight.size()[2:4] == (1, 1): + # conv2d 1x1 + weight = ( + self.multiplier + * (up_weight.squeeze(3).squeeze(2) @ down_weight.squeeze(3).squeeze(2)).unsqueeze(2).unsqueeze(3) + * self.scale + ) + else: + # conv2d 3x3 + conved = torch.nn.functional.conv2d(down_weight.permute(1, 0, 2, 3), up_weight).permute(1, 0, 2, 3) + weight = self.multiplier * conved * self.scale + + return weight + + +# Create network from weights for inference, weights are not loaded here +def create_network_from_weights( + text_encoder: Union[CLIPTextModel, List[CLIPTextModel]], unet: UNet2DConditionModel, weights_sd: Dict, multiplier: float = 1.0 +): + # get dim/alpha mapping + modules_dim = {} + modules_alpha = {} + for key, value in weights_sd.items(): + if "." not in key: + continue + + lora_name = key.split(".")[0] + if "alpha" in key: + modules_alpha[lora_name] = value + elif "lora_down" in key: + dim = value.size()[0] + modules_dim[lora_name] = dim + # print(lora_name, value.size(), dim) + + # support old LoRA without alpha + for key in modules_dim.keys(): + if key not in modules_alpha: + modules_alpha[key] = modules_dim[key] + + return LoRANetwork(text_encoder, unet, multiplier=multiplier, modules_dim=modules_dim, modules_alpha=modules_alpha) + + +# block weightや学習に対応しない簡易版 / simple version without block weight and training +class LoRANetwork(torch.nn.Module): + UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel"] + UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 = ["ResnetBlock2D", "Downsample2D", "Upsample2D"] + TEXT_ENCODER_TARGET_REPLACE_MODULE = ["CLIPAttention", "CLIPMLP"] + LORA_PREFIX_UNET = "lora_unet" + LORA_PREFIX_TEXT_ENCODER = "lora_te" + + # SDXL: must starts with LORA_PREFIX_TEXT_ENCODER + LORA_PREFIX_TEXT_ENCODER1 = "lora_te1" + LORA_PREFIX_TEXT_ENCODER2 = "lora_te2" + + def __init__( + self, + text_encoder: Union[List[CLIPTextModel], CLIPTextModel], + unet: UNet2DConditionModel, + multiplier: float = 1.0, + modules_dim: Optional[Dict[str, int]] = None, + modules_alpha: Optional[Dict[str, int]] = None, + varbose: Optional[bool] = False, + ) -> None: + super().__init__() + self.multiplier = multiplier + + print(f"create LoRA network from weights") + + # convert SDXL Stability AI's U-Net modules to Diffusers + converted = self.convert_unet_modules(modules_dim, modules_alpha) + if converted: + print(f"converted {converted} Stability AI's U-Net LoRA modules to Diffusers (SDXL)") + + # create module instances + def create_modules( + is_unet: bool, + text_encoder_idx: Optional[int], # None, 1, 2 + root_module: torch.nn.Module, + target_replace_modules: List[torch.nn.Module], + ) -> List[LoRAModule]: + prefix = ( + self.LORA_PREFIX_UNET + if is_unet + else ( + self.LORA_PREFIX_TEXT_ENCODER + if text_encoder_idx is None + else (self.LORA_PREFIX_TEXT_ENCODER1 if text_encoder_idx == 1 else self.LORA_PREFIX_TEXT_ENCODER2) + ) + ) + loras = [] + skipped = [] + for name, module in root_module.named_modules(): + if module.__class__.__name__ in target_replace_modules: + for child_name, child_module in module.named_modules(): + is_linear = child_module.__class__.__name__ == "Linear" + is_conv2d = child_module.__class__.__name__ == "Conv2d" + + if is_linear or is_conv2d: + lora_name = prefix + "." + name + "." + child_name + lora_name = lora_name.replace(".", "_") + + if lora_name not in modules_dim: + # print(f"skipped {lora_name} (not found in modules_dim)") + skipped.append(lora_name) + continue + + dim = modules_dim[lora_name] + alpha = modules_alpha[lora_name] + lora = LoRAModule( + lora_name, + child_module, + self.multiplier, + dim, + alpha, + ) + loras.append(lora) + return loras, skipped + + text_encoders = text_encoder if type(text_encoder) == list else [text_encoder] + + # create LoRA for text encoder + # 毎回すべてのモジュールを作るのは無駄なので要検討 / it is wasteful to create all modules every time, need to consider + self.text_encoder_loras: List[LoRAModule] = [] + skipped_te = [] + for i, text_encoder in enumerate(text_encoders): + if len(text_encoders) > 1: + index = i + 1 + else: + index = None + + text_encoder_loras, skipped = create_modules(False, index, text_encoder, LoRANetwork.TEXT_ENCODER_TARGET_REPLACE_MODULE) + self.text_encoder_loras.extend(text_encoder_loras) + skipped_te += skipped + print(f"create LoRA for Text Encoder: {len(self.text_encoder_loras)} modules.") + if len(skipped_te) > 0: + print(f"skipped {len(skipped_te)} modules because of missing weight.") + + # extend U-Net target modules to include Conv2d 3x3 + target_modules = LoRANetwork.UNET_TARGET_REPLACE_MODULE + LoRANetwork.UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 + + self.unet_loras: List[LoRAModule] + self.unet_loras, skipped_un = create_modules(True, None, unet, target_modules) + print(f"create LoRA for U-Net: {len(self.unet_loras)} modules.") + if len(skipped_un) > 0: + print(f"skipped {len(skipped_un)} modules because of missing weight.") + + # assertion + names = set() + for lora in self.text_encoder_loras + self.unet_loras: + names.add(lora.lora_name) + for lora_name in modules_dim.keys(): + assert lora_name in names, f"{lora_name} is not found in created LoRA modules." + + # make to work load_state_dict + for lora in self.text_encoder_loras + self.unet_loras: + self.add_module(lora.lora_name, lora) + + # SDXL: convert SDXL Stability AI's U-Net modules to Diffusers + def convert_unet_modules(self, modules_dim, modules_alpha): + converted_count = 0 + not_converted_count = 0 + + map_keys = list(UNET_CONVERSION_MAP.keys()) + map_keys.sort() + + for key in list(modules_dim.keys()): + if key.startswith(LoRANetwork.LORA_PREFIX_UNET + "_"): + search_key = key.replace(LoRANetwork.LORA_PREFIX_UNET + "_", "") + position = bisect.bisect_right(map_keys, search_key) + map_key = map_keys[position - 1] + if search_key.startswith(map_key): + new_key = key.replace(map_key, UNET_CONVERSION_MAP[map_key]) + modules_dim[new_key] = modules_dim[key] + modules_alpha[new_key] = modules_alpha[key] + del modules_dim[key] + del modules_alpha[key] + converted_count += 1 + else: + not_converted_count += 1 + assert ( + converted_count == 0 or not_converted_count == 0 + ), f"some modules are not converted: {converted_count} converted, {not_converted_count} not converted" + return converted_count + + def set_multiplier(self, multiplier): + self.multiplier = multiplier + for lora in self.text_encoder_loras + self.unet_loras: + lora.multiplier = self.multiplier + + def apply_to(self, multiplier=1.0, apply_text_encoder=True, apply_unet=True): + if apply_text_encoder: + print("enable LoRA for text encoder") + for lora in self.text_encoder_loras: + lora.apply_to(multiplier) + if apply_unet: + print("enable LoRA for U-Net") + for lora in self.unet_loras: + lora.apply_to(multiplier) + + def unapply_to(self): + for lora in self.text_encoder_loras + self.unet_loras: + lora.unapply_to() + + def merge_to(self, multiplier=1.0): + print("merge LoRA weights to original weights") + for lora in tqdm(self.text_encoder_loras + self.unet_loras): + lora.merge_to(multiplier) + print(f"weights are merged") + + def restore_from(self, multiplier=1.0): + print("restore LoRA weights from original weights") + for lora in tqdm(self.text_encoder_loras + self.unet_loras): + lora.restore_from(multiplier) + print(f"weights are restored") + + def load_state_dict(self, state_dict: Mapping[str, Any], strict: bool = True): + # conver SDXL Stability AI's state dict to Diffusers' based state dict + map_keys = list(UNET_CONVERSION_MAP.keys()) # prefix of U-Net modules + map_keys.sort() + for key in list(state_dict.keys()): + if key.startswith(LoRANetwork.LORA_PREFIX_UNET + "_"): + search_key = key.replace(LoRANetwork.LORA_PREFIX_UNET + "_", "") + position = bisect.bisect_right(map_keys, search_key) + map_key = map_keys[position - 1] + if search_key.startswith(map_key): + new_key = key.replace(map_key, UNET_CONVERSION_MAP[map_key]) + state_dict[new_key] = state_dict[key] + del state_dict[key] + + # in case of V2, some weights have different shape, so we need to convert them + # because V2 LoRA is based on U-Net created by use_linear_projection=False + my_state_dict = self.state_dict() + for key in state_dict.keys(): + if state_dict[key].size() != my_state_dict[key].size(): + # print(f"convert {key} from {state_dict[key].size()} to {my_state_dict[key].size()}") + state_dict[key] = state_dict[key].view(my_state_dict[key].size()) + + return super().load_state_dict(state_dict, strict) + + +if __name__ == "__main__": + # sample code to use LoRANetwork + import os + import argparse + from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline + import torch + + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + parser = argparse.ArgumentParser() + parser.add_argument("--model_id", type=str, default=None, help="model id for huggingface") + parser.add_argument("--lora_weights", type=str, default=None, help="path to LoRA weights") + parser.add_argument("--sdxl", action="store_true", help="use SDXL model") + parser.add_argument("--prompt", type=str, default="A photo of cat", help="prompt text") + parser.add_argument("--negative_prompt", type=str, default="", help="negative prompt text") + parser.add_argument("--seed", type=int, default=0, help="random seed") + args = parser.parse_args() + + image_prefix = args.model_id.replace("/", "_") + "_" + + # load Diffusers model + print(f"load model from {args.model_id}") + pipe: Union[StableDiffusionPipeline, StableDiffusionXLPipeline] + if args.sdxl: + # use_safetensors=True does not work with 0.18.2 + pipe = StableDiffusionXLPipeline.from_pretrained(args.model_id, variant="fp16", torch_dtype=torch.float16) + else: + pipe = StableDiffusionPipeline.from_pretrained(args.model_id, variant="fp16", torch_dtype=torch.float16) + pipe.to(device) + pipe.set_use_memory_efficient_attention_xformers(True) + + text_encoders = [pipe.text_encoder, pipe.text_encoder_2] if args.sdxl else [pipe.text_encoder] + + # load LoRA weights + print(f"load LoRA weights from {args.lora_weights}") + if os.path.splitext(args.lora_weights)[1] == ".safetensors": + from safetensors.torch import load_file + + lora_sd = load_file(args.lora_weights) + else: + lora_sd = torch.load(args.lora_weights) + + # create by LoRA weights and load weights + print(f"create LoRA network") + lora_network: LoRANetwork = create_network_from_weights(text_encoders, pipe.unet, lora_sd, multiplier=1.0) + + print(f"load LoRA network weights") + lora_network.load_state_dict(lora_sd) + + lora_network.to(device, dtype=pipe.unet.dtype) # required to apply_to. merge_to works without this + + # 必要があれば、元のモデルの重みをバックアップしておく + # back-up unet/text encoder weights if necessary + def detach_and_move_to_cpu(state_dict): + for k, v in state_dict.items(): + state_dict[k] = v.detach().cpu() + return state_dict + + org_unet_sd = pipe.unet.state_dict() + detach_and_move_to_cpu(org_unet_sd) + + org_text_encoder_sd = pipe.text_encoder.state_dict() + detach_and_move_to_cpu(org_text_encoder_sd) + + if args.sdxl: + org_text_encoder_2_sd = pipe.text_encoder_2.state_dict() + detach_and_move_to_cpu(org_text_encoder_2_sd) + + def seed_everything(seed): + torch.manual_seed(seed) + torch.cuda.manual_seed_all(seed) + np.random.seed(seed) + random.seed(seed) + + # create image with original weights + print(f"create image with original weights") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "original.png") + + # apply LoRA network to the model: slower than merge_to, but can be reverted easily + print(f"apply LoRA network to the model") + lora_network.apply_to(multiplier=1.0) + + print(f"create image with applied LoRA") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "applied_lora.png") + + # unapply LoRA network to the model + print(f"unapply LoRA network to the model") + lora_network.unapply_to() + + print(f"create image with unapplied LoRA") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "unapplied_lora.png") + + # merge LoRA network to the model: faster than apply_to, but requires back-up of original weights (or unmerge_to) + print(f"merge LoRA network to the model") + lora_network.merge_to(multiplier=1.0) + + print(f"create image with LoRA") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "merged_lora.png") + + # restore (unmerge) LoRA weights: numerically unstable + # マージされた重みを元に戻す。計算誤差のため、元の重みと完全に一致しないことがあるかもしれない + # 保存したstate_dictから元の重みを復元するのが確実 + print(f"restore (unmerge) LoRA weights") + lora_network.restore_from(multiplier=1.0) + + print(f"create image without LoRA") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "unmerged_lora.png") + + # restore original weights + print(f"restore original weights") + pipe.unet.load_state_dict(org_unet_sd) + pipe.text_encoder.load_state_dict(org_text_encoder_sd) + if args.sdxl: + pipe.text_encoder_2.load_state_dict(org_text_encoder_2_sd) + + print(f"create image with restored original weights") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "restore_original.png") From 1d4672d747a2af7a0bcde3a5f8c5f782a2ffa499 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 17 Jul 2023 09:05:50 +0900 Subject: [PATCH 091/220] fix typos --- README.md | 2 +- networks/lora_diffusers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f725db35f..a46d6a78e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This repository contains the scripts for: * DreamBooth training, including U-Net and Text Encoder * Fine-tuning (native training), including U-Net and Text Encoder * LoRA training -* Texutl Inversion training +* Texutal Inversion training * Image generation * Model conversion (supports 1.x and 2.x, Stable Diffision ckpt/safetensors and Diffusers) diff --git a/networks/lora_diffusers.py b/networks/lora_diffusers.py index c17b6e3a8..f06212df4 100644 --- a/networks/lora_diffusers.py +++ b/networks/lora_diffusers.py @@ -431,7 +431,7 @@ def restore_from(self, multiplier=1.0): print(f"weights are restored") def load_state_dict(self, state_dict: Mapping[str, Any], strict: bool = True): - # conver SDXL Stability AI's state dict to Diffusers' based state dict + # convert SDXL Stability AI's state dict to Diffusers' based state dict map_keys = list(UNET_CONVERSION_MAP.keys()) # prefix of U-Net modules map_keys.sort() for key in list(state_dict.keys()): From 7e20c6d1a132d09ed087ef9d054645d9c9b68aca Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 17 Jul 2023 10:30:57 +0900 Subject: [PATCH 092/220] add convenience function to merge LoRA --- networks/lora_diffusers.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/networks/lora_diffusers.py b/networks/lora_diffusers.py index f06212df4..c41111bea 100644 --- a/networks/lora_diffusers.py +++ b/networks/lora_diffusers.py @@ -257,6 +257,15 @@ def create_network_from_weights( return LoRANetwork(text_encoder, unet, multiplier=multiplier, modules_dim=modules_dim, modules_alpha=modules_alpha) +def merge_lora_weights(pipe, weights_sd: Dict, multiplier: float = 1.0): + text_encoders = [pipe.text_encoder, pipe.text_encoder_2] if hasattr(pipe, "text_encoder_2") else [pipe.text_encoder] + unet = pipe.unet + + lora_network = create_network_from_weights(text_encoders, unet, weights_sd, multiplier=multiplier) + lora_network.load_state_dict(weights_sd) + lora_network.merge_to(multiplier=multiplier) + + # block weightや学習に対応しない簡易版 / simple version without block weight and training class LoRANetwork(torch.nn.Module): UNET_TARGET_REPLACE_MODULE = ["Transformer2DModel"] @@ -432,7 +441,7 @@ def restore_from(self, multiplier=1.0): def load_state_dict(self, state_dict: Mapping[str, Any], strict: bool = True): # convert SDXL Stability AI's state dict to Diffusers' based state dict - map_keys = list(UNET_CONVERSION_MAP.keys()) # prefix of U-Net modules + map_keys = list(UNET_CONVERSION_MAP.keys()) # prefix of U-Net modules map_keys.sort() for key in list(state_dict.keys()): if key.startswith(LoRANetwork.LORA_PREFIX_UNET + "_"): @@ -584,3 +593,12 @@ def seed_everything(seed): seed_everything(args.seed) image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] image.save(image_prefix + "restore_original.png") + + # use convenience function to merge LoRA weights + print(f"merge LoRA weights with convenience function") + merge_lora_weights(pipe, lora_sd, multiplier=1.0) + + print(f"create image with merged LoRA weights") + seed_everything(args.seed) + image = pipe(args.prompt, negative_prompt=args.negative_prompt).images[0] + image.save(image_prefix + "convenience_merged_lora.png") From 8a073ee49f6ec29429c66b8ccfabba49bf167ebc Mon Sep 17 00:00:00 2001 From: Pam Date: Mon, 17 Jul 2023 17:51:26 +0500 Subject: [PATCH 093/220] vram leak fix --- library/train_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/train_util.py b/library/train_util.py index a4021c4fa..ea63b71de 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2141,6 +2141,8 @@ def cache_batch_latents( info.latents = latent if flip_aug: info.latents_flipped = flipped_latent + if torch.cuda.is_available(): + torch.cuda.empty_cache() def cache_batch_text_encoder_outputs( From 3d66a234b0b029753b8a6b3001ed5648b4f8b254 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 18 Jul 2023 21:39:01 +0900 Subject: [PATCH 094/220] enable different prompt for text encoders --- sdxl_minimal_inference.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index 25b8e51bf..d441877d9 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -86,6 +86,7 @@ def get_timestep_embedding(x, outdim): parser = argparse.ArgumentParser() parser.add_argument("--ckpt_path", type=str, required=True) parser.add_argument("--prompt", type=str, default="A photo of a cat") + parser.add_argument("--prompt2", type=str, default=None) parser.add_argument("--negative_prompt", type=str, default="") parser.add_argument("--output_dir", type=str, default=".") parser.add_argument( @@ -98,6 +99,9 @@ def get_timestep_embedding(x, outdim): parser.add_argument("--interactive", action="store_true") args = parser.parse_args() + if args.prompt2 is None: + args.prompt2 = args.prompt + # HuggingFaceのmodel id text_encoder_1_name = "openai/clip-vit-large-patch14" text_encoder_2_name = "laion/CLIP-ViT-bigG-14-laion2B-39B-b160k" @@ -169,7 +173,7 @@ def get_timestep_embedding(x, outdim): beta_schedule=SCHEDLER_SCHEDULE, ) - def generate_image(prompt, negative_prompt, seed=None): + def generate_image(prompt, prompt2, negative_prompt, seed=None): # 将来的にサイズ情報も変えられるようにする / Make it possible to change the size information in the future # prepare embedding with torch.no_grad(): @@ -184,7 +188,7 @@ def generate_image(prompt, negative_prompt, seed=None): # crossattn # Text Encoderを二つ呼ぶ関数 Function to call two Text Encoders - def call_text_encoder(text): + def call_text_encoder(text, text2): # text encoder 1 batch_encoding = tokenizer1( text, @@ -203,7 +207,7 @@ def call_text_encoder(text): # text encoder 2 with torch.no_grad(): - tokens = tokenizer2(text).to(DEVICE) + tokens = tokenizer2(text2).to(DEVICE) enc_out = text_model2(tokens, output_hidden_states=True, return_dict=True) text_embedding2_penu = enc_out["hidden_states"][-2] @@ -215,12 +219,12 @@ def call_text_encoder(text): return text_embedding, text_embedding2_pool # cond - c_ctx, c_ctx_pool = call_text_encoder(prompt) + c_ctx, c_ctx_pool = call_text_encoder(prompt, prompt2) # print(c_ctx.shape, c_ctx_p.shape, c_vector.shape) c_vector = torch.cat([c_ctx_pool, c_vector], dim=1) # uncond - uc_ctx, uc_ctx_pool = call_text_encoder(negative_prompt) + uc_ctx, uc_ctx_pool = call_text_encoder(negative_prompt, negative_prompt) uc_vector = torch.cat([uc_ctx_pool, uc_vector], dim=1) text_embeddings = torch.cat([uc_ctx, c_ctx]) @@ -295,19 +299,22 @@ def call_text_encoder(text): img.save(os.path.join(args.output_dir, f"image_{timestamp}_{i:03d}.png")) if not args.interactive: - generate_image(args.prompt, args.negative_prompt, seed) + generate_image(args.prompt, args.prompt2, args.negative_prompt, seed) else: # loop for interactive while True: prompt = input("prompt: ") if prompt == "": break + prompt2 = input("prompt2: ") + if prompt2 == "": + prompt2 = prompt negative_prompt = input("negative prompt: ") seed = input("seed: ") if seed == "": seed = None else: seed = int(seed) - generate_image(prompt, negative_prompt, seed) + generate_image(prompt, prompt2, negative_prompt, seed) print("Done!") From 0ec71660988fbdfa769d181774d6ae893c358950 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 18 Jul 2023 21:39:36 +0900 Subject: [PATCH 095/220] make crop top/left same as stabilityai's prep --- library/train_util.py | 75 ++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index a4021c4fa..785dc0f9c 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -121,7 +121,7 @@ def __init__(self, image_key: str, num_repeats: int, caption: str, is_reg: bool, self.latents_flipped: torch.Tensor = None self.latents_npz: str = None self.latents_original_size: Tuple[int, int] = None # original image size, not latents size - self.latents_crop_left_top: Tuple[int, int] = None # original image crop left top, not latents crop left top + self.latents_crop_ltrb: Tuple[int, int] = None # crop left top right bottom in original pixel size, not latents size self.cond_img_path: str = None self.image: Optional[Image.Image] = None # optional, original PIL Image # SDXL, optional @@ -256,6 +256,26 @@ def select_bucket(self, image_width, image_height): ar_error = (reso[0] / reso[1]) - aspect_ratio return reso, resized_size, ar_error + @staticmethod + def get_crop_ltrb(bucket_reso: Tuple[int, int], image_size: Tuple[int, int]): + # Stability AIの前処理に合わせてcrop left/topを計算する。crop rightはflipのaugmentationのために求める + # Calculate crop left/top according to the preprocessing of Stability AI. Crop right is calculated for flip augmentation. + + bucket_ar = bucket_reso[0] / bucket_reso[1] + image_ar = image_size[0] / image_size[1] + if bucket_ar > image_ar: + # bucketのほうが横長→縦を合わせる + resized_width = bucket_reso[1] * image_ar + resized_height = bucket_reso[1] + else: + resized_width = bucket_reso[0] + resized_height = bucket_reso[0] / image_ar + crop_left = (bucket_reso[0] - resized_width) // 2 + crop_top = (bucket_reso[1] - resized_height) // 2 + crop_right = crop_left + resized_width + crop_bottom = crop_top + resized_height + return crop_left, crop_top, crop_right, crop_bottom + class BucketBatchIndex(NamedTuple): bucket_index: int @@ -1016,7 +1036,7 @@ def __getitem__(self, index): # image/latentsを処理する if image_info.latents is not None: # cache_latents=Trueの場合 original_size = image_info.latents_original_size - crop_left_top = image_info.latents_crop_left_top # calc values later if flipped + crop_ltrb = image_info.latents_crop_ltrb # calc values later if flipped if not flipped: latents = image_info.latents else: @@ -1024,7 +1044,7 @@ def __getitem__(self, index): image = None elif image_info.latents_npz is not None: # FineTuningDatasetまたはcache_latents_to_disk=Trueの場合 - latents, original_size, crop_left_top, flipped_latents = load_latents_from_disk(image_info.latents_npz) + latents, original_size, crop_ltrb, flipped_latents = load_latents_from_disk(image_info.latents_npz) if flipped: latents = flipped_latents del flipped_latents @@ -1037,7 +1057,7 @@ def __getitem__(self, index): im_h, im_w = img.shape[0:2] if self.enable_bucket: - img, original_size, crop_left_top = trim_and_resize_if_required( + img, original_size, crop_ltrb = trim_and_resize_if_required( subset.random_crop, img, image_info.bucket_reso, image_info.resized_size ) else: @@ -1060,7 +1080,7 @@ def __getitem__(self, index): ), f"image size is small / 画像サイズが小さいようです: {image_info.absolute_path}" original_size = [im_w, im_h] - crop_left_top = [0, 0] + crop_ltrb = (0, 0, 0, 0) # augmentation aug = self.aug_helper.get_augmentor(subset.color_aug) @@ -1078,8 +1098,11 @@ def __getitem__(self, index): target_size = (image.shape[2], image.shape[1]) if image is not None else (latents.shape[2] * 8, latents.shape[1] * 8) - if flipped: - crop_left_top = (original_size[0] - crop_left_top[0] - target_size[0], crop_left_top[1]) + if not flipped: + crop_left_top = (crop_ltrb[0], crop_ltrb[1]) + else: + # crop_ltrb[2] is right, so target_size[0] - crop_ltrb[2] is left in flipped image + crop_left_top = (target_size[0] - crop_ltrb[2], crop_ltrb[1]) original_sizes_hw.append((original_size[1], original_size[0])) crop_top_lefts.append((crop_left_top[1], crop_left_top[0])) @@ -1841,7 +1864,7 @@ def is_disk_cached_latents_is_expected(reso, npz_path: str, flip_aug: bool): return False npz = np.load(npz_path) - if "latents" not in npz or "original_size" not in npz or "crop_left_top" not in npz: # old ver? + if "latents" not in npz or "original_size" not in npz or "crop_ltrb" not in npz: # old ver? return False if npz["latents"].shape[1:3] != expected_latents_size: return False @@ -1866,12 +1889,12 @@ def load_latents_from_disk( latents = npz["latents"] original_size = npz["original_size"].tolist() - crop_left_top = npz["crop_left_top"].tolist() + crop_ltrb = npz["crop_ltrb"].tolist() flipped_latents = npz["latents_flipped"] if "latents_flipped" in npz else None - return latents, original_size, crop_left_top, flipped_latents + return latents, original_size, crop_ltrb, flipped_latents -def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_left_top, flipped_latents_tensor=None): +def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_ltrb, flipped_latents_tensor=None): kwargs = {} if flipped_latents_tensor is not None: kwargs["latents_flipped"] = flipped_latents_tensor.float().cpu().numpy() @@ -1879,7 +1902,7 @@ def save_latents_to_disk(npz_path, latents_tensor, original_size, crop_left_top, npz_path, latents=latents_tensor.float().cpu().numpy(), original_size=np.array(original_size), - crop_left_top=np.array(crop_left_top), + crop_ltrb=np.array(crop_ltrb), **kwargs, ) @@ -1918,7 +1941,7 @@ def debug_dataset(train_dataset, show_input_ids=False): ) ): print( - f'{ik}, size: {train_dataset.image_data[ik].image_size}, loss weight: {lw}, caption: "{cap}", original size: {orgsz}, crop left top: {crptl}, target size: {trgsz}, flipped: {flpdz}' + f'{ik}, size: {train_dataset.image_data[ik].image_size}, loss weight: {lw}, caption: "{cap}", original size: {orgsz}, crop top left: {crptl}, target size: {trgsz}, flipped: {flpdz}' ) if show_input_ids: @@ -2063,35 +2086,37 @@ def load_image(image_path): return img -# 画像を読み込む。戻り値はnumpy.ndarray,(original width, original height),(crop left, crop top) +# 画像を読み込む。戻り値はnumpy.ndarray,(original width, original height),(crop left, crop top, crop right, crop bottom) def trim_and_resize_if_required( random_crop: bool, image: Image.Image, reso, resized_size: Tuple[int, int] -) -> Tuple[np.ndarray, Tuple[int, int], Tuple[int, int]]: +) -> Tuple[np.ndarray, Tuple[int, int], Tuple[int, int, int, int]]: image_height, image_width = image.shape[0:2] + original_size = (image_width, image_height) # size before resize if image_width != resized_size[0] or image_height != resized_size[1]: # リサイズする image = cv2.resize(image, resized_size, interpolation=cv2.INTER_AREA) # INTER_AREAでやりたいのでcv2でリサイズ image_height, image_width = image.shape[0:2] - original_size = (image_width, image_height) - crop_left_top = (0, 0) if image_width > reso[0]: trim_size = image_width - reso[0] p = trim_size // 2 if not random_crop else random.randint(0, trim_size) # print("w", trim_size, p) image = image[:, p : p + reso[0]] - crop_left_top = (p, 0) if image_height > reso[1]: trim_size = image_height - reso[1] p = trim_size // 2 if not random_crop else random.randint(0, trim_size) # print("h", trim_size, p) image = image[p : p + reso[1]] - crop_left_top = (crop_left_top[0], p) + + # random cropの場合のcropされた値をどうcrop left/topに反映するべきか全くアイデアがない + # I have no idea how to reflect the cropped value in crop left/top in the case of random crop + + crop_ltrb = BucketManager.get_crop_ltrb(reso, original_size) assert image.shape[0] == reso[1] and image.shape[1] == reso[0], f"internal error, illegal trimmed size: {image.shape}, {reso}" - return image, original_size, crop_left_top + return image, original_size, crop_ltrb def cache_batch_latents( @@ -2104,18 +2129,18 @@ def cache_batch_latents( flipped latents is also saved if flip_aug is True if cache_to_disk is False, set info.latents latents_flipped is also set if flip_aug is True - latents_original_size and latents_crop_left_top are also set + latents_original_size and latents_crop_ltrb are also set """ images = [] for info in image_infos: image = load_image(info.absolute_path) if info.image is None else np.array(info.image, np.uint8) # TODO 画像のメタデータが壊れていて、メタデータから割り当てたbucketと実際の画像サイズが一致しない場合があるのでチェック追加要 - image, original_size, crop_left_top = trim_and_resize_if_required(random_crop, image, info.bucket_reso, info.resized_size) + image, original_size, crop_ltrb = trim_and_resize_if_required(random_crop, image, info.bucket_reso, info.resized_size) image = IMAGE_TRANSFORMS(image) images.append(image) info.latents_original_size = original_size - info.latents_crop_left_top = crop_left_top + info.latents_crop_ltrb = crop_ltrb img_tensors = torch.stack(images, dim=0) img_tensors = img_tensors.to(device=vae.device, dtype=vae.dtype) @@ -2136,7 +2161,7 @@ def cache_batch_latents( raise RuntimeError(f"NaN detected in latents: {info.absolute_path}") if cache_to_disk: - save_latents_to_disk(info.latents_npz, latent, info.latents_original_size, info.latents_crop_left_top, flipped_latent) + save_latents_to_disk(info.latents_npz, latent, info.latents_original_size, info.latents_crop_ltrb, flipped_latent) else: info.latents = latent if flip_aug: @@ -3348,7 +3373,7 @@ def get_scheduler_fix(args, optimizer: Optimizer, num_processes: int): """ name = args.lr_scheduler num_warmup_steps: Optional[int] = args.lr_warmup_steps - num_training_steps = args.max_train_steps * num_processes # * args.gradient_accumulation_steps + num_training_steps = args.max_train_steps * num_processes # * args.gradient_accumulation_steps num_cycles = args.lr_scheduler_num_cycles power = args.lr_scheduler_power From 6d2d8dfd2f6d739620de686ae4b2c9e76bc75708 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 18 Jul 2023 23:17:23 +0900 Subject: [PATCH 096/220] add zero_terminal_snr option --- fine_tune.py | 4 ++-- library/custom_train_functions.py | 36 +++++++++++++++++++++++++++++++ library/sdxl_train_util.py | 7 +++--- library/train_util.py | 13 ++++++++++- sdxl_train.py | 2 ++ train_db.py | 2 ++ train_network.py | 3 +++ train_textual_inversion.py | 2 ++ train_textual_inversion_XTI.py | 2 ++ 9 files changed, 65 insertions(+), 6 deletions(-) diff --git a/fine_tune.py b/fine_tune.py index 58a6cda0e..a906b2383 100644 --- a/fine_tune.py +++ b/fine_tune.py @@ -23,8 +23,6 @@ apply_snr_weight, get_weighted_text_embeddings, prepare_scheduler_for_custom_training, - pyramid_noise_like, - apply_noise_offset, scale_v_prediction_loss_like_noise_prediction, ) @@ -273,6 +271,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) diff --git a/library/custom_train_functions.py b/library/custom_train_functions.py index eacc23d83..5b6106fbf 100644 --- a/library/custom_train_functions.py +++ b/library/custom_train_functions.py @@ -18,6 +18,42 @@ def prepare_scheduler_for_custom_training(noise_scheduler, device): noise_scheduler.all_snr = all_snr.to(device) +def fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler): + # fix beta: zero terminal SNR + print(f"fix noise scheduler betas: https://arxiv.org/abs/2305.08891") + + def enforce_zero_terminal_snr(betas): + # Convert betas to alphas_bar_sqrt + alphas = 1 - betas + alphas_bar = alphas.cumprod(0) + alphas_bar_sqrt = alphas_bar.sqrt() + + # Store old values. + alphas_bar_sqrt_0 = alphas_bar_sqrt[0].clone() + alphas_bar_sqrt_T = alphas_bar_sqrt[-1].clone() + # Shift so last timestep is zero. + alphas_bar_sqrt -= alphas_bar_sqrt_T + # Scale so first timestep is back to old value. + alphas_bar_sqrt *= alphas_bar_sqrt_0 / (alphas_bar_sqrt_0 - alphas_bar_sqrt_T) + + # Convert alphas_bar_sqrt to betas + alphas_bar = alphas_bar_sqrt**2 + alphas = alphas_bar[1:] / alphas_bar[:-1] + alphas = torch.cat([alphas_bar[0:1], alphas]) + betas = 1 - alphas + return betas + + betas = noise_scheduler.betas + betas = enforce_zero_terminal_snr(betas) + alphas = 1.0 - betas + alphas_cumprod = torch.cumprod(alphas, dim=0) + + # print("original:", noise_scheduler.betas) + # print("fixed:", betas) + + noise_scheduler.betas = betas + noise_scheduler.alphas = alphas + noise_scheduler.alphas_cumprod = alphas_cumprod def apply_snr_weight(loss, timesteps, noise_scheduler, gamma): snr = torch.stack([noise_scheduler.all_snr[t] for t in timesteps]) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 48785ca6f..100b1cf8a 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -343,9 +343,10 @@ def add_sdxl_training_arguments(parser: argparse.ArgumentParser): def verify_sdxl_training_args(args: argparse.Namespace): - assert ( - not args.v2 and not args.v_parameterization - ), "v2 or v_parameterization cannot be enabled in SDXL training / SDXL学習ではv2とv_parameterizationを有効にすることはできません" + assert not args.v2, "v2 cannot be enabled in SDXL training / SDXL学習ではv2を有効にすることはできません" + if args.v_parameterization: + print("v_parameterization will be unexpected / SDXL学習ではv_parameterizationは想定外の動作になります") + if args.clip_skip is not None: print("clip_skip will be unexpected / SDXL学習ではclip_skipは動作しません") diff --git a/library/train_util.py b/library/train_util.py index 785dc0f9c..e6e5c3c47 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2750,6 +2750,11 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: default=None, help="add `latent mean absolute value * this value` to noise_offset (disabled if None, default) / latentの平均値の絶対値 * この値をnoise_offsetに加算する(Noneの場合は無効、デフォルト)", ) + parser.add_argument( + "--zero_terminal_snr", + action="store_true", + help="fix noise scheduler betas to enforce zero terminal SNR / noise schedulerのbetasを修正して、zero terminal SNRを強制する", + ) parser.add_argument( "--min_timestep", type=int, @@ -2825,7 +2830,7 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: def verify_training_args(args: argparse.Namespace): if args.v_parameterization and not args.v2: - print("v_parameterization should be with v2 / v1でv_parameterizationを使用することは想定されていません") + print("v_parameterization should be with v2 not v1 or sdxl / v1やsdxlでv_parameterizationを使用することは想定されていません") if args.v2 and args.clip_skip is not None: print("v2 with clip_skip will be unexpected / v2でclip_skipを使用することは想定されていません") @@ -2856,6 +2861,12 @@ def verify_training_args(args: argparse.Namespace): "scale_v_pred_loss_like_noise_pred can be enabled only with v_parameterization / scale_v_pred_loss_like_noise_predはv_parameterizationが有効なときのみ有効にできます" ) + if args.zero_terminal_snr and not args.v_parameterization: + print( + f"zero_terminal_snr is enabled, but v_parameterization is not enabled. training will be unexpected" + + " / zero_terminal_snrが有効ですが、v_parameterizationが有効ではありません。学習結果は想定外になる可能性があります" + ) + def add_dataset_arguments( parser: argparse.ArgumentParser, support_dreambooth: bool, support_caption: bool, support_caption_dropout: bool diff --git a/sdxl_train.py b/sdxl_train.py index 8459671c1..630d8832e 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -350,6 +350,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("finetuning" if args.log_tracker_name is None else args.log_tracker_name) diff --git a/train_db.py b/train_db.py index 439f4b9d9..7571efc38 100644 --- a/train_db.py +++ b/train_db.py @@ -246,6 +246,8 @@ def train(args): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("dreambooth" if args.log_tracker_name is None else args.log_tracker_name) diff --git a/train_network.py b/train_network.py index f7ee451b1..a873537c8 100644 --- a/train_network.py +++ b/train_network.py @@ -487,6 +487,7 @@ def train(self, args): "ss_multires_noise_iterations": args.multires_noise_iterations, "ss_multires_noise_discount": args.multires_noise_discount, "ss_adaptive_noise_scale": args.adaptive_noise_scale, + "ss_zero_terminal_snr": args.zero_terminal_snr, "ss_training_comment": args.training_comment, # will not be updated after training "ss_sd_scripts_commit_hash": train_util.get_git_revision_hash(), "ss_optimizer": optimizer_name + (f"({optimizer_args})" if len(optimizer_args) > 0 else ""), @@ -670,6 +671,8 @@ def train(self, args): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("network_train" if args.log_tracker_name is None else args.log_tracker_name) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index 7be8ba809..e227a13bc 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -487,6 +487,8 @@ def train(self, args): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) diff --git a/train_textual_inversion_XTI.py b/train_textual_inversion_XTI.py index 0e91c71c3..ba5c7d034 100644 --- a/train_textual_inversion_XTI.py +++ b/train_textual_inversion_XTI.py @@ -384,6 +384,8 @@ def train(args): beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", num_train_timesteps=1000, clip_sample=False ) prepare_scheduler_for_custom_training(noise_scheduler, accelerator.device) + if args.zero_terminal_snr: + custom_train_functions.fix_noise_scheduler_betas_for_zero_terminal_snr(noise_scheduler) if accelerator.is_main_process: accelerator.init_trackers("textual_inversion" if args.log_tracker_name is None else args.log_tracker_name) From 225e8718194e4a7c3f3ca51df4a8ae5a2cea49dc Mon Sep 17 00:00:00 2001 From: Kohya S Date: Wed, 19 Jul 2023 08:41:42 +0900 Subject: [PATCH 097/220] enable full bf16 trainint in train_network --- library/train_util.py | 4 +++- sdxl_train.py | 2 +- train_network.py | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index e6e5c3c47..f5d5288bb 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -2687,7 +2687,9 @@ def add_training_arguments(parser: argparse.ArgumentParser, support_dreambooth: "--mixed_precision", type=str, default="no", choices=["no", "fp16", "bf16"], help="use mixed precision / 混合精度を使う場合、その精度" ) parser.add_argument("--full_fp16", action="store_true", help="fp16 training including gradients / 勾配も含めてfp16で学習する") - parser.add_argument("--full_bf16", action="store_true", help="bf16 training including gradients / 勾配も含めてbf16で学習する") + parser.add_argument( + "--full_bf16", action="store_true", help="bf16 training including gradients / 勾配も含めてbf16で学習する" + ) # TODO move to SDXL training, because it is not supported by SD1/2 parser.add_argument( "--clip_skip", type=int, diff --git a/sdxl_train.py b/sdxl_train.py index 630d8832e..4dbed79a8 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -273,7 +273,7 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # lr schedulerを用意する lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) - # 実験的機能:勾配も含めたfp16/bf16学習を行う モデル全体をfp16にする + # 実験的機能:勾配も含めたfp16/bf16学習を行う モデル全体をfp16/bf16にする if args.full_fp16: assert ( args.mixed_precision == "fp16" diff --git a/train_network.py b/train_network.py index 3f78f159f..a55339c4b 100644 --- a/train_network.py +++ b/train_network.py @@ -350,13 +350,19 @@ def train(self, args): # lr schedulerを用意する lr_scheduler = train_util.get_scheduler_fix(args, optimizer, accelerator.num_processes) - # 実験的機能:勾配も含めたfp16学習を行う モデル全体をfp16にする + # 実験的機能:勾配も含めたfp16/bf16学習を行う モデル全体をfp16/bf16にする if args.full_fp16: assert ( args.mixed_precision == "fp16" ), "full_fp16 requires mixed precision='fp16' / full_fp16を使う場合はmixed_precision='fp16'を指定してください。" accelerator.print("enable full fp16 training.") network.to(weight_dtype) + elif args.full_bf16: + assert ( + args.mixed_precision == "bf16" + ), "full_bf16 requires mixed precision='bf16' / full_bf16を使う場合はmixed_precision='bf16'を指定してください。" + accelerator.print("enable full bf16 training.") + network.to(weight_dtype) unet.requires_grad_(False) unet.to(dtype=weight_dtype) From fc276a51fbca83f45440a6211b3c372f04319892 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 20 Jul 2023 14:50:57 +0900 Subject: [PATCH 098/220] fix invalid args checking in sdxl TI training --- library/sdxl_train_util.py | 15 ++++++++------- sdxl_train_textual_inversion.py | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 100b1cf8a..34312afce 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -342,7 +342,7 @@ def add_sdxl_training_arguments(parser: argparse.ArgumentParser): ) -def verify_sdxl_training_args(args: argparse.Namespace): +def verify_sdxl_training_args(args: argparse.Namespace, supportTextEncoderCaching: bool = True): assert not args.v2, "v2 cannot be enabled in SDXL training / SDXL学習ではv2を有効にすることはできません" if args.v_parameterization: print("v_parameterization will be unexpected / SDXL学習ではv_parameterizationは想定外の動作になります") @@ -367,12 +367,13 @@ def verify_sdxl_training_args(args: argparse.Namespace): not hasattr(args, "weighted_captions") or not args.weighted_captions ), "weighted_captions cannot be enabled in SDXL training currently / SDXL学習では今のところweighted_captionsを有効にすることはできません" - if args.cache_text_encoder_outputs_to_disk and not args.cache_text_encoder_outputs: - args.cache_text_encoder_outputs = True - print( - "cache_text_encoder_outputs is enabled because cache_text_encoder_outputs_to_disk is enabled / " - + "cache_text_encoder_outputs_to_diskが有効になっているためcache_text_encoder_outputsが有効になりました" - ) + if supportTextEncoderCaching: + if args.cache_text_encoder_outputs_to_disk and not args.cache_text_encoder_outputs: + args.cache_text_encoder_outputs = True + print( + "cache_text_encoder_outputs is enabled because cache_text_encoder_outputs_to_disk is enabled / " + + "cache_text_encoder_outputs_to_diskが有効になっているためcache_text_encoder_outputsが有効になりました" + ) def sample_images(*args, **kwargs): diff --git a/sdxl_train_textual_inversion.py b/sdxl_train_textual_inversion.py index 54328000e..a25150511 100644 --- a/sdxl_train_textual_inversion.py +++ b/sdxl_train_textual_inversion.py @@ -16,7 +16,7 @@ def __init__(self): def assert_extra_args(self, args, train_dataset_group): super().assert_extra_args(args, train_dataset_group) - sdxl_train_util.verify_sdxl_training_args(args) + sdxl_train_util.verify_sdxl_training_args(args, supportTextEncoderCaching=False) def load_target_model(self, args, weight_dtype, accelerator): ( From 86a8cbd002f1b6551b00c404fa5709a1fd0f477b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 20 Jul 2023 14:52:04 +0900 Subject: [PATCH 099/220] fix original w/h prompt opt shows wrong number --- sdxl_gen_img.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py index cc9e8a280..6770c720d 100644 --- a/sdxl_gen_img.py +++ b/sdxl_gen_img.py @@ -2159,13 +2159,13 @@ def scale_and_round(x): m = re.match(r"ow (\d+)", parg, re.IGNORECASE) if m: original_width = int(m.group(1)) - print(f"original width: {width}") + print(f"original width: {original_width}") continue m = re.match(r"oh (\d+)", parg, re.IGNORECASE) if m: original_height = int(m.group(1)) - print(f"original height: {height}") + print(f"original height: {original_height}") continue m = re.match(r"ct (\d+)", parg, re.IGNORECASE) From acf16c063a620c0d775e5c471e0384f5e54a6896 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Thu, 20 Jul 2023 21:41:16 +0900 Subject: [PATCH 100/220] make to work with PyTorch 1.12 --- library/train_util.py | 6 +++--- sdxl_minimal_inference.py | 3 ++- sdxl_train.py | 3 ++- tools/cache_latents.py | 3 ++- train_network.py | 3 ++- train_textual_inversion.py | 3 ++- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/library/train_util.py b/library/train_util.py index f5d5288bb..5f6e7d48c 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -1104,9 +1104,9 @@ def __getitem__(self, index): # crop_ltrb[2] is right, so target_size[0] - crop_ltrb[2] is left in flipped image crop_left_top = (target_size[0] - crop_ltrb[2], crop_ltrb[1]) - original_sizes_hw.append((original_size[1], original_size[0])) - crop_top_lefts.append((crop_left_top[1], crop_left_top[0])) - target_sizes_hw.append((target_size[1], target_size[0])) + original_sizes_hw.append((int(original_size[1]), int(original_size[0]))) + crop_top_lefts.append((int(crop_left_top[1]), int(crop_left_top[0]))) + target_sizes_hw.append((int(target_size[1]), int(target_size[0]))) flippeds.append(flipped) # captionとtext encoder outputを処理する diff --git a/sdxl_minimal_inference.py b/sdxl_minimal_inference.py index d441877d9..1a9509026 100644 --- a/sdxl_minimal_inference.py +++ b/sdxl_minimal_inference.py @@ -146,7 +146,8 @@ def get_timestep_embedding(x, outdim): text_model2.eval() unet.set_use_memory_efficient_attention(True, False) - vae.set_use_memory_efficient_attention_xformers(True) + if torch.__version__ >= "2.0.0": # PyTorch 2.0.0 以上対応のxformersなら以下が使える + vae.set_use_memory_efficient_attention_xformers(True) # Tokenizers tokenizer1 = CLIPTokenizer.from_pretrained(text_encoder_1_name) diff --git a/sdxl_train.py b/sdxl_train.py index 4dbed79a8..7e3a8416d 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -174,7 +174,8 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): # Windows版のxformersはfloatで学習できなかったりするのでxformersを使わない設定も可能にしておく必要がある accelerator.print("Disable Diffusers' xformers") train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) - vae.set_use_memory_efficient_attention_xformers(args.xformers) + if torch.__version__ >= "2.0.0": # PyTorch 2.0.0 以上対応のxformersなら以下が使える + vae.set_use_memory_efficient_attention_xformers(args.xformers) # 学習を準備する if cache_latents: diff --git a/tools/cache_latents.py b/tools/cache_latents.py index d403d5594..b6991ac19 100644 --- a/tools/cache_latents.py +++ b/tools/cache_latents.py @@ -104,7 +104,8 @@ def cache_to_disk(args: argparse.Namespace) -> None: else: _, vae, _, _ = train_util.load_target_model(args, weight_dtype, accelerator) - vae.set_use_memory_efficient_attention_xformers(args.xformers) + if torch.__version__ >= "2.0.0": # PyTorch 2.0.0 以上対応のxformersなら以下が使える + vae.set_use_memory_efficient_attention_xformers(args.xformers) vae.to(accelerator.device, dtype=vae_dtype) vae.requires_grad_(False) vae.eval() diff --git a/train_network.py b/train_network.py index a55339c4b..310f7506a 100644 --- a/train_network.py +++ b/train_network.py @@ -217,7 +217,8 @@ def train(self, args): # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) - vae.set_use_memory_efficient_attention_xformers(args.xformers) + if torch.__version__ >= "2.0.0": # PyTorch 2.0.0 以上対応のxformersなら以下が使える + vae.set_use_memory_efficient_attention_xformers(args.xformers) # 差分追加学習のためにモデルを読み込む sys.path.append(os.path.dirname(__file__)) diff --git a/train_textual_inversion.py b/train_textual_inversion.py index e227a13bc..265b244bb 100644 --- a/train_textual_inversion.py +++ b/train_textual_inversion.py @@ -343,7 +343,8 @@ def train(self, args): # モデルに xformers とか memory efficient attention を組み込む train_util.replace_unet_modules(unet, args.mem_eff_attn, args.xformers, args.sdpa) - vae.set_use_memory_efficient_attention_xformers(args.xformers) + if torch.__version__ >= "2.0.0": # PyTorch 2.0.0 以上対応のxformersなら以下が使える + vae.set_use_memory_efficient_attention_xformers(args.xformers) # 学習を準備する if cache_latents: From 8ba02ac8296c08ef8c880d87d7134504550671cb Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 22 Jul 2023 09:56:36 +0900 Subject: [PATCH 101/220] fix to work text encoder only network with bf16 --- train_network.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/train_network.py b/train_network.py index b482c80ab..6f41d1997 100644 --- a/train_network.py +++ b/train_network.py @@ -401,6 +401,8 @@ def train(self, args): text_encoder, network, optimizer, train_dataloader, lr_scheduler ) text_encoders = [text_encoder] + + unet.to(accelerator.device, dtype=weight_dtype) # move to device because unet is not prepared by accelerator else: network, optimizer, train_dataloader, lr_scheduler = accelerator.prepare( network, optimizer, train_dataloader, lr_scheduler From d1864e24306aa56d0becf9ee45ce03897eeb2b72 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sat, 22 Jul 2023 19:34:22 +0900 Subject: [PATCH 102/220] add invisible watermark to req.txt --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index d28018d68..22971e1fc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,6 +15,8 @@ easygui==0.98.3 toml==0.10.2 voluptuous==0.13.1 huggingface-hub==0.15.1 +# for loading Diffusers' SDXL +invisible-watermark==0.2.0 # for BLIP captioning # requests==2.28.2 # timm==0.6.12 From 50b53e183ed14d72f5c3c2af768f15c034b1800c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 23 Jul 2023 13:33:02 +0900 Subject: [PATCH 103/220] re-organize import --- library/sdxl_model_util.py | 4 +++- library/sdxl_train_util.py | 23 +++++++++++++---------- library/train_util.py | 7 +++---- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 41a05e950..a7f03afe1 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -1,7 +1,7 @@ import torch from safetensors.torch import load_file, save_file from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection, CLIPTokenizer -from diffusers import AutoencoderKL, EulerDiscreteScheduler, StableDiffusionXLPipeline, UNet2DConditionModel +from diffusers import AutoencoderKL, EulerDiscreteScheduler, UNet2DConditionModel from library import model_util from library import sdxl_original_unet @@ -486,6 +486,8 @@ def update_sd(prefix, sd): def save_diffusers_checkpoint( output_dir, text_encoder1, text_encoder2, unet, pretrained_model_name_or_path, vae=None, use_safetensors=False, save_dtype=None ): + from diffusers import StableDiffusionXLPipeline + # convert U-Net unet_sd = unet.state_dict() du_unet_sd = convert_sdxl_unet_state_dict_to_diffusers(unet_sd) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 34312afce..54774f888 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -2,13 +2,10 @@ import gc import math import os -from types import SimpleNamespace -from typing import Any +from typing import Optional import torch from tqdm import tqdm from transformers import CLIPTokenizer -import open_clip -from diffusers import StableDiffusionXLPipeline from library import model_util, sdxl_model_util, train_util, sdxl_original_unet from library.sdxl_lpw_stable_diffusion import SdxlStableDiffusionLongPromptWeightingPipeline @@ -18,7 +15,6 @@ DEFAULT_NOISE_OFFSET = 0.0357 -# TODO: separate checkpoint for each U-Net/Text Encoder/VAE def load_target_model(args, accelerator, model_version: str, weight_dtype): # load models for each process for pi in range(accelerator.state.num_processes): @@ -33,7 +29,13 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): unet, logit_scale, ckpt_info, - ) = _load_target_model(args, model_version, weight_dtype, accelerator.device if args.lowram else "cpu") + ) = _load_target_model( + args.pretrained_model_name_or_path, + args.vae, + model_version, + weight_dtype, + accelerator.device if args.lowram else "cpu", + ) # work on low-ram device if args.lowram: @@ -51,8 +53,7 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, logit_scale, ckpt_info -def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtype, device="cpu"): - name_or_path = args.pretrained_model_name_or_path +def _load_target_model(name_or_path: str, vae_path: Optional[str], model_version: str, weight_dtype, device="cpu"): name_or_path = os.readlink(name_or_path) if os.path.islink(name_or_path) else name_or_path load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers @@ -68,6 +69,8 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) else: # Diffusers model is loaded to CPU + from diffusers import StableDiffusionXLPipeline + variant = "fp16" if weight_dtype == torch.float16 else None print(f"load Diffusers pretrained models: {name_or_path}, variant={variant}") try: @@ -102,8 +105,8 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp ckpt_info = None # VAEを読み込む - if args.vae is not None: - vae = model_util.load_vae(args.vae, weight_dtype) + if vae_path is not None: + vae = model_util.load_vae(vae_path, weight_dtype) print("additional VAE loaded") return load_stable_diffusion_format, text_encoder1, text_encoder2, vae, unet, logit_scale, ckpt_info diff --git a/library/train_util.py b/library/train_util.py index ce4b59598..b918e56b5 100644 --- a/library/train_util.py +++ b/library/train_util.py @@ -65,8 +65,8 @@ from library.lpw_stable_diffusion import StableDiffusionLongPromptWeightingPipeline import library.model_util as model_util import library.huggingface_util as huggingface_util -from library.attention_processors import FlashAttnProcessor -from library.hypernetwork import replace_attentions_for_hypernetwork +# from library.attention_processors import FlashAttnProcessor +# from library.hypernetwork import replace_attentions_for_hypernetwork from library.original_unet import UNet2DConditionModel # Tokenizer: checkpointから読み込むのではなくあらかじめ提供されているものを使う @@ -1884,8 +1884,7 @@ def load_latents_from_disk( ) -> Tuple[Optional[torch.Tensor], Optional[List[int]], Optional[List[int]], Optional[torch.Tensor]]: npz = np.load(npz_path) if "latents" not in npz: - print(f"error: npz is old format. please re-generate {npz_path}") - return None, None, None, None + raise ValueError(f"error: npz is old format. please re-generate {npz_path}") latents = npz["latents"] original_size = npz["original_size"].tolist() From 7ec9a7af798b71631281363bd80520559b2f26f3 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 23 Jul 2023 13:33:14 +0900 Subject: [PATCH 104/220] support Diffusers format --- sdxl_gen_img.py | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py index 6770c720d..b5e261053 100644 --- a/sdxl_gen_img.py +++ b/sdxl_gen_img.py @@ -1288,38 +1288,9 @@ def main(args): if len(files) == 1: args.ckpt = files[0] - use_stable_diffusion_format = os.path.isfile(args.ckpt) - assert use_stable_diffusion_format, "Diffusers pretrained models are not supported yet" - print("load StableDiffusion checkpoint") - text_encoder1, text_encoder2, vae, unet, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( - sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.ckpt, "cpu" + (_, text_encoder1, text_encoder2, vae, unet, _, _) = sdxl_train_util._load_target_model( + args.ckpt, args.vae, sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, dtype ) - # else: - # print("load Diffusers pretrained models") - # TODO use Diffusers 0.18.1 and support SDXL pipeline - # raise NotImplementedError("Diffusers pretrained models are not supported yet") - # loading_pipe = StableDiffusionXLPipeline.from_pretrained(args.ckpt, safety_checker=None, torch_dtype=dtype) - # text_encoder = loading_pipe.text_encoder - # vae = loading_pipe.vae - # unet = loading_pipe.unet - # tokenizer = loading_pipe.tokenizer - # del loading_pipe - - # # Diffusers U-Net to original U-Net - # original_unet = SdxlUNet2DConditionModel( - # unet.config.sample_size, - # unet.config.attention_head_dim, - # unet.config.cross_attention_dim, - # unet.config.use_linear_projection, - # unet.config.upcast_attention, - # ) - # original_unet.load_state_dict(unet.state_dict()) - # unet = original_unet - - # VAEを読み込む - if args.vae is not None: - vae = model_util.load_vae(args.vae, dtype) - print("additional VAE loaded") # xformers、Hypernetwork対応 if not args.diffusers_xformers: @@ -1329,8 +1300,7 @@ def main(args): # tokenizerを読み込む print("loading tokenizer") - if use_stable_diffusion_format: - tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) + tokenizer1, tokenizer2 = sdxl_train_util.load_tokenizers(args) # schedulerを用意する sched_init_args = {} From bb167f94ca417e97ea1a6018b17119df6abade91 Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Sun, 23 Jul 2023 13:17:11 +0800 Subject: [PATCH 105/220] init unet with empty weights --- library/sdxl_model_util.py | 13 +++++++------ library/sdxl_train_util.py | 9 ++++++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 41a05e950..69357517d 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -1,4 +1,6 @@ import torch +from accelerate import init_empty_weights +from accelerate.utils.modeling import set_module_tensor_to_device from safetensors.torch import load_file, save_file from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection, CLIPTokenizer from diffusers import AutoencoderKL, EulerDiscreteScheduler, StableDiffusionXLPipeline, UNet2DConditionModel @@ -156,16 +158,15 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): # U-Net print("building U-Net") - unet = sdxl_original_unet.SdxlUNet2DConditionModel() + with init_empty_weights(): + unet = sdxl_original_unet.SdxlUNet2DConditionModel() print("loading U-Net from checkpoint") - unet_sd = {} for k in list(state_dict.keys()): if k.startswith("model.diffusion_model."): - unet_sd[k.replace("model.diffusion_model.", "")] = state_dict.pop(k) - info = unet.load_state_dict(unet_sd) - print("U-Net: ", info) - del unet_sd + set_module_tensor_to_device(unet, k.replace("model.diffusion_model.", ""), map_location, value=state_dict.pop(k)) + # TODO: catch missing_keys and unexpected_keys with _IncompatibleKeys + # print("U-Net: ", info) # Text Encoders print("building text encoders") diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 34312afce..f37cadabe 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -5,6 +5,8 @@ from types import SimpleNamespace from typing import Any import torch +from accelerate import init_empty_weights +from accelerate.utils.modeling import set_module_tensor_to_device from tqdm import tqdm from transformers import CLIPTokenizer import open_clip @@ -92,10 +94,11 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp del pipe # Diffusers U-Net to original U-Net - original_unet = sdxl_original_unet.SdxlUNet2DConditionModel() state_dict = sdxl_model_util.convert_diffusers_unet_state_dict_to_sdxl(unet.state_dict()) - original_unet.load_state_dict(state_dict) - unet = original_unet + with init_empty_weights(): + unet = sdxl_original_unet.SdxlUNet2DConditionModel() + for k in list(state_dict.keys()): + set_module_tensor_to_device(unet, k, device, value=state_dict.pop(k)) print("U-Net converted to original U-Net") logit_scale = None From eec6aaddda8a3fa993a7150821c029956462e37c Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Sun, 23 Jul 2023 13:29:29 +0800 Subject: [PATCH 106/220] fix safetensors error: device invalid --- library/sdxl_model_util.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 69357517d..f37cd71b5 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -141,7 +141,10 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): # Load the state dict if model_util.is_safetensors(ckpt_path): checkpoint = None - state_dict = load_file(ckpt_path, device=map_location) + try: + state_dict = load_file(ckpt_path, device=map_location) + except: + state_dict = load_file(ckpt_path) # prevent device invalid Error epoch = None global_step = None else: From c1d5c24bc7db673b7256bce39e7a2ece033ff033 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 23 Jul 2023 15:01:41 +0900 Subject: [PATCH 107/220] fix LoRA with text encoder can't merge closes #660 --- networks/sdxl_merge_lora.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networks/sdxl_merge_lora.py b/networks/sdxl_merge_lora.py index d75da7d76..a91b62d80 100644 --- a/networks/sdxl_merge_lora.py +++ b/networks/sdxl_merge_lora.py @@ -204,7 +204,7 @@ def str_to_dtype(p): ckpt_info, ) = sdxl_model_util.load_models_from_sdxl_checkpoint(sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.sd_model, "cpu") - merge_to_sd_model(text_model2, text_model2, unet, args.models, args.ratios, merge_dtype) + merge_to_sd_model(text_model1, text_model2, unet, args.models, args.ratios, merge_dtype) print(f"saving SD model to: {args.save_to}") sdxl_model_util.save_stable_diffusion_checkpoint( From 7ae0cde75464c44e29b1bbd1983078d2587d9892 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 23 Jul 2023 15:18:27 +0900 Subject: [PATCH 108/220] fix max mul embeds doesn't work. closes #656 --- sdxl_gen_img.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdxl_gen_img.py b/sdxl_gen_img.py index b5e261053..d2f59a336 100644 --- a/sdxl_gen_img.py +++ b/sdxl_gen_img.py @@ -958,7 +958,7 @@ def get_unweighted_text_embeddings( enc_out = text_encoder(text_input_chunk, output_hidden_states=True, return_dict=True) text_embedding = enc_out["hidden_states"][-2] if pool is None: - pool = enc_out["text_embeds"] # use 1st chunk + pool = enc_out.get("text_embeds", None) # use 1st chunk, if provided if no_boseos_middle: if i == 0: From b1e44e96bcd4c8150baf80f13ed45ef916ce463b Mon Sep 17 00:00:00 2001 From: Kohya S Date: Sun, 23 Jul 2023 15:39:56 +0900 Subject: [PATCH 109/220] fix to show batch size for each dataset refs #637 --- sdxl_train.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sdxl_train.py b/sdxl_train.py index d47720ac3..f5084a42d 100644 --- a/sdxl_train.py +++ b/sdxl_train.py @@ -333,15 +333,17 @@ def fn_recursive_set_mem_eff(module: torch.nn.Module): args.save_every_n_epochs = math.floor(num_train_epochs / args.save_n_epoch_ratio) or 1 # 学習する - total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps + # total_batch_size = args.train_batch_size * accelerator.num_processes * args.gradient_accumulation_steps accelerator.print("running training / 学習開始") accelerator.print(f" num examples / サンプル数: {train_dataset_group.num_train_images}") accelerator.print(f" num batches per epoch / 1epochのバッチ数: {len(train_dataloader)}") accelerator.print(f" num epochs / epoch数: {num_train_epochs}") - accelerator.print(f" batch size per device / バッチサイズ: {args.train_batch_size}") accelerator.print( - f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + f" batch size per device / バッチサイズ: {', '.join([str(d.batch_size) for d in train_dataset_group.datasets])}" ) + # accelerator.print( + # f" total train batch size (with parallel & distributed & accumulation) / 総バッチサイズ(並列学習、勾配合計含む): {total_batch_size}" + # ) accelerator.print(f" gradient accumulation steps / 勾配を合計するステップ数 = {args.gradient_accumulation_steps}") accelerator.print(f" total optimization steps / 学習ステップ数: {args.max_train_steps}") From e83ee217d3c270009e60395505c3529b5962dc98 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 24 Jul 2023 21:28:37 +0900 Subject: [PATCH 110/220] format by black --- networks/extract_lora_from_models.py | 300 ++++++++++++++------------- 1 file changed, 159 insertions(+), 141 deletions(-) diff --git a/networks/extract_lora_from_models.py b/networks/extract_lora_from_models.py index f001e7eb2..3510b5531 100644 --- a/networks/extract_lora_from_models.py +++ b/networks/extract_lora_from_models.py @@ -16,174 +16,192 @@ def save_to_file(file_name, model, state_dict, dtype): - if dtype is not None: - for key in list(state_dict.keys()): - if type(state_dict[key]) == torch.Tensor: - state_dict[key] = state_dict[key].to(dtype) + if dtype is not None: + for key in list(state_dict.keys()): + if type(state_dict[key]) == torch.Tensor: + state_dict[key] = state_dict[key].to(dtype) - if os.path.splitext(file_name)[1] == '.safetensors': - save_file(model, file_name) - else: - torch.save(model, file_name) + if os.path.splitext(file_name)[1] == ".safetensors": + save_file(model, file_name) + else: + torch.save(model, file_name) def svd(args): - def str_to_dtype(p): - if p == 'float': - return torch.float - if p == 'fp16': - return torch.float16 - if p == 'bf16': - return torch.bfloat16 - return None - - save_dtype = str_to_dtype(args.save_precision) - - print(f"loading SD model : {args.model_org}") - text_encoder_o, _, unet_o = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_org) - print(f"loading SD model : {args.model_tuned}") - text_encoder_t, _, unet_t = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_tuned) - - # create LoRA network to extract weights: Use dim (rank) as alpha - if args.conv_dim is None: - kwargs = {} - else: - kwargs = {"conv_dim": args.conv_dim, "conv_alpha": args.conv_dim} - - lora_network_o = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_o, unet_o, **kwargs) - lora_network_t = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_t, unet_t, **kwargs) - assert len(lora_network_o.text_encoder_loras) == len( - lora_network_t.text_encoder_loras), f"model version is different (SD1.x vs SD2.x) / それぞれのモデルのバージョンが違います(SD1.xベースとSD2.xベース) " - - # get diffs - diffs = {} - text_encoder_different = False - for i, (lora_o, lora_t) in enumerate(zip(lora_network_o.text_encoder_loras, lora_network_t.text_encoder_loras)): - lora_name = lora_o.lora_name - module_o = lora_o.org_module - module_t = lora_t.org_module - diff = module_t.weight - module_o.weight - - # Text Encoder might be same - if torch.max(torch.abs(diff)) > MIN_DIFF: - text_encoder_different = True - - diff = diff.float() - diffs[lora_name] = diff - - if not text_encoder_different: - print("Text encoder is same. Extract U-Net only.") - lora_network_o.text_encoder_loras = [] + def str_to_dtype(p): + if p == "float": + return torch.float + if p == "fp16": + return torch.float16 + if p == "bf16": + return torch.bfloat16 + return None + + save_dtype = str_to_dtype(args.save_precision) + + print(f"loading SD model : {args.model_org}") + text_encoder_o, _, unet_o = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_org) + print(f"loading SD model : {args.model_tuned}") + text_encoder_t, _, unet_t = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_tuned) + + # create LoRA network to extract weights: Use dim (rank) as alpha + if args.conv_dim is None: + kwargs = {} + else: + kwargs = {"conv_dim": args.conv_dim, "conv_alpha": args.conv_dim} + + lora_network_o = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_o, unet_o, **kwargs) + lora_network_t = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_t, unet_t, **kwargs) + assert len(lora_network_o.text_encoder_loras) == len( + lora_network_t.text_encoder_loras + ), f"model version is different (SD1.x vs SD2.x) / それぞれのモデルのバージョンが違います(SD1.xベースとSD2.xベース) " + + # get diffs diffs = {} + text_encoder_different = False + for i, (lora_o, lora_t) in enumerate(zip(lora_network_o.text_encoder_loras, lora_network_t.text_encoder_loras)): + lora_name = lora_o.lora_name + module_o = lora_o.org_module + module_t = lora_t.org_module + diff = module_t.weight - module_o.weight - for i, (lora_o, lora_t) in enumerate(zip(lora_network_o.unet_loras, lora_network_t.unet_loras)): - lora_name = lora_o.lora_name - module_o = lora_o.org_module - module_t = lora_t.org_module - diff = module_t.weight - module_o.weight - diff = diff.float() + # Text Encoder might be same + if torch.max(torch.abs(diff)) > MIN_DIFF: + text_encoder_different = True - if args.device: - diff = diff.to(args.device) + diff = diff.float() + diffs[lora_name] = diff - diffs[lora_name] = diff + if not text_encoder_different: + print("Text encoder is same. Extract U-Net only.") + lora_network_o.text_encoder_loras = [] + diffs = {} - # make LoRA with svd - print("calculating by svd") - lora_weights = {} - with torch.no_grad(): - for lora_name, mat in tqdm(list(diffs.items())): - # if args.conv_dim is None, diffs do not include LoRAs for conv2d-3x3 - conv2d = (len(mat.size()) == 4) - kernel_size = None if not conv2d else mat.size()[2:4] - conv2d_3x3 = conv2d and kernel_size != (1, 1) + for i, (lora_o, lora_t) in enumerate(zip(lora_network_o.unet_loras, lora_network_t.unet_loras)): + lora_name = lora_o.lora_name + module_o = lora_o.org_module + module_t = lora_t.org_module + diff = module_t.weight - module_o.weight + diff = diff.float() - rank = args.dim if not conv2d_3x3 or args.conv_dim is None else args.conv_dim - out_dim, in_dim = mat.size()[0:2] + if args.device: + diff = diff.to(args.device) - if args.device: - mat = mat.to(args.device) + diffs[lora_name] = diff - # print(lora_name, mat.size(), mat.device, rank, in_dim, out_dim) - rank = min(rank, in_dim, out_dim) # LoRA rank cannot exceed the original dim + # make LoRA with svd + print("calculating by svd") + lora_weights = {} + with torch.no_grad(): + for lora_name, mat in tqdm(list(diffs.items())): + # if args.conv_dim is None, diffs do not include LoRAs for conv2d-3x3 + conv2d = len(mat.size()) == 4 + kernel_size = None if not conv2d else mat.size()[2:4] + conv2d_3x3 = conv2d and kernel_size != (1, 1) - if conv2d: - if conv2d_3x3: - mat = mat.flatten(start_dim=1) - else: - mat = mat.squeeze() + rank = args.dim if not conv2d_3x3 or args.conv_dim is None else args.conv_dim + out_dim, in_dim = mat.size()[0:2] - U, S, Vh = torch.linalg.svd(mat) + if args.device: + mat = mat.to(args.device) - U = U[:, :rank] - S = S[:rank] - U = U @ torch.diag(S) + # print(lora_name, mat.size(), mat.device, rank, in_dim, out_dim) + rank = min(rank, in_dim, out_dim) # LoRA rank cannot exceed the original dim - Vh = Vh[:rank, :] + if conv2d: + if conv2d_3x3: + mat = mat.flatten(start_dim=1) + else: + mat = mat.squeeze() - dist = torch.cat([U.flatten(), Vh.flatten()]) - hi_val = torch.quantile(dist, CLAMP_QUANTILE) - low_val = -hi_val + U, S, Vh = torch.linalg.svd(mat) - U = U.clamp(low_val, hi_val) - Vh = Vh.clamp(low_val, hi_val) + U = U[:, :rank] + S = S[:rank] + U = U @ torch.diag(S) - if conv2d: - U = U.reshape(out_dim, rank, 1, 1) - Vh = Vh.reshape(rank, in_dim, kernel_size[0], kernel_size[1]) + Vh = Vh[:rank, :] - U = U.to("cpu").contiguous() - Vh = Vh.to("cpu").contiguous() + dist = torch.cat([U.flatten(), Vh.flatten()]) + hi_val = torch.quantile(dist, CLAMP_QUANTILE) + low_val = -hi_val - lora_weights[lora_name] = (U, Vh) + U = U.clamp(low_val, hi_val) + Vh = Vh.clamp(low_val, hi_val) - # make state dict for LoRA - lora_sd = {} - for lora_name, (up_weight, down_weight) in lora_weights.items(): - lora_sd[lora_name + '.lora_up.weight'] = up_weight - lora_sd[lora_name + '.lora_down.weight'] = down_weight - lora_sd[lora_name + '.alpha'] = torch.tensor(down_weight.size()[0]) + if conv2d: + U = U.reshape(out_dim, rank, 1, 1) + Vh = Vh.reshape(rank, in_dim, kernel_size[0], kernel_size[1]) - # load state dict to LoRA and save it - lora_network_save, lora_sd = lora.create_network_from_weights(1.0, None, None, text_encoder_o, unet_o, weights_sd=lora_sd) - lora_network_save.apply_to(text_encoder_o, unet_o) # create internal module references for state_dict + U = U.to("cpu").contiguous() + Vh = Vh.to("cpu").contiguous() - info = lora_network_save.load_state_dict(lora_sd) - print(f"Loading extracted LoRA weights: {info}") + lora_weights[lora_name] = (U, Vh) - dir_name = os.path.dirname(args.save_to) - if dir_name and not os.path.exists(dir_name): - os.makedirs(dir_name, exist_ok=True) + # make state dict for LoRA + lora_sd = {} + for lora_name, (up_weight, down_weight) in lora_weights.items(): + lora_sd[lora_name + ".lora_up.weight"] = up_weight + lora_sd[lora_name + ".lora_down.weight"] = down_weight + lora_sd[lora_name + ".alpha"] = torch.tensor(down_weight.size()[0]) - # minimum metadata - metadata = {"ss_network_module": "networks.lora", "ss_network_dim": str(args.dim), "ss_network_alpha": str(args.dim)} + # load state dict to LoRA and save it + lora_network_save, lora_sd = lora.create_network_from_weights(1.0, None, None, text_encoder_o, unet_o, weights_sd=lora_sd) + lora_network_save.apply_to(text_encoder_o, unet_o) # create internal module references for state_dict - lora_network_save.save_weights(args.save_to, save_dtype, metadata) - print(f"LoRA weights are saved to: {args.save_to}") + info = lora_network_save.load_state_dict(lora_sd) + print(f"Loading extracted LoRA weights: {info}") + + dir_name = os.path.dirname(args.save_to) + if dir_name and not os.path.exists(dir_name): + os.makedirs(dir_name, exist_ok=True) + + # minimum metadata + metadata = {"ss_network_module": "networks.lora", "ss_network_dim": str(args.dim), "ss_network_alpha": str(args.dim)} + + lora_network_save.save_weights(args.save_to, save_dtype, metadata) + print(f"LoRA weights are saved to: {args.save_to}") def setup_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser() - parser.add_argument("--v2", action='store_true', - help='load Stable Diffusion v2.x model / Stable Diffusion 2.xのモデルを読み込む') - parser.add_argument("--save_precision", type=str, default=None, - choices=[None, "float", "fp16", "bf16"], help="precision in saving, same to merging if omitted / 保存時に精度を変更して保存する、省略時はfloat") - parser.add_argument("--model_org", type=str, default=None, - help="Stable Diffusion original model: ckpt or safetensors file / 元モデル、ckptまたはsafetensors") - parser.add_argument("--model_tuned", type=str, default=None, - help="Stable Diffusion tuned model, LoRA is difference of `original to tuned`: ckpt or safetensors file / 派生モデル(生成されるLoRAは元→派生の差分になります)、ckptまたはsafetensors") - parser.add_argument("--save_to", type=str, default=None, - help="destination file name: ckpt or safetensors file / 保存先のファイル名、ckptまたはsafetensors") - parser.add_argument("--dim", type=int, default=4, help="dimension (rank) of LoRA (default 4) / LoRAの次元数(rank)(デフォルト4)") - parser.add_argument("--conv_dim", type=int, default=None, - help="dimension (rank) of LoRA for Conv2d-3x3 (default None, disabled) / LoRAのConv2d-3x3の次元数(rank)(デフォルトNone、適用なし)") - parser.add_argument("--device", type=str, default=None, help="device to use, cuda for GPU / 計算を行うデバイス、cuda でGPUを使う") - - return parser - - -if __name__ == '__main__': - parser = setup_parser() - - args = parser.parse_args() - svd(args) + parser = argparse.ArgumentParser() + parser.add_argument("--v2", action="store_true", help="load Stable Diffusion v2.x model / Stable Diffusion 2.xのモデルを読み込む") + parser.add_argument( + "--save_precision", + type=str, + default=None, + choices=[None, "float", "fp16", "bf16"], + help="precision in saving, same to merging if omitted / 保存時に精度を変更して保存する、省略時はfloat", + ) + parser.add_argument( + "--model_org", + type=str, + default=None, + help="Stable Diffusion original model: ckpt or safetensors file / 元モデル、ckptまたはsafetensors", + ) + parser.add_argument( + "--model_tuned", + type=str, + default=None, + help="Stable Diffusion tuned model, LoRA is difference of `original to tuned`: ckpt or safetensors file / 派生モデル(生成されるLoRAは元→派生の差分になります)、ckptまたはsafetensors", + ) + parser.add_argument( + "--save_to", type=str, default=None, help="destination file name: ckpt or safetensors file / 保存先のファイル名、ckptまたはsafetensors" + ) + parser.add_argument("--dim", type=int, default=4, help="dimension (rank) of LoRA (default 4) / LoRAの次元数(rank)(デフォルト4)") + parser.add_argument( + "--conv_dim", + type=int, + default=None, + help="dimension (rank) of LoRA for Conv2d-3x3 (default None, disabled) / LoRAのConv2d-3x3の次元数(rank)(デフォルトNone、適用なし)", + ) + parser.add_argument("--device", type=str, default=None, help="device to use, cuda for GPU / 計算を行うデバイス、cuda でGPUを使う") + + return parser + + +if __name__ == "__main__": + parser = setup_parser() + + args = parser.parse_args() + svd(args) From 2b969e9c427a6f6b13869064f82c6c90193c3f37 Mon Sep 17 00:00:00 2001 From: Kohya S Date: Mon, 24 Jul 2023 22:20:21 +0900 Subject: [PATCH 111/220] support sdxl --- networks/extract_lora_from_models.py | 69 +++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/networks/extract_lora_from_models.py b/networks/extract_lora_from_models.py index 3510b5531..0bc1afe0a 100644 --- a/networks/extract_lora_from_models.py +++ b/networks/extract_lora_from_models.py @@ -3,16 +3,18 @@ # Thanks to cloneofsimo! import argparse +import json import os import torch from safetensors.torch import load_file, save_file from tqdm import tqdm import library.model_util as model_util +import library.sdxl_model_util as sdxl_model_util import lora CLAMP_QUANTILE = 0.99 -MIN_DIFF = 1e-6 +MIN_DIFF = 1e-4 def save_to_file(file_name, model, state_dict, dtype): @@ -37,12 +39,35 @@ def str_to_dtype(p): return torch.bfloat16 return None + assert args.v2 != args.sdxl or ( + not args.v2 and not args.sdxl + ), "v2 and sdxl cannot be specified at the same time / v2とsdxlは同時に指定できません" + if args.v_parameterization is None: + args.v_parameterization = args.v2 + save_dtype = str_to_dtype(args.save_precision) - print(f"loading SD model : {args.model_org}") - text_encoder_o, _, unet_o = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_org) - print(f"loading SD model : {args.model_tuned}") - text_encoder_t, _, unet_t = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_tuned) + # load models + if not args.sdxl: + print(f"loading original SD model : {args.model_org}") + text_encoder_o, _, unet_o = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_org) + text_encoders_o = [text_encoder_o] + print(f"loading tuned SD model : {args.model_tuned}") + text_encoder_t, _, unet_t = model_util.load_models_from_stable_diffusion_checkpoint(args.v2, args.model_tuned) + text_encoders_t = [text_encoder_t] + model_version = model_util.get_model_version_str_for_sd1_sd2(args.v2, args.v_parameterization) + else: + print(f"loading original SDXL model : {args.model_org}") + text_encoder_o1, text_encoder_o2, _, unet_o, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( + sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.model_org, "cpu" + ) + text_encoders_o = [text_encoder_o1, text_encoder_o2] + print(f"loading original SDXL model : {args.model_tuned}") + text_encoder_t1, text_encoder_t2, _, unet_t, _, _ = sdxl_model_util.load_models_from_sdxl_checkpoint( + sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9, args.model_tuned, "cpu" + ) + text_encoders_t = [text_encoder_t1, text_encoder_t2] + model_version = sdxl_model_util.MODEL_VERSION_SDXL_BASE_V0_9 # create LoRA network to extract weights: Use dim (rank) as alpha if args.conv_dim is None: @@ -50,8 +75,8 @@ def str_to_dtype(p): else: kwargs = {"conv_dim": args.conv_dim, "conv_alpha": args.conv_dim} - lora_network_o = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_o, unet_o, **kwargs) - lora_network_t = lora.create_network(1.0, args.dim, args.dim, None, text_encoder_t, unet_t, **kwargs) + lora_network_o = lora.create_network(1.0, args.dim, args.dim, None, text_encoders_o, unet_o, **kwargs) + lora_network_t = lora.create_network(1.0, args.dim, args.dim, None, text_encoders_t, unet_t, **kwargs) assert len(lora_network_o.text_encoder_loras) == len( lora_network_t.text_encoder_loras ), f"model version is different (SD1.x vs SD2.x) / それぞれのモデルのバージョンが違います(SD1.xベースとSD2.xベース) " @@ -66,8 +91,9 @@ def str_to_dtype(p): diff = module_t.weight - module_o.weight # Text Encoder might be same - if torch.max(torch.abs(diff)) > MIN_DIFF: + if not text_encoder_different and torch.max(torch.abs(diff)) > MIN_DIFF: text_encoder_different = True + print(f"Text encoder is different. {torch.max(torch.abs(diff))} > {MIN_DIFF}") diff = diff.float() diffs[lora_name] = diff @@ -146,8 +172,8 @@ def str_to_dtype(p): lora_sd[lora_name + ".alpha"] = torch.tensor(down_weight.size()[0]) # load state dict to LoRA and save it - lora_network_save, lora_sd = lora.create_network_from_weights(1.0, None, None, text_encoder_o, unet_o, weights_sd=lora_sd) - lora_network_save.apply_to(text_encoder_o, unet_o) # create internal module references for state_dict + lora_network_save, lora_sd = lora.create_network_from_weights(1.0, None, None, text_encoders_o, unet_o, weights_sd=lora_sd) + lora_network_save.apply_to(text_encoders_o, unet_o) # create internal module references for state_dict info = lora_network_save.load_state_dict(lora_sd) print(f"Loading extracted LoRA weights: {info}") @@ -157,7 +183,19 @@ def str_to_dtype(p): os.makedirs(dir_name, exist_ok=True) # minimum metadata - metadata = {"ss_network_module": "networks.lora", "ss_network_dim": str(args.dim), "ss_network_alpha": str(args.dim)} + net_kwargs = {} + if args.conv_dim is not None: + net_kwargs["conv_dim"] = args.conv_dim + net_kwargs["conv_alpha"] = args.conv_dim + + metadata = { + "ss_v2": str(args.v2), + "ss_base_model_version": model_version, + "ss_network_module": "networks.lora", + "ss_network_dim": str(args.dim), + "ss_network_alpha": str(args.dim), + "ss_network_args": json.dumps(net_kwargs), + } lora_network_save.save_weights(args.save_to, save_dtype, metadata) print(f"LoRA weights are saved to: {args.save_to}") @@ -166,6 +204,15 @@ def str_to_dtype(p): def setup_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser() parser.add_argument("--v2", action="store_true", help="load Stable Diffusion v2.x model / Stable Diffusion 2.xのモデルを読み込む") + parser.add_argument( + "--v_parameterization", + type=bool, + default=None, + help="make LoRA metadata for v-parameterization (default is same to v2) / 作成するLoRAのメタデータにv-parameterization用と設定する(省略時はv2と同じ)", + ) + parser.add_argument( + "--sdxl", action="store_true", help="load Stable Diffusion SDXL base model / Stable Diffusion SDXL baseのモデルを読み込む" + ) parser.add_argument( "--save_precision", type=str, From b78c0e2a69e52ce6c79abc6c8c82d1a9cabcf05c Mon Sep 17 00:00:00 2001 From: Kohya S Date: Tue, 25 Jul 2023 19:07:26 +0900 Subject: [PATCH 112/220] remove unused func --- library/sdxl_train_util.py | 48 -------------------------------------- 1 file changed, 48 deletions(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 54774f888..6ff0d48f5 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -286,54 +286,6 @@ def diffusers_saver(out_dir): ) -# TextEncoderの出力をキャッシュする -# weight_dtypeを指定するとText Encoderそのもの、およひ出力がweight_dtypeになる -def cache_text_encoder_outputs(args, accelerator, tokenizers, text_encoders, dataset, weight_dtype): - print("caching text encoder outputs") - - tokenizer1, tokenizer2 = tokenizers - text_encoder1, text_encoder2 = text_encoders - text_encoder1.to(accelerator.device) - text_encoder2.to(accelerator.device) - if weight_dtype is not None: - text_encoder1.to(dtype=weight_dtype) - text_encoder2.to(dtype=weight_dtype) - - text_encoder1_cache = {} - text_encoder2_cache = {} - for batch in tqdm(dataset): - input_ids1_batch = batch["input_ids"].to(accelerator.device) - input_ids2_batch = batch["input_ids2"].to(accelerator.device) - - # split batch to avoid OOM - # TODO specify batch size by args - for input_id1, input_id2 in zip(input_ids1_batch.split(1), input_ids2_batch.split(1)): - # remove input_ids already in cache - input_id1_cache_key = tuple(input_id1.flatten().tolist()) - input_id2_cache_key = tuple(input_id2.flatten().tolist()) - if input_id1_cache_key in text_encoder1_cache: - assert input_id2_cache_key in text_encoder2_cache - continue - - with torch.no_grad(): - encoder_hidden_states1, encoder_hidden_states2, pool2 = get_hidden_states( - args, - input_id1, - input_id2, - tokenizer1, - tokenizer2, - text_encoder1, - text_encoder2, - None if not args.full_fp16 else weight_dtype, - ) - encoder_hidden_states1 = encoder_hidden_states1.detach().to("cpu").squeeze(0) # n*75+2,768 - encoder_hidden_states2 = encoder_hidden_states2.detach().to("cpu").squeeze(0) # n*75+2,1280 - pool2 = pool2.detach().to("cpu").squeeze(0) # 1280 - text_encoder1_cache[input_id1_cache_key] = encoder_hidden_states1 - text_encoder2_cache[input_id2_cache_key] = (encoder_hidden_states2, pool2) - return text_encoder1_cache, text_encoder2_cache - - def add_sdxl_training_arguments(parser: argparse.ArgumentParser): parser.add_argument( "--cache_text_encoder_outputs", action="store_true", help="cache text encoder outputs / text encoderの出力をキャッシュする" From 50544b78055b2b0f71a12d2af68081cfff581b9c Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Thu, 27 Jul 2023 23:16:58 +0800 Subject: [PATCH 113/220] fix pipeline dtype --- library/sdxl_train_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index f37cadabe..ecd2db967 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -74,7 +74,7 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp print(f"load Diffusers pretrained models: {name_or_path}, variant={variant}") try: try: - pipe = StableDiffusionXLPipeline.from_pretrained(name_or_path, variant=variant, tokenizer=None) + pipe = StableDiffusionXLPipeline.from_pretrained(name_or_path, torch_dtype=weight_dtype, variant=variant, tokenizer=None) except EnvironmentError as ex: if variant is not None: print("try to load fp32 model") From 96a52d9810689bd2bdfd2148ec883f8b506e06c1 Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Thu, 27 Jul 2023 23:58:25 +0800 Subject: [PATCH 114/220] add dtype to u-net loading --- library/sdxl_model_util.py | 6 ++++-- library/sdxl_train_util.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index f37cd71b5..56e6a9514 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -135,7 +135,7 @@ def convert_key(key): return new_sd, logit_scale -def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): +def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype): # model_version is reserved for future use # Load the state dict @@ -167,7 +167,9 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location): print("loading U-Net from checkpoint") for k in list(state_dict.keys()): if k.startswith("model.diffusion_model."): - set_module_tensor_to_device(unet, k.replace("model.diffusion_model.", ""), map_location, value=state_dict.pop(k)) + set_module_tensor_to_device( + unet, k.replace("model.diffusion_model.", ""), map_location, value=state_dict.pop(k), dtype=dtype + ) # TODO: catch missing_keys and unexpected_keys with _IncompatibleKeys # print("U-Net: ", info) diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index ecd2db967..65947c526 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -54,6 +54,7 @@ def load_target_model(args, accelerator, model_version: str, weight_dtype): def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtype, device="cpu"): + # TODO: integrate full fp16/bf16 to model loading name_or_path = args.pretrained_model_name_or_path name_or_path = os.readlink(name_or_path) if os.path.islink(name_or_path) else name_or_path load_stable_diffusion_format = os.path.isfile(name_or_path) # determine SD or Diffusers @@ -67,7 +68,7 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp unet, logit_scale, ckpt_info, - ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device) + ) = sdxl_model_util.load_models_from_sdxl_checkpoint(model_version, name_or_path, device, weight_dtype) else: # Diffusers model is loaded to CPU variant = "fp16" if weight_dtype == torch.float16 else None @@ -98,7 +99,7 @@ def _load_target_model(args: argparse.Namespace, model_version: str, weight_dtyp with init_empty_weights(): unet = sdxl_original_unet.SdxlUNet2DConditionModel() for k in list(state_dict.keys()): - set_module_tensor_to_device(unet, k, device, value=state_dict.pop(k)) + set_module_tensor_to_device(unet, k, device, value=state_dict.pop(k), dtype=weight_dtype) print("U-Net converted to original U-Net") logit_scale = None From 315fbc11e5e539101db7255ec4fe5c9554381e6f Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Fri, 28 Jul 2023 13:10:38 +0800 Subject: [PATCH 115/220] refactor model loading to catch error --- library/sdxl_model_util.py | 36 ++++++++++++++++++++++++++++++------ library/sdxl_train_util.py | 4 +--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 9b9fd38c2..eac83b886 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -3,6 +3,7 @@ from accelerate.utils.modeling import set_module_tensor_to_device from safetensors.torch import load_file, save_file from transformers import CLIPTextModel, CLIPTextConfig, CLIPTextModelWithProjection, CLIPTokenizer +from typing import List from diffusers import AutoencoderKL, EulerDiscreteScheduler, UNet2DConditionModel from library import model_util from library import sdxl_original_unet @@ -135,7 +136,31 @@ def convert_key(key): return new_sd, logit_scale -def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype): +def _load_state_dict(model, state_dict, device, dtype=None): + # dtype will use fp32 as default + missing_keys = list(model.state_dict().keys() - state_dict.keys()) + unexpected_keys = list(state_dict.keys() - model.state_dict().keys()) + + # similar to model.load_state_dict() + if not missing_keys and not unexpected_keys: + for k in list(state_dict.keys()): + set_module_tensor_to_device(model, k, device, value=state_dict.pop(k), dtype=dtype) + return '' + else: + error_msgs: List[str] = [] + if missing_keys: + error_msgs.insert( + 0, 'Unexpected key(s) in state_dict: {}. '.format( + ', '.join('"{}"'.format(k) for k in unexpected_keys))) + if unexpected_keys: + error_msgs.insert( + 0, 'Missing key(s) in state_dict: {}. '.format( + ', '.join('"{}"'.format(k) for k in missing_keys))) + raise RuntimeError('Error(s) in loading state_dict for {}:\n\t{}'.format( + model.__class__.__name__, "\n\t".join(error_msgs))) + + +def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype=None): # model_version is reserved for future use # Load the state dict @@ -165,13 +190,12 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dty unet = sdxl_original_unet.SdxlUNet2DConditionModel() print("loading U-Net from checkpoint") + unet_sd = {} for k in list(state_dict.keys()): if k.startswith("model.diffusion_model."): - set_module_tensor_to_device( - unet, k.replace("model.diffusion_model.", ""), map_location, value=state_dict.pop(k), dtype=dtype - ) - # TODO: catch missing_keys and unexpected_keys with _IncompatibleKeys - # print("U-Net: ", info) + unet_sd[k.replace("model.diffusion_model.", "")] = state_dict.pop(k) + info = _load_state_dict(unet, unet_sd, device=map_location, dtype=dtype) + print("U-Net: ", info) # Text Encoders print("building text encoders") diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 5357d7f7e..035ceba93 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -5,7 +5,6 @@ from typing import Optional import torch from accelerate import init_empty_weights -from accelerate.utils.modeling import set_module_tensor_to_device from tqdm import tqdm from transformers import CLIPTokenizer from library import model_util, sdxl_model_util, train_util, sdxl_original_unet @@ -100,8 +99,7 @@ def _load_target_model(name_or_path: str, vae_path: Optional[str], model_version state_dict = sdxl_model_util.convert_diffusers_unet_state_dict_to_sdxl(unet.state_dict()) with init_empty_weights(): unet = sdxl_original_unet.SdxlUNet2DConditionModel() - for k in list(state_dict.keys()): - set_module_tensor_to_device(unet, k, device, value=state_dict.pop(k), dtype=weight_dtype) + sdxl_model_util._load_state_dict(unet, state_dict, device=device, dtype=weight_dtype) print("U-Net converted to original U-Net") logit_scale = None From fdb58b0b62d35be045f884307cf5a8945528bd74 Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Fri, 28 Jul 2023 13:47:54 +0800 Subject: [PATCH 116/220] fix mismatch dtype --- library/sdxl_model_util.py | 3 ++- library/sdxl_train_util.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index eac83b886..7fe7c5622 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -162,6 +162,7 @@ def _load_state_dict(model, state_dict, device, dtype=None): def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype=None): # model_version is reserved for future use + # dtype is reserved for full_fp16/bf16 intergration # Load the state dict if model_util.is_safetensors(ckpt_path): @@ -194,7 +195,7 @@ def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dty for k in list(state_dict.keys()): if k.startswith("model.diffusion_model."): unet_sd[k.replace("model.diffusion_model.", "")] = state_dict.pop(k) - info = _load_state_dict(unet, unet_sd, device=map_location, dtype=dtype) + info = _load_state_dict(unet, unet_sd, device=map_location) print("U-Net: ", info) # Text Encoders diff --git a/library/sdxl_train_util.py b/library/sdxl_train_util.py index 035ceba93..ebcc3d399 100644 --- a/library/sdxl_train_util.py +++ b/library/sdxl_train_util.py @@ -99,7 +99,7 @@ def _load_target_model(name_or_path: str, vae_path: Optional[str], model_version state_dict = sdxl_model_util.convert_diffusers_unet_state_dict_to_sdxl(unet.state_dict()) with init_empty_weights(): unet = sdxl_original_unet.SdxlUNet2DConditionModel() - sdxl_model_util._load_state_dict(unet, state_dict, device=device, dtype=weight_dtype) + sdxl_model_util._load_state_dict(unet, state_dict, device=device) print("U-Net converted to original U-Net") logit_scale = None From 1199eacb72a6dc44d776800dd26ed5a8668bb682 Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Fri, 28 Jul 2023 13:49:37 +0800 Subject: [PATCH 117/220] fix typo --- library/sdxl_model_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 7fe7c5622..1bc96bad6 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -162,7 +162,7 @@ def _load_state_dict(model, state_dict, device, dtype=None): def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype=None): # model_version is reserved for future use - # dtype is reserved for full_fp16/bf16 intergration + # dtype is reserved for full_fp16/bf16 integration # Load the state dict if model_util.is_safetensors(ckpt_path): From d9180c03f6fcd24f26f356ba90caa7ab17f869eb Mon Sep 17 00:00:00 2001 From: Isotr0py <2037008807@qq.com> Date: Sat, 29 Jul 2023 22:25:00 +0800 Subject: [PATCH 118/220] fix typos for _load_state_dict --- library/sdxl_model_util.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/library/sdxl_model_util.py b/library/sdxl_model_util.py index 1bc96bad6..f490dfac8 100644 --- a/library/sdxl_model_util.py +++ b/library/sdxl_model_util.py @@ -146,18 +146,20 @@ def _load_state_dict(model, state_dict, device, dtype=None): for k in list(state_dict.keys()): set_module_tensor_to_device(model, k, device, value=state_dict.pop(k), dtype=dtype) return '' - else: - error_msgs: List[str] = [] - if missing_keys: - error_msgs.insert( - 0, 'Unexpected key(s) in state_dict: {}. '.format( - ', '.join('"{}"'.format(k) for k in unexpected_keys))) - if unexpected_keys: - error_msgs.insert( - 0, 'Missing key(s) in state_dict: {}. '.format( - ', '.join('"{}"'.format(k) for k in missing_keys))) - raise RuntimeError('Error(s) in loading state_dict for {}:\n\t{}'.format( - model.__class__.__name__, "\n\t".join(error_msgs))) + + # error_msgs + error_msgs: List[str] = [] + if missing_keys: + error_msgs.insert( + 0, 'Missing key(s) in state_dict: {}. '.format( + ', '.join('"{}"'.format(k) for k in missing_keys))) + if unexpected_keys: + error_msgs.insert( + 0, 'Unexpected key(s) in state_dict: {}. '.format( + ', '.join('"{}"'.format(k) for k in unexpected_keys))) + + raise RuntimeError('Error(s) in loading state_dict for {}:\n\t{}'.format( + model.__class__.__name__, "\n\t".join(error_msgs))) def load_models_from_sdxl_checkpoint(model_version, ckpt_path, map_location, dtype=None): From 9ec70252d0d687522544841a23744c8708c39d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=92=E9=BE=8D=E8=81=96=E8=80=85=40bdsqlsz?= Date: Sun, 30 Jul 2023 12:15:13 +0800 Subject: [PATCH 119/220] Add Paged/ adam8bit/lion8bit for Sdxl bitsandbytes 0.39.1 cuda118 on windows (#623) * ADD libbitsandbytes.dll for 0.38.1 * Delete libbitsandbytes_cuda116.dll * Delete cextension.py * add main.py * Update requirements.txt for bitsandbytes 0.38.1 * Update README.md for bitsandbytes-windows * Update README-ja.md for bitsandbytes 0.38.1 * Update main.py for return cuda118 * Update train_util.py for lion8bit * Update train_README-ja.md for lion8bit * Update train_util.py for add DAdaptAdan and DAdaptSGD * Update train_util.py for DAdaptadam * Update train_network.py for dadapt * Update train_README-ja.md for DAdapt * Update train_util.py for DAdapt * Update train_network.py for DAdaptAdaGrad * Update train_db.py for DAdapt * Update fine_tune.py for DAdapt * Update train_textual_inversion.py for DAdapt * Update train_textual_inversion_XTI.py for DAdapt * Revert "Merge branch 'qinglong' into main" This reverts commit b65c023083d6d1e8a30eb42eddd603d1aac97650, reversing changes made to f6fda20caf5e773d56bcfb5c4575c650bb85362b. * Revert "Update requirements.txt for bitsandbytes 0.38.1" This reverts commit 83abc60dfaddb26845f54228425b98dd67997528. * Revert "Delete cextension.py" This reverts commit 3ba4dfe046874393f2a022a4cbef3628ada35391. * Revert "Update README.md for bitsandbytes-windows" This reverts commit 4642c52086b5e9791233007e2fdfd97f832cd897. * Revert "Update README-ja.md for bitsandbytes 0.38.1" This reverts commit fa6d7485ac067ebc49e6f381afdb8dd2f12caa8f. * Update train_util.py for DAdaptLion * Update train_README-zh.md for dadaptlion * Update train_README-ja.md for DAdaptLion * add DAdatpt V3 * Alignment * Update train_util.py for experimental * Update train_util.py V3 * Update train_util.py * Update requirements.txt * Update train_README-zh.md * Update train_README-ja.md * Update train_util.py fix * Update train_util.py * support Prodigy * add lower * Update main.py * support PagedAdamW8bit/PagedLion8bit * Update requirements.txt * update for PageAdamW8bit and PagedLion8bit * Revert * revert main * Update train_util.py * update for bitsandbytes 0.39.1 * Update requirements.txt * vram leak fix --------- Co-authored-by: Pam --- bitsandbytes_windows/libbitsandbytes_cpu.dll | Bin 76288 -> 91648 bytes .../libbitsandbytes_cuda118.dll | Bin 0 -> 14026752 bytes bitsandbytes_windows/main.py | 658 +++++++++++++----- library/train_util.py | 2 + requirements.txt | 2 +- 5 files changed, 495 insertions(+), 167 deletions(-) create mode 100644 bitsandbytes_windows/libbitsandbytes_cuda118.dll diff --git a/bitsandbytes_windows/libbitsandbytes_cpu.dll b/bitsandbytes_windows/libbitsandbytes_cpu.dll index b733af475eb02eb04f5ad8cbf0530a78a58bc758..06d3226c46b4ec2d573d5f5b85f2a333cbd5699e 100644 GIT binary patch literal 91648 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 QQqzfeb{?`Fwjd_|51qOncK`qY literal 76288 zcmd?Sd3;pW-9J9r$N&j9D1%W^MvWSZ%V1m*BRE46xC0Z31q78%QHsSSg&9G1I*D+- zj@mx9YHM3+7xk&_L-&9S2_YmbLclE+7u@QNqcyldK;i!0@6Wk2nIwQd-|z4B`{&1t z%)R%VbIlhX)f1*p&JIc{?_-!v+B}9 zFP=4N?rjUa)${NA-u#>H@Xo&J&O7f4dvCtgJ3n%#_qIE|x0RhzupmD7rMIN`_n zcTxD(MPcMMt;Y|$%&|M;z@7Z_x?Hm^nt#hp;hS8pqZ5&YI$e|S_X7S>{`t}LMXH#q zr7tpk4oon%)PE>fe^Iq6C}YG}rR~AJ%K0yvzhFKmNMHikxBz?CdB-Yu>+N@;AYmln zXSu>&9SMtq?g`Pxa@pw zs7p7?@|rpe8F~fIt3u{P zU#N6qp%(i&pgm{K9BpWgfL%9FW|fB-GIy~d0rjMqL8`SjK^`rAPzjOG4 z7ISO4nYl(cN4osJv#Jlp9nE`D~3m;3P`>So+*3D@J{-Sye2BX)bn|(7IcclLF zPXw$`_3OI1Nsr}LHUd(IKCRb{{(5YpTaW4Prp|%swkM|nKrtIpgZIYN8g%nol*(F$ z_w?F5x>m6%HFw93Qh42Jfs_G=D+l4gWLA}vEJo6(3lp^-H?wl>gF!%=fCH5 zS^*&5%+`AJ7q!Uz7-_6Px6hr28d3&?{J!il1E0F1|c{~7iE2L!W` z@;>@k$az7%wr2_orHqxgQom1+F3!*644SXc$IIz>BPunOW75@BN~;{#mhytaG&QML zs76~hr!?y8HoZGS23`pnv&)?a?ho+G=t;$Rw@)v;U-z8-xi zThD00E1zy|Se$q7*BLGsZl(>u62$9VgAI1Q*`~*GYW?W8b-StsElz(sQNz`$hSzkn z;!_>NFXYHcKCqmU9l01xps6zte*-asuk!S~rmrvrz4n0iKzh2%RZ(PzjHLy>pxLB1 z>~o{1zvAt|Hs|R{9l6DNY>cfpSU~1_lz2p6b<~BSEFJbNFYC!TY|od^b8wv@bKiQG zn+fkrLPtf>f%wI``Ic_()EnN(v^_hL1u?uYF*=m3OP1AZ_bxwWy)LOwAa$IPc_3(S z36*}nw7t1vA&cu~Io4ij#R@I97LP?+b%5QNygFot3ySAF6g0O~mVO!3Dw{%PKRq`2 zpFv}wZcd&OG(ZQ;$un^UB2NAuuKBp$g{wE1(Ht}ag_XuVfP}&bJQr6QxB1y=J!4lW zmQ{Axwu|;yp`goURxGsZjf#bMf3+Un1i0ZkyG1YE9?q-GI8r(M%TVdE6`IgD0Dyy< zl%T(uj%-XvIf&jKg)KLLlLzcAdTd2raP}6xv~lU)pt-~L{P%MhogFd{1kC}q=W#sQ z&6Tmc-TLfi7HW_81v#=kQDgwRwr8>2L>|;v{f84n>58!+G;BU=e$hzUnYhV}5?f40HlY=Ld(k=rP`Q4qbRw&}^};WgE?9 ziVilH8^!W>gFq4 z`@28Vhi}qLt%bw%Smt+Fb7_mNjqcQAW7G7JGNKZ2o%4~b-Ah?5K0v4F#(yh8^3S(^ zxE8h7)@wBnA}JKBK0g@!_r9PprZetAayS<&*qVVdA+sZ%0rUu&TXbVVUeE+JS%Q)6 zv@S;916wjL2PiPA3w0B`ZgScQ0eT(*>SC=%5m$m=H*YVfBAExP(h1VQ%$YM9ZOr-_7Hx1{L{_Nx-m6>atZ}q^>J$&>Bz9^I{Ykps%g{E~L> zxgbi<;}5KAoICJ5@faj6jnuIvR&li4?7(B@5Bb~*xni4kZ#IZ$(`VB*H65P5*KWcD zWClty=!AWabOqDv&z6H?ygCyrOB_4LdhCoOZ+Jrq5@zG<`nJGYT{tEM|&ZZyu}G zHI|flze0hc9oDE{a7jE~K!ggKH&(Hi3p)6_WZ&k%qQbIP{*JHb@5FWdy>TsnXM?W4 z*F}h?H!9LOAqUD8WTFoVcwxPN1Q8*NjCsC7n)S=%V?7@qOg_HI$Cb&)U-Iz>e2hI@ z;3K|DZ5Q`v{bnnl3at?bMF9KDdn&uos`+neo-DsfO2$0XQIUH0oMh#FvE-~l$;Zpt zR#x)yB|aViHmYt9;^T*W?ADXt^-Jx^lLw?Hg~^^AemdEcQuf3=0toD`OZ4TDWc8C- z{hH+Cf1`+XPxA2~AHSb`e4mdus>h-|wx<;Wr|RVv<^)s@XRpQfG$u3u$jkzj8Jm36 z_N+~2J;1EK&U?RJoR{+t+jCzsH_Y5PFcpoMuh^cs$(-w$vs>k09pt=VdnP6`-}xsp z|E4lA>^*$^9Ur?va5iM2uDQJROM&3O-%%hcwCbKxqAT?QvYP84GtMF+m{|r8KZTS* ziqy@&6|9xa=L(+U)fj>0aD5)S)(x4tpe6*nCLk8 z+~J_H+>N!IH)9Zg=j2rsZ4J~38HoAQ&{pPZG_)NJy}bFR!x!ucl>Y1P^S}*aIro|` z1%~fQ>VxG*UwgYA3x2IfKT3=2N4dzr3V^?{+{nDwY_zw7Wn~5ImiUv9tn`$nyx=hc z=kbDvIQ~_e39G;iuo#8?e|HN)dMf{cTvmw*>APiiY!=0Wq{#|AIEhAa^KUw+Wk03p7ih5lU&u42i{KfWEOgo%3>4pQkounYz?MdpIwy+y=){# z4PJQ~xv6dv7(HT)qDjz^J=ENc#rmH3)5CDrI05mF84;$lR@) zkf}5B4+N^yb+a&>S+q4i7-@dpbW`Z;7c3b!cR^;*7&kX)&W9j$!(5SHM(M+wL#1sC z=U3M54G#_+Xh;iZ>9wDPZ^mspZ?}f0TocP2DmnSgIaxPG1%|f;&C$gn1AJz5m60!n zzr(`kB4MgN+l`A~&)~%yfM{wIGeMP~YPdtjY4L2mIUP{PgkVfX^%SWfTXIy8tG#;j zXrLB{KN_hCvx3+YdW=7C9mgCrEkZy5QGBA&SIX$;&n>5>6EfclnrDWF@2x=BX9l9} zX<;o8Jp}Q62igvrjqy;xtdH)?xGF=d0daQ)4%DZG2ZOLgAgJ%vYJbNrf(s9CjGv9X zbgkyUm{Pmd$*-0C2Ii+1)rVp^g_Wh-3GA%|HtGU|Z34T#3)n;YOAdf-hffX~X9k9U z4&VXUm^A>~Cxwp>Y^cvH2w?Lf!0y)#*m(-rfHRFk0Cr&yU?9%cT7a}62xSjF zo)9$sRr>5aJ!7|Cx^4bdc=U%%HwSZR;DEn6Gjd_jteP7v-5u0MqsZ>N&j=cLHv0vQ ze#3Y3Z3B|HzZf{F{Ufchj?Y zA*ad)*aOA7?Pe}?HQbx-H3N(4@vN1%0%LmD?%1Px;?E?pWI*>}?d78QXtj@n;-V^Y ziuRw72+LCP;R5U~)-#TR35Cyu!n5F1+jHR`A#1LoDxansWpe{&bNfx|oqR~aA=4Ke z&hkO69E`yBE*SWN7kB|(#GQhs~23Z$1c5E2QPpbfcl-L$F6}kv{SqH zVpJH%tc#Ab(^~Ajc}dXxIDX*^cp2K)Q7!sDDqepcv?XgQOHfnVMjVXIJztN0un#5% zm=T(3!!Td83Z7ujpo`5H_1NgN;oI2xjGeS3>P8_he%-+0D+3N4D67r{-kW8hIm`hz zdU2^T3ghSVQ8y=op14^cIDDs`@#65^PC?yZDkdIPq=hfQK$YSeG_QfS+I)U!`2JvQ zj8a_B5$^vQwX`4q81Nro4Wr$5+w}2n31~fFL*kUtR!TUI5?d?CPVsF@A0e)3G4`LVkNDmBUH@G0uO{ z9H$r6!!(7e(uGJij}{$&O?opDsr`s`jm8k4dF>)|Q^DC+rH6eOs2(z9g%#kwP&e~v z--DGgP)(Lzh$RP&yd`9&g@$j6k2tU?GjcYe<1BRY6wEw85ttg9?LwK#jD~o>5U44T zU=oZ+wR^Z8w_9sJwe5!#>#Isw6-mFnNlT(*a5#hx7o)%AnB&)}Ia$>}_HBFq@H9jX z<^%hYKhq6Ktb+9GB{9!D%xvAv)@SSF^OOIFZ)cV`DX|}sy&IECzGl0AL8Wv+6(uK1 z$qX1s=Cb8xpf?+!KILfiVtJ;%zUt#g(Kr=!iwb%h74#MeuC3YK1lOj{!VXyG4>c{m z9#+h}tjEv-g!hZ<@4iS+5$t~UpwiJ;r|4&v=x1%z!^&EqhdCnN9+;1)e0?ADuS6{$ z=2QuB=luz?(pkyJG8C~+N?|)BOind@*Lb+MGU|SHxGwq`-vi#U|2z; z#;wvNn>iJ+HB6~6?sroZgr#Gpwd*T(nBw5ypJbyTM8Cxi6pFO)zzr5V6f^mj^+AmJ zu#oDpsH&J9gjuME`yy%2d)@Z@2vyb8NBY73WP5JG1MnEmqjW)KGc-^q$IXVcYFFhw zB!Vb7rT7C(m|Txrtgt&j1w572UMxCxp`U}F$tU^NA;64@a%BBh&dj9`F1JCGS&>dSM5GcT!+ z4~IS3S4E~ZR4?5UJ`Ff%d+vhJo?23SxIUh~E^Q5{5CI}KpLVPsNbiA6Gvv!(^-eud zEqcfw9?rgi|My|%w0}$*F;zFw2ix;k2x8GrJCYTfnic=9Ztsf2-YBIi%`HLmWv5sU znhut3iCpN6m(_s;_Nwj{RUM==)by|D_Dq7xDW^A=k0?a%Xq&{G&jK=5(-iDYtKDh2vruK+WPq zm~M&v;(!Plw-op*W4F4Y4+l#RpbwSiCYboQjEh~B7b<;Ci@nHKqMe!A{g2=-h}_tO zbp5fAxhr_^Xyx#2!HjLeXgiR_3O2Mu5`Q^pH%y3S-Z$qV?H_@odhEM-P=Pb4HbIo)w+UqJ&G-Tr!wQ!P{s$r;Rh;9cWd`&1OG!NfI#^HOboE0Oi`#TVhPrz z=o9>L;BUjB&4H1q&4um0#fUcnqyehUg;e+o+hccwF6JX$o<0Q)lUlld zuo{6*1zw6oWa)))Gx?BkDXM`f4?d@&J>{{{8SB@ae1{)$=C6TutW0-SIpl#=AG@;f zvYF+F3rtrw;SMk}2nndDDh*XrsEAD}@WRi53P1!ukbIR$8*)CnZF^QDldSdr0(rk^ zhxN%C6koNO4Ja^xA5IQT*3FO6@kJqXSY_=eT1^dWGp2&hR6{ykBh2p{MD74@a`>J7hJ6w70`ILLPCsHJf*J=Kqc(Z zwLkwLAN~N)<3mRlLaG4u2(0B0D(fsCjCMh@0u-y zHc%B_ud^1Rxu7|H7WK!P^}?seyWxUp0n-5tm+gb=vIX;CENjDGD+e(!d>eE?Ja7N`r(JGfErAQjVHa(%v( z%crFLd(q{-8GL>LUvYLX@STe!f=^gE;gN#KCkZ0=$Jl5DkP^M%cp+x08yvNolfZ2R zmRtLzz_R^i2xLrd-@==3i<7k}b*yt%-4Bq~Yt^Z_o&mwotjMpZeP65H1|f{xbrxCN zT#{+*EEF@*3T|C@>vf)UJP&m$<}S))V<8zQ?v7q0}t#pP3&~)b_mq zatL{LDmu8gJa#uU#A4cFPAmD<{m6-&qMKv=m`(`{2xt`t;#sV>u$*c%$Sk=(MClg9 z22uS6>X$ z^da9wQiM=D}#Rz#BA|6w)U&qp^8xAXcsWY=?jH zbrKpfg)Cy#$1733qUe)Kb6>e}2gFYJlo1KCRjcVMWG@Xs)M}2PR^52Kpbmut=9`pB z7SVZJ4UxmvYF|Y%Sk}LefFT-pSU|p37%^ILzpoOmK3v=M)w$0in}8V(Om1}m5)$qK zca;s&+IeJQAKR1pGgbx)@i}}2kU@i`J0k-~*LGSB1prW6ygzEG;~Z(_ZNTr=pm_uf zssXeZHa~Ke)(+GQ_cgi!dPACPS-(SV$%2C4mh~f~0l!grVNY7N9L9ZPx(^1|VbQPh z!UgmrW6-qs69~lgYOvjvxQ7ga;D8x$$(bOY6Y{O^uOL=MG@E{leCw-w_!vG3-OvGJ z-MSt6rCFiJ|EQan&H0+6t?&U}>i|NHKsPGtkhB(8vSM7pj%yD@vMS9l<7eBRmmbCI z1I#wtb3Hm~ZigG)_H02Ssyjuhn_L$%A|S&%txsoi)Vr(?$6z=WKJ@Aw^a(ihvi1HF z>DI}~ZoLAv4c$Vq^@2oE60r(jdj{}Vz}<7aY7G4yopq$19o-AEX%}OeTQW< zmqA8CnGCet7j2rIFwggw7SXb?#LXxzRP;D2>Hs9q!egHKnl(N-zo1K$+AR~hCPh@L z3e-5eT4N18(%Q$PLMftv+*2hbe7$hTC1OABfhPg}x9fqi6TH>~SIVddG9r!i2yas+ zp4mucLO1V%8UL1oD!2sPu?pK5>y8J_v6+b78Jjs0(|UE}N!O7$8F>{IsP@a{`ON5%v`DVhm7_}h4M96rM~T#%&fcLrWDQk4 z`njX1K9w7E#nZeloTq^VC^8ZzB@!JU=yuT_%0fqfLZEd@nLn3C25b;2OYQ9q$-&Kk z$qim2P`XqEWnZN5hUlmpAkB@=4?!hC7md;G(CRcAwnqe4SHXj?M4h1aXC08Kf`ofG zA>q!Hx|Q>(eH;mVvJK7`{67i%2BM!By4lw}N*c8Utig@|1sW*=jL=Kl!k`(z-ae=! zQH0b9NuN`!QGHOuoY0d zWzUOE9ip2P3dtz4ET2@e%PN#BYSzsoLF1zMc&?$j=9@udRQzf%j-wHfG0&dQN$hr7 z<1Po@w#CmQN0E#MCu4-l$VEfuo9h(^!Q4QFL%p0H_*oQX$0U7+{M*ZE0w-Y+u#!^V z6_(1KO}K zrKaJGIeM=B4BSm9V6gPH@FfU{2B31wkctV{jjR#8)5;N+nR^j#wY>Q-RL}Qn z!y;>SbNbqNrdG&1a%jQ+9vpgv^ghX#D1@NaV@FBBW9{;*XT^Rj<#I?8}UV{z=13m*_@@ZNg)DftA+OUdx zYjA(Ur(&HpuunWg8+f@^i1}n7&`NX?VjTbr8`uI!bW41d=Iml8+K2ImNm8PlBdg`Sw(u>fJ8M{U`(UBD?N;5K zl80%11B=AkIE7_}XC-30S#{oZkiWgk7zJW;#yXS*e-D@2o(eYEpY3et-7Wy%_7t;8 zQ z5ja!1Zu~_yF+9h*;{s-l?86dfZZ%G?ZYVnBqh<=q8`Hw?!L`jBD zLM^$A*uWUlo!ETb$qEyN6U63Kq+(%o*CUle(J1D3!UZs`GDd#BpKSv~KouCJQt*j^ z!G}Ty0`Set-ef6E*SQWV-9c$kq|DEG2ULQTIZLW0DjATN5wB_H{!VI7AY%LS$vrg= z#c%c7(p=kqR;tgw9(EM44?P2DvQ?_%(+1bdhVPtp&CN&Yx2}7B^x_X*d3fWi`oVYg zhL29UZPUu1KI$6YGOyv53tg`7heEUK_1T;B+gey-D5D`*+O~XLaCn`dxA)S2y!OMlPA}6B#`T87n3PQj=tc;6tC$08_lQ4QF>!Dxtf{2H z05kgrU>!iH7uHeA=+ORrt=nvYc)F(!l0J;y>D*LNhbd-2Fv^EaKlq3a*`f-fc2zzZ zs~b*rB#dSPj1wv$pVCKV$tu#4NPm>b4;u22A`&V1nE@~4h=Xm-0WX?y8G(EqyDKaW z;|APk9L}Ok)SFIlcNGxk?2dGSJVjGx0{uXqgE?g}9frZ>j0pMJe zNC*JX)#^9L{o0ei7mNqFRZM*gL)j*fdxG>qH4wF6Pp!{28 zvb|6qe4snZA7X5pnJAn<`S*~jP<~!dUeIb143K|e$pofXQQ8zv3u>a^;RZYalLexw z_;vGCLW8o|A%cUj&|_sNv;cw1Wo-&3GEEeSP6Ut1Y?>Htl}WG1=P^)l3R1xXu&~Cu z4PQLnh5*blCI{7h(f5MD!7q*lfp?I490=?b35gUDL&wU8(*s!ShjS}A{srQ2BcY6O z#RCC=3$gLQha~{O5+K78Aj3i+1BBGAA_-#P$2Ia!V~aBIaqMhKDM_6g{q@KKf9V=^ zf_ilybuUtvCZkRiPRx585oO0Ab!~>4cZ{0!P6nKc|BPb95*_ zKp25o`+(VI9uAoQsf;bRqleQM_6fws?2qTmI<;P04!ak{V%u{!nn5f_X`6QcP!Ol6 zoxU);PD56r?614Zj!Tw(5Ny>ID;p5)?7uL3Bk6BEFIINM{0a$TMg?p*|7J#`2GFz&RXy59@MC{y8kY3|9U$Z@w{Y2fEJ2>9Q_~jar6|m}p z$69r$wb!a!h03}LC+24!Qh|SXVM$NAGZpI zCh7D4eDqE9IffG7hCVmln*hyUI|!Oy^f~9+|7-euz0};3K9?c&IMm6PJAxu^n1H&>;`EYK?MzHSO*V5F}# z1?zalx+&bL^<{trin)MkGnE&7D}Tq~YPMcHbuV;CPRP$8=K zMIm#$BA2oi-JXQTk?2DQ$$2Hwhy_b7)}3$0IK(L-(_44#B(3US2}?g~wG;#Wrg?BBrE z17NzV56Sk@gGH(N+|@IfMo!qFdK zMB{3QbWLUQ+*QT@vFkTS&S+*`0BBz;6T?TxnqkvNLX;AG(x93Y<~e_;W~fumDNZ#S zjeZF8(F=>}gN9qZn1CP3pW&4EIOQSSLV!2*e1!M)>sDITf4uVE|7H0h$0>iN)1Sdk ze+IBWeVe)F0E6xwLQzvMkctG}b)*O>lT3IZ=tsbMl2ac+!4TwLgF_9e^AYJA3k+7U zUSEuAt=hW*d+^}?bvbxcIYnEW{X$l;nn7Z82q&g-K#ym-)nvj{_FJmb60U91;hMH5?WT!Xc70S8PIV|WrxY6wOab6TdEhsZnZX&#?vOhgcD zy|EzED1uCpkGHYk2YtcHI2F4Eg#HUJPS|CO3Q;|&W5{K z`6Gj!cs_b>bk@n#@P1ZZY-LN;WVyx|H#u`LZt~43nZV?`&$hP-GQ0~2#$o8^eEyU# z5JPgo0L?bB;&f;Y*>-*D*i3k$z$6!-2;z6j-y|gAJSWs4-B3LSp3GFpt!{}2iGP4C zOmbVXaX^q75%r2;=~(V-f8ea_!sOfCgE>(N-yP(vryQ>HY|~|6V@YB$Df+R2&PFVu z*tjFsov4*W6EMt3p_>kC>q!$?KQwKjhy6&`vW#v^RqVBb&y!P+fY=HF@gcOS<)z`! z14!6|-r~GYJ_Q!?Q{ZO47#NSs`2iFD`ej2aV|URi^y!;;V^~Eq$HAztQ@UJ3y(~lH zDI~@!&$q68pLkN)9C(hr*y%3}RwWg?B5uU9M?2G(WdzKxQRbAO6Du^7LNk5$r%=&? z%v^a2MP|sBl^0v>?@=!k@p}4D@eEvSy@E8QmG!a)ZGv=Ei?D=0ay7&%KeTSU95(ur z;)pvoHmChDq-uF!LVqi$NB06+UY|L-w!B3fR@uy(28{PLv>k!gU9n5zOwjYU!{{*% zxHuCP9)zg~&VXeaKz9(=Z2Tom2n5o>E)xP4Q+E@>dFUIe$hJJ_e|d@c79tCABVj9d znq`1a*0MQ>-Kx!%g}ngF0g)=#;XMh0usvTv(2+P5t+o*Z0HJ9vlK>E$1JN8!#DL&{ zktg1O%;@=eue5m3nvE8vu9Hw#J9K52w3fLH+-1BUbr2tJHC4kji`v#xr#YqD&aEX^uJ+Hoe!gXXxKw4VKGrbmQW3Xcd}AWQry zo1VGlx$>Yh)UI(__oHqVKXfz9M>}?iv9^8A+X?v*{0hgRi2qz-B4-ut4Vj0`&&$ov zftp%PC8VYV{S4q9X0W_UV>axo2yLnPz2H#R!GEEUF})34sK>11Z+a{KU@XdggIQRU zmtf{0e)bOc>1Me&58iQ9(rS6$A(*ZP4a>KJpMX-;hvAE_^dacP8h;015%IwqA7F#l z(Zd@0X*s7Kz9nK#`h6^2nE zjw=8v<;e5M(9IB99aB}(f&Yh)%wB2e6Opj%PQI6YdN78(331^1w_ zjGkn8a-4D-ijf){x78|~N62)Nkqmw|M~YT-FG|gIkvhf+#BU{vgpA)7kPz^66n|`7 zd&uyW8`W;>jqkIr4%Q{kdsq&)HoJfjph57U!gG(U*4WNwd&Uq@#u%8&>m!$dy1;#J zEymlBWmd?=_6&!pMy6d|4oR!px|7L>$8XO-eNJx{=A&_IPLEbELaXJ5uV<4lvA!Nn zW~(N1oF?liqIEU-)oo6bFxMgdF0Z(+YCpl?rVozaE`bY-S@;0uQipv(5!}PFm&xb@ z;%kg4EZR!>1dZFCrEJ3(Wx^|s#iHRy-lTha}%HsJ{^X@v^w_&6eDi;^iuX> zK2OhQyA+IpI-|+x}Ltk`o8f4FT=I zR4#&)CD46+742!i?ezrlM;27YNEY<0!Hw-{uOS`$vc2=wt^!^996*TJ6Q1r99%TLf zdm`$6qd7svtBNV82r~Pj*u>1(_%!QhcpaeBjqLSYiwGoD0;mKdrJC>LeMrqX--lX| zSIl``hj$_DwP-JcKdN-&dUvJyj?7;rcT#_}u|H}yKez6KR}>pqD;e-T2I#{b;PCC= zA?GB-`GVj2>6u6eDdA5uez&A}#td~KjF zXg;u(^%|yJQ2n(K2Y?|_^}H3Q%E8(rPvz#Vc?b+PqKu(HDPOs{YzRS`W36NhMwAf~ zh&U}Txx*XLD$Ezyg?JyNRG1&=vFM|C1eX`lkybyPJauZE0meIF&Gb@6379X3jCoUw zwpxCvu?!J$?05K5j@(mWHqX&kz@tE2jL80xC>Q@FeMMlm?J=r}*O02*xB=J@AbbS2 zJ7~c*B7I=UacBzA_ZX((1H4c*l~q=!n>YGZ{Z@e6<&X)#J2sx3a~Fn(4&doU+vAa^ z17SB+k-4`51yEI$#PL$N;r`xv5N{UfDI$*G1?6|yUsnaFX*Fj99N6edEIzlqB;bw= zwSIOLP!n2II-0Oze5hw}CL%aS56jjKBD6-}X8 z74Z`=)=Cm?$eCP@M@OQek=dtukpbdqwUtqC9{1lio8aiM-(FW!!c+u5S5ro6} zj-H(CKLY{ZgA^r05?c%)(_40|LXApxJny3fMG*K)kVFq9N~FhXp0E|mdaac>{62(? zdgxH~A>-CI{Ix=`#HFRe`~teuUs0wKhwlMJl=4)60_AA{J4?Cn2uKsG3R=yd2t0Fa zez0V$TdQ4*r|3qmDcFJ~B)t8{EPz0Cw3w85aNiLy-@pYzkGRsPknB5wLh=(OKy_F( zXc$77n3bcQ*~^CD!FZ4@MmzgN^2=cmq19rM*ibD)sa{Qr8 z=bm5~VlIO&huxSfuud!2>1MSbn%p|;aafWW*n(w=6~COt8Q}}IYkR8k#3flRq4l71 z3yz_6Kn5#Gi{$Y*P@M~~j~E*oq0tNDNv>BfEn;Tw{X4NLv$NPM5yrA13jOjX$6l`+ zGj(gjhY4I`1SO#Or3ATVP7YxFb`s&;@5EfF_2^bW@Q`)H~evOcpo`nLR@< z6;e+#2VO8+ZO;|VRZ(ybR|pz?;yD`!07v6l8x>;EgqQSwljw9sJ@s;xA9#r!?CC1s zhg5|hy@NSEV4d>D!`;t`}0jbaG@`SMyyZ2b+DDN}W4cMGxSR-29|iIESk_G2&|n8jK7J#2iV*?&x9mF3%oX#_2WKX42f zIcV(3(HDe?n@2=s(aJkh$fG|wmwIw8{a6Sp0^Lv4mk9K!)@wUc$fK@Qs;O23Qjas2 zf4YTpsnxC$p@CBIq_fb=l0wYt*!1{aS{^N-0~`Y=Bss?>N)&`G6evjJJaDi$l3fSO zjw^l@!)}BLTfr9EuOeqv0$ad<$LK*Ln|4*-PsBA@mjLEuKz0A1L(+kS2A$ zRXkH-KLyXxG!Jd?q6@Kc?^u`IKwN2q^dA{a5!M(ga=UV_z>_!=Cw_hhV>dEj&Wm72 z%yw(<_3*LuCmfoy@r&0X=%>5@6vdQ5%SRB1LGvpW@I<{*WlHaeZ}3|#@;W=Nfl2s;nO?nap05AwB|2Y{Wpb7NmN?_$`kYDC2LCIY1qX~i>ai^7a4 zz(I06Zcy6GH?s;bkj5RviJ27VmD-^E`wRgh-Hg`zP^%DhTs!c091*csaPxfCLWgye zv@qTai6M`K33h`2*EiaZoQmOq3pk;YsVqQwl~P$i>vj%V0+FU$4hwh=X=)KLoUYsE zm8WlF-3mgr@559Fz|>pgF)CBDJ*RV+B?~btPZ29(WB+evWfYs@tXwEvgy8FR6Kq@A z&g;3bL48tXVpqy|S{%0h@wVfR=k-|}&n~Mk?7E?(l_bnnlhLCfjvqIo5fm@xYW7mg!w%j5rQEB2HMQn=)sL8*SeQMdI}ag9!G?NhqE@owCze9fJgYM z^E1Usn?`rTe)t-&8A*$75X=feR|gztSzeGKFqFR0&J|kia?%3&vZE{9X_2$c37OnK za4NnsfX#N|yH?W*=cNRE!jVj(OE}K5`sAVqZK!J?_C$3r2W6>{@XfN`fw>+}UYsv9 zgAGRpqi|An?g}L(PW>HamB}h4J(l(F22_C&cEbkJPoxnWwn#qZ?=EckM!V!d^hTkB z-3*y7I_k)LnA^`xnA=4TGQXlkxRl1m)V*1V6;v!Lu{Y~^)SxE|C+8ojYW^Ynb|(rC z!>cSBgF4uyYqSoP7t@^bA7Kwn(I+AEGy0FdBubn_n?1CRDwtkm-{p)(s!nG)cKcIl zw;v<{H$6%@d*!AvvTbPr&U)T$&7H`82q(*mRp-Q4@NhP4m1BjFulmryg|M7VV?4GJ z^ocG4j$CzcH=dOFu0LNlU@yV6%KKMihaCtt>VTBV%iP2@FP?$;3~qmd&Ixm<+EMw; zG^qd*XMJQytQwZk@ebPj_jlQ|?bZ`=g*zQRCa^GWI7NtT{;u&u-lO%Bv}G4NLbx#|fH4b>kT^!_mGytK3}RhR(08 zIf$hbneaRoiEH(6o@sIwO3Q|f)fu!|UWiAY1A=~g9oxX}8wJbrlBFW=w)a7?ja;wo zUz0-vd;C@~ABS$UV)%uN>a~FokFd#Ocz6lJMMV%w%0(g#T`)(xt6`3|pv}$ndL^2l zQeOIH#BG;lw*LkdZ={UW{uu6(jfXFgc)OJTjgbCnwYS5VpDY%6OUpwCjCq;b!0~zQ z*Rhvy*F1{)0uVLK1%-%n7~_T$U8`A%L=K_Ky7v@hAAB`23XZ``u+{znMa(9GD7--0 z=fOrPTUl;%hp$Cl;bQ3kCQ6Dz`Aa6u_Dn_AM(%-We-hwRVEqN} zYLUiaKq<&3jJB~!Z6M;m%pWd7fsk<%B#8RRc-+A5eIL`>XX6Kp6p)Wh#_;7mr?S{(5v zr}a6!rKa^Sd_Qqsd2e`*?+wq9Dex?X{E4BTc?@{EktOhqe^-DRAMZdC+!PQ=0>ck2 ztTq*neF%*BU?-IzNZ#ssK_ez*O*L}*Q;1F6=_=L|wc1h^W;glP?|e%H3%Xhs^d}I( zL*_dHnw<7VG_|Iyoew0aMSZe$cVl8vUy#W~J*0rEdM%oT9X$kmri>Lbo|9l@tmZYP zn4ie)0g1OLUtL7pt$D5c3U9&VoQHIC31}1yq*vpSYH7A$E`7*5tp~y9aauWTdoM#M zGFwSj(h}96%f#-;bM4FcuB`paL0CA_YRcj-*Zy3j)%+Y?JPrjozc;EBMoua(SpZWl zL!U_oPE9l`E9%+=z9jp~#Yq ze&7zzBSue4?L&BaavcA}%=H{ccGoyU*CpoR9u!RNW8`5)MNUEqMMeIN5`ytTGqZpp z`9Ai9t8|k#5b@~=;&Gc0k2xU&f~B**|G-{gMrT<|PD%_eIiubV&S+!`LFSMZHOOvs zMb!!l(N*hY)|wzD$D}JfxJ{6xH$6E9n<$Q)5-9zTViSij38G53@5f!yCyDd@F!Y}A zzm@R6Uf@p@HeUoahnOx40bwIOkm$ZGNhI1uDGrMu{Pe2BJlaNtJ?ChfhWJu>j7Qd! zgvYbilWIe>NyVZY7~Zfo>|S+1B>n!uIX@|vq*UE<+PJLfaqGo^Ekt@DWv@lWPr^hQipQG zK*=e~1D+A95INS%Z~~l77*4dBXVK(FyyI#=mkmI`!WJv=)Bsm(q@V02ZO?JquCo4u z{Z>hq4$jEs>lgM|3Yicx940|x*ES_4BDp~B;R4ZWe}c9`26j(5i{wvuM)$>tnu z`iZ)!-S=`Jh=rr06LueL5N0f<*dDV$)Z%yXfQ9zWgzHGbh)KikVVI!2|;nKR%E=dAZ^cVkz|A5Y~JtUnRdTLrY?nV9>D7+Ul*RHLSTP6S@j z)wB(14_ZiVf1WMKw83E@&9#p(7tv(#*;3=d zSFL@}(t6g}1LEIJf%q7r$OaH*b!ee%JjTrTV-s0uB2rwmhx1{O*~jcartCv- z@+JP%$@jZc0$iQ=)*Jy1;#unx=76&}LFlMztB^EYejW8<)2W}CTN&!~@dm<^yiDN(>;Z=UC+ z0t9OHQNkXGuK@uFh>;(F8-!lNC}?hxwaD`POUD29Q^`{s~?|QRx_OtcFvu; zmiNGSMRQjzDR}pf&uCihl~QE8H5FSr33eXXj(B~yH5LgHtQZEt-fq?5*bzuZ?Hck+ zmJC@j4ab3(l;y9O#KOjs0_zbJU@)V(9eCYpt-&Mfds_xO9+YR4Rr3mli{fUd)sFa1 z6vYeHTk6)dtVv}cHmQ3J}8)9P=OZ2z)?YyIes| zlbg(83?T7j7D#i58aIugxa5GrjK0&are_Wpfhf^7%!^nYBICThx5WI-{Jlpf^cvf|+0KWABw!G8&Gp-@y{5VYa2r4kHfPW)$ zWgs>a62~rU(8rvyUDo|51XnAyDV^x;XNX!AOlJ&I6N6%6w8=QbWm5mQ>!s(oy*%0J zWq;|w7YrK2$q!dBh;SMV3XC+w=lWtmLop2I@_3w?aU4)Q3c1Z=Wl7+b_R)AuS#PQF za9Yiigtu%qQ2G$en06$`dIXF7Y3x|FBe(13>CXC!EaTewT7sD)lMq$F&n1eb7|3gs z<&Q-96_J48`>QBLqfaECC+%aI3@girr_~zOsnWUSX}jga6JhG37{C<(P{M9Rg2Z~0 zN$uGvm>?f0kun^iABm&J4<|M)i5=D%)}J^;HLUvQ62qF&H7u?6egVR3?9qR)$r-)A zx@&aFfq`?sCS%)%G8|jDVB~#xGm>Frh5Vr2_BQf?G{bQ{dw37ET(5V%7ik`N$Z-#8+flqyXV=&Xe+R-XVnUaNES=! zSBcv$HChN2_`)QQ)QC-RTXD?0VALrr5`$xpi;R>p>SCeXF$KYc=YHWl9&`n~Wh$&yT+`K#n*jt4=FdnLcC5tDu|2Pk zP4cA~I{8va&K*K3-W`H>g(b?^>+gQV78Pg=9WU{@1OY z)OVW44#C2}0J&(Bu$kHD%r7O7RWiI&p_hj5q4W_+hC3uE*Em_+6yCL(QM_04)eL^G<|~*wUmP)~q7a=!FGW7AO3c?RYasjF1_%SWc3Dx( z9y>!y0KP|`h<~O-3|=5)k3$TeK;FSN(wC`<81zGDgf?JRj{&LZP7E@OJ|Qi55#p00 zqkgws$*30e9;D)}Jif(qepxF5Qg&MZ?#B#}frlUqaQTxGSRGHP0rVgN#$VLJo=Q3} ztQ#HRxHv{NxC9ztoJp2LoR+VLs*s^-oZ5EJ?_uAOBm8Dj2L-PC`J*!saTwxw(P?!~ zz#86x3AQH} zRT;I9;yv5bE>aOH?T{Osy!9Gx5TVQOl_0F861LM8bO?u5HRFQCjV~iiLlI)hN~!Mm z@+S178fCP>M?}_2#)W7H7;u?xsucL{5n+8kQk^}r*o)2jTXB9l6Hyl1etyAVZ20%^ zi*kJ94m4oYGO9@DcW84feg{tI>x;?{U^_R5E%+-{auzCV5w)mSgqBtO(g6~p%2i?;y!(S(sG9W;^u053D%@0_o=!=AH*DDT@@ zznZ1zWtJwt&>vOAuX%x9v-ntfLftsG6R%@wJ#slOwxj=V=B2CTdWw zUcdDmQen$OykM_@wx_Q~XSM(>rqTlmNrhM;>y^tc6ZkZ61;A45w1z{4mb47~O8oUu(vgYz`2Lg0`5^Q;AH0_QLH6wCV_uT;F%vJ5X#Vf# zBa4mnnvYL^f866nTfW5W*`L*yFCO4e_1}}$Vh-Jg33GA3geC21jw928j%Mf|_J;cmrEk_~7Ps6;= zP)iA(4yJ}$c8fJ`D`meCW!3yULhrc2(@wN3cP6ME%q?6U$(;$@ZeCBq0uu{@rx&BL zWI-niYYx(mLscfC6AXOB7X?26o>SWR=?KmZ&ROj=4YFXYf3iSp-DB(~_mJCwumv!L&IPrM!a(9nddG|^gb%(Y4x2(>53N7fyvvNU8S=J#Ro3GrL7=)D=t%Ol? zwEGgH?X>PkCCP#^+D>Z`(vCCQThTbbk_iK#ir+lenYF~5#J>~9-zJgc-d}*}adU%; z!3Ephhrc%SGyJwXxN$SeNIbQelmtJVfa;V`+-~?$S3*cpZ2J9g2r8JiXem2kK(*fi z2EXKxAff&w|M4gJ&s6KXsI#lEBB4{QtB`se*bPH>fGG^9zBqa`ec`zv^4W4GOMEB} z2X7 zd`WyF#mw_;&yr$rM>(!44gGY)&^wXH{61RV*t|G4jC>OD)KO}rAhDKL2w5{BV6p#l zoErIn7p7TCFt-ykAw<_)!<&-jkZ#H)3E~eO{x}OzsK#8GB=XWK5|LT_nJOIA302^+ zlnEwUbpj^Zd<83|7x?eL#)M;yu_~QOxFf5^BN#MoNvqw-Do@0h!%mfc>t196`+Ysay#3a6n9%wah$z+yblC_#WGNHB|4n(ic;KzYr?z!MKr6Xyzl&vXL8W&lQ zTmTGdY=@eabWL3xeorhTNEQ(n-vfCJb0eB0)5HYraZ4w%uBkQ_?8ea0`32oD_<$BYi{_4c6)$ zwI83cmM~O9shf-MxU&b!OSFjkC440pLcj$cl=FDJ>Y}|OhBFK;86TwAZi|({U(^V5 zM8?)g2TpTaemXyw04p*ojbZ-L7ir~LED6_!Jc1dbV{vTUe(Sr#*`k<=-LWw_?PVxJ z1D6*kNiQFO_;R%^zx^zvZ_L4)=4-JDUs|W*H5kW$e_GAgNF`Us#}nQU5%i(ho%pzc z9|{G885r0;iS!G^mKF?dXM_`b=8i2pU%u{_MCR?^0o6z7BRdlQo)eiEz}XT3?1v9X z!0L#Dt+7fkpRE-r9mH;V7QPZ;h(U8qA&wT{g<*)!6`_Y)gT|d*5s2TpR9^FP)tnhy zGz6cYMHOUdg{%;K)r)HgUqRvNF_qX+PeF7RRzsg=hV`MyF6+oJ7U3xIu?Zh2S3g=y zK16EKfuM0Y;|>5lG3*HZlfX~#t5kbk7%GW4I(4y=^tG;rIR?E$gl&KE%fcTh4nnwQ z2bOLMe{QCgZtAl7L_0I!^o%yR(Fo3Ge)rX58P&SAH`Qqm#uM1t`&zr8H=;c_f=?Ey zEYVm$9t?O6e@^D z*+AI~avM>Cz@>~**Tu6S&UKSf1|>RWrDFszUfsx=$vyj$Lt?=~(8BoSkhn=^GI@nwI4Yv!U0z=Vj1BI3ToI`pisx%cck`F&~z600#N514qoxcDgk( zw!{Oa3o@5~h>U!z9_j{4LO=}_EGh??S!8WI4>j=1M|^QDUW`vwpUmkqETi05l4%y1 zTZ}T8)5d$tjZ$m5R1K8HaX9!o&a2jih{i&d=k&4+%wfgP6|6)j;CiHOA!yFPs+Hpj zY6rvWM(qY7Od{+92$ht!P>x2lgnZ^r%4dwvO@xB~1=4oc8%jPawjM|7apW`OVpt;I z)=$URFi+(V+?cl%=s_?Q*qU+|vJh}btOkAud9Zt-*Vn^dy-3wo zWo>>GKI`Yjv;wgbr?#mhcQpGt)tZCa zy9y^{-72Jl!kplnfS03xJjz4aoK&0^F*u6(R*Q58JQsSj*rhh2L0$acZbTa?=Rdz< zHU3Cw<%xEodFyFS7q1-L+D+Vv#^8gs?2HpUhQoIfo@_PmJ@l7uM{}s{gWDkQU~Yv9 zV5#Hqs8;;703~p#CrYf&`aR0X9^u3W!n$Bmt3_abcLgtvq9edwWqtZn+y0hwn*Ob) z)Y(J$U#PqHlrBT6S{}W2%6uO}ALmXYH-y0EwS!`nc-7S1{lA~OGEN=59PWp{aq4b; z0aJIfOr0EHtd+OpN8&p#|!hwo)#FcQ=g zT%Y*%L}f-x*S9Bv2jA)X_C#p*w({ZifqC`n0~Gq~R_a7W`s}f8d_p1^3#9R5^ZdSr zxh<%L8bYA(=B7}Frmx!My8PD7`bf#tLaiaAKR*71^C2mGI3D00^acIJ`5&u3_CY|? z&8!>~mm<)d8ae%>$SxUq)&mGha>r(-wR^!LHh77?%~`*?PksFlw~r@ojgd!U$TUVC z#RdB%ard=KV7f7Kul%N=KID9+a-LO}FVy8rb>aIcVylZwz3>j6nzJ6nFS_Bfevghg zJ6I6vl@&$0HR@-WwuQFm_mJGw9!!Y6+pQ@qYK)x4BB!&+BsB`-j7lVNW9RkVD;vd< z`$4+n-@$k9x>wduRdzay>|_xh&z*}W^NfSwaT{nlZ_dg`0=voi_u@PQ)B(P9X+X~B z!67r@3!S1;zx+FX71g%*q$|b6W%vtq_k(=FBqd2?Xa355mGs%(2rBCiCPJl z73>7X(UC6#%UoK`+XN8!z7LjzMj{@y!vB&)?DD~PEfAceYy@xePPwYa;g;*+w!{G? zvv6(+wc#)}0prHRE?7cQ`Ml&@4!9?*j3)pGu&TZg&~48L=c5uZbsAlmgadW4YOBa{(xmoOh9ijNEvjLY-xaKfTSdd06$w4%^;D1`4bAx%VR zQ2S!g2L3ZW>BuXpKW8^SG>tQ^CEv+oKHxJqI`WVA34E@B>4Q$3H3W${axGE?LI}Cgp_0DHHR1vXnnT+G2B6*5jbH!uw%uZXR2hjgfF?U3U=x zqK2FwkZSIlEiXFmh2);|N~9`&(aU3SCEGMtFT#*1$}J*B%y}qe<^|2~7FL?$urXyZ zuw$H9LUM4vN*=5sDuMSX?G`%;N(4)O#A+hhLBrq;Yv9&}(ayp_T%J`*x^KzyN) z29Pm)ru7%70{%$HGYNk+p1a(V7vt$!%A#Fv$=BoO(JiTqTM`&;dp<)U0+kWZK=3{| zL8!j~4Ab!HIjjzg8dEV84C4}Xo;2Ytq^pr9_$Loe1}jyHE<`us_dWaHm;D!$M#>QW zg}R&}^dWV)q}vc~M{chn%-|6G&Jc9l!*OB=aH|g1&%vO=BLs=Ok{t2bp7T%(POl1| z6z!ZM<}qcet9U(rvRHfKIg*+>^u1?yANm!is-eG!^b-$VP=Mo?^TTlHm-#wK;&k}^ z@hUzwIkDVqRp%Pi@$Vz!82o0vT91 z=dK4?by*LhxZL6UZ^wKCu|8^+60Aq{7x>Q8%r3<{lARJu%>u+{)xbqv4ZL<%0v6q3 zucdrq{C@I-MLe$yeXK^+5@$q;3xWz}#7J*t5=Qtlw}ubY54N4YH~L;)WLU}2W!Yjx zjKj4zArI$VqCwbMsip!rLb$Dy?uXR6HzL6=+<%ECfQe4ri?W4ox9&j(5%*kFAlZp^ zn}`|dsb65cK(JF`t&(puIUlFuStJYg!E%CwqRQIT_o>8w?R=jq<@E0Ey2RhTXcvUv zXZ_|rD4`kHNH2a6BU@2@SlChzV#0w0gix0feFxs^+I*i-qNgAgRR37}>C4$5;XrUC z!-QetbY@-flcE5qePVxx7l*DxPXZ&$R;%KMRYyU*R@|MfR>ycbCzNM|j>Zf)WF~ns zDUS$+J=2Z3!MS(=0vIQgKEr+(5I=z9*pR)8CzI~;a5Ah9tNAsL{vS^7t7oD) zncmH7IK2{MyQ~0T_{DCJ6&Uw;+E)Xysx;fP0c8P<9J@cag=B5Sf&(l$kYjxy33J;E z8D^o4uEGgq7>Cp@WaxHk+ZAlm4xbFeZ1o_(9+Z6ulBl^QR!dJD=>ab}uSab2Ton9@ z7tXTBHwBD&mdV4G_Cf7+Rz;65d9`)f+} z)%%QP-jK1V&AOV#7!U+^U?VXYpIXOqx$*&ScIeb&*FYXy1|l>WDo!Q-mbC?&u@wxj z(2u`bBvBq$({h5CsB_VG@v;wsfNR5v^>(?5$gRp2lB4OZY@B|1KFTrhEeTKcKI`3D zf=)T`Tg6ko&)SJJ1-M?(KF>m4!v2MO!mz2@%h_rLsD8y$u)$dmvdp@o zJAw^3=LH^Lb zxL+)-a0(~RS;D5t?u_(ybcB%6ts9~a=9(9gd=@K43UR|>q)bqs{VGl}(kiO}ZzVtb z9=!_kbj7!>z#iH;G=D!{4)N}jtE-2zJjY9oNt zLE?3I)j{IRM0y0vv^`HC6>ogLgaZ)~2=X=2cc2_74LT%1)66U_4FTc?-j7A_4d-_EaR<=Wat6>~nX>?@sw`mES$``?CDLD!*;= z`!D=GG$R<{nxIRWMI)Xvmv$umO8e(i-)Kt$FSDW%9lD?OF1A(ytcBha9$B zXQAhi)Dilz-FiD05WvHSbnSSS^(mAM?H>eCVPg=R z{c&x_PF(nW>aqVo9`m6%c9)a9;-3bm#?cG=vCHlO)KvrLZVO(tJgD)$wl&a9{Qpdg zj_kVW5c;hQV45_@Vtu)_iU$E^>|#7~C-H2=aJh zBl1sE`Td!{FNc->7L}%>djBQ%ecP@1Zrs(_k*lpb+|dFEb3QCNaC~f(ZgM~77V(z? z+i)IP$jtpI<~U&QwzHb<`G49w7w{;nYwzy~Ghqn10Ra;(GSMJG0Yiw2$R&|P2OBg( zP`plt%!G_2lW}GOiB$=r76{Zxu~Mr&QLsR(mEsMpZG&Q^R=-B86|JpvT8khVvxmozyy^FX-w#tk zd6USkmftX+CgAr7Lu!7yDRXRiDlGb3$Esrk8jHI_oNNg(Isu=L>OT3!uSGUiSOtf& zOj&-%S=KmO^bRFY{gb%rR{-Q>sGMxjUa0icXX&Y3b2%Hw9OQkuo$H8us7)L`Z~X&% zfwFioDgov1IdB_MmvU#eJ+HNdsrmDBTVIOPguA!$v=w9Vf-=tPw!Tra>TgHOTYp<} zMA^$*Uy2SZX)SintFEwf--zFquHIXI@=J58pShqli%HO&%vLu$@pGIVu{opiA=RDIGb+7Vg6U02u)lVJ@kMG#K*OamP?~s{VhkJ^cx9Dchy6E=n zk!)pVxqcoaQq1L^ig{{TrhDpc_Y*{f2Tdnqnc5SSJEN5E8542Y^!4&_prz3mb^tHx^3+X^Uk zOJ_S~&SJvVw5;EZVm1kF!QHMOc2GhyZoL!RLSXqAB(;1InoaJ8ibhdlI zOBs)saJV(KrF?zr^X@fSd2`QsDVp7SL2CIqyTd7bT7AIo@^d=EbeK=)A9_nZxcIW3 zPphuWQ#VMRNugdQLzA>>nr+;>Tl;$aIkI-@%jC=8oBz}}kc&D)rQ4LA*pO+NIS`Io z`+C%V^UIB?@e5^A@Vof=5HrD2$JRS?5qoCUxFI5~9r<%EbgzFPub3f#_pu#hO6%)J zZ+@dbowT?9?!^gD5CIjJg|PhM#JsMOU7e_oUjbXJ+_OR0-FiK^kI>{`Su##u2U%TgQF8BH|hfWdSGxtLd@y*Wx zl73z&+{_%Jsf|~-SEb##l>8dkHJhJ;f6lQ2i)!Jw**cPKDw;pDDmh6-b7zKx zjCAbyji43!sj>FdiBR?{*Bk=H$-fPXq?8Tbjo+*B@|>gV8ht8Ix+d)(7&D&ydsfD(+eOiu zw0$ssk&JoGn3r_7QITdOMn@v3w{^OA|JCIl-03EPE}4|LPI_kgGmV$FIyNJ{YOnJ- z#|8{i-PbtUFqIs6#uc5mYOm`#M>AFm8;9kXb|KYSdh))~bN2DhTQudxX2crPR;4Y% zwRp{#3n5a-`7&>pyZo#6WO~^4INMQ<3qywt{n~SE+;yxuj*T0w{hzG;FVOxMYX6J0 z|7U9dr)mGg+JB$+|1aAAPVIjZb@kY|!L~emU+I93(p%=(ql{#~pT|sz%lEA>#t&;POPd;Z4`A%}nTw=j z<33E0_ek?O8t`i&@y+MvMEnPZLzQ*RSR55>0b=_5pQ~^!cW};6T@fn!OnJ z19^)yvn*#0#4Y?(3%}FCKYVGA{4V%rRM4;Kd&T0u$>Q%R3%><^@j^ypYU@EJVXIwgbqmcRKW$aahWzkV{%QY2zQDb5_iB=IYIZ`cAhK#4>)bT<#pi;KQ@I~R&f)=)=CX! zAdyyHzCLXZ-*YH$Eeo|SWRgCwDt_A$T~h(MMi82hslQ!0jn>_fv2l0nZun*d{{^~l zg!Fw%y=~B=22GJKB=L+i=&1%h)1ajWU1ZRpL2oqZtp;s3=pzPw-k^Um=wX98Ws`+x zv_U5tbcR9Q2ED|fK7$4gdXquFZ_q6U{gpvqG3Z|ndf1@$96j6<4LZ%B6$VW|S$EGj z=nR7{GUzgct~Kb74ccMQKN|E?`Q<3f^OXFcBhTjsEgYrWe`L^@K~K^?bD)&ZpxX?3 z(4eP`(f!pJbelonHRxoyD$BFXpuaL`>R6p$ZqU07+G)@xBVN-D`cET29y91hgN6;N z1;W3BMtUc^bp85ojVpDzVGkShdV_8>=#LEgh(Vt>=wU;jsXyD`oAx%jYQeL|pp^#A zHmE7*GVGbX_;p6Pj4`*I}KWC_^UJQR~z&ZgHAT+v|iF~!zC4S z%2=8t+C6iF0j4>9H|ZCW~8igdcykZT*F%Y_VD@E6_Q zo4?rWb9w9P8mhg~KtoWeeaDew8IbUp;V%p>4K^$fy8KPm{*bOhbJFyN!`^0B(7)VO z=MOH4)`~+U8V&@PxS|aWuDXWc62<7QCc2bL@kYoTQQ)fa2I~C2=`eZ1-ry3yF76F4 z@vD5DF~b#!`le40HrD&Yfoe}(pgs_d%&43-eR{pODSyHQb=6FzT#K$y72$@(b$))6 zFIeOEMgo|pyGlI)SHyp9qd!>fcLf`w=t4=fuGtj`R)PNw{-`U|5MUx6)a7bb3Hp6ni23=8mq%Q=GhG)hEH9tnI^`5sejrk!3y9OiGm9pWJk|6KRre@qLdi5q ziuO!&xm~4K1g~0mFLy#$wGW}^c>hUWR^?JMQ&;8fmkWpVdCg|>6kL&b^ zK{>OewU3UIb^5u%uQ2RMMtgD^G~J-FTwOlq(rK2#A8AmRLHE6>yZ3Hak_wr1v38oR z5$#_W<`!m~D^|#1jvhXbPdEl6 z8q?#`+kKM}zikHHVbEO$?J%hLOa0cAYN4`0+z1}|J9t$%J#H*?R2G;R2Y(co9ybeeOZqv)wvdh;guRJ)hAeXZ=@Ool zOMXmD`qPtY>H%rXM+bdgpGVvzF7jC8E%N<6B3oe5vzPKT!?OA>=#{^wE|Fbr@t?^T z%O&peSp8@B@^6MAa?*D4$sfj+K2PtuXx29owCe9&-$KVpN5~Ra(P52;)ETKC%+Zef zNZPtA?a=C9!W8|Cg~xp)zcVdm(Mdfs%S${-ovQ#HUlLCj;VdEy=7@csV#&i;A9goG z^l$2=TO74G^eQ9aOZqx3b3hcdfLp;Iz<+`+kTON7F<=$g0DcOd1^)#OgY-glfTzJr;2^M1RcaEL0WJrP z;AZe6@N@8=MM`}HJ_9G7q11eE1SFry7z-8xAGi_R4o;h{)J5PPa6i}qJ^=&IVLt<$ z3BCt5gY7`R@AEV8Ja`MpoWBL!3O)wOv&auH6>Kl&9u(*RDJ4pc0%w78u=`x{ZVqET z_zCy|q?amnDwqwnfk(iT;27YWAZj8g0r!Fj!NcGqkbIs}CxNrTM$is^3|<9qgQWA7 zIsuGvqaPH2MsO>*4?GTv=CZ8~E&%s{pMmGWTcG#?r7FSY;HThE;2q%n7COOxFq;+U z;CWPp`RHAs)c3*N;BVmaO47KHud9JQ;20Qk3Hb!3gL&XJ@HcP(jJZ^)1)vq&2_6K$ z0xyEUgHOS%McBc9a1cZ;=S>u70~cMTR28TJFMvOTPeA(BO6654^`4h8XE87Q!9;K! zcpH2MY}HEDf+)BS+zqyax4}ms!$)3&i~LG?0n0-IB0XRdI2Zg0d;~rNr!P@z4ww(> zzzXmr_zidgjIX7RfeKI!{tj#b>K~W|762b;0e66hui?!EcoB?UN?C$(-~|)vl{y2Q z1NhB)btkw7oXQ&eY_I^-fM0{(ftSFiU{Hfn@{{Xlf)~L-&;{~B_yZS!8t`rK0{GLl z%+tU>!P#NlK@Ipem=h(fpb7jKd;~@}k}seUtOM=fDd1YB)SI9Sq%J28P1HkhBiIZ+ z0JC_XeigVKJP4i!w(HOZCViXs05*fWuBVOMKs^K-ZlqqVQ0g*}x)M2149)`=t|G3W z4qWtIr5*#F;Ey1qjr;=_gBtL6@C6ufJNXO3;JaWmcpu2s^7Y_*;C+zvJ^CCl6|4lK zHY!yJrhz)p0&WA_!Bb$=9h5(q1cKlOa3}Z)IP3f5BUl7(16#nO;3e=jn6QaF1#Yk! z+yQvFN z1MUKkf!~4gKPPN(Huyf+3Z4P`z|}jIx(0;6>);?rewh3O`@nv15M)1s9#8@*!SY8L zYrq=tEche%01SMLxPyDZX7Doj8#o5C9#?AEFDV1C1vLK}Gw?i3`8-1&g3Zs;UxN=o z)ns(7f$pMSr788wZwOP7mfun@q4O7%E{LD;txdOm`^Izs$YvUqL~24Sm~Q>`t-Ina{D2IVB>~naI0bc>5A~b2YhG zB2SZxC-5pXxvoT>CU-P}SET$AZ&kIZ3qA~Jf zU^j1BLtV6b$undK?pYm+Nt~@+x&Xb;#nk zQkQeW+cu1Fn)EpC_$U2{&9vuH5R3uJrhG%;`E{9%Lv5-ZzEL)XB2zTXrtLWxys5%- z!?ToOk?`c5(kawiL+(uBDb@-S&}1W0^f*})A)I{4DyHo9|UM|S9hsu2alD+*}0 zKJq@lo_|fio-R#batHtH^OEehkY3wRry5$BqJ|a?QbP;VyHZ1gt8yJl%CX<63Qk}Q z1}%8aB>{9n(JH5?ROQ&FtD#+) zvGmT=j+D@#DrW`dMLaX#p5;#+=Iz!IXd+o}d)L};< z|CKGvsj{MW=12onN+tPF#QJ)~AT=WDP$PVHHKKBW8c~#_M#RXw6I0cR(ZT9OUy3@h za*#TavOBSGWLI`1k3}nvg5h|5j3CliF%}B~I z>YT{z!l~+);(n&e8Q~;9($t9gTB&wO{Slcrah`TSWZq@)0jVjmQ|X4Lx6A*6X*Y`I z$?`ABZck1@AZbX;Q4)EBBmIx6B57OlJNELF{L})<)|NuMC`_)fIqk~Xl^nBoCKcq4 zb*iy@oN8orpc?8+R*p)C>YB*=;z?v1+N8c(?Rq;JD0=kzO($9P0CQPTYse?qr41m{ z{!`{Tz?8AtZTaaczt*90eZy65WtPe<8m4l0j_Dc|%jrC!V|d6mHdT$~fa+M>#};L& zu`g$LjfiD+4(-USu#HJoW1_><7&^T%l|$5+qD(brXHM4%vEd!I6RA&hJefr!ROZX6 zT`4hVXkZoTA3GR*Bhi(k#@dFeVO>LF8J%ezgK0y#&LrjZWvi-%{2=Nj= zxAL_dfAm?k{x zL2tY0==OuVRj*c0XdBYs>iUvZ!EEM~pv};iVAsM-RxKs034keMwc9f2PohIq#!hEN zZhEpxC*DrdV<)bib)4`5`wiVzyDc?YrBZKFU)IZCE93pcRMnl7?&DR6w}Q_|o>LDreV6n$a>U+T$W%I1fxWk9FMimq22%CRR|<2AyM8}SestKI5P z8>2YTmQ^`eWfi5UtZ-(?mPvmRb&@W|!NSy-S$Es!QwG5Oq2vqgpFTg4N1e6E*rfcz z_5!WVQD-_Xrfz~Z@t?vxgoADl-(cE(FE^D;#YrV2`*UO6WYJ@U5z3vAtR|3-6w+ZQ z9mNaq4i0N^WtgzoZ9hm;KRE1E8}|%R>wKANMP-H>eAB>~qf@VsHg4t&(aX2WQDCpg zm9b(^ma@~wh8EE_f%~xJ0sRhq)rZfT!6K*k&-BZLHHNUp&|b!DF#2b${R~!Vg@Zbn zX;kFOczQTRrR*O>-Z)i^#nQPqGr!itqaG*N$tPqLvZ|M?ZDb1LS(+M2o{S_#E6YqRV_k`~6e1UqR%PW6&A=8~b@bh}EYemJND9q341i|9wX zo+%ZyAI2zLj`}Ze^_u-ZA2lXqWLSQASHkILSy0 zb&)&@wK7J7f+Kob677-}>Sb>^X^-Ubd-ywH9rGFSD?G+Dv7Z8(41K-rRzKRDBy99a zn$A>J^&R#jL5JZ#(N3BeGZT2yXCF@2!u~7%QYh0d!*7CJ%Fn0=os^x8xSRQJwc9Rp zs>>=<=!a4n*9WVN@ZgYbm{Sd-pB%O`qbn^oxN}g*S(Q83t_JTJM%x>zI@;NX0JR?* z^}%AdaoBdWFH4QC9HvGiJ9=mLJSJpIbEvfY26YYWa8%i4T!<#CXmqHWvOh)H8NXY; zOWy%H482ynEjvYJ`_ff5V^22yYj!xRYiNwVOk4BNFKkE-<%~st(Q1`uyHzEJ7}K9p z%0-cCYoNtOnGt5&R`zzlw4(;E$f?;MgI8?we1nwOKLwS-qy6-@i;iwTxLfsVVLpw& zF?Ov#a5ARv*v8TXJRtg9$;!1qmHB8Ubt^;TCvT@8(840pxGCI3zK1V$yf;tU&k*Wt zdZK>mzk7#C9IbKC%Ht-jJVIJ|$lPhaQ|(}HtOHbhLOhM}&rzAK@h1NV^d)p%Rjxh5l`ER1T)tt-MO|>cto4Z%`dG<$=^MycnXHBvGFEEkNWU0n?W*;eLsi;N z;>PMsnOKA^TqA3w^ewVSN{8MKQL z%FaAH^f1djP+<7A+HE;0Du@0xhjx)e+s~m-$O#XR+0tz){aoslw1+TroDjN~*wqs1 zqZp9C57S#|MgWz`r>QJM4ynY7c)aB5Y~ zr~zt_tzF3+OX_+TRY4nHqU;MWwn~3jP|R2cCLYrB$7S^ZJ3fWvZW1BX@5=bv{w+$NXDeY zscHoMyZDjntQS%Slco&>w(JLz&wCtrZs?^*47eIuXDxjS{S^DLJ9)7Y>5T;e9>)SJg# z%pzkeO;M$LQq&CA^XZg{F=wX#Ojg4_pzd}u1FlM{$mK5BaOy^8G($OyPEajpFwX+p zv~U>XaZ|XdK5ndsEVBBTKZG$qlQBPoF+W|6+&Lnq&F3iZOv;;j5gKId{ha$7>M8B? z#mT&51Y$Pn5N*CXD4`9CJgHVyPbl?!AbYs-6h6s30+{w8T3glkp2QE;PA$j%```k@ zPaWo;fojA4IOeA*7IMl5y`k|~s#*^U= z`lKh-aN91GEHc{u2XnR}hsqc_I3)QY`6!Q2y`LCFKfyi=dUDW{Q#d>(?()Rwn&s(a zAG7z91f$~^{TZ-6Y_qBgc=`RfiJZ7^!mU5Q;x3PzyO76xPo6D2mv9mvIa4B!Rj$gV zu@e57>4^7}4iS{I1M*n)R1DQv-TyK%$zG~FR=Kuba^ilpAGrb}FU8$_%y>C_<)P_r zhV!mNKl^eU4uVCL-bU(BCv7EjI%B|W+FA*9e;#vt&;oXV4$ui=pbMxAp%bx#Ow2A& z09wEf5Cftw^CIRFAOu=K8|VN9)Tt`a20B0&C}6!)1vELRtbb&kC2N}YN^}CX5Ic}P znyN+U1?mdSS7Qb(pbdy@CsbrJJ;cw8j>W{y2Onhmk*z@%wAT`T0NHD(Z=ec!;`dvQH=bc~uXh<7dPZRDsNg6oSMLbOF~+bUjSk9@S-J zu93`*y;H#~umA+W3UDWQ2s{Vg1RntBK${v1W`QffGO!NZ3w{Y+2S-4<)21eXGH?ZG z1h;{E!7st<;0Q>k@0$S1z!jho+y=ISr@%|#A0RcwrpAF%umD^GR)E{V{opC^f56|t zfWbDE1I_@YU?K2$EXw4Smk1ta*{e(<*9M%6g6Jus|o5CJDc$r$xJGEwYo%*)AUfrN>R4Y`ATB&YQtJKZv7Imxoj#{nOsI{t9tyAmO zcU6BccYSqr%Hs(|mrpJ9Eb&J@-8UjUTx?htsP;!Z)eSy>w@j!ZaTF4UNHQKYZ>zc!_8qEdg#X^e5lYpYr}i zoBEZ#&L3`2)jkO~80F4@XEC=;mM#xO{PIrRQxlq6sH(rrF%+%kQigAim+KmJUT$zy z2I~F3OTFBf>EmSOdc4tS*yHnayQ87m6xErOkD0BWV5pCq59jLINYoqk_i+mZYqb`M|R5yhB#(;QLFZKF-;l8@WMeb!Jx=8g& z{tKIs>3|LHef64Jle8x9BjeQSZqPskdR zx!h8LvW!wp_vwKvjJ zkQ%#p?betHVQHKQ7mR52X2djJR9aC&QZ;rTPQNJ^QO%*BWOuvuiN|phO#8MpH6P8q z+1iZs`q&+Py$drF<8QLm?&CCU*u<*3ksDV*OFM(zyT-!mr?Lt+SU)`~Q*BA_N zi_98RnDqa8hgC~=U3Xm9fY0jh8t#d8YhLPa_Q*XnOO^DzuaPAUfk;C*Vofvk zv!~wd?EyEw23}-7LM{z9Rm*n(n$xIrKN;!Pa}*#KFFsolthd?WY%k-Mbfo)lV-X+}^!N zBoqktDQ1nCkW!74P*fTx+N%v}%wA=|$wecL-I*b^qMGh$iQl7lQekUF)as0MND0hv zb8i-hAN8rOcX34gSjBZWqoT{4i}}>?-Sz&xue(Iu!@b>TW0={qWum65*Sp!{YB!vF zlxszz&CNsMKm(JwW)F8%Rex-H<8HQDZwwBl*q5UTH`e)CQfQO*=77J>ry~A(X7ddZ zzh*K!Vc{}PEc4bi>JC~-3zyjr;bI6i(5IOOPkm!uG!UxOg|*Vr25E7p0(6@x_dsx| z=1t>iX9`)!X^&67FVM+;L6)rT^e4r|S;Cjt&yrvNHlBmA>9DTvip@N*hBgRhgO^oLc*QFH8Bdp3gsAlXSj6TFy$PEF5M-K$SQaB-l?8 zd)YFXq^cL}^ZoRvhV4mg+By0K{(5hywjs=Z@Il9=tj5l32ruBH40ZmC7GJ|R6V$KO z9BqEAc`RYq+_9j}?+>ZCDLv2VGIjZgQZ9+r9Bly*<(mdF|5CYqd2@X#&%&+Lb{@FB z(T9hiYLJxZA{EAfq6QBjoL;;;9Sa&6_=7$}-5(^?e7VBZzQa*j$2T4r-j&)ZW>j3F zjSdfsjX-qU&&76L*zZ@io>1mA@PP@r;p6X#O*e0-{UX9O)BB;MVnH(tg!)Rx>ypTM zd}u>V>OhZ6X+XY8(GYGfQIFUpu=2p-us7VSc8QFrDq-tEvQOxp%O!#hR^cUJ}Uf2(Z%g=OVa3n$A~n>x`kyD?bpZCp}o z*=sB2a}&kImz8)fTy(kmZqjVeBK^}N9=}vZ({)ir*}0{~mvckWK06X>j0THm=Pl;5 zAJrcAiu~UC#f>$^r3+{0F-HnB#8Lqx#ihDu{r|;fB_*BX?g; zVq#fJEH8@GG!u+B7neeJL$hYF??yQPGc z?Z2U6u4owW-_bBnG+aPUsR;7rnC?>gn$=aZoO~;#tpB3d_;0L2YP?%(Gi%7pDP~@N z%?KUusYC}&~&O%ovgrM9oY|3Ynt;a}D8D(SCnSYGc9Hh<$hm`5x;7Z43KioU0& zu3`B%jfH4%qhO9>c2i^t>&AaYfpk12ddG8~==oPVFg+>V9oVB<4ZsaFF-@D^0aD6~FT=?nTowp71nadKa8ZIp1DO6Oc^G)HEH#97544ua$O+M>ZM)jlC{!Lsi3527( zg@Ev91DZ`K9sM!9x^p0d%0&J^TXph|Hx5kwjgtotJV#e8!;>m;q&y(qY5Uh zlHK#|e0MM0TtOvl2r~v$6Jyd$Kn(-tQrvn$Ehwj=yLsiPZb4V6e{tiICH}CfV}`V< zYH5Kp#Z=$0jH03~>5oapW;KgFN&Xp6W`X`4E|)>gFZRE9mFwjie(2sj8zee(e@@e@ zW)*(pCeAs(qFvK8-PGjSC6_Gr^43@?zdl*j-1?KNYgodR*D^CkvOhVqsZys|wFILU zwf)L>_hA;n{`6|`4D*dZ4^7UaPt;8>{mFOtNX5ndhHDwSsH9&qiDv?-<&T$j4ikIE z32oUR8P#973>v)4i}-t_`j?xX=b76OS8|F^vUqKNvUC`2Dd|yZ8p}!u19kW~`KK%sUuk|jo+;Qd_t=fo;&>O)v z%tCJgyD$rFHTXhrH~8()d&aOMgG@X0qp|GczC*sdILZeko>kEQFwE`Hw+wR(`bI8k zMLq_ddotf=!0gK7n+>OMr$x-r*MR7WLGK#Ry=M6B(0Tcs)BOi&gzlU`+A;GzM|BuT zzHx9!Z2(dDa_#mn;AYG*sQon3h&dC=w<1*sX6t=fxko#1GH0#d)#*aai!jT#A?^i| z&pV(8LH-x`g0>1#7F`fL!Y&}OV z=gY$&AHL8gFavW7^i80Z1=Mqnp10OB{nmQ{a`wM$2Kn@|0o&Y7GS z#+(T~eKz?={#fsr%H7iy;O;J+K7@G(<{i-7V#;6Sp>7~;MCf%T+=+!RbOk8J+yZR} zaz|C@v!DaB(7%FLFn2+>pKG*{Iee!CXmuFcP|7z}h-V1eP)6B(h#6XS9x{}j&_(A{ zzX+=e`hgqyj};Z0e7->Un+ZMdTf_yK3h1Nd#0RtWtiRj=aL%KSey-E2F=u0zGr7xv z#7EBEo>F0$q3@dJi#d7^6SgCD@Bu=sK_;vz*U0?@9{ISwMQ= z3(W_0n1#*)EtswM6Xo9Gno80LU+6}VeVBZPz67M6bL37<2U>nY&3oEHM=he<-qY!H z%vWL->H&3_t#=dK;Vrz3xS?O@e_oC|W}zQ|)tKcR@qEq<=VO*L#Lof=SI!YTJbM2i zXNkvn>1W=>4*lU`^64mXhRWIEH{r|q;(<)mq(6~!#>;B-GL^H&ch~ANa_0EG0QpQ< za`w3B8p`&4;snjB<2@OA8v%hiu+?78+>4A9YV?Gf2g+oKya3hd+c(*{kNbT8KED7D$GKM-bCJG7CH{JV3u>*Z>%D3KSDp$ zyq_xcZLo*36Z$ELVHSGFEtCsp>m5$H^Eu;I+7Wt$o(uM17J3%Dxrw=Z|=pQ1eqHSgwI z@88Qk{A=%~-$O>|EgRMhgt3_47x`zJGry4(lE=th5LU*9q%H4q2?V->pe@k zZ+TWbeFf@|(WhdY|=Pc;;PKq2|3wX12X@SyCgpcd*RESlJ~&PpHe@eV|VH@a>pd_F#Q93>wQ$Yr#kRa`Wg5_r-Can z%UzTUAJhF>@4m`C*_n@1=Lt)w+>=d3-g;lQco%av;QoU0gKhyb?(_Qx>NUf>51Rjk zo<^awo}_<6z8Ja(ti~+#qhF9-%txVTJf)A_awl~mko;K$eHf(vlRg9*2NIUhCx1zq z!hZ@n=~v_p{mCL|6OcKo(7a#MKmU_@4qXaFXC3r@!@LdprePNPzF|HL9o?bJ3!P$^ zi=Z1p1v-W9G5A9F8D^omyY+bHK_4>AJD~2T$rtr&XbtsQ%G_* zGw)rU${kGM3zhqqViqcQD8(#P?n2tpDfC(3#{9qQv9TvizLOP+@s>L^66(nm>F-*vOV6cZMBKm~-5O z;`ecQVi_k9miQyxj#lR~Z4aDem;0Cb>-a4Z{?8omjm!-$Ygp~`G%!$arEVM(kH@g+q`LW`{r$%cWmz1 zT(zZkOVgH?EvvV*ZP~P?eap5jJGSiI(z#{dmWr*5wpMMe-5T23w6$gH>aA^CH*Ia- zx^3%@t-H2%Y~8!HbL+mXv90l~U0aWCRok4~wr%U!ws%{__S)^C?M>TTwy)kU-vP`g uyn^;=?M?0N?R(pgw!7}FxHoj~-g~?5b=?=buk*gl&3&W!Z_fWr4*Xx}ugru1 diff --git a/bitsandbytes_windows/libbitsandbytes_cuda118.dll b/bitsandbytes_windows/libbitsandbytes_cuda118.dll new file mode 100644 index 0000000000000000000000000000000000000000..a54cc960b823cef30f139a3b3adc59e729fb7001 GIT binary patch literal 14026752 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

<`t%tGzF!>ph})s~Kmwc)i+=KUBWH_gKC?Azy8s zAznqZiPu|GzEE;+>^?|V*zbf2NO$YIQo0|aXi1lLjg!)S52BXR9Zn}K-3`!qc0^V2 zKVjbW=+Z^L7xru0uYgl2Mw-ubzUUQ^&^zqccGlv5rTJ=~QLng3^orr`7q(j@YhABfU!93pREzOuBSpX?a!1*NNP1HIFR2y}S^+GIIPYHV@dUn$2Q{kcYzb#?uwhuP`3t3|_W%bd8`n2~& z-?=44TdRBj1NpUPO7_2}qG-u)A|`&N{CJB__!{8)xb$bX|XQ(2xB}+EYmPA8aU|{ z{Hg|WD*eHevbK@nb98^O$?c+8j(PFbmsEi+2an!{Ls^NZ6oUu4vp4S4I~O)`A#Ce` z+k4|4ir{ejHFP_CP7*mj@JNUDsF?j9i%$QC#qy51)*ZBd!+ytQwmVi>cYJEy@j-H~D4ag%k&U#s2mxb2S4)*UmfJ07Wa$8EMdep)13 zzR9{{b+tRX+U{6w+(8YHH767ScMRL?8lZiUI0WN=+>CMKOzRoFL147}8ltted?QFr zdHl_~W14lxq-u8**zUO0x?`Pn$Fgd7jI`YmW8KjLy@OFJ7j+c2TK&a#N7-8vs}$>w zzf`;9B-G7kh(4F zv`pHUyKj?2U{LEhyq!8r?Y2xc?y1;~{E@VN*lSgX%Q5*WuT-q6@q7EQ-xq}cUhzWs zIrtsI)S%>t^9h(hljju=R-=digYRsuZN!p>#h9DdXP=I-Kie_+zHXs#7YKf>?EEXb zhV!eqApE?VYqQ5^6TZrYx4P5BV$;E2I7(jghlJwtE$Z|;=XMB-8fKnDYb)U&r>(oUOrUU2%y+P;c>J^pO=E46+_{`<2)_Y#Y90K=69J z!Rs0!m$8x2?F(E0b+X{jK+|qq`tz?d#Mp&v4Xv{gyKv1-fWH2Xf8mJdRunCmHey26 zTZGAEg2@jfk`d1VXt023(5VupsUYWFo-(L!&7{6HOPam3ADN%cLe?M$`#YJbo?zxi zY@1zxr)lp_!{1bGzfarZ?wCcNw)Shg@JZ_<4?ncGCW9O;6{AdSsD||1W~i_+3~`G= zKe9lTRm(6(FnWAZ9B$~exNM0Mka2Nd_(T7@hnch zy-h#bMkX{a;k+Br58+eW?uVZQL5Z@(gM%7O-BO~!&2#oo*%Iit1snbBm6uv6dm$!e z3q-DL(Gg-HV0Gv1qB}KZ46?6K_YC?v_1MI8d?*=;kEH|n&ICU7suKJjkd34Q0vTl( z6<`y}U@9OcQ~FaOL7$DOwu&H_mMD8Y#5$)M{^_-(J)T6*VrQE>tU24fWGU zEMUEX6-KW{TQPm9@B5du&M#23)NTMKpuI)d1e(-t6O>A-T`rw)n?8pGSx!~)r-GcV zvj7c(bt3aS3i0-X;$zLWgcUXe!oNZa#$<1^cC8k3c_Re4@(TR(qibyb9_RO0JEz%9 zsm~STkY$r++#k)d|Bm}_vY-33W#|IE2M%__@O2rom2M>zTPz>HwxU}&zlx6G=it}T z&JX9U?B^9#NHp2&gZ}9|_kd7U{B3}hu|#HO}XqX z_>IC_q%hsnmxJZR<@C|rDIf?;O3cN9{CONG;P`TAhJ-|&rDCmLfpL-v0(dN1>Y72s z%>;2e{3jFBQrOnwca?s3iQhfu?>&gw^9FG;2o9nQW=SYkieiHP?yI6f*%&#V^dx3V zpoJr$WBR!r5XEby+Lo&LVRTu;TDJJ7J42n~d*Pfqh=pJR6~xNAI}J7D1vAD_iKSwU z*Rm9kqaqij(;GZQqDh73FJDFmnd85pu1iX9`FU?rllsQ@@9LURBZ+I z`ACsc9L(8J_JIld;N4i4{s8v+^Uxi^R6GXr67u=w{QPn}A5Y>R_^I@KR01_I9&A)Y z&wZJFUB`%?J!&Uvd?DY#eP;(0EhqLwDLFBE)e=e)2g{RA?48x76Kmg6I~VzA}%D`!T{KeEoiweMIxw_@dYK0J^&cN zKyMPe%nUgYePD}41Rf`LsKU=zE~9l7{Lv&CX()j{Tj^U9CUZayT*01sS-XE;^b%v5 z029kab;SOONmz`dLY(NHXx=I5Oqkb>`LaLQj-mzSbqI*PMQ2i5g7NQTRe^*ui%y7% zz8U_)=nrBkeima6D-6-bVp~uQLA=(&H3P$n;5*^|68;p{ED^@I-|(MbU|#YF{<9=R zJ&IZt%KdXA*XRS5Cl@T>pS$8li(gfTifZSp?B^9qjr#Ns`@K{6?-lLC&+)vJF#4u7 zeh=eEizc$subTDl7W!MD5e8l6Ir#Nn5nlgU)y^-spI1DM5J|SS{>H=8Uu3-ukB66@ z0Y$u#e_@;MjiRN9#b~Fu=t7~0e}2p>5-qRwMN6Tw_?aWb zGrxqo$Y(xDCw%iyO{79~q=#xsFFbRfd(pV@cFpX>Gw>g692LIsDZ zLp~IY6ss0VVYT=I0j9U;K2eL??X`%LwYbl!#Xl(?Rf9@XZ01ay)BM5I-FVUgY*9@^ zbU1W6dgwON{|W{=Ut)O~svi(|_$j_X0-vDX=)AXmPxdIckFA3wDlalH(%$YT&pV6SX{E%qM@L z-5iGqt97b2Dj`+lZ$DLwu;5_aolD0w`Oe)tw7lX2B&wvV=7Pv))EGaNu_K6J{G_5S zV*Jzsk(MzK5#uKsO;BuMjh`|>Qf>S+A4C{G74Y*WC1!v^#raH}gPDp`oKaJ0K$MJA z49qAl6ay>~l+my#L?qC;9HL8SE*O2G>>(D&_|f$wx*vlt$cKs3>0+8eOrx(Jf|y5N z34%C$^tHmclSW^y1#uFJH0)!ASLWJAU#%fB#C-c9VEy?sVd(IWgD{pJ1khzaM^yA!|hMA@c zeGRI}@2X&tl?Z!Ptyxw4h$Ykrq%$d52E35lL0_C~A1Vs{!X$Q_AK0|^V{u4ApBwoJ zs&-fnX45Emn|=o#fB_dTpW@Wshx~vR^Z?>`i|1; zU!LO_@1^G+Pk7&S$uZ#FW>z%uetV{c_Z6(`j`X`1_TV^v{K@|0W5E068PUZ1I&d@f zdo?8K(4XvRcRb-eyvs4*eZ`Z}#C!V_7TyC`*B$Bi$a9V-y!T&x40x}e9!UY)I#}nT7Uvvz34|qJ9cprYu!utW%bw~O=?X2So?^PEb1KwXe8cn>Xf}5$| z%~{tS;oYvy@r3vN9ghL;2lAtdcN=gs@t)1P?g;M%t&b-p!{)6YrP*Vc~rt z>$)Snd!BJT;r-J2$AI_jU^MZ*0^CgfejAc>*k5jlKc4VzkL-iv@%)94L=*4TnuYgu ztm}^Sd+=$;6W%YKcMN#HJvEwm4*)k)zqdn@4)uHADaRAuU6Flotl!rKqKWqxQ!Kpi zU|m1DeitD>SV_4+t;zUSCf?mOWjvCDn<+V{Ov8j-K$(oh-eRQYFkhrB#nFu;X0nts zaKyemN;@1U<9Gp%(~#xcfb`oIe?Tcg@(q(&{gxv8HbV`hF2;P*JkWJPif<(nWF^Wx z&fqDph{FPLz(^VCJq1Y#Iv~A`CwBGr)as0Fz|Feg`yV0cZBG z+(_ACX7+YaCXd$(;-N-j4-ynlJ{zOcV=5F`wqMXtD}Z zUNou1b6yI~h2gn87ls)xo(qe^5mQY{Ya9!3Ou%tIj!8H!#1Ye8VtNe|VPbmCLj@0h zQmLS#JDq|a4;%d{m^@QLG!dD@Z{yOuWEQ_90^&5R*rQ>OpJROF0DoPp8_w_5MNj2_ab@Z@>W)F)6j98N@CfZ~dTdv;% zZV+Jxb+MnZIPoS3$!Wq05|?f6jOR0De`}NHKCEaE^9%pK%kzC?G91hEn}?z)&wqfM zDbJH9P&qPrz7G2=CyUXVv}vMKEmFnc&uAPY)iAnXF%ikni{{4G`@;ROQgcP^}E0c09{K8|MhqQ z5C_&1R#5xH6`teEzxilw0!NvI61gK)YjUVbHI&LY3P-I{4OH;vi9qQ9+KqB5p++bn z##R;(Cg;VnQ%Qw15)WQ8 zPR)nkh5scV-Y=KjZaTSLIAA~gA-VlP+gFhqfPwNN1RO^&g4W^%cCffU(74WySxxE#7Db?c2=-eDhnvOd7DD~}1xx>&IQVm#g$(=61#et_YH$6RaZ z;v9bM1Mm`lVes14huH8PA6swn?R)Am;QRIc(Zn|hZctyw_as*32=IM1F$>lU70wqb ze0Gchab7M|Udv<64z^tfB8pO6pu#c8Z`dfg?nQacaAgWQbuEv438b9~HKyRfg(C$I z&2TKlF%Cxr1{7q77$U*c>LgRElUb`l(}N07V#Py+3=~uT*=TH zv(e2-q-Vp>=xJqhW-1HDsm$Kd!i+UH*4Clz(No{99Arz{>wnwuiDJln26G5Ar{hAQJf>&IwVHM$T51BC&FmR1l>z zXue6Lgp#P>!4=K~sVHzJC=CV91W`&zB^pWzaV97e17;iGcUHzW}S&2njZ38GkvBKI?x3)6T)0ih_G(DE&f7e@wAa1F7?4x-_Drjt6v8=m0wE3Gfay(HXN8 zJXH|KYe3MGU{WD7HU-Tnvi~&t;D(!%py0#`~tc%(V3J} zXF`iC#LQj-ox1c3zzNDy0OmBm@I33z9Qq6b%`cEvRGVK2*Ow)G8}#Lm&=)`QIu7)u z&!A}O%K=O&+w>)y)hBX&dE`G0`tnEU%SFfoInbB$ZjP3|lne;d7atUn#;=k3mw~$* z^yQDxmyf=4q%Ys4M@wI3fRoL?oCZa7qAwTiY|xiKLSNq8??_*k-xw`@83s-^ec8k6 z6S;r+>9YoX`6KjY`aVbc@;Fuwi#Kt8YrNYXoNW5?CaX{F`Z6NXwmx{nCx)^p85*xo zvaR=~L=!^s5P?bQB?R4BNT-#fNa-|H;}zi;gJ5Z$T>ULpe1jAN8eXwoiDLnX4&q3o zBpzz{*@Y{2|M`#?oOkKNcq6ecK!48>xKPd`$-IK)z*ZQIqc| zurlTQ9m_g0`MS3?$Tw2?p8AzT`BwflYVv&?tW5cy+MCLe$+ydv2Kh!R-?P4ODBrl$ zsLA)=eoMaHdPOeZUYi=^8>xKH(;dn;`TD5I_rvQf`SyX@L~6eyKWvb1r1I_axkLG; zr9@4>->H^-M?q~OmG88T4f2gtzEACODBrAWqbA=|!OHA^ABWmRD&GYg8srI6thHe zD~g$-NOQ#*qFAcsVK7I$(s40CTnwoq3qpyE`QU;?1}8R<$Kb>U(ilA1%XtgTo{DK; zWF5qcArA_fl+sX9$f5$JNph%=Zkz4RkTbfJ*WgK6@GV1eCejipZbh*`6w6VZFN!*f z3q`S#Gar~Wj>|*Z5$zQT6+8#o734%HnUaUTl70#CEoPd9vM)goeqlPEW9}j7N)0;O z9CNZshwMt6G2hO63E*Zqhs@K?w4ne^H)E<9Ih2D)!}LYU3P}`m?uRC#jrnC{Z}NY2 zj=7ze6%xDOP|hvcoMVpT)Kk9%bB;L)`4~J&%rWClw^j;IN9W6YOoF}~Ek(|)oSKF? zW)G_;Hdu(kIW~Af^TJ;irTxZ@_w%dkr+-z0e*Q1%=c`D`9HV}Y|4X#=^E_~}>1P3} zYoz)az8>P$m8O0cK-+7qpAn`U7fgcA!(=E!Om=T%hz<8g?y)tl!fBPF7$=G$6q|`+ zp_WJMQ@{Wokn_fII2M4uHI6WUUR48EKq+Cd5;K_!9$bMh6^;?kR5(UX3d1qdsv35$ z={SaPo`EAgBl%Kti^7#=punzFxHxiT)tAwT1T*K3t1X;?tAxiQw`eV#QHeu2ngb7p z1v9*GhH}m2N60l>D`(&e;b42f!?l41IZ8xc`)7McOU?=%86IdYo)L-WW=CE;GetT! zm;S|-tT+XzJvp{vtVcB`6TC05GLdRtKm!{Cfqv*?s#Fwm{UD|~VWl^q$ z3*YMtq%MW`#>OqY{{t@V^96X1#V+u>w6_cPYUzhfRg~^YbsF11F4Xc)y#U(Q6VC<#+@vhbCOZLr61z48y~{v<~oy zK~l>B9;+^k79MwjlZnUItSAxTu@L%^2GOWmld5-3JUp5)bm8ywP>)PQ9O|cO)B_o0 zVkjs|6eS?ISITjmiKC8V0gjb8Qs{Az;)-MxFoY7ZM>8sTa3zikDhjQskcL766)5&d zq5=W~bJRpbFb);hz8<#iwwjNh#e3|1Qd*bD4OXvljf_l zpvd`9;9PL&Awmb{j(WCjw4MZ*E0os0$`&)#S$wtH$AI)Em$D31`nC_AhK02VA+qqi z5byfauM9&b)@qD-X+$Q*Munu+As$9atuE8&bz>=dD1NwrHGGcvI@p92BqdX;Eq%7h zuji5m`32hcUh7nT$|cd0-`=j4{Dwg<$SY-#c|{<<@ozWCFVMDVwNv@!B}Y$w7l0SM zDBIsW=!FycEiG)2U!d*IQm68JzjO5DHw?T?`R!#{Ms9yq_}--0@A3cV{_hY{77qKr zi=!vMc^6soyP%6R`|J5ugZu(*Q{HzfKc!Rj?G)5NR*QN10tw*O(F{MVt_?>1JQA$(A zP#z=Ug&4Bu<5-C!4dpR(=b=3K@K7EDcb<2Rqj5Ke%3|E!0|g$p(~zFW?KGrMCYm%9 zdQgFe^d2hMhV&t>5%T{$q%Xu7h*To74e3SNL98Sf$p>RdPkWKmkUn&zA$?l4A^oEF zoQm|4#4wRo$|1eA{9Fv_bqwi|RuDsajOLBy=SVEb<>w!r$0E(3A$?z{3W=1`3m6h+ znL~POJa3cd$X6TW$tjxZ^85yg4reBM+quz`XJhb!i)DFEf}TVy&$%x*$n%KuJpUc1 z@_Z~Idh)y!yi9q%$+C^mJ~zy_$x|l>X8GH4_HJ=O^1E;a8LGxhG~nV2Q6%4s;zATd zqBvh4eypuldJyf54^du(`N_SkU3 zJeA8nn7lIkSvX$gSIPaFUz$iWeY8IjHYXe|6H!JruK-nr`-R)Ze#!V21>A2b+;2W* zR5OuLokBa3=YTsgmMc+^QoXwf@;&lrM?pzy$% zc%~ zMFO z>zhpZc0DUn`SyCYLB0{m_Xi|qoXR)(j3~-?RuXlUoX+y+$1qk|TtdFF{kQ9ej;zvYtv?d&LIutt7qDWdb ziDD^=i0P;pLeW?%Nnv)JxJqHRu~c%t#;X%K%r_0r{lN~=NUK_;+TnJ2*)fO5j4}9NnTr? zi^>pGI3H>pIVjgVoytl=pJYSm%^QnhEQ80&#gPC1@3VytI!kw$4vy38{B5Bv9oVY&1{VX|aR83|LQua?clkyg0P z!?7uj3vhJfh!t@Bg<)DK*UmJ5te6867$SWWtpp=sd_j)BLELX186w<4>RhZXnuc4t zVDP)~6#%JBW4lrw7l#>qz@S~6P85g9bkG;O8AEJ*F&XUXGjE{719k-Pt+imkeVQ_Z zE$#rSkA-+5^SFUBk2`2F5guz~9{1@3zzSg%e@1tED}f&S#0e`1B6Bg3ZGCANe*0$B z2mBg2#Ba>WQNyndSef|EW@Vg{=m5V3Pu2(gb|OpVME|;<6gB*|x3usRy66bMkx$eI z{3gtEhTnk}QNwRGSeg1KbkPxhU8dIu{9Z>E&58akZXPxK27r}`pU_1|`0abFKH#?# zSt=*^jX5!D__YBm6F;Ggj__OXXnnx12w5N}_;trn0WnN8`rqwME&PNoI>K*cetp32 zM2GktI3a5I%?2w||Aa0&!mrD;`hef%&pFe-#Z97y-vF>O@e{h}2)}*7`hee=1QAQwE-&=KcS0`@LTXmeZcQlWYHY?zu2hZw>`$fPw1i}{6=c^0l!C|afaW4Mp46W zHdvYZCv?#feqE;42mJ1t;|#yW7@9_@{~Z8UCVoN}9pSfcN`1g@0#aU1>~~C+D_Z!q z0V@+fp^J|2TQIpk;P?7$XZUshC2II>|JlM%=%OS1Mm}60@OyNoGyD$x6gB*2gO#a& zLKhw3*Cnq$;I|D~G$;1E_{XT>Hvp_m{Ddw#!f)Ti`heew4)GgvIBNK{0V@+fp^J|2 zTk!Y#fL{f&Ku+|p`=O}exBZ}npU_1|_>G)UAMiW$xHJ3?9Ecizv%$*LKcS0`@avLW zAMoqw5WmGgL=C?IU}fSbbkPxh`yQ$f_??I>niKmS^WUi9*9NRi{Ddw#!f(O2`hee= z$f7yHulx5=!*Ba{7Jfn(9pN`}Y<<8l1z9vF_#OB*YWU3tD^vf3E;_=m%Y*d+zxK$Y zIl*u7{;1(M0IW>>gf2S5Z{Pj(0l#8oft=ts28)HFls{+#RwjNz7aifZAg4aycL-S^ zC-`;W7d8C0e`Db%bkPxhBgfPS{5m?s@4(kl!*4cNnffPm(Gh-K?yC>@9YPk!iT*AA zDr)!*04ozep^J|2+m~G*@aydmzcF7%4Zk*EW#T7v(Gh+NM%4%WCLoLEME|;f5jFg_ zS6KK7U37%s$b0Jpem6~WhTj3KQjJpoI~%M_{S&(A2){1()Cc@tLKe-5{w>}cHT(vE zm5HCwMMwDU8(AOl+lDNf6a2<}9yR>hfR%}#&_zf1Ex5Zr;P*PRKu+-M{-3Dfw|$R= zpU_1|_>H`)KH#@%yfgd`?2a0Kv%$*LKcS0`@ar<7KHzr;n(H1BjKk^qu1Y*$$0qOU>*x-d;fAfJ!vhn`gQoNrw1Fyd=#_MnNCLO*0HULSC z5@jB}+E${xA`T10LA(X0JSEQN(m^l6hB?R{;44FOjkn*F8DTHKE%>#U-|$fR^4lPA zGQsn6} zs>a_BL6`eY5}>2u>y-pRk_P4v4k? zpAC4+RW?L@>59!|UZ zN0m$mPXjmFS7ad^d=K8j6aGEf+`^Om`?bhlz>nt`{(CGRjV~kBwr%I3)hr%!+fL!$ zY1>Ze-qB6bhC#J?cXVdbyUzwQNQk|A8`j<-Nron=T9awLP5C4kk&WCxSIJ<5QF3rV7?4G}swtT`KvhM= zQ-(e}7wWwgM~Zl0Dje~!rI78wQbdGv(6k){L$trHv4?INECE|+VLPn=ebQJdK<}1I zhLBE?P7YZ@CTQb$16;C)xyT0qZ{8XU$FTisanA7#jsp#Q;kZcGOBis9cd&6*Y8mh6 zgUAPVhmFC4{X(?CEn5WkF{4mTZ0J)!@eP6=Z2p5v7#0!Ir+^zQB7x$aW^5gEcoQM) zpGBa`9eu3+%!YTnwBrl!3y?o>jCan;XyV-(+)TV@vbG-$?|kTYmeB77e>L$&cTkQ_ zAT0hjc7{gRf!M@||M3JWQT!hwda*@xp(xJB)rF#1fZ}{nq)|bEDCU!TXPKH0N6MoB zvJpI)ZG=Vv`8bcm5voRggaWmvE`oQh!w`UXtxG0OWJ5iu&;tbz6+9@YR4_*gvgE-2#-VoFX z3IUP+o~Q1;-PMtH@O|fxZ(b)qxV4_DQ>RXyI(2Gkeqh^&gYAVI5 zK#ZE=$f((^UxCuli^Uu@J4BDRdOlWKA4vW8t?$467wkTF%>SVO_O1JO_TPOd&Fa5S z8|Xi-{yT5TfBP@keIu+8zk2-jsrq;J-;T;?|6Ngi-2Hcp_rLvz-_slYKj^7W}vWg57V0 z)#F$9-@di~&i=a(rCI&g>8)drzto*r?N(zeQ~Ysz*5!jLnNH0tjSCvbh+%4IQpQWr zPlZCM*_C{&e=mgIcfDzZfsThQ-|iQkg?d7KAhr9SxQ@pDFBCDnKw2=}{GD$^oe7QX zTSU#NEfBx?ZJPeh!~X9FwFR|MgJIg)Y&hHK=sVX4!eD=w_Rf>|Vkv+B`=EG!bwpe1 z_rDcrb+9ZNYoTwc)g5Hk=~G(d~w^)_hG4Kt7w0o z)qZYikE$(rohYJN2hsk)M*GL3{qwI7?GFRtT4V&F)|wgH0`+Z(x}~<@Z8Hk{=6na1 zR1%xsC=TT0mN=;-Hoy_pqqg8hL642AEqdS)*+S9CXHe(|LHrPUXv9|kK^Kpu*agug+?2nnMX249f6Ha}tyDp4BK;D2=w0;UJ3(m$uD3qGD+wjAf zX3sGFST{Kxw=n-~uI4t=&4d(ju@HUt>rv<{B^x*5`K|diu`z7cS3EDR$9`v;m z^aB#~LJ9iZ(svO4eA=$oaWcw}l6L?EAQN&z7LSk)S^{ z{e#fXdZYy{SdPsDJ!e(Jm4lw;N4LZBj zpd3l2rd!Z}xlyWnoK*KU@5HP7Ll`qzBj?cB5_G8q{nUH$pqEO}cT3QBO3+VN#e*Iv zK|d%#FOr}$<8rD?f__+nw(wwo-x!xuKYcOU?xhm+VyW)4AB%_iQxp(g^Fp-UPf5@g z{YkY8BC@5mba-BZenEn^@F4Vo4e{!pEJ0UF(636E=fvgIED3st1YILRAC4o_a)rw$;aj&XJ(IO3)ol zKWUyASGF8}KHBaK2|8VZ&i`w?y5EqX&yb)kJXrT#FUNzvLxRqfpu0(RtB=Nmc1zG_ zNzkWA(3_r)2c2j^w;G`sa^1}Wp#0c7(hvG!v{}QJbLjfNMyYnLRQG98-9ulCSNB~K zbe05d(VtXX9Jk%71l>o1w&+jjPEW+EyPX7mu>@`5LFo6^$AjMTT(sRoCFlXBpU_>l z#Dl(Df-aVzhfB~6ug8NflAxzp(Cj@)UA6iMJ$D(i2tBo+5;C=u1YKc4Q|?N2FRhJN z_j}Jq+x>t9y-cl~{u1pT=L z-5^1y{4rkLpFb0AcN^Z1HYM_53Hs=gc+gKv(3ui+H`6c1_uzQYB@*;S67;ze^ruDf zpwE(^eG;@=g8qC^Jm|eoN83G4g1$n6?mILd^a~brE1Ak5SCV5;3WnSWIMzUgyf~u( zmY|Q`9S?e?1YIXV zzac@p=f{JdAwi4#&nB;Jm7t$k6c73$3Hpdsce4cjc||J4?_jCFtiQ=*efrgMR<V8_Pd*7Myps%u^ zE9UE*56KVBAXcclqIXp8=w#~RAw zVZKa){#1f~U#h!nT#M*65_IyH1|F=tMS|{D8n5mQ3A&2}-OltA^N**+gZ}cdXuESH z=(8ng*Q9vR%O&W+67(e!^rsPxi&LZ3f0U^=O3;%e=wb=_^SBo9vnA*|B@6%zD93EIMgG;fEk6*BVAcUz`N(0&QJM5_DjZtYwB4&D=;x)nD>ui3US&Z?M<_;Hr3p*x+^eRa*0~w2taCFhXuy0V z)m<;uogCLHd9eijjRgIv1YHw%HFtDrwB5F^3_r)%_Y$-k*J@EIL3fg%+n9dQ-_`M` zcBcfLAwj20(2Gc`V{%Kr1l?DHK1+hWduKf8HWqZW$Bb&^!HE7io23cs+-dZMoU=ZF zOs#t)N;UCb5}-)6p;F!V{XJgY3nl1DCIq32CFsr{$Ak7s(05DFcS_J*K8gq3L4sZ( zK|duyr+*j^y8hv4yEjSDZ%NRbdc=diPlA3`f?h5`pM6R^=;0FdqZ0Ie67-|n;z4(j zpqEL|OC;#ZxOT;chobF%LV|ukf=*0`SNFpb^im0Wu>?Il%w6nbNyRY|v{fIuWuXN9 z^iT1iPm!Rl`UqViL9dF7`R)g!?Y8P8^c@oPp2T?VenNt_>Lc_F3A$TyJm_mJ=vE^X zgYp)$09xlJ(2w=Vk4Iyyb7xr4$Zplgx~=g>$y9toyt?&2McX~atc=hTCCp!L8xQ(9 z3EHZU(DL|BZW9lBk_2tlM`%mV5c4kW;z6G)L0k0^dbotS+CCn1^8?X#TlEoImTNOp z;z7SGL0k2?*?Y%WLZZ;~iIUJ$=O;m?`Xy+qKGr=z!u)7$yt?~J&{-w~p{;p^R9g{u zE@`!jlsiOcaW!7;K zxl5{Jodoe*6ylFjhy|@67D*5@q7eU#LcHG!VvGbaFbZ*=9>FRDUKy+25=7@H#O)?T zBr8b+!d*vjF&2MVgTsHH-WO^4=4c(2t?Jl}tQK`wL?M3H7{RIoypgKV9}i0qcSIqs zk3x)T1#yD};fq4N7KM1O6-15%(KQN@v?qd9ODl-B5`=zlq~(`KAqK)Lx8wcQ(Uz}_ zLOd3QSkemOAqk=)3h|F9#Ew=F*GLdo07BKq;6{C5ebM;H;Zd9*#W}f5Fr%9culX|E zVdpj2`!x@jM$>c5^qjDBKx}$&3=W*~ys31b`mx_x=L-kneBmegd?-jfC)6F1gbxsX zh3iD}{c`w6$oI>Uy^zNu-v-#FI8?a}hcgdn;&^U>I9ys=@GkL*Tqb_o2vr-7IE|`b zx!5{yh-0UPXYvr`+c{rd#y5P%D^&GnVgz3_*v=YZskLN9>bI`)*TTFrge2eKTc2a1> zL9M`eiwOo><6tf-;+I~)+@Qh#mS5fp2^xs^84AIL|C(QTS{2jdZTP=)zmn#h4)Lw@ z@@KdZ`2Eb+P(XICnj zXgfqz*7$15Cl&L{H$=5c4JN4CCjF!~q-wo4q&oCn9b|DO?)Tvo{3M=-MgKuOkL$W%r(x2QMb~`|YHxm(2sFk7+hymsj zA_AT?A8tju7|JS~cfg<7>&5MhDJg)@@0(H$8=^>{CIRltACU7tLb!AtH{9W1NsN<>no!wSy|40 zWe%jYS3Bs#jEl^QFEjv!CaS@?l-=swDiw}5x6Y4R(+YvHulG7{RZEh-5c-$^S$NhCjDU)6w80A);4=b z{(>1P@W4q$%g`3yA=OV=WV5Yyfe`wcVno%mhb{p#EZ&O-2NQk4nGXCeo3AvfjJMUfhu71q5jZ9reEe- zLsrt)8lh5s6FfEZS0N6m_teA5{u;$_9#?~HeWBOWP*m_m=$$Nma+A$AG5BI7Lhc1G zu482I#X8~KfJG7NOHzX#2XekA3h*Mbtv7hCH#pg$KRyE4H5IhkNXAAs4gbi>eEtC+ zH(9VquoqjX>Q58P0Qf7R3@x3MQKa9An2Jh&JCReLiI8B(=QGNI1cw3&nuLq%+6V3h zlfW4$&^0mme8vJK3zjX_pKE8cy~Tmy%WWpx0EZ&rkf{bsFmT2>yul9M;7DM(%il|@ zX;!N8#Ng@9wrQKgX+~TM2h<5>9N-}+G6`~~1ah(kf}qyd&3sZZ0o{#W zLa*PHjvmJdpM~E4%rg%1rk_o@zcQjCsaitBPp!z1N1ij)+^T7rs#d3Kq#5KMc(Wr$ z&6#Ro_ii<)V)U%ftPVRr`V0B~t~^Ufk)OaykWYqa3hZ^MT0ftL!RSr%YP#Bcn@>Be zRvk+6r#AY@r^ASm-L z01^eU+6PQfwH7s$(%=ma#i;7`HB0va2asR~Y(!0C!p>&wh(ZAS!C2ZhuQtu0_CBaq z9ZgbmzX7d6-F`4(^v40<)$VW%4t35|dw+x6R*6lB>$btlcN_9iIHEi-qZ&%iWxuNe zo4|UPF-Y~*7|9WZ6%r|?zgl%4&}%)E*#kJ*CjRDlwHBYYPu0Hj`kM!0>zjL z-NQzX@(lNkFz0RRj+nGjtq;5knN^}{9aZfUwfBdr28jmtuWCv5zG3#C;>}&JRNRCa z&lhqh@LF6k$CcW96Gl`rN6q#O~1N)WB!WzR=l8-q2W#+%bH3VN6C&LH4e~;8>e4_ZxpF74tmaUhoA^QC1Fgcoq~m zJT(Ol)Q`?A)J8$forLk^%{{El(?JGba7ji3y8&*waEHVCj{v2nFZikuRBCXM&;op> zdQzy>c(sogdvkaAa|?s%zT9jcVPF1kON0S27B~s0Z4p0Ug&= z$zsLS1zNh)+|B+GBykjy}UI)v4!14O6xR<%VU`gl4Q$^q22s{Z6@6B!T z_w@yTr{-?+Lnc6V0n_wQRt|D3@HlFqR*3Ney9#Pz0cxNYeTf>H)-kG*Q9}OYe(b-@ z9F-mplhIZyjiHH|3USBPL?O+p)0&HXE$Zgc)bGie!CwfMjTZ=3?AWN>Xd{+yul# zl|$hIO)x;7Z6rXlO zI#qFup?9ZWAzzht)(fE_Zugt z4Gmp22dE2zezX4NT;O?H*xBjN>`tr({(*IUw7_i$8HEKeQMDQ$Fez3wK`qSLKKNWz zg}^Rj$SZp=5vyKp@o1IJ%1a&dm4ZrmtGCSWsI8MHbh5j}N{594n!TeS zdn0fSJ6+hjz!Dy-jd57$Zh<13W%GBXhBM8{5&ihH)5DHVYbLi|F7we>+jKe%b-3xR~R$cRAzxzvF6l zn||a(cGeg!*}z$TFi~K=+hSg@uuoeDl_h(J_h2)mu*sy-jA$@w6<58d9%PaAm{awq z!5v{|=_3{uqW}VbYp6l2!-{0j*##W1SeRS2K)_{U(kIPAqZ~jTScaY5sRuy*Oi+^n z5dM$=$^Fcj(7iJ-zXpf*JAws`BkZi>9+4P`*cTF6vDiY(YX_B*m1_shNQPq&RxDAW z16f*`Py1-ZNON+Z!4am}Z?&7&p9=Aks84$%qf(?a`m|Rw>fpti9fpi6@jzEvJ9xaE zJz8_&ys%Qihs8YyYA;phh2ZlBuZDU$t3GsxFj1_5)dBX0E30Y1Xy9tSpXWeLTV>vR zz|N8jiDjwTl}+s<_7E-6r`33%r&aAv^oE8e>p#FQ)RY9J&=)Ktxqw4qXM9GaDLtUo z!9`-F_cTC7#@!)6UYWwRb(ew|he=^TmSKvbTgc=c6Y=-Xm&YPeR#u$XnJ? ztIpSIJ;96TYt`Y+V9Yk*t>JA=f1%yTcwlOS3YwG%nk*7D;??hcw}X0f*OQ2p#^c6T z3muC~Ft`50Pqec-r|m=@5t01;Phg%p#H~Y*=|AkZf|nwT{$(WSXX*!$pq;6842G6u zWDx^V+FirhbM*|k^b;J6c3$L65UDPGC6?=3BxFhqWE!FK7~s<*<^O}_mqdauBa41z zBsia`gCoHiOwDC52AM;{BxGi{70CRpvxQ7AA`|`N_;8JYj!C-^tkxT`lowirW^YWi ztdM7V12fXolu;X%G_b>A6)zl+u^|TvwPvMP!3Rpm!q=xH6>2aS%#i1h+#i+sFuh{Y zP_T`Q1~m{)o0{%fl}3N?cC0tw=Mw??GKlx4JdPQ$aHx(f92$&;1ElaUa0zlAxe)9h z8k7J-@atmja62Rn)(&H#qoNSlrE57`LW>)*O@%C>>82%dN>4T9NmK)eF?kl$uDQsC zoU}44c?GXe40d+Z z@3&(@#(M=mn$7vzfs!}kEB%2SqB0`P8mC+Uu&>lG<(jqpjAs>k3zB$?UNH;fF%56Y zhF}J$E#Sn6aN+AT*CQMzB_}Gk*wY}#CaTIE8*8wgh6iX*swsFK2~$6GFt)x1Pg9`r zK+isKhcG|DMy}++XxIj$9TxKsfH1qRt`sf+{hF`zU}cLpCFL0or&?M zq``V`UuKr0)hHbYVjec0Xc&wP9Lg}QKQ+k%ypv^>-a^+@SBDBTdgW_e%&n69X@y1?|p;vm=> z%BJ=mSb!EJtZVTf1zd&I(p3(%>c=FSSFTotA_?)|L(OfNejR5wXgye5Ryp)aU>`9V zgpwh92f~`d<<5ARGVZ|Y>_c;5x*`Z9e@r4Vy-@Yb}@NSH@&1ud#v`bE=8 z$El@i@Rf4(fLFE|7HVgzp}%r&^lEcJ=64FUTheqFAwq?!VZb{)jqtBMh)i&n!4Wns z8e4`ohpGSng=tj5-ehV)_UFFf-Q?{n&`KiW@@w!2pcvt z0~^@P3~YekbjxNYVrXQWM5R|K-OykB)O-!Ai%|WATIL>RFceh9b!sT}ovnt25Q@7R zgjGs)aI8HvpQNi{>SMu&jtPII0nZnsTf?K+ml$2^p^Qbcu!i0(a!P7P zWCCb~Z}(%?*LW97lCg|{Z;8O`>;1>d)O!5B@eYwX#`vAbIzo1TJ=1@A{0jR`7Bb(0 z!fK#^Vm3&?;=+&#h#zIOg6nUXEL5y2dub?D>o8XIK4u~?NDbyi| zuiq%Nw_IqJ!6Xub5&9eWjXfrQy^Nw3%SFljmIb_w$_3M=6E(rHBpo+gz_}(?A6JN` z7RW`(Shd3Eoz2Ih*F#1jIf4YopclHt96zCB!e42?XU2nX)gBdv#A{Cnqo{u{i!~JG z_O#~TBb%7<82r0|3;2-zc~KB&zjZ|2nuAQ1mS-ZP69v7Bq4m!?1a8d6V?B5;n>6Pk z1dd>(BQ_O`odsF&6&{zq#qdCBg0ySA8zEzUx7M$)#M{@K^SkDCSo>amSP-UA&c8!Ab!UmG<~TPx zD5ohaPBc4)lPnQ{DOh+zcD~%r{xKrC-Zhkh&}xVZ)C^WMOfa2Qm|$|ZDfh1n7oiIV z<*>EoYb{cAG}sYzSZmQCG{mL1FK{yJqRNy_xn{x`^H7?@OZP{92;rU{aPa{Ol;s z6rR!}qKKF>h!tA>cW*iAh4r;LMnE~NxG@;LGxX0-B1#%_#G2yTfT-9JR%-)H3XzMy!#Dl>E@0jL8pHwDU86 zpsHN&Do_}*KyaxV?%5TJkXbk!qx=J&QiuTi^^u19N2;2~&CNXY0`_k6MynIj)THe& zXlZ#x^lN!JY7!mHG|&XMTT6j-pXO=dPL#JdR-^P{m)T3B#_iw<=7(h>2;Bql!YLA8 zml1Fq&gh^cFroCQ8XQtW%77?W1M?iH31R1r3xAG3aR029rQ?Y&+Q*CateZ*rA?f<1 z!ef7)$qTSGf5*zR=l;ubV0P~IlHFJEdlhT+;=EsMYu`4k~AUMPr_@4-l z%T&EH&@cysAvzknBE~=o_^hrWsjTrD9S7YU7c?1 z6%&m-p@qwP#j{cZVR^4OI?}L#dveTh*n;*qRO~vk2OAXV@wSDC!OYI z7YKs|i{^E+%^vVfQL6@bJI2UR=0l6avZPKQ&rS(Wb>qK^|3z#amtr}318M{>rW-Uz z;m0C(a4N>()fleaGCy82pmfqgtjorM777NK*-p!W8YT~yEn33jm@w^^ST!d19F2Bp zsef;iXj_vk*fgb1OK#WCz8TiPIVXawFVhSd6k&{p%xdV2FCt1Giuoka|4DemWw4~D zb}dK$Zp0{p|88b@2Xdq7EfXO@Z_0lckNqqYHGQXQI5_|T22BDs44Tc~5PMH*$k>C@ zAHRVl1Z%>=(Qk=JQE!{X3 zSo-!(gX_}(qpueLGS?pqA7i|oh>DHsGR^Al`lafkN)Zt4G^Wi{4#@_2W!<(o*x7(-dKextn~Mf$JQ98?bom^kE>6+Vgb4$jm5D;2sl~6DY*&h5 zQ5-SKQ5kU1#)?S*Z3sF@MO4$%Xa?;fh~efoYk}IaS?`4v-C`61vyT2?G5k?(jHQPw zJPbBEIJ`~xuhSN|{)wC3kdE8UP6`>mJ4p*{t9Ko#}zW|K3^=*WpOk+Kk5A}@3KkoFq)^L=GZqz4qfe#ASXi^_1 zuZ&K{@i>EZRwOi?6KF~DcSjr1G`~~0iOM`4YbQ3sLu~Y_aW-3@N|q&lr{=6;s(L zX9!&*PArsAq$zZp?Ac%EYd?5H(}eB1mt<#%p5~7(IHRZev0;pJ=NA?Rr(-7IHGrsr z;+Fx{z#HPwY@$+O7t|c@;ASq$NCO$L4}2*dpSHgV{v)dP51;mhPy0a_y7lc>k%b{y zD*dy;X3xDsHff`VhNdI*Dnhjb4H*|~Q#&v%38d6hu0)>D&|+gx_)EDtE;JEKgLliwgDXKzpjRh(_*Y!5&a0~D~yc_;&>QxH(h^kq@nmE za2#nvOIXr1Jb?%?*RLOsa&G5I9vGGPHf3PrpsbA=99Yr>Sq~W)xXocJgLh=9Acp=2 zAhn8m!2CgJt2hf{#xpkX!4uYYJvg`NHuA4N4t1|ay)cvFH05P!T7&;Otsaa%zV~+j z)%ZUuce{U>ejl>sHuwiyB~yXvkIA4|KS>~8=FSmwMOlx?`8XUJEJluWJrz01#gt<6 z?-4MKBaCj%A*TtO;rMDyBS#Ru1@8BBAul0jVYLDw!Y*ha^f&%Vha@%rNF~gc7QJ1q z$Zg!eF^#C4VxZJOm!iE;f1VYfJV)cfrf7NCSZlog1XeBnuncfCK7;jsBz(EUBPfcL zw8rioA~~h}qww&9nZIUk708<43k5OjfKRGQF<%wniWDq@oeH63z@&peoWr*@9vF_J zKDF$BTjS^Ovj{PtfR*nRVgV{W4t-Y4MGkF%1N}2Iq$Z%p20Q%iz!>|`Flg~G7*ryM zsy!lrKp|`|bj0RK8c%UjV}<&ky~7i}LWob8{{KgV!l(-)%`y!fT5zvev_YZQ+W>#6 z@ia$6Cq;+5pyrlgwL>+IL%6YV7;waNk_CNRNXrIB7?<4i8u-zo0fD!3Ko6mX2oKw3 zs^nEt_CM3FVLy(Wnb9g9Z7VdBXOT*ldYo?TAE@Gxd4}>zv)}A()VHH&g%o3SNU#<}E{PjmVLZ6Ih2pnUf;fSl?}~ z5m8`Cm$f6BzSyw$(qQ=!$}r>o(Bg-r>354#%QA9cD#jH%EC^isQ;1`$Vc*Y#+!+J8 zEe;H0KOdG}D9ZZGe^8^W(?31aAi`2WY!Pb&{Zd$$utQu+Cf5b32~Nu<+xK-M}R8>QFtC@z*> z<3t6q^ztLlnAuEvm4IG&;=rPUTOZ7~tU#}q&j1y4AGnXKGZAnm)lNu(*UF!zcQy0h z$^4Kfx24G!0{e(t1Qs>7Y$;z&Hn2qwZb#_r!nCNLk6N?_A%w@LmE~EYI&C$_hgL0Q zvr^Cy_%X5U3?V}wD-y%xVg_o2>`l<`MI6HE`Z9Rp3jfF;q0C)?oCc1N zMmYbCW7^O!aq%)ZRcz8UgBCC++=w5c5(h#mGIld2WN%=_TBDF~-q5h+RL!x427!n5 zq_spxDZ3dpI_zAI{Gp*Lb?63^pf?v0z6B)>6z#|Ln(1y;TV!0mf*9>9mhq#+9g{&Z zDLAl-1^$wZWyHi<Q%~wt|)e4p&|rzTW41tBxk?Q^59Ae?hHfB54#3F%GA=J&A>2 zZ9Y6BlQC|RR~4s@#f}y3cKEbPEdFqZN!&-vInMiNJYHj7M$3fsX~JTfYjm#pe|8gX zF;KF2eSp}p#opB-W3TKut{GC6QnhG$yinW5i!m@xU^>AP-Z*=Ebz^q3nA2P7vsfHz z`{r{Mc&IrHJuJA8(*cGFHvg4*i{MA8>3WOL5R3OQaS#*BZVahu`W-__Qz~`P?}Aw> z)@sOMgUw?jj7=rBGKkg7O7Opw16rt|6kg^8x*Vmd+MrTgA4bi`&QrlW6b7?I=B=&E znEfLxBz5|Hqzaa>^o^bRHCW>T&-S4rY&UJzpX8HJJoLtqr1!+DgcOpYQ{};m5-fW+ z4?xfy1Em`#mn7qKf8^)|XlYyBoTCDOL7bPbp~tNTuSR^guf)it3Zb^a-w; zg@wdssB0SK;q9p_9gblChC>aPuE&D(1795%h<9u^>O)}B&63;O@* z`eG!b&w3&q9bg$~s)cH=&$XkkR%ZZreHy*!KIXS1f#I@#ESdbqet5ZPs6D(rV!1^Z zK|p+Go;`axL0?Xc0&~)A+V~8m;(`QB!as)nj83v4L6>{8V@Z>Cfn5P7N7n^ER! zvegl^HExj)wky=tG+kfSnN?uSpoYjp2O(zyRuwAjE4-A26v*HN^g1s@-SZ?-ricK_ zuCQ|s!{~a`z<9hXNwZO>nzKMwWTI&5kk8#;JTxa9-(Wr4+V+!)7UWvVS7XgJ2WRQU40R{*8DoUww5WMd%*ArPR{4Eh#t=A5U<#0o&eV1f>TH^tVzKhrH>n!V`{?07j_miYzjEeR#=|z%`tD&>9a8Gx!aOc-E^qw zU@Lp68&VS@s#&Z$Fwi*F>1zjyL46w-Bys{eOD{vLdA70)zuyX_8mo#d{aQp*)NqM` z9TiMukdZ?D$pco!HpCY%qav!EWc$L__i4M z?lbUhkGv2yWdO^JCC%h|)x#}aM z7`Og_R7_-k79UeuAgWSjOmU;A9y5|Shu0XcL+nvxVpe=6Jn~-2e z&TaxnBhs3|8s9`3`yWm#dUCza`3jTPYzk-$H*sB?tXY0rip_t5Ir5susG*nYQKgvO zNGvpdt3K91=T^_kg!~1tZ3osG1_x}}VSmav9e6qNG=0h3zlRSeodlPb&q}qy)@SB9 zk<&ScAs&P&>#YrOWLE|bC1afzu4HaBMm*ZYi_V}T9_c`HIGouaFSqIs-WXC`8&ZVL}1 z!-TL&bm8Yf4azNgvs!OC5;12P^$XPo?Zq9h`suh9neum#6_?cx*)Z!*IUhC^@!m~; zw(1cSWU9Ews(CLr7AaE=&be8tb}p+G?X~JtSl=+U>eFOvQ%q`NpI@#hU{oYEF+r-! zX*H3|A?!ckA8f%i)5_=524VG7$-9!d&C_vCjv^|Qd_I(tG@SI|OE0{&g2h=kC=V35 z`nRxy)Ffx4<&br;63qt+Q@;X#aj^~i_JePe0U{zVhQV1G_|j!6tVceue19QyGd8_S$55V+9RxSu_P3dG+WHTR%0|0hOiTY16Htp+xNs@tYt zq-uXBvgQ*(c#;4u#5J=+czXa(5@1n`JEg6kB)~@5&z~fC&V$mi`l+}FslHGtF2{bk z8+$}8O-^H-1E#nOd9YE{lvI#?fD{W(#Rb3*)Zi?%Y^zR74xR|;3weW9okJa$@8Vcb z6CLB&>-00Y4?2mZ2D7=3;ijp+$UIZWsRZ`~$MZ<)>@nas{Q-8j?!t;WhS&(G*q@ub z_rV01XnK|EO0O9W`ARQ$9qbK>ZBF0Vt`Co$;^BMErag`GD<(!QnCX=j1q zn*Y#9(%G!<+t(~?x-+<&K^Q%<*iM1&qg_}{y)hl0%AXJjIj_KK$%xnr8%Aq-i~Ief zJR`iJzozpH_T0U7i7dmeZ7|6_k4FnUP-JnXUTcKfmZ;pNV*OGWoX}7ZDh~50!p={4 zlwPxzqZj&5zZR!klwNrcqFdI%Gi1U3d_DtEfXn?J<-8W>dw@@>BFfG9o8h8|L%AI`HP`qupF<)!JtA)y4S`xFMsBjHtGdxr{wi@6Cxy@5* zlwPl9EJG0}ZzGsyNk%aO@GQ;14};r?Mfdk72+z0%7*tRp!{fb!R-^Z!aV>Cn7=z>!(!| zRN#0N@1rUK4Ls0T1R2Hy$=of#WqUsSumY6D8EQWKz)dMUIHP3ZgfzT9?Wv4PxM*}m zM!Dfxlu-)Le&wpI-r538Rq%V1tE!R3=%angxH`miEVJ!X#-y&sXizeZK1CZk7CKZ7 zuSB71Fs7fn81CHlWLD4E@v)C7EPq2VelO6`7#6R;Y>k^Q9>Ta;9trOI6M_##g7+|W zVI(+%!C6KSG{jJS3%e@DFfL-+cq2`W@Fycly_l45C4rq5M3N@5zFv_EMlslx!O;D# z$ROU?iItdxcnse#4>?2c8f}4gN=uRXSVLi!{stbKLwbLdgv-xa`j(fhrtV?kZ$^S` z8GIoUe3ik+BEfeaKyWdG7A7dGNJivcK8GH1CPxq{$6{VWB-=pbRTSjWjtX4dk>dNZ zw(}#wS*-1}NU(vy6C=S53?>`F>>XjJ7gMQ0^kP zkA|HmMAB|y+RI22&!)bG!otq|ky1x6b%_b7y&rbgN0Ru;ynY)2A&m^UwUNY!?nmMn z0}hl~$Y3FZ5(!he#IX8uF@KdMSEX0yQm!8DM__OQ2 zxR9=Ode>P0tn5s@j39K08iM_T7>M&wVebAFF16UrVH zEw&ou%dNdVlfCy45X)0mrsRmCG<>g2z7th<%%5lThAWY8_HJ*|$G)U5y}iHj=I&G$ z;b%u+{{bmzw9TQuo<$`y(|Fn}a^3~|@;;coeEqzRGDm*D#IhtjSry#{wASx<52_)b zx5=^m4;O)Lh6pfKyWHXJce$gigVw$u3cwLZvE~+M7I^QP{DNJ4^Cc^+1gl}K2s=kW zD#PZ2r>y=6<=K47YLIl1Y7vYcu@|ZC1mK*$u$SBbk2ny3+f=v1k3uJlLR%nVVV1?3 z(0(1`#bWTL3s63?|b@f|Q5(uq&r(I8B9ncs1FgL3e0**l`$wvjd4`zt>+!B(Fvx7pNspGzg0< z2!aM!HhVr>kKQQ(zIZvS7N&6Uq&^F>wp2q|NNVBEgb25K?3A24=s5Cz~D&8)rLuu=aF* z7m8b~QEDPf#d&YJNEu&!exJA{So&aV{62b4!VgpcKm85}$@aBgi{vo-pYJJ+Fjlj; zDV!*tVo~PZh<*wj4ws$CRWbWRtlA9i3R}5uRl~^j;NmbY3gb=cul>E$+;695gq<_M zr|tz=c(Di@J$WTuf&Uyly&(H*pO)k89R{dZ$^Qv&ExD$)@q})6HFa0#vI8!i3M1v& zmo{~H69Fuhe^LVPgLNqXic~C*166*mnMdn?`bIq6CLV{b!#Y+!Jiund^uu0FhYLA6>n@cU=^4N zX7Fi$<5Gksg1;<=htEkqREvc2x4j2(IurLP3RWN<=7t^cR?>@6g@bZ#<^Gz9%AA5_ zYEm;)!Di1Y8^F|H*=aBBxm z&SYy{D6SGXIrLLs3WwJSyr7I_3G;8kGT@KjNKn)8YYBxb#3fGb3g>6AHe4#%jlqUc zF+;fLpxk{eaHkCgllN$^w%!+fjf7IGc00V<76YSlz9d-nPa$4QQ27FwaX^gOC#|+& zvw1E3VP_#U9&GMshnr48<2H!$wT7_s_lU>+SJ=Vk?Yg5Y)^p-yKi>ai{$TP^{E~p0 z`{V3Jyp`|k_czw9gdQNNF-Kz8|C_~Ltq_yJh-Kc~BW(Q)+RKzeoPqA>O~N=GQK|;{ zQq_nVaMM)n{&J!pygVJ=1;XorQUU|frN1bU$u zFcG{U7LafpkFa{eut9EccqgDQs{JPxCVlVieZ-e59-mSc&4gLS97#kJ4-uor*-&13 z*YYi7+T^YP3n@Ly*&wf$atUxzDxL&!J>|16!M1a1`RY|nQ|8?*x)vL*=rUgherFlh zO%&w~)Zn(lHX^`hlXI)4tfFwr@#Y@&7pi!nAC3DTJ^oyqh9da*bH1@%4CD`x6Jhc^ ziX#ESsI7#Zk737&2AR+t5TOP{n61OU8FtP`JP|Es0VSC0$?QJO7$fJ1KvG#bxNm`) zFdSM17_^uJwZs}nxrK|BMO$DjWGPu}#&~X+;8&o4ke>DzD*T6jg5G(*tKv^ zQh)1gLt0s*+Z^m#VLj`y>yIKGhkI5Tp~Vc%T~D!SD4gOg-LciHY5&ou;i8NoU#TDJ zx1JTzS*UMe=$l4u_v%d1$1O0X=?S8O1~LG4-r2zzKlb*t+6AF?;nWrEvJlg=T;dK6 zG>3AO3oR4lG5%RyrzQXahbW`brEsuIxAvBZfpFk`!Qk@$1{?% zj8{V^ax%iP=Nx}>_Qob0pNhO8($3p&aLLqUZ*Xu)p*96(<0&Qi`9Rf8&(zEDbLVeaPXQ?QQmcM)aT`DEHP1ogwa(LZWvs9SrH zlFpP9y}?sFz4v>y0T5!qdq7bzOJqKanR_Av8V;oQ0JoY%$K~mb=bV|*ZRE#WCca=h zXneI?k$^L?K|qZOTLe^lT^x~_YV80Bci=5%k`8Zoas{r(36JWOldm*z`EqJ z)5x08+5{WGk6r*Op3%MuHsmQxs%mP-$FVbw?N)5GIjD*E5QiaXN^o22N1t{%SRUpA zaqQVg@f5l@m{-S~ zEl7eN++w`B4*x3pbt8TSybT64v@TJ3J%X4N@RK@xYD`2`8aaF!nIh7q+q>fjQRl8F z-quJn8vP&Ip8HRX)1GL5t!s+yzkQ#_hWottAKafkPm9z3|Iq&2@PCXyM|A$h{#hl) zCj`N0$OWHwiv<#@@>*mLh+R z+G8={?2V1T`?C~-aKA^TaO18=q|lZvNWbABDF)%-!&12M&e*g+Gk_KxlhN2*FF~$hWvEe&6G5jAYkDXnAQGT(n&>a*XV$lD8um8N}{J+(nf|Oru&u>ni-v3h^d1{Qm z-yA)hd*jd}DzBc{5-YDhUHcy_uQvShc=(T#S0j@CJHBQ8@$cWo;pgAz_#Oe{#If~9 z?WChI`pquPe3HHc{foxt88jHcEv1^3U5T%$sCT;%j2Bq1T6&e0KYL?5h{5N|5dS*= zjeU-lKVIp+o^oz+9!20EAD@}sWQc!_&%-V`e^fs15c*p*+({^s|DpQah!fDr|3mhl zFT#TVDc3DdHJJQ2Di8kB97i7fM(NS>lQ{Hf{1F09l8246`o@Oa4~z|;tj30W_lpe= z=^q=`Jh9=Eb7RA~m&S&*yx8y~SHy-l7sZBihs1^-@y3SN4vh_O_Qiyc!4JZUL*o-x zbj5J~51E}N<9Fj?r^(+|`;UIsy8Z59z6nb*${{y>6UJa~0-sX;RIiA^UM$WzAm-}E zB{vyt)7UgBhJPBhD`UgCco0w?Puf+n>9fYigst<1+dbluCT_s0`u*+2LB0YUj2H^9 zc>D$LG2lFTFR4R@R8WtDG!_Mi*zD2i3OS8q4 zRw_y(i=(ur-f%Rtw5KDb9hnp9Hk1>@biAruVD!D_hq+g_xd!m)R zaXLl!;Am+DF{QnRWY6kJMrm1cX-(H#D0`x%O=f94dE(}I3n9PF7pNO|#mei(_ObKV zZ;ZdNC;pq(kA613xZW?pq>F;#@(Sm4F<(nd0ESy66<^HP=R{QkhBMEP4VU~r zHrxUWimWfBXUB$1q$P`S9)7h0<51t7%%Lj|$enB)*PP8Wrs60dl%!yLo}9*Wi{fim zAj2>F8T|5p2`}W2`ToyN=wW}`Braq)AA=LLcYxywZ}&~GXD}kv|C}4aV48j4MSXex zd;_pXdL`cIx@h?Y$$(gTQ3Krkp#A$t0m)kw#e7aXwI=}7VE3mHs|UoWPd$xJ(EbRc z9&U>b!tRyus#s-_#G|27m4rL z;%meg3;z}3d$IVQA-?J2d-xQ>?iJsU#kXF3*NN||;(Lksy2bY_@$DwQ)5JGNe5Z)7 zUwqFM-z@R%Bfb}iZ(s2>@_#D)pNsF8;;W1A9`QBs`9}Dg#kbS%i08H9J5hW~#P>$= zog}^wbY-4W;h!SDe({|qzB9ykrufbl-#f&&Tzu~o-wN@)OMDlI??QZy`*B#Obb~+K zvsNT*6yMF_`;Pc-6W{IP`>y!@U3@U1LATYS5VuOhw);=BJO zrhXy5ABgWp@m(vve-q!w#P?o&#l5UT9H7Me8D4F>j)ygEt1uXhOH+^y?qLPE*`(pw zq0d@;+D6X-8*amG_n+v|+>S#0(%!)aAI|tqsPmn^-8-Rru+}*ZH$Bq$eiCj#9mr2e zQvB^9I}?%uyPJJUb-rv=v+?T2?x?~NZITv4RdhSZF;mmGTRocXZRpD@1LbY18 zF|F~y2?RCd72Zl|!qcpq^-pkM0O|%`$=Bb3pNE6Lvcw$T^=hM^i6!3_{R% zKlb=>zLx?Pw%|;CSBfa%RB`t#ixfa3@M21Coxd|4wp5juQfE92guW41+A^#0LkI^g z*vAamw)&oSyyc{iU-T0nryFS?mE5PYsjYq)0^(L2e(?+SWpC8`gU)zt_5MoWnMrG< zz~kN9!{Lg`G6HqdYm7i!{Y`k9_Db;jUlF4}jgJ{gc;n2pbw*Z5V?5Z8M>qH$Tch5B zX5$!im%xt+WgYQ+1s`dC2WN)E&W}%KdvTN;a|Dj|P!Qr!DwsmNw82MjD|qpgbb3V; zf)~z0sWTpeKmzWK^N^^YrTxTr_w0H=WaTfL8SP8}k|JBnZ2W?c_#I_sr9B(K^ER#} zuPOP}3+$&OtUrgo)wd&?NrBG#dLwWG=(QT&racRz^OjLod4K&ul%nk{yB_DIr{Ab| zG%(DZx2p`#xTWqus{TO-(R5<{A;YyI>^~P&&gM_9cOS>*)#1MK9Q)(Q00I0Q90utk z_zIjF`|bE92#R9@T@6*#rmsYwi@r<8`PWs25U>;b*$XH96fT1mCAAzLSQYxyN!m2G zUr_;Gl^VaQJtowN{XFSq!*R@3dHwRvcrY>@zbmP{?!jHIlyaQU#%n8`GjKxIpRNr~ z@!@VlJ6zFBs`BMlPH`Z2X45C=KRl;RPU#$&nPIz~zINctHgFRKo2FMAG+MY*{}H6k z-hpA!zG7EdTXnwkxj%{CLpv-wK86_E!kzx)iXCMs`e3~HwQ#eZ2ghnKc+AMF2KvuL zW=!Eb%i8LTAT>A)-vxEAMYMhkB3PHIXy{4ie_y^bB!|K6?lPeE4gzF5>kIuDg zmXUWtspD9HNe9<25<_ zz9FM8$MKk10PL3=%J1W}M=fcX~xM5grP z24gB^m!4%FVaFyJn}-L#pnBN!XQ6>23Q^WZf19xLa>j7To3zB^ z*rC)(BJ;UO((J?MqTW#Im59=u8WS+fUy8_JQsic=M_i!rY034PJp)O3!DJx*B}E^p z-H5f6O)fu0l)n|}fm~Zz$3XjV(*>)qCCYc=)3hg$8}@%2DP2qLjQpNePy~T|=Q_<^ zS&ncpnFFZmev@(VQ>0}m&}gq_-^qB8s}u5sj69jhawn!45FmhNiO+>s`n%`jnQ^?s!n~o>TmwY>0P1-xGL)KwsIYS%Sw>4e9RXaX)!q#|(^*L< z^>-4)-;v4UUHo1a1}RuqwSLnL6Q@o85|Z(}m~9+pVI!5}l_{ z!z(;Zc6|^WWhI#)vznLXDGyN@&)qBc<1Rgd=>RfiGw!pPS4A)wT;ge%@4#JOq7Y04 z6?H`9W+1Y#0SgVc`}KrC|3iNSxH6AAa;?1)0ivLM%HZGGr5EaxZ;^k==##K1TY9O#c`{q1L_xg+d}ROe}9liq%C+`Y;mZ0B&+*)TS>w4kRU!^@qOI5$cn1%ErM5xm>(3&Q=J_0m@UIb}hUgDe;%b=vc7`?k z`*ec#LH9C*fd>B&MAh0)MGUL0wVwXonz5t%mq}&^6z9p~|@3TU4QMFfEP-r$@SE}T-&|+~T z@Mflg z#BPNe_ygY>wmX1}cn%C$&_mJ2ywT!d7V?$WE#vs)Uk!{9Y} z0K>)nO%Pn>!s7r>KxpH=?0jv9XKwRk|82$TPICKO<(KS6o#deR;X{z#M)zr@Untj6(F1PCvU`bd5Z&O>uy#&uH z&er)M^~c=i*=G=KAd;_<*^@0alr^87FtuGl`zpZR0gzhz8@Cyy=Lb_)!>g?Msa5(5PDMR_#M__&0`0DJ+e)e>vV7XBp==l;P8E!zKxsDNP==lscL?o^+ zRiYYgr#ZT=!Q23jOV&2O)600x6i?qkq#F0q>%j;*?-DZ@c5V<;#h-PciT7$6kcjaN z4h}nCVG7E**y7xfVV)A1qTGwUyO2&W@-NGz$3@|Q2c%KhygDX=2aD9;JXS+QM5Jfc zgRE7I?|BR0)w76}2>}6I46$5<3Caz3IEQrDc?Zgb^rmD$c@zMlf@b~_GW@s^9d-LK2=!La?p7`XP zhk7GlZgrVo4P2LwLJQNe-U9onS^+Mp7Nmup4G3wK>iP7)XZS;fE+f2!;Q|-HuoB+w zQnTUDE=W_etJKx#4*a2{(-FvyRt2@Y3KA`WD1Z@E^&t4pzGoVOkfvkBx{QK44QhPT z*r{<1r~mhK@Ud^dzDV ztY(qtR*{E1X4nNo-S4@D!2K7%X~N?|N#qMuU5w>|8mM;QNuDW<#(V)h&EKH2U?&)` zV_Lyx#DNX>>;(P|_v|LV2hfM%p1SycD85_7_e=4mtPb~lPJEY&@7>~CDPUg~->1a) z0r6cRzB9#llK74j-y-oHAifuf?-}BoF23!=_lPL@8}Z#OzB|Nsz4)#a-{s=_u=vgv z--+T|BEDBarwjM=iSH%inil_Y{vde1eO zOQLzy&_Wkjq48Cm+GDI0_FG}Tk}<*<4ERms5ygD5dV-1{`rG7Lksx05!9913oy967 zn(=3Fr%{KhEzDy18FG2USYRf8dCsR5VEV%&3|e81?wQDk0>pERh?{}95`FAz6jjiy zJ7KgMdZvsIUwqq*A5X%t%F=%jo)Iv46uR{HLS}3&V&mW@+8fh83|D=zQJzcx3p`@- z9^pcfZhiYxzgUvlUb#H9M#wbn{$-$ns)d%r(Sxs=ZMp>7T+EN1lKwLMF-R)XBlN>B zcevHStTbC0Wi490N3`0dHwq6C->h$3WJbP$$XHTjjf6hO+LW zk{ez@dB*ENldYm(o5MQr8$q-Gz{EQJf=7+EMcRXI0sj;f(Hs}=?W9=bvLKG5^bqju z=H^DxoGjgLw2}RdQoRm+w`Qiii!47c%MGy(6cVyG&dmYCRw_%Xv?|nrc(I1tv#=1v zgkWvF2k-01(JuXV#4I-XI+EYW{PA8Zvp`Wxz|Ct;e&|S-FO)h9@4bM{OSKW;^ul7j z2ePvy(Yok*x%*A?Af<7GUHlqW*4q%mVd-ZD|J6^#Q9FPI2<-L$`QPD_F#qH41=D@N zbnh_TQqvt{x&uu2ebfEMbRFqNIWE)9GTnUB9cj8Znr?;ZK4`kHn(hwM{nB)w{+&_o zLeniZ-K$JD-*nG1-7cnk*o3#p|9uyuoR>{^lIfmpx}Q6Z^rfad)O0(TZe?d9eTM1w zG2JguG~!Re>V|)A)4kJlH<@m`c1HR@)2%Sw2Gi}@-bf#3x=)zy$EKUeCyMZQhUxlD z*KfK{n0VBf;XS6Cl4`)YOgG1L^G){()17F#cbM)%(_L!1Zo41ZiDHb($Os6bni3WZ%p@$PDc8Tru&rX?lIj{ zOuAfSx(}Lk5yZr2c2@)bTGPGCbc;+k%XGV#?opG!_L=TLGk%j9w#xmeRru`gMm>W~ zH^X$T{EJRD(hqbq+;2?xOVj<>bl*4Kt){!)bl))D|Hs_70LE2Rf6twyZTe2%Ps+B0 zQlOO0CQVaBx@nV=mOhp?Ev15+&F-dInq-&VO`9S@M8JYP!b=N+Mg**YSP>N!Bp?Ff zDP|8-@)q|E1)*{96Ml=*-%?^EX8%Dh#X z*DLd4WuB+ZR%Je7rn@qqR_1S%d03gRD)UWca>YMEnbVayUzv-Q=~3oM%B)r9CS~qa zW|K0_e7sHN>qW|JQRa4Ko}$buWxlJ@?+s<=3uONHD*J3@pPM42xrlZmU)87oufT;;x2nIV%-3Er>5IY*g3 zWmYS*Oqt`985q%|CJ?TsW`T!~~L*^zJ^9l|t5{Ay1+D{xj*B$)`bhnn^!!-*62 zM%qKsy)eT~9g$pK!9+ZGRy3Aa7VN;LwRk)lcO9K@1(L2-EL0%~SESw5jG*BDbmG3OMT$5apCRv7&ul(`~kyB00 ztLrneh>67f6w%HkUVt# zJ!$nTqkOuZhfmzj1+tMpsw(^u7o|WGPhLf*+lvfAIlwN2q%otSo5gidDtI6>1 z^tgA|Vq_e^$oM?10ip^}PDQASS|DnEJk-p>9 zcG4qNKeEIpn?9DbA?s53Wy|fM%FCAfLzS1cG-MGtXnf_+D>HY8C@*ViNt2gF zFSN?G5~5m*q1X3p0iyqGPJtZrx zG?>x~t?z>i98AA#xt&eH!Q^Gj{h`XsS{kwl98ABo-eAxK986x;(vqfM7CGtlU5!?T zUf;6`$R57E1QgD1&+)?f({ebAfE@bU>wCfcS`N~TWH|gZKFPvw*6=LxaBeSBveHVE zDXq}6fjvWK(c3dD%+OP~~MUO<4pEre9inF=zq~CNFDg8=`)iJbUR&lLx(4 z?)HV_L3%^d8eY>HiNzxAyHe{=Rz$@bl&{&E|2gxa;d11_Jg>@W{Y%c5*MUtWAsRTL zAeOpL!|c_Zz%KW1)&65%PV>fG@~nDeN~N_k%z$lDtNdHF|0Ff_!~DB?w=W(JM%zP? zWF*?|uy&VSccHkPbL)S#5DJi=H7+ugN?M!H|BFzvrH@>1r1V}+Q%05Ewqy}0ZBGp` zPj^gjCC}2)luGGslPXd=C3SH9#InPP>t{+GzJ6keFyi`|QU}*>@bZ}@ukD3XWl28e zF=t-e3u7vyRh240J~bhF*&H!_O{pSnM^s-k*Qo9CjhMcs)co}Il&9L)3J+c_sOHIG z#nXD7&@5Xg(il0WzfnN_%p%XK>RQt}6gl=LzZuJwa>X)T6Ip;zekz>X<3Zwz6&krv zqrFAZ)J3F4v!9=QE$(^BHG7o&*t@79#AE2;nhk|Ycs&KO>uaT-$?cea+4&J) zv%(K8T$4LXxH;>OUUssTKS~C(x?ud3k31_)XdTVD9@?bpl5)3 zMbunXS430q3!>rmMQBuCPGft_y7b9Oq4GsfU8sDIXLm@xAN04i`6KPg3iKqg@+!nZ zs4re0(KH=Vk3egbG8F{rjQh6kqEdTUL21b|+#eDZyye zzb72u=TBhsV%gaUZA+br!>=;z@jW@t1D}t3Fo8ji-!@Im8@u4sciI3g}J2N65 za>P$hTYCft;aiza(cFC0^cSe7s9!_K2f;Uld=Pv?$OpkUgnW>ES{ctXA0%Jl`5^dm z<-_vb%^mGQT0s=ui&z0ewQe=beahdQkf6QG^l#Bud>#BD-&|nO`Bn2s?Z(!_YJFnLP3ba_<1wS84$-xQ4q{X17$+jzi(mP!uj z(9U~y*GCe`=&pF6ZEG-)Oorn%p^&E*tfC{5n?LmZuN5A@f2GG$QCZy_!fssuZt-=6 z_-LY{xw$+XZdyqnO;nbrKAISWypS&^R6c9p7rfW{*uSKBAH#S2vf_OV-|9OcvIYh2Hh9 zvz(?t$Q6jk1N&U<;k~ZbaQm)g3yDf3<9H44N=Bou)@b`K=Hf--d((71da}4LDRQQN zQ@NL>#pfiKj6heh}^MCi&Ll(@n(Ql?b+kLml|oG}#h%1zV!=@Is-AdyJIRuk`3!E%^>A_tG@?lhyaT zOG+ePql&-j-p~?BxM*NYdFcuU+S{W^R}+E^w9-ema0|FX;pRX`Ytn^10mz;X`asB) z3?z1wLIX-}cbeRmu`)b&xzx|p^UxY;_l}ePT@}*aSS`(_cyxET-4%;R+wfTs4#Vw8 zcErQ3Kx;f42<>yl!zdr&J@N}B3SSXg1POd#lxU7v1no#l`qGGK>DQ~mHS^i6%60vC zsgIezjVfOo!&0wo`78Bf>z4GrTczo$lVyXrtQVZ^h?g$;8PGr<`_+mSVa+5%dBDI2^wbb66;;O}0yre2t z>@X?9^n;4O)Ko-uNqdZ9kU0K$*U2u=v8<^hxI3J5#iCdc4#!0(hI%QZ$Zj zGZbo|HL|N+mB1xSn)W7K3qS1Iv~9zNV_l0EyOu-}HIjh5mR40BOBY9V7AQI;q!U7_ zRjN~7)Vpdw(tfrJ=|#^l#1D>}$k8eN@PT}|)0M#IFrrxxhZ3$1vF?plAQlKllKW0# zOCrt438aNnK1pgbvs@>*mY^WOD5sdopLc?+U%jfmYOImvtj8nGzQyu9fnG&-D2*y2kb1e-N;6w~@`U2+S9+SJOT}*>OZ@6fRs2+X zHmdY&RD3R#p6TgwaEjy`Q0;tINb2{5l6NT0y-(3I6^?1TRX8k5II=P#1ke_) z*=nkHMqqcirnNPL!u0n|mHAfNBlF92?_ORk&-bX3rWmKmhE5FjymWZTd+@7v$?(!e zyT2{<^C~mlpS?%=WQ3y}9#!dE^nLCu(s7&HZ{_-p03u_!v$>^A`ovzw))v2ZaKFu#*oem-#J!I0&2lQyN^pHrW`!&Dk=oxX| zktN=`d_5lN@?V4=PWitii(Jy#tNUfqp>(lK?Gn)I;dkl0S_Dal1DfAK?U~3-dGwr1 zo*o~fB`v%_dVEZIq#ylEx^(@_v>_VrBGi9gL~9CUb^KBKG;02xcy?-kNR}yEj}OV$ zeJ<{4%Vjx+jY(0FE@AM7j$PuF8Mcn*@>G#Z_r%4x6W|013T(}nm+wi&W5T{Kxl zr|Z*#w5%RgL~B>%<@lpG`ZWI*Jg4UgF_J7(wjMsoclr_SLCx=e?V0F%vgC7j8l5Sd z*+)C^`A*Y zZl%W*v*+NCH9(!j_DtaqX#OQ*idcHwiGgI9vi0yuzWy_5$ZZFBc0eB16m=5YGttL1 z|1RyB2uX(d)59gX`cDtH8$5mR$C{;1Vtb}|zo`3{pkC>AMNP6y*?RaSU;mjjE$lA;~a*dblLl=|}SJ*ZiK)o{8SI#93ZX8l4^wA9!YuEuuA8 zryzwJ(Yrxo{=C{VxseR>r^kcj>OVc)Zt!%&A8WiiiS3zu4r=~S&@=RO%0pr#nUv@B z)AgWmoPMNF$+(o?Z0(uoOOADp*Fc&)Jzmw|X@MN9O*;iC+(^eR&Hn(=r^zHjl4Z)) z<3sZGpGiY*v(cBo2!E_m>m;^k;iJtJU3ktlJ|LM+=}O_~KV6Sb=pKVytcmL+wr7&L zU-R$5vs1r8vP{`}I*@$*XVQ?{A@B^qA8YD5iS3!_OD3fJXKT+yNHWZy9xln%e|ot6 z;Aw#ztX1kHwr7$5n*RYjr}u5dK(b8PdiW$?|Cu!8<~Lj*jk(U!w{vr_=2KT?=Ti_AEUe{*q6Z z=HG+oY&sA-$rL){*_IBP45HKZ=myUK{IQlzUXDMKSyGzvcj4Ko9FQziwjMso*MBCB za619*ALL<8Tqm(TQ~3Ke|DG)2GsrS!>*14p{b$mUTQ_(HNM0I^PEXt=Q&KXP;MoVH zk5fz@lIfHW6psFLFLTznQwvL{Cz;)vUp5`|_)!=n5AP0iQQ}#rD?PE8y$Kq;GsvJb z9Vqw2)(d%h|=iSAYkBV-|r9SO>gv3}^2G3yzLK*t;2PjYpdWY{c;h6_Mt_L2x({>q4PfdioXrHnz&_yfz`ek)fR}+etFW#M zoCQ1x90uM6PVpjqV0;bI02lz?1QxF5Y(4O!HAol0Rm+(NNCMXbcbp12z(0XMtmmxZ zG|qMcVc;U*=?$Fi*vMHFn6jC(ZNM&IkB_tO0zUzEZR6}vh_ly#f1ktIxZOw};KEkU zA~(SVHs6A@yp6NFfL`G7JHQLf{4(?h+y^1!E)>G9=H{3StJxl2FjL`6W-sjYM9I1?qDnZW{zI-jQg!Y!GyZ zY;Hb5cfZ|D(DmBf8U)=Fb~i!S2RAx5cv+m%1j=Czjq0|vmx;L2dzhPNSZ;BO1Ku-X zTyMGUiMA%&D3R%15nbJ)_|H4}9ayeUl6i{$)EQPZ!({Qan0kT$h}PK9tIgu$Og`oS3JG zUH>H9!jh)=9n4?huF8yuXx@Mut}8X&D#)$mU0SEG+$zb9?oNo!vD~W24GV#I0}D5m z-1L5?pL8I5S)9@P5+5psvWvL&ppEV(x2A-!GjB2Lnh$$S327{5mqMo4i`N#VZCU;Z zWkw7sbXKKwkB3{E1IeZc)u2Ay#7R1|?^zp2u8y>C4ex5hIWus=#GsnZ$BRGs)o(d% z9Ts=0*?8O!DeWjIY^CU@guNF2rMeydF3r9M{%+k4fA30mXw@ww&u{6|^(86*k>A0C; zdc#;Yy%Nt`N@E7@E1J1wYHUhlsoTKaBlEV*ip^}C;WkQ87oRS6OP)#KnFyWfNlr#MlMv2CgfoH7xpqdsF>gGZ7dnE?YnadGRnBAcjG1iuz|{Uy6aeYB5PmNB z9SOg=DZhmi*uvy2wlFl4Eo_*<7FJGY3tyi*FuQ+dud#d*Ti!B;9h02HjtR|X$5hT@ z$Gm>Tz`XuBeY1LJ_>79ltfFNsJ1RM!9Tl3#j;fr?jxwgR*#k5Cr}s_mE%hPnBgeBN z-7PwJfz8{b%UC))hE==*<-Kd%Et z^NQGnajqATn)*0+pelS7l)R+WYM91mRZeBIUPu0je1^=1Daf-@HvMV1 z&7Z*LgKj?P=7Vnjy;cfA##qRh2^ljW1F{gV$TPeQFE!?{QSM^j!jfWElAO(oL-Sex z38*H(PmnAN#}~8l&&*`SkIoWq@4)>z)BTOvZkjYb;6}Uy1wLg1Tg;yyT0VM6sRP3glV@+eQms& zzP7NyYqM)<*n?L55Rk4DxjjgJX*!YHPk<+sPIkN0$;PYcWD5%_>2`zKgAm$*2DAf} z)7Zj$t@<7_W{+dDLsQvole>^+?-~`rw zU?OYWKZ$MaoXl!kO3~gNhxX=Jv^Pu8-Yl}WHwWgi1K_Vp&6F~$-$Z(vUUtj3w{8C33`n#7(uFp2$O|73Qk zvy|P^GKJmn%+c)fM;D_`AH#YtWb98}xV!8~l&wK%eYn>(5tFnA`jATK=`xOH)BC43 zPH~s|7Vaw*agM1tuTybe`NkqP{h6a!$)ja#0KNLC4#r-g@baMV3Nm&B`uBY4`}Z>T z&(8emV;Hbq(jw`Ne@|ooMtZ*rz5kS4g1)De9T7T?9Z`8KI|BJE+T*^7z2hlej~mU7 zL;U9>pT;7-eIH}&>GSbE(S>-W`88s9b`!Rfk)LQIlJn3W&qaGY2kpgd(O%5xM;kB7 zH_A22=xmhH+1IM_J)xLQKtDU-+7et@DEo8jr;-bcSmQqY;ZsxKnC`{CX4F#bGFbd#u4D?W~$%;&g9v8k2w*;Mq^ z)PB*trI&bxy9@3MEO)4`+?T+8vE}ZDEAqam28ILvFN)Qr@a__O+ zy>LIpa_=X1cQIRp{*h`KrOhFdE!<{VZar`_7K~;KS}+DceHpi9bj%o6jOWobCXi#Z zi)f4hx6oMOzieNhV`7lF)rck0mZA^<(LZNss`%w$FcdI)R=0{+!FLR7|UV2Jr{X2cgxIvs%vFO zW8JqLe=30;KygVaa)h6Z$I;VD`|#SDmJ(i>R@!1diZz9CsD8YgUBOF{-gsv+e)SmN zXt$a6sqx^Pu?8F4#F(i6kSW5t1rLt^6wvJ=psA+xs%cZrFi$F_1&pOg=c#-yvX{+S zIGRmGKRgvax;J3`2RIDz3qfPEQ+ZCJTw+~kdM#)7 zndMTm&zU*~Va-8Uvr&(yv+)Rs;?S^I#UX%)a{-D&gv?S}ekmUXbzkKhF{6ZDc$YBo zk+HE7q|3t16WHcQk^XOBe2;Q5`I&KSd}snI#`w1j>sMC-=R*wXs@vxrL*t7XXn!$> zz}RE<)3W`gxHp2zG<7z;bMJR>xX?MdKfJT!l)2fV%G*s;Ywdc1g*+?hsNoS)Q zQt71IwX~P@4CM>ow6I3PF%%!tCEbnLXrwMk6SOgtx1he!7;s>8e{mmoFFdk@9r-Ag z-7#z;;xwvZ6dMSj-ZeoVAs^#-&2B6m$Cjf1cMUA)pWipPcXmvUI_4}w{WnfzV+Y3c zk7_Iy?V}HErW^yGz=|uEu|spQRyq&!%q65Z#{5Z40y5k&?$qe!95b5DG|prteWPQh zTrZ-$@WxVhW6N>u^vVER_r`WsbNCE)?15vLYyT29t@BvSPj;~Got!-hG*WoD&vokk zN3*d97YnytA3^&d^nft96J5$}s&HeF#~_bE9z$3R;V^{5Ae$jvn|wA23tt+2PFmC# zT{l|E(RtH!pHqsoz1M1?-BeG`KUUR~%kc170MX#r2$Pm4QA^@HfLbEwhM4;|jKSP+ zG@I_h+)#`gRJoj1!lt2LnT9rNnrHIB#D3MDqg_2T8SBDmt$HDr>Wyv}?Qc@GzmSdg zw_ns1gyEjT*(ZQE6`yW5#*d=5tbbH*Q6r~%dsGQK>J6+(JTrk!Li;%iy0~X?_EErn zoDA1)M_PfNfu4b$rP0qh7W3o%GuhP6S!`0vY&OoQ5aSpsi=y9)V?JJ5!b&l=D)k^u z`(&>tbboXl!}ndRVi(Fjg-z|);qk)03T{s*eaK(8>paHHv212?6q^}BoEnO-)_}F- zew7bNjMqX%Y#i$Ps7iy)nT9ksT(a-&8{JzRlW9Wvd)DzPen>)cAaO=IE-Dkj27kWFz7{} z@){o4QmMy(@XSkTDLjULYA)Z-CU9hjTJMnU6zQ=9VFDAtCiDo65%w8)pD~@>pa=Qu zcAZDIeG}QZYe%cLZvw;jH|!GNEWwXNK^t#(!;+jvBV;s)KHky`-}JD50zH~uWFL=r zBX=vk((O8ram09b1lF&Pz#7UCSVK7i{pAr@LlOB*^UDy{c^a_JQ#pgpdtLS?GXA64 zp=0p=05Hcix_!=c)X$JwcZ-*bF@5L+mHy}A;YNVU!9JLyr-?qD-aUMU%TAr1zs^hP zRm2e-Ex_A+s$7fOGTJxiSX%Qr3Tr-#u;#N6Yd#Canh*7JD4vqen5E2V%-{y2`iW}8 z#!`Q^2;YLDT$26EH=`rIg|m+#ATkB5kFhB&Kd z-;;R$rDj)U$2UdmCy5s|olU+KOK-rPinkcgYk?mq`(`}v)cnc*5zT+>+|d}5VGSUT zHNx1mMl&AQfM)NP@D2-d$W-HEpP|N7qMwY*S}FTbw3(GykDH1bB z{mk&t12f;^%@RgQ3=N0Wm)%Bu$8Ys)I*AB=@ z|B*{4+lZ3Zd3*z#xRWl!;mfplg2Qm7@L@I;h8{V zlmP`7-rF|BHV##jJfb$&Wk1P z*eujfWI!+8n=#C~y63^~2$&0CccJfE2%Q&!?kKpGA)g>);J=Xd4qj`$3mJ&<>0re~H0-;|$h2-eB&D@H-m3iy;H(0S*DZKp)T#3;+zn)l$F((3&=_ zwR`b)iq>Xn&A4|C;s^9hGFb0qgi(s{rXuWV2J=ogSmO+YH4AQY;5HX-^9V>xF#ZA`#zF2X$f}0UCn21Z4K{EJ+-ne@HSntg-KlV^H(1|# z#C-$kHX+U!(D}B&zX9&sVLuaLe+18GLv|y00+7)Jor7=>L;fz*|2Ky^yyLydOh&=R?*7@asZ&7eTL!;dUwf_am&!;C?ympN9QP*sp^9YS_DB zzZUlEV80&r8({w|><3`K5%!y4zZv#hVE;VqUx59Ku-^*%mtemQ_B&wzGVBLo{|fAP z!G1UFUxoc1*bl+}b=dEP{Tr}<6ZUVx{%zRrhyA;-e-HKtV1E$yhhXo8{bAT2f&Ed~ ze~36fj`%+T`;U-sPa^I=hW}3x*PkK%`ats({C)wqXTbX`?9aje8>HKZP?kn?uYmrm;JX(z z-vaG-5zhDF-V54?@%#h$JqFoN!2e0;^b^#JpMj?j{!fGM8TdU5n&+U~ufhLY$eoL} z0%-gl!aM?P0s0kMN9qTtFBSbR+S+dNhZ&=1pdX+%uN$B?-;H*b+FH?Hq7UlSj^aD7zg3*F5t%1dWE;2EmAa^pm0Wx*at4p%e z8dldb&=BC(1GDr*xZ|1jNsImXOYltqzTxO!RLopQ;d?@ujWB5+FYOI~5qmRfPqz!t zv`>@vchcUzp5yQgKHB5x#WU@@r9FrA{TzJ@$N>8Gk>2~$w*vH?1no(t?^$ReioRc< zZ&9c(r*R97ap)T)8kHQ)ohKnyqp z&^pfn^e;Hmzy@ktX>Eq)AC0Gi9_RwP0rIo-sE0dn5c?iV*F*Mc2x9|y09r?*Jnh*C z8idgUxHf@*Gs?y3kO_1H-Yp0lX~6)TeZX*T0>jw?4CgK|H{b)h09s4J*##^H^Z`BC z6VwZPJ$L_1Y&@<1L5w04#2=( zn2_(?jDh!2e%%1hh+$ns`)9~Pm@dE#cmW^K2+&#<@%#RQy8j~d0B~jy+9~+qnf(>vfvyWE z#j^`=1KqIq0F9(G?1%8&3;6IH1G>K9& zBG=3U-06oAVpcHN{ zzzui-AJ7Q&!Y>B13+M)VfI~np&B?%k=pbzK9RYoQO2Eq~MVu?w_a*8$gq2k9FFdhmP*=mq+KeqaD#H$YDyTOLqd z>q44SU2=i0k!Z2siuPd9zAW0SMfI zV$T4Z&cc3YVCLCH>?6QofPWNgTYwL^5cnGK8c^XcVtasJ0&fAHMuZDo3fu}j2s{V8 z0aOQy*vEl~fl*CGY#neV@Dwm3i12~W1Ahb-V@>fK;2z+0;OKA>s{_KoCBW^#W5Dac zg61N&9@qnX3HU!?>8>J{0KN^p4XkM?VsYR#;KWD~YXj~E-T^k9gE=6;b|XE3D}WyX z{{oI`MH&Ft0Y3(c+CUH72pk4ZY{%RTcm$Xnh0ee?0TwG_rvY~XQ?g3r}PQ0)P?PL-AI`BGB*;T}nzfYqNu zSp{AMPTr5XEpQlEc^T3l_&rc@c@g^*@LRzB=_0ldcmx=KMG@Nud;$0?;Jvbloek^* zZUF8D_*F%03-D#&9bn_tpa)(9>br~B7lF5crPma(j{@DmBfvj_ldeS>2Ob5+URT66 z1GfVI0xGXZT!BNt-vRFpMeG{jk3i*TuoeV70I<&%v0C6VpdVOqpom=s{2BQ0jgSYF z+*HJt0lR>kfS&^FbC3g^2lN7?Z-(x`jle6w(p!pHD{wdP3b6F^D9gatfY*QpUnpW5 zfPKK1foA~TQ^ZaO?gxs$h`a}`1D*yvw-&Ljz=gnV!2Q6lfp>vLUqal0y}+};nA?ij za$pDWao`KUpMkNrLuX(oa0&2JVAdUoC(sIf4;cMrwJw@yc;2vPq*NWJYzYYJMbXzZ(#M;i`XZC?*e}W z#@!1ypdGjhxEpv3co`V?4Yc1t4bTK!0o)Ee4E!E=8(4H7>J#u1u=<-t>|?-BfHS^@ z@(e8aHp(gR46y!wlntQjJ4NgO@HWu+U8EndMZG8k!1KV$hv5eN0vPiM(hE2rxF2{E`0x*)D{$vl2QUCsK8`#B27n8mz#i-$Aspak;Or-{T?d%>W7HMk-@u(eDPnVfiuMb5 z3pnRz$OqsDz$?JapCewt`M~2qKQOlsVFI@TF9D05g3draunlMe&IK+6t^%F}{tKM? zG}><9Nnq43P^N%OfS&;qo<4ZH?gG9G{0R6Ja2R+UFb-qP1JnU6z%4+@pV3bNmjI6d zZvZuaL0$kq119|+`WoOI;N!qGz+s^JMU0(*tASg9`+--1C4WWP0j>ld0A2>hzEs4H z2UY|)00DFNaftP@Z z|3H}qs(>2c44@6T8u&W!81P$Q0GRv+@(0)m>;gUkTm{?$+z0dmzX#p|=KK?B32X)8 zz%{@fz(c@uzyMJ4FSJF#kw7I-3!DM802cw50XGBp06zkr2VMon{u|{Cr~vALUBIQl z?Z898uYmzz%$tZCuo2h|Tn5|#91CIbN0B-^F{)@H)*bc;iOMzQ}dx0l_7l3~P{{@QPMtuin0!IO-0=t1L zfv*8i0sjEr0_aT}zPw|_Y!n;K#$ZPU_SWI+s|jo(c4kb*d$B2a1uzZYwaj4H`OaoD z?73&ylgW-?3)qp&#TK$f>?l^oj%JJ5G5AL4Sauvco-Ji3;OxH>ae`Yp^WY@FO17L; zu@zVzU&&5lA7Ur753^I)D&}Q1Y&BcMYFQmy%TC4jC+paHb{gBjHsU+2&DcM8I@`jw zvIe#dOQdJ89qdfDlYNAp#m;6QWq#Jk0<4JzS%`&MGuwsp2_x(roI==&lMLH&dSQ&6 zi}MH*EXg|99-M2~iE|9kV;^JZvyZb2*oCZ%eS%%YKFKa-m*88OPqF>%GIlxpG`j+e zsaLV9SvR|eUCXXx*RvbgXV_=i0d^z1iG7aU%x+3yPe&^zRV7? zudqAWUF>f5Rdx^i8umJV9m}iVVE3_avTw0(<1DT3uKgukG;tL%3fkGvsc*P*sGY_4Y1eP>+B!w4fap=FHH8|#032< z_FwikdxyQtaQvNN;5Bp+wkVD=MjK;{61>D6XN)%{7!!?2#$=<^m|{#drWwQ8OIw-jT4Mz#)*d8C^tMt zg;8lNH>!*kMzyihILY{sakBAY;}m0+;WcWE)y5j5)~GYq8mAid#yVrYahkEg*l27r zHXA@r%6h;fdw z+h{e~jCLbx#Ef%|xREfDMu)M-*lTne`;7C9j~VA1A2%*AE;PD~PZ$>&pENEuE-@}O zK4t7TE;BASK5blKTxncoTy1n4*BI9t*BRFvHyEEWK5HB>ZZvK(K4;u)++uv*_=3@6 ze9^eo_>ys(al3Jc@nz$n@fG7v<1XWF|BM%nzZx$YFB`8I ze=}Y+{%#ByuNki!|1jP#{%QQn__y(<@gL(Yi%lOfJ zF+YYc;m7jh`0;!xKY=gfCvrD0=N?|cEBSI>#aHlZzLKBBKg3VwALggS&`8vLypT;-vjeHZ|%zgZHzJ+h)4SXBl&d=aG_?dhs{|G;epUpqY{k)L} zcoPru5D)WazKgf;2tSAK=B>PqxAQ2E@pE~cCwP)~@I8Dl@8tXVdHiGieExBM0lyHR zFMonx#6QU|=9lnG`KS1Pei^@W_-FWM`2l_-zlnd2 z-^_2}pXXoTJ^YLOR{kY^8^4|3!N1H8@~`ka`Ca^O{#AYt{~ABUzs~RF-{AN0Z}M;P zZ}a>4cldYt_xJ<+LH>RI5bxy=^GEm(_@n%X{4xGGe}eyrKgoa0f5Lytf5v~#`}kA* zY5oiT4F4s6mj8-B$A8U#!+*=4=fC4G@Za-({s;a?{wIEz|C#@V{~v#m|CPVQU*@my zzwuZ3-}wN4jla(S!QbHjilXPKEBv{kd6v6j^Th$rw@vS%lJg_V54TY09{ypKv zsja~doF?5K+~@V4S>vm#*}keQ(GrM5Y4&<|?DSUF z*RWNq%2rivTU8c>1V3&lgRb6MNg@B9SyLl|Xu?t1L4Op-XNLoA-r6iIZZA=nyS=`; z)wSN8Lj1~Y{sx=~?~k;_TKy1{B`#)g{!KM?tJC6?p8&VFtgJx=x@Mcd&b)@89_M+7 zKMESTw`uTA#uQ)i| z-xg@^z$xPUaBm=;0`FG`hkLjAYvqyqa8aZx+eEgSsR*TZ_)n9G;jc*~aOya2A?!ej z2>Hda>c}C|dyp8Sift=Xa2QnHgcjX&rQghKIfBH<4ty!9v> z{u=2VgL^pSU9XFwLc69O!kp;bUQ_2G$*qOl)dk93??j)Lm}}POsc$?iYF!MM5s0)< zF+a106kBhPTN>?pixz=dw5ad$Vg)ZgwHLK&Rhg`dbdr7hu54A&mXoz!k5|h>l-gP= z1J^`j`}}RVO)$DAY!(W$Y=~44jSLkIqDQc_q0$KRNB@+ zFziR`r>dPdliI3E8D4_~qvuYVvgJZqPdVB)(i#scG1o>~Tm9#S<59}IL^w&wX{A0z zd83uZr?y6$0&{esXJ|ttk}nyO(>yE6Y~~gYNM1ij^xv z%`2)x&CL}nS9pT%U?5n2iq~6LR<_+NOsflFH1k8oa75Ig{-!V;WJ!FlQse_q4p~YH z$W2w6)}j8#ljvm53sZRtqD{c{&lq=XM?TRtEBE_xhXmrK&*H z@^Dr8@}{sSP`SJ!7;rCNQ59UdVr7-Ps=2aiMWq{6fZAcyu3@*t)Bw55z5dgza+81H zGEE!MDk4)_Tj_}ZR2=fC#%67lIxoPE!isha_b6~}aKxLr3 zqN%xQd1VDs&pG6L7<0yXMHPZu+2jtcs9aGIYzlhHmj{-6Lgm#f1HqL|<<(h3&WAB) z$jzSR!HN~`l`Gv9)t;(~^6K)Y<>l2?fr{opWqDJ@imV~$!ze-y$k9+R+J+0HQ5QQg zUdLrQ7+7VQ7pU=y(NC&I$z>t@QR3yOP+#1;BrO`X}a8^kiT$ofOB(JDHFH9pO8cWwv=eJQ+ zb=?<3{S0q;ojaPn)fi3h-iwQ+yc?Aq(TPGw6wEP@y2FI*X6(XSkqM&CRo<)_RsHwPV*L$aU z%iODLkRGdRRH&dny>4Bq43bQ@w>&Q)Yeqmu-3Z7ybp&Lr8vz-ojev}e!;^t58Ghyp zA;ZjEA!C@CD`X5abA^myX0DJi%*+)s3d-CTtkb3Hty7(+E-h8rlm1p*p@`K4e<;#s zb~HKsMT?ZfUo@FH{6#~V!(SF;8$mQqYj~;;Tvc;MB^J(F1BngE&E(-v(uyX{GI0O7 z-=r04=1D75&XZQCpC_%1N)F-(wY9BDM9ov?UZEl=+GjI{SOTIG7`4U9WJFr_Ev7(;jN9(J&-jWolc^h+?4p-vcwcpj*WKLI*(A-pwljM zqft%eNopWz4R7<~PK`%Uz_h_}e%vxI^9|e@xRkkbMuCdDImR*DHAj6cs&s*Au^PU> z^oTl3jG`F}Z;9?*6KxgaSu>YV@U797Ir6uSw#c%Pnu1yn{?u2HczW-$uBLvY)iCU? z%}>74bqE2}Wf_bM^`H|bVropeJCoGP4ADi|LKm!vkj0!a+Rhx8TNz)ML7X`>w}?06 zuIe^S0OJ)NEE|>6Yq+#Ipxf<6G$JpZC#3Bjxnc`Q!Q8X14 z_l%n5Bq~+ChAqmZSnc4JSgl215(W^KmsEuZ*F?H;3%r+0hM|-5!YysPd@(te?jt8-WEP^Y)TO+X;?GeHHvP?E}RE4Pn z>1~aH9eAvGXYyKJb{Ux3nwO4e8ylmA!t$}b`B%dpjIGTQ=gUJ9TAvY;BxYJ8q7y3c zNa$oGuV~TJC0f3zv1TDjXR(V0{Jj(Ikg8VD!`9p(p@%QrR@p>r?2tM(q5|Wgx5CaP zMU4OR%1x&hI8$a?qKFwmf#PiumhDu2$&y!K>7zRPyI0Y`(w{m?n0nE&=WHXK#91R| zInNlbIBS4B0^+Rfah^Be)f#P8L-eVgr4$eeQc*ETOPP@hS~yl}SZ*Y9R#E`K|m@v*tqiQ{%LP1d!@z(b0VmPr%TVKxsh6(9%E?FqAmR)#st- zqK$tDF|hFuB?4mYf9U$_>_bprXCIpOTK)~85@GAQEW$%9KsNrNL;&xRhtmk?>_bR? zoqcH9Ysoi+W4yC!p_BCmHRBNTUC`oHR( z8=1I~q>+i7$WJjdb&Op|?)&k#wb6IK6&`z-DPFdf*#?uEh@mtD zqfvZA9N*_p;M0*r*xw$A;6u+fVjr0G4z`|_OepEJo zrQL9Zq>^(eQqo=z=o;C)3P>UwpT6J-{cL`N%S^3=r&R#tdL3;v!LMGFA}V^SnX_`< z&TVD8_@up1ZYyDi#GT5c!r84{)h6eb8zo^KjRQndAT2!NmoqIaW^;@LcFS#;0tgOjiL`4Eo zIYs%*H=Q-HR(e}*vY-xAtd#{LE7r=DkrkWDsF9ItYm5ik6kA7KY`xfYQdkbA1!9YX z%`az$#vJyu#U9V$NJ&L~I8wCK$RQ^8^k9-4r9TLxhAX0;v}pW`75>K(EG5-4bughP;EU%!JKt6izJ+B+-9Gl)|f z4@!+(%3rj|QZq3I6-_%13L$pT+HIcELMPW@Dko=A|yIop&ZMOO4hzaGTbK5){#W(C_>xSi9XR#*jp~nQ8EK6^kgwK!r4Mn>a3fkc>pz*WeJ5L^2TE?R<`j#%;wWpR)v2a@TD4uLd zJ{*N7qo|G!bfBVxOS36yBTt=XGt{2OL7Z%in>w1aov4$g)6zs`wt`#2yCM)QE05z5 zQX5lQonIo0GACNJazCpN`v;B4e(+vKt+0B6>^^CIgiMoE z`;Mbt(^K7SFzpS!rj$vLr3uz39hyqbcgQWEj6`O$rpZpysl&7qha*%SdI%xGg998e z1jkvq^j9>1t8pZ#IBv~6HjNJXT`#Ct4^7?GI3q&vZzIxVg|j>t=K`RmnL zQ;1u+uS&!cXQ_%P`nR}OiQ{*z@|vxE^HyUxD#=BQJy>N(ryumx=al@x53aUoQ-{P2 zeq3ovBa17Kbadd#=a|4u4f8qTFU6Ik@6|K{RmQlMM$%0*khWsk6s`y_58(v9aK-YF zCs-Y7Y7SIaRxhtufq&(p<#Z~cV}oW73CB&N1wt?H&{^6k*V4JNq7hFW5u1%-hjkF3 z1BEy#e3)m`<}Wsn(l8Wl^C&Ju5t~PO$|iPQG|^;^RIsb&+`C$xv-=A_L!q&Oo<{OjmSgm{M-6VNHD zYLY!zGdSpgR*!6|hKROM46Stktr^ob%{OiNA>GGu-9aOA8Y}AFR*ciN${Y=9Z02Ck zJ{oi&$TAw#DWeJ5MWic`G3nNr9EOmZZ{`?K^AuyipjZULJp{JPGbELNt$(ZE8hU(i zmvN{oApEQ2kq{2{wFX-aEgkJyR>!uAQ{cp)6&19#bzQr8QXEd&7e~ffg966_PGd#7 z@qxDSiM1yC44y`cLN3N|ZQ&3t2VkWl_pG1hPU0#H!6?QfepTz&v_#{GS3ym|8e0r$ zC9kGEw53DDGlKguDjSoDoU3)L9iOwVsh<>PN{V z&)c@zp48k-iWcWOV}T6|j7V*DHHXL~I)&YqN892t^zdEIPovaGVB5ukGCPqsu7BV2&c z{P;JC(p^9p1s0bfg;8MP7*ZGo7KN-~q((4>j`8cP_CGE8(?u3C+}DN1#lmGcZuM-L zLsR*N$1H;R7F^qa)`J%^)cdJBXQ+&(Mmo+H+SSnlmp@PGg;%&jq!(V*3XxuTB{QYBN0X6ek^9-+uZW^T4eP41j`qm8 z9brFRO5okz)`0_n)ocd+w`}0*I>SNA#`kh5C{=FOM%u;gFhd=Hi9VxF)T*^~-9zqM z?@&FQCx_;BbVI!HPP=bnxfi$J(Y<>kTovd-xYe?*EpLAdV6wTEQ~Lju+c&`$w*T_UP5<>xk$EpM5BG|fv8tC#m19u zxhRdNK9Ja!2*-ysz!w!B0uW2Jc4|$rP+zktO=C0pp1_}#H`ijU#=ow85B55EGn)om zFXz}rBH2_=v5_u>gT5m;ysx3R5V?o<`Gi_vrEv%~eR!Wws0G%h5el`yYL-W+o1!#$ z+T5;Y;-Ws((dAy^m8dyEC+GTbD|T2oH^f+c5XF46e7|O1Q!1Ku>a}p+9F}+@QGX2E zu9D5xdpPe(Z>9eYIUJh9aTGX^<6I{RA}TX&|vRt&8h!3vBYQ=GSOIw zEfTBgeqVF?WCle&2(6aYbR?te+FK*-S$0y0JHcpm&gw4hE0Skain1(3;MK}Tv2#&w z+_R#Uib_EXT1X*zO|kZZ8_{qIF+Fyv5c5ww;wc~`jCrgDL+X;V4IxDCY_~|o+M+dI z*qYDCNk|YEv6+J>nodVB(ZDU$2sy_cj%$Z`Ph>fEJ9sN;YZ!_q8t%>*uCUgwrKA`<{Zo7c+ z3LI?>JG=tNS;G#mz!6rK@Tl|0%0KOmb=n(jzTRmNbo$#ib(1Oxoc7%MB}3*rE0}hAfU|t0m|K>v2&Jq1&`};{ppGGj zfHp1KP0hCOGrnSUj=wG;YYg&X)fIM5xi-gS8%*u&spl*&Ya|L6q(>=79*AZIyF^5x z$W;Qfe-ckwnJFeCe8-~&Fzd#=SiD77kJx!zE0=X?+y%|)R%xuGJ5s`1z5P|h@P6mgHIE8;htZo zh9(hd*P0C2^d=*bi0o>AFBD1!+C`g(uaZT~Vb`>PP1i!~2HqIx6ck8xlPB6132s#C zTh76zcrqm_7>=}Rww7>k_Zo3=A&pVd!=V|fH}5i(PIQ$asT3sIdc<9RYt|4)|DI4^ zB$neUx?DHOVNF0qjBbp^%Y&4h{J&Y-S|j!d*KY|YI$9C*M$GHz8#R2yCiKI5c#%7z zy%(uyYyItwf3O34NZa*kjOxf&)uhc=XiUvkq0h4}vRmsDAH;7IZx2Ea?jmrzM?*Xu z7U^D>?zw5LF3s#FRTzrebXBy<)w(ktnW7hctK9EE;a4R-vBI>DBzG{mfXo0Sr4 z$N{9k{2mD((X@vmVzZ9ZRxesOrv#gGN%f=GE<2VBUb$84k!Zplp-YUcy9$e&a&1@N{v50O`Ez!98vr=fG?#Nldb z0jY6VR)!4CG8p{9Scg4*-Tw6+s%fE?TB|Oo5{a5=p4264MaDIMD)}ukGkeu-fo>dH zF7huNZANkSZ^E<%6BygZSoP7@)|z^%k>PXcU^#1snv+57ajM7H2E^78!TTEeSTI|O zRXd_op~cszs=VgKT2Hgv%mOchj^oyJb1)i?HwQIa`mKewGHXjTc`Q)Ib>iurnM};i znCewT_?6IG*qa+OX1Y)i2vk3XB zF&+joR!TRw1yraq*tUS|IAz3}+syu6`9?#Env$$Jj%6QdM}ZY->U4e|!rFnr^_GFE zEtPT9D_O7wA6QgMX z0z=0s(cyklauQkF6rrv!waF9#$o??6j{?oyk!X=pl|#u51aV@Y&Lq1Hs+QP7l{sBB zqe3%HYmV5mFBVP8v=vFOE)7;i&o7%mk)|1k6o^#Fym&ZGf+#-265vN0l)$SaS-PNn z=8+YHs3I%Ja3Z553_UWYfMG-io1vR1r|LyUX)6hO#;PR*=LG|u&?*7eqJZUVUkzvt zS+!4;UTbwFclY2wjYj%Z+*@}A+RWN7?D+ImYoMk33^H-{iSN~kVQiw}Z3Ay&kPGx2p6lM%k-#J9DT-T_mg^RE{r8V>k8 zSTy{mOLSMcIO{|95~u*>TIUI?)~~`wvMfqbRg}#PNQGksBkgU0-RhftjE*tT(B>ei z(MLJn`d~m|F04}bwW_Qg=N-@oCat(CSj>e4>(-i$)CN0}Sbc&FMa-tmF`HltCldI2 z-kb9q7d4Wo|sq}t4&a=nNcp`fB6HRwWd6nWhirIR8$^yMqt@|V0pFw4511G8S_ z9G0(44#%2YXw4f$n665e+Gj}^ehthnDnk#)TG$?F%cHc>;S^LnCG}th#-hgPuxX#F z)HNEUJV~Y@UR^uX$h?C--xzgv; z1#qU#S@Y%8BR+_FX)|egMqc*VfLzzfiCnJrQ&J(7C|SivBWBXr=Gc;5&9UR*wm_sk zWGk(3JGTS-4ymgVBWW7a#N|F8?R~uJM0RAXV+nFwort$3V(}(*x?n3DPZ``U{*;PS~#|X)`&p1QoF5-Qm&1ExH5Zm&p|8w``n5QH$0^E!-lt~!&ONh3^@s&`3O|HX9`alZ@vpC_5V>x9 zabkaOl1!ToTE`7ydXDjTEB<0(iIyEjWur9AobOY@s`C+T{KN)sDW*{V>Oz7yPsmIK zUoDi*GxXf-=ITrC7z`p~Sj=jGUN#h_08ytyK_9>Xzj^r?xM&o;1a1D>OuTRb>C}SDaicJeF(L;l^MTN`^j9q#Xx>O?RX@oP(pu?ihYb zkfV1>WEO8rxWn*8>f*E~06wYr-YnP@NaCGt$S+n+Sx~(yvR~L^IpbxU{;X|b!D}Lw zJE@mVnzxKgRxg?kWD!i9G``O2O{tJYupG$e@|J?dYbt6zQEB~RRL+9ts}*U-we<L!to}^qBj~pW9%$)_*SYbE4-|@MP3-Q|K}r^UP$=@FY%i?vQ%Q zGKZVknSu7agL4|q*9Y~TIt%r=oNS~Q^Of1-X}LR*@%m`y7E~~BpEgI_|_N`N)&?j zWDV`zuIt32B|diE5NW65Z5?UW(QDaEnp&|3IF}TSB8!aEAQ{rez%P-W{uzC?8Ty#+qf~stpA&wm1=bBONvm31f@di{$ohktvQ< z&Vt(^&Pp`52j)OFxf!W2Zk~(hZ*bPAx!nV|9dPT`+!ik=X8Yl`L(^|9+1GM6gz z@C@mHvobd+bCNQ9r%V4%WqOqPmub>{0m=aVyvn>tnNKQn+&JmKR+$$o^EqYC9WVVq zs?1xJ`GPX}1nIw6nH!XuROYQpkH?h#C1p;SDEVB{MnCntr{?K3mx*DD!#cUaI)aaF0{= z*=g=?qFPG}aB+_`U-KjX?SVKOo#sZL9n)56#?}ih<=6``s7XTmrvJy@n}AnUU4O&toIBcV_wnUau#u zuDO}$Rm8QXxw-@KoL$}7$eWyLPoLeYRfX$`UhMbGUjh^N)5Yu(zs)n=>X)q42i9UV zqx-0bq6abqDdaFpIS5Sm5e53&v^TA>~Uf<^q@UGYI$^qUT>vL6qiT-Ko7ew``WO{=#@~>2UCp`y0gq>K7 zI{qK=Xx|&dc|{vCnP`5Wy+~btYbyngvnyy}(TDnM4IhLxEk;~LnDBCT09q3`U8aI( z3g;j5hG+)zBh_~e8|53fBp>cp+8TvUiADDAHuz3V~zmIBb;QpagXlsaB zXWjx-%=&=zq443D9Xx~eAuyAbOZ0t(^gR5j@8oeh?~WGBT&F$DnWM2t>|*y@a@XNc zax@-;a6Ellfu4o}IX6(&5nSIF@SqNa)&s}Py;aK1&Fqcxpk49?DqNU^wPS-bKtH~p zj^IfCf7wr7w4-WsEu*c{b&SWKUtq}nTS_;OB0q0&(H%79BbjMoA-nM;h(l9>kT=qe~M4*syD5p z`@1^b|5De4;+l_7>+SnDpFVfJ;z+}b`=@JAVfChs{x`KO?`9;^|HcPacA+i&ALIid zdJnG==WO(S2!aZSS1l(prOm%G&z6qczY;BF2X&&{ioIogSmo5|J#a%WK0W zd%@QBRVPam-=K4oBu*6nH=k6lYx~sc=|MLE$KDO*^mDXj`dJVf+?8|~sVQr3YG`Vy zsGK%PPx8fyeYfc8YQr2fAG&uYp?6EU^XkP%z{%gZW2#OcUgaHa*-mwGSZ^BE^S@L- zKBKnZ(O+1%6dRckqoezc*bUc2UZlIUwV}5_@?jw22&lrf(AUPBhLaurruS|1JogAc z#0jKl>I3576Ykk%zHu0N-I+v!OJn*`Klnt{H9X?`S3S!Rel2WmUs-}HGb=hVHp8_6 z`Y9%Z%NCB2|5#uC)yUA_Ou0?yZ6EFOp1vm4Ya9L0R^C*`#|>aF6}CaB;Lteg=u_H#Ep+e;Vrlb$^Tq z#bGpbyk`1f+V$S-c@w$Q*t!mC0UQ3MEDmt>NE=ad=IdRpGtFdO*A!li(aRpr3_in; z)a!nB#e)2Duiu!9Xf~Cgt5=5G4yI$~qJ)QiIkDMu>g zMY8;MxIruk=i)+>9Xs;5ubuC%pv<(jtMNhc&86GQZ8ezTydy>m@<^Zb@| zP%$TZ#WKI8x3cfOKcc9q8JR_N1*hVquM;>nMpMO+;s`xxsjP3urdo`Rd#&hNQ%Q&M z(Ar*v)BMpeVKR$vucNJaS5RNGhU@oUyQSv2YwFuKltXO|EjZtnVqD)yi6@3wQb)=C zYBT@GfBpI*oRegHtad+9CI#A%R1~*nN-*5? zY0aTIY{M5xJi*==x{yTdC8F56uCF6RG?`Y_uc~F2Q)_}L3$2Y zy*^002pcqgLHZfvDsPbJ1Hx`NZyUJT#HTMcf}2M;zNLk^#f0msb#5Q&OT%=47C2&s=??Mk!C-mRi;X;!7c3R-AnV+!7B1k(4We+wFGs5BPB=(X9F&iuNh=a71 z_zUu|J4k;+c*g!BxcW1#!oIU04WmFEzvr(OXcjEKL{M<^k!w7*>G>O^ay@s0v_Q{Wd<g;j9H(y)^)In zlJIeXLm1)vFsTDtnPtcH~nG ze{sx%52sbeynQ8A*I-aU4RrM1hEmS|DO`BnNVyc~sBa8Fr;a`3DeD-#HKy+C1DFqI zZ4ex1xE6ggjze#o(fg{tWo=V?YYXoRL|^F`iB^16Oi*-kRiS^wzWD*;P4C!>|Hbus zZ?8UZjH7tO1z#4GA%E(jcoN?nH3P?llSElZ`9M8Yw>3>z)iD88^8~n@unKeT6Pmpf zyc3Kz@VNIV*L?GHf05%P^n!GX_l@<{ZT(+!f&BjWAIO2Wzsg+_{O#3PDgRPDvmO7| z+#s-*{%X1F_23&vj`;5U-Gm#*5gow~?{q(eW{JI5RDbOCr`Iy?pThs%=QM1}IQfZ? zSf@FeJf9OLCaiR?29oP*)lMU46xaSUWCMnK;sKKb$B!q~Ffux=f1P}m4H$lJ zRdtdZ~-%s{l&PabU%ngUr*_N5QnM`=pIKA74as0-2Tdqz259_YXFUEbh$Aj(RaOV zZH?bw7pzau#x8}rn);0NoElGEPOvWMsm`qR)_M7QTYWg(m+7acWzb}-ZL@zvL5 zWM^k(*4AWa)p>HVYW%*;bbl86c9Qt^O#@?aaf+oeOo!?XEUuR3L;o-)KQ?lR}bVukJVN4ditGWBh!wU1-N7{#5>)cB1+u>4dv}_e_cy4;)UQq~Eo; zy5K-^Vj+P~Z)|97-*8Oy2h8VF-biX>;6UMEVmFAAk50x3(H|(B`Mq0Haa1;swog1M z$OwyJ!0?P)AO?3etMF_mQ6FrbmzXGI=mBdfXBuErmMV97H`x>{nB~#y6%(7^Qr7S zORJ~!WOv0I$sD+xo$7S>Q|Hgg4!a*P9K`eJKSF!#+j3lCJ$brLb*IRwzV9h7LuZF4 z$w&SFF~B|KdRV7$r`It1<%+t5oH2A<5rkX@QjluK?fW>VA^yO_(*#e`i3$q^ zUk<#s80`sUdVq2%(uKH%1Lv0snJVBt^9+B0hvysqEPy|Yh1+uA50?qIyMdM}VIK}` zuNC%Pz-zJg^clipT-AVY;WAMh@S;Xx&$xUg$`I_UfHloTyTLQgY(;)1pnL*5+OVet z{xE)u6|vpm4*@M}gg=b$uR~tL?SA0l^}?Rc;)jE`-E4D5FU|EEj% z&$wh0{zve?3TU|)WtG1d@W+=3emAgwv*6o+LoOG*3;5L*=$!1m6Sv{3*d70xsEY#2@(5(}Ldz zJoqf)hWt4M{Pual(=Rc{zXx%Hy$d+wCBc^i*XaZ%U)Waxx4>|n*#nIG0N)yU z=mHkN)NvUDUIDWMd=Ky-Oc&}&`W;reevf#t{Qn>=FxSAo3z+&5{2soCFf5;U2>Z8@u5517|n{Uk?0fsNi=4Q=EeL0IydB-vivON^}76WZWMvct(m8Jfka0 z@QiuUf@iE6B6!A8!z3z5#CHUK5hHjkZBcZrM4hmA0W;zx+5$cgc+Cij#)IzxemPR` z6fe=YnnZWQ9!rt*ZGyokf*)n@N#I8td@}eHgC7Hatih*(A7}96!A~&wH1KYN_ed1( z6Fj5KFL*{zrr;TuXG`=1;!_2@Vxr)?flp2r{BGc%rV9QLaO5<>yMVLv1z!$KD>U*4 zsLT+2IPlNKf;LCw&m4f#GpI#u*8;J8h zVD)0bw*hZjD&o@vd}+Dh_W}PA5Ii>elDS%Z!_?^H{E*JbEV9FJSJg{M_ArIVsr6CXeq}z}Ord(~v0~@v(^1$ua81leRt~KO= zDc2kFz=j(PdEoXN4SC=vHyQH4lv@mWV8gA3JaGGMhCJ|-+YNbO${mJ0u;ETa9=QE3 zLmv3a-G)3cz+5{fgvx5avsjO$M}B%N53d|4>02; z!RG-BUlx2h@RPm5?IGYLuL!;y`1PxzKBs*WHN7VIHlX|0qMUnxpT8maL%>Jg68uhJ z>)V2F1G?Wa*d!af|BVa5J`)Ejxgg)rO> zRsq);d>3$&P1fs{Zs1P4thYOiyF!HhZs2~0OwkC7(HbiJ2?s8B;;e%S@Do_B%Jk)U z^nrm7z;IYQfmemgw0o>c$B)6k0iMwwfwL39dw}P|d#mIHqZ^ChPpD8(9S2ll{le0BoE;*g#(7_R}tMj)=t18;=M2G5v05_tsP z1AJDK=?S>q2OQ}#(gkdXS&wiTABWijp79-+9`O5t=O)VZ8Tc;X6ENKO+YS82;60;c zs)1qqHsB=&-wk{phU2^+SdfG?rXY>LEif$K4g3&h7i10r$B!2F9^g6{w(kNyVc72m zeq-=ZW1|@`EK?5L4x{G}a7Btt@4>zb_%IBIwG+4>hVz+m+!*jEON@Cilfg4S4x`5z zcmyU4WsGsiSd>ZdjI&_IfM;9|GZ{Q%Eler+HsIGV92TX@v;c2kSul;@yMVz7LZ%1!EzA?JXIz;k(;o1Q?J)0w?*WFmjj{yX z?m;<8#&-mIydu4f+YNpv@XrQ+h|y=r0P76C4R|vQr>h6}vcc~I9){^bJ}`!+%k&_4 z#%VCS!82CEyaAqZ4a@=XUBK~vnPN~*JiupQ_&>D|XwDFE2nW_1d>im87(EWaHw^pz zz|c%#9}b)c!{4+Dc)4NU4Sde9-v^A$5;88}Dj4>&4ftD_oruGJ;OK0Gf&aS)xCBQ3 zrohP)kuKzC9H{IZvib z!84u(vlDz9a1RW--4Fa2rVH_5JOXnmc*cxr2p2qK0n9G&jLTr21K$OFWIF#R@xKFx z=Nt7WFuFkerx<6#L?c|ra+opT8Lwm>ZW;dyvmf@1|A6@tJfmEQItt&>1*~ENp79_| zGkC@$FkRpoBa09R@Qh<&*xm!Y2xb||24l<&lz;GyZkThyGZw>igJ%pF_T9j^ViC_S z;C2`f%D_&bZKg~+@P7{nPML)=jc=3(98oIr)&;DD;ku;?cm)i9qi*02VGiK?GH#oV zGj+f--Ueev+IxUebBwYC{8bs+HOTA(9xfOD(_EQaVDvHuyb`7hGTp$*^F;lh2YeRh zZqA1ahO)f>{K9Copso zz9V?XgD~fUXZ#MP8$6?BG2#TCF%*XF86ymP7x4Tgutyu(4SWfv3hffEQ8_iRSw(=!}-$U_bw zfTJ!DG9F<1g@UgFZieCiR5$Q(gWnDOqro2n4&NkXT)*nrAD}$Q64Tcc;J%D4Ia1!=56H9e&EepL^*L?Aye#DA>#tZUTN^a*lvRd z#$ILcz@=AqMQ<2Ap!e;CJ4D{DI*z zv*<>YTNvio1Ah&}aXti8ZbCT+9}X;qVgHu_uZ3ax8-RNap7BG2KL8B7S;#OZ7<>|N z6AZVZjJphb#ytkl7;%dTD;jva!S?{OZ$({=_%JSm(c=TW$lxypK4b9D0pEq;c)kaG z@HUZl#y4Qtp3#51@Q3kcgTDp%J`Bt32j=$(nF3&|!M6c-!>|nFTX!JMX(oCbxa>~U z&)^xaxC`G7d^hk{Fna$7Xuezc$@mt`8|)TXau5Fd;G2P4V7NSA1I*iwx)t`7z}t6V zyaT=mSb87oI=4y3R`493Yk-d!{Lg@2!f?C5=(%6;RS%$_4-*5oUBHWBT;O*C{|FO} zZ%q%P%)r#49mxY;0>k#*z}F0ZKQQ7UVebM?HTXQ>HW+r>1N@W09|F1`Mj60&^Z?H> zc*booW~7VpewbqLjL#Z8<8KU}(fJ6>z2Ld%2 z)gE6~wm*;=Xl?7jSwjKncUI?QRoChf3*`84qiuE&7m<4cEA?X+b)ocN&|6<$lS8uIr^LCI?6M* zJ4!s?xv{XcNS35@cF-cxQ?wRLLRYwr4l6k0Vix7`vNEU>_LSDq2qjzWWuY`XrEFMb zr^5+>j>eX{^_14KHjOvpP#Rw}nHE?wCmjbedA)_J+B!Fg!?H@&78b5un@VaDIkAff zmv7c3le4;^xwWRcIh1b4jvM{RQjeb;-%547p)U~RZ9bINUf&!+vDJ~h|Lc6{65^tn zwnl|+Z)AUBPEx5BiYn!sqRZDu%vQ9MQ2XmhJpy%R)bRvbYLTl;-OgLU;KxShbdq)`+3IpvWy$XMKrSZ{JAy zd<;l9z2@~o@u(JOY(tH@KALvVsp!lU+mJm3#wC?Q5x$wzJc`WZM{PwVM!p5=8S9@oh`LuEvGp$rF?!@;w_s}aTo z6PPPtaWfE#HHjf+Fz`NV9k3h7G2V(76&5hp!s2P*Ww3Bt!CVE4TY+0(5o!ao4Hjnu zF9p5}yfTJdx%QvQ;~j`tu+fhAoR3#kUW$P3$#^qtBW^>s@&7o;yL^%;4CmERo{7xo z+UYel?EJ2-F=Rh-e%Ba#D9K6W_T#n5yvdYgHd{!ZMm6SdjvUE_rPu7Xzemz2iX5f; zkz$Srql8Rz7~W)=&C2zrxFcl7iG|@ic(-WOcXq1z7C{!kZInD&N}h}wswNTNt`s)I zN|s6Z;787$CZCOodigFDFMg@g>^J?WeP{X+hi`I#2C2H zUaLfS5EPOHFULYQL1e%lf7kprLvNxFudd6YUv zIY?n$D1lP=2g|JSkdMmCqhuEZhncg-me0*7FgP zm2SbN?*C)!`TLI6^BW}}{r{$xH=8!mfVF(e3AKEd`5WiQQU*RzZyir}_g3;z-`Xir zRPvY5v6XyOiHo?BKd*l!|J(qT{I@4m@;miP{*7ZQ`NKFj+jL?j-)zz=`MbE1??!ED z9-xx%KE9GaaBL-?8m8=^DARZ;EU&ME*OKy(Mx%m%Z-5Fu#&VhpzRG%R1#iBChDu#@ z7Wxh5-YWh!y^23HU=@F=`h5ZZFulKNu3k>y;Oh4UmIdF}@4UzN`}+O+`d#$nzpvlF zuiuY$;Qy=j`{I68`ZQO+2e5;y-xpgJe_y|UU%&rH=4rm~zyJ4VY0j|!e(%w~drxoQ zz25}Q#^d_#LrZSg`|cN>uJ10%$4}6RzWaN}^xeOe!@>sWyLa~MyWj9H_T7yMnrKvZ z$4=0=`c2Rn{rBwt6Eq|G`tOSdnxJV@{vcV)nvPlpBrE5_bi{} zqlnx4X2^Xs1XJYj<@hP`sWjxs@pI%^G;E_WNuEU`+`f)Xa`l@g&!OKPohDzJ<;$nY z@a!b1jHk-)r=jq!-(2}pe|83iA2VM*iL}Bj%+FSIdOfu~&%cslc-B0fHe%L%sn_ef zm7?^i^E$ewZ|2-7IWj2Hn?Xm$4t@%qS1bmeL$}CBLQgV>jwoD9jeXPT7gOEQY4lCh zIKVXerPQhUn4~lDGs$3*$s~(OHj|u7sa>B&-%NGtTh=DrQo6ROw*EY_{LoQ_IsEnw zuG#cgW#A>2F=L&MbGYQ}$C+r8oDQes2TV}DddHb<#{6MRzj?${mDBEl<`Ivs7j;M2 zsG62omQbF94x92Y_l%M6e`2-h+YnKxDQ)2Op{KD7#pk*i3q%+8E)b2ND|=U$Py>Ww zdU>1_ufB^FqoV(htQZ~mziq|n8GE}`BBTEif&$fl{!oABbs}C5G1iG3|Lt`mWB$;A zb)x_B_)=dFYBkn_BCt|5o)^{zu`uND;Pgx~-AePY-p1z@P9v-a4I{dr63zXWgR;!; zIs0`qx{v8-h;<)K)?wL(Ck*4TUWN(77;?MtG;G=h=SW9z1L0n({r&NCgx}CNchErn z3|^bM#-uL=$-5$!V}CPNPI%Ep%oDD}V$d#QG01F2(B>c6l8a4a%u$Jd*O!m<#h@Kx zF({$YX~U_HRaj;TjUAh7vtUJM57uoeEm#l=d&i*F{zAe^*sIRM` z{nA)jicz}lQCQ6h%afvf(NZd}@I-axku;J}6=F#Rr?6UGJyKeh3|{zxOThq? zs|i@jclKZJk1+jbYVfdH92<+3{qZDa(Ew}zh2)TT(h*g^Mk~;d(zqyM5e~kvvNConcu$#*-@|hGdIl&j$&Egjx&3Bj6sd+AyP0|W7UoOigQYOmkYMQUimDLWK zr8LTFJC$qIFG>OBI$2#ybJPPAYnfnC?~#*`Ve^z*WpyPo=2|%g**H(DzE4`HTqLV4 z$e16V}mS!lcIqRk9lK1qN zyr)l69*b`-MIg9PpcnZAu)w5-sAQ7d=|}rF9Itfx3XQrH!!O^;C=?V zwd#@Z_I~~zHuV8%jOmp~Km;VifL^7T032=c_#1uhn?-KCt>rB(W5aFW~WGQuiQ<<#>Ei@+oIK07CdhA^f5t%#RR$v7hj5 zXCnNhLw!m2Dnof$QsY>*U> zf8fVZ2>aBVkUC4~AccoJ!$LwrB3!hJ4-a=u3Ia0zDy|j(~zO)UdXd0!>^L=SU?Pg1HXlSXz^iqtPteEU5s?MXe zre3>+!p^OE9*}%Y&?Y?~p@}lMEOmh?(Q=_v{e7s}@w#(xWf36`zUCVpb_O+H$(aZ@ zh7Gpn+Y&a&%8YBioxQ>t%Bx(VDsbyOTA{*jE-Lj`r3}sUs+7%SA`>*~1~)~$%@n3O z+bv@QZBLV$f{G)V!Yzj-bu@*T)1)JooRzo)qn7nPo9pwNo7!;gNW-}pAbz!ATzRlk zR;N&+wNO@bNwa6l>QqY9s=uajA<%=IPMUfy>iAX(9V#hVt(8Wr%Yh4}vFcnY)a}dM zyVy3WBzT?4`m@EA<+IRNesb}cjDU&827?`vx|nh;*GlO1PPU<61|PO}jBGnV!88 zmwZ53xDLngx3=6R$4UXRB&@Ket_aCzmoqF#PAwJKW^m6K9p}wbnSGY52B|=Oj!f#0 zWtUt>SWz-Bl&&*B*3eO4Zp@vN-Ov&9A%%J@3z zmMJotW{(XKo6< z>VzQArOzd#3$eE~Va7uXdbI;uJ`Y?!r7j>#yK9hpk#HS*&r7Qo#y*HEkt~3;VG!zK#zM+RyMppG%X@YGUg?pz_qA$>M zp7JDjT*iwod^~sh`#LW7=p7f+W#mpzf7oJDpEQM8W~7>{yBrodrzseGT0$8vwIHlU zDzRC(=$2~Lw@Q`v5+3T5sIO3rZMj*km4_qeW++Sf52UIU7#RlmfA9mTRKY)_7M-w3 zGM539<2y5t^A^!${$qDaxILnOETZtjgGshf~FUzlS32TkfWNkS9hQEt@JrrgdAN3vF(AY~|M zFwo;wyD7~1iA~G+xuhb$vK6FqF6zM-(LpcgOrIuAQGUyRobl>Vvl^c<)U5nkLIlPr z&vOKv>Q5yTVt}CrVxZit_XpMQOheS5Dg2Z{Th*zi37XF!ZY7^Mdec#ZPBppN-p2$( z(Ww|_fn+EpxxQP8s|M zTt*YM>eW&SSE*GH{~5)oc?zjsc__YrsglE^+*oy*9D{llg@}i_bM;}anr4a9GSVy- z1y$yJnyR3xTZn-Y%Etoo>v2$`^s=H3wIrwu%rOYM;G{uEs%d7_QU=L~S5|eHOzd#uEx@{Qpnm|9_gf1Zfa5%P1Z)C2Wa#i8M26G4==KM1Nq3DFyZi1U0}w{=gD5 z6KUq5YRo(-r>SoJd%PDV1XD;(OO~uABG_qUo3o}ZfOGfIep+~rNxd91QlrS4U3o!a z2d0y->ErVXe{+4ua>>+Q9v<9RVXGw7PjQydWi^wAS$|Jz2E}RBZ&ITDY+23W2@(pi zj-z-_j-;khh>|X;9tu?^NUED6wCX2mgpwes=@e>RK~ER7;vVz*d9Ca6Tbtb!Rq|>L znQ@+EW?^YS`qfZVgCrfWxXNokE|H$`y1apByyKgiN+hm$?d$Z0)q!f{amo$7i)W`M ztB;YUd0vx>napHT!elm+*y%ps%DVgS`GNwgR`F@;>Apa)&6`=Wh@?mB5;DB^jdV4Y ze{D7|ql5}?IZa9rH0|LAEytpl&rI7-_6F8fER?McAk=w4fduSZdmWH6f&m%Y5(ove{P44Zy zDNSO6&X2)OWiFF6Sxdhk?H z8EUSLcJAlqbc*$l{70T>{~Py{rsx%JNErWrC#pZBA#QKxFgahRg*q+h#~15-o|ZjS z&eyVs$c0*Vv|ONNM==*E7i-xO@)XMrvC@U+L~rIY8tp~k;pJ!xhRECth8|ms=8VltK^c>&cQm=4m>@9sa$TL6m^X>+MVfH zBOw&fRGlK+K7NAEk9OzyScYk;PRI7+C+K_<{dPFKOID_kf^U?IsS!9qkTxC$MB`z+ zGMxb7(wrzQrxTMClQBuz!LgFmc1)j4q0xG7aJ;cvgwX=x_V39JWlV_3jgbGha)U!e zHcUaQutwxRo;d&c3Hgtw>6B{MTP79b|J{szPD$jjwL-4}9+na&E zMJHMWRH&~`8rrc{R^ReVrWQ$hb5e47)7BBDrwBEl-*S-9Y4X~?GNDREH*|_L*^VA& z1$oumxGsH{YtVNkOb5Tq6{^AIG8Zz;``h=WAH5$Nct}!RWU+3P&?3tAx!lRJg#4Nt zMALx6RU~S}1QnAEkf%*`%-)*;$8c!yzdIN>pe@1YNHZ%J#_F`NP*ox)& zRTbDTiMuqW)z$e5%7a&FITeAX7YI$@5X*1TF`*&$hq)b%G=D?Ub?;C_NxWG)zcplo zq$Z$ejg4uVCzqTfKt_9g8s*F>^5>8IvrUN%J25`ULn);4i zlrbbHK)Ed~XD>tN-Wx8V-xZGP9wbJ+SNzpN^{IvT)RbR{U?q0#(#L zXJZ1r_sN%i^hrTIw*l`aV_9Q8DX1yd_j}68Jo*%3x!t60=<_sGEjKw0FHgoRkm34? zy=IxP<9TU4sTYn-vTx+(W1M<1MIovebN(Qd?!*2^;$bePj&S5M`ztH%)j&r>Eu7Or%Z)m3*^my=6FPiZpske1$q(Xvkb z;PAf;RbQW(?l1JF&kK{bg`pwNnVW+}zq(vfAEikbVZSmi+ia*`O6vaEQ(T4FkKt@V z!bom zka@Ngt8SaYwjd=;TCO>Gv% zhi7~=EWR?6l(=7D4V3?Gqih>Ueemh=@+{IiXJOzToJGFy%oinheQhbF+s@)K_5}Im z5xKRkb!ZY2yjkUBUp*E*&{)mO{o!7c&74jqF_&Zc$fRHn>rMVBDmv4C1$e*70{^0b z8A>TX+R)BK1E(oB>_zX`3}HPEQFzcr-o!!_yMW(H83EGi(**f1Bh)vr{xg#@wctz? z8q6Wg!r$XHEXp91eORNJgJILF(iHheE`ZuA$*V^hEb^)z6hCH*wI!dtb@U)5QRloO zMPiL8LkpH*c6G0m0jrmF`jV6l{zWO<;R{tS`#|D3hC-~z1q(4{gPEHmN>ngWQA94~ z$2_CqQXiGZY2HUAtg9LXBmPG*{SA`ABwhVQm{m;kxY--0T7!9lA_7?84?p@au>hE$ z+#Ck)%m~mcBp(%viH{-=SrXo||en^j^sa z{vIjYvfF8^a?m1*_derP(5JvEsa`rc8%xFPO(`WSzv9s!{=8CR=q3liHi#k=x?`}C zj@KM0X|~?-bBdDYILs@SeUhgrX^!E%Tsas?VmlNlU_aAE79r zgDoMSItDBGvSYAiX*(}C4yr6&I9SQSl_fPSw8|0hiwOI^Af3F*`o18Yu2LG6;`99e z92Lh|$dwi-77fkb6GP50KQwmM*O#I9)jpfNa)-oCsT~!nJ>GLQVGen$vW3*&VC?2e z;>oBa)b=1)*i1qL>SH?)FB41@CrNg9dd3BFZ6TF3+EbVsW*$*xx^Axds=1awR=9&T z^X3scK8rQqDk_Q0%Cl(RI-J|Qhh~~SY%+H@Yu;vBq`pnFoYqQA97b7QGO2CYkA3fa za~oNr7O9_NqOF4hny-V(l)tfxSgHC3l`FCd3Q^0T1T|MxOi9X!pgPnvUOk5zG~YS2 zP)X+3m3X~K$uyypUZ;LZi`61ibiDT|s|I7TK5kXrCKLL%d8|A23(8WWd9`4wdZCnL z$w5TFkWAJ?lDZjnz*$tJTq&t9LsjZp3H_J?HQtn>`QlCGOfZofZ$d97-c-S40TZm; z#GBClVJ?H^KxQy0V^YCn0Tcc0eCB34Uk`zz#vG-c6>5eflrmOaSWUCl$E74nN>qP} zF8)Jk$vDcGyXPoh#T_US<$Fw;Khrc@Ig8XZQv|OJinta!ZkA}uRjUnE@>QmYjz;>6 zDS+wEV-L`pb=48)G3RFmFaq;?`%c<%lk-qm?@>GAzTsmw3M_BjD9+j`yoi?c?Gji^ zl@Zy8-^zvZekUy&V2{9hs?&T-(wSg@RHtPy!QiM)%VLtvBxgO<=z9b<;JaF_i{;KM zM;6xIq88j>ZPkz3p{L%H3s`CL)f+IPx7nV&5o36Vt~fdDMvRHA_E@1f8B59?WQ)Uc zDB0pk3tVBJZtmueb%Et|q4Bu>CM>1q=a!G5}qdsx@8K;2=9 zS6{)3)^c>Af61#Ek?K=&F^^$>B1a)QhRWl;>|L~an>q-6>d?(;{(8f%%67NNqZ zdpitv7)wQ3pa{uQKOP;~-(T+l{=yEUH1-$dsK0nP!C%;6R2ON9QvWugLb;sv7-uPW zvPxu`@^hgQ2_4ivmB{Z{C2}^hc8F!aMRl4Iv2-{`!J=Xl^6y)DuCkKU!}19Hj}6Vp zkA!CA`*IOJo=HucXjgv2xjjXBjVpm^%FCR=Q$#<1L~gZwWLBf5hw(~xG3F96{|}WnUJz&X$FI3}XsAD0WQ>|q zpvD>#wzEL_jF0 zB(wwi)FD6QkwdZ;SUN9-6$Fqdia@T?E^ze?RP>+Z9isNXChAmpUh8TRRVSZ zUk!`4RfO zGtlSPbtLiaW>F$Wpf*#>5cMEJz=VndEW+6RAff>W2XzNw`Xf{&59+FtWj$AS9%!|>+V>dE~8}3MLU(I{p=zk%2Gt$A2^DTa4LAG0csZ?S~cP{3$u+FX2gsG8+gGhE@!=tWQ z8L2yn)F1yq0M@MZ>TaNnbVhD&P;4PrhsAq8R1^mn<9G$VjRFjM|G{52Uim8*J44SB zg@gydlgQ>k)ZWF%=0Y}@lFS9uf%Jc9xEX9=b|`1=CiH_)_4f#ei|3%qbLg&6z2pwI zJoA4b^s+N_v)-u}Xxj@;MK8~Z-{U!DhDKXZAuT^6c&526+6`xAuVKcS!^ z9nUrQ3|{hMO?mJl=N=i%YXT@n`VBGg-1NYOXC>w=V=tbNqHMByn;=br4Eztd4zU4-CUtqmiXnV?)gld{M@ zEcjy?-4723$LgRM*RVP$wqo_EgQl|vp&M;ym}Mo@L08Jkew(6kht{KvW_?1hGL99j zCMaH3GBmV8r?3)@TfIb9HQzFGCc+3;mzjt0gV5`Q8`ciRBilhc6jDrheThX!@`KRt z)cuWu9rUl3v4Yhy?5pzj_Z1H(_zFAdS+TDmM}5V^3BJNkXpOczBdpt?2D(jlWQW^} zICVKz=p?f8Xep;C$5zIpF++J2dTUFelQtVFY!AcL!?NQARawD`hdD}}uDhn3C3HyJ z`st9K%U?EIeN~RreD9cZ5r$KJ$BbQT?-*L3aKpN!cw{?FK|qR0Av|W$vHT#kL3MvM z*g>cC9o8v*#|+)s{=VWt=$7{L6?V`pV_!jz`ih4We1#o!Oy4m(p=0{C0v*%O%FPlry1s`VCL1lvv~W4^(Q&<3C4AkFeT8t5N zlGJvsz}{|!Frz-D#qrlh1xB1@iRH@wa*B8U2vQJc9a_|>m%G{l<^Wz=j+2?lfRrcViVQj#@W=%gmdXtI)Q4z8RGom6y4 zi)fUZja=+B$NHPhteDFhxUcCAnerP>e1h_RKh0EVwwA&Plwh3yv}+lEN4-{xc@2zU z%kY0it;Gtes@zXO6@TnXEGW-0JK{60F|&RZDoR$%gnp2Mksw#(pJUprPfzvN9IKIP zsySReU{a38$E?0#aw9@!j0N?9i_n$TV`No#@f_POQ!0E9!9yfJ=t`$Z1S_uMiLIcx z3Lz#Q_{@?q{GcnJ>gkMx6%<%^u>$KZQCBMp#_!dJSddhD=Q22 z%0pSM&)O)pLTjx_uOftc>l$tivJ_0IP7IG$FO;M4Sj@8{JY#_gC{}X4xxbR@1NxMO zdbVY#mhlFZT<_8UeaiJ5uXJTI$IGpp(@)nm!13~`3oIklZ=gB42s4d(bTI1xHPq!8 zt~JSocB-IXgd)|wTtDwMPenqoz-W%=2cF-tLOEL~zv7uKq5KLlCS2XHY!W{RC0OBe zJS?#ay_c0>_nNUp+uvV2oaiqsp$yCZf*kc14=4Hy%Ti=oxEj7fE`v@iRj#m08rcpX z)r~D@-B^n{oa8drjlGjXWNfv*i#38wx{B;Qm;xaWd&=@T9idXV|HFY zjoBhrD0E1pkJXqR3ysNhr>uf@H;6%-B?;CsKhGa!(ReDnXz|$(XTy9&pAxO!T4qSMx=x}* zdpYhlVI|t9%%;Ci2(NwF>OhZSCb?}{+!66v(dM%*?Ktiw7`n8mn&wd&>VbI8GhD_T z*>LU;4ws?-HJrPL1_y=O;j)L8L!s7(#vcS)wLTQ%bU1=6A5YgEDK}24&W`?d4e+Hi*p1u9u;9TgPg*wXAGg z!)mwH%vG`4Z9vYlY>t;=El|5%(5rU4gt+43dIQ}<==|``BG%Gx70S1IZ(-kYB3JXutsxZH`bEO-HT-VE&ViepVl>VN2$M-#>wZ=mAJs9GtH9*WnEvc zKP?kbmYwGHln^c(@TGbE*j7`PndZ%&i5EV|wMyw_K7X2THDh*KdOI-PXJDp4zbDQA zq3oaSPxEJ6c5_^djsL&+NAo=!1_Dd|N<1}lR1ruP2mJJp(5M1VwB;vg+TuyX!YX|? zLd)5KDZCtX)3&oRwv6r6qjA=Uau0iuB-D?QGFCsn6OrM3`8VgCvd|&&F805ecN_`i z%S4JDMAqFESkkMbe7{%9n^nj<%H6C@YqPEsdZK7uSyg!tt14UVanON#gq%#Eulxw> zD?h^e%8!sayfG|YeS|{bn4FJbd5sj%WSx$MiXu+o@vM+=V8;pxs>>@_b$Nv}1d_*S zF5fz9XvdebdQQG%x=oVqnl-AtsV&9)0}}=?9;=DBJ^C#Z_{0mZ{XR2lW z<_oz2b8$1{;%3VwV-?56t(d_Eb&aLyYQ>Qqr%SNj^!>>S)K6E#=c;6TjlTFMFGT&;EdgQ1YH*UDuCT>1x#F=~IikqOg`XGkPl77d{BqyH* zb=QkHnQ20v(-e+}2(uNJ&&1>U8k0(VQ_K%=Aq-BEBKL2lVluhYWTsazjrs#TdYYnk zhtRlWTt5>rjgPddHF=wI8wVA-0`hW81TsYTMcN0NW*Wo?MAkJlWikH*mgEkZ8O{MWm^>|i<#W> znCjQx&|H)D4N~B)L%B6+dztlwF^kJ_%u)Y{p;3H%SVV#qshWxMYtnAQ3++=DoT%_K zZqG4~dq*iZn;xaq3~Z^xk!9m9S8p&!xUA%+k2%3Q9b3|CM^m=agDeLh^DhIFR@^9G>3<~c#v>@E*iqmcQP9`l-U-r zaS)9PPmtU(!`P~dr5|SUH|Q_o5NvDBnB!2G}UckkK|EwjzsWr|`R+#%%3J@Cs;?r+C+ zBaq_pOtFX1+5rvUyJB-g7Zs-5Wt~8D`xmm7^>A3Cg^<=6d_g~$R zOr7H4kV`0av!{v@aab9--}JC>l9z?g^+I?!xqs;9{4)~#oFYhxZknphLF@$Km6r0>EhNvu9)I*l@yD|Leqz%QJ29HM)^tXhEVF) z8C7I1*VCn98R2aEhkw@9DF)*E#Cj83B`H{xE7#Vm5$ z3JZ4V^!X_eaXY3WHtw>iEOYHt4)5KmER&SWbZsts^B8;cT`r5{=dtyrI^D-~T*5R& zW;ki}EOg&A7Wy;O)b#1FL3SazTmtq^=itKgIk?Jv7Pv8A}PTT({%-X0e)M+ zeoZT6dQl<2+^f?OMa76^LlMXIhecJO-|76!87y<7PX984WhNIRyWN)*v&^rHSzaq) znHHV?vV>(KX0pt(nJlwIr(e!wnfzIx<8Gd%C(ixRES7SYveen7coX+LQdLE%QL{zr z&YBI+M(jf3yyX6FHp`XFL5O_C7-s_4B*=uEG7j^?GWP9PWspjZ!Dde`F16(x>Z3Zf z&uz1t+;itbDh^dC{^}?r2j+4D(&n+)IXZo99!iRPXa(o!(h7cihfY7KU>Q#((+euO zG`)b(-C^@tWS&lMn9nai)M@$x7Fo|CPcC2)(?UJ^3t8l9ogP@oA&ptYAvG^znMW7# z+rQ~_>SFNYu3W5VmG*1)XxI`KTE;Z)4p<-uxDiASOkB#LoyS7YEXC_o+cJ>>rOVjI zYjpb2GCjQI9Nx<1?A0SW{bD)GOkBbAvK5?_Z?53Ct^m_!o&GGqZ*5gf163?@e-&r< z;VPDyR?YN^YJU5kPW?43v$2L{UaH}@Lu)zxHMK1BDAREvm~7)pq@s?cZmnafgLQb5 zn$E=@RS2$l_H?QWe~TUe${r+2ilHy^V%<62o{bt~t>Pg_}p+L+F3W0C7v-nh(PoAqt z+r`b~Ki9L{ybXBazJjUtHd||F@5aZhJ3Cv7vKQkfI*!-WbMT2o*TH%&+8_;SGLQS< zTu2^@a~J;r9%+xWVA^@i-oUK9k=agWKi*i5c56WwTj>6kp3f}WNhJ9KX76V<=|cXv zw_FGdH*G@hxtDI@*88bV*frwTE@FPOPCwOY#l;BU{n*89AAbqc4LW`A61JamDcfw< zseLo^t2eX#+d4n_GPb#1r~kN&?U!E8HqYxcc?3riAZ1b8gh5TL+-6@&J|0u_o@9kgl{gaxWbFY1C7qgGtGh!HD%-p|Y?aIc?xU-$KW zy*__@^LjncInO!o^PJ~A=jZ&$tj8Pgpm@&Xuit@VLZ&-UDGz!4BaaW>>9Qby<<6e2 z*1Ddq$A57r{Vro&FoZW2j$mu=!tXU!;VZL=pWx(-GqiT%-AJjWlot?*AfnB~(y3Qd z(o+E8+^o&O&aBr_3f7bqe!EYbg3*|gkbtA1_cN1K_acJBX#x`xpLa#%14N>v?^Ea@ z`n)ZFeb^Qj6zR+=A2wJMkO}p z`F(?>_qZTGj<`3C3%m1L$&q?zvfzpPK{?JP*(t1Onsk^8j4| z&_X%nw~q{4g(z5(D6+_i{&`WxT4Qj`2mAb&;L!1%6jqI<5S?uqSB zeB9AXz75c?2?WMJ|7~cx3RTAUM?S8y?*(8=gaPBjFF?`Nz}Qn*936-e6JlW*hfeiP z!hrEBzY9H^F{rwD?Z<4mHyMHn!?<$J(fgK2rC6#w?*XleWbFuwt&kyts#&-nph z*P?q$Lj3+oPyKa2U_mEL(6Le*e9mU;V>L%ujI@rT&&MV4S}QJvPj)9}CDY z`aY5p@=L(HO&BmP{1}+)ftiwz$v>V{^w7%y{fME0dPrR0L{_ zP+4 z>*s7S{!zuzRq{`f|3}IPXh! z95vkvOh;#f{Od^{ezycrnLuE?0fVIJHnjZJ2EO9WNzj*Y3RV9?ATa(8MoH^7C&YCO z>B_qFxr0EwO9(Lj3Ob)%J1+>Uvq4_{+ez5@Zv*xp1Owv*^lj_yEEqpD2{>U4fcFRh z#_vRrHDR}iH%2glUYj!G~J6XZ1y0P)&4kaRO&wo1IF({T?>Y>7abY@iErp=ql~*S>W72? z<2#|M3ENa6;bc%zMaxki0`n1J!1%QQHepsL8anHIj97{u&+ys!Gg38KHj@Ri?B=zQ zHTi+Sark8v7JtC6&8WxM1DGn1CNORS*|Y}Vm}(o_~k;WvyVUKIxDA%N1-d^zlc#^=buswghDg7LpZum(H~4AwwC z8z(Yv5v-D{016QZjQ_j}ig5odF>5R&M=Q0p$#ioSRfw%%{Do@N`Unmpff^rx@lXo@ z^oy-v{Cl;i=~1c)ph%rx6UQ@lfFuHe@glaV)-T!-UN29M-P__ozyh%qjQ@KaYIauC zwBlwJ8N4b^-=}$zVaZhR`V5=t+8;_P|HJb+RFH4+=0&i^nE z?RzdK@nhys4yEda0JV@NFurjiH0{BKlGPM{ezLX;js>QbFkpP&vFOC-VfpOmqVgiY zw|R?f0)v4fwu14c$DyXLm#g^Q$N9}Sl5|5zRS5vbA6fz>-++>%2gza@F=bso9uSNr zu@#K-rGV_kEV_mB3zkkA9O?t8jX+?0O&<)#iM`!cjaikxjZKl40fVt7wu15OG8pr% zVjV4cmF@2@Cjrn-05Cp(Ih1^x`XXP$?_EBLy7v^II)G{fYv_|3|6t1 zwZd;3&N!z6h=D7%g7Ldfg}N8WrW6bNHsSh$Kd=&@G=aeQ_(~Y{om`w7{gX|*;&dP| zsKrJwZ8<}sZ=Md=ck$tvfA~(41M(_>I!O%}-?a)(+6U98?>Buv()w`SnZV2-3>bg? zOz8NY%Xsx!zLKpo<<$UST8OP+e0Vhg-_OP4Kbcz$^lQ@df7s@WVoaUv{oB^hh7uz?b54&=ph6cf9Qd*qa4T3ti_;#L&kq+!*@R?-`%J4`Pci%Tw1;XNGw5OD;Tf75w-mSwG~?U={Ne- z$%?!Mm}3ZoFM{z?K8Nc5y*!oQ^*LXO8JBMc0Be-k2o_YP8f?SO0KFl%#=q)geqAHq z0?Z;(0>2*_f?p!@*T)uO!;8^#XFE+LL`>=05nVQ!o3W22_eAv!8_rSH)++lCdcKwJWHuB z|8zG{y@cw;$z|Dg=y{9P^ZT~@Z81_ZZjGqN699}C?g8L8<;M7jll43^3;-5Wu@#KR z?n7e^qA^zn`MEe&($eep%l89w0%5@TtOuavw{DDI_wkbXN8I*MvD%8QVEm*9fp{Ao zu;al=OT~wQIFS%w{Je+Jp5IXy2QqP7qR=RNMUx$1upWzzV8MuNu$2xpjp3T%Y9FHp zWx5@566pcsOCHJMg`L&nak1e3)gLc$FF%@Ot;>__{H8AotoC{|qGwLxoFuEU<|H1g z+$+Kb0o@|f=Ium8#@(MA5jG(FF~TG=lrJIDf`oGsa)h|)k-~8#@mGYM04yR^I4JO2 z9_ta*lZOSd_2gs~fAz6pq4f{L0ZT6_oiW(Z= zf$2oS54=E&f5jKE6jLfpp#U}`(B{Ds5@9g~Fc<+>cEO4jWCa*syK7iz`XhQ0n>EG@ zb!2{){BLlcMGgkjx*0~0@B}=32(IjY!bc4pCqD_)spMiX{>3K&_!GLoU;jmX?CvS# zpGNs${P?Gk{|@r6^vmNH1D{4db}+FOjKA|V^8bv8_KXi0StRcUpq~I>{NCLFl%e27 zKc7#NzlMD5ZDK1JH=jlRUl7^!tPj9B@;Ly`AOINu{c`}ki%82JAK*wb-Q&UTC$@s| z+nxvDKTyNB{QN;t{yOppC?AZ^`UdjfLnQkRAK1z6HShsKLMeMHBef-v(ec0l;{h3&7tHIo!MOcB01g9yxlLmRz4?9QpG)~*Jo9~+@lP@X z_oX)Zld^A~j8UtuBh0#zz*p>tjt|*%zJ0%^guK!6BOuNr1X%ngY%m|;Zt8b&vouC8 zRebihKf**cWBccee~<7Zu!pPbhX7u`H6F)3Ru;sY!z@m-8Z(u@@Zu06L-=0rOEA%> z63>)U%Mmlr;FrFX#Y4yu6a|Za9rXx#oH#K>)bsJXF*DB(NZtIZ9}gxP1Gpfzf4Gn) z2UZ`t$BS1jTJbtY{P&YrJM&*gjhLiyEFrBSgwWFpG!MUm$c9nIXS`Cb>e_&xk85Y2 z_9t}Wc1*|dXabXff}bIkR+qz`sI?U#V|7U^MM#SaN)asY2N?Jy{lW`){M8I zoVQvfRR0XZDpW7LhDa0%ILfwGBg9~AtwF|#uj8lVL^w2lB_dy?$jylCLS(}waB;oN z#h`owU-cqVS#VE=Z-)zK3c+G%pz~$q<2gzcw~e8Wn!5)t`yk~4fqw+MXGVhXW$&xF zkRKGp`E%nB0agWv9YP3e_gPbG>bMGU=o1 z?M|th1v*%U)}f%dS?LhP5DOf~R*8r4<8kYmGP8z>IktQ|3S7cusgZH%3yrL*hsB0i zxQSiHM2Eh$a(YH&mS83?u!N@Wi*TFc^r=WaMm;Bo7gLtwYZN)QFvGS(YAE0<6eavy z(^ZsZ9p3`s81*6u?BorA9j9JQ86BU}JO$@LSg|I_80BoBoQ>ZMQBF(_;wOpZU~h7F z4)^szn{O47F<<>6Q1VQCnKH*r^&SWf@1aTLO%{M=hkhj14X} z?)Y5<_AF525Y)ptwnS)SA(U##v4#V)Pb8$;MJk7{?em0MOAysgSLlryfsmTd;eQ%r zDqEyjJz}yM_br(MVFlh*LQBky4TX5?gFx+wHSBDPLEVB3tAmtT7&Jqx)e+=+tsJXF zn9CxBJl^KCvRiU&TrQzm)sG644tEMT|Va0k?1F?qvw-0zDV-|$W!KfWv zEpPHPF3Q-XGBYZ=k`>9}DqRjP$=IICt<(bYAvF<+p3Z)XvN@DG?xm8-X6T6JQ>Ws* z8$2`q2EMtOi#(Y;0k-#GOyvIF2qzw+E(0=QJTH?+r`X7Z%_>Uvswb1WHxNrMMe_0- z%b0OX@a$PwLjLi{Z#eW0O^1bQAAxsULT~aofES{I@hNp)1-+E>66NT~$wG}0m7}C4 z<3`P9Pv1t;HygkVt1ec1Nd*kX3_BWW3G?v=(lmW0g8~!g?KA?ts!H&D#EyIL<;CjW zs#0AOIreKCy^3k9s1hnxQv|ic`3A36BWQco%R4LGH{A({nT=H?M%nT(Qu7Tbdu}%{ z=4_f9;xU_IZfqGDoevp`HPtkmV`k`dwU;cPY6rzkPoy}-lFC8c;^SUDJ0!D>BI+CH zvY0D`GJO%t>(7iGDJMP5p-3sRS`{r}O|?@ME6#pFm5bGnTm6CktvvKHQtEf-f*p64o#0PzQ9f+8moE3pxCY{F<2CaY7R;ll!PG+R2e} zTc#d;UVbpg@Lhay@CfKUgPpt+ zf!WFKh3S~PE4EFe#o;Nnm#4&rk%y{~ORM)s`{fYS5Vw&Lja5_Kipa zZ)ht+6~fcV^c9qM1xj8nu05JcUQP*@cd(U9MTW}|mR?E;OMzG{ZuWF9ri8_yV>hz& zu_PP|_lfX}Cd`JlPbK9_{Kpd*lT1PO?&oDJxgkuaMQW`lGHIthp7el6w!Vk?AuCS`aLE59yIzfr4IzR1i_GU095>#w3mWQ@bf1u{Sq>9 zOi8%N+uy<3_6P9+YCo>*gS@XIBd!3`=2m3F?}fa#A|tNsfxM?8Bd+ZZ_ML`0+IIVC zp&E7?23{d}$B{@)7s#vvoWCo`SQip@QNk`nMuN7ej6eXb+=*Q3jh&Rc6UNG4PpFU` zk{!^FJ`jbdaX5IiNxFwAa~KKRgAaIPXgeirN9ivfpXf(4@3)$xf^DeaG+4RKx00M8 zL&dGZ9pScHCoQKbvlYo(Nf9E-mTf|M3kh3L)(-yQ3G$ll)5^`zc@)r_39uP<3tXyAtqBZVC0n62 z$Xi2sYd`}K21pn{&HcewQsk0;N}#4&$hAnYK)9)!UQWVtP#<7@Bp{;nZWEMV3PI*! z5QV5XwKQ=wq6>Xm*@KqOL%AL**8}Q?&`km&Y(rOq${7`!iM*MVhltYo3F<(6f;d2& zK!_+U5L!q;L`gzOl7NWP0HJ{dL=<$`B-J23K~jHMksuS{d7L6r2x5pc3ZdjMX4)s% zcmOURM;?gXdQRdpMBl4W8Q}yS0_+fEqOp%DeK24}l!HhhDnWILW->*76{ra-zk&ct z|02*MD!+gLVrN~HSb*qHEA$$ydkt}-mp>-<_Gc0^A^xaB-$yt>-$A@W?6u1i(;&{>F2&>7=`at36g)1dP-3PGoQf|fz&GRQrvPpv9k{V-cUA`OrBZ zGSOVXL=$s9iNO!~DW~3vY{sd_l;u>V4silaw6HP_D8RN5=LQvDkl&%lV zl)ZhZ9*K2uUR}VCcw0~uaS&U)wPD%vICV=H6u>GGAQ&k9Ar`ui8SO!n^giMf^e*BP z^bX<^^asQz=xxL+ls+iz3QW$Mw~$exgiw>5SUItSw9OT3m?a)9vdb@NzCHC3-o_W1 z+`?iqepVnVUHgTnvVw(oRW1BLdCht}?0)pBY2~=gAtY2bSxtOM~7`E~MJF2r8&XiEj~7GeMo84kYp| z`0qmGbd;rD=G3AQjc8O76`>Ih#)5qrW21rp2*4`_dNL0xg1DYv#vX6J>kOctfSFG@ z!X*U(k!KtFF4_S7^r)zlS>7(M1xQ~)aM6q=@wO0xWuw))K0>hp7X*m5^Y=D&cF@uVZH?SwBn z%gnMc!#br$gd|ohM){KffaET{VN+(j--z?2+-+`AO`!mJqZwS@uOsGm5)2W;eU2$V4TV%P5g4)KRgX65Ay17L-B>Crvz8&Aow{ z%TB1mfGh)Lh zl7$)vR08oRLfk9ND=1?psZ1~Qz8ip^EXVj?E_J!K=;+4!|7Fz$Ll_*-FRauzs@UWWY;TqL~txEm? z(@NqRkrjo6wO^2WLkT7|;nii_Yp7BC;g&@9a9AmqSgO<#ZYxJVS1aregis|KU9Aql ztm>AqTpp@sgJKhWkSThOSOewlC2@0=0iSoRl8dNf4{neu^;Nrtw@rA#23eRm2Aq)L zQ%GAD+Ulz@9q#P@nF%M^prQ;1^Ki!T+^`;qQ_*rac4qtttn2cMRYj!&@O&_6*4P~hN1~~4Q@owY?fNWnj0-PPS0`Nv}hyLZlJ_nG0h4es1x@{ zO1`H?%hv2^(h4%46UvI}G(znuv5Vt9`G7RaSZ}rFM)o$g=i~$I{Q$gRU@NhvV3wya zVrC!2+LAelGJE$4w@7QIVDD#6nXQ6z%KAP*ok{v!)S7a7YZAsrQ7P>Ripy&>S?ZZV zKF^Dh8g(BT{{}7(%e84IG#W|CETS3G$a%Oh3ah*Wy|AB_j6)659x1lIUce`)rkn6d zY<+c&`V!nyjRJ+Ljn!!eZ>S|wS|p|A+C+YPmBP0NWcj@?>rb;i(p{Jeyc%P@mj4_k zWU`pj)#?Fq?%^v1%d~~M0Ph;lqy-& zjOcD$=8oVaTeY?EKa8-`x1feCLu_6HvxnKd1lx>*Ry`X6kF(q!+KdNf7Rb+1+VZoe z49F~1YtIVwA0a_9b99bd=x4|Cvr^spSy5+Jj0ab}Cz?#0gS&rAv8sZ^&JLE}7^$xv zxsdU=WtbQpzhS2>MsDw3f$cq^J-c-CELmL70wTlDtW>G*yd->d+F2(8aN`@vP3 zRaX}C#u5|+m1izgPIyUBk(Y|U`;xFKhi2rq2~#${K_>^8oT}R)1jY=tZOoVz+a}n5 z5p7r`GhFL4yz9VhsCKps@hw}M*?Wdo#&d^vr<+G36I2569*pAokU>R|yZ}{$oMVs= zGLMB4kb5lq;N5EZIOKxzpd!fVg$&B|js(9}K*WF-tflN=P%i8azTQ&93MZf$FoG|` z$Aru|4eI;jI551GKMCUiSIS69dOm_jNwSVMG>Gn9t5!Dw|`%Yp|jKDuaw; z@m{Q3we;NpD$jx(Pzh9CGA1N)B|$E~C!B^Vb0-voY*g4%MBGC4HR8Ggg5rte!jr{i zXy(ai+R5W^>j&e)s`YT|dI(w2nsI>!Kx}g;AtBmhvQ*WW5F72jBCt8c+0udUv9i$E zvbP<}_(qlO46ZDoer{rp3R^<4O`$33hg;A@c0f$a%eDxLy9Ji!C~j#jmApS3PK9dhTksAi?@MeUZ3pKsh2ZBUyw z2_;SLeB%VRNzfd*GbuVt*Kw51X)Lp@*Z~Kl7TGDA^$0cIwMlp~-wB;FF&1ZTLaUld zgPS%ML&G`~4k$Fd5qQhy@Fa-00o#^c{8kZ$$WUj2@*P``*NQVX39`A*T-ycTLv2c( zIu>}deulFIiW=;(08Y}uK2h9uD%&F7&C}2Waz=#n936URjs+f`fwWmrH;YPZu){K- z%-RuX>l`SC-VGKTPyqGe?hG@g0XQuuu@>d0-OfKf8|V|Q0$Ni1E~}quOnEdv z8jE{sT_~-~&4Hph$SQ|4qp9IIwmk&VjvLv^AUj%CrKvj>Hb z1RUNItiOeg%+w0amaVK)IsP!g7WdT)t53_S#k`mP`^b_%Zk-_zJ(SY2RXbO_<-nC3W6K0()v?<&N6mkcnL@kE4wwk*0}HXr;JYjHO<`0R zzUBRJGYWuAP!?o^N-d_4DTAfdV@;umdAz)v?QNe^QrMa2tiy{)%uJTFwA&0=5iAv7 zYznKE!S=a;QOF zY6)eW%7+tLE;5u(7x7RrlTDzgy37guC1{wMEp3-^&4nlInj<*Jq4vgW@mk* zKa|eaTY{Q%0xjxkPGFop{GjGE?F@&IIEB=l;RFtAa%}f>JXgzDP@huILed5su5ufJ zQYh&hB+0q%OcU(Fbq6J_L(=(H0v+A}6wk+6;^$k!S`+Owxljl$Y)mMJPCcVD%L-Dd zm-RI!+(VglavZ~`p)K42?v^ zq!{a~ZBQ>95?t1OvSv;h5)%2|*_u(m@mMWapF3J}>#dMhYJ6h~D+DyFDYum6gm;5w z>umx1F%5tMB?7+aTbMZ(m5$EUOE5N=OES4zDYnl=1S3$Azsc=Pa5SzdE?aE+kl zng**Lb)d!tm8J~DHKSQNWscjz?6dQ^sb~m>QDJv|@L)?KH?S^U(0b2`4aM8kONWFP zf^I-82Q*e=SIseEtS^_8}&&OBbiYX?BuKx)!>`!%fhwjQld2n_igicQZqooZ!J6^2 z*&CKtj#)=(ro3qp8)=a3(a>p7UQ8rYsq7n}gta-6%H;*An9SsxNX1Q1Ar}|1$e@_c z)@H?(9K*=8qGDE*3w@EG6=ge@Y5C+KiS+~%CAdv)IV7z!F&av(-H$7BUo_*QT}j-a zt356%vD=4*RV^6FEuBIt*(tExf>c$f5auk_DMZ^kdj`3cZ$We2s^Dl)lUolmHs1Dr zq2i;L%*ZYG-r1oy>kZn8fjY%6nQO zx4z@;0=5AQ3wIfm%N$@CtLp$u#qT-5P9K0V1KZiW8rHv?rK%;qAj+0o!Bn4x>2{Fr z3HIPHihmTvIa9_}Eelvdwap3|m*LjP9M0s?rC2Bj7vuPQcx8LBrqIkbeF~q1iEUp| zquxJL_%YjlY(3r`j7d0EKGZvvL4WTUOPOOVx;+#a!>M|Vo!8bW<<5kj!$KlEoWKtr zRmC5DkFDx}aUHwa6uyscNa9vxtVKLJutU&f;czH6g5RcoYy?}eA>@wnq_2=<3Ih>O zdcqPmsjel|s81uE$GSguYL#;>ix`&PY~62p(QstboO#zI5*_F#DkjWWw@ z{nXw^UdFcC2FMixTek^Ad)e7JE8HY_N7C!h`Kh-j>MjS)VBFJ)5oB zkg(rKCD@v*W><}+G+P{YV+@~M>bz-9@NiHyJMaZ`nZ@hynpu+FSU-oaRdK>=5uIn4 zjazp+n1n0s9f?24%%gV@61`iY_Yo3(P@xYIg4m%469-We5_;aFC_L(kWDnVLh}(49b2Kr2#JCLZUM&bQVIQb1JkB zA<_92x)34J#TB{~A<^X(x(XrDwH3MnA<<10x)mYO?G?HUA<;b*x*s9YLlt@yA<<(M z`U*m#Co1$bLZW9Y^mT+p->T4e5E6aALO()C^m2t>LrC<~3jG2hQ3;&{55G5(I0%Vo z41^_JDWe14LRKfE{{o$)aeA#&V))(}@up0@4Rs4zfV~paIYtP!>hkqv!xj;A-5X zjR=Wy721T5XsANC^^hR4E3^e6(KgRL+O23T>wAh`Se>LDc#VCrI4C5R!W&nJIH3y6 z{17h>NzD8wf)+Ms@#_M3=j*~IHfO=>!g9t?=GGu|cJEoKy)LlTD0-!6U?@TV!96Qy zA`ND+h0m{?gD4HI>tuGfEiyJ2^7Rs{{>OJtWJv*a1)q6yE-SA6kKf2I8A3JgI>0S@ z`5Z9!Y+vfK)^J8SoN`vntSf(}%$iqKa!7O4jSXXJP%x1JuhT8&GAm)I1O|(doiIs4FPtP}lxl@oycryuR zE0oj(#=yFY4d|;57P$I+&R!|8W|*3mG32yYgqn-dMVayj+(pyP)00fteL6F{)wz(5 zDtBNU$UiPc>VZkQNQwjm>k_={99%2R$7LxZ(*L<6PNY@i~qd%=Vq{ShQOhR!UiOG}%&3YMQK+l8uQUX$um`lt86T0zn1}3@T)QfHy z)+uGXT6u9KtQOIidig}~jin6hLJulsOG^IG4ddnZ(7*6h!@)PP%6u{-=7t4zzZ(`m zW(vf#a|^nB-=Np!?pB!QfZ%+u4aJ)(2{sx2IkdI31#P_%sgz>fP{A43Bf<%D4I+#p zo56}#L&}nL6&T&E)txJ7qF!F{eEG8gxM=r@d(mIbmjY1!43Y{Ubk)2fPNNu!7ellV z$z6nqNnN^GbNC??df1v2N-VyV^}Wyf#T52x6#dM9x%hH zADGmY>FixHQ-07HR!!>5>=5`^O~%erUlyIH@;yKuBqG4pk!soUSM(qxJ-5^kvj{P> zyO`z69CCv+9-1LA%xp8<<@htZC6{C|)T!(ax!EvvX^ZU=se! zO2PmV3_$a%5TX7wu$$<`ez5XNB%!Jnc&eEeoE+tsS5!(APeFugaj~iB7FL^icodFk ziMA65%xi+(hX`!&)*Zc!hj zd9a-FJ#{h?=aq0Y_uY}D?k;%y1oe52b^&jNDA8;;(fdNV9a?D~f7kUozl5=`d>0eh zMc?VAbHGQ!8JBugv9q%B0-)5bZdf?Oz6CbI^Avu!)SHXF zE153Mbh*x->2A2i#tcVA>Rxoe0w(2Zg}0IcNFZ=~B--Xo^9TQ>KQU0am6NTEYzV)&UbUQ?lDWp_70m%u?OL#H2ac#VaR1 zla2%&Ids_5^Tg;h(3Jyg#?174eF-A4t1IuH2BZ=UE`^~-w-!-}W08+Kx}0PDk>xD( zLpl&Nqw^JmCyw~K!2bR->d->Ffx%3@Y7i?^4;B!~QN%!mA)-6zPtQv^gs9w`?qq41 z`nUup%sd0?x-4{e3ca100z!wUFteMf&r4X_CA&HG4ZpK3qh9$2I-5F6x6cG0tj*-+ zQ)e49(Am$UCmAAMkK&qz!jd1Rik?UZy9T+BHgn3fk%==~mEDY$J!Urx>K?mURQFJC zgDECHFt&TdAL!Iw)ChPRBtHJuB=x zS28^H-e~puu1Fo|5X%uW!6ZA8+FfY-Bx$>a;nh;57Dlt#p*d_2qf@%h!My#XglVlC z#N2wQ!km51?{TA0tvrVwm(gE(aXC18T+Sej$N}YR)W4e7m7nNebZn}Ce$5D7^s*O; zc`wkjz2xm z>H?-qZywX7C0`i>ITR{U*V|;`0>7t=n5^FVlIuZ%O|PH;)zIb6_44PtNBKuWLAnlI z(~OazxOpx=%>`^^n70OWw)xfRHX^!363o&|V5C_xBdLM`;%%t{#qoj=a$G-G&tfoi z(XG*D%xZrT=a|=$-I*$so3(MRKE@vpmV zM6woAI5n46TL*L3KMTp|y{?kK&(3ovufFJ9EZzvwy%A#h z1~7-1c|DkM9g51=qUbdyY}`!g#Bx`oROu?P@(@^l$byn9kl})PwtkiXmw^>8v;1`` zcc}qyT*_G&M_$1U`KMg5=A)xLB&}S1X4Wf_?){Ggh7e8fS z1S7e;9*l#fWJGf3BCni9K_iPK&b=}G7+akBk}((F)3a-kms^dPwHh%OXDON~UAZ%} ztQl*wRA^2;CP(G3WElo;;_>ZINl+_yQ6*^$R&=1KOGlL=9ZW1<@cRn7C1+9UOSU3d zthp76OgZ%!M+%#ldaT&0eMyimCRODmE-cHzY?c01A=$1!CYX3Z9haIG&5;F&ov(ft~=4xLw5n z-r&s!x*Q52=MmC9sV*ClsjNIL`PfLbSupT@JRJ3$D*53K*7N`-&qF-ed_NqJzYl)1 z?=!%L5i8w`0d65;+-rf|0|X;hx*NkeD@^ANJ=>4GJPsUP_DYP{(=cMoO{s^yOJ+U4 z0-42AP{<`#IvK1;%svT4%gYQVRMGsv#XNu(&Yrr{hgrn>vMlA_B$nK0>WiR9-KhRW zVMx**6$W=m7VC04Fw@#GUAESz9tPkcqS6xWA))Z7L^H9qGJ%jjk^f)Aoqir#tMF1> z**O$d8Afd;kFPfbRoc&Wdn5QrRO&lf1zJ=e`B$bq!lHD|9&@9@C-NOa{&!4qTx^(? zGB8V2VZW&UcQFM9DHiS%4sQ)a%2o2cC8_y#^5`}=uec4)E8JEYdG@VH%HC>$-2#M3 zOuiY+rWM+x!E4+A#;-TgaW>NO*MXI=F6%{Fj$LB*RbW{#8oFK1l^7zlHkUDSX=Bxk zG;m9sAUTM*7`NW`?_N4##b=Q0(6Y=gDMJ&MWjep#ib#%+Pdt%Jo`FRn+-T5m8Z+nX9LFJcf&Yr)uBlXcnWU>t&Ui$<`!2FyDoTW48V zvQc3!O%=KW7!fv&+0)68`Kf#JX;Nfi^rlR-km0D@d@AznBU8h6IyGFZqB&sUwgyi5 zKxUUibWVbpC+02#D-e@0V5J;NmHYL31-qB3V@tuxI5g|#5|k}2Mp=2W?@U}aA)OPm zk42_@EHbTQ5HpTJj4pHa5{}M#5zO0Dvhz8M^hxp#lSMiu`2n;-$23bysRv|O`k#qf zh0`-kGSLXt6Q?kN6nQQ#B>^ZBbHKdQrU^7A!h@h;3}KTsZO10^ASMH+$xyhHCIelt z=-IX4lA7V(6>f>HaPP<1FCY~GhBE~g;L~xXgTiXVP?V|nXO9#;T#ojT&NNf*8^PiV z^a#8(%?rIP1!A5=F6dbbT{y-MrL9ZU`)Go|KvBK-e~Kyh!YbG8NZli^)b0@qKNC5A zrKhkmc~7<$KP-sfV=3YXaU$4i$nJI)k%SsNS__Xd1hf;`JqQb|CFhAPSp<^Mf>wEt zOiZZ2mjcGAP*4hVm5%mco)27sZqKyQV>j}GaN?($nUz-VagNpVc%;*?aEyM~D)=0R zn}Kk{%r1J=7hG}Vd{#UPk)!c5p$@{|1-n=d?H>x#ouW`VNLy+-sF%9E(5nk#4r1`; zKo{P5W1&$GG#aFDya)e=|33RRHcolF8*c7K_Zq>}-PQtS`&cMbUI0L%!KcQI0vr88a z(90MjqU+VvV48tu+yTS;nfP6??OOwSmO5g3!t(>wKt|s@y{b5%Y~K^0d*KcBcrgJA zik|+tb&OpZpr=}60o{cwXGfVND%W=%CP<1S(AOV|n0 zCOod)DGdLjinHLIEMwK8Hr)hA3EiL&Kg_^u(UFg{E*T*niJ^P_jx6tIAtzLEOaa(| zfbKxOXa@8=g`EN2rce&(IfVGJD`DqB33lKeWGc2_NLzLI#C{%6;S%}W`C>uP?hw|O zt5DyGOf3SUy8wt>)C&|23cBOV-r>o{8N8C6qi`6rqmpf)mbxVMeDDN8;J-z!Vm7Fk zsYxhSq!4leVFM-`S@Uo}$rYlh+jHx*+l9WLz!>@S`PyoU&26yKtaGw?orz7|L!fheV1CR#5(&lc+Y?R6Z(ICGl`7 zj5Ts=fn^*l5<&d*A(o2ki*j=<;1;HgwnbR~@7~l26qt6M(D6?Rg-yvToQG4C8}fpl zLqvpb4OGX$x`=3FVTP8X`sN#5QfnS!zzQydKn z?V;tRK}rUjNiF?5OE?R)r4Vt~<2LcME5q8)<^$EJpcI9%L&C0~QU#`y>yFNY|lXb{jMi>jo7vXe~gkAGO!v1H; zE^oi<6w(~^DY*ebFXJO&A`T-ZuUctM8-@H^M!66W6|-Ahy|5tT`Uh=F6kA!7jGUINM73^4DLeB4eRY- zb3MYWx4|~7@q+2c<9x5i8Nxan~QE~?dDvd2x2GmpDbFWuv& z$C=07DlgsRrpKAbUCB%Lxao1`aW~?nM+QRF#|*!5l=V1XZbsbjcsY!?l$GSOi{9cu zSC*-4XB=BdTwcAk0SjPgFo@YFrY%|k&neYqinIVq_|VrX@40E(!D!IV!oMHTs2H!4 zPsc+=%-gb{qHo1?k=DL}p=x2@?<$L*9HzyuM2nx2%U5fs3dN_XtPxA~qw0QqgK32z zJwuCQSI_Fy`XepXI%C7Ln~H3iz2Rms4NI1S65<1KsKQbjb`zcuRP843cm9(?CYQjXNoEMbkwzv7AGyCGo@}a2i&?1L0k5Fw$hVVI;0fF`w zwT9}2ka4_qA|J+LBDq0zxe*t!ykrb-x#J#Z9`}|zDLEr`{NNS(@j_XY@g++v#?oMQ zYRT3a%JHy-oJBjg%7-HO$_47ONXV0r6Lf=GoWz%~yetemRUXAJ8Ufdgg$};JE5E3l zOE5-A-VqyR*kwHXT#pxgTRmqOiBi{V}!!9@K5M^ zk$OH=!gtQNq%g(YBk4tKd}<#)K1Pz~4s${vqk1NU0t7?GFD;plM5cFkR-*`(F9QOn zc9_`!9evd#{Rr%0n2O5DW;}il7&1}p0I#DJ zqU0@7j>oee=N>P4OO@mCthZo!(UP}FIUdh?oO`_FEmDrhvmWOjFL{fUv8UJbRib3qPIM`9xr$t69Fb$#3iX(K5{rr6G)1u<{DaRZZfXV5pvbak%KIQ zf7!$EmTT2+Lld!X;2%g*vr1ZO7Jvp37OAc>tHIXA92}o;n?z7%4^>mA))`vVz*3~C zvwL(=o{m#AYQafX7Yc!tUc&qSC0gD>JrSB4bQ;6)%sXDHxPT|eqcDa$Rh?y0XT93V zV)(3PMV8v-Ht!rJZ4IP4U|5HVpUiee7=!hwnQd(+d&Xo%!+L}zA!cZTq76l9Wtfbc zs6{T;;b#Y+RnaDnTvM^u)UY^~0jVf^d9)&wyh9cXcnMW5zP*RDV5%rkyWoteM1$4Z z6k+q2zb0lJAiT;|ZbWeKKqX)yVyLbKE0YTY8qiEna3Iv6cf4$>@xM7;q3`IVWq8~> zTuG&Nxp8#Dk|Zoi;#id!UZ^x;LFBadFev9^IGH#3s}1=;Z6Z6GDyJ#WE0k;d9!fSj z)mU&QffY3Ot!}};EGbPBr>GtYKez#9wBWej!eSGb?2wo2=i#69Y;SQfJp@2-DRE)C;#feBxDm4V@C>v7Bv#Q*ol8>>aH z5=N?1Rd9X{jsP_{+eGq0HReAbo`UTi4{6jWYC|+)R;7Y$svZ>Z5<}RgLlMq2x*#|~ zC0G_RCAwW9x%FvLSc|9T6AOlanvv`Usej^@;6HJaVW^0eSn3}`-3%9kwoy$L8Jhf| zi+=nTPm)};Psx2OJw1I!0@o&Ev-@l*RNTmA&b z55q|tU&nE1C4%bljrivsk!8k78ODIxGS>JBi4HM-o-&R}jJ1jeiJ$T@j|cs@cbf1{ zFU;fK8Af4Sqp82xAgea@o}bX=D*?Ot)66c z*$s4xfsiq(=|bxN+3_W9<4%qCTeiLA9ho(Kj9NZ69F%|Kw_Lz`j%c&c_bwf`$7#%E z-u9aQ2~HN%@x{*}iOw&+q`bYqYGSSV*OLF5LZ#{K@~=7nFH&eRDE&>G63{M)_Z!I!;P9$mL^zT>P_s6Z+5D{CJ?Vn zy)|5~yw!OI+Zs`RDaS;UrHZD24;P29$mk9(dvG0-J(&%#*@uJX|6%W4;Nz(7d+{^7 zv#Zg2Rx4>%I+AuQOY8N@){gv?{2aePyazBK5(5JmTgJE^%xmqKFixDHq)?VXQ_+&L zdC)3_wo5`9r7_8*p^1{xX4^ojl-!#Mp{;T+O}7aNZZ6dS@9&J(6290;{x`iJ+}!p~F(_TC-_0j54m*g*O{fB?879*uD*;lI#TD8JVP)Ss)-%N{1sNIBu zzc3i$FXXED3znRDf#nzS7mnBS7pCL=D^MmI^Uud&1n2&Y9N%*7^H>+|iZ-IQ{vyqg%^H1HN@M&8+ zU)e?~)9gw)pMS%;oPT37#J@3I!@r?w{2SA7Pg5bZ;&_OazDP%LFg(=$$_k-o@j;9! z$z+rx%ioxnGs`Hw7^em2I>il(9p{n#JFYH_`+ktYOcC z3il1Ex)cVdC|pvRt`@UK6#~GRJ30;YgtjjVEC_T3nuIAAGE~3n(U`5;{S!7yOwsLyg&O1DFJ2+swdrqK^p|oe8ClPsI=MuMNxmYa<%}+Mq1yVx)~K{Mu9l z|Jp2<_C%~GI-#CWVLAlStI$W2e=-L$4vGUO66A4M1Du!te5Z(`A*^prKG!`9* z!Gxy{T;$0*cunE*ae7x-0#$(|$Z)nS-dMqVD^Kne>p@TZ()d-~Ut-O#(gNC-S^8CK zF=I0S^2n7`JcuTfr?Xn{h@*E(?(_W1(`zUUZK1EwE`&oHlF~$(mS{{cdf1HY%R`#& zEdgJq*gTs?ISz+KJk*tnFfJabG~NDfmC?-+u<K#RbiAEvFW&Xa>)o42HXV{ z?(c&Ev}{0iiS>+f11%901v&x^f#rHZ7w8ByfO4`I$n-CM;a)pkql^pN`bd&}d`&+QetQhAOPr{@HY-o!Zm1*zqF^4Tmf{upoit*yIx2 znLHiAQF77Z#@CaNnyOg-x4H1DB0|Qe#)Qyf;B{xc7Sgd<7ZVSprUe!+u<{79T+H|> zQ3Iag3GADQ=b?Qy7IdldxY>N+Us!O~g1Aw(s}X{>W{I|DinTK)&=ccP zSD-173G~E*nLD?3#st9=>t(J$Qy>%QiS;s9pec|EoHs9qzN5J>6X=O~uq&`KGp4n( zvREne1(pOB1v-SvU>*O{QkW{*91QcP)W!U%`~v>eWEX!b(afL1D%Vpvn0y=D8~Ibi zaF;syQ#uV$G9~OziWj_!#(^2#r^>zjQ+_Z11n?q+ZdJN8*u$^~#i%cjY>b}EpG<`Klg0x6hsPzvP_<8D0P3O%2%U#fsjZ4^lvim_ z97mVyX#Jz>0^QLiJ9;&Span4mO=tPXOELcOM4CT77~+qYtN7!ks_w_x$UlnC@J^5s zlverU-g5r<2!cnz=E`7eS{#J&6&dfH;>>5D<9H#Y!P23z(jt;cG&5XTN%Ec|4t&ue`jnJe`M@={>b10{)p9{ zd4!GZ1Nh$}3bhxV)F1|!)FKsYj6Z_^mw1F3&TL!ib6bN!C5ADN%rx>xbe%skUCkeH zG^D$NKjOlmjvpCD_;40s8~G!|Yl9C1^WU|T{CCl~e>)ADdnolg3?oa2go9Ei?ddz2 z_B*UrXh9vX-x)Emqz&FK$;xQs<6+F_NLDi|m^O}~WeFm>4kGeEY@Wh?3RvhxmaL-# zUhrf~b3@Cb7*09@ZGo0RL!cODD$aNLgVT5O2h)GVAIi7#hsI_8keY^B%O6tc99y9H zG0;$Q-{TLtV4?XZhBpV`gPF?khbCdB5V6pTkUsq9r5K?rDEC8Yq*GS-LtZo3VAM|d z>%m^dA2QY;9A^4_{xFhx7;<|6<{`&TJ;=@rC3TXM3ILJe{XNpyj)8Dew{af&AsT>_ z0>(vK+K12%AykYc(^m=)B1I-xJB=>aF|$+9T+qxGlBO}S260RbKOyM;G%hICJ~Sqi zY?C^MjKWidC*eS*6k@}p=7UkBC&rJiK=YRvQHpJHED~c2RiGu%5Ll*Bq-GTsvi~{W zVc_;s_ft~e$J>{nZRYy`Cf@7x4ySjoGIfOCZ^I0CQtgyrR8Vc1-*3W9if{Syc)QcQ zU(9x#&++@ceqx3RMw3WOQNPOXpNaDOr+O&JqG!=a60yV$3n>qyNcQ>P)r`p~|E)oK zSW2a%5+9g}V8^~zj3Sc-s-iq#CK!Za4Czo4m8z%zT)Q7b$YL;rRQ%4weM)CL29Dk1 zvja}{YLv6dr9?-q^xubpwXqPOF< z9z??>J11Fbyl9{%hehHTAc{>gbFd$e3Xc3F2gfm5yibf4(Ml)}2tb_Xv?bOVd&V$! zypLYsDhyO|h2mc>BP7g!R* z#bPjA%-+WaKM`g(K0$L5W#acT_p<31_`T`}`MtRh@O#I;2*S+${9Xf|95tIvfm)Lj zG!kX3A3QM5ef(a`2Jf9x_`Q>>`Mt-7By@Y4kkIGZVs@FQ;i8I%41zB$rlLkb$v732 zJN|h-mOIMFFiL#yw1S4!zC;govEm=l2tY-{!r~BvHHssRZYX?@RGm|`d#9B?2TQY! zll?6D{>gq>fcAb20}usNDgOTL;kwCwSQ4x`o;jD`&IjCc(eWsXKF5|oqNFpnkG9Qw z)Lgjs{;`ml;I13SMiAvidq0MLrFrQH0vd9%XC%cE?>E9pG5YgF8*v4`b$da>IN4w@ z)1bEI3jEczm;ZevD2{rFRx@v^ku?NGj0$B5tMroeon2KDYu;91tr0A^yoXis_oNqS zN8I4d!LT~O;1N}rG$$~8rVvOaIamkLu{g;- zVT4)o$i#@;dSs(gUD^trne~O@^aSPw25L1>sJfu20+~ReVzDJa)Ai%&?O z^u%lkgGZm34e{YgOzfFUP0g>MJZ2q{QBz=$b&=g{QRJ~8Fvzbf+>St7pe4{G#8!3k zp0QviPe_NWYYi+bEvI+GGC*+v0i+SopEEW=A?xBjmBj)2Jl2h=*JtqO zz6hk3n6bn{U>^l$0OiHtAmuasNBnU5_xNEJlY&)^A||VfSK@b1{60U7DZ}06Et$h? z>@OH%c?%G$h-ZqJf6VW;&!PP0gPdeMTKuA*!GGX)kGJu|cu(G~$N1f@&JPdwf*tnE zb)c#Iu)hlB9sDLgY$f>N;!1uPlitI_jaVNMA6}HO_SH_yUbBf)F%`FgAI1*q;n800 zu+l4Iaag57Dh0XERInHvfzJxr=o}HeX)+1v`r7#UgSd(?lJ&RZotU+^0L93-&)5X# zD7HGG*;2as&p*5zZJ(L=WKC5VAH)K@u1`yt^^{j@hZC&Nh~fOMG<^$sGOm(`yp_o+ z!D!==1MGEN9oy%g=SEw%7Nyj?*!17YSVEzX{8RaLBa9y^eKK>1js6|`=AUKq_^?57 zC-|Y<1ZZR5<%i0D2*>z$C7ZRcgphTVq_o1odHLli7uC1E3_fQ7KA4PafC(bW_*nzB ziTchsOF=?)DC0lo2dx%S(RAM}3u=W(96d+`V zMEqXlY5ZTnuTfoFv@l^JIZW^l6*PWGUxcWlI$#SbK5jiYsPjY9ef(e%TnRj6B*_mc zOGJ!=h4mD}0{7Gx_`wo5rZ0uv$`ATo{9ppMvJP2MpJ(7^V%MRi4D}G&@o`_U(Go zOvYxOGix(BHvJboH+4SGSsgrQKhAT5V?_L)2nEOF3p_Xe0?EOJv0+TaotF4rg${m~ zdKrblWXcQR@L@_Y9!wFY0F#GtVH_A6#)2^s!KlWu`@Dp6rLJVKWZuUgT)M+3Ha_SI zx88YASR7Wxc6YF2@R(f9eyR+!tg&qv>)rtLhRuYQKock@H_igq%HYKQ?OMW;Krg^S zq7((@2{XkD4H@4DK}7lxj<0>w(@LzG-!ZzF-+^1!ky8glXQg-!zrzICgY7p4X7ULH zivsE3z`Xm8vQ88#vJDCjxZFN-IZ+H4@KARbO+4{O{Pv<)bT5J8!4zQ%FnJgk#(}Z% za5t)k6pYI6FlFs_J5-mJvxN&FrIqIS%w*bam`WSa0I+mnWu0Lvpaqn1Mhi|?$jS*M zCWI$MC8QR}jtN@XFF6Vx3%bq zMd$%+y(nWR_^o9brhy^P{z_!tLU4ISpp(TV5%ht1rd-kbIy^-qD5x_2Lw@UVF-|l| z;TNIsPl}8Zv}gw7QZ?jT_^o6VkKZ~|qzCd_v7&G*j_}{AHu77G@H^G~RtqLinGu7> z>Fxa1(n?CHjDcnF{W+f9=Lb6)3O>ZT)j~|Nb)*h;e(Ojtzjb&GzcqaU+)I(#27W6; z*zi_<>-c$ry9ipTFW~c51a9J+>_!?e6EFpsatA%zjuhmSA1X!T2Ohm!!E%p!&O|h< z_&-h^V2j0+KEgL++HTHJCr`PX^ak~~($Kys{e4o?G_^-ZAJw&6asI->iF$c#LB=E- zUo356RhTL{+h!uI<|4+P_`1-p<&BU)5zjW)p|}oxoVEtaaq$rHqga2z_fK)YfBZ{) zfBs99Ll-aYOdhqDDdRmYy0T3a)SOU*!zcKDdjy=K2a9W&Twjb685Tb)$^$oA@$Jgzxie z`MybEQ@P5k0VY*~M_ovT!^Rj&$TUwQCy#2vgaiM`a8mPRR1&JaAV{gu&i9QYMYo-b zPN|AY(BUXiCD<@XxUY~7`lf{)CH##r-)D^=;$H<>Dqj`YiCg$Syn6Rd-_Q5y%lJMO zW^4`L=WOEpd}MtJ4{?vwG)1<~FzENRwY6I=T&A#xwz zc9K#S*HsP~Yee~mK+{QngF=3Nh1G!yoYwi?u|<6EOpNc%(NH5(M2+=PjkQx{*`VlI zfZGo!LC=Yb^r-JRFo>ayX?*V>t-gq=_o(w&U>2Q+!gGU2AI}+V<$EVQzV|rid#7P0 z@l2OaL5XaWjyu^qiW6WHHREB!B~zwJvyP%AR&*cWTd2M|oD_T{mwifs0kHDL$66kF&@F2?r^-oW=@KVwe`#zL-%W-j4- z@_6h-1mXAdJ(IApd@StYYmluqe2;zs-!pY7-!t<*ZI6-1CGJXb1;5$o()JYOx`_z- zxOQ`1%oiejJ*r`ZWy|Yer}TBhk(3g4TV)LC=tX1B;G4oo2YOMvQY@noQfhR)8N85X$8=bB}iQnX`trn?o*|O%_`SSY-)+RjNL| zghq<~A{uQL1^T_ySZOkQY)}k=xiBMK?+-K|!?>Lj1AOPS z&@`y6j8Dp}0AoYwBMbS?vGe%O#D2chxrXnYsU=pvGpE5H<2y?cZRhdLbkH&v;yaIL zk~ex6$l8r#lGv;rld@)pp05imFBa~!1-YdtqmDpZV16M5S^^EiOeuwo+VnRn*C#^K zmw$r(t6=l&hRHa;0dx8rreK>9*yp1m3H57&V?4=kz`*#1LT_MuZRFN&IKFWER`Tg}{x6Lz2CeOeT+t}c;$AXR3+2&0hMKloP{W{3fP7i6 zb;Gx#L9ndeM_DKbg2lt-cNdTr- zgi1k4UQeW6l8cwMh6!D!StN9KEW_lg+rVQT4cg(EgJI1>Cj=axzxMGAl zuS_I*McE3jLwrX9_Fy$Q({QinJDl2po(2uuU^~Vd0-kZ$qo7S`d`Av8RLYKWjPGDo z+K$1sG7I76Xal>Q&DuLrM5;wtMPX&j%c+bdfdzpsGLN})mdXggu4sTuh_NUzPndER zjY!%%ys%i<5bxb;szK~hXUr;qLF)`24c>6%M=V=qy)<-&*z@VL7s1&k33{qnTVUGN z$1fEz7{A(0X;~6As3LWmaJPDwfu++K9f18a5LD#I&m#CEAz6c+6q^%F$NsO4uOCu<$S}N=>|& z1Wo2wlojm?P|YBal7~+hR>}&&y}kIS(kt7$%+aIJ%GmKe_dB%9(<~UH zV#iVb9uD8*i$7zum0#wX+GWVSOXJrbM4K&%GWJ7$sd>J3Df~q+XX!j`kf!1@cJxXO z|IL@M@L3N<)DSj>h6_f7@=K;aqg{fCd5Y+QBP^stK^GtI(Jn?_z#8E=7=w=w-ia(z z&_$DXX&2G30DGFKf4p+SNpCjA3w2$)FwL?)$O2jZSeYSvtDk(H}b~G zloIgTjk3~sGNB?CWI;p)y4vxYFm9bgSN59Z35{5k(sivDY{Yt$l|Tc^jk3UJKurHE zS07)a;Jb-(jQWc&ut1oxlWDv>Xk{5M-HbSHCkE&?eBvTJL9UF=Ge+BFxX(+JJFAXY zY3Hjt^Q6>hc;Yfy{h}yRz6%+g8jy3h2yeL)UiU*X79eTlX2GY#si4UM&a5)r6#^qq zd`N_ntfp$YZqNpsA!8?29*f90noCkIljtTQaw%~#rF`Sbl#qu+mt4A>!m^Y{teYi< zQG&#=b<>PNK;Rv$EC_;VdAD zpt%HXhfXXCGDIg{3K_L?5}LPTGF+vdr{6__xh3p#+5e`(cJ~pk5SRhQF$UG0;$d?;v`1nH2xu^jKT&!rQgbcod> z=_3#a7f3FY!7#SKhgrO+VqtfHsEX07od=Ql?SV*2XfBsv3`HGl1oF^GDy~3Bph1{1 zJ4iOvlY|hceUxZOYQj;Zo+QY4U1v&|IP|Hlli_4by0%IiE-i}>HRomAZwnEjhh`jf znT*G0)Sy79=Zwy=7+jIdbPbhy!zaNq~Y;4c&=ZxgIhxwMS}vy?Zvy#=kM*rJM#sTgY#!;@j!V^12^&5S(Im{7zC zm70pHl29Ch1|hEb#S7h5Q4SgpqLGN(BGG8!6Xe->ZE(r6r=g`-np0K9&-Egy+rxgR zJQZ|vDyf5Y2V@M|3Pn;HWqeFTULSIjr)y*ken~Wr@KKlI`Jl5*w92DGh@$?-uu}{c zN{7@8y3VNRgc+X{3#B8H73o07%%)Q}iMoYa$=KR#&q?=a=c23RQGNq|_AWe5&^XK{ zl7k^o7brAKT?zjX0TC21RLZhW_yR8pgMn^C7&z??85jx3Ks#sZ9cT(#ZoEOpp>`@8 zL!qp|jg#KUu8L20K`Vkq_~c@>U<8rE3@8-mIF3_M8aSZwzokLSBS<4z#71u_7glB2 z3KaNU8rZWhHjo5#=nnjMHcn)b>bM9WlZ!(iNu%&C`m#JMUcV}{Ikg5=s0=31BPnED z9i5|08p1+Ji=bu#$O5f;v_a?I*)J2ZJ_&RFZbCP87*d zl81A3w0J?O;z*E)kfmJVWzdG|FSiBNpRy8aSlfmo>w$hyp&uGCw_>C^haVNH(`%-7 zP!#A0^gBkveHjNeE{>iht#ZQ>d3Y^*nrSS(sL`pC_}1}I$_)?7%6N$Kf$TMohj1Ih zIPQE10H5q6T>u5!$flcb3Ce}`oGh!2-?6CORC>TBM+K4 zdOoVWu@0&^M(Qxrrf1blT6$N|al{9u=81qEvER;_F=eyc=C8w82qPUFVR zR)z*|Q-gQYBB_+$iYng%aTG!NEmddidZXFKR8oI18@f`VHvT^Vjx77Cc|v++LVXAztnx10{3fb|LB!_riLC75 zRvcR8wEA(`kk}?b_slq0%gL7dN>UYj@5L!QTg1k4*fQji`$aB_P=B)iRHi^SQbogy z+d-<7DQ78C_m++sg1NK=K7Hx*5>WxDTl#0G;Qg~?a)|2q_R1>N0-pd!(n{YU_l$qEsac6wPRM8QKKf~Ws8Ns zo9bge`sTT;kCk9Q2HPED{jQY$iZ(cXv;z&Koedvm1u6At*f}iQ_jcgvRsQesmE-T? zE2rqMO5#{F?laXi>xvfskfHX|k;La<$Mt_l3F#jmi9>i=U%p;v67H`thbc*qrKRQ- z7ydrZ&e6-(#h>`bS3EsfryP#2*ntjrB(cI&lH$8pSD+)%7HA2?KcYhssf3CX=F7)F z!j~t`*OvRZHUqPaej_?|H1JVbbh(@feB$LE8hx+u(KS^4e#h8h@`1~ zGnKK!D2}4Pn=ixi)UweJCzcJ0`;!L6=NbJ4`~kKG5)~fD_GYdZ9z?}7>(e-u#tsi>c1 zf=JKy5)%OjgU40%dqjv2kEu+2l*-`Z4LbIR+?YC|8M7Jo82ba^L9)20<3`Yjz^vt_310%M74n<-T2(nU_QL!q(Lq#4xzXvtc1UdM9DztF$v3Exq2Yma- zBy6NWvI+e4y6_e8RIp^|Qg~ta2DYIGwoRAOQ7k-Ogkvp&>=ITZGEwH>4I}(wWIraQ zifzcmQap31xm#O01@%G^r=XUEg|P$mXExD8@eoYsS~D_JS^_^-SNW3CEgTtVeOMFy zFzj0F?vsXp815~&t?*$TsRcT5NPh_RJyiY>v~HjMA%oTG_&c`;sSUUfLOB-laOLv` zi}^qKSQMJ9^Z+6|Fjx+jKJqB7&lK)MTpd7h^VEL&?BBH5;tz@gG#}Jito+v>p}6@E z=q&Uv!s(5{Zvck;dx@=hFOtlI)w|=jiM9A%xQ)Bt6)IQt{8RY;cZKkB`p21g??I%l zzU&O(x$5_)HL_mP<79nrI^LQ?0h>ED0lX-X-+zBWW*aQ}V4j9VcLBZA?9+P_StOB8YyWqba)FNQ0a2xrZ+WlZx!mR*@zy`$ZH}(*l;Q(~NP-(w-#D4hm0O^fAl$!Ux zoy6w+2EZmT2z0=Zx(^Xz{u|d4L+KWPOW+WgfT7}Ek;%RA>jWww=Ktf>g8ycE-6*X*ZxikOvI8yNGD*0+@iI@=fITZvqqvbO8M& z7o7Q>0GGfbFabm6jTEBZhzG8>@W7$s4MZs10B`_9{`JCtJ^U7dNuUCxD=sGf@^uvM zT?Z%<*aQ}V4j9T`OTpH);9q&Z;J-%jUju3pFjU+@es>4JAxn=5%rzq2gJN< zwvi}`?*O<24j^X#x2-}zSA(DfVx@h8;EjNg2ZTOC{vq!wO3k?nU=tVwI$%h@5+Ot7 zD=6H*0+1(g2`oU&`^Xl0g1a4H5a@tdd7q&Am(wFVg}ZPW0`mkWfdL2!u9#CV7>rB7 z>_4-ak}Fw&0zn=S%ik}k_9Y-#fRNydm9G(G?_!V*g7QUx0zsa@Ca?f8^NmfEta>5h zc2cCF;ssQq!UX^aFyx;v{O3~)0+T=mNJF)#8R@rIQ~i{NiOYi$&o~4&fdLpQoJ%40 zxd0U)eZ~;{=Lr6DKrL;I1Jr zV5mIA;Pi(8MS=oBeh^?2SOkoqyc*yU7zE{2fC53Dz$UN+tb|J^Pzk&hfFglQP+m@6 z0-L}h&7jG&YScmn$2$`iN*27yjcUJ9@Ybb`_n zfJcxga0#3~fJtBw_!&Tnpg^Ds?_#)I0*AmPFa)I0XkKVSqrp|KfC53Dz$PfA$V*@n z7zB)<+zaq~07ZfVfkj{vs08jp@)DH00X{*IpderYTn>Rvpb{{Gk`6El7(p=!C=fUV zHi6Xz&>$N029Q37lqtNnjB8aX^WnK%fe56I?EVLtp~>3_yFGo=_6M z!P9Jlrb5UMM=_o0=6<0a(>3maeksr9 zA0DQ?3M{+hwmIxw*bf;P8JdLB8^;=RjAct70!y}l5l?UuI?0H!{9t}|w<2pjNUJ4& zp3ut^vy-1-a-(2-fc&1oA|dXdL2UhgdW?S`qKF-jY*9FoX*p}$mqS?jHz~Q&ZxUaT z+_*vynKS^>Uw;m1OUVyX(xyONVBrHqu>~3eOJhVS2y_X9%$M#ZvPU>nd>_MgzD^Cy(~@EPChz!-TX)6=BKQ2 zG+h;}V@)j*kA=nXFj(d3Bw2W7w@F#VL;H0$JwjhPS>h9@;6o@wxOIW5Kqjy(zH#vd zmIQhNivkM*^8#IgjzC+WCD0UT2-F3t0-3;a@TIiCyg*x^A&?0yi4SKA0?WA191TWb zNuVdND6k+fFVGd}2($%S0!@L2KwY3JkO?e@Mfw6u0zH8RfsQ~^peoQ05r0vjE6@_C z3oJ_%>JcjVGBY)67M{G*kQU7ar#!q2>0`n@&k70fU^KUR^ zn16-&A3@YXzg_y+ zY>$VYn05Vvn&SVY4i>%^zM{J-P&H@h3JZT2z9~M-_AAU4$|**l)Y$%isL215g8!#C z?#inJuNG}lf@36!QYPWUS-q10CY(0=fAF6t18tGnO@cq2kmHMHs_M=Ve%gpokspikdIJ7H7LMba!>3Q3>YMH7$7S}e+pVsKmAQN#gdHvMH< z^&Xd#D4C4=IA{uI(k#dZ0f$^onqo1`uChh(b($m4A`Cr#W5Y1!EA+iuHZRZ+SYA&Q zPoP66=8#F9QYo(!VFF!&B}fEA<{_Hb<%ftH&qr2>yEI7LE<}ahu0i4`uO>=CpiL;a zr4Q`J)Q@G$t0*)t&>&Pw4<~yk9}W(Lt|WFbQ~Z}31$$`)v3o1>cpf=3&N7-NDPl@j zRKyk^EX>aO-SEsiwO$KHbOH_)7JM|Vvhbgb1F(IC=2b++tcolT)^SCg?}V=q5c9B9 zaieNPOd*NU1`S6^t$@P}EF-XVVP(~U+|(r3C(B3*G90Kc~hi3*mGH zIs$EhmOxXWAy5~n3S=U&aS9J1%nO-tm&GiQG!d3C z1bPC4`C=hN8OMDD$ha%qjzC+WCD0UT2-F3t0-3lK z0&Rg7VZRBi!^y?&S+nph+!fke*{9Md9ip9%UJ0+*r}CY~uPq!2M|6op!!;^#+p3nF^qen05)^gM6QS(tOWb548C zX$DTNqj!^8Fl*0uS7>i#pGvF5I~~0eUa?Q*JB?pkFcPL&3pzVu%5hz05SVZ$5k)>T z%-0n^pZm;dowcFbf_b{)*H#K|yXrd&bww9+1exTlJ>OlSy_J0`trG8a^h$WeK9%n@ zel7XtQ3ayQNdbr;C(j7;HN_bj&z#KJ9jYbgX^LN4DZK6K@GR669ncVDI%n{Dr#c&DRR!YlTve5dhiop06@h>rimB0z+n1M@Y-&*%OH5>9la7>u}|eYjbGz$))a^?Cj}saoIE4U*A!=DJaaN< zcc{kaX^LN4DZK6K@GR6631|p1ZL{`#cZK#=_NlZ=ywlMu;T8K-zSH=%wl`}EM3<8S z5J66!5$0=(GcukznX@}oYn!Jj-j-58r;+OEAe~r``jupnl3ZHzD^2o0r4^io`l1zj zf{Zq6&v#d7Z)KlKtHe7Uy%JurPvtv}U(?>KFA!Z$3P1!oc}AG8FV4t#=48(9P)(bs zFW#0?pw9i_LVGLwR9Yq8>FAa4 zihU~IY5ZEtoAm{v%Si!>9la7>u}|eYjbDquSy>>uoD_fva`KEYUs;@y@yyAb z-Jx21p0fD0mBN2s9g?!>ZLAE9ei;Fug~~#Ok{}bCwdcDlw70TPrB&jcj$R3`*r)QH z#;?WRtSk^+j;p~z3q+BVXN39c;*5-EPUh?m)nfD1#jmXt-gb3(7V3%y=m;`6*(dDz z?h5U#>{Dr#c&DRR!YlTve5dhijc?W!h%P4uAcCAcBh1$nXJkBcGG}+F);Ld7{Mt(4 zZC8h9p{Bq&NKU4H)}HUK(B8^El~##&I(j9%VxP))8oyTmW=(JVPVq{X%HWz<^S zkX5WG857$f4a+`(6+ z4Bz{vti}?a20+5-?_>R-^fN;Se^$F@)Br~Vf;-}G^Q)q;+y1)kqp{A)@Y< z-5R3q8X>QGQxIk66!D~P#8@ZSgf zAZ%RDz3ZK@pWFh%)o`o;AqV?ee9(T?U2tp%;ZE2uZvx>QIBti%88&M4jt#IMHj&}0 z*1**R)>W{d-Uz}nIPkPx)I^@&00KnDc7l+C{pxxU&|TP3*j=#E40g4{{=_fe+3wE3paZfj;o%AV><{%*e@>!;Ym1dhdlvX zMxH)_ye&ft>r|}=-bdjbfIS{$^+f zsTVTQ0*3?YRxmBXV_y#*yAIwIm4eH4Q2iv`2W^E3uVNFQn$% z5d% z=~ul10>pg>PDHVXJBjsWxR4QctZC)34kG+_5VnHlA7DREf2(lSx8T|d%HP3$wVfz` z1J_a5Ux(d{YW)iAPqcyX7jPge>KBl+1nfT#GWuumLUpO13cP<3Sbqd6{=-B41L58E zF~ohk1%6!AO|AEL5sbvu4+q{4!3#B~{#M}qU|_u;ROmhRJ%RV#@Iw2khXU`N@T%}0 z2)w@$ST}(@c;5kUJ-k;2-pk;vgZJXVdwyV@11jDo>gK?^0baaU z)HQ*36}(WT>axJwA6OYspc9?p0kT(^Uy6N&ExMF&L&#S~1hQp6%6 zJ`4x51=mrKOmOvp;tEPLD5bI5)YJGpofSmHPrwgoB1nU5>W~w3S4t7sFLbnf9g4E{C*=<%`rIVM5E3Z&2lj5 zL}`a>PBayslcEtU%fKQ;1BZM}pUqxjanN>VG-(Pr@k|(?QdzuneYC z-!Z_#Vxr~1d9vliW^<>bk;q^%L8xxe;>krw^IRMh(t&EWy(UiVzJP z%&jD3A%lo5A6pp63M!~6bu0rGPsD<2uGLf`F={o75$nEsDg<0}ttL)S-vNparq|O* z$Rtwc6*wymhuMPbFeqk4K=Ij_FxaK6( zOwYd%6cx{Zr56cZ*iH$-H7BCx*@qc;dL7cSiO>!`7)VGc#0pPELieRkN~k$?Y#~WV z#DZ&1LgMM`KoKJ91`}(cq~WTFNPd3NY(hdp3&3Lv9=PTNM3gr*pcX0@@(TUjl6q37 zDoawi;F=SVU_y05@wB9#OCo7sBn{V`gj#2l76R%*LOqKqA-LuQRN*-(pjN8G*E_-E zL9UO&As=g+Ek{K{J18B>v_H|BdX}2KC!#$K=bVUUla^L~pAAZ_oJ6FNh~TP-i0MS3 zlyquD?Ia>iG$J_XWK>}?D{W|&Ade2Do@_&;f=C!HxoiZAxx$e%QqLv8;R_D9WM%{} zuSD=(#Dd_(RpGD~25m<$v?60dGH~GEZD$in%qpG)RUV`u7qY2i zE#UBol6ewNIh_qOPbE&VKlL5FhZ$?52g4-~_6M&lB0wmzw>b5B92}CLZpI-1lL@vsqmDi+EUNOz~c)ZxaJy7d+_X_SE=C9iP8?&T%)P*oNP3L zr4c!1snnyenLEoO>#0B^SEBe6?Wto8;P6BoxaJznERXcYjnrW3!NfQ{8?LzqLllyY z0ohQGHU$gymm*rneW2JC7Ijgek}Lk)lGKxk$_gS1wK^M7(21Eh%YyF2Q_t0a;tL+Q z<|NZGUozF;(TUOy*PLW3JSQb1SQM~`HUkH9XL)3ENg$d^9DkxCb*zeVBO<{yCz?u} z65du(u&_>gG+c9nAqtgAr=Ao6k12TInv+b0$E?PKe&%4XH8SavYFE1c*+$lOFwL3H z7X08Rmo>0ZE?i*nm8-tq$a?P#rP)rb=&|3bVx=TIa$ESXe&jK>r;D+VHL%Yek~_i5 z5RL|6#Xw$Y+k0}D$l`BsOtzq&`7CzaWSiukT+)6uw$NvGlI0J`QAaX2 z`u_&?YpJ=;h2}bD_$R8=kf|OB)qhGFIN|@B%gp?N$VMh@-uUu8iZ1ENq|L5B@ee4- z%Z8-aBQJVGBMW^=jvcBAv3DSU%6oKX)g55#Ah3Bi~W<;9(nJQ8fF&R zz1@=3lv`ZyIpP7?0#kofV3#R)*m5k`{tT_9Dc4u;+gLtkO-pswd>l5O-279OH7&;a z!K>jCiw%`n9A=<32enUw@nIy;r%NDYbk>5Ab*upa4TaE+M;;o&c0q|<{}L8mb9FlF zu48!_jQvQo-(Z)2)2Lyd!ET*^JieT%S@xQwvU?dj^63WT80!%quS0y5UH;yF@Tu%Q zA47M3w|qj*hb29Q z($RY^FXzMCz}tzt_Kolg&bb{*Oj#`cGlQj-E`wdC<~kPIkU)=hIY?L(W;cd&YoIA4 zDCE%A105Y54hxyAMZsTkJ?k>5EZxb%x%DSZW(u)Zm#}2$q`LKTCS&6NzL_IzYzwPKyHYR7 zvs7)yVh7N8WJSHRkv+`5l4N5G*~SK)jX^h$#o4Ahm7N=A>-$Ysjs1zQ`&H7Puw__w zG}yAE2Q$z7FSL-RhINdrxHIkP?#ZYXOBQ3XH54*Cu5}CC9@I%ivvLhdegcRL|(z4lk=7|tf z<)|IK9IDx8rTW^qMOlkwc1EWSiB){T)VC>0tj>^PUn$Bh z%Um{&*UXX6Av3lvod?Cl@+@jq#isB#VV!7@5USFSR@Ju>(B7ZN|G!z%`w``9{UOD* zB)KF-5pn2*j)*PzTTaPhtxGNT(6_+z?WG~5V6j-b$XYv0>E;KJk7aE|*0&tMjiQvu z;%TN5a+QH_ZlhDx$qXg_YJs&cF0ji#xj3Zw1*Xq56xd?k?}XZ6M!t>bdQK>lO?V7{ z%gaL1IyD@dR;AwdrK;pgQtXf%Vj~4PcApxxV}~Lkc6Fhqxv|XnG7EySm{f`mEJXz| zR*K${l-1m_C@S>MM!1%v#j^9zKL<)xQL`$PuZ~)^VKX{>V8zmmSEl?wh*TPVLR4%hs(J1uFPH68n z{rv?NgF;x8SnP(jp>?m*qm6|K+a5cxDw{RwZ5Gj2tS}{=sV15LTQO+hx?;&;L+h3= z$BKx7A#iKIUM2bUy{lH~?2dE;UaEtGXk!y9>s_-3ju|*8$7@G zp47I%tscB(Ll;vZ1XOs-Qau!_f);3wF;~9)p(>fV7Tyf<)`cv((yY>Fw)s^(8z8Pl zFWu|Pp>jRqHG<<3m6hpb0LinX>lZdsp~m?@>!ZSa+YFF(Ly zJIqe2dhvyu3)O34OSa~#hdRz_D^)M4Tg$3@%_>{EqfvrV*}Ryx!qx7Z*~1DmBSvo3 zD(qh@GHUL8IjQ#KNYpnq!a<^D<+?SwWy|zH%wsP#hM?j$G&2i5_Vg&?A3`5*r5wmYl%s zg$+B>HdJes8$S9{qttVI6<&@}w6Wg4)rC<0D~+MvJEKvy%c46MdzWUNaQ-V9$=+^vm=|Yxa|bP00wjBfo%ub17X>2+GZSBi|q{cS+vge7!9Z|W6yXcGxmRBQig`%=>k)<3~WCKTT)2<73vmcbgcI_c{f{p$ui~U=^X4}z&=8zM=<5LaH z2yH+Ub8u2&VNG@e9+;&LbfbR2)J*0`*H2x-79P;7Xt#+qw3ba?C}K!WYYi#+2JCpP zA!E21LtdJoxto6s8?Tw>pCAi)srfak5S7LL-Ie3DMFoZXUl_8T`vdks1kX@k(WT@D zU6MmZHmo0NU2BKVJ9=>SYC{^jA-mL&jGJ50$y-|CAKCz_+1lF5@}WjU3ODMK)LhV6 z*q7Q|UrJ_usY>!#re(dy`c|zfOKtTYTTs(dmRj&vQ$uEUmB%);w7}o!VVU(2k0n=o ztS-~M5|IW6J=T=amtlzMDA5?;3sVDusNn1R$|;9iym?VeaH25!VlB#It8@7s*!J=TWUm`(KeOKsgJ z)IxNden?$`1YTyTO{;Saw13sqJ8B{iydHyF`GQ&Ac= z4y>p)s0qaJpjAf?w&Ww~4JIjJDE4O!$iqMfUykv{%dl7IA-u#}SK6|q*0ioIhV^s} zj()5wGCXmat=xegdh}onc~x(AS$f$ro9)yOG^s=AbvIoi>jze=e)Q`Dlw_$GQD1UGt#K!WqHa5|TwQLn_dS3ZE7g@uMT@UK&=hZdAlk&x zVHO@}j)e!7Ln%qy7aoWkMmZ9D$qp@Q!kXQXalkOEuh0*yRo6P~u0|R1%{CkCO8vlq zIsi%HVX+9BK3m)$H`uo2YK)bnouP#XVk=g#2;?=`pKZdG`DLl;D;CpGDm+6q44=im zuCql{8#unx8peNhvoMSL)lwD~gQZZ~SgfPahnh^K zr76!^SCu2XUU~rU)wmH>U$VlP)_wINSjx|23_G_#2;ZQLgb*iq%n_=N0lu*Kq?{6?(XvL^RopM=hS&>EaHJ50r z#=LMuDu$&(D6Sdos)Ywyo0^JYEH6az;k_?4Myhkmi(zdwlhve;G^?d@DBT3ofPQF2 zS;17eZDl?zm%@^Z*|8*B{~uNF9vsPi--&&H{hasoya5b$rvVIRF@wkS3^0S4!K?8G zmZY}1T$0Pj&i3w76hPZ@8>AR;k9TUGD4M#Y!VazS(N6y8TB%ZWE{W&Xs)TmcMPqus zhFFR`S*ucXRh%2cdoDWVibpy*Ct126pI+HcQiXo^{QCF$zCXV&xGP5qB>{Wmx%bF_ zG~eeV9mp9Wm2hZk4wrZ}QRy%=d!dVeY)!0iTkBB#p-IWI=co|E(EfcLhBN5QLiXN( z4=Fx}T!^%YFk^^Lv##=jlnNMJ_FgN$(97#Idqwz8Q0yfY_6tcWBsi|#`^T$Al`cma z`ry&SOjD%|?jNp-WiT|+@rvoGlc_VC%|2vjE*Y`n?W6*lZ{5JcS^gYnrQxQbFXlLx@P)Ma1=2t>`kKuF8XCe`uw(v9D zCs*96%Ch8&W8cFoNtkb^;~?#pEYnS*5@RlHB_zt&bkmBEFfadgW(?*On9=26Fk;X# zzO-4Qc!x6S9)0PwOzFm~+)ExpyYwX>SQ0^X45PC>wo@wU^!9i0{)9{^lit=MXwV$= z69^&NjnB+f`f^sug^M znwLXGH!!tPQT;EITJ`(q2EKU`CRC0rqD~^E@Iv`nxeF+$% zvDZBbtv<|k$rGW;#|TcAfG;hblp&7w*zQpvAP@Kk=(Nil!o=-T$)w6G zV}>WFrh6Q-XlgcW(X+l+t5hA(wt5r{8Uhs3jMk-R)g#F-ximg;y91(NY(UK@MLX1} zR;o^-c6+w!l5$_=(-BovPX!}XoYxF~GBj@ptVe*eK{x1!7ks{`Mu(sp?Wm}VNdf*I zo7X39`+V?yP1|1iikO%&X$LkO24Leo3?%LpA;E=LOMv#0GEhh+F?O@hrzA_DjsDaq?cy5)wXRG^7NG zxC~U{X8sueL03;7`=bs4uM~CWxT%tND}U5H8;GgA4iwNVL`P7kiFaRpoS1U{Ngg(B z%RHBAbw^{-{#2^e9bH%oSNpRdwL+lOnIo0d<)TjcWzzXcEn{(Sp8^7R9Emb>oCb4a zN9!&n3NAgP9EYQvO7PJf=^*w=6&}dgk?;5B1a*ARmp|G7MfauHWQUvR|7|D#(iZG5 z``bGFV{iI=-CW2B?!@3YHa#X7oX|DbV`>XC0oBEO<*j2Wpeyw2aMZ#>?+bEf4vsxJ zV4~CkO^-JR)R+y}Di!m3hn`c8=K^kLqFD}fq1{#jeTQnkD3}mgoVrr%u<;eL1XVfq zPr|T+mRBs&K;6RZ4G{a%!>BKI9paS1u9fsPo`Pb;|+YWy*cC--Csb2F(6?Q=RJe{pU)qHb$+MxK|K9_=c zEY8nc0<0n8T_Wu!rWBw=3;F%q;Rb_=ODui^JUz`Ru_ZY}jj1lsJrNeWpM1l`=HOX^Cv@5i~A8zN8DxR<>qk>Z)Fh zC0|`~8E2$otzY!Tldea_Qo1iF_Z=Fm%qf$pBt^$2C5ub^dq=3X&dwAL!f11T-YZi1 zOO3<5FMESao3)x(X67@>2rd=gU+;_LUfB8yovD_B=jzutz(&^2`qa$7zom(A`4`?; zQ!_8W1fTV5b%%ZxOgKMYKRa{j3KXt&$r6?OJq|NFiJy<%B?Yc$#3>-t^Wz!jBhwBjv?DnxR2`{Um`l7sgHHf>!qA5%qU=C zkoz;3D&RyXT`4VhCt$g;(ymObA)g`qQuw+|!k6HeRHo)+lm8O@^~#5Hvd)uTDjcn7 zqs)YxU3nAyA4{^;N*1*Bg+n@_w6iarPBKj2hB)1 zXfB^Q#G71lpBN7_V;Qk3<+J88^zW&gOB!9I{ONL!YRA-cz%A&)YYnjQuCUO+RK&=M z)4K!-xvMh-*T$-}8&ps*ik{z;Tm(ueeg^_dR#_{52X4Ih$C$-)3T5spkJhJrtKJjPn!?9(24+Fj z5dsdMUhaupm!_Iv)>Ah(U<$gzkf3md(`APzm)m>LqPYPk&z4S%rqkOULGB5ORtGly z(OeQLq%x${9Wi^q&wmX%s`7zWS6#leq$&I~+AXBE`%s1W=9Iqb^2IyLt}q@v%7&RP zPM($rlHlJhuyaS2Hxw+tP^Z?nOo5z;uM58O+QuL}5gd2enEq3P-&Q|dmvwxe zkAKTy0vLrnE-%N$ahoG)c%v7%ntyHiY|R2Q!v&@f*AjZ!Y(RnGMOM3+r>XxUXE*TLYnR6SSFrX!ugC0oTx50*bf{U2#nVA)~3J zh3iM#x)Z{8(=DiQ1~nTC%SNE~(ZX^^$Uf`|=p-=J-1q(|F5rTKw(yZFA|5nK7Amdn+ScelDkIxX(i7p%Yz<-gg| zytq;Aq`uG>NRxM~En0U7zK7ji)wh^GZdw&+OX-#=Wxs1*z+k0z`$FMij?Rzuf2y&o z%E8LknaZY4H>_Y%(FMWaFDjp{Y~kPANp5g>%VztrBm6T&uJD?!3258m)ka+r_bGq5 zjYE#2KO!m#aMh}e}lxm z_oaP_#M;o>Mpt+WygnH3@ud2xFVsF*gN^()3`;pKt*&VPC*frXzJHGJt$O|l#%uhc z6Z7ffw*0;XsstM-esfJn94g6oe5E^Zqn2J<(Zu52wSIv5a%v9FuUtQpT(?=~?m!}q z-}`ut7Bs%_G1(k5_z@8G^w(D$|L6joYTKG279OnWA`RH$!A7GifE_*{l`B4|TR!l~ zjfUWI#nUyC8~K|pO?(b|-(wrzEi%MyWomV$D=^FlMC9OVXnnZ4(i2LLJ%-)xYEPKn z-F5l&V;wOAC~l{R{@szTT(l{rx_r)-9p*Fz3KqBb2T#*h1z3NDAi<*0B2&H>NJPFn6i% zPi@#jae1N7cr%kaGr7sSZVU1IX58-z>Sy(TI>}kY`mC_I-1lG(`8yki>~owUyLV|5GzQmuW=&xe!Kx+*JwK!c4TQZatu5&O!qFOnk>4{S#knQNpIzz* zBXcA+?$VawDNPIUo`~TueSOLH7v2X~=ZIaHTu?KTmWls#Ae8RRDZaw^5LyBe*9c6nMIsqo>*`kB@eeIwI=M8pw$Kwxpl@;i(=Du@;F z%H5fx$G|?vmwE!Y{?1kx54IGj*FthZ6V>}=Gdi+^3hZv1AjQ4q21;LUD19n#F57`n zYPXB-qOF6KoioV4K4niej_>lR9YZLu>=<#D-tAFwb3qLa?`Ui(cC=^sWh??B%p%m= z^Zo9Ba$f2Pyp~C=Ib3lSk#1f|CD&Ej`*d~L*P+5|dtG7jVa^hhn+hN5D`Vf8dN+!w+|*(n`+LP0=dH8ow@xbS12AWb%J2^eO^FN?ZYNsX^zir7=E83 zksq-;)eFD$nZ`d!~6ag?b@vH+HRKzqb`4d2b`d?ef4Nn zvBAOj_qrYjukE$!;Mh9oWfvssu;Odg4!5nGwCb3Q8WryDQV_DkU&=?UIK*Ay<6YaA z`>q-1O8W~G7+Ish+UDMwo1o;rE*2kb5N6A#n|l-(+R+fe&Og|5*rnJ}W7CcVrVf^s z;VLw`9_7}sPNMJ`u9?b8k2MUgyuPf;VG*<0N;KnJk6DTR_ZyGxSdo!!E5RFr=n9EA z;s+Sc54O>F#c%Em=!zU~Y-}QkIS>nXcQl`DWRki`Tkq4tHipC$8aq_)a>b9qFQ1d& zZ|rTN&YSS*9ns_}F$Uha=W>$|qXR_V#lkoD6p_=R;%KUj1%*Dcf?L%+TEYl)sPz6O z)Sa(a2SR$U%W)>8=c)^7lPGO1cl?|ui*@MS8iy%71ae&lZ%$*vf~JcPc61RmuHr zj!dmz)crI0JGMW))RWSf8_8{p6(4L35HB17?^igF46D2AyExokUf*+tR%3V99-UfQ zw)_`^P|~f@wdI{P)ej4iGG8Zu{JuS!S+V^W^5dqDS^#b;x3S2Kot0st0wpMy)wm*cUMfnv|zZs z^E)K``S{qsQ?xt{c14@OHA@F2B{FroWy?uL@u!w-Zn0E{%KdcwcyYycDVBrsSJW*a zjE*)+HpdyY)VfWqBTqtg;KuH7$`hg{#Xm79KW!VtbV}{&6w-q)KP*%J>qY2gj=1;1 z27TEXiQmyE0jWx8&TLm@nMD_F1@2Cjie0hz@x~wlP+Sq(G)vz%lY&WCIgpdCQ{%Wg z(`C;BCb!bnfpf`b7F=Tg*%D7o=<{g^fcR{O#(vCqi^bEr4JGq)LoMrbt>XpRrp;>g zXT0`2=PHx?tB&~jOX!n@1=XvnTD@Qk<5g}zUwG#a;8aC}$BywRiS4OxkWlNQPaUz< z&`Mn~yVDiZTU}Asl8KT^7nP5+QcoO)xB1HOab4of7kKrFKt~+j)A#n`04N~Zq;7hc zfmppq<8@ADPzN8|>#X~oZD5UFh%J~eBo@s5%J6Yjq4_Eh1GD%4LCTlnJ3VFZgR;hS+}og0 z>WGE+Jxjr}v8T&0te%+eO`@NtSKKai`tw&pq@ zD~*O=4BvX^Pe`cfST_F|GiBwD#bOne#ZoFGcY1ohVzAT`DwOK7OZob|^28g6(vIES zdV+$@(P+sSBV$l`sm2r)xmXo;2aZ!$y`iTrs$d z>0?pE_|#Tanrh*`Ktd`8zX{xU-o_m6LaXLn+Djjo5oW>fOBxWFBor4)u%3@dOkq%C zXg`9o5Qk5U9hFrYuV8vU3&c`MRGx&vnki#M0p@fBuN)0uK_@6_hHnVoW`R4_GlpI9 z{7acL;=#{^No}Shc%Gf~2Q!-1j-6Qf)Ql?-TvF;R09Zz7cxSR+l?JXqk8!en5;-70%t`y99C$d915Wu-MM|Z*Mq9(Qbp*YIq&!5 zSl6tN5PEl3B~T7<4F}#P$zPjKrBHc~3qP<{YYhG$$ygciHeRGmXE0@wZSKLe%lU z#gh*OIFrUcY@kG(G^f1F%+$|cjOfBhOc#m*{6J$Lz|)h&Npr}%eALyr8v$lfacBf) zNNmHRG>+c6tWx=Yw5vyMy!!?rhD3bIM^6iGJ9b~Cd<2hUpD8pMmK4ka1>Rwd-i08v za6SKe_)Omt=*6q}Wd$|Xj>F-fX^HV(@Oj*sUpDAMZ9}7o(O%3UQN`7ZZ@(d)M-k`F zVJDAbm(615AHi;TSfQ!lkV5`$CED5a>|1y@Ly3@6tXMaH)*l)V9sR4uf^~DCzI0)Y z`Y%u~l7yJyV2|vQ?&T-RFXH-F;O2hkuZYv+`9D`eRwO@7W}CB~O%-jz8sg`^M%-{$ z1DbDKJ78+{);oVnoT#ewFF#}S&Uc7ArvqX9yI84j;`m#{Wo;aPgE+sd&@(7E*axuE zJb0En8mF)eAo|LL@OY2IY}SqMEo2pR;)U$Ds{jIOeMzqD`p?Nqd%DqJH zq5BHu-(0X?0h5Hd^vkNjw%_^_U&Q6rQyZLF#JW{Ho18xfo~YBJD0eN8-^+*(i>!ON z7?fRDAF($V@f@{}|Cm_iccjRl?J`w}>1eZ?;7svCP<2E}Cthby{Y5!Kc9(wTzad}+ zXCgP?HzR9`(Och`j=V4;Dy02MF%snQYScVb76UoK_=10MfXEkJ2%X2|#rVIRGzK@7 zwSU2Jj9@m#gRaQ|xG{MgIA>yU#~}@c4D$C5m3ydC1W|I67(5bTaOS@=X)QD=^bbYO z1aqQ@dYE3;UmCjCrR0yhG?FzbtR0RZ7CYQPb{qYW)K?0K{m~+SJlFROm3-0Fy<9f(C1TGNh;X~efrR>AtvE=_nYy@%saQ9F`9q+q`L6`V0l?S}T0K$8@ z44o3c`C<1^q+3|zcnj#9x;M8vx5OR;R!aFo)Hr0?a{yJ)xU|=KnY0@LgRwS215v-9 z(*P1KgSk8M_CB2}!6u1v+O61+752=#MH-z|X_%?6fU>uml$9_C)xe&gMy3_o8>ZnI zaC`R_XJBfH<)86`0P~=%ksdKO9t)`J<8;-agSX!Z`oI~1{P#&%uGkB$BtIb17;?h`usdXd>c>{LAdb8&uYPt zmCru3f?)hvSpjklPi+70(L7e^2*3)Dlm~}V>oByqtZ6R!(bbCBDxc|^AGW*4!&g@| z5A57177Y*3 zGV6K3a8zmR@((q!3dW=yVu}vc4P5-e&VLcbMXK@$1vU(Tlls>0=H=^Y?w~l&tSaI37r5 z0!K6p^BbO>V3)ytU=ttiN@usR7QQ5$gt-`7~#Z#i1nu`^sGi zj;J@Nb6Fdig>E#yLtRAN&46HBx$yR(@%fkk4aHYRBH%jP9dt zl5@iY$?#54(4VQlHDA#%hpslCYqgxKnSJLLIecb9d6~Me03^Fg&ozp=KA3!2jc=8= z;5DgC#528LPHzo})XSpz)Qm%!*}r$HwMT=ua(B{xhO zYt35i#H@nXIIRp?yaB6lf>Q>ZWVB1OF`E`=m0A48%#;n$_`Cq@Bm?+a<(cIRx?JIQ z%7wd&TDL2hJ*5QH?R42eWR3f&lmuO%vW_EV;8>D?cRRa@vk3KI9 zxR8EBFn=Kx*D0NJZ;*8ZHws4$=kv^bDVB7&R8rxFE6NQ)e{!3C1Zv#NAB~0Sf!|?|7CIEp|lr@t`qqH_KWB2vAc@pwg_?H)pVRpAx)Um5=Sls0NqsIHJFEESCBpp`D37wZ&_tu3>M(5z^%qHzGB$pI? zG&$23W>2xsq^=&Vb(wnaJ-wb+*3q-}7ltYhmzXerDT$Ww7MIf;4q&BtReKqBqU^l1 zb{dr&j-_h@PBeZow+N#v;PM#O5bipZRxAWT9d7b8s{I1%^4U*ZH0)+so3(E(jkfGt zfW6zd0*`CjEYYnCy0438W!%Y@>DF`uXXSDOmwSyynSkV+#YMS+9|!ieS%59DU>K=MIHe*#m>z* zCNO>{1JkNAbUoR(yjv38O1IR1yn>H%S^fW@G>fbF@}u`)qUt|~XnMbbk<}wP)>Cuk zGrTdvemfq;q0ko%o~&EBS?gA)pz_dcy}-!OgX_EDvr1N^)asvqCY{)@|2bE_)iAePg$(1tt5&1z)0f z4dLrXtElx}kh&30ivZYIsTe@3(anV*B`v&8#ium&Iw)KY$++&kI5q-GO%ou1(xFBGUf_b)s1qgVv}}p z0Tzzu1j|(QTLh-n@>|yuejP}@Lb=a%ZV2Uk#J!)HTBbB{g;y&*E_=rY7BlCVL&-jCy5t?0yu3hO(}z zM_N!*xXf+G!}l%JsHQ=&=Jt*%p^C|Aw>{Kg3cb;6(V|1aE|rRY!2E@a+Zf0 zgQczGP|Nf<&u}x?vf=Frv|I%eMs3QiE>CbNeYSEgIe5V@^XgX*MW z9Z^_?k}!N>Hl)$>fR(KV!I;2V^{&|x@_A)1 zXkQ-|25qL0+;4yV6xg>nXt^k;+z9Kn)q7>th$+c{#dt%I2D+$YEt0~ zug#cEZZN&DxG)4ppmAL91wlXmGAglDA9X0ww>OJG2|1bgX@6bP)?($}v&pkQQyy9u zNfpu<^nks;qvXfoL}lIR?(D2&WAf*9kSABnFM%Zt7U~jl8nA3VV#Wdzk;JRux8~BZ zf~5p&-uvk#eBGqt-Im#ai=rwKj{z~VTQy0-h>%<76jMOdu-DFLy>`@@i57NsEjSVx zw3SZ{J?K0Yb=o1xd4}tiqgq?Z?>2x>GxutH3(LwH**rhEmRjz-I8rsXMm{$7o&_>% zS%FodKR4bYcR8Z9%lop{elfq_P#Y+L8=i5NTHNW9+bZ6yc3Tm>onF8)sS~aJ6?mL< zSTCikq_w9mR|l&X74E@|@wwuIC1vfp@+qwfT05A-(>h+;d$2`-c%e*Hgdhaaq*2Eg zdFVFw4XkJBtsN-JM|DVAw0~)^M#_^QzwCYY5=6}8V;~exRnm_^;^1rbGx)zw;UMTQ z6;I(k+y;iJ-j`*UOFq^mUR@Ot3_V`f+SIuw!h7hh6?cK^@mbeOCpqI<_C&{~T|0kb zZb=rzuHiS^F9X6<-NpEkX2h1TklUsBCyJ45*o&NEq^g+RiZMPjbA$2p^wwQ!EMaVH zU%H{{th+8dZP^Uu3TB&~KQ*pX|JKl&0y)#po?7kfeHAs)OLv=nF=Vt04_b!T5k%c< zVwXj&HY?pkl(=-dY&=~$-Rkj|09+G#0!at}SWgfFgF{uk?}&vDsw#>b@bDbJRa&aL zVp!Rdv^K*3O1u31vfd8PJVepw6|Ft8)!{GQSq0vqjio#2wd$Zx`zMVmqRLb2>peb~ z*V@BepNcEwUX1E(AEL$hZS&lz+CE2mJEXL6*B|XX2JikV;7|IMR8=S0l}ayRB9tNT z+tbu%d&gV!cNIe@D6%?#Bp6A(C59Ligtxydb9s*wCCqj+pg%{3#;uCs>KJq z<|=K3=7dY{>(nyZVpMI%d`3H@wnJz}&p8SK5Sj9K`Vs zdbei zc*&d3_+;UDPxogZ+E=po;WBVM+B*MGZ-0RL;4QT-UsQ=Z$1) z6VB!VRuN0NzXc;2sycoYSDvai4Z3txMTnz4BMwNmLW!2^&43X|SKcv_YgiTZ@di{k zD48G=jKNtnMl*X)X>)csXhmdP zfMaIwKY|mKR?zma5l;h9fMrJ>paA2UeZM0Y<2#BFQQAXWDjIA>d@5|(c1}~`H$%XM48$_*SIi`bE3V^e3KNadc(HFjxD^IGBeCZ9+3 zUdqnm$2)e|5AwjT2iMTkv!#1cr49Lmb4pfCtP*?~;cu7oCLqgdULf9u*B5gFowD~} zhn63`dp^CaF|N-CoN#SwLF;)#$d71`!s~tE{|&DLZt3!v9~kk_fx_M0A;i(A?(V8y z)sDn}2$pN!JYV7al3!sML)K@-i)#ZyTgVo6-`}E1heIh|rJfQM@8t#2@uL;UgjqP+ z89+S>dO>cmyhy&f0`mb=*J~1f^k^3M8D^U|PeE|#cZ^c@A==%g(&Zf|9t8WqGiw$F zD;Vo0ce+JGxQGwi7G>6nJ&%kv8zn4F)Y?98`QrREWHkO57!fKw`p^iDAbENEM2%%M zl_|4MKKEDP!3~XyCVLcl#!p4Tq+sV-(r5T`I;LF;(_QF>b9Ho{sHk|lJ&cI5^8#jG z;aKamXYXTlSpV9j%|DuTQ{L(nzuK-qThiO!D!R;?;cK91xdFPCiNxu< zTRkxgS_~L%zww_Q+26)vXW8Rn{e_J-hE$kwu>B z>Ei{bodbV(9Jw*3T5}NLY8#+WoeL?~qMao9A-Vt%Y=6<;zZNA7l-i!W7qza9r_%j$ zaBvMYkf=h~x?sBP**l!d_VUNo4U7EFwJ09fl_T^ZGk-6=rQZZ+C?3@mNuXK}*ydqAm96cl*`{2@Y-eI+Z5|hYpT6p0 zS^EZVM(HG%ownO8js&}{On($ga>^C;Rqj%R8$1`a+i^A*r?E6|x2Gp3Q6X%x=^I2l zk?GGaDTFs-JEdtxPH=npjRG;~FYOo^{>pR`=N0aD{^~iw@_HBRX~1Kz2k7hE&whis z=-l5_^LcBt!ZW6m&}olT60Uo!hA7#gua3Pw!DHNPEBw^!<2-WX5YwnMRqD0V7vSG4 z^xB(?)4-DmT(6y*?6reaSP$P~9R^3H5bd?&VkCl_`L-RW@!l!?2!8nOUK)(^-jgS`us%R3^K8$xS z{U%I|6XkcT@A!<9UF1AMO`iHn^--=Plr?{$V8d?{GER!n%uk|NFf>{)Ey|uKCsF5w z{MNnPL!_o%94>UbmnJ1{qsJd9NSQ1ul?M3;V`lzKy z475I?K(D^;caRona~OtjXnP3s+j$W`;nt)z^dnGF;)1leXtCV)jT1giaMrQTw|O^u z;Y~9CD!TIifki*kP+59IyBX5u_^IBMdc*+^r;=sX-}+9y+vfUz zfJ`28?!JA(at(}E*5C1R`_Sm8bRBe=!}x_$vH=hJRk4S$YLBAyp^C~R&BwW~lX5); z20kaV{vVB2lKT6S##iPs%WiVhr)Y*+r%RDY3|7Kffrz zds173i%yqo^+idgFTIBhJB>wIp@`iBzMOZY-J>Psx{(nETJu(%v4PlJgntGb@2V!2*dXeiyef8k*ix~vtD%?GhlgIyT%n?j^3V&P6-QBIwS1%IOfztR0m+J%7C zhQEeRO5iZDl2=%%*;G#o-U2pww5R;=3xs>(_*dlL=A{1pR7*9;c&Yf6kai;B_%puq zN#e503NuyLr}T8+RONhMj-WHTe-tu5QBIs7uU;Sfcjq+&K_%yp&?e;%1}8%djHW6Z zGWb@h0y<2E2k`23KM4_M^pMx)FSPFrF_l4&i1kfH%9Qq=+Zd=b-eF94x(~eBUO|G$l5DN_$eFHu(;aTN_l@RO7_^2`%MV#Bqy0qBm z6N?7_5;BJXBmyk3MX~sz^FNBXx$HglR$d|ai}Avt zs#!Fk$;Gh3zYGwb@@^PfnmUqsSH)y`ZXq*X8+dwB?Sl|3?DL=KBg~f4SGs&u;aPG( z{Ln-5>DUik&={XZyr{Icrt%9b={1{?b$$AFy3;O&S2SJ?PxLM$6OV^+`$N%Qf6#sj$jTBRvt9t7&{N9`2B+BF74zxc}W`blDK&4-E?F z{B#Yg7qVfU%Y}7bihW<>M^PyKb}*!HDJ&OJ!}%w{p&8fX0??Ef6c!HR8wiTCV0jrY zgrWly)-6K51%6~ffA*CX(asOv)FRjg5HU@@yh=o{r#=nlFE;km#`0w zV5iOjROr1c=TO2lEVQwxA#uR|aVac6+A4c1#k?^uFO?06rOFsvut=7}M}x7l8ihqL zy%ff0P*}D+05KZUWEq)sI733NcV5QuqL!)gl*UiaE!!}id0%eEkm}hb3{Db#{KpX) zZ!9e}G=3(Ga&t*EC_96v*m(WlV3?TxyZD`)!z-il2K#TlixFH*&NR#sT<|#*Hl1Fw zFQE3moMuQ;7QmXEh7lOSNm;{La2g5H_$+>gm%<~O%3sjJRtTZc;&>80KeP1np3g;4 zyAYa_Q2CiwOXY{LWh3aU$i(0UER272k;5_Q-SsxU_xoN4Y4*%0G5vVjO8^ zCL_RzKI%qHu6nlh^EN?zp%+^%>`QUnTZm6I`d`R=q7>18BXPXsO~r7q7ez{@UR26r zSBeLbldYz5DIBK(W8_BSDnf?1!<^rjaW9TjBtPP^c$Nz)yu>taDp)iB&C8Gi@Yb8Z zd`bDBiIRhy!sV)7zgKl37uSXGNEHo=<19E`je{HDk|Eg+&R=&a_t2E$k~5FFF%O8EKokKwEN7?zby z2I|_Q*0FmzjG&NH(7vfYr}4vR9Wtl+{geSGmQWw(IhL!)I^V3<{W@Rr0fK`yZRxa6 z=d;*Gu#IBNVPoD-@}5xVpm94~?{XJ`v-9a(OwqX%j?+HuM*KQgQg8>_o{W2boMv$k z#c^HNKnEOXz+_$N6Cq32jv3-FC?y5@u3r^ zmiU1o?<)!&!eU5vp}j^8z!S-O?U|@gK2CKI;Lw1N)1<^h<$p`xR1W+G0SyUQ*aCC; z3rTnycSt@?o5ZZ~$xO)(9le6thK|F!s+g8XHdqGz3YGm(n0fLzqe= z3}FKwN$P@X3j-R@-*FyK;2~6vWJ(vHJWZur_7k_{qeS8imRS6BkVo~`dQ4QIf^^OK=e zZv>`RY`K?6E%&+fjGLzZWZ~U8b@cqHnkD;J#2#Y?H`Q7qZZG|AXwHI_1L@1>5!!#1 zX~N_()(O|5VzEGwfC%80~ zj=LoE14v}Tf#Jm?)P|o*Ic~ZfGTErZ6If~dpA4T40&%HJ3riFJL4=t|@dX4ZLKMyX zoo1Kw>p-GnZF{QGrTM5YXcv)ofH{@vnHf#a$C*3BT#i?Mi8nb>Cxm&XqN%?3Uzs9_ zD->WV8x9!%M0Su# zOqU=3A))UY>v7SJKjV!rep3mHk3F=8AV~#B#)6(iu+RLaH1rVt`a`};T>nCA_&CuMLy9;C}C15mN@$|ad^MEWKkVIBPsdNP4gWdfQ<1Y#lSjf0%(EnF?bMSKkhTuvt=8C$V(SM z?k087yIpS)N|!_%{sbUk(;2@bb8eXLa6Uz-KJywkplRSGxFN;isxrdqg5+^*Vf=M8 zXR^_R2B3+P5g*nSJhU^3zq5pT1BvmlR9$)3XAI$`bjpclPn~c`izgpi=LxQ`A7Pbl z`dyHa|48YEVJkKK<6xYP4?MtFQ~4;4|IuT@ym*Znw3v!1z>b1jFL#ic>Vu%KmmIp+ zi6;I%QimwxVI|b~C=l<_v&dkWOqo>4AAyS{Vgt|8@oA})Ps93-L|mg7Hc@}3@nOwp z30M3_^+s5OV}LDv=&NCEg1>GMIeOGCWV1E9kc-)c@JLNp$}yY;Cu=c_i`WS~j$t`X zf$7R9?xQo}_lX7QJTO}b*6WHwq;f z54_Wv&>)wJ4RVnIi+0Z`bF~VJ>YjU4R0Zdwxk~pOigM3+MRm{pLs3<)DC|bdRqR9F z=}gGZreby$zlG0r_#E0YJc?d0hC|-zOe&@gdxaRoC?rBGs$}pzCBJCLrMm(lCh~C#s2jW$HMW4c3M;bWc})N-EY2=DyZ{OV}ueR^DV)B!mnJo z_Cr|LADHiy{B`rI#X`>fs-TTwe`TbH2LZuluz$0+5J2V!jiZ?@am|8gWX-gO4efpw-~`58$!vGR{}g zVARQvqX!*(0onchIC{V_d@zUV4YR-b3w$LzVa74@Xut9mk}M+qO7^t7z<16~nSmZm z`JTY_Qy$WgVO_CFewfh~#n^j`f<fg#Z|17HBm0}TuY z1I)8$I5QlQq6y2gL`iD)f&`#|i02=-Hy8C;a?|kR{&hH%k z2dxiJGXvH{tb3t5#PL;}!B;XmgOx`YPXn+}5F1!JV=q2I4V-rbLqrT=l{!QvKO`A$ zDO1vv%2N0+K^_hnLm=nvD`H+}fs87uefaCHVVV00nulemY&7+s?Y;mm4wXW<7#|kL zS22XIWE4wATqR~oqJH;scP~Cc``4F`{E5nj%8q;cKsf+Y2|ghckO7RP0JZ~}ve>?R zE&gHA$AZ0IUz_@l5^`_tpZ4QId_rdK@IpVf1DR>D+lPCF&72pInxGPL-&$ovZK>Gt zsv!xNdS|^dJBm+8%Z6p#6QOR*D=FFO_jri+o|u~zDdd5D?|#?~tlc$7BKk9u|DWD4 z{8%C0N*6m4s5%P=tH?-x(D58S=y`ozZ*pIeg1R5$r7odXDFPYLU+R+3J|f6opDwZX z@X(ZsrG|iW=0y?WnCp1F-LX`k?(<_x3w0zwpkPtyjKvN>cVnRkQ`nI_nDs&xpid;E zy8tU;1AU4O-s<=`gHAlhatUSNbKv4QND}#Kk4z$TCIZID_%#5sclzsRnoe0`ZU*AcJb} zgp2sb3+a7QcgkaN@hPkvH2(f~iedQ~lNaGP`lSuTKe^#Zxo{tJq@kUVLUA0)iTEl> zP02WkX%xmL=%B_(JPb!Gw1;p&qe!58MrgZwf;fdoCg_FGN!^o~@eo!JiHAxFbbD3qSTSb?6Bo0-;$Q$)UVWavN< zlaeY4jZ}O_KkC(p?;gR;W@dGGIK`j=_?kCz!Ffb7!f0g(xI&LNMOfQ$rgnsLur4}G z9>Uww^bXgC+S3l_pTp6lszLeO=^pjm-5yh)>v01+y&BVmOev)MT^HO?lThNwJGLBjc4w!^7xq&x4rt}E&e@QCcK+Bgvd;>=FZEBT1dhQcX;dIPicq!_ zDLUbk|1J#IVJW>6mOnCfjKd@#_h*$-+rO3G2^@3IQsaRMl<**usm>2fkvUca&7j5} zkaw_-(4iqW6R(SHV>QzBIbV}V0Sn%u&pENtoc9J)T1KF~@vcvQZ$0cykEyIbPjL5t zjni0lvBGI5K%}=61lE2gpvWJ}2Q-J~s{vi1t;ll~vJqtOOboR(I9UQ6nHClTPKO4( z9Y_Q4;uVGVAsd_s8Bgkm7M@#PQkY9w4XC4j4HhK$Q(Ui1tyT*dyAM1~%c|Jm=9=)a zK&k%F#KMAxDgMD>GB|(d-LQGh<#F`qy~XJtP{%00)9&yZ%H zQudiSA5U~aG1C5_zwz$IbcIYX3-fl5rE_&-2unS1W^Ih+utCn5G<7s^pSdK3e~H07 zP|?m~6e}gQBcTEp(&-sxhgVvt^VEK!u(_;1&FL(*(BZcCtF&xU zZhuB0#Pz(hxhw$bvA^5}*=O^fFG{Ahu(Pz;hCKcQGR|*5eroM!20QW2sWq>`iVLS4 zg3lJN*^Y>3sSlps?3~Z;R-Frop*Q&068iA<)0>JH(mb|=Np9D9HMT5+Fikvdfd)+J z#h{vGUjoREX-6P$EjEUscj%wbt}pe_Uav;ar5I8wh;4~8pZTO*TReTI!O`q#`l|7z z+6;*uHeA+Wgn4uEGze4_RLE(COP6scK)VZY0to&`5J&LA$WNWvw zQjyW;l|eO~}AvXQajqHMoJ7WQ+8W8l9>BZJu?E#9Qqj$5rPA zfWUVWZz)$2tDQ>|QpLu(_j+WJpfxuuly3l!1g&yY+MPL#zS{9;7vmj2EHmkay229s z_6xB!oeGzwhM3)7Ys2BBQ96fZePX|N%>%RJO-U`(2enfUpN}qe_yulv#oCYVYb5l< z2j%P9DFMdrQ#Pav%f3-j#K?j6Y+O^g=q<9mw(l&M0V<0fDZ49KgonysShFQq`_|W0 zu*Au%|Bk|+kiEcOiwjrX?<5$<+*}Br#ClgG>*e9HZSooy)7ppvS~A7L>)4UKAt{79 z%ihprPvpRC#>*B-@($>Gn8I?^Md$A(zq<}ISLzK|=V2;9_<_vkw>OtH34A&0P*JKH zcT&E+x!i%n!SYPj;IPkcAfwChYWIuTeMI4)&I|jJb18prse7d=zq6`_-A3In>!1PB z+||4;1vPKFhK79%5}SKNgPr?(VM8JcXD@50-P`&v(tytMnbVtw_%OJnxM*X)u&Xur zMRZ0>Or1t|;xsl0)cg48nD*~I+8%vO^lE!~6^yxauVY>zPTdpRe+QeTM6JkyvR7IG z%9=Qx2TvMMoL}cUFQ@C6UYRWv>alhpNu8JT?lhRcyaKa+JHVM?mAfpSB(cG~)>k5L zAuxCWSu3dV#q7=H21%W-dn_?%N`)ILsKvgmgd%TsF5}s*Gnfdkx|B|y+`fhi?_N%y z7J5LZ)As%fo$k`Wz6yMU{>8yN3Wn0glEP7!%{4dsbr!wl?0VIIsmirgE#v~4!6K7? z6WfB?j*-KVQw1zlQ^1Au9@9fze%`ya)DvJ81aG73bO->uWeBki^3<tMDFhD7 zUS6`ioYRVLp+|f#tOwBZqBo&Ft*WHHbg}yClURWFnSnxO4OWc`R^9Qc>JGu7LF-kI z&Ly^bm|yA^SBS2wLh`!xYJPW1Wz@bh2ypu3g{7{L5G@gmt={=1_>_4cLHS_3^QF|9 z=4XYmkm71|**EYQ47TW+8i4%xmPhq^yFUjCN8|=Y6~u|0CTbmF`?4qkw>;<7G#daU zs$H#$G7){#+vDyFaHK7^C&=$)2u278S}X9pA!bamyfZRP~EWDEh9#4Xl$S(OwKQ6G)kIns*k*tF!r$&;2`D=%Y)nY>*F_F=t@t@U+>;wJ$m(|q8fad;4YYrfhN zopeC`+M@*6lEkhHo-XXGn7%Ij;r$+m^J+d`-W^87Ms9tx3s%FEP$zFg4ENZ!_jLJZ zGF!NMx(xQiZP{1c#uqPWFApw}FD;CAZg{kpk-S^ayEgIvCB3~BZHYQ>3(VXcpkYnq2hsOQ#BflBhmLR$dG zfEmMpPLB12`s-__T-H5+gePyDl38L)@i7CGRWQHne)K;y;iB#uYx$8oms%00zFg&GA^Wt#!ow`kEu;FRv+Vf#X*6P`0_D@aSssb<87*H~Z!W)?B); zzP$J|V(f+g6$85d&hlczmyK>XKKU(qxKds&sK1Ff&#rHn5)h8ra~tq}y=4Zt{MM!% zs;OHr1J-Y>Y~eenVY~La8^!JG{f}g9^p6=FZ*Eu97q$$6$n%l0g@tuul-PH^8q0Oa z+r^EK$y56(gn=5pu$GqlV z;#T9eBUL*XeHWAc?z-a#J#(coa38m`LYRs9#(Sw%2lQ?gOgQ`Nx~C?4PiX@&QokcO zKC&K*CrS>9+Q^R*f@?KcniZ7F~lpK7qo_6ZZ3A75`S%k41Ysxrn|r!C41l6b4K)$nXwu2eP<;I`kDpa*VY4`$tbbHfl$ zC|9c$vwwr5t$Ob`uX{WeNLShLx8?CQiL0!uQ4XQ$4n&8kMsWVQM+t>N*?Ux#>}zg#(C5!&P1-FaRObGDGKs|`akug8yL8FS*8jww1? z?Qx`hV*t$2K8kQ%mdPzUUNF86Rf+Epw%_GcM0fCLm!deGz8Hi+Scwn>9=|M*6TPGU;gCJd+;cABd#y3uY%;Qv- z^1BR77zPTbz6KegnE>22g~YK#5bD#0`|z1{VYCKWDkcR~w0CyV-1nHtvQg+C7);bIOp z5tcc*DSKG25w97Td-t}tj~D-?4YR_v*&=<_VZ&3H;MS{+@ELDu8WRM?rm;%CeHu8S5JYfx+|5)#Iv|f8)4;JH5VG@+t&^XN!N3 zyRk(jg~JpnGF{BCpt7=K>*%T)%ik!q*;%m49cx>{@tv|HIGnHNDc}hh2dk5&b7_#? z3Ri!K7~J(K4Op7vH#Mya(26{Gy3LbyUwwPZ-MhO*i#>QlZoA9l1^N1Ew7~9?#U7Uf z>om1#9nDAAZFV+rlQy+pAiFb#M(=q_>l+(gKW80{d3$`kq_KMGSVv=-6{H$OqkrV) z#&K73WSyCzRr59EwCQ15Mr}OH0ZaBX*-!Sn**Vh`s9hggmVNo+>7I|b60xZ^mp!+R z83beVo#JT=VQgDHP-^0lLE~2~Hn<=HlWiqmT}F`CX7P?ixi^;dAnSf}u-M`9<#jVy zmEYX#6k+ndMs280MVnw)icYIgDL&-0j=)_vbi8*B29>JzAIDcYD>&++qZ7wf8eVBL zzY?f|Ij#G(qi=P?u+bcExTsMJGTJ}-dWgP}pVb_A>r9sImH!4dtDE^TH7;b+jC)ga=Om$A^4b*m~;6JS@uWL}ERaQ7%(^+n5q2c<< z7pHK=Eea=>4Iam$r&ac-AUA6TtdN*htSlaLbTDhvtQsIGkRFk4Y!x@%RxoJ@lRW_T#pC)zo9UgUEenAx_BZ5x+);ztwan?I zp=ImcphJ&d`8yKkI|`@xsBL)L*I)x%UM9?8--PbN+LW8s+UwZ4gr#lbfcB6R0%V~$ zsoX%YM7ho1&ow=S<=cY{fe`ETaK1SY-X*R{6O76OtIB%}lD<6GyEsvuw|Btywz`U` z*qn`}oFy>E%Dl(e<_%D7m_+*Hv6OtTe9QXn+{#pgKt)%p=_GZpJ+XfVDKoHO_uKE@ z{~9)@Or$|%iK=rgXzWF9IW#fl>9z#dIItJA_7I3MXA^TkHq;voc6Wu|wRqJ=LWeu4 z_VIBpt?u>DDI{9tp%(kpwQPlG;XI#jjvoO8W`b1HZL3=HD=urKAlz2H*8ZQ$Qk^uri7>R$Kn;d^5*-cR&cG>m>0*+LQc zb+;vyAn(OSXNZ6vlJ`<6{N;uhAgpI$g(%En&YYOvGU1cF_I&CGy=zAc$EbG=khpHY z&$$-+g$x2zvRzKL^a-+p?(Zq;L~%L~5SDS3Go|<f=?eR_Oga^xtJ7XE zxlDWYxu8OOa@CFXpgn11iT1MSG+2y$B|v+rS@*Oe?Ilb2ps3U$?Hw7MwSOxfZ2zV} zd%3=#CX3E*d2CNHjDm)x_B9UDrB8tyWsh|>g?12^aS_OYF(e)leDWTKmi&XxHD1Lq z-ixU1H4$ac;4?*gXArv4p}p@&_BC84`_w(DO}I~-H=5LDM^g4Rl)&lSAd)|j^HuhO z0H=W{?{XakOI#!R$GnE}Q4te^2gEolj7bp=>A!5pVvPr);(rlRF;oWY^%5cb*FhM#(90RS$pzCIteX}h zFHn8Hh8TvWV4$c1rT5dkjL8DIlSlTIJ^9P+-w7ytsX1lOJN%mB)|U%wKqHO3r|ji@ zOks5(B$Yj~s>=kNJ+=db@aP7(tH>+FG~Em}VOr^`&_j2~x}LYf|b~`x=w$Yma!kB1jbg0G1&UCC(6; zaaw9T#f4RLEZZi%db+I(hS$jjgjEVL&9`1W}4_pYdv$~g@Yw>B5 zWKScWhSiJU4kDCXT7rt_67N(osHQQy>;agHUeUW2%{7ksook4-z!%6i-YbA#2#h|{ zMg)Nt%9s3MhQ`by2xvLgkwp9FK$QBxB8C-eXO@l>$QHIUft#Xo!Pcob76bFPh4 zmA&CUSgrIujI_xg^q~j%mAzyIpH*cK#92Z8TaVpBD&P?f>wiU<{21bIi>o8bo&*}R z+_6EB99{hgEyH1|yyJHARe*?&AZFFq_#DbV2CC5el%Zf}H{7|_#~=ZLlLx0I93yhH zdkzgWdaKy^j2{zi$x3soKLeLD$!k!>VIJbzzKqs~Q+W`LAJe&T8;+{wVMNyZB>P*; z(xVHAqcD63=G_wvU;pFww+12X5;ezlXayU4(dx(D(Q`Bt25&fG5JB`|a!NRCf}5^; zFJSN=(Qg-#ysK{NxcU0xGYyLP^yIjY^z`x8RGHdMKx+cpm3TmwIwTLW&UHcl_;Iy46O`GApo71l2_r=29x?{A4(mlX@sNEA$+u*JZ?{46 z0XC`-9s~QzSNX<&MgG)UNGIwnd-YG?&jRExqv1hDFC+%cOJF9NTw3gYwKlLs&hv=@ zWR92W%QU2-}qSq)p?(xX~Q-D)JcOW023`Jj}_x!LhEJ?ra5_ zb_f*_&7p!f@CK%m39mHx;`dUS3(<( zwW&51NzdKiTAo7GBqP(J7k-18Rs}vX{cA`=#B_p9QiShdrUP6~Y4wUsqbSfSHRkZ#2DV#8PeeHsPyQUA53mR^A!bPXPb71Bbw=hEZo1!m_x}}Su72;F-{QCLol7HK zYX3*HzZWgoll~qz5C_k8FTg0sAt-xB^;Cl>s8Ye>{$3x-&ds8VlKmE6=^wA?&m_Os z`48M-1&upDH(5W>eE_bq7`BJ7z50fVZ-0HgAD61@Q|Yh0fcp&N@{waGwydH+@Z!2v zgM@xN^_WSBO?|^E+Vx#f#v^!utYkJro7_HcHPj{U5PE`9ARC zKLyCUE2i+nr*3F`5ZRS+XrSD(>d8{jcuRK|ITHcz3u4JIwan=&-syB%pF^sfy3t-L@_Sg%nh62#b< zCQN)skhgINPRNLCyzFi#-)-&vNA^05HmxAQ%#ER(^yRmvrsxUVok0M0uE#RWTJKab>wVf9#>)N zsMx||Y49&JOL|z@FY50ydrOpmxh*f3N&T&fa#-OJO)$SaLn^=7>|c(_^o*OxIkpTL zJHmQl(!NcmP%5L;FtReom!m2&yp6Y}H4jri;5vTN;5mW~W)6vzm)m^|mMewEoSzey zZxywd$@v9XdKk2W=rVaBr}=grc;M+yFtYD_dg2a~7lFnsCv*aScvc~gL*oE4{1Vz= zr8qv_gQ!kr%9S3EiRKLO0-xx@M5AHlUynkKkayHsjr`r0M0ogqs!=Xj>LQilZn<(t z!@Oxwh+=(a1dSjVU*bCVmB651JWI0{QTL^}8>K!2lg2CgzBvnN0_HG3c{*6yaBISNv)Xw%S~Vyx zxb^scLtNOM3w0?M!r~VXGp~E`VDl9)fqliJgt!JOX1rM+|Cq18?hw)N0PJTTl?0P& zmuvGT;l5Rx(!P+A^yOP;NZzf_-_hLHm@jEK zTPn<#+60FL>-h>LRo%_1P}%`>&6a0ndb~(V3xtqg!CmHPzCp@4_%q{Gg}!kMT5_wJ zpief4jA(31k>vx2RpVpR4)YsQpYlrO3<=85V%`pA=Mm>+qzEwD=|piQhE6pBKs2%L zS7JfAFS2h)`D$FH+}vF6%Avy77b~{IOhf$lbPVlY4EN}y(n6*_8k+8XTS-L5(nIeu@xdgv6x5 zvNZsMTV*;FQHis>6VtLueH7ra0_Y6L-&Yw=0^fCYqtKKcMBZM@H&inz1CF`?vwZ*# zW#Gn(#%FC`wr|E5jGuuPUP0!#6!PqK{EjynalDDR5!->&R&DkNYze%LAj|b)93hd3 z$l3!1Xpq2b;bnT>6U}Hku6h#zp!u!8lx%P09G3citg!t$WoOXJ7bGM<^;1+~h5s5* zd`K&9{6aKo@~zh_pDfCM>$T`JI0FfMZH64Nv+Cekq=T=P;JR0vE+HDzDN}>Nb2=?{ zISkF{tmT3BRr2-dqZ}>>qVXZDn?4l_6P7DtwEJMEJf{t(1LR=JeUTaB(5&fJO2Drq zzVXmt&kW9QVPu2{g9<0XOOV6vlF@zo?2^qO7~ZVr)wJE4v*$qGf><$ zU%27-`-}*lk_Rpm#>cOL_v;TaL<-a1Hgf$sY;eC3g6*IVDP$)-kU%|uZYF^Rq54f; zCockk6|CO6{%mtz3x!O-EI2e=b_f);Ud>O&{BbDh-r7zgtH}R)<1u z{}AF+$olUv5WJjrikah{Zm`yxL$}A%;$pEY6I%E(uvJ3~wtq|BLB=5@B5eypp@xuc z1-pG8*)Nj#v?@nqy0|UhsMdAT#+wV{3ct7j$xc|Olja>%HSgrktnJNX^+gjqp*C@p z#9(HUIp{ID>e6@-;1Y$9j#gp$;4&NwyCKLorL_#Wp{tCcFZ@2&JI1uE0Ho4*b7edz zk6`!ELWhWa10{v?;JG_|B1}Gv^8Dq6wkx5QVA-P2+#tjuEkm_v5L45V5=gEnf&4Q5 zO4`@teY!TZ(xcBPt_yg|OMi`|42hdEbh`1_|-f4J)p*UK)EBZu4Q{=)aqbVf#Q^!$-j zBQUgJQZ`iX0X#^&#XLGD-9&sIFq^)qu3w}Kq{<6#73q~1rl##HeB>Vu#IPn9ljlbf zmycfZvhp5}ybbBsRr^YMda5IZZ7d$NgwT6=vN&a5DNYsbEB;8)UKKT(oWURJ?%*6R z6nZF(AXA;eNi!(ie`0DHST{-@UghqHPAd%Bptr$z`%3BGkg5@VI1yI!R5W0wac$5^s9d`$l>JZ)Zwv#d4<+FZ}aZI{Pa|pu#!M2UAqpV zRr|_NaR}c>vmH-^Kg@V<(8%B0R}Qn?>&dLbLx!nMF=%<$4^{h)E+@~s+9zs#0>*{YjAoK?*i1bD3y+t5sHxrKsBqikLUmv|U zRK%kNEjA&{wnfPq>qjt>PrsV{o-vYrECeZF62XLhOp_uv=qNKnf+AK&&q2ySn;iIv zB{6Fxfi)%*}dzvP$6-{4OIC`98Vd}a#2&|pWxQSk<#5AKEBrR__&(xu zi5-QLQ^e)GKt+2M|ELkv z;6IsvGwUxuqfCe8Rv)RW(WdfK&iN=gL8*5!Y_jZ?%Rd7$xy8c0A2Tnt3b%^JU*m4k zF>shWp9QhO+{N{(5q#_%QF^zG{KE&vbD7&I>#Sgs*!fiCr{HDlJ{A+(v~dI8d|)=a z>KFWGEA^(?iuZredqPq_LcJ%FXU&$I&GLSNQgv^|ek}PTcgKuE)LzfN4dZ$0z-$dg zKd|n1Pfg)yy#MD8Nu4LiY$dnNR^et<|J25Mg;sPXH7)`2@NfV{+&rZq)TH%`==%;O zb2#lrwcE^%RkTljQkGvoz1jVMxe(it8)hq^^&XV$PrKOKiM^$U5Re}x?U`u#F0gjs zUh88h2*@LyBb0?(BC()zc8t4u=LOOHIM*YO^NGUkMYA<?l&;8p!32Nu>-X3H0Sz4w@S7Y~a>em##4SY<19%WQduexhB9Eog-I?Tg;J zi+i1v2XTw*%VsMrm>+Yi_Kg*l2VmI-BvMSi>F$uwT^X6T==68YDjJ(x& zDeb~F-BJs{`1uxg#Vy1A>xupZFioULPaMd87pLj%egV591w=*oa#27t7iG6b3%fvO z7OyX=F9jxV9Ktf4K=ivQWobsa@;fHAX#I?!hYm;C zzhWEPY@}?wfPKX`RQ-#GeI^j%LSzPvrD~*cA!O=zBLz$rS*Qvpzv~@9mBpx7liMx@bi7r+(1>^2(&! zv(PR%lX@3pxemI-Ap(&zU*K{5PjFuS4HtR{@GtHoW^b*aZEYTTP#y1m+->B;MDX@O z8&;L&haj}}x6DBP2C#=<4*>R%w`pkAAn5FZ85Fv{{)$Oc@}SZ3TP;XX>OOcRWwj>d z>qZL*OH*KuZ+P7p$nI`oxB@Yn-CZ_a{tEf?>{G+M{CP4O9_z4Yr~VlIIr3Be!;|SZ z95>Ir9_IPKRRh5E9_E(OdpyBlUeK3`x`kr|eA1Xo2Y4I`g1MyU%woz7Via@9#>h5ND@pE|AL<|Qw`}^1&i2OqK7q9%lY<*p@yocRq zNr^yAdQbrv41=I-~U1&*e)lVrk&E-r|0>xsBr%vP#OAlKt`}46uPW4-dLqH5`*K&ECZ- z9UgRNT(>1s_)PsOS*0rj@ob0l&7j+Ou#s+AJvQ zy8w%>*^-aCN*I3mABXTVgUJE2H93GUccXNar}I&S;cEL4k9k%whY)<5FrGo4Y*NNA{N9Ci zbJYXGF^s??M`W0l8m&U|h~7#J%Ot1u*0J1C@HG;3!mF+LfZht^aye@ec#?k678s7l zlIMb5~H zU+0YE;x-Q;LcZzh@jCgOfqZjRp$8+)SS+Sfs-S}($ad4qreL}Nv92X*;2y@te+4yBbiJWtle(b4oD`D0JWmnzXHjNMFG7@LJf zbTkaWMCnU~v{8#aVYRARMKRpxpAh1vXIp;G%}_;c^4k4tFaBU6{V^{31eVkGanzd# z{dYd3v~?tner`T$5o`qV&$`s`x=G(aY}}yH8=67GPMan|aaj~KOe)AEIg@tX?RPUt z=F@-VM&BqoG=`kMH0%Mu><8uaB#$%ED)M|NCTKfYUq^;?%=h}v#2DT-E(2O)oo7nZ zL-+JU^NEJr=Q-O=B^ipsjv8r3B9Sh`ygE46K(^o=dB`-0Z|r0h=tWzZopb~iQ%j1D z8^lbBw2vRs#0-aA`@#_3h?l>ZlTi)1G1-O=L0s=YK7_2beSOH>lSb>RPcwt+p`ngJ z5!GUXLdcak>A>#Nd1gR?9Stb%j7h*NvB`9}O-%ogphSY5KA4Q^eM64UMyicx;mmbs zn%r0jP9+)U62?I1O zFgEL+$S=WfU|~LOj{S^RVxzgSb5i`QMic6tUZg*$J@YE9W$Z99WqIr{F{S3KzWDc^c8hE8fKKum*!G?yz|tm64wO_% zG}3LbObj;u&#r+KI2Cc8oy_A)1b^3$v`Y!4O};kbT>RN@dej!@hUI=t0!XdYA@D?v zWDHMyxqA->OHRLFQ)Uzm9wY`M!v8#(mOC_9>+;nXUlDM79rT###1`F6Ah$fc7K>&{F77|uZ%&*2pkXaxg8ehrL1{+Sx+;AEO>hGj+ zV!M@=Q!tqvyl6vp+?;!Ew9h2@`}U=wl-xQKc`n}vmqlv7cL~WTYs#g}7_5E3CJxQo zT!L>SZ9>Brdk<)Vtmc?^j00nG#{$jk)wVC)33g@NfBXUZF~AT);@ZeFld7z8bV> zxYUsE!^2~ImBu};`1)98W2_-F)mNVz7Y(Y8k4rL)UObXyzbM+0V8$y8>2w ziE$nID!Il*(%JC~qj!X!2PAgNoq%zKGw z!JPJ!EkS7ojUF-ymU8t4HOE;W^7JUJz2A5!ox3BCGW*Fy&UrX;yNCa*^B~DE%q`#u zh1;K}M>tpr=#yQ5`>lt-luwylu1ie$f)cEQLJm2t9XJ|NgO-QuU`G6OBG-Me_*P0A z>`yXt7{=jL-2^NZ&fiv`U~p$%x|q#c3=U}hSiPRb-1yl38N5i=l_d>I7PMbR3Z1tS z1&bx|8OCSiSKD#?lKtVi3x#Z(lKXAO96FY*yEMbexA3p~X(do-Qwc?BUwB*@%M517 zVkum8bil?ftxKE=FX7{&@zG>OM{XSRqZ7wp=`#5rx`1qbRqC>2y~`4Q{i&n3I_Eb> zFHF@{#&mu=n=O&fXX@FG`!`d{YVL2PKIK=QNPVySxUc`8yR0&Ghw1aI3rRNx0X(Ji zeE+*TpTvgL_&CllOkuO)pYrRUa;uD+7&O9Smldb#I5zT4orn7*S+ZEd*SU1`z0zRq23^psi z8K2JM3?)Bk`9%x(Biy8r`i{kpB)rO_M-Ms|mq#yPcFqB?cK8IzSzK09y(TyCJ?9)Q z8O9YOI3tMNI8o`KQ*eor%0YCT z<%)wvvi>>-?L(opjLt43i(NmjY??*?QU!F*aH9!64*?O8{on$&v_-4udng zZ!1MB)P2^QZLK;G*0_-!kQfY$=uhsCME;`(rnd_JIY~$*QM*9YW80$_TqEE~rL|Up zgYOvNHqqvf7qKh4Xn%~?2{^0@;Z9G0e$-!;REnzq%fmv)bD}vz%W$wvf!%@X1zOXo zo}*(8fMn``PSpd|fJQ>^9SHxrx9XlLRbhdyi`6xSwy1gx&0a^O6*T|eBRNHM_(a;_ zSvQ)iZ`eghV`QF8zGDXvX{P!aJ(^gvA=G`1SBGnw>rH7-Pbkd>h{JXyu4%C)e-DQo8fW~Shs2!rilt39~YB&z1 z-VUd4M=y8(xj)2{~T|UVE;v|VtkO@SwID72qB(BIbQYIVSufVEzN-dHWO6g- zA#(;dxPnvCyEw&z>Ld1m(p*e0$`ZgH%S+Iw<$oDkXg`@OphVXI+D~l~H9wx1H~%Lv zc7mD!HA&;VT7fS82-;s8nDHBf=Xz8q z7cf32zt!QuqD-+G z@)9?5u8*7GoG55CI)=)NVa%{DWph~vD;BD&C9j5FEz9Q=_y|=AHCyOCh0ZiI)7=>b zx8pVR^lddw=geTDqFhwLrK{2qW+tikWaL)2IZ(%J%#k;&h#qP@HPn=2^MDpvQKk(i zmJzE3|GXnpTdd~?^SDYENnagk_WGD3B5fBA=hjMgC8spy0O=$dK86(U$J%0`0jLww zKh!!RK>D4}7D`oHtS_gRZE;}15`q2Cm9f1!-dbGHMd+LZYp`P#8~wZ``ecdIgyC{q zn5eAvMC$&N4+WayI189VP-;0-99)JkUEax-6`mXb9MJxvhS2~okdT-|AGUbjY+_no z=!hOI#yeoyy=)%oFYEAD?98G$a^-Z#>(R&qpS6F@5hJ$@&tMr%Xv<_Epmes2lEqlo z~^BL-FT0r~Q5^-d!U_NsIN6&`TBBSJ$&hsSE>9{4Ds zX%AMqps4DbI2TewSUC<<5UoP;POfB8La=zDOO-UG8zkT8BG9&Ur$Yej7HknQ6uf*( z5$ER$fsO}u`gl%ZPXN`pTf%~Gu34C~MK>*iw=Me2{*iOWp*5g9=T)KSzKU>92cdpq zVXh3kkm`hhW*ts9E->TM=#z!s+39}?0?F4b&7o5=<@{v2WHi%5cl4uSbwr>) zJ<7Tw*UJnaHJaI4f{rkU6-sI2e10fpobOL7o-t^iG&!3#nv>~S?Jgzd>}(o!JDHuu z&e<$>jzET+0|NGyve=hJe;FFoXuDL(x+l8#?4v_g%EUae!Gi|#7|lq{6zPADhmB^G z{b5>agu;6BNTGhm_;PL$3k4_yvH6ZTdOHQxNhVw%wVPgI7!%Y0=1`_l%uGpYv!Qgu zeK>{kbJ%i^h}f?G|F##?y?@<5pYBq0UdC8zrsj?2u={n?t6T@6WIC05N&+aCzi+g; zo+)63*ZX{?Hqm#Ef4TOeQDCg3#?3I@~SKpVJGLh$BW9m)9jOU&eJ(Uq+}0P zja0NNe|+8BTwm|_x!wwxn#a38!2&OxPAMbFgLc!WD<1VoQdN(DqUFfIfhKxPny=L+ zEbcyUQ`7PdpL`1|p`|4me#Wn1-^$9gbpka}Sy(8xA#g{ss0sGKXmfnLjQ;EdQnEsx z;#;fjcZk<_MlsGj2pFEB*u z2Dt!eoKq%eVss~^OqXW3uafjAG5`nXNrPYK^K)Z`j-8c@+C;XXbh2cH@=3KT)w2b& zm#yRq8Y-;|?IFdW3t$vX6m+aHGle!@B|Qe;?}*H>m>n%R3dR~Cd#riFjldc!bhAXy z#?(%LnN%H1aXLLf;68v&0cGHLpRW&t~RuKW2a@xS&!sqXpYog*D4lsV>dEiR(baz*VQ0WEDhcJ2kq~ zfh|O??HsE*7$*zal^Cu{r)#}ak+&3@tuG8JSp1?TSIgrgTGn@Lq9U5z3^i!rf_|3T zzT?euU|tWcAp=={Bq*rhSQxiBYUHA0jef!89((EHB>1Ax{0ff@o_%ncoQ*H4^pVUe z3=ANgV4c70uQ@oJm={e*DmtU`@@Zx~MO}z+g&yE`$7xs=&?NTh{-jNhymWDH?Xbl5 zQ`z!r<0P8z_;d{O2+KCtFgw1LQWj%z1tIfjvo-s}eTr1QxOq&G7)Gk<;Zy+wJ^#j9 z_vC|EgKnzI_QZNsy~or3m|(A;<%3fK}9;QwoiPaNb=*_ zx&^b*y8W@*8XbpbaBfw-M}0?I{~Z=oKMFOEVc)XWBlg0-^Y(oCdKn9fTE)bOp}E_& zN(0j6USy$f5c`{d?}asYS?!&|vD(=st#hiDzIU~;r6Kw6!XE@h2Ps_FfTSh)M{o=~ zaO7$Vs1|znM-Jp?yjp$>P?+@|pSW$`-#-e?;H8Vljv4m}@<$VuHkVl}ccIpNK3}bM zPUqiV@9?Vpqv{!tq_X02)kKV>jUz`$xX*s zQ8bP-(<3{!OpP-gMiG^4RnpnqR3>+_m-}l^?e6^pK%>#!=>ER%obP<+{Lb&l<0K+z zwM4K>9p4D@oPdPRQRi^t1Bs?8^lLVi*gH$D$H0Fb{=dbSQwv9UoP)&{@5CS@Ig2f? zEHD;v5*J!%5iea3B&M>ryaIaV!9Bk2X!=!`C-<>Y6FmE~rbYkg()Mr|3E{o^E+ zb4qP}m=*yTc;6|xR7yaL!9RRFk&~?zIQ!T>#X5P)ozGQQT0V@Ug4b2>cj<6ED;Buo#CM&Y>FZ16uCmvc;nTcQ!uPdRn`YJ*s!ey8 z8vkcFX7ZKW3su$4wflMV6r;Zeit^0fh{|(FBwy6H?8u13fI>xJ@i79KlbDUuv#UoU zZk@1N!*N1n6+~{c%2w*6B9mZ07g@I1GHMvh=**#6i79Rs7HomUZ#blbBhW4HEsGpl zcH?1T!2?VA52oE%k5&qz3$*AW6B)v~x5cjyFAXi>YEutO>2t(IwoI@%-}eP<>YR2h8>>WBGZRR;1m$SL1>1p~nQ1FJ2#7MTcXlGb;*$ z)WM0qvG?X%4(}E?GzGWzwdfpvSDq1!7lMd2gliUu*r~#C_7@S9wdr5d`Q&#IAI2bB zug?<10o*TOCZyC-UJ<~XNWz+Ux(>o82;}ChDMW9!U3?2!ICtv>9zNY!6?)5Co~J?! zGF*Z+XM%+me5+I}mlXpd#C5dJq<0ru%rWu(vSOj6@tVbtu9QLVg&d(#6p1?TJxn!$h*NoF>%RQ9yl%-)7A z6xZjY=spZL)`2vB)aBqZMmD5$A%rhsE!P(J%a7?_5;ml`7 zMnopMXcqjUn~RKyK%(*M!O}>Kc&r9CoI~9x?GWjQh zBlD|-TC}G1wJ{kB9aKOgNYs^zEUdV%jVvn^KWIPiP_e}dCb`>IJSKnc1pHr$E-6^p z5!sTCHl{KG5Qw zVeiOPGrxxHVV%uYd1Z^jiza{KV4134ZbRqqZRqSws#Gy~fjUET#GVn~Emb6)6BvU> zonqbFMSirb!0KFTzM%7!^7<-9){W(+CwiaY+~!Eqj>A+-YO+>SaY% zXg^=QTU&2>dlzI1lh_bshBGg?8s2nW(fAJayevMfPYhrIgBq_K7$c9D4N!%<-L02H znC4ONqwE%4k+^=ImpZ-V9!hrGFL^|lqv($3+y1GcysR}CgkRNXQj2n%KQ(kiJ`UJS zXQL}{U+PBFH@yAtD+nicLAE#Y@^TG3mRnstZ#VhCEv0)bzu3SO@PeRt($_17=a~D3 zyxst~xtnahw@hH1Q(`fl55o*jzP*mRj0(uNoaZ&p_k3V_i1_sII&u?{xT!R{U9qa+ zEw7{a1|<)a7CE9?D>u6^x)y(tC5ib<8d zjXZIc-nl9mz;@SEh6qL1oNrJ8$@j1$e&6Pq^x|CG8w_G5H{J0cfGHrdA-Y(RPc1^o zDyd@-P)=dPn1(aM>)7+IvnO+X6$Fdd^C~Jxs^QqNR(Awkj3i&(sISpt%Uf8O6C3an zYheZlFD;Oeh4KRfgZ*VEFO^$gcJfx`7&^J{K;dV^#HP+t8zF|uF`RO+te?#s9CP$< zsbW*|G#Z2yAf(n5fxxd+V}q1#Wt0 zzeEITUhNMg;;B14fOzP8660=mr)CSfxA^XC2~Xcnjh0-kFGDlKdGQzh@EU-(>%P$B z5xI!omt5f*JUrLMZ}GM_d2Lzi0t6C0m3N~RuJ9Ulh(0K;a7hKNf?sjP7DQsfb^P zcq&aU_^_$DEbvIRDRA55T}?NEwy<1igOtsadmqoyi8^b2+1Xixjcy>y)aFvNC7sXq zt}EUB%W_91xTf^WC8c+}_ars_jyGj^Pq+{&E6cczb*n8fx4kgL8<@$&EnahNxUVg&Ysdui;wc>k3sWn4p!EodkbW1Bf8T!5(}r|HAlrO8 zzbp8y=+_&+I;fu8T>cocXM5VX~kAgADh$p{;I^R@6w_IwR;E5cNnQB z?jD=t@lWBEHfBpS58Lv(H0VgPJ5-ejQN!vHgrGrdsq&0vvz;ctBEDOmfkcXfQ1u~y z%L7zeTOcV`Dc6r-Lb!Rs<{aPf(kre|Pif2)68^YnjU z1x|q?vox;}YriB;Qi5wfBPgy&MeR`XvSvLe+d}3Z}J2{^^rN=a#A}fH>AGG*2UzNF_{hCLLzUP7>z)*1Fls2St8%ibvRWbV>z zw;JKdj6^f(dBcXEcyGqgNuxwo(}?1&Y96#bx0-)DQp7M~;fIA1j@`$SLmZ7fhT$WJi<|3@iCC$-)(#dQt4l7l zTzyt0?5J!lt>gXS;-cgl+AFkaxX#Kn(y@sW5ejt|_huK+mRKDg5HR+fF>e5^#bv?2BUVOYAKggnC_dxL{GQ0`Rat`Q@q3D1)eL-(D3%r$eQ_y2|uM zm6sWnlGBUMGoWFhVuJT++hKd7OPLZ@hbg`;RRCF-YIY!-u?*7_R|zP%k~hkJF5^Q($5Ke6c{1Awe3<|fr3g?1)TQ3;(}Ez0!p_^0q)C! zCE)ZdVmR3rfzgfKozWAZJRd8daxQ*B-c4xIVsLmiOH4qJ$VupRAAWU>KM)FoR?F#qGdN@rlf&pg+M_EUy%K6>})&z^B7S`w4W=*i6-aq88no z6t~$RIk=_mIBRZEqVvc=-q;q>;$Ou_Ag8=HoFiit6pB+oODS7!zz|{ml1<^P4s4eU zRN}Tjo)x!)&YL^Yan$gU1;ZpeWRd)EC~Hs{Ta_*6d(W0cxm$j7El9s0@CJ2@+cCcJ zbVZURkt)N(!y*;3i3H|RC0ChBCM6WKPNncuF_XbhGvfd);r}=?uCq7;&V#!GmaFpJ z5ySw1z+ft;o$p@)EhQ%GH7`E${T9sn>uzy7Eyyhzx{XL$7#o#!=WEY89!K1sPI!*6 zw#DA}g**;=KaYd3Q7JoLzl2_5FK#yIZc*?b@x!|U{1-#-F5oz9R8r2@o)j+T9EZS% zOW_9u?J@>Mc(q02z1VjB{I6p8oBp{L1u%%C_;j|>sAv^qrdxqWkpCB+v%iYFViM92 zy8Iyq)bI%29ItR@Dv!761-unkMRenwM&0dvP-smBMcJXp2!-%lJczeI0B=Jg-oSE3 znUQXh#=E-2ZNZ-Mx2lBv)Nh>?HKj3+-Bs%0?Gk5z`OtxbsT^{yw-wy(_M}51x(ZvU7AQ0f0u4u&Xfn`L)1z-oJn^X zO^S3Hme4+%o|fdpQnt%N$WHqSCg6-;0wZl2Z;VNSib)~7I>ke314QK1amz?V-}QBw z_sFE|uUBwK#upf%9gV~6$1?sQgI70Rc#x$@9~o$F`EYt{M1${M`zwb23SUtR?EyDA z(rA!hJw){Cve$mVV#e?o$P8&7a@uxMAxx6iU-``kDEW7Ys8;`o-o{8dWWK}mjeV~5 zC@=c`)`Kot-0S<68{rll>Vw0+cf^uu@}{32;x1g)18C;*oF}gQd#`;MzbzfI-u7X) zc-Vy>^+OCw+)n3^YeZqVCUP{N<6B>#Bh!z1@k!er1Njc)wSLKQqq|)$k*N$U_Th@( zM03&L@5qN0&n$W+;xiGagZt5=ZHb@ChpCR3>I{p>IF?U-rg;(E!j;bXUYVAk0DHHL z-_ETp0XhmDh3@RgsI*AYJzoAE1}CG6uiKUB(!9(n+x;bp8K~H=MEvAoRO(O;lb=uMmj_bz1Jbq; zZ+$Q@Z9j;~ZKgNZBA4Rft;0aA>3)P{Pv}4E)SuP?qf8r@0}qw$bZoK-L$b*xKcAGh znI@ab^%|6udx-_elw;M)qx};iQ)8Hba_EoeWsvomE-(^nOyhDf4-*-#qvg^xI-Qb) zpad^7k*ao_wK-1h;1t(7=vF2y;6@60Xw#X6>1mN5AH{|@RBXUuaX)ZC%vj%~zRg>V z+oFCM^Hi${=9|7{);Wn4~x28=l6uqWMOfsuWRkwN%=$QH`E9Lxc^ zZ#3`LMMi_!j5s zx4(1WWByfS3K0X^O@F&fJ=_S4yFdk4zC1bj<&966sK9J70XHlhyaH*FLTT$)OK<$T zTRjw0^5H-ly2(|P-O|Gq)18>?!pw2-7ThrZqO*{w02(Up5)WNN6THz8{VPb1+>Hjw zDzHpG*&wkqnuQ)wwv&H}qaf~xpsIcGS@95Sw66;dZfx&e-;g zkMi^u$2WptVVKX@#2CLfIs=WsXuqGybz&l)>cCsxhd0!arqLpvjB8V>P0}-g*%K@; zJ>!*MAZ<2%wI;oQm9tXOLSMhpjpcWbzd=pYPb0p`9t=(OslaXJbMEisoIJF$3*%L! zizjI4ic%9_2+X#ga#`n=dXyg0PW#nf;EEKUX??|y?gPnO2csj%-e$u8fG3%fPCy^W z^7#1C<3r{@1FoY#Icok)?W3OvF7wWD`Qa>k6=}xqc1wJ>@gi(ynGru! zK1fF=G)BHSA8k-%9&B*)QyE@kDwCCx`ciDN@#j)>R;Iy8j2X4x6}BYe8f>4@VB;vd z>t^71nL*e;2D}eMikNf>TUB?h9(zBA-9!C1P5f0`oI(-rAgyYp|^(y z{tYp49Mg%Cp~L_>+{9k*Xt=9s;M!6yj7#8$P;O{lAT~EsCDvC9myipX9{Be-HH1@P z_Tvt46h$G+B& z7}~)QcAKNIcWK9YupBNT<#V_L(2)gl?M@t62~ME~Y9<)Oo}l<)9G{~D-^YyvoM)Jx zCblEDut02Qe-?LuuTi|Xzj)EPfk0pZr#dB7@j?-JVtRWq%r-uU+JsvB&VPh0O>HAQ zCT4i?b9eim*9ky6%X9th_;rzGGGbO_rJ|@}2$>85?#0Chj|o=H$?)}yma{J)4t*9E zMTQ4ZDyRR5X@6Ckj4CWNO(hor$RRr!mi|BTxJ&?hA|gb-$&h_3?zJy~YaAmj^og?7 z%jsS^|c4poF#GaJTB}xzJ!bEWxpV%e0Anpa`so*v&Qy z6dD<(-4UG@;p6K7u85aXzE(#s>~&nQAo;{w&AX$svV=sV=G~OsDZ#?~>)40(pD{AK zniqQr3^$e+X_|CO+Kq|<9C*L|+31ugea>iS!GKnQAl`h-WEq87i$>{r4T=l+CrXFI zm|S*4qRpwy$S(W=j2JaoM*b{1t#q)hKLdPPmD!z!=e8-tZjw8AUvq`0 zG#4v>oR|a+7AExQl<9(w=?%gkXz;;XI`v`L6vRpVZQw(RdUNeN1kxo@Q2B0&cjSg) ztnWvI@N~4fXtB-VpJG#Hm%H78E!^@4UF~~ASHq^)Wn(O6aJM~WE73W*|7gmJD6VmBHp&G%mXuRGATb z)GtaAF@pJ=)jy3q52HpArgH^qdP4WDE-V?>rK^QV!=ams=A!mh^iNNSzE<(>g%klh zBe^ij@=1IkyvVs_rbFU0`4HXhvz^2O>^8Il_a=oFrYt8Z7--7DVR z$thW2=!z(kAZS~lo&w?IXKqOl8lQTNbCD4%;@1NF2!XZ$Cu5(SL*Mi&@Rl??1e}3W z2PW|;+Mfx?{kab;m~oE%9}eOk{B>^f$T;VUZ5iic?;7Va$PhW#X`cI%j7hN13I@X& z=iK^dEHvsAJTRo33r`}-q?~hDm&iI7M8~2B)5XdEe|zS?*{=LI+jwXaTF$=<8jPKD z!FbL%H<&cMDp!$r$K@VUK0|~18|OTbofgf2;79eKV8FT1KQvIh)9^%RbWf-B2`fb+ zZaLz&J|83bU_Biyjo4mE1w8Xb-9Po_Gq8kdIpm@qjh=3H6F=Sf2CA)V~#=vHYj zPM)O<1u;6KCVd@@Y|-+BoBA$%bb>sgDT4$#&$XGAq16nuz?&c8@DVp*T)&COPgl5x4(l%HZ4i0R4BwB3=e zPno`_rM%ZWDf&TZjOu$HZF_j+qQ#(~4kH4W0S;&ibz%;b^PO$q`p7Y#Ps5s`*RNiu zGbkF;(Kn^}#`q_UPsNnVf;6c?y|>KXiGSei&q@BYi2Ao$3>#}pK8$XVSDj9G{CvkW zNCZ`8IJzarSWrWppy;|BW0o-zW5sgTtH*otVwx}%A7E_)qCYvEM=4rtk zybI5e3zL_7%B7)Br1cupWTrd}qs1|`eg>KoBNleIFwj9XPlCo>9bNz%RVIU|sZ)m` z2Ua7&#n5L_cMEaUZiHOym`}P}^1NCyIjm4&E!f=JtCOfC#*~I$n}T87;Mc%J8EVqT z&};6J$|YZ&fm^Y`Wb%{HZ8E`}%1jm-7z%AhwA(PjTg=yio*jA(s~(c>#|>C)BEc@C zLJ^doG_*;|KMA-7R$6Ta-Yo{AGDR*@!8%!1;T!gYm{DV*ohC=3tLIgjXY}q-C#MC5 zgzhJk1KKqscV%wpnrNcXjL(Mv3#cI72IrvDGnocWO)!}2Fui6mn`8E!=z{ysLx0EF z4!oqJ0~nbW(<2)M7`n^r(rI|)YMY;SJMb^g{9I^b-WH3z6#*oABCi834rZ8cNstbB zyE8p4tK4Ykw8}Fkcr8V+ajM-YZsBjAhbl-*g4et!CNyB(JSv5Z{IQ4pZ>pwOGRm2<+eY){T|yyzJ-kJX>Id5^gw_{}_<%3#lM zV%IztNnlCX(fVhs1u$OjMZC%|J_6O&kQ1eQ8U=etJgx7Yitf#J<)u6XDCx`Cd6;6O zb7^~qQMggLr^))|dn~IR3ng_(?4Ep&Z=Vg0V!{;zyB_&o0l>)iDkoutyHcaFb}V^i zx&0LB$?`Wn9yqAg4un(4+#dq3Z^wuNPGk&<0+O9{Xo2bFJ(o`riEZBN_cZSn+`a}b zWK(vyVpDm-r$KQilr~^Gdy_uh8mr`d2Ik=@pVcCd^kZtW(tNtjpukI$@38jC{-63t z8eQHUANLVT_=?-3j#nXY)0)h>eeHV!{z<=AN>^c5lX1@{(`+v1)9*pMAU2FPrzpuk z?w0P6_#Yx!ZC1Rm-jixsn*g&RpK{NoH&|^4$tPL;9;$FnLyMHZS;9)qNe2E?SfH7L zPoYxL>lc|Ss^uy_*a&b|E_xmr?g+&O%s7n zsb{)<4|Y8`!fM?u>elXg^n29YUP_k{W={?s__bF&_6Ms-pBZmFLbSe=b&)2+kl#)Y z&tk!-iObOThSLdaQB-MQv}cEM)ytk>Sa*cV6}5Plb^?`)rjS^4HHGLc{iQH9DR`q{g{szR-uP|KdNeGyPd~EQ+ya04+KRYd7`MLyuWzv4 zV#2ld`tS#(wkPDbQ9(_S=p2c+3*#uG#z+XX{tgBlBRvUym}d0#%$l2+vik@as^r^l z;+f{o=%gE_5!H(CPP)P9ecLz@nM9#T>v?~3heg3CI^k|^h5-xBY|dKGu0LETcq|9C zf>x4|KSitHy?x%*%=m4n44`lsprX^&Nr0G?r+NFt7+Y`ur@(#n$q1IiqaXT}CtXdH zNWu+pjqTvih&ge(yznpd1qs^I*^{%{(|wBgmDA$g@&Z<;^db)W=XtD@hSK*z_Efty!*b-j}{u7qe<+*a}(P&A143j}*MLn6G zD}&Sb#+Plx-YC<8<43eIPE;ehp%26o;){fa*{ax!&eabTdJNw=osG^lzv`m8pI&6$ zZIwh6ICV%sgZCTX5!5RLCI7bmmC%t)$KU+M8nr>>q5w|&cz}NRN6dEx#(KOoyN1Z$ z6i}gm$B4CEo`D>{@6_)o?NS7sqvqp@71>^;=6^q&A2+@~3@c(p+AE>1Q-cY7q&=RJ zvF;hZF>d||8a;j>p9B>AH*2hc#sJ)*LP@At>}8EWV#%d5Zu$2^Zi(U5eWAf{(#hDQ z^;9?^QqOy~8NJ{92`^6o=LBB-=p5i)1~JO_1k2U8sXxx>d@rKg9opm6*zKLP(F)57 zmd-hJ0q-{XP_+$Pes?n5W)NnRTR)23vM_p{+IUAU0ZNvcl|`;gITcy4Fu!vsx457K z<_R3daK~<}OQ5H~v(iG9-*=UTHs)j00pGa3Oe<|}bWzbEiLQI|QFukk00$fwR~Ntuw$h7i|;PF6&k#0 z?mXijcF(O@&-T?#pSSTUZX5l80ZM^1estP?(1$vBToN% zbXMdNqm!}&(a*f+0;ui-%pB4C@@eEqQKAM|50pP(zOIPe{t+yxiouAt6%K&!gv!Uh zYweELG2@RdPHI9`1itD*aub3Bq@gEL1^QK~@;Ln@R=KstIUWTN1G_6qtJ9_536)Vh zR4f+CXXcsg*1WjWTW@xRMTK{XJ28BXp`vl$vgXu;l;?pH zxk7&foNF0Xqc+BY$vy9@IY?&kP$6BynFU`yB5bf;*y z&=aRl&VeG;+Rtajvay@aSIyHBd!v)wMtAIeV>fxDE@HLii7mGIva(>eh2m|o1^;^c{^QjnCYv;q5MVq)t|45*p_sb&XHY6)a2z zJ&~gZ8!d@D!CQ?Wphn4u*k&vyxip6hlJ$!yPw3GF@s`Y$>$D(p=__+u&|cb69D+3XMk9moCUKS5WoGCB$RK^vP#rQ2`2mtH1M|ZdUR4H z7BQI7g4E-ZdxAf+Q5$y>oEXEiq9+RQs35wtb)@P=C*ff*LMLw2C?W57z?#+krU$8` z@Q367gv_0~D4e(p`uH+&4s|D5uq)YH7I*ymCbRKQxhiR0nZ>fr z0d#NUFuBp~$K{~H)~`>}ahXXE13BESeY0;_WU$5w7i27mpRMk#tm>3nTWN4!?e*C0 z=IhZ9%{Tm-&l3SWk1Xoj((cdli36GC3@);&^11m{HONHQOr$v%q|UxonVAJSo9cCo z1HgToUk{DyE)?6|_;AqG<~g}1Qfsl%h1ToQTY%Ut!mPf#puNsCu@*D{d5@#Q<`PoL zEzzTI4}N5T@ZJ^tM;(Cr$&E>!FQzJ!4F`0Fr`VX)zl2(MK)+g?Ks)IQj;IVz)>SXi zy}{e<`vSQfc&^uY9Vl`+0I+a-`?5 zDF=Yl`d6t1UPWE_x)MljuC|0@5WKYpieWCdg>kXmem%ONgFDmQbhOod%{!XxmVeo= z2GPqP$NUwcc{x1Vg5E)Os53xxmPD|%hGv`O1yg#WyBP$s^>Sq1;<_5a%tnEH{WbD+ z!gyK+a=Q5jAjMtkPU_?;L{Z#|D6)_%FKOLAkGcaI#mgvd;%n@5ihEFsxy3oj-6dcQ zHba%*^6_S9<68OnYO_1HvaIf)2Q<`1F0{OrcUHzD9)= zG;)LQUsYf9sIOClaE0|H+|!aS0IxX;FTY#aiH}0)A+;WPXY9alzR3feSrsv;JC^h7 zPSP}NtIV|}*aL6pZ5{)PWgC=OTF{}~L%HQSq_I1o&eWYXS$J6#?=H_lNdpP5vK`6} zM(u{~?VD>O86s84TYMic?T8N~Z^rq841*RMTTw&fD=RuDSYM*xQSh1XzoB`mV!3X5 zed5jqVsEU`hSuF*H-JrDCip1Yy^*?3tk&(4LwN5ncQf;|Ek0J!y1OWZGP^u$p)TTr z!sb57Njn59iZQ(XtD3)4+`*H&+g+}_;TSY)wewg^16?D-nRajT0+k| z=GUp!AG|J8C~rdRQhLGwVrm9UGvgQf(oL67ev7Q_utiK1_(~q08um`(_4ULatY{3R zmwOBanEO~yK_}+&Dn|@&alF%0J3~L^jCA^-glaL;4%a?e-7B~?8qMdGi>xk=ZY;Ef z{uAmp?n=s!Y5Z`WwQ=vC_h>qd|H4>fn^!J7OFZ0WwJc{0A+~A=(PabaYvE7^E^_gG zIb#ZaaPzJA?Uh_&(`&6TZ6Ug@gNY8oKjl&?pVw!cI=3bbmsp7bd&6RvWyxiXJsn>*1gy+UdQAj@o3c@nEUrgzM^yaLc6T*ni) z{n9qInj=$+!e$<#Xa>`MIXb2NSiG%gv(r;5Gxpem{OTz{3QNzoSQQ%hzO=)u_hy583cZ|x z_mAzHbwYnTObfWj7M#R3c^hkk!^So*Uy4*su4h5I7l|u7e9MI_L|$njm*%OkK=Xq) zm3>m44o|h7gl8-^)!g@JFUL=)JCqUN!^;$rCX%XFMDn)ob*lH+7MrdX@SAipTt}|Y3}z; zwtfy5H20VK$}J!S%lM&;AMoY>#Rocn)9C{?}8L$ zXKVR}qX@+w_XkZ*4UGGF+Ib2@j&Yy7FPM8#9FqXo5%)OUkiy=A z40ZJBCf9&%9l|bN*!%MybV;czu1jz}2z$Tl6C}iBh&3-dG?(!sZ68!_$*aT7eZToB zm+tB`1A#92i?A1YI9Eqn`=hz;)_(jZ`ACrO2(A4@ywk$iygZZ~e#IBO(A)tO4h8Ep zhCwW*Kz9QFtTT&me0ywIn+adAw?~Dz6b2;B2UEHD8>7R<=hA^@lzY3>eNbDbSy^#{QVl3By~VUQ44V{`bVN zV-bu!z~wRK&c5-N*BBLwR33|JRaVfbgHh#<~ms3H16ONXT;p@i90k5Vxq>GnE zBn*}=Wj_)(@3{2+F1ptrY|u>D3qR>I++O(zai^?=P-A~c->(J3VcPd}%AdfS8}b@W za2>W79-YJOO+(o{T^x1YfxygNfmBSHW^>*Gcu@e$lQIJ z+shyEFx0H=Q_oOWip2k|=Y)OE>E7-vhLC+0*?m7^Tl;?D&VMLa6z+3-Blib#}Xe!(IK)?w%f7haPU|fDVGZn^B(|C&) zEpqqA8*ma*`upR?K5(*^0{=xq=G?uW37dd(fpX1hC~5@{+~+y`!}abaqIZDjD~F6C zvNG2TFpghlsef9b(WyaAWUS@N^dMAYWqgo#YAp>45*6kK-6H%^q6_quHHpI<*uj!N zneJ5lq=d&%$X9?WC_1n;#&8!9>lcY+Cb(<-7Z3wSV%X2BGd$L0O`#{JGcHT;H@_rc zEDyRY3LT)Y6)|{Vywa~&)H{R4v0C?l`5~}7I5mY?$oeJ7RKHKA%B%x+nn7`48NK`f z@R!^mRD@Gfmr+h-W@qi~q*F~8(v3`NC}rRYfBidyZ0oB)x~U+P-5;31n5@B*V|S(o z$?o(v3JmN;eVA#wyhK zORUJfsX)Qn2dQZgunSO}hRPx>Ly{I9Vnw0B&Aj=IVFT&zja8T7c_}5J=%j@2Tkzzd z&Kw>rii$qYNB-v@sHEq7D;b{LCU5T3O#Fx!Jx}-T4IXtg{>pIm>lZ(+f@RC?oyMHv}U zuy&I2DYiA#H!5H1@3$^0BmK%ST6qGx#bx|1D{Zg8`HU>L9|?7+Urdqt&$6rZhQojK z^rjyWv({x&e)sX9qD(+nF)$0>7=bIOGz{{lbAf+prmI8YiRR^@pz^=`R|W#8P?DQd z(9TGwM-#8SS(%w>lemdU>-_wJLVLGP(3|N>MH!ru`sd{jSkzzf)0^JuX^9^1rjcO8 zpy<5B^d{O*tV_=>z>ZQzE-s`^iZ0+$M&zeS@+CtPZF=^%y6KIxHvDkUD(&ZoPu9#N zXFYdHI=SEgIZ0=VeR8givB?xqDT;ys+H+4oizvqPIxU`zDhqE&F~)o;a8*QYG2fE* z1vRL+u~2N#*EfM~IJP(@k$6XbQd*J_lw48)LW0w%6%1`k#~3B`ZE&mQXUa2pVA7v2 zR%=NWYM2XL@c(yglbZKg8hLgR;j%{-+Z6aOwzMK;rbZPKKZW^Kv(ES}BG@}m3|FcZ zlIbD_AX}|AnH6?!4lQvEK96Je)>Be_b{37cL97pZOGAaa{A2M$Tw+RmVGyEJOxfqi@US#&9q?`1@a|1T+Gm#Qy}7FK zGQm%jSulaPV0)$;^vIk6SOamz{#-(X9||mE)#wy$tqdiK3utygEZBaTSs8g2+(FK2 zYi6pas?cdEzfh}L6sxuyJsGRPYSi1S(NiP&zWPF|frOB-!kiiz?k_4Hm@ zT+7|Qz)J@|Y@G9IAJ2fI$Kr_Gee=d&fF`hS3{zfD5)$gLAXrTGY7FyeYHFlOB%Mhq zoOH2&09*}M`x`8fOuf=oUUf1_BMS|96T91I;qfhAndr9}q$Q3=a3A7<`1D$TUmpyh z<=wIqOX8^0tGR}DtMqLijiNo#(*w0l@avz6cB@}uMC$jqlbNk<^?lF-w)2ekR3$PH zQ9ep84yb(kEnWrtC6;vq(>k4Yf!c5p0eoPyCVHE%Ffzam&Qpsw#s668ou6;;eSHn! z=gvyei6#RV3wi9btbQ&%(JP%T%?!*mnRCp@Ztq0Dbrxw|nf^ZIT!(qCv|Aalh1YZB z-JS050T;>0Zr_9~@lQ&-xdDW3$$?x<_cq84w@I6==IHt61^g2g`X|Z_zy^OXS{r}^ z#il?^%NAlVlYkxUZ(>{xOiei*cGYxadt$(Jqh9EQ98-vq&dp4G*-I9eYIDj3)UYm% zT#W!mpwrORUem*gTTe0|r-3K<(sjtv)o7EO0WP!cBp!*^1;sZta&=zzFsfI&nbW_B z;`a`uE{e|v`b~GF2QmZ-4ZiKd5`Lx0eSMe%i{ezNi6k~}>>HwQXm?utWkyHhRIb5^ znTcA1t1JyHwa>d79Ai9KUs|H)+f1j*Ek)&NlD&*cfoaPV>cg@VC){ssS5^jAh(mqV zh{BEV5~#VGfVgqbNV|RW^H@c%thA`yD^IIjW^dZyd>Z!x3#g{t*ODQkg}(lNi5QK| z^-m+{$22blii8ykHxSdggxseid$$Gm3zsfqM{?HzQX=M07jXStu_)mu2+eN4$V4hl zstgRk%E?TWEv^~^oQ?N2z3aQ>iGH2RR|f`~oupDBRZhF(-Q;M`K&x)o$vM9 zJ^ogLp&yEj&9O>vKUwFK)ef_p!E#F!+}2B3Z@h7Se1aP1#}to*({jMZ4NB)zGL&Ps zoU_i;-(U19UvjLim&-Y4FYe@gwmgBIz0j_5OK{^H**ZTUW0!~wAJ9Zv-7X;Otn&eA zm$;`r#C2QeGcxM-WXeZy)>WupRVGOzTC#7JO>5;mPG8&@pcRNB|EVoQI8^hS>ez*1B+vm+?;hjj$iwk6TNd?~fsDrT6EdN*N!_fxl*_4`OVbFU9T8)_xV$ulW+9@p{ZFZz zQ&K)-mU!z$EEmFPWHR05YC0n~ToelZll9UloILBES!Rl3HdLtH9qVc!|Y+anP-lWd%ar%DE3zImRr8k|W}QZP;*G8#F# znc^ljUXuHzINS;nBL)NiAoJ+;FlHJuX=r#%{1bFQF*81GyqbBXE3rhKfBlPFw}Xg#0J4mRoW>Ts4ee_B4MYP=BMl0d8Z`6``c{vt0akT`4J=@mju5-{YL0q{eRSxxcwBl> zK-HgNJfF^FUY!!T>T9{2_F`q4`k}Gp7a3@;BE{f_1l=%ju`~de<@B`5R$eO>Rkr6< zC%Q*K|6{qNGH^$t@10bK-KGOLgEBy7rG5^Ylp)RQww>X|8GjZO4NQo;xl~SJi&v!_ zkR9mavcYcbj*ZDJ>cAE%I~QBP1|_GQ@7%_#Rhq%~(NXwvI&2&nPZTvu7vj$L$Ve5d zlosn(Cmf5W2lfx(P#L)0y?*2-fss91BolkuZG+8jF+v4aQ6%nSvOSSm{qFk7C6>n&Kds5;K;N!X1k#wjp%g?Nol+>L0lUUur*jx>DUc%_CmM_-a4F4XCOcUL zGB!V29B~vYWoL$A$L7X6br#X+*&&mX@6W4XU7*s`q-ewtY>r3K`)#wg+#JAFOT~P+ zg-M$2jjKy*SH_RN)tV>zcgaF8Ft$+GT$V{H z@?vRfkbX^PN{JhJ^a>tzO0mu4jjAyhzNJZ=ZN?s&CL@9$()f2An$(hqI_VF|-|l4L zMXi_HvwRaSKJLvAVPak@(<3q*5*=gZxXPbG-_#80$xy0&C9>5~f$ zrNZ7(?B4``S8WNi64-=TcjH%Br89y+9VEI^URe|uxdtCvG>8ZD+MKnv{{G4$P!*{g zxS3gmv6PQJ(hG2_W&2kY#x1_Uz=5KjiAV}Fx;%&{Pju4@VW5ssXG&b5hUro`MpsiS zM;0(ad3}|v;q<|{w6Y>ToJXP_Qp`9RqL?^XksMPxy|<`&!JjbLc9D)4l$2zwU(Rd{ z8ms6}$QLC)nEmqklXsSEVl5!B47jgWgM;cHh4JZDRFn}9lz%ub);0-au=u`HtTb>- zUrj(K%#ndS*g-fW%~R#^@pAI3mQ3$XqDqhZ#`uatUfCD;CjF@Lex$JFNqR(O*4`UD`hylE<7&8Ky9u01TProw=BTEE6cCd**>`d^ zUJ@v_WIY#l!vnBaH&{{##_%AB%ieL`8Nf;Eb>zO~=gF1L=OsQ`Cqz&-kPYRg_C^hX z_x2_eUeQ5>w_txsgoiyqNGYPb#9l|!iMP-c%j6=9*4G#3ZM637Ma2y__Qz<=f+TcW zF0>Y~H%@+o&_)cwOs%0)GItbQ=+2y~o)GWOu8Dul#Fv{6s$flKl6#VsB$Z~imOy*# zgPqWJZ9H6B1Y%Cy_&dgpcoc|}vyOizvSDFy%dHP98wx(IOB)M@gX6-N^1CHTgh6_i zrBewdZZClP4fMP|PxCD4I76D7ZGRPfqXV~V!0>> z*C3|-Xm)T=VLEJ2?fAx#bqS+IWmAKIjHM4ydGwh0@c0IK@wAwMA*mZJAmLiaBgflB z)Kxh>zhd}6w%HWCHXIYo`rY{z51RVUiU_6Tt?o_Es{*R%5|hqX)Kh6CuL|qe;`z8L z#Clbs^8Zlw?$L2v=bhkp>(TE=^}B&4(FLHp(GL(PJR0c6gDAYgm)X|)NftqgloTf} zQ?eIk=uyem#PS@URUO(VN1mP8)XL6|;z@RUX^mHMoVZL=6adLmkCZ~(qh#s%MuG2JK&Vpc*wTtjrB!CVD2M+*XuLi z>Rw^HyQOk@UI7InIFjy6O~QFQC3}EJLiyHP%ER847q&cn$x|Au&dgFEJ4Jy?0VH?; zD%`hlY#-7;cdWyuW+ZQA;g~Iq-aO_6L+L&Rep)b+99hTidn<-#irbqvqSQ&vymw?> z3RF+@p&Z@F5fE;rPUsxj!p8XciE&$~U+FvH2CT4Nj=N#^69mzY4@ywLD? z^#{!dk9e>29m53%mO4IERg`}2=2`oxBtV^6u8gHR|;uy3sQRjOGoHO@#YYrcCh4PCqiH{QZ;<4^%TZ8(&)i?oX z&&IOm?*YFcrz8Uid&SoXEM$6^8GO%S_$j%iHE^@NMIJ8IFa;=#sV*5A#>iufC-!C5 zv)3(8sR)G=ac`My;tDRv(2HbLp#RZ5}{B6oyXRb4fN znyPl-ca{*K0o-YRWF8+cj*Kj+e(?Ivs{*hOx1ltX&5p16(&UIjK5a9$XKt2P7J+z@ zA3)gqt|T-yUVSi+of*(3ASTuQshlnVavB1HbmRoy$K{ol#{a_7fN5eTt1cfPPmf|kYQ8d$jQWiY zyyb?P2y3zQMi*-6@Ph4xv`Bi%5Yx9>LVlwa@nlz^O1B~+%xt;uz^eVWhkT({0uIOc zmsAFfOh`*qj~;dS(V0az5Gu?X&YNC2#98>KaD!bbrK6S!noVpoM@2y@QSMQBwDdg>h%ZJh0 z{%-0jMY1aj81aPoH901l9#Vyq@$sc&3TWW=C6;@!Eda`g$)YsAX8GVK2cYn9cg{PE zm=->-EE#@$HZPAKF~G>X((1C*`IZ$tDrk^eVKBq7r&Ue^Yh6neop@99N?9QLgS zJF(o676%f)<}2%vGnp%pBhU-4907(FWMS(-x!vl-%d;JuFKw^35BA-%x{Sb+tKg)A z34Ih}$pw4ZGCH423y&RJH$Up(mA}p(ZNs8GDkEX@y<<|gw6`uZ=B`&}j=AJ($AJO# zp)Ldzn-eoGMGa3Rb;5>*DCAJ6p?YNoUmBLscx7$|;RnQi0_lAxoLbTRqX>;;OQjjE%-HnUNCzuI3WLBZPR#g>D@)IE3GNBl-o+Aodd7(n+ zkm+6H?@|?uCM!)BbL@4eFQasjRAj(P&P;dcZZMfCavQcRl`B(v3krb6A-x>DV2XSy ze#?sa+U#yn`!sC@F!Yba6!-qpEN9X<9QG#ukHz5whiWO^B7nY=08-*XJ*0g9dIVF9N$)~DQeeRj`s(zL!gE3fcL#tfp%%H*9thZb0 zqqUqGHISnAk&Vr{Q7~LL_8Ox~6q@&_{wTR(^D%V}%Km$Y5v^kmD~^t$^Y6(qBv_m& zsLSmKF`R32S?`?!wy|WQ&Z6c}BeJ6g+dId`H5r&b4*{QYZH8!_yMH%?&8ZCHI zj>JS2%Ki~S-i-GsB(`ayH;v8^wKsV|^ZMIoqBe10kW1w>;_S2WF}OuJcQb#@-Q+x7 zASCs|=f>HTKY%S!>lD~F+|BRx$S(E2C);o%xSQQSG6+f;7u=0q-wzxzxOxb^9j?tA}_+w^VtvA4(FJRo8Kb@q#Fk~iS^c6VCUIa|F;m%@e;PbDBXyA z=!RduA?oqeyorD~E6p8teWSOYmu^I>!z;jCA6V;g{G*{+x-ndx#Dn^9ATA?S$H(c0 zSH8jFCJ%#xXmyZQ5QPBuP<5>a0;1X95)h4WT>>Kaj`-LxhH?>nhFLs}%Kk*=!(7zf<;W51J?gBPVA74^;iyi`*eQ-4)=zW# zBhwj`v=7|bi;q(>A{$hTXN;5isFmdtK?RuXJEK~cF319kh;dX0Tk9PhMn14CDEM?2 z!*H3n-GjVh>t^;JoYTBE7IvNVsLt~5K%0f8&I+TzHQn}t#yZhwfaYu~DeaRE^`%;#joLEi3uDwH;0u{bJ;pZ;A6(-k+>4WCOL+SrLe={7-1bXZ)AG^#=LN#Q1E~bWjAZOZEeY24}yKsuNp)E0NInhVzko++j`+JfSwEfFW{)=>4^=J2NZlJ@%z#9o+I!0I?iRuH9mY-RX za%QSsVVyUG4r9>eC)&tG0Cx{!)M~IgJ#ISH=9~@=ET8F=#}cN~kS`__@jgzup!jVJ zfVa!DB%jU1%w00?PUx>%-&C-Pt>kTr__6L&AIidY+Ko(+g za~Fpu+JBu&xKu>;GGWkFM`HSJdRlV2-+_EWzqZTZK9igqQSkP9!rWS6j9#piD|s3Is+S|vwJS4Q}npejX8`pI>Vyj z^dBdK&4P2xI@ozOrKthtsiS9cn7zlzgg6n{0E=c%cdTeCO z_y|xZDMb^=p?V-WCc&`O$kP)3hbTjJGAY#p4&uT@CxT?#=@AmJcS2DG&ZM3(MJQcV zG|*g;fcrviBahOJ2+8k?&_^yJ4MVg8E8ws}NHk=;#YiZ|##I4RTTvR7gpeXc&9^XP ze!9{U+vi3-qwRCqfVOl00*Evsoxn-uLMWua6(W^HDG}A*qEw_4k1B7|DndFTO62y; z9l!oo?B|^X_B*0%dJkF9M?+!d&FVm~?VTPERAjoF2A}Yx?bivzt=F5s_(wo!Z9?{98IK07n?{MB+O=rViH%;cZ*9XBu0zYz485FE8vM2=lCkD&fiD1srI5&KQ{2$52+ z-&YH18L~6|k3}U0suWT~FsS?;hFRefQZ z52zgaXQ(Do)f2^p8a6o6SpA|eC4c+SUbMY4G~i4j@W)%{5U;3T3`+7YnzDE(-QFGDi<&#+by-!9XpD1rJTly%yOUlD%ZP+w z%y?YHoVea6Ep9En74}&@%T=QBXmBOqVqEx33OgcJr_!H`UCQl+)1GD&u9Ci z#7Ly`^=LF`0)>A*hpn;H86r>Q|Apb7kHwO1OK5eObtUYLonk<;CsNM2qlGO%tB0VwDZH4pIIDV>P=$~KCr+jd|Q)_17BA9&72g~`q^gb}(6mU97Vr=yy z7Je>)TSY+;IViRH@w~e)#rn5Gtq&(~;kEb{*Qdv^C-d6yfC;M?`uF!;Xjwe7pMY}0 zoUe0lhXm*AUD$qKRNXxSRDM~e`{P^Gr^>sK)LkTg-+pHYmXX)}OOmN{u>h2W?r(%b zK%x&{EV?_Xpu5AYnaO~p$_xW#@zP{a)Jb%A3VmTq_z3X-&wOR5@QJ1Pdz)V8kumMgj!hdyFsNt*P7=Qz6s2$Qw-Ne2 z$uMBPxn~BU(8HsMkhs4^sl2k`q1_pu&j(Y{17{9NmIe+7`FxM0As**zlgB}i*k#o) zcF7hriqLM;BiVSw=5N9J!!AzUxtft-U5A|ih%?p-UW?e+x?n$q+>*RUV}T|~F3|e3 z>e=2w+AR;DkLuXMTth@|3AR~xe*R69Hre1g84R$<+=aS#KqfZqwRC-uKOv} z4<=+L3%$rEPxsp&lHbWIR0viT=nmf1BZvy9lzCn~o%|Pfr|3u5;%shE#e-w`7koo9 z{Q)YwKZmL~C5cG-X4wNHApZFGmV_30G;#D-d?&!CE7CUy$`N}fEjV9f_D;@+1)U@( zVM*FM*({{hfb`9%b&l&1t#bmM^*R8-KN@cBa1tMsxx(DO9^+66Dumh+PppEkx8`@x z*2b~&I6&&F=Yj3=tK8$xNqXiBn0NX@bT&0<6W@9(D2aYqJI!xR?fW`AT=&im~hLi34N&3pktvDwWwRfstltFazsXpl(WJC&)&5$`s`u{cXt<`Tv z1(j-lwXE*a+gn*QM0U7^EX`d`4G7BPtRvzCh@OG0_07?r^3J0S=ys)I-O14bvLdlV z+Q(Dqv+&JH^s#He&}@y3A&4A}DZ9KxqOzMyD!XXN)Tq*(I5`(gS9#M{VVwDR?RpfJ zue4hYEJ(XWf1gAWkF)^aA~tztX}9db3zQ!J)d0>Em3Fz@thAdOmUh$g@ zFTX@~#Y4AgdPm;>Sj2}brDgKNrr*tsMboTx5<{L*V^adw*^U?hCN}3zAA$#Nh zgduHpVviI)mfoi`1_j-Rm~%qzV&GZlZu$C2`L045a89yzK&W`*8!_bUFy&;H=;63> zgGb(wPtM1_Bz=QZM+Es){bG9AxHoE~DWvU2J9MzgT~yQuP>(&+-u4iS|D(yrw?6zR zR7L3>`-8EJ{taHeZ-K3UrbEaUzN>iXP=};j9SFz2h%G7y#|ClWz4=Usy!oLH)pGcG zG>dPcUVM|Yh`tSEN$(q7|BTDR>}ikJWz9p%sLNtm_j*3tJ+9ON{ZtRuxl&KH^-bJW z?6w6dwC@%0y~kzwp6-4{?3eD9UdIk`xpzUPd~b)+Y}Ds>Sr4qiSTFX(CU3rgJ-waV zI~H>z%GK@>!}U6Lt7EqucFT2l8|+^A0Mj}0H+&9H)cIBhGPe?8@31={w*b~ zJRE{II_Sm(gnykU?gySYqnKx#N)|G-cBltl?_QaDb6Cc$-LU(3`k;n{aFwMFstm$5 z!^`*xD%_#kkG(>B_@sQXHefOYkE$6zd8B`E{vuYhuP16ItI3??=?@%iaSWqFezgCS z2ch~{7|{&nhm?ckE>Y`D-h-+;hxVTDc#zCK?!e23*s?0-ZfOW)qTbpyt9y9QL0ndP zsBCivm#ZmW5RZ0qL#mU9l!vNQqsl`l4-SIa4_9X<;d&9JV!W|EMD28TAdzUYQERBcs>=^eXEKveD}ZBkx_CTPoZz9xPNL{B(9!P=v#xmq{f zL*;uE_4WG2(NPD+G*x?g3_u%ehgH}_hq5YAS#yX@;;-Ib`0r-NYvTrn9S*3C=`g#g zoXZ(7jW3RCTKynIF9!YVpvsFf+m(%D(NYLo#|2i9uw7xfje$vxJ1j1 z(Y8_^yy(K1gy8ft1sTL+?J71wKq?eF2+JAx%Ie&N##ay54L+}Ge5i4#Hrau>JtgyG zoh_yhQ7C@P<+2TxZv-+^Dj(84FxsOKyi6kHe(BodHW=hu2>P>7y|9j+AU z1vVWT%wYh$J$84Oq>5hELgGda)G7WphhK{akm-@XCiBo-IWlhy2M!V+1(1v(U{X_B zXH$|UMJ=B|-_OlRcpd`$ z&^We^AHvoHDlH#6G)@e$5_%*R(WA+?q&NJnvoLi=rL4UhxP8H}#JViZVwVHe(>jY6 zi4s@P!gr(9@qO7_o!ke!YHGjD1G4S#Wn}%`hG-j`aadH?&086-wa#|`@Hm_4Zl8S~ z+7SMNhkL3fz5ffoH-5VpdI9|11V+E^G4gGAcFa)+NB6NuFZ*#8C(S`r^XN+oodzw_ z=~Sk34aipI;y6^IfqA9`VBU}RU^b~LBv1C@3mijoKgtwWd;f zN+`bLoDBNqllluJau#$p;j6 z8i3znSLyZL0|vv&u+j6R4;hHyCs)&~9WM13(G%3aE=^=CMow+0*(c4fQ(bs+ZfjWklgv|QPP(NWEf1BX*MMjnrhSDg-zwn5w-bYU?zuYR{bi0Qf;m= zKkKuBK?Bg!OIMO{356>Q^Vst8lq!-DTVI+YStk_qY!uqyyeTLvgwK}?mMHC7W5s&G zm$V$S8^uxykv`feG{(#Ya#{Jl1>;Lcg~H8YZGorPQVo5v7h7)Q zZqFn1K2Nh+9DV_1!6a$sX^+^7P}`fD&;ge^TA8lvTxDR&S-OjRaguOma{G?FG+l?T zRV`2J#7_TDz)7ZNS|SEfGrPE8&GHs6>PzMLh&BC~B)zcM1v8f}16T{`UcC%Mt-e)V zG>Lalh}IeK6deaf1eLDz1`LW~d7_O(xce*3X^84Orl7L74pwhY8sd?6o6|m-Rh6d9 zyjBAiL>i9L*r;vi_myqREGpZXs>2BypRO9ON{fy+)cTL21|)IS5;*n$>|M5~w%X_N z=~Wwjcy*$0b^L$#lSNJL!nh^g)qiD@>@bO?S7vR0?t15o zj25aR0677`h(>CVH?Eh!Jy^`CI1)ez3=Bi6mvY6YJh0;|_5nk;pC_xB(tSpdA z)8+YD5=G;iiMR=V!dAPZdUXaJX#JfbXY+?=GDHdnc0O5tnLyD|`Ovfxuhj7bl!s{)r>pO?gG zR7*!EGf;uDVQwHgdgQ(OyiWluk;0;?*M|^cYE{9|7B-e9S0`Hw8&~DkDO5(;hz@bB zu1BS@U6v(+#pdq><4f`%i*$4Yk@|g=WiIPJ>hSd?d7O??`%kMcOge$ml_>yGw!wBV ztkcR>nkb{U>q2p&2di6AEs{*=)VwM$>PLgBg9IVSQwCJ4^!4Pd4XC^c5_2UuQ+N^X zZLuBXOcL5>K-5+RtxmV>w7hUc+E}QYLIq8YkjGL3qL}qw)xcY~y-*kMey`RIOuzsy zmld(J)wH@#k$K0s0{SQ0%K@;{iUL8)>^F*YD4}<51VQBNv~&f~zauY9E3)m)jk`V| ztt~DEVkcDS0g$=-qDu=T3Hdp+mY^J~Nv}AlV~mNSTd4Z0#U$53eG11fy=6V&wV!>i zinErR)4*EKywsdVSE^dRF0dDGbM)Q3<)eTm5I_)yz_+;kqUB3vo}!01H|W6@OYqw~ zDuh-ih>yRcu++W^7DJn7z_hLw454%xwSEcFzZan!jJqg%-|PTY=#5{+46OTSw(+-r zv;?xYaL<@=G&^Mrj|u%(3abs2D`?P~#{tM`xBwg)0AcohsVUWu2FtwD_D~D7M1}TO z1X!pSCV|>lX&f2pO0xT_YRS-$lvv(!|(GXL;ghd+AX z{D>?4C)A)6s#Eh82Y4*rp?n!S+cBh@)Z3BT z+%lnj3JN>)&H>p`R=>j>!7F`-Gb8y0Gtvdhr{#l(Ao5B&s)HlzT3C2N!FMKDK9mS=2dJ|IJa^@(RSP)1|D1VR3M_i#rC|rL z>WtU=g`l?yFxn-eATL+tlnC-J*DyC7VzEC_={afTL%;1L?mnA>}lje1M;8oty#@r{W^faLiOCmNyZ)m2NX zKvVH3u?x+&Gh(|SnAejF9m+iArsB7x*O9x{lpdQ_?izqFiwf`)<4re>xM1&!N~HAO zbn7l}=K~C;^LCpLwPRe1Pl3OUljEZkzp=gv4rhzY0zQjJ292lmZgWBrD>o;)I-ZoQ zOBmvuPye0REh*r!@hI>56)$k_wl}24aix(N1#%nU#sE1~dhxK@HNnaQs^MJ&Hh8ub zfbR6c6o9G4>b^#}i}bV!z`yB1t))=wYW__N;NKB+KZ9*FCY$?hDqmUcaFS%b(bIH5 z>HtpLS0cdX8>BKz^?+}yBg2IE4K z6G1w`K^C^3>|Hc6)hmZJu{y5Wp~{sdHw2dLMT84j=86>cf-P%bXX!Nyl~v^5$vmxP zo7~kIJ>ZA4%Sct$>ZX5mVG+iSV4Q(=s?wSb?G(doQ9b~E!S7WrFA~JhO&XgsHVBT9 zr?dwf@vSj!nVh#FV#p1y+$=XITQZYF<>oL;l|SHQiogVCImsrRd)S`cua0AEusF&umsao-SrqC8lp&Hscs`{ zq8-jc013Ju1d#W7#|I8Cw;8DA8mkV&ebvWg9X5u)eq~_64s%o-8mnT~?g*Kt;_r6) z2Htghj#F@{CIE8{$2a(9-n@r*2a314@lDqkaBj+f@B{NN1r&S{@o2Leq1*O;3C67S zuaixap#kHcx9{?}9H2B>2alO|gM%Zah(k{uviaCagV;YDO8wBiw@VfiuvQz$Qfck1 z357cvAbHe2l02k9WMLC;&Wl>`!RyG=yV;IZw$KL&!@OcZuWqv*6tP-=u|{z%;_td` z{H3eFlv0N)-K@2V*Qh>3oWVS5L~we0*IVByZ=&Y?Q7HQ}mR{YffkW{<06I&1s~sLb z>*CNl{DqD)!%m*{bb&Tom40 zb^~3p-#cQnh3U#~pa^I1HDAFOP`;FO%C{a7G(QCHWXsF9{5g~^OU^-|d~rbo z6uSMuP(iQ=#YjcdTirOMey?y>4*+z(I<0tfH6xUs#*|2&#yDOWrmPhMT&PY& z1P9?ZeGB%`@c6isEgWvzM8=Ow1LF>?d;i8A<22VwtS^ldW|Y&?V?&32gVJk4TLAT+ zBDWrZR#Dp=Zwu9-LmdtTaS*kvw0EeDk>J|BL-0{9!R#)sOrX8o-)j!9)KuSeZKa|5 zKycU?uxLnbC_WgRzQXW?T8r(0Z5l6*)F;NqYfzv%G%oex^TETvXKim~?*(Jz#P;4Mf*<0qY=_C)Yc0x>DmM6~YCij^hR^PH_5%3X@GO+`af@8GaDsA}UQWJrKKQ ze5f!|F+h=g0st79m7&72Zh~KjJquq55;@S#0}PYX6atM+lK_-%LhPEzM6Q_x`7<$Q z!#6CKkvV`^T&{_DQKiv-&F`1|Tzj=JQMFGX!vl0H$%@9ob1>9YNFMN-q6ZV7`PIqk zG1nq*>suc4TCsmdB{Hv-x(rdA?axfZyJ?@A9)uRi^;ETon>||<^N&l{n{oQmdtD0a;S`%weQyzY9Y z(jLdi_Q=N8 zCl00=hE{*S0l&_}f_=@S6KAh9(_6*PLkQ(2`nB!_1ffN-!4|~_RTeSs7u|wiw=z<*RK8>XD|{ zjRH1@@;utT;%qQ?v{}uIh-3^q8zE`%^gW{7g)|4DYwv|kPnM*pQOYi@28_XF$u*w*uWA2C&0R1K45U{Xc$7Fq!{?b1hsE(5L%f zsNv_D`EU>ZxQ%Vb@wtQ0b)D0>7o5}8tl*r^XPwi*kgE_)r21MX`1VmjzcY4Srox~s zzmIM%!d9xnrAF0C8LQ?1R>L)bjTS}>3h5K$fH7+makv^mLDsE>RLuvl!oWcVY9Cf! zFIIydiAqI`=w1esS@u*uMx9g9)@#5M2Dv#(M_sVA9E<5zLdq-mb&;XTj(T6AE*Jq= zU4>bp)de>XjS6OpI*A;ja3yG!4}0v_az8a+<1|D=PgMqOg=*b)$_26HvG}p{WAVzT z@4Os_q{}C7b8U(krfo0=018WO5ggph&up?Q9T7-fPvrlm@0Dn)h|fC z7MIYVNUC2NxZpvmp7I}7zpy2WDy_bWa##8nI7AaZtNM8T)S!Ifz&TEq7TJLo;=v`drkPQdknG_aWP-UK)ql0EKUz)%eGRqs-N4h&<;gr(NFgftN_JYR|w zbVMfybwc*(&GGowzKM9pC!yFFT>6(To4FJ#Xf%`^&@dCn%gBMo6j#m+D8y;BB+$Ms zb0}Ul-T8C&rJ?vWgg{*+)%?4V`(;o(!P};`sh#VrmOvU_u z>#xW!7>Mq@5VaD5zjl z_vQT9?&@HrALMCg?C%Ky!i3}!elLBcPuh{*lXlj_0oadp=cnNQwb7OL(4Ld~`*=yw z)@C5Fr*U^cQtbcA%G_Jr@>MuVV=YSjyiJL1TS)t0G8nJNI+|}4K&`S0%h=ei{*-sm z2nrqY4e6BlrA}UJliAxL9U2JTpG9K}@SI~ZR+8Ow{knx|oU$d0Fsc(AfSTJ1Wq+ek z*;lm4Z)0x}Pzajlw}R4UCT~;m7rX>bp5nIiXb3t6c5%)WeS-#NchT~gOJfiDDseAo z{(C%p(Nn<2&USvlCQo*|eTI|3e*1>E#X_BJLEhPjeJD^iNG)u6h8<4=Q`Bngc%vkv zwS@ZIOi{w~Q!^wMfC#uCyW5qyK}@y7-T~->mu6)Rz7;n3^uCQT#vVZ5H=v(qzc14Y zdZCQ7*r2iSyAQ{2(I-S;Z%`NxWB!=mmgo;yo{x=bJaX_P~a`5}oRnn?wrAI^QlE;bHA$UQIF#hE<5 zu+BFMA^-nu#j9u11P(b(dCd4Q7bAV7c3ro%j@ zC-GUO8dtx0DVa2K45@oh+bp$YmJJ9Z&DikueI-2GD9gvOK&(=^rZuuhjtb zdgya(QQVjA`paOPq=WJOw#cbog@RiPp+)0qx+*QD1c~A|TkD)g@$aMCU5kl>-NFx65=t+6#iBOGGf# zfa*Z<7kj)aM{b}3e>-&Iz*hDF1%zQs?x*tA~FQ7F4?PGsif=MYpM{6kqya znAgwp9X|UTSc$*x8{Ee5KZ4r@e`Z|w+`meH)8Gv(qEW`YV8R>5_3KMk%)^a%Id z<1}y#YE#F{#g;680f^HliZk8*2@C!(26#1u!Cg%rz$yY*LRHGbN{Xi?2jtC+DB2%85gp9yvZz^s_e#a3FB#!@T?A(KCCv3`;* z#=093OdHVOh+nsX+2962eM?9k?gq6=Ux>E5D4pWkzUC1nu0(<>V4w?wwgJxz+B<>8 z5A4yclQKK^=JNoCZjfi-rHI6Qowq-L=a05gP`E7;JQF)>9WlP|iX!x^nC_7_&5z3d zg-eL|q;VU(0*H%_j`7K@;7@#mU9md;>O~LT!MB6zAEN-KN&_C)X{^m>KO{qZz^E3W zSxJ0$P2pG3wlOF=eqdQenIky^Cf)(O*F$^HNc`9{JF(wM_tOs*Fj_vd69um>RJgm+ zD+>SYK$HsG!6m^iYEGV>-B~(~ewO;!ixF&IS&`|nD0_BiWyQGS4t@d9_B-$DD{JXBkVoUgh-$A|_jjpur zyK{FXhGTJ>p3T~qDbahLxZgsUWp!7*%&?hYV>Jd?K&STD=P+TyxLt0QiwfU z&2NKaH1Pgn%mK&$#OebFrtDTsKQ~E8p>@;Va{Y8DU2P^hGenoZjkul>j{GkU`Lf- zC|u}K_)tbPne@EMdrh_u0Pm}kP<<)V<^k(!ffMvb++U3;uuAS}>?XlKG9@Esj%X2AS&QK%e-*3#Yf+2{xX~b| zi!lHZ*(3Ml_pE6s3K@w{#~@_)BraaZ@@tcyxgtbmz7gFBA|!Pss3AtkPl5gh(q-^# zAov0f5p1kiGGL!zKAm{X;Es3fE}~n9GPew_|EWucZz;G%QHzqlY;(O)48)*H2g8t- z|I$7*yG21mNMQ@L((6A=?ZekCD15?iW+8di>F|L0)28JW#G>r z)#IcY{Q1GX)Ov)>oyN_Tge1%qzEf{g@U8ekS!2@a zN*tH2qf)5OOV{;pO~<b!@C64!0dQY;skG_?s&pa)z;7;XmaNa((9LG{R0Q3Q$w<7F=r!E-W=>s?XV`kq*q zTyE%@zj4@^FJWZ;XvGy_iZZ_ymdg={_qe7Z+pQ9bpp^RGeE2zEhYE4AGofrpS%+eM z9U8dg?NC1g5|jNfc7$5tI~~fs)1i%)P!K`Tv+0JvMtm*7lJxV#gx6+A0Ut{{eFMwc|`F)^Yq4qer|MPL+3??k-EMy z(V@HWd~55-WPVTP`5s*c1nl4Xv~%U)z7izmQ9zPOWj*k|Pp+-48x-4?sTf>?nt8H? zoJbv`lc5n8f@?uMXJdU06UfOYX@6Zm=SzhYFK6|K+UzjDwPs`nFv)qD9geN4DfZD2 zbt)O;XEODfz7x<}4AQ*Q&oX4DW9A*I{pZKg!`DHung~CFkX+a%CX9nl20Ke!Tyh^<6 z`JpkwVUxoW0#r3A8~fBB9rkH^z03Hzj45*2qydRqDUyxKrvvCu}v?jPf6W0<4=6`TLA7x!8_UWOuid>MEBukBBXCa9)Oq*t5B zUDj@KHs~WXs+}0psCc5T5p$pJUDL>`XGvz#=f3~tI38?hGincTtpom6Hl%020LS1n zUkpO$Q>k)n-)@wT?Hhwr&-`FRxh4IcIut*q{wrRk>DWWdX5qn;6g$3Z7J84Hh3Vn? zfF$Rc;$4Kmr2K7shM{$zTiH7J+8%Aa~#viz8*v*GFB87RGG-~OoU zw?BfqJOF>mQ)G+|N|*$T6UTLqNw3StPhf-|hw^(;{oPV4tci$xEZC{op8AO_)7b_l z+eJGuwfb>J7dQYKz$t}S7r!ZgSHzrqQ~6`;Ki^9FC=pM#5|E08yDq_+pKqnJ^IF$t zP+J5wlsD!*a@McW;Lo7R=2RrlVb`1gs8f6nmdZb)XV2*<%!D&(6rZ#c9-Wd;>6B|Y z36ROc`B;r=N!CAk!C++iN(wXf;BB36FZRpS3c#=uoLj8*yYl>G`6!e2q&Ky3sWHab z+t}R;;BKRFP!4N(8oV^oIL)aO#C#417inXn1C+1Kx8X5Vb%FE+;BF=-z{)a)F5}_l z__%kgal__YPmOsmOh{dSGn`;^<{x^{Z=^pIrf+tIMS$r-+Ha?PZPxz|T5x#%{x)ld z0jXoL;~0&{@fmKj43-`&&G|;A&E)y{HcR8D6h6-YGYpO#3x8OwIFD6s&w=iCa$sxj zBQJ|>7N0l%4j;wFTpKXik>%ra(#J5@-)d3NX1RG-Mp#I1&O8^!DT~L$EsC}opZB*} zDC_U!AoNA~Lgw!+*8j4u;0}*itm&u27K?3IERJQ7A!pZO87w_mFx6W>^K?JM7DG)q zmd7VcVKv&_!XNkr4#V%PhSr-pi~mSxJu5nkE$cX+e_;>VY%JPrG*Z|GxLgX`N5c*L2;?jS3n&f= z>n!&(oedbG&ZGuAiJL&RHEivkB#osIX7VqR+h|3dRepw1HKzOwgQEG0A3xS#S?=D6 z&ieZ*xONhUt?Dd~B}>vTLhpYa$^8>9g2VGzgzgRpvEcbU*!&dk0Za2GKep9hTK(Bo=t7uJ4z+Q)HP2^Vkop)?Pd?TO(M_>#ubTgP_tr|8>1w0$8hz?A>&ZTq}9q75@ZVZA(PBHBI-kimQO_m4%n6?EJ%d}=Yn zmR6;$AZ`b$HQAp^Csh`0h5LOrE)?FsV^res5$K(0g?$qHv7zBkj7 zWB3xoUP@#q7FK--CIBLVZRy^y$$4F#nH=Ex9&ne<$^Lvp_J_OZyO7DD>zbU0xsaN` zKpw|7i_3*w%7>-s!=oxEMS}r@%loD1*HK05_LreveDOL!jc~HxKL(e**z3m$a8wGP zqkgP{)iC~y`>i>TOTG9S+xUNYdiU@~(z8zV{pzZlt&*&ZZFRTHZdsP(?s3`Ewq;wk z%d%vvEt}SKnxqrpq%thIFd-36C+md3R60%Q3Aq$KlQ4t?Y7_`f$Uu$lgbA=Gh3ThH zGtZExwi7r*_Ht^yUN#pN#D`#q=kWIMkEj08287{8sLf$`;$L{>{t>ThIL1lL2mcy+`0eeOk%jLZNnl+)DmCt_{CPq~8|ec2dUwCP$DU{&cX(A+VZ* z&=ox>6a9%<1H%xVgMY?517|_S?+k#Y_;3$;2Z>4__D<*e&?Zrh>w}tDj$#AghsVp| ztC&Z*@DE=@QIAG%g0IVb6ptzs#$##|iYd(ug^f4#YrkBmPWqQvdt!X)QD^M5*m)!s zYX2<((;Qo6ctG^3?m%nxzj0xH8}sVlM!`H?uBs}bUVTB|RKzP-PWoyVFy{vscdAC4 zE-W;KHoXf|Vy{&-Rf_7Dl}mbYe5#^6!L|1o9mFO4d^{S~qa~zM{dDccMI9>RW;N zX<;x?z=_{XS3Jg-8^dFBu;! z>YMmIzbjjR^5!W@?5?c=_2jSV|B+0Ze{XBq8tI+D5l9ml!!78z$>)qyUKY!d7@z|Xa|rqk&Byj8^i1m}1< zL?1Cqh+W-`wKHSKAJw{97r1a&Wla5PGNZ)aW(bkxXI4xv9I!z9cMlcbu08a3WGC>i?A<)Z9se`g%F!yg81e5oi;~9Zxdt z>UfRZZ<6suDOuCLMEbW=n}qKD>0}K^CQJyr3Oj+uU$`2E!gB)Wgj7)WL14%zZ+RI$;e5p~<-d57dej?d5NYuU+(M}KneOo8NqGDH8X@xf&aG<`JAUsgCP~7!Vz)JVl(nRVw<;{ zkr1dVN@#lnTN82z-Wf9sLc=vvByadtGtuZaF$^Etydpn%QhhXtP_MLfT;h#|y_Wy; zWJVVDqZ^pU*Z%%IA7mdy1aPYZrp4tA^JmZ)NbCqgxytBI{~oF>o`y3+LhtKWxm}s2 zp?4%VfO#w!SVhq!WKYGOf?VM(5)r^!)un;F^%t_k^0iF|A=4uUclJD~$S4$g@TCrw zx-C4S^*3OtM{tjshzaGwx>Tt&|HXZYvNe+*tl0=|Z;|wR<;6-<@I^{Te6cKrd~tlc zV!&oh^=GA!im7_f`@^(k3(Q?FZg1NrXuDCL2S}AUpU;OEdp!Ak`6_AuBY7WvUeOpd z20pdz(84Q(yu;=Dl^%#FHA#_0?JrZ?Fv;y9=Omio;%$5h>E5VeQ^k_o*S-(dLlEwm zZ=fnJ1!3+Hdf?M!ZNuOc{e_(5GT!9UNYakfdCVr+JWe4pXSPy>S%SH2xM|C?FIH=s zsC?Oj*4Ol<^bUq+N4R)d-_gyV8``j60+$cTOUvq2?QIS9m5mLBIP2#o^iA`9VI(;p z>o-IMEUn3xD=kGHCDKOc^4E1e9OMSaxRN#WM0oQ)ZEhF<1n)tQZPJv1bkllUn33;S zOj$ISh9VZsc{es4p>QK&z@W_+lAESL#AbKpn1e!f)VviT2+G3Prb%F@DDljUBIGr> z9Vq7I8ygmK?{4a$kvm$CntKgeg#vZUjiffP7IY&$f$LCyXOTG8yOxnOumE6i3ezKP zD&J{%LTNvOA>i|avMm<&YaN2k4!vajRr$W&4mB@t(hkPS{fNe2RbHX0pai-0O=>A2 zso_K-J-&VuL@J$745hdsd0f8}ncUdu@#WT{6UuMMZa`^RD28xa9+nX5{Fl{DYFQk? z>D0U(B6MQ8i^t6l`p7I!rJWFhTA%fT&zUN1$E*;fnlDT|-mh?}@A_1%%8uBqv_k0a z+&+|)8JFQ1+T2AXR}FbWa^L2}o^Y;+3l6n>3?8b59I?Dj*z6z)^CQ~;XmL1r7B+V_ zJ7#Xj7bZ71eWbTuR2B)+Zx^EKHS*<1q@^yt77^Wxn;H!-8j;eqO;@-o-;ab^cC~OV z)QNB%etcVY`BzU-{?4LJVuun}cWI+2tVoK)(d|HGER?AUm91D&k0;^jpzw4`udJ6^mW z3SwuJo7D~6xXUiy4`T>ZhM-t0Y^qi5^u^LmLn5WW+?24vnCUCl77c_yEBEk4=_q7| z$qNmER|oThm^bOo1PdqzR8!iW%~Kmru4vM;i>y!lSK=! zH2v2x$Q(&!yz|`fgC4RFWr(%S zj&Mb}U89ggoR%y#WbI>#&{PIpUp!i*50S2fHR+<-422*G?;(4oxQT;NFg&aRyba9m zhR`15hnuxnpLl0kj$e?#-gkRa#; zr7!hB=h49y1MJv|QGt4_d3}Qb($TY6R8HcWkinNlZKngG47mHvu|)d`x_vAxLjdy!$z`=A7{2ATFR30EOv9-dJ+uTwA=<~50j9^r6mI`Fc+mzmM2Clulo#bd zw3heDrNySSp+?3xWg8Qk4Z|`z)O1+bMFe8MBA1a%OyJZ=zPaP0po{nQ;g_MXF~qHwj=4jXijEt+sNUYJ!6`llVgm_ieyT|%T?uN*q!u1swEHtjXi&b`)$68o3m zjJXKjL4c)JRQflh+^*_^&dF_AZ1Wcf7n^>Y&(sX0ex=!G7n_d2tQaIKHno}+>q9w+ z+D@l0->Mq|>-3c*Ou6#Dj3GCJCqr3)7o}?8Rl~X83|Lhqy(2B|H6&M<+-SHcHPB(h zIudwyA)Rm!W8_OjLsJsden28JCv_!)<0d-WtS-7j;@FN$4xhN|{@pNkhZ+_OJMoc6 zV7JTRMEOSDCvs7SVP#_lZ~HYkSB2Ti3ZxVuN#VsBM4#I)8Gn~McE6rD?z}(0f_afR z=}1%6kU5C?7C{vTSq1^3u(#3)I7Ee88<_QXt!#0p1}5VXQq1Gq(r!%|i1mK)s=O~t zXvxAg$rNC-5>Z_vc|(;&m9kw8c01Zk)@ZXsC~kr7K$F>2xVfnh=I*w07#pZc(njry zrpaLfH)6(l+4+{x;}=2val;`~;0!FY4Fj0+BjxU9kdwRGM*8|ingI&yMDr_kfQ^@x z!Qn;!3|1blC*&6!Jv@;jN7`}TxrvNdxispcMD=)Ke*?1aL=6p89R%&2%6UqX!${bv z>wVE6eg6i;65#CpO$-(mtOH;NApu)k%;1Ic@8!!iEeXhIp&tmXD4uzV_;6dq1oJqo zj=+C7-Acnt4r37HW-P9}zk$5q`2Y~lk>MEiywU8u;N%%;Zuqih371L!+e?}AwQKOf%Eu$t)XK%{hzs8IQuQg zTUoP3hc9%=K`wRgpC$Sh>%dB5%c~OAwBI1uKhziNryrBi7HTX-CQa;ZbbcbL$S_Bg zHX4*HZPy{AkB~iTvQ||hoJFGYbo1VJ9ePgTs1D`-t`Z*J?g;%plne|B)IVCmE|yt~ zFDI)OU)pW8qgRw?SGMuz(G!?S2hlp^>n$@fyH{HY&>$*Q0DF*4sgzBmAdzo9sIwG@ zc%IAOsQV)8^^a2>kPW?9$LfhfCNWFoFjH#|tLQ5aR5n!8LCf={pipz^NHTza|0Rqf z3|b5dZKeh?E3y0z5->i3wO9}#kJZSlN5`5q3DeMxNO-Pe@1HJg)SxmlFheNq zBL&C;6-HcOLAg?F!mj}MThpXQv`Y=;RN{`_pKmrGfM_z)fa^}{pIcni9bpJ~O?jMt zYHqvX(i3k2gJW?;w@)F4ccr1@67BZ9-cU8@6<v?mwThy$%x>7FEx)< z7aX=8PuA!1O~GTCyFDpA-wPK}JuW18H(7^`9#8q^;FDO4uB|CiGWd%(ga=Oog!oT! zIz{Qbqzx5r3A%`?+uzHI20@^SF=r0*DY>s9?3HAyLQRe4HE^>q082-L8HTX~;@-g6 z+a)asLN0U#QzjSiK#P$n7Os;W#VNLKuF;p;>2VTm35lkQ(wZ9~|GU|g5!q6nmDYSQ zQ@4?Eqy3Ll%l}FtWP%~4Ed3_|hP+ts6Ts!QWg`khaca3og?(%=6BhU8YlbvAKW|8- zI`Rx;n#LKjY9XH+J$X28#WP>+aD8y8b_Itk73bX(0F`;?1XCS832uD3>2k~#immxJ zaK=BQXo3;qmG2BA4PUzD5i@_Vu-aO3Qk?sU!KNXe zjgG01B@%OKXq95GmdBQadF*=suLy~Z^z+vRJsRuqS1=D!EjR~{j7G5~!|HGHFtZI(+HIynzOf4kkUmP)lKnY9kgy zm|hbDEpMLI&;_^Fpx61xn~ZT(IGXqQ%pD4+)>OcYc@-sUm-Pr!NmenLg{|w$bRN3k za#9g^5{5(&Uj4ChcitIDjydQD?0aLyuAtH-m}#mG(Hw`iHv=yTM29qoU-bGN5wij#Z%JzR7#Ap=Q=#CW2jI zr{<*k^dIDQT%ojq=$s2HGj#SMQCz=BKQV#}ovfBm$ z*Hl6sj;W81uf;mcnG^ldEGVyW5+u&x^V(WlOrD?u5k?2}-Zq`vMRSx|cvd7iOZ81i zYXtgtr6%;C%DM!Lx|nYD_zN`wc6H3$!oC;)34&%pA<3G|-O*FX>XAaW`2eyzqTr=U zbzrUBeT~ar)`G!w@s)awGtUlJ?L_&04U=$h)fS+b@alhM3gupIi_8g43cx<))g(}a zu;!$OmpvgngMN2O-5388FF|PRR}C3F zHZ=SyG*5JN3NS)Zk~Q@y5%+Y@5h~3fJV|i=!t6u1; zTobFyu24vVmj?=GVQkf7oH+)MIw+6oZY$=kuwH6GtS`6285CNA;@#Y>BhptYUq>aT z!i~E15OdyIwvc|t97-Oy`@)zb-t!}ZHN?j6#I*Lbl zkIy9S67){kOVcTnLj_bU*D>%ZUrf3sSv?2*z!vwaNnZw!*WgOkH78b*aR138g{7-* zYIxNhDjn4g2kAbfq!1v8q!VOZjiNpdn}eZL4JVErlC1Az7?hrY847M^WP$(nk(164 zFS-DH$eb*=W2NiMsy$d2x9z1;y6A0dTwl$Qs}WX zBuiySc;F!5E@j4t>TUia3WNzL2XqVjkn+|9Q|61!9g;Aj(k%zz58>HO8YY_ytJ1|6 z(O+gb2XxVARp@KH1Uz3`re!0XIQp<4ClBsDLLQp<;(7hOHz4 z>aHT)_A_g}aQ2yp`-Pb`i=&QQ+F!LfB%wn>bh)dTgi{7ecK@#_L5bt-Xd z9iC`B)zY|Mx&yz{ehn0W)I|PzTOdH(W?famG_S20B5tUBwCbbKnBWPE%DuX#mW}|w zQJALL`_07N9xquT<=AE8%_hj$UnYScLg}pG9d$T&8M@c~4ue%~r!HV}-51QzB6q(I zxN)s&h@96yykqm=9;1h9=ph@3Q^FG#ZefxI7f!A@;qon^lU{gM+JPbC)(+Jjd36tV zY!MV}+$&91mfL6IHWv-*k?Cg!1&b5gXVN>Sl&N`X#6d;4wsdv$daAYt8OyEKRv#+l zH&dyH^QRI@;tRp$1tWJhdR-sjJF^5{8Gc z46{};X^DtVTTAuet2%3`v8TWGLxc3fF zZ|iN`P@BdtQTr2PmwPZUKBG7h!K8t-No2ky)igg8Ox%6N7lK$93n66^3mMhHJ7$(F zF8xuT&rbFFLmg!y|4ge*xR-hzv8$?t<$*6eBbg|z<`U~cx#`yTmgj{wWO}EM@AXqV zo32?hQ%@D^z&Tfdb!&Ca6fRM@(l060v7b zja5nG!uB#bxzW9>tz;jVQ9NO}tJtA(w}~}y47bl5C@)z{)YaYoK5au#CG;GW*69KC zJ`1BvAQUsqo)AEv%aO4N{TL!(p;~VaXGd4W35l z9-SsOKeV?76i8Yo+e`DFlocOmGr|C5xAS{Y?^UNJTi;oL;ho7i2O`e7nHB=8f8rgn^m9CT=@8CB7oVjU1TV8AvJDHBtXZU2=Azo1zo=wXREMh3cNCXGcV6gj;I_(hDoO2KcJQfWF(Fk=I zJ;a_+-c9TAka;d{|2zrG00P&Qn=9vGfIxFy3wto9o=de9F0TI`Z(CaJg3B7*K{K`ZwVA0q6w!6pU9dvhkp+wbz;|Y@m`qE zC2SfVuxWe%LyP<2=RkhBsVt`iC(PRLIB?C{8YM71P=Gg~0mJ!cWMgxzM#MK0 zsQiLi=EcJuSZ&h=S|KqM#xmN2Dg@0c+rb?Jc_18uLy{s@3BYioB(!Wfx7b^fT{v_o zcjT~(_ZDjcu}qfOnG-#B33rBQJPE)XVQb%kQK%@vm748h`D{~pEUh7uEBJ#nNE#ki(&5|k|;u}(9?`)ziWn@JOvhSGjk%fz)A zF@^pw6p@Q2-l?#Qw}qsD8#XeMo*Uo6xpOCK3id!<8hl&>HvWs5ZT2gBad-!a4xL|Ji@I$f0m(dwC)M3swK>;1|{BWHUY@ zXs;9AfZA^AGOfISFr-9N$#%T7f7;~9b+Q#G?CP^aLk=fcd=S}O9D$@N{es}omFO)> z4cU>ziAIGpa_?h!nDVK4Y=(0HHiH8SDLhgwWZ*3Aw}1XZxYY081jI*XL=vAyf)`Nw zls??*JCCPAH{RVsB(m~1{+H(m>V54dl9Vh@U}Dp+6|)5c(qatQDav}ha>t#XUtC-x z0Vzn*;~Mp=ljFHXg#f?C6M2nzbu!i89%PPCjGt9$R32OXb;-H-C+{6kn2KJwvX9zljv6wns0NqGC$d?FW(w)g~lg@EKa|-}|$HYaQ zgOLg6AeI|<4hFFkQV)6eAS=2D%-{xijlBU(-Cx-i+~3z%uYM$M@mD?sGC|1NUwAoA z=Kh&iXrDSSFq6?`Ja+%<-%Vs(qQesVzxU&G7)G(a!x6l`m7Af%MHH!~!|4k=y$~HB zIs~+4{_D#Z#D^bo_~^xp7Z`pR!C}$yG6oO6=~bPT-aB9(^y9G-*1<@>b$|$}_YRF(G@X3&=5y;pC&*}^ zmVFyYo=v`Y*gh!tjdiGuL^f1WRn?=hAfJKgeGHfzk5X2~09UfAfoT)uGQd~GjH(f5 zkm!DR4U%il`Q@=WkSuXcSv_PrjJde+x5~;B$X_t`cEtJ8p&0fLNd3^cr|0Q#P#~zw z?-9&*6IcmfnZ@7Qhs;92zk;;@_zxRno-^E3(*2GT&K1wp@iSRAosa-n*JKL6(vIBo}fH zawpzF@{Y9{Zy%!M^&zKOiSQ{=>itSS@}M^Y@KLEo&id?i$P^%<3x>x%XM7GsVfEz^ z1DOIqRl$Rdhk{H2?^6yZB9A&ha~0%y*h>!^JXJ??{4wFuu9jd3*Y+Fm)-1yeWkcQSx0+ zh~P#M+Txm!W}5^#uwQJ>~IGEPByNw7XG>F-Yqou6ktE;Hh)FlsKG!jCi;31Zba_&rSbW1K~2 zzGPtpAB@8h$0;Y62D2j&pkWNc@el+yOhJpgL15uT1%jFRyyzXU4nH)n@fzsZN#R7r_$|?=H=|@rh|oZ4D~kBbmX!@-a(Kz+yhJgmL(%`xH$^G%{eSX( z-vED~+RwvNj;R2wLH@@X=FJ*j>zGsY``8<5D1X2kB-3HC_7A9cbton4j|G)kQ)4E# z@!(${xIGb*gHxelvS79cQ;$I*dbl0J>`0rif3zQd0fZH5gS_7sa6ul1DpU3j(kBlk z9$0DzFualUL%KfBIXpmz^P8JG$rt#&l2=;_#eJD8>t}GXDn<PJGzC?fY zkWHWQeFR^D65Kl+#_w`ZOh0Z1EzeJNA*>mvhNj$`I8)p|2*uUIzSGA*ah$@Z6Bua? z1tfWupL+|bK060<2#=>5{)qCtdizIuqr-UiM4xvlHSK+7_RsY`AL*__bN6aBHE5$^ zt!7>Takj4hj;JxrOjwo&yBvMy9ZWTpQ}=^m;W!tD5~3QUL5yVKC(qdC_@YjbL5M4_y4SH(dneXFu&-^@?<6ucDf93E|pX)O} zKaw>+A6d+QA*mvCLDc?mb3aj!clN`oz^uIL*4#F#ogPA7e(h7{Qiw2Ca+S7;@;LvMsJa^AK$evh)d87U_ zr;g0M?;8UK_mC#NkrR^ zSqB%@Z-T-L1K@yhXJ8#BsQh0!`15_FSvWj5`c-Sc6zOvjGL=xJruwzmnu<)mU&9cRfa7*v|#=3PdUdwfUpL%@ZZo{U>kZLu&tCczTd6+oiWqKZnYm2+_ZiW7+ezXza zPzlNX0Fpw0ANt|e=$%HRN4Yig0LD7=U^?E2oIy4%l|uUALjDVD(1$y-0&pZmRzjng z_xX#Xhj24e6;yVM2ICf7sC~vanfC|DmmosXBh338=*OMsVQb8O-GsU=_V*6*HPO4E z-utNg{!)3Qcd))DVg|wFaWFHqVX@b$$KtvI;kDj7IJIHDkX!3LKfcxvXiv`%m)(O4 zwf;5iIG~ab>fB)7JII`9ha=M(WJmAd^i}n~xZdy6@SiJuSX)H|-{{wX+X5k;@eg6X z|9u$Lpe#t5JQa)KV;WhqhEA!6h@0n)M((c9a(8-g7mH$~M~g?1h|i+dKK9pPQ_FqP zXQMCm_kz%CHW^vd|6pP*;=UE*DmADcAl_~O-zVX%Dn(MLJLMddA`uM|peN?K5VH5; z_5rd+9IzgU>act&m>-CFvz*$Og!xVJ+S1Up`rkRdFHE23^g+%@u-@!h zi}Ukfnhy;Az#6Wn5!NG}FO2?C%$3t3V6<2>9A4+r-!;J}Gn`Ze^WV-Q zv4E)iBJUie;9`yIheB=xOGob@uzovBydkpwx2} zVa|{yZY&T?9SU7(YrzbMi0+yp_y;H#{&9t+;a|%T45YC8GjnwcyTvrC;dN$x&>uJT)=@cM9dQB(RV+p(stkGcgeeVa( z8r*6Rwi2l`O3V=;`i0IUwCR70LD1XjlMz*k-tmlE|&h|!%r@)}zV2N{UWTGr>(jl1iCEpsbG?I9Q>Db;V%FE!AuIL4tpVC@>1Xq6TNr-^_|i>HWkxQu z-9F1O>l>Pyoz@`B2_aXiQpEcfV%pH4Yp$xi8M3guZcbh_C)D6DV$ zjPx(BPfsgXNPOeTM*-j)!70`C^>yWnS^3yW9J%P$)|4y8X@zs1DJYU9qB8VSFU|ZU z7`f0l?f`W!!mx+x=L%{K@6nQ4e0_cC+XDw}aejc`#Wg38JEJmX$p-A!Q zg=;tjs!Mx-Oh9U&+Hac!SfP0LtkfPTbqJ=L!_M!{gg(7wJ(g7U@!<3eW|r#^^PiQ~ z{2)MjkURyJti%sonhCwX^`{qds!M$DY;bHtC)BmmKHHp8K0dZY{*SyS^z<@qShS{f zm(~>qjD5M&stGAXHk$DtXHE8qwTeM}+Smt(z8(6YAQD@rGcX)%p z5;|Bwco@Q!`W04w=9O4AKYC#HoyT|v@Y4d?zE`bWX*#+N@zp+9R9j=ACVQ|Mruwgb$N zDRf)(nH#VLsz=Qx!2Re;muyPUYe<$vXJ2kMeb&@&Ev+G&qq@JnooN5r72*AhwAEwp zF5uQa*?{IZ+g)1KSdj5f__GBBn!}tZkhZ@(ja%&{W5`;L1K(9?YH7hFu6+0&L*mWPNrsgBjv;ZT zB-zr`KQaGvLVC%T2Jbk;VLjmY7Q9D7I&roH7w*VEm{L4L}g<0qPxYk+nIR< zItO2P4{C)Vv$u_S7FT96)?48JtKcT*%oI6*DRcQEiU0jf=k3bE;ND$mWm93aq~n<5(95RyD$qM0scfxbZ(1ThqM+Fo>q?ZBI2gZ-z6TtIRHNT6ea# z>|%nC^yGY0*O9Co`8;;#wwL|$Z#e#FD8IYjJ~c3@4!v60Yc87xW+5_0tO_`(nH@jB zsK4r+Q(*B{qgDLmFRI&hm&Uen6X4c%-ox3?P1KhC=U%Puu0&UK2+ecK8rIpGP7~^` z_t(t7JTcqU=`A79Qlm+o)*Guc?=lliCsm357=xkdHOk)Bvf(3WH@R+K{YjWrrf1&e zCpcp8{z&jdGU5h}pNpGo@MY}M`l5b@!#Mu;AL89E?s;ih#VpWYmDx~`aeuF}Z2Rnj z+>GE}z}MB6eU~P7YuZ&*Km2rgYuWEsq*l!C7MGS_n#^D8S@X@Uy8kM){TyxgYx5u) zgUx|?^1<{2zdNz4tF%V>U(lV*z=O`Yn0-bF{ETRd?aY?>UIqjhMzjc6y%SCaG=J~Ye;|V=24B-EjR)G?L%g-rWTS7m1ElQ=zwVNs38V>xgVR{RBr%RVB&YR}AtLqle(L3`M88Ndb3YFm0eQa)StLJl~`dDhK zO`9_flG;qLuSn`+mANg&1_5}BI1qrPb!ds|V};h7iL3(NPnFiy-j9rjB(%XvXO}6D zjfX-Cn*GvvYf*U}_RAsJ>JH5zaX$0}#IL@paJ_~DtZs2GLtZr(~BF=oGs87?67MgSFt1)P2 z@6AaLQV}UvaKO;E%}Bix(U6|Y_&{>TA%^kMW>FW1zJHK&i8r_r-RjCi+dj9r2MWs% zS-uk_w=abij)-d(x8@#le7EL8gxI%G)Bf3r!ab^R*Yz(Tr&tJDhQ?Kzb><_ItL_K% zNKZ>WqM&r&PSYbiK}cx-X7C^>XbwDmc$~;#gF6l@jm}uz4b(_R97??NF1j+h-`Htr z2=n(}m2WM!Uza`cw*&v44%+33Fh6mP$dTygM8jb``5 zbzDGyr|21cdzE@5S=~%SAu_3axk;bOUU7aFEZ+S2s>;d6N6)U4#Y)MhiP{IZ)KmXnGMe6o++t z&IBOBM)@+mc4Bd>BcRh}V7>&AOzz!aSR^s35WTs$6|i^(1+~Y25&1p4Xshi-m=QdA zcDF*v;qYbk8RnfrIuxIm)Mo?oZUq&qKoKop4LMf}_Z#+W(4yQhcFOk`A@kesB$W!6 zA)vr)4-aBog^hPYwiR}_5y)h{ZhXB44ganyE9D+duCGIpmEe!=5$nC5DVT^qHazEj zYO>bsaKpMI7mgY>2a=04g+=Y-SPZUCRwVCJ!&~?XJcVn_W#@LbU>R{(-1!tY*W78M zo$)+9x!>+0(oP}X?xtkr3L=cf(XoF2*Fx%BugI4d8*_FUg1K-*Zwv4%l#;q9z6K0W z8OlhX@=VBnmeik}y}uZOl7cYr&p^k2UeqZ&1|7EdbhhQNAow(5qkU*FYB~}=i7tnl61BJdWky|a&IwDn1qFhFE^^-%T4B8p8E9d2^RRm(Jydvwq@H+W&DAX{!6IEHG zK1(R=R<$?2R=yvq;LF9vgC|XXe5(aWYIbGkS>_8v75$A@xqFR(nLB)4gVO+n+#bXe zTEG1iVWBvxSmDBTfO~4=bd63Dt*+1ceDOMH+8auqtNw4H38Po?7GOJ(I9x#m#{GsF z#EW;&PIDH>_=x?K+)weA5Ti)>7RK1AG4*k5du9QJS|d3+ozWp5(515R|Zk`&!V$Y0@4RZzUI>-TP>>_@36>-)L{(g zNI;p%Y$^SmkF{?_Lo6;0ujAmN?)4Ahg=n;)mhy9z%6i2XHjk?7Fz6sIXB|Qn(fCd1 zszJc@(!FX`@1`rgH(>s_k;kF9$Tb;dqRnUWt*VAK0=WjODEA7*3j}GIy2V|L?JXsb z=$mliP%?tEl&@FYLIKtU9M9!;5h`PJ3rPTOXph-LO^kKA)TZ26@9Dy=s!mKvjqgOX zGqU#?Q4OEEu9!nr0zHDIR$PWDW%p;$)5S-S&7p9M46KwOI^CgA3g4FCypCN`nibvp zS(bw3sC=EgFk*O7%}=?9TAMxxapZHs45b~wYs@`}sJ>1lpyGi-3~HJlLHVI186PeT zHhW-Tk#GYd-0NGc%{}n;hEW7@c+Lggw$fB1nL0(d9vg0gB)H`; z1_ExY?o#=!WFswlG{byHZO+#4=d8 zPC)Ve^}z~S*zSUc+mbY@yr?5_*=yx7sZp~9*$E-`=endrfQ0K^T4|vr-cJyp0dM>!9eVAoc$fuAPUN7-`yA-fj$7qDw9D_E%8EVtsZ@j97b7{Pg1O2otI^`kXCfD_#=y-%vA9$Q_$cB<{joyW)ojW{@q*6(;h#b_l71 z-J!GcjLY%H6LZ}4rV3N-OtHRg3w>6%aI4t{GuZ)EPPHp><=RvK|>Q1`4+tcF-TCTU)vemd4P! zB4!#Orkp5YteP0(P=mWGFrwXY;u#HY_WDMfd*pb8MBa~#obv@aUtNcE^5rs=g?M?t z(FsrOHnL3Y%K0KRj56uBkf;B$EpklbUKZMsA@{|h2*{70Qd;7*i#wPRpPB~R(~i8b&nA& zrL|@Yf5&1eVK|{yj-3^IeP^RJgLqBAl@}Y0y3#+j0r?wQXw>R$VX*EaIL!I8^q1N! zWOYGg&WVOF0w{&N<#m_G@^cHA9e}hStz8(a6Q8+bNvV}KkW3W|GYGNg!CL1!p`yO- z^VwVIw+@(OTdn|1-!D3Rw%bvam%%05@Q_rH16@zXTct`^*Nb>Y+92h{4L=e?I?xVR zZf?Nm)oix8Qgc0^#%^>_EEL>=s=^&v-KZxg?`e)`(Yd1y;*rpj`k}j!h-HNFJ(g?r z*htIlGTB3F-AK$klR55mQyUZ%B=f?+oTn+I{^8(V_i5-b;WiJ5rvHiPi;1uLf@FOG zD(x_|7V1xoSpZT= zI2B*fF}6LS@FF&x&ZoCJ$R{DxyUu&+$b-r4ybi$yvZm+vRlfARvt*%tGQ%t1`m31A9aBpRP zWnIO>rG`>T7p_zDZR3@i`L@KA@wTCw(XDLh-)l4V-qwfL0bh4N0P5+iNuI5I9pv4n zGL}4co;$ln!2o(&dc`2-50B3_iQVXOC=Il>ZaOdJME zLZ!I0WprTzD6F~`3G{oS7B1Xgaz=?@i$$^DQ#H459EGMiNcHDaP~QvJL|;NeC;zFK z`>SM*6mE)ew;Th}6t1m8nB4I{EVe~n{euBfp$$-4Bke`0_f%>w5V^oeoGF(cK>_9r zaAWQcNPcLT-8m}?(%mOTTP}CE6tU1QVgrDS9+3&O0`RRoI09DXv|B`bT&;E6yYO(K>WRnWT&^$vov zW*(|cvZMLYsY1q7hEJnNG82ZznUqYSA0HsE6`Otpjs4{{F`W|A6@vxW44&R^bLqD*;z7LN3N1O{ARQX&BKG`XZG5BaLYbBbB& z&RPofemTevTO0$Im9%8OCLj%lJ}|Onq!|YUNu$a=n+zXjNyzG7kfjZ|P+Q)D~lgsTpzlEFe8PoXHjXBOyNOlvYWd)Si)eW1#R&2+HS1m^D zrGATLH!OzY$ylhd8Ll~BE_FA2P+VZ#K*aG7mze`9R-{v_&X{Dg@=p`&3!R|>+3A8q zn_pF6?)>T{r;CDxkU$jC&vDB8B>M~~1hX$DlPZC)GAYb~oY}%MQf>)u>cZ@7tpk0V z`Z*_66qBw{+)cXSJ`dca{n?G09aXuTD|N0}^Wj0@Zaj;w?~*3P(#mR_R_S1Ls2VkyRa; zEtWcbb8qWm|8;@mF!j>1i+fe9?uZ`nQuS35v3w1Qh$XZ_DZzrWugZA=-IP04A_R~& zlk7xS_a0JsN0d%Cl38klNkPTS_#RnCyMXbe@P$Dn)?rX;@JI-!79;+^#b<>r6(D&d zV4xyP?I1Ep8De=^aYChyRd7+~dfL#8E-AoB;f`1gD6rIf6zfgju;2-qWg9^|Vo6Z+ zbHS`&k^{(@T4*hURhvnA2xUoK5SN2L5x2R!Opmw}x4V5Y?OD=46LL|dr<(;=WR6QN z`!XrW3AD5{*G38&JP2hqJeU z<}_+v(;vV(P`*`%9sGt4Ioh4`B$YS3S{^YkiV#x01UiPG4DuWR8Y>mETaAb(06R=KmA?1}K zx2%cC5_R1jC|#dxi<8Pt^%dR`(~xDTDifYeCJmNOqI0dW;W3{rDMgSP5rY7>$Dn3Y zsatP{SO0&q-aWdF^ST$^-#qXl9)mXsNa7F#Kme4?5k-&y_!^KR_%f@p-*0c}B2IE5mQ-gWx~sCex@Hml*9f|A zaje&06jrT2gbweueIqZUbCgw#pb=Ho(T;QaaBV`Ez*Z1uT8~c7)VbEfh~+df(H1IK z1p!yKBmJwbXK(A9r-`}lC$T6I*vDrXK1t&gq)t{?c9l~Z0-47|g_Ewd9!|_@&t*Q98^x zyD6>ri1luvE~XhQ49NC^;NM(R#ll8Yc93S$<}C4Yn%d&>`5D@4aiw$3t|%zM*iBHT z#+nvKMj|HmfQDAKtH}1Jkwxe1}Li$ zQ^chF|0a$aT=CF^>MCun>Mo)Ed_3Oe-SP{WS1@q8Q-!nZZOPl^gm$PpqwaMmc}eE5 zkS~ul+y26(NQdL(otz5W1TR%R<{-8DViV3M0bDUdr9e_7cXg0km3HnC22ak-Hzm3g zvT=3QVVz0%Aa6Uv(N1m^S_MSUP7womqO>W}&T%*9xEVu8p0hGc{Zdg9TQFQz=j{wh zw7el6#xz^ql;FLoA)JMJ?M{$K)fpx2)^-xmS6~%F`dP%)u58W(C5}{OX=C*;G^hz~ zQ`LO1IE3%G2f1<1VUf{-F=0C^CX6MJIz+77=fKp%g4EsNa&s7M;j0oH;6b7HprBK{ zzr!UY$m3VLcQX>pSmC`7^F34MnRz_ag%vi~`5btthR3S_i2$Zh6L4Q{BdF#la_5lh zg6R;nGNaz#ER6+eU1tszRn*C2N@PG_8B)mJ=5rN6Ax?35fY7x9@%1+6(>w^Xa@5`i z4rNCDY-|SBt<6=!on zU+zRcP(QR%p>V}`{}|1ammfP%-8zxbZ(>1+V=JO z3$M?c&^EC)U!^!^nvOe$6(rx8O$JOpsPol6M?-ES69yGZI!YI@;bDMHEtyw-su5iEfBNm&$DIToF?UJt_ z>z?!djwjOsUfMalK@>GHcBWflAB@oEwrIuNJrR0YX#=rbyzPUb_A&T1FDqW@^#8uu zjcij7xO*{9VYz9{(69leEsZ7O6o?NP)67EkZP$E+wRpd~Q@Zgr$vq9kY=Cj2l@?Q8 zu0%B!!(O=>)&KnlOBC<#PZAn@+hYcA8;pQFVfne<9X^#Uol5R~9j@QS6VkmH)6KK- zcu=KP;x-X-)T8-erTb<)32&rkm)F;=p=!`!ktR>|hM4WjPbYi4g8@lJqgnt{1ShCp zgtH+@K@FaPAbef0lSC*As}#@_QNg${@Tw8w^6P#jh)?IzVcoY+plz2<;j898KlV`3 zJwBF%%NBQpBkISH1eni+OiG6_Xu|?lVsGrbais~CAbg;~HFGiuJ48fyJ@Ih^UBt~4$e^4}nX_GZFAk~0&z%NbK^ zjR+nay06e?;j68eT)hWjH6XBEDOS=8)QKy8UIw+Cn}! z50ic`0t>Ci2_S`{qTDuv(JOP=1}QW&FA(b&+Z>s!(f)P|UxmuY-sQnQbkD}$9 zf^FUz7p@l1tyEXtx(f<5LQXIHfxhM#2%5odpzcQ1whHx zRL$+jHR0>lc5WhWff0)8-`8)PI(CB6mG%q%blBP+j!nZTrvJ{kdpKx+6zkNuD2dFz zJ-=R%i7CHRUdu}~GLwTF9=be#bXydUVg}TNV*ii=Ed~CKh04V+WH!>4EZ)eR`#yI> zMCdO@3gTE`z2di>r~{!v=xS%hW}m!5dU7zEx#f?To@5FY1G3})z9Te3d)i3OA2x_o zVQ@Rs+Z1%5Y(G!-;W$Z$r2*-1e3ndJKAZ-UywISoLO=~3f%f)8DFTM1`c99%opV#? z1ttTo<}g27+og3G2UUZhtPaiSG7Ww&q?wt1dwV!(Vy2OH22^{yZy;cAX8`xHIcHKX z?{`VybuMC)hTWo^n!*N+gh23^|B(caLr2KCB_4mu-ke0v-@Ys^8XS~pG$7mC2Qv%y zc4D^0F`%%k3g>EZ13zqWeiuG*7=kUy49xxaJEwnYZ@Y%`DjsZa)4-6u?avJ2l+NM! z9iyghZ%0Gm%LHkMonda;fe{I8ubuHDbWg|2XlLRG-P`plkKE6Ny!dzCS$2eI=W^yS z?bHtww&5dTOgQ|=_l}|MNG~4|Xa|xD7Y%aCUkbACnEaq~U0=S0|Kl__svO1PXz>W` zWXi=N?UY9qY;JNkhp>_OQ7&QNLiLZ3pnIo$5a+nZo_Aq)1iRtk&U5fQ?u?XiK>tA8 zWf4z}3{tU8x&L@v+3v%4&d(dqI%g|z0c+Kd90SIoP-Mzyr2+ht&};`oc!Vl#=1Q>F z6pByQSYq~yI`lcGOHkH0AfMQk7Osg0LE&tWE$i(w^`>z zWV~lOXQ7a${#9mTcPAh6SQoO;qiF&us0nrT;-d6WbjZdeMDO^k2_G2_V$;A|!r2ZT zxI&)?H8m*f?9RyY{Jhj-;|EIJ4l$F8u_0*(S-qt}q0ON@0a;~}2M!!)If;h$U~O-m z!X0}*gJm@|s6zl9&=U^#IObtvNN^|5X+Iso7I&upUDzrl*+>Op5F-ni%} z99f+fs(U~N5ic`u`=V%3{)fCGW+6#w;EGLL8g;{4eqN`0`OW&CM37zxP(!N08Q(?b zj~zk_KjMztEds-UdR*4P8HP2}6f)QKC@Hro0i9n6>W)O-P2_JDNB=7i`{DLo(uQ?J6qb5bYm)CspM_+cIZ3u0YL z)#Xp$9^M!bMZ-z%1>g^{*fzZ0JTKea#(%-zsQ(*j&ISs!y6UY z@h`X)x}Q#+7_S8dg_u>&@2Ad7%s$xk)`K3+d43c+F)DJQZ!+kY(N!K<5Iw;dp4BrJ zgi0{=#vWCJ`w;%=-cH~2BhTztp6j1Bf4B4iv`x|a9B-EHedKQ&oM5OI63x!D1gqbp z)1XRXVtQsqzEJqS+W9OF?)d5=C)oJsOG~ZKa`GqQDNR5~aZ^xXBz-|_3E9p0Zk3nd zV0eM`z8HB;aTOVLkzn@0J|`3*1}oeKk}0*!i|)4R)-FaQiDLg@B6PPd5WUlSKB1asDxjD`&y4DA5f!@+;1ljXRA6Qfb(!gx z&05kyZPwxw6B12Eeds)?g!;T6fZ|>GbCLa@3o`k0P?C`&xx+B10Sb(CItYF!ea;1a zN}++E#oU0SFy15imQMFmuA91-g*WyuEcCv3v_wOyOyTdzVlmsm3s>alS7C%%RGxR~ zFHi4=I9ou5%DL`&7}_(7vYA;>&3waI|C3Od=|@kKu%t-dIL=SS@wa=b7>a5Xkc5Me zV&gJdH)JPsY-htcDc9VRSBL3W9{QSAC9qR}YyoQX%C zSyC{;35A#Zig4(A!Imj%eB{u%HnF0L;fo#0<$WFKL}yIS4U8fjCY~0?QpcSi zLMIHnWk{74%%z`#n*() zO$l;m0JEMu@~Xx=-;g*)4wLT#eSw>q*{C` zsI%mq-5uWILtWE%^wHFwOFM`4b?KQ{=UIpI;gwkOy7IZ~?td!o(pMv`=SBV5-0n|s zJDMhf$CO_3V+zk9MBCFt3c?GQHquhWD{VuZ6dp~egvI{wUk4<*{Q%gIs39lt-uHbb z{`SQ<9W$eln1FI2dny-aVOL7+8e;S@>wH4B&J%eHUtQ}7M2Xth#>TqORGxM6j5Ebs zTFL-s`6V~%j!E9c3W=olRlc{l2nlXyYu{g7l#fopy>#lUjfP56);yn_?md4WP{#i}KHj15U*A>d6rzrpe6)2ZSp$== z&rF&0PVUr8Q?oK{e!xek{&r>tN_r3TBYVegDz!*0I(PLL9uQ8Ej^bLMm5~^%?{F9b zix#n9ndo`pk!HiQz{KCr$!9|`Pz33o*Ur$X@6WaAzFmQGThlUozkDeYX+Vv=oeiE_ zoR--8LnMDHj0Qo?m!6%rF9_y8WcR4Wfdd&*RiyLvMieUl0q|kBom@yPpx=HN`3x_` z#zL(toJxy>ry3I)Dt_RO%U-kyEC3rR1A>Bz6ALX`mR}8s9kv3RUQBIY$y6hZoD?Py=3kiVk~(xYvDjnL=?*;}AdX}pH3=ItqR$+)i zfRH&@`If5Mga~3szdE%ipd)FYu6}!ZMq*RBe-d<7M392>w+&qjsv)dK;r*K1*Mpk! z45Y`zb%<%lSDP2HNaS@&24TN_ux`v_j-->8i4wv=ZkRW^|!?bsB>eCUlO*tFX`k3ae&h81eOH`hALHC84CMZt}I*s_m-qwf+ zvsC{+mBK#6xmLjewuDGeb{GCuY@;xLvh>o#9;^*WtLyd2PfNwFr#iDISnjnA@_7wV z6b%{_pkwm}KJ>5gEa`VTG=gS(dLLA^e%Os8um$qy06K&9%8fsT@8jjt-8Q#hwf&wp zTgjcCo9ns4kN!=7H$~K2x}iT`In`(w9QEFH`^iRQ9L9;`^2x>VhJ_gC<2Hw7XCv8r zuJ&?s&7j&>n@xktTg%uzw~X!b+2!Rv=TBcBj*?$c$?3cQeO;pA!O!DMB&z<|I*xuz z-dsycZ*8@!>!Zp^2ym*jO0lqk?*CI2R?z z@BhbfBUzrrVmojjEZez1m~GKS?zF0Vh}^YPv$G0Y!c)Q)4WD|{T9B^?Wf~4+2(RSM zhnHaPdV6m0KZ{6%x>FDLfz$zq_MzyiAb&K;U zt#^V|Kh>1!qv-u7XJ%B*MLI8b5tU3-zUB^eNE+*~)UL_%+LvJ~y*UJqseE>N8leat zy*^6vwW-i*n-WWHXm;&fywvhi>tN}>hlqRM(6dX^^j_)r;hV|#LB^oP>YD*~%aa-F z5wBH6%{3VajB74+=u=}eI*rW|v#EJa5fzK>&tZXk#Ea)^j5g5ZN zzZwC~KqEP1qxe6^;lwS-<6VS&ay zz8JmIA;J7Ar(7rqz=Jf|(AWBu3!(NPxpaZkV-V=cJ~V>#86PG@Wf-x=S}$<=Ax>jM z>d(~Yc!_w+1$D!#Kq?0pHwe5a8Xtwzji9UsJ1?a1h>${`g-UHYJzzx_Rr74_X z0}1qoyfB5h{3^I+g6{QAD#Db>V&S$qC_N^Vh`+Ir>?DPrQ2>BbW?Eikt(sAE6ig_b zMjU1+DyO~?qSK$C8J{K$e6PhL0iVUZwkiFK&au5T_F`U*u=XoW`C42AIvr2Ui#O(i z3jGA&C}}%nLw56wDQXSk zFi)ISnf)dy7YH?FrqY-g6VBvleMS1_hvE^Y;A}G8P!Nm&y3Pb#^xv0Fmu^OW zEcZ*_3*giVYqdG^)X%(-d#G)z>X9ej(>}SS-%(9ws^>!j1OhYzjibI~S*f)`JQ~B=y zO<_`BD0~8m`j8hu`5GOT&$55xPJIL8>B(hUl8N-u$X9;N50>TP&MGqD5g9Lp@nM|i z--HCa)M&)a=Ocf$c9Ynm#-A$#zjXnD0YxtDET65s@WK%NTO&%Wl zbJZdVKcqrtL!WA>BsEn!jl9U7Z#F?5Ao&xGIzEudGz;HeMpMdc@p5wwm;ji5$JZT_ zZ3~mc&}%d3##kAV8dgqHW0Vv1(Bj#~LPDZjpszeO_uBr*oJseRyiF?+7(}0&wdpVf zZM%GU=*v?I3Ej`#CSO}v$ACPEfQLihnO^X>;z)t%rBOlDIqClC5Z^;@c*6o-nz}bL;C}Hu%bbMKRPVw4};&v+Jf4L6XnBCi8@` zdAW~7i&b7DYID*n764E^nEj~w+6=ZnfGS577Eu*;CzJnNZL|pvjHT~3sjo*9L*HJr zsQirqoeyUbkP9zR+448nXszP_W>i=vY5BV=gqEm0HsKt1nEcqBDv2g^((Q=_jlTmd z<+WftvOM(Vi3yEg9Qw}M8m@!2dv|%ouh4y0ps{~>N~gu4e*xpi`A_vb(`z!+#D7^_ zh7neRho!qkh)=m7j|FuvSw)Z3oRBtGx(|``)Zz&mP-O6GpPFneU=-Zpx!;S~jsy9z zxuB~^->M4uY|MiK> zD406fz3pBEnw*^V_lh+@!d03W^Np$WenHw)914##iifzSB)p`Z&(~M%9HaA-OTHz; zv2E5G3wF_YfM+I#DYw~_NoaqaqZRcGc$|-M5&DP#_(?KiE;CFx>dk1E%5+Mn(%dSV zE&??Zdabg?$!wy!xDR;r`uXjRMv!=!04V`!uCpoF=%^142MvhldCVtz!)+zwBRE>rrv-)h&ilmf z$4a-l<#*q48rfQx^>8#Ne_v4l0AxFlCIr=KpS(&27ps~eWvmyDyLuegiQrDLX zTvNN1y8TEtCPC)WvD1~hN4^WH&6!GS%_Z@Uyx~rwvO7QrOjp|6qI7-@FK3-!ORUTL zFzO7%Z8aEYBy!UeMuXE9hu5px;)+!CRLmvbco=Y5E|Tq0Y`VLEw22j=OCIwcx zZ=NN~2Rjb(eJLVY9#8vW(lbXdHE(XBRbOd6%q%vj{-6b};(sH}SADq&k?}tFm`9z) zD1)gNsB<9lw?If?t)=0KrtT1`&AX&mjHQU@JBxzmFnr`Y>)fr)?rr7GX$h%csih^Z zn_|qZEFayVgX3N1);@`Dwn|P;)msX;PIt(y-xXWefVG@%iPS)OnnD!n}W!$WN zCRUcf&~&Ei){7vVQwK)OpdEw0nYLYR%PZBnTqvre677Ujs&V*avKkdJ)vHm zSV5$!x=MFSsfyaQS2+WT>y&#L{8;T(_$-f|uc&elnN|@8nr_Bz3<)47BnO`5syGBq zLl`KUZ7#B`vDi<#e9krA1J+h7A75{OFmlZz!O-iuYe0@1dwqR^(>_CD7nxOOD-yI@ z>Ai@3a!-1_%jah+n#lA@{^r>(9e72#XYJI9m7BZB2O+z7TZoOT9CfL%T$ld^f00^M z;$XFLw;1SAZJ?vB*42MuG9sqP7~52+u60fxLSzaTBK58z0bH=RE}9Ie`;}XlSMjHx zRQHH{+!kurnqVeGZ|$LJ|5HXPqZ62|h0N==aQN1VX>tqJQeW>WQrA)k6&~InUV0ej z?(nYt#BjA~5c1K9EksHru47$=AQ0&%O~qCUwTaE9i$w-S^HqR zZuTMfpDAWeNoUL3bS;9u&%d>q|c@xPJllEu*aetjT2VELSeh2 ziku9NW7R^OXh3hMqYupKK8jVkpb)B}^h)=5X?+d!5Y&E@G#ZgS0FzvED|}XZy#w?z za*?)aSUTN>X2_zqe#0f0Kw~rsD_Iu?COBlTnIC1~Y0|0#gdMj$aROMV#~&-Mtp6Nc zE7`Qp4m8^UfgzLQ#g%nnh_}Jyx{)@u$0L1`htoe^sz}r~yf)h-pW=f==?Z{tqVj+u z2d=&I!MWzjo(4*73&{kgX&J41scv$d`oQQ4Gh8GRJ6K#t-qdE7MlWI~m>KT~u{tOd z_80T@^)5p2*~0krDvWC(lmuCEr>9{yf5rR(swpi}#l^dHtJ~eA_1n0s%ZR|s z!mn9EX&i>1GzJIAnud49ea*cBW7OsGw%0Fhk--;Ej%xyMcw=K-xVUMQL)&uky_UfK zo?LL^sA3$a6J&%*qVyG2I>=@1Gl}sI$ONs&5@j${>fj(cT(Htf6*9`;`^Pk-I5L2A zwl+oh5hY*Zit(SKD%6gzteZmm&&US=*eq2{ABLLgsjjRG=m^)wb?=nqL1QLd#D}k& zg0I7uPp?@3QLS5)xZ3{Rtiq{K76jJi_ahTxpXDjm$I!8tD=Q#?U3O`%^tdgQkfB0Y zk*+!?GncynKCgE`VhXx6-;MmJ>ua`rL}LPDNb{QFdLKj}hH*fdbDQHbM=0g8 zB@7QO$d?a|n?bscJk)_eW0t29<%q3&!>^G_xR&BY|d< z>Ix{E?I$4Pm5sVL!Le zf{iuF2bUrfI|AZN+dL{Bd_bE=YCXwUI<<_BX!9|_t1eLZ6~S%j5bGa; zn|y`V&8T>wV?K!(3ggQV+ucaz{P=PYjK4r$9hZfWyurt(yFj5vYQ^;m>N{I)MXBcn z3&4o3B7IJ!<#pTO9I&EVZ?}@$;1}*f7jzC2Aq zWMS+;x~v;fOv{yVnE6cvm+C|iXn+SAVTLnifg-+x^}Xu@iwA%W(Y=Ji@Jrfur1a`Zco?1YIyllg~lOfH^#wFuzYUGms>#u0-&9ZP5<>7Nrd7nD|Cc+n+Y?4_ z3Zg5EDi0uNPF+I%Se`PfCy4LFq|~Kjmzp$fzy}2!ciK6B3DX#Oyh6wpFgfdDYFhP* z8WSbXuYgIk1|?;A)=G!3D>}G_42ykeNrkJkW}0>Q{$(?Xq%2h{3SjK#L)|a&ne`US zRhPQNpd&Vs&g|%=vGpGb2|k?-xVkT*b26(e;L#8xskt^uq(PJ2C8 zK7~G9nyOhtD;aWLP~BPNJfHG0eT2!r{^d6O%%afpre}MB z@>pF(=IrqfV*5{99PoT#&B6?*>O%f*YM+j-*&J9>tF5S4dA5uQ&=?fQ3#XTDcj8sU zooMP@P6f@KH(zi8Wj0_wBPwF0xVEkXoZbD{@VaEv#Ng$dr6?m86gg>R5D96kS8u-A z5|)t-3j@U~MLBaTH@#$nByrd3{P_56d#ku~vka=ncxBcSMjoiN;ToVra&Y7%L`!D2 z_vf* zTUz^%HkX=};WbvC^-8|trOJ&A-!Ct%=`Mc{$R0L2z0?Z0IIwG{t19Fr5>2mQ@D}H1 zbq}JdTvp0Ln@X1}h6i}bl_eY$E-%4B*{1U9N}CX*p(lZ3wUt(lh{Gp_yMz@Zv$hCf zcV2Db99{|ej{Ng1wj?36NL_7X{h|9aS5+8UqpmJ@&uX`mLrF=}JVFv`no%0u`xMYxNbpGA=`kO;wb6=&UuMXEU3 zadQm{t%c|yP0N=KtKK-Kd1js&zj?iaQPZMIwSv-;0n+=*`m8P>q~x9gWZts$a%Bl^ zB41R3h2lE;9Qi<)h&eeQt1E=$r%EulUWG{Q97(Jg@9`_~KY&fhon2mDGw!|L6WLsc z2cb803d=nA_OiMLN~lKTYb&ZuOg}Pl^NOv|5c%~NIl5aK=)5<#GTVJ`;aj2BQ{&%< zROOOk^)oO^Fl{OR{q|Gwb(M$$g=JLGa|Rwi%w5(_ zb2f`lp#j@~E|$>%xmuX`@++eNqh7UyLY?$jGNQ*YM;%!(c!P3K7+j(*4j1Q?7v%u~ zh93))IONqV37|*LsjyyTbK5G5)jGaH)>&1nh@;Y8C4dzkFt*a8#unBZtu4{E#m=K{ zW6Lka6R-5nW>)FZ405`PmRR0EjI{ElC5W!ef*!n!J1NqLg;;P)S~&f6lX7C+65YLX zqU0%TtFn*D&y_3F9Wn20ILX7*6+spe$Z7$zYH?wK+;>UU+T712kCWrE5A}hs0=@s` z+8o#Z3<=6Zr2KwLRlJqWW~~bldr$BxSD<+t0@o3bOT|WQ&x9-mBdb4aAiRTgu~B1~ z9pg=nNwvQaMV+rp%X8Kc9?-B*#i5a_b0AMISzy?8(2>F;OG{mHb%^UCuQ)QyJ0!Q& z=8P4aP@AZucS1*4U2VBgNtKJLiqC7a$?D9UA^w&CHDNW}a@~eJaC07;m>C1Ns$s_5 z_OEefEEiVMGbC1cAPj=gbu-M`v8qsOsC|W#VYx4|+x{$aGzwZ93=BRUh8B9NW@G6> z2vBko_@8%)(3~{Bd^s$CVL4JG5nA6V5BR%lSOgH=o33%66{Y_rSlbI41t}pwO$Bo#t)6o2rZt(9%??^j(U1ghNy83 zQH_>oXVoYYmg2K#LkbdlL5)>}x$2y#A7nWZ%QPum=K}_FVI?pp{kpq#Ka|(-RTLoWtQF}|uZ4h!pM$cj~$R>L;Zr`J|d#o;&8ofg9wA!w9*ttLY`6diD| zC2)2O{Q%;s3;7&IXHZpihJ&lCNG4jdV&Z}88sg$yQsbi9Oe`v(vO-{R!Byl22}W zWsVultsE440)%o;2q+dW#|OmjSHQRyHA-AjpK}PLt0Cl-t=LX_(m&&R!f>V86EKcu z!atQ>pg7jL|}ivtDoECja6?D3bDmS=OxB#&a7h#?oKve zuWM*aZ){#($7$XUMEA5H5(&?CJzOW73&Eg)gnRbkHiGqQ`D_?#Caa%E0F*h*!P^RW+6sBv{fVoFkf>nRKeXE65xe1ZYC&S~ zhSr)8KU#7wH1i)?5?Ota>vWcY$SGb5zo9vVW^@-r7nmW&knMB{QUCoqS6XVKWh)^A zibLIYgF8`k!f<2sciqcZD-#MOmOELh7Tdhcr3Cy4629EWg`7zrfIm@`fr>rfa-4x0B_b6g=H5w z6^%yRb^rA3~Uxeyp&n;ZRQo&omr@Pbsm`5&dlmL{sfdv~GV! zu)M(Yn5+)4ns%mi4uko9?s;)`h8j!*(4X7<2l1fsb?GLAUltRh6P_Xps{^x|Zd#5X zvZ3y(V)C3l0gLA0c*yXe0c(~+HSKUj;n*tdU!6}B9;kH)X3MIez+j0<6QanKJm32g z*_qNMbg30-c`2-j$;+yXI#il(YAzTqmclY}fQJ<3wA01>9{ko@mMlzMsmz=d4O(8Y?Q$NKn$Zy4tcsHy zs=a)EMiocS)}1bDk-zO3=s=DNU~`@b8j$d491<8- z41O$~V6g6(h#}4AD>yOmYTL#4ui8(^vyGFWObgT%mJ#i@se5al5MuaLPdky81%prA zWIt63t-_=gazXfncRNp&R%=EjQENZOW5|5=MF;bj3XwxOWnPWQu_$Qv_LaHEf88zi$e+xw%SxP7^uv15B2f zelvm{>U1QPfZaF|>O6iAA`63^rK8K>|2j!l}W+xo{gI7U*}~C#WKlO@`z@E?t7cMp__N>xuWg0*L>)km_Ov zB``1E2QMZ!7LwBV%DI3+ecd~pe$-F{g|h)u;^d>bxw>^T-f$qXN3M9oayv8NrGO?e zmG7U^9WrTs$x+z@Va!h1IZgpR({n>ehtw^e8TSI=L-v8v#aQREp13#>lYY;rb9x4p zu~_#qo|Y`a64_oNk_Tcn!*>V)^o|MbC&P1yH8rYkVFbu@1nFSg44UneOrpG#HyjR# z;hC6ud=ZaXYP&(k{(E`G1SAF#3S=9eqdI6Oe|gw;J{>I-Y82C;hau5lKsj8B71pu>@rgR**)Ag~17MNqwl94#%wj>Fv3S^}3B&vMxfM zFx~a#xtJ78g=n$~D_6jnL$52lFb2lwVuJNXF4Gt$!^^QAA(!c_(g(LApz=sK>WTq5 zgB6z6C+&7Azc35`gek=uI{bV~6oi#9owjZ;P!m^WA8g)?JfhaObY*Gp>xPrqx8c&T zrpkL;GlQExtW6tSchcQGz%<{8567i+P4lG}y89do>JYd^FrNk_f?8F6-8p+r=i-RD zGMA>C%%_mDy3IIQh=X32aw+#Us2?z1iuo)!8`6pg327Tp{m@Ath#Ag|lyBnSg9ueZ zG5DJYb~WA!<##XOb_v8GkUFi2xmilX{+~?uD7lB#p>({lq{E)LRJxkBBezMfHv~3GF?GwI zOYOCf!tqi)?S)7HMRm*zit3mqRy^LZ7J3W4K~g;{`?churDu9)(+Op(Et6e5F-3yGKpPCDU{%`Hz7S9KTmUVyWjU1y$Vuo-0VNuK zMcK+h;sOTk4JUe^i6%4#PgEe#6Z5NmY5?Wp(vs#YiHXjQl%aU*4^vNh0< zD$?&ApaEF71dt;sEt!;;M3uNV_T3naCZTE1#G5??D%s)?qr73lA6Z4#8aL$zR=ZyK zb?SNsj!>~7b^1x@A=V2+SKP`6VbA6Cf=h9L5|OO3n+eEs`2gV*2&48{u@zm~4p9o; zyWTmkJ>&ggaAwtgIl>8YzPudG%zVkY;-Bu?vFb6Ia|Fte?)!bO~AfFA`dBE=KyYdJw&0Y-!K-&@{JQ;fF?u@tPv+jWUx zgbSx+-(i1(K}}9nPlqh7Pz{vwlQ(j305Q(t;;cN<8((%4a z)NHiIs+S@mIl9=t>56pwK?x40R1bxq-XW&XrYHvhV~TqB5*Sdo_{+as(NCjyR-`|&N5s^^YPJ4Cq|4?p4>W*^e z;mEo~v7Yf{xhhFpg+-~Qpbm4B65`CY?;g1sCv$V)w4u|*r&`2ITj>aZ+-ruj8~2+} zhC}9)WtU+;IlN@bbo-;k1yv28;)h*24{QpZ%QWPz!c12oG@1mzWqF?)HMbvcDQCv9 z=@*=eg!#7|2P`ZXO`{^^EiNI-P(wM~FyNN9{G;BiwAEMclL3tkv^n+z5f>%d3*(8F zyp>;vGlL=Q=^6@JC7t6W8d=0SKaLTghcWpG5|e5iXL9i=e7d}q$;(@1x2kjHAst6v zd24vkl;{|~zfa!!ol)a=<*mseZS@1Q z5iR$h08o5u@Z{!$ABJ8Mz1}gR??r`!JaNK>_LuJts%Hm9mvJ_X{yg@?hIk=6=s5!_ z?K7LAIg|yJ;5Tp0ZE|jp3`@sd)cQkGDC(v@s5%_iKF1UadovG!Ow;!Oat8PH5vM}F zknH9<9?7jwB7~e1ct5&k#}nF6WKq;a_Aoq$bUmnI1LPIvFsnT z-Q~cbD&~TNx(JZ}!3T03%7q5oB9m#~5QeriXp8UI4S78GOV36m`9q{UnjCD2V~>2I z^u!jV=9Ay!Ko%`>_*lBT$kQV`!#{XR06Oj~1$fj!ar>)0lu!KqW{x9UqIZ0Eh@-AV zf4a+|u0`SJdwakWe*|Nt|HL5af)fB(ykE4A4E6?9!P}c8sc&#&1jAp1Q~eX8lzVVw zgmmlf7Gi7;gA3A{6uQselG_vpJ-^}Q^jdV-_*iUDCa>n8EOQSE8bt-`zq=xp}-Lr_jvc|yh9j;-8Ij_ z9LtQS$6X$m{dD-X)=eJ!%x{7ycW7k9ejmxf?3YCIw?3Iq^7^;{n65>3H}d@sPW9?)YYTL?<9?gb~L#uRRyOyN4Jw-A~^Z-YA#Ln02*J zPYQxyQ&ZaHM@an00N{Y)2x=Aspvv>SLSqjdEO#jT?~suIio2wz=B0;5d5N+=38{p< zB!Wt7pcEa{9?K}^WARb@F^tUPn+HcsRBCy2q$O5IM!FVNA36*=3!sDt4<0n|g&U)z zqY@o?s8Uwwu$QjDwR*Vw7ze{l#eQsHx0T=vHr!mdg3os-`+^%Y-)=)@3<2CbTdAu( z;<{WdyrF2^eE6XezD?OPKAjb^2Q{#1e>yoXx;tASJ0BWtGgL@At8pVo4q`2%XoT*Z z9~*^LtVfxV&S&C>^vA>v<4pe<>pqUKvA-p>IR%9qT<7%1naRsp*I7R5 zMG!&*lgQ)YT?FM6N*cT8pBzT$i2e+MQs#J!q~HG@W2f(<@~}iwsN2em1?=!9%OA{R zM^rvs9L*_o^iEQSBpTgyxBN6dGU6e>ltoS({t+x`Iq7O|Dp^qY6Qk(LLYBdAC}u?r z^I-3;BWgVK+4o0gZLIoFChp)5(BF44!czy^UChb}Ul^-!qJ6yovJK3od*{n>Y zKA>z8f0r-Unm3K2DE6qD*vzST=-CvyI|$)L_`1#L7^JE3g3uA+4JwVu&U1YeBO{XY zdODJmKB_~fh(^5sOA^|BP8^Nmo>hpvE>o$6Cd!nI4F^jpeakMKJhJ!QS97y_)S@SI zvEp8x|D)MGGy0_G{E;JjKi&pWD|*h8I#T>Q;h|X=bV?^k{g?~dVXuWj*P@S{IAP{&Ei6 z0sQu-b0Ds~?bJ-5O(C7@`^7bZ7WpvYzIBgp(Z5Nc3w0U)Q|(vNw)xA;2s*o|wuE!(%p#Qq2ty zGh3L74@2gCi*CY)Wrp!_Gc!6jI)lA^>0t!!!_nJMPoq@7dhMGpb8a4(!OIc_TNoJ7 zIjKC1y>bzo(GoWP0X)PIqf^-1 zmoA{7zjFGmg1-IQHw)_AJTT=HG>?KFLqThWysB}v;k*o4QN&sQ03Pc{tNx;>C8tOw zYzOfBrJ}y={M(D_Tzvq)w~G44-A+-Zuv66WLLRO`{>{?n^KX?l|7K}xC~Y34tzl=h zhP{31JWBg3r{5~=+pm4Iw9d@~@GAupLn!STr&;sZD;KaC9md8#fQS0ygE@G553i_LkL>+MzapRS z_V%TRP|#mF{Z>KWe(jqDb#5M*bPAe9$wDH&r96b)a^5*EVB;UaQ~mM$FO~F=Q_@4& z4&e7oC4JlZx0lqp`T%}!mGq6fos#P58zmjezE#p}_N|g;-z;ebCC#Fw73_>wu(uB} zEm-DPPQO*sw_p2aNu8Sq0QN!j!y6ST)v_Y`Z+QrZ)w~Gt11Qu0p6ibf{Zd)cJ^bZ7 zwrKEQF6-OQzrC!^)d%oiee(jqjb#5L&9}Nr$cwbEvP|T66V0d!^COOnLKY)k&@&4P+#y_39d%<{;VQVYKI*|X&*ib59`#~7 z#0_Cv8}(r;aw0IxgDSjtXD5fbVHqI!O>UG)rSYlJJ}6k$NAia`EZnY3|94S=S&3BY z4=6M|3CJ<^UKl={l^Ft$2%|wPBVU1Lc_asopVtrJTRBJ3MEOWPTR1$f)9(#_$6Zz^OlNTm>L=ed#% z&MTgcaCKat3hfXH#VyJmDdRK$NvA~BblyCyj1WU%MmfV`l|fF{0NH7CrOAUWHeTXX znND9Hg|>f~v$dy|?x(RsH&y{7oHF|0F`Pfbb@8(CN*h5>xb~4}z;BW^Yn;k(Hk)q~ zs@jB;X^PVo%1=15vP;VqSpRTxhBI)LAlhK7aW;duag6IS;0db38aJ8$|LJ=3I7zO% zPVo2Q$~)p^Mjn+JSs9V{QPq`EcV$&|SLklZN2e{>LNen{31Z10G-uwcnT3YDvcA z=MyhqygT0Ud%x@bUR!ctQtNY|ITXp=cnV+eQB|hz;~T6iZq@zcFMu~ByHclA1lH0j z17B@bmOxV1PGLZRI@MRD$>*wQJcj3USi*hC(bv1wYC>6~wGJez)!K%$)Pb{!&AGL_ z2hqZ*)9}@SleCI%k6H?tPp$0+24WR>+2hb0fhtJxx-Xkc`XVFy)4X z`rh+dl3UxIi#sre)Li$wuz@nfJf8k99jQtGSB&*>4= ze~L6gxs%iu0l!aDkpi3^MoFjrKp!;Fo+BN8>2_^;8}-9&=RZyNwhh|1?IP{xmx^%P zMTPdm?E=xh)wba-ZBilVuEH13(|)Qz`z;GEw=L!g)0NTw?fE=Oo*-(Sg7q*5*&o=Bb?Z-G8EWSTbDU=-*!Lp6!H}A+^a-cLxquut!inAZEUUv4KYszpw z+A`O2Wk;(ll%Zk*?q8-nQH|-ITuGOG6`xy4iHM*d&x~({{+& zZ+-C`-#2D^IIGF`$X9~SzAX||m)fJ>^8%nnWz`E4x3HYaU)RyP$ zr)6jV)FW)LhuuVSclb-=ovbq0h1IeZ)y2`c%gdM6?MEDa!xa_q&F45cSrp4nlxmA zF$J7Gd(GWnYz|a+ztk@MZh(!ygxcLDcOO>KHkM|4VZM)m_UeG4OLz)E*?wuTPkWc$ zRlY9|PMd#)QqctL^7~=?C5*M@5}?6Zb8#etItkEzMQS?i`@hOy!)S%}8){>^clN!c z)TeuQglMV8$wDHI&aJLiIC0F(N~;WnqkmTFtgHkvlcW;!4iXK|k^2Vdf7Q`p$}X!6 zxz(iobPcoQrDt#+2|dqo1aS|hV#)iWRhsT~VDJ(Xwknte>H72!ar*)Rt&!LOXa=XXKSydK}E0weUjmnKByp(5hiufMa!jO1!W_o zF3@580~__Fm@%xxqCOM;$UHze`}5Z*qR^mW1;s{@;qI`zVz<#??2x3USAD7Y5Y3iQ zLA!~7C^8A`{-oVVf7{I_--(t&L4qO(eWO1AirqX8O#-5*AT~&qdr)GB21azHB=uGx z>H&F8EI2TL(Q;P*cnQ4+OQ<+mCwwJ85PJoq^;za0MV>-cq90z(Qa~0l3SmF`N)b|Y zw^F zE7_%JyfJxufM7?ri^j%VtvaclCLyJ@kI>Sj#ZNQ+SvS) zQ%g5jGQt%RUVtN3*NvqN>=uPb=b-|kpcy{yALxoI#aMP4gpUWSp?flrO~C}i5Q1{T zR5j?$F?-3sEn>Im%~6aZLM1_B0wy4CKH~Idd>9s4U@zOk1Q_k0OJl9Ng0h!zpiQ-w z$2;vcyn^9%G9d%J1Yn8zBfyHATE6)W^Y0{w0U(jX7>V!zNo>Y$M$KmmDk{*8^aZ59F)3e3 zgw>|V$coKGwOY$?J1xjg)Yclj?R7X&d-=wP&A#vC!^9vhi$Q`DO|9MhKru)nya4CB z43Y>HgEarzC7quagOmihjDC{cQvf@KHRt>*0|mMPd+E~0m(i{YCO5zkdSP8Et7E1$PBLYNo!%)nu*ti=b&s!;{59oJ#ds$u{O3|?k>TJEjy3Os) zisUTgZM!1R_BP~7WzzV-bt4Lza2-1&Xv57-AeDTtA{S9TXt+ucgx&5cQehX$M*FPZuJlenqCrvwTLTpKpi;;>t810nesvAf zW`&9-v$x}63d~M>%x&ie6-f_t*r`3m&PX02M9M)WsoNFY_NcIYszD5vyZSL3{rcy z@VqAj0UfAs17l#bh&0w?Pxqc)7LG9=f%1yLXzSFRCs;F7-~| zUTS;f(8f8XGL~_^_e^fsr}}PlO4RqVQ*3@)Z6DLJx(eD62|I4vAD`N-wn1DpHz4%_ z$6-uomTK+c>H2zoAQ&Ib{z2lU!FyF``a#j8(?Z7KdUc~c-K5dx?oqQjV;yi%xP&dq zVVm`K&x26lqt^OJ=`5|ZT><2vYu0M}XCURtEc>@SYJ@9COG{l^Qp*!C9h3>tsNJfx zMxb_=JgJj+ntf2MwtI58<$&d3tqkRsEC#Jwg;U0` zv>fy@kR@n(C<8|Q^;Qd#v|Jk+${(#uqXY0B%4K1O#D%Zba_EuF)q0(jVF>Rc+v=4| z>jrk!B%M)5XYl2%)fSvN9lf~>-<*WrcH!%+z^PW@?3LgME$7;4hf|!nI1Gi!%8Hkr z-X7>;Hhvc5z9&8hRCf)SF!2Lv1R|Dne!#w-3G#!cCGmrUl68!L9Nw#?C_iXf4LD}Q z-)SWpqn*0Z=$)bQ#Uuix{(2>beauOn@)P&_F zT6c;x*pbJuP>l+TUt^$?PmfRNWCfMY>EyB}B-|ub{1Y;{HkJXz>0rM|7)a0%2k*7v z$qO0VLEBO2Ae_eSHAf8{V(%19&)iozN>XsFy#I?fklJ)|c!rJ6IGJ?+ObQb`-t^C` zW|C}34q%PP*4O8(@fzK9omL%KLo z-at=19qwPULj6nWARyIypfB**K<_kRK7C$0`Tu?On3OuRH8@mpjfNB6DBCsYibf5jci>_wdWnh))|0+xO|M*9=8{Z19-UI|Be- zvOQ5sWbLvM^Qink44)RF&i-EfFgn@U)k~!jE|KZ)-+nocQ|Nn)qT4llIH1+aVckDd zlEZ!og;Z>e3qdL7ay87GM#Wo1H;=j^8vd@tbbDZPCmdN1=QRk?q(Yed!lQ5Nijvxi2lHlnS|Jnn;O zy1ykEYIpyF62IIAa=b5rB#eanlzPUMSWm**z3WgqK6Vt)(5J9P$FKE1P}M^ots5-r z3|McUU+a2z%5t6P0BM%uF68%g=X)s@^kC%_7RSvoNfV#`Os$bKVhioT{@M8Dy4j^p z{V?Igv;k$mMVBi4-YNL5coLqZ@kMpA-@Lfgy{vc^bIy=M?omC3b3ExGz5OcG&!DYc7z0zhWcGuGBi)HgSYB3lp!|i3J&lzaeJ`~sN-!_>vb+Y z0!HatU4;0j>!#8pC|1b(`vT>QimYy38|^3J&VG`6`{P9G`d?cI8yPf$`*Q1C}e z64>8?t*wy+8GUF2JLyJbZ4HafqpGHQ!hY9Csfe90{u0T}-CgWGLF~}v+zw3>uCZCD zgBj}I$`BC_xj1x(8~V}_a0WuXAA!aty}uNKu975;ZYA7T7R2R=jCH9dxXBsjQ~aB= zRGlxN#A&ehsYLfy$-Q+wPTwaiG-a40IY44uR9GFSw>gza&EzfRKD&Q9Hv9t1)pY()cqfFru9?qVMa_+OWM z%FZEF`mh(?s!js1?i`$kXz-S--GdOJWskrpZlFT3bIkXUj=f^L_iacC+0A_Dx}o7p z&jeu6#dC^t7)Ss>edwiUAe0Ct0KqOAs&g1gpkF0!R;!ZV#cFe6iD`;qXud#Zb6<7H zF%o;xfCE$tjuTJdUKY%=E#!}XO*9$VTWc7TmTREhyYU|B<68oLm%#v+xjZ}6;8NUCNOFT(n~VnM?~@*=GTr5~w)V-}G{kycI_Me2)+A7L{+OWkv=ya*^L!wB^a zXz5BWZ5s~!_kw9_;&Z`FVu?2?*o>YfNhrBJ@_CXXAd}}@+?d#|?)VBxwsX!vO2{qn zS9ZVIGw=@r$uQb^@(pV#pZ5(3{4w81x8ew)U&2LSMk~SLmr^bX=p8 zG6A_dX|o46W1`xP1#^h?fdpA|3=Ax1PLb0>sTpIebK5sKav$WUpX6^+ZnG?spg81F zKH?iTijG!Ht0$xOTXSLeO~s>%8#Hmp(CSl98`yMENOC~=;K-oy8&@g=+8P+G zjO8e;1%$M+cx~q3*pY$pV3_`5u`n=z=at5>4j}u$VBN?@x#IZHQV-pJRH)zs>}x}V zZ7f!L4q6W7xRPURJC&h>LxGp&QeUUx{hLQpxNp>7vbh0d8q%IhxjX{!Q&X}Z-M?;N zC?G`83k96w9@ zZ*0UbH@kW~+{LvF(y0NG-WMjmQ!5q+boY^68GCHI9@CsR7y~_~jj8l)c}5G%{rKB) zO+-T(>sX8v!era^4){A%QO&p`?tl$z%*w$!@ zz5eCyJCp7Rurdv0w}hY(Uj2t|sVE6dJ2{W6N0X(_KdrXVW4SzFG#rd5=dOE{{oZcs4vT(8CR5 z$P5REwWGw*&~zA!13CP5_!!#zw8F^+@vLb--pUa^ueB zrb=D`O2cbQVPiO)b{lB5fn=%U?X22U8JD`%b5}ykDMhWI~4D)-tzs35-?a~^q zQKE<20I#RQ1KoKjG%(TvCS$3jg7c-+Sd&I?xwHCs5a1U}at`X9pAYwpH0Xjy1rXOX z->8QHuLS@X(B7%ZzL68ef&l9^2^7b}HmVR{{|Rt=o_b6N2yaOeio<3J&2SVw)2-%A z54$%+aVsmJFha9JyxljDEj)F|GwkNf4%eI5@$MohUM#kx_P>?@J?6L%a&PenZI2T9eoFUfLplY3h|Bh%rbz+5FR0MEf{bpt7F@)7^UIAzdnly0Hb6Uy zkqHvv`;aW8b&3Cl!(=~Wa&ez)5 zCS&MmehxyOCh9i$L!?f*O2t;7i~$H0;6(6AP{xI07;qLB=etU;ShDCT4I)dyK#4;| zJTJ(u@TQelrbUg%^Q$}_=@-*lzXB>B)>hCB1w!5IT?CNPGtu1^eJ9MOguS( z$V_s{T6T)o5}p>GCY}bKx>JM{r6>)~SCURY#N0?Hk@PTWaNZX1jwkV4a&qap;??;bFo3gWgK8tuIQyM3>Di@1R;`<=9`N$CYu+a_*j;* zPTXk}oMbVh4HXIhPd$AusCtQeAaToff1I76Q1{1EiqCoA1mu#hu3e@j9AWq-Mh!?w z>8~OXr8(2YtJhoo|Yh6OrMIcOI3>ewS_|ez`h6U;2Bj#*Gz88=9ffiwd!WQmHg3kuoc( z{RiZsD5+ZZ)$Nt?82g!zh9+rnDpT!&2Nnxb8B#~IfYr<8F?N@7MGDN!#7q5HaKw!9 zi)JMAJHOC7g}bRDUv zAVe*y&ZNVzIaW|0`ETpkGRMv&NwXKX0o4XCe#kkhD*yIVt%Hg2{-YK6KDCF% zb~sAmD}JsGOKC12FL5XHTc7u;4PBWrQ4-VrHXEKJLsYZ zY-P9?O-@{5(+HF!9@tpKS5y0UY+_M(a*L4bL6yPAvk=7Wc=a`mbFuP3(!Bp6&328M zs?<2+Ead+r8y2?Yoa3;!Q1EDLWBf%l2i>x9oWpTXHjP#na}x=s4XT@4&Ijz@!)c-v zc0i-cBunlx8&6C)5%E@#yOQBUuHZ4LK|t0H7ITp7%c}}q@8XQK(k1={hdJuj81}bh zjFOeZq_rn5N?UZ%ZU|pr@ic|JI_JS+12fb4o+MOIStakeSP*i{M#vd?OYVvIP-LXc zv!RT|oBkf861kpa&C}-LYv!Rd7ti&bKu>Dt!2^j1ZRLn%qh>r%o4ENV@}dUopjdDQ zGKBw9vw)gA))uNbSS)ZCUtDxq4zJ?h#uIye0E%emgV62nl%c}H@+huZP+aCL=Eq?T zrQ{1tlu|}+#4T(59ic8k6|!a*kheJ_m(@Tv;G#m8i3T`mKs-NM*GD+w2A-uyU|nD& zq;kk%fCcRz4&X59N&)5$5FZYArF@}_Y>LAU>;ja6@>%9UkMS~_ zCX(NFnBhswulxt5??R!Ntt`LoN=?vTY{S{!;tXPbP%iewlM?L;_oO|$f^0U5OrzQP zl1PkVt7Z5Qa8QC|hDEe#PwqnEAz7%$#uLkfPk-}Wd>V?e@*T8F!bdHY;Ik#PQ#kv= zS#DQE>z67UaPi)$R8Y>!HoUM~5^jpxtQC~L;wzZXC~f|NTJFc`qXj3OM#uuCK1R!dlH*7JQ5A!@Dbr>=E;losFvE zd?c}olQR6SwCjC{#*K}2MRka|soiY_I7f9&bpb{0>U5OAh^p;&pU6o=!Ei&KUO`2B zN^l5F7A?S*v%RT=CaDK;j%QurcQ)I(5p_;0VV{;(w;`)ofohD@W7&vLwKZt-@it^s z?xIVbtP<_f()!+jnyY!vpnDs0skX6+QYYo+nhm^4R`dbxG(C+h>jme-%R5yUGANJa zJ`_HC1db>$2_E!wkseh~J19Lc$qGd`VCHhFZ_(h5kshn>l>2mF<%7y`U{=7Eu$z+| zezln`jaerzdxK21Aonci+Bryn)Cx`@IWo8SGs9d;9_FN>)U0mxrD{o@p4WDlbONW;8^vyu#~7}hxCuG89uv$Zcz=Nf09Qk3Z$Qfy~) z_=+gcVu-9fI)BPKiv@Z5;c7NJ+F}s0+4vp^lYr?9ji#1mc~liFM4Tc5;|p<%=*7LY zHF?kxv=|^0BzDk5ZRLUTLNOiA&dvaGL~t8hRZNDKx{p51$#O5-XuB@0XMR!na>MkU z{Dzzi^cERE&EEF}GBfvIZaA>HdX@nbSYPW>Xu8eZY-XSNNj^|N+xTvwM0$Fu*vnk=|=Hd$+#g>F5O09HCfa-)DE z^nzDkiWR13f!(M6)T_7Rg<*XuihyR;Kat=hzA&h>Pd^QkcP_&jU{rlzX$g;|PPU^`=c8WkWtxABSh>s*eF;h?&%zZ6CQH%)#5VzOzc8&r(E8o>FZcQ6Z|! zW8#~?x0L?VexttapGa~#SS~`3@@n9ORdyPLA@Q%cciVw}M_c{j%j!W{8CGDrv_1Kw ze&gMS-+0p2{6?mI-RL)pC9uZ=a=#G|`L&eRZ&>i(76_rMDRbT3O#lV<5=WZ+(`rTg z8^~)zf4m1HKC?yGqpACi6bf>J@_>}y00N$d=D3YcQ^S1gw6q@FB@NBoSk{IdOVa9` z(#F8mSF|ZdFW}n62Tuih0V~2^vZDN@jhHxd3M(ibT^v-k394GV3v7SXCa3KL!1Q3X4><3RR<%Uu^2J*NAOjeH&p&3b8c z06_cssw}(IehA?dm|SJfq#K>WhJ|9DUO zD3?QpZ9FcDT|HKMspR!uBZz=?JR4}qrr%hw+x;RXtjUk7UM9e+hL@4kmX{F-m**&6 zRRdkz%@}@NN`sfmynwys*TLlr1J{Z6Gi;K9%0cb@Fv1f&lD6E8fqO6=OB%@9U;#O5 z{ENfRhDDawY1edY6=?ukV_0Ms{%t%l5g=;o-3$urZq=AHBFTi8VjjB>ca|KXca%xC zDSIA^1L@N|Kq8rYjQ#O*vIoo!J}U1W42`s}3ro)ArAcV$lMi zjR@$8YUG>mn1tB2Rg}}QRVakyQE*d5-En!AK{2fy;x=RwUs3C6l4y6%M$^RC;EBC9 z;2@{82g}P5k7?run-ucM8=>Z|s)}3%UkXe;)IN+%>(D{ronirBn}_yagg0BF)Rv7z zuswt1Koyavh??*paGRpluMIk|l{Pg*T}_8iPvw!Z?RbEi7oCbKez&u+{sV5y23CSb2(`!a7V42vK(27^y z4jiTJo#ZY9DegAofW;zf8ClObgv7>ZDby@6;J?6N1AY_lW)8996)>~iJ;{!ccE#&9 zqFLlQC=+5MP!2?;B~*$hcJu9^q_le{xvHqtZ+1#mBxqGDJt^RRM0}!M9Uv#r1shN7 z=G#G4Y4=ZZB5kwgxy-3nMk&$aN)5StPmA1E#bwPJaChOc@x+7&Cjq6CfF7ouc*)~L zShJ=8->*QOhqbm5c%}lGBtE(sYSzR@yZ9P+ZGF_V=K1kz;|WIx`H1@^ntp$sc=wM& z!zN}^x(&N?!zR5AM>=Y(nR>k3kT?one zo8pFh2m<-t;J3P2$+Li{ZK7=#TiI2II@>j1c-GqBVrRXEt!}qd)26k!>zcCnMj)7b zHDqPO^zP|e5C~v4?-GrvzOgwY>Yc}jQKPyBe1jKfwOS4IN1l3*p@!WW7??mi9BQoA zhE1?K+BLtKUIaIy|LKlZi%o#&)pVCNwikQitPBurlt|l)LXj2>Uw3aNPS|jg+$K(` z%!uDIWeYnF>4Sc2a~Eyy3@$F=oGMi}~FYJ-E$=?rz2sN+a+ge$mxUIdmL-pF6 z=>HTr+hKbD+rf%D%0rLvC3<@*#1~obTy+PT;@3T@gIXor+_T>QG#fH2%jG>w^2SmM z%rE{Fm+DdvJ80#DSR>%?Kd`$h`N-5Mj0x)PvgFLzK6JghpQ+}Hz{6EG{d9QNtU_g} zC{0?`O`vXZ*8dFDey7>s?9=$*=303`ouV`xKDJv}m$+2j1BOPER%X-vEcIDyy*6P> zIUsq>o$8P>Ytzpxx5b5jMDAyXN<{xQp-J!(29GJhWA0I3;y+< zxHn0r`yhVQ=G^z??Nxps#@Om~?*qmuI=bjkU~0o;VC%F!xCquRtY$hm@a3xd;360! zgNvs6(`Ctx-*e@XCA)8JEdnEKiSunOy9TEy@Wry=XjdILZGqwnEqEx1!P&&djdPlC zghf3Z#D#Mj^J5uW?e~^d8U~H-lEjRp#_zr3vK$OhiAD?*bpK*Jou_*%!Q7xF;Xj=7 zTT*XHNPFjqrk)!tRSXe1v6nbr*vG1=Kk-}XXrBOgm*NO&TAoWwG2vVEffpu*qzslC z9=>lWB|_~nkW3T0Lhu*Kqva$*vq-v}7M`&~r!w$}d)<~7;0g3E8iOT>UL8?TW{kBw zSW3&BXs{INU#y?@IlUPIS7n|q+#dhmbl(S5zGV1I!KBu6XmIa6N1CS5!xdcb5i$Bp zl121zL!rsNcjE9EO%!sM;`*euN=Y`3f>okQV|NLi4JJM%{{~o4Ky`)}?h0!3uCAIm zq`$*J#isu4hmxxC`)Lwv9)@7QA#)TQx0Ie5bs8W^WYtxqvCMkez)Y?Mf+M+0@h76v zw7GuFuXG_VkjBkhW0`+|wM|1Tvs7^cTMu*K1R z7Yw%En|OKH$^eyisz+b0%Y*ZbQ&oy%`43~Muv^W%>@3O?(C?20{7OphSK@yF6TR-H z6Fl3M__>k6gA-PQ)dKkfR9ln~`qh4hDopa<>HauQO|E`AbQFfR%9F<=Jw@;ILWg1b zMTSZe*QQUGC!nkNU%1RMg6AZ;8@?OJab&iQB^|@;qR`;#m#-W2BbRXNA~`_=FlhCb z2rfqbOX)4sZ^-oWV3kd2t)J-A6=)Q!LUWe*#G~(thKM{5Vj4)7nh|Kd@aQ~}VbO-h z+x$yi`kqLX$nQeX76ETQ))iB3E2i)%CQ5zoO7>SWah#D2jo8XdhEL~?pakwy@TY#{ zNi@&)f;42R2rS?ql|P9F*?y1)OuZYSd5pmHdprF4pe5Q!B3qA`m&gdtVS3+=g zcOx=+XN(p>iB-NS_s#N5f?2?C4nwsN^|br4FNBXZXO%{3?c))5*%+zRxsnZyL#67! zaUU`x0D3rf6?%qTS}A~`O^mtgT<*QEB1QX&FGIZz_eIB!|E_eJyuTb#$PL{8e;IUF zc91Xrnc>nckN?@Pe9oof9|GLB`sC29{kP_S+o7K}DDncu{xJW*Z%@CCcHET=9b=z+ zDzZQ^|H^;=obwMf`k%MHARPlZa&^dV2`osV14jQISCo@%4F+`kZ|=lC*N0Nc$Ng`R zPiOypzyCQO=X89!>j#f^f6J#ON%dh05phw@&i?Ja|LF{8EgwxdJAHTe%#bXM*x859 ze(N;65qSULho3`eGU)%kjF9k>rr{k)VmEV(ba|2Kl@ers3DXb-&&zvV)SfJ(b%+X)%QL(S^@Xd!APhL-mJzx? zaTt>1$>wVIYLH8-K``R}hI;?893qJJX78cfuUv{Ke=M;+-Fi8sDFWVJA=2z%PZNhV z+hJ*{g7T=4+>N~T4`J!&Dr64b?Gpbe6fV5K#qxFJ4mD4MCXY;i-yZ(uCR|_sSmS1VNY3;lgtSgkJ3Y8 zGfX$S_b_@KC3l1MAfkCrOXx#0wxvRoA-;{$&dRm54r)a6x4=hGbR(kBM7d zlJK+*IHA?bQHmDWcr!}6(btr+r$V#ux}(E-^mYpG5y=ZCAM|vKdwQIYP6a)^)|EWns~j0ofGK@Ml_2IG zn@HJYSASRF$TVyWA7paFC>zHdgLn0`If^v6F^b%MNDBPiSfxNeM#d8h9>AZG@L(O) zqvRUtoh0~>x|!$-`$|xv>goY-o)hsdMKeLLtb>Q~TS%P=4ZDQGM>^-{0Q-8>j`JRl zq0A@_F^Pum#kGQhe^3Wdg^MQMK7ok++27RV!R^tZmiTin)n=@x ziUY`!I?~huCA^j1ps( z{8;~Av*GvoV)=B#BRiWm!Nr`?-Kr+pfIZ0&~-KpvO&1P)d4h849jqgxb8@4_@y4q z*BM$R&c7~6jZt(tRoOebaLN%B60s@DR*0fP`>dDc&DyA#}~lQ`n@7 z#oN$T@?5GX3{u{A*DqmWNkCEU%D^x)jt4yo1EF z@BEn=gXAa{f_Tm$`n!8&2TCX4>T)!gn=~Uf3YRF@lS*eVef=DB5e#MJq1L(*ni%(I zukzy{=QP%mqmgvw8Wgpz#z`53aI>EMVPHM>)8I$g-ykmAA#AgWZ_M;a_ZKwc@o!Ao zQsgReOYvhE5iU={D!?;*DXC9Ol`DvPO|(!X*|(o1J`^4D1`8b`I^~b-Eb;f5l9+(}*UJ=~h_3&2`wqL7;#Fup%~G)ZjUE8rwL6R08^&mMsMg`*QOFC5XFxV+g%1Np=eKL z?te=!fMgl|>i~6D9x@yp#*!n37Y83shOAkp^nycgHP{@&0wK)gfRIVAyy^I~as2yn zEo}UF{=2iCy?q?tZjZk{j+=nVt2!mxGEpLy4O3!Qmf@lg5*7$JO5hfP#2Sn>diTgZ z3AS$E3zb3!X{_|*yA@vo?;x!5#D=Q)l#oa7O+oF2w@2}u<|Y<`4iruj3tY$&}fxQQ)(s7$^^q%0jKx{2FNlawK&32w6jwG9nY)xV8-ltoWaznwH)`4ra4 zr>J*Z((EVLC;^?_#M%={#ZSbqP6%55Npq}ABM3w|nco^EoRl(5+^QxGX_%-jB!`KI z2?i7s@bte1-zW3Q-%!-?i|%K0$^Qzwe~;Yp!$%qxDM*_tHc-aslMv!T;|5esHsm=J z?Jd8ZA6cOu8boIOK%FFL5TG+Lwa-!?9K2heBs%IbLN}7oHCCznzrq4Ja30BLiR3sT z&5XOMM`^HFIQQPC&Jxg3N~Qb@)ccjaBL!MJ3+e77SnCloC0|!v6SiXH!JDDlt~!rM zIOK((_?KLhhyJ;m)^PQKdF-0^HYt?w9jLxNGrPb;|N5^1fSxuONV-tYhheU3I1i*r z&TSR?-mclgc|UU_r6#-PM?pu14wG7nQz`(`?;5Tyh$s4H+MI##GW+I68h8~jyg=#5 za(_`C<0F%5e~k{3TTalL=#6A*qVvPi4+bZCJk^KT%jBt^3Bg1w1q`E^ww$%?v`~1V zsZmQ24%G0YloWK#c&2X#fS)8X0zVnTrZRA!E_D(TkYNrJ%5%yslLY0K!emPVdjT^G zMiVk%ShbQ_tWAL)WswU)&~O&&O?k9Dhekux!XakCO6FWZX8JPTdSWC z+WB&i0k8R~w@4lZNzz7%mg#x(l|6)BGfHZiJ*c{6T!;$iZ#UQdQZ_N6aNkT|3;_nJ z$*fDv*=U*LIb<;Urj}1|7V5IQgNIo(GS)YjQb`1lWMD@_IdRl~Fa9*(M=247B+p?fF`MzCk~{|4 z!UG~GF#17g=TP|7L~&*82YvKlNTivUGcQAVeOWU9YqihMDM{SS$;00*#h#*oq+%`? zBT&UO1#~rmG@xN~$4dHA3eWp-G$eu>qWTgIB9Vc#7r3edA;S~PAzB?ov3rSxvQH=k zZZ3dwC+`*npGY+?O(YdEjd{Z1JR$Z}(5Y5%ctY~MHo+?;3F=gkrP$#j4X6)GrR)*? z5cA{4KvLAfsrdCVgsB6G4f#e!!3W!aFoZDzZ74-8I62Kx^QxoT_>ZzFW|0)k!yh?` zQuzZasA)$H52d)`cSZC(?>znMGTSPO{O-Y#b|8RiY&cOnfE^lypM)-u#6f-W9}^8g z_&mjTM6k)d__p9Y-*=1uCo{G+UirvsoObz7wn27ZP2`H2cuo+33TGF z)S+tF_%we)NzywB+yB3F%~k${O4-{MFMNlKL z{Ik~e5w$PqJZpiBoKpK|b!YD7tbJW~v-}{DO%Q}=V`9tp6i!=gWJ_&l?s{;Q_RGc$ z;v5i!!aHR$%2DA1mpUYH8H=MPD}qz4FzG4~84Cbf;4v2Pm&;zBNN zxK;p7AqaImD=JKK6fTTq9cFqQc4T<@TbBfoL=^#11p!`V{QM8t5kG%|z|7tE*g-%4 z8|}fL`1v2g+Q{2@&@CL@0?*rR)6ah!jF$Y5+9ACEe`y1K!ZQjIBJlVa=c>Tg$%8`x zVNV{s0SV^N@%^vq1Z-i;_UoN_5)A(9(#ay-4d-T8$^S%G`Hm3ZJ6Hw7faodT5!;^O zJI9X!N;t>IHFU!9@z?R?oJHW$+?`Pb##1P2zdRv~yZ1hPZuxb+!Ts`Y+W*ZjKhRd7 z86V4Pei_?&z%Sd1UyeXbU$)49epALN0tuct_e-l%l1*b^x=a8w*r5(`zYAc8jekkiKw)B7?KAi2xuy@=1P)Vs;l_F1?=fyujB-;c=8V_ z=_CD^KmI#lsdVLd0EiVHSnY}-MI{vVA5G}Ta{1wc|7bA~ed_1zhy6!oNWlzpMqqP2 zYQOA1k8AD!dFq%-+o59(m}>PXJgt<1QjgtHJqiMMmC%*`^QqvlX!y^|snDQEGb&yV zzC-ekgFgnILg}hJzKXlW7+>Jpl&QnweI^A19_Cl~QMMKV=KnJDi>`YZ@+m%~^g}}R z_%O_=_(tmevpYkABUL27$o!8Vc)&xS$B`p#^!!GQq&}0pM|0#o>I6f*VmdlbH$uU2 zI&p}rbjE2O1oA-{e(BdfG3U#mQotPzvgHB9G`(UxF#CiCu1q-4EeftoAPlZd7K#Eq zd<&IPlh7sumeMP-CkO3NboQJY>|sazH(=GWHqF^FC^8Fv4DNTd12Z+KkDgx&hWc4; ze3Sc3_K1b{o(u&0*(K3}a6cOvvb`s9@k@3o5S|AF22ATeZ-@HN2itUm*^E+_LP3vg z!D`l^bk#TSM8DwP1zasN%NbroQAbx3v(Z(xkG3|7FW^`-(CJ|F;~_5*qu^3DFuLjl zgT9#x`Q}a-Q_(b^oiN;_up5nqeaNSuGjOYd;XN0IKErcPE;xg^A#U;Bf#c?+FA{@~N$n_gqS3;|GD`5F+-1$Jj+f(@5uqKwugS4N6 z4`GcHy-R?rd8>!StxyL;;K+Lqba11aZ8C?WFGVHzJ#3Ex# zM;%rPMzLjZc`GhSTz*Um93^6cscT>FV(ETD0!@_gq76g$qQyfTlGVH@*9C#1J28Ex zW6`$s7+^;{(Q5%BA9ikaiMYR6`34B__8oG#`0dl?o>>&U~?eZsd z6gp;^kBz~dEgJ&N#QU(akJq7*Y{Y12boArE5M0Hf5lzRi0}c&G*M~+50lS=HL!+s~ z*^S3JQpJa0)xwEFnJ$*YlShAv|4s~OU91?>0aI_rzj101S_X z=cSw^`_7VL!9ny~3^N|dzFUgDSPZMzMkB-N)F6O{CTcu2hc7l78J#;82ROhJ89u(d zK=4TZMFCm#;o~t8t`0*2vb;9MSsj;)0knuD^D;ziUjL4A_H<|!o&c7ABKlR(5{scd z8&QZCg7ItK(+g02(nsj=7~D8_q*63Zu`PZXCxPQHj}2u&Y$h3_$0=zDyCh$8v?O;l zW1_L;OVN?hRN+{7oG6@>ib7%|Bhb5QMTd{u=E#V(Od1)`U3y^wOwwB{oLB}bXMEHS z`^I7_3_#=?iB9+!uR!@Qlri7X$?Ir%*L|>+5tu_57zYOXFR>`jkNOx+9Kb}ZeEyV* zbV(de7Wr&b!_r5vHoFCXrU-kZ$lQv-Sr$$!g;Sc=lP8(NOCku2Ohcqx%uanwZ!{#b zz&7hK*5ZR$FyzMMq2N#t z)KK35hk7W5$1enCS27RzEagG|HoHR`?j+)1EAZ78j}JPns0aNCNJ)0uJqe8ILIqo3 zA65m&FBmwL21aLfF%CW`o^SxO%>RhsisCIMoJYa6Zl7?i*<{BuCOdg^`~oB`2^~xT zYyc2YY(QLq4rrS2CZIQ94AvKtaVLy_j!o4Zs%)@s#Ru!#`Z4reqr=$Sq^n?-`?8XKDd(4={`q5 z;T~NVi`1CKqJhB`yFIwVkw(PaO#14(9h}7?XjDv?o8w{%a9J9Q#X+(tZbic%L|I{< zV;RATeX_W2Kh zfB=KKJyy7`z#E=?2;eZtW_Mbt*`0wAaO_~j)AbQ==sFbduUs0%f@ta(Cx`pGPA-ML z?vieTM}=$o?rBARch14WoPi1pg`KXT)_vGLDB5E`9=*w)_FrL7`zP#aKVAX1NU}2B zdjkF2PdL*(aHhv`2i&8`oO_hfCwI&z4rWXChJVgI>Pm)}xL^ZWJRxH~WA}QW_#VUm z#BbXHx)8O4a5@37P%ePzylV zqN2rJ8Bw)pe44m57=I!$epfMgbp#%9I~fO$*d_5j5`SnleUzRh*3&?D%#F-3pWMz| zGht5OwH7rbpbTKjrxsj@P_cy`%edWZ`>ChXIA=*0(iz8ObRn_e{&MnRx^Np$&{&`$ z7hqUD&;xyUL2d(vT!_>HJ!c+Xo(B6OJkd#{B)YJh4@jeTr4n6H%x*G^AS>T9Q)bVU z>4GhFFG$&MIe()7%SH$N6b+S*t~C@%mqx3E8q&3$>d{~4CjK(qBvGMFwELba^w zfFII^inv4fgpLvkT**CtK$@8#Euq^-NsEJ5%#*nMk|)#gE^CJ3JP9rL*qqZ+Cb*bjC63qkl9DoBuZhE}ziJO*4?y=AeSI0{lGRD0VX0Qhvbtt11 z?|~Vd!a~c=-(Fp48IFaV_?dy?aO+a^i|6vvePXW}#Q;o{ww)#*D!c!d?BWcUUH7_SLr37^ZLi~I7@>o~v` zPv#d<@OR+=i*kirM8g_hyy1U^1I&}jWM&jIkRqLeIc;n8!gTYCu*hqcn(iKaq=(0JcJ)F^2FBx{NjOm6zYF% zl6yG6fv@@T@VpQaD|x>LAQ67Gqz=ar#n16Xn2_$Ipx4*6$N3y#L;s}BL0EiHEn$K~ zYK+pL28ZeBoQi`dAoadS8>As<1-)qW?k77jOk1(u{n{`sgJnAqZt&Hp4Di-8w-w|B z`YxieVZ6ffMb49$@5qQz+592T`bZ ze(O8l-~Ju%uZ>3(R0tllx$|HmZ8{G&xi`peC!m2FSDXjg?J=R6pwaCw}y zzktG^1{GyJ$^66$U9hZ!7m;a!~};V8%21o8YnuCh3`s;sioGt@vP) z`Zt-RgRI4H_&(+R|Gd2mm>k!2CU$N;y82zWyQ`{S(_PiineHB-3*dlwNkUN~#epah zEea$dS`;)NJ`)s|!ldXSU9dH_D;P1eaKJKr}|_uj7Ot*U#^`OkmO`FV9*%mbw4 zAxJs_ND8{ue-cRA&*!~z8s~Z)OzK^ONxe;&)cXmTbW&EBO$%l3W2#?PeiA43fs=BK zAL?s3X6VSbB)`J+j}nUXqr zDD(prWT$~p;IsD$ys@Yx?GP}Hi%z4)Px>J=nh*)02Q=>?uHHj}{T1dtR7=JGSTaB4 zJrrW2_>@M#MjtXS(ia)L>g#tm9~DDr^dRt13Ftd6Y$vQZ6KFh7%7cf1k9G#%o;}Hi zbzHbE4(ge&kDleyF9@0F;90?Xh=9liwS!>sraZh$)Z-}44YzBx0x4 zAj@=PaZK5Xq(j;G^o;0d0B**lDAnj&zf$l9)Qu-FFQ*0s8|1G-$K-$_^D*of5_xqL zFsv2%td@!1L_kg1&wU^dycA+OJZQwpXWCJ6z!#Lw)EF@6^hscsZZR?^;f~pyggXvl z(0I%Rtcfczukmkti8xx~3A8MX!Y!f+)WdVm4W}MR%YZG4*A1tsmZA@MIG zy}gYDeE_n{0vLi2%+yJoz;ca?W2VkjxyS}jmjT9<@NbAdGru-rf)SrE6C)urQAq3) zMTS)g<=vtP9jGsg6P64&QpY4>1(qt#rlK+22sNAwwb*^2$_soVMi0)Js$&qABDbCr zFnW{3zpxFS<6H`p(6}G(6H!uTpF1khJeiY;yE9S}EBNx3e^(d*`fD zeymS1ek>ZnD=~V60X=>rmDFn^ttn)fi~bp*A6NY|C1u)-j!3r6EFKjYqiO$4U*%3J zg0#~KVY)2^0CJF;1CUvDkV0n-QrD@XsDj>_3IRyj`*;l13`bQ302xJvWBZUM3hXfs z>@ok_lRm*6`)o)OJ#bddsxwPcN2wi4DxB|xaXvBvCNcudF#R|irN9pzrSh5SmrK~D z1MDD`$yvXlj8f&?6b#T&YB^kh7J9Apx@swh*Kw4pfY^yIZIsHDaYi#cN-cy7a5}?X zt}iyLr7XUvQL4AfPXRAr0JXV1gN-LuR41uiadwoaxs?6dxY$?0l#YR@X$o-QsDP@b zrH7J=h&h>KUy4P?DG)WssRjIV{Fjw+N^#&Klo_WWnWn(g93v#ecR_HQ^R=TPA<#>K zsJU5ql!iOl01{Mclc?#XK-Bb7?=(T)#wY+TV8%-oH4pZLqu#N!TLL5&k{#lkM9pD5 zDuwk?DkN%-lgco`#vxI&BwT9_wJ{tWoC_}%5;eWlt3=JzC}BoNiCD}|h=H<6(;TMe zG|jmGYsxfHJv>U0O-mMeE4VLVwu}#&4R>_Y4&V&Du`8Pp7$StFb8~JcPe)QMz<;lwQ2$SYYzM zar-LF8Rn#lH1&QLj7CA!=>>)ckm^zz}=A`r7U#U`lC_AH8%4ETzZhcf9n2 zK$X(r5kY?R(wpQ*FMW;thyt*sG{}!$dgCQ^;w4Mzi3boj%BId6SdZiMb=Kn~eVz3< zOk(a(T<`_|Z^;McHD!+rmT;^=Er||l%CVT z+_xr1e~ZoEq1xXBR=sU&A&Gyg?FuCS*E>rctM``-IR{=BnyKG2j{=1ET z`UX|ooMjMoIdfgr_Fme^=Hugc?`xjaXBmK$FWr!^!GyA*GtM#<)0kzFrs43!3KG-7 zaOrTdgsR|2BV$zzE};PgC~P!ub>A6v$&|5qSOvQYeQb)eOuVnjIB!|Qok zx$IFn;xirpz}&37JYVCT!alZLirsRC{%l*MiGaab*=eDb!evKJ}LdcBqbTDH)9n2UsK*lie53K#e`%baE(BV!4I3Xm{BgI3Ze13l2@G5V!#sm&qj-(3TQD@c}>x) zY$|${xuOT{^B+Zv*&Ql+;LvRTwMo$EB1+cTg!zmWzLRKbn-j`-Do7m{G!4-(8a2_%^JUn9W` zq3FFIir!-&!Q7{Bc-7ZPFmCM)Bp8BMwa46Q;Ua$wu6$%w5)KZHWM?zF`JYB9O218Z zHY@ta6#F|o0ve1}eT@e5ewKmmRi{Hx4(2o%C3w0OPmDgx?C-Q=F{?^c-5ZO=$4|GX zjH>W1Pe$y=t`lJ14+6~l>E}*D{YyGI5MZ1f2r#>&{>cJ(ANDaN8dMbMac`u*1Qo7q zny}-_wDNyPe+eqg{Pf(64do5G-tf~)aT>qok%VK zDKImAlL9kC?3y_R1`Trx42F*p6K0<-$I%jpvT0st!Jz&c3ucgKv$=VClLa%(t9D$H z#~%R;<``Hoit`x8qsI&rh2*XzDe&b82`|K@>5EuqQ+`~YeY}K~3A=G3O&|hH;0(iba>`2KzcNauq3R_u?85p8S4AI_fuexN zo+zOV3rxgf7@K`)c&Ou?B2+`LXhMkvjp0V9;VMxJHI{gs`{LdF6u2rwN>0T?(DmYq z(`lcIy7z#Bo}`K#(pBtaNLMihae!VMJXTf)lE9N8TjidzGW%OAqVS|H%162jepEgZ~RF!1N z&Paw-mBBTtN;0IXBtxo7lF|J!{OCOPMyiT9dqop~d^iuj?K)9q+6{>+`#@B2e>Asr zXWbvi>|>y(B=P-Sr>6uRV9lVXBwt5QN&a8aQ*g-pe)jeBln4GJ^pwZu^pwY5M^BlS zuhCP|&SUEEm9*+SMj<(6(12*Q<#@__#YFj4YDy}k$uu^pDIdBn5>n3MeIHfkUwn2b71k|+rj!o}DXBRj1?p4qD+@{IE0QylGMjEWOaVne14897jr<}oujDLV%DX6PssFN9dzx`Ay z{6JCMokARPwppM59yWrZa{U|LtX=ztX)rGGaY`Nkr~((jr2803u?D6?+`WkV{E_*o z@dGI{IsVb3rXL*L1ra+2jj9EIGN?6_29bl(m6-n=8r5X*9E6kfTgZV3o-Tyt-<)$Y zDE)P~`=uW$1=tHaBn1DTVGB6{T~eBX?8?)3l)04xKr*IsdWzFv_luO?Zo*sl?J7_5 z*d(#(y9Z{(EK~|ZX2fI4@DVufg;s7Th2w3Cn?!cKE>DfN&uI}`dCGrG9i_XQj(SiA zq3^s6${@Q=dDvFw(`^e`|FQHe^wNvQ=3aUoylPv**G(NQ7qpZEs>3o*+A7q+)M$AZ zXbz;7PLc}HoXMVbALz}kPZL-upCUE%#Zwz<@Cb;G!6R@gR9on4=z%o%gw%0|_)$z; zt6qQ5q`oKI5lSGbvfx9Y2J?he4A(e9S+dym9pAfV(BSRIQXy%jmN-yEB#KDq1-jbo?UTw?oD@T6i~Ts?zOo7GS6f zSvC8y0;K|eo8j(Y)!=;LqO9W|{u|+5A*lv6{LgnU;2y#g7GKY&dAlj$gdoz)-8+RG z_R7Hhb3V9i5@}|S_0xpra%S*Ua`sqa@>_~`Qk;QAgG+%}tHRS3hqz9mDQ3`H@X*Z+ zKGv<^Z1KUzfO8~`9A4z%Tgv+IEy^_6UWX2o13I6wRrsQj=&~D69>e)Ux`d-f!nO!f zz2q>?;f0F(x6WJU#EI!mKS`V@j%_d~GEfFN7LWqtqg#y(=Ig=7z|aDYJYa|sk9QU$ z)W<-=dGl)|91bbrR16+T;L^Zh(8*74Qf7Ovb1W9#;GvUG58nJ5 z$6~X5onzs{K%2p==yMq5T+HjdlJUVU@%f&;SwgXh|2?@}*5~QLDQwnL2d9>?hRf)w zv=6-O)Lzu8s9{wxQeF(}EPS#J1sjdBsFf8jYpPxrTv@)H@WQ6*wI&{xH=8zwCb_2y zDxLb0>RsNr3B2^n8}HjBHhAyNhHcCw@A9*NATC2A=h-UvE<;;`6+T@CB@GN*6&a!e+qEsG9W{&U93lcO6kF6)%!~xzivj)&dulv_Zw;NFQJNifB6%tc$sHm z_0EQ>xc8R;{r-GIF2>yhW)AJB^%D+vm6LZuc}oyQdMVz}npIiBlL*OpUn;3@VAKj|?N!e0Be)VXc16@@b@0>)%&Z`q4({ zj4=CQ8OzuCfBX=5b|F-83$LlT^!-hjhQg+XTlfhLw=mam%k&}DFZ@FdxA-42YL-F` zw{%^vgO>g{taqhH8}^kM48EoJsq~rO!uq;Fvvl2{S(+O(OQAutblsq-NmPQWiKES3 zKzM0W*DXQUWts`a;{SJ>W;L{FR$o(ftDCBBb*}1G|B&?fE{5c3Gsp`UJjOpxi&7y*#n%)|d$ zxQXbS)hQ2CFvwtLTbFN|u_iPh5!pL#kYTKWPpZ@&Z2-#wf8||8n$=opMq;Ai2?KO9 z{yZryMeu6bi~eERtMQBQ8_80Q4PRuovNNJsPHi{;CsFtC!R8vUJ{JRiO}J4|BwpJu zHP_Oc5tK&%wS+T_4&Mj`+wrm8WIgL*>qGZDgVJ=3ZuDBQ8DDI1#?@J1! z-(l|IS~~gH%>0mhIMl&ovNdMib<;fz-ICr=oOVdOFR z7Q&z^qf4cURUh6FKo|TB#O?I-GYXD0{Y;!E->O7IGb${ouMcjNy*y*ZXi%lU`rzD* z`nteIyHf~^ZUScfnaCK_rGHFRBg7QI)DVG@;fc^png_UdU5l1YkXmjF!x%aFUU(I+ znNX8xNy3DR9THxsSSQes2(7H48ZFG8=*J0c^6XI$76#TzIGLZ7nn#iwU$x~3v|j$` z!R8TtW1mIYOWrZqC~4YW4dWL%@9!XZ5j@7Dnc}y8R-s3&c-+p^6Eux9KK=O_iB=}< zNX7JEXh$FBA7R2EcCwkJ=8@ROagRQ58DZbotYLx85;k&e4V1$`YxV(fmSOO$iFg@Y zIeUcQrA_t3n*EYP!S}_Pgluqei!kL!Xw0;loxJ~Rpa`raZAJrHT@g2qBf#+X*v1B@ zTc6T5zRIa_^4RfT${lhQzA~eh_f?x}+XaW}aftMYdT)RLCQKjBrY1CaS)|L5ShB{L ze*ZfneZ5co0SL(szBd6b2c#uk1j%xg&{g*!zoI6sp+o_zttSCS;gWY0^6+cE1MiEl z?)-8Cc(k%^E= zFJk`kseN9Z5m~fzS1~`Jw^Q?cf*1nw6MqId3@Lxv`QK%qdZi-v%-{$=!huV*DTN0< zl;c;?dZxvB+L!qJ3A0|2{~zs5NA1JoplX; zg#cl2U`9)y#~~)OvdP;aqf+0!;@x=XdwIw#p-yC2Auai!qR7be*70Tx$Z zNWcb%n-)f(4#3^xzXK(aWTX?(TnXb&`z+RM9EK-y8PZFxc>6Xy3NKGL5FEsC=oI=~ zIHyrzi0cAiWcx<*{qa8aLZ(3121SfVKX_9_P+q5 zFQQ)J9K{sQGc9Q78)gCDNeH6|zk*ZMeHlSX>~C84r%8fMlgU$2%h*Ep5@&h^SC~Uv zrh;e^3xS9ZVEk(y8Rk?Jh97U%As2@sqLOFesx`dhDkVP4yw#K0;TdUo>a9`G6sEZhIc)Xhu}0NnaJ8lJA29UH4;{KGD~jm~USUjP z+oEg2xW+C#N`7tIX|%DL^Ybt`#~Utv9DK0aIdB+|V9(kWj}I}k(vD}s1{xc=?W1VjdD($a zO&m!!Wb%cZ&QT5T4~-*-RZ_NdzKvyRLfg-Qx=9&tLXL4X#hsiMbK?gdrg(~S@oWr) zN3bMz^M9He{xbBDghgAgsNOHD!ZUr5Zd z@tttJ2de}cj`J-iqt3GTs+7A4WQQEgDU^F59=x3JS0He{%#6r*1@qZLeEM=BGFeIc zj|lcxng4S2xzP%U5t^IBYm|%okHkkWo2HwCBJ@Xj5StRy)2f>jl+nwG-jK&;og}%r z#O#rz|1wwtZVn(9vc231vO6*>=5Y+wE?wg=;2bSIJpv{D589fL@NyBI+o| z@FDIL(ri*tr;ku_oTC?aM8~=K`1FAyB6;~QzsVeUCrdk_5>JIUDMt+TSLC~$tRaM1zGBQbKY<&3%y%42HQgr2kd-5MK_Zz7#Q=<&nd$Qx&>;|n6lhn!^_341p+K*0$NOQsKVZ9-i&1dmP`=$=d?fv zJ{s{A7{BCMLvlVE87S8RUZuFDi2}vtF_9%~#=Nq%L>S~Mo3b_Zm<{eO7X<&|GKw%i zqYlptP<>GX2V%3zEEYqRW0$xx!{;3{uLZp-f5B&E_)*P$sU|HIxtEXRhFWsxLO8wN zC>&KMx$M-A%T|SEk=_~ZosQFw(w=5yr^Gx>;Xe{Q969T0agcE}p86Lxwl8v+>Qzju z2HI944aH3Weg!96I$Y)wJjH`Et~ zS~rhIDBzl*PE?RXd({P=MTV#`!d_=PRqWL&AZP?8#O}IirQ7Sejj2Mp`3hPQTL8gg zEZSA5EDR_%+X9I6=Jh<#8mnx<4Icjfy8Ui$cI*gXz>$zSb>eeGL^YJE6`cJ;>g|UnpfUJ`!tR z%3{2>X!mN(#G7{>hdLx&LiVpIX2cqBG{(z6+^ZlOZL@~(EoI2qR`$RHYU#%#Og5#F zpqEEN3xQM->kPAA2@c}Z+#$?@&D2C|A1MwH21Mk!=LsTQ`)tt_aWlQA41BThN~mJ| zui6-vXwL%;OyYvWay78agmXo*oKRS3pR>@D0ks;nfQ$>irqzd3J6{Kf(DJF(ZupR% zFcB50>0%;kIuPTSj>(ygbNe#tE0`P0sw2o2X2c8}v{>hoO4?rGQjT&hAf(t_DP=v{ zSIA)gBTz^X<`wfxVbH`oR?bYQh&~Hv^>%7VcmVAqxsh02_a1%h3g*YBbF?v^1zH6^ zyQg^?nJe}jDm5HUn6YgQ`Yac_&2yIa4s>?|vC9LdwSCH;hr98VGHp&;lT&BCHWD$s zE)B&GJOD@cOO2o6(vaVSbGGpQmNG+aM^?=aHHOJ~X&O0sp^xb-+rn_mFS!~bNl!3? z37SnmMoQAu<5-Wva7A=Dt6=- z2HI}k;sdRf<5R?>(mLUyE{ZjwL3lQLcN{^^kQKGq#X~{z5MA#&TFX$~aQ@kSMg=Ic z;~5bDA)gGirjZ(G0@s^}AE#%YLjz!MO|X9vzW#6rNgq_U3wc}!%~Fli;wP01k^Wxg zoKPwcH7opb4RMH}h!3^6_*b7Wv6hVtu(6@0B>{U5wT77(YMHz?)J)WXRt>dM#oX2H1j-S<$*6drtNQ0-7lo|px(KZn1@p{NMHmsHTY+q5EKo?*k z^b6-V47%Q#L`Op&>M$mbI@zNo$9rP4ZK9o)Exme~>q(0N6wdm41Z$7X_54Y$!!^2d zM0I%&kgyI!SU*I*dNW9e$Ag%8nRK?Gp&kDp2p3hLzWRzVOKU2muPA;VcEoS}g@_lP zpQ=Fci*d1h1v@Mu7%7sL>l5Fs`|xcb93?ZKM{-e&uf0pUFT?}TZgiM3^$PzRn8SUFSa=lr-R(3raitYp z5-@%Zfrt@vLuWW=g6o@CmBhh62)=LT?}n_GJcSx|NQR4tOo8+_EnrbXAC<9&!C}4* zf2eddw6+$meG;cOKM764<#4g_ zpqVHAzVM)CSc2bEG<;+A-vUDI5FDJ| zmOVNnIxk7#`IRyPc1&lO*~+*{ z*H|qVTtl|?=;(Xp3qu1QB1XZNh^N~p3KPw^NREa{6e7b=H!iwN8t2ovRowh?xOi6y z3!{YN`$o5dLzk*ky>qGHiU;@$VI5f{d}Fax!9J+Hv(u=Ab4g(!q@qG#Zz z8$`$?VL#VfDA7VaI0BE#?J<&o#8AE~%SbL8i+MAnmq4);qx?!7Q6NZ}98o8iWGEAL zG=&D^JVOSAl;ZMyH!bkIU`3fv*19=;B{Cw0K@al{QU2|4R+Tt1d?CRUg)!AtEA(QX z*3!d#=;H9!jo|NvpR=w;UL6pKAT;(CAM!h4rffWS!#VyR(+Y!mowPAWY zLYc_;Hcdoiw1YX`1eOz&xH!p{}dbC)XZiG_?8U+OwsUjJOlsCVZNtj1~+xX=)=97L9Z-j zXpB^@VibEFzYlwXISy4yhnGiga-W2NU2s8wT$;@dZVJ5{Z$dit56i);8deDhidzue zKWt_O1w`r_6iVqqp{!x@FlL$(X!&)YbZ4xyX*uHLv!R?aU@;G)J~Oa0Qhb34jL|A! zG02?W&vxN=iY6EGDn{ao)-BBIo*mY4yktP;IM|GBMZ%n|iW9=97#Y_X}E=CCF6XTZi}0O^IcZHXnz+`u;JW1D8$Rwpm0NuGGC2t zqjm1QR~{tzW$xrNe&G?5thFU6=N9h&927rU=7b3T!*5}Y7@19LX$Z`uU`UoOxCJ)+ z87PY67P`%BxUj53zCKDo;aR?n3y8a0R-5|9ahtMrp3F(JB(iy9GSQpGC0`U=qgjxB zBG=dvMK-Jg`SI?FysLLlSnhK7MA0>No+@W40hsbcb_kt?_AF_JeKTyCxx4w(nqgUq z*z7JgFnT3zN{b6ilgxg;t5T*y_nbA#chBXgxz%SX;L||NDbEOEOmSgQgpW1?0EQr< z1&qIFRHr#>YkGP}*G7cc7g!HT7(_bNrGefxD?#3XvoxUX@+E6a`%*Oka!os4z(^fa z#s_uC)2)T#nD|SaS~U~h6iCh5(y%}ysC^A{oNu4ExIq?6SU2CtFCtP`(2KRt*KA!F zAa^FNgkKy{r`Z_iS63^=s}5^ltk~}@PlxzANpA)M#Iys^R^yc^2JFTZAW*)2qB*~e z?y1&fxpSg1gI2eO051+g*-S*EHjvnmas78P7`aONjO}Z;HfG2Y+_G8slI1{MYq!`4 z0A_272s4FT)06OMx@`|#XR%w7IFYL(?LiF*C@~u7=6bz()`mB^O^2cgDpr@e%dbaxNLrt=>QPduI5sH0FPruZ&I}N^}h37$tm8-mloR`k+2ZRb%YSPPlq*TQL#M}cJT)y z0b&i(expHBanX*p*DXuJnY&l;LwCL5GAQg*Ahkd@5NDUU(T*AMOZ?R55cutOA&4{= z6kj-b`2f0Mi7I$qzV2DOYQ-Rscbuw0fe3pF{Fw;eQr+|vLK3^x&f-kTo_AS!(SP3! zUHa@e(g~Z|=NAEl+f?dO`R%)m2uyY|7xf6S)^Z19^!h}StjHn$j1kfWJLgP~y;nFF zp@zMmeU(QiGUDe8$YPPZGRxKP_})a`zTU|G3&rx}89P{8Z)gomJ_f`*d6)ptHxIW0 znaj|0Ad}Xt%H6fYEv@Ck-g8BR_mtp@&E>qu$o=TcLTbD?rkqEuu*b6Y^EJ3J~ zx@U7Up?kJui@TqOg-mLntVYSYa-QD=X~33EDGnX zrZPxqwJD_I8YyflE-m+lf@DYZtw@Yy2BG!T*g7QRa$x3bTqtxr48m<+B#*l1x-Q;= zj!U;$4=l7Csf?c2mnX_2u#_e1lnX2x7Ir*Mp)gL?_IfF^ZBdw62cu^fvx`&7SPxik z*(ZFV)t)8hFL@G8V3FcX>)EvXg|M-6sW+7xiNl~yIu?2E&Gk~VWFw_feD&;NbJ3A^ zEtN{dFzRio2C}}zLKlhqqf&JP9M37~TU?>EWgxdtn2@#BCyx}XjtHGOAmhTcC=D=1 z9;NCe!5o3xUxG~t#_^oihMag|3ftv+VAsj<#8vBQZ4rZWbZtv^OOQZ};_ZjC<-d-I z!`jVtD&+@k4TGYxp2ggr^`_R_>$zOTraPmFvy>k~g*t+O3V~JEX(Am|&gKdg2UC=V z5#iu)sy2uQ(Ski>hiU>CNkMJ(guKP}*^cN!W=eRlJ5EI~Z)Ywb(At7BgHv6Nd7oqW zX#|6X$yJ2ld(&k#I;hr_6N3l~AXb&JTPr3^DlvPRrTFsW+vZRsS!pF#7awk)%7E z?)p6#vRsGKPJJinYo16>q3r|{upxHe1OiEYIb6I55?&d{Ngp?WVGNRB`@gSj>q=K3{sX@xz z)#PjT)y(%N6bb(4`nSc2bfcPb2Bb-Wv8@vM>=X{wq`4Lem0%;D65b2x}tr)P%hUWat4V zl3Gcy_uMegUV>iRmlbhe@t&H-25A+jHJ5LL>Y!OSE~ja3s@OMx2skBiT)_e6JirMIERU;$ zKLNn^LOhJ0oBtqKRnDF{BTxoSD&sw_PG88EF9$n>(c}GG+T8BM)K>TFa#!BI`6%=rDasI%p*0BfNc$#7JgHY#lUUBMKVv zg`aE#b*~kEc;Ww}sWA%s8SRHTr24)qYML%3Bbm_nP7%gKHQx7K%71v<_EB zFmOcey&kzY_;V%Yepa3R`9BETJNt_pR6yS$J&Z!C7{(GK2SvnfH4&Z%$cfuB3@?wM zhb>mgIo~KI1}(+;M){)k4PnrNrCc4fB9(mbiCpem$*^U-i@6x*TBWp;FB}=XncP;U z<-&`gg^`Ot=b0@8#U#Ow_46&aMY+6N#L3iBo)@z9Syi^EblKX6?00(BZ7KdQFbDYB zEMLAb`2`^;HuaVxFJ3l%xL&r(MYko4DB`wOfcQZi_F4ACw5F#6-3))y)j_qJ$zem> zMKQzQ5}SzKE2{GeHj;aVOaPp%6%==ui?g6;PiEzJ+Oy4HtRM6e1*MF9*ORMFVDj{=EH`PEq$4c3dp#76U+`*Eq%~C>eF6 z?gGk#kuRi^v`^GHBVwzk>K0V(_6Z9bvM(A{A1sy`*khOh+QoW6ZGbwWanUN5HTxGd zq#P7|$eIf!r~&=+rt=BKcy97$LmIPEb1dv@)HlX39MuQ!F`9N`sgCzFe`&mr*(8iB zx!NS0louN#p}W}PZ4f3(2$^uJkWJ^uEu^y3_*e#}{26}PYOiD$vkn4kW3&1IT}->8 zSu`Aso@lB~m&mtnJ<(ijI`m$s8rjygwbVrAkRoJ_hSO@V86(PGbb9&YWZa!NL9OPb zct|*F5J)O>PQrfWM7Hk2D%Eho#BZ_oIfM7e!a6g2OZGCtFCiM-xW%8FRZ0d$y61s; zw2y4gy`7T{KSHynjNyMEuAa)!#sC_?^k#B|orkQVC+(!>rHNdA&b|9s9Z=;9VO!^t z=>d$}C;7519M%6hOHI0FY0{EAC(4!>njtNZ_>rNdjDL|?wcdj6wYu%RTh$SbnLOpd zQmYYI$4PcN-Lqx8w)%9dVa=d~HAXBwYDI(atm}}@>}Y4HHDJ&drV<|COcX2@aayhQ z13tW5Jv`F72c-dh5^?GNhj4w-4*xV_Z|peL(WjJj>oLDA4_kWEgSN$XuP(MiJ)k@@ zfrqW0hY&GirSrA}yDJ_euHbyjW1S-n3v=+UoY#U@k&le6V$+YbN{bjq046wYgl2*OEPVrVfZ7pjHh=Od@X}Y*)wcT-8sWGzJ=erm*AroF~ zcld-YEw=+u>D#JSb1_Y|_tdnS)h-$~vc{Qd)25pbn;KREUY(jJ3m$k*c}vKwW2QDO z;(zM1eZ|GA(_f_WqT7|Yv>yzqMK{(yx5&4MgLZMrUhGwi(}-Rr2`Mm&OMxWML>WTj z*|HM~x#g#!hMg@=sB+eqTFVNQJ`C0Dz^;t-%7l?_d2Cmi>d-CEc@o6B z%roD5TJc$8B6W{ciDkb&V4=bQO{tmjk~az`^iiAKe*1jKX2wNNmd6d*ZAw#0xc7?F z&_XLj#;wHQUcBPOVB4@H0gA+u0;$N2^XfZN$~f7vTAt83*RWcEbV8;3TEo(`3AL_8 z@ZeWmp?a9a+aS&JK}*lf&?Uv~^>X^%DQVD>N3opjCye@7`54Tt^>Ve$r4LHAv(0Lg zQ_^bj3%sdJkp3>&Jydjs?xm6o+j7HY_wg5smJr0Lyku?DTY<2!l}q|o2fA}>sR)#y zeWKyx4q5L+$zLpO1qO3U!XE7tMIW=sLZLK}>&c^Tg;4_Yh_JJf#`d>ZNO5j6^YXBj z%sw|Vid)@QT{eC>B4b`l=kZ2*hhjnXy~?^A$qie(I4?MKD@63>Fy!{g_zu`*1R0xWP*08aQs@iTOAGL24hOM$XZ1pu|*otRL)=#rZ0&Ou+n3NNx zKxP5qmmDlgd$R!ZT5p$2p$L9s_GoePw(QrumX3&h>flzDrY+5JC^@)Q8MiVi433!k zLP30-DMAoWdkFK@LfX5?sAZ-`ElCJWY1Gmyqt%D_sFS{?W%wu;#5 zZb;cV$7|j5d4dQ&YV~z@)Jo)26U-0A_UIc*?Od!o3ot#~vsW?EuE;>^h1Fn+(A`6pmEyMtEU zLx}d3WXc*a$Rjt2GJRms5=ZTo)JAI5ww^QH)spJ9k)W+@fVjcX(;tl}UOTj3@S%X8 zkk!u$q&Kar63Qbv@3=BKUqMWmb}{X>TXJ+L7cRT2x$oj%!NiMC(Qaw!Kq_Azu7=7% z++EdiL~bEB(0cSur*|I45sqvX}{S`t(+q6(AyI z;?Yq%lk;6upPUPo2@Sg}A=Ln~0mb=%*n#?-y_G|`m(lITr5pvXnHF%cqG7T7PJNyd zhE%0eH>a{S9(_e7dWGMUhz*;OHpxP6@nCG^Y_Ey!&??%C&eMPZZe6+fcqgR+AI1J`ml*$l;FK^=QE@#x1qAgld&leiIOcgg6knlnY~c&zXHx;i2AI8( zRtnxq<7c5wc-_c2R=qrqrG`;hJ>upl7Ta<>JG{Ld_GHx|WfYU`XJex-%sH@mjJk@4 zhOfl21;-W`7Zbx6vlzCxX7NxaOdZCw{#3rEd&GK4uUme=eWto@!{QN3scx(S{iAGt z&WTmw$-p~Bj@Gs8T@rt0;dD zL4(#!J7O5eFK$w4eNZLD($(UNtPJ^vQp@fP(65<#+uSZ5Ti$ zlC!q8F&8k9uXT=Ncn8_aH4pk!*%xUyr- zh}eYDac5-XxJzN`=vs+}`q2Y)YB$vip1!)DYE@4^5JTKQPmeF?fX#L8)oPc`NlDYk zfD|OaKJW3!X2!yp<$ltT@%s`+k=cihOz=>+^^!x( zZ}Q@Y;RXMNShL8jI^?dV1ua(?e=0scDbk0_g~=Vr(&nMozEqf@Q>pvFLRcvhONPv7 zYF|OUd|~`4-knmfy)Z?rLC%-RuJ2y0mi%`6d=^9B_@k1&d<(x=ElmxGw_BkD70Wo@ z1W?QnGx-@%<%IGD$3`;T_GuVWl<9+d*Inv#7M%7f=nhuEc3kW%i~&o|9*kJ+`1E#~ z*s?1UXWd=(iQPG;kNYD#;@x zfXi%5e~xr{w0#%64+pGwNgk7_IUf;n^(lk=HHtlja$ zX=JhaD>FH>?myTm>kdW7_p>2uF6V-}83c`Sz4a1j> z3mk5&?d%C_QR2%zerWuzgfk>p&`eimfTJsT*aH?Hze@_Bz4dk$TFsFx(_LC+CMW!N z-NMhbngiKbcLlw}Bb}|iKnx!-zD??!l)cFA=B3Ukl&2S4z9a?j%(X3|;D*A6%i2fU zGk~ZFXlKc^^~UDf5?Br3lG7pbsQvq>F%GGQBAiMK17%LW#30r_y)f*AZ_sHlz}u(M z@z|`?n6d8K5^ffdxpLm0+(t~Qi0$=)_iv7);#Hk1*y&nrMRCe#INEO$;X_`)FpUEd!I z-P3(2s%PfSovFP0 zfqvU|M6$rDob-%!Z(DA=&F&V?ZztP^5Bpl7+!GXQOY=t9zu-Btw8NmpolfJbZj@PtbPQwCBoVdn6UxQvjC-878P5n5_C>%@mJz zG{L(Zej%rCv{+%?xkGU4p>bnz7VT^?ENNeJalKonphc1L5>DUck-hv1YQ^P%?G@I0v-kGe zEpJD22Or_P&fO@Lb_84Qm!fMsb`&|?9Yv;{7;T?uksvsdK#Sryx4(IGrQ-@a)@aEUn475~5*Xux zpCL!T$tqjKC@TRm3m(B`F{w7Yx#U>#NPJ&0ZPoaTIA1o!d}KeztZi( z2+J=FdPa71h0Pvb(jwEY?Cq-gFAwOTa;dqvFu`3itJxfEt5?W|>1w^x0%e+6WOX`Y zTWeC~mWN5|a6=v0OuX-H8Xxs~QefWG_W= zzNBX-$2JP-6_uiaERxmsE={+lN4DzOQ`Ng`S|Zj-#ba$;y_nB3NVAU&z8<2L5!HXPUA9qzjEPFVic(Oq-TH{YC?)@d>Pn;gMI^GwEwp6r;zpT=hTwmDmuErP8Wa2-i2`-r8 zTSib=CH9rv29H3qmnHXE=3ULm-hW>guEJ%^yUP4!7Kl3~*&>N^|I5l`8Htkb0^beP zy=POiFNg8D0=yeA6wG?rBwyYhJ&DX1nWz&H+^cy&soHEH=A}>^^0y;N-G&IQHIwFW z{6wBPcm)rZd(otKHUBf-)tm#nne{B<>>gD_Ys`|?vtU6(_f|TOMyEZ9*0I@_SK=bV zrC`+G8C8U#EPI3OfJ@tvy36fG@RCGFSCeII2TGa+LzKv7HB8b72zJ5itte>+Iyrva zo)e>pqVM(w_F6Qz@xN_gFuWs7NEhRjeWw>gK04Sed*t@&(dc_N)X7!ZNFwPJ@2(_7 zVTjmcSNo#m^kfux)ae#0FFAT6iF$<=x2Egrq@N*sl0E;go2nCZ@WRkiMi!DgbW{rwaTB8kaW zxZXA*b2s8JGS8T8IUYx2JPgG%4llTjVjtn3LrWEYjBf4`Rv7G5gT_{bU}>lxYlF7# z3xf(G42gwx3zC8zn_fj&^l|oI(Vv4YrTAA(@~_^dcxC2RcPOkq#*dUYHUak0Wsmyi3 z>xW79*THxAQl|{1t^>SB$UimwBKgtmX@{iIGli4Em-zkG6jr~iaS@VAc_4Q3(V??1 zrp=v}v=JCwBVkuelL&708jNJ?d7IHJqcw)a{M!tD?zPm(#Aeh!tK-`oQ2VI_B8~7L z=mp4A1sgLp6e@H08}0R+w~ELDtLJpWWYi96V=N%BV}7H2Ay`dLf3teozXe{=);U#i15Sh8-@%0rM;%%MQ8r9}w?)@3~zI(I~G zJ)MrF1C6Fyp)r1D|LJrsJ$`0iUfURb5n{R6J&Pn7t54@OHlyXUbtKBjjh`uMQ)@Mu z1ux)Uc*W|o``N>{unAI+=KoLT-aSf=yS^9v{_4@yuj#JtuC9KKrmNpC&2-IZMl+*_ zr>uuHG8i>jwq#@M!Wb~Qz%7quYitNE355uj#D&OaeY0TdC?e=)vxi1ubCt)2M$vKR z$~JTa+3RJqNi$bB>&wlfNOHl_D4zY)815nG?jL*h-nqSG|Qb{i)xR+r$xSHaCN2S=Hrm+oy+PN zq^jPHVqg#sA|3a)V;ll*om5*4I+q(l&;ujtvq3_-5z)Ck9vZyC*^z*mYQh4YdgSvI z9Mhc3A^H%<+kA3;6!pgpfC=9CjW`)Un1Kf35f7&<%wGs*O<_b|3`!%JnxbH2Fa-pH z+5k;$DIp>J4F@d-H$gsM00OoUGE=#*Y{bmeQWRQPDqIVLotK%ZMlx!q6k+&nOg_wn zf&2FWnr($pyRae4ey}MeA~2Q$C99=yXd2L3e)Eq-Gu4gwDB8QKt5L!Bndjqpw$j08 z@_B9qv(>jj#ux2;0)g#|$ZP1NX5}b1`bcuEwTM_h7xv(_wLAX^3wiz#E%|FB=yi=V)(a5V6p4{B*Ed>og{jM>;W-e z))ZMj0^o<~XFxO&_Mz?E0`{^^dW&Nm*IYz*xi0}g@dlTR z3?#By4uMNPo(m7`?;VfW9|TPmI2U!!;>SQKXZVS65JeF&lrEkWs9bp~{UJ7yn-MTv zs0H#u0jqct|8I{mm^!g3;}jpIn;6P>g9TTj0sAK?-QjdRCsaiHpTFDqgh}u9b?|illck*SsB~t-w~VK!iooor0~fZ@kR)d@KRbHc?k*(68V%KZ@!-Hf8#FrjDcz=4a^i1g&s!3 zLrpMY@w3rUUBcWOYJ6J8oY=(K~$Z{s_SwQin2WT}(ahOLm&+O^2VfTSyZHbrumAoB(WbarjCx2MlN-XLIRs8<5)^-07Hw*P-jRz`%ew+V{ZXuSn*9U^-uu;{&3> zw+>v)fXD(b*{Gi@U`(`uw9S|Mn8M5iOahOj3w^3>?RZK4ZP?!O>vjU_U@h;!EZdU= zHwAL*EnbN@cqN9&N1N1M<>aK#DO+K1#Lt+=|3gF=4^{LBAxW-u>MZ!J2|9x$lvfK#u!x@fhIyf&WahQA}SAzRE-*-O`| z`O03gO=1qxk zkb+3jRk#6PHg2MA8Kp9^mLQH;QPO=Su_i10=-+^3O+g5$2+Q0+5zOC8<43{}Fi`xc zoM>N3zSLK;vA(kF62)AloXt)%oWngLUCNF(&_C5NM_Gy>nqLVe$1DWbISP_}2->UA zRCz~H!WJmPBW&^+Ja`_Z6~Y35Cr25NkKO=jCbmGwp%i11TQ7^!T&3M)2#ucZS1h_8S)(N;c8&fBn_DU8`l4%JE)lmzGAa3>;rFNdwfnD;U+ z!539Wky>M_o06;~5A=FaS2`f=d^w6Iiue4>rHVLR>PE2KLe(PL3J;Qun@Xtg13gJL zJfNb=n@B#XV0-|@qH$C5M&R972u3fB%(qLUE8u)KJc>+ObG6J1glV; z492-|h^9Bkaw${Z$z2~a8suOu-Brvw=~C1NP}WYPrNeKs?xe}tn>qc~zT%@cz_U68 z*705ok~bcs^itQmmD_|x5R5t`+3ATjGaYx*G5n1m7PQmFYj*k}^@hG()Kb_)#9^8@ z|3fxm`hTixqun4R_wS(IpqAK6AGuVdZRQ%RTs`s+U&j^jJh1UVAWxb9HnMenWU)wt zXwOMY#X2sZ#glR7o<{U6o*ZDL^f53V1yAGYNBau6b_V;4xRP1q?DQUg5%qT$uu{NH z-r9kUB6j{&@$+`Nul|*+;2!UVG2`YgzqTGOrtuVDbpjUFPV+e&?QZ~jv0_Xo@Lv%} z$qB_uvtNMS1fD0PW5xk#RA^G^1))9P#1VVwTQUR>tZ_yBJLxY1iI+xVu;*7;0o98K zf)G@TKng-AL%N{Yh-ToEsD$pAVW&gw2+nE8{e`@>=3f?43*1Bl{}$0M5`x`~LixoW z`f4Dj4Ij_Oz;Q2sC>a|CLW5RF{!mm;cV$ISN4Eua&|`0HC$KF>M|)Wh%pkJ%A$(J4 zwJ}T>4wFWH4hi`~$S^{;!U-7O1cVo(dk$_+<-^wZLDd&5T-5)(@OodHSnvHP)`#Hs zBR@U#AiV|em8?`|%u1oB6ix3Y^4q*`Dr|chGeZs8Dz0R!KDw86?I89P#|;%hv@-rdvsV$z$@@AoHsdjzR*YHvBrYD@qKs7K z_l;-e_icr7@(APP$F_iDqnic&Nx*OoOOg=K$u0}i+ zAq2gQ4C>TvLNAje&|kX`3&sbOI|pJnHD+XXarT{%GqJ|L@fR=_;v$tQpz-i^X1E#* zWh!~H&uWFlGfGt~+rNXh?xq@r z*T|HM;1w$uao$-(*I@@5laYB-G`7|;qZP65t{M>V{;8kOL&029x8}DXB1jb*=yU~M zcbvc1UwlLvgWbvp4J!8201wV8Ev27kMn)Rki{0<@FaA(>3=c34Ka*%+u*JagmUf%v6N>M{z_B$_&q2v7$V>xg4ikUm6z>1dD<1x2u|j%XcWp;2JuC_bLzb}iX^Xa-g9htvwkDqe;4QSYS1{9 z^31O#_>owx1O_+DGB?VIgPYZG6i{2|xopHdwM`vn5^3l*>0w4oaKp?#{;l+=5a`l~ zx=Z*v;=kldwB}{#*MwQ3_q(TRY1u<-J5^HUZ*mHD?8i|9RJnVK3@{2wULY;X*|2*m zE@xRq3;8fy=adh_1y+(Qsrm`dLN*^DaWlSYEpb)*Vm)T+^mF9rOB401oPvDE;ZAvI zs+@g_*Rz6`(d5`Vl{bSHy$z7uj1IB^Gb7f!*>tLZ3IMJV(72~yb*v$b1QCQ&ZCP=$>F5xkTqnCjPUBH%aO!AhcLgQi&w{X~pRFaifh^y!6ZI^QbF4d>3VxAQHIW!*8U1H~NqHIQ9ymr6 zob6>1dmp0HNHq`Ft1ZkXMGlRIPIJ3bqTprIq6ZBui=5D27I}goojW3uv^^XgDF~*K zvlvpmY_yk+^iN46g#qv*i$OPw!4JF5Y!RT(00zj#xF}M>= zQiM+DU^MnaY63X1E%ni=PKUf~A&Eg=!Mug(W8GyL!~0lhl<_|g-}8aBJR&vYqin=G zm5V#DRuN}BMW4AG_f7@*}%D&R>w@#I^3Y*1a?3Svhx@zao%tpOH$5`GX1 z%6|pZ#p`9gEXWwLXnOyTFx@O}foX&w7b0!Ve_4ms4jbE>aq_Zi!;$#@1$140_|c&L zVpNOlMMTKpH$dr@Ms^MfYr{nAL{`p*+~44w7{-4&7jEY^<=l=W#k*n7J;^zE>g3FA(pZ}lGB#l`XAs=0=oL|c%2vK(+D{v|-1%sH7?ylkf0QwZ~K zxjz*!Pxx;otA7iNBw}K+g(^LPKa^D59E0~TlN~`fYz$#@&VajVfF_z*4vs4$H_2Nk z(~A6fKG*B;{S(OVI)8Rtv9_?f3T#(!05_4u_rZefob*?~B=Iq(DNO{aCvjomU65q9 z;r-mg#JD%4!X-Ohzm&F9u=_1v22&K~hD+mU<2p1QBTMcDg@cB&)^&4;)TrfCHX)P8 z+~s`AB+d-9iVY{-)+W3x;@LAD?)qq7gzg6mlQuC7N#=?$A}|1LGcxVJiaQ`z13tH5 z=Sr^?wOnYB3EHZ9!<-fdS<-V^!G=pHGjXG@QlI&EEvzFI_e<{6l)Nz{q5tr4d3ikl z2E6@iSaohi!p?=v={_b7T3&&P1!~y|*e7U^ zY2ARoGi3i7d6Zn&nG)Aw3oQZU+yjqO#v**6`lXVclZGED0Lv&6U%#?Vr@~b^U%cTy z#pUaLZb_|e_Bnuh4dUI5TGz92eS;I_Jgae*&OM39 zgq+SXeM53HWKsP_&LbL)ji1#wz^~$-oUbS9{-mDEW=GJ>vL3fwI$dwss$dI9A&Rl> zUnmVz#i?^=>vang7fJ5lll$QVoB|zQm9O>#YFdszk3dN7N{;f{6W}oz1yo*-Ctm7j z8jU(Suy>2>%-m_EW>I3@{4GB52@FWb069-$$WzEoN;+4KtFY91g2EZx#CJ!x9+8ii z$8Yz3lhWfFR1^edzg8Z%goyibgaS0`Jw5`iQ4`rUS^kVSjsW`nFELDwtuwsNh3H?a zkILIpacIt?6>&s`A>zJ)Q);NT#5q#BrX!K1)ND4LTXzZ7^L&q&`cI}CdcN3nZ*hL? zRQvI?2WV~1=IiSv0NCY)@JQ&amwSPBtBDAOn#ICP)iGz6hc2f?vukgkb?JI@e ziN!U4J32UdWFed0G=s=D?TG3`@5x-6#MY$=i@~nY0d|`=%xu}_>Q`F6ZR+7pDyxa< zl)-UylGj9mPA--c6LfO6oGQC;aG&(kS{-_{DwpWVkRD|2t;K4pDxa*S$^(G|lD4BF zR>8d$?ti&{iFcpkdrxIM9y)CQEA7h@1MF-MSod3Tt-`9MqzvUdu(-TkbAX=RuE~0^ zIl0}}$c3Eh-dd_n+;(^>OgOw+be;~ocIW(r^R!wVxD(fm-=zMp`{ZCWIN54$_W+pn zm*7}{F&_qVoSv!qXxRe3lh_lMFK22PkXn}-BiLP@%1-oIYo%yOq2W!S`T&U-;=*W$ z*K}La&_OgNcuyhLAuvQ+k1UO6HnCF33<(zXU6;o*HV=0I{|L8Qqvy<~ap8wYuG9gwgQ)q(z~Dz&s4N1731&r6&0|CRYNG$0Fv$WC47wnKRlVv-~$a$R^@_Q!c(Nr4?>*v>j%n(T45kS)dIMv?ZaRj z=7lX7EGUN~&MowqiMH-L9!A0r>CxObf19_S%3Q}8#O9iX0><3It@(Pb?h?Ax)PyG< zC=*DJ2)S!YWnP|?+(*+>Js&LF3C4%F5Jhq_KV^$!!&^mca;Y|)#lu^1x%(hV-pP4c zZa6GzB#%bciAz~0lQ;TGXmoPddM<69)BrRo)f9kOTiv8}5@GdStvr94L+I>%q+LwZ z@wt7wJhG8vs7Y}!pRdcSRW;!fZxzVm!6J&H&je zo#!*-_|O_1I$fNAVfF*+s=^<&M)128)vL}eOx86%ZlTwmtZ~H=OfqH0ZI)rmMyyPo z6YP`Zl#y04f?%KwL@?)MT%sh`FSAh>8^J2f(?#YM6MVm%tvDxBf>GsrPbzXh$MuTs z2&TVXhyodv^TMdS$fY#R5U7c`-6TmD8@$R zW+XI1h(8ZD>>k3ko+_=38Fk6LP>%#X;Aezt$S~k+3nW+iPo&4q3$u}sslhd(HR8b$ z|28mdkI5AfQR8ljK{=Js#A$UEN>MsV6%8nY%5)fcdJ@=~(ujRsj9ROBKHhC0V{khe z#Uh0TGAdF9uB8i1`*(5oLJ&x>3zD%r;9da9{RI`ylnMego4u%efuny1S^&y1*lc+B z0`yL9SOyFj*VCfPI^j>?S}_r3se)V-l|~riyJYQ-_b(7!F5`-OA&tvnypP}jlulSd zg+&uYl^wxN=F8~*cGB>dkRvKP;BLl;r3zOHhofNN#Y2yUsZxuD;rhTAf=_^Oc3Z{O z{L~i})|;2SG7_smCRbFPYj1G7q7rkTt%|{+$m_cyHwcXWbU%^_;CnHc=4EepREy$d zHEB&$;SCExHuqU|uqj8U@wqB~CHXFrD8z(zEUA@QuMu$Jf%JAKVuUz;Z(iKB0yqsi z)S~h5_G=#&d3n zL*)eRjl!5)EFfV>A>|e&cROj3)C$rL4<^W@oJQqjR3qMGA$c5d6lS2QmD@qI7)~P* z@L04BWQ)ckXhOil6x-K1^96iz4ZG~09wznYIqQW^0y;}rucV^y4ZsnZDGvN__YoFd zzlu6tJnB!P;swNQdq^Y*@z!4*F+M(ei>qfVe*LZF8?l7`Q~WG%F5(l2<5Ad1dOY%Q zg%HhdZ*)-IwSX)73_ik`w-@Ny-OnL4Q>_c9%HFVquup3*3@+AQ7+kD7Vj=t!!*M@_ z&SG;c>g|QFFV6oH;B1;|;~5ySpa&qx@@Ijwt#nkcAr6J&!!Kgi{9-E;HMX`zG*XTE zLF_SGfC{sU_mUa%-w@Itu6Y#o-*YQq9fOsc7@|$pt6=uA!7m(1EX#PQ;m1UG0!>K` zYZ3g*0jgCmM4b%;GYCE81zt^3HhBUtmQAu^M(tD4s8g?vkyGzR6Yf%eN1PJRjgkB+ zIi~`0_TDaHB3eU%ED$aRjTeJj5niNl7@gk;wNfo$T*f@u4(qM4uw6$Uq$L19QiE)^ zOa^Hs$^2CY*-`Moa1|_=a=!rc*RN#9`V>S67_sWMuuWv_t>4Han%d5_%B4|b zc{!Vb+HiO+n+ck%*2wCpG~oG&$LxP3SSf8O4keGvmirVj>&NA@l@jMsP(zG^_eG)i zuhL^f0=#pGdu|hH34E^xle{lRffmX^w1f3(I36_X@m`(J*DP*Hscc$^9jy$YD45SR zE9hXE>)sv38)lsjohajzrbE3BXLD_}W!BTlK|ZlYdt1?zi7Dcf%&aHmAusgujp~iw zCxP@$S9-oSv={#@)?ziYuBPaV)E{3yUBeB)-=msDy}h|suU@NRNAd=}nAy~6TH<7F zRv6WUz5q7m=Thp3g{&l@0iibc`$)qIfS37dtLESW&~!4mkPSi~xnk1}ZAI0(9E`hO zvbG*~eo@^7cTEE*C#Fd?MKN%n(OsG6Jje=?qKsJLnzyZ+y=@*Ku`jl-7v&NdL9!;G zwOO+UogniO7LZx}Oxchi7c8Fz7rjQA>sZ$ruRT_#(SR*h&qPKH5)gn2Qs;ERk`N#7 zePL(yyBRo*JlO338`XkP8=5u6k&Zl`oOp9|hLj1k&UG+`JR-lIoZ$3p;2+j#v6(L; zt?_!vWa6G z+LtO8D_kBth|V(%9FdoEdG|#IneY+r3X-m%MTn-jyoNYk6LCd(o3XF{N6}^hb4|O+ zyMN>>7nl&_kLpsZTy=tn*UDAdU}|^3aRUbbBs{2f-Vu4Xet3N%RvFf3ClV7HMu2)Q zr2})TMT9@V~K1P1k5VnRn1QmdmFwN^1FhuW7SxbmffUIxy#m?P}SIl%*$I@GcO zsQ4lqHPHP=TwMR6pg<1eT_zX@2qFAK9&~)|W~CQ`!d55(lWcPBi`X2~g87nG5xup< zf3{f2gw-=N->jDn1_bo^9?XY_cU{D0sMD&;KD2?66LjAjAE&|noEu#Q=U&$8xKrC!C zNg8xT;LWd8iGx@NUKs$gOWL>U=gSD!B{A3S`Aj&_F!_ALVoTZhrUgX@K_F_wYv-Y{ z=HtTy(om3$7Xx0SslSmHH}7}O-qla zMt>{lhmOd{a~1PNhT#O2rQg%7a4sArdH{oNMsY~6BB}a-pOMND{b9ae4fzpGk#xs_ zHp_K_KKW_S=TXgf`qVv(O)gb|6k*=kebKXYFGdpK(K1{rFJ_gX4f}2eauC#mI_ObGW!A5c zhp-;O1({VzMEdnKNE!}@La;IIZ)c)(S34K&W6Dqh{dzmZ;Y)>$7Z<|`tzR!TUOdy*(n0p2?88Le!A=n!-8avnLt7MyX)?4dv*vAI%DaYP$ zc^V!L+Z*bPwE-@n4Vkw#1gPY6_jF7_^DW5M#?b__HpHkw1_H=wAf{$q6P!7rFg0S< z2B5e+jAzyc`_(1MdAS@``cS~`#+`FyZ{Rc^P#dQP$L|qJWRLiewXt}kD3}|VtTy-} znHy0Bim+sEq-Nv>*^ek>3z@6t214{z!6bni(P2F--!0l3^ncZ&+TDe#dLy&uZYb|} zH})$5GGr3mjg&1@xyjs@Q@+gaqPpaR-La9o5okmWOa?&Ej=6_G!c!O?D2}-=H@m%* z`*OIN;0%d(H=vH-Bte2H&)rBydXVeg4OKGkW}`ai)$`)0UK28-I|MBovnk*pTcc977EWNpf%oP$) zOu$=HXV#m6J}nB-;Gj-_ad62FrsTUs-ub((H6tJL4W)bzY6@GrYYUnyi%?G>qYCox z3lR8!;zr2hYPpQY$h`sr=G%Gp2+w&?Od5Hj+Xc}r6%%eLlPT-}OUf7!5?JMeRNVqv z^jN5`)xqD#0#s|00qGMX2~7L+zab1UFUZ(w8q`HqlrRHn?G!qGo9v$+H=Y`4?X)1@ z#+@4e6~TqXIyYj(I5-Xmv<27oRg=1UWDvq_%Gm!i`bnp2qSyR0qIQ1@*e&wjf35Mr z`2jN}snBzMzMv3(Fi`+}f_To`G%gIG^hiX(YzA5nz0wgx>iiQ7Z`8-|?tU&I$Us>5 zm5u;eAI0k&31N@#@CeHtpm>>qoW1m+0&4PSV7zkYCoowhl9*~4-5$^4;Mia)?89<1G{{DE1blv$ceh}<;y{UN($bj_n&5auOV>}# zVN}(S*V4R?6*Hra{Ei9A97!)h86IsEAcv@#QL2m3kc}wGPy{g~AW9vcw~Y)0B*{wW z{!T-TLz-FXZnEHQ1egnj&QSmdOACF3oV-qh5aQPH@i=vx)%Jh6eyzPp?jyo*50o%D zVG{LA!QSl>T#dgK95Edj+L00*ZPWmg_`ZBi7 z{a{Xv^8NRcGo|KXDOvY^Ov8KXD1j^HGC5aBMQ+`F`zzXi~WUgMzsRPLOAI_`|W|&ct1I4K19L^=RYCyj& z>OZUoGWc*Fq6o7?J#$Xpj`jMvnvBN=IuHAz#{b-Yyx<&bokMgUBL5R3c#)?i7h$^8 zdcEKt!#;_!zVx=9bbIYe*1X-(3La}!WT(7T&b}ev56Rr4*6EsAJ}93pXY~wp3nUkT z{C>KEXCCPayfE^*w?kD&m^tsQO-K-sK>Sihh+MGP|F-B2Q-vY7Q$AZ9eGR~*S`)!{ z5Ngv6*tk7#J5|fQTI+gkP@~?ZV!6K^9fZ|itM>n;mCoJOuYJi?uL)2$}B=Cfirz<~{1# zpq{Gt;8%I#4DjjPdV>NG(64#-s2Tzf1-L{K)>m8SYPztCJC~-p&N%^!N8$%~FP}si zYLga9D z=LPJkpG#_O=wXY?)v_FDoofv50U}v2I5eU5T6G9?Y;oYH2YCh3OY2-y2Xb?zK%2yk z8Mj-K;EBnv8$UvvJWTa?am+3lawkd{dhok0JWWj{)72?#T6cqUkm86&gG~3eCF#UG9%LL28Qer?p%#PP({j| zN4(V$wT=399U7g%($moSEWX;EFnQ{S3d{QKF>iXINYgeLpr+Aw*Yw-1D=nvUSPqs0 zHZap2lb5uR;0zC=A7W4IQb*^;+;_LWUedV-xYKws9TPJ_Sfr8IIVbffY(3+nQ@0HQ zQvcrc4ye^TFt7{*3v;QdVW4%oqfe3i<4k4%K>KOvR!rj;rMX${*5d4}rrlc5<}~|v z=2m7U?Z=?Kri6B?%e)_P7PT9yi5Qm&LVsjO9&gs)l;N+cgUYrc^TnopJM3er%eT>@ ztJ9#LN=#FY9sEV9e?46`xO`gO^?;D06eZ<1#M*)?RS2fvdzhM9}3ej zqOt0{YzN?GsOIJoCfT2you5aT2RY3nk5`*$3y_ur)!<71K3?X)&(*)5lm9W_guSt8 zv)pzYtwvNP`Z!_d_SK#AkJ+Y~1fFwVn1@Db32i|fZj`sDzV_fG3A#U#3^$Z{7eOGu z(R#c-x*x4^dME1b{NO#Q_JClnsJA&o1np^G%D1&>YkhLaAcrZlHg*0o=J63I19az{ zrd9ek)#q&`Js6?Mf#pRhm$#QVjRI!$n6#cyd|o{u614C$uf>_X(5j;zE_Ga3KD60% z-HNwb^%3?o2z!QLRgsc~0ZaYJklG6^Lz*w<(XvB-b7bm8aG=mPeai`!1>YOlVvLRnf$1|v8xD|qfphv z-fj6cdL}tOx}TT#-lwe;i{$~6yVg79abQXR`vm8(1Q6u%Knq9A?b#c{2&e6f^f$;{ zueM9L>Bz?zckJ7ZPFtoAk#w%wgx737l|o*r5Zz`VzUWMJAjo+em`v4>_x&@~7>un# zNA`%xDODb(GcOJQ_sZZOWk~CCQy$a6H`eE7TlHEWF#@+wAkY_ZjBONha!{q}Pm`x7 z*6gV);gV5j9k9s64GsGIZ3#S!x1;I}fInu8+fo|}=&`WzZCpdk098hYRv-L{(~Zf~ z5HmJ^Ic^^tq-1DX_OZ?1DWjM@+X6DaFXHa-^_-1h(bdG))rJ#Ifd*|_T&iwJb2Pu`xZ`YWYRKZ&XM z%pbturc0~h-#(Y1ea&|v$!_nN%@hJTihn~>(AV`Cz_KQUCAue&ln=CIC&F#!M zXq;PJ65qMqSQ^-IfKoqay<>Xm`15+}{JB-=*KcfYE)9&9?yN?>ck@nK8o`+QKIe2q zSc2%ux$mj+k>Q+ntw>X4tTBLYwnbeQ>rcs{&(4Z{I{)QWAyoW@|Mbo!&T5OJe?*9N zVEXiG_`hp)h(<_HI>M;=hvf&U>Njg384nsu-+Mj|WVo{u2nU?b0OH*RKvBPd8bQQW z>V`Hc8Fb89k(MO;u6KQTMF@s%0q>WQv?(?`P{m*qV%k(&!uAr-vDzTq42ZT+&aICA zHIoO-ZO%$TO$UL}fbNEUAm9p%;ea8N8tKnySG(@TC7#}6OiB02D`Np(9}wIoLHA+` zVlWvGbJn{x+6-hZq()6V8yovVKpIY_1D3#PLIKoZ0sA7n#Oa73Ac)n9kI@4}@*n#j zkD|`Sn0+y94=SfV2@l0^QoAVI7Z<=EYd_pZN}h+?V_4L}_*h^yxho^Wo-Cpwg5jXW z#RrpwK^nLS#w>0=w1lK|JLT1c8wXym{D~y|8s6kFc@;@i(i`$lLpI&0OLw~17HF|_AeaUK{3_#ChxEK$rHWFkadO0Y(A5L z-!9~eOwMwfcL(ID8d{mc@GAosgx`8Hp`nJRnhJiWD=YE$_NO;7)rS1_C(aenfN~_7myZxY##?7?D#&Z8Bp( zGaCLrhQ@?U-wgOa?l0koeLJUyG^j`R(Z+hwzO8w@$&#OT5AO>n2|8~jnflscu1A%# zp9C%0pc3P?+51C;G0_c#oP47kGrz(dK^63`Fmo{{*uTu_cQEaqIcwkF=~T0+_l}(4 zTwtKyQK(u}t^ZYOKOWcKhKZvvjxr&`%V|`PmcY6lvm$r~^DBsXfl=(f(o8BP>lDNd zY#tggEGp?FzNOo!Mb)$o-0=Jty!tWsDUj>YvCKg%|F=M8bRiTyq)-#2Zt#iE*}ax z?}@vO1`IQe46}HU-cq4}0zgu}=<@ZIXrHxTD%vHVF24_o4{dK~K*>j;86sRJe`H9A z*%0-nVDV5!_=79aXj;S2%B)AxQv3)jeJzgutK!0Vke^<=P(+u;yp@Md1~Gs`ERGCF zTYG*4k26L46__SirH=;1Yf{|_=rqGU8+D@e6l!cq(8I|j}&KpBXi+Uxj|A-s-&5=4ojAo8SurtgQ~ZZ#PVzg3hb%61eTWfo-tWe`2&;z%2kv#lvhxODBneS4du^JMkqH>UPt*W6c6PeP~Jefjn0li z>;D%OkU|Aa-e7inXZ7i*n@(J#-)F|L^5$_{1-un$T>};R8>A-u0iaWtg6=-Dl|;ye zS$3b~XQ#51Le$+?3L`p#x0R6m9p->sWm6m?F)u)p&h~($qzGcrIZj%CH)~_7KK;B z3V!Qp!Fbq5c@{&KvQ6w)WGQ=g3zC2&jlQ|bUg5O+AE~VdayXq+JTH|O&3$9` zdx`;5fzNIqEa!?O^`2y=QoL#^@O)9`JeLT253!L9)2woDjxq^bBkJvw7v1p`zPcZ# z-XgF(f`HXj01DB^F$VuF>)-QU$gh=^Wa3b2Qy;^`Aby`uU`_zgBN0eEsp65?sjM7; z`5K73Rz#K+Rj{5YtT`)8R%q!Rga}+W&N(N=L7bUSY|RGNqo_uTa~V8DQnC+=7Hv1CC6EYX1nENUlCAd*)2TYj51on&v zWM!vplAer{^3emyL_*NxrS+mqian%>s~$aADkl;FH<^}o1zvR`M(hs&(a7bU@jo4x`HS^#BC&RI24hALdKx(5bNRA-v|PCjyFvrf&+i~s~Fl%|FDj1 z{^ZyGnW5ZfVWgB(^_4#5-Rvr?Z58~u}!sU4* zf-8fajX%612)IxIWl<1tlmt<5UGu+QM4*r0__lz>ZbA6T*uFLXV&?Y8U)(?%ZY>A? z5;k@m35$f%6|jjcp;#2KXeUUMJNVbH5q}2^&0Fi8MD{1Y+JE`a|No!6bP{ODKe_im z_qG4OUJr@G{+mCO|3$+72P&d$D_XLWg?kC~QneN8C*O7IncSw(zi&sBFiWRSKq7d_ zpLjLm{#*i;7xg>S&(fy(sgnFdN77EOKA_0<-=~n>{C;)^ahCFdW(?%L>M*tc(HLDo z0P!GIS}S_@D;z8qP9&lB<2~c=c)B*YKap{ekz*v64}F?G0gFEyP}UrgN(1^lWGU`h zp6F4T8Q0>ZIrmS$j|etXdbs=~q%W!kwdOnINd(zj#);R8^r_V)`f896Tr$3j|I0zo z49*344*MvwL*qE`4&JFnX0Gr8-00q2mD5q}QF<5aUM+e-K0{tG(*F^3iwb&lhlV@& zVKZR-{=9&&cW^&{ic{(5ESa;o57Yus#6Bz&w1%%z=|dAng4_3Ut;>5z;bQdW?O0bTN?R_Y{eJnSoUuyleG4Vb?zn#~e&Y{HZ}3-W^=WN*6nS(w%zcagP>{+MZ# zN%XUK9wF`H6Ti0XUe8n12v; z6L5ck`|$clKw9>B=yaLYQi?5#bl%LV}oNZ z&%GHJZ0=ZcxzPx^R66xXag{gT{a!*!ND5l2@*gd=6bt^mkiyEnpN|F+k4K+>6pG=q zWrbi~PhPc2*|3Rl@@h+ayqxDOAlII*Z2l1OAO<_I&}aylF-GYGH#C!FplD^#{QM&x zLS98wnXS-}4mBGMZb+gdSD@*s4MFS?G=QecHXZ`M$a!wG5N)&Ndp%q=2Jh zxji6(JN7w~cn8g82d)@tnI>hyUyhKqqshk`4cj6dSPw=_LJBW+hVFesr@Qg`->@hb z?9syUM#JT(H^~{4{*gh-Ul_#tY_`@C%mTi?D*3{gz1mk1&Sb$c08+ z@~Zv{y5Y|Bel1`Oc=`df9zHLNiB^xrdYS3O3Vkk6-jppC8XS`U#!i&r!T@0`y&y)- zz)W%#Au{E`SzS1MVt&(h`Q&DgD-Ay7zCAflz_(&18o10d4d-$>Ay__|2Zvzqe!4D$EqC zpXdn(RyP}5k3R4UxN5H9Y;x!8*FxxOsO%po8WHkGoYo^!*7^cga6U z8`Sx|wn6ztgYNzJdlAuK(9gl|EdO4|p!>h4XXs&r-goM^7vaCw>Aim$B>8*OgIQ6h z`n8x2TMgx*N40-|sND7spvAR+5AmAq-;2N(ahP00hoi z<1;P9t5D&}Tcv$%yMgOX8tBe{fbdw-_uaKR$H9aC0YP4EafVEf0Ry^gu53X(q`N@k zSQ$<~h+PXU_!?%hn8RTN3O3eR*{M^$1!BsT-MB&xk=po3oLV6m1s=WkJCzxNN1p3_ ztgzcFWOr%eL3GxIp@=S8*y$CJ0z^;G>Emdw=~-(WC#PHTICG=5IxfS!_a{2$3_H4r zk@Fdl7Ha0M5(ORoD2BPcc+4};6C_q{(L}R@w2CvTb<)P00+|%k#%Dsj;H2*e(nb6G zGpGK22OaSH#@{2br{Yq%LOn60?||WM?vD_U%FAU8D0npm<=*e$jR@P1d*fBEGo;4) z^CW7gk?`!`sn1u!HvD^$`$EK}H4LrHqgspb2%OB?6%zxhEp*RF!~mQnHt{;aD|9|) z_;JbQ@5o>J2=l-rbVq)y$Ity{G}hyv0!r%CA0@WyA<%01R5&KDjJbUKT*RcgUr$DR zA^D>HWIkrn;;)4xeO~{yNTdh;x*p+SQeis;y94qO*}VYpxlIyAViJUU5(NNOaRZ2n ztg3=H0e`|g&kHVZM4u(zjO@1zkJq(Cz@GwTJ+>cimYuGYSl4%O&d2Dffc|=jc~Z@n zqVQ%x_Sp$^oWx;0m`+i!_~`*^`yCJfq|$i+nLGVCZ!Gmu8{$1CmymT5RG%2APd%eM zae2M>`2Ovi^q4NB*3rQ%G;!_OT|gqaAlQ2QY-E#$SsLZ%PHf-qMS1P#GvBZSu=(@6 zwHN-^XswI!FnQHIoO=$AupK7OM%cVgIz77fC8j+)M&QMRtWcb8Z{MZgnZO3PD=F7T zhw;GP;Zfps=ML68$NC>V_F5dKEVIY#eYJSHPu$>+YMe#~XmCe;IotzvvRGdW8}DG~ zsJp`kwRV%Ue?bU)1|7aAgrR42<^}AYC+Eb%l<)?2zdj{k0I1DP83f`C5Xe12Tw&-i z&NEtbTwn5|x+A`0Z_lE<#6|&HiUzzxN4aE~Hb;orp|;ZM?{6!S;r>!m zG)dVb1GhAderSH^z}ac~2HK^wl!j|fex*0w$U%E&K6x0*nJFM)s5Y&i8 z{e0LVqQi^Fm1&Qgd(B^R8sbw&xV0v4Yen@Yk%!_i@?}5fw4BYXp^ojz23#aUeIlYuC)EQdl3(AVU*Pz*Nh7f1R4w z7}+P3MG|W3Md#aT!Fgg~o^~6ozAm6nM?(El#Cn=+IH1b*6Z>_t6&!J$zp&8EHN7B(DWP(iYM7lcgRww=-Jl(Y=^@B1tVE^!`)( z+)nUcy%53jeNwVgj#G)qpwzkB`|!h=tg)~tzg?HkRem$V>6931R7K`xrxen3#a%1oc3aKCkPY;>nULXw(pe)?dhRW`*MK$w)SZ_ zNHb@85XO-C5i^jY8N|4A_0f-{eYr4a9q!hsD1@&Y!GPj9TWEtrNb7u zu8q4DOzMCxL#`Nwo72Hj5KTg9p>_!o3ULwvJf0p%Pd$cNeobka{=2r$O_79}O)I8! zoVz5@f`bORps~h!+?KQ-@^)3QKAxU&MRf)P=1T)EwbKsXF9#PoFkXU->pVU+v(B^@ zI)+p@Z2)k{_qJN?iJcZib=IC;7=+5xV+jU$9BB_JVTX4xhn1e5*-7ueKE@f6#-0CN z!X#Bck13GZQf+G5Mi$S&>~wbq@8U?)Q{8EuxE|dtXS>RXU+gLZkRfy3fv|i!P92+g z?e5(~zl^Z+VR$)unL2d$!RQPqRKXf}IC%*%5W~YqgEP}mmI9m|Z4{;kXwWmltj;Qa zWOa2eY=u@|!XUUH2sp`-088f*Yo6B-7R|t7bvd%3L>mV#&Cc>880F($_^C(Xd%Zl1516>t|6yZscJRaZ zNi*^I0^Nxko7{0J-jN{^PK8Dyr`=oS$r2D)f8g7GQ<1YM;V{fXlRCmLL9Nx@(czHGCpH8>t8lPQ77=1@9dPG14yfL@>Kn_mak! zZgee9)Wc5=kqmbql?QFo`MEU`+|y*SxrNBADUtQu!F>zqSpVnc=be>mMX)&xIE$Af zvs!pzbq*5bzTlNu>-#Y_I{iUb+Bd(rVDi1>s-oQPmy!d6fsA);f1ws z*QR~azH<2#=bIdlMXpe|tMR0Lh3sw9ZI$WVQRzxqK+;zD$Iw+%+xzARN>A_HNsrkg zS@*#mF8IVGxm866n-?VGt6gm1j)^(kO&crE>uAI-J;~J7t|I>{jmbB3R_ovh>an?J z=K^km0h6uF4Op96XGjZKM~eLiFJ&Y z9Rb}+BXxcV7$q&g7K;RXTzw^AhLh`bUD+IRG^G1ix;X{C`xtjR4A2T4t)7|R+%yT% z5Un$U<);i-L{kNkf1n4vIjipJjzq}`m#3-E?W&%ih6Clq{6I{8%cf9Y%v^#~1I>E2 zM@+l7H9bEN_?_dC3iD^-N9UjF%wlH2NT^tD(@7BLR?`n8Trs&GH(e|Frg{fc>fZ zB?JxuDAYL-^SEXx1c6I#E-v)Ok}EVO=(LkN8?z80Pm3297d)|k2J#g-(e|ZDnQvX1 zmwgCNY_W$_%>jI|^AVY6Hp@>sk^1=slQ@t0vOkTK<>2(<8#Z_N?DS&L3b*EQ*VgHP zOM>~Bh?)QNqz4}V(~Gnq2mnIQjJdK$CQ zv_sI2;ZR)t;A(KvUO^KsmDVr8Ar!Aw4jy z@0_5_@Z25U*vu7KLa1E=I&>aDs+z}*ROZbfHl^d!_?K57Jss6 zO-nWemYr^{eFbuO>&hMyc5+u190G18J&l144fl9J8i~7J^Ovno08RZoaz;Qzg^){5 z7ED{&YeqKpV=t`k0U?1w;l2Re+`<=m$zUo{RG{A5Utgd|=6WAvh0vK>aFu2!GzfLB z@9DDzL>k(YhntImO@}Qm1`vqQ*}Z5hnD0HVw%#2@iAf-E9p&3=dtSqWcTT$b1TeZKKvk0SsgcW7m&xD)&-Jq|UH-R*F2;fp(WW9~K{ znm@lgy2T&RjEaT`FyMQt(U1n)lelm(x*MtGrE}M6VYhqiYDsY<$FUGOnUU?x zq|%msEYD1W$jNz@=e?7P+)ruw_$2k@I7iByjFEOHBPYi%n8cI#W#jvy{oXnA2Wmqt z-*UhE-Ftuc-cKCqy45%@8e;iY0eon)PE!GgeXvN%#h}j<%0Zvf;PU05dprm4_CV&U zs6#a1w(5RpTw_p$sa=xaih^gQ4NV2;LL&Sl_tBM-T? zUmoo?3sD$R=ajx~rQ@!g=u@e?aTxyf784=dc+t3MO6cKV?VVJ)iIE-`0tN5a1-ZdG znL1%D^KaA_^ULJp+8khg7H}C{J7;OuMnq|k#}e}p1R#N1{K(xN=OMxA3Ar^P<8iIe zoRgngpoJE`awY3KY9yvcug?&RPPR8z<@#jKWArVI%wO5OmCsGJ`#%8WNzN730ND=> zU!T>9GkTuATNLD{W@zR`!u&Pb#jF&Wk5enKI6{7#!jN|r{GP*#_wrLE!b8uY>Ew~Q z*qn{Qxv=q6kuayGZ^`DYV04D<%=nDWDQ|i-KOLKP>C*5>tUT9va<*KCLn&*-vMaKZ zyr9-gy(P=9#}D%%NT0LdgENUAdMx}`3QNJ9HbBb1E58@Yqx$dZC>kqYxqos6jf+IW zA+#0OYpcYWikh2%X+P)Cv3DJqzm8l87e6k)6T+3!JGl^^b}%P&P7@cgWGTET8jK|@ zhbFdOZ%|4*(w+>z)BJFMp+UpnC|J~sgYrTM+XQL`e`g?%0H;ARMd(dXYRvU zVtl~bWNqlxnT6@;6}@}@rO8PJ0`zEIIc|s%MWIK8(R%p!O#5n-Ydo0_^{BjZTcg>? z@shm@{xB6iUUWa6f{M>2Y>4RUjR}Po@rK14K+Y*&gcm{%ep)nLSB9pBc>O~g_3#k> zc>z!o5=jje;UOFy!VSwXml#u6<`ww~iCUA|H5&gouL`@ib_LdfzKLm-M!KH)FTyD4 z76)Mxf^Kxg8bO=^D7O4^Xi}w(2u;X3&ow?6o=|>7--6wPF8D?!{Rq=r^F@jxg3XL$ z7rJgy0CL*du9rv-S%mdWWARoep~mnt6Qqkud+XMuPqOGy{*Yh;;|L$vdZ`%f_MQ$o z^IgZ1_F`w>D=YK#)!$ea(jT6WV@{t%b z2*b~2!@>G*z0TC-@NHVmr+9TapW)3jsWIL@Lwc_Fwbruo|2Xn`Pyyqi@IR?R!TbBE zq}1baYvFIgzB3(u-V`1Qf73^F$y)AXl-85dXPHiO%1gXKq*3W>f{1|v%lD_gPLiVA z%3rF)v;(99qQRF8q*Q_>sr&^QcVGAt7NWH~XMUU|o-ybeX0Y(516?{zeU9YMbo98= zr@L^<+V)HUaf|Ss<_M}0eMnS_M_hvjB@l{XCWeLWuCq`r+iIPY4~o)`@$$s=7-6! z^IwCIm;ZvSbqXwXtDO@+HlGgQ3W^!hHOhUuOQYRh_1gO-1Zc~xfB(^MC%JGvfi{VlI+FRWBdh-A6mg$5d_nsobDugCRIreU zdgCZLU#BC?&h(DA7Yl0?{)i{#?f;`)DK?I1tDKC|RuJKuTg%)h#1L(D*7e#-hH2|x zm~j^8zLY{PLaevovbQx3|B?F#4|eVtOvgLK?u821`)DiOue4%#fUWoU+eZx@hmm+x z`x5pegArVZTd_enqhcR!?>ZSFT!mfOROIsQpsBlc@@M54CyMtvurjsgszvpN({gJ(4bdI9Up8< zOhNWl>{BUh@Xsjn@gU0EI6?azP$LZCGKODg5uq4<2&tebexg_T-M=_abc-l*I68_j zSW`UsIv`_wY~n6dmh+M7=%}o6Xq>36p((ZiW^rQgU(i+@9H3*D7#*dpaN4~#8fWc+ z!qdaFH9I;AodJ(1X^o{+9N@~oU<|dm;Y0Dae4L4~-noX+g~k$mm{5NT9e0{;EUlZg z-#0pndxAl;b4M_hHt!!WJY-vtkhY}z=UlP#^)6i1@3%XZ#e4I5{@-A(yhRN8ArUB}r(|CHOlXvz0 z2eERm$hmdpF_WJ?8dc2-K|Q@%Xlw>;3A}L*NjW&oUP9!^;w4AVjq0sR1gk9ap8hz0 zICG>>8!|G*1r0U?{&4;Xbp>)e8#aT=kiChq0sm>5R{peP1|@XzsI!H|*fQUibizLR z?RHS4N?gAGmHuVouH5`qK_bT41l|w|5GH90zNx;^Xn_d zx{^_m|H!LAE$a}~K(7i&HipeN$KlcX%?bQtOXQ@AZ>PNqpObB`GMf(KR=jxd4W07e z)?hdO_7u1lZneb7x2;NC^@J)g*sNE1OaKC#Q!OGjoH$%);qmnLXHPir* zYc`ATEu>XiN~eeMW=I(-Qz0xjo)w94#%6dp)CV03UyTl`&B|c8Rf#RA2%4(+yviUx zlSJVp`1f8eu!36|Ty`t@71P@s9R@)c?}~0kfqP4&&j|uG9d7&RkAl>Eu*a*!hhY}J zWgw#g2>BicogDU||G%ulijeshUfv-EKhRYChQI6oxI99Cu2iT+F_bg0uK{bRq`Ss# zKJrzslJ%(yccDzk(5P?^KL^bUv`{jRza`HKd@WF~ho zR0(o@XRHJ70}HhNvWLQ7^Z5Xx$__wOzeyus8nfSx{Dq2T8(#{TooU721d8hS14RuO zG=KAR8N<(P5yi%IADdU=va_8!^N;YfoPk(@%n`r$SS(D!Y#<;Y6DnFQ;8nUu&9Vi{ zcV*_-G&#QE_x4?1DzAedyx8)k#xNSx5Jz$>#ye`aii{_By;P#d{(a;j2|&pnE)vuga*uD+X;^j_ zLHMOBSydaw0TxmrvH2^YcM|PSSKrI3ij6o^718_}Vsl*LRKAeQ+DPOmdy}0fSWTt|(b#D`G2 z(v01~E_o&CPQ^m*6l*TUCTW<=@tL&%AL-`Ysk8DM8f21TEC;-?7AOTy_Yw_P-q1?g zed|ayhJ+{t4^7T= zzTXnl-Q5Oakw02Gl#w2vYl~sEm5izy0X&dp$|XD+kMzM7YAsF4@K%b<#SeSjMW23& zvw3pn5?ExKoUijn9^u7iY+~z$Cc?ivm`hVFJuj;Y;@NSa%1t6QSdwM64LO|>;Mbw1 zN&w>eELW-o(jWafmzHi`lU*s@BPch)V=`B@hRB(}nwg$%NkQbHZ-lYRoRVD=MoGg?#1-0IcGeEN7S+Z1MJG*x3K3+xu_# zQo)_3-m*#C?{v>7CKV=NFUd_Tw1xP1Gv{jyu?ZYbSOhR_{2Sw5u76x(+x0HF%a*HM zUGxEuW8RHumxoA2Kc}+rr2dOA?fEqTvy^xb32+<%11&bG`@nVw?pgm1ap}DaEh+tG z(pnTfapM-|I|G($fu=2Y}{n?<2~J)fKr8qRSr3Tdna4q^Bb{H zgC}pJI+k5*dsO{uc2U9Z;@mI{8~L}p8vYIRNXR4BTo%_4z4K5bD>$a!7mlmG$|jLqID z%a^;AvkRn-Cngn5(#6Q%8Solt2gKIrqDw6L#1~lY=!JTDq1W0RfK}9B)8+f^qy~u8j(;~#L zKPKOO9=K>i+(w?;ro<6iN+-bYQ&H8Tkj4#|_Rg!CZRW9iD>%_$;ckwXPR{T31_ zfQ!$75wyU8mwHS;?x+Mac$*DJ>=Cff!GUBttZ!8uT!4~yjE3Xln zeq?Rg{R)pYnU%5J477Q@dv>|740hC}h1`s+bJ3UR3~#ckS}iPF{3h_(G@U>)*wRZ~ z!xr2vXyMKuoj`R!#Oo5)zTXHb%Y9=9`Co${EfQ@1^ zB=(mq5uw=&#RU}|u{?;Z`RTxd8w54wZq0Zi#!p~w!sO8eJ2|3K7)_)>%7w{zLs7>SQ~`B{Gw*9rb}f{ zxw%3iM_g>B#i6as z#UlQw6pQp2WQZW6@y2PtD_*__Z*aD(f00*DZU&zx%@N5K7ufQOEoS9sS|X`RPR?55 zf>KSZXP(bw2kz?mY|bK0B+4;X5rYJG;`p03yq#9r3J>jgQZ0 zc+JU~XT~w*ai#{s)5K;NFq()(SO{!{gsC~uq8#B=0Z51zE?r+hNh0@JepH!YYJVAd zF2Z-)>zo(rEgBH5G=n&GdTTK{O9mC+)*34;E;=mjUu<)dL%m1fG*^-H3c)*xd58So zV&+#Sbo9Ae>z&eQ{|$`_<}$_04a#OGZGJBGcDdEVH>m$4exfA`jrR!#J8S~w35~DBaA#a=2MCmWE30sD zRqO7)PY#8dqAjMT7CkY0FWKngn?2>er3o)kdU*-6G}r9uD>u#}TMp};X<$AP?OVCG zXPR_Dd8b@tMkoDtX{im*-lEEJR%mEmm(rz0RTxOBAW*;nxg`(Y6`k!xWnsB|;iqF?R$1^9amUoNg_EnzeG9(90!jU}$QXQ=U?rtWG!RE;hK?bBzw zE>m&RD}k&scUMfJwtwTYC@$+IuEFND#GD~)s_(6=bfgn31a%toNh+oxzVx2`8`;Sf zeQqvwb<*Xjv9WMhEO+ioA&i03fI_w)D{{H#{fao3dS$YSJpFK@S_a(Lka`y#s2M`$ zC15x4d&V(A@3dTTQf0tCRe0#UQKBgaYax-J;Po$mDIo<=B^wq$sRx|{jCNZP)A zH%mEdsIatT$f=^%f=5E2yf8J{nLj#P0*us$nz zgtd0yYtjl0%vb?m3ppgMjwTA16R>NqYj$Cw+w*ZcH&j-Y)P$xA)P~7EJ>?0tchXZz z8?FK1I&I45(#~ULDjgwf%W_LX?HVWYFO_vxdKo!uL{6ptQd<=Cyl9PVU7b1lq{FYt z^=01SnesN;pLfB?xUnn|HxfKFKEzpr9R4#o$)J(4FDymKK2fXt5({2`Du## zIO2JDp*+uH-c+RW6*&zy@?K|4h8!?C?vMIJ6U)s<3d`9}A(qqGG8jaQ#+LaOZK{2+ zO~cX0zwk0b7DTMNgr03KavJArzYF)gXv8_7#-h(Si`+!sQ6T^Jl#$H6Jz@K{BZo^f%2wuXL5KGOo9`>jx+t2x@d=kw%RZ2X z^-HCfI~No8903`nyzqp1d>Bzg>U$svXra=ziajD@b{r}=Lui^Wj8k?MPxW2ffLN-qqvyKR7 z9zo@zOU0y0U(rJ4VirrVjx845b#VL@=`C2E*;*%!)0s{*ZGl=0BcpHt7YVn&sqg_u&|u-ua4li&qF-k)o52vzOyf%HT}Dfi`yj=24Dt|%K^K}MFDSh~qb z9bNb;&9wWcErifKxlj8iFJ%i^=38cP#P- zFf@QqnKxkUkKbzy#Fm}Fz_LwzYapNK>p{7W6pKf28SEx5&d)xe*1@ z1CPy)P$`DV=BH-koaY1&+7plVzh;`9{+)T zpzc{5kUf>J#u^XuEpD*jaj`N<12Ox-fj1N%*lw9*4bBMH!8yY#4)l5{jrb|zyq+;W zrgPKsQ#p%^DK;O2GR`%-7Ni(t>&$E2P1&cj7>`szQVfj!wO9+DMB4WRHLwlG+)16s zLL|lxYyMdZ^Lqd(%*KL}OWSZDiD{R%>Y)&?UFx84TEXtYy3H{-iz-5UP3dyeBL%2f z7ksx$GZXp-*>^-Jc#VT9qp6@4n13c1>e%vYpB2?mRee4PE5AS=6f~Z?=X!mp#=Qmt zC%?i0@m9N1LfVuPclCF`+&5t^$f@*mMe?z9w`7DuUKQd)hFSEXcm9Z!Z;-PUBL%c6 zjxXR?0!G`;9Qz|HgEgKPd8QK6F}Fd$e+q-Kw_IOLD=R|$<>`f3hO;50vm6vv4%7)B1Tn2YH57B|ns zgOEwIJ@P+zWvri+F-Xn60iQ-3e3L>0XauGqK(k6#G2z(+tK--hgs@gTpU*3l&SVsn z?#ZqCSZIv+OT+cN50~dNJg%P=o*JVuPks)9weVD)@P}f-h>{`v$+f3daZKYBv6n_} zC!3FroTXVBxmR>g_ny_Y@V>b)*5o`2xg-zXYg6)$OQB$!{4Vk=xCkg}9gFieJ&s^U z;VF^8-<8r0o>x~mr#L6{@l6gD_ciJ9B5C!GO9uqTS$M1fQ$+d6=~=uXibkzpGO4EC z;7O%Lu}{=kU!ToTaET;~-~`#=QUbL|a8AI-;iua)@erGk41?p&lJcDv4R@ZV)5KXp z42f$a{g_=sMwMcUArbxB#tq5}&Hsda^XmeyJPp$En!m$>6bTslVgB&?7oijZ-E|g` zL#Y_okC0RAVUs{M5Q8CSn^|AX zr1;j!8Y$24Ce43A@_E0_HMcSUO#g*~5;9}1NWtbd#(W8hyIZUk!L>?LzpZCym z?bsHUMfq1{WB9N~{oR!BCm8TbkE?EQ-dZ`*(}H=qH}s2=LgjdmivRk0bc{`J?fmtw z5IxoY?38#|`63C*mmiHB3Ozc3YHekse)b6S0q4H50mG%zX1rC3KG^beIu!376+Dr? z9Dlz`L=~k=<3=w3vy#hQJ>Fcy9FuT#BK27r|2mc4E=9ycLur*#LKlQBNb&t9h1tnX zQQ?r6ZE;m-oxyBfiyEk7qG%9^-i>bmdjPSTUdSoMDT0E?Q>FF%!ZW=c~58w4+?vY21 z2kBNo|2IjSI2QRw*to7{bh`MtGx%7OmIm=4m$5mIJA3oCy`$f{cBv*X>xHF1(r%1Y4s^uMP?__OW=AaZMW7Xwv!Dj|+mT!N_!Vv_Y3% zj|sAB(12v}$L1_9;WXIl&Cl(!UlyZJdVh7{2Q_?3p$k7$1)&8OsUMaExn&_Ou?2`Y z*I?5(-%9_6B)T*(1m{q9$~T@oyQY4HeZaG&dv_Ur~b?h~6>6inCQ+gd-N(-Sv8 zKMJ|gqlZ5~C&(_EjknnOFYVx4CPEpIxXP9jTo5U7dX~29`AS^%I>)auoPm%l8XD^0~@LXY@S&CCC=G&qTgdFrka7 ztN9~a;|f;;%KdCY3&)OZgL~qIaY4ZJ$_*wp3eYbS-^+(jE3-1DN0R3eT z588kG3qS&2KPCva$z6DB2z`KWem;pxDRlnTc{CR2v@Jy?PdafsMD~wn69)(~KmMlq zqgD8SB%HIufBK?_-pu(SyMBVXGEs4>vs9`lBYwPmV4C1P)!C&39YR2RHxeRm4(5xf&$;v56S{Q1$y0o;UQ-2Z1%Hhg^?NC-4a7a`} zAxu1e^MzSKCI|M7!;=U12k211X8qF^UAg(X26{1AKeC}#(}!zimGkSTNT-9h;CzRB z)qAis_boN)Lb$%NveL#Q?@kG_X>hYAPoBh#1Eh7$+9r_R52r!P9?zQ`Yn+mtQ+$KY ze;zTKF2s3c%vou`!cnL7=Jp4a!_5PXY9^Z8lz#A&MhT@}KWH_$tZ))uMoc+eJ#bM7 zUgem!g#`DTo14f+?d^jT%&)Jn6Zb&4zPh@qq3^INlef${|iDeJHPD_=M}*+uL?$zp$_XsYyB9JFs<3+C-07t{t>+Z*ymMZEa1(l4!J}4s87>P0jy2{2u52=iajlW$*5z z0ovlZ=eKF;yhBv&>c!7o1AE{m<)`?p_5x%TMcOZDnmp{a=XDn;K3YFrt%q^ znE966WSi+jVL_+oKu^zKqLot`dP8)$*p^B^e=npUHT6luAlYL1zvWFf`1c--{Uh%Z z2VW}4ZF?&GnpHl2Tj3>}rR9AMe!3X9rxhx&HDqUM(C9z&E|*%}b%|Qx{T!{=JlGWs ztY5?lE}?g7+qAi%Q_SBy1B8wg(?SCHgWi93xb(t~PN#jO+z>2r>ZtV(&V|+R4K`p% zGd(XtK#uSRWM|<46ntwDY)Y`W@SE;#ejA)G2K_SpCUM!l6DqCY4GEjV|I-WMkY7@0 z^zTA#%I+^~v=+YMPdGFj^1~?Sr_&Yq4KVd8YyHj~fB1gP5GIX@uxdd}g#mNshP*^v z6uM7(t!e_9X;SQ@(=kVKg2AtcZ}`d(=4G4XVST;9uR63Dz9Fr6=mSc#b%$U}FWoo~ z+a$!Y(v35lHXS0wCw$}Fs)ecU#;FC9J_zs18)w&{4eo52^!ST7JJ>XdRLWGh@pp&| z-!O1req+z2{4VavpV-Gy4S!~rK|&AUiOL=>FRr2R`aY&Bkb}nGuL}O}wxop{0{)X) zJnx)yLdHXbz1K58Mz4o|DC}sGv`@4cl%lzTbXf*JIM)MCJDQ@TdLpZ;zQNP*ZarR-HJ&dzQ z+;celSxiZ$M$G-UT=OIG?v~iMV=`R-h)#WvAT$HT+C@^{1~*u3i-Q}kGcFJgPZcZ3|Q8;b2k9yKVR<^8zl91n(H zeh^;xRNm!-*uIbN#`Xce2Xgv(KBUqvT$mm;A&Qz@tfu<#iCD$Eztdegahnc#nC%cj zZz{t1aD9j8$$w4`*Y$@K3bp&G7Ornx(kNR&lb)8JyM{ThCvwq|aJ_m#L(iXqed5G{ zPSuSKN!BU7Y^X$p_2d>Wf-zPqNES_b|5=cPd=3|?RY}1G--FmlySPxRNxe80-q)bK z^#CrMI3e}ngY3LXz=Z|NPwvM?r6Djwb+Ed)D5(ln{eCHhoh(amZmIfw(l~Y!B7d+G z1ZfsK9+ZY1V-h_0E8-3k7Ere`blOh?Y5F^)`MTdLk2);;4#r2~IC@{{8vKY#`K1&D zxu3;Bc}%6j5944ZgM$y@;A8;@KZAqSQ5=A3((9@Ur*fQtl=7S7pvEikgM#hZL#2Qq zQI{npAG4%j@&lISL&_6h$dshW9orW&I{T&+(j_U0>nv$%zMx-`&V}p8A9{#*WDAx; zEy0g&NngBZ@MLynw*oo`c75s6B^#sU)F}n5vIuT|;lc%_Gfc~)XV4+#%)tS+DZ{|_ z;#o9)`Jr>?@b7~UK8P#t-`&ObeeZi8whuh;fIguD zKZ;fu%9xZth5pL#rm>m7h|M_2D_=li^7;2;lS5JRV<^ekv4=r-uD~UbfZy*i-W3L7 zDk0{txD+KpWN77b7|ned2P=a(cmf9}M{t1gn_r#70S0t&y=2|Lxwtv&ilX2SML+1p z!hfRC*usp(s{OPztqYrV}@>O|(B4{ZNymb|P~v z0Ag!>ll#8FkWu%F{U6euPE*Gwo!J=rO}%monY}UBs$c!Aw;wyF(8u2E;hwv8{yZ8L zsoST~Dd=n=j@~DoOLuycLuT&Td3?2_&FAL|*mO)PnS~tgWh4xMl=Exo)b!2{o@z{G zp1!D#a&{%N0?Id`J{%5R^peq#+7Az_DbV}pMu<{R7mw&sotVxK4~5z)Q@bkwkI<=+ z9_3u$WeZK8RJrtOr`w6;*GKSy8T2%%A3L~y;sn)|0-1%(LOXH2JabpvT&A-^!SerDoK zyHLtaOrm*;@X0?rffl>Ek0WgYY(TkfTq~WQIIq&RkccD?6VnEjPfei7%DWRC@}Hdm zm)I&yj1zI&^|=X9PI-O;ZB|~G0OKf^C%{_f)+W}VRMYU)3HN-*m#2t|>I~prlhxGg zlcLU5cXr?=K?_ThAq7b!41+F%-|XzrqaIC-){mRqlmXU7`e=P}vN@32A)C@m5D7Tr z{h7?XfzH^ftOQnw7_h(jfp+J`se(O3BvpJl@)pv zWvdUK2)VyeEd@&Wt1|AVx&_0{b%{49&!2I?d(j&CB*;B?3`3h;TZ2;n@Ucc(BDI6OdXr3HU2wO*%h^ZGH{Y~TGw@r%o2zHPMjE2 zml0n9@VH-HT(~ag+>QfEtu~;n2^#sFAFCtCIh+j?y_r>iec(9dhS|+Fu)6Dc7|dU| z8zO%_JDG)#vh1U}$}QHXHx#aV@??kRlmTUWRtMEk#dnr4+|dxjQ3up)|A8{0^l^Euhkm+NjCME^(;-=&Zu28ylK1dy+U0_^jUORM0nJC1O6676t~yCY9^6 zl@?yH9#}`GR99E&QH+vl0Ok4gT!W@YCKi82k{Z;%ffN5kRp02G_!?B6tA=bETVJ<3 z6|PifVUyGuYrTTR1QaXck)|NvsN`wK-($6vV`pgVHO58zxDX@fI16p8E{|Sqx z5GB`K7A#QIn?8%G^MQFxz@?}Rg5(=}eUGBR+3Yf8n^8lW8igL#AR^xBa6g^$(cTi8$)wnin~Xn;jdASt4iA{BU5{=oD90 z{?C~~v;r283TNOZxVGlOPGTWwVWQm?FX#x(&*^Y)j!7=1hlgE461^reAW*-I#+h(F zomj&$ruZpIitSGbE_X7-LWU^vxGa%S9u_8G_+_{zz(v#?Yx-JOBZ704T33~JIa3d{xZyu6YX8y;@r$H09+(4Y~5^n`!{hB*Rcp3kEy8?=GH?T0odC+RWx=K`@F7|<~l zgZE`+*`Ox?23DxjM&iDwb=?44b^bLkNjmb{vZx6Uz~jdShvutPZKL2%Z){+I?yC!& zT9nWYJ|D~v`Hnwyxkj~ihv{Q;?3e+D1d#$BEJB;+qXbO7HvDuI@5qmg;PahXHlIp4 zR6ao`bPly@Q#jq)$9MCY4DQP1@X8qJE(;gh4+t7i+!y+nO%7G>&?Mw%7F8Pj_EU?r zsB@W4<>N(Sy^6z1qPSrZ;rVeIZ&7A(Q739{%mzqOVaO8n>cD`)W)p;Q&cW?3nLJ@4lQmdGE}6vVa&yQb zjDFQvISL;-sPNB#GP>X;{bood1#gV9X-fwWS#fdf{GGpAP9AY)l zr8Gv|BAlDVSzk-9j-G?F;MWFC^45Eks4aV7^4>n7T6RZQ^2?j0t!V3QSb)mD&-5`DgqCsI1 ztLC+cOMW*I&>O7M?wmBBpjJKw@)SW&zF+@xXiC+)1L z{tmJn8f%!LXbQ$0LPM56&I@FWvt?j#_fgpX9q-Xvg?Ui_dSprG5`w z2<^k+8o&k(#eKklkvR=dWc5gO*MGW;+eTMHjLQ0?L!JD4L;1wpA#*%`boIG z+26wv{kH9g#&x{Gb8hE_WEKpzlTmJ2pCbF1?U8|3pb1~ zU+a64%L8!eS9IE!7~Jsq!J@)xyigoN$msEq!gnLdYj>#4xN?^7@n|I$@ad_;*+w)2aBrUNV#Jja9oCJ;z)cE zrc>$FA=%@LitI>%h^&&&kuptYaTnm7io^jlEn{x&T&1H$bl2t!pX}5k1hY<$Ed?|_ zWJ~{TQf5l$033wxLQWMN{_Fr&B8uQi&_Yk6b43oh$w1^CH->UFrNMj~iLf#z)9C_+ zFfTSg9coC4=-+BTz$DuRV$-^3{Vdr$#Q=W(8)a4Y6EoT9aO5ZiDV*AO!%XSM%gd~z z7}AUPlYW8f(K{hAEquqI6bX>lzP)cMiH64y57+$vc_5Cb*f9a=`VrbZFTpIC}sK zej`J7`r1y;k>*fyU-H5znuud2^wSTvl_ae$|+K$5!IYiqm zj_zQzJz-t_qP+-4Ikr0SeeKGpcPN|;_KlL|T%=vcl zGKZNd;c6VITrbG?!(NEJ`V`Q#B!0m$krWQ$esD1F$MT3=>=7`-q{8(q?Y%&dA|>T> zHqbeD-=>N1KAon;n z!OehT_zk5x;-Xv0T@7O>HEI#Abu+wc5O*&ZQfnmHwdg+@6fkzC!`CIRHYz{Y;D!Rt zofv|?IPYwD$D$a1gLwl9>}dyKqUHya$Lt*+wbn9krJCF7ErwfUyZXqzkQ_feWlLa+!#SAO@DM0T41Gjm2F46Y|wyVL-pwub^*lzA)Js*#1S&kBJSirS}i z!X>7jtx3zBX(IFabYlnadHD1FLO^XZF7~$#>T~ddA1veB24!A9ZtfENd|w|H0uH*F zsp~lHcU!b|0-wem?~b%};(#L)kJErUuw%nDu&8uY`{csB=d33PwqOZxqm z1JrlZCn$8`>l^qE_TSyc+t9>6s7iwm2p$JV2rM>js5Kk}y;F1H`j9@4%&f^7cU#5; zv`w=EhU$ePca>9OyQB;CRB~VDV@qEjTVk34RN5@=7R1{ z;p(^ty&xL(U}HR#5*EifI{|%X?&ezowWf~n`cBF~7r?pItdWL3Dz`hA5ds>;%bRHI z{mknN5cU9Sts1UL@T1SXJ8yyHS>}gx+AbL2g}0`J0NVB8*C)|$D&r!5@A4NuUj*@J zwEgY`Xpy$ZK@&Rl$@XeA2m)%KWK9Nlc+AFI@ufC6jT)B!dI~~+w_O_)R6XW*R}mSO z#jj$J&kl7!Z)W3YF$fZC3(XvTmr&jxeU=8G_&BdVgY5|9XR!hSs8O3g2$-W)0J(v(L|vbh-`aqnq$c(hm&S;J0+X zyRi$-!a%JXQCfrgkp4@)NrJ)7J%2z4yB4I-#x6Yn{8|TqN8%9&pSFfdYlf}Rm7)+1 zo?cZMYPxH#_^!Lc3~q3(&Bc5Q&l)Uu`V=BN+Pkd5$9B+g?H#nz**&n2dkvv)7lwuK^67O4 zDqK?e)$~ElB&aij%d%`=Ctphv_0538<{sSJGD#^KEPHy{1*haj)C03Bw23oW2=->F zwGDwYwRggx@Lz&I@doTV+se=&O&_)XN!?x;;(^4X3L-j4GKqIK%DcWDXhuN>v*Pp( zVW?dleKF8tX&wUuVQ*vpeUq1Hlc~XT&ySK=(dYv_fJJ%0+g7n?6PNXEDEy{!LrQqt zaHwTzwhfWR-0h2c+y2H5^Z2wMeDLuuU~9_*?d=4-#iIYHb7^s@f#`vvOE3|T!Y|&C z6IN|ZSg~qBl~n);M%7w!-`U|}xG{X&<>Du8=$6jTzzTHQGm94WAl<34Zc_g2Nt5Dx zxK*Y6!J-TNL1;2}jscVlnw=vV7Xs!^P~Gd%<+#wQg|Q9}=5%H}*0+tA#MZ8W%(B?( zz9lT{Lp%9B9!t5BX#WciJ`*NbZc0 zWKco&D{|i>s&M7GYoZ9>S$uxk!skykJD3@D`2PtV8y$0T#pi>JhUYugk_JGl6$IV( zbSB&F#Tyln;kF;q^qo7v!EaPCZC93;DFWkC_(p9{<#3TPoWc0tt5JFzA}(iUU^Rxf z5Ao*iSV!dpR!Du=RnX$t!Ad%W-S##eS14Rdb_r;{bcTh-U2?sdK~^e|pzy1Pi5y(<~JxD-jIoL&Eum@FT9=pkD?nKTSMHaOz! z4yK*m{!#sXcun$>v)f%fb;{Wt7&`ClrZ#geAZV@a{8|~Cods-m=Udy^{W#;Fz9Mvy;>s}YPL@out9TNAG+o8T8Cw*Scb#1}wmxmK z8o;k9XScBVzrbFDfW4CAfWG2;E`tbxh1YiPBVZjn9m@}Qpsx{>ub57|C>Bg}_yo$f zEV-RpvHtN^8vBqkkraKX%jwhD6whFDaNz8wrvS}xI5~ID+0D$HQlR`G0UoT)`O<>B zo1dRYMNZD)bhTjaX4dn#K?jxT?#v}|ZxG&2XYfyY*`ObKJ zJ+Db9wvMqBpH;S%Kg3%)-f#J_4eO_P*I2b`kiRj(d06Uu%pmN?go;W2<^Y55g^yO@pEL;mI$!UIYkzg3*$3@ z{LABIjm`;((@ksivCEJz>PzD;bT+-bGCmJb#@JWyipoxI91Op_I=+gs&g=X5dU<_( z9kbZx_@+YTt??}z;MX|X{UThR$Cn*$QN6zGom#lg(CPrHwxN*B4PVWg8)!H+z50_5 z15)8EdMY-FA#d~P)j^$4Xe_OpijJ938o?C}0qzT1`DeK?&Gn3<#wOKK{ z+}>60whCdjJug^$7e?#F+6i}OPOX>K9nJz2+%cdQmjif*^A$lbvjw;#8<3 z$rvWkv88DflyCG8>N}-GG2?Vp${ivhx~-DmIt9JYgCzT{sE#E)X)l$X20dEjvv)Wh zxGR(_^uhe}^b+k?{cy^&caRYFLf``aoQguT8FRGEY;WwKwph zvCF&EKZ|Eav#mW&=ksao=ljQz?jK%NK5q}gR0wfeCuKo6Tj%ls)D^o!FD@y^sZ!y}j4b@%smC%1>-{)P6Zh7X@MXTYHnYL!Q{(-aDB{j5&J&nAO$2sfn!g|I+m?P;#7Cx#<4u*{|uY?&-&L z_l&yw{hFDsc|RmuWj#itaTHY?#Sd-{t~f6RSaD@+i?I#I<-sHhaH6u3dya1w7m6X5 z<6~HyMkF`JI7u^6#Mqdm5Dth(?8+>`6)aBDfn+6zgv|X)0oGY}t*f<0U0q#W{n!84 z|K9uC``i8{!J?RRMg|g~@L555Ys`~^-vWnyv*`xc3og>d0T<6l05K6M)P4fdA?L!I zjT|Hk8=PEGLrsHb5?tiLUcx;i7CHA!aTI?^_sq&DH#$7c>$@pXR$$f$HbWsZjst*9Tv83hESzE${E~!Jjb1NfLd2c{UV?o%p`K}E2!WjLFQ$9$ zI&%@vvJ7d4ai)$2P`N%m4bf!X4NnFzsQGz~4$sbJ&=~whpx;|}3&UR_;;0`=@-&Vo z0PLDkIB|Gb=)Wb@|I;W0lNsg=K4hGUV96osl$I80aY$kBZstakVOo2N5K(cW4FCJ-4?HiBq%e6WZwcgkg*4p%C{CoahdtHe1i_*$)o59)Pv z8b07PU@JqIa3E&jnM$~7soTYGgs~aGiuc|I87~jNTCCi@Ly9x+vq zBkgXUE{iU!&(E9G_;ShQc#FY5lvy?CP_O?M!Mj^D7>Gc z+dFHY0dPw9%7BNarUFO@a2XSsFE2G32|tWE%Bs#Q$_k^UY%sm1*l#Gp@)4_Hjs%xWyD|31pP6sX$8m>`k<)|GJ-Q$6;9Aldb87raz zt2q*2Ef3OdtR;l;!5m0&{#w|l9wZFdzUY68jsYkT?#6}V{#q+=O9|?+g!;DIr^bMC$T&4B z>c^yi$0J51=dR!<|8q9f7fXl}8!z4LOR=$6l~ba5Ce^@;!Q~qU$GhJIT~(_Q+*CW2 zFn9r-BA{Q#@c0pvPus*j8P+h;J=k|y^= zh@yi(s*8>PubV#(CqF*=*ME1#?K9cxAPt_2cJ;tMBRU+jCB6P(uDaD$I0a>5tuwuy zxZ9yT)PLra&>tVYIec@Jhc8&&uUF#QnaWYl)9?E~wrV1$oFUbRF%#AH8J$U0o)yXo za(?X|9XBjNjcfU;pqn$U)iO}$L`tO`Kk7vh7fa^Y zs%W*nf}Ibo=G41tvS9or>z}A|O$Eha`*(8GCF@NXjExZFK&GVJAq?J-{3E?@^Y$Hx zLcW8U*x~PB{WoQ_)_gO26?u*R8_Z=~pGL>}^Z>urKF}?e?+yJmpU^%P8S&mgM#HC=sTaD=XClMX zg8!Gy%^ccSW)L_%HKc^`DI)jpFxL_Kurzr9B!T+DTg=EzM@3OPmg#w);*D>@{h-6S z`f979ziocPf40wOYLFu;P;2_N`Fia?!XZ4}|L@9ciVLPSA{uGD1jO?vyb>udL_o;* zLe!uPS@^mC)_oy_R2LW)SK}|Ym?MyOs`hHa_y#0Q?utR# zSDkN&I;j29@H4-J`9&%_wZ%78cl4aHsqtCd3t{4$9X>bEMU6!GDtzj0_B5JkKy5K0 zAfXxs89vP7RlfYNJleG2OWK@iYQfExw}^N6lgZ6&6Fa>zk|8I0NE?pNf|Bqn6REE& zp(C|Nb3<-v=78)3Z+uIzdgp3e*(S4z9MDYWQ1-;2&VJlB$PT^z%-qaR>&7Di0+0*2QJAVdvWm-fpd!Za08*{OA0&X>=`N_$hL3C`&7e-@)?+Tg-u0CGbgi7JC8D)zHhM@58 z4(gqevG9xIFsYArE~*nX?gr z9v-R*xL3mZV(KAtq~Rgt?dkFb0R>md{xnnem3tfUT>ooiUOyR&;X8C6(yMDZ^-nLr zehdppBcyw?TZ!BzMoj%;J_cu9H0OSvX>6>Zu~f$4Quk}$C+(~VPk~QOhF>N!a!1v` z08Au|S)zC34pe&I$;T0*k|X5Se2(duvTq3Z--vSB@3Q`70mdq#X8SKdfTlNVt zPVcs6*Wz({NDXXGF_v*=nA=Ro)iz>Up$$IC^$+n@6VIB?xu3yH`|5I_!+s&%9DbUH zFE_5PIG<(SpuW27kgDJjL!+mE?Iw` zse$&uqPo_xh;u$uU(LCUj6uBt+X?h<3pX0eCLt!JrZu%OHvD|O)-Wjf5B_Ico#6lz z?GK6_=Z{AnHIiJmlIg7wFvQ}9WsPfTI%W74%2yDEoB$V9?t zi&L@QaO(Y`>SjXdX;VS9x5XxIp|FMXvt9EgtgqDmfaVtIWA5(!9Cb}(@?q640>ZjA z+YR9bVYO<1Nwhyd3SUQXgBome-ukf+R;0zHHJdT(=jxNtLmxwiwsL-{VPk}-@l40z z$RAm_wba0t=CSrt_)d33;$(mt^>!_VsgF8r5jt)}@|GRGP_F#Cx1HY$^IN9gxzUCj@= zZ{c}q#>7%$A@y^~Yu4}8nh=qsAt6)JrN-`z0ul>4wKLg1(tmNWc2&Z-xol~y)v-iz z@S5QLKD3{74%$50t9xk)Sle^04rp|)ubRJ4kUjeimoZ(cEJuC^v3ddrT(@Qf%e&ng zG8D?HIdn>CEi5@Gj`4H>FiJD1m+=8oo?lo34Jx3L(IuDeg-;{4qArU*FZ!rKu&7JP zeRqMQHg5(un_n;_!MdJqIBe?C8j8T&VX#H@iDhM*4W5`;7FINdJ3-kJv~+T0_%b5fWpGq9B}F)`tj{f| zVq(R=s=p3qR?9UNvJi5^5Y48W_?FEMi0Y>i@=TQB9 z@xj%A-lK74!4R{1XtMY6$xS+}A(ut{i`8)C2MWuh9!7gF+^;BU>Tbo!jfn0`KTiC?i;f4#aiPII97&#E4r++ zHLHCwwP`Z}9b`yhCp7+y7HhB0_xZ*%vpQjg6)&T@!{v@m4=U$pYd#^q#FpDvK&`N$ z+?uVaVz!B?haS9+hs5^Vxh}yR+Qq7j3=l;)tBtgGBaSFJ*HZsvMH{<^bx!%Sq1fq! z^-vTB53vmD#w>Tj=+o3?U&tL+|0o@?7_eF+im1G3s||&9J$8elxnyu(ejV(%V&hY7 zABN;#XXbR02d|FSaQo1)1zHI1i;sf)Uv8rfR(SLtL*%XSedS}Z?!tg|YL5;Q_my|M z-6K$S=(T`rm+P}^ghKD_A@H-?^%$7NhN1L=gL};mP^ON;`7p+Mr`_jQxy!9SxOrxD z;X$nBuwcDGVxKj3!o-sM{lBkiUFQ#&f3%v-!{I| z*+1ga>aE~h9`hfym%@neVFsr(p5jnT?!M?T;6(O~WAd@Nxo3IayfL>s*HMTKUcRfg z6`oUonoENHSIf1~fk*Ji6hmGDB}Y~+)_`F*wnM>_u@l=30*m(8O{*~aj{p~EYaUfY zo64V(8DnOqMU#DG-fjhkENaORDSP*aHfQ*T8&j`?V2h(Kk@KasdveqB4yYuxZ;M`< z159cEM39z`>2p07)d+M{_;NIC!I!ZWJAgF7)E`?8R!lg5$M8!l{KD+;OZC|q>_Ynq zeXjxqt+AnoB%ZFJ^bB+mXoxwFA%9b>>EEGiwL8E@^zp0Ue&yQj8hwbE`Tn-Vdvs#E z9jXn9*`uhQtuh6BFDhpYTaeVtTRe6uroRI_Mq@v&QQ7~FO~_N_9k!a<;%!>n3Lh|+ z9zo7+JcbP-_sJmgKFd$^n>Hwqk-ub&wqpr%comWR0T* zoHqvV3gK&hlPs!N$p5?1C?ezj{WBIywn7c}Ux zeGZyvCORY-h$EvSHk>TDeHB=c-<*-NOf8&~9!XQ$AkO?=24)2MsIe&xUn%bUBeGhl zg>WLto4~wH(&3iQTAGZA2H4Sn4&g=oB8;#+kHlS^QT|ZS))=W% zl0#&P9Wm!nGDoju@Ot}=3?>~1OgauFCVtPM;*DMwzh166+K_C+%1e?bHJ<4WqL^Kr8p$1)iI5$^K7M3M4+(B4kb=15`%~ZdY2tOY zP(RWfCeA|3$8oH2z5@q@C$;xym3+*KEGoA;?wdqhV}HtslFgmkKSGeNVJlyHRV#$S zz7*98rHfiYEd7&K;EQ8gp>uh*ALqTC2q@$^t==oDuy3}!5LMh0c7sfM8&Uqvmg^zrfr|XdZ zpTJ#*@!YajpaCnrh>k1F*&|$^(sS^vs)gp9FeJe!jAB0zEBIN^&Fb*Rss+S6rO|PX z-C1u$b~B<{DDJ6+_U`lmT;IDbn$v#NG>RWx_;;OCGBTjKC_sE-C*IczCpM=kP&BoX zmb5TL_rE@^h)hppr|q%qp8n55e+17*wb=tVg;DEamn%d|-$Orlg2U3k;Nfet3;j5@ zR~0V%LZSCBJVtWr`V2m?pes`9btjTJF#ZZ(7nM{RzUkaH5_{n~*i#Cq24{)r4&H^f zQZujvLf$SD6x*1e51x`rSIj~P%2xiohDXK;XaW1v{%A+Jh0()%m%95)`Y6f|;$8Np zQbNwhh=zLd1?hHM4k@qozl+I-#9Q?{{BR9dDSvOIaE6c^^*qAf)xzla2Z&uLkpA`J z{Ys&6eR`%z1vl<*hJ;};MrjA3U*Oq}A2XzP`z%}}|LvonJG7lOl3PIxXD(!!%k zR8TX)ycwZF?h|Uz$72UjsCMU^aA&szPKThuTBX=>znO+VEw~-8{!K=*4i#F%Q11F5 zFKdN~2nK5~fgG?xpp|V0f=4Z%x*mZ5k-G>z$CR71Kw&U}kqL&hu^SF16wG0S{}v)8 zE9kOeC8`v1&!NpXk>m4P4>$AqVhiVXJXmgQc>y$&th3V|Qt^3A>Ya`X;^o2^79FQO zj)_0^5c&W~d8OD;F5Sc}liyOf`?-Di-Qgj}3Fx^(x-nplD-DmA?bs*)jjj^HT)(`i zgNt{@$|`yg+~q!t8S|~ZgqJUgUYaD~GVmR#OQGc!|4)XZ5m|8fAeRED<351+Qtx(9K6=f?j7z@_P zp7KG#1jAQcD-?TJ@`Y%^C?G!ib6lh?)PU$(`KMc2v(tZ6;y}T|C73`Me1>+BrxrN6SUlt^hnIhQ=iMn2l>PK zEwnkC9^@fmGYKd=1|f#3(5WQ!!qnB0Qh+8PNeYp>l0z=QJETXV6g8+2_wz`Z^9w=U z4`s(Gbf8TliX)CI=``>T30>Ec(gRc$`{-ay_Ve%jRi<1F`FSPe=OjNrjzbs-BZINt zuQEUXE2aPD=YO0T7X&yARrk*H`*bCB*7>xE`>E84Mxj;(EPaR-KU(W{as*|Eo}cKq~FC zVJJ1KepL)S(}pjo&;|aQ{%R4pTEahx0Fp&AkCiv6^kbZIky&?kisT<{7RbIxh*?#L zxBhzV3O`XX{`@$qYoUXa-`Apo`KDf%;uwnACTmKxiY}k5^yf)H_H2!n!lXt9J_88;uvx zOWXj?<-0}gjm`_Ah8kDs&DCEgLGufEfX*+3@D^>*&>9VMjwLid9C6+N=WOi)?|zW! z*H$Zh#d(AGPb8c-lBG+|8sEGjn!rL1B zO=~6IUPD50~Ahm^ZRybA2tC33Tdz$nlBLmT5Y_j3z##V zLwK#J_z$0?V#Zyd4U8Np7mjlH@c*w`Rr%>JUb^=#qQ5!h|8|+%`icOhl05O$RyohC zlPmmI-9HZAvY>pGP7hT?;8#^xE97AlUBe8k{5rZ6ugXIZFHJf@#NUf5XEadhy~-2H z1W7J?4~!DItm|RY<;e?4bah$9*u^C;^DY6%ga&gGyPm$r z3W|SnUMVvqh}?8|WddJUTwbXu(`pSxOtC_qy;(xdr%Gh@!XHiZUPx_Wvr55zZUmK} zaLnG5<(-oa?+#aj-||fuM=V)U{&9@+e>&{0VQvT2XJno3+KFQty z)y-IRmjoL-3TyNc*1Gug<8aQTDlQ~VbynN#>MZpZgAUg&aK_K1qB_s|dCpctUUh}r zTI{c`BYKH5?}1ae3eZ$}D44co$);ANGGOb7;_4cR%KHd57C39vDbAiaUqTpTt)@c_ zoC?`x=wwR~9oy!24()63SAK`rGYxl)I7C53qi_+U-qDH8>U>op=VpSdJ`s!3y9ZHh z{pnMkDyTiur#44&F@5T7)y+;9sEy!FtI!(iGXf?A(eO}u1kM?olu7>)4$ZSCYtkfs zK&>~rQrVQ zNe^p>z>vS-tH75Ahu~8o_~Yp8t+|Czf0^)WwA4yw3<7~Y{6qj9(+kfhG0Y5oQF=zk zEfY!HYIQ`LU{sQEzbCL`G9N!gHLTnm$mFG(N3xqCdTUYigRgu$Z+0w%KF3 z88sg6&y3Yfo>Q?C90SNT0!007$9kb2p7pX!uU?|^u^9y5!IOxpQUG3z_`)7d>jd*} zVSRZ2TaW#;}?Gi*aPL8R&`yu6^Xmtiu%N?^B;dw zePVH$9#)^qJgmtW+3RIM8opeJXiv?|ig1o`Bx~GO{g0WXBbax2-a>5dlJTUhj?XWP zi~1y)Y~xY!;Ao%Kq$Nk<20ugg&q^-w12LT*26fOpMmkDZSs==RA6xU6FP)(WsWcDGOp@IvbLguig8JeRfE45D;oX`gxb$>a6 zilaI&*sWRax;CCkqX=>V5Xs7oa>NnZ*AcyVQr(L$C<1e1O6H$)0ak5EnWdqu^b}%4 zn<>)cub%~-c3Lz-C!SA>szv0=sFaNHU4Ak6AHq7RN0px%N-Zw&qr~mZq=Ult50R!I zrC&@xq=+foomqIOmx1FGm8xzLv?B7jh4a1MkZ@*wKP*EFKeZpu;N>oe=#f8=D*E?z zTD}#i=f~t-ep(S)HixV0Ft3)^LE;F&>5oH~z!eXrY5eV2w zH+(P>)uGn~SYlVuImxN<=4@lLd|NrHaVs{x?lCN5`CzbQzgvl7Bq&S2ltj;j~YCEe&R5XbvIOKNArhtcA zxD`(HgX{8DU08)ZKBV?;(gkJkZd!Ra(`xf0G=dHIZ!K1z4CBA|#C={SM!zFNh>h(z zbuI`24WwVpsXz02f|Tpg_yLx=M)mFzOx)6-M)uoQ?w=C$C=bX{a9O_U^nzLhIMco^ z=#1>8%!(u3+rt9F9yxkdi7W5>s|PF4uy53RQwlqQiYkJO$VQC;rpkoBXYi+=%Y;My z$aq|fWqO2F5Lsz8r-0n;RQqqIK0CEjrYSgyHCY@6rO2j)Aqojjsf-&^Exw`&g!h|W zSf}WmzLJW4BVwilukpHTiFvc4xw(L321r}1#WDa^~LVA zsIp8@a!X}r?@u;=i1l7<5{Kouek0lBY-(R`dU5iXb1Sw4U*BB+Fw;;vJ?X@jk?!P$ zQLU(}25m__KP*T?)?F1mR7CXXXgUe-h>A%M+I@@xo=qq5e=$i+?#DPEJH?7cm{X0d zIW2`E0qtJeXPsxznD&*rL0F+pp${J2xq%44J7GpPlpDbrR3(RlYa3aT9@ltA8c5lj z{yT+XNYLXbtH5=pns&Hw#E5lvGtjU0=U(~=$%3Hg;N3D$%x|GOq(R>Lh@T`1TeYi{yDyh zay00qRWm+=s1;?2Sx3n)E^|}{auvHsN$61_Xtf_nLi}jhkgY!`1E40(UR~a#DMLJ0 z=A@o93=zdoY;*FAJ5BDy!WIb@g1F47j6`8{7V{7o$&nda-{yLFl(o%OdDS6iPBAl9 z(Z6fZ!o^_AByC1b$@+&yP&de2xtt!HTQ6Up0)~2DbeonqV`^O;3&}22p@&7YOpsI0 z(Ub~5(sudj2&eY$il!)}f*<#P@_i~_hVFnazpn}kiem7 zbow$0&B0V%;09C7Kdy2ko`htuFn~J=D{H;Bl^}yqCQ_84->TF3P(PFwj1LpZ!G0|W zZtk&497U96NPAS(QsR*gcxPe`h?#oH5sjZ&25iOP%u2&#G=D|V@R%d1Z37imoDdvS znUNq{;fauUB3Z#iyrln%tdGI`4x1UIhe}7dP^6kyIE#TJ@_DQAT(Ye zf(F%LssQz}g9yC!Oj1Rrplm`Om2(lLG#ayWq7#&8l;e&tdevJ`o%;#`!tC2F&Y}AR<+GKj+|nwUwn|;T%-g0ozSiL ziIQ_Wyhx2f-!_UNCkkQMaPxhJ7^-^RAH}+4p?>DjH3tMdMbf@@a*7knu9y00*Zbw7qVnJ|hY>#r{!Jf%_NIwD<}%6iS&;G4}! zKZH*?ZjdV`&9TwMfW`G1n4({p&DB0ef< zM)9|h(HJl78^v*^a4S9N3tU0#(}-EjPQzpQWuy36QBxY1n||;(2+c0Se_SlWV_mvw z7pZ+wb1UI~GGP@VO9bAI#&ld^6({zcqUgV+G^Z7X7%ue3@>LhxCsJC`qgIip5_nT6 zY!}hc;9Sfo;tkW6B1SQ4;T~o&t`%`#rKIV><6A`$*L1EV;jnnLiM%DNh)|Crpf9b6 z7^$-toAd>jC&7_MtYT;=!a=SVbwT9? zCxtPH;EvpNC60%Uly)$HrIJxh7Mn&91tW~2Sgh#94%l3Zy$|BcPm&Gh_z_DCo9Gkt zk2TS_JYry<&9rw$T(G?s6WJ-V$haf@pXh2*3)|BJDA|V5tMB*v1<@XBK>9pTyk-@$*L+Se z9|&XesFB8bK`X9c7f{hCr3gi=aZ4b01F;Kch6P4dc5qA{6iS&vL59QT)Mk_rX0swg zuSvn_o}rAI#gY8i;!c2NTX=7^k)^r=~2@`Orl zcPOSs``s(|Lm`Pau1AMs@?czYbMw6^c)#G8Ljf#DjH|_L-4vNEv}Sq)|HoLwMLUJl z&qaig8R^9%N}f-B2W-f#YEO*@eFGqKCk^YR`+vMyNDJMF3ch_FQ#ud#vH*Y;dwd>9`UVu# zwD;Dil~3&h(Mtdai+i%5z9)mZCfj*PhJxhEot>T*>+DQBnZ}L;S|%hQA+2ULc>ukr zl(c!NwCWYPOcf}ejqxnOtO4lL(?*CL3=`T2Po{vfmj;BOxN?6r-ABAg!e+8|K7->< za3W$Kx}Uo&02^ZM>+pvxYMV`MnyJs{6ZW)VozDowwP&i{Pc(MKK11}w+c$-=CIvA~ zKX&gXH1o z?rDe~lM6F$aXvm3ho4uYQ`-@_u5VPTo5nAXj;OR26ymYzy(LmZ@i_Ps^-3nJ%0JDh zyd9Z}m;`G=O(1m)KBm0fXAeX{*S0h$g0c_WgC0Ab3Wa6{#g%Aubx=G!Q^9c|GANFP z`rx?Rs`&D0^*NeR>FwLmU`KK#{FW4c)wVYq_1-o$W`hf zsJxgBgL#Cuki&pYj`Ir4{1eH#o8025%Tl@u3mhl|k3Pqy0J<+^+UXCa%h-G>aXky6 zx4e~<91@YD+E0vW_HQfuhTIV1X7RloOq@gonS2h^TYDVYd5Hc=Iuv%1;akX$xW$+? zE?B2g9!R~~Gl3_LS8CgyP^;jf5tqf8BwOPgD4Y}egLl1;NOXx13pGumg-)3d0sGU7 znU4OUtf&?l+}Z4x$Ykn!P@+e2;hlv|Gsm5g7K7lp}=6EvPr`lN>{JdZ% z5Yi%7;5(8{mgkgl_2wmiKHMK4%c|ospF?_^a(D8owaok{C3U=&4C$~3H$#40pmH)| zQ>tg(9ahE>t0bcZQ;~>Em2>oM#(8&iLZUj}3CGoOroD>+KU2mJDGwTjn1a55QgQo8 z0?g+ZdJmE^esmoF-TuTSToZf(Z3DZ2k}MAov6_%j$5Z2^{`)m*a1Bm|Ksv%DtHbxQ zn?hWBFU}kWl@zB|vM+Ne$<&8C{CfI8;hBe$p;}nE<{nY0k~-En2$>t~2V5y)ZrnST zGP1G3;k%xByjF@)DQ#|u01-%6i4D~GP*Q+xI;0a@6BEpN8i0+0`b#CUHDWpnE)8{F zA(Z&37Qu9J=oTFb)6>dB7R^^k>92C?It_oo`^S}@f4no!tLwEx_>YvM)g4hkqI}n- z`IvIqIFkCld1CejLDY^g^R(zkwYKyzy?R2aU5+RyRpT-31rcAEkzxr)0pCWJw@+-) z?fOd#sJ~>wdk+qH;g=3C|BXTxV&>4gJ2>}<63i%HRbjy2oklT-&Xur9%fGADchAOR2`iMlVnb?eEWH#88}x|q;h!U}WkZk+?pSy!@G>Ml zcIigq_%L?fVO(t=eFt}{97S}lu*XvyI+c+|~ zj>_Y$e^IkYa?IO=-p^aA!*+JU09+$Y~>rA z^II}*OX>btOpx-qfke_3-Zq6#`BLMdo90JMCdfr zH&%*8+t^UYi|>*$oab=hj_{nd383t13~MH>2Jv=PJ)(?XP-G=4>I4OTJg**O_Qvsv ziQC{GwdW6wtHuV}Hd@t=0sK?PgDGfl%vZ)uOfgNId?GS%I^z@eM&l3wHijUF2?Ig{ z|KYN1bl@-#z>NoEVCx&iWA?-IyHzi$znJix)NCw*s4m`fP^!<7wGDh_op8!?%IV0F zgy=clc*Jw&N+eky&Az~}Sqp;w*Iy~^fvJ4-Ad?b*3_94@Dq(P~#Qq z7BxOz_ngu5t}`0U)|)3?LbX}jQF5p~KH^}8Ij}-9y*>a*pOgL5$?V(yE9>(m*#*H} z8**)im-LO8wGpHetF;obN{w^IS`u)4Jxy3dP^BG)Ts zaJW*ogZ>L;tDaNBoQol;EuF>)WBMU>GlO7jrm;HD8450|Rqd4^Eo-AwR&YW2M}H-} zPBdu6lyJ!^29=058a_0`*{2^5lf;|R*wBFy9jnm>V)5$D+VC{K!qAl-$#eFOW&(j5gF9I?w&O zXx39#EmVD(;#KT{ki{iS2oEQ^kHYUE>pw;6!or2QISm=|#ra4$=Fwv}6Y?{U$C@4~ zHS>$mW2^#m8%yzUyng|76VXJ}t_1dkasfhmtyhSWK0Sv5*}s*U26 z`%QBqd((cus62e)R&81Z7`Z>(6zoGNCYYO|2t4gt4OoD$)|M0faqsndSCmcL0$h>SU`s9MHzCsV-t8YS1;C42Hq<)Bw!?nVebWjnYhxJ_Z}dJ}+ve^%pZaD21IX zxgnB-(r|o&o?qQ!IyWx?P{b@1x{Zuawdn)|k5B8%+SK=a+IUf$3i;G-^r+fi)U>VE zddItCL#XXG{Wd?C8g0N%QT96i9gW?L68OAN?KUV4SfaX_ljgj~i&s66oC+)T0)DtN z+ZoJc;Z>^dC1@ENS`Z)ZsD$Zw1%>7_v$_C1cV#Tr8CG~@DyBXzD3cE=&&4{N`Z&S& z+P*xiG8*!^dLQ{(_vMc2K|F6O=Jr;(=Q7kyeZu&e%t0WnK2&^F;W&#jEj!4!SZ~e8 z4&Xf9nX!KohT{586T}Ww*ztdIR(XEj_&~we-;et@HaiZsb=G*jV@fgQL!8#jtYX{7 zOH&{I;`Ipy`;86NUFze^8Coudlb(=Dl|s>^%Q z4BTb%v8Mec0sJEB6M}X@*|R=BDt~J=eV5&71|;Jn>Q6_9y_528GlnVR^0h@Ui^^to z6tO)`?uK2jUrYG)?6Sqx8g=3baSq$dP`&|lY`3u`0V|ssn}jX2KN&cK*Jm_EKv`ys zm-R+^S_1$$qX`;(#ZzhxsZfA3C9z)@`VX&gSEd~TV7wY$HL+M;T6sR5LEQ5$2&GUU zcy^{QFFdij>dL(Hp|Qr08oP@F;`+~)=j46|)=|*^X_#-dUCqD`Y)wsZavxmv1;`GI z0uXC+c>pJm3zxx{B%d`tu?#1?&gXWlE#=F`$L0Q0oX;@yAl_Z5wd$@+%0lPYm^`zcT zPoL$|D_9-dXdDgY&UPBk<10P0v#gw7wBR`Jh(@?IHs?Mq2HA|l*;|WYVSobWFu$Ig z>p#ttm<~f^U>^)S#E>2~zu0GBgVvs4nR!d(T&^|Sb@-K5X3@b=3{g=aIqNV>i?9r)5!v{~PbW*t(d;;aEeRUfC>SrEb&h+K`xxFwQ7(fVM zg<;2Stu_>h)>J6|sJ0ftD>u zsbzz$yeMVhKfaQ&BmlLY#*i10rq>7@AGbP<5Ej6G!y{~yowVfh-Bt&NYFgzuvH=i5 z-Qg>h6?c`l+F>Ul_n%CMF#E5D%rIf#yE=pCNsXl8k8fYrbh^J>SxK*u(Ai$Fo@{T= zf=DKM4;@JuRr00A4GnoyS3x$ts*6VtcYZMZ8Aw$mAMLMNDAKA)XJ0(r5#TJ#G=>b7 z8tz?JTa6VL`BKkQ#$;Uo(M+QM7-vgkhi&OxXeYrh+mK>2Z@(uVZxe$l^7K+74G+gT z`FcFoR_2sz+S9Fc!X^S4nlE$uf9W0mq4yjW57U!kpIhGxALfX4khI25@6J=JpXe@z z&1h!PMS2tRNkicSbo=FLw<#Mj5m?uAp+N6yUk+POidvTU()V$f7inIXP{ba-%KjK) zr4*fBdM*JWRjqtOh&yHW==f~rT@@X?WCxuQPfkp zr3$Td+V7w|Lnh<=p}OCLpM28eQ?Gh|JeonxU$=CwJeydUbP$|yVd=``6iUF5x=aa| zKdHVLR11RJyq(}pN16TQC`|TKSExHV1d#E_JD=iJ_6*{GvtbT<%37Ul+z)xPSyEoO|9Q7DUYSn23upPt-5uAys3o?nDVTA^Q`&`@N1+@ z8;q@%d4s)IL@k7%o`G@|EJ_XHb@u*;BxDBF`;QjRDzB7ZgDRiK=d$+LsHk@Z@3Bn6 z>%_FjBHm-Df!>B|4qRZIc04sQBO?lmYzHZ>t?X5kOXf_H^b3-9Ar~?+v#EhyiJ~?^ zKd(vPL`d!{uheQ`oX|?GddNte+>8XJwhL#yEoDz}S`s!tVW6fHeJQu8hZ9zpuSE|` zj=Al+)N}#Xx0Be)*?Y6eJv)|ZI>8wk)}z*ehT2IaYuIA8H2@zq5gqlf zZ-OiBQ**_fLxrA0$)1G@6+b!-K5~daw*5^`7<9sYj~UZlWkhj`5&ZFrlMxgrbq#x# zQt+rCdw@WuJxWdw+ZnvxeuJB&_NkHR=OgV$yIMGAv-eb?9MT8<*}~a=UfI$9xZdq5 z`Gj{#5HXLHNb86&%m*PSV?iW0yz2g`81j%1y!}4Zo=MRMT^80NsjL1!qu<{PbvGP? zkiMT+pNPRDKdKHN5|jWRi@Et~j68PNW;ES3f1c}SupOqG=GVf=WEj3tz#XIhrAlqn z%!ItWsN|W!=8uGr=v4l*OT$wkrT8xH#uOdUhXkyyW{_1R`-(7(AUkG;IDDO37sF`; zevhW_;&>g~tSDk@_2FHGPN?qZi`#y_v)${*)-Tor6*73=-fj(Pw2GzsUQ`r%9mn0Tfx_{b!wE3AP`5|+A& z=k4MGRcXyaa)v?4L-+MEKeT_G1UG#@cfCm&ghpMTb!q)ZI>Wheg=ahp!()cAcd6A# z!|RMFJ4a~NKJAT>c_{a~lgB6X3lwsRv$%F6Vdsy|1a2=HO}hkEe8G>eD$mcDhdVpi zv^qO!g@urgV29hUXEYJ6n)w-<_2%)tNUApp*3?e&Uz~$pTJ71ll8F+(CguO``#Rf0K&XOR2q3NY(2Klgm5wmao#RNTNu*RpM z3CiAtXh@CA3CeTBL~U_o$YlQ`0!6W#&ZzHiTwWa@*hhOnbna~L&)E3~x&38Yb@MdQ z9_Ca3Q#sb&PMD*sN~<@(I89juAaHV231Po2;8bIK#umw;?oPrJIHfo`se)Pc;{+>y zeVAVZr^d2Ygnm%y_48};5qd~P{>$Dl57oJ^FiTjGyUXTpW?=>wuR2(Ec|<8K`oue7 z(cr_%htf_>shK-5F>pde98|0h7 z)APJ4VfS~W;zcCw_~XTl^UmT59Tyd;eL3xCV_KnE+qPt~D0jaC-_`N;?I4ehA(zP{ zPW^Zoz9lOqLaR}v)U5Rp(I{kQof2mkinDeh_o7`Ogk~%s0o%dMl_h?dDZ|pBu#R;h z<*qn|;x)T4d83EiAyB3b(#X>pU*z_YO<#P?&+{0N?%)?CE1%qRez7p;bKTVj6rOoU z#F{Ox6Vj)810hb?XmAMqt;g;9`Dl3X9C=*oQ%*8ireturPf>yN5OULWAYRIPG3@=W zK>2V#k5Dl6!O2jC7d=Y;LB)Nx% z87OV-7d3z4Ft@*8h4QPmh}5e<0-5~!_5#7U;x#A8P`n7awT;v>gnUF=ptwjC*8Ti? z^a_o5`E#M&5q{ZXhagPO$+L+>yPrj9XQ;e8k{+>Pg+vyvB;wc(l<>-4dc-1RHwj)e zig~s(t-?RZAj{>!gxD90&qK2AAkFE^UOp^nBe(_~=kmN08(Xx&DX?e?#T)qix}O(0 zeXbTgX5~2xw9Lqv8su4Qn3s^`^=(A^$;aG0s3N6do*%p`y^HB*DS=E(?_wEv(d8`( z>K>-B@}5Di9`9M$yzGxDpK{GsI&RWp=#hATtn?54d<+R^ZXOz2Jswx7xqk_bH=V-B z0KJ6u9)b^ZF|{><$)@nj7bhoG-1I-GH_z&)ngp%47Tv~j8S?lgQu#E8HwJ^hVq|1U z%s!g!`eQIq(%aZI3|>@ERH9iA{_1>A)CyyHw0CHtsndNhX?~1ptNA({3FQkCA>V3@ z`M<_gLAI%q%jzMr@)^lt$o50FB4$u$|15g!RZMH_M_GKMvsdzq&=}|IfwA=dN}Pe< zPtRvAfjoWy_@J{9dUkvgeQ4$C(s15Spg$pk+$cKtNx(aK)6dvS9AgTxX6AAMqr#8k^ zp;CkmCiR~IB6_m6MFM(jqDO*CqIEiE@?=XKm*{N0og%b0mWJzDD zG*B=FFiEQXTY{*;chx&*x!n0@9v>}}4XAH=`kbV}>3qCALFGt-j&TX~IO?3M$BT#X zr>e*E74^7it_uB2^YVDUe8gLC@q(lhr=Mi*Z;Sqk z|Cg?Jk8k5V&jsJP;tmY%AVCR35O;v&kOWAAGNYkHN~GgP<4a<>xlNSBanr;Z(@Lwj zPCQl|M`A5I3P!CdOUdT?$yT*Ky%!R z9;mu|xdZYlqiq}=g9)$@HzX=0caP0hmDNL;Gevi=QgHW@=`oqly{YiE(ijxoB(z1v zbFF{}c$#cIaZ5hTAlr#U&Eqef$20!YF^RJH%RMQ*F1UO2)@Fv*h}B=Oml^H3n6-i5 zEn^2Edn0qzKiWiDm%3lhV}tQJ>~!yoF?Vl}CDCS5+UqExYp)-S+ItPQY43%V4SZ27 zv=ushg5vJp`}&zCYn=}cr`$0&3SAI3)jvZW^vDO%*6JM@-rXCbKpH&eO?Pi06LTa? zi@h1_n$35NF5^=_caU>`H6q6<-^bC8SBzsR%-o2*ks3vjsW?^y0yE`ofVktO(G0>@ z(?1$98zB1}koFSJhUo4Us>(*Wra|n;-e8n)0X}u%+Gr2ckyXQ$19(-bj`l(^<-Zbo zBq55N^vmW3kA^_@UK*iP$V3>3NNz8OQex70y+6%KI&soQDJ^XzjMvLOoN|Lp8?Q&p zU4_PK3YDIct;!qLQ6@xI=Mw2bZK5P;)?x5(aAoo{7GJrB3sY+{=52yaCF}0RQ_4mN z7k~?PSZQEGu)9jl-AiEA4rnvDWJud5a62S~XnUEX5cvd0hQnqP=5eDkg?&~qghV9Y z_u?=$dt$JRddEWU9!RtH7x1mxlzj)X_2x!DQwQyZ32wmD?b|Sk+fdI`R3z;8(&;*` z_*bK>yVswJ&X3+zzB#&|@z&GWXQM)xTHYaBjChIZYSP-+gqk<2z9;GKF@J&=1T9Ku zk8RkCK;IY6Byza+8XK05k%vlp&fY_kF%U3RsUFKY8;mj6OXImgWnhw@{8Zk3H0Epw z+WR^8QKZ%*lV`GP9zsi`{SV-cgz`%FbORa3XcU1Spu#!5iUX+Ebq1sqmh}leOna~& z0MD^%LsSE`RzyA93F~f7rFXJVeQE}gRN<7gk{6u4*3^^=4$NrJ#o|i-ygN!=BY@FtlyK+g3HZRWJ=CNOFyVQ9u?3`|2OqvH5rOgyNL?8=s zqAMa$yOs)4|J{WYqP6Mx=)iI-{N{)_^>gL$XeKv}M9>Y;u5s0`hdsne(;ne2CP4=v z>mm3hUuzFqbo%(oM(RzQc|f|+NQGUhw;Kwv8np*;v)Ab$S5t_32Sf5S+Ji!|t<&ON z%uKl)wkPw`R;xYTbGYVqZ^RRVuR|TRwpe?oCFHgM zEbdeX=T@J8_5Q*wTai7 zCxIo7uUe>T$0uSV3Ga*-f{Stdat^g5%!A9Tqn0|g-R#^Q&Ng+FVLmzbyRf)J zy|=mDnP>*#^(y^N;i~ac9yR0cK+%Mn&;b^FpI#KyHm3@LCAP1lBN<3At6Bq4%a50r zw1s>_;>TB2F|%(qkV2y3*Y#OsrH zLXo1c=wZRQl2bHp_(EUN!tG0n-XOg>)}a%fLw!0io>Dg(`)Iuj=dO?nFvS=eUlpNY z51A-IvfeLk)~0XSxC@rZk66Ym1@)zCwP{;uT$$FH!c{4AV9pXV|3YloR2b(#yIVs- z>g=2h3fk8NpUJ!|pC}C^wsC3TBKL?s^oxBt(zxEEMo8Y_H4(&y#l942L)W9V!d^dQ zATN!y0*ib|x`X_h#I}Zzlqci&N-&D;vuU3T`Vn>^PrMP&(Ci3k@Ah1#4fZm9IYwr0 zJ<~?9P{gYNu;vPe3qL5e+mcB3RP|y*o#5J-1t!vjN`tbZarJGvimR<{|dVQ2F!j0uuDKWJg6b7#^IQ=S*1B)1B+f(ro6s z!{yT+Qx7)c1o8_G$G~(9<~^}S5#bdcE*Mt?3#kJ z9&{`mGp)21=S?asTal1*JfFnNMfq>A({T)w5US#ycDS#+*yNCKlB155uo?mN<$85?QIrqW%ub&Li>FV~f-{+-AmrtgX8Uus5D#*Rkj7|_D%_TI3Bsz9I#~-qfOT2N5 z@d1JnYO#yzGHX6^|K#;t7sENIhNR=lOa{FnaxtBrI)!}t#o6haatua(`9=y*&4tiC zz3=`Z>-{GscAY+25Zp)Z4MYEmyM+o_5v7e@f5ChN!mD#<;ys%ehz-d-`Q=$19B#jp zdD-dZk{W?7m|v9zG9H~rTavjb$%jwR(qvU!UiAZqV|WSSM`F2^#;S?rIZsVoaAT?X zf|{7P37^(D-b{CN4&Xh|5?YA7^7qFsQD@bf{a~otXaq~g=Wq9vPLoI*&?v!@AtSxN zeyK4dAR+4R#?0eU?OVLxttJX4-3dAd1`J~KU2qJ=5ONM{`f=0^Lh2*r8~sU|^o@i2 z=C@Ge5K;iOPyQU>$_!{w&y@G|8Pfg@S-GPR64ezZV)T%S9I$NKMuzZ6osXkm;XaSz zgLeU?FsWuT@)Q=|?36|kX|Hg~JRZc~KO*H(l(ty3foH07xt0{S}onn3M{@_Iix5mKOsD8HjAB$d># z_H4_TILSVjLW)ypT*ST){*mX_`($3To=p_H{VF^=8t|fC(@* z?NH;PxcoXfu)_`&8>26knl97XZ@ScYBd)z38s)MrnE*_0$LPzgdfZ|m^_`3A3}YwT zwP`uMjAdO9fDG+i+XLduI8aBM2bOi2T0QB;rJKanXKMyYeRI6oi>u%kJ(-Im4!FL6 z2p7)rjb0p%a_4$nX11=^sX1c0OFg9SW}}!zc>m-~EkMNF08j{9mx3c7G3~h-$R~xB zo-Jk0I>h@0-g}pzN}K1D9uGhFY|lple8~rb&HW-$z5*lXx_V zwRtfCh$Y*(IE26cT*{MBm39fZ^qxM!SXJrJofNhLpPEJL{=`F#)Gc@;f|G)Lt0xWK zXrx>*WR{CVe=TgRlXsV32`r!@b5RouQ?qetXz}HJhkLLEqW9&YTq0t}9`Z9$Q)0A2 z$jd;I`}p-C&8qa%?EaAEMm*T>EUT9x*n^rHIjJfe2k+3kkE}1X7ZhpjUN+W@L%Wi- zeoE@O;#@r#M+>0v*=v=50M7+@tDbWg;D)ucEfvAF`my^a&$gN^oiZT&jDd5~s<$+{ z8<4MF-r#wy%scn+&Um>eg~46n)j#3w5@~-2B-_?mO4il#I9M(1%Uz$}3Y|qOT#6wk zltb0;au$s>oGR&$=AIZqlhj<}ZKOtCkTzN6v$X|CIFVCqJYO*gULr>1hzq&9*^Ugq z`Kg{VJ~#DP(=KP5UJ%{3(yB0&N}S7~(NnJ3BpKA$i$f#Fcx|{tEX)HnFUZH+U(cBg?`%Pv8X=IPqprVz4CYPq97&(e zJf&v^jXF>DrD*%|su{S{`G4}V0_qfQb=XSxoN(h(-xN4a&DDW)yJ`ON*zIjS??@c2 zY4+WZG`L$j2_94A%u;d5XW{&`p};V_*5TmVT;Wu>Ykwxtf#TO;bsVuf-LXRTZcBln zhdn7OHNqk7uUc>ng>p@)wdQIT0}2Tw6d0Y!Pmeeh+=nMCX+7|f<*_Dv-Tt#+(+#Az zuqkaJaLZ6?lw*u=Yqp{=^Wn_AU*ZVm;hVg~%Iu53&2s*WG!olS4FRrU_q#6Kz0Cad z{76Xe`{Q{IqgXN<8f{ zP}809?k<1bxvzb8l@6>(=VsiyQ6KYw{ZalF_m{?VE`ot+sYW@6y$__% z`KXrS?0hcd=U9cU%_dFmi;#Z_Wm2gQW&&AX+1y;Lz+N=2^c4Ya)A!J`u&}Q*c^e_a zwZ+OP+PG3NSV+GD458*2<%_MQMHO*^m~SEZ=CJKLT)c!U7p5H^i|_D8ea1u>zhEI6 zygq}tFV-E_Z7#or;M1Ygs7FkF z*uwRah4ISh9#Eu5fa*$9`JsXQU$6lx*35_sb;w>Kw%<>=QC>#J%DF%eoRQ7M69)Ptyl4BY}RHF{#K|y!gBarU9tJfD^7x~A41a>sUnrf z`%)PVL}U((FozXP5USY5vfyU1cr-3g6B8PR3QJO1^s*t4_FPtQ=O*uY)6Ro6*rN*k z#>smshia<8%H?MImX{CMPJ;A-r5Rdv#{&)Co(JMvITyi&M=JVyjrSQ=`OpKre6kI> z1aQ9E(Yjn-sU3o>RJ)D;%N4mimEusyl*^quwr2ZlKgCKPL}O#lI$n!i_hPK{0OW)%c(U~reunV`~JtViuMLh%}ESPh8 zdHvFKPcXnWqa~rw+ab8X>44a$GL0NRq67Hhh(FGZesfH)E?_lHhwB=1aNj>3@h?nP zLq;f{vjJWLDK-rVfanu19S?L(#%GnXbjr&0MYfGa_NrehROI6+`U-7MJvJpuxDn%x zP(j(vrM2-+BkGJZ?gx;Dnt+GXZ07u+>H3-6s2q`iN17i?;|tykP%Is?+ew+>EGq*tM~(j+*1n5PG?Nx>Pc+yw5lJTpt~cqh%d#QL!; zTpH|t_UZ|cnM62t8jV$?y|`2kde@|*{&-MTsw5RC8%br>UyWjfxw~L!!}n!%*r;PE zK!jIPqfIG2JK98Ztj&~NhAM0Mo~TW7uMZFWlcAJcekk8GQBp$mUTJt2LY2HyUQC&r zY^!$A+>~)fBsv_AI)2eyS%X~(r)g6f1IV=5~&w>{kgfSxa&+o6Hg#- zg`o)gu}jt918k$fjgBz1TRA|x@u@l~7YaB13muAUn+(?XSNsc=1O9~&Bi)#qQZ*`k z$Gd=4Drgmx@-FZ*lcslpQ2~koawuHE(cz%DTDE~Aly_krrKe&siPF>e@%KHM1?sO| z;OxyhdqBSc9A>VnZVHOZnHMTw^Db}#iUVH~4|o^Sg{pQVs({^lgD+I=%}Ut2&|Nt| z2e5P8IPb#!v)W7c=JBMtIZ-z^Gx*E?gH}mHb18dE%BuBWX0eGe{w?WmYkZM4H)l^V z<|dUV%}wsNW1P$}`f66!SF!YNP9gk#hLdyX+qsz+jLieH#%90vnJR!@DT?GwovHqP z%BJl5?AxMXPkxGQs$NPeH?q3SNUvC>2RV*DKqMt7PMnmGTkkMKbeQGL(0ql$uZrx5 zd#aX%cTnM=no<3uib*++n9~(H_eH9+v^9iamds4t^ocRIFbh*UN+|S~3G|Vg!mK9) zD4=FWGMLS=Gjd%?sPbc#iXCGdl3uow!-KM^ZJ}e-B_>~YcVT|PLs~(@D0g=(cAJh< zQ)AKrV=H9-SWqdqZK37f3S$wq$GJrXQcXQ7^QE8tgUQKUHfnSqO7g|w_lXC zH7S|8NY-DCPgq-x@`MMRGIho$G@&+zhp@FZg}h>zepTRfmQ}Z;gKD@o#oEWpE$euu zVY8eBUuY}k?t;YiI!-kc)3yY6m%jSdBIE9ErBLv8cNcCqgQ{HBwwOv$+d|E3H>jEI zrnD^%BjR?OC(xg_^a3mWZDwEIYN-HumuEDfP8?=J(Y7G%?jj4X5u(fj|7*njmu*v5r4D%eYC=|nTWSnx@xUwzb^v{BM8z~wxfAC&{9K# zoZ%~7EdDijGe0YDu{tnJ6la`pA&&Bdvx}+llSWKQ%+s%=bcz8D1Hf-Fui+|hi4Gre zU<Zz@!HS-!-Z|4*wWMk$4~y;&t`94C(c zG4nUhJ0j{XYx2zK-=NfAx#sNNF0mot{%=i|GF7#Y$^J$61U>o1Zt}K)k}J*AO&BWc z_|ayLbeYnpu#Q>Znd8`9pGe+qw4wj-b{O9|8^VB?I5*_Is*G{WDq9sr--;h8bYWXT z9zG%OF%u01?Un>w$YZQ@F=4VP1+}};hf%v5d?}s?l8eVU74`33IgzkgDQB}OHw;?L z?@O})3GNmUJg}o(ar8@thWs(Xq(fi9AlwCpY*z-WjcN^C*g6!;L2ypWSPcBq)b}}` z#m%Tx?cGw^%`CCVYc;O{^~>nmbJ-&CvrmRLxQe^?e% z#x6glBf>&nD4E_zDn(;5&3l3m|A4F2LQ6`cR&a+PC4GH^KL#O{nO+rT#2wHGfJ)iHU^RyOL|q1?&93> zh~0$xNk5i~O7YL#OrbGvG!;0w75STtTxYf2Eb=%2S;QuJg+4qRv{stbh}2^Hv|th0 zab*3f(!Todj|R%v^j>-Ygz`uY6JP>$`N{3H^EZt2Ug^4ZJnGFn$et2_dsNt!+SOUD zw)LU>ttTWZv;*HI+wQbvCUZ*Ot`d;|P(=U`2D`Y^iMiEUF5c#i93F||Ll0v?KN)Tfw7rRJb~hx(sZa6 zk7-k6RfgfYgf*Et3nQN}8P5FyFBeb~n@fak#Q6!D;^QF{!F@WpyF;p;}nfAh*KH0b|DAmGE_s#sgTv=Y2ki1h_z7OB z3tBUC)@l_R#N-!Mj)*x?>f~=J9Od#V0Of6aYDIdkU3lJ!{dVf@D#LDkxVC*Vb8QbUSToV%+FTmA`B*y`q(@N z{I0x^g>{?{%?tLiNm!Z4A&4@|-g06xJ`%&em44a%Xfw8GQnPl|vlu;uUQ;H!5xOko z4dR@^I8tFXN*GL7{{z9_W=*UK7_@BhDsT>0)g!rS8JF~Ym`((1+Sl7K7uTnC;_NTv znutcv;sL|E)3&L834)vGztaf#ocM6#>jRJ!C0K?j(V_{IJnD<+ZjTJ_l9&>m`RtUU zF~)%W?<_qO>*_o?ztozx`&!ZYr4{x{+iix?lgF72 z8OXb(Y?0O5`DHIekbgTF0%knSs*ur;nOZJope5L>eJsE1gqK4x#QB};F=)J82kefK z;@w6_WtzQ&)a7ZRkQ;fTw#kmXvAlvz*?iFsx6gu5fhqOJ&_NvMG2O1%ZM_uko{ z@@j^1374twpRm`VY4CV%fQx;04$4Uqg&_BQRY~zCZAr`1O`T~V5yr9J>EgT*5qv`g z9dp|LoAkc+tyW{!hp^qkJRrc==N$$rb)~+KOkv+4&e$pDWZIM;g5eS)>Sq{vx3#!n zaH9Py>F-(-qVgC=3S18N(}>y|XNMBFHQJ|8-fV3S)R!?$a|<#x&b0~Oq^JcIwrd0J zWytAMBy4Y%U$zCz%I@;OqmcQTV#Rub^J0fLdu@GyYs(Uj`%1^^g0s7PvN$jW#HRUy zL+xJMp@hP>ivvqQs{xrIWh=J`TjPbheT3PHfy* zP=CZ&Q1?eY5vNO{{prlVC}LxK0H%;EjxR{>g0TJ*RMlIIolj|B8p@x1KYM9~`rc2G;BY5iSXyMXS<3cg zb_*WIz{zILjDCmrgWNJLnZ3-=d6ARm@08yNceUOU$E`@reK8hBA8?n^m0Be1b#YYd ztfDL^J@UE>`^lKaKvF~mSxb6!tJ)Zn-Q}bXZ+8dhC~qO{=I@O)BwBtU%#9%FarRae zx01EGO@W6?sqPk2#`4>dD@cyIj06}EEX}e0V6bE?qoR(R?SbW|6c-Hk{?Mht;u0}K z$bY%LxcrT{*?pjPCN|)eg9XlMqrJ#C7@b;)m`)Mzwdqqy`x)Npvexe$Nck_Jl}*gK z5CT_6c`c04Ps&H2YHPP!v6unrqGwRLDY{0`1SaKl62*}EDC3kFQ)bNk!JF!95&0$7 zeXSM>d)&lT^HEYe<(%|VtC5f>2%vK@vkbOJz$N84V^XkN>Hpnh8S4Ox@WKiWsd&q7 z)r(j|SoskV$SAuNLhPrs;ZC^~!wHpPXvYV*6$66`cn)6U zOWA$5RwxA5s&L2tEUyMWQ`{<$#-JvQ(x@)w;ai8Ph$_5X;iV5pMo9bZ2|f^>Qud#X zFpIY0od@A|3?&v$#!GEKI)+qtw}tXsO12UJIA^ zoXyJ#GT6`PJ<09x;a200ZWtdTT98uXu zpG1ek%7@~P1;xa6Kk9Itv<&!X;hLTkq#`G&0Rf?X7V%3`DjkkTgPKV>>H;DsCG z)fQz=hUO!YxKZd_oYlGEbJN`s3kg`_PXfvw>zf#OsJpT;0`#R_JmhYC`2P zj*4n*`w-w|$jM`&_+#X>GgnPP&_%R~wFiZp&W$3%OC$`%kdYIVjC>~kaYj_Q&h;Wj z<<}Ko40~s9uTU{38B!*ARe}MWQS8r!)KD-;F2=m~buM-_3d@k-0QATI9~o6_CF5o; zq84$p?Fr3Iybf~^P-X^JsGIL){=SRNcuk; zn@#DLwOy|4TXU)ub z4oHsc%UIvsZ%5$A>1)U)CoBv6B^&eok2^0;`)PoCMghGcCwS?`=_Lzg0=F>R^rcxdh1=bBAWWQai^$O)Vuh5@s%#px)g{V|)oa(x- zl=lsI9?%K{V7JxD%Y4!+gp6!{))sR!NNiu3QFED#?~e)&1OBcLY}6gaQ+AP~X9W+z zZ*Oc_iR5_wZM-KgOD6|@A&1(R=%a-Xdh?mA;EA(0u$3)0^(>E(BW-4rL8jpu)-99= zE>r8FrETYGW%L#F)NO=k6nqW(bUmqrK!Jvv3jVEXhP;DeYCV-1jPur`%|;hJ2?6$3wP z5L`HeDa>eG%=;zafu0JvI87jE=S|!lX7qmma-=|-S!KxKa`3{-`?LjK44k}Z=6RjT z-Et7WVOXc36gSoy!G$YI41-$#lEJkXTD};AN}0ix6^$>qy#grPOy`aT=Y55i&X86Z zJQVNx5kSLWNE1|CiN$irvaF~gOU3du6~~)Y6zo6es5nu?XYR-o1BL@P$;!`jg;$ zokUonkoD_0kXj<@a}2hrf11ZHmBZTeQQytRNBv8Z|SqVZdFUHHlOm(>!rHUiYtqN zAxkVl*=q4Y;4y#)!1_vSIaGWY68h*qBlRK7H<@97B#6j}Pv2+gENons_0L0=L|ZF1 zw6)p&<^J|fMr%3->-8deSmU1x@!aZ(Ov#()x44sQiLXZ-Vh@j!K?7G5^hLd`!f z>gTbesCGVg$s6$gc{mLOtFrtR7Vj+9E`}5!9}bJOL(19$`pQU)jPzSSX)AN+OR!Yu zS!+J?cgEqMr;N5(4*BQv*lRZ&@z0No{`q<&;t@AGjPs4xN(1D^jobZWPJoUBT+aD2 z^5i<2#VE^BZLLt#*5D?w_>{KB2LIhogs<`cpO-~!4Zc_Aw6)19r?aBAR;l7DRQCMy z^RwFT`R6~9GS^ZQ8FLMNVAf)^GyG+=G}%di@rkGLMtH2K5Aa-}-(~SMR>_)cA7fJp zktK62JBAXjxhBqL1as|B@K)@0V;C|L>yKhCjfgSVq|$eRQdsMt1;ae&>PU* zsUOH1YpA%oVRt8&Rfj3rWh)cz4$IRuFftChI~Cd8Nsb>-akmbrLPT*PZeEk|GKEj2 zqxKF`=dASq+ss9I^7o^E!LZV2r}lY$odZ2lck=~nZLCd)521;RyOU|&Zr;L0tTo)i z?w6D9PRL#Zm!kJYa(6_{Md5r+wEq~t$Hg>vHdc3c;)S}s!`KX?$Et>=NAVumcc}QB zFxT|{WS#Y%4Gyo|!v&eXCE07^VRMaDhN8POoQ$i%V-lAjJ!vx)-o7gx(_#s8Ew06i zhn2PLn?6YL1^3nBzRqwOl&5y!4u&BgBu7N=bF*)9&Ke)H*FuI{xoNM(rK^Tpk7kvf z(oNgt?X@UM!iLL&DKR4-6!leBVr$Yj)EnbpkiRH;JC&@r!|(=j5t3jLYq&V>gyDu| zA>13_(?q9)?N)XTce)Eqx)+A|K-m?HY}6)2nLm*f2*s^~n~}!Z_=6%{G`15i{E9qt%J~ zpUXGxEdEKiMmx;E9|w3K-q4oJ;G>DSyB4>0B3^RxQqo_WlIC?{v~)d`v)0O2JzTH* zMT|=L0g>FcLMu?~Mf4Eo|6|yiLa8}i z#7}|V$PqIEptF#y|vKGo_Q`@yMG4`jtmY;))VflBa88UXH zmz@XtHL5ueK)be6OQ_9E)y)V90BT^8qheg8s!9+^Y~Rdz0fVKUP~j6$0W1(2O%`kV z9i)?V^9l5An?&AjHiru3DF=u8O-7vntDaHx92BHJ`C5vV!p(#+MH<^U8}dLhhn;R` zF=FSWbIq@&IfVpijW^}{*t2y+6HyqCAIG(wQqx0ku@}+q*(PZQFW=8_FeSTei5pHPSA{X5s?++ zKhJ8FkER&um84V?DZ~vgv`S^q~npF9T_+UICD(l zmJi%^SeYcO^_w%(KeCDQe>*p@DRTu(j%k`aJTuKZK(8r{_LXU+DmrHRpDk|dsWJ4+ z=EL+E>0uBuy1h3IX8BsTCm~UtiKIFb)Z>j-C*~7rC<$=V4WB(6oq5Yg95#b`idiR* zHqS+8SPya93^BN3OEf?d(d1gwU1HpBx1x8;ioYcIo!Dp% zsE#?BwTQPM&94f)@)6b&cy&cUaQ9cpZ_Nj`5jq&?}o?C57FF+Zhd{M@L4%0@e!H!6a8f%6}J zXZY-ph8mIaiT-In*&d8CgPqs6dEOX1p0 zYeYWXyWJQIgPt4lKgo^&C%Y7pdW}mti-(|N=j4oy_A>C`=p&-M!`dOP-d zUy0at%#Q{&v=B1Y_D6Uf+>Nty`ora?%(eFQ2vng>Bz%+J6k3_a(LDJ16o#A;Z8!4< z!0%mnwZ_8&x{gQ`^^d^!kELY3acNcN2~pPbf*%r<&#nEKqpPFesx_lV7jpHrScllY zn_~6Z?2HNxv4;|p(AY=+ZKO!r`$%!ENN->hnzX9SvQ(;j=X1RM3BkMralZ{Y@%m^D zv$uV*Y1e}xlCYTL(n&6*lOR8niv<*on1cKbu<5}@Oz3tUmvTlzn+h%n+0}EoA7~8o zfd^sNrPs{x;auXDG*9J(EeIqGU(6*y0Jw}o&v0|T?uOe}g0}bm>9HkOD9rgt+R^&8 z`8pOonB7~_zQ5UT6V^0T1iK6KawwlxS^37E*UcwvAbf<{J{mQ%+Bfgq@1=WQ7uiY5=Je^3}v2@nUKRayB&?cZ}QYkdPc`_I*(5NfHQx)c+m(TKAJK8vl z90Oyqg;_h&eIuzo%pl7&+cDYZ)je}N^N$wW*vuo<>~_kl6ox1RceoE=8AqbkJ)EBo zD}Bl>$-t=grH5~qdz$P;?R@zf+WjJ&9QHk6dOIT?|KvfQ!1P`zweuq?tg1+ZD|~*| zWe(T-Z@KW${q~9H+Ib!?#Sz!8_dPyr{7Lc#{+VfDNr!dq&7Lhr`1WuW-FI?uV4vYlgCui+E1n8&B(^jmEm5sNB4f!E%#tC!! zViB;vld)68#r^Q$4X&pU`M-PoR3ws9TM>ubyRk>o@_Zd4;)GmD97&n^I$VRXx(lt~ z%l0!M!CKEu{eUxKqR&e{{dK3`mf7)DFW$Mls0%AE_S+I$7@#b9RZBugKB7L;tfrvA z@LgR5v>DV{yRF3}qpGO?^xpG3i(ABT@UA_N7(LApNycUqg_2 zNE6W9eyPtmuMsaX*|_>c242=RyIbm`tohWZge8|<2yd^r=UDgQ`S4jNcCl6uWR9Kj zLw2_oi;g-ZiON}iIN~5@@%DX+1HY4-w>yN2`8f_dB_lT2k0hLK`kEGNqTL7RPiJ_o zn|@h3(yY%rETTo8x1r(_eG1oTvPvt0P3Vr*6qY5dWAa-Ig~MLA1>^$-)cKG}tlO=n zI&L?8)9E%lsDA(qCzwa>3sn~vm)vgos_{FdWtD9j)8pBe6MGTPB;|E0{c1$gN_fSQTL{_IVXH`ES6P^i|N2h|-c*q5p7oDZ z@D~En5(uG(^Y{pR`;~|f=pSbRY;YN53plUamc~GCNSa8b+MA3?=|!iTM^zI^li*+M z5tIi-o*9+QFQ@!cD6W-YrQ>Rem%o?vO9&-KB`)HZ5+EFnn4E5v-tDL8sV%EC*h<2G zoBR-Hae_)ek2a6;kwl)-TY|D3R>$s>kA(6_NqinqBzBvnTWV-#>dsLKs6$SNl6Glu zXEO7y*rOfkoR#Zw+Z7hmDCuVe+z1?c! z60pIH)2q)W5K0?MAS64nV#WRi&OF*FHO-@w7jbi;!WdspQ{4)8F4ig2d9G<4<@`Yo z=Y71DN_alID7}!fOXZtJi5VT~&ZPq1D=McMe=(+)I@ehv-npKZqvacVsd2sOfh1vn zn)R64T+*QFYqR$KEAXnk=MLSNPU$64NzU%4+;cSE(@X8ktXW(^BQEo8G5fPC@X4Ut zaoH#}wwqd(MwRx>rj@~H9Q14ynUnUp%y(_-hG)#rkF#>NcQ&oAw0gWnVRMCnvpevT zWW-SiAhM{qg@b#8@v> zJ)hD_k?4p$91q;nPX`!bYCdLvT-+_aplKz!(d@0NDr3=7g_9&b4B(MKDRbvYu%*8FbXoU zF@>F*x-&WwbNJ(=XY;o_aWYA4x{J~CUImqG*# zQRb487v%rYxj1n6_UVWL7ipXyZ6zQ!dfi!qBh&eM8YS+tAthb7YHSKxx`7mrz^Yj4 zb=aDu^IpM7BVjIc<6ox|=nr{|xgT?;_H_q!=`s1vob`n?^?w+W(?JY%sDml z5$Qtu#}*nE0MmuZT}svJ$gxW=`)6B;h!Q>|J;bS{n8k&`A#%9v8|q*44yyk%8Y1|T zFv=~V4UQTX+*~$|QayYj&STnF=8Vw$rEB@LOn*iwcs$T*<{hlZ&yID>t#&M8B9XeP zvPk2*7c&219tpaA0J?$xMzNr9<>zv7TkQPN2@eY*clczF(+@CNP7CfN<8#P7hE;Iv z_oDvi!G1(_M_n)Gy|Cavfb#D;gpu+(F>1D*>iNv!bMtv^9Y8}33-~7|vK)Qk?xbf9)h(MuIkFEMa}6woM%Tq?e(twq#dgJ#q1GD5p!@ge=Q z`N8OpLW=$)P-}8Ft&3ghq>33mtCqHwyD?v;!komj3esLj*<4s(pHA{I_}6jsf2m+{golAGazJNxL=y|Ri?*i38arc)~AZ7!mgz@g^L(|$1@QK>U%(%&yd zXi351UChQbEZ3J~Dk4U+ROtdj6*5a0mZf?`@xnw*@rnf;4aX|KKAR7Gn{s~iZc*dL z=ammPAfN`mgR#MDQP^PKN_2+vc<47}wy>z6ieerVMzO6M{h+^D0R@P{RXLeWEA#;T zs7O*9t4C&Jru?#2+BpSM=&4Ysr;p`_n#juQ`B^*4>ZS2K?kMhRn56Z(G6eD-hIGVW ztZ(wBh;HJgF^1MF%X%pu4257rteuSLrQz)CytJMUeRo`xFO73fF(Q{pUhgE9tpL0Pl(vyg*=KSS$F zv-x?umQk!nSS_AXOVGQK*3oa`67mB)?-dUuwSWZ3DboafBR7hr5{uIcPol~4!V$?B^gE@FQI+UMAC28OMaX&E@HS6VVr}%&#hnw~($qh| zsp%wBUa48l6OYP&S}9i2ZYd+}S;e?p65(>AlI( zdP;jwB;}Mv@pSHP=Yb~9a?`^ zB{N!&v9~@`rJN>US4Sh0q{;-0WxrYtQuww2S_D0vX}GUu0J!1pS9zVC2WUuJ5oDTO zT(na|r-%G_R(`rK;&Gi(*PAS_d`^&` zmZs#V7hg@0^e3#&--)j8yz;c55F?SO{T?Gd9kh-J8I=DL{*yywtxwg+{2XpT<7^l< z&^S`u(Vu3`^+mp_Lf%Na9MvhmV=R`?0~vXTL*EET<);_KhN)pFJ}pI6nvX$#=IFg& zqj1ZC3+JwLwaTK$q~xd9Qz~1)Gspb|?_T}~-xb{Td=`~hcU{n5&3(l=gfGMjQ|@|@ z)_2$W;AI6TmaYURGMOcn6@Rh?FsN_2>&>LOK0)R>b61#AhIldglrTC7slz!mbnw4W z7sz}y&ztMjOQbJ{JoXZMCPTMwJ#h>5C7L^XM*OuPHwDN3_dj(a${XwRFFh7=)-z!= z;2g8>$Pk>?=eOmvjCHhrbJl(}9RjK+1@!Yx|J7iTU_i$Z#W)OG?K7d#y86r+67J$u zL-LUdn*0121PL`*^;dJks4Rs?V)fi--;d>DefEtL(mK-&i870N_LM#0G7KyRPcV|T zUF{i^8Vn@s_>*8hrsKA1U^&C*-SI!x=3kzrFonT#l|8K^^ykioR`JPD+{rOComl>H# zqQgM<8&iJnZwH0_G>zz2-UtKI-p64{q+3@RJQ+Rtj$&#D))lJBbY; z3@N=X*Z^hte~+yxT4Ubz2k|gZ4%$PW7H^p&1hP*7(sJ_erh^Mb<+ed%Os)A`8LiGKl)M=R|3z!Ifg@*a5suLF-+Ggr;1q-e^-&> zV-Q9#lV@7qMWAw!ZX|1)7Y%;yu=ic*?W(mc9Cnx^hi^U+w$@82{fRBU_L*@#gpn)i zzqfGfFZM>8!-Fl{_hI=KY@-zUz$+Y{X1%p`OZPU@6Beb%Z6atgr4Am%9CA0C2O~0l zSV}{=0cMi1_{@ZH^!7@VIf$eC9tUJvHH=v%ohh_1Q-XmhY1qSpbnic49M@6`eF)8= zhAkTrA83;m+Cq7a+^0K*0vNGXKwo~u>3=$7%GJt*)-x#A?4ZrTG>O>-D-t-HBC;$RDxJIyuXe zXAb?se~-K0lJS;kG1(vLC=(t!WD?8jN#0}@w0nQ((d`i^$+4mZn;=O!ud^ ztJSI-JWowcfhQ=PSq^T2ykF6nQdMT|I~Tbvh#-IGNtG#2`IJBC!dBA8&k*{60dxQ= z8KOdsVGZ`3>FwENG?vU)Myv?I(1W!RlRw}E&K?r%D44RPS(_e|&aAX-M&j^dGMFv= zJI`%Vsy8A`qkgO9$rOR-=(6|YG=>c&I5v4@MPo$J|Gwu@e{ynCCeq*0*q*ca&+X6B zxgpg{I8$U6MU|U9C}YAgnAEs|57^(Riko_Tqkd*$QXvo#BwQ;{LFsNR#*ddA{>Uxw zUs66Zi=Ma)m-{}_Zc|H`)G&xXcTf892~lvPPzAY(89J_^K1UtpUX^1;42z_0S>x`< z!Pf>7GcP?p?#<16|D2M=^a1@{h3p81*<|mGP_^$E}3z(P?h8!ycxAikLsaRAU5936BY|+N{;J^VO?J6!r0FnwdN~sZ( zbkaxDk1rKmI5Kn(FfjuW+)9bCaWO2@c+6&4odsNBejxJrIhR;N*pMDy8IFQ)Y?cN< zG*NvyMJ(yu^5b{ZNAxr3R6G#lu)a$Y%hMg9-hVrqJpQ1f!N1WasUVt9m@{HJ0#S9vv*_Ma`d-h-i6e? z%>re^)+51BNlf_;gUv4zzz6)|*=HLotGHz* z!<&MFX?gecuqNb#k!e!tkWRc!j0Z_5hwxce1)sTaV-FwBoY5in&(5p_tT>YBQ2N%KX?sCOv@F531LMk&156JgmtqE5pSF4U%hM z2f+R%hfB+!$H?`hk-@X@$tc`(DP;0&d>N2rIYLrF@wwOde3Dk1{m}iD;9KmXSku$#Rrg83xl*lwW3P*KT9Lz%Zs7X#`TX1#^j26EUhtG zM8@(Oo&z{N4aaX4+*D1>Vhu@JhR9;F7GwG^HFJ`Vj6G0~j+HgR1fhjmE1*U)=#--1 zt-)p@YamB9qaCFEROwfT;FOUFq)jM7MO^V5$AM@Rz09;iQ;VRtuei-lJ*v~g>TzsM zvQXX;IC2gP-`kP8ME!odHbD-yX$omuW5iBnB}r58z#Q2B!{Un{&0zxWgEuZe!RPS} zNt(y^r8UK%=6VdA2le5PDmCZtpOPH(}#ehoyJ%6(vMyuj7ZuxZM zBeA>mq>)Tj{a*{2RI4W-ip21)#P*Ys2!O_D)Mv#MOhL8h8o2?(7d*{@u6cbc7x&topRZx z2eqrMmPXwU<||Ymd{nS%c1tCEtgc$n)&RC{WHMM5j#L$Hlz86F9Zkrobft>ii8Xch zKEOY@yu}_lstYS*)4SJ?YV!DrVg?l2St)wLIpwHU|~`kbk1GQn-8T@mT2!Ws!9 z$1K;M$iQzjYmO19+809i(P}peYtNCH`wU{J*iV(*Fj^vsgXrbv-KlY zE*m81ROo}DUsY5%S|)Y=3J`APNJR(Jo+7tq)H#X}zkoiE8k|7_RaC`B3LpPTywH^! z=&Lv=4xQhDw$~MxRK#`oD#=xA0E5@QqI6)$a5?1Nk3?oDoCtkM!6Zf1q^Ml6iMgy8 zxB0$ylv@Z!<2Vwbax=_f@06k@jpK63C5Fkg;tT2>HPlgZ8stqS9bT51t{{&|6dE&L zsSNw&$|{)hoLxu@X_`apqLsvg1cMZZ?OhepzL4-p6Xba%BX}g*V}=rHI-N>O=mw%z z%l?j8iI{QqhE~aj+{;Pp5y}*oXAw^HTlanJI0OO^%ulV)C3_W?RPGz2yPX>|Xrx42 zlo96EGxrzqR6$=G!J?!BI^>#q{K;>JD4Y}Z$N92#09GbyT6imcB+hcF?O9543M+4S zgH!_OPv)zd2ym(%;-ozlK8}h=8bJ=6BwzU`3atNGuSN-7d@n#nRC4dbkOq>_3_ER$ zKC*Bgg%SN@&_oP_0sx$aMT1fje2=zlaY4WX7MPs>x&!o;=)Xx79FvA3_+1D?l2R6_ z4EZH+N0GzOt9~8Ve2BMUjiRn1nN$jdT$hJuC}&&AM{suuk17RE;3LAuc=>lo_)9hn zUG$Se%zylu`!~=EQRgskeSa&Y_sHYwU+UDgemwt7deza$VMKhL442M9XV#XyVUtTO zuP_y(0wwCy7|egP^TZ*y*$u-~~uH71de#wp-8RI_H(=(ZN+s=I;SPMm-^J3YU(F zS4}~=@jQC8Y9Pcx2t9yf6@#LNaN~J6rB)r8jJJ-i8t8n1p(i8-6-)a`T@Zt-p&>_g z!F)a}QFSvJ93|^tD+Xb2*ivEKP~fQENoay+H{upRZ_Xt$XqdzLa$3+BlE0Eq&3qYu0nNn zQ5V)w1hACrM)Ms1oewL2lpQJOs^$}9qKcB)tAFd#EG*kpKaxMVDR|AK)!KaTD@0G; zU52^S%epEt;|cZd{8_fhWZr9~Ik6jc0*U>uKlMXr0)ZX($XB#UFE+v`WCXxA<1P|4zf1Tc+ zx$9OGhnODbPbhUx^v~2*-B>^f|1=5k_>vJrnYWgt%s1MX6EjKh$_No)Go>ib zh4$+SQ%e2VdpRAg7Ix;$^XVy$-cjamq^X3q1vMsI)R`MY-k{t{p>9wEcY zTyq&)w4)2wdn4(w>Lrh*hc0NNHhOGQ^AT_7^ ze09a?{(Z}@KyG)sXX9{W?J5tT%9S&3AScQ%)dz%_RqH1ytk7BfwOe=nr_Z6X4`k>1 z7&HYuql@A0x-2p40*6LbAL=FWIqNpD75naJJ13FQ5$Q#g7GtJw~ohQHJZ+mT5Tqot@DxK#>kRaVE;hv<;SUkY+W7Jtp* zU31LveG}g|Z7StF+PPXvdmkdNHTs&6t|O?fo09%ASHJr+uk{QdF7PTH9@M`F=&78h zUM6E+p~Zh2^#OaBotWB&wjb7d@01(QH5Y6*7O@=Q*{CoW;Cd0qC3w^hej#)Y0aq2h zAT2r}V+|YBH2OVSQr@)zTYNDImpuq#m%$!aJdNNQ3F#sA)b;Q5O97hn+UF#?{>@g2 zJP^$5(wy?X#o~Hz^uoCGhw$H`y{{-~y|0)o@K9?9vcU&lgHyJ_YTd(t+A=Ontd`%ff7K(z%x(qSIej=x<`Xx52j<*Em{LX;`4UsuA$S`<_D0ID?)OcT7V_%% zt<$|NhaO>2aZc-9t}}Rm`WxAbAt-YmWcqzqrEakM1iEL8-d{k*;|!L=)zi8Fm04gG zJF7KZ3xLi{c=+Y>ROwnIFM5K>-*KdA+JXST?o}I}$#(9!cOBZ#&8p6sCSaIO*BZV< zsGiKbtC}I~H&9tvKuNm=SL`0V7Js>Y@2+h5(&iDuL* z)pP>1$`vk19p>smRju{ugHH1lIsWF8v^6*D+j+dviKnOR$OS;Kh9qE-n8-GtS;FLiAv zwdjS-Hc}2UU8`-E`jlRA=pt~Sgu8+B_hja6boB+yc8(3O6i_aKn+Ico6X(Gi!48<- zxCjP-_3a{96IQp2V4o3ez)fP4<0XP7 zd2y{o0EsS?N(ALHKJTSBOp7nud8YN&eTh|n~uXw%CjAv6CXUkAesu{eT(0M`7 zIW6v&O)2U1u;jS#_R|^goucGPI|}W&y#U?m4mRvwJK1qqa9Q_soBF_%ReBHzWl`<7 zYk3oVsRu3jk3}ms0$AvVM60b}OcskTM6~W$u5bgKcqg(v1({HRK@*}3-rz>WLcD7w zAP=Y4jlt7*9Ib>jVzcNtRe>A?AO2=~Y_nclCgXF z+s2H0A9$GSM_XG4k@l&b=cJ6$>)xpvT{udiwHJ~Vg`D_400gHSv?ZCGL4|s<{0*a* ze{((~m$WPJQp$pWnFbUgV%S&;@)aOB@DR@x=iR|A+z7!2o12KJLrzr4Vkg*1a|9Vl zU4X}9hvCd{h&5&v^xZ6%RU+FweRYWG-0gPt0NsI*czf2v?y(GGAta7=G-+}`3z;U_~0nz82HnTh0_O{PPnP8^kol@!aj2Y`k zIpp8m$$_&%X|aT-MFst}5)`PzJYG#dLBNK! z+o9R7G505Yi7d)?a-)(|L-`eTNXyM}G?z1R^G7?G%tAm}H(AyKm1rqEmO83bDjFtK zXj>+L?Hk2{$L<64foZ`sF^e@-eG|F+gOtify{TaCr|NSdyGdNVsdsY)>cOS_VnRre z|JCrU%e*e$6=i&Lsz!te&7{f5HB;c^nZg2XcqR9XItSRJCII$OWTC5?^GAxeu~*nG zIDk&Fi%q;!SbP8RW#|T1HO;5d`ccthZ^I~KbwYO|=Ndip`p@HR(imbfbf{ebs)x(6 zK7nZmt9%;E_4%ZfB>PakqiMN_&DG2HKub$Tg8lXl2Kz&{kOh;u-{@7+oILg@xPdt8=F&4<5vC&|}g!yV3eY$+&M{ebGpNp$Ks zB_U6L<__t_Czr!8Z9=D@4LM~Xua9I8vcQ;f3M{zJP|*jEAzRW_Ro#^JJ{)o2X4d;i zV$t81<+4L#MGEfgGn6+q=#llKxD@vp8J{Y>b%|oqg{lNi^$C#0y|=5P*N?g!LQTGE z5~{ewKrAkb**hZv`ogk5T9eim?-v~ET}^wzGeD|i0eNTFKXb2e55C9}wV1cuTY1!TV)~d4)$3`O(boux?*)Q<<%jme++YPT*?Un$hFHP3ss5dz(FZr`KZ9k4j05g>YtL5f z_me^E!SaE87t^mrRuR(zG^Nkx2lq=L6`OXxIV$-F>J{g`molrOWf05$)S!Z4(9ZXi zRixT~1`y28=2U;JrS`&eDp+%<7AtTPwuwOqLxK1{l*y9gA8@@VdQ|^nSHr>zEkyQg zdg7Jbs^~zzJ{b-{+KI_7V6AVSf|8)2ShMVF^u$-BRnf>}*0u>_9YX9ADm$clC#RI|94^kz}84`SL{%>5N6m0%-m;;lg)xsuf`+*BW_{t$N|zuhdv z7CmnCs<>;8IZ|p2Kl`k~)T+yd+BQLlb-6O5>W{61WOzwok6{iJQ%)N;#_?F^Nvuzu zQ&^?YFXHl%3~7%jOIrDf!wLn+m+m7#QVGvySkLxSODIkUVdnq`GPjI_V$3gIgspwV#eyl?Sp122l9gm=ke+-v?U+c2=a2I?&%SX z)o>xS@09?(;7Ub92hURXPw9+m(K}PuVs&57Msx;FT~6BvEx86=>=KkD#QfR^$vmEt zAI^K3pP=9$UaBBFT-0q*<(E>|kSyq6H5*&9petd1lRPfESh9F{fn}cK_wXyT4=l+! zF5kjS%@Lwt#oA-;R*}U3Z#%q=zyY=~2FvZ_WwQloBr+B?s@z%hAmzeP9vdUKas-P@ z4NOJ59GyMYj=@(MKVP?c>J==m+TCr05)iQ!$)wt?;ru-z%#%0G_rOW7oK)EIZ%AXAZ8akv6#_^1xt!UssOa1 zjw3n^?qF;bw}%1-ULftIAW20aFlNS42YJA%5y7LE!lXeM*(L+7s>ds15QSnKpe*M` z`Ihl8xZ5~Cj>CL%tEwJA$m~M$Md~4QBUN9%2cGhhOZ(Mv!ejeY)bL`Re147?#N+We z>9Mc{EhkwVFXe=O5XF3ffCh#}m$tUH$T^*R#>$*n6Zg+M7Wbrrlx`;@jy>cL> zZCowr6WG3jjBghUg+lPlY&J{&ff7Ys_M?stw@qMutsndu#Mc;2Vpbol85$8^PH+VB zp2kwE^V3NaY08Yrc*~txE_Uz!Eq}zo_>CS@B|g zv4PvI6kky#}>dCaHAEQ zWN))SB!BYg`q8Qct3d(wv&3>TR+JXrd|8Wm6PT(iz)hUN{w)9@y|>*-qQCb`QfWpH z1UUDCwUt$e^!1~}pMRcP69M9O$t0xIIuix()mwLN+g0chpUf#1qI7zL>Mgu00&IHp z1ZV>uOYKe+)w;AJ8nzX+vmOl?^9&*4TsETGD<8eoDHtYo#W2ipiahVZbEKCJ&pIKO z=r7tQrlT+>dq~hbuqU|yq`^flMUcS*h9P{Eq9zFroUD<@lupb=iio!l8@#{s~&`p z-q}24$_ezm>j`HPl+LVXokwvv|FvJ&7c|NnD#;f+(4HCQ{{&HHpzQkTNO4 zX5ax6!T&=U7E{QV2x^}&n7jN56p->wcamK86hWKB<`ZT40&^+sPpWr3+yJ!zzZSQ; z-PgJILjI=OAI6f)Nn=$ZmY1nlm9+^JKSU0^uqxUeFz=j$Rew2Q`Ix%;*u)XU`HE_Sf6-Z4@+=@#I^>H9TVOW6z_fmDMe8ebU?2Tl z4|3t_9D!~6yQ|lo2@sNrjs#;pv<9;SbfD?G0G$0E$0&df{?TXmb66(9Xj|XT&3o0? zok_ilu`B0gdlCcSfrNB1eFKY#R>iW!%hFTPF|1c{JfZ*+escrfKmf_fTl zaj_mVy8!~FH*jn%N* z;VC+k#jQB*>uq4T2P{4MQn=}X z&G0CQ-<{C%5uB6Fe$1YvZkiKGn{fK)rL`Fkdy{>*-_0h&@8T7s*@SSX`vKU-{Psjl#mc~%0cuuYGRK7s zW~(y>Tz3)Nhi0%3Y>CD|f_D3N5IGckva4RpTa&QM7*^yv+Gci4YuGYTMckm8*Gz@JSm&^19= zdFZUNhBc^lu>#%$b4h>Ine44n0K0A?6}pPrz&LWTyBdJ5y~0~(1H^T0^#pNktpOg=oL%+Cxs(w(07^HuxBmA^)1 z63G*gqGgcH&iVlv@ag9q06rGSx zgz^~%4Yge7JPgMCpM2u_)zj#mcD6G|f-)58IO9y#@&LQ=Mcp1Tn#;_GtJ{cUvA7Mw zin(#5ivwXH&6L+4De z-oTJ%TsJE>dqgQ|??Z!pHBCtJxG;P&yP?1_4=#vz|Eb0{2WC zI%d~+MH+f9z;s17J|@6`rM>S|Y7{l#4niR(kVHH2}b%R;y?4zOh8b3olA&SnsSPTFr2EU+d=YW}N)u~~?FFM?As zHLS)^Faqb@m%7=kx*7KS&@<5o*5>}Ev^gUgps^;&=79A74$&j|>acx469AOw6~EvquB5*bZ`FZSrL-YEQ%d7SrGen6SZEx8mNE+0>H}fw|JMS@jOi z<^+q!^heXToGB%ohA>2te zqeGEsvqicnIDgIOBJ}&sa`h%{CinR@?(rmTMi2zQ98^QgLA1dobj4E4h1^#9&uFu= ztSv)LEW3nY|3BPGk-EhGW|ceB-Y}JNrsd+M&3+ykcd?&b&fx>CwvPq|Oiu&0kR^8> zb0_EJutx4i(wPda@Lgw`@aEmCIc)uYK5X@>F}z_(Ui|kFYr2nkADmch?m_7GDC%rZ z5mOkpG+JAEOXP%s=sAq!g&>Z{64Zcwl^Lh6+$2^7H7ItS8+!ro=o<;!u zBp?nm+W1ChEP^Fgr-Rs}kRKF0wc<_CocA(bCC*S=SH}53%LFAB(B@9ra&{I#ZMqYr*sA5y)NAt(XoDRP| zbfz(m+?S@P&=$$#4Nh?Zcu76E-ro{-dq^VnHu79tO zq1&*5PA;}ndF==FJUOc|cbc3{Ew=E65?>6mFnUdyp%pUjv_w7}enLgnFU1xEu&A8= zaMBv^Qw>#|cXj~+dEjc@Qf@vCt3L;Jak`Qb-GM?=i2^~?ZKWW$!3UupaR|Wx(};=| zc0zumb=;g!D|ei3(%z(EeYPG~ryVUhBhlDoUOjyivY=1u`LJAWO=e+gen!EmBk#eVJ(`IJR zeK*|rW5TiA%pb~+4F(~y06l5m?v*pMXVOgTkdJo9bJe zwYN4{f$N>bVp;&LBKrRm> zY6ITG@7SkgOl8`e(WL;VHw`vOVI$oz`wu9jLK1~<*$`zsy1;lhv*|#JV2V41WSd@h zM{o%dHttPm)Qo8+(*f*Q(~|4~^Mz|_#uPf~Iw%f;spbHXUd|PxkAMuN;;~M2b14ES zPOcl%LVC`il0<6uR>NX7?8ajyoP?dMI z=96z+qV=n)-x^`^!EHx562XJJWDBhY^7|rqVEqXU9Y0_HDqHuH89^`Nq0JRYne4v@0z)gBAaU-L~BJ+K{9|n7!ttc6DTT>LappkD!s_y3sl(BaA>z zWK=DHlxqS$yU=`Yo;4rY|cU!m=H z-f`5Edp2?B^X+!q#c3)IblOeINu5l-ezn)L;Mb@VvnTuNVBnCJOak`om{jaR@rfJP zq0ydEdp(DW_{mO0&Y;yE=f(t_g*K8&hf>v9H?TG%As&^ouq?;p4k_x#E*|COyiT>N z@RAs>5i@9`TE!F4V@TDD>(^jc5=;V6e@0!ymm;p-FUm#S5|-~A{x~t%{Icb-WfF-#qCohq{6V@ zhHYx3Qn0Ds(y0*E>HZ@j95$(b|3@E}lM9ib?R*thx?#6gn~B3=90CG}aF|RiM5%VO zx(J0_aR8S`QSrs*o#Zkkx?;=|W4;I-V_jUIW0iD8C zs96;)F@4iOA`WQFLqm*aMI$&V2PwnE^c@ReF3zlJVn{=h2Qe#ZC#NA3X=3>foX{4J zp#i#>7w4hUB??X|j=pnML?x{9&85J63A`bS(Vh)tpdJv~#i$4o^9_7i2rZp2g!_~u zW!sbQx$}Ltj6MwV-2!JxsL|j!s5E#dU4g8n48V!XT`1KZ032cqU#dp1vI7iX)v2eH z@tzpsGC+@R3fE@At%QX_k1@d4u#O1Z+n&PaPjdGZxLIms%7Nc9pY3Mhzmpm)Q5F&t zb-9xpsI(D;KXKA=3&2HLJdDqD{E9DzSv-;Zr*c43*z8mmwj*xt2G?m)7LVqtlqt-R z3FRYUb3}gT;!!xv>E8l}W3wiiNkDXemHso6t!w{&u@0L;6Lx>9T=7sbLemq~u%@r7 z{7(tn6t~J%sI$@oNMZtnCmUII)i>0R;QxF`?VOhGN@@qIMu!>6u^iz#!6%ZCqNJ0G zJ6qx9rYfrXC{77DGntPv>utkG+R94srJf8KmS-@Kp;brF%Y<4DvB_dWq-({v$mYn z^dzeijRdC22~AIfgVDbfy7Ppwk-9ynCPe`c4Rz@JSb0Gq{VeIoTdbWN2m_vmE{5j{ zMgn`oL|oG&X)s27=_M2TTQMZj-%`K(e4;9i+B1s}|MT{_& z0boyBVh}|VQ4JbK!@4jSs&Ks)hgTAs0Cy=why0@mk$dH%#DeGX2bd9U?7`Z>Lkol; z=xwB9f?deJ#Xt`y?DGB*6#v#7xe;L z4z!z>{N1Fg$MYh}L&)k;;J!s?S4cJ{Wl9A@H0NtA-qiggMT7o36F`j9J27`x_tbI#Rp($@1~ z605J^R25I}Bpvo^K1wdXB+~LXiu;~|3M8a5psUf@Q zYhzgdPTv_}q_}ffiuuDrWcDgyH|HD%oh>l56hN00zmXCxrgPPd&t$TkbAhAau0(ThnRjjbF(rahx@AR1!}^pxZi5RJ*=wkVJr(T2acP1Thc$=e!hhj-tk{D;5W^TXsq z=bH_TIxcKN(<$VwO+tk==j2RSdpA>8R^vFA=hQC^mpW4$t4Zz4QTH(Hn1wr9zy4D} zhjt1XDQW4U%#U>RU|gpVv?a3zkDfsWJyl)x4#SDrVNqNh7VcP^ogWH-ljbjGTwnJMQ5_)v$XQEkcUJJ7WoR4^L^| z#e^z^4N?|cNesQDvTl&kfG@b>9u{sA$DZgh$>r#aY|Vvt(ILUVvgkonZ#ak5+s2o9 zw(1IsB~*Xn9*X4_o-sS@9NnviCX{+#V-L71eE+pCXNOCY7QubGtz8UfO=ZZM$`-6$ zy4N6ZDFi_;gQk5baPiMa2^L3mIMRBnbpN$VKC}d=eHcLwPVLJvnz7bu4by07jWUYK zE~Y+Mz1JaVij9mvg)cFvrz9A&)myW}e2BI%n@^>VwzZA5q4s6bWg$b_xmJmrTYS#Y z-0=LceJAODvGX63CpIGVN~^G~!n`nI!yPm^s*MUCiUjGW)+L<-zgY}2OZeUE1ri}P zdEMP>Te7JaE*V<_LRmk53ADi$qvmeiM>aA04w#n2~FzakyeZU`uia%M5!fq(LWryInTfS$0*h<%3td67Z&Yr`XTl)^Q zTx##`fqwlFq(o8I#RaDO;rdSn8-+)(IKu$rhy^%ui3<{~a3EheBGlP<%pWPUL*|cS zvqNQZ`?Pv3vpBr8fyAW#h_C#}VH@kv;5rDn9VzaJ+dJ(&=zzPaYZ)ux7tMVrKY2VQ z^D|W}#H{TLP{q@WLk4jps`=<6@$@x#x{aEVnhU!t+A(J^4#Aa;b>e6IK%18__U|HS z@bklLR27Riy^**a6#(u*>yIFHVGNG=$Q_0B)+@}6=WZ`yCgRnb=oWGL4-Q{3uoRya zBNo@M0+ifBLGabv-XU{G-EhYrblpu9QQI2co5L%&DB+=E`snQ+LLvkD zqU4YAVSl7nbgV0{=*ano4AI)7ia&ymT~6IpM~W4PBUfBgu*eL7B5x^SbBn>VgGLO9 zoW4bt7(5-k<;2_E*xFBxK`P~pu~p9ETWt(;(|&y%hsd`+PGA+n)yN-SeJzBWd8?H> zOZYNv!A6e773GmYRj9nSRZPzl(9CnG6lQJ`GM`ILR32d3Wm=3jve4!BW3`$N1$;45 zZ-aA1twb2DXl7M3rOuY4@-6x}^QG>}iW>M@<0FTNk!})jdvZCd1Wl)}gzcBLI?Z2V z&i&GIlu~9d<&@=URna;vFXRNuxb{2?Ek|(Bua8UtUP!_hR+-*`RNJZPCt7eP15xdA z!vFGHp7*&i4NzKFKSa4YE9jQ3>}=3fp|+Ph%m1-_W&R1Q#3xN@20mQO{6I5!XV@n9 zAxfBAvil_FC%0eD)SWVvYz<1Uc9|_d&WsQV{BiMA2fUg2hsG`{VgCwA>iXjFE5zzly~GXyE$M`qjvC3*{VWidqk-BDj4< zsMmprL`+WlzlnI%2r`avf2&)AKW7^rSwwEN<11dMT=$T6-3u`%R8{7o{%|Wh50$&) z{5(|E@I7ok*}a0O7xl7(EFJy1sOZqk{Ses<2#v}!BZtNOP}B>R5Tt~=NCvJopWGjb zBaJta=7?2pE<&jnQR4zyxrkrtqm9nU`p^1Thi0hMT|zPx`Qi^tvNkTFK^GO2zL;;F z!XRs*>?IxVABxUHBS}FKYxq({j1bNNU6AG>$rmAUgWr;9T1XlhSEYoFqzy={kC>Gx zKLgp>+ac)m_*qcZ6_Z%?#8CI@h#uv|~c zAR%553r+ZW-Nu8K|L_ZCDOPS9H2E9|ttB@J4lmW)UW7qc4`Ico5JjA4r=X?LXeKN3GZEt# zxFPl6=t;8obj}~cjK##w{G&-u%7UCqh;IOUVYs?xoovM^mcy_arL_}t&L8U z@G7J_90a^1ATDjU7--xlTL^9^TT2YK(_!cT(WbrKUkq;X!3skI{b#=VmSTL_+kHH^ z(>obz0$huR&9RIIHY(n32`vp8^^dn;Hqc;C-l1B@X{-ilYx;GUgkR>&N#l{x{BVYd zy4`mN4}$|*B2YJnz~-IZFn;kgZivVIr|tjiNhkL$cf8$AJK;0M+a>!0{9iPs#V+o* z5!~;eU`ZRqknhOZt<;@eHELr1Cqte0z9>1tnRMO2aw3j4^vRNMiDr zp!823pAFwl5}oxNx1RpbwZu6(Yu#9G8lOZ?{2x&Ltha>k*)I2YgCu)MX7cgS+t2!U z@#s^b5chVUnte`O(u!jtgj#R!|5lY`fnSnH72b=i3Icam zp8a~2ey&Kwx1?XAdAPQsS#)3Vqe*i2kQd3^WAo=%l8f;9DA5O80(FOeUABpyNs#<& z_l(#N{#2lM0+U5XIgzp1zZ=QF7Fz6K0Ga=w==}oM3-2u+%SpbFv^Ox)+p=?4J%w`N znGXX6l3i+ON2d6~Iihc%X6A=glr3?Eo#$eL?Y#I6H1@+WiWy9;Yt*6;R@X~76gI$? z{_S~Kh@Z94OGZHzek-}+7@A^SB|E%#RZ19pG2|{xA1idXk^G4V>;y86f9kx1H+LC1 ziP}-v4>1%8pZzm6gsPtA_CBywz?V>D7SA-0uw|R6f2eXj$E_=5tNPV+_-BRDUHN5; zg7UQ?iN;9Kk&_lXq*6nWmfKi>e=8F>&cJpJpJS!|+5TS?)c;^^zd%TM*-H~{uf0jm z&UQKo)qkzSkY95xO`b}>a+%S`j>8x(=BV)f5v|*qnV)AKvRE`UJ+88m?B9jOLp{DX zj@!KLc5=nv+TDy>8a+*oUvJ$NJ%QA|{%SgG?~m@PubRViFiJve7aT$kht<`;zw7Q# z8^7MZ8#2g1GasL)v>RMw&j`m`cV$}8sClfO?TuRe6PALEdm2Di7`oVEA}-t8sozy+ zRDU^aP`h$3NWlL04eKFj?>IsY1e|H72qDA%NyB2MEFNHnIKv!5# zauYTYp9)_$biwHKKchKRsOjCk)MsiAx*&DW27HzVz)o5p+*7IW#Kb^V3?C8FW!m*0e~@3m9)ufr<{ z%~|Z7-)RJdQn+mJ&QApDuiNG`YQ1~ov{ODgvEabNX@zj2_ zG)#t2ehy;iCR{j+~LNsg%A)ZX^))w@X2|Jtxk zckHd&dw!;~r?ji^tNaCI);7+jD(2fV6(eP0I;`EjeomOn$gZMkuxXiOBvH=n!PwiK z=WWC0qD`49aiqqoRxElu=6lb9n}Wk5C>u~j9sqHBEr*Wt9l zy8ViKuG4K8=VD$FBwj01$&t z&~z!?^3iVP?O}A3M|DSBQmO^K5N$_Tv;mX^#`dSG6h3a@Fk8~Ym^-UwLwXLiv5u+0 z;1Fq2r`a@-aBETF4ni)IvvITJAhRD&9~W9SARm#l=R1%Gxsjs(g`acmN3QuKImE5d zD16k^J_zlh1=k~3LD8h9K`Gm1=%-@Cq5Mq{x^APrX~=W+Bfel7Ot_4V4?v5E1zd#D zJvIG@FwClN7JF=&hPeyUvT+F^;?CmMHh0%)h$y*p3B^~x&@CjjWhsAFjT7N z_qMh^qMjdbZ*S@61vk+$V`_pe#LRo~f~wF4PZ2i` zYDb!{LCR;AN?xL-{$F#lY9FaJ=>2JlJE@v>Y zycVNpfYRT=EXh4>(nIoxo1~p(9F@vzm>uU;m7d1XJ9MFPlRbdSxhnK!)6hwz-s+MSIN0sQi!P8j!PaFw0J2>^Q zI0R~B;lN(Br{Ob;uhln})Ms9XDkLo_W(mkm*7CWD?ds6O6T=dmq5l?&DDG&kGZ@w& z_p@=OR>7|wt|7rB->wjYd|vVRsTycAMc$2&MPXIUZ29!e`qfm5&||v*6*K|8n%dT= z_I;{R!=#Orw&bZY-VA@;N_ok+6~;b855bAQR9UjFrY#v$*TYMeub5$4TpVv{svZ)2 z9)*unnRp3*-SQUk=2qDx;I`^AMxiCoZ9zm@@^Lx3r3Sr+;G`;=8jmjdu!0?Q13t_6 ztKwyLVc)2&BKaJ?2x8`MNZ>HW8UYB5juUcak7wRkc0n45O%LstDd&gi<^K&dhp+vz zrU}JLaJ*asHKfx4HNei6DX0vpdnsKb;e07l!UP56)MCtKvaA~tpGJ;o)pk;UjBVk;Kp6swLAW@boVSurP z)&{qrGBM=DB*t90sjwb$ov<=GybPo{i$AV0$*1c7PArB_pby>uX(B!D^Dy(@m3!}8 zfh$L;Sk#yTZ-T!jfw{1#@p5U#;n)CG(6`RiK2ln6^htgh+Ao!g1`_0Ef*!!2mo*{i zuL_m%S>8yqQpd%;>(biqW5g3&OaH;d63<36w8IxL+?c9$Q*SBFE~Erb??B86x- zgU{7=X#rPU%#LrF?^d1PE7ZtwQt(y;)-C9jj)fUhESj-1jps`K|IO8#KudB~XM*?t zW6AYp{E-p{i1qKvaNs(LhiFEoM>hBo$AEfDpnUVT=+B z+LGLDhhfG8vZqNm-KRl)rkym^no?N}=?1UeJq|z07`p9tvY5sk&#C!BOrPm9=e&Fw zTgLLo|KI=K@80`eZg%}5#XPwJfkjDhIcQLHL*kKIS)1d4 zq7vqY=Snk4jdQEb=1e+?G{}a}aS3y6uENrbrQsDjEXv+z0pzRh3hu;Z2N4eGuT<-} z-ncmqsj=zGz>tO^6kB4#DvEsC8=HFwp+K1fW5Tp#TAmD*O<(hgA@uml*+}kQ*8IFN zL|?^32RLE?Dh=!48m&2mLWnefCy!9Lc5^DPS|nIzk!J}zGN8>Vp@xq$%Oe)r%cygN z;qJX5WxPZ9@~*4WOsf1e&K_DTuX*$~8#8%*Ddi8N7a%_^-si04J(9x%H)M7I_{&FC zFjgy-ABJ>jP{HIcHkbKodXKX*4^whWaEA=?xW!n>`2~<8g?T2=p&!p_vW9P_;S$`Zd5mb&hnvld0xX_lPI*xXYHWRh0d^&(^yZoC@+l(R zl(q9{>%;ED+^-Uvaan$KKK_Y|xFH?j+Hik!R;XP>3%HfhlZ~W6xXCXx5u>rsd~&~l zcUUThnZx2M4F^hQx%LGohtq65YaQ^Z`xVSeax9Z8_AV*NFpP#E13{FrIv$c+y~0Yt zD`6;jg~FuM2(ptOa80F&MS(&kWn}n#0jfyrXr}73Z-=8q~7p~NRuU& zangZs=-C6HAV&m3);=I4)kf55JN;*w7KCTNe5U1=`J`9g`_!U{vS7<9fjC+DM&x}`F8`JUaK6H5y&3C4ubVLc&6xP_fZcF z>(CQG00D6%=+q%n@Ix(N+OTysVBJB<0fjAw?nS3FQCfnfF-L450jItPSJy8)L0|u* zBOTCRM6_QSR@2~e7n>xv-+$2-)P0(JGH&FpjPlIs)AwU``!gg`BPw+w+D6Rs)}9z;((u_AGkY^;Ew=gkT+9p* z07=+dp7SaqW_h}0IU-U<=OynbC2Q_ZN&1IErR2-FQ`zZCb4Ky7_STTCJzq`+_vtSJ z!hPF<^He-7EcdnNO zop^$fO~b~!3?7I0_g-@|f+RL3?jO^>68x@|GQGT`{CBgGvOs2MHnUjop^n?SX)M<5 zEAB=K*8GL)9J@*gv(1PN1$v3t==@l0aR0AKQ&AvM{Iliy+PXm-cYS_hP(&NB=r-2U zyijB_#p^}dP>~?xtRs>Xzy{!yFi-ThwVnO6aVLNd@*FC>x@#{57%?%cy?_{ZXl=oo z={g%k>iP?P5HL6gosE2UnbDjL{pVk-_KA4?u1jEk`vkH@4G(_g4VL#eklI`f$4Kwa z`5UG@Ta%ZBrM$C&QjDF8;1Sbba5pGkwO(*GvSI^SQycar+UNm-*r0&69&`7*q=}8@ zUc?^fx*fMj+~Y2py)oi^d%R zSApWQfw|BA{BnKBz1xw4Jha7fJ+%w4tTOj@{ZAGjXUV#i`TsuX@!E{><6=MZ9un}%9htj|s1Ph8Kn!Y~Q_;k$t|3eKYlkZ(W!@nnzHJ-XRCoLYI zD9srA(iu!?EP2DQ4!wNqiY+^5nD;M+4a`-&E1Qddp1~UuYvQGZ4mPNf&_~_0rj-rH z27Gwn#$zDw^;T&iUR&QM&R<=j*+U+9Ra#Q%ZevE;a+TnI zv|w#f-0Lq=J+|3Jt$bZeLlh zf*hk`r+QDzwwJ5LN_R>*R}uqgxNe8udoN&Fmk%N$@vmHN7k;;nNfa||P4YOtj%Hok zBW*fBdhC*I-uT>Fhz6T2=+eaFsAvV0$SdJRV*c`|B)SUlx?q1xLn3n(u*KGZptQ3 z-H{xt@Js0qT(Op24)Huh^VQWL8#2odnP^;J*Fu(SVj1{DhzIRJ=f+jHnwTP4UUX4{ z0=A3Um^$Wwy46O=(3@huc}bfMsNKZBh-_@lFj22Gq72QHk(Y7U8Fw2x2g2nBnol}K z6>X+wxA;yYV(2V3T+_J-LYQ?gI08x-`vqwJ4SMI2r!&z-ht?Yn%;Ns2a%KJ%`<-4t zD+wuw62K>6-#hhb{pLV)9qy!AvFk$ zo=Y4qDEN+EZ6vk3YtwMm=Xg6q2l)jGd`MYyEU+7a(DPqs=uXa?$DzloBDwsl<^)`kct{C|?Dxv3|*h^ZINetqRHKmX42&&%oz;MVw`vcM)e+1qqSaS$kW|Nm}r_i000@bMFaDPSe zB?)He;}7c*zbgzJri>nTeKdhO;WTTES7_q_ta-t)c`dwjOg-Y#yje1fxMd zw*4A4vQHx9`A%QHA3v5=$7#D4R-Di-zs7GmHvx+J(6N&>l4D6 zD{C+8LptZ|Lr|PF@}{;He~9&8G$6S?nWS!_24Uy`aOb~wSq9QN+$n1E^wC?P5xuw> zk$`z|YPeHx;9eJ0DF>-<$Dy^7?vVQl9gPd~moFa0S!nWtxupJ!P=T1Q_C*m^pkp7D zb`I{V!sW@!mIIayege*&ibovvP+mY9N6vr2`l)zWajkkOL^*5}n)KS$6~{I&P75-q zv!tC)3>?Ed!va-Zv>FHJg+n_B^HI0^k`}a({@3pJDQwZAc^005VbsnK>j%Turdz_s z;bcGj&|zz|y5Yfd(jN8p;ydZAj@(5Dr!Iyz>`ABhrl0zq@|l0qgc4E3E0*SMtG6Iy zv>^AtXxt-u-#@oA?itlA0s{&YV&%bakdhDzp}+3fm$!_BCP&PKczC^r|4^O#8%`u4 zBPInj_au*}6fR#%rJdNnXHtWx`fy$R>RHsezUq5sq zE$>5)ICi1m6u{MCcabLdA3r3@|CnUcaI~njKasE30DfseummspW4+SwIzCgHgQk$oer|n0B$svWi6}& ze(NMAb1MfM^@dCE@3^M<&ZO4MK6Ld1Y>t`8bU|ixpUl_n}k5_Y5m#wwF zh+knlqxZ9baB4}7u4Rj6CcZ|$vSbC1A#MuNAO3?r<~8zRpZSa}j8ml&y~9nxJJT63OT+YtoF@t*~8rr>G;h zb1A1~D}6u&@&vwpg}Zomlt4S2eW(XOc{fz5&DnJsl17)cu&K;Qhk)T>P2WsTD=>{v zB-i2Ql|W_y#NlFM;dOcs;s~GS)0kid(+3VQw`spLYjQPF#5WvEjNg9&-Qn!Ek+qge z7Q)dOK+Z&(?j(0+Nim&8gQmv^r7`5tl}({^5nv%3V@j`bXrSSYi1y@3V~`y<5(YvI z4izmtLd6td{FpK?==IqHmCT};qrCo&sUd*A^fIrfd}*4s##6&un;Q1IYnE(fYUEpu zsWDI+p{8G)8WTBPLrR0jG0=F!ues0BM#wz*`=S^Ez4#)G*+`K4Roa;56x3CGnKn}6 zUv`+he8zrhUd3Q3x`>adGHZgKyoyf`euNP^UmM-f`u~6ar-NEJ$bPHK3NR@FBMfl# zHTZ0y*B?P|M?at?ADySE2@*aJAf^q0#++WsxsCm`RB1bsLhnY=H(>+*kXHbrpbz7V zM=Jx4Z*+wdPtnG}X8-_1l?Q7Svg$Pm$zvffqZK^QNj%t*fY~fGd4KxXfw||uAm2r! z!z&6sr$lC1aqcf?XF?85q2L(bY$?8JO(@Xbmw>QGdz+#{&w4yyw7=r9DjILbgN?L{(g$ zCC_H!1Er{XLl%DakTIv))pIe#Qr^K{M+tbr(Lf~Gk$bOllRqE8=bnB?D`#UzVzF2rW$(9mWi{%D5S3q*r-QLLbikkrl8 zfh?e;(+J^b5DqRxU-BzhTxkOQ9ksDXe>$dW6UUy!!{#ylZB<1KBd|&zr>T9YxMm0V zA%f(q5$WHU(`cpD(!NP$rVonk@zZdn38w`p2I!fLcpX_)*7A z%$I+Gl!jut>hp?D|4fZAz}pb3WSo$wY|Uu%dkUTaB`%VMbV@I-wL@y!OS${XS;4A+ zU`9_b3#z_938QpT^zM8&5qJix^X9$&(1y#on{!B zc%O&3Do5(Tmgk3J{rZNT6^1?Rm!lQegQ@v~1M+aV@-`m8(;?)m7W zO_eYoqOAEDl!B5Mg99q5f>`n|g>k{=Sc*S#Ls_N#t4m#>?#miR^pR7#N+mHY`LF1` z>Hn4SYSrP4!P2|q`wo|*Y3<%Wo!}c|=H9Qaa+z?RLoaV|#5K-p_kMANT_8rd_qhRf zNszElb+AQ{I5*`7vlSUk+yQ4(YYZckD736B!ZiCKM|16q)Qoth8Z712tQL|w{~PdA zk=c*X`3lW(KrMWlnE+{&-5J2R@Y+pIF)`zZG1Xyv-y!X+T}Ai4R@ylXb#_kb46~iQ zPukf`G9?&TKb}#&8X_TpSV+hBqF6a`<0msDIxnfbO)a|_IU5y*j^0~>pt7*>;_0yRRu%^ zj#cixU!lkUbk$c#AQ5cx>UY*t^m7=*`(Q%v#wzegwe?DBKJ4gVHzolQ%XTk*NL%$0AwirC=$hkZoMW9mT_SDZz>6wuJ@2gK>-su|u41YAdP zy?y;O>W9TS6F)wg*+HG*n=!|Uod@gE{ARpFcGJD`^ycd+v)!Mkk-++u5K208^VjT9 ze|mEjAANUb4=a1;lKJ@JR}uDe`;!f-Z6p#!_tv?0KZY`gN!D7RsNPN`xmDP~XNQ{W z(JwF#Pq-xRZ%DH@(DFyhOcvi2>_$nt`r*aBH=+YfLK*kO@h~hL4mHV1DemYj2&!iH zZ8dgk?rq~I&p3*+oBHl}$nL=TH0JkDXLhvO?7q_jgb8A(_-9`m$#gNI8k>1&K>%Us zG`E#A;$w<u$PWp;Zvbb$nF(THuh)5m}vy-~^Gs&l+d)|i;bvtvIUU68(aM&sE z^_G{MX7~3i0FBD(9Q7rQImv)HL=5nzvZVDV?@CidZ#!`N!x(n3q-KMaP<P0st0^pJ5^0G36dLqn3#x2b)DU88%vcJInr2h~Cy>0WcEt%>vTTM%2L z8IF~X0B;I_6%M1n-}pk?dzX}ggm>O4i)R6t0ZzQoZAP>o9?&Tw(-;r$g1-=J^x+{- z;B;T+Sa3kcWKwC**=cd9QV9S<{DvanJ2$+D2#W`)u~8nA!F%;}pE(P!59)Hb{E z(L)$pvm?sf)@x7)>eDXnw;CW^b%9wH8BQcF$8^v{*+c4mj?ca>d-U-u8pGXIDzhVm z0h16Mf5^N7c-=4d1@d)VI)$(iD`fE=;Pj&P$mh}R(evW;NZV75W+po!ZBQX2}Zb=o^q5@ z6s8uDs1r}<=v!Iv)bT9|H5P#R8hQkF@Z9WKIsPooUaIyTB8R1M;pg1z zMo1fFnD@8?4iS=ly4%?XbQ{nBS0jcFE57!RB>{qRwV-;S(lM$IbGQ=GL7q6!Tn#9=)YjCrg%@FtLutq zs}AkUD&#$(^C?%uPe@DH^-qHvQx-F(O0zb?M@yOL2$9q+XM;}x1tI!HC47o6H8r%I zAA?cRfAT3>$xi>feR`@(L?6%2|7%)>w9fY-y(~uBp8#MMy~s?o7A@rNb{38{Ph#^Y z4rQ}VY@0r@C1n9l$?o4*Sn|Y{E_4TMM0y#Wy;80~&66v5Qc9kXr(jq3sIrxT!bWoN ztem{KRjnF0+63Pkif7lLdZ3Qxf^ow`nB#89YK}`q?+7BzjcoAIJ;-530N+Y+_E8WL z^k;wW^)$a%)DTFZMbLjwPTIMsr)vPv&T=X0P1>cXXSJgq&2GqGNsf94rM82@x>!+g zq#hEQLW)ZA4AqBFxEP|=djCq<;<*CzT#TSOvTUFb)2k; zYivpF0ITKyclD^$j$FFtTXn3%n&{EAv+wgw`LAWXPMm~Iu)lYlU&Zc1RZ4o$9C-K- z#i&<-{swKf>sT<7W)AGJ(T;`R2QMD~atlZ2XyF)W4Q&DN#lV^7%~i8HO{)xnE`Nan z3GiR_4x;!p`o^yBaKE4iy;bw7V;g)r}d9K?@1cLVx25U(y4wJPl*WUfReOFfpuB!)jvJqaO6_QazQ=Ir82RN zCg=XY=8?K#%M0roeOpAm7G8T3->cxz;W<2P)Z>Uqg+sGd6fFed^jIctBj>NRk8e+A zg|q~0^e?Igx-QzB|Lt$XRGMbxJ`@=+-tLsPT9l4?IT%^uMXzUH^m@FmdoVY8n%5K615ruxdTUvN zk(xnOc~x72ix>IrlIX3;lxkddGZ*((vykaIST+~k0lIo`&4IwRy1-5G0IM7}ZbeEy zjFqg#1y6gwxi(81h8M$Lgy8ok(g2x16W0JwkLQw~dzwR6VH+9xKDpGr8 zlEs!y3I7VFJ54Q>8Ipw5+_bMm*EjdLJ$vN$WbW-h{P@c~N7?Kt%O0VQBNd#UHSyHO zUQaE>YGXst;m7}U5JHIdMlX*7g~dH{5~cRa_^Yd-atG{}=k{VZ9%TbB1VPDb9^!|q z2V$h8jbL~6a?>6PZMZ$W1hAHSHk+RvA_Mm^EuGx@j#< zMjTgl494Xl6rIynW7(|5vMvR(fd<*!g?5W_zCQM6O(T>=Z$Srjk{9IMt2;S0l*_Bp zzZ_)*;Bj|b_R?t>Ro{}%95tn?_}mWHo9?U&BnyMybqwR6~{c znpqLGBjrljOO<>RYQ?$5+YYr6LQCQ#A{4M;*RMPM6fyD}&c&yl|Gm}>QxzcNxA5O= z`Y>>0zXg@)p7}B4)i;JyRCwQp{W01$W^M9Dr?y)uIq==GyKSJE8XdP;SXz{PV6)N* zTG@LLHCm^8;#=WXT{J5_daDeFV_bKJ#osp2)GR{rJ4Zr}{Oh)Q(8lRV2kh9m1W1-A6T*ib4l*MuMfSpDINYi#M zgz?ng$~cZk`4BX!Q>${l&sI4X9VEwRvIva90S7bKfJnr)WMzW(@eHS+{ivM_+U@k; z)vI=Yam8sKa7S)OpfGa&VoZ6 zI}7~7@By_mRwioe)en#wwMQH$phPo8qV;y|gjeoF4ESy&i*mGq8SBVk8~%T|{Z6$w ziL^HBHe?5k*jyFuhNNa=Dl8M9Cd>!!K0>ow*SFy*H6`y6o@fK!n%0^7hX;8s!mKF- z0x9Dbes@^P#W)Jn3wPRGvHhjrqTpp2da~4tS`Wb$q;E?(zf+Msutl}}KN45MH|i4j z5u~8b!rQhum*>>TJD@{7a(8ofdzaXjbCB#e6!r((ux5V~#t}oRnoKhgQz{Ll#$Cy{K00U;x6JX|4EV zy)?J1OTqP8Ohn@0Lc*kJ%A1dg&>`~c1%UbeX$9BS8^Mw!k#4E>03%&Y+GAb!SX!s4 z5iRaGR%-y?u3<|(>l}y2RsZ{rw7eT@$YBomHJ>>C2=jRCD@XdlQfh$+^cQgXe|_go2wqXhHoEq z)Yg8lKFo=vGJ*kD)Bj=GxectrS{;VW)6;t8A3^{&&g-13^_hJDDx~`}?l_QJt1IQH z0U}l1jLt)Us2Gs}BGpYV0m+N>ZzC%ozlRZH5hb^CuDlwV*g01T^J#Mo+c847yGOd-T=4iNxnT3mb|REIw0ra5&EQmUZCg%kWt4x8f2v}y8mKvx>l;`YPchxxRm zUx~NjQzxhZ&~Q`f_H(Y;luPDDzyS9z4VqrYW9qvkt>${+by-g;zqH8I2X5;S${)-m zlp0=sFyny6rZuUoE}Zq+-Z)ct@$Pd`OA94#_Cw5enc6UvaDUd=X_?r}yo^~3BwW#~ zL{jDcr6Z?@{oh+X=w=7_>=oH%xtYc0-`rXOk457Iu$Ozl_>ZcpJ-;d^)pbb~Ruxlb z_u|vgV^&<+T2Y67O>%StQ`nZCYJppgVi5qzcszxOX>Rqno{B7jIAT-1qVM~CDdgR4 zk=!OPFlRm3CJ zosF9C%fOUS1~mXWYpHI1t1ER~>tKbTzVNuIiUxz8;7AS{_woW@jo)_4<%Fu;Sz|ID zM@P3bs`(5$l1plGw_cvUTMbZHm2yyz&-uiI4`A+q>d2x8aV8FcvFx(ZOJ`>lC18BM zQ=wTag%l;k=1NPZc{+_cq^ zI*ZP51>v8y-6^Yx&^UU&l$*8ypVpPLvYN0PI&C_)z|6yrXlbqhu9uUF0L3}?k?-gC zD(C#)XFw0@^|1?hyUlL;I>&{Dywy=q()|Wxw4IBN=ogo?R}T;E(?TgxSB8M`XhF(t0^Ot7FduffdvOG7HgBd z6j-wVOAt;IMDAIqbNMuFXI;lQnx z;tF7-(h5fMmR15Fl-BFT_FOiH?fG0DTMGFCU?*`c6q4hB^b;$OQp2x4%?Vos)+$B+ zc4Q#16Y70G`7UlDv;r-%dX-=Bn)p6$wjNoz99fU7mZXjuO9d8&; zNObh@knUW(7nO3WH$ks$Am~6Df(CRWeh-R4)C_OdIMOfz7kZ;;mS>H%TGZSMHY?jh9K zEPAZhE5#2~-Wfj-{)t9?REiRK1s{IG#2_hU!n~F4D_Wo#g(Xb}CBMYn_n6WgqwqbBTnAIu45SpA41c}`Q2b@S z-rtT{b9>6LFhdm*lIG>yjFlhy=22zFY7fnEPpo!+#@PH>vxWB;v!mxTs*7Y>LN&Z2 zVAgW9TzFIY8`IYrxFLqgG+}s@)7z?ayXmuGNtrVa?4`mJW?dkD z2000R%)eSQg&KdM0;3+ecHew&#R@W5C)@HLDCkW$U`r%z)F&<5xxd@7ADgJNI~%tD zz#G3#SIeaH>xjNLgI;&JT%Q7S${XCv>lee)dKE-9HSP~+ku&%*$LaoqP;Qg^*z&$D zrxgVc2**=0!2?65x4aJ?W!beg{{d;!%DM*Rl^yQ2rA zita+!W7Ua|khQp2-VNAjHNr~{7-(`c{sRMN5HS0@IAh=Yky9$UC5=jp7TBAzS0<3IB~)-6N!#~fm;BAnGbv-$;9^G?BMWC$S92yqlkj!E=FM)OPiN<}UDRR8gBIp^f~ z<$Ygosrz)}FR9e6t9~I}7&g`LBsm}2|7Wu1t?Y?1^dTN9EV)fDdQxZ8DY<{9Xp7>$ z5=;nwK);;DnLpxF(JjHaTSNNH3N2O(vy;ekTerN~%J@Y!PQmSy%%!zGRb+>FMk{i7-TG(`ppd>d&dwc4 z+^x7>73;(K^K8nF42u$FUQNs%6NK4gg8=$6JM`FShyk9^nguD<7)N7Tj%%_Y@5w$5 zoE-Z_X}o(j8kB!5R&Ke62GC^S^eNn0p+Pw(nc3 za*@CqZh;mY1QRdPvL79ZKwnEnFLY+b+P#`2u=g?{MsMsHc7`5yN|R$FF! zSF@oG2L<0VhcnTUug_`pW=Gb1Pm`upHA2vTpFr)?;jEO`zx8`3Iq=Q7cKGW+X3~Xn z0}jEzoNJ>l*0ZqqmuqS~MA1pWusoj}6$}4^LxTs9B-b7^$cT=KfwO8zi4{DrlbfmF>-R(=rVN2npG?>Sc zBtg9~IPUMbF^6_{GN1u83f|M>d@50s?^X*A6PF?_GY!)EncWqyivVU8|JuQPDsx3B zNLt>kh)?TH47;n4Qn_>HPAf0Y|3+PMKE1yn&VMr}i%-`U;Yw+aIt!Tb>KI!Nt-{d< zuj>V4*~Rk~AaB#6L(YX}Bb|Yy09{g8b@%vc1G|V=&7h~*^0#D9SeL;N;xK7>yE1)x zl+Vv#H+ZJGyjHwIDPI;QXamdv8QQZjeie|Lc zCPWJ8X3Ur)O+X9AL0*RmVc2XhnYgmJYgjjuG*c!hYe==og^}cy`=KIuiq%3bE`QsJ zvf-bDv9C>x1v(N?`->j{5;0n^Y+sq`Jl3m-JEz6J>T)^hu@gvbpb>XGPO*KXlqY$r z?d$hIsIm`}^%V0-S@GJb$#8474+asJXsK1e86z*XLn_KCYeXO1O8wtDW;3|ALpswn z8wITPlWWt-Egv1b$KeG#PYaIud(_M0TJCq(%0ThFejYU}5Ni=5N~?`LOwEPU%b{K# zZMq>#$Q456JQ&fZ%ZAY);Wpt~0Cx{8H@P2i{ha^j%+E2WLW|edka|iSr5ia;@r{$&7_kzvAmuMKFj>?abL3$ z3P$Xk@8rJ;tfYK{Js=NbcwSsPpZ7m-AABUpPITy&os~QZ=XY4}hEv@E&3&Zjd_BR$ zTdq&a+%F@2t!!2Oa-$Yi?s$T-ZE`<*$1{|*ak9HUPbjJqeD-j*JBL6HE3~Q0xRJ@K z6@p*LiVfX*MN<7eEv#z}>svp8#tBF>s>u4%VIXnib4J`b-_T3r*RU>_pRN1XR4t^qB)$BTD^8 zc)2AuSM0y>zFYxM;oCL(4427}=O3*EaWP$^cz~}*dGz6ZSLsvX)G0pp3OIZ|)0)y} zLED@vg=U}PrXe(}2*z;2BvR^r0)@?ysN# zk4G|9TO-`mATbK-t6d1#VPe!TBBE+;tRrL4uvP<7XJ0a}&>=hvn`Z0n#6bM}V`EH4 z&|oe6(pmtbM3 z(MythdF=w|`4B&f-05n5!B+G5NAaaRZENly6o4K$m!aQ;EO}qAP=G!bUotbZmu;0^ zPU9M(G+;!7@K%u7oBc7m#3hsh@QKgC&Lyf!L^mN`v==>MJIg=Lmov_7S?A??-g!6^ z{%6^FM2i2N{?i##T-xt$GhkVHXMua)mIC}yc0sEDCx8~E`9q3FlE2NDz(|NCRFxqC zXNWEc{sYt(xDV!&=B4Q6GvdiSP^F{K7NCQS%}bCg0c|~L>8VQ~WV~NrEXc zym4*%JAygVNwL#x1}VebvN&3(o&<)SdcZqZd}LyO8&{A}T37gpUXC!ikyVH!P_($j zmH9(@A49>0YTYTgDLY>QHHWV)@0hVvFD!OIn$w*AnHEcW-E`j%>s-S7zlcbA#Lk+a zT1G6Q0~JJ$NOL5Fxk>P|r)>(A1u+qIM{peI6kKTwXHFz_Az910)Q{u<&WV7?W7(yo zgp#yi>Rf`|m~&-tk}=})@?rC$^L}|w3R;i2x&%1eM1NXoiszDH_TU<12| zrOlfQF3K^>2%h%6P?D#FyMqeGipvjRzA~Li!WqAXXw!e+FqUWtc&D@IjK{uU0{hPh zR@se=jNcUI{H>K+k%t;_jxr^OWmtEMYcdYYEgxe6Uqu}*j)pS2#6Vn>hi{ZkKfn-r zJ#8Ah$&MNRhdwsFa&(8xtxbMYD3_z77G@Bu;_oV zzB`lT`J!`04m!8bP1VKYp1 z9|dt>#`#OY#UGkPYW$rMWtNzcrO8j2_>SU8R^NNHK3qs?R}2^UZ@C_+fy6yhFu%tt zg+uEriQ4=^qMi}YcA%Rcd(vt83)IJ}ePM~+($=%}PME1ZNwC8wFnn6wQKC)D6oWA_ z>l4y2Gblwoe_nR}LXIR_JURA#Ik`zQ>lIly)gKu>C7Gjr!m)IY|C?2bpDCv|5G+19`TJEzv^(y0iROx z1b287OO_MwA`9>lWUX+X@Imt5f4;ra{Y?lV=J1Kr#UB5GD!wG}xjKB<#j%uF?sm5; zc%=o21**?(pxM2tn&-<8N=pzpC5%nF-GsGT39I4*u`)W}LN4S>Q$@ih?9z7w> zt!BDst`3qP5pQByj=s=~C_Su0T*rngzNNrXiL*tw2wx;5^j_XwB-)bYZN5kf#U)$k z;H_vv!2!>!oDsY6$sq{F7{^St%(n3OlHiCbzaf*MdqO6@f%6w|FPR8fgxE~fCCg=& z+0Kk!2#Yd6iYkn|yvN1S)$k}Out(OhN$4F`RQ ziuTf5Pdd% zy*7jGo8*{FM@BT75y-pyJ-Tn+7iN+%Z*|fcOiCnk7d6#jSQ*(ECY8d&ADIK6HqO%G z69qqi2lcmyLkvClmo!h#R)M|ZK}Pl{Bn17V03PZIp>jt^qIdnwh=QBcS+?=B@Rzhj zUctzVRD>W&i9JmKDRrRI31I=}z zr7L-?XI7~@URlpT{daB5oGSzN4#MH|;!*%bc~ zKhtP@3k9#k*VU9oXeM?jd=4X5U^U91M!f z5gOl)KGiGpS!soC(w1k6xy6~%@=PWEd?PLh&-x<4{oLMpI^Px1ovD);8DZ~j|>`bw{0S{8;``&Q$ z%w#cQ-q2db(WB(dez8~0;}mjp!}*^)M60QnC^@q^iIOvGFi*}{9ejHD%^*3m0lVpp z4Ww5=-?r+>nRXL9Up>g@ou2zToNsm1F3!(jf$2D)3iZTk!oA6&e=a3wMvfAzIrpf& zyELVd&jeG&P5R%*lDa%&{3x)H$8VJ{J2mhekj|L{VN{ZV=34TFpFy*<9Z3Z@R7$iKDBs*7Vt{52^S@Yk}Fw1 z_oaeNcWHcU+ z@xG$$%;20x?YF9K-TUwV_dC4$1BV+V7&jhs_+?QK#Uybknt}=CKoT^(uwWq&v(!-# z56!$k(OiiQk>NRbFf^3-PzHO{keR5A3gIa$K)#>>CnwY0l5Hq?>5dW^5F~kNl!p?- zWsFQKmsdwTwd1m!?6S%>&KpNMl4?h};QK(2 zj!5H6k|8(@0A7_Lu~A`34&;y(ZAJOv1&YfiOE}eHY zC=vP&o@xNgT_GjA>*`=5ExDg!I+4kHE%*%Oi3E~J?j5RYGjYcZuviJkNt^+99!?W? zcU4uV_ByhU_~ds~FbA)YzhDA_LQn`-dURkjE)OAG65L;o94wQnEhVii0kl;X|5=?x z1W%unGZ`lq9!F#^FI(Bv^CF8>iomRqSqP?Iq*9$+*RLDcY#Nj6;s6`WM5;1n*c8|{ z*|~yD$+E0x<|;C+=c=RYxQEkSS_de8h}L0>TdyqeOKz<_Kw9{zYs-LZ>jULI=ARcEk1@t9M$=fxzaFYOOZwMKE$6#lX5l+YedXOrTG`$G9uPlQBt2{VJ+0hh%+m@A ztI$f!n4^_F+W2~aPFLIRdKl(6Ao2%?s+Bp1uyL(XrIjP8s)ux>mC7DkS*{i>ad5Gk z2gPIJ;Qs0*Ckw4KgDUMK8JEaL6HU{426zW6s=f|fg*_^ojQV$|KXsib)*+l&Sr9}k zCBQ(h#MSW%_Ox^LOOMddjff_>G7eW7w34n}a(U#87OfPL{yMMZ{dG!~93=~EHrUK1J}#IZDhkk?}&>l{XSDK8ENeg{bq_t&G7k9BGs{bU}b z0FVuP34{R;M@&C}OZPKxT^=`M^fpWfY^xo(;PY6)6V^tgndd-2@CL}l#|!;WAA&Ju z%wO;1Yd*f_db{gJya}Sx`ic?ev z`Em`FWb1=`zBUFdB&er1l?Q3Eu7?(lLX?uv6t|Ev^y^eVgGEoay371beVhtg96W3f z0=+I%MqOw(9VimIVmvqfr%c86k%Pk^bvRF};LG*NT)vKN{D8{N_Nb1G!&k(-g}fMC zj}j?40jm&QAK>bNf(}?bICZ&Jj}8eYF&~8R2R>*hE+-_V*MEJ04&(1U8m&k5y_APZ zDQApPW|mRo+N#YKYBifhr6I$viea-t#J(XhnUy^osiR@CLOn~iSUv*!9fW79 zWDU9x2+IV|gW*92_ zwqTvsA8R%s@H%GT#A@gojTcY;db_oY5KL6reJ0_am8Z}K{xRS3m5_HcOh+=PCt})% zXxKT(?2ng(C&`{E4T|N^&@8Wea_8QJYvwpq7W|OhTvP$40RWks=bH&jSglPVLE#Y? zf`AW-dcOwkj-(TC`pM#!3~1xY%^HUzDm;bmH+Zm9=Ws<`5a2d=wK3>?R2zQ>;N257 z(*Q`KtH`k9SaQ()xz0xC&{tf)g?s-B zNI3l#nHeqqYf&bO`NrToz*c7ZE%}=JofutOYYo4X9L?X|M;`8czhU7Y=*xV!HHO4I znn!V^`3infaZ8_=xCOgjgGB_3aKDN3SPU51^9yyXRu-H$^jqEoG-ZI^27hmFnLwt* z_Jyu50jh8W;WrP{YeoXahJ+tRWD{Lh`4_^(|2EV%B)r+P+6VzAsU=?HV?8{b2Q=2W zEBo_(M4UWmw8bwmX`;y^4IYxTp?|ON9*2xgJZ67FPIh5LR=)%psGl6qa|G=6r73ED z!JZj%C^4mkGoPGNwf>nYl!5sY!gv_X%7gjftjH7<){9dLCH47a`OmDsPfkb=5B4O) zd_F4XlatfPi7HPhni%g{a5(5{5&qBj#l)tTmz=#NP_QLAuYr{hCE4E-9_^`Ifa@0a zMDTBj6;i6{oerA>(E&0-eh20Td~JsXp3nheeeRcGP&?(Y^h*xrDeoif=M1C!I!j4 z#qSpKf*FcHED?4bst3DO=bajM8d&3c8yT5kMxViz#tSCr2lI#%Wru6<3iKmZ4;Hrc z^Eg?xco~ew;(TxhVl9LQ1VzXm507O$^%*<_!NxebB022GQ7WOoicBc+4v5c;7+zZe zuKR};mQXCneJ8lSkrx~_#QF;k<`)D~sTA>5#JpB^^dQ>5FCgQV+M^EzUS|m6R<>gV zHR;X#$y%gFdg$b4z7E|P*-o)hpILyfjJ9FuZw;l&4wB$RE^iF_3{0fk2I1sm$OC|G zo3Kn*fXYjO33ZgqHzvID3?ykQUuo$N7mV?T@(V&rUkk+n9t%vyVZPgFfRU|RUnfbQ z&FVgc9K6xP(zFLMp7284dqj0ZeMuTp0AxJO7wR4ZDT52&<+-Sn&)3ItV(9tSH6?suG7ElIPxyL*ipU8doc-EN-Oc}G8+zf&!unY$R_N-aKRlx;SbsTIXd;8C^XccBA9)X|&8JN@T zP1^JiuvaQ~a58?0Y|DZi>1B+L@4c%$Ym1hc8Nld@rhM=H!QN{Pl!&;lHIy%D?ZHFb z5nMT!YT+bo6;woO@8A=7nOw`uJUM~wK;^r1FFvNNHT#nFmy)Ah-o9KBL|!%%n*5yP z{NH<95pH%ewIQ`)J@+1I!mn)gr7*&q1f4uc3L6#owhqY%#cv6^EyP2RkH2?Ys2R>n z_C0S8?TfTz_nre0DP+Y#$8W<`2l_mWJ51TZLrO%aev7;9D_hMtciJ>c7WN_j{<#6` znj8w~uq&Iavz;7w01ZoklWW{KwaXi!&1exCIq4ulE8+|{(|ZuQG($&UO=2t~y@}E< z+u@LoisxNOBbwW-9~8G1+Br!_6RdFGmP(+gI=p*@J-?E`$0lg(#3qCPadR|CN$X_pzk) zbUkTyKF}_c-oeHd*cl5HJFF*=F!ceW?{w9qc)E%MvLVFNy`Fpz&Q)KF6!#XW$nzdTuwm?-IAb z$+wo9l&rMJ9TmgS?cQi)-R|{C|LK@9<96R=^!=v~FL#4R{?|65?C4+f5y$ybuIH6; zuk!3TSmb&j>0WnXmi(uGbD@g1-kI>9#(CA8bg6x*$nlY(9N`c=rTADpNjILWU{mw2 zg%+fFH(d&&3fit1cw`)z@0!|M%*BI=KpWqHgS;0BIE&vx#1d!VEH#V^x7*8twWv-P zc9E`vt83yJNp-v3A-D>o>mpXFU56+X8{VLQ#ZRYXzX87&+s7Z1iA#ehzHC&#OPjWG z^=T6ni%*-m=s-^Doh)Q2lkGYA@d;I<6UyPooGc$SbCEGggFi|mVhlk*k%5$Y4jyH9 zDgVL*0?-6bN?RB>8|dV?6g$chkM$!Q<8OkH3672Z0nKjr%l4BF#)^mtNy&8OWvfg2)WNeF1lZ5$~ zwK73)l8d~2Fal(fOZuU(&S2pwAc_|~CnA!-yAT}Ep>Z4Ky7Q9Gg9PJe7%W&G6tXES zAbZBGeAYo9=JL`ADAc|J<48?1+c=Zth3Acl1`^-SKLhEMl19YH$AVbbno*fo3EJ#Y_ak2kuP2)^Bsj&{klJCVz~mk7Sy`Qk#eVs|P= z*6w_R{lN?_>qW<(#v-vW`lr$LOR+#$`xBmd&lr`s+&|e{YFqishmW<*OS=zbNV0Qq zRxV`PkQG)+rwd-LpC>PuBHPys|MAzD|1$l`KZPtml^$oBz-xF3rsC4*&CKpl-n(|1 zc3)@kki0R-bpYh<>(A@dAf!a5-!$7u;3#J3J(FB=^g6^tFDFlP#kWt}R~3s0zKbL+ z1(~l!FZc8KxNRh>61WvzEw?u#g7)g0-259@Hqj-ekRVWi%nuR%H}tPWk}T5y@foVR zMQtj2Qqp~ylE~#<)<}%0qWZ||hg*RUQ(dh%@ZS>(Dw=v0&Y)el#Y&%14=YxQJQ~uH23mVSN-n;9jiH6s(%q)W~yt7OtDK%kll zVlMK!f05%A^dQ9+V%PBHzH^i1s{@Kp{2Wwn=F(EC;*Kdi{5sm}i6q={G4t}Ka}&j5 z)7N7Fr_{GlLhW@n$uH0Bat8&UQw}m4CU3GKDds!V1hIAx1he68%$liO7`%f0%hk$w z3isPCd?TtoBl~amM9!nz0Qgw(txHHM)#?P%1q`V&tE$E1VR5crAyyU^m731$??`Rd zYOwkuKjKXl-em`1e>HTnb;AN|KE#yiOi{K1M-mKLEK{(|>D66DDj@uU}cB zIJh~Ryxs*0FU0bfyD8A9ee5H*Q?*AvNkgDTXOZlQMA7t{7MtA!hftidWPhDT zKP+He#yrGcsx*!^Vx{jx7kin!$y%b+k-gW~0HY8Zy}VW}bz)dVkl#0ac`a1x07v1t zQtH41!KRUQxzwpnUk`QviY#^JRC0V{=FO>6t?O#8X%~@s)w=PACW|}T%*^hv8+KnW zp7N0AgbAR67K!nz+GMwWVff!Lymd>foN`}d6VRuzO4HZ7p8=*5zF+s_U2J3d(dJlX zqF*w6BnHXchS-ek2xJHOWeD}f9k0~;p#*6gCM}(cdqyQ)c&}#e70KoW!+TZ60}p%b*2#JkbUl4;RLtK?U)9B+3;mSrPT+LrB0r1!Wv_wE)^ZB z%*&j30p*hisk9I=v$Yxj(r@y~-z~ocbiY?f{GhR!^uNa@U9w+3aE1cDAP#0R<(T_2 zN7%?$YHYZ~o^8C1QpEJHOC#Fbcu?}b&oQ{f^{L$8hq)Y_0N%?ug8a=%PaRzkr$SmE z5gQ{05Mva~`4z>ZZagkvDA8F1BR_L<=>8nx%1m?oiege{fdnoZ(p_RR7Q?q>-Isui zsvtfom7-Jj*HelR9OgV+j~qaDY4F1yCgEvv^eQGVgO}-*{I>Hi(qNWGf7K~Ns?RSF z3!b>OsR&+B#4EXgmcS+~jR~oZN>J8)F%pTJblJAy#T#36Y^OQ6!c~yKs37JUIqmij zXMm$3>zh@sx^i$)C^Ud`#rp?&C?n7CyCex>er7QhIL6Z3UadQoMDjMcdDCK|WMYVp z0t*-?Qk&0)ZlvA)AJg>6vP43UlxPsb#8--g$Q&TG6OAjTHr)%jK?T)ah(>zrlr|*t zUeQngGwI?7Kai|fq+NpL*AO2){dp=_0v*rM#|V_y1Q0n990tCsqWmZXdD;0v3g%>h z67hvNL`)}Ve)Kfl0x8%x8~2ejmz4!7`Yym8WU-qeLp1pC?iQgZbA=J2n8LSyoDf_% zP+~w}9x;SRj2LjfKBe(5RU4-gHcttMDdQ*E7n_a26;n8CKGP^VuuuQ12`lX^2v^^% zk6&T>zaYv0&B`~WqtOOAQe%6;p{zRqb^3Q#BHFMC9_3Qjb1|amntjn|OHg(^L@B)_ z2s9otWq?_LHB}&y5Q>RoO@(ML7*_D!@Vnr=7`kElTXRJRJL48rTr3fTQSq=$VmZb+ z2&)Zb2;{n}D*MlGbHmDR)0}tm&1s5#Y<9sLuinmBe;6{I| z4y8kn0CnJEbSSMnB9VD966{eW^WvH+A*Pt-6m|F}ds>2Xuc!>A)+4g_W^yRKC**t} ztY2IhBy1$w45UUA`gX1~W;A(iiK1n&5$j^=lztJo1kP(A{i3n1Ula%AB*xWIkr*@K0jt9%`K3o$^z=F*ivs3kH-RN*$e2+x|zr2$OAhxU16* z?M-=icMt((II#(eIVBovjRzFOEkRLY_&kBl%Vc51nzSM7_LCN|kP9NjmK6ex)?5UE z1|Nkt9)q8*iSa~x+nXt$phmffI;5mWi-rtKyRqZZ{YJ>6_eypE2T1E%3h5SCldhCZ zc)&98$aoHJ(6ks5k+fj_D@h@J>k-Tw=|0>vhGM4|1d4t-{05wly$`*$c;D3zsJn&* zeM$OYVM05RJtGG0DaQ|B>R}5*<|`m8Z52brm|K=iNU>NiSwmDww`U1JfFSkL$aZMf)E8 za?CkSLrOPClyyc_dEPSgm%Y7(?BIU`XUMuHjKfx~_#8f?Rj7vSMY5>iftk1M#qOpy zD%W-fMnrrK@ZyUhjaz%UQ)|~OF9mkd{A}4eL1RkYYXe+ycLYgi>7Gx+TWc|>DubFd z{fXl3PhIeiw`;<|1lH^Aa2Uql7lzbBGCjRL6-#Ly=daQdguyFSv3(44KQRQAVY%dh z5Np#<#C=*su@{#f`bq#pmkT@8$wgpxf7C(U)Jb|VS#xaka;>AnlwC9QIt4V!B<7#! z>q%hJmf}Oy1&a+aNdJ2UoU5Fg0^~7g)9hwxNa3-hPX;uHoN($^vI7{8pg|N%mjJ~p z(Xq!<&ks7eijBAH9EcgY0cBn^<&Mj&{mqX^<`oj`O}J%**=*6Mjcw@G3QC9>Q^+RN zX`mrCLXwj)0=6FJWTQHuD^q85;V+TL%`++CcJ{WATOcc=H`O5(E5TrA1%E7GnToXx z%q>Swg< zh)^I(H6s)P$Bi|DqK|8#2&f(%M@C3OC*$`fHQM{Fwr)fGSt@9*#=Xk1N59> z;(Z!`@_V|z^b0+#efBbabxww?_pRbIf3NJUH?Df z&|IX14SClMHahTGAgS$~`Typ(bs&6PJ+qS>$h{v+)7FZ4)4$pW725zs(S_5@@4yQJ ziSWYUAoH$f?tCYaaOe9whV!nu7Z=PrO=|%}1GvKCVgg>Ld1fP7M73!CrS-{T+O)nP z4Tu68wZOX|!3vXesT1JjGK~HhIA~_uyD4}laR*|pCF_qQ4}!kfnHw()oLhXGOy^C&Q4GQGAK&t_4c>A57P7R*?*sF5t{jgZh|kRfF!oCexkj*G80 z1oG=|3B*bP5h z{0=@vOaT4QSmXfuWvG#goeJnwqLh{#sA!D`^+ianAy43>zM^=B6o|ieF+9G4;k@a7 zb%Y{C2Ha{B(QhVQ(R~RhL0LW6`%Y>4fvkdW`pn>i7|hJ8FJ`kCpWPP>#Pi@3?$2WU zA+KU07%sp~bdFQ9!v^!~%gLmS8eNy<=S<6s=Ag_i3!&h|ad3J{*gTgs16&L|Lz$0J zZShV7J@{w^6&7+F?Tqe%H=$P+x=>J<7+=z-`Gf5kC|S3^q|7Txh0XV2HX-m^@<+Tl-uBBA-gP7|)Ynh1lTcpRzw(k&HWckwu1w z8*^_F&~w2~Lpc)A1Y!2VgQT1NFR)sEt3v@T32-e+$~wu!lNUV3%Kj3 z)RUv*>fuxjb-z-{vpl%%5R5mNyycQiB0T0CZya@~pTlcKr?e=Sohf1&FfkY5rJukE zAo_B0LJ0tYB@l8UF&!78oY{+TEP#YvmzS&i)mxfO@Vwqlj_@3BQY^zLcrlih^!#ZI?SiWLM=2k z%8gbcM#|J!!@1ab)l7n9&j_koBmzdm%*ydtBH%SxTgxU0`qLW1eq&Q39eNr9Hhl0# zzURFcVW$I4#@;=H4!Y;w`xv-PcZB#3I`G*x4q&D5E$`uA`_oNqFP~yG1~e7vPu_WN zS`zf&&q?&?;|YAsoHV(QStzY!eS>`^H}kyV-N(Vq=p(XO#n<46^r$S}QPhNiN&qsw zm|L)pYo@GDTd?5F23T{*p^=AQSACxP5y++~C|3tc?T*#HytGxF{xw|na3rGS+US_< z3)y-t*D*t>84T%9!hP1nOsjOw7y(ihH7{PDNt)VgUa1BA@h>>C3fq zgTH1XoV!_sOKiBB-?o2Fn~I!1Y{W*$#}CVsN&Z6M$!;KJwVwqYNrj;Ihdc?ke%&`f z3|T4_fFX&$Ne&Ix8Yah))V8;p3)@C`qVfTUQY=?@A0ZYSH4t;I$n-a$FS+Q@nE$pk zjo$`SR(#LEKs>xMcnS7uBcBwapqNbwJ+(#HndkaT9Q+vlfh0Ik#VlS2MocyYhxjvK z)V{>W?@0_V_P9a}IZ3c=)79;*nHiHp!@mJbM(hbpi0LhrgOm!VqoCk7AF`QTTd=*_ z=8S!X;(dtG4soil%~a)ui`FzS_E`z#BVTy=|4zyTp^4Tw*S(YNjvn^{0(K!NmBc}j1C(!}BWXOP zfkEYsSPWms#g4)8!uI5S4g1GK3H{E!HUPr%xp8@bT*LfU81ya!g#~B@ve(v|Q{GD^ zr$H(~M70x{9laxufWC4S+4qEoa&t3jU53zF5)ELoIht&;*d(=voc3=y-_6 zW^h;@KfHefC%j*J$;}kvrxDNDdP@Y@eR*O0t)Fewl5T6) zN@+uQNn1+N-JrH+Q5`D_kuj{SWVr4|w4hNNde(->X*v?UH>8~A)fqff?nZ4ntcfvk zM^yzaDw-o`=0Z|z$nM6`sOGsFk;S++#^aCEI6H|k29NnhE<{b&OCPZa@{HxY(Gf?;;>aY!qDh zHhc%&))Oi83)M4@34sE`endwDB=?Ot(j*X9vJsx#S>N%Tgtw8ON7(*_!A5v=Cz?j9 zi6UGISYBJwosA^eXTCLck`5XfZX}1u^=ghwIGoNu57UNd0VLPmDClEN04Im3V~mN7 z(1>D#4K!YwGg)|q%QhtDr%`8xob-WBn)g}iWr0`GHFu+*jJO-URLEKdhIFosby(V= z!*7I0<-QTIHwwT^Fn%;_$tNOJaLrOK;b87Epe`McRXZRLK@FNj74ki;m8+dtpz2jS z5Wv=yY9~8fT?42k+|V7WdZnbErlm*!N)>8Bwl?Z-4(@}^Xk(_S;N=DzRNon%!pp_O zdZ&)}f+HbITKAM2AoSo(<>OE4rulPbpppg{Wpe(;RHv3PA5a6XQ#Mg^%|x zEoVO3bvF#f-C(&rqYm0^<>oA=jb#iC07nGnnVw&_{*crCnzNB!&|gttEpcBtu7JDf z=>MjY50ArF0o620QtnX)=`56f4(7tTBdwu+Q`VExv*J-nC-S5K6MyiHj;XJb$X1DKi$9k+}!Ua$T9G%7(H^T#ZxX~gdA4Jzy5tc`!^S?K?QJNUku^D zkg70Q6eF}s=2Z&x;mMtBdL+M1pJ{S*7m}zHQ&P=4@IZ5A)L$wpwgl4G)^9QisiQ}8 z<>?WI3e+<6{FsT7#U4qSA3=U{kLHl0p5L(~*#c6mgX|2;(#9kYq%fY~0vO)T!syP* z`smK`IpHMiJLi}f91Z(-lC>1_@6<2YcWSnCSu^3^352v#WOOtZGh(?WqI#{_i0h4lkVl_;LNgm}GvIrYT4n9pW$#Ci!GJgYq1=H#TKi za_ehNxH>$j-bf84DlE#13|aGn_2iWsL`{p9q^T}B$Aj0^q(?dwq=!Qa*vLWLLeH|8t^nRJ29d82U=#OK5J%FbUL6v0g zXT$a*5I54BXzOkT<0;t%S#v{XRI-rDF?AmC)D^uAdKE?~Y9a!E`AU@-H|=mGQp%F^2{vZhRK*<^PDz7LM1!Nj*V$7jqpyRA?#T4eU3^mj8%soDVC^>IA+jTN z?mir>{4c-Y`$UN10rxR&bfus&frLp6F?FXe)LHioHfrxN*1`?;b0^LYH0U`b0cV-X64X>kk>zi zA+P$B7<`hS`!DFMd-c9==6vssU

+MU8F!srhPBe+r?XPoY4?Q--2H zWu}yo!W_X+=>#@7Cfa#zazsC6v2HZvF%oPs$5VneFRYJ`_r*k?1(xn}~T^pl%0o|^{P(YciDv4T4KbLNY@VhR1+PzhVBds}C6@UGf5WmJOY_#d>VBRhM$LJ zXs)ceG@AlV?I203ff*q=PeV?{(3~YqY8ZYKQ=yg@27;Llcn|Ox#5=$-=74o9Jg0x5 z0X;}!=DQWW*-tY6^Qm+GQw5y_s?vo*0(bT_y$QG-0cbWnz1h$v&(1ZI;#ri%{X84U zkOSl5Q<4=#foNlNP7BV|EGASkFu^gKbG@Moh~3XJ@hMQPD0YfZahR{iB1T_eQz5}^ zKNWl+3~3D6=7sgqvoJ&Pu`pyZjqN`&CzCP~VE)(j3JcPiN$?cMNdog4l$w#IY zW>pKZ$?do}pO{q8dR~V^vzHj(p7dYid1yZzISWnKQh|eE9e(tcDnhJU;%IeZTA)CR zgH$0{qQ+KogwXFD&mvdt{#kvX7EU>mG$N#hfL~j%3SBgw*Dvk~dvGC&||ZwFQaQxM=isu)t0@tW$N{dkCjXg{mbf_U}q# z78zL;ln>PrIom_VKdoJjIy)dx`o#*P9$=v`T7dM0(w{!obv z1i=LI-zxbvxSyfv7#DPlEk}ZwpKc;KwGg&Gc@=X`A0OpY3+1Lt2?v#LRdR+$7V&Br zz7PvjZdJBmk4bc0f&mkrcaUWuIjfNSLZOgp6(TOoVCYg9yhwtV8ji9HhI2=9918#~ z;NAzxKz$ArX94d?Z(9TmD@s2PBXtbnh!}0lx`K{eLWw+=PzvFvBkyGdq@R6jy`HdO z=~&(USSmc_SSc)2!|rOef`7SiFo4c;&05yn^Qyb5hdw}xxeW8V6c$4qTh;qv%U#|7 zme0do<*BHRmkG_PAe*KBgbNaj1;gOG9=e6>&5nLQFOhCj)!PWmYT8#~lbV?DM%8%Qid+>1t z@dw6^INz8H!Q0diMF*>K_%2*=zPuO>k1fvJRc$PR`0!=#Dm#zM4vS@8}U9tgbaeB-^XUTd=w4kp4>P&fd!zBq96Vy?~Ie=^+e4x~d!^ zjB#X+rn8e1>hL^#2{f)Yzucu0vU9%qm+jFpWq7{Q9G=&EUm$IG{-i+YjiBz6b@x1( zzdiGK)jeNU?8Evtib2EV!)UoPgSn+YXPxgw;0;&36R97KQ9KbvT1rq`i03^r= z_IZqgP5^PUd;uYit00K|P{j>oKTOi;tNk((vU-skNZu6Y%cBe2z=u<&wOnX=7{D&j z#*vp}9j$Cn&ufG8m)6YB=eMn^Wa|hjP=ScbVZ9E?V({Msk>spyjt(z2sDZw;Ru^Sz z>GTA=((?TZ&FJ(|698@Zcc=q?>Aq9ZNt&+U|6-ZSV13PmUhl?x;(UqQmOTEQ{M`e2 z<|ASAces6CwXMRA|HnwAvFM$^rB8L~Y!P3)Fl&8|+pE1wKq+DT0i`^7I~i5bgHfGz zbv}yePk8kVS@j2-Uts2DJmzwmJlsplE@y*!J~V7zg`#VU3FgE5u?D8>;4Jih$QC96 zAC-X}>ISnPo>5Q+Dvlk~W*DCS;1@9sglij}yKxd5AMRW*26ZmZ()68&iSxl(Wm+fO zSmuF=G$q?c4nNJlqjLe}zu{3bB3@nAkK_{GSpfZx4FGL({YOdv2xp`Ek{X7(v5ZvH zp@D3!1Xq@+%v0vJpL760(5 z0SgPICxz-e2**zP1}rs)6$eIv!=dSFA%(EN#^yS~Ap&nQFG-U>!4h8Y4=o_fu%uU1 zr?iw(11kG7hw|>r#?*Z6Eh>9`%u~hM{qMg9b88T8e)N7D6>BLm2{-K1zmq>lL_UJ& z43}I|;=+VWqXmR-R_DF1Ha$Mh}69FpwP&802cHAV(% zO^ID;C>pzCGL8XkoO~cuJHD|my~UpySIB$Ot{rJ)na8gzovzbRq?!)C`hb{OhWGl`2b;S=VTUUp+iDZT zXr>Ojkxra~+tVAgvVzt{vuRNiZ^xjpw%QnC4Bx^)Ni-*Q@PTG?cyl9k|9{Cz!|R{8 zp4wa8I>LbH7Yx9vHvn&}OYX{vtyaA~)IYqF%(l1M^%I^BCz{mN8&4vmUEk_-!BT@S zDzeBFTmAuX3n5@ zPglDS!a<`yXE%<|&5=GrSa+WNn3$8`I_2g(mVSAZYfKhQ46p%)eKd8)PvEs-x3o8D zcNem6lK5HwpCMU>CPr3vQLcC-j>)oq^WT<$c-L%iIse>be88Ie);kGf9I=NATqzzh zekmJr;-~OMK72pXLAo*3_%6U$y5272rb#Q^uz1XAl1p%Yi5HFzU%8yqu8=Ia5^E#Y zByiEhxVcEGF@`siEpb(NYz^rj>Zo}#bq1h;O)?W*J|~(qS)EnqCQX5O+-6o9HTQm* zr@s_S-!rM3k3LDyw(zq0HX4&v%O!5r4#;zOT`M%)lv6MBDPqIIN*@q#VEw>*=5C@sdg*mr% z*Q0-_rfF=`;1rx#TQSAv%>+03u}41}N+V=XfaV;%>C=%kSvvg!JmMezGO=oEZDyAM$F)6ddZX=Ym*pOVa~1e3E}yX*0A z0y-Od)cYztHz*C4-k@;+h6|30yuV7R1@zdD0X`o(kfk^RUC)ak(_`$+2&T+zM!BN^P3|`nB8}9E@X(2koC*ycpsYA~KE&7n+ZbWd%*Wr_(npTIJ^Y%G6BCVT5gkQq zg%ZVEfclO7W2&Uz{QU--gzn03p|H@+zj2$GoEvL8J4buLgeL8<9b&)?I`ekCq^|k7 z*5jvl%MDqFCjIznF%_SLXeptAAWlQY9hcJIw<`)JAt1c1R{PYChltwR_rtT&fbK>E z;e8KU5+M#k84w#>JRu`m#6=neCOWXJ@bvC$ne_0_n!ASuyFI-b3Vd+OVF-1!RMarg zm|!ww_zNyI33ov&6>MkZF_oj^pmG|!IlT!#@c^&>jgy-Z1rLsPqB2I#BE`{yMm)1S zMKb=D8gb-IVL(e5K|>ig5(@5;m}S+yg*@)+pHl1V$`%x0T#ayN`@yklZ$0P>hCZ z`m}eV*qTxQ+BA2hkNKHA|Z|HKqJ8 z(2sLPWG9w4f!Br$6-*>y(TOc(ms>={ZUUi$xWTeJh#KkPQNKNk?U(7GN6HXMJ%Wzu zXC>LwBzrH~Djf9bgR=6I-QA-;DaYDd(w+%ER4B7xQOpn{@OD2K}nLc!R!4$E;^z zCZ=D6=(#B!zXBwD9dlYa;j&<|PtNJ#4>m|&qxPg7>JAmXeE$=tsZH56m*8{0flVQA zwQW-2O_PzF!H@z->mcFl=PAA!<}0*l}RM& z&9K=k^5)zX6+GKLU7GSVU+BtHE}3&6z1#~Jn68?0pdpvHL#i2JxL>jh)Ayx=7NJa0 zUd6W#P32~YgInmEmGS+|M@aF^4G1&$rSu9jW%^W3viOEaL5RWD-`t>Bo_-|MAwT+~BgX#as?C${9JbZau!sxqI-^?Y; z=nE*YO3@-w%UM*o$_f(gEn2yyA7%Fu+SzX^_`|JI~-Y9G;2w6&Vv zdhN2k17|wUSige!(??WmpihypckEX%i!RpF84RNj2WewX48bH~4_8-x&Rv#4ogC;I z$W}Rm;j)S$GEDT29-U|e+s!IwwQhYE@GM918gjrxj~xSBv9NU%b6H$*1-7uKXTc62 zjvvPs_VkXSXT^yV*utLH72s&;H}Go5k($BF3g_e(yNWhH`$v zOa_YslL&HT@=Jqoz%rJXF<{^Zr(v_PH9tu<=iyfXO2B?Ms_)0FdCo5!r+IxJE}F2^ zUNgRTFaMY>1=7%d^s^gDpMCaFdsj!0)xso^Sr8H;3FW;e^@9nSI)D=nnDh<~Cb)o) zI6n`Yk_G${eEQUq9my=|^4m&hRY_2H|9(WRTG8?Whf>Q{B)1F`h_r+^-V45glZbF& z#g61wf(AfHy9)~g*+_Z>Q^^4jxB)m|TmYx)t01`fkPY5d?n(208T=}|Jf^p$&e8%J z46QiOMbFB6VW%E*tOf6~7bDrMiZtf~fXp%P3>dX4zcw%mAI6XbLr1nno~j!h1d^aS^Y97lKJs7&)_y+T7mdBM4r_ z9tUN)6}lAkK6*Qq&c^wOL55T$&@vOjN1VOmV2k1&L#L7~IJkY#6G$Yceu7&(ADx6T zLr|<-_K1m2DklDG4g_kM!k|n`i7+C|(VoPIz@I`ubDV^4zQf30E2yk$cObp&^a- zPNBG{PYgCMQT7Q@htU<@bOdEZ${|zjBcDyhx5qz4!M^|{H9%ZNnOcu^OOjti$V?|s zRAMkF>LF;%rrJ$~u@veIa+gZSSRUmqevn4j--0ofR)NB6^5X?fe{fntf)SA)>kYrH zccG)`U90^-0*fzKvd_hZqa*2Hl2osGr2-oXoI21|nOg>p zD=L`NsPg$2za*RTa_MXs^(lPh=kN;mc@G0W2xkpx4oPM))!;A^3oh_kgla7AwXa zikT9=kp2uBh=PQNO~!qS0`{AOA4Gi$3rXL$QBgiLWHV7z=Zj#d*$lOHJvxbRsF`S3 zu0&lq2Y@cPLZ_0kWB>n5y?K<})_E`ZU2L_XsxE-qtGj_(yICZ=(amOWqD6?LL{b~e zA|*;||P zrySa2(ufqelRC)w8!&RLIuWaZ@SspTFM9JVcpC!4;exUSDHfqC%+N>wqL8(kl3+4! zt6RgqJo$Hh^S~`vuS|ZX@1nU)*hEHMe~%n3vPq#;Bxm=j=bt1=woK;=Bqi@mg^-sU zuFK&G<}#wa2sWo^$5B+iRz!GPDYn2N=;$s00(OF;?B2Z-Et~|TqnsU)!Fl&*x8(MD z-@gW^&bKUD-c7qF^ECN@{XR*W%tIAir^u=9p1i-MZ~fPF$@i)#fq5I))XtBGJvm%& zMT{?XqcN3e(qCr~Vg*|vf4xU%Oz>u@G1!#G` z8cayC-;PknalNE*Q9m|Z1Q;yrWc)>DA+?4O&-2(pMsWoggR3ldA4d%iV74K9p!YsO zrn}t~ix2f=Bz(2v6Tybyj$22yNb6kp@}+i@LO2nvm3Bf_(CEvcuJ6DPFB`&w#f>M(gIpv)cItk zjL$&aGg;|MdxE`0#nw4(va&40l@WMv*LZZY!vFY1CURof4DU~$4gl&IuRsRMG)F5L zpI~hGq}-R>A>BaT57Zn{7#6y7d;EOu(vY+t4524~puPh-u&!-3;{D{TRQFh`*7;{H z$nd^SP}+T5z3!7Os@a0zy%#&@t@9T@a-$A?mDwniJN_7CUYe{N1>E361pC{<=wrAc zHOMhqrJp4epo_%+_*cL`L2Fh~Ou$*l!1Vl`(OrW5aW-P73AmpKd8EJrk%IOuSVk}7 z;H2Qc^CZ|zidRZ$haQJ9ek+x6feu{qDWwCHLD|A$r98Z>(*kp z3X2jAN+}!l>l5JvbnWCTD#3VJuF+x{_Cgw&hGg@7GrVc+um>pNj+62Z5zIr$Vl+^-e zSOBsLc?u_>aQWnMjZq2RV421%lEuLEJIkV#4m+*a7TiKr9JBWGnfDY0ugA~(Cwnp& zGCvWX?4^LnCSd7032^uVSbCf!08BJGIi~=GJ%TVP*wTvbif}k5cGbi;rF1MScJcpX z8L=xtNleGH!sIp@){Yrs7i#G-UF_nvj%i{Sw{!y+yL@yKqt|*BXhJDHfwRf-K9)Fp z^siipG&KChcouk~BtUXsc)36;g;Ox_&8CLh`jrz>w4a6h*JT(QDMc&II7qd&QPFJ9 z-5Ks@W>c`}%q#Q2Oly&#tCrmAKK_AJX=jpB9W665X0M#^4A~V0@3e@Dg!XBqN<+eQ zga3Y-BIBe9;15qLg+@t-tdDDy3`~>}{<6V*SdWp$ji=zsfPnm+iSjTKD`}cMHdX=7 z1Vn)Sga9xPSgT*kBteLqoMV~->eF?F)4E}#(AGo@$8uc&AXgkN6PR;DZY1-uwAw_e zC}O^l@-u{s*J74vPy3z*+2=4Le$W%{xFFS^+#6;V9xBB9G_Wzo?0h!fx2MSCeL31& z=fkC9ypOKOUo=q5E2g(JvpwEN-X4Ur&1U>1DQ;|WQlwvH1jeRal#mG_t}}0gBN8HE*M7(?QyVd=Y{w|7$wy0q$7;*5fV&llb@!Ul z67$*IDv+>#WAobsF+j-Rgr%aTVjzn(0<#L_V*S7*L9fJBZ>hWzgY4#d>uVrc500|C z#dVt+YX~v8X2YiDHTZ$=!P^dCi~Kf33LOA1DENcsweeE(V7ydu;w2U?Hm^hX5W0T1 zc^KUz=my>9_2`Q6lGYAjk-T=INzu{<9l9=B(vFO7SDeKzkU2USqXy5Ctqd;}(YK(JahiWA5t4-R(lWWG>+6)R}mRhIXYIFHOCS`?wGbMg|kWL;E7w(@ltl-?I-XogQIKE z1dk^m$4y{ZgIkWEIdP1W`Sy5efAdnbWL_REwR#5+Mu<9J5_;EO>n~L<2TLqk5@L3+ zb5IJFatqg{1B`}>2GOdB^NWT3M~)nh0k={A5a0&j0g|=9dIT!>;hKd-M1vy<+#p$i z8+_KYZ4Z`~RArgx61-vFDFSJ&Ect5kwGu(?l?H2T;nHAZgHz=I3R8`iG~3A=b_l(A zb9w(Vq?*hAo`Gn`yR`XnL7NA~87-BUp`b%r2avGjsO6>6(txlhQ66c|wtWtSX=QcA zsU`S=v=orGM%i+5p*&#Jx#eXyn85A4^yYwgddqI2$YoNLVu>n4N zpg96)mGK`y=6m`XKzOP;OrQgCFN?^!Wb$TruaNM%`6O(C_KH^@36+TV%*h~7cv^)< zY@mt}HbC`(?k4SZ=q3rb9L&$VJ~mzYaEJ?GNkOu=13DaobeMHrJ4QczRFrDU8&!u8KS$)V}(-7dKMfyECLfy9A~ zXRk=^l6DDZ+de4FmGOcB#)a$F#`ALUO);*tQ-I2_p)rDw=!HR3#LTEWyNccg$n3eY zHTvs!E>QhRj(AAkwr-u%cI7uh(hBA%wD>j|Ls}k%* zrFjX-Dm=!1^d5P#?*t|R%(P5$g+wh^Tud&+cF__S8k9m@O-lAM1p5ah1~r~Jmcg`+ z05n1zf<*(-g8S08sPaX~_C*d{A5?oF1Am-TGK9#sr?QfVd8! z5J&bkfUPD16!EKj<$^0hGR~%l3M#T9`vk68fyI(VFCut+G3CEE}n# zH1Zr67IV((XGWC_E#7veC_q8l3+y6Ci>pdr84>b-NFmbqz;`jAY$C#kdx0__Ge9%# z4+Z*l2nxdZTdB#3Spj#2?TTxYXCqu4*+BKnezTM2KIz|ckj)|>(Mh$0&2thYIS5Q$ z(!A8}E26WvvH;BP%=gJYGJs-ZvkmYRo5KHX_ZEUYmSx&AnZ3U~L!I|g_>v*ok5cG? zw=kR9NYFEfH#89O2Vu+=L`>mzlRb|w8{AY;9g&F5I^eJ5J!-Om0l7L`94+LlqanK) zTvQn?^nJWhY-`n}(E|InB!n$EjG>a|Xknj1cl)W`aWPyluM1I5XA&;l+@JguFDQ|YubrL8%}NNB4~+!dU$ug=E8)T;&Cvgcbhwb=eMqW~O7_dj&r3v) z5m5kbGk#9*#T7?A2VWVeigSzlIjsNo&OV3>r$I? zDpXp~g`lW!!HEL@A1a_oX^Djj8>y>V;4$RlktBK#7M7bO%sVWk(!W4~z%>Ooi^Ek3 z*FODCICy=+Nzs@Fzl}xK{~{)nwmqbMD!nIGh<3ML5+-Yg=%Aq3@1~QJ;3)e`$#Ot- zCu*I)__^JpzlRs-!7}z*&@dh>V<$3n^q>(UzReAPQa$gTtu8$Q?e4taw|QkzOjp^(9WhzF#>&Wic)Zf`G*7LQy+`ixi@ zdJd((a#tSn?b(q}=`U!6>z;;ycl53x%inUEeL>-cLnartAes-QBU|aDWPtXnPx}OV z_h{kb>qYAQr6ADVBRmss>T8up0N0)W3m-G~owc(*d;5#@{9lmu3v9fmy=m9FMLeQ& zr*Fo zxBkbWVNM8(vry034c1o+xS_Y7pel6p&*D9X*;C!k+|EwKm_x$n?uQ3Kdo!QFS+pP7 z;w*Z|l&n{ZTJlzRL83<}4lcj)JQpk)F3{6YNnfwA-^!9BuRr}1$gea>9Fe(Z#vein zhzSFAFD0j`?Vo!F(UK^KM(-KwNQ|M>HFrOFCU^xc32tr|X_LiXO&C8yz^>2Lh3FCM zqG=+JF@IPX?(L^DF>1ps^|P4~zEPkr6BYnxRd*(b8K|YP{01E&Dx|HHaDugI-AbJn zwx+SbQl~QSFX57)`>a)|$M4mCINo)?{?trOp>dlRhkvw`Ia}v{q|>l||3{Cvc1rYM z;l?z5@sRze=V6(9;fbkMqwfk-;mn4$-Oub9@m`*cNP_8WQ|~4H?>tVUbl=8<976qv@={v6&idme`E2E>8}!9- zGK!^2L`d@FNT@qisYdMJc2OV!k$F&~$@*S#%%&=11}pxU$$ZaHU!+N|rV+IS1i4Vjjr6A7jx#jnzGtMS{4Aw=FE2JJ@JFa_a;>=_ssf z&QDl>p#x%-YPRsRI$_!URg@Be8HO)c3BP*}La+b{w*RDnW05?UEhMvxqW}!c^`OO| zfG74)b9%y>b?}S-K`Hc5Dx}g0GyF9?Ky}P^)f;0rXtl;njGmLnY~9+aj>WVq1M**= zvFb@XgFCPqxT~Zv*4j)mz(Vk9&&1s|8xuB|>Tm>l;RdqnM&kUkZjdn+dsQQ%BIeYB zp-tG7iT#hkmLU$RxBvodh533JSNh4b-e%&MEHX*qs12lw#qDxt;!C>Tdb(18EI^s% zdTA-V8L1?Xe_T)L7Fms|BeapHNw~{;xmJV(ZZ)egcs3nck)P3Akm0H2Y7XEn*xS+H zGPvQ;($~%@zj=e6ofMqsK25?$mG3Bj!&UnGBFPu?qz~!h%K|<30tt1H|BG)H>A5fC zU4fF5E9{3|h0nh9>HTn zY>k?d^+^iPm#Y@m-X|f#;@c4x=$~U=E%+SL2sdS)OU94zgZrF)3$O$iK6n9+pPKx8 zNAWdKaL_uUXtAB%FW5y?8NR8EqhNjV`EnKjp32b4WMv1qVe!ajIe0l??p;qEP2Ie zM+KICrkwafKCxX8tT#!w@=w60$9hG8wVTEtUHOz);`GP~vYwYvK4|XfdIVWr*ig7O zro7$gd$<|J(NG|>n&HoqCsnt&z+a0LO&Qlaa3$2&&ML}K?>v8Y_?HXEXi}GiZ+|2e z@eQC|Fy=)(qXzOZ2o@YpJ>&W@eoje8T=G7kIO&y)%Do}whM!?BFkY9l(CXaUpj>g9&cx{S%2Ch`&hLc+=by38Ci5<@dVE(A zP09t)726l}KhyMg`iC++Q6$=5Fx<1oJ0r3Em6Cr}bnzL|UxPI{brr%cvXp@26#ytSV#0Iotl zv5QS8*HGK0OJLgL%^nsFRO`3(kTpHSFME^<@`%=ma!`Suzk-mRp8? z$;y-p4q0akQM#+NqVz-mcmc#=+F`g(oGvSI8j%BDrWn1AAV_qZ%qE?o~Mvvhz=P$JQ5b zbsH5LXBsEm#_lVU+i0S*e1W>|E?sb5F5rhKW|1KFa@g1h;n%)zF)O?nt{AF+ui-f# zZgC*jG|I4ewawE}Pb64~sr7xx#jSJXz0~%s@keKQ&Bl6d8^1oO>-%6)=)x7;3W*KZ zEJ28FYS*_T_;l2ahdtT2?9$`!B%;{~3QU$#{!Q9;P?^o9tZCVrDv^Ej4Gq-b;fQ9< ztczRL@b}u?-}Yc&g-CizcpfgF9F?2L>>^x{dcO<2`<^IElg!EIpx8fXr^#d52b`?t zj~Gnz+E+g32u_+spAq2$%#}uJm=ySMgw~n)QKn;yBM}yJ%@{LjOt1k~kad*lmqs3%l5DP?jW6tx#e!YTA6&8Ad5gJckbrbS9cbA_^I z3kjo|LQ*EdybP2GzpevP`oTCWcvIKtzpf2Y$OR2Q`qwD@7fVaVxts$B2x?#X+)ywc z8eQO*hdn*zDEcS7Pa|zRs*HHd>ds7#Hn2#^KQZb!@K4xsn9^Bgy_#%vs>t}+C_u;A1 z@`z<%+y1|R<5MPXYnO-A&7pGjZO{|CuW*@pg_+mDF!{@vhdy|F$g02PAsw)*Y7*VW z;=}0XEW`oi%Cei=Eu%vp)zQs5JvIaq*K2!ce7f)Gmx&^jL!17bkE$qNTC7(X7FXB3 zAdLpc?57Q7oalq~x-?`o%-wkoc_tt7avQasouIm}Lg^7fDyQLRD-T2YM6AxYHN~Ri zTg|HP(CTy@@;gfE&eT23**{EosOGXxbt_ie0%9ISJ}=v9#?`ci$$^1|tN?`CPjC@K znz*Q>!*2*`fLO2iIf1L)y5y2Dx@lLPf?O*t2DvtW-cgKA`|XN#!(bZq*t#=PBrwnz zh#9#5DQV1QY2$g-Aev7Ve(Iq~lmPnGB4x zV_CmBewlctd>9GG#ve0Hw}bp5o7B{!B)|zC6!Gk`Qmu`S3H~~CX8q0>y!a1<3BR3h z7ByuEMC7wF7G{8Gpjyp=()?=lhl#)fPvUc(B0W65O@GzCE7{_L&Gb6-utQHEKIqve za~MG(ensoJmF`1c#PlBI_03R0GBqrJ7VND+^+P7y3e?|+`;3H7DPC&XBxU@DUJB)s z5)L3D9Pwa=k2|fBHM)&k-n&+mr`O;;4R;gC;YazoTrY;}pE9`{N4V^IYfBX!+^(_z z+-wg1lR$Yoqe0t%8QDl=UoWSIWM3)P z=KB%r8VUBiY-6T`%*eb_i|27?Z`z~LL9pI_lH5hva@vWNPZS;@VPHgx@^(2 zZ;I@>uTWM5ecd)Ztsni!Qi_!SMMkr=d;Lmu9D+>xCoCe zUp7xn`h`;hG*@WNG~T*?Gqod*;mcJyoJ!HXu_6X)GZm;MauozyNm?p&J3D`4rCaCl z*plB*JPYof^j2=EV?FEt5-Rkku<4Cb8jnu3iT(~m{n(NqTjPcSuN~tcKf-L4^KUO1 z_eLbf57*O_(mk=NhoFSnSMe>9NA)fdfS97q7K=Z8 zkuw(6%J*=2iNr1M4*0pS2?_2WArKqrbupk>1lQe_jj>Sf5bbplZr-Cm#kJrrIYbDq z7EzB2!@Jm+W^)3jyvG#xE*gJaOS}`oswGiv>d#)hH(#S|6LmXraJ5+lW|l@3X`R+9-c~r z#k*amapHni+2QX-jvf0rc+2OcK;hl!)$%($unK{>D;OIoo^IcXjPT9vAr_~I2$Y9gbVA1__8C(MUf9OzQoM23<#qeOTwhHMG z&JA?Dq$-Y2wc7Z|1LwbMsETXhF77=2hK`VMP~T5$suJS+%RG_J>5i`zRb>oLhd&2} zyIv@(iiHU<<qkuB<=Yy zhZou@;rP~@SjhvBFdFDdlLVg(67{KHB+L|F=zEzM+QaX(l=pw|8j+0Y`C(Co8z7u< zkjQ#MZDDgB2^rF}&}|Ikhh&KSKeRdd?F~TvqqOM%zsQ=8po!t`PBDw*22bU~I~BXU zm@nqP)fPhP=uf#H7l-=kS!DJ?-pU(qKf5DDR1uKF;fh}sa1&&}n?vFU*@PiX0O%wF z6?Dc*OP>3qiLTuMP{YUD>hNu0vRwR|MMjpO?Qh<#QBwxjKrN}&^V7w z8T`ILZJ$G~r`4j?@=|x91{6;R>E&wTv2b@>L?|_X819%CY68YP%(k`+Pcpc}le{l? zQypcP;9uZ=m5pfGFf5NTUO8+S^keT{X2Iwq(f`i)RK*y5^;w+kxhF~2CN&nWiNC?b zkd8tpD^FmSWP&_gGk*Ym4}ycH`(&1(^R4STz6QEJrrk-yf@u?9vt|_s_9KLD0yC1m ztoi2?ssiw#bkby}3>dSOnB4-RaBY=axWJel%fkx`1OnZg%(*dpw<(R;J7(-LD@NjL z<{JLjO#a8mOhs-EAUqtp?Lb4*|;!73u7dT{4-F#|7`U5Zps20U5G@+?SCzvQj zt646928>aF6<+{jP+S<-%$JK3nr=-9&MTepUxzvpasrIlL;|HW3eSX;ce=(?2tjw! zqWu6QH}dx^OuirMM$y-=h0$y@gS>UV&Yb47=<0QGlu09(jfp5NME%I(ct!}dOsvZR z>8;>}yJt6LS@86R?CH>&bpr<4#8Q9>F2i~_{FouejVHbXgG&~nCR**X4OyM9-?EEB zJu}v5SnO}sEk=+G#$o_*xCu!NMx1 zT}^cEfgDkEAfHr+w@H?UiLjaxUATm+o3N)fEN+=U3*QCkCJ`-H^Ee0N`f6Te<9CAd zyLUqr390EsRZ*6bf)r- z474?1T7|>#$Vu>K%2l}P)OKVpfHuK|izDmBSeH7M;K7ww>o;~n8+E_6E=m$(y(+_! zFxF00z=`AD;1R-q6` zy_66!gyqG^WR`A9v7Q=IY9dG^W`Z}!+tqrb<7ugphQb%RI-){MSY3I}QjoKuVvO`V z-)I*k6u3@>(5CdGtpfZ8_0um{1<6eq$8*LRZPwZ;pl6u`&${)rLi#&a! zJ568{S1qjw`=Wk>TufrYltVqG271vm;Q#IG%RoW=46}Z5C5at`OpO%d#q?n+RFJf1 zwg_Xc5MGwtEVHCl+@!}I!g8%6_ke)dzv(Ib2a~!H3mowM%=U;aVt4d=j`z@y1y8`- zYBcJuvR-f2c-@+s-f0_!pn){z4cbxa_h9Gj@6wbl7}9W=*-O%x`0GB^ zn{n>??pqz*gK}bQyxHmCU0W_Kc1nCx$~(&=ag1xHV*=k8Ef@GDsodD+Ao6 zEcvhiBdGur8p+R` z4+Otg_CaFXOWVC(kP>{#cuC1n2&v{}A4FUA;id%HKxw`Pi5B#^M}mq!mh<@A5Kh}= z#>x7T5D)M`y{b=d!=FR8_Fw8XE@nddIYgCrUvJbo6-O)w(5Cu&gm4#e*BiY+EDi;X zDErWx9eVB!YVC(mD{J#=dhbh=fCS7hG2!dt~`xL0-enhOyMn1p*}-r9W`N($6i zO>(HnTSD{o$U;gWs~8|ne{8`Up1B$1=2Az6yxmIs7PEmY{|$=>^)vuo<~z}IQND%@ zo**%12~2`{)=EkSImrf=isL;9sHr$7hYv}<+D>iqk0?l$0WgvAB6FyccaA3PALcur z7cl=Z!`Ft~l}c#Qdq_e#jD>`^xSuNc|cG}({`mC8LHS74m5ECFP9 zm^Zm)A>0p!hc8UANoIeES`I*_BNjf!QdV=7L}wEF*-hj)XTTaB`14PYg(kRcjP zA!+hSlR=Y^JIgwu!#&q(F23&=@k<@>=;B;8#)F4Dx7^^!(TexsB~vx8#N zB(_g@HlabC3Tt7Kv8;>`d;}+*d3oq$C*LoQx!Ct1)h-E}89zn8LkpJ{EHI|vPeIXx zBO6SZz z6JS8gTLpyvSh;bv^%RXP96CS+L>#X&SNWgPt7QS+aOT`Z7!* zkXgg}Q6$OS3G1zM#b_2$u-auC`4r+?o3GirFsd&Uw6Kvw8CwQbB5VF25$R?iEJ9#R zC(XM}cvj~7F^B=d&Q9c&{22zA?B0ByQt^}@7SvBL-dmZa6mZe z$}WZ~wASl#2;r?MM?ey$<#CYHH@y|fFWv#qC+MYbdlZtPBv^q~QASHh+_h||^0+Se zxs3HN#J3VJ;yiJET?XZYFPgw5M6qS4e>;c!m0;ZpggKO$4UgZEtX~Reupr7!h+?CL z0a=FV;gX0fEJ3TQh)FRT;hMDIPN*JEKxzQMM3A#W5i8pM#uAPcOwj^BP8?Bp}9uGA;l4l?@x@>@VeSI$Y8j< z_7p;e={US}QeJuEsi~NGaa$Elo@jK+5U{B~{+W&-ghcV2G@dpu z*%s4gIGHm}OPjeeu~1^63+cHV2TAodQrC2R+EoEU=+x`TGow322fX<*E1 zEy!qc?63b_9trOSTF~zies@CIA;E2}^}G1FEX_%7Q;3cAKBPjUDY>n6NQ5I}qu)xX zW-?O-S4BS=M=wmUfA?G{MTQvM!4mJ0cP&e0*bUhvHCrkVAspau(>phcE-<4Eiv6~| zVJt||Ay~4B3OL z+%C_RM~O^_5W!@H@y+Sc*NvGdb0b7MJYR1{9wWf-{LyV`+OTQ1{$@zRWO^XAoR;dC zwNf~97vFAASB5AxK7_ZFDD zQx-!M1i14<0LtsH&p6oy{FU(v)JWsHoT?yH~{Ej&J(BL~K;GGoQTKzRR5?_vwH6TtPE)P!e?(O^^ zNm&u|W~3k;fp;juj0`^cBpVl0@2%#xzrZM!^?t2Z4Hl$Prb1B>?)}A4i$F4kvAT}`riflUgCdrCwgr9MeF zFZs^Q727EcAJ%H1q4;Q!l9QY)DIY1{_tNaqyWG3+mm|7P@9^_QnrFxrj`iKV;;yPR zuV3*BeFmnkj%e}x8%_Rk+QVr_Pd#4K6&JH{IZ1f>N;?=nSl8WD6Q2ZREg5dA|5Q29n47XH5F(O$6rvvZ^r~LbJVo_tz+6kZpK3h? zc*)Rg?Kpo*)8a%j@^!#_KX$G4_ZUWC9eYGaFq;G@Ar0OZfJc^f_ul1Z9T{Qqb6KxD z$Zs219NxZCScf@o3Px&~|K%vVs!t(0Yq9%g$)OGjV>}uhCKDY?-KDJ$7<%<679q) zFdMGKs_Dh*8c+`qhN+!HQg{P{F9=N)>|2Y$UZ(gUkIhDI($sR^+hlJqMPE!sU%~-U zyrn3k=c3FFoSzfvR^}P&l9U_ORqtjb=4hg3z?A4xO^yv%2v}4nYj1jV3yl&MsRSxS zfGp%y{Zia0ISv?O?({iDrhA5n<-4T@u~-NTH^Qi)*tD7z5)=xq^Uf5^W9i_gK0FJN zo8+9D0&n)Fy5ARvB*UBnai)MdP`hLU`BD+z{y;he0tMN`pZ75f*(XH+E_5950TE+yV@KN)b6xQ%R}Y z{O(46TxaeUmNKa2-s1R{M$yer;{ZWR#|Ia3!nmFo_lo==2;I%nxUSX1--Z3jY+Csh ztYj!k43gT38iEYHy%M^EY8p)?Y061cN*V*rf{rG~yQusZOG!=ze;ou5my$Yu!mP*j zwMLB~^=VxVxD?N?H>zako0^RtLci6G#?_@;BCOw^0{d2eA;wMZ9{BJ}ucN|5Rdc83 zixk(9kac?I5_nWlL9r3kVGP%prSvl0pv*=UUjFNpI7z*Ip1N-tu?!PWM$_G!4Y20j z;H^im|1Rle2iCD{V>+nLRnxp`b>IBWzY<-{g7x)!UEu4r(xhMF<9xXuR)x|1y%M}3 z26{EDHf8{W)Dsv4({Q2J^NBUlnE0d{*xrBvZmNt8DL@j9q+$vne&<1N^lKC z&)nQ>hxJA$MB!c3@eK&xB>g|v_+#YUTYbY}gD)0F1Px{X>kvjo^VJAR3aobj^^((V zek+DxQWqT5w5A{h%*CLREeTOQh4WwM*2Q8}&mPohXQHMdedN1&TcV+KV2kotw9!O; z1g6h?sXp3e^qj)c$6Gs+EfakOGycQctHTG7wZGk>;4`iBXD_^SiRil%cM&1l!TXs- zgzP|@Ch~2e_x}B7n*tz{?SlIX*`+65KS4aLNTUzm52yzoY;m^Tf)Dkv^P;JEBs=NW zp&yOEbh`WaMq(?WFw}5D?Z?g|i<@q>$%Pk~1m_K+4UuPlLn_L12Y~b4#a$#bVMJL7i z4U*t5IfojEhP^=w$J1w8udn$?2NojBH4YnQ?&u&0E$!ky-aG){_`oo8a^La>Wi9&T zn}lnvZ4hAT(+?cjAns7>Q=k$hd`=!-*+@(ipLq)h8L15_#eml%hJ^s|nP|dV&x4Ru zML^s6h#^h-Cc`dxPJRZU{drN`Ai#M|=aJN2{_JQ#ea1I=gPwT6Y z7fSfFp2riE@M&G{W9<4QJaXPhZ%{2{xu{otlX@&ZOm*?Kg6QrLZxAe=cMzU zsSN~zQK{)Mn$X?*8XGjgRi=jQ#@a@bV5$za?Z(Om&7(VmZfS#TbWNNSMk`LuPdV4% z>IYh1RWT6wv>=R988(7r`UWixk>3tln1pWun+2Q!xdN6k5;BKuK_@!}qz=Gh80Js! zQ#TUP>+Zv}K^qPMa_5*#cb}9tk~~&&Tu8>@0bzr##jr^9JD~M}0kL+(C4V5f%A$5| zBhD`F@TdKBCiqb0N(_^pg7OT!ECq7s%)fv+7i|=~aSb*^SPyOt45({U)pq;zMr27e><@OWOL}{P-zQx;z z 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

CKE>-C9&n;dB%^s%MhH6y`fb=d^^@?4@a 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�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

HR`_e}=d$z&6 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 z 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 =wNnh-6p?rsvdiM86^ZG}~Fpm}u4#e7Q z^srcHB9^|FB$qJ~D$|R+y%Q#YV&y*#&PgZ`0n}yTI4!|(r4a_baRJCr^ZOiQJv|^@ zUw`ZM_2N%>w*CDLcJ)}%srmj8&A9WcDvBu@kHueEwXTsY&m83ca5}hZ+)H}bjoq+U z`hCXOmA$J9G2QPEDWe1cuS0r_Gkd`#;y*HzFc_Ix$R9&M3HoE9ztMho3_>bYvmWD` z+!zE^C~rOH@2Ni+o5Fsv``F064#Rb2UcC^r{=eoJoplK2jmWaez_CPL_2WhMCWJI9 zYbeppsaICj79)Mr{#O;xaiYU0*OxpxG0iS@$}EnE`D-qXaM>{PxveaTl1{1MRuxT8DCrlfgP@CGOI_o~3w@GmqV04D?=YV@P%G)5T zUBV@xWw1$hFaH)F!A>ahWt&d8>Cf`NRy1N#h1-Ar20XF^DtBS`d{8mxK>lE=i;@`yk zuanRBFX;cAEEW*c#!hJB8@P>t+oZ~6vlaf8KSN_a57yVywMX&ePqi=KGL< zbj}4p4i-KsF)z`$fFXq`i6$oP`zQnNQ5o11A}Sbs*SI>un@lP<*~Mz1+0U$UV!~oI zk|OZRr@`Pb^$KClI^6^MVdNT&4e(&3qJv$YkrF9kp_`8Nv1JUpsj_HZj4zci z)!o|s*h)8v08tqNp^mLzvjfB2;>Mo$;3T~+Q zE+=-a+{}UZcip`9S-3tuzn2NE0^c`lFwSlHppxsdGme=SVvxd+>L9NHLqil> z7CCgM*Kql#wSmzXp(>g|$R6Mfasb+6IRm@8du*@CIV=`cYn_bzvDk*^<|^JN2hfu4 z;AP&`{b!6yqk`@58cv+eHMvkuVn84~Aecaz9M8yXed?8bo`fqiH$4JfL(5@!x1GNC z$ib~%Wm{O6bHjTr@xo1Em99xBTO#p7$AK!nSmaCD79V>ArB|p_eMFr9#kSYgaxi8e zTF)E*mcd04bC*%C@N&Ngym`btD=V~O zQPG*N>i-X~zBKx*MlN~qV!z5cMBqY^&>aBBl~+`VP(eVLTI@?6(!S%89ZcshMxKQ$ z7XBCvtitzsp+&VEzT$}FWk;Cl?55#VxEvahL!9P|6DN5BUTdB=!el;&Na=2JBx3LS zN?JBbh>fOk=SveMmBuIAmryJPXsANo#_0mOWizZARb8hr0pkKBi2uK$mIN zgGY7KWq(mp9W6?)6zOuhh$rqtsMc3-$k50`jd9TBXnv)`M?Rs;Q>oms?jDjZSA4xL zs8v>^c}BhDhXfMzOR-#DCNeJhA)X+QV#OQ|<;(x+Fj>z1*Zs842JpJD zDd}=#g)XDY`ac+=%kH@4R5?hlY-bqswTa0Udu7PHMDZ36Fq3i+u>{7vG?r}#!$rgC zf2fO2$r7hqjxZDjgGL25PKo%C<{a}ck>ytlL0&+{NujP*u zChDopnSs2sFazFjS#j-7ZB0&+{%Z`;Y0_wTQopn{Ri1%D_hn%+;1l8QjkQQ*67oc) z?Z70QQt*A9ibUjVfxIQUlrXjbaB3}~rBETZO;0%=pC!@6Y9`E@mjyLE^&`$A-^>Y~ zRUocj9}ioox*j9ArW#XECTA_GucvV}Q;y@7K%`mZkl?$Z>Xlebr;V8iGGQRRsk)U; z;}~C!;n;MS{n@O-{OnoOm`_qtr>ErU$znuxCX_swkL;f>MauoB?|x^rthv>h)Z}E7 z$<6f_?b9rjaRa97LujO~Nqu`l2l+7e(F$=U>)HFfbScV~}rfMLxNVu|$h+9Lyij zOEenqvUnPUyLK;2&X)`AzDUm;XCMMn$5DceZBNr-+-U`=2`Q*LA*J9 zts@62kHHDalLHcE<|guO6o%24&O2W&QvpqAy;7Q+%ePoP3pJ3KgM>_2!Hdq9D};6D zLONY+@nBw85++BIN4c3!t5le07~{kOMvF9sR;kf~iGgsCOqSI!FtPC@OqjSqAk(b2 z(Rj0?FCooo`PLVMfh3U)BbKl6-Qs z0L)!hg0Z7)_e69oXRR}4 zxH>tTFt1hO3098HzA@DghLn7hR0@n*fCC-I5*(D*!AxAkl)QG~WpIYG)`yr)GC(O& zKMdw^^jkE+w~6SVIM8<1GttSMw#C5dl+T;gCvaEFd<*WHgH*Ihj2s1zz*L~7Fnvz+ z{DOcH05Ld|z?ZSKo-4{)yc#L07;J4g7=+`LMR6dF;RluBk>+%WQbNMciwh)QGyhcUjAvJ7y;E1kMS zVry^ohkX5Hgbay|WfrV4!Uf11=NH+-dHKnys{G~&2#&WYU1kdv zdein1;;Rc0574-m-g)1o93Mlln}fkfvme&>-<3&9p`*0*sk@LMyuIeIhq(5|hLl)eP08={;aAcGj^D zi|@`W4N?+`UPYoOkmX(8>0(I1TKVnZ0v7SFAPOJ3*FDF^l!$&R6tR9kIEL1~B~h?w z?o<=o={DoPEmKaRFSKb>dZ&Ma(I1cHw@ski^hkVqQ1^r1U1q8mHg~jB@dugq@38by zVuzO*u5%?+)}9%gx9jN#JMxn#~~7D4|Za!NEFRBk0AbZ9#Iwbm2i<2HpsJWu-7^~p08(gsLx zY~7td12y9|u9G_EtN-q8|4PS=D=^6^30hsz>P^n~R^T$-r+JYN+9~;zjx`MzERTd&EnY$;P%fyAG@n8lP-$!tI|bZUfs>gyEb#6H(7qmd`A!eB+jU zrl#_vHC+TGZy9HRB#>3qh&1t4ww|w1hFGk^C_LY}8eNWYy+0pb=Hq|wt1lP zdYerb4A=UtGL5!DV4d&qWO%CwOFOzZ{s2)@)&jC7-4}{nuxL^G!Lli4mzInt7^fsU z06Ts-B)KG6ThpfkDBlPdLDvkyka}kl?s5WOQwUR-slcFQg`s= z)pyTecRY{(clxJxus%G@oM{oOF{mlub&q9R-}65-_Z%ITk%eRiP~iAo6dl7Ph~LfY z&jEc=OElI&cC7TvKzNGSx6o8#{q_>Acl!LQIyvFB)F6St55tBqxnejhM1HPZ@v#j6#9;Q(3ySIuaAa&lc_lMmLK4ARCpn;m|o z`G=re1LVh1f4Fgc+;O4k$4-+^<(JzKEN6C{5|gc*X$#)uWE$8zbyC&%`rXM%MdQ=2 zD5!p=s?y--q{cVa06{i^(G-(CRpOr#*Cv%hQM8t z;nNmeI>^Owi;Lpj$+h*4OI{ak;=6dD=ydl-9VUJ&BeCIo-4}QhxFbHe-ekpgz|j)W zH%&oQf6&h#AKmHtpOfn8Ge5RC3Z1dIO8N|V;1g?@T7Vrtmt=IV6@RzYU`Iy#FxQKIGIh)#&b$?5wfVOZH2{JsGqF&(v1ZL-+!k9NB(M=^rd5;1?xIWtdql6rdo}83cgAnmY?K(`<9ES{ zjMuGJppY=?m$1H;-rZ@SkEVa&%hvD3oT1j^!?_MQ(B6#>J66GK<(F(B&E7$|7|TET zo-H62xvH^K_hGao7gfyXg%1m*LoxxQJGI|rO*CP2)`4!gD>T_%^!Ug?H zZkmVLA3tdr3@AlX{0+idP@7v>n@bi)%}5-~@jmxYB}zXOdrA)18BgJ5wnt z?%=xpG}!~vAr|Q7hhD{9Db`kv=e??9<1VdZ;BeiWPU-JKG_+pOWyi#ApokRZWenZw z-Qt-hC2p%|I)#arR}?1P!z4c0c8sp;{KSK{qq15sT9i1*+Wziv`8Iw4#Ic@+Zy}2g09m#4(c8soepsR2dQULzWVS|GOgp!ac{;$FG zIR@>diNspof( zr;5$Qdy4At-IK>g<}}1}-$2+{38i)irH|!@5d;vIRtz|H|EQYS0qrCwap6*PC{g0u z#1S`KZ}B7bHk2%g<;xecb2>vE8r|xQqK-^<4xaP)xjb^@00w`cNW{R7n$N<7+S-C! z?Qm(5Z?cj5T7V62fgV+2V)H9q;j>w=$2WF5|2M-x{wUnpw;MZbhoRt>gt{8F_GIc7 z2Gm00WVXpTtUrUhtp3i)ERUZ$D5)Hy;Q{qNS~9zFQep*|pxRA`G;sFr8kJSRh&Pdr z|DZ&3a2d-2-(`Z?7QiE$dVhVBoX*>B(237=oxJV{&m$Nt^H9GAow}W+Iomm2Z!@6{ zLQIqyJ7YwUim`I0!E`usG@UDzos(EK1nV}l^6sPE@p|X47z5Igb#~dlO_a}fxsx!$ zAeZhy%{jDR;#K7AvSeTsoirGKPyU93_JD6J&QCDbHLn&1hc^tD&{ju~zne7&r25Z` z4qL3;TCSS|WvO1K6H5<=cypjC-N!zlo6C^SxGN9*yGp%s)?vBnp1yQ@Wtdq+Wq-j$qE+ThEU^`l3G1EL( zIn1Ow?523D)_}jl^u!uVCVGlubFgrv_f&XJ+e{Rxd>{F6A~+{MzwuS#lk&&opL9l< z=0ZA~?J~2K6=ZNvol`1`#cV&wR{*jF@URk*Z`9=rOG=xm%SZXVL_mCQRxm4wNhq+r z``4sFLf|>q6nJf@bT~Jme1z89ct9)pHn?V78|O+u5)PqJoOnDXA)0u%2c?~|>8c!7 zpz?OW6R)(%X;6>{I?ZdajBi5A6R?f)m`?Cf$@ zrVA)reR9r1e%!&FhIDj(43EvWL!qR_uqH9aXBe4Avl5R-!!QdfHj_9w31AB`(Ydnv zIG%(+D0MbH2k|wVttjW*%KnWZHhh@PD-@l}sOK0kjAWGk)XAmhx!LTzeh#CMRrgm= zSXbQ#Wydu(>OF38jIkG+OF?d$xsA6|b5b|=U(U!sg(s@}fovwJ?x&-k;|}auP_!rI zHYuOT$rc5%SKaF$5AOj4sqPn|?&J0derOb0vvd^U%_siT!6S-x^}6rGHza1IwkDDiPja&QUsdtLF zq=-w3#(zOu4uU2|P`M-zLt^Uf8ZM}HZj9pK5#rJy-=M^eLn@4wuwTNT@!8);m*FMY zutU2z1ZONzF0-?jBfr*OD_c3MJ!k_g3eo zr**3FQ&Z@O*rY;_7~7+1INg#(Z02gfm+)}w4tAgOf%!c^3X%EiZj7CX{S+L2U=(=t zG4<#ph1$`GK6D?Q8t6X7OXQMrL)I#t$5=gvLO?4p(vxy?7h#s><=GtH{4~kK03ANZ z;^)?R>xJklkHr-f!8YIW;j^F29e%%Ud-xxm&geUF$IHL+mWKbc_KsJcRQ7A$Cnc3Oq(I|FO@mbmr zPiaR?XDk)NekzL1IwhPWgU{#@t05ux8>NSD%G27BXKHfB>tdm&%cO3qYZj6m0=Tc=NU6^^J*#3a+ez*xJ8HO+m-^{m~Fv(e%o}6s+Wbdb3 z)9O*uW#}lSjY~-V*|6Mnta^P1LdP|HtQ_?ZuaNJi7e)(Sl!i^61m#6uIr0s3_cKCJ zBUbUA0)3&N9HpFI<*1l+$yf?&FS5!J$OgYW@BNcA7(O_fb#-8SdJo_=RgM}tFYua2 zjQ*m8Z$h3#MY$=EPK#g9c;%yztL5{(XWf{$UX2mpeCV-$>zXHjT}A z@x+WOLml53AGE(yJaOWL#gfi!9!|{Y8lbf_;zrRyNxC7}S7spINd#$$-nub%qDjRG zz;p>xs%bF@G>p#}FoYgj-Ur)Hl z+ay>tglDXcjg0|*=Y?P%{WVc+B0$h)&_h-3u+X_e$`wSL9i6K}=lQV#eA7GDrssSI zqobobgJIO!*GJ2LnX# zf?b!s&9o#&35?ITJ`|hZVoi_7{IEXwh$JvPpnr=&_*MTFD<68=A4c5m550ataS82j zk3#{E7A+C_l85&REx z#-EHyEnt%fkOLYYmznWVnTd?r*S!KUV6);vD>@u3Oy(Pce3Tp$trycNbYBGjA@dLe zRbh;~CerfJ#GLY?v*`$P`nv#}3DVqWoKE>@1h)e_kegAdh_H!@p_XbK!m%e&Ng#++ zDWcqnlYmt*IZ*yXuz-68WaU>q-5XT|QzV4Z1c>GZHJ4KzF6CDyAIjfdj2%njzni7(R;U~59; zJ@tqUm6{IGhzce%TIx{k&9A4_qxe^Ioe#Z);0MJ&pM*$+Lik3$c@+Psgm0k53tevb zp8S$vk9h4@0Su;5ZyWgzerFeOjK`7OQP3u(S=%YyGr#+Yq3|^4k+nwFIHN>uc&HPet3G7W8MT?DbWRs&7`Y z8ZF4vs;@e=iVh!c=o@76rO`(mkgB{nU9GMubmc6)b#1MHRnH*FDGBL~&umN&tBdWY z_a6??o1=>+6Y_NWkb|eLtMhbC1yWGWcFCt=-Jvicw{Zgr22Pu~_UnW6rVH`voV=_4 z;WXqhb!dC{A1~vbjrJ3uM zIfHoZ(}KkM-hlb|*5`H^B=;JKZ~A7qE-B~0i9sg{Xw|>Bl!kn&FbElRs$$U-Yo$_+ zO!^!@>MA(S_+s`7NXs!j1a zcSUyR-E^(PUT_^$kRD89DY{Z+-PI;@Wu}%-)1Jz_AhSiF3lzG_0Ob^bujHwjXxD`hqpi<9}2-jucKtyKCBuMu)czr>VRdP9v*nOVPsj%ge!q;yqKdx=iI%*XQ!k?-%Y`6} zlTxvyfCI+gA)mjq%UgWEiOT^Mmc|bO3Se6gI1Ass)L(WKi#fjvfx&GbNO@2+oX4d_ zpG=&+J1jN(e~7eI&RLzgIZWI5807+M{{o{^_PrsK1A+yPPFH8}Xdu}}pb@%J&L4ni%C?{K^=cr~t{CI8PE4(;9U zKLV;nhWxNuTRc#d3<%>-j!=_Bgs`7AI=gs3A1 zTO`}M;*FfeCi_L|?=sj>`wFZNSR6xEpNmYJ$sXfZ$0E7*`$GW-I`v^^AuHs}D}7oq zQE2;uKT_Wx8IpYhmT)c8W%z*p^EtE^LLSQ}y(eFu56^_f;YvrR zj;Nf<&TG#FvRzT=`h7oY@v~D;ww{;X@4O(1+WTx1-=giAc?udpi{%FfDmWwQh`DPP z2cLz+j0|_F8WzPaZ3N0Bn)p5Zetup?X!9(Tj(mB0rb>B>Hf8_(5Iox&1uj|t3#S2H zJ2p3Oz2NHl-8?Sb>(`}3lLQj zGG9LD@ziLjG4piFqdZ?M5HlNlrDLoh+kG%Mtz~; zc8fXzZspb~nAVBf^RB+D!DgnEW&6@dkl1YixB|qUo_Y;|<;%c6ySkTrS@{xTo!~d9 zy;d&MiW*FSWu6#Mte|cnRu+Wvjy=&w#xWLQiZ~G-A)_}Eg z2&7f9xndKhl=8wb+!TPuf~QMihi}49sSv09wO>Mlo_sJr4<5_mn;lGUU|MORMN-N5 zmIz^;DRtNefMk^xNb3g5E%J2m8=aRNIQDvRA<%TE4m_TUeA#WYjRQ9n3yCdu2&RPB zd;u(S^H#zON28VCRWlGpq6~TJ;s)L=fh%q{__+Z~LD=Ex}OJJ0HYiO0$YpN7bVmofAd3YW4+Hlzuep zgkx<0c~wxx(xIq!j6bL>mel4%(vMVaV5z)A90WvORht+PuAo9S#-4~(a~gdf&O_fp z$)oC*7X-Dd(YEiP2LIkE;4N~-2k~G|J4rSnx^pe9l-UwLelNWFW4%3<7AZjKwRNttVe6AsMs*wYiVWSl@dZC0A1I z4`N6l823H2K3FNIC(I9A@x?{+10pUVgo!)P9+v6YVrCv@tzQbE>q(h%w$`xR2nyy& zhFDQr!2q_$-`bI4GEoQX2l#(rNW@Ad^8LjW)aJyJ`GK9smqa`3(6Ma5&tSs0G~g3YOk+~t>=eD z?JTvP9~G5NQvTPV(o#u%uAErTYine#LSjT$Nl`(}F11;OolgG_!%F=Mt86%BPD<~$ zDAh={U{4)?t_4HOoWfcqx-NA1aL?Wi<^WB)+nI7m8-0Wl)7=Q)(|;q7Yn^CFBj6?6 zh~HY1o`8fXy`2&JxT*FNp^O~{b3^M1R)0R)P^|T-kF)JR82OWc9V!f&eqS^P8zkro+G_4lQ(maKJv(SxK#8 zUZ+=AZHjFw-IJv4j**Ok;3bcmABGBeg9bpAlWfE)Y?&Fd~|JtQ8$-7I+8J9kdTI6-k+;y6D z*bF-b8^E2lkf?EEHSHYNW_W#P3tW#o5{EjVm0bC_ONri+y!u&?cI3(oP6u~%i11XG zs~#3|7WsSKZC+sjLq%RsCjj#HhD9UMHW&DjermnYSR&Iyrn+%AjVLCx#)PlF67sER z{b^LX-^V1f>ZyK#h9%#9W!IO|-Bail=Xpf)l{BoOw%`CJqxFqg3d=H4&xhk06WxSv zX4`BuhLJr5B#SumIbxl5os`Gow?vhpX0^Jvly8HnCW8iTvh`1v@_dU)-b>3umA#t- zX^*B4XF3-~@(8aTZnvYXMTr~%R~aj^QTD%ZH2+1ZqNKZs zWx8wcDrw7+DkzpCT>zzBXdBM94tsV)UHS>2Ucn`WslKhkzDo5&`2RmsZvq@gdYuWr zJgTxTpt4RBsz4wCR2AyLkthI#s=}4HL9$!SW*=g+$!4N}YO!TmPC-3hG~H`uYh+8Z zXWV73>}~DrSUC*uY&$kKT)~h%-5yy=L1=h2OfI>uWMLgC&JaB#bbnWr>6uzp?mEVr5UlV!1 z>2fa?kJe1@XfUcXoO0#7^ya#tQ2y?k=_6xfJ1R6lxWOYwRvTco+vHtWDWvyS+0!-0 zn>iKB(8soqy>24w^8#u^hmTLO2;RT~B!HSfR&;@tU??Bg7(soQEt9d6R2)b|4DbLs zo1ld$cZI1tUhxtea~q8*fW9b?08ySZg%texr7ta7eEN1L2qb|b0$cOYOHXq4+k(wz z*T)S{^3?FcfkM&CDkWC+^T7^Zc(^7Jxa;Co5k%2jatJJSjYUw>9Br8hfILbsf>LY~ zu$vw!03WW02ta}jpiMzHr~}nU^|#%!HPwq5q9l@U|fQ!sTdO9xxbS!vGnVp;E zjWZp+ZOvi9K=(m;1H{AxFerMPSHHM$i0;4?0Ea+==Z!WzfxSRHb+4ALRCPeUYAQ#> zYY39rx+~8sn35s)`aJLvhl=WHxM6Re{Fg96VG#-+ z{(zSe4fgi5EJGL`AOyn))Ry5Tx;R~NaZFyNS)geHX);LTT>s~n$mR)P$2DYbqjA=2 zp(zF9i#pBS^={~dq#CRZQF)m`pR}3MWwJdUGgkNs*Exzci1SN=Xgj|2hWL9?s6q(t z1g+IZl{b*9%JP>$VB;y=-BR2!{BF&>G=6yA;@q$HxY*Imefm9Us-;w=?JvKHRcX4? zL7iYIO`O*slLYSUZ2Y}=4_p_30;hNMe^Xc^EetHc(S`%x{+2{++n?Eiv2$8(`vWzl z^0+H1?!C4ZjVo_&JCs=Ox|OhVWpn3ockFslJMVAqwEaSd6;y9#r~N4b!ed)*v!#b{ ztp`<~D_R?!NWl8T$dL0Ki5$XA9G6{hP3id0zrCioc&C{)-Q#67aqQx_6uvUNwsjE@ zo9NLWU-p`i{97uYKiFy$r(gBi*GGeEm~XZH_4}?if%dEW0DYp`riA)Bs6`DRZH{Ps zwe8OXxE#Rf_$d!Kw{DN?;KZQX5$$NM<8eo(%&FAJ=*+nt!=I=@?KVQ`9ou(lWC!)C zkw*iI?3U(5UxeuFc;U>ijnlRQtbki6I~&@+Dc;>`dq%|jotCG=X1^1E82UWvA zge8i|FD``ZOFbJ ze1Kb7wduz^fOp4D_5#=(rl;Y-85k7nd>QbpVTk4giE_f9wnJkcA5iv4yp`Ng z{E}b8)K_C zIf*0*e0BtTGP|~Nm0?weR6x{Lh(TkGBP@YYwrZOY?8q{=fN-$m4#k)3@6LX}QTsdb ztV!ud1c~BF)XV@Y3+XeA4hxe2m!4WLlksyasWk;4y2N?og_66KT9Ign#DeU63V{FH z8=?T6`bnUUFr&!dS?oX^0vJjrMB55|JL=8UvIf*^KLaS_lTSL{Dxd@^o1U_FA*Z7l zabhrf`03X;;~(|o1=1I-PvkGJ7){ptbpIL#`G*^HZRg<@J!ugjjS|ZCI57!`Rrk5v z`bE$*oSM5rJZIz4Xz%cUb%MF^UL!p!qY!o;Dzt=7?8L{HkPwxZQ>Cr-cA#2aUxEKh z=Z5m#UGP^1N_SUmAdJwh(erlR-lA`G(y_I!H>>=G73iY7I2J>{}1vogafONn)j&)l;B2lCZ-YFnzmcE1K6 z6%k*n8%&2!t*S1==5|dJygkk?tMchN>kkr}Dsk3sV#@r3u(Qj1)IVUH-O~9<`&w~( z*4bTI+xTl>3cQYATHE+P+(1r`$(C*_;vh60ou9kesM(n0L${jKdcXsr5BAp_II3hv zxWe9*Dd*zht|wMHd~!mKPn^CXPxDeUv2A+G6B7#WdN!aaWhZ7GbkQ4^3K!P?PLn9H z204B~32_}hK1acwJ8QIIxganJ)1aiUjcuaar*{xj!ENVhA=YD z%EVYVc;&s2bp!Aui)RuGKsC$k%F51}3`8|JK(Wc#e@Y&eU8${YAQ7}j^{>4Bcq?(f z{Xf>`Xu)P`hZj~5ofA1Yuln<-NjIrf>F$!m7w>L3Uc^jXw0-~p5IEi3RIGrcwQrQ} zUvgd~U0A@xLPb9o1=eYb7ms`%#aFw1@uD#RP}DMnj-eNxRAe7uQP=}4>f%L-c+10U zVBaxfz`@h{d>{xsAZ1^ zY2=%`y||+iV+*rWV~kj4+Rex$X2caZeXwL}tjGblu3>o8JQFv2jeWntF%E-xFLBLl z2_CD70lovs(%kl(2>BgvTv?Di%_6MUC=t18lE1By`0?0for@`AW&0t`&N+V2v&}6k zQ1&k`EiH@T&%s6^JX~5^ZlmPCG0@PPUUbn8@3p_nNH7m9X~^7nFgw=JSjOy0Hq-|p zt;xs;V8M@b1BjLHF&eVj8We39$llm~#U*1yzfeqyG!zmO3PL!vrZ^%YRUa4&;z`E5 zQ7F!tH+r?E;Iza?9d2MwYl4BCat+8mhIUKvKT=@<#Sv08-r0@COjv<-udoM`G}T5> z=hWlW=3-Q)!DDsT-+q{RgqhkS^NH-_oU<*c;h~DzObYaH;&@7FUIHLVc6LF4kz}O3 z(%dYxERmUwBpI2>PK_()!&;LoEi`llu?2X|-Sxyoz_zsJ3cLMf?Ylh#llWTYe`5Z( z5@WvT?s#D`)nqJ9C7V2h`&?@V+TR`iKv3}5$J>vQNLq6yn>g#H@aKMSn}*-_S~rs3 z4|g6Tk+kM$CXRjdugrb(z4{J{f;G zu8OO$^ZygOxlp5s0;tgrAuaEWY|v8Md(Z!y+%qZon_(@zhO3zQEAVd^lZ8^J&T0<*^pv9DL^Nb3cxkPrKXxG`9P#%h(pMo4Xj+s$(!XSdgQkebHXe7hMo9x#H{ zWQ_+?(<8=%V0IePf>G-$-sv;rL0}+cJV<+u2ZG(iMb!B;{w~Mek1%&}%?%MeZ9}+4 z0_Q|}rEkW1t$<(KV>`j@6yQ8Kg}0lG%R}^|US}64r3Z}%^Apnw!gQmD6f1;r+r*B`@tFnGB66F^P5n^!QZr$l8B!HAyDdu*FhnKp&hy?|dQ zUfa!w&MAZ#%VzQz`>d!xYd)U{Sq!5+D6V8=`0hq0JnC1HOj~0V?-gKAm(n^iR2^1G z0*3!9parnrE%lU8{TRmF8p^pj!5Hb?!jfBkF}3KG-p#L1+7y;RMD|JY$W-~)LoH8ExRWB!%eB$29>t7ykKNuKTX*U7W@Iuf>Pp#cCkxUwYr`&#! zD0V=lMmL!Dud_}MS#TPedjkz~&t+2c(thNJD&+>J&}7>WGPATdFhP5ns!ExLO4)Pc zD%Bq`4Ag$TS^hR2l&MI2+&13lZ` z5J;v%rF7ARCkO8)?conJP!abLqBkZUQUc@s+>~34WN%a}0%V(D1X)yI3z zZjAJNb!ti^uP*RrGP0oiM;3@Yr0=E2)#gxHe@v8C7T69Dp8_X>o=@N%82&*_16^%1 zTP|aYV{^Gw7z!M`gRQB*<4ljs`?F~50TvXQmA%Yod!&(Gy_p5jn9vcD6}V8fX6db7 zrwQMp)kG2`qsf?03(8*RW*YPB5fn%Qlw3%ZC_3fcON&SEyG`)NwptT z*NPFc^5OvfdTb=8fbEan3M=mD|nHT+V+$J&BP3tP#u z?ib(cM3UpWf8q|S?e)w0H-g$8!mpnnn<4QUy7z=2ap@@&wHOohJx>2F{roe6oD%50 zb8k2&&&UT0$n#E&d3Ry{tVey2Hz8d1Sh((K*NKsZxC!cGEEZ7Ke1D(zeCf1Ty-rTF z59x-*zoe7?HSuj_G%&p;6R%vYO3^j(iC@3}2FN@5*62kE0F&E&&P>=&Q7mYB8SOG8 z>1_Qhq+>990vv@RGe36*b%E?@FXF_yRyu%jp-xY64wLpnV9&{W)OjcE!_jH+=@g_Y z>#W6s3XoP$b7DHxX%F4#yxMV5E&ClVERw(+ao(Yo1YzAj@MVVv z;tr+bDmR1!p<=xb+j;-uA{u}EY|5eSdYo=bS9hZEc^rE#9gn-EcZ0nhC!EOmo26rv(Ctz#UyZ`UW+Z`;js_*R$_!>{R8jd+9oO`}9(Jnp#L{2-|HXE>R|iB?{eC zZT04Lp$$OAd*U1FN6M8k`@Mn;jj3PM89%}<6rn%a@oj$Y)fgPrW2a=Y0FgT1@O1^y zh$WL92A)G07K??xhB8JS!D9>Jy^da*TePob>iTYJp=w`4WChE#W4W1m42|-0TTw9v zIKmbAAa>T%q4Nh3F=4$o7Z>|rt`4)Kx4ImFH*?|~8hH1lkcf5ZrO`k#LND4)(#hBL z?fMS-rU5~xC=XpIA;M|2o4*xz9)v}|n{_WD?IO=-%%GNZP!Zvrr&Z5rAdX0KW$yxj zDERx_g18_Gk$5eD&2}|9uADRGb%BThH+cx@ethfXVl8f|7 zL@^{xS7Hj#P%xU}6(XIRjJ(UJFV9z|F>#t64T#3S9TABJAsE8;eosL}uunkxB-m`C zYA|yO--f~^!!Y|XpL=yl;XtC4P``mZCjEW7mt;2CtKj1iwAlS#B&h~?V!Wz{Z*%>k z!@}tn(K*=I3yH*I=uc8%eH|7dM~njYy~TEGD*=yshecs|9F|eb__i`*vVx9#a-OzV zeAMNVb(@o5L25A?)GAiMe7wyUrWKI^^UlgyNTO-!R^0IO0L*>Pd}2&K=n7;Vk-eXM zS>o_nE^%8Vie9h1hsik)SWi?Tud`niEA7@ca*@LNQI`*vtPrXHu7Aehq(1n9<9#aC zZi%x7h=>A7oB{~ftn)Fi1hNl+z>0?pGQT%^E3!l&BSX;^6SD@th4h|tDqZpT4^V4x zLBJ;_xPPoyY+yKIvkDL5uo-tgOqhI4%e2am2BKCA(y=;UnRj6UxKw)i2C_ZEKg;v1 z+8PsMZcW`1p%2Xv96?}L1o$W{x6b}U$o}rsO>6~WJCR#Y480+@LQ`Q@Zk4Alk=*)J zTr&jxIi5FJ-6g=nT;hLN0i{vT8OCjDf8VFVdD7yoXd~p7WV*+QHiE9iP6X5_BT>VD z1~HuunNh*ImpW~?vj3H{|D7wZQ~pk?DmMkq_tK*|_s zjM3}91^Q~t>)xy~apps@OW!FrCruPTOK+sS8rvsmy`*__<6@VX?z^?eL`+1}euaGE zw;@N;VVfx*$Wov%*{7d`x(`qlVTVbePXx?=3(h?`A>GfM%HKh8<)-519%rzA*rRTF zV=@Cdh{J_qRNeb1D38LE#NY~F#BdMSs31L3lRD|dWGC$=Mc)HG&pci#hE^1|_j*RZ@aZRr zeutM%Jz^Ey7KBW^aCuIftKzBnrc|GjC|*adVr#FjYVDD=mJD|Hpw;G<%7#36sz2#B z_V8q%_8dTV*<4ivjBT6zojpYRj~cQHTV*~;-KKPW$$32+lw@MG!MZo7Kmiqknh4NJ z(9q~24?<%L-x@S!nymyah}L$#Iums8Yzh2u;9rCeknJZcvvp7^q3z+OZgO_kxHn7l zaMY1JopW_r1~~7jDTodkQx<@fpb~<>i2};L+kX7k9@u<*z78f(fq0b`A!Gz?pEcN7 zUya96d#?`*b#jF{v?{;0&lp^8v8c|l=;?EHFEPooxDV4K>nx9+k+kO1_c`UnV?4{s z_fjOEBXP{9Z=;Hqwfl%tW}|WS`;Z5@#)MUJK{w<6u*URF==+RC^Th_7X+HH{2VP$&8_>-fQG5OXb#}-g^3As3_zR`ncE`YxnEcc$q4}@h!f>8ynd9e?lTX0LMo{hWF&ym;AO2AVDSDFN# zqEb7aJhi?CvI_BV5X^`tX`y|RoI$bBI8x!^*6pR7!obMmv=}wMJ^}Z)gpdo&7Q)5} z%l+AFJSGpXlsha^uGlT!U?Fcdsr0l4x>;JIf!k5|tMxIVZ|fi-A(o z{upbth6M4YWac|^3y#{b)RN#W-v)5T&{BWh1=OR>^i{C!>w+|9rlSb@QR2KqsZDLz zBWkgd7{)cbEYAEf^p7j@qO%o!*o9Rhna+Es zn!V0`*w?-ma`uP5WADd2j+bzcorc_9FCLZcogMLhLxy8c<`dhUwHojuc!?u?2sGj3 zv^E-&uZ(4Tbs_o_C_6W)Vf{W6pVqib9{?eyBY)zwt17b|X>0DVgxZ9E`EKT(b2F7C zAXStnW=iLmzY=DZC#o~&(bVB^K3Hy__c|DPChrNi<+g-d21hU%kI7g-`G)MK+vbAp+{m%1Uf_w3Ba|c=rCR-y0G+UETu8D**Z=468$#!?Rls%RF zv7qx5j(L%KPVw|~_@LbKw|#hQ&(I^OH8A)c2T(wAFXDM7sy7N z1waAg017Uos-O#Ph2T<~nyz$1h}UVYFv`=Z^Td>nHVpT=cNmQ?Ha2beBU?}xm>?Km zrPf&X6*J_%$@ie>UAnV{td9Ghp;HBV23AUdS~o>Dx*)r4 zHgJ~fJ#wpmT=wCfgTC%QW3xe%FCJ~Fpo!s9HO+%2g8sAvGu4Vl*nw*m@P1!%4Ix#w z`_c{&Wv&MvFIjgR30&=YxKK2`N!Odb(e3!O0<^od)4a#K-wd4{%NLksVJgnUSP|RxY)!Q=38d z!yEapZaFOWpLCnuBHV&-(<(t=nNa8CK(T2t9{B`6bG&u0SAt>kM4CE3DYedrjQdm3 zWvNxp-&PbbP^elw*Y)NPCmcVTCxbV`TYXpwYLGA$=P|?QN_W;Yx55w$NTueSl)wv~ zdyIhsvnGx&7NW~t-u<-nZ4o$&&!jHcgv?nT_o6SN({4Xpq6X9j)bNMx6Ez5FB3LP2 zY@P2voPrL!0Y4<~z#2o_cPaoi`f+U_q_u|bORad=Id+@*Kh3!PjJW(E=)cY#i>(2% zyI;*#Fo6T=(K(sgAeE(wX0Oshi9Qxm|IC#kAi8Y%QP`MEARiOHG@X3Z9f)nTdvVi7 zNIc1$s-DbCC;<$alatm04*%G1>|-}Iiva|!zbYOq>n$9obN#B@{Cu!zxBQTh$KCI^ z54(ec7N@|&+IlQUI$&L!?0Wp-UglVC;gM_rFZE&3hW#QWDO#AnyB}6sK)JOrKKb3k z$K^xr`Tua{fZKb|MJ_2bc=FkY|2C%7e=fC7da0F3P-~VYz7q~pixU%t;W(>ZnR=C_ z*1#}=6e*fB*{l7B;V|klgL7sRFyZch7&hICMB@4--ge`rq0-@hD?+M2maz7b8V3fB z7JY5Kk8m`0W_t0{EAPgj^J5+!#UD!%tk#DU02c6W6!lK@aCq2hFbItG8t~AES8nw{ z@d!#mQR1hEoin3~v?QTn#A%AgiFa7S7Uv9vloOaSgAn&nQu;&WUGN+hu<0Uu7!-dY zkLL4H@ijTb8z&>#17n1j7^KyMRz-3Ay?+!cN948XkbYHqBVe-#qMiw=M3mY-@JM0x z1S;ihP&t9;n3b#)+YXkf$KkV5kBp31a55O?{@Q_8I_qAIK>^FMJ)-9qUBve-9}Ki7 zNnRsX3isq9FP>!3NgH0kph#z`PcJ*t=BaC>JA*WoNXLF)DAe=Gm^&)_*i5h9kl z;8UMREcJfl+hv?qf>Z1yGl+@tkd3y<%?3n8;@|^_WPwc^#8f+AqCOB;jVJ+?W1MDR zP=**#iQnv( zL>gGe)U5rS(7BqPFir~Nf=Q$;_j!##sKbDusNZSB8P!?qC5D$?DrLQRrxL-O%eg_- zgHU0-9lRyq({|&uOX88&Adhj97=%IOzKGXWZzQW0R2`3eI3(IMJd+K*{{>_3r-pY#mmAiP-knOG3W$^@6u7($>pFqp-GvISAu(j|Bp6ZIkJUj2;^<4*wy; zscvGM(lA0oXs0mj_2Fl1*o!cRQhwMxDdpT%7OULou=RD+5gVOQ{ak0)qhI%SnZ$J0 zEuj1>gElkt$T+6_m&@jUm`J{JX8G9pmjn>SAh96 z7_wVI(UVxvE-(_UjGy_$d#uMiDFz4i`=v=#YHk{CjrT`KpK6+hcqC-XtZQ`Q%+LR9=+E|7rEyl}P-z)M&OrqX>!rwWG{H+vce+G44d@Y+|V!RER&j2n5uXQ@cLi2= z9dLEi!^s4<`^4mAhmjs#QldH68HDyU@8V&7M86-Og*)!l9u7c9nxCIn5RNPf={KA+ zuAPBagg8d5=H}#9bly_n*JFX_ms>recl^sk?UO{qf{)GSL+uk#00_#D8FW?gTjh6F zAuMDpE5=DwGWU7dWWT*>oD8g^>j2T(cPxG!(b}y3aZc*@$o{ap&xGvvV0vI96ZZcz z8fQDxbBFG`{_LYmh}3p7=aF`jcV{c44~@;uiF7rRJ)ED%=v#+V5)PbPXh`=J85T*T z?uq{RphUwTctn2!W@5(imHblsq~u$5d<6k7w&^D?YA51vb3^Ox6By|%A0waaj0}76 zuE`}EP6SGhfA|AGkh=$focpu-_-9HQZl46_kzq#SW#pc5F6A&CI+5g(@(eFuQyyoU z*^hzolGNRzDM)>NCA&G#Y`!X9AAG;Nx1asloRo%B&P}rQmy9XLCgYdj_8Paz%iz^FCDDQbwZoaKaxwXYtMzvKH5gC zLlIVa9PaT$;5_PFi~NN}Fj}$-w<+D~E5f((eM4RE8=;%xM~5FxX%vPgS(=z|U}}-E z&h^RKM{$fBDmauGO5sjvtV${DN-4lC+(Sv&Q*gnAjJ1@)RqjDyXw1E$-@O8>Qa^Sh z{o2>vBgygUX$$Ek+#?ov5!|!$?%8SgY^+LY>`Lhs+#h?%@tGN%K7-Q{%j_NzhH~!d z8TWLoN*U}*nMs_Ez2x{DTpj&$I6Z^YaYPu(x~C7gr(;zbz^*i~iqo-|9G^$nOaDAh zAHeB2!teMGl-sDnK-St5jCz%U?fdl}9xu1DgYxsXo8y5$|?? zPXa$O&0vb%z8~y(h6CqhmY1l)e)inghK9n*Acufy`CP>zvH|^($gc{Falg=4?9f8w zpkh-YRlre)4~cw8;SjLpw$gJF!{ICo5+nmJZz)-q$4avk*40vV%DS4Xp+hlFu-urz zz&K}LEiKQhB(%pEWp8V}oFwHwTxLm$Wv#hldA4&rH&L#l>&fp#>TVKmpU;Bi&~Q7x5yEH8O_duG9JyB!);lY?Sw?1o&>lQBI0V%#mKPOT zV|@oHjq@llfKIhNkyDk+%6;OCj6&7v^0GoNkPjp%m~t<6c^s_E6Dh1Ku7#?ePQ#>^ zD^IID2bfYnX6mE2DxJO9IXudDkjWUpcjy#Pqi@N9;ei2#gY3h6wO*D{dC_wU=Yb7b zE~63|g`bz@a|YxLqLeMx!zkYk$n4nYEf_%{@5%3Gcb%=vg@|v!_UT|>>INysu6>3vb5$|-)t(?G8iCZ*;}aI8moD`;-~r_P_2u%iv)i8*T}MSy zkpP~PI5-?K%fyAc?1j<5z?8$n$xG&5K5))K00MED`}nE9%>(@%a&FWk<@UejAA4fu98`McVJeb{y_kZ%M#1CcXPA7 zonEHBTdtIy-Ez62Qf5GE7RuB{f2r6wK7sR5aXUy5Knj)R2^^e&S<+1e5-U4EAOI)9 zcIAJXh_Y53htWk^u;1F?E_OcJi)85%*OgB zHQ>A1e0Ne~x3fscr)JTj6LLEq;j~pxdy8p%XQz`R@U$IEscNx=39HB}l&|;zH4+aC zB{WIaWMIPY%yCfVr(mU?A1i4p@!ez=yf)Vt@+AX*m_-wq&6P}aLQ`7EmMj^C8OO<^ zCC8*^p}*kfskN{#ThW+2+^S5zilzi(RRQX=I18A6dkvwnMQF(GD@w*U8SMoyly_@k zt)EEx3!g@-AkYterN?7XUdp*o`hKF%goorW0_dg~`o4)943FXuWcf@*W^1K$vq<)f zDAIDF`%T88Y;;DcqUnxRpiGfHk*k;FB}Scjwphfh)1aF8R$XB|?OJ@$pz|Y>grD44 zo{mVSjaLe1XB`NkRR6fs_p#5tIx2Y$nYL#OXP=RW;d#zwr6a~3Dhv;cM`V^0J&q>~ zCtKsy%6R*?ljG**=Z}Yot&G!|MZCSkh%X30_Z7P2QErYnKe3+Qxw%m9wrkN-^rkv6 zbK(aJbrG=uO@m2PlqUoBay5HeH&7TywaC-?I7r4trhWxb;$_(08QxwTMJVb#uOb*uX5v-(!X+4a7R)>3 z5w{wL`4th#usiUeBC4oraVXweUSx7jQZ7wP^eY;Op%3$VM*N)TEUF(4uHvtEV6cPv2QX6< zLu0UmLHcQ*EIh+jYM6a9jNU2D&%vWzaaJyfA3WZyY3ozbxu*i%IZpvqV$n9r_?@Vq^im1bdNMY(%<14bTDZS<90U!#+Moc)$=RS2m zOv1?E_*2s$>k&FNUP6@X9dP|)q9FTIskVSu^r-yjzk~Dc46d#l0aAkT83(Ys1?c@G zt|BQ)aixyg)KNwB?%ZFgV*&^lffN8dzK-txo8X{^GMtnp-i;3$pLT@88qBfh#q3d4 z^`8ISs|{J^w_icVkoFf5I=wI{dFI}9*Nmu?AX$0P@PppgB@~9ywgy$9?ZGQ$-bNrr z#SNFTsBqU+Zb+4Z=V15to?lK-1teS70B#Tr)6Re_!IG4;98E@jIx7S(!~gl=wyV zU{>*YB_6$U=dD@#40Mv)x{#Yh2TEjZ9>B-q>8!p8FvO{EncsV0BMtMawC3lh9O z;x{}Jo4;M7T_{~wID2>K$M!C_b6P`0D--=qs6hJ4PDQG$8&4OJr~+)PcWI`e5rVj8 z`b~uL74U|-r|-7rqt5yIU1?RL@l%9TWb@MsGxlgo3ibckT#YYSPtv zHcswsyft4!xKL%@;>*A~B5wmOv-nKP;-i4fAaYp9ylL@;+cgOio4q}IorQ}we;aKW z3jF}$>-sB-zx2u?1>m$Z0am|M1m=l%L#+g|uU)!XpYN*QK`;fLQpZySvnTUCXLAf} z#KExR;}Hwn2J(#wIllawtKr&6qymPzt}neRGYf~=b;;%T=ccT!#^AtC;BGdPM zlOvtD&QqKuc#Ipdc{gacwou1o?p7^f=k0|$Y84di5+AvbbZ83}-{aP&`E;t*;a}#5 zZ)Z2*Ez2~NCb-Hiq71S>U_y31KiUMQbu#KOH~RRo`$6vZK*YS_PkJS(su>9+uF!dsA7c6(ZUetwl8AgxPvWURH6$n$2 z8ERPmVCfZD{L4pJ6&uKel7F}?Bb5QavNYGVK2Ac%pPuXTQ-vkF2a=tqE;>C#u+UZR-Bxc}l$De6*`~%3ukSHiTkq10-kO7|bI3!|&e1h>)BXjUF-4Ijr zOMl(I3Du9dY0AW%e8=za@{xl1OK#4Rx5o1# zjbx8)IJfwX5n7y4*ORB(N3pl_aFS|}c*lzrdPW$@SJ#acbeMsv(u=@ojf$5SJ3)*W zb2O>JL%nEVcx1pO;dYPh+erw_aF5%Prn%h#rh) zEAzaC&_ILYrFL}ZE_g#bh%#G#JaE5Vk$yOi*ebqIt!tj`JM)CG8tQ*Gn>#=X1V}5ey}j3^O;%6hjb<~msoSqH_(T5^xI|S$puk-6LL7Zh~8xp zXLHF_D+=kwNE9%5GQIISrn=IV;%33=$rt9tB%=lEbFM;Cs?9kxRjZMokzgtRsTvcI0a+i+-8cvx7)9O<+>3+1;^ ztCKhXRa8${yT;^?R=Yt4cn;8S`z1dlLHTsm(u$=s)eA4U!i=(~?LYA-e0o*!ucTJy zOrA;3YJRYs<9+Td7_O^hW=LM;!I4qZUdn@}yx=7+UPBkTz1sCshtjvDe}!0WWl~$a z022Rmb|5uk2SlHl^4o#2gGrR8`mN-o6kxUf#3T%u(nxluB+ifga7eo1v4@yWCacsX z4(3ARUwW12#Xpjx>G>`nu=xulzK^Yt7?mD2CbGOu^OSwq?qz_hnsZ*vA0iTxQIn-L z+2~KoBGkZi{ur^ftP<--fP3SEC9E@m_zUeYYa&4eUbySosa5CCV06EWc3OYCIxpfB z(UZTsDhZKC`tKyF2BFH6^D@Jz{?a<^`GWm3r2ldLK72 zzP{)r89U%}e3@}4S!mRC5J7&LZTn!(@w9zD0JD;x@=;;%gS)jC@=JB8Y}(c59kGsxX6E0))VzM z2B&!G?ugz~dV5O>=D!NMBO_&JJeqAc0-9N{pWZQ_RG`?@{I{} zi??I01fG>_*nz^&4N>&4*ty1;lo+$WNt%=fYeM>1%K+-*m)K&n27VuQq!TXQDQi)` z86B?l8k887j~MxSqNsgH_Map9C=>4bKXZx1E8ClY-StyqlRQYx0dNvDOUVP0q+E5O z>%{}J56hT3iF|%^TjZZZ2DgWs5*vM_f6~)o7zf>c6zmXp6@y708&_f@n7oNQt1D7q z?*8fugq7jjKEkM@@`!p~Ts0X+@*uO19N=OP@bxWZ`}b*>^M zzydn7jlQ$3!K4;Rt#vW+7|o%nNZ!KasJibaF{3vC?Ft)RrV$JrYs+#lc`U!1SR|&nv0*d$=CZ^@9!dVJ z#6ugmnZ}jTF=U!q7Cq<1_eaOt?A&2>T*2Fa+YeHW!%9{{UOyU>D7Q9hviQ9G!!d_p zI^Nt$MR}fqj=Q!7)7=JmXju8>z9?dhqJO7(Ylo%5F0BgDkp}aWU?k%xRmQrQn=UydI6uvSeNYr@xzRRT ztYG{pb2ZbML?C>G%7TG0M$Awx3LlnIIzAwwVjj!`0a~3={>Gf#hAO!p_=> ziFYuuua3yXXiWc-iYQsM#f{;^=??5Z_Ty;RxT~&c*OOy5mF|Vb1;(5#jg4s)pBM?* zuqodd+g>omUgsMT3@PrCzGPhe!h<(3{Zh6Shuylfy}c~bD)k>u%gEoYU%em|6vYe{ zYTF`#O@9o~DlAt(mG82CJ`)@vWx)(ajyu7zg_|1d|_BMSzTU0^X(_JKNFe)a*vP!%$&WR$a{8(w& zuHe;&Et*Lu85yHsr;oau@lkaxd8{EvRhN*5V0aj!R9}zh^z|O=8nm2JZq$Tpn~M$W zbOCug$GVh}>4-&X52zHN>x{B9RvNX}7xBmLHOBlbLmRBPF(&7_>mi$XjfT#3ud#zu zo##CYd?B6SrugRQpypxZ=cU0>@pIX&2S6iAunF6 zj}EcUv^X3F!6qz?n2vEW;xhnhxB%5OGiE%IEE!L*_H@oOs9q$Ekf?Z6Au@ioJmfVh zeUj`(Q(k233&|X+4od837QO+bAkg5oJD4t^!54FRnd%EN+>ni>p&_`!$6(8I1Aj}? z<5(?>0HM2tR}FP4aAkVT3f=+uk6;jg9139N_rrfT-1${6ynpH&SVuYA`>E4_~`jau}Bh(3!^-hGC2qOpm z4w#DPTfkWb{Nm0(CsASXD z@GAjKlRzLD3B3ijR0hlesg(92V#vZopMGcs09erAG;YDxt65Zh;)R4Kou`k`ickdevDH8J^o@5mm z3Z%Pz0zSE$W6T#K284Cz7y5h>k$5B0(+Q5Sag#QWKJ6ug#H@Iu-!DTi-Uo*1hImh7 za{)Yp>Gni=tQSUl;@!y4h_`x!^eOq+9~m?+#aQ!PuY9~dhKhhpRBq%zkxC%EpYI)% z%+!VU0q>J<&>P3upPUh^e*V+Mc>WVR;}fZSCEq({dV26z^g>0$Yy`+3-lu?T-#JPQ zw$tLVer{eIG*EEp6ddoqd1@>?rg;_dFdVQ*3}J?9_TsBa-Ua`tx;AL96yXg^}fL~?cJ@B7+rI2NYN|*9$38_!;>-N#)$8;8qM4q?Ne?r z3K9mqCh5(!Gv}|u7R|>4CMZ242hnJ>LudxcZ(x{0W`}_>+cgUQi(6AMxb~UsT@(S!E;=(Ln2s3ND?CnlzgTSQ>F{Hp>!JP3vQ`$z)O`MrNXC4imL# zmw}Juj}c;M`^E;x#NGACYs0-dMST|1oJ6o1h~s+_iG)socyURKE`yIdy7Rw!JRl8u zE$u$dlYo-NCN+u;S@awWGyP{R%ANh#f|ueoKB3Y_Z)IcjqQypQf4c24nWt~%`shaY z#3M0lJkEAb5E@Xk-+@6!_5v`LAC%9bJ|goH!JNh#Y+qhsL>~rC2U4;ModDLV)z`mR zn{0YGy606OQvP*h4q$66Pk(uSGN8aSa%z1gG9yuJ#vt5&Rs?a8OwaySbuwVIPr$5! zCnPGkADqG91g7VHFgF>n(BLo_|Cz*+^V~~6nwdmbfSy_#5Ju6;=;?3I;@%Sd&jp5F zf2V>wiS*nTr*Rzy{_M}^r6wuy;?IvE>dK(xe>F(S9hQ0>Hl7zfQQz0RXsWOthpe>` zT~#~?&@Y5#%H0ct!iuaL>4HpSB~ha%MDB2qo=+5=d$C6*#eQrOFi6BEA}W!>Mp8Fe zC;+KPXjgx$QvXi?1T(20roYI|Fy~W=!?;7P4ifu&)ot7`v*A%?#zLwwjIn)ojq zEb2HE_6iE0DoXc;qdRA?3QI*2BmWyADe+TnpuQU-omn}Q~!oe%`b2?R-;EOXMU5V>m!%DCNsA<8O8Km zrp-Mn%%h?FV=0nd$t!@je{$n#cughxrT@f0Y?tFc{p-2XoI(WP{@7TXnL8-tRRa4_ z`|H_BL<6wh-v>ZIp-=Fg z&$grW`8CxS!Z#&j_H(VbFx9)tZPjM$~AI&{wI21fd0 zQR-We=y@a%FO^iLhP>J+5YsC@qYpr-k50)0F}{m>ON)p9+Ph|ahK`&xY1i}Q#k>iy zgol5_S>E_F_P>1U5)B+eOs*e%>A#=^qqDALpakBj^6?Yy^4S2mjs!%rlu%hBVW(qdbh>f1Ids?Uc`@o!2o<= zIN7VQpyFBI83~ZFOS1Uf50*y)N@v&Wyu>Q`;eY(<8_887pWF?jJ&YLC^)sfhwLKD$ zP`>SxJTjZ`9{VK#NMet0q~n*YUliH%Jd((Op++KH3-S8vNcQvkZ!L`kG>zPYrZ8+7 zmgl9{f3!FfFsSvh*WcM1378^%^vjzg0ZXJSU)&f8I2}q}u=v!mLy^zQ-mBc<#WU8X z=&K6gj24KV*+C+Pbr6jQYE9eI_YK>F3!gkg{|9c5I4~pq z=SzYpEDW77w)-+H^iI7Q|J$xN)o+v6*<;(Z$Q_=ynP^%j4>BTWP!WJ|AOI)Bb($%* z(}dc%va({Gz)CMdCETsoYG@I4{L}e*qX7&2{KCQlrbfxbb7o)!SPSm*7yQ(_^A~c~2t6jgG3Y;SjqvTBZ0-m?gwhRd(Q6P`v>k5 z_w{>x-`~%d7vV1zReTu>Ms-B)$@-+Uj(vr~g7#;~&3g(h`}o5m1Hs`x@*w1`9lULM z6^J;u2@T%_COQ?WG_YH8Z9R=@fmFE{rW0vUEGJmd$OT-AnZCtBADBFGaxiQ|9+|#k z!LTkHk`@+3Xj3ynx?+e6wFo+L(MkLNRqA>OGhXwY( z5$MGG@8>DF69Z+B>2YiGNv6j=C49UYed-`ik3Y;q;#4W|Q6A}wqXSCCTR;@?t@MLG zCw=L|=bnfr9derj5d|cM^I!$*9aJ(dia!PFgU$Ec{X`_`P)WpG8~jf?2T^77us;Zw zz317Hq(cX3L6eN&)bC+7ReK-6nR{Q3B^^fhLsMgiihK`5f!d)KuVKB_1rW!f8F%*R zOW%v5Ak+#OTnH*FvSL9CIrJj59gZ?po8UooU@Z8J!q{D0v)Zvl#{hlF1 zKK&#m&yK1t)SJ>i9UY;MDuQ5y@*^Yk5oi+!Zv9pHr@Y3`C9luuQ&L!RCJs(%ygzS3 zvvV_zkBwje<0U< zHMdF9nyt~psrT#ZDe(1XcqV~3=x z4Etka5Ow5NmX>t#ZtIVWh@IG9Tg#J7pF2hJett26raLX~D@snH#I+|8Ws#TZ%#GX{ zVQvQ_IyG*&Y2rpf>C;?(Fu&e4u^(9+J4zfT2->K@pvvb?g1@x6@zbO}MmnXwqo@dU zaK^4EEcCL%JmU>VY^>o3;79%N(o4|G5H{;pFx23TlXM0eJu`zhIDgH}SQdWyxTkSN|4-H=Vh*)aNWZ^ZwMhW9jPxXopHB^Zt@JB=r$@Co-JH9TzC) zA)G7njXaLsy$=|9GWlc4@5uNnc#>br%LcQVXh^QGm(R~MFsJ#<`g(&a@8xIE^Jqe~ z!?FMTTO5Q*wL{?l%d%4LFoDv7$`$3ku`%4LlUaHtCu8UVxbT(5G5EnGx@%8apMj~* z2GRFs*M&Q+H(^{t@pO|*oPD%w5lt9weNpY5Kbt39i&YYj-7j_Y;e-I zC07swLHcii$(#X09(R)%oJYoBSBU)>p}^o;pC-i?ku@qN->$|R92uKSZ&VT(F$iIM zr&etWtJf1pz=hweRAfSSAHrVRh%vg7FX~jHWVmH^z zibC1%l$rn#&dXi?_in|>zFk~DqEI#QQVGY8zmm^432v$xXcF6UlL~usX{;%*CN1XI z6QIM=eT${M3|`TF?_|Ct-G}N;0Nw1qH{*zR-%VF6`>-&t5t_^HG#knGN%7Y^3fbdvma)-f@3PSxQ`gQe~bom5o1Y zRhhS_vjo~ztR{X?TEGOmSt{jjuX3fqDp!g3>G-RaC{iEd#|@UD64WV*zFMj1WuwlcfVkMJ}g65*F^UZRblx9xMxcxg2pqmlkc?CE^C5cgy*)oJ`KH>TFJmogT0+5lWv;wK;X1nm+$8 zn?C9F4qF}@7GMYMdRfn(cq^{P{9MyVAj^B$n;70lj0JmlAJ!;;KGNLB6_bs-#)_h_b-o)VJPAc ze+eK6g8DNVA5(C<`&Y*X8&(ttNV*U~4TIgkCEb2(n?RB{liA>um5w|(OHVu&4>ysp z)#XwW--T;MiQ!p({FqL1Jl^23W?jqlSiJGU>G&7|K=C_X9E+=Dfe93@?;?(k!0Zqn z!`5^;tbcGiT*k4midj|;H(1W|$e2%hJYoBs$yG2^$_@Vgo=4(7y0<&Q@V5P>cuC<0 z*$^wfQn_7CT`x%pW|R43$=74?wys>~ub-e(q%&k$Bk=X&%MIo{IWla_ol^ zp|LIkjQ%oOY=k_;HuDvma1n;=#t1V<9LN?>hVS}jYz!8nzhuo|zKE>`aTJP{8ssUd z6e#sV)zX;5FbQa?7(Q>$I4h0uO!-h-_LMc02JZ$F6;Jr@n* zk?6BPxJmi&n4{B#^W0^I7th&9j)ji??!c%%}oh+%^GTnTo?8n;A`4d=Y%+$Mv+jf5t;am1l61du6yiveA$~O)Qi)`S zSt^|}Z@&Z@doqkKlUhy6#LD0@k3x)R2#E|8o8t_?zvWHhB&rl+BuJDmff^%JWt{X+ z5!jagDeqhDkENPo+p-+onUW_GPcpMFG?7;5i%m6sxYB!*)>-cs0*Gz8Ke2eWCvHOU z$)ex0T^~j+Fu}?H6A%fBCT{)$66;ZE6azFks|O$zj(=^cTcp1cLkH4C;%vhpOEWa_ zchsQp(e6YMH=3m|XHaz3p!l2`;1e(XwD;SC;~5Obu1on=oqzjoY3ga=&Vv`Y;EOO^ zfl>@4FPO7@zr@q#0hHIJM4kTpMXw}%;~v`|Ow&S--YvK4^%LYe7pIADPt`4WBJ0QI zCSI8~h?&284mf4&t@7cNR=^BniT!_Q(`nn|Q?#a2=!ZQ@JbhNSi&*dfToo1DQ%CkUyi+g}$3?-<_pdbl~Gz!rwI*pud0g zNknCV+AJR1pM&9JBTm8V1}AO#=>0cPH}JLD&f~sWgW)x&5x`?EckdaK^U+-Rh}pH;Xg?|0GqZt-wV8??udwLufk zXO1*!$4&CZqf<(cye~?Y@ez#4@!+Kn=L<<>kvUHT`xDvAcXWD2@hxSu35m|mqR~eV=R0`l+0{QnQF!vcp%cV_4?}idzZmLqr`PvNhiDQq zXz4Gq7-b}N%QwS^XbViZbl;|YLdt%gc<^UeZz6cQH*sv@kt|x{HS<_-O6928R<@5$ z-9e(sCmtQ`kbe|5tL@Q4tf;?cH3r^X{oqODX|YFqVDU)S;kmYe(R=ddKk#jFNazaI zo*2K{5pAodcW^xM(jzeNbj8@u@cT(uq+Y=)(d^A1cSTOrX?5|Z81BdYXIWbiWlP|w z1~_BM!gOaOLrseYiOdq4m6^LQTJ5UkNCV0}rxI?A0B|-2iEXM}l{dWKYj8FaL4vk) zVH)7$T=_}P_DMulJ%Aj+sjMk9uA{RbMd@iSu+`v#Q!;WrbgqHOTNy`9#{yAKq2Shl zu$>e>KFpciAezb)B*Ek|eKI*fr!nNkrFS?|xSpTuNLiB%9zcF9SXQmG2XToFaX65b zt=>lwMps5e-cgA~dy0!i%^~Hsrl!@Tnuzyf8QM z=m<*rjo{*uLo9!N@yKBF*B9Gy@j{nErKS~^dRC{VW=sZ^CSF2FZ@h#Ysj++U7Zvvp zlWq0@)N{!Db(4h?N+j`U7_WxkYWNV#U*A1E*t~sr@Ke#L+2RM9ZFmUP>ThBDNzFEt zz3#?WKsg-6FvDMuTy=N+r){6~kq=|7eKEB&)sxm>O_F_ZW@J(pnLYrFpV}4~F8N@h z_xE;rkqjwi{6?RB007iw>C+u6Qkf%VZH?$o1d1c(y1bq86||uWa676pJ&5Z!XE{y6 z4d=?Tfl{K|i^_KaqM|&*v^ayry6#(t-Bj9{DytB&RG%uNmT*~@iJ6|ot+FA}XK&4d z0Ua%ym}SbsYOUOn=vblL!*2I?1L!^Yxw4h%hO|0|XAt5VB-B*SVllmi#UMa@a<&G_ zb=7!zs!)pC2y`m|xSv@iPX?GYGLtJStNp2YO>iZV3a;Laul1>a_ye*j+)D+?y# zSxByp$mFXjcIrj~sm{AummRByEL~=o7Jvwzf3ke-9j zWuRG3ovoVpYRH?gRZpDaj2yVpv1rKw+pP3R2xLj(?nq~<#_P)?n@CMrc`;KpIpFEm z8uZXCIBq%Hq=)c6l~I?(to=oI^K~w}RnWX8X#X8!U=5Dp%;adM5l0GhbJ2GoFHI4H z&>Ed;FGi0lRLRbf+D7WjY==D<+6jfoCJ7%n|M1Z$84AEW`OfL^y!QILx$QZ!8Vsa6 z$u<6rDX=$0dfk#D}6l=peL&bOIbB$E~Xnhrz8z=)I@pG6pAcZ`U>;m1Df7NfClBg4gdP+VIv zvwfOtRS7Z-H9k}RWR&u7SSXwRlraKV(9+6CMk+DwGzU>|)Og=ux5=gU<^~;1-aP{m zYw{k38~^Jk2~45fC; zZm>W}7s*5t$Y`;DPpTDbbJ(lAI9kL9!)O>N8Qfx#>IQ5=;ni@x)_?EPPIa_R44NtS z1d{J6kIz!6!=V^JNXflW%fo%*gXI6e7?yt^C|6*h3?-7+8-aAou9?5 z>~P_#jv&;^++6qFMfv(5ZQ9uZBR^W*pt)4@{Ty`OL1-wzFnZuY@5@;?VzF;Kc}fXQ zjyI4#_{ZtgtVT8&A$tm3VB+Lew<7uuVVSh<1K1ohX#|aK=-G5G<_XAVGP!Xh})kfH01Pt9_nqW z*rWJs9f23yz%-`91BcPM13)trRf0`_28Uok-(`06(J%Nr7&vj9%VPkeSr6XqgJ>~t`(Ukdnt8o9* zmK`RPR7XyYY$%%#I=wriBeHzrK>^<95f#r-Xlit$R|VopX2gKG`-c85)~QT70_p>S z6nb2y)34H4R+Z_jh&8RLuD5ff)`o$3H?4f#>t zoueZ?kpCOF&)Nv?Np~)el{*b$unT8(INDc=bC^?ISNTeD&ek5_u1t@BwOoCC&jMwjFd*d z^l0hDB2qg%S5kIKTeE86K;0EEBK|I zauI^UHMH!Jv`f9;0v_;V(~>ObaoV(0xLUnnT1vYc^$lq100bz_=l15?ZoV)0wgx0`cPwsD=4@PYlKI{6oC-XtxH**Fi%X)d_wVop z-luy)?6CVgBBJv5s(nJ`+LCV#4{F8RK(=Z)eO1h#z9U@f38{?@on!5D(IUpn_FNah za!n2+r`mG|Z_u#cEhUQg^h?m`ncj<2H z{QUfyK16hWDqm3$%<(PkJTtXF*B#&*L^oA@ z@tlsTW4b-CDT%4gs5ZcbisU7pdUpS&3>98XZj@Ba0_*BZIc^9x{VY7mvvI*h$b7sf zuHG+hxCW%@!~el$}pwt>lw56xW6_n6&ua~Z`cRzj*&@iI%-2TRW_<+Z6IKJYl#nuD!&rzZP7R}E%q+NcYPRa6F;KLSii_Q|hv zQi%1e_aNvgd0zWpf!y|1XoIZL&9)GzcNltfX{8JT#SAW5=~-5;ltFaPBra~%k@!{i z=IeP)vdb2d`K53^kL0x**wHzkS3b_8vrvk2t1q0fdgtZ}UBPz|aV`o;-_t&}I#(>n z_8>SNR0JT8(v0yZ4XfV*@6~yOi7I003o64DLG&%loZrxidNx0*YXuLq8_@5w`>;Bv z_6j7Z_n=3`aC8>&z|yDnvU32g-7D3 zDg{d>OO_Yg#M6-27;u3j=Szx1>k9uby4FcU!U#%1&}iAR%IZ= zWLMU7S9Gt(9ha_P3nWZtcchE?t_!F)b_)Yp>sjjx}im+jqVAz zY)3j52=N|kazhQH;9aA#Mpk8rS4r#-JK=ag)P>afvI&xDSRwIHxTIMfGNv#x)8Yf# zpKO)UomUmBwZSLrgOnPTKee)1{KuXRoTe?Dy0TfcVdnYk4a)45H4ahA1$h`eK2k($ z_k5Oa+ST}!rQs8s_Do^1kIA+Pp>t!cYsWmQT(4{jP|x;n(^hW3EO|5A1=SB>uU6@x zWb9@SG{YOR0mZrphB8Ri;4wurwZ*2GsaD!T+Pl^i-h)iFDvD=D<849Ssg3fM4u#Lt z1lVGxRPBI$lvOTsu_6!Ez&>lz^XYnNpoG3yG{)jrRgSHcs_+S?_R8Q4z-7Bqsv3e7 znPOljl};29LuY`2v{h1sA(L|(ZkpZP0!jqQUtqeJ++6JCsr}gUoglxidl14OFE;EC zQR3$2=9)|^m*PcPEXrrMT04&6!h?x#uSDyZv)?$4aXgr2wFxhS2a zzqy0y%MQ~%Z@syw4hho9sqM1ia5ewxIJaBUeCV|9pgA(*WsN`1dCTfps#QXvombBl&h;LHGpj2NtWO|GNPsP=*6NjN z9NzC}L3U*4%aR8pwn-;(0h`EIpI6|PKMi0Csd zaZw8LqAG|;UfeB7{`ghR1>#)b)WHK)Ug$Ya);E8p{4GsZfXqC*$@LtNO;lq@``z{`9C7{j*z;u zER(g_i`V5LF?6#jF_>G{U`yd)*5iPcE&*oGUg1i$l4dXM)@o(UGadO{A~Iu^Y^9O` z0bMwLp;puEnQ|GL1=k)%t?2SDKsWG}7bg)V01i+v866}4LbQ+6m%Juy>8Ohz=XxKno)4LhelYf;>c ze%Dhn$+KnxFq|9#055|1jb|>dbp~k}TR3+txrd$LEptQw-kciCY}cB+(Ep;SI5KCq zWZ=x4q`zXUsRj>VCO?#Ic0&w3t%X6wyiYesln_eN;mN>Mt+c^;wrh$db+d$VsZ#W2 z*GjrIGRW$U=M6E<6{P`m!G(ApATZfoWbbBnOR57?vmS4<)NURc+6~3YK{Ky|pI|TC z^`*T<%{E9J?fUpWi`7j_0OKcHDa%|CqFL+)bfhL_D(hX;#58^BjiLsZ9vopl)Dmy7 z`{eBkU;^KUTg#+qwK^;~IsG<;OP#N&HqSNqi{h0A zxQrBm?TC7=$hv7=sc#~yF*RT8G9q^BN_~?VU!r)m5oN4D5FauE_;P~-!M{-L_)~kE z3LCp7{qVR1XJ<5Z2@6hP8AOS=gKPaKkco1vm@i_;sL5!V+^j1EPfEiMgYE%QUR&?F z0Oq__?22cs&=u<)*HGU+sGqyOCb=;SWCyRxVc2h-O2T`-&nz&46gL|b+wR$;=R1yR z?qb(EbFm6WnXh26R_=)D`5FmlP-=FqYzzrK1|b43ySLc{sI`-$FGSbcb~4{(HxZvw z!6FX1&%4ni|2k&l_4pd>JE%l``=b3#)qxf^c~Td`3mt%{<`w7I^_~MWiJE-o=`AFD zYfLc2XtgiIIE`g5U}LBuLc-mIz9f-I_UWBE4Y>?4QZcQWGR|l3tf9=+8-vXO!Yu(- z`KHE&@Eg0O^TYCxO&W?_)mS)1L!KXZkS}Ii*dk%=!eHs_aPh+q6s@MuA&=S&0p+9q z&v?GWiCj+r?3jSZnLcRaW;j+??9=)6M%dEF>!w#r^%Au4dL33y)=W=UF?B)g;4G9# zXxjYN21`8+OlLB=$_9Zm2pO&<2?H9UeUYgwR#MqAAh`{ev~HO0oWapmd_kqIBOe1+ z760u1rZmb4CfOC17Q%^Ik9~#Q}LO8!WbKVA5d@F&wB@n&g%p!_fuPXH$Kce5WogRJisJA?|j? zbUfP5XOmu?VN|IMeXX8>tvzXh@Zpqflk+abEZTIKN2E|(wjgXv=(CmD0$5;ne@$mg z*J}$+!Fx*%gcnROVT6TDa~r0xvQw>f$li71!$RlVZl~suQo22wZ@XtMVSyTIXA<*k zRY=68y=t|Dxk3R;dl+#Ft1I=jHgGShRn=}+W7M$w<`Mg-94YM4dR1~GpAyNxsvTO! zTDhhP$8E{;#uv_5_tq9_vU~dMLem#r(1%mr^)Bd_FS}Efh3v%zS+K!}a0?X9d*0-o zde~R#JKn=xtWXt&d`j`IC0LW;@c*~|QrnunQd6Rty@f^?>SkGiM4H#QfyAo9)qbG) z;x)}T9Eqz!rV6zPT6o8GM!Ha~*+7bRq1PD9uK7ZofvnBODCo%O?LVKaSN~ZRU?5Nh zu4x(c*2QYWeF|xxr9OlEzDd@0D*l@8;v;bqqIo@)-dHzalKb}#J!R{|L`RlD-LOS# zk|(uahcWC%*UNKF63B6~ls{CSB(cp_-zeo}d-i6z%_=t+s3x=2&AdsR%;F`P`2^j! zQmX)ty|TMdS?}9IgF&G}C11x-gi5|Zc(K8!2PRPDnV|x(?n}oJWR^L*-f>a$mwt5+ zKi0JMhLG_SpXZvN30~EG(ut1Od#icH*7n&|AEWWbco=Cs)E`?tQ(ZU2l{W@UYW|f? z9TX(1H~dFlbL$SogJOJoK=|*9la-5i!ahTL&I&#$i-p~Iz9fr~tTI~_&6nA(fB?0v zezn7X^VTeJ+wvuw=7ZThdj;Ga1*JQ_d$^k=TIj?{_k}Cw2eaE1FprnI6El*n;SW|M zxF@*K1w0$3qW2x=xQb*ezq9~cC+o4~%>~UBywx`S;Pt7UvNR5h=&&g9soe#Whi@+^ z=;7eH&N5|{EYW($H@&ye96DLg+l*h5zud8$+RIZF-4!TnLU6t9aW~yURPEXv@>+TW zBI+k3>3Xd$G~HtGR!^`%LhRUXcVp~&8wh=r0SdWrvRwO>8Yb3&;q;P4`UxgP^v;HL z80tGBx?QQ8wKm1COIF^|X0dg{6{$$b1iUiXT4*x3qvBhJizaKNu)w-W05h500?ptB zU0khhm9Q*rRdg|1sp?`H;b|mjE}zf_6c9%hRfRSyPO14mCZcSSPf4q zZm1%Nn18z=`+n9BPge2o*ww}g&?_*M%Im5tv7>6@coni6y0uK=+)|KrebwMj86qg6 zuYI-#8z5DvO+NIJG8DdME_i?5lwy@$G<3Zejos*`LD;O!6g_x#k7|+>H$EH%)QDBb zfN)f{%cMe0+*WA_YGUdo6+uX5m^C9zJ;V1b_C5+(ulF4`xNJ4z8k|MR1XZ#Jugc%@ zmo((|TVgNu!(eoM+lOFUt`NdQEsYo_$8;app$*vy;`@uX=Ilk$oXpHAJh-MA=r}t5F@fO58kDFN{MCCURy` zAtJU4JLQ7V;G`S!aYT_Ac83bb$R9`R%ETb0t;@34v6YyO1$w?2;rC?d3*lU_C+(JuLFE4VcEQn_o1Uo}O_yp-1vDDYem%^#@BZ0xPBFvHF3j)-d5 zmm@pX#?MJ+lW^HGrZZ1Yra%r+ur+J|4JbE&JGhdQ>w+oM-G7=`dnZ8srzaz`4FLk^(u=bZ^*5;h z)KdEP5!jE@NdE2r212m6BT*S@kCFAdwE}U4>2UY8$DnZbikRYv~d%Rz72YrVfCtS`A z3PcUx$_7On#Os);6pgka;zWDaRoha{HJ8pud?!sM{<(N z&=N{qBlgk}ckfv~I)j&pD{Zpk#s75^*XftI;Ec920HEtos$+#VlH7?m&q4{y269?D zl9ObozIQA+p6?*tZ8oS%2w53~AC3lQbbjh;yg%;wSsO`HwsP}3e4i84|8!isP;Or3 zyIf$2Mzg*n4G-5P{}GugSA0ioDi~E=bHd{pn(5@FER^e`I;O12)+$1=H!z7>skoteF8*Lt6HC0@4aR#ZK04@EZ=UuwQ;IGJkA zY(W>Pv`Q%c3%_)}N7g>W9AGXKosR&oH`g9X?MF3+F>va7E-n}fi5ObxvQMS#M%DDJ zzBt%SA)UZRrkLH|K&6cqLO4;Sfs0-3b1q4CbUC{u3tcX=l!NTH8%3VOLC2ELap3;D zc-U~0vq?OfJ6P-SR&x03CKR^(;5(ZrdBR0XI?Ri1aK)4HrNaip|N3Krr6%-rNUBl5 z=i#xw?EVq~=O@>hqAuAX%fq}UGw&@aCN??NyifM6gKGIHe$XR=&oK5HsOtT$K5-qE zoT+r-PhN+UptnxOr&cOk8`|*c#QsLDDq|q9nA&EMe0xxnN8-h1DuT%aMmW>Adt}LB zX$A#_!Mzs+4*js_Ry&a#{DJ81lr2Jk$hy{(ksQ-Gf`E<5yD_6WD%Snz68vkP?Rcak zFofb9i3+-H>{>4jv|Qqdr=8sA7(;`%(-3nyomAP6X|G+ru2 zdM2?W#h?B6n>@j~|Gyo6GgC$Ly9V6g(jS9Vpw;-MdL?wtnt5D1M635{6t4W)-H|bdiWNN zW8PSNpiE^?!XKGEhJc6cG9t&bD@80;5l5aq4uO33j*`YXLOy68>TkqwSulc4Lr8tv zWnPx9nIFq|JTfY+yIdbbfdWn!V=)9sA&(=5GNI}V88&nG6!Cn zO+{fon;OiDOw{C(S?uEDlhaY8*c`|$DTxO;%*%nJ26?UlTPNu@I8N40zEFdWt*k@<<=j%srBpfB>%cv z)ejIHwY_AZ9O7eeC&W?AcJVNS@4t46T1=?{jwf~CmdT=g#?rma6mlpnx72dR>0j?9 zNw?Y-)-gEK;-psmBe#$5<33}DS(Ki-N-gR-@#HrdiHkFb(};w-G5F8r_bA)y;cSP) zxesAL-^^Z$M8!^6|4oSBgl)I-6P*8iSGyECiQ!gklIbic?E z_u#E3nX;X2LOu;GPajUpoLztZNyLyLsPXV9D8|IipXl82*~3|kBgEe_m>}m4=P;Gj z7K$>oToxHt#piHG2ab?MexB2hJLTtNL;dIM{SY@8eF$okT69`zO&yl|l)dThU8bfP z`WjMk4_w{LZs{`oovm#Bg#1k6+f)6o`lsY)1ZvHK?6i3Ksj16J&Y)0AOX4Zw_~RM6 zKPI;skI+~dq%JsioxY;jzIHSh6dO!vU-nP+5ERwQDlY9Z(^&8*U4C#71bbsn{Swet zr500Lw*z3|(oZNZYK7x_DNFqXAif! zjKlTKuL)8sE$>q6teYvj*~21u4zh|`u+Z}gFG``o_Og6&zJ1vuwY(W(A0p*q<}jp^ zrNgmKDlOQQR%l#lA!PZoG~Xa!2IfqaxISMcd2haR8O=3&h)|fZt8(ieWiN9G#anD& z7W!1YIei$G>4T^Q{OzMhRYtvV=8rN>n08u;TXEd>Xpck7g)%y!6-TBAjYy;p`pE88 zlxKO9ob6|^mlh1DC@sXNt|C4argW$-$Gp;-bIYwGZn9Xp#*3m%a3|qWUW~&n6j!6x zs+aT_#QwqCprXL@JT~5ovt{Mi;h@+@LGE9NfMRD9CkKI_xYXUH;8?Ls*iL&DGaUEA9ptJXt!N`t^yy zWfl|&GnpM{|6ezqa3cm2htp!`U!R37N5_w2|4JwRe_Qus>fnVM#qi6ZH;vEBoZ7z} z5F4M*3+e#Yg^aVuALhCKWh+kiFUKtX%W-S}vXi;K=>k4IYnkMD!>gMWEX zLd27C73`NpJ?0U1B0`6u{?anRaDBfrlwMyq^*gvnL~1Sa7}@WYTGH_3iFJu-<5nQD ztkZ^Z653Z7V6^Zn$@k-(*-6ZfN3hwueC#AWpnnYK?ojAKU=jkB7opMP5S2arPi&r? z_C=gqmFfL03qY-S)e%>FmpRfXvZ4)2l<++E6W84a(&E`1??;M_l0;?hN4d86*uj$| zJ;EL9T^>pkby^V3d={B!y~}w!M>hCoaVrn6C|*^*TNRQ!3qNwqqxxrW0NS;<*!eQ3 z#v+Gl^=?wBxE($`><~EYvcT(bU1IKc@AumgY~7B;CRAGGcvYuJ60@-XKZP()){@&` z6-i7j3qwG-SEosl@7#SSc#OF7aS`GRNv_<^{IaY#(}$Ro7}}Gfy@TkDFXxd8%pm1= zov?WUM25Ul_Gzl(#q_zq0*8K(3o&h z0G7qdA0y)hNzj-@x#z4~@N7HyL$yUxQGLWYQ02#^^B|FrM*A}&T~;0$wstRXIQ(vA zf(Oja^=LzSG(NA8=O1M5fpafUI2}eqJj)^J zM;{E0nVA_VMW_~d2%lI-YaL%){9A>k;8wGL8u!Tn0<3WvA2+HPgE=!9#2uK)R*pcL zWpm$jJJtVzB(~GqAn8%xOo#6Ao>^Q3UNho%6N=u-297i+ZJB8haBY!=t$7orAMY5dW+YIK{C@ma~8?!NwgF!3S0xQ4EHjFCNY%X13iG# z81w}H&+v^mQnMb~_E(-n@*5rGhw@l&;#QP#Jepq`pG~1@YPrD=C;6#iA89QeMzI0c$RSpl6MoNj)SnV*a}v1O<$Oe`yjRB_rXFL~hHXlcVJONT-enKYs z?;lqvIhTYc@pk9SX~iv3;a-~cO7!r7n?v^aur?^-b<`u1%A}p){~~Y_^IW6nQb!~_ z5n+sz#yQV5^SQ~HA(=v=A)9#MP4>5=Et%Ce9CeheK zvNLz?SuWkQ1U%~FQ$Vv%t|rgsbZ!9sFn*{eD(AkLPxrpOdG3i^y762f+x$4`&m4cV znAXfmTUvWgN|Uu*NDt6S?s;b;JwO^-dbyl#e>pYorsoq{Utbm!^t<498eg?Gg^6Ds zlE6WP9g%)Nc3u4{F9`rCQU&iJ)R2y$QaE6I)nb^UfdF>t_c;lOt*})aU!|T0mwA5L z7dG%}NLz~hqhtmpNKOgu_Xk=2KFJ)^czk|QxeI!n6vS9j@4_^QViqoDt5t);2d_>} zqKQ|N!^2nt5D&}op&^8DCqxmlqYr&$k;3}>R#|*6e2#3JVO}JLp}1iu*T1W1|A=#_ML!iu%&tkf8Y{4Y2>k)zD+a^*XICR z#5mnLsi5USIU`bkc=2#iARcjLtl~;JIvUFirJCZ>6T>N8oVwqQEH6#SA#u>#dvyHZ z$NC40XT?K7wg4X}vI9@<+_8Zn)DE+}@rQZNLLV^#-s^}x!23z={$pOJPRXC}Z3&YU zG}VjAG4T)Ra4+V(?`LghH8}49dSXaNg6NYbKlly~`}mZ#10Gw&b5D$M-KR)8vb00+ z)d1Bt^=xeL_Mi0%2o?UhNnQ``^$W!s^ee=5zUsBhc zRhJAhW{slVQtzNU!}pWuIo}iJl9viyd2XHiAKPLvd0``mznh8JGv=kjmz{`py+mC( z^la}g0%pV$ag3;kZ}F6TF`w6I=}I&p(GJXz@+)q)MnXF+G^lv~o4LG3*%o~G1Pp}h zqoW#z7AI;?6J(c{qfwQ-KUAH5PUX1vrUi~SV>q-SeT&HtT6B^0p_Lbl5t$u3|7xUt z)~=(^{#`ZsMlht%(l-M|g?3)#==__(pgs#Ii4bgsAGv`PnQM82t={l@4OV^!DK&C9 zo&22f+y`e#{(LyB5E;*{oG&5axsrIgf@zRVZYzz7{4Ggp0C(dp51Mi1M+5XoAd3_y zHMT78=agqYbqZ;Wu>n~p<4co;yn*x+y|t1fU877st5IQhWF)TAyRN#KxbxpHiv6$N zGqE2pc40hLk#1%oqdyIX#LfSPP>V&A8K2L^9oM+6#l_s!r?5Z4|{egnLK z)Mr+91fTZ&L-LnnfOR%sNJj!X13E=Oh-=SaLa%(iFw`b>;^JuK6HZ^OIY3$&9*!EY z*L`cquhTvDZGT`)BZM!GsNBjc!mt9`^?I&{Yg!|P2Jahc4E{9aN0*L^JD(vzM}z(# zmuuq|Z=p-@$Gupj4NsqjD}OlLpa$rUIm{k+EhVh@{ zKeE|~tqut>Vpi$j^O`Wh&<>3()ce- zB?Ly@^=ZLEAMIO#$S_$DOpEkl_xVZNQ1h9oahHZP3fHl7&tjIbwk?PmD$SVIbWrG9 zeiMk@LpBpo1STa=0}ay$7<7u@>9+?^J7_T=SLAHHXCy_oX97asy17lZTmwa}8nm3t zLBOLPO+XNSni`aP)27jf-vF%VI~E-sdp)FCJg+HSIHX!&UPCoxl?e?~ke_Gji<9MY z5B9qB-TUP-ikXY6$@%0+M7Yfdc z8z4v*V9Sv&I-LcmHdkDmDpisf3W!w9pMSMj`4vVs-4EB6Mdc6@vHG&h)%%)Fv!T}G zu}k?nMpO^sn}xP5^_@x&3@^FzY(C$#0Y3$?)3p3Xx!k6^>HIf0Ht^R5oP`y)Y~4Kn zW*Kdhc2|gHf9TfPnbsg;r}6bn&5c?0Isy<^egLN<%vt-zV6kT{9RzD23lG7hGc@Fq z|HJA*&~93@+jhty2O&$y_&4grEA}CSnEZ9OJcbPDo9pWyJds+Zp%A^lX&DF$%c>92 z)s*q9L$>w+8*DcaC>T5%-&54c=hX%^!Wuz7JIz=#xg0?1lR8Zc6 zvxoxgfMpAL?Oh0KKkE`R?TeOyD=vJie+dz{pbbt7ND=GMBv4SDF3Dtn>9fj8I&|3M zsl5z#Iidct_na4^HKH<+yLA}g@G%`%5ki&)Tar0ACn^*PwWl1)zo3e6&AWm*nYgwU z&vI%r0Qd+wB@>c|)VBkveM03GvO`bkqdjJwp^n|L8VWfL`?LkyvmwjifXf2g-E`iC z1Fk#{9M9)n_~ho-`TnW6MYlV=P9x7Z2S_3ot70akFEn^gWhvN!&79Rr_bTH|VXMgt z4oPq;40WR+mc(v#_}kL`R}m&js++DBx{EuHYmGfPFO654OsglyQV~&g*~_ z1}{?-U&monp>M>%+(xiFB(rqLVRGpUpOj`?nh9vCl#GR|ml9~q_xYw6alqj%aZL6{ zybZi{-1qrTFyc2Iq=iGWL>4XJ`+Oti=>86;4N3<)G9S(v;t77IU{DC8<&N_o4t2~( z&;Z{Ua-wJ3By@-w6g12rH7+|F6q3;mJt&SCMkgzWawo)Dbqc6@km;8($|44S>q?k9 zCibR@VerYlAe>tX>_Z8GZ9+YgYMhJHyxIKz@o-^X(O}k z?6XyIhigk%3J^98B2A|Luyj+WQr_Y)dczj&a{8Zm?frrY)!|L2#YhGs{gFUfAVSysJ1Rxh{Pr< zm1dUdiPR>Uancg2Wk`h-sp|=ZpHApDS@0Y*Vv`FFRR*SQz>C?g)1reg*W}kvDX93F zS19yZvIuSRNYeOt1$L%)OFMbu48U$^;mJ9t3eNFIVSn3xx3uFQ%n;H~W$Kb7Pv-Ly zg1sm*sel%wz-fYr)-e?kMfY! z`Jznn)l)_^a|A7s798NNum+Vo18s6f>>!IP{4n)KDja9?x8+H(-cHDA(Ub#1S7vQT z#o++)A@8O-&%oV;MsUS%Lzh&%c~r-sNf%Fvsd0EYJ-^hLrSmoa-zzp0l^n51UhnrL zTdIRdv(vWkI;q+{n!W$OcRkd-RCsCwh4<*GmJ3*P&XaV1-}%|^&64d8N@Q1w=&K&| zh-U-8Q##QhO$>DN#49)uD8cl#LD&L*w6Y%t;J4U&N_lNFEOFAN{1j5FHDm;TyYPJ{ z+0ewtq_3`o$>c3Q{lT| z8tAC{7YqCAVL0DOeZKHi7>Pi1ejM-pT5;Xd`w~oa<;M|qYl6OC42MUXbU#2so_B=* z?5LM1;gy@=QYSb!@%eg_SabOO*MPe47f{oD_?@-`k{0tG+%0qWx`jrVl@AIOwD(>RjQIP8x#bmc+X~ zf;54~SFAFJ*Q;!Yoe>?TKCy=cdVDVHFU-n(hYP2^R*=}y19yk>ec#+AnT|GGZ7z$3 z;>zEzQ|bSr>`j2=xXv@d|K(Bl@iHqj>+Gtmv%9KEb^>eweW5#Xc7tRKDUu?gV}=Ql zqDbx9PBkg2Nx@{YMO%<85hVyBz_7TkffXCH?2RbH-mv8HjLH<2hBO{W4ej+xTJKH{ zjP*!fZMbC5coeorylVqw?z$Nuu@ zkTLj8t&RlpX&=VWr|RotVSn?l?{ctrgs6{=PMyyj_Jt2$pF>m=WX&M^*NZ7fI%Zxj z6g+f^@}IOq=a_xJRVerZ0eb$H63l1ll~(@6hqekp1(+YY(FbC!?ez`sP7M4^0V^#`r>Py2uppfM2Tr6;3Y0#4U(4w)s%kNHDKgaM961>pF2pf~*t^HIq*e?ekk{-iO8gJ((u69Uo&X+P{}uw2SuHPtvX_H9_hi z%)-}Gl6~^^#ZG=t*N;fcej0QQT$?s{CU9WNLso^2*$mH&r2B>QGDaS&LQ=%w-$>)Tv=k z??n2?_nlQySAE^SC$w*ck>zpn9?uEm4Y9v|e{u)YieP&qDFWfyviB%gKSIKY!N7bd z<*>4v(Vgta#L;mW%8(rr+nsqDIpmW1nn@w)s6Oe#G0ub0#v#v14c@2j1% z_gcoK?&Xk>8~mcqImj)Hkt@|RDKABTPjH6mZb~?ukjHRMQ+@bboSBhhCel1&sYmHi z$qgea7$-O)Dx8-GB8}r3C}Z`y8Ij=(NJ7^zV0?Z7wDx-e0t{&+%^iZf71NE8v~cKz zG@_XhufWq{hktT*=foJfh7OHkHYtzdM=@y&Hf8;1#g?2If*_K+N2MTA68R=9A0lu< zM5%X$Oqf!xn*tV5cT>dTxN>Op0DN;qczAI^@ZBZhUX`Dmc>{=??9UasC3oIf?+f@Y zyu5LCKR;!NyB6S1-Kp*j(%bG~0!C10d`%E;K|^Ol%j!0zx@fc+P~U6igDZLnx^!9Gea^Y+N1vitHkj z-=+RmZBprvhT-A=Ht zr{GG}k}|%4{jsf7466KJCh`Y-)Pz-k_r+?0T7C{pE__gV`)$ ze&PYk444okWhiGCBxM(~|0FneOzq-VB?Z|sUvT+NCl&8%8f5TWu!{GZU9`_`& z#nQL^_+EAU_~c>rpC%MKTA4B&txR}BdpkWb~Jx|c}W2zI3L~yj{Uri)*=(^IdGyN2eJXoSg0#< z1lTo34;K_adN;hXjL8EAs6}`bNK)9n`{R@7(sst^3$vLF;$dYxS+FxD0}g(DC=!rQ z(!eC6i2wuxuu1Wv;lB4IbnG&h(nW4RUc&NL?}g?MtE2aAoOIr}`Tj{V62!&7_`l>n z0^NvxA`7{{4xv$l1SXZ)GIPn016WP^aT*DoCyjnc%iVUtfEVQ^w)&gOsJP3QW?X;M4rTmQ)de=|HyUNF<%l8 zprRqz7%;Ibz$^qg-etce2Gl9|z$l@^EX_i2A2Gla8aMhG8TRzs5gQc$z=)tfTx#(w zuxEeJ*@C%j;kv2K{GI3-%sCAqitK|u10DFl(t@a1$s$qwK>&OuMhLBNKI$fDMC(^D zzM)`cuP{n336~81!DOHzxR1i2@px2|Ch#BVNBI2UQ$_?6?ZrD^jlkuBi``7tmXU}H z{_>E1A|rNQlmdV(fW6*fVG`}VCPQPgotRkU#`bMzBEY2Acp)*$U^h(S$N>X$n>h1f zBpqS)KkF*_AfgJO2@){24^L)xFrOCC+7Es&I)XuXp4h$_F)|5RjLtUiCo$zmUqx&m z7jC5C%j6RGSPASL;^Tp3`AEV~c3#6f02zB6CNMeMd+LCKgtDS_HYdVa5viL1aBJQSi%mWdP3b-~ z!=xP!wI3?D8;5rFA6EKV3Q)>h0oX%UR*lZ9b?=5Tf>97pDE$i<9n zj-oACfD?rv-pfl9v1>$!gRUY2E$s-y_{Ld9M&uI};7iL7mHf`Iz$Rh=%)(=cgOV=< zkVtKBPQ-S;;K;RajleZ;XYy7mQuv^&$=LIms3+F{e9nu+$I|Ur5Kg5a0191Eh`|#k zi!>@%5_W_*v9pl%)Ui*8uIFrCFd1OUsvDbu+}?;F!w3BXl9xgZF#C3P+&Tu7*f$!RI; zhB^C{j8+k)x%XP$CAg|G2+kA& zN1f0jFu&-3vBjgdKp-v`vbrzj_hNO7q9?za)g_M;q+5u2Es{=1_Nw9ufAZHV4eZ|u~?9^@X|dGke3~63vw2-Sw24&dmB10 zcGZL{?B~}|6efwHJOLW*3jho{rV2j5G8@Ha^La#E0nsvjqc+$lcppYf<0B;2m3Z`i zK9iAmM?`_R@6|8@41)qyoM@t(mQA*V{#c2UVezBr3Qs-bqL=|(_69A4x*)=kY$ZTWv(gI# z=|SOef|StZaBm{CLpT*ZFUlEL;!j#i%m4aFkOoN^!A1aP#Lkn7BjH8r3#KS@%5McX z@%Gt_U+lh?>5BlrT6!WfPzW6B0Vw^7>>&+yW&+ROD?0HBt#3j5%)x{(Ez%d-uh)Vi zqd5OFPv}Ln<3V&7B}Y2?YBU?Ogs3NIo6sIYzLyP=Q=d`F=cq1)UiQ@>u9?OJ1aRC2s-HD^U;}zTDfCMqg@& zC-Di^Gh3{`Rv1c)5U%pv{q@80Ci*~w+ZHxtc_gJw9tK2_BYj{!e9e zODgPgvGYQHh{!*~sBF$)H}uYPJJvg|j~Re1kTx~7s88L?QM^3JYH1G)lh|93C#pEk z=m|enLa}>=Loy~@$xs5@`U;%M{8VBRgC%n3sgXh?|rk@D+i0*PAzGQSul1hcQ{QNo_ejz!6lOZrI7pGP~!)VYK* z64P#|Su(sx_dE}j6Rqt8G}WE+z^~z=J&p@T_cCTblsJ46~9k zGG6@n8?uq*gk4|ALOlVzdMcB_?D9+5FnYqb4ea6j5fvqq_KE@}BfhL$x2wgpU5)h( z8l*SwmAPV9XSSfX`Y?~aA;Yez8n=>c@ZnsCN&YJ ziF>^Fqz=q>RtK*(PRU#@zc7w>E-NnjHOk4B&^wZDACz8>* z3~6paXy83rk449E*^zo%SUTPFAT7xWw5+#kT(=Su7atO~vb1CsWX$>;=pj)6$T)c^ zLC?7|? zL(hnAM8gu;*h5|JgXH5k{eme>pyl7u8dppZeF+L-j&2y?(WSxRYG>d z{$keA#P}c+H+!{f?j3a7PI{DRr6FS$Y%&ZN0>S?=(a*%ds*uoobrVG=4G>^%8^0(; z9F~7!5Cw%bQ`j7l6bN!(?i7>&k#7LI0D$*Hb}*4sFy9-nLSeuV$01XICC2)dLLuwO zaPEf|l>l58C~?gEYM~HDIF*%#-<-+B{R}3e9xFM>gEyNv2Ba~M3N)#|yeSr)5E{V%|+8t&>5zGdF6J(vC%#y+uZWSg` z*kd8Rq|lBl1V?ZI@JNT})M6a`CES{T6+nz$&J(s_+!hSQ7i!o1xLD+{yi3Pq`^xhYMX-u*me)dlP8L*3BiXpw<*9KS+bdJZt1D_qXYq<02+l5@pcqC4yGni zqhiNHHy}r7E$Ji1f`{f(sW3c|6+CMcoP+>x>H>(?+6@qRC1X^N`2r-jomWvLmz5g> zz58T#oJQohylpLR$Bm(I@^`blUpLc~+Z>7HeK_WZp;pq_Ny0pvu6FU8|v;GI-X9d$*gfP|QvF$wk7UyY}^9}Wm;xyC(4a1?H}86Pr-XWIriylAkdLl~79W+4h2O0bmPi>=!I zUBhJXW)8ZteM0Q-)w3gvem_y!nIyueAlJZk8Q;35=(;|J;9d1C@n9%>ude|EAwD;4#=JO{*e zJJS;3+Q{ayHp*Bjy&c16F|J}gMV&}0B*dwdK@hFE7B1SX7sbAVmTZtJ}ft3v8R|(D8NV~D_He#(H z;G~u?nQ`4#bD-lPl*`1u^9bq?2i?{l*PK{x5%5Xf&c=g`k_|F*Sz#2VLSw)rdwP*) z_%J)4$tVEpUSlc7`5@cQ01PVECY@=nPrhUc+kA>516KNSP`fuO#EngoHF7j0q?hb_ zTfyH2*{+@mvdA_g?WqEh9K1ie6HjkC(Br{M6#AWP|4VRF&17sDKiM=7g?@@@_O{Xk zp>qi(GB1_4Y}oi@t>j&=8py;Ni}M)f*n?u`XncsM+d}Efl#EYei021Zo%_WCz(V)Q zjGv@FB7xQNU!G*6$TI@Mq;nqa2iXWd&qs_gWzsK_?8Xt+fhW_0>RK9V>mn3V6IyO< z8$@y2;8V1p{+F-N!ALP)ykDE-swc5i|6B#$}*p0U0-n+lJ)l z;*$cVzJwUAYh2lNgqz`9Q3QxXk>vKKK_G)nu&@9o@V{dFw!!tX5L*^3834xt$9YAu zSovz8^Og(!fsG|Q&Xyl@YSWi9&;i+J6%f%%VGNq~q5|#A9>ZX?33O^eN_!Rw3J~Kc zpBc&w7At2xXgYVB;vcHj;!wntd~v)Y$*co3M?`rU0ku_9P+z(W*y9sIdGA|LU zULXA)prLLe->nI27@$K;&*|yIB%GsM(R;b)82$kLA7JCc;V1%y+++ z_ka5#;rcxYNBG5LtG3(El2?Xa=MWd({p~{rf9hR=z=g$AVMYEFwDXgblpcREGr3r* z4nNy91fS|>1&G>FSd4|IHzP*CN)+2GBAQ>!kNdQa+~awZ9N4YbBnNS-JT=ufLDzX< z)Ew;}`(~@4SgGFiIqOB`PbS1hPeD>h6NI;rY7iz|@`0zogWfzTpb;KZGW4tEiVrUU zpCGIN=k#VdimSsHxs6n$(Dlzvk$Evvh6Qd3rX=kt32^_-a(G{#0Fq+mkyX5RECc?Z zMX~!vb|UZRr#9WYfJ(Z8M&%Ry+YqFOtace2)2SBtSnR&Rtq56Am`1U9#t3va?!xN3 zx1;x!?oQ5>;zQxl4}!be$@4Na9IPcNlLSN`BS9R@EEQs9Gga2i-a@P#n}9&j&E7+N zCbjvaaS~g9oGhi>RJQ?i0YtwEOt8&k4m){1N98eOIUxD=ZA&Q&U5J63D+2($?lN&) z)f5VYK@_29UR*F@!&GOl=B0$8Jrk2a>0iN0dJIwIa`4+j5bVjLdf8^v<&;YVrG#TJ zo2`|hT}LEosh{aw2E$gq>Lv*SlFP%``vkayZkj@51le%vBxr#jlNb%d1m+ElDnwGC z!+JY8D}G?RP#!R-4l_|F$ISl$#(Sao6+(p}(;x)#m7-Fp3w;CcAyRG8Uk0>7CDWapOvvu#aQo2n#?<1%SbT z>Hx%*i3mrqeH*G?(arS6d99+E>3xN&&JhPGv2ZCg_L^?(_)x*Jk}wwUhk&T6xUr~d z=D07~Q8kzQO^Ob!mZDj(MYk4ue0R7u2WtIXhDMc%*;yvJB#>ie@p`Y zl6}Y$!{`nguHI!9pu%A7Sd5eLx``+HY+6dX2uN{0_^23Mjkp=*?>RjfRnuw3FJ`@$ zh>f3#jN)A>F^bmDCI(Rrg~eESdUIboF}^o?9`XjNBaTc=EEoHf>R*J2@FJ!Vr3m%~ zUF328VPSZxF{|z}HRfauslTDTZqiKekoAeXo~E_{-lX z4owL5dW|R!^?2B`v?C}7dv;7|B`+fATE$QPerXu%2g6tounstHyBc8 zM5BK|js39td*3gAlRA6Qkq$=bK<8!{ikGP)4$z_R!=5p`a=Ur48{KbSH1?0DahEhV z{O`?+7gKcc*f*Y*;o*fSQT|Ky8(1k?+k#wX+@h>!<(@=Z14ZjhYulkna7h$Yk~KTCfW{DxUg(-Y;CG(>Jp8`K`$3 zXZNhd&JA9)U*3+afxM4sqtg#V&nd*n75H^O2KnBLdj!xRi2ZmWHokz1a+DaB3!=>X zf+pC|k&#KTT5bqGGD#joCrXYYI(CBucdE&^`xm59{KR%d#8fWE!u~JD#SxAPF+du% zq)6x(nd_&vQ=-WryiAKWu4Y6R$L!6g_|2yjapclIHGB%0YWiDIf4}1Q*$1z~C;t;U z|5Ckgj@g5)XZ2m#?MvLq(eR}`pWP-%Dm?C7f=6AEeG+xfMh7l(Jz@b38nh2KW32>&0q8dXZ20dFfcCP@oPamcrbO(x(@@jN7|7mn^8 z{V|Qc5i@D;*Pe-`Rq8{m|4Vy5UDSptO$k1~XprgNbhJ2(7l8zA{cUpi!z9+cF(mZ2 zQie_eXtMF2lKmDq>j7u7cMo>RX(RXJ-QDb%vEdKe@LInc7Ap6>Jf)@V5t-M4#nqBa zxxe?RRvMAi_))U|!jYPma&4M!hy%*~0}@1nvr=<-|3BIEz^6-E%JiuzKhf{jCv{h> z7oYwUCfL#!9)n}W*9!0rwCD@p6X^MGR<+cC(@Qh(m;X*hOO5)p2kBbJawDIxPCxSe z_sd!;FzJ(6@Xyr2>6(wEhOJLs%hL2#K40&r4k>4h+(bBCcri<1y0*MwQQRZqRDTA> z9XZ349!@<&2Dx5DxxtBfJ_~+@tm8^z;4A)+6|PypCgt_*hRm$bD?9xSkr61lZY)2{ z-jAtI#GIFz)r1*Y!+H3_P{V1v5{zB?Td}pc{W4MJ=ozCGb-u`7w|LaW^a+ixq8!q*wd81)+!m5&B`>rAT`sO; zVDc_W&gZ1j=iq=^ZwwroZ$cPwONq`*x!dKyQ9#+VGePAlK}oojeH#2W6|#XxJoq)TH|cpm%ASLMW_v{TIct-t5cJ zZuY%Kt5}nthZE%?xOaCfY0qx(U!b_~{zWW!aRW7VlO0yh%;X28o*P`+f2P>(vwRIi z7$Hv&F30?rb1AUb*12QKnO1v30%*jB6M}=njCl^ps+tXpA`S`uuSz~e&2#0Ja}Hz* zGtaT1Xf|s1r8|Iv0EUVB`2KiX=P0pqVn5n`@cEFPA4%zW}V-`1Of_^}!?auq^6_c0`<+N$Wf zCGeB3*bW6@WYeP21O>5JYKq<$>J|81smN9eFX38KGKmc%i}|K(Q5%oJ*BAS}*~Ic$ z$D5{rg*ojjmr9(TK8K1@tp+K=NJL7`_SBS1{IdUr14grnpn5NFM`ftJn6DuNrA4g2 z)eawHeQhS64`4&MT`2lzAqgBMj?2cj3HoVNh~SIa!85$@Yl)_Jc=VFFU8sFo8sr{_ zbw#y^d-m6g5bQn$vK(h0hdKRv{QWtppNx#QlnJj*uOnQm@z?Z)S?^x@0-Q$&5u(jU z{_?igcq}KH9YY%7d$GX^5$!5cr0-& zwM~_QgyepXK#OpbvxUW41v9f?Rv_EV45S*~2O8EQ3fqB`GH&e^QJ5>DR4JKg!P~3v z2&>=Tf_L7Z_9$#Y_<~w-Af;>gd~&%~k?fmeu~tEDS}9qpIV^<{h>ighA)Oa$74*4R z!7(hQb>N>jd;iW0pdH_wGf+m!o3~eSdpJMgN8fxLA2p`Xv6BuYoGA269PX&&fQNc| z{bpC^E`XX!^==PoD*R8C>JAGFKdm~L?$gb${N$duy7uOI*fqQ|)tZtl0n}MI(Q8vv z=-jeC_10+4Vl=1l%~=%YW>Kn?rZAd6Q@w&ug>(7Nd*Aw8_;77D>{J<@I){0johsY$ zGX86*N!9R5td=q4GLvu;=Pq=^Zgg?1;U6jzI5vmtC_MXV{X0i8yt|73TO;}A(_tU+ ziRAng5*gp>095NFXg45 z%%;d|00NlJww`~hn{{+Ek8ajcn5&~yDdo}4pQ*mp&3E4WRyV_kYxVGxdf3f8j*BH7 zQ@K`#R~`C^SElsR+xm&cpF%cGJcj?b_46I|@9bxIcNPD)`uXP5w>~O(kFcNgb5+-G zO(*c=%~gw4Sk}?caOuv4rAkRhKYynBRzKf)?_2#0Zx8oKI&Tc5s*Km^C@kiUaMhMj zOx5txl%9XHr|O@Z4`jmu(ebu$Xx`RQoTYwJ|I?1%y1R<&w>tWhr)%LCT1GgZZ^Bph zt)qDVq7L%)W+yQ@Wdp6sqc9h?u~IV7$)Bmd)ya3>`&K8zhcRISyymtH&FP52ffEsP zt1$ey-P*1SzLY~U$OUt*6@AP2yHl1Czg4)<7pM>Y5JXAs-qi(cllKtBg;ltU1t|T2-*8rsNJZ5 z2$J1zw5kb{m^stYj6U%>DCJtS@aVa{ns(?tt!K^MDD8Qs2EU?QHRI8=hB$N}s*Ba^ zfaWXJ6i6+nyJ&Q(gI`^ottS2MY+=S_U1Qp1NWbc`+1qZjs9R{`i=|n7Xv}6S_;R<` zghm#TBWbpk!|83H8m2qNkoFV{(a{}`^3Rwio%XNYk5s3nx=r=Jg7Kn;7eK<>txS#B z@n+SgArxR@DZmRFWk?g+Rqu{=scPS8LSTxH=o7Zst@`+OrRt*cBq}>#3pb{!0R&^c zV%5L1H;uzaxjJId7R^=%1h)A0>WCw~NR^mN8+z4brcgk7kMw8(0io*6s`CYL@@Mjp zE#|fA@D(G+1vX*5X4{5H1a0kUfV{m5uql==KHl!4-F`@0pr+Zxp)?JFU`Ve53E(hQ z#i22aLk@#cE(B69^pNRIH!NDv^{Rj2fwQ2?C5j_Odba?=W4zd#1vk{Y9qX-QLTIP3 z!R?sHnNrE8y;yJNzhTxNDz(9FSRjB-oMtK&EFJrTTK)0uS!YRN|2`^UxQDmzJp=P( zx%tDaySF9D@Q@z9W)vphB-(%97HCYe7CwmJK|5z;>qFw?4(fkHH=HG2bC#wx!&`!{ zvZnig)Z+f|`A*CjEIFh+16##E+EaiBcnsuz0Wt>2G^4G!5iHSQss1wcqw^_jvZbD6 zjF(yo!(1jSj5Mm%Fju{Z!IwKp+gH+7~Pm+`C&JoY)qWo8SqFf76TUD zAtYPQ!40kHGqCyT@YFrHsI{>l^vobUTV8|`%!R%x2!&u@-q2v^p>)N zWj1I3(O~(BEUoO$*D|znTTP~wC{2#WEXMdTqcd4%)_WBpSZ;LCBZzlI_#wDp=~j-y z2t)8f$wv?7BC%dXfH_qZA!iT7gwasKev1nMEC3P$F-&?=pp{-KJfv~h$Ot}O)5{8e zY>^9CxpNAt^DC-D2~Z+!`OB^+bLog>Lp$CNw8pV@oyu+8}nMnw}}myS|3)Jn?MSI z#X@rYhCCv)9jf5QcwW5$6Wf6U*M6U*@p4hKS;||ulb?YtjQWq}0ofyQvi!iOH8o?~ z%iyZ@x^n+#div7W`tGoeM1dh$0TA6y3Y)^fS$KWP_Ma(ydH#cvMPBD4cPSkQ=!n6jna95 z#8Y5=r>1O#uWMF@3;?B*oAMX++Gv4!OJcCt97M;k)kz;JA|kJYB*K96=5qcTzf&A6 zVu@7qgCQ_eel*U`=koz4!CY+BF|FobJwFg4f$;d%8l-m+n!qiz8YCl#iRCUYoKdS| zVF`hk`NF<4jfyL<{;wU#Q{J}sD`#@vvM>}%>S$?3tr2Y7zZJEX3pr~E0*FR65RM^s zU3~!LlUg`qP7RkM9%gE(t0Jdha`ep&AdUQFP4Z^oQi7n4CN}<2Sk}qbAqd4rcS|0% z&HJ!X>qFRG!%r|+icS8UJW+K2Hzh}Fh@I1VrrC7Y1ZR!s{#`n!y5e!=jA}Y-Pu3s+ z%jH!_MXosyHglL!>lrlfZ71`dXKVIP*oeIDtw<>1bk%vlF^(j@snsQO2R-)Eg)?5+Vng*zP-AT-sns!iN{>cNmTxzoXUUj?NG=W#3fMqyoHlYMwY&25t zO1oH`ELX4h%kg2p_FcOmM26K4WZe;n2FCfh3nj0cS}c`z?P3kZv|fIbGqwxiX{v`P zOgAt5gkY3?s4u(1%?nlBa+7AXi*MaHSuQ>bQ;%l8Ye~$jLm|ls7_6yd=JQ{Y#=SeMF8FjQ>e+5B@g^JUfAAkd%|j=zygrULO0?a&e})NJo`u* z=Tp^!eFVSp^v$1}48A8M-#nYD;o@Qfy1y^E?=Vo0Pk>vnNd5ESPQnw)1)LiOzGI*SI^APs zoJA+lJhGo&xJjx1%-tcS{?_9#E0NL#t-rFz+^UY9up>R_0;R=*77luKw~9{`QIV?Q z6Dhs$|D`LKr#%pHK`n*;l;7T;@-9wSHSMi2*RcVJ*xUup>7{y_hSh;mxL`_}$HMZP zwR50)-dr?JFM0F6Dz4pJtmwy^&!HbiE|8vs#n0AM9F`%euL6^=P}O5UGIGbwCFJnRSp~DCb1eHQZ7OOUW{oxD(Nru3OX8_+r@2n6j8i6>EU)7#dp74LPfZFGRXj@ zKe(^Bi?cZ$#g$N=i<`kEhI?+f5DsBjPTs5t4{x;~g==`l5CN32>F}hX2GT=wV8pPD zQnR``ikDEcSlGq+Tv!B8`qqHOxr%Qb*P-J0Z>(YLw5}Q(WB_g6w$VzvI9*lMTa&K7 zHR*8qPW4nAYxtiksc7;$s&4JMpWgG2e)ja!{--0a-!g$8yVdedv5FxNn-Qfgq2{!I0)mGRDd-|A@ia1H;7Mr(Wc zM}|D?>ZV7`P9aWL!v`E(S?ogNKfO4u3geZ0t3N}*fu0Hex!sr!@oaCt)e_7uqwe(W zsyFjKXmCwnmc>~WSZk)yFo~?CdXt`iMs$}jck+-*(f(4~tfL$5(t#N@Ii@|UTlw){ zP>YE!-V5G|O_n-p#J-)zkC&z=peJqz;eK_{ZP#bRBw0L`@z%J zv@w(UDl|6vhRX83LjD}Qy zkI<*C27x`&UieIeG}zy_ud4=V5WFc$P&|=E`*qbE5rP-oaU6u_RKVJ`n7P9I@b&G` zhKrffoRM>cI222H6^UNq>K+CvSq4Sy3Ae!>k7RE@8{Ixrt@eoqY-Yr`0KqenU<4*b z_;d0Y(K#Vz#XxH=V}pa>dBIB7L0P5%ctiaWU^5PwYD$oNQrRkZk(Ue%I?jFg1l|em z87w&tFk228cQ|O}#tecjlM3pPox+kSLO`*>KQle;AKGZ$Ow1$)YmiIeM8!i7=g&@0 z6WrN4SF^)aRdQD0a%W=XM9(fu{Z$#fTNyMbUXDYk&BWVr2#s#Q`GZFfV>l44snh>_ zPnOmMC^s9hPR&kM<+Y};iy!jYo@ZK((W)97t;T7MJj;3p%FNY9Gc{U8Xo2hx@bMefaM6_XCwD{AF@i|+eA;+u@1mimEB&4LY@imz#N)>XdtA5*k;viNic189JF zTY(vGe0bjcR?S;#Wu!pFFbdFvAK){ir`jShqTxBd{k1zqTLy{#@wS8>u)!*qz5lY8 z=tn#>#Ex3MJ7tZzS;QVOAxenDlmX@xvWsI<_Msz7$pZiy*IP`>Ba`+;7mK8L7MJIcs}Ge5VO`c-Nm0#qW!1K zc}zfrR{0x)6}9Spk@XQz=AZI07cxNeK+GnH?lj0t8DJM|4qAz~%2?s8%8ggGYuy}{~wo+oT)<-Xrgc>*1~_!yYlujP0c+W5h5 zYCM4sKKLD-har#mf8XH4U792h)Ffst9^2UtVJg2$(Rn!rH%w+7KzQQi4@)qFS&I%= z*ZFq2Hi{sLP^&J(Vsvug0K%1;6d!#IoqZaYD zb!8}!PsdLX?C?WFQpT*OjT=K^e6@UiG%&84tYO~gAi~!ZCgGiCt7@&ZN;#L5ADG*% zDZmw^sP9x^XZIdRa21oU)?csrD>~Lgp4lsR{3ns0xp$7_ClvE#GFRJ=WP&q>5@5J~ z5q9fJ(@r#iPGOO<%}3{r3|3K-1Myx%(iT_%95lJ&&>k+l*cWh%(*Iu?k`QP%>`lNW zGX9HTP?s7C3&f6sJx!F250_JRc7vBVA0I?IMe%PX^c}ouaUwpTY?)ycT$t2RZqlbk z#1k2GwOL#7Aft)Ct5_4mHCPS;-PY5{C^{S>OQ^I!dF02;lHsSlSgI&a7Ql8yixuoNS}v-}!+dt~qc9#*y;2{(XTDi!!s6oEIi$joymuXaf~q)YRG4m5 z5cj!XYFFAAT5sQcz5?8(Tnh)naELQV(rOKd%wlC2#Xfo}E1O$t1-Og?9uE*I_1;kU z^`r>SqEgW@b+7mBZq9V2b|L4)1kY%5$XFEF`()7$j&@2pGxjvHlW$jZz5|q=vtlp> zYUBbJlR)h-%>`U77P*!iyt}Po7zO{nX{9ozhafyDrtVW*<0o^$w2HX{w0WW`!? z6=}i8PAgvZQ-Z6sVpZ551N$bcc1mz!tyFkD1k+VBte=Tg2gIk7xUcyz2AaUAYFC_GiNb_|ov8hX(_P^oS>YUQ>O(QpObn7Z~3( zaEUn0eh0F0c#`6Vs?RHHwJLs+5&L~`8CW_~1OzwCF!KZ#I6JA_tWYFiy~%s?u0!$u zS@dS1RP`q?XW_7VnW}mGE`WI`z|uaSs}4qxp}3qOXJ_4hU)19>|2f;wNG^|zv$g-) z=RzcW^(ORMP^LkY-?Vw$B_yeja4rVf!|$b9Wfy+)JTfBD%%uIA*NRl|Sh#GjN#UYPX*hJSyP> z%8f||dLC@%+R;VebPEcvtjo2Q%gsh6;GLQ}A~rauNkf{wI_L9ljYgkC`v4{DJ}l{d zKF>pFj0IocYB3t%AWa}dgP6YWb12bxuEkRvZVt<|qf zte-u`6O9J6k1lm%oW2APszTG`5dg)%rP4GHrJuuS=PTUKGJ2P3a5LMOB2Wg;KV5b* z5FuucXkpaGo3^vxZ*m2V$s3a_LS(I#lt^Dea3AGB3-BB2sdTXf9Gmyp++(t> zkkRxNBviB2`m34INdRwzHLR7jeukg(nBI2TFNd)?x74ya$sA{Zq#k?zdV*HBYASpX z5W(sg8V!)txHjjVlR)O($R-Aiw+4JV1jw+JV&)^5vFL<7a1y{dX9|zL$^l~w4(FH0 zylphm(QnxfjP2;?WkT>0vH9I|c4oO+Rjfx0#bY!wr@7#38L^?XE6#AhW@#9$xpqA6H{v5Ta zI;@Zz{3%>6d3hLPHVKsIZ~!5)sTK0q{I6V^FH99&Vtr|8iVwh=>e_(8Ii;n6y!qV- z^Vohh&)pcC@FEXj2T%{O7nmnD==QWJOauZ?;r^+@q{IG<1V@;zw1~aO*sd1#@@e={ z8)bsLK`e#57UvVzD}YiqDnWDQ2I$B(SvhUWCt;jx7pr~BOu|^u2%>LM7$+sf0{IG5 zX+?v#l5K|qO)6c2W zxjo_tkq)@zpC(UTcpCA(RG8#SQe@IWh;~Jj#8l{>2rTJ9Cgs>So$~8Vp zn>Pr+Am!2?Dn9)piM{|y0vzrA(`-b-oGLgsldR_l$kGJeC6A0;^@c^I5pb&-;iseh z4=^)hUO#6YX(a-f(_Zzd_oJjs;_yrRo=K}tM!617H5YN+q@9h!#vXn&gB-Yu*(bpl zBeVqh(d01q;Pan0;OY0u{nJ|oB|XlN=k9x1&-l6e2gS+z6Yk9@>!*H0%b@F6tR^BG zoPn#}Kf8D%%fMY_629}wiEpa7{K^3(JcchSz~};W&Z+P7Od{}KQIH%~FSyww=@PmA z?+N^sJK?6|N5UZdK*6uHk<}&prUAFvh!uwSiNiRV*EFdQ82#Nm$VSGqP*Y@&WD2mq z{yP6wkZGqgqZCa}TiYe@k+o!BW5V!J{1hvL+fieQIurYsa=>KR3dHr-iA~Xh6^`W=)pr z>oC!-WugNud`q(!^>Y$$F`hH7j&so($JgjmoV&?CM&ERW_SpZg6A`#dzE)JOR?>C)Bjg=7_34JiOgH=7L<49zZ51Alm$=|VyW1yoUz&e z%i6m@%W;)wqW|7i)m>fh>i6rMs&h`CJ}=o_vX3ku$yntFwrmJ$%QlaTu-i5W8!V?e zHqMdcpdvAeB-^;dBgjZL1tBxQkV}Way-Yv}APF#W z==<$HdfBjM&ARLMT2-}c*RH**>#_I#zyJIH-@{^xL^XRp!!iP{`D}IUsN&^>p}frl zmIjGN@DUiEk`#ioHXme|4}S<9s9GGK={2lG!hHGOyc>4774jQ#op!)?WnJHAoF@cr zE_`|V>~d?~@)=5`60#!+sshx5#l(bP($DT$>5$tUiI&H92#pg$Q!%&+;;b#LI^s64 zkXCJ%AzZ@gkaJ8ISQTHb*m_vZpUZ%V#=RCQsJbD~^lnM}Ozz5SwvCoA&*pGlRwSo7 z*WzYz{LPv$Uc_RGL=|PuX21a-Hzsw2H@^lq9<{AyT{OAN&9RW{wK7gb=9Y7bVj<-2 z9-l3Z;DsVZZ@@oMM>mP~L%!;|sNd?!ro$+ryc09rv$>4JQf)$*vw$}s#B!X9R1R<) z>q3NSi-vQsT#KrT!)%`m&xoMTGjzQSlLV-oFW509=eN9H!_zDq;Vn2H+_>Mu!eXiG=lWW*=cH69kKKGc< zDb@X;Xm26>!udGy1r;UA)F@+|ufTnmZtpRX1_1>|RXlHnsXXxV`k*^G3&x2yoX#W@7|HX~z z(7HxeH}L)A!$ZVI&ouj4*2%3lO&${O+?j5#67(1|MnGUMUB7NjV_peCa?zBMxrW#1 zT*A7u#pV8gWpQ!G786s$`I#!p2D{hh%+#Q{Hq|tTzqvMVqStMDi!t%x?ur%B_61Xo zgmqDK*`(Da&*`lq02`#z9Wz_Z)x2baJ>{^4i64y zx4Pzh#-gp6{$>8(>+#gG>GyA3@+*Yz%M5|rz++7np%B2l?C>T65>=hYN0$}MUgg+n zTY-ja$r$p5su@?D6ezyKQSq8-1arY(38bcPCXurTR^DdF2F>M$+4puEX2ja1Zs)7f!T&rUx zMz!J;sF^We_IzXr#q{#bY=?HvHO$^lL5!ToqhD?|v6^r*7Z-a3)+%-dH?!>Yln1Hw zDa*nrlom)u7pPSx;WS{|9x^lCI`hj=E#dAJGXuU=7%_TsILGh?Ae zFbCVSr`r!xqHNu@`~8Eu**%U(sOE5fHJ`VKH=x&K(H!dmugmySoucD3x?wIw?J66T z=a-uJqy6Uc$|7dt3ywoX#}_YJ2BdTJcW7+Uh{RMm)0bLsmDjXy+^{m8_H;4RX|lMv zT+TW$oa;1sw^_E5Cak}-ku+~*MiL(a!^{p>h4rkl(7zl4SQ9bhRp?EJ#FK^HMlNDd)L?D9u@r%biKbV?L;*S><051rD!nm7Z7^+)xj_53ztYmHu%4?8{aR?E%0GucBAS1DJK7m z*GLj^yta;#mFZ7Xw0Jp`tqy3a7~EIWgytF8ny}(k*WhRv$ejkL)uKhwBrhx=p@V!| zO9Ra`uvb9#W!8f4EC`{;UI_6(6CD)NYagP8bi7~;o?#s-n!zG-7O&G00dKJ5vee-M zEg`n}?uQ8eR2DAZs5FNkL`PBV^vLXg^$ieo>~yq%>3gdGRStzE9-0v>V5;LTL>Bn!W{xYg9&A7qTUnRmKRQx~18w7XV`s13h^O^77LsCgMg5~m5DagbBu zkjzo@@`t91v4B#lm847hu&L4&?lYrix!^Pfov(t6t35Yb;Qo%;y8eAh24ymGrQQPM zJ)_iFU;%UWfX(|9u&UACv1*LR&|F7+$01$st+__v;I8t(<>Hc?7l4p@RSs2`>(e90Gobb7iA7z%&G7tO|#W?zeDu~$QHg1>4k z`DoVlqQ6VEQQ|m6E~z}@0vQN9wZp~Y*rgB`f9L6asJ+6bwA`wvjCLV ze19f{{oHKGcll$8iM7@&1hJiy^`g;zzzShMh@N;cQNdDCG&c(@7*>fzG&eh*#hFXM!db0>^RY}-aX{=$ zHz0b3Ur3`7s?S0CLVy9b2qyA2h_H!t(8OgW;_&w?p{?!!D!X`cV zATsllRv|@uSf<5)K9klA@SfVFz@j&F;j@)Pc2FXWithCrI(PhE0@W4Ya%!+|&4R~P zC^nG`G)I?$#Z^<+A%Q+0G3S$Rv%>jZ13VH~!6Qt!E_aFg z^&K0yhX8$a#m9^oWp+Rr=Px46NH#AInuyumF0fu@M_z|&WZo9q9G_N~^^8xfUD#15 z=*hx-u>uJJvnPQ*ph3O;7V5pFRPABj^pvOfe_5r7!Rs3>TNb*9+;S)o_K?;Vbv-04 zc?|;36?F`1Z20+ks}>V=z%JU7kl}P8URA+dW($QnsP(`T5z>+w75(C8k$(hdtCw$vsTpY1Ti89oSZL0H_naz{kbc{B7F$X zgxf1+NCivTnS{#4AzhD{_Ih`PdWD54mtIF9TA2+Alc@Qe)b%KM^UmW4jJ>>M&IN>e zN=Cl}`C_5k7z&xt%5{7>m2|ct8dduXN>^Hg3K~jfC+7!TI95PS%WKQIq(f_4azmJp zE#@$1gpil>fmb$iVQ+@IcWA>Ir`(!P_bacN&BZLbBLfZUbS_+8GIBjWk9d{DM^Yh+ zXB`QK8zemwg3hvmyNP>@*pnk^Ig81^*5goH=C|Y=Sw*6-nDZqKQXh^4GBRq7T<3vJ z&Cw#19=}471oH0#dUX~h+7jw@p$v0FvFHAn5GC1U~fY7#8>3;!l@ytfH_YOI{xb~>CA_pro zjsYQq{4EM>V;l-Y0jSLRl5 z7iM0Ny0lP>AO=A^x+sBM^l386Bq0L=QYGA!k8(KR91FG-qzL%mite^LMl1d=!OH(` z(8{jL!4$1nrBuhCt!#|`AWd&;rDS@WhIwMAk?HR(J?pg}FV86GWb!}36f5n#jUx5+htw3^6=me!PvFYX7%tsX+E7)1s4SogZtOMAI#*~u zH44(*Hr|uGI^eu7H_`|I1V{LnNXobaME?&$_mIKE<*j4q;e@bb^3hT#7_PVX-Ao6YxdJYT1M{d=Tw%As54 zH#Cw58gt;N3rIT$AgcwCjen`kNAvLTobELWQm^6u_2>@v2=~?99S~@Hj-w9PZ1-wM zek)w1P$u%pd)#Rt+9&2#!EsW<&;5R8L*wJ|kumZ22De|8S=XeH5$2Dlhwp0+06~Q4 zqSZZI_Q8cy7BT7X3xmS4rVlT!m3GDuuz5sDWcqInc++BbMb;hSE*q)+ro^A=TnJTHqyMipbiEB-4M~DPD97m8)b-3&ly1`-jSR+`HnlPa1|ilX z$JmNXCI1E9YAq^hA*>Cts%F5^$!sM#q}z{v zkj9w+@vEt~n+Yy7LJOXc#%~Ly*9%Xr$FM_q1 zf}ApvO26L5pIn|fp>^f0DMXw_V3!Z+&XOG~bj!n)%osPMi$I$5zYREXsR2#t#g1_i z<9`L&e%evzajRFU-CZ@g5#>Tea)+bAJO2CZt0??YpE5!E4d1Zo`U*|Wyl4k>)q^ko z-dFI6_g`G95FR~*=kDJ6(?0#3P5KEkzfphF(-i(#0-Oj4NE*_^dKoi^hyS0i(0Fh9 z1RpcpV2tE9m3f8}gYt(?k9e&Ie|Ud%x%rhYVwQi1hXQ-v{f}34zYkG{nMNO)0OD|B3#4n;oI9+##GD1wENE8|MDs%btM1t*FKEgtlFVG zLl*iGqsMlC?y<%$)N7&%`2dNejpR3v?Gs5OqB#o|Zo~a?LzY5)?>9YE6Z2duzAbc) zbIEZLkaipT4PP1$ovqfjKkKLN`Hf@5b!z{tkx8}hU<2Jv4fI^53$jbKG5FEYgc-ov zpW9^30Q|8$EL9KgvJCXC1asZqb#E z@ueLM*JfnZoXCRXRLkt&J-5!|YiE9x_T{B@$l+T{8%_vASZ0rI6At(#vz_OW)i4p1 zkdIsdusv(#P!?6>;MF{jM9al01I}jw@zLW0MugzJ>1L>OrY&$tN`**BAS>_DVhb;# zwaVc}@lMg{B0@ElPxtUAEkO9Z5K{_~#(oGV!F`nMTg!z!R?e=z)hf7sOXrE|-PpHE z%{FgK(5mWI0=`TFVzU!LFUT)*WuEZ+<@82g_i#HH=DRsr?S`pXhY}c0Y2h0(Fe+Nt zxM7`SB(vqVp^QvlFAt#7f~|dsq57sq_mY9N=F0NGa`Z{pNgu11MbD{cH+xQwz-l9K zzGVkR++8&3GP59DRde{F-AR`@qq)1@nnIW9iY^oLR5yn%vqw-C38 z?G9WnqgUMf`mRjhba->b5XkZ2gHLlMOjDnskI05NEuv1c3Gwy zGogJkP)mNp2Faeot9gg-Jfi1AyPn5Cnog`mcx0!QEcgp6dNzc(0$0$GKxoCyA}b4= z99jB^?L4Bn$Pkx{P-~PPG52f!wf2x{D-S=Bu-XR_1PDp+T4X2%O;}{7QVEkHJD=-9 zk6?T0$gZ;1zvm(07~knqF0w0Fc4WDW!`aBLi$Kg~Xw?)Pe{y+0hPO_GG&rw#Ac5ii~0&u4}=P2btGDIgc3Orr~l2;l`8NWLArm_=?2?3obL z;>l?H%h!LJsKaBDq4mv|d^~!`N%L5;$r+0g!Eg1TACX~X@#>=Pz#AH-hnQ-4pBOP# z*E)Pb$LfDk*EL=9al}V-@&R$!$oP2v4wxyF>NtB(+qC=O?QJvdA;_x7BB$W~AjW{}c$o-*{SUgf9(*PhIqnbO zctk%6rljmxxSfvF(G|zSO?3*q3nwHGc>%dK%Tn6m?Fn^UgQ>l@tzW^Xk-@Jm&Bj;;>S^KC>%zMut z-E8|6*>&$k6OHr(v=g>+=UD<<0X-6l>8XcJXot?MJ{G7 zc^n(B!%tr1Hb6b#MGPLS`v$NW>Eb(~f<_+1f7iD|Y%vB3cKlwO;ni{|U;^LJnVFMI>=Fo4>$z3B-hNA{8#TK_Yjx-T<)k3ECGqD<-E=P+_oxL{T%gv zceOl8bngj2J1wXALSamlnw%!e&B}pq{ebP$LY7>728pK+M0q%N%qzA7}cQ)Xy@qq z`3)J5v*7gJhg~QMKelrtRcljC?)3_VF5YBmL6xFkq2xL>xSP7y=wYvx_J7CG|9Cg3 z%Q^prJxT6Ty^Je$Plpcg-z6tGXN^9a!y{wK`!Cf&d#5W;+dNKj|J4n8?I5?z{r$;&FN~0WDRcy&9jdH7bm7{+f<-i=q{LunnR8Zy7r3H0l zvC*Zz#3>K8m5l(q9UC(d6=|oumC`_qxTA2QR4GJ17tNg! z-^}s||8AEwPwFU#zz(?@?>V&smP*elf@AB>BE*PP?%UL%ia*MxW7d2QUtDUKTPlV4 zaM6uPKKP*|g>Vy&+De^J3=pXM;sQz;)&*hr=VxyCqCHuK z>0K1z1>_X?=Io}0h)mK&=uR*?wH6Vecm>Z31cA*V%0uw%(*ZoPNg!%S7d?lFqUcvl z^ed+AOE8kfMP)HeiH^m?+uLJj#;j4!1zQ+%q}&Yq*s=5o6rSg2HN&5UVZc zQpPXX{Y7~zt#q0c12UIbVbH8$HAz&F5P#XjVv3!**bzmlkOl<`^qvw+?Nw@-2yRA4pF{K9+TU{;YIBrw&b zK{n5ww?aOhIZM;PjshcDDjcruHFl;BNCj z?S65TopTO#D)9Q$Sq#DM;6GTHSKYzGZ1|typue&tXApp{_XbbyR@7GKAG(zv+fij} zO^+%bmho3|Y9G^y%6Pu%8{s51mjizVS??|ad=-aI)0L&kyrL-MEEZM%5=`a+wccv= zDm5gDwLWRZlVreJ&s+V9qriliARdLxLr2lXwuQMVn->WmiIrA3S$D9OThG}e;$Ac& z1<4_j@o#xe;vcXD5mdiiZtWt#EQaT<4ZFn#u}4vONg(#-gNI6|8lkKvr3 zS-LZWjjj2cn?P*F)8XdMRpH zSe;x3xN^W)=0qpiu0O>@774`5fr-mU=Ow8>hrwIv&oP*6%aV`qAkn=QCA!xdeRNe( z!ak-M_rjEQ9geQq=%YOG8j>!*yHebbN0yI zidaq#fd&KB#vyY!UQrD?>3n!NOVPbEma(e9<-gCH0K0Htu z_hz?e#%Hi;4x4>k;C2-Pm7EIiRp=y?eM{{hhWD~)Rtz1P&MYLPnTOQa49DvG?ZJ0$ zJt~n3?L$KB{y| zn8;ufUUEzzCe92H?BNV+Lzc_c%n&x|N+^1zirkrT)J;sqJ~_cuR2@?i$-ie#AomPY zAeB4OEc@6!6HrCh0IC>(K(xUcmv%l=dHKBa@MW9ixx>NqvH69E3whcbh# znW%2XTjwEtaDq7lC*S9Mm>~k3My8X8^TU{>=$;+At~vRv-ZNaF%s61Rk7f1P$o>c~ z(q@t;zj*^7Wn@}|6BTjnMDp88Y_!Vi;Djj(^DZK8e@J!mYm;JbUc?)vOl-`YP-6*z zN-IUNfv6*~0Wnt8AW~-}*>lzIKB20rZy>@#%dj zcBj)&H?hfKak3|B5#{RQBy1-&>`bS{$a`k*m4|S3IF!Ngil8uqNAOLv5j6ca- zk?z{jeFUUaDY9;6_UQdXlff}pVsZYt74GA;zh`GUCAUv{S|_D0z-!0Hd2Er1S;RfH z4Bdk-Ahrrb_qf>3JJ-@Z%c=r54{1C~Dy5T0yr_Nh8+LSZ?BL=LPo;)ivB|F4V|dkU zS!Q%NV+4}kJ#3;o>mEj!Ro4A{x^tL2w$VAzloq#ZfpLNOM zN^}^o{Nd7vqr*1YD(ZEcks=1x!&_@SLS@7UT8;a*6hK~MnRu(wJxn1us#3wX3Bgk~ z3dv#TYk*tuSKVhrTZj^{YCO3oM-l))js1nCgbD>VeLP5o_L@HCD5L=-WNjmZ0?Emi zWG9F9)hzli;FDWxZhLFF92_pl$t9`wRyH_XaucI0B}M?8^A|V-sOTS5ZZWkk$Je zdhauy8`}tgjqelkk)52(cv5omih|Uh1qVi`V~3KJoD`YUWobl+Ke{Yw0}wq9c~W=? z>Lh-}5yT)~^0MI}1I>jrrQ;YD4R9!ToN3K*?C_8RC^Y-ED6V-aA9zSRfPT~M6 zGw^BhD2v_~hg#k}Lx_(Q-0KS#qI z*!)L~&d%R@N65JsP-Rabg*G(dj)ZWqRZ~&QJqvzyWK4f6@63%!Y2%H_B+EUB5cTDBOQ`Sf@tQX&X17myAk%xt$ORw?jxN#}=lEN6a$Bn8 z9Iqo`JIANb?q6a00ru;5{F~FdbKFCbEmr)SHo4cFd4RTm{I!$P+@GB79rce-oz1wy zjJKme-R?a)t^3D4l-YuGZSshaM)-Cd9(nD~sXw%%Q+rYG_%=)h-7nMY4D9@kHzxN$ zQ4-I_9iO(7Q;6LR#Ba1aJ-T}ObRYI6E@EqAKxtTkTSMScy6COe2zcKqNZ`JWS28)J zWu=LD-_pd6O=C7-rMaDPcw@tE0EUXl_|84YR4i+b~^AC1PzS zZ{dt4-Z>vm@Hrl^B!QOCT*_yLI z|6$sHO_8gBQ*7EVVJ--8mt zhYW$V?JvR91%;dy!^7u>Tf>956*B>0roG=Nm^i)9u6;<(q~aU~qsuu@^>d}%U^n^u zua`)!#yK-Sb<3qB*P?(P2E})dGMP@ERy%V_K6_PE0F?+1(G1j~H>3Ho2fmq<4~kgl|$|Zr0A}-TlJhT`F{z zP1(uoo&77a82~mDJ8isC???k8E64-r==Ns|lTQi+Bs>{A*iRzE0|KbjWoHvMlkoI0 ze_R3mC7>%zoKF{R~kTc)zbkwsLd>v4kc?K(^C8$U8S$XrrojQ{~3%@&gH(wZ`zs&QZ z*~5pN&(?5tuIyZ0NMoz$YRbv`GEOTg{&%W4wj>uuZ{B5^hW{NdI#QhDNd9-QK?u$7 zaB`qc@xSBCN?TP&5G%iP!%=z6dhRY+;r@5Bz)EnV^2pyJD?Jz6*Bq5)1sz$6{O_O( zo>Y_CoDyq25XvWovPXkUQjWVvRy0xU+*o_T@pof{_VCJTMd$%h57es~X5u#OyB;1R zz%(J{f!|>ut)LN+)Y{PY)I6pA0)iIbmJ+*ymiU6z zyKOTQ=TuS9M4|KLQIjbu?AJCc+^hw;xSMY-0ThhhUjejI9dDV7j1YZgb$lH6Xt>Me4o4xyOzY14bRIkMMw+eDl)x_5eoT7XoWHN!E{K+~z3q&!=VQm(#PZ%Naio_+O%vn^ z<+l7>IZV{f;Z0|uCJ(dspSyLKxy{tY3YadyCfv1-hd(((kQ`^mzltk612c`s-^X2e z1)?;8;=Jbu&^-*(cGLi<6kP}^y%9G-fJ#y0r)!h;4zchaT>>bH?#tz|JV8%kx$ovm;4SKJkF))K7dJ2!Qg`C5Rq}hbKDA^<7?zu&N~cBG{JN%pB@}gh6idW1WW@S zOXk>ccJE)?bTsn_ch%w3tbc%az9@HRZ>elD9BpK<|G*n`oRX%7-UXP;PEFE=PiuoG zmrZr>P7zaa1ui^nQfRcPextpm4bsA=L|lC$qewJ zGmOQG3`+DSUC}YVnuZ0+CRxRR9dNp0Nj~SZl&b+zC$Ns8UD!I5xqBjLfLAlEL6N!G-Xp zujmGH3?N0*U?JMkJ1Z@6BDSa`P3Ur1Z=o6R3%Q3<|1k`_ciH{NvgzSRu;GGU2vu43 zi4jYU?%87UVQ&4_TR(gyUHu~nuHnK~8vZk4!>2cR@T+pH8IerG>QYR7?IsgbomaI< zN*=9+P+x!PGs`QkFAf#(=z4g{BLz;6=3>FAes4(-IGUw@# zYQ2#5v~Ml!iYc@9`dk0115GIwAXd{sOl1IlH6Bt)BHg0TrU#}pGMf<_nIMSjeVD1i zdydp+-k-+|Og}(t_-?`EiX8(Kr@lJ<{fm-oNWEkNSq9ydN+qf0gr4#yRDw zv8)>5AHrEoMGEe&V{xP&^ku=_P3zj=?y4T#-O8k(^@X9~saE%&ol`%C0QzmuqQg^} z1enHQ+ZYD;3x~C}#(I8W*v?@?=*Pi)!x?sPn98nySn6G@`-dC0Ic?JMH@qW|BjjmMro*l9pyu$4j_Bb*4~ypNAxq)=$m)rSro)2<+698*;y4z8 zpa?=44uZyTPy>YGeQn6>m4`nKD%mH1pkT5665*2smYjmA8U`=IyDP36#i&%Rxp-}HT3xKb`4T6dU2X1G-AVHo+2Ml_ zwZQ>=(0e9)5Ut`%7qWrn)_aR+cAX$w}L9&X@kgP@~(1+v+pbv%>9~EpDsbdHPBG)^riQRN?*(L-5k9K*1 zKv*R^vc^|JU&=OVR4llxrU#edsXn2NCj6--UF&Y$F=0}5h|e1HFEh2-g#dxf;T;gY2a=bHT5_8w$6`_h(8adI{k8FlF#Uom&@-IfJ%4`H zJ3;mqHGCgV*lLIGdz9MT>-b-4*mOcX06QU9RQ4%oFbQn8G1;3GC9(xd@e!aD1_;1c z*9wEH(|CmaOZ3FB0$V6?+E=Cn1FWQ>VTHCmGVtYnB&%&A6a_8$h<0`-H`&3{04~L+ zQ7b?qvBoYyi!3%15)wHR5>l-cTvx9I*Xce~AChK=&N=?kQc3GymE9yCEmh8>&&ocD zBLEAySsai52;rBQ*GoQi!lsvIY8t%+tlL5QA;CFsIldI*@Lj2vp2C3;EA)&w;L za>z@CVy$Cp-5&}f3Q}$nNIAWvIz`H+0n`=+2c_n_f`g*;(FeYS5oN+YX%%Ypk|2|; zNvZ&8KbLD|YR*e45IY0cdHWA1ni@g45EyN}()(e{sEpj@G{)rk!=Q)vEYM7>TCE3K zE@11CyTB`b)ADbdFiJWslUOSa%l{s7?BIL4?cB!r;P-6*dx}N3nZfs3(5b#ft5>4$ zO@f_y_V6u~1u@7Txv4tel!zUUnSeQRZTgps(qP?wP5h;i>lNu=OtJb59!cv$VYW6k za_ip6-F&1_`<@YJJ3nZ(xYw03f;u*G-F#&v8k())FRk*i*8lt3>F875bI}i^Dzd=A z>D}xWsFEJJwL<8Cs^fr&;ZAvlkt?Fo9&ox^i@}yHl2NJ24%0HP(GQn$G}fVADzr&7-S%il|!Y<+fB6e0IIu^d#r(&YA6$ zHvE3R(f$J|f+CYOdvN_p^gRspg;bxh#PTbcDCVTTXD9GHm`WHZ6$vKlXIJNU1+Stb zflYy4Hr+1NF%L&!q_$L%vfG8}NzU1wGustA{GQE274b~IS88y%|I5gDUrvti^PUaA z_XY$o`QGkU{EvgeM{FwI1ZcPj46Zo-3j1};CUoSDXE!+oNP$z(hElt@$tgevB)FX5 z6!cXq{w*AsNN}aMwt>zUT_Ly?qPN?Au>^X7BRB;?(b_B`gUm(5}AikA__*UK&-^#BL-^vs5Z7R9f4$D6;zE!SX z;o>zuC%!FKgftgbz!d;*V)KV!15xG6E&m^)%D+N%t3ZAM?Se7zrF6lrn41s{5Ca_-ym5En!x{z{N~?*|L>o>HBRLJk#{=s{|3lT<0Yx>!);2@>G{rcQ3`y3zz4dl1U|&CHShtbQ&Fg6jgEmK)t2qS?euDJ z0i@9}9@gh2rO#PgUy!kdmBaA>(0K?nC0OMOHY^J#7aj+w>T#>ErqFEC$p!lX((3|1)ZIm20;!zzOIXsXQxsFIEa=TxRV?Yyv>?-=%lFU=GT3l~XOl)RZd8$67OBl$QDh>>^%?Z- zXv#iQ279g-bI>wV@$2?1MBk>|`*&cSD2o$D7=T zSi28ivgIx*?c<)7$U?~;y`Lur9Z=HIzFH>Qhqo<(OQC3=i!GGw(LN~IqkT}aNBbz3 z?!&8^?fLEF09lWZAAmr2U@Fzwg3UzFKHLI{?|^0uxIVhqgvM=jZ$4@>7XQce@Luki z#_-+-91~(ncP}TrxW$e9$Y6h&MF((R)lLV%zdBI*Fdf(w`3|^HwU5x?0jSz>r9#!N zLe*|cfr$?#<8Mg^X396`p=pQcelaxd;Q^s(znmA;!Iv<1>5Zd>IK?%82SuW=JJ@8^Y8#Fnatv{_?F6UcwnMym-?mD5H^5k zteF6+Z0g#Bcjcy4T-)3wVzvcu!horcG+s7Qml(9NM@ZQ zd%IyK@ARbPoo6-f?S_|4-g#Ezj$^twCN%C=OQR7}P#*H)w2&9W<9Pm?!eVdQ7VMi` zS1zB%a0qE_qHb>=-&D7^k8?NsxSDn>p>el%T7$-uA9c;NkMUBr|V8WFyx)t#cL0Jtfc`FN#PRsj;th_$tKKd z--`@g3h$MA%yJkK_{!{2J&#nX^GId{y56HzD<*Kckh<%31W9n6&T-At;&%XchX{fG z-^V?0eM&+0AKxn^#JAAkQf#4Fk1S}`BkNx1 z9+3gPx-jyCZC(e?>B#bMj?k+|7WC?o z1-*J?L9dP!^y)U?mP}ws=ZuFeA=e(yssqF79mYp5WLhaYtnGqUJ%Jk9vCU1(AkbAH zs)^WjXXM%1;^gGAEdhg905~lg%IC{L7Rnx>YOeTMGkye_R~EG)-lrGyY7FCSNX9Rkp4Q81p4{0d z)cY?!wxm^h+3lK8_?pqsIrta1A=g8d_tucTUr5o zOVCc)Eu+xOo>S|B!=?oIrm$3iDvYe@)4ie9*=NVY8a8I|t(Gpg_h~Iz55JYM!hL4@ zTS7^+Pc!NHc@3fiG;RCNC~bS$iPBad{+&h7w}zaaKenRFy(~_q=QXHeQ|&BfCS6Iv z$;NQkih@7a(iH4KV!hCC!G{2ytxxr`uasD$Z-1{qMU>Yb}RwR08v1so6=Rqag9 z1xL-I+|NjGR@=++;9*!n)#QYE_)9Qpz-eN&<=pE0?h=I1nlzM}eR#43eyT)Q)t*gQ z_WAB#QJc*wKS5VNVB>eg8Le7}&RQB?3z65;{k?T0F@H&kjlZ{f!3H3ehOXD&JH46t zW=}!!Sp|@e*9gBg?P=k+>Z|&uO7YR69e(RZPxJROuj=nrJv_ZF9{G>rGb?@(T`1(w z2=XWTkK%YsGcwv492j2%@V_8ROq7Sn0G(a9*UC6KtMe!hOhiwFxbyU0u_#1OJ=|}{ z#ZC2Ldq3Wceh~!9A5B{cU}SiL+7z^)<5+3=lXZx-yeWGQ)>mXbfWRpy>)MK3K@#V$ zqgxQNXLNz=*(pMZdWk$a+LS$`SID0IP1&;+z0*#9UiM5Nd%j$CxLDBf1gQEhNa58p z0@k?TL6iFBR`dc@{}ywkD!K-tUUjg($jf2u=k+CUs_VV`dQK95UO%tUd zG^;{s=vUE^{{N;lwEECZK1yfr*znQKI|ixKlV}<`Lz+G(a}FVM(llgFnieuA*8j6I zC(Q^VI&_SizXJaK%pZAwM>AilQ0!m!CkGX0rgo<@BXyxVEXiRi<39%2p>rn1#-C z-2N&|KJS`;P?qS8om=+)nT?1O;a(r+S)OAJc|(#z*MI&h81PDPj)-pgQVFUvG$}WG z;}J84(%LV<`5Pe&GY%lyycN#?8cV0TGpzp@oTl96JO{9>Hu7`I$cIliS@Hdu-OiyD zIPkYL)`47hFu|0;9NI`h?C8UD*182oEyU!m$A*syr6%1)VLhMff)O~~kW(<+0*?k7 zy{)yB73s?8F=g;wY4BJ+Ke#jNVEe@2&X#2izMB!`c*&1NK*F{UHZ|0=kIiD{n>4rI*vSQe|D#q(IC;r zk1boN_%TefQ!IXL&6HFi6MJsG#aAt|VhGDKX{@1diu0I7qb~Tv?%moTYES!VC-89f zykl=FEAf}57?Y;JbJ7zsJB&sGAYarN2NUlpq%%aOX?%#6*de^DhcxeGkQ;sY`cKx!M>9bbsb$^)-oMJK%7cxL^nV} z$6odW5ueS_Foo=_HiS%(=L5RxrxHCsK)?wzW;CGPyUV4~fU;j5P`=co-OrT~um!t; zp09M+@>gL-dc)<0HcAky>Dy8&p&fq+>J7P-kaD1I-NHX#C(UPwLbH-LP|p7B}>^)63dMfs7OD6M`H9!1d8_OVJ3hu@Z0V#p(*OA zYcG@_?aqAF2w*|rOKWv>&b&BH5*ty`ZZkZ*!i>WyWV_$!=6)73X~+sQ#4mSq9Mye& zCIrmDVdr}nTwD}$5gg)2GA%#gb>*c`VCC~qy)Hc;?P}vm;VHtEboTQO<+C9*Kj4IT zAMxjrpLcL+$ef2g8q0%;+5Bq0jfaUpS`5(v$#TGUmEAFDAj&{m`bN3;R=LfTzI4Oa z3p5kJoK+TXo2Jb!u}Fc5y6nRTFM`iNn_iFP9p4Zs-i1Z=2oHu>0dZazXR95|f4)BL zvxU>PqqsjJcC~SW++o`N2^m+ZAJC>^1+IYc_X@N9)Gg1pXyyaa4?oR_{t{}bMLZK| zP|;d^WJ9PgIG`8rjHTgJUdY^L}nfuzek;IY)J2;S%I( zYVuY%@d$E7KFHWXPHu(Y4{~SR3FJHkg1Oj3j1s+$R0Rp%UM-FhyE}tCdNd^guZ>_L z9Kl2weH6U2!RVepLMXXJ*ddcp692-Eatq4E7Hc!Pz0I)%c~@Srcx+JeV8sfy0lagz z)l$iWGa5#t>`&n3%-K*=enPCjT12c&8mwNwo*JiU8{(PHVw}?OCx^LI?~mCK7tsFW zUFLY~TWZdUPuaK%746!l{-%%t<5O3UM)+iaq-H&c=K23BoIGit=u@ zt2FR^=jRbdf}oaR!M%vF14k2i)~6 zHzE&a0QoGus(HNoA!WOsVosF?c>x!}P0(5vwo(sXW1r((6b%_(2aVyAGP(Y-gVT^G zKF)h?g$C|x*2%E_pH95*F z5%EH(4z=o7HPJG-x?5k?swiDNW)){vJb6{2>Xg}4(os+i#z7qru4f`L_adsm_&8qC z_As2$2qx_AwE zm8Xh@QmjAvty5U2jq02mZq_|(^|@rz-t?^DCJxx!tcHk+=@li^SC))W&lygruj3vx zpDK2qMB(XJF{+WST%M%Y>QYWJa$h4}1SwbfNgACvsRiAX>iuBPstJ-Y7Jd zFf&LKRfz5@O!fCxpe#~aQV_qo1XWhjbjyn8Es&KI<9>cG&D#dT!LeL2UVA+BGiJp**NV;L5NrP7Rvo zQ;~7zT7kNsm>7UC8@b|6a1meMyA{D}wAKP~Ql(M#jWpWB$Tcqc#%r0emiLX!!~j#I zWcrMs;ePnWlg#B->r`?%d1gR!1HUocS(zIvCG72?I3!dO4LJsIY-%W}g@M?GZ!|9Z z#t9tC;jZ4n zTt1Q+oyI&z2U;*J^9!Q@au1$(j0=}b2L$lhG@&_V#_z#<5@xmnP0kE?A8emQZmo|| za|+LuIo{B)fmNND9V|?A_MgkZx5Ju{M=&x%tnp`nSVFQJn6r_+ym(vn5vPzx&kxKM zseqgrk2+O=Ejgghp`^;&Uhiy{<-pozD;9ayyAklWz8|^T+xzZ{{~tUnu~whX`xZKf zb#po6TXOUfF60dj3NgNwyupn>0;|;m)WTWM8#-Di%pJx ztph}ljJG%p72jITWc;aBUYb6CLcJivn-y{RSypzRM~c^4UD{j1mzy&Zz31<~kd-~( zVzcwBX?ZfUh8&zlF1khABk4Bv0zccIjmuaa7Vwnaw+h&?vkv)qIMN7_o1aI;;S!tN2BHuI9OeQyE8Rj#0n+g+pP@^G|Cqu; zO&OS1#3|nqJDMhupuJC%AE5@0o#Q^CgWCwCC*Wn91eG$bqZX7 z))7o~vVi2v8!aXABjtIyHGSKHd7paJ$cH7=Sk#yEhN}zFqtf(M)bHf5IAGF!RJrgRtNb-oJRB-rWd7r;W;aBytkHKU>6g@0u*|*`{Vc9EH@NXMa z!?y5mPf=S6kpT23(!3D5pJp%n^DJl&)&r22sgo`S;&LM{zil?t7y)C z#mJ#Sai+F|Zeg1A?lE-kN|g$g2Iop+?aU`Wg<|!KpTMCQ68Xu&$Epf0rpsM0izU$J znma4gM=&=FQK=`22o)4kj{j~xdh0#wC_}2~#wmjI?rF5)vI0?r;b{l)u+wG|GgRL; zMPDQL;-l?91z88dXuVPiOTE*&3kr|4T&*m$cOhug7JPHqau%gbq{Am@InG>`r<&-i z_w4A@b{Xc-GOY5G7awi37C7ug)0L17cG|GL=%4B6XwJ12%qtB6Uh#rXrtDT6>191u z&nlPfmV)nWKo0>!c=eGs;%38*620TdE6FB~Y1skwHd=5yCT!GcPgutiW+fbFb**mC zO1!lXV(rrW{X|C(y6i${kFzS(Y>sli@=g2yFrO{R* ztJ}g%Y3+nR#m}^p$`Q3bFAcVI$3Ck(uhs?p_LdP~Zs7)7r2rI)vf1)XkW0nsv=#le zPe;#URF_O0wulc`z*NUsnH~`4ME>0+6(Ogq>Wu828G_9y?kxH^4`!CB{E@@JQJ<|h zLPqnYyI-zj)gbHI^h4r;J8qeKQ;rN1u)6O(A}=`EH*?`Oa|l0UQABrdKyN$3R8L*o zT9DNV*ZB~YHV;v0AtHL%I^;}hO`=71E%!W`p?D&-rK>RB9U{ea50!0)XCE&DoV4uJ z(R9v{a(QZ;Zf>EDwTo*toOK(B8SD-RQvw<`qQNs#EcCO7f^`-e%Vm86xB9|csN=uj zYVVg1=_RZ@h<-X!>G+tmE$@T;7=g`mf-Ay_>TL>h0dsb5N0?do{y;Y;)LXY)s0|X= zQEcMyTfJv21rpCvZ(Bg=xC!KGPzi56Ij#a1rQ;KgDdk9Kxl1K_0S&ujjcxO?QU%0~ zI*zD-DrOFrjmdUzvmB6l+2;g&%59q7$vaRTB9u`Pa3K!rk|X!Fa0)o!{m<7WB}6s8 zSg5Royz&?0Dk|>0+qyd8aLvP)vE92W%tZDVIkbNX?AK0Aw8MU zlv6J*NZ-SNY)xK8hzM&|MTof7N6K|d^)3nuzJ*|Sxt=(iG}y@#zvet=nsXB7@6!Z_ zZs*p8MFu0ajKDp<5YR<1Up_&Tk z5usn+lqS&W_A=lE-n3Jn3xkgB$%AUy5qcZ>i9m?pUaFP_kBv4^da&H__+jVVG>cnN zs=BOl+0XSm8*`p1sZrhWd86d>+^p59%RYkZty4#8)$23(R_H60n$yI{j?n8_8Old? zb>5kzeB_}u7KxTVYc?FwC;i<>j-bT&ihA)C! zciYbCuDdzHJNkIVr%HyIud4F$5ngBP# z8@Pb(iz^PVDHG?Uveqs^;AUHzB(wCbSCUtFU`GnX`;}Lc?J{ohQEo?c^P`ruD2t;|!9#NaRiR;t*;EQP$albCO>Z})aem=!$^t&16H(1t@c*n#7JPY$76 zSPcr_;ksBCgQc@guG{H`(ygg{*OiK2hx!;~+j)u~x|%!>kQvj#^|m@DK9Yrb1?%=SsHMD^x7O|3?rIN;&Lw^DfmWVS1RiZryIT6-=}b-@2x% zn6+k@F!ISezIOLrppc*w`0Va&l99HgN$%deux`7p52WO6(S)X5Zc=}{i4^$hx8F)r z0Yusw(BH)uy%sl5HBw$n6u)8cUds`3e(M%K`a}1l;-3I3hq4Kime+jdac)BQAO(l} zfm??HkC;8l(-DmX+SDND;-fCy0OBUCA>g5{QC6b5iT`AJ2E?X*FLloI@kdcy;{toq zX+igbo&CfYNwB6LRev>n3MK~1sR;H&!M*XNpf%ugL5ov9*x-X!YGoYJ(O+FbUZ8aV z7?D<%y|2TZ8t=EtcvW5UTL?R}mOvm2;LNr*x>=m23~e*-3($RI@$K54o5q(L_%MUu zf2)X@RVz3GY}qvL?0<<{<@b_L8Z**xr|wrCgP+~9^KsMUrX(x8IrcnBsq9TK=NMZJcn{_D=7fUP0$*Ezt@SIGyhs4r>sj70vz4wKYNl+AQ5{g z!Gh<*aFyK5!G@G~mRh;>Q=sj%Y-!q3@NbCN&f`Cae{I@osMA&kHBIEK!<0Xqpd_tbKJ86`IK!y_4wzz4ls7-EfVJMh1ku%d4{bubpC#8k8 zjsoaw^9szSGF}yps3wf}y^Sp5v209K_;jLZHAE1C26@eG-ImV^3u5z+ikqq8*XMu& zVD!Ob$rY1GKVG9gfINpFOBSZBlD~nsE#}8?N)QXq?<1(8k(SZ3clD$KW}YEFUs!^8bC&;(2Ktx-{#cBF-vh?S_a z(ZJ3ve((-TzdaoAHzXNe*B=1E1N^8fF(n$Hi08bn&2Ze%a&Z@wu(+Eop=NwO?%LQ! zO^vNvmP{6RO)c({s}C=r0A%l6*)JzW<-4CyRqC!RH7z7czCoh#z zV1eWScLih8MD)s7JR!`Qs90l}#(YhlJuXCWE4PakV4m1$8>+nBuHh5sh$whBZJbn= z1!GcHHyvhl1BYAuV<~WoT?fm+<2f$}g;ULd1J~I!!UO_R6DF`YIJg}4i&Lb5nNeGC zaN15C(S+-BI5)x^aD>Ib$LcuPDh5@W)XK)3tH7W=x@?r=Q{wv;JHcJk56bq3aTp*0-$(^g*D_YPLCZ67O5JQ$ohhwx+bE*hc zEgM=On022hR!$vh8N2QXbz>dA(t<&Cd3*`JLT?j31cPVbwD7PgDbj=7W*GVT}|n# zA`doEEc9K{)( z`WJKIzO81iIrb8dSHew=xV1+N{na@;@`|DR`kB)EC}-^VQYRGb_{*kppyPlI!a$G}ZdJyCsT zk~87d7#%{)=aU)b-XSnT{o%_c*j<3TGDX^bXV({#VzEp%En@}+Szbi4!2U51M2RqI9+kh_jZa?k>c*jvr6UFh${A6 zy7gtH5(_5k*%=k!q^oqWTtRZ};-f3Kq?DW-z<*gf?kKwfQmc+4;I#-JXTuDW3PLY| z=fDp)lo^jVg;{P;bOH<$b0(cto+~;Wu4mK1ASE{3w24`p6E5xYD4YjM&@H3fbMC=I zo9*1cL7x-i?3w0fyVF*rbi_FS{*~e$*6QPxA`6oIUBI9+0SCS6@rh?%Qx32IA==8M zn?9XtHSMcj6+*=lxT=}>CDJMJ}+gk}d*>$dxLVRB#%rI4GE zbO!T_SdTjg-QwlRf#sYPWCs^=QT=RolPt;Wc3L&% zXPMW94=ITAfrjD^?~*rbC1c!`-6mUn`Hi*O=_%5U6G%SvN{Yk7(}Iqx(p%e5Y&;!F zD|3SGDZ?6%r(w5D@yO)4YOE@(0*U*ppBYL={Yr1>9uN5 zSb!&^NKR9IQRy{MLp;N+d|pFCzXMQO2__dQJ?TLmnV4f2A4SrrY$%BL=weVPAmo*f zo+U*Xou{D7RY_a&5x=V$V$f6?L6b#27FW5j*;B+tGx1|MQE5@sQfDOT8={27ZBgug5n8zn2?e>g%x=cCp(n08Tf_bfTd1i$#9%PKA#xHtw07 zaZh>Cr-wye*ag=3&jos4i}Z4(}=c z_{*J?<1yyYKjlSwAEDG2GHd~XB)gv4ODX*emjP&etdOVvG4X;P^h`Krh4IM*&0Iiw ze8%O2-eDo@OrV`68rdn52q$k-v+x3$!_0ixqxe!!g3NX~HGeY;d!oxU4zrEoV5#m7 z)I!wjN@CQ@E&4QDb{~_)xMv7)uct|IkD?des7gu7h(#~-jMv}k>3A+cc&S*NKBT6V zbOAfwZf87)z_7H^Y%ZfzN-Z;iwH^2Pk{0)D9FTL~kMA9pAe#4G7QfI1k`&f_51;fE z+ri4&vr8xsFJsT~KdlKtPyY*-U~lwF*Cu`ayC@i%!GAICRdI$D9Q2mL9x#nOzNg~f zh7KQuCN1Lj`;FbMF| zCi2xP0w@4nEYqC5{Q?#K4Ic~ki}MDXH5oE|F|EY?04hgzbc-VMt-?igx{s& z;fCMUSBs16F=$K8UZ^Sxd@q?O1pwR9?1iOxD9zJA0L;>G{bVDGXeHB_rA00nE_sjK z@Vl};l-AWEjgrc8H@vR&>w6?VRt72UDfUn_?2+81#OW$b(~Xr-yy0-AokBd!?>k%R zzvFBv(Eyl}8_pIVBR?1q1lPp=(hzw+wvs#`rG4rDMeA)TK5*)nX|EU`$Qnp+(pYuj zN*?@;=JYPNcnCsJUPFNP2_j721}N~m4i+p+$Cx2VG0hY!eR|)J0n8jrKwZGX3U8F}yjIbB#l(54WDagZ>EdSatSZ`wAH}YxEvBW9S^y z8i4yx(8}m>3k$G1X`}YJvZD39yD7dINzs0#?SMBtKhMo|)b3Q_r53M^-wWy*5|f@` zUK_u&<-XlZiYX=as^#%}^;hwcJvO*lm%{h*v(uv6HFvx_j(cx^HFz)IJ7>*SiodTI zEP5k=E+08T$Pl*`$N2ci=+a5TuPMgutaDD`QF>%*thB4Hky)5JD8u2?TqeOv*46lUY+Y3vRKbL?7za|RctB3dUXi3Qigfcu;^!BppeaKPb)!$#Ar zdArl=qee>9?`Ue=XS2b;HkB?PtrMHFX0AU?&@}_|p z!(AHI7IgfTk{F(30(>tx*08f!TrNvgWXwS^zSIv|L!;(* z%;IdBn{=0JsX5?$HH9H}Q>P*9>8nGC_8|p{j^0IBr?O(E{XSyU%D0rR*>iu3BKzpe zy^_DuJ`V;4?Ee&9c~oI%l4(n?QPWO9ST@)!yv{`gg{3mO5K=r&0$2{vgs2{ z6X^Z$Y(b-jjcd{SG&rsZ*QY?~3A2-#$Q^78A

zl8(sqwjL%aQ|CcWLQ|ZpxPtmQ zq;B>?syKl68Oq+AP>5@PlOZ;(I}_?{!_kr5pG5kOItSD#kw@x!K;oQI!8^$7+n@7p z9Xusq_wkP!=IrM?;PsxB7H2t^gh&R+PM~Fv^|mYzh7S^-&EA+(xBLU*1ht%#7rZjk zMV$PO=p!Ops@j2|bie1w^Z9DkcE(`VEJzNPjZ(yxYt@(+;$`f~FW!D|K%X8{de$cQ z%gw6;2W}g(_=3|r+qoba!jvJQI!{m`<=%{hIcFT0B2?sFILmDxpaDKUw~VxfKOIR@ z^bd^gMCxB_IEP7bX`WRFes6*xFC_+C7PV>qhpo5jxjoy>Xb-{1KRb)M?Q z@9ao@2a(g%V5b)#xt9}t7%FmSWKNMCkWQVgYkU3!WN0L<)HQl16LAVxwFx`5Hmtll zekX}z*1IwchX8(e%Pri&P`$P5V08ylez`fEvePLL%93_`}e#SeBOqCIoZc zb^*|Y>=cH0DwNf0K0$&O3af|A%Zsmy9@g2hZBN8R3EQlAI2X8E$TE@AylH#na)YKh zmND6nS6Qn@4zNgQkpJ(2vc!6_Br39iuw)S`y?jY7w(-@150}!#bnZlz_%_-eF!-Zr95JH~eNf z;`T`^GTLQZT5vRBgQsLiOh-RSXqZ%gD)hfu9w%2(>3b`Kr^+$1$J=m|FeIN^c4an` zhJ(JpYF8Izb}>q>P0ko21$9n*c!}jXKiH@^BDq=71!0F+KMwbrEn6)wHQdDfeE%wvuvh&lD zL#1+b?B0uy_Lsq=BveKpy8l9qkKKBKumrLhI{_hag5xeEB}saE+b@cAL5p$jZEG+| zV`8|qTk3i=D8L_tO@6pkYWP%tG1St2ij8rJ*7AgCdhot=6@Xj$9?a(b83R-JaHHGz ziD4$Z384suK7eu6FO7(uh5y?fMi1S$-e}yUq|T()ZyGE|L?px4Xa=vjH=S;-w_05o zzLyblZMQw@je71I9!{k`+@MA*GKKY=D530fZVA{QjBKN+h>Y6@b$5h0sU8i0T4z_?gz4>04e!OWeXN>41H-n{x3z6Vdoe82NIdB2VSQ<1BN=5 z^Zo;cnVZKady__Ddna3ag~ES}*4EO@1!VTU$0-5mzW0Y1(jRW!*--rV{(j>R@ad1# zC3*pL^u0l`?i|1d>dfsfUklx*rjN6FqKMcgTi9> zR(deTQwA5y1<=xNEOr?;hxr{1Yw5*qBR$y_lhGjrqZ_Klqa5D9p;_#=+G%uTK6EVw zFlM}8!|{`{RTa2Z#lpUSx^n5W<6D6g-W{b=VH+0YzJ3*6XXfm{6Z=1c?X`6Jb&hX3 zZ2wT77>7IrEvvA7a~20K_^g-q-f|1lzB3F<1Xx|5v>0-n*10j1a(_pRl)ndj3JO?- zynSs}qafcqmr)7`as6v?PBgit`Gs68NYQS23DtU{-GYv@OijjJIZtr+}+(1NApn4Z&-KcbB!Il5Y`BmrDIPFd$AKuAat6ZAZ zj&*i2i=v4w@Dh7FDX&N_clQn;vM~UIMPa7F9$d=BwPB?+xv#sFn-Ck@qv8_m{7Tx< zVXt|8!TXwBo`1fQQPj~DY?uhfU@`on2n61d>{4RlSIY}K(t2ioKl4uvp@4snS&3@qwYXs~#dovWQEpr?oEgU{cdyvHK1Xu0Az&l1t_M4| zS3zo{Rf|5Kflj>NF6ZG=0$#|^O#?CNRb7GQ+D$-f+?b431n7x+T&-OX6B{FBT@Z%R zR?KLH%x;kielBRTu!Zb%(eK>-oI`sah)t8b%p4Y9KhxVCOt%vQ{qm;Fs$3jjeZEBE(zP=!$pcgqOi-1Afx&|Qc5fJz3^r(Qe-K25fo z4R(x}a<3>#4QP0hjW6w7l@xSfoP$1%L_7E-Q-LL6Sjb9_L&Zfp74|lqiuAE@J^R@fbOvd)~ zcgkDoQf;EYo#dx7ssp=S;joZq((vpv!3p-h*H%afcE7Yze>m8^uR+1?^I)E?z_r-@ z5pW-Nas6PQX6eLI8B%^#5#&-jfi&v=<_d{);{I-831La~KXj1OVPu?!HVcPYkoT{a zIXW>EMgJ;<+O8I*h1TI-4LwtyUS*!rg-l=;M?0S0!>2&4xRk*5fk}_Fl?>RQ=?4{5 zYROKoW{R0V{a+6v(z{r=8{C7?ML#_=62Kv!AY7ej5pO%2rapfPHw6_$K@`&9_# z^Yj0i!S-_WWh7qo(;7e!$wK4kY&n+;M65D-Q!zfiQl#GxeZYvk& z(Ca2IiIyhdNmX4G1c0?JP^K9{QX^D5vg(V45EN7{*acfdo}7#g$_hXeOiXgC}~eN(krb5Irf17)Xi4-fP5bGe@?iXLH?*uQU7ccR_uCC57u4MNM z%3g@reV{jrfu3UzE^!{QKz9@+&{?#^%`z*BN?}FS!xsG*TisE}6X9}2FXcjAy%rgw zQuz1|BrDK}AgdNX1baJU=5Rh!3mEya!y#oh+c8(b7eI*x zz(1gs4nBHdB_BIswvrzc=PV1J+PLV1i5yf|fk6o_NXV6GtdPIl&|K6e=s4jK5l#-2AYScd49PK(Yo&VWlF% z%Cd`p6cEiNizO$sqF7~j;NSnzm$xEFCa zGUBy5TxC4JnN1VExY2k~G1LlX54`s>gyZ*_h_g4n&P0q8CgPmSc(2KHPyHbUWIZ6+ zDSUHgqKT8Ak%G4jGoFi%l?=(e_gZ0Qv@FLXJj>jIUz#I1XYA$w1}Bl;ViUck3@LnI zcQJlB(9^w>yh1SN1{kgOguNE4H} z|4NR)Mx2;AE?C3&_TB*{c(Vgpgo5)OOhG1ih-AKoDqwis!|NyU{P2F){mwem9)QTn4SnHk5d zA@ z5e<-Q;FrNA#O60NPD%Fr3caNW?;2a*6qC+i{+P)peF4H@pcBqOC&cduuVwAx{Cx?J zkj>v$HGb6UJIHt;Qde8k{hBPlf2mh8f>QKIMC93SO&Z z!VfO_-@}rSa0p$iLGiVH4xwV?$x21#0$HyM*;_YQgwdq_$atSc=vfD(mww11oWGXq za4=TTHxfK1BI}KEV7;f24*mv%a1Tt-=(U$2h26m7M5P0b3|-8!gLy;~3Ur;TX7CCA zm-OOXDA2_X(2#+JrHe{&Y5{kDI8_v2TF^yw%F=2o<;ND3zb`g5EMz>D0Ek@z^%xmb zt0;|`L>Ez&G)pD3IlIorsBXUZE{;k}`AS#T#t$%0SP?QxDGj?roFNoaLOC@YW1Y0j z^sCBcr=$r7&w@F(Zy^B4X;AYZwxHlSiij(QOh_LBGQOA>n z0hq|#mlgMyxS3_(m+>jc1CaBayMyB9gO2c279>7e4g8tlk! z`LMCaxkV7li-)Z}^h;&OD-TuGE8niFU=O2jmUvW%4?m4*sohm-3LZQe|2*KpQ@p@UL}vNC%#s(rOS$>^k(C4OZ(3F@ zhhQ6b^9YJECp{E`{W-ir)3TTuXLDoLNv+2@oYT^@Jkr!D(o0D}zZnngYoP(+kD<-L z;L92K*uWLwm~#Bn93)lo(?7($@;H5fv~h^*4VpP1NBdd8(*bB@sjHJ*+NtHc=0E zD}{P~CF?y$wj|}*I z-H@7ByAJ7`M<*Z2>k(ioFO=or>D9dMxYh_Fj?}3s^Ahxoj;@uRNjWqAGsu6G9c7Uy zPB<1sCDf#E3(IzSMuI;ToC`E9>6%ZyYb(xgw4y(oB_+)-2>vb-&_|U^M)&{#b)Lab zc1sS<8$dV0xEih1s4}n&ymJLx_SYA-wWIu|IDWL!n0|;?{*ujkLiXT!yjog(q^!=AlC>;3{~1q+(U*r|#aW*cHr!JFZz$(H7hVH57W! z;6Z)SL9Gxd_>Il3UGaz}KmYbarBcHGC|+|+pk7=OCQs<5&-I>B<|0l1)2&-2&co+< z&}{Rxc#p0*j5$x+u-#-2W+JuM%L|!{5WCpnP>vz~Weqq3ibcKba`FPMlicq-6MdLs zcKnFlSX7yz`?!uq_#6|xays-ec@HbdL7E)dG-szSsr16ELV9(MP=ykTw<}3{0XLzl zPB~%vxUSErca`%KB>S`q4B~_c0T$$v-V3YzuVHQXwiJ(N3ds&gX^P251?B4tw#@Sj z1|njfZi2{NRfrfxyf~M6MMeuWR+n`fsbOGiEh z;&3fLdw*{`VP8z?{wsOafmFOB59?Yacbsy}u}D5%)AxcJ1|PTfa!rTfGP=qI%!Gb; zg17C|0va4?%q7T1o0YMYnLE9$TnuO=Wc7>=4jc-%wn&-Uz>cpzN4jS>Tefo(=h-Y` zomM$YeKOH6YjGX4+nLm+ZPml|G>GDgePo&ABB9l}7=k$#(rwMn${6cau-@Ucup*D& zEsTYe$|E);O00{M3^)6&K_eCO<(%`rlg@LM$_(SJ>Ps%S&OO-{C&-ggD#Tp`)BraD zjSSzWx2?tu3tA_Ubl?_T#g1eMO9;cQJQ#&LAwS%~r-L0x#vv01x~N>KIuED92Esk3 zE>)4}l1Un;kJYIa{B#DaNwtcef4MczS{sP1zBql2L-H77fSdBm9UvEnN1PDMyPVIC zD$irHvgIRz%SzP%{L8A(ck|AS_(dTD8eYQzVl`1OWW$EDNXY?kbVyUGtr_@$9Ogxb z?t4XTIhctqK3Z>#k>_%_`iq`~8_>yJ8aLGME>d@I*j9e>%WQVNlAom1%M0r6k#oMI zRh;uUz-V2YU0=5AP!H=|j-F&Qz|*I^9B?}1Lx<<`ZfXEbJP*3vx7(8U6VUX_E6^yA z%KY@Y*-6IT`-f}o;ECQgPLrEnPX|v3$lY|@9#q$p^QyFGKo6*60f{UT$x4?SJz`FA zGJ!aH1smncoL0FV4NlXXeIxdv3Pls!Js*3uM z-JBhZ%9Xfzd%NBaI12Y$-c*y8Pu3R?A

+5VF9p=7Yj$8wAQEm~*g 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±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 m;T2ro%4w}zTuMHw^?gRDu(3pB% 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�@_ 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 z zx_vJIaljBcJBshut~Nb5j4#Eizyp?V@tGKokQF@5<#N421cd(pdx@8wzfh_%Oe)#G z5DPaPAFqQY{0B%_LD1;)*kJwaUCm*UUz4v?VuoKd!Mzq!ulV$0^ZJs;L3CC0;%o&o zGf1wS6hYDV^;S5bulx+F-AF zWO>Zj0(B|kv%iJ-hBkM7P@I}Y^}g(l(Vq%#W>xt_(-5K9Sbpa4jYiW-U>@j20;ayz z0;}OfXec46fU+XpJblnzg8B#*r}so>8HfTk zK#g!;epBnpV9Wl5$pj7MA}`^0@c6$B-dUJv$xWMr)2=!NhBwKY7>fyYibB>-JY z&vfL#`RCg7k-?jk!lOPT9(3V5VK4`tFhmg6f#-EZhY@M_Puq#zi)v@GWyf$hcrIxu3*TY*s$5HsKz=D{{Q_W31I zkc-X5j)D4rZ8Na)qSvf}EILPHLRnBN2LQITC~?(=`q=kYuz+7bVK9=vyOP)DO;ExG zM&VP>Y4fte(hERly9@eV38ak}?2o<)R0z0?o2V~X+n+VO0o}jZToi^t*h_AX60CdJUI~s}pvrhH?@Nrp~)f z4o#nlyMRvEyuNCQxb993x^}NVWa>e8{0|T#Q$B~w-W>k-G+c?bgOso! zA7yI@t*@b&hbgcj3(K(@dXS;nT3sBn>WR9E(~4?SHIbL*2piIiUNfr>Alphl6wJDQ zLSwC^rdBKjhUHVJvZECRZdl&fp65?!sPqs~B1yZ-ndx=#iPtPKm6YEyO=K1~c3XVM z5*tf(OFW&NMTnJn?7%42%e!tB6JRl~;0QT?-+M09vP7Ttcd398NhO^qL2hA@2NnAp zAadlFm$c&Y)unlf-bG@v+Fl%ZI&&}3;PK?-XFLZnYG&}=3HP|TTdgh9gC2&B)EjlZ z*iY_+c=zt-Rk%;XSE;@<{09VQ+9jA2t^5V?YCvs{@}&d0RKFC{bAp^}C;_bqsanzh z(V}V%5}8SqRYt_DED}kwJi3jq4PkIV0XP_DVOALb6+ikqvs1~b(Vq)ri03)>dz>%{ z3T}!U=g7{gB-q&m5f7P{4N^KXEUGuVMlt*9poqw#?%K~=h2RgLCzN2c3Prq*;02r% z9c7s{uLuao=SGiaVp9UhQB|A1=rzL3Ok~8M8xV2xabcJ5D0~?>)LEe zaf_k?ts0iRy!v9$EiS&O1a$(8RD0O-_~4>47sEe~3n=i-RYT&)(@nD?71cX&`{*fD zWHt+wsmKhI0OYG?Vdc3hwrU<5kM1sR6GbLRACaz#;lmNp@OUod@)5n5IP-rz9>4<> zP~TqS6Z{w@;rK_-Y>OlU*W(&U2a9lE40S-{CP%#t&_QK8c{Hi9N&uau`tiM4>8J#9 zWBI6@IC|psSs?%=Mz3tAj(+_0Bpwqi=WGfq;L@=hgZn)9(v-}mk8mcO z$}REgaKb%yDv45{q2Xj|Nmt^}CRE4#je4f$j zd!BwOfhVOCV#u4MGbEo2mXB#vPI9k_1k2X{C6ipO>JtDDT2JA-Ab#mx@Vi{{VE7vQ zVhOhyAHK$M-{Eje3B?Su!$;UahtcUCrA`B#({!Z?RK@FhnzUzV_*&|^tJCD)$#>$~ zg!htoCTX&Ji~@6sm$=azr2Q%B$ICDA<{L?}zp+5do<@TEMip5O1mjU{S2XA?Af5Wz z&l$aGRQfnA$dd}Coi`Rg?H8e!k3_+so^&-hAa3$n${gS(bPq+3P`q^yFUb|kBYtbJPM>= z&SdQ~xcs=xy`%CHr{5#O^QPZZe*VKFwj_NP4;yFl!LxU_lGNLNjfALdz3%OQ44ddZwmPfv1Q~!e`!_ zIyB=TTNALGK`E3eygrjG4+9xgPDz#x4*SY9%DH;Gs*J)zr766Q;l-oM%hBm^lm@bP z`Pi{hI>nEtA5HEYJ!;|;c#YSX4F-y%QfPMi+rJ=rBxR)%Aypbrw?NKcA5S6??ys{& z`>){@W4|S^v4E+cs1HNgBZD>NNO^dQbAu{Za)jEE(&$+qNcN| ze7Kg(jIV)OlE1~J!Sz>%&5R!U92}-PMlXcZ0~J`uX&U9j*1YG6-~F$po(kk2Ft1xt z+36UKs3vjd8XhmcEx@37*H4P}I}>^2Jrv9}e+i$Ls;G*k9!e6ewh-mDHl2^2D+;L5 zl#lC@_YaHtj45G>TAR;@?Yk$tzs?$xeqy2tn!e3{t1>H4H`Z?$eS$)Kb^8M;}d8v=WWxDigtZW3*N948S ztAn+4U0zdPia@5k1pQb2YzUC&vykEB2)+^2|7h#87<5IBRLNM zb1X;|Y!i1ZUV@{(lIDgVnn#TNEgnxNF0VzwcKkQ+ig5NfOD%XPah1#h62-(`E2%i3 zpjrM5r_lqPv>O_7ao9&zmEEApEq*!>f-?k@Bb^32EG9=VwS5i_4 z=IZyoK#)}ts4<@n;W*rtNxv@Qmx-|a_lg$*o6X(buVzEKn7?EToSXMcJ_Ny6h3Uz+ zaF4&ZDhRmZBY0J;lS6;vjyJecB>AQDUMq=VmUve8D>)1^3FEVx&%!f_2G&Is29OkE zb`f?6`CFI0`bJ6robxZJzE{nO;6;~%P?|6iz7$IyNWWZjPFSI!8B?cmAB=V+!4CLn z2T=`8@?!`%@8XR-S!)$z*&sGd)x&B0i~GT#y#`+l#s$$Mt4|7n(Hb(ZM{89zJ;HFv z)Dw8W7r~3Z;h*sa{SdAqjU!9JAZ#CJQ8Gyx_Y2i=zq}UwqyO&Hz;yPMqUf+}oXuSZ zu9jJ{{bR)IbX<8dYW~}5IBbB~%o$epQDMm|c;nh49K%-AnHS2e$gxSxgg_*ij{E0rXXZ<(7OAA3IXu_V=KFwjsLl`)j1uh)bKg8sJIUb$j#*~W=N@N^^3!zs2#J{)omj2+dATTyp=vV8ivYDL16bAa|64xS*_ z-;Gnnz?xc-0Nn%CT6GAa`Lm5?TIR`B(ous`Z%mo@(}b3LE%XkJE-OmYWlsS&NiTXw znwJ%a!K&Fz>m0$*_q42}4sFlvw$K{Xi;M0Q{7qG(lDy@zY*oL%Q4N?>zEy>8T(OmG zZ`jBljPJ`dh-;phBftvd1RIsIHw`&EFLBC36i*KCCoj=cD6Ai`U!Q_PCJdj=nMu1Y+ukEf5s-k|6Fj0czd!?5(K|~7UAX?kkbOgto^^N

LuP4vo)A{wN8c~U{pWUQfip+o^Cki&p*-Y9u83s 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%0ArXr8{;X6GpOcWs3vTHyaa(T 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