diff --git a/.gitignore b/.gitignore index ed71484d..c47f6be8 100644 --- a/.gitignore +++ b/.gitignore @@ -153,6 +153,10 @@ datapath/ checkpoint/ node_modules/ +# We do capture the notebook generated .log files +# as they are meant to be read as reference +!notebook/**/*.log + # Ignore generated lightning logs and config files */lightning_logs/ */config.yaml \ No newline at end of file diff --git a/README.md b/README.md index a3a04abd..e1c3e73a 100644 --- a/README.md +++ b/README.md @@ -31,20 +31,33 @@ The following features are not yet supported (that may exist in [blinks original ## Environment setup The following venv setup using conda, modify for your use case respectively -``` +```bash # ninja-build is required for the new trainer sudo apt-get install ninja-build -# Virtual env, with python 3.11 +# Update conda & its package listings +conda update conda + +# Virtual env, with python 3.10 +# python 3.11 have issues with torch.compile / h100s +# and if you want to use 3.11, you will need to do a nightly build install conda create -n rwkv-infctx python=3.11 pip conda activate rwkv-infctx -# Install pytorch -conda install -y pytorch torchvision torchaudio pytorch-cuda=11.7 -c pytorch -c nvidia +# Install pytorch (>=2.0.1) +conda install -y pytorch==2.0.1 torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia + +# Currently for torch.compile + 3.11 to work, for some paltforms, you will need the nightly build +# if so you may need to try the following instead +# --- +# conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch-nightly -c nvidia + +# Verify your pytorch version +python -c "import torch; print(torch.__version__)" # We use python -m pip, instead of pip directly, as it resolve issues with venv not loading the right pip python -m pip install datasets transformers -python -m pip install lightning==2.0.2 deepspeed==0.9.3 +python -m pip install lightning==2.0.4 deepspeed==0.9.5 python -m pip install ninja numexpr jsonargparse 'jsonargparse[signatures]' python -m pip install lm-dataformat ftfy sentencepiece tokenizers wandb ``` diff --git a/RWKV-v4neo/config-example.yaml b/RWKV-v4neo/config-example.yaml index 064e180c..5e67c7a7 100644 --- a/RWKV-v4neo/config-example.yaml +++ b/RWKV-v4neo/config-example.yaml @@ -2,8 +2,9 @@ seed_everything: true trainer: # Configure the number of GPU, avaliable on your machine + # auto means it will automatically detect and use all GPUs accelerator: gpu - devices: 1 + devices: auto num_nodes: 1 # @@ -24,8 +25,7 @@ trainer: # For more details see: # https://lightning.ai/docs/pytorch/stable/advanced/model_parallel.html#deepspeed-zero-stage-2 # - #!FIXME: currently only deepspeed_stage_1 is supported, due to that deepspeed cannot handle repeated backward hook. - strategy: deepspeed_stage_1 + strategy: deepspeed_stage_2_offload # Floating point precision for the model, because RWKV is built FOR bf16 # you should pretty much never change this setting @@ -128,13 +128,17 @@ trainer: # Number of datasamples to train for each step, a data sample is considered # a "substep" in wandb logs, and a "step" is tracked as "trainer/global_step" # - # This decides the number of datasample, to learn together from, before backproping - # any weight changes at the end of the batch. + # This decides the number of datasample * the number of GPU devices, to learn together from, + # before backproping any weight changes at the end of the batch. # - # Recommended to be a big enough number (like 128/256) where it prevents the training - # loss from flucuating in the process. But not too big of a number where the increased + # `1 trainer/global_step = accumulate_grad_batches * number of GPU devices * number of nodes` + # + # Recommended to be a big enough number (like 128/256) for finetuning where it prevents the + # training loss from flucuating in the process. But not too big of a number where the increased # GPU vRAM usage will cause the training to crash. # + # For foundation model training, a low accumulate_grad_batches like 8/12/16 is recommended. + # # You are also recommended to configure this to a large enough number to fully utilize # your GPU processing time %, and avoid idle time for the GPU between batches accumulate_grad_batches: 256 @@ -191,14 +195,6 @@ model: # without eating up too much vram by keeping the training context length # to a resonable number sutible to the current GPU setup ctx_len: 2048 - # Data samples would be cut down to the respective max ctx_len_cutoffs - # values if its larger then ctx_len. If the data sample is larger then - # the largest len_cutoff, the remaining data will be discarded - ctx_len_cutoffs: [8192, 16384, 32768, 65536] - # Experimental settings, number of tokens to skip in the data sample - # prefix, for the respective cutoff length. Used to speed up the process - ctx_len_warmup_steps: [0, 0, 0, 0] - # Learning rate of the training process lr_init: 1.0e-04 @@ -209,6 +205,50 @@ model: adam_eps: 1.0e-08 weight_decay: 0.01 + # Back Propagation through time, used to work around training of large context length + # beyond what can be supported by the current GPU vram architecture + # + # This is not 1:1 equivalent to the same training process with the full vram + # as the training process is split into multiple segments, part by part. + # with limited learnings from the each segment. + bptt_learning: true + + # Segmented range to performing backprop learning on + # 1 means to apply only for the last segment + # -1 means to apply for all segments + # + # For multi-gpu training, this must be set to 1, due to a known issue + # else an exception would be thrown + bptt_learning_range: -1 + + # Limits the bptt learning only to the "current" chunk + # being learned within the learning range. While this reduces the effectiveness + # of bptt, it also further reduces vram requirements. + # + # This is also known as tbptt (Truncated Back Propagation through time) + bptt_truncated_learning: false + + # Aggressively clear the cuda cache between each data samples. + # This causes a performance penalty, but reduces the vram pressure + # + # This is useful for mitigating the following memory pressure warning + # `1 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance...` + substep_cuda_cache_clear: false + + # Experimental cutoff settings + # --- + # Data samples would be cut down to the respective max ctx_len_cutoffs + # values if its larger then ctx_len. If the data sample is larger then + # the largest len_cutoff, the remaining data will be discarded + # + # Leave it as a blank array to disable the feature + ctx_len_cutoffs: [] + # Experimental settings, number of tokens to skip in the data sample + # prefix, for the respective cutoff length. Used to speed up the process + # + # Leave it as a blank array to disable the feature + ctx_len_warmup_steps: [] + # torch.set_float32_matmul_precision, used to optimize operations with tensor cores # this should be set as null, for non cuda core GPUs torch_set_float32_matmul_precision: 'high' @@ -296,7 +336,7 @@ data: # multi_column_keys: ['instruction', 'input', 'output'] # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' + # multi_column_separator: '\n\n' # If processing prompt/completion jsonl pairs, the prompt is masked by default # use this flag to disable this default behaviour diff --git a/RWKV-v4neo/src/data.py b/RWKV-v4neo/src/data.py index 03eb7e54..eb56e82c 100644 --- a/RWKV-v4neo/src/data.py +++ b/RWKV-v4neo/src/data.py @@ -59,7 +59,7 @@ def prepare_data_static(**kargs): # Tokenized encodings for multi column keys multi_column_enabled = len(multi_column_keys) > 0 multi_column_prefix_encodings = [] - multi_column_seperator_encodings = None + multi_column_separator_encodings = None # Process the multi column settings if multi_column_enabled: @@ -69,9 +69,9 @@ def prepare_data_static(**kargs): # Tokenize the multi column strings for i in range(len(multi_column_keys)): multi_column_prefix_encodings.append(tokenizer(multi_column_prefix[i])) - # Tokenize the multi column seperator + # Tokenize the multi column separator if multi_column_separator is not None and len(multi_column_separator) > 0: - multi_column_seperator_encodings = tokenizer(multi_column_separator) + multi_column_separator_encodings = tokenizer(multi_column_separator) # Maps the dataset record to the tokenized result # handles a wide variety of format according to the data configuration @@ -112,11 +112,11 @@ def map_tokenizer(x): for i in range(len(multi_column_keys)): # And process the column if it has data if multi_column_keys[i] in x and x[multi_column_keys[i]] is not None and len(x[multi_column_keys[i]]) > 0: - # Add the seperator if this is not the first item - if not is_first_item and multi_column_seperator_encodings is not None: - input_ids += multi_column_seperator_encodings['input_ids'] - token_type_ids += multi_column_seperator_encodings['token_type_ids'] - attention_mask += multi_column_seperator_encodings['attention_mask'] + # Add the separator if this is not the first item + if not is_first_item and multi_column_separator_encodings is not None: + input_ids += multi_column_separator_encodings['input_ids'] + token_type_ids += multi_column_separator_encodings['token_type_ids'] + attention_mask += multi_column_separator_encodings['attention_mask'] # Add the prefix input_ids += multi_column_prefix_encodings[i]['input_ids'] diff --git a/RWKV-v4neo/src/model.py b/RWKV-v4neo/src/model.py index b6029652..9c0d6be3 100644 --- a/RWKV-v4neo/src/model.py +++ b/RWKV-v4neo/src/model.py @@ -2,7 +2,7 @@ # The RWKV Language Model - https://github.com/BlinkDL/RWKV-LM ######################################################################################################## -import os, math, sys +import gc, math, os from random import randint from typing import List, Optional @@ -22,15 +22,113 @@ import deepspeed.runtime.lr_schedules import wandb -RWKV_JIT_ON = True +from torch.utils.cpp_extension import load -if RWKV_JIT_ON: - MyModule = torch.jit.ScriptModule - MyFunction = torch.jit.script_method +######################################################################################################## +# JIT / torch compile special handling +######################################################################################################## + +# Currently the features we need for torch compile, is avaliable only in +# 2.1 nightly build (and is expected to be in 2.1 official release) +# +# We only enable torch compile, if we either the user has explicitly +# set it, or we detect that we are running on a 2.1+ build automatically +from packaging import version +def is_torch_version_above(required_version): + torch_version = version.parse(torch.__version__.split('+')[0]) + return torch_version >= version.parse(required_version) +IS_TORCH_2_1 = is_torch_version_above("2.0.9999") + +# Get the JIT / torch compile option flags from the environment +RWKV_JIT_ON = os.getenv("RWKV_JIT_ON", "1").lower() in ("1", "true", "yes") +RWKV_TORCH_COMPILE = os.getenv("RWKV_TORCH_COMPILE", f"{IS_TORCH_2_1}").lower() in ("1", "true", "yes") +RWKV_TORCH_RUN_MODE = None + +# We enable JITMod*/Function when supporting torch.jit +# We use TorchCompile* when supporting torch compile +# based on the current runtime settings +if RWKV_TORCH_COMPILE: + RWKV_TORCH_RUN_MODE = "torch-compile" + + JITModClass = nn.Module + JITModMethod = lambda x: x + JITFunction = lambda x: x + + # PS: i have tried mode="max-autotune", and mode="reduce-overhead", however they crash + # for now (8th July 2023). I may introduce them in the future once they are stable + # + # Additionally, torch.compile has issues with the pytorch.lightning module directly + # --- + + # We generally have 2 major options, either we use torch.compile + # onto the key top level functions (train, val, test, predict, etc) + # and let the compiler handle all the decision making on how to optimize + # + # However this was found to basically just match JIT level of performance exactly + # --- + # TCompileMax = lambda x: x + # TCompileBaseline = lambda x: torch.compile(x, fullgraph=False) + + # Alternatively, we can perform a much more aggressive optimization on critical functions + # that we know are compatible with torch.compile(fullgraph=True) - which provides the highest + # level of optimization possible with torch.compile + # --- + TCompileMax = lambda x: torch.compile(x, fullgraph=True) + TCompileBaseline = lambda x: x + + # --- + # Because torch.compile is expected to change overtime, the two options should + # be tested every now and then, for any performance changes + # + # and we should switch over to the broaded automated approach if its "faster" + # --- + + # Used to wrap functions which are **not** torch.compile compatible + TCompileDisable = torch._dynamo.disable + + # The following are known warnings in the nightly build, that can be safely ignored for stable release + # + # `torch._inductor.utils: [WARNING] DeviceCopy in input program` + # https://discuss.pytorch.org/t/what-can-cause-warning-devicecopy-in-input-program/175566 + +elif RWKV_JIT_ON: + RWKV_TORCH_RUN_MODE = "torch-jit" + JITModClass = torch.jit.ScriptModule + JITModMethod = torch.jit.script_method + JITFunction = torch.jit.script + + TCompileMax = lambda x: x + TCompileBaseline = lambda x: x + TCompileDisable = lambda x: x else: - MyModule = nn.Module - MyFunction = lambda x: x + RWKV_TORCH_RUN_MODE = "torch-native" + JITModClass = nn.Module + JITModMethod = lambda x: x + JITFunction = lambda x: x + + TCompileMax = lambda x: x + TCompileBaseline = lambda x: x + TCompileDisable = lambda x: x +print(f"[RWKV.model] Running RWKV model using '{RWKV_TORCH_RUN_MODE}' with torch '{torch.__version__}'") + +# --- +# Isolating out known operations that **does not work** with torch.compile +# and wrapping them within a torch._dynamo.disable, this is required to get +# the baseline torc.compile to work +# --- + +@TCompileDisable +def deepspeed_checkpoint(*args, **kwargs): + return deepspeed.checkpointing.checkpoint(*args, **kwargs) + +@TCompileDisable +def wkv_op(time_decay, time_first, k, v, wkv_state): + return torch.ops.rwkv.wkv(time_decay, time_first, k, v, wkv_state) + +######################################################################################################## +# RWKV: State Blocks +######################################################################################################## class TimeMixState: @@ -59,6 +157,7 @@ def __init__(self, shift_states, wkv_states): self.wkv_states = wkv_states self.shift_states = shift_states + # @ TCompileMax (no difference) @staticmethod def create(N, B, C, device, dtype): result = BlockStateList.empty(N, B, C, device, dtype) @@ -67,6 +166,7 @@ def create(N, B, C, device, dtype): result.shift_states[:] = 0 return result + # @ TCompileMax (no difference) @staticmethod def empty(N, B, C, device, dtype): wkv_states = torch.empty((N, B, C, 3), @@ -85,15 +185,11 @@ def __setitem__(self, layer: int, state: BlockState): self.wkv_states[layer] = state.time_mix_state.wkv_state self.shift_states[layer, 1] = state.channel_mix_state.shift_state - -from torch.utils.cpp_extension import load - ######################################################################################################## # RWKV: RWKV Time-mix + RWKV Channel-mix ######################################################################################################## - -class RWKV_TimeMix(MyModule): +class RWKV_TimeMix(JITModClass): def __init__(self, layer_id, n_layer, n_embd, dim_att): super().__init__() @@ -132,8 +228,9 @@ def __init__(self, layer_id, n_layer, n_embd, dim_att): self.receptance = nn.Linear(n_embd, dim_att, bias=False) self.output = nn.Linear(dim_att, n_embd, bias=False) - @MyFunction - def forward(self, x, last_state: TimeMixState): + @JITModMethod + @TCompileMax + def _forward_kvsr(self, x, last_state: TimeMixState): # Mix x with the previous timestep to produce xk, xv, xr xx = torch.concat((last_state.shift_state.unsqueeze(1), x[:, :-1]), dim=1) @@ -147,15 +244,26 @@ def forward(self, x, last_state: TimeMixState): sr = torch.sigmoid(r) - y, new_wkv_state = torch.ops.rwkv.wkv(self.time_decay, self.time_first, - k, v, last_state.wkv_state) - return self.output(sr * y), TimeMixState(x[:, -1], new_wkv_state) + return k, v, sr + + @JITModMethod + @TCompileMax + def _forward_out(self, sr, y, x_l, new_wkv_state): + return self.output(sr * y), TimeMixState(x_l, new_wkv_state) + + @JITModMethod + @TCompileBaseline + def forward(self, x, last_state: TimeMixState): + k, v, sr = self._forward_kvsr(x, last_state) + y, new_wkv_state = wkv_op(self.time_decay, self.time_first, + k, v, last_state.wkv_state) + return self._forward_out(sr, y, x[:, -1], new_wkv_state) ######################################################################################################## -class RWKV_ChannelMix(MyModule): +class RWKV_ChannelMix(JITModClass): def __init__(self, layer_id, n_layer, n_embd, dim_ffn): super().__init__() @@ -172,7 +280,8 @@ def __init__(self, layer_id, n_layer, n_embd, dim_ffn): self.receptance = nn.Linear(n_embd, n_embd, bias=False) self.value = nn.Linear(dim_ffn, n_embd, bias=False) - @MyFunction + @JITModMethod + @TCompileMax def forward(self, x, last_state: ChannelMixState): xx = torch.concat((last_state.shift_state.unsqueeze(1), x[:, :-1]), dim=1) @@ -186,10 +295,9 @@ def forward(self, x, last_state: ChannelMixState): ######################################################################################################## -# The RWKV Model with our blocks +# The RWKV Model blocks ######################################################################################################## - class Block(nn.Module): def __init__(self, layer_id, n_layer, n_embd, dim_att, dim_ffn): @@ -225,6 +333,14 @@ class L2Wrap(torch.autograd.Function): @staticmethod def forward(ctx, loss, y, token_amount, currentMask): + # Currently (8th July 2023), save_for_backward, causes an issue with + # pytorch.compile (see: https://github.com/pytorch/pytorch/blob/e600505e3209eaf539e8bc99870ea55236cefbf5/torch/_dynamo/variables/higher_order_ops.py#L735) + # + # Due to L2Wrap being a major hotspot, we should monitor this for future support. + # so that once its resolved, we can include the L2Wrap step in the torch.compile path + # + # See also: + # - checkpointed_step ctx.save_for_backward(y) ctx.token_amount = token_amount ctx.currentMask = currentMask @@ -242,7 +358,17 @@ def backward(ctx, grad_output): gy = gy * ctx.currentMask[:, None][None, :] return (grad_output, gy, None, None) +######################################################################################################## +# Static optimized functions +######################################################################################################## + +# @ TCompileMax (no speed improvement) +# def F_cross_entropy_reduction_none_optimized(logits, targets): +# return F.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1), reduction="none") +######################################################################################################## +# Core RWKV module +######################################################################################################## class RWKV(L.LightningModule): def __init__(self, @@ -262,13 +388,19 @@ def __init__(self, beta2: float = 0.99, adam_eps: float = 1.0e-08, weight_decay: float = 0.01, + bptt_learning: bool = True, + bptt_learning_range: int = -1, + bptt_truncated_learning: bool = False, layerwise_lr: bool = True, dim_att: Optional[int] = None, dim_ffn: Optional[int] = None, load_model: Optional[str] = None, - torch_set_float32_matmul_precision:str = None + torch_set_float32_matmul_precision:str = 'high', + substep_cuda_cache_clear: bool = False, + substep_logging: bool = False ): super().__init__() + self.ctx_len = ctx_len self.ctx_len_cutoffs = ctx_len_cutoffs self.ctx_len_warmup_steps = ctx_len_warmup_steps @@ -285,6 +417,11 @@ def __init__(self, self.beta2 = beta2 self.weight_decay = weight_decay self.adam_eps = adam_eps + self.bptt_learning = bptt_learning + self.bptt_learning_range = bptt_learning_range + self.bptt_truncated_learning = bptt_truncated_learning + self.substep_cuda_cache_clear = substep_cuda_cache_clear + self.substep_logging = substep_logging dim_att = dim_att or n_embd dim_ffn = dim_ffn or n_embd * 4 @@ -315,6 +452,17 @@ def __init__(self, self.load_state_dict(torch.load(load_model, map_location='cpu')) def configure_optimizers(self): + if self.bptt_learning == False: + if self.deepspeed_stage >= 2 or self.deepspeed_offload: + print(f"[WARNING]: it is highly recommended to enable bptt_learning when used to deepspeed 2/3/offloading, otherwise an exception will occur when training with dataset records, larger then the configured context length ({self.ctx_len})") + else: + if self.trainer.num_devices > 1: + if self.bptt_learning_range <= 0: + print("[WARNING]: unlimited bptt_learning_range across multiple GPU's has a performance penalty with datasets of mixed sizes due to its constant need to keep all GPU's in sync (consider using bptt_learning_range=1 instead)") + if self.bptt_learning_range > 1: + # Temporary error, till better sync logic is done for mixed document sizes + # (lazy to support this right now, since i have no idea if anyone has a use for it) + raise NotImplementedError("bptt_learning_range > 1 is not supported yet") if self.layerwise_lr: lr_1x = set() lr_2x = set() @@ -402,7 +550,7 @@ def configure_optimizers(self): 'optimizer': optimizer, 'lr_scheduler': lr_scheduler, } - + else: # Skip the lr_scheduler process if lr_init and lr_final are the same if starting_lr == ending_lr: @@ -469,8 +617,14 @@ def num_step_per_epoch(self) -> int: if max_epochs > 0: return estimated_stepping_batches // max_epochs + # Get the train_dataloader + train_dataloader = self.trainer.train_dataloader + if train_dataloader is None: + train_dataloader = self.trainer.fit_loop._data_source.dataloader() + # Max epoch is not set, use the train_dataloader - dataset_size = len(self.trainer.train_dataloader) + dataset_size = len(train_dataloader) + num_devices = max(1, self.trainer.num_devices) num_steps = dataset_size // (self.trainer.accumulate_grad_batches * num_devices) return num_steps @@ -482,7 +636,16 @@ def deepspeed_offload(self) -> bool: cfg = strategy.config["zero_optimization"] return "offload_optimizer" in cfg or "offload_parameters" in cfg return False + + @property + def deepspeed_stage(self) -> int: + strategy = self.trainer.strategy + if isinstance(strategy, DeepSpeedStrategy): + cfg = strategy.config["zero_optimization"] + return "stage" in cfg + return -1 + @TCompileBaseline def forward(self, idx: torch.Tensor, last_shift_states: torch.Tensor, last_wkv_states: torch.Tensor): B, T = idx.size() @@ -492,11 +655,19 @@ def forward(self, idx: torch.Tensor, last_shift_states: torch.Tensor, new_states = BlockStateList.empty(self.n_layer, B, self.n_embd, x.device, x.dtype) - for i, (block, last_state) in enumerate( - zip(self.blocks, - BlockStateList(last_shift_states, last_wkv_states))): + # Avoid using the zip operation, as torch.compile throws an exception on it + # with `zip not reconized as a valid function` + # --- + # for i, (block, last_state) in enumerate( + # zip(self.blocks, + # BlockStateList(last_shift_states, last_wkv_states))): + # --- + bs_list = BlockStateList(last_shift_states, last_wkv_states) + for i in range(len(self.blocks)): + block = self.blocks[i] + last_state = bs_list[i] if self.grad_cp: - x, new_state = deepspeed.checkpointing.checkpoint( + x, new_state = deepspeed_checkpoint( block, x, last_state) else: x, new_state = block(x, last_state) @@ -508,7 +679,50 @@ def forward(self, idx: torch.Tensor, last_shift_states: torch.Tensor, return x, new_states.shift_states, new_states.wkv_states - def compute_loss(self, batch, batch_idx, do_cutoff: bool): + # + # Custom overwrite of manual_backwards operation, to skip the "manual_backwards" + # safety check, so we can perform manual backward operation step, while using + # the default trainer loop. This is modified from the original code found here: + # https://github.com/Lightning-AI/lightning/blob/37c244f94be365496def82870b22c2faf0ab889e/src/lightning/pytorch/core/module.py#L999 + # + # --- + # + # This allow us to avoid disabling the "automatic_optimization" flag + # + # Which would have been required to do "segmented learning", or "Backpropagation Through Time" + # where we would need to implement manual optimization as per + # https://lightning.ai/docs/pytorch/stable/model/manual_optimization.html + # + # Otherwise an error will be thrown if we call `self.manual_backward` + # + # However this would mean that we would need to do a full reimplementation + # of several features that were handled by the automatic optimization. + # - accumulate_grad_batches + # - gradient_clip_val + # - logging behaviour + # - distributed training co-ordination + # - (And probably other features that I am not aware of) + # + # So this is a hacky work around, to avoid reimplementing all of the above. + # + # From the current code implementatiion, it seem like this is blocked only by + # automatic_optimization flag - and has no adverse side effect otherwise + # https://lightning.ai/docs/pytorch/stable/_modules/lightning/pytorch/core/module.html#LightningModule.manual_backward + # + # If anyone have a better idea, let me know + # (have experimented with, reimplementing the above, but it is not trivial, unfortunately) + # + def manual_backward(self, loss: torch.Tensor, *args, **kwargs): + if self._fabric: + self._fabric.backward(loss, *args, **kwargs) + else: + # self._verify_is_manual_optimization("manual_backward") + self.trainer.strategy.backward(loss, None, *args, **kwargs) + + # + # Main compute_loss function, this is called by the trainer loop + # + def compute_loss(self, batch, batch_idx, is_training_run: bool): seq = batch['input_ids'] assert isinstance(seq, torch.Tensor) and seq.ndim == 2 seq_mask = batch['attention_mask'] @@ -517,10 +731,20 @@ def compute_loss(self, batch, batch_idx, do_cutoff: bool): if seq_mask is None or seq_mask.ndim != 2: seq_mask = torch.ones_like(seq[:, 1:]) - if do_cutoff: + # Perform cutoff for training run + if is_training_run: prev_step = 0 - for step, len_cut in zip(self.ctx_len_warmup_steps, - self.ctx_len_cutoffs): + + # Avoid using the zip operation, as torch.compile throws an exception on it + # with `zip not reconized as a valid function` + # --- + # for step, len_cut in zip(self.ctx_len_warmup_steps, + # self.ctx_len_cutoffs): + # --- + for i in range(min(len(self.ctx_len_warmup_steps), len(self.ctx_len_cutoffs))): + step = self.ctx_len_warmup_steps[i] + len_cut = self.ctx_len_cutoffs[i] + if prev_step <= self.global_step < step and len_cut < seq.shape[ 1] - 1: pos = randint(0, seq.shape[1] - len_cut - 1) @@ -535,38 +759,34 @@ def compute_loss(self, batch, batch_idx, do_cutoff: bool): seq_mask[:, :pos] = 0 break prev_step = step - + + do_bptt_learning = self.bptt_learning and is_training_run idx, targets = seq[:, :-1], seq[:, 1:] B, T = idx.shape C = self.n_embd total_mask_sum = torch.sum(seq_mask) + # If total_mask_sum, we skip, as there is no tokens of value to learn from anyway + if total_mask_sum == 0: + return 0 + def checkpointed_step(idx, targets, mask, prev_loss, last_shift_states, last_wkv_states, prev_steps): logits, new_shift_states, new_wkv_states = self( idx, last_shift_states, last_wkv_states) + loss = F.cross_entropy(logits.view(-1, logits.size(-1)), - targets.view(-1), - reduction="none") + targets.view(-1), + reduction="none") + submask = mask.view(-1)[:loss.shape[0]] submask_sum = torch.sum(submask) + loss = torch.sum(loss * submask) / total_mask_sum - # Special handling of empty mask - # (possible when real_ctx_len is larger then ctx_len, which results into 'chunking') - if submask_sum == 0: - loss = torch.sum(loss * submask) / 1 - loss = L2Wrap.apply(loss, logits, total_mask_sum, submask) - new_steps = prev_steps # + submask_sum - new_loss = prev_loss + loss - else: - # Handling with mask - loss = torch.sum(loss * submask) / submask_sum - loss = L2Wrap.apply(loss, logits, total_mask_sum, submask) - new_steps = prev_steps + submask_sum - new_loss = prev_loss * (prev_steps / new_steps) + loss * ( - 1 - prev_steps / new_steps) - + loss = L2Wrap.apply(loss, logits, total_mask_sum, submask) + new_steps = prev_steps + submask_sum + new_loss = prev_loss + loss return new_loss, new_shift_states, new_wkv_states, new_steps total_loss = torch.tensor( @@ -574,36 +794,179 @@ def checkpointed_step(idx, targets, mask, prev_loss, last_shift_states, steps = 0 states = BlockStateList.create(self.n_layer, B, C, seq.device, self.emb.weight.dtype) - for i in range(math.ceil(T / self.ctx_len)): - if i != math.ceil(T / self.ctx_len) - 1: - total_loss, new_shift_states, new_wkv_states, steps = deepspeed.checkpointing.checkpoint( - checkpointed_step, - idx[:, i * self.ctx_len:(i + 1) * self.ctx_len], - targets[:, i * self.ctx_len:(i + 1) * self.ctx_len], - seq_mask[:, i * self.ctx_len:(i + 1) * self.ctx_len], - total_loss, - states.shift_states, - states.wkv_states, - steps, - ) + segment_count = math.ceil(T / self.ctx_len) + + # + # BPTT learning, we split the sequence into segments + # and perform a backward pass for each segment, on its own. + # + # Allowing us to perform backpropagation across context sizes much larger + # then what is supported by the current GPU memory. + # + # This reduces the need for the checkpointing process, and mitigate + # a known error where multiple backwards pass throws an exception. + # + # While not mathematically equivalent to full context size learning, + # it makes "infctx" size training possible with deepspeed 2/3 + # + # --- + # + # See the following, for more details on "Gradient computed twice" error: + # https://github.com/microsoft/DeepSpeed/issues/988#issuecomment-1549417269 + # + # Other possibly related issues on the topic: + # https://github.com/microsoft/DeepSpeed/pull/677 + # https://github.com/EleutherAI/gpt-neox/issues/62#issuecomment-766366413 + # + if do_bptt_learning: + + gradient_accumulation_steps = max(1, self.trainer.accumulate_grad_batches) + optimizer = self.optimizers() + cur_device = self.device + + # We use the average segment size, instead of ctx length size. + # this helps ensure that the segment cutoffs do not make the last segment too small. + # (eg, the last chunk having only 1 token) + # + # it also helps ensure the segment cutoff points are more varied, across mixed dataset sizes + # and avoid potentially undesired training behaviour at fixed cutoff points + # (this only applies for segmented learning) + segment_size = min(math.ceil(T / segment_count), self.ctx_len) + + # We compute when we start the segmented learning process + if self.bptt_learning_range > 0: + first_learning_segment = segment_count - self.bptt_learning_range; else: - total_loss, new_shift_states, new_wkv_states, steps = checkpointed_step( - idx[:, i * self.ctx_len:(i + 1) * self.ctx_len], - targets[:, i * self.ctx_len:(i + 1) * self.ctx_len], - seq_mask[:, i * self.ctx_len:(i + 1) * self.ctx_len], - total_loss, - states.shift_states, - states.wkv_states, + first_learning_segment = 0; + + # Dummy 2D tenros of shape [1,1], are used to do "dummy checkpoint/forward/backprop" to keep everything in sync + dummy_2d_zero = torch.tensor([[0]], dtype=torch.long, device=cur_device) + + # Get the max segment count across all GPUs, in the current batch, which is used to keep all devices are in sync + # Once a thread has completed all its segments, it will do dummy checkpoint/forward/backprop with one token, + # and stay in sync with the thread that are still working on their segments + # + # This is used to work around an undocumented behaviour for either lightning / deepspeed loss.backward multi-gpu handling + # where the `self.manual_backward()` / `loss.backward()` call will block / freeze / hang when being too "out of sync" + # + # This can be viewed as a form of `fabric.barrier()` which is invoked implicitly by each `self.manual_backward()` call + # except that it isn't exactly a `fabric.barrier()` - because it does not block immediately and instead blocks in + # the next `self.manual_backward()` call if the previous ones are too far out of sync. + # (its confusing, but makes sense for efficency) + # + # Additionally because the "code line position" and params actually matter for the 'barrier' code effect, + # we cant work around this issue by doing dummy `self.manual_backward()` calls, in another if/else branch or loop + # + # Combined, this makes this issue very hard to trace and debug, as it will manifest itself as randomly "freezing" + # when out of sync during `self.manual_backward()` calls. Without the current work around put in place + # + # We only do this, if we are doing bptt learning on more then 1 segment, and gpu count > 1 + # otherwise we just use the segment count as it is + if self.trainer.num_devices > 1 and (self.bptt_learning_range > 1 or self.bptt_learning_range <= 0): + shared_segment_count = self.trainer.getFabric().all_reduce(segment_count, reduce_op="max").item() + else: + shared_segment_count = segment_count + + # Lets go through all the segments (including dummy ones) + for i in range(shared_segment_count): + # Apply state truncation, if truncated learning is enabled + # this limits the backprop process, reduces loss learning rate, + # but save vram across extreamly large backpropagation steps + if self.bptt_truncated_learning: + prv_shift_states = states.shift_states.clone().detach().requires_grad_(False) + prv_wkv_states = states.wkv_states.clone().detach().requires_grad_(False) + else: + prv_shift_states = states.shift_states + prv_wkv_states = states.wkv_states + + # We use a dummy masked token 0, to do additional dummy checkpoint/forward/backprop when needed + # for each additional call after the current "segment_count" max + if i <= segment_count - 1: + cur_idx = idx[:, i * segment_size:(i + 1) * segment_size] + cur_tar = targets[:, i * segment_size:(i + 1) * segment_size] + cur_msk = seq_mask[:, i * segment_size:(i + 1) * segment_size] + else: + cur_idx = dummy_2d_zero + cur_tar = dummy_2d_zero + cur_msk = dummy_2d_zero + + # Segmented learning, applies the forward/pass over each chunk seperately + segment_loss, new_shift_states, new_wkv_states, steps = checkpointed_step( + cur_idx, + cur_tar, + cur_msk, + torch.tensor(0, dtype=self.emb.weight.dtype, device=cur_device).requires_grad_(True), + prv_shift_states, + prv_wkv_states, steps, ) - states = BlockStateList(new_shift_states, new_wkv_states) - gc.collect() - # torch.cuda.empty_cache() + states = BlockStateList(new_shift_states, new_wkv_states) + + # Compute the backward pass for the segment + if i >= first_learning_segment: + # The learning loss, should be normalized against the accumulation steps + # as we are bypassing the pytorch lightning normalization + # https://lightning.ai/docs/pytorch/2.0.4/common/lightning_module.html#backward + learning_loss = segment_loss / gradient_accumulation_steps + + # Perform the backward pass accordingly + if i < shared_segment_count-1: + # Undocumented multiple backward pass support + # https://github.com/Lightning-AI/lightning/blob/678f642808c54e4c490caee4df5d357301c976bb/tests/trainer/optimization/test_manual_optimization.py#L251 + self.manual_backward(learning_loss, optimizer, retain_graph=True) + + # Accumulate without gradient, as we already did the backward pass + total_loss = total_loss + segment_loss.clone().detach().requires_grad_(False) + else: + # This is the last pass, we let the default pytorch lightning handle the backward pass + # and return the segment loss as part of the total loss + total_loss = total_loss + segment_loss + else: + # Even if its not the segments we use for backward pass, we need to accumulate the loss + total_loss = total_loss + segment_loss.clone().detach().requires_grad_(False) + + # GC collect unused memory + gc.collect() + # torch.cuda.empty_cache() + else: + + # Normal operations without BPTT + segment_size = self.ctx_len + for i in range(segment_count): + if i < segment_count-1: + total_loss, new_shift_states, new_wkv_states, steps = deepspeed_checkpoint( + checkpointed_step, + idx[:, i * segment_size:(i + 1) * segment_size], + targets[:, i * segment_size:(i + 1) * segment_size], + seq_mask[:, i * segment_size:(i + 1) * segment_size], + total_loss, + states.shift_states, + states.wkv_states, + steps, + ) + else: + total_loss, new_shift_states, new_wkv_states, steps = checkpointed_step( + idx[:, i * segment_size:(i + 1) * segment_size], + targets[:, i * segment_size:(i + 1) * segment_size], + seq_mask[:, i * segment_size:(i + 1) * segment_size], + total_loss, + states.shift_states, + states.wkv_states, + steps, + ) + + states = BlockStateList(new_shift_states, new_wkv_states) + gc.collect() + # torch.cuda.empty_cache() # Wandb logging only, if an active run exists if wandb.run is not None: + global_rank = self.global_rank + global_device_count = self.trainer.num_devices * self.trainer.num_nodes wandb.log({ - 'substep': batch_idx, + 'substep': batch_idx * global_device_count + global_rank, + 'batchidx': batch_idx, + 'global_rank': global_rank, 'real_ctx_len': T, 'train/loss': total_loss, 'trainer/global_step':self.global_step, @@ -612,11 +975,22 @@ def checkpointed_step(idx, targets, mask, prev_loss, last_shift_states, return total_loss + @TCompileBaseline def training_step(self, batch, batch_idx): total_loss = self.compute_loss(batch, batch_idx, True) + self.log('train/loss', total_loss, prog_bar=True) + # If set - forces the above train/loss log line to always be on a new line + if self.substep_logging: + print("") + + if self.substep_cuda_cache_clear: + gc.collect() + torch.cuda.empty_cache() + return total_loss + @TCompileBaseline def validation_step(self, batch, batch_idx): total_loss = self.compute_loss(batch, batch_idx, False) self.log('validation/loss', total_loss, prog_bar=True, sync_dist=True) diff --git a/notebook/trainer-validation/baseline-setup.ipynb b/notebook/trainer-validation/baseline-setup.ipynb new file mode 100644 index 00000000..c0025e73 --- /dev/null +++ b/notebook/trainer-validation/baseline-setup.ipynb @@ -0,0 +1,386 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# InfCtx trainer baseline setup\n", + "The trainer validation is mostly done using the same settings as raven 1B5 model.\n", + "- Layer count: 24\n", + "- Embed size: 2048\n", + "\n", + "Typically with the following dataset\n", + "- \"teven/enwiki_10k\" dataset, chunked to 1024 token sizes\n", + "\n", + "The following notebook, helps perform the basic download and setup for the \"init model\", and \"test dataset\". Which is used as a reference point for all other validation processes (unless stated otherwise)\n", + "\n", + "Generally you only need to do this once\n", + "\n", + "> This project assumes you have the rwkv-infctx conda env setup, and you are executing in that environment - see the main README.md for the conda env setup steps\n", + ">\n", + "> All training runs (except dryrun) is configured to log to weights and bias, comment out the logger in the config file if you want to avoid this" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "notebookRunGroups": { + "groupValue": "" + } + }, + "source": [ + "## Preparing the init model and test dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--2023-07-09 05:50:16-- https://huggingface.co/picocreator/memory-size-experiment-for-rwkv/resolve/main/Echo-A-1B5-Init.pth\n", + "Resolving huggingface.co (huggingface.co)... 65.8.243.16, 65.8.243.46, 65.8.243.92, ...\n", + "Connecting to huggingface.co (huggingface.co)|65.8.243.16|:443... connected.\n", + "HTTP request sent, awaiting response... 302 Found\n", + "Location: https://cdn-lfs.huggingface.co/repos/cb/ef/cbef09abb2634a3375b28868bffa285226dfeabedec89b28c2fb302221164d66/0ec7214ed16737a6348254e6f96d8cdc04d3b5efbd5f53fe9337607ea42b5b9f?response-content-disposition=attachment%3B+filename*%3DUTF-8%27%27Echo-A-1B5-Init.pth%3B+filename%3D%22Echo-A-1B5-Init.pth%22%3B&Expires=1689141016&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTY4OTE0MTAxNn19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9jYi9lZi9jYmVmMDlhYmIyNjM0YTMzNzViMjg4NjhiZmZhMjg1MjI2ZGZlYWJlZGVjODliMjhjMmZiMzAyMjIxMTY0ZDY2LzBlYzcyMTRlZDE2NzM3YTYzNDgyNTRlNmY5NmQ4Y2RjMDRkM2I1ZWZiZDVmNTNmZTkzMzc2MDdlYTQyYjViOWY%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qIn1dfQ__&Signature=iKAiomdiJ2ozlWxz4oPdqWyGJlQrT3tZ12ygG6zWwpGMfJMeAxomB%7EDh5malirVHqmvjSA-YLV1z0GAogkt91VTcKZCZQoFwYMLSDFFbGccGNKA5n8E6uzvbLe%7ESJNSe4ADiMy3--cyxtSITH2E6WbWFcX1k5nVWAFDAjDUr8wYE0FDH-tu--n-ZpFm1XQwhvVdow7jW0lGa-OJe-4orF2ZWJzE2c1-DGp-q0XvyD2jghe8rjy-FHhOdXHUj2jMK4AqomLUoVETw6skBooWwGuZL5S8Mr3UKKLh1CxqRykI3fyhhkhfM8Rb12XoBO1NADzAC27j0wabcCUppfGOQxg__&Key-Pair-Id=KVTP0A1DKRTAX [following]\n", + "--2023-07-09 05:50:17-- https://cdn-lfs.huggingface.co/repos/cb/ef/cbef09abb2634a3375b28868bffa285226dfeabedec89b28c2fb302221164d66/0ec7214ed16737a6348254e6f96d8cdc04d3b5efbd5f53fe9337607ea42b5b9f?response-content-disposition=attachment%3B+filename*%3DUTF-8%27%27Echo-A-1B5-Init.pth%3B+filename%3D%22Echo-A-1B5-Init.pth%22%3B&Expires=1689141016&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTY4OTE0MTAxNn19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5odWdnaW5nZmFjZS5jby9yZXBvcy9jYi9lZi9jYmVmMDlhYmIyNjM0YTMzNzViMjg4NjhiZmZhMjg1MjI2ZGZlYWJlZGVjODliMjhjMmZiMzAyMjIxMTY0ZDY2LzBlYzcyMTRlZDE2NzM3YTYzNDgyNTRlNmY5NmQ4Y2RjMDRkM2I1ZWZiZDVmNTNmZTkzMzc2MDdlYTQyYjViOWY%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qIn1dfQ__&Signature=iKAiomdiJ2ozlWxz4oPdqWyGJlQrT3tZ12ygG6zWwpGMfJMeAxomB%7EDh5malirVHqmvjSA-YLV1z0GAogkt91VTcKZCZQoFwYMLSDFFbGccGNKA5n8E6uzvbLe%7ESJNSe4ADiMy3--cyxtSITH2E6WbWFcX1k5nVWAFDAjDUr8wYE0FDH-tu--n-ZpFm1XQwhvVdow7jW0lGa-OJe-4orF2ZWJzE2c1-DGp-q0XvyD2jghe8rjy-FHhOdXHUj2jMK4AqomLUoVETw6skBooWwGuZL5S8Mr3UKKLh1CxqRykI3fyhhkhfM8Rb12XoBO1NADzAC27j0wabcCUppfGOQxg__&Key-Pair-Id=KVTP0A1DKRTAX\n", + "Resolving cdn-lfs.huggingface.co (cdn-lfs.huggingface.co)... 18.160.143.2, 18.160.143.124, 18.160.143.47, ...\n", + "Connecting to cdn-lfs.huggingface.co (cdn-lfs.huggingface.co)|18.160.143.2|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 3030345861 (2.8G) [binary/octet-stream]\n", + "Saving to: ‘Echo-A-1B5-Init.pth’\n", + "\n", + "Echo-A-1B5-Init.pth 100%[===================>] 2.82G 124MB/s in 24s \n", + "\n", + "2023-07-09 05:50:41 (122 MB/s) - ‘Echo-A-1B5-Init.pth’ saved [3030345861/3030345861]\n", + "\n", + "-rw-rw-r-- 1 ubuntu ubuntu 2.9G Jun 22 04:41 ../../model/Echo-A-1B5-Init.pth\n" + ] + } + ], + "source": [ + "# First lets setup the various directories, and get the blank init model, these init model was generated\n", + "# using the original RWKV-LM repo (as at this point of writing, this repo cannot init a model)\n", + "# As such I have preinitialized these blank models and uploaded them to HF for convinence\n", + "!mkdir -p ../../model/\n", + "!mkdir -p ../../datapath/\n", + "!mkdir -p ../../checkpoint/\n", + "!rm -rf ../../model/Echo-A-1B5-Init.pth\n", + "!cd ../../model/ && wget https://huggingface.co/picocreator/memory-size-experiment-for-rwkv/resolve/main/Echo-A-1B5-Init.pth\n", + "!ls -alh ../../model/Echo-A-1B5-Init.pth" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading readme: 100%|███████████████████████| 424/424 [00:00<00:00, 287kB/s]\n", + "Downloading and preparing dataset None/None to /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7...\n", + "Downloading data files: 0%| | 0/1 [00:00\n", + " cli_main()\n", + " File \"/home/ubuntu/dev-infctx-torch-compile/RWKV-v4neo/new_train.py\", line 8, in cli_main\n", + " LightningCLI(\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/pytorch/cli.py\", line 350, in __init__\n", + " self.instantiate_classes()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/pytorch/cli.py\", line 499, in instantiate_classes\n", + " self.config_init = self.parser.instantiate_classes(self.config)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/jsonargparse/_deprecated.py\", line 139, in patched_instantiate_classes\n", + " cfg = self._unpatched_instantiate_classes(cfg, **kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/jsonargparse/_core.py\", line 1128, in instantiate_classes\n", + " cfg[subcommand] = subparser.instantiate_classes(cfg[subcommand], instantiate_groups=instantiate_groups)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/jsonargparse/_deprecated.py\", line 139, in patched_instantiate_classes\n", + " cfg = self._unpatched_instantiate_classes(cfg, **kwargs)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/jsonargparse/_core.py\", line 1122, in instantiate_classes\n", + " component.instantiate_class(component, cfg)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/jsonargparse/_signatures.py\", line 558, in group_instantiate_class\n", + " parent[key] = group.group_class(**value)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/dev-infctx-torch-compile/RWKV-v4neo/src/model.py\", line 452, in __init__\n", + " self.load_state_dict(torch.load(load_model, map_location='cpu'))\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/torch/serialization.py\", line 1016, in load\n", + " return _load(opened_zipfile,\n", + " ^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/torch/serialization.py\", line 1424, in _load\n", + " result = unpickler.load()\n", + " ^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/pickle.py\", line 1213, in load\n", + " dispatch[key[0]](self)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/pickle.py\", line 1254, in load_binpersid\n", + " self.append(self.persistent_load(pid))\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/torch/serialization.py\", line 1394, in persistent_load\n", + " typed_storage = load_tensor(dtype, nbytes, key, _maybe_decode_ascii(location))\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/torch/serialization.py\", line 1359, in load_tensor\n", + " storage = zip_file.get_storage_from_record(name, numel, torch.UntypedStorage)._typed_storage()._untyped_storage\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n" + ] + } + ], + "source": [ + "# Validate source code and env is working, by doing a short 2 sample dryrun\n", + "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/config/baseline-dryrun.yaml" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# (Optional) Baseline full context (1024) training\n", + "\n", + "Perform a full 1 epoch training run of training context size = 1024. Ensuring all data samples fit within the allocated training size. And is used as the baseline loss comparision for several experiments" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2023-07-01 20:53:18,310] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", + "Global seed set to 3941088705\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mpicocreator\u001b[0m. Use \u001b[1m`wandb login --relogin`\u001b[0m to force relogin\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Tracking run with wandb version 0.15.4\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Run data is saved locally in \u001b[35m\u001b[1m./wandb/run-20230701_205320-k8flu72z\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Run \u001b[1m`wandb offline`\u001b[0m to turn off syncing.\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Syncing run \u001b[33minfctx-validation-full (train-ctx=1024, data-ctx=1024, bs=12)\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: ⭐️ View project at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: 🚀 View run at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation/runs/k8flu72z\u001b[0m\n", + "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/wkv_1024_bf16/build.ninja...\n", + "Building extension module wkv_1024_bf16...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module wkv_1024_bf16...\n", + "Found cached dataset parquet (/home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 675.41it/s]\n", + "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-3d43d1724bef83d7_*_of_00016.arrow\n", + "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-5033407f38c97f24.arrow\n", + "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-78e7f3a5f1679aa4_*_of_00016.arrow\n", + "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + " rank_zero_warn(\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "[rank: 0] Global seed set to 3941088705\n", + "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/1\n", + "[2023-07-01 20:53:34,204] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "Enabling DeepSpeed BF16.\n", + "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/pytorch/callbacks/model_checkpoint.py:615: UserWarning: Checkpoint directory /home/picocreator/rwkv-proj/infctx-dev/checkpoint/trainer-validaiton/infctx-validation-full exists and is not empty.\n", + " rank_zero_warn(f\"Checkpoint directory {dirpath} exists and is not empty.\")\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", + "\u001b[93m [WARNING] \u001b[0m cpu_adam cuda is missing or is incompatible with installed torch, only cpu ops can be compiled!\n", + "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", + "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/cpu_adam/build.ninja...\n", + "Building extension module cpu_adam...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module cpu_adam...\n", + "Time to load cpu_adam op: 2.312431812286377 seconds\n", + "Loading `train_dataloader` to estimate number of stepping batches.\n", + "Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] \n", + "\n", + " | Name | Type | Params\n", + "--------------------------------------\n", + "0 | emb | Embedding | 102 M \n", + "1 | blocks | ModuleList | 1.3 B \n", + "2 | ln_out | LayerNorm | 4.1 K \n", + "3 | head | Linear | 102 M \n", + "--------------------------------------\n", + "1.5 B Trainable params\n", + "0 Non-trainable params\n", + "1.5 B Total params\n", + "6,060.425 Total estimated model params size (MB)\n", + "Epoch 0: 100%|█| 5318/5318 [51:02<00:00, 1.74it/s, v_num=u72z, train/loss=5.940\n", + "Validation: 0it [00:00, ?it/s]\u001b[A\n", + "Validation: 0%| | 0/54 [00:00 This project assumes you have the rwkv-infctx conda env setup, and you are executing in that environment - see the main README.md for the conda env setup steps\n", ">\n", - "> All training runs (except dryrun) is configured to log to weights and bias, comment out the logger in the config file if you want to avoid this\n", - ">\n", - "> Due to existing \"hang\" issues with multi-gpu with bptt_length > 1, segmented training is limited to 1 gpu" + "> And that you have completed the `baseline-setup.ipynb`" ] }, { @@ -30,126 +28,44 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Preparing the init model and test dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# First lets setup the various directories, and get the blank init model, these init model was generated\n", - "# using the original RWKV-LM repo (as at this point of writing, this repo cannot init a model)\n", - "# As such I have preinitialized these blank models and uploaded them to HF for convinence\n", - "!mkdir -p ../../model/\n", - "!mkdir -p ../../datapath/\n", - "!mkdir -p ../../checkpoint/\n", - "!rm -rf ../../model/Echo-A-1B5-Init.pth\n", - "!cd ../../model/ && wget https://huggingface.co/picocreator/memory-size-experiment-for-rwkv/resolve/main/Echo-A-1B5-Init.pth\n", - "!ls -alh ../../model/Echo-A-1B5-Init.pth" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found cached dataset parquet (/home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", - "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 986.66it/s]\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-3d43d1724bef83d7_*_of_00016.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-5033407f38c97f24.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-78e7f3a5f1679aa4_*_of_00016.arrow\n", - " \r" - ] - } - ], - "source": [ - "# Lets preload the requried dataset\n", - "!cd ../../RWKV-v4neo && python3 preload_dataset.py ../notebook/trainer-validation/infctx-validation-dryrun.yaml" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Trainer Code validation via dryrun\n", + "## Configure and apply your preferred settings\n", "\n", - "The following dryrun, helps check that the existing trainer code changes are valid across 2 * 2 data samples.\n", - "It does not log the run the W&B" + "Adjust your desired deepspeed settings, and gpu device count.\n", + "\n", + "Enable/Disable WANDB here as well ( Enabled by default, as we need the loss curve for this experiment )\n", + "\n", + "( note you will need to rerun this cell, if you restart your env )" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[2023-07-02 17:14:33,790] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", - "Global seed set to 3941088705\n", - "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", - "Detected CUDA files, patching ldflags\n", - "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/wkv_128_bf16/build.ninja...\n", - "Building extension module wkv_128_bf16...\n", - "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", - "ninja: no work to do.\n", - "Loading extension module wkv_128_bf16...\n", - "Preloading dataset in the current thread\n", - "Found cached dataset parquet (/home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", - "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 723.90it/s]\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-e4cc6a1335c36775_*_of_00016.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-37a2fa7498f01de6.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-120b4276954261d5_*_of_00016.arrow\n", - "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", - " rank_zero_warn(\n", - "GPU available: True (cuda), used: True\n", - "TPU available: False, using: 0 TPU cores\n", - "IPU available: False, using: 0 IPUs\n", - "HPU available: False, using: 0 HPUs\n", - "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/pytorch/trainer/connectors/logger_connector/logger_connector.py:67: UserWarning: Starting from v1.9.0, `tensorboardX` has been removed as a dependency of the `lightning.pytorch` package, due to potential conflicts with other packages in the ML ecosystem. For this reason, `logger=True` will use `CSVLogger` as the default logger, unless the `tensorboard` or `tensorboardX` packages are found. Please `pip install lightning[extra]` or one of them to enable TensorBoard support by default\n", - " warning_cache.warn(\n", - "[rank: 0] Global seed set to 3941088705\n", - "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/1\n", - "[2023-07-02 17:14:45,934] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", - "Enabling DeepSpeed BF16.\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\u001b[93m [WARNING] \u001b[0m cpu_adam cuda is missing or is incompatible with installed torch, only cpu ops can be compiled!\n", - "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", - "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/cpu_adam/build.ninja...\n", - "Building extension module cpu_adam...\n", - "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", - "ninja: no work to do.\n", - "Loading extension module cpu_adam...\n", - "Time to load cpu_adam op: 2.321737766265869 seconds\n", - "Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] \n", - "\n", - " | Name | Type | Params\n", - "--------------------------------------\n", - "0 | emb | Embedding | 102 M \n", - "1 | blocks | ModuleList | 1.3 B \n", - "2 | ln_out | LayerNorm | 4.1 K \n", - "3 | head | Linear | 102 M \n", - "--------------------------------------\n", - "1.5 B Trainable params\n", - "0 Non-trainable params\n", - "1.5 B Total params\n", - "6,060.425 Total estimated model params size (MB)\n", - "Epoch 0: 0%| | 4/5318 [00:21<7:54:47, 5.36s/it, v_num=1, train/loss=9.810]`Trainer.fit` stopped: `max_steps=2` reached.\n", - "Epoch 0: 0%| | 4/5318 [00:21<7:54:48, 5.36s/it, v_num=1, train/loss=9.810]\n" + "DEEPSPEED_STRAT: deepspeed_stage_2_offload\n", + "ENABLE_WANDB: True\n", + "GPU_DEVICES: auto\n" ] } ], "source": [ - "# Validate source code and env is working, by doing a short 2 sample dryrun\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-dryrun.yaml" + "DEEPSPEED_STRAT=\"deepspeed_stage_2_offload\"\n", + "GPU_DEVICES=\"auto\"\n", + "ENABLE_WANDB=True\n", + "WANDB_PREFIX=\"infctx-bptt-validation\"\n", + "\n", + "print(\"DEEPSPEED_STRAT:\", DEEPSPEED_STRAT)\n", + "print(\"ENABLE_WANDB:\", ENABLE_WANDB)\n", + "print(\"GPU_DEVICES:\", GPU_DEVICES)\n", + "\n", + "if ENABLE_WANDB:\n", + " WANDB_MODE=\"online\"\n", + "else:\n", + " WANDB_MODE=\"disabled\"" ] }, { @@ -157,62 +73,65 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Baseline full context (1024) training\n", + "# (optional) Baseline full context (1024) training\n", + "\n", + "(you can skip this, and use the optional baseline found in `baseline-setup.ipynb`)\n", "\n", "Perform a full 1 epoch training run of training context size = 1024. Ensuring all data samples fit within the allocated training size." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[2023-07-01 20:53:18,310] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", + "[2023-07-08 09:06:42,637] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", + "[RWKV.model] Running RWKV model via the following optimization mode : torch-compile\n", "Global seed set to 3941088705\n", "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mpicocreator\u001b[0m. Use \u001b[1m`wandb login --relogin`\u001b[0m to force relogin\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: Tracking run with wandb version 0.15.4\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: Run data is saved locally in \u001b[35m\u001b[1m./wandb/run-20230701_205320-k8flu72z\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Tracking run with wandb version 0.15.5\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Run data is saved locally in \u001b[35m\u001b[1m./wandb/run-20230708_090644-3bz2cq44\u001b[0m\n", "\u001b[34m\u001b[1mwandb\u001b[0m: Run \u001b[1m`wandb offline`\u001b[0m to turn off syncing.\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: Syncing run \u001b[33minfctx-validation-full (train-ctx=1024, data-ctx=1024, bs=12)\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Syncing run \u001b[33minfctx-bptt-validation (full, train-ctx=1024, data-ctx=1024)\u001b[0m\n", "\u001b[34m\u001b[1mwandb\u001b[0m: ⭐️ View project at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation\u001b[0m\n", - "\u001b[34m\u001b[1mwandb\u001b[0m: 🚀 View run at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation/runs/k8flu72z\u001b[0m\n", - "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: 🚀 View run at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation/runs/3bz2cq44\u001b[0m\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", "Detected CUDA files, patching ldflags\n", - "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/wkv_1024_bf16/build.ninja...\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/wkv_1024_bf16/build.ninja...\n", "Building extension module wkv_1024_bf16...\n", "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", "ninja: no work to do.\n", "Loading extension module wkv_1024_bf16...\n", - "Found cached dataset parquet (/home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", - "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 675.41it/s]\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-3d43d1724bef83d7_*_of_00016.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-5033407f38c97f24.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-78e7f3a5f1679aa4_*_of_00016.arrow\n", - "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + "/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", " rank_zero_warn(\n", "GPU available: True (cuda), used: True\n", "TPU available: False, using: 0 TPU cores\n", "IPU available: False, using: 0 IPUs\n", "HPU available: False, using: 0 HPUs\n", - "[rank: 0] Global seed set to 3941088705\n", + "Found cached dataset parquet (/home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 858.61it/s]\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-85ed41912c749812_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-d919d919e3a12608_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-f2a6e7ee57d796c9_*_of_00032.arrow\n", + "[rank: 0] Global seed set to 3941088705 \n", "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/1\n", - "[2023-07-01 20:53:34,204] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "[2023-07-08 09:06:59,020] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "[2023-07-08 09:06:59,021] [WARNING] [deepspeed.py:638:_auto_select_batch_size] Tried to infer the batch size for internal deepspeed logging from the `train_dataloader()`. To ensure DeepSpeed logging remains correct, please manually pass the plugin with the batch size, `Trainer(strategy=DeepSpeedStrategy(logging_batch_size_per_gpu=batch_size))`.\n", "Enabling DeepSpeed BF16.\n", - "/home/picocreator/anaconda3/envs/rwkv-exp/lib/python3.11/site-packages/lightning/pytorch/callbacks/model_checkpoint.py:615: UserWarning: Checkpoint directory /home/picocreator/rwkv-proj/infctx-dev/checkpoint/trainer-validaiton/infctx-validation-full exists and is not empty.\n", - " rank_zero_warn(f\"Checkpoint directory {dirpath} exists and is not empty.\")\n", "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", - "\u001b[93m [WARNING] \u001b[0m cpu_adam cuda is missing or is incompatible with installed torch, only cpu ops can be compiled!\n", - "Using /home/picocreator/.cache/torch_extensions/py311_cu117 as PyTorch extensions root...\n", - "Emitting ninja build file /home/picocreator/.cache/torch_extensions/py311_cu117/cpu_adam/build.ninja...\n", + "[WARNING]: it is highly recommended to enable bptt_learning when used to deepspeed 2/3/offloading, otherwise an exception will occur when training with dataset records, larger then the configured context length (1024)\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/cpu_adam/build.ninja...\n", "Building extension module cpu_adam...\n", "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", "ninja: no work to do.\n", "Loading extension module cpu_adam...\n", - "Time to load cpu_adam op: 2.312431812286377 seconds\n", + "Time to load cpu_adam op: 2.3396010398864746 seconds\n", "Loading `train_dataloader` to estimate number of stepping batches.\n", "Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] \n", "\n", @@ -227,95 +146,536 @@ "0 Non-trainable params\n", "1.5 B Total params\n", "6,060.425 Total estimated model params size (MB)\n", - "Epoch 0: 100%|█| 5318/5318 [51:02<00:00, 1.74it/s, v_num=u72z, train/loss=5.940\n", - "Validation: 0it [00:00, ?it/s]\u001b[A\n", - "Validation: 0%| | 0/54 [00:00' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/interface/interface.py:572)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "Epoch 0: 11%| | 610/5308 [12:13<1:34:07, 1.20s/it, v_num=cq44, train/loss=7.50[2023-07-08 09:19:46,835] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: 'wrapper' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:358)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,836] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: 'wrapper_fn' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:337)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,837] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: '' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:313)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,838] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: 'log' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:1550)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,839] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: '_log' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:1514)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,840] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: '_partial_history_callback' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/wandb_run.py:1383)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "[2023-07-08 09:19:46,852] torch._dynamo.convert_frame: [WARNING] torch._dynamo hit config.cache_size_limit (64)\n", + " function: 'publish_partial_history' (/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/wandb/sdk/interface/interface.py:555)\n", + "to diagnose recompilation issues, set env variable TORCHDYNAMO_REPORT_GUARD_FAILURES=1 and also see https://pytorch.org/docs/master/compile/troubleshooting.html.\n", + "Epoch 0: 12%| | 635/5308 [12:37<1:32:56, 1.19s/it, v_num=cq44, train/loss=7.41^C\n", + "Process ForkProcess-128:\n", + "Process ForkProcess-127:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "KeyboardInterrupt\n", + "Process ForkProcess-120:\n", + "Process ForkProcess-124:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + "Process ForkProcess-118:\n", + "Process ForkProcess-122:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "KeyboardInterrupt\n", + "Process ForkProcess-123:\n", + "Process ForkProcess-116:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "KeyboardInterrupt\n", + "Process ForkProcess-115:\n", + "Process ForkProcess-112:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 103, in get\n", + " res = self._recv_bytes()\n", + " ^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/connection.py\", line 215, in recv_bytes\n", + " buf = self._recv_bytes(maxlength)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/connection.py\", line 413, in _recv_bytes\n", + " buf = self._recv(4)\n", + " ^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/connection.py\", line 378, in _recv\n", + " chunk = read(handle, remaining)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-111:\n", + "Process ForkProcess-109:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-104:\n", + "Process ForkProcess-107:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-102:\n", + "Process ForkProcess-101:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-98:\n", + "Process ForkProcess-99:\n", + "Traceback (most recent call last):\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-110:\n", + "Process ForkProcess-100:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + "Process ForkProcess-117:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-103:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + "Process ForkProcess-108:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-97:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Traceback (most recent call last):\n", + "Process ForkProcess-125:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-126:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "Process ForkProcess-114:\n", + "KeyboardInterrupt\n", + "Process ForkProcess-121:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-106:\n", + "Process ForkProcess-113:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-105:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "Process ForkProcess-119:\n", + "Traceback (most recent call last):\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + "/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/pytorch/trainer/call.py:52: UserWarning: Detected KeyboardInterrupt, attempting graceful shutdown...\n", + " rank_zero_warn(\"Detected KeyboardInterrupt, attempting graceful shutdown...\")\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n", + " self.run()\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/process.py\", line 108, in run\n", + " self._target(*self._args, **self._kwargs)\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/concurrent/futures/process.py\", line 244, in _process_worker\n", + " call_item = call_queue.get(block=True)\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/queues.py\", line 102, in get\n", + " with self._rlock:\n", + " File \"/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/multiprocessing/synchronize.py\", line 95, in __enter__\n", + " return self._semlock.__enter__()\n", + " ^^^^^^^^^^^^^^^^^^^^^^^^^\n", + "KeyboardInterrupt\n" ] } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-full.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " export WANDB_MODE=\"{WANDB_MODE}\" && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml \\\n", + " --trainer.logger.init_args.name=\"{WANDB_PREFIX} (full, train-ctx=1024, data-ctx=1024)\" \\\n", + " --trainer.strategy=\"{DEEPSPEED_STRAT}\" \\\n", + " --trainer.devices=\"{GPU_DEVICES}\"" ] }, { @@ -330,7 +690,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -478,8 +838,15 @@ } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-segmented-512.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " export WANDB_MODE=\"{WANDB_MODE}\" && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml \\\n", + " --trainer.logger.init_args.name=\"{WANDB_PREFIX} (bptt, train-ctx=512, data-ctx=1024)\" \\\n", + " --trainer.strategy=\"{DEEPSPEED_STRAT}\" \\\n", + " --trainer.devices=\"{GPU_DEVICES}\" \\\n", + " --model.bptt_learning=\"true\" \\\n", + " --model.ctx_len=512" ] }, { @@ -489,13 +856,12 @@ "source": [ "# Back-Propagation Through Time (128) training\n", "\n", - "Perform a full 1 epoch training run of training context size = 128. Forcing all data samples to be segmented 8 times, via \"Truncated Back-Propagation Through Time\"\n", - "> PS: Weights and biases logging is enabled" + "Perform a full 1 epoch training run of training context size = 128. Forcing all data samples to be segmented 8 times, via \"Truncated Back-Propagation Through Time\"" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -643,8 +1009,15 @@ } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-segmented.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " export WANDB_MODE=\"{WANDB_MODE}\" && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml \\\n", + " --trainer.logger.init_args.name=\"{WANDB_PREFIX} (bptt, train-ctx=128, data-ctx=1024)\" \\\n", + " --trainer.strategy=\"{DEEPSPEED_STRAT}\" \\\n", + " --trainer.devices=\"{GPU_DEVICES}\" \\\n", + " --model.bptt_learning=\"true\" \\\n", + " --model.ctx_len=128" ] }, { @@ -654,12 +1027,12 @@ "source": [ "# Last segmented (128) training\n", "\n", - "Perform a full 1 epoch training run of training context size = 128. Only using the last segment. (This replicates previous known regression)" + "Finally perform a full 1 epoch training run of training context size = 128. Only using the last segment. (This replicates previous known regression)" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -807,8 +1180,16 @@ } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-last-segment.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " export WANDB_MODE=\"{WANDB_MODE}\" && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml \\\n", + " --trainer.logger.init_args.name=\"{WANDB_PREFIX} (last-bptt, train-ctx=128, data-ctx=1024)\" \\\n", + " --trainer.strategy=\"{DEEPSPEED_STRAT}\" \\\n", + " --trainer.devices=\"{GPU_DEVICES}\" \\\n", + " --model.bptt_learning=\"true\" \\\n", + " --model.bptt_learning_range=1 \\\n", + " --model.ctx_len=128" ] } ], diff --git a/notebook/trainer-validation/infctx-validation-full.yaml b/notebook/trainer-validation/config/baseline-1024.yaml similarity index 98% rename from notebook/trainer-validation/infctx-validation-full.yaml rename to notebook/trainer-validation/config/baseline-1024.yaml index a4a5dc1d..3acc501e 100644 --- a/notebook/trainer-validation/infctx-validation-full.yaml +++ b/notebook/trainer-validation/config/baseline-1024.yaml @@ -3,7 +3,7 @@ seed_everything: 3941088705 trainer: # Configure the number of GPU, avaliable on your machine accelerator: gpu - devices: 1 + devices: auto num_nodes: 1 # @@ -35,7 +35,7 @@ trainer: logger: class_path: lightning.pytorch.loggers.WandbLogger init_args: - name: 'infctx-validation-full (train-ctx=1024, data-ctx=1024, bs=12)' + name: 'infctx-validation-baseline (train-ctx=1024, data-ctx=1024, bs=10)' project: 'RWKV-infctx-validation' tags: ['RWKV', 'infctx'] id: null @@ -79,7 +79,7 @@ trainer: # which will create a `rwkv_model.pth` in the checkpoint directory. # # Do not use the `zero_to_fp32.py` script as that will have export format issues - dirpath: ../checkpoint/trainer-validaiton/infctx-validation-full + dirpath: ../checkpoint/trainer-validaiton/infctx-validation-baseline filename: null # Save the top/last K checkpoints @@ -136,7 +136,7 @@ trainer: # # You are also recommended to configure this to a large enough number to fully utilize # your GPU processing time %, and avoid idle time for the GPU between batches - accumulate_grad_batches: 12 + accumulate_grad_batches: 10 # Various other settings, you probably want to leave alone fast_dev_run: false @@ -325,7 +325,7 @@ data: # multi_column_keys: ['instruction', 'input', 'output'] # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' + # multi_column_separator: '\n\n' # If processing prompt/completion jsonl pairs, the prompt is masked by default # use this flag to disable this default behaviour @@ -335,5 +335,5 @@ data: # Path to the current checkpoint to continue training from # Enable this to the last checkpoint after the first run # (if it crash and you want to resume) -# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-dryrun/epoch=0-step=20.ckpt +# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-baseline/epoch=0-step=20.ckpt ckpt_path: null diff --git a/notebook/trainer-validation/infctx-validation-dryrun.yaml b/notebook/trainer-validation/config/baseline-dryrun.yaml similarity index 99% rename from notebook/trainer-validation/infctx-validation-dryrun.yaml rename to notebook/trainer-validation/config/baseline-dryrun.yaml index 69544cc4..a76ee3a5 100644 --- a/notebook/trainer-validation/infctx-validation-dryrun.yaml +++ b/notebook/trainer-validation/config/baseline-dryrun.yaml @@ -3,7 +3,7 @@ seed_everything: 3941088705 trainer: # Configure the number of GPU, avaliable on your machine accelerator: gpu - devices: 1 + devices: auto num_nodes: 1 # @@ -240,7 +240,7 @@ model: # Segmented range to performing backprop learning on # 1 means to apply only for the last segment # -1 means to apply for all segments - bptt_learning_range: 2 + bptt_learning_range: -1 # various other settings you probably should leave alone grad_cp: true @@ -325,7 +325,7 @@ data: # multi_column_keys: ['instruction', 'input', 'output'] # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' + # multi_column_separator: '\n\n' # If processing prompt/completion jsonl pairs, the prompt is masked by default # use this flag to disable this default behaviour diff --git a/notebook/trainer-validation/infctx-validation-segmented.yaml b/notebook/trainer-validation/config/torch-compile-perf.yaml similarity index 95% rename from notebook/trainer-validation/infctx-validation-segmented.yaml rename to notebook/trainer-validation/config/torch-compile-perf.yaml index d278052e..970f1189 100644 --- a/notebook/trainer-validation/infctx-validation-segmented.yaml +++ b/notebook/trainer-validation/config/torch-compile-perf.yaml @@ -3,7 +3,7 @@ seed_everything: 3941088705 trainer: # Configure the number of GPU, avaliable on your machine accelerator: gpu - devices: 1 + devices: auto num_nodes: 1 # @@ -35,7 +35,7 @@ trainer: logger: class_path: lightning.pytorch.loggers.WandbLogger init_args: - name: 'infctx-validation-segmented (train-ctx=128, data-ctx=1024, bs=12)' + name: 'infctx-torch-compile-perf' project: 'RWKV-infctx-validation' tags: ['RWKV', 'infctx'] id: null @@ -79,7 +79,7 @@ trainer: # which will create a `rwkv_model.pth` in the checkpoint directory. # # Do not use the `zero_to_fp32.py` script as that will have export format issues - dirpath: ../checkpoint/trainer-validaiton/infctx-validation-segmented + dirpath: ../checkpoint/trainer-validaiton/infctx-validation-torch-perf filename: null # Save the top/last K checkpoints @@ -118,9 +118,9 @@ trainer: # Generally what you want to configure is the maximum number of epochs # Leave it as -1, and it will keep going forever till interrupted # Or set it as a number, and it will stop after that number of epochs - max_epochs: 1 + max_epochs: -1 min_epochs: null - max_steps: -1 + max_steps: 100 min_steps: null max_time: null @@ -136,7 +136,7 @@ trainer: # # You are also recommended to configure this to a large enough number to fully utilize # your GPU processing time %, and avoid idle time for the GPU between batches - accumulate_grad_batches: 12 + accumulate_grad_batches: 10 # Various other settings, you probably want to leave alone fast_dev_run: false @@ -189,16 +189,8 @@ model: # This allows the training of extreamly large context length (eg. 100k), # without eating up too much vram by keeping the training context length # to a resonable number sutible to the current GPU setup - ctx_len: 128 + ctx_len: 4096 - # Data samples would be cut down to the respective max ctx_len_cutoffs - # values if its larger then ctx_len. If the data sample is larger then - # the largest len_cutoff, the remaining data will be discarded - ctx_len_cutoffs: [1024, 2048, 4096, 8192, 16384, 32768, 65536] - # Experimental settings, number of tokens to skip in the data sample - # prefix, for the respective cutoff length. Used to speed up the process - ctx_len_warmup_steps: [0, 0, 0, 0, 0, 0, 0] - # Learning rate of the training process # --- # Initia learning rate of the process @@ -224,24 +216,41 @@ model: adam_eps: 1.0e-08 weight_decay: 0.01 - # torch.set_float32_matmul_precision, used to optimize operations with tensor cores - # this should be set as null, for non cuda core GPUs - torch_set_float32_matmul_precision: 'high' - # torch_set_float32_matmul_precision: null - # Segmented based learning, used to work around training of large context length # beyond what can be supported by the current GPU vram architecture # # This is not 1:1 equivalent to the same training process with required vram # as the training process is split into multiple segments, part by part. # with limited learnings from the previous segment. - bptt_learning: true + bptt_learning: false # Segmented range to performing backprop learning on # 1 means to apply only for the last segment # -1 means to apply for all segments bptt_learning_range: -1 + # Force each substep to be logged as a seperate line + substep_logging: true + + # Experimental cutoff settings + # --- + # Data samples would be cut down to the respective max ctx_len_cutoffs + # values if its larger then ctx_len. If the data sample is larger then + # the largest len_cutoff, the remaining data will be discarded + # + # Leave it as a blank array to disable the feature + ctx_len_cutoffs: [] + # Experimental settings, number of tokens to skip in the data sample + # prefix, for the respective cutoff length. Used to speed up the process + # + # Leave it as a blank array to disable the feature + ctx_len_warmup_steps: [] + + # torch.set_float32_matmul_precision, used to optimize operations with tensor cores + # this should be set as null, for non cuda core GPUs + torch_set_float32_matmul_precision: 'high' + # torch_set_float32_matmul_precision: null + # various other settings you probably should leave alone grad_cp: true warmup_steps: -1 @@ -254,7 +263,7 @@ data: # Use this if you have built your own dataset and saved it with `save_to_disk()` # with source left as null. Other wise configure this to a directory which the # dataset will be built and tokenized by the huggingface dataset process. - data_path: ../datapath/enwiki_10k_1024/ + data_path: ../datapath/enwiki_10k_4096/ # Other wise provide the source path, which is used as huggingface dataset path # this will be used to populate the dataset_path @@ -302,7 +311,7 @@ data: # This is ignored, if source is not set as text # This is ignored, if set to zero # --- - text_rechunk_size: 1024 + text_rechunk_size: 4096 # Apply text rechunk to the dataset, even if its not a 'text' source # This is done only after dataset filtering, and if source is not 'text' @@ -325,7 +334,7 @@ data: # multi_column_keys: ['instruction', 'input', 'output'] # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' + # multi_column_separator: '\n\n' # If processing prompt/completion jsonl pairs, the prompt is masked by default # use this flag to disable this default behaviour @@ -335,5 +344,5 @@ data: # Path to the current checkpoint to continue training from # Enable this to the last checkpoint after the first run # (if it crash and you want to resume) -# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-dryrun/epoch=0-step=20.ckpt +# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-baseline/epoch=0-step=20.ckpt ckpt_path: null diff --git a/notebook/trainer-validation/deepspeed-2-and-3.ipynb b/notebook/trainer-validation/deepspeed-2-and-3.ipynb new file mode 100644 index 00000000..ed351575 --- /dev/null +++ b/notebook/trainer-validation/deepspeed-2-and-3.ipynb @@ -0,0 +1,1139 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Deepspeed 2 & 3 Validation\n", + "This model being trained has the same settings as raven 1B5 model.\n", + "- Layer count: 24\n", + "- Embed size: 2048\n", + "\n", + "The goal is to validate the trainer across deepspeed 2 & 3 - with and without offload. All other training params remain constant.\n", + "\n", + "Note, you will need a dual+ GPU setup, that is capable of handling deepspeed 2 (minimum 24GB * 2)\n", + "\n", + "> This project assumes you have the rwkv-infctx conda env setup, and you are executing in that environment - see the main README.md for the conda env setup steps\n", + ">\n", + "> And that you have completed the `baseline-setup.ipynb` and the environment setup found in project `README.md`\n", + "\n", + "## What does deepspeed 2 & 3 do (With/Without CPU offload) ??\n", + "\n", + "Instead of simply splitting the dataset being trained, and having a full copy of nearly everything in all GPU's (aka DDP / DeepSpeed 1).\n", + "\n", + "Deepspeed 2, keeps a full copy of the model weights on each GPU, but splits the training gradient descent memory usage into multiple GPUs, or offload it into CPU memory (+ CPU offload option).\n", + "\n", + "Deepspeed 3, takes it a step further, and distributes the model weights across all the GPUs, drastically lowering the vram requirement, while increasing the amount of GPU to GPU traffic drastically. Gradient descent memory is still split across multiple GPUs, with the option to offload into CPU memory (Same as deepspeed 2)\n", + "\n", + "Finally, Deepspeed 3, also introduce options to further offload such model weights / gradient descent, more into CPU memory or NVMe. However this option was not enabled or explored in the following benchmarks.\n", + "\n", + "See more here: https://huggingface.co/docs/transformers/main_classes/deepspeed\n", + "\n", + "## Benchmark results\n", + "\n", + "Benchmark was done on 11th July 2023. With Torch 2.0.1, Cuda 11.8. On two seperate machines, via vast.ai\n", + "\n", + "- 2 x A5000 (AMD EPYC 7513 - per gpu specs: 24gb, pcie4x16, 34.4 TFlops, nvlinked)\n", + "- 2 x 3090 (AMD EPYC 7302 - per gpu specs: 24gb, pcie3x16, 44.1 TFlops)\n", + "\n", + "| Deepspeed Strat | Time (A5000) | Time (3090) | VRAM Usage | RAM Usage | Validation Loss |\n", + "| --------------------- | --------------------- | --------------------- | ---------------- | --------- | --------------- |\n", + "| Stage 2 | 24 mins : 55 sec | 35 mins : 04 sec | ~22.3 + 23.8 GB | ~85 GB | 6.173 |\n", + "| Stage 2 + CPU offload | 43 mins : 08 sec | 59 mins : 04 sec | ~9.7 + 10.3 GB | ~128 GB | 6.124 |\n", + "| Stage 3 | 29 mins : 12 sec | 50 mins : 04 sec | ~23.0 + 23.2 GB^ | ~85 GB | 5.665 |\n", + "| Stage 3 + CPU offload | 1hr : 42mins : 38 sec | 1hr : 29mins : 15 sec | ~7.0 + 7.3 GB | ~145 GB | 5.668 |\n", + "\n", + "---\n", + "\n", + "> ^ note in theory deepspeed 3 uses less vram then deepspeed 2, however it will also try to use up more ram then its needed for \"cache\" items if possible, maxing out to the same level as deepspeed 2 here\n", + "\n", + "> Torch.JIT was enabled for deepspeed 2, But was disabled for deepspeed 3 (not compatible). Torch.compile was disabled\n", + "\n", + "> Full report with charts and figures can be found at WANDB : https://wandb.ai/picocreator/RWKV-InfCtx-Validation/reports/-RWKV-infctx-DeepSpeed-2-3-comparisons--Vmlldzo0ODM5MjAy" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure and apply your preferred settings\n", + "\n", + "Adjust your desired deepspeed settings, and gpu device count.\n", + "\n", + "Enable/Disable WANDB here as well ( Enabled by default, as we need the loss curve for this experiment )\n", + "\n", + "( note you will need to rerun this cell, if you restart your env )" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ENABLE_WANDB: True\n", + "GPU_DEVICES: auto\n" + ] + } + ], + "source": [ + "GPU_DEVICES=\"auto\"\n", + "ENABLE_WANDB=True\n", + "WANDB_PREFIX=\"infctx-deepspeed-deterministic\"\n", + "\n", + "print(\"ENABLE_WANDB:\", ENABLE_WANDB)\n", + "print(\"GPU_DEVICES:\", GPU_DEVICES)\n", + "\n", + "if ENABLE_WANDB:\n", + " WANDB_MODE=\"online\"\n", + "else:\n", + " WANDB_MODE=\"disabled\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Deepspeed 2\n", + "Perform a full 1 epoch training run of training context size = 1024. With deepspeed 2" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting ds_accelerator to cuda (auto detect)\n", + "[RWKV.model] Running RWKV model using 'torch-jit' with torch '2.0.1+cu118'\n", + "Global seed set to 3941088705\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mpicocreator\u001b[0m. Use \u001b[1m`wandb login --relogin`\u001b[0m to force relogin\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: wandb version 0.15.5 is available! To upgrade, please run:\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: $ pip install wandb --upgrade\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Tracking run with wandb version 0.15.4\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Run data is saved locally in \u001b[35m\u001b[1m./wandb/run-20230710_201455-u3419fsk\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Run \u001b[1m`wandb offline`\u001b[0m to turn off syncing.\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: Syncing run \u001b[33minfctx-deepspeed-deterministic (deepspeed_stage_2, train-ctx=1024, data-ctx=1024)\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: ⭐️ View project at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation\u001b[0m\n", + "\u001b[34m\u001b[1mwandb\u001b[0m: 🚀 View run at \u001b[34m\u001b[4mhttps://wandb.ai/picocreator/RWKV-InfCtx-Validation/runs/u3419fsk\u001b[0m\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /root/.cache/torch_extensions/py311_cu118/wkv_1024_bf16/build.ninja...\n", + "Building extension module wkv_1024_bf16...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module wkv_1024_bf16...\n", + "/usr/local/lib/python3.11/dist-packages/lightning/fabric/connector.py:562: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + " rank_zero_warn(\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "Found cached dataset parquet (/root/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 706.83it/s]\n", + "Loading cached processed dataset at /root/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-d9ebc51d67d5ce31_*_of_00032.arrow\n", + "Loading cached processed dataset at /root/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-c63aa2ba2a5c9680_*_of_00032.arrow\n", + "Loading cached processed dataset at /root/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-193f68ea4e8054de_*_of_00032.arrow\n", + "[rank: 0] Global seed set to 3941088705 \n", + "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/2\n", + "[2023-07-10 20:15:11,785] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "Setting ds_accelerator to cuda (auto detect)\n", + "[RWKV.model] Running RWKV model using 'torch-jit' with torch '2.0.1+cu118'\n", + "[rank: 1] Global seed set to 3941088705\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /root/.cache/torch_extensions/py311_cu118/wkv_1024_bf16/build.ninja...\n", + "Building extension module wkv_1024_bf16...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module wkv_1024_bf16...\n", + "[rank: 1] Global seed set to 3941088705\n", + "initializing deepspeed distributed: GLOBAL_RANK: 1, MEMBER: 2/2\n", + "[2023-07-10 20:15:27,547] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "[2023-07-10 20:15:27,587] [WARNING] [deepspeed.py:637:_auto_select_batch_size] Tried to infer the batch size for internal deepspeed logging from the `train_dataloader()`. To ensure DeepSpeed logging remains correct, please manually pass the plugin with the batch size, `Trainer(strategy=DeepSpeedStrategy(logging_batch_size_per_gpu=batch_size))`.\n", + "Enabling DeepSpeed BF16.\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1]\n", + "LOCAL_RANK: 1 - CUDA_VISIBLE_DEVICES: [0,1]\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /root/.cache/torch_extensions/py311_cu118/fused_adam/build.ninja...\n", + "Building extension module fused_adam...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module fused_adam...\n", + "Time to load fused_adam op: 0.08059811592102051 seconds\n", + "Loading extension module fused_adam...\n", + "Time to load fused_adam op: 0.1025228500366211 seconds\n", + "Loading `train_dataloader` to estimate number of stepping batches.\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Emitting ninja build file /root/.cache/torch_extensions/py311_cu118/utils/build.ninja...\n", + "Building extension module utils...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module utils...\n", + "Time to load utils op: 0.0865182876586914 seconds\n", + "Loading extension module utils...\n", + "Time to load utils op: 0.10229158401489258 seconds\n", + "Rank: 0 partition count [2, 2, 2] and sizes[(757504000, False), (24576, False), (24576, False)] \n", + "Rank: 1 partition count [2, 2, 2] and sizes[(757504000, False), (24576, False), (24576, False)] \n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "No modifications detected for re-loaded extension module utils, skipping build step...\n", + "Loading extension module utils...\n", + "Time to load utils op: 0.00031065940856933594 seconds\n", + "Using /root/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "No modifications detected for re-loaded extension module utils, skipping build step...\n", + "Loading extension module utils...\n", + "Time to load utils op: 0.0005862712860107422 seconds\n", + "\n", + " | Name | Type | Params\n", + "--------------------------------------\n", + "0 | emb | Embedding | 102 M \n", + "1 | blocks | ModuleList | 1.3 B \n", + "2 | ln_out | LayerNorm | 4.1 K \n", + "3 | head | Linear | 102 M \n", + "--------------------------------------\n", + "1.5 B Trainable params\n", + "0 Non-trainable params\n", + "1.5 B Total params\n", + "6,060.425 Total estimated model params size (MB)\n", + "Epoch 0: 100%|█| 2654/2654 [34:58<00:00, 1.26it/s, v_num=9fsk, train/loss=9.000\n", + "Validation: 0it [00:00, ?it/s]\u001b[A\n", + "Validation: 0%| | 0/27 [00:00) and the tensors embedded in it cannot be detected. The ZeRO-3 hooks designed to trigger before or after backward pass of the module relies on knowing the input and output tensors and therefore may not get triggered properly.\n", + "Epoch 0: 0%| | 9/2654 [00:12<1:03:18, 1.44s/it, v_num=hk35, train/loss=10.90][2023-07-10 21:52:27,545] [WARNING] [stage3.py:1832:step] 1 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 1%| | 19/2654 [00:24<55:45, 1.27s/it, v_num=hk35, train/loss=9.440][2023-07-10 21:52:38,695] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 1%| | 29/2654 [00:35<53:16, 1.22s/it, v_num=hk35, train/loss=9.310][2023-07-10 21:52:49,953] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 1%| | 39/2654 [00:46<52:02, 1.19s/it, v_num=hk35, train/loss=8.880][2023-07-10 21:53:01,142] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 2%| | 49/2654 [00:57<51:10, 1.18s/it, v_num=hk35, train/loss=8.440][2023-07-10 21:53:12,393] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 2%| | 59/2654 [01:08<50:34, 1.17s/it, v_num=hk35, train/loss=8.310][2023-07-10 21:53:23,578] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 3%| | 69/2654 [01:20<50:05, 1.16s/it, v_num=hk35, train/loss=8.440][2023-07-10 21:53:34,875] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 3%| | 79/2654 [01:31<49:43, 1.16s/it, v_num=hk35, train/loss=7.840][2023-07-10 21:53:46,127] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 3%| | 89/2654 [01:42<49:22, 1.15s/it, v_num=hk35, train/loss=8.750][2023-07-10 21:53:57,434] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 4%| | 99/2654 [01:54<49:03, 1.15s/it, v_num=hk35, train/loss=8.310][2023-07-10 21:54:08,634] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 4%| | 109/2654 [02:05<48:44, 1.15s/it, v_num=hk35, train/loss=8.380][2023-07-10 21:54:19,913] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 4%| | 119/2654 [02:16<48:28, 1.15s/it, v_num=hk35, train/loss=8.940][2023-07-10 21:54:31,134] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 5%| | 129/2654 [02:27<48:12, 1.15s/it, v_num=hk35, train/loss=8.380][2023-07-10 21:54:42,445] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 5%| | 139/2654 [02:39<47:58, 1.14s/it, v_num=hk35, train/loss=8.190][2023-07-10 21:54:53,669] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 6%| | 149/2654 [02:50<47:44, 1.14s/it, v_num=hk35, train/loss=8.000][2023-07-10 21:55:05,026] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 6%| | 159/2654 [03:01<47:30, 1.14s/it, v_num=hk35, train/loss=8.060][2023-07-10 21:55:16,241] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 6%| | 169/2654 [03:12<47:16, 1.14s/it, v_num=hk35, train/loss=7.940][2023-07-10 21:55:27,556] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 7%| | 179/2654 [03:24<47:03, 1.14s/it, v_num=hk35, train/loss=7.970][2023-07-10 21:55:38,748] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 7%| | 189/2654 [03:35<46:48, 1.14s/it, v_num=hk35, train/loss=8.810][2023-07-10 21:55:50,034] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 7%| | 199/2654 [03:46<46:36, 1.14s/it, v_num=hk35, train/loss=7.660][2023-07-10 21:56:01,273] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 8%| | 209/2654 [03:57<46:23, 1.14s/it, v_num=hk35, train/loss=7.590][2023-07-10 21:56:12,582] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 8%| | 219/2654 [04:09<46:10, 1.14s/it, v_num=hk35, train/loss=7.910][2023-07-10 21:56:23,779] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 9%| | 229/2654 [04:20<45:57, 1.14s/it, v_num=hk35, train/loss=7.810][2023-07-10 21:56:35,039] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 9%| | 239/2654 [04:31<45:45, 1.14s/it, v_num=hk35, train/loss=7.410][2023-07-10 21:56:46,272] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 9%| | 249/2654 [04:42<45:32, 1.14s/it, v_num=hk35, train/loss=7.910][2023-07-10 21:56:57,570] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 10%| | 259/2654 [04:54<45:20, 1.14s/it, v_num=hk35, train/loss=7.720][2023-07-10 21:57:08,760] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 10%| | 269/2654 [05:05<45:07, 1.14s/it, v_num=hk35, train/loss=7.780][2023-07-10 21:57:20,041] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 11%| | 279/2654 [05:16<44:55, 1.13s/it, v_num=hk35, train/loss=7.810][2023-07-10 21:57:31,226] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 11%| | 289/2654 [05:27<44:42, 1.13s/it, v_num=hk35, train/loss=7.660][2023-07-10 21:57:42,485] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 11%| | 299/2654 [05:39<44:30, 1.13s/it, v_num=hk35, train/loss=7.590][2023-07-10 21:57:53,682] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 12%| | 309/2654 [05:50<44:19, 1.13s/it, v_num=hk35, train/loss=7.620][2023-07-10 21:58:05,024] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 12%| | 319/2654 [06:01<44:07, 1.13s/it, v_num=hk35, train/loss=7.690][2023-07-10 21:58:16,304] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 12%| | 329/2654 [06:12<43:55, 1.13s/it, v_num=hk35, train/loss=7.530][2023-07-10 21:58:27,641] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 13%|▏| 339/2654 [06:24<43:44, 1.13s/it, v_num=hk35, train/loss=8.190][2023-07-10 21:58:38,891] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 13%|▏| 349/2654 [06:35<43:31, 1.13s/it, v_num=hk35, train/loss=7.530][2023-07-10 21:58:50,088] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 14%|▏| 359/2654 [06:46<43:19, 1.13s/it, v_num=hk35, train/loss=7.690][2023-07-10 21:59:01,260] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 14%|▏| 369/2654 [06:57<43:07, 1.13s/it, v_num=hk35, train/loss=8.190][2023-07-10 21:59:12,513] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 14%|▏| 379/2654 [07:09<42:55, 1.13s/it, v_num=hk35, train/loss=7.590][2023-07-10 21:59:23,706] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 15%|▏| 389/2654 [07:20<42:43, 1.13s/it, v_num=hk35, train/loss=7.840][2023-07-10 21:59:34,977] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 15%|▏| 399/2654 [07:31<42:32, 1.13s/it, v_num=hk35, train/loss=7.120][2023-07-10 21:59:46,179] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 15%|▏| 409/2654 [07:42<42:20, 1.13s/it, v_num=hk35, train/loss=7.660][2023-07-10 21:59:57,460] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 16%|▏| 419/2654 [07:54<42:08, 1.13s/it, v_num=hk35, train/loss=7.470][2023-07-10 22:00:08,664] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 16%|▏| 429/2654 [08:05<41:56, 1.13s/it, v_num=hk35, train/loss=7.810][2023-07-10 22:00:19,933] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 17%|▏| 439/2654 [08:16<41:45, 1.13s/it, v_num=hk35, train/loss=7.560][2023-07-10 22:00:31,107] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 17%|▏| 449/2654 [08:27<41:33, 1.13s/it, v_num=hk35, train/loss=7.940][2023-07-10 22:00:42,373] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 17%|▏| 459/2654 [08:39<41:22, 1.13s/it, v_num=hk35, train/loss=7.880][2023-07-10 22:00:53,695] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 18%|▏| 469/2654 [08:50<41:11, 1.13s/it, v_num=hk35, train/loss=7.340][2023-07-10 22:01:05,085] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 18%|▏| 479/2654 [09:01<41:00, 1.13s/it, v_num=hk35, train/loss=7.310][2023-07-10 22:01:16,417] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 18%|▏| 489/2654 [09:13<40:49, 1.13s/it, v_num=hk35, train/loss=7.410][2023-07-10 22:01:27,839] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 19%|▏| 499/2654 [09:24<40:37, 1.13s/it, v_num=hk35, train/loss=7.440][2023-07-10 22:01:39,083] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 19%|▏| 509/2654 [09:35<40:26, 1.13s/it, v_num=hk35, train/loss=7.780][2023-07-10 22:01:50,429] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 20%|▏| 519/2654 [09:47<40:15, 1.13s/it, v_num=hk35, train/loss=7.190][2023-07-10 22:02:01,703] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 20%|▏| 529/2654 [09:58<40:03, 1.13s/it, v_num=hk35, train/loss=7.220][2023-07-10 22:02:13,056] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 20%|▏| 539/2654 [10:09<39:52, 1.13s/it, v_num=hk35, train/loss=7.000][2023-07-10 22:02:24,259] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 21%|▏| 549/2654 [10:20<39:41, 1.13s/it, v_num=hk35, train/loss=7.090][2023-07-10 22:02:35,649] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 21%|▏| 559/2654 [10:32<39:30, 1.13s/it, v_num=hk35, train/loss=7.470][2023-07-10 22:02:47,013] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 21%|▏| 569/2654 [10:43<39:18, 1.13s/it, v_num=hk35, train/loss=7.250][2023-07-10 22:02:58,306] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 22%|▏| 579/2654 [10:54<39:07, 1.13s/it, v_num=hk35, train/loss=7.380][2023-07-10 22:03:09,548] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 22%|▏| 589/2654 [11:06<38:55, 1.13s/it, v_num=hk35, train/loss=7.500][2023-07-10 22:03:20,909] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 23%|▏| 599/2654 [11:17<38:44, 1.13s/it, v_num=hk35, train/loss=7.250][2023-07-10 22:03:32,076] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 23%|▏| 609/2654 [11:28<38:32, 1.13s/it, v_num=hk35, train/loss=6.720][2023-07-10 22:03:43,277] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 23%|▏| 619/2654 [11:39<38:20, 1.13s/it, v_num=hk35, train/loss=7.380][2023-07-10 22:03:54,426] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 24%|▏| 629/2654 [11:51<38:09, 1.13s/it, v_num=hk35, train/loss=7.750][2023-07-10 22:04:05,750] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 24%|▏| 639/2654 [12:02<37:58, 1.13s/it, v_num=hk35, train/loss=7.190][2023-07-10 22:04:17,012] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 24%|▏| 649/2654 [12:13<37:46, 1.13s/it, v_num=hk35, train/loss=7.090][2023-07-10 22:04:28,353] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 25%|▏| 659/2654 [12:25<37:35, 1.13s/it, v_num=hk35, train/loss=7.220][2023-07-10 22:04:39,644] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 25%|▎| 669/2654 [12:36<37:24, 1.13s/it, v_num=hk35, train/loss=7.280][2023-07-10 22:04:50,981] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 26%|▎| 679/2654 [12:47<37:13, 1.13s/it, v_num=hk35, train/loss=7.060][2023-07-10 22:05:02,348] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 26%|▎| 689/2654 [12:59<37:02, 1.13s/it, v_num=hk35, train/loss=6.590][2023-07-10 22:05:13,813] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 26%|▎| 699/2654 [13:10<36:51, 1.13s/it, v_num=hk35, train/loss=7.120][2023-07-10 22:05:25,198] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 27%|▎| 709/2654 [13:21<36:39, 1.13s/it, v_num=hk35, train/loss=6.470][2023-07-10 22:05:36,538] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 27%|▎| 719/2654 [13:33<36:28, 1.13s/it, v_num=hk35, train/loss=6.910][2023-07-10 22:05:47,870] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 27%|▎| 729/2654 [13:44<36:17, 1.13s/it, v_num=hk35, train/loss=7.190][2023-07-10 22:05:59,116] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 28%|▎| 739/2654 [13:55<36:05, 1.13s/it, v_num=hk35, train/loss=7.120][2023-07-10 22:06:10,441] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 28%|▎| 749/2654 [14:07<35:55, 1.13s/it, v_num=hk35, train/loss=6.720][2023-07-10 22:06:21,993] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 29%|▎| 759/2654 [14:19<35:44, 1.13s/it, v_num=hk35, train/loss=7.030][2023-07-10 22:06:33,729] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 29%|▎| 769/2654 [14:30<35:33, 1.13s/it, v_num=hk35, train/loss=7.060][2023-07-10 22:06:44,934] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 29%|▎| 779/2654 [14:41<35:21, 1.13s/it, v_num=hk35, train/loss=6.840][2023-07-10 22:06:56,221] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 30%|▎| 789/2654 [14:52<35:10, 1.13s/it, v_num=hk35, train/loss=6.910][2023-07-10 22:07:07,444] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 30%|▎| 799/2654 [15:04<34:58, 1.13s/it, v_num=hk35, train/loss=6.880][2023-07-10 22:07:18,714] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 30%|▎| 809/2654 [15:15<34:47, 1.13s/it, v_num=hk35, train/loss=7.250][2023-07-10 22:07:29,993] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 31%|▎| 819/2654 [15:26<34:36, 1.13s/it, v_num=hk35, train/loss=6.470][2023-07-10 22:07:41,377] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 31%|▎| 829/2654 [15:38<34:24, 1.13s/it, v_num=hk35, train/loss=6.690][2023-07-10 22:07:52,597] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 32%|▎| 839/2654 [15:49<34:13, 1.13s/it, v_num=hk35, train/loss=6.940][2023-07-10 22:08:03,917] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 32%|▎| 849/2654 [16:00<34:02, 1.13s/it, v_num=hk35, train/loss=7.190][2023-07-10 22:08:15,235] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 32%|▎| 859/2654 [16:12<33:51, 1.13s/it, v_num=hk35, train/loss=6.840][2023-07-10 22:08:26,693] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 33%|▎| 869/2654 [16:23<33:39, 1.13s/it, v_num=hk35, train/loss=6.660][2023-07-10 22:08:37,992] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 33%|▎| 879/2654 [16:34<33:28, 1.13s/it, v_num=hk35, train/loss=6.590][2023-07-10 22:08:49,357] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 33%|▎| 889/2654 [16:46<33:17, 1.13s/it, v_num=hk35, train/loss=7.410][2023-07-10 22:09:00,752] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 34%|▎| 899/2654 [16:57<33:06, 1.13s/it, v_num=hk35, train/loss=7.090][2023-07-10 22:09:12,165] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 34%|▎| 909/2654 [17:08<32:55, 1.13s/it, v_num=hk35, train/loss=6.470][2023-07-10 22:09:23,515] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 35%|▎| 919/2654 [17:20<32:43, 1.13s/it, v_num=hk35, train/loss=6.590][2023-07-10 22:09:34,737] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 35%|▎| 929/2654 [17:31<32:32, 1.13s/it, v_num=hk35, train/loss=6.750][2023-07-10 22:09:45,948] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 35%|▎| 939/2654 [17:42<32:20, 1.13s/it, v_num=hk35, train/loss=7.000][2023-07-10 22:09:57,229] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 36%|▎| 949/2654 [17:53<32:09, 1.13s/it, v_num=hk35, train/loss=7.000][2023-07-10 22:10:08,527] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 36%|▎| 959/2654 [18:05<31:58, 1.13s/it, v_num=hk35, train/loss=6.410][2023-07-10 22:10:19,993] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 37%|▎| 969/2654 [18:16<31:47, 1.13s/it, v_num=hk35, train/loss=6.560][2023-07-10 22:10:31,269] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 37%|▎| 979/2654 [18:27<31:35, 1.13s/it, v_num=hk35, train/loss=6.910][2023-07-10 22:10:42,542] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 37%|▎| 989/2654 [18:39<31:23, 1.13s/it, v_num=hk35, train/loss=6.840][2023-07-10 22:10:53,646] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 38%|▍| 999/2654 [18:50<31:12, 1.13s/it, v_num=hk35, train/loss=6.690][2023-07-10 22:11:04,825] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 38%|▍| 1009/2654 [19:01<31:00, 1.13s/it, v_num=hk35, train/loss=6.780[2023-07-10 22:11:16,009] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 38%|▍| 1019/2654 [19:12<30:49, 1.13s/it, v_num=hk35, train/loss=6.720[2023-07-10 22:11:27,209] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 39%|▍| 1029/2654 [19:23<30:37, 1.13s/it, v_num=hk35, train/loss=6.340[2023-07-10 22:11:38,419] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 39%|▍| 1039/2654 [19:35<30:26, 1.13s/it, v_num=hk35, train/loss=6.750[2023-07-10 22:11:49,681] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 40%|▍| 1049/2654 [19:46<30:15, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:12:00,918] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 40%|▍| 1059/2654 [19:57<30:03, 1.13s/it, v_num=hk35, train/loss=6.750[2023-07-10 22:12:12,215] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 40%|▍| 1069/2654 [20:08<29:52, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:12:23,557] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 41%|▍| 1079/2654 [20:20<29:41, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:12:35,049] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 41%|▍| 1089/2654 [20:31<29:30, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:12:46,293] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 41%|▍| 1099/2654 [20:42<29:18, 1.13s/it, v_num=hk35, train/loss=7.000[2023-07-10 22:12:57,577] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 42%|▍| 1109/2654 [20:54<29:07, 1.13s/it, v_num=hk35, train/loss=6.410[2023-07-10 22:13:08,832] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 42%|▍| 1119/2654 [21:05<28:56, 1.13s/it, v_num=hk35, train/loss=6.590[2023-07-10 22:13:20,273] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 43%|▍| 1129/2654 [21:16<28:44, 1.13s/it, v_num=hk35, train/loss=6.060[2023-07-10 22:13:31,561] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 43%|▍| 1139/2654 [21:28<28:33, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:13:42,917] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 43%|▍| 1149/2654 [21:39<28:22, 1.13s/it, v_num=hk35, train/loss=6.500[2023-07-10 22:13:54,198] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 44%|▍| 1159/2654 [21:50<28:10, 1.13s/it, v_num=hk35, train/loss=6.690[2023-07-10 22:14:05,525] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 44%|▍| 1169/2654 [22:02<27:59, 1.13s/it, v_num=hk35, train/loss=6.470[2023-07-10 22:14:16,789] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 44%|▍| 1179/2654 [22:13<27:48, 1.13s/it, v_num=hk35, train/loss=6.060[2023-07-10 22:14:28,123] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 45%|▍| 1189/2654 [22:24<27:36, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:14:39,372] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 45%|▍| 1199/2654 [22:35<27:25, 1.13s/it, v_num=hk35, train/loss=6.470[2023-07-10 22:14:50,613] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 46%|▍| 1209/2654 [22:47<27:14, 1.13s/it, v_num=hk35, train/loss=6.000[2023-07-10 22:15:01,851] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 46%|▍| 1219/2654 [22:58<27:02, 1.13s/it, v_num=hk35, train/loss=6.410[2023-07-10 22:15:13,153] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 46%|▍| 1229/2654 [23:09<26:51, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:15:24,412] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 47%|▍| 1239/2654 [23:21<26:40, 1.13s/it, v_num=hk35, train/loss=6.250[2023-07-10 22:15:35,700] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 47%|▍| 1249/2654 [23:32<26:28, 1.13s/it, v_num=hk35, train/loss=6.560[2023-07-10 22:15:46,943] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 47%|▍| 1259/2654 [23:43<26:17, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:15:58,318] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 48%|▍| 1269/2654 [23:55<26:06, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:16:09,709] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 48%|▍| 1279/2654 [24:06<25:55, 1.13s/it, v_num=hk35, train/loss=6.810[2023-07-10 22:16:21,178] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 49%|▍| 1289/2654 [24:18<25:44, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:16:32,647] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 49%|▍| 1299/2654 [24:29<25:32, 1.13s/it, v_num=hk35, train/loss=6.250[2023-07-10 22:16:44,045] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 49%|▍| 1309/2654 [24:40<25:21, 1.13s/it, v_num=hk35, train/loss=6.060[2023-07-10 22:16:55,345] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 50%|▍| 1319/2654 [24:52<25:10, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:17:06,786] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 50%|▌| 1329/2654 [25:03<24:58, 1.13s/it, v_num=hk35, train/loss=6.560[2023-07-10 22:17:18,016] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 50%|▌| 1339/2654 [25:14<24:47, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:17:29,237] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 51%|▌| 1349/2654 [25:25<24:36, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:17:40,591] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 51%|▌| 1359/2654 [25:37<24:24, 1.13s/it, v_num=hk35, train/loss=6.340[2023-07-10 22:17:51,865] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 52%|▌| 1369/2654 [25:48<24:13, 1.13s/it, v_num=hk35, train/loss=6.190[2023-07-10 22:18:03,173] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 52%|▌| 1379/2654 [25:59<24:02, 1.13s/it, v_num=hk35, train/loss=7.060[2023-07-10 22:18:14,525] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 52%|▌| 1389/2654 [26:11<23:50, 1.13s/it, v_num=hk35, train/loss=6.590[2023-07-10 22:18:25,750] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 53%|▌| 1399/2654 [26:22<23:39, 1.13s/it, v_num=hk35, train/loss=6.380[2023-07-10 22:18:37,101] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 53%|▌| 1409/2654 [26:33<23:28, 1.13s/it, v_num=hk35, train/loss=6.500[2023-07-10 22:18:48,351] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 53%|▌| 1419/2654 [26:45<23:16, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:18:59,654] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 54%|▌| 1429/2654 [26:56<23:05, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:19:10,902] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 54%|▌| 1439/2654 [27:07<22:54, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:19:22,229] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 55%|▌| 1449/2654 [27:18<22:42, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:19:33,414] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 55%|▌| 1459/2654 [27:30<22:31, 1.13s/it, v_num=hk35, train/loss=5.880[2023-07-10 22:19:44,709] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 55%|▌| 1469/2654 [27:41<22:20, 1.13s/it, v_num=hk35, train/loss=5.910[2023-07-10 22:19:55,883] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 56%|▌| 1479/2654 [27:52<22:08, 1.13s/it, v_num=hk35, train/loss=6.810[2023-07-10 22:20:07,117] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 56%|▌| 1489/2654 [28:03<21:57, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:20:18,430] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 56%|▌| 1499/2654 [28:15<21:46, 1.13s/it, v_num=hk35, train/loss=5.810[2023-07-10 22:20:29,753] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 57%|▌| 1509/2654 [28:26<21:34, 1.13s/it, v_num=hk35, train/loss=6.590[2023-07-10 22:20:41,025] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 57%|▌| 1519/2654 [28:37<21:23, 1.13s/it, v_num=hk35, train/loss=6.000[2023-07-10 22:20:52,363] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 58%|▌| 1529/2654 [28:49<21:12, 1.13s/it, v_num=hk35, train/loss=6.060[2023-07-10 22:21:03,604] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 58%|▌| 1539/2654 [29:00<21:00, 1.13s/it, v_num=hk35, train/loss=6.380[2023-07-10 22:21:14,925] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 58%|▌| 1549/2654 [29:11<20:49, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:21:26,313] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 59%|▌| 1559/2654 [29:22<20:38, 1.13s/it, v_num=hk35, train/loss=6.500[2023-07-10 22:21:37,569] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 59%|▌| 1569/2654 [29:34<20:26, 1.13s/it, v_num=hk35, train/loss=6.410[2023-07-10 22:21:48,820] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 59%|▌| 1579/2654 [29:45<20:15, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:22:00,152] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 60%|▌| 1589/2654 [29:56<20:04, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:22:11,384] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 60%|▌| 1599/2654 [30:08<19:52, 1.13s/it, v_num=hk35, train/loss=6.310[2023-07-10 22:22:22,711] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 61%|▌| 1609/2654 [30:19<19:41, 1.13s/it, v_num=hk35, train/loss=7.440[2023-07-10 22:22:33,943] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 61%|▌| 1619/2654 [30:30<19:30, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:22:45,278] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 61%|▌| 1629/2654 [30:42<19:19, 1.13s/it, v_num=hk35, train/loss=6.030[2023-07-10 22:22:56,639] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 62%|▌| 1639/2654 [30:53<19:07, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:23:08,040] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 62%|▌| 1649/2654 [31:04<18:56, 1.13s/it, v_num=hk35, train/loss=6.090[2023-07-10 22:23:19,427] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 63%|▋| 1659/2654 [31:16<18:45, 1.13s/it, v_num=hk35, train/loss=6.030[2023-07-10 22:23:30,883] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 63%|▋| 1669/2654 [31:27<18:33, 1.13s/it, v_num=hk35, train/loss=5.810[2023-07-10 22:23:42,142] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 63%|▋| 1679/2654 [31:38<18:22, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:23:53,573] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 64%|▋| 1689/2654 [31:50<18:11, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:24:04,876] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 64%|▋| 1699/2654 [32:01<18:00, 1.13s/it, v_num=hk35, train/loss=6.250[2023-07-10 22:24:16,269] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 64%|▋| 1709/2654 [32:12<17:48, 1.13s/it, v_num=hk35, train/loss=7.380[2023-07-10 22:24:27,538] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 65%|▋| 1719/2654 [32:24<17:37, 1.13s/it, v_num=hk35, train/loss=5.620[2023-07-10 22:24:38,866] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 65%|▋| 1729/2654 [32:35<17:26, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:24:50,204] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 66%|▋| 1739/2654 [32:46<17:14, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:25:01,578] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 66%|▋| 1749/2654 [32:58<17:03, 1.13s/it, v_num=hk35, train/loss=5.910[2023-07-10 22:25:12,928] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 66%|▋| 1759/2654 [33:09<16:52, 1.13s/it, v_num=hk35, train/loss=6.250[2023-07-10 22:25:24,343] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 67%|▋| 1769/2654 [33:21<16:41, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:25:35,588] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 67%|▋| 1779/2654 [33:32<16:29, 1.13s/it, v_num=hk35, train/loss=6.090[2023-07-10 22:25:46,927] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 67%|▋| 1789/2654 [33:43<16:18, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:25:58,230] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 68%|▋| 1799/2654 [33:54<16:07, 1.13s/it, v_num=hk35, train/loss=6.660[2023-07-10 22:26:09,581] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 68%|▋| 1809/2654 [34:06<15:55, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:26:21,121] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 69%|▋| 1819/2654 [34:18<15:44, 1.13s/it, v_num=hk35, train/loss=5.410[2023-07-10 22:26:32,953] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 69%|▋| 1829/2654 [34:29<15:33, 1.13s/it, v_num=hk35, train/loss=5.970[2023-07-10 22:26:44,268] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 69%|▋| 1839/2654 [34:40<15:22, 1.13s/it, v_num=hk35, train/loss=6.410[2023-07-10 22:26:55,633] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 70%|▋| 1849/2654 [34:52<15:10, 1.13s/it, v_num=hk35, train/loss=5.970[2023-07-10 22:27:06,846] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 70%|▋| 1859/2654 [35:03<14:59, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:27:18,153] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 70%|▋| 1869/2654 [35:14<14:48, 1.13s/it, v_num=hk35, train/loss=5.380[2023-07-10 22:27:29,397] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 71%|▋| 1879/2654 [35:26<14:36, 1.13s/it, v_num=hk35, train/loss=6.030[2023-07-10 22:27:40,695] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 71%|▋| 1889/2654 [35:37<14:25, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:27:51,898] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 72%|▋| 1899/2654 [35:48<14:14, 1.13s/it, v_num=hk35, train/loss=6.190[2023-07-10 22:28:03,188] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 72%|▋| 1909/2654 [35:59<14:02, 1.13s/it, v_num=hk35, train/loss=5.250[2023-07-10 22:28:14,419] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 72%|▋| 1919/2654 [36:11<13:51, 1.13s/it, v_num=hk35, train/loss=6.030[2023-07-10 22:28:25,885] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 73%|▋| 1929/2654 [36:22<13:40, 1.13s/it, v_num=hk35, train/loss=6.190[2023-07-10 22:28:37,288] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 73%|▋| 1939/2654 [36:34<13:29, 1.13s/it, v_num=hk35, train/loss=6.440[2023-07-10 22:28:48,745] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 73%|▋| 1949/2654 [36:45<13:17, 1.13s/it, v_num=hk35, train/loss=6.090[2023-07-10 22:29:00,118] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 74%|▋| 1959/2654 [36:56<13:06, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:29:11,577] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 74%|▋| 1969/2654 [37:08<12:55, 1.13s/it, v_num=hk35, train/loss=8.750[2023-07-10 22:29:22,924] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 75%|▋| 1979/2654 [37:19<12:43, 1.13s/it, v_num=hk35, train/loss=6.190[2023-07-10 22:29:34,275] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 75%|▋| 1989/2654 [37:30<12:32, 1.13s/it, v_num=hk35, train/loss=6.090[2023-07-10 22:29:45,560] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 75%|▊| 1999/2654 [37:42<12:21, 1.13s/it, v_num=hk35, train/loss=5.620[2023-07-10 22:29:56,929] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 76%|▊| 2009/2654 [37:53<12:09, 1.13s/it, v_num=hk35, train/loss=6.280[2023-07-10 22:30:08,217] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 76%|▊| 2019/2654 [38:04<11:58, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:30:19,485] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 76%|▊| 2029/2654 [38:16<11:47, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:30:30,813] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 77%|▊| 2039/2654 [38:27<11:35, 1.13s/it, v_num=hk35, train/loss=5.690[2023-07-10 22:30:42,129] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 77%|▊| 2049/2654 [38:38<11:24, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:30:53,384] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 78%|▊| 2059/2654 [38:50<11:13, 1.13s/it, v_num=hk35, train/loss=5.690[2023-07-10 22:31:04,745] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 78%|▊| 2069/2654 [39:01<11:02, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:31:16,025] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 78%|▊| 2079/2654 [39:12<10:50, 1.13s/it, v_num=hk35, train/loss=5.560[2023-07-10 22:31:27,390] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 79%|▊| 2089/2654 [39:24<10:39, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:31:38,638] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 79%|▊| 2099/2654 [39:35<10:28, 1.13s/it, v_num=hk35, train/loss=6.250[2023-07-10 22:31:49,889] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 79%|▊| 2109/2654 [39:46<10:16, 1.13s/it, v_num=hk35, train/loss=5.910[2023-07-10 22:32:01,038] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 80%|▊| 2119/2654 [39:57<10:05, 1.13s/it, v_num=hk35, train/loss=6.160[2023-07-10 22:32:12,201] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 80%|▊| 2129/2654 [40:08<09:53, 1.13s/it, v_num=hk35, train/loss=4.340[2023-07-10 22:32:23,308] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 81%|▊| 2139/2654 [40:20<09:42, 1.13s/it, v_num=hk35, train/loss=5.880[2023-07-10 22:32:34,711] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 81%|▊| 2149/2654 [40:31<09:31, 1.13s/it, v_num=hk35, train/loss=5.410[2023-07-10 22:32:45,989] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 81%|▊| 2159/2654 [40:42<09:20, 1.13s/it, v_num=hk35, train/loss=6.060[2023-07-10 22:32:57,285] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 82%|▊| 2169/2654 [40:54<09:08, 1.13s/it, v_num=hk35, train/loss=5.970[2023-07-10 22:33:08,645] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 82%|▊| 2179/2654 [41:05<08:57, 1.13s/it, v_num=hk35, train/loss=5.810[2023-07-10 22:33:20,033] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 82%|▊| 2189/2654 [41:16<08:46, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:33:31,312] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 83%|▊| 2199/2654 [41:27<08:34, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:33:42,553] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 83%|▊| 2209/2654 [41:39<08:23, 1.13s/it, v_num=hk35, train/loss=5.910[2023-07-10 22:33:53,755] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 84%|▊| 2219/2654 [41:50<08:12, 1.13s/it, v_num=hk35, train/loss=5.380[2023-07-10 22:34:05,014] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 84%|▊| 2229/2654 [42:01<08:00, 1.13s/it, v_num=hk35, train/loss=5.500[2023-07-10 22:34:16,286] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 84%|▊| 2239/2654 [42:12<07:49, 1.13s/it, v_num=hk35, train/loss=5.440[2023-07-10 22:34:27,645] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 85%|▊| 2249/2654 [42:24<07:38, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:34:39,136] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 85%|▊| 2259/2654 [42:35<07:26, 1.13s/it, v_num=hk35, train/loss=5.310[2023-07-10 22:34:50,478] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 85%|▊| 2269/2654 [42:47<07:15, 1.13s/it, v_num=hk35, train/loss=5.250[2023-07-10 22:35:01,680] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 86%|▊| 2279/2654 [42:58<07:04, 1.13s/it, v_num=hk35, train/loss=2.890[2023-07-10 22:35:12,925] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 86%|▊| 2289/2654 [43:09<06:52, 1.13s/it, v_num=hk35, train/loss=5.250[2023-07-10 22:35:24,304] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 87%|▊| 2299/2654 [43:21<06:41, 1.13s/it, v_num=hk35, train/loss=5.380[2023-07-10 22:35:35,757] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 87%|▊| 2309/2654 [43:32<06:30, 1.13s/it, v_num=hk35, train/loss=5.940[2023-07-10 22:35:47,053] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 87%|▊| 2319/2654 [43:43<06:19, 1.13s/it, v_num=hk35, train/loss=5.280[2023-07-10 22:35:58,413] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 88%|▉| 2329/2654 [43:55<06:07, 1.13s/it, v_num=hk35, train/loss=5.500[2023-07-10 22:36:09,706] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 88%|▉| 2339/2654 [44:06<05:56, 1.13s/it, v_num=hk35, train/loss=6.000[2023-07-10 22:36:21,229] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 89%|▉| 2349/2654 [44:17<05:45, 1.13s/it, v_num=hk35, train/loss=5.560[2023-07-10 22:36:32,477] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 89%|▉| 2359/2654 [44:29<05:33, 1.13s/it, v_num=hk35, train/loss=5.880[2023-07-10 22:36:43,866] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 89%|▉| 2369/2654 [44:40<05:22, 1.13s/it, v_num=hk35, train/loss=6.120[2023-07-10 22:36:55,220] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 90%|▉| 2379/2654 [44:52<05:11, 1.13s/it, v_num=hk35, train/loss=5.120[2023-07-10 22:37:06,706] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 90%|▉| 2389/2654 [45:03<04:59, 1.13s/it, v_num=hk35, train/loss=4.750[2023-07-10 22:37:18,021] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 90%|▉| 2399/2654 [45:14<04:48, 1.13s/it, v_num=hk35, train/loss=6.030[2023-07-10 22:37:29,421] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 91%|▉| 2409/2654 [45:26<04:37, 1.13s/it, v_num=hk35, train/loss=5.810[2023-07-10 22:37:40,743] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 91%|▉| 2419/2654 [45:37<04:25, 1.13s/it, v_num=hk35, train/loss=5.810[2023-07-10 22:37:52,197] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 92%|▉| 2429/2654 [45:48<04:14, 1.13s/it, v_num=hk35, train/loss=5.530[2023-07-10 22:38:03,481] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 92%|▉| 2439/2654 [46:00<04:03, 1.13s/it, v_num=hk35, train/loss=5.840[2023-07-10 22:38:14,861] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 92%|▉| 2449/2654 [46:11<03:52, 1.13s/it, v_num=hk35, train/loss=5.940[2023-07-10 22:38:26,179] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 93%|▉| 2459/2654 [46:22<03:40, 1.13s/it, v_num=hk35, train/loss=5.690[2023-07-10 22:38:37,681] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 93%|▉| 2469/2654 [46:34<03:29, 1.13s/it, v_num=hk35, train/loss=5.470[2023-07-10 22:38:49,131] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 93%|▉| 2479/2654 [46:45<03:18, 1.13s/it, v_num=hk35, train/loss=3.700[2023-07-10 22:39:00,473] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 94%|▉| 2489/2654 [46:57<03:06, 1.13s/it, v_num=hk35, train/loss=5.690[2023-07-10 22:39:11,799] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 94%|▉| 2499/2654 [47:08<02:55, 1.13s/it, v_num=hk35, train/loss=6.470[2023-07-10 22:39:23,145] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 95%|▉| 2509/2654 [47:19<02:44, 1.13s/it, v_num=hk35, train/loss=5.440[2023-07-10 22:39:34,446] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 95%|▉| 2519/2654 [47:31<02:32, 1.13s/it, v_num=hk35, train/loss=5.590[2023-07-10 22:39:45,813] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 95%|▉| 2529/2654 [47:42<02:21, 1.13s/it, v_num=hk35, train/loss=5.940[2023-07-10 22:39:57,083] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 96%|▉| 2539/2654 [47:53<02:10, 1.13s/it, v_num=hk35, train/loss=5.380[2023-07-10 22:40:08,459] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 96%|▉| 2549/2654 [48:05<01:58, 1.13s/it, v_num=hk35, train/loss=6.000[2023-07-10 22:40:19,836] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 96%|▉| 2559/2654 [48:16<01:47, 1.13s/it, v_num=hk35, train/loss=5.340[2023-07-10 22:40:31,201] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 97%|▉| 2569/2654 [48:27<01:36, 1.13s/it, v_num=hk35, train/loss=5.280[2023-07-10 22:40:42,540] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 97%|▉| 2579/2654 [48:39<01:24, 1.13s/it, v_num=hk35, train/loss=5.970[2023-07-10 22:40:54,033] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 98%|▉| 2589/2654 [48:50<01:13, 1.13s/it, v_num=hk35, train/loss=5.470[2023-07-10 22:41:05,393] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 98%|▉| 2599/2654 [49:02<01:02, 1.13s/it, v_num=hk35, train/loss=5.250[2023-07-10 22:41:16,745] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 98%|▉| 2609/2654 [49:13<00:50, 1.13s/it, v_num=hk35, train/loss=4.160[2023-07-10 22:41:28,049] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 99%|▉| 2619/2654 [49:24<00:39, 1.13s/it, v_num=hk35, train/loss=6.220[2023-07-10 22:41:39,405] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 99%|▉| 2629/2654 [49:36<00:28, 1.13s/it, v_num=hk35, train/loss=5.780[2023-07-10 22:41:50,716] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 99%|▉| 2639/2654 [49:47<00:16, 1.13s/it, v_num=hk35, train/loss=5.720[2023-07-10 22:42:02,073] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 100%|▉| 2649/2654 [49:58<00:05, 1.13s/it, v_num=hk35, train/loss=6.090[2023-07-10 22:42:13,337] [WARNING] [stage3.py:1832:step] 2 pytorch allocator cache flushes since last step. this happens when there is high memory pressure and is detrimental to performance. if this is happening frequently consider adjusting settings to reduce memory consumption. If you are unable to make the cache flushes go away consider adding get_accelerator().empty_cache() calls in your training loop to ensure that all ranks flush their caches at the same time\n", + "Epoch 0: 100%|█| 2654/2654 [50:04<00:00, 1.13s/it, v_num=hk35, train/loss=6.060\n", + "Validation: 0it [00:00, ?it/s]\u001b[A\n", + "Validation: 0%| | 0/27 [00:00) and the tensors embedded in it cannot be detected. The ZeRO-3 hooks designed to trigger before or after backward pass of the module relies on knowing the input and output tensors and therefore may not get triggered properly.\n", + "Epoch 0: 100%|█| 2654/2654 [1:28:53<00:00, 2.01s/it, v_num=3yg1, train/loss=6.0\n", + "Validation: 0it [00:00, ?it/s]\u001b[A\n", + "Validation: 0%| | 0/27 [00:00` script, - # which will create a `rwkv_model.pth` in the checkpoint directory. - # - # Do not use the `zero_to_fp32.py` script as that will have export format issues - dirpath: ../checkpoint/trainer-validaiton/infctx-validation-last-segment - filename: null - - # Save the top/last K checkpoints - save_top_k: 3 - # Choose by the most recent checkpoints (step based) - monitor: 'step' - mode: max - - # If enabled (true), save a copy of the latest checkpoint to 'last.ckpt' - # useful to simply checkpoint resume scripts, at a price of disk performance - save_last: false - - # DO NOT set this as true, as the model weight exported will have format issues - # expert as checkpoint, and use the `export_checkpoint.py` script to convert to model instead - save_weights_only: false - - # How frequent you want to save a checkpoint for every step. - # This will happen for every X data sample, where X = every_n_train_steps * accumulate_grad_batches - # - # In general you will want to avoid putting a low number (expecially if accumulate_grad_batches <= 100) - # as the checkpoint process, will pause all the gpu training for some time, slowing down the overall process - # However you do not want to configure too high of a number, where you will lose too much progress if the training crashes - every_n_train_steps: 5000 - every_n_epochs: null - save_on_train_epoch_end: true - train_time_interval: null - - # Other settings, you can probably leave alone - verbose: false - auto_insert_metric_name: true - - ######################################## - ## Training run parameter settings - ######################################## - - # Generally what you want to configure is the maximum number of epochs - # Leave it as -1, and it will keep going forever till interrupted - # Or set it as a number, and it will stop after that number of epochs - max_epochs: 1 - min_epochs: null - max_steps: -1 - min_steps: null - max_time: null - - # Number of datasamples to train for each step, a data sample is considered - # a "substep" in wandb logs, and a "step" is tracked as "trainer/global_step" - # - # This decides the number of datasample, to learn together from, before backproping - # any weight changes at the end of the batch. - # - # Recommended to be a big enough number (like 128/256) where it prevents the training - # loss from flucuating in the process. But not too big of a number where the increased - # GPU vRAM / offloaded RAM usage will cause the training to crash. - # - # You are also recommended to configure this to a large enough number to fully utilize - # your GPU processing time %, and avoid idle time for the GPU between batches - accumulate_grad_batches: 12 - - # Various other settings, you probably want to leave alone - fast_dev_run: false - limit_train_batches: null - limit_val_batches: null - limit_test_batches: null - limit_predict_batches: null - overfit_batches: 0.0 - val_check_interval: null - check_val_every_n_epoch: 1 - num_sanity_val_steps: 0 - log_every_n_steps: 1 - enable_checkpointing: true - enable_progress_bar: null - enable_model_summary: null - gradient_clip_val: 1.0 - gradient_clip_algorithm: null - deterministic: null - benchmark: null - inference_mode: true - use_distributed_sampler: true - profiler: null - detect_anomaly: false - barebones: false - plugins: null - sync_batchnorm: false - reload_dataloaders_every_n_epochs: 0 - default_root_dir: null - -######################################## -## Training model settings -######################################## -model: - # Model to start the finetune/training process from - load_model: ../model/Echo-A-1B5-Init.pth - - # The model size setting, this MUST match - # your current model settings, refer to the model card - # of the downloaded model for more details - n_embd: 2048 - n_layer: 24 - vocab_size: 50277 - - # Context length to use for the training process - # the larger the number (and batch size) the larger the vram usage - # - # Note that if the datasample context length is larger then the ctx_len - # its training process would be split into ctx_len sized chunks. - # - # This allows the training of extreamly large context length (eg. 100k), - # without eating up too much vram by keeping the training context length - # to a resonable number sutible to the current GPU setup - ctx_len: 128 - - # Data samples would be cut down to the respective max ctx_len_cutoffs - # values if its larger then ctx_len. If the data sample is larger then - # the largest len_cutoff, the remaining data will be discarded - ctx_len_cutoffs: [1024, 2048, 4096, 8192, 16384, 32768, 65536] - # Experimental settings, number of tokens to skip in the data sample - # prefix, for the respective cutoff length. Used to speed up the process - ctx_len_warmup_steps: [0, 0, 0, 0, 0, 0, 0] - - # Learning rate of the training process - # --- - # Initia learning rate of the process - lr_init: 6e-4 - # Final learning rate after the learning rate period - # learning rate will stay at final value from then onwards - # - # NOTE: lr_final / lr_period does not work with warmup_steps - # and will be ignored (or replaced) with the warmup_steps logic instead - lr_final: 4e-4 - # Number of epoch to reduce the learning rate from lr_init to lr_final - # 1 means a single epoch (so lr would be lr_final from epoch 2 onwards) - # 0 means lr_final will apply immediately - # -1 means we take the current max_step / max_epoch as the period - lr_period: 1 - # lr_period type if its set, defaults to epoch - lr_period_type: epoch - - # Adam optimizer settings - # You probably want to leave this alone, unless you know what you are doing - beta1: 0.9 - beta2: 0.99 - adam_eps: 1.0e-08 - weight_decay: 0.01 - - # torch.set_float32_matmul_precision, used to optimize operations with tensor cores - # this should be set as null, for non cuda core GPUs - torch_set_float32_matmul_precision: 'high' - # torch_set_float32_matmul_precision: null - - # Segmented based learning, used to work around training of large context length - # beyond what can be supported by the current GPU vram architecture - # - # This is not 1:1 equivalent to the same training process with required vram - # as the training process is split into multiple segments, part by part. - # with limited learnings from the previous segment. - bptt_learning: true - - # Segmented range to performing backprop learning on - # 1 means to apply only for the last segment - # -1 means to apply for all segments - bptt_learning_range: 1 - - # various other settings you probably should leave alone - grad_cp: true - warmup_steps: -1 - layerwise_lr: true - dim_att: null - dim_ffn: null -data: - # dataset_path for the prebuilt dataset, using HF `load_from_disk()` - # - # Use this if you have built your own dataset and saved it with `save_to_disk()` - # with source left as null. Other wise configure this to a directory which the - # dataset will be built and tokenized by the huggingface dataset process. - data_path: ../datapath/enwiki_10k_1024/ - - # Other wise provide the source path, which is used as huggingface dataset path - # this will be used to populate the dataset_path - # - # Use either the following - # - hugging face dataset - # - Directory path to a directory containing dataset files - # - Path to a single dataset file - # - hugging face dataset mode (ie: text,csv,etc - use data_dir, to configure the path then) - # - null - # - # If source is disabled, all other params, except data_path, is ignored - source: "teven/enwiki_10k" - # source: text - # source: /home/ubuntu/RWKV-LM-LoRA/dataset-text/enwik8.txt - - # Use data_dir, if you are using source=text/json/etc - # this should be relative to the data_path - source_data_dir: null - - # After loading the dataset, split out test data used for validation, - # This process is skipped if the dataset includes a test split - # This process is skipped if set to zero - test_split: 0.01 - test_split_shuffle: false - - # Tokenizer to use, use either the inbuilt 'neox', or 'world' tokenizer - # If using a custom tokenizer, provide the tokenizer file path - # --- - tokenizer: neox - - # Minimum / Maximum token size of the dataset to use - # useful for filtering out small noisy data samples from large datasets - # (eg. removal of small articles of less then 512 tokens from wikipedia) - # - # This is ignored, if set to -1 - min_token_size: 64 - max_token_size: -1 - - # Rechunking of text dataset, this is done only when source is set as 'text' - # and will merge the various sentencees, into larger chunks up to the target size - # - # Defaults to 4096 - # - # This is ignored, if source is not set as text - # This is ignored, if set to zero - # --- - text_rechunk_size: 1024 - - # Apply text rechunk to the dataset, even if its not a 'text' source - # This is done only after dataset filtering, and if source is not 'text' - # --- - text_rechunk_force: true - - # Custom text column to use, useful for dataset with alternative training columns labels - # This is checked before multi column merging, default is null (disabled) - # eg: 'code' - # --- - # custom_text_key: 'code' - - # Multi Column merging process, default setting is used to support and merge - # "instruction", "input", "output", datasets. To disable set multi_column_keys to [] - # - # A minimum of 2 columns is required, with non empty data, for the merge to occur - # If no match is found, this will fallback to the default prompt/completion or text column, - # or throw an error if the default fallback is not found - # --- - # multi_column_keys: ['instruction', 'input', 'output'] - # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] - # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' - - # If processing prompt/completion jsonl pairs, the prompt is masked by default - # use this flag to disable this default behaviour - # --- - # disable_prompt_mask: false - -# Path to the current checkpoint to continue training from -# Enable this to the last checkpoint after the first run -# (if it crash and you want to resume) -# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-dryrun/epoch=0-step=20.ckpt -ckpt_path: null diff --git a/notebook/trainer-validation/infctx-validation-segmented-512.yaml b/notebook/trainer-validation/infctx-validation-segmented-512.yaml deleted file mode 100644 index 3b8f015c..00000000 --- a/notebook/trainer-validation/infctx-validation-segmented-512.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# lightning.pytorch==2.0.2 -seed_everything: 3941088705 -trainer: - # Configure the number of GPU, avaliable on your machine - accelerator: gpu - devices: 1 - num_nodes: 1 - - # - # Configure the deepspeed strategy, we recommend you start with `deepspeed_stage_2_offload` - # and adjust from there according to your training needs. `deepspeed_stage_3_offload` is useful - # for training LoRA on large models on a single GPU. - # - # In general you would want to use the following: - # - # - deepspeed_stage_1 : Each of your GPU has too much vram, and you do not know what to do - # - # - deepspeed_stage_2 : Optimal distributed training strategy, across multiple gpu each with sufficient vram - # - deepspeed_stage_2_offload : Reduce vram usage by offloading the optimizer state and work to cpu - # - # - deepspeed_stage_3 : Split up the model across multiple gpu, useful for large models, at a performance cost - # - deepspeed_stage_3_offload : Additional offloading, for even greater performance cost - # - # For more details see: - # https://lightning.ai/docs/pytorch/stable/advanced/model_parallel.html#deepspeed-zero-stage-2 - # - strategy: deepspeed_stage_2_offload - - # Floating point precision for the model, because RWKV is built FOR bf16 - # you should pretty much never change this setting - precision: bf16 - - # Logger setting for wandb, if you want to enable wandb, uncomment the whole logger section - # --- - logger: - class_path: lightning.pytorch.loggers.WandbLogger - init_args: - name: 'infctx-validation-512-segmented (train-ctx=512, data-ctx=1024, bs=12)' - project: 'RWKV-infctx-validation' - tags: ['RWKV', 'infctx'] - id: null - save_dir: . - version: null - offline: false - dir: null - anonymous: null - log_model: false - experiment: null - prefix: '' - checkpoint_name: null - job_type: null - config: null - entity: null - reinit: null - group: null - notes: null - magic: null - config_exclude_keys: null - config_include_keys: null - mode: null - allow_val_change: null - resume: null - force: null - tensorboard: null - sync_tensorboard: null - monitor_gym: null - save_code: null - settings: null - - # Checkpoint settings for the training process - callbacks: - - class_path: lightning.pytorch.callbacks.ModelCheckpoint - init_args: - # Configure this to the path you want to save your checkpoints to - # note that a subdir will be created with the name `epoch=x-step=y.ckpt` - # - # to convert a checkpoint to a model, you can use the - # `python3 export_checkpoint.py ` script, - # which will create a `rwkv_model.pth` in the checkpoint directory. - # - # Do not use the `zero_to_fp32.py` script as that will have export format issues - dirpath: ../checkpoint/trainer-validaiton/infctx-validation-segment-512 - filename: null - - # Save the top/last K checkpoints - save_top_k: 3 - # Choose by the most recent checkpoints (step based) - monitor: 'step' - mode: max - - # If enabled (true), save a copy of the latest checkpoint to 'last.ckpt' - # useful to simply checkpoint resume scripts, at a price of disk performance - save_last: false - - # DO NOT set this as true, as the model weight exported will have format issues - # expert as checkpoint, and use the `export_checkpoint.py` script to convert to model instead - save_weights_only: false - - # How frequent you want to save a checkpoint for every step. - # This will happen for every X data sample, where X = every_n_train_steps * accumulate_grad_batches - # - # In general you will want to avoid putting a low number (expecially if accumulate_grad_batches <= 100) - # as the checkpoint process, will pause all the gpu training for some time, slowing down the overall process - # However you do not want to configure too high of a number, where you will lose too much progress if the training crashes - every_n_train_steps: 5000 - every_n_epochs: null - save_on_train_epoch_end: true - train_time_interval: null - - # Other settings, you can probably leave alone - verbose: false - auto_insert_metric_name: true - - ######################################## - ## Training run parameter settings - ######################################## - - # Generally what you want to configure is the maximum number of epochs - # Leave it as -1, and it will keep going forever till interrupted - # Or set it as a number, and it will stop after that number of epochs - max_epochs: 1 - min_epochs: null - max_steps: -1 - min_steps: null - max_time: null - - # Number of datasamples to train for each step, a data sample is considered - # a "substep" in wandb logs, and a "step" is tracked as "trainer/global_step" - # - # This decides the number of datasample, to learn together from, before backproping - # any weight changes at the end of the batch. - # - # Recommended to be a big enough number (like 128/256) where it prevents the training - # loss from flucuating in the process. But not too big of a number where the increased - # GPU vRAM / offloaded RAM usage will cause the training to crash. - # - # You are also recommended to configure this to a large enough number to fully utilize - # your GPU processing time %, and avoid idle time for the GPU between batches - accumulate_grad_batches: 12 - - # Various other settings, you probably want to leave alone - fast_dev_run: false - limit_train_batches: null - limit_val_batches: null - limit_test_batches: null - limit_predict_batches: null - overfit_batches: 0.0 - val_check_interval: null - check_val_every_n_epoch: 1 - num_sanity_val_steps: 0 - log_every_n_steps: 1 - enable_checkpointing: true - enable_progress_bar: null - enable_model_summary: null - gradient_clip_val: 1.0 - gradient_clip_algorithm: null - deterministic: null - benchmark: null - inference_mode: true - use_distributed_sampler: true - profiler: null - detect_anomaly: false - barebones: false - plugins: null - sync_batchnorm: false - reload_dataloaders_every_n_epochs: 0 - default_root_dir: null - -######################################## -## Training model settings -######################################## -model: - # Model to start the finetune/training process from - load_model: ../model/Echo-A-1B5-Init.pth - - # The model size setting, this MUST match - # your current model settings, refer to the model card - # of the downloaded model for more details - n_embd: 2048 - n_layer: 24 - vocab_size: 50277 - - # Context length to use for the training process - # the larger the number (and batch size) the larger the vram usage - # - # Note that if the datasample context length is larger then the ctx_len - # its training process would be split into ctx_len sized chunks. - # - # This allows the training of extreamly large context length (eg. 100k), - # without eating up too much vram by keeping the training context length - # to a resonable number sutible to the current GPU setup - ctx_len: 512 - - # Data samples would be cut down to the respective max ctx_len_cutoffs - # values if its larger then ctx_len. If the data sample is larger then - # the largest len_cutoff, the remaining data will be discarded - ctx_len_cutoffs: [1024, 2048, 4096, 8192, 16384, 32768, 65536] - # Experimental settings, number of tokens to skip in the data sample - # prefix, for the respective cutoff length. Used to speed up the process - ctx_len_warmup_steps: [0, 0, 0, 0, 0, 0, 0] - - # Learning rate of the training process - # --- - # Initia learning rate of the process - lr_init: 6e-4 - # Final learning rate after the learning rate period - # learning rate will stay at final value from then onwards - # - # NOTE: lr_final / lr_period does not work with warmup_steps - # and will be ignored (or replaced) with the warmup_steps logic instead - lr_final: 4e-4 - # Number of epoch to reduce the learning rate from lr_init to lr_final - # 1 means a single epoch (so lr would be lr_final from epoch 2 onwards) - # 0 means lr_final will apply immediately - # -1 means we take the current max_step / max_epoch as the period - lr_period: 1 - # lr_period type if its set, defaults to epoch - lr_period_type: epoch - - # Adam optimizer settings - # You probably want to leave this alone, unless you know what you are doing - beta1: 0.9 - beta2: 0.99 - adam_eps: 1.0e-08 - weight_decay: 0.01 - - # torch.set_float32_matmul_precision, used to optimize operations with tensor cores - # this should be set as null, for non cuda core GPUs - torch_set_float32_matmul_precision: 'high' - # torch_set_float32_matmul_precision: null - - # Segmented based learning, used to work around training of large context length - # beyond what can be supported by the current GPU vram architecture - # - # This is not 1:1 equivalent to the same training process with required vram - # as the training process is split into multiple segments, part by part. - # with limited learnings from the previous segment. - bptt_learning: true - - # Segmented range to performing backprop learning on - # 1 means to apply only for the last segment - # -1 means to apply for all segments - bptt_learning_range: 1 - - # various other settings you probably should leave alone - grad_cp: true - warmup_steps: -1 - layerwise_lr: true - dim_att: null - dim_ffn: null -data: - # dataset_path for the prebuilt dataset, using HF `load_from_disk()` - # - # Use this if you have built your own dataset and saved it with `save_to_disk()` - # with source left as null. Other wise configure this to a directory which the - # dataset will be built and tokenized by the huggingface dataset process. - data_path: ../datapath/enwiki_10k_1024/ - - # Other wise provide the source path, which is used as huggingface dataset path - # this will be used to populate the dataset_path - # - # Use either the following - # - hugging face dataset - # - Directory path to a directory containing dataset files - # - Path to a single dataset file - # - hugging face dataset mode (ie: text,csv,etc - use data_dir, to configure the path then) - # - null - # - # If source is disabled, all other params, except data_path, is ignored - source: "teven/enwiki_10k" - # source: text - # source: /home/ubuntu/RWKV-LM-LoRA/dataset-text/enwik8.txt - - # Use data_dir, if you are using source=text/json/etc - # this should be relative to the data_path - source_data_dir: null - - # After loading the dataset, split out test data used for validation, - # This process is skipped if the dataset includes a test split - # This process is skipped if set to zero - test_split: 0.01 - test_split_shuffle: false - - # Tokenizer to use, use either the inbuilt 'neox', or 'world' tokenizer - # If using a custom tokenizer, provide the tokenizer file path - # --- - tokenizer: neox - - # Minimum / Maximum token size of the dataset to use - # useful for filtering out small noisy data samples from large datasets - # (eg. removal of small articles of less then 512 tokens from wikipedia) - # - # This is ignored, if set to -1 - min_token_size: 64 - max_token_size: -1 - - # Rechunking of text dataset, this is done only when source is set as 'text' - # and will merge the various sentencees, into larger chunks up to the target size - # - # Defaults to 4096 - # - # This is ignored, if source is not set as text - # This is ignored, if set to zero - # --- - text_rechunk_size: 1024 - - # Apply text rechunk to the dataset, even if its not a 'text' source - # This is done only after dataset filtering, and if source is not 'text' - # --- - text_rechunk_force: true - - # Custom text column to use, useful for dataset with alternative training columns labels - # This is checked before multi column merging, default is null (disabled) - # eg: 'code' - # --- - # custom_text_key: 'code' - - # Multi Column merging process, default setting is used to support and merge - # "instruction", "input", "output", datasets. To disable set multi_column_keys to [] - # - # A minimum of 2 columns is required, with non empty data, for the merge to occur - # If no match is found, this will fallback to the default prompt/completion or text column, - # or throw an error if the default fallback is not found - # --- - # multi_column_keys: ['instruction', 'input', 'output'] - # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] - # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' - - # If processing prompt/completion jsonl pairs, the prompt is masked by default - # use this flag to disable this default behaviour - # --- - # disable_prompt_mask: false - -# Path to the current checkpoint to continue training from -# Enable this to the last checkpoint after the first run -# (if it crash and you want to resume) -# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-dryrun/epoch=0-step=20.ckpt -ckpt_path: null diff --git a/notebook/trainer-validation/logs/torch-compile-perf_baseline.log b/notebook/trainer-validation/logs/torch-compile-perf_baseline.log new file mode 100644 index 00000000..7162a4da --- /dev/null +++ b/notebook/trainer-validation/logs/torch-compile-perf_baseline.log @@ -0,0 +1,1010 @@ +[2023-07-08 17:51:59,139] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect) +[RWKV.model] Running RWKV model via the following optimization mode : torch-native +ninja: no work to do. +[2023-07-08 17:52:12,529] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented +[2023-07-08 17:52:12,530] [WARNING] [deepspeed.py:638:_auto_select_batch_size] Tried to infer the batch size for internal deepspeed logging from the `train_dataloader()`. To ensure DeepSpeed logging remains correct, please manually pass the plugin with the batch size, `Trainer(strategy=DeepSpeedStrategy(logging_batch_size_per_gpu=batch_size))`. +[WARNING]: it is highly recommended to enable bptt_learning when used to deepspeed 2/3/offloading, otherwise an exception will occur when training with dataset records, larger then the configured context length (4096) +ninja: no work to do. +Time to load cpu_adam op: 2.326359748840332 seconds +Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] + Training: 0it [00:00, ?it/s] Training: 0%| | 0/1315 [00:00` script, - # which will create a `rwkv_model.pth` in the checkpoint directory. - # - # Do not use the `zero_to_fp32.py` script as that will have export format issues - dirpath: ../checkpoint/trainer-validaiton/matmul-medium - filename: null - - # Save the top/last K checkpoints - save_top_k: 3 - # Choose by the most recent checkpoints (step based) - monitor: 'step' - mode: max - - # If enabled (true), save a copy of the latest checkpoint to 'last.ckpt' - # useful to simply checkpoint resume scripts, at a price of disk performance - save_last: false - - # DO NOT set this as true, as the model weight exported will have format issues - # expert as checkpoint, and use the `export_checkpoint.py` script to convert to model instead - save_weights_only: false - - # How frequent you want to save a checkpoint for every step. - # This will happen for every X data sample, where X = every_n_train_steps * accumulate_grad_batches - # - # In general you will want to avoid putting a low number (expecially if accumulate_grad_batches <= 100) - # as the checkpoint process, will pause all the gpu training for some time, slowing down the overall process - # However you do not want to configure too high of a number, where you will lose too much progress if the training crashes - every_n_train_steps: 5000 - every_n_epochs: null - save_on_train_epoch_end: true - train_time_interval: null - - # Other settings, you can probably leave alone - verbose: false - auto_insert_metric_name: true - - ######################################## - ## Training run parameter settings - ######################################## - - # Generally what you want to configure is the maximum number of epochs - # Leave it as -1, and it will keep going forever till interrupted - # Or set it as a number, and it will stop after that number of epochs - max_epochs: 1 - min_epochs: null - max_steps: -1 - min_steps: null - max_time: null - - # Number of datasamples to train for each step, a data sample is considered - # a "substep" in wandb logs, and a "step" is tracked as "trainer/global_step" - # - # This decides the number of datasample, to learn together from, before backproping - # any weight changes at the end of the batch. - # - # Recommended to be a big enough number (like 128/256) where it prevents the training - # loss from flucuating in the process. But not too big of a number where the increased - # GPU vRAM / offloaded RAM usage will cause the training to crash. - # - # You are also recommended to configure this to a large enough number to fully utilize - # your GPU processing time %, and avoid idle time for the GPU between batches - accumulate_grad_batches: 12 - - # Various other settings, you probably want to leave alone - fast_dev_run: false - limit_train_batches: null - limit_val_batches: null - limit_test_batches: null - limit_predict_batches: null - overfit_batches: 0.0 - val_check_interval: null - check_val_every_n_epoch: 1 - num_sanity_val_steps: 0 - log_every_n_steps: 1 - enable_checkpointing: true - enable_progress_bar: null - enable_model_summary: null - gradient_clip_val: 1.0 - gradient_clip_algorithm: null - deterministic: null - benchmark: null - inference_mode: true - use_distributed_sampler: true - profiler: null - detect_anomaly: false - barebones: false - plugins: null - sync_batchnorm: false - reload_dataloaders_every_n_epochs: 0 - default_root_dir: null - -######################################## -## Training model settings -######################################## -model: - # Model to start the finetune/training process from - load_model: ../model/Echo-A-1B5-Init.pth - - # The model size setting, this MUST match - # your current model settings, refer to the model card - # of the downloaded model for more details - n_embd: 2048 - n_layer: 24 - vocab_size: 50277 - - # Context length to use for the training process - # the larger the number (and batch size) the larger the vram usage - # - # Note that if the datasample context length is larger then the ctx_len - # its training process would be split into ctx_len sized chunks. - # - # This allows the training of extreamly large context length (eg. 100k), - # without eating up too much vram by keeping the training context length - # to a resonable number sutible to the current GPU setup - ctx_len: 1024 - - # Data samples would be cut down to the respective max ctx_len_cutoffs - # values if its larger then ctx_len. If the data sample is larger then - # the largest len_cutoff, the remaining data will be discarded - ctx_len_cutoffs: [1024, 2048, 4096, 8192, 16384, 32768, 65536] - # Experimental settings, number of tokens to skip in the data sample - # prefix, for the respective cutoff length. Used to speed up the process - ctx_len_warmup_steps: [0, 0, 0, 0, 0, 0, 0] - - # Learning rate of the training process - # --- - # Initia learning rate of the process - lr_init: 6e-4 - # Final learning rate after the learning rate period - # learning rate will stay at final value from then onwards - # - # NOTE: lr_final / lr_period does not work with warmup_steps - # and will be ignored (or replaced) with the warmup_steps logic instead - lr_final: 4e-4 - # Number of epoch to reduce the learning rate from lr_init to lr_final - # 1 means a single epoch (so lr would be lr_final from epoch 2 onwards) - # 0 means lr_final will apply immediately - # -1 means we take the current max_step / max_epoch as the period - lr_period: 1 - # lr_period type if its set, defaults to epoch - lr_period_type: epoch - - # Adam optimizer settings - # You probably want to leave this alone, unless you know what you are doing - beta1: 0.9 - beta2: 0.99 - adam_eps: 1.0e-08 - weight_decay: 0.01 - - # torch.set_float32_matmul_precision, used to optimize operations with tensor cores - # this should be set as null, for non cuda core GPUs - torch_set_float32_matmul_precision: 'medium' - # torch_set_float32_matmul_precision: null - - # Segmented based learning, used to work around training of large context length - # beyond what can be supported by the current GPU vram architecture - # - # This is not 1:1 equivalent to the same training process with required vram - # as the training process is split into multiple segments, part by part. - # with limited learnings from the previous segment. - bptt_learning: false - - # Segmented range to performing backprop learning on - # 1 means to apply only for the last segment - # -1 means to apply for all segments - bptt_learning_range: -1 - - # various other settings you probably should leave alone - grad_cp: true - warmup_steps: -1 - layerwise_lr: true - dim_att: null - dim_ffn: null -data: - # dataset_path for the prebuilt dataset, using HF `load_from_disk()` - # - # Use this if you have built your own dataset and saved it with `save_to_disk()` - # with source left as null. Other wise configure this to a directory which the - # dataset will be built and tokenized by the huggingface dataset process. - data_path: ../datapath/enwiki_10k_1024/ - - # Other wise provide the source path, which is used as huggingface dataset path - # this will be used to populate the dataset_path - # - # Use either the following - # - hugging face dataset - # - Directory path to a directory containing dataset files - # - Path to a single dataset file - # - hugging face dataset mode (ie: text,csv,etc - use data_dir, to configure the path then) - # - null - # - # If source is disabled, all other params, except data_path, is ignored - source: "teven/enwiki_10k" - # source: text - # source: /home/ubuntu/RWKV-LM-LoRA/dataset-text/enwik8.txt - - # Use data_dir, if you are using source=text/json/etc - # this should be relative to the data_path - source_data_dir: null - - # After loading the dataset, split out test data used for validation, - # This process is skipped if the dataset includes a test split - # This process is skipped if set to zero - test_split: 0.01 - test_split_shuffle: false - - # Tokenizer to use, use either the inbuilt 'neox', or 'world' tokenizer - # If using a custom tokenizer, provide the tokenizer file path - # --- - tokenizer: neox - - # Minimum / Maximum token size of the dataset to use - # useful for filtering out small noisy data samples from large datasets - # (eg. removal of small articles of less then 512 tokens from wikipedia) - # - # This is ignored, if set to -1 - min_token_size: 64 - max_token_size: -1 - - # Rechunking of text dataset, this is done only when source is set as 'text' - # and will merge the various sentencees, into larger chunks up to the target size - # - # Defaults to 4096 - # - # This is ignored, if source is not set as text - # This is ignored, if set to zero - # --- - text_rechunk_size: 1024 - - # Apply text rechunk to the dataset, even if its not a 'text' source - # This is done only after dataset filtering, and if source is not 'text' - # --- - text_rechunk_force: true - - # Custom text column to use, useful for dataset with alternative training columns labels - # This is checked before multi column merging, default is null (disabled) - # eg: 'code' - # --- - # custom_text_key: 'code' - - # Multi Column merging process, default setting is used to support and merge - # "instruction", "input", "output", datasets. To disable set multi_column_keys to [] - # - # A minimum of 2 columns is required, with non empty data, for the merge to occur - # If no match is found, this will fallback to the default prompt/completion or text column, - # or throw an error if the default fallback is not found - # --- - # multi_column_keys: ['instruction', 'input', 'output'] - # multi_column_prefix: ['Instruction:\n', 'Input:\n', 'Output:\n'] - # multi_column_masking: [false, true, false] - # multi_column_seperator: '\n\n' - - # If processing prompt/completion jsonl pairs, the prompt is masked by default - # use this flag to disable this default behaviour - # --- - # disable_prompt_mask: false - -# Path to the current checkpoint to continue training from -# Enable this to the last checkpoint after the first run -# (if it crash and you want to resume) -# ckpt_path: ../checkpoint/trainer-validaiton/infctx-validation-dryrun/epoch=0-step=20.ckpt -ckpt_path: null diff --git a/notebook/trainer-validation/matmul-precision.ipynb b/notebook/trainer-validation/matmul-precision.ipynb index ea23420c..1c931249 100644 --- a/notebook/trainer-validation/matmul-precision.ipynb +++ b/notebook/trainer-validation/matmul-precision.ipynb @@ -12,7 +12,9 @@ "\n", "The goal is to validate that lower matmul accuracy has now negative impact on loss training\n", "\n", - "> This project assumes you have the rwkv-infctx conda env setup, and you are executing in that environment - see the main README.md for the conda env setup steps" + "> This project assumes you have the rwkv-infctx conda env setup, and you are executing in that environment - see the main README.md for the conda env setup steps\n", + ">\n", + "> And that you have completed the `baseline-setup.ipynb`" ] }, { @@ -20,61 +22,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Preparing the init model and test dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# First lets setup the various directories, and get the blank init model, these init model was generated\n", - "# using the original RWKV-LM repo (as at this point of writing, this repo cannot init a model)\n", - "# As such I have preinitialized these blank models and uploaded them to HF for convinence\n", - "!mkdir -p ../../model/\n", - "!mkdir -p ../../datapath/\n", - "!mkdir -p ../../checkpoint/\n", - "!rm -rf ../../model/Echo-A-1B5-Init.pth\n", - "!cd ../../model/ && wget https://huggingface.co/picocreator/memory-size-experiment-for-rwkv/resolve/main/Echo-A-1B5-Init.pth\n", - "!ls -alh ../../model/Echo-A-1B5-Init.pth" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found cached dataset parquet (/home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", - "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 986.66it/s]\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-3d43d1724bef83d7_*_of_00016.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-5033407f38c97f24.arrow\n", - "Loading cached processed dataset at /home/picocreator/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-78e7f3a5f1679aa4_*_of_00016.arrow\n", - " \r" - ] - } - ], - "source": [ - "# Lets preload the requried dataset\n", - "!cd ../../RWKV-v4neo && python3 preload_dataset.py ../notebook/trainer-validation/infctx-validation-dryrun.yaml" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Baseline full context (1024) training\n", + "# (optional) Baseline full context (1024) training\n", "\n", - "Perform a full 1 epoch training run of training context size = 1024. Ensuring all data samples fit within the allocated training size.\n", + "(you can skip this, and use the optional baseline found in `baseline-setup.ipynb`)\n", "\n", - "(this is the same baseline as infctx-validation)\n", - "\n", - "> PS: Weights and biases logging is enabled" + "Perform a full 1 epoch training run of training context size = 1024. Ensuring all data samples fit within the allocated training size." ] }, { @@ -229,8 +181,9 @@ } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/infctx-validation-full.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml" ] }, { @@ -396,8 +349,11 @@ } ], "source": [ - "# Full training run\n", - "!cd ../../RWKV-v4neo && python3 new_train.py fit -c ../notebook/trainer-validation/matmul-medium-precision.yaml" + "!cd ../../RWKV-v4neo && \\\n", + " python3 new_train.py fit \\\n", + " -c ../notebook/trainer-validation/config/baseline-1024.yaml\n", + " --trainer.logger.init_args.name=\"infctx-validation-baseline (matmul_precision='medium', train-ctx=1024, data-ctx=1024, bs=10)\" \\\n", + " --model.torch_set_float32_matmul_precision=\"medium\"" ] } ], diff --git a/notebook/trainer-validation/torch-compile-perf-a10g-ds2o.ipynb b/notebook/trainer-validation/torch-compile-perf-a10g-ds2o.ipynb new file mode 100644 index 00000000..cd1e856d --- /dev/null +++ b/notebook/trainer-validation/torch-compile-perf-a10g-ds2o.ipynb @@ -0,0 +1,1747 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# torch.compile performance uplift validation\n", + "The following trainer validation, is used to compare performance differences between the following optimizations\n", + "\n", + "- torch native\n", + "- torch + JIT\n", + "- torch + torch.compile\n", + "\n", + "It presumes that basic setup has been done as per\n", + "- `./baseline-setup.ipynb`\n", + "\n", + "To simplify the benchmarking, we are intentionally only performing\n", + "- training & data ctx len fixed at 4096\n", + "- a 100 trainer/global_step\n", + "- of 10 gradient accumulation (per GPU)\n", + "- no checkpoint save to disk (reduce the influence of random diskio in timings)\n", + "\n", + "This would (on a single GPU) perform the run over\n", + "- a 1000 data samples\n", + "\n", + "\n", + "The following experiments were executed on a single `a10g` gpu `g5.8xlarge` AWS instance for consistency. With `deepspeed_stage_2_offload`" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Install the nightly build within conda\n", + "(Skip if you already have 2.1.0, or already done the setup)\n", + "\n", + "For torch.compile, as of 8th July 2023, you will need the torch nightly build for several fixes we depend on. This is expected to be resolved when merged in for torch 2.1.0 release (you will need to perform this setup outside the notebook)\n", + "\n", + "```bash\n", + "conda activate rwkv-infctx\n", + "conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch-nightly -c nvidia\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure and apply your preferred settings\n", + "\n", + "Adjust your desired deepspeed settings, and gpu device count.\n", + "Enable/Disable WANDB here as well (recommended disabled, to reduce perf impact)\n", + "\n", + "( note you will need to rerun this cell, if you restart your env )" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DEEPSPEED_STRAT: deepspeed_stage_2_offload\n", + "ENABLE_WANDB: False\n", + "GPU_DEVICES: auto\n" + ] + } + ], + "source": [ + "DEEPSPEED_STRAT=\"deepspeed_stage_2_offload\"\n", + "GPU_DEVICES=\"auto\"\n", + "ENABLE_WANDB=False\n", + "\n", + "print(\"DEEPSPEED_STRAT:\", DEEPSPEED_STRAT)\n", + "print(\"ENABLE_WANDB:\", ENABLE_WANDB)\n", + "print(\"GPU_DEVICES:\", GPU_DEVICES)\n", + "\n", + "if ENABLE_WANDB:\n", + " WANDB_MODE=\"online\"\n", + "else:\n", + " WANDB_MODE=\"disabled\"\n", + "\n", + "# Ensure logs dir is initialized\n", + "!mkdir -p \"./logs/torch-compile-perf/{DEEPSPEED_STRAT}/\"" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Preload your data\n", + "The data has minor differences from baseline, and needs to be preloaded here" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found cached dataset parquet (/home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 977.69it/s]\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-0b77c6df8d77d6b6_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-f32adc0b9b83547d_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-9a2bc99bc09b7d14_*_of_00032.arrow\n", + " \r" + ] + } + ], + "source": [ + "!cd ../../RWKV-v4neo && python3 preload_dataset.py ../notebook/trainer-validation/config/torch-compile-perf.yaml" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Perform baseline benchmark (no JIT / no toch compile)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2023-07-08 17:51:59,139] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", + "[RWKV.model] Running RWKV model via the following optimization mode : torch-native\n", + "Global seed set to 3941088705\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/wkv_4096_bf16/build.ninja...\n", + "Building extension module wkv_4096_bf16...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module wkv_4096_bf16...\n", + "/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + " rank_zero_warn(\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "Found cached dataset parquet (/home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 945.09it/s]\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-0b77c6df8d77d6b6_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-f32adc0b9b83547d_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-9a2bc99bc09b7d14_*_of_00032.arrow\n", + "[rank: 0] Global seed set to 3941088705 \n", + "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/1\n", + "[2023-07-08 17:52:12,529] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "[2023-07-08 17:52:12,530] [WARNING] [deepspeed.py:638:_auto_select_batch_size] Tried to infer the batch size for internal deepspeed logging from the `train_dataloader()`. To ensure DeepSpeed logging remains correct, please manually pass the plugin with the batch size, `Trainer(strategy=DeepSpeedStrategy(logging_batch_size_per_gpu=batch_size))`.\n", + "Enabling DeepSpeed BF16.\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", + "[WARNING]: it is highly recommended to enable bptt_learning when used to deepspeed 2/3/offloading, otherwise an exception will occur when training with dataset records, larger then the configured context length (4096)\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/cpu_adam/build.ninja...\n", + "Building extension module cpu_adam...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module cpu_adam...\n", + "Time to load cpu_adam op: 2.326359748840332 seconds\n", + "Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] \n", + "\n", + " | Name | Type | Params\n", + "--------------------------------------\n", + "0 | emb | Embedding | 102 M \n", + "1 | blocks | ModuleList | 1.3 B \n", + "2 | ln_out | LayerNorm | 4.1 K \n", + "3 | head | Linear | 102 M \n", + "--------------------------------------\n", + "1.5 B Trainable params\n", + "0 Non-trainable params\n", + "1.5 B Total params\n", + "6,060.425 Total estimated model params size (MB)\n", + "Epoch 0: 0%| | 0/1315 [00:00=1.0.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.1.0)\n", + "Requirement already satisfied: cycler>=0.10 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (0.11.0)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (4.40.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.4.4)\n", + "Requirement already satisfied: numpy>=1.20 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.25.0)\n", + "Requirement already satisfied: packaging>=20.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (22.0)\n", + "Requirement already satisfied: pillow>=6.2.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (9.3.0)\n", + "Requirement already satisfied: pyparsing<3.1,>=2.3.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (3.0.9)\n", + "Requirement already satisfied: python-dateutil>=2.7 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (2.8.2)\n", + "Requirement already satisfied: six>=1.5 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n" + ] + } + ], + "source": [ + "# Install matlab plotting library\n", + "!python3 -m pip install matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First step figures ...\n", + "Baseline: {'it': 1, 'time': 9, 's_time': '00:09', 'loss': 10.9}\n", + "JIT: {'it': 1, 'time': 13, 's_time': '00:13', 'loss': 10.9}\n", + "Torch Compile: {'it': 1, 'time': 72, 's_time': '01:12', 'loss': 10.9}\n", + "\n", + "First 200 step figures ...\n", + "Baseline: {'it': 101, 'time': 175, 's_time': '02:55', 'loss': 8.38}\n", + "JIT: {'it': 101, 'time': 172, 's_time': '02:52', 'loss': 8.38}\n", + "Torch Compile: {'it': 101, 'time': 225, 's_time': '03:45', 'loss': 8.38}\n", + "\n", + "Last step figures ...\n", + "Baseline: {'it': 1000, 'time': 1464, 's_time': '24:24', 'loss': 6.62}\n", + "JIT: {'it': 1000, 'time': 1407, 's_time': '23:27', 'loss': 6.66}\n", + "Torch Compile: {'it': 1000, 'time': 1399, 's_time': '23:19', 'loss': 6.66}\n" + ] + } + ], + "source": [ + "# First we need to extract the numbers from the logs\n", + "import re\n", + "\n", + "def convert_time_to_seconds(time_str):\n", + " t = list(map(int, time_str.split(':')))\n", + " return sum([a*b for (a,b) in zip(t[::-1], (1, 60, 3600))])\n", + "\n", + "def extract_from_training_logs(log_file):\n", + " result = []\n", + " with open(log_file, 'r') as file:\n", + " for line in file.readlines():\n", + " # Check if the line starts with \"Epoch 0:\"\n", + " if line.startswith(\"Epoch 0:\"):\n", + " iteration = re.search(r'(?<=\\| )(\\d+)', line) # Extracts the iteration number\n", + " time_spent = re.search(r'(?<=\\[)(.*?)(?=<)', line) # Extracts the time spent so far\n", + " loss = re.search(r'(?<=train/loss=)(\\d+.\\d+)', line) # Extracts the train/loss number\n", + " \n", + " if iteration and time_spent and loss:\n", + " result.append({\n", + " \"it\": int(iteration.group(0)), \n", + " \"time\": convert_time_to_seconds(time_spent.group(0)),\n", + " \"s_time\": time_spent.group(0),\n", + " \"loss\": float(loss.group(0))\n", + " })\n", + " return result\n", + "\n", + "\n", + "# Extract the numbers\n", + "step_baseline = extract_from_training_logs(\"./logs/torch-compile-perf/{DEEPSPEED_STRAT}/baseline.log\")\n", + "step_jit = extract_from_training_logs(\"./logs/torch-compile-perf/{DEEPSPEED_STRAT}/jit.log\")\n", + "step_tcompile = extract_from_training_logs(\"./logs/torch-compile-perf/{DEEPSPEED_STRAT}/torch-compile.log\")\n", + "\n", + "# Print the high level numbers (quick debugging, if log has issues)\n", + "print(\"First step figures ...\")\n", + "print(\"Baseline: \", step_baseline[0])\n", + "print(\"JIT: \", step_jit[0])\n", + "print(\"Torch Compile: \", step_tcompile[0])\n", + "print(\"\")\n", + "print(\"First 200 step figures ...\")\n", + "print(\"Baseline: \", step_baseline[200])\n", + "print(\"JIT: \", step_jit[200])\n", + "print(\"Torch Compile: \", step_tcompile[200])\n", + "print(\"\")\n", + "print(\"Last step figures ...\")\n", + "print(\"Baseline: \", step_baseline[-1])\n", + "print(\"JIT: \", step_jit[-1])\n", + "print(\"Torch Compile: \", step_tcompile[-1])\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Check if the loss plot is similar\n", + "\n", + "No point having a faster JIT / torch.compile, if the loss curve does not fall at the same rate" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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jEZjVzdDCCHEXiZDS91fR/0Oe1zPjBBCCCH2L10azFitVlatWhWsH5Ofn8+qVavYuXMnAFVVVaxatYoNGzYAsGnTJlatWkVJSUlXNVkIIYTo1gYMGMBjjz0WfB6rzlt306XBzPLlyxk/fjzjx48H4LrrrmP8+PHcdtttAHz88ceMHz+emTNnAnDOOecwfvx4nnnmmS5rsxBCCNFeF110EYqiBH8yMjI44YQTWLNmTZe1qbi4uNkyKd1Bl+bMTJ06FVVV4+6/6KKLuOiiizqvQW1Q5/RQUlGI3VYUsX1g7wOwJKV3UauEEELs60444QTmz58PBKaY33LLLZx00knBUYnOlpOT0yXX7UiSM9NOr/62g7veuJ4Lfrsi4ueUt46k1lrV1c0TQgixjzIajeTk5JCTk8O4ceO46aabKCwspLy8HIAbb7yRYcOGkZCQwKBBg7j11lsjZvusXr2aadOmkZycTEpKCgcffDDLly8P7v/555858sgjMZvN9O3bl2uuuQabzRa3PeHDTAUFBSiKwvvvv8+0adNISEhg7NixLF68OOKctl5jb5Ngpp10GgUNGox+NfgDUKHTsG3n2i5unRBC7F9UVcXu9nbJT3MjDC2xWq28+uqrDBkyJFgzJzk5mZdeeokNGzbwn//8h+eff55HH300eM75559Pnz59WLZsGb///js33XQTer0egG3btnHCCSdw+umns2bNGt566y1+/vlnrrrqqja1a968eVx//fWsWrWKYcOGce655+L1ejv0Gh2px03N7iyXTxnM5VPejdg2Yf6BODQSHwohRGdzeHwccNuXXXLtDXdNJ8HQ+tvpp59+SlJSEhBYgzA3N5dPP/0UTcP945ZbbgkeO2DAAK6//nrefPNN/vnPfwKwc+dObrjhBkaMGAHA0KFDg8fff//9nH/++cydOze47/HHH+eoo47i6aefxmQytaqN119/fTBf9c477+TAAw9k69atjBgxosOu0ZHkziuEEEJ0omnTpgVn8i5dupTp06czY8YMduzYAcBbb73FEUccQU5ODklJSdxyyy0R+TTXXXcdl156KcceeywPPPAA27ZtC+5bvXo1L730EklJScGf6dOn4/f7yc/Pb3Ubx4wZE3zcuNRA49IDHXWNjiQ9Mx3IgRHw4EvK7uqmCCHEfsWs17Lhrulddu22SExMZMiQIcHnL7zw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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the loss curve\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Extract iteration and loss values for each method\n", + "it_baseline = [entry['it'] for entry in step_baseline]\n", + "loss_baseline = [entry['loss'] for entry in step_baseline]\n", + "\n", + "it_jit = [entry['it'] for entry in step_jit]\n", + "loss_jit = [entry['loss'] for entry in step_jit]\n", + "\n", + "it_tcompile = [entry['it'] for entry in step_tcompile]\n", + "loss_tcompile = [entry['loss'] for entry in step_tcompile]\n", + "\n", + "# Plot loss curves\n", + "plt.plot(it_baseline, loss_baseline, label=\"Baseline\", linestyle='-')\n", + "plt.plot(it_jit, loss_jit, label=\"JIT\", linestyle='--')\n", + "plt.plot(it_tcompile, loss_tcompile, label=\"TCompile\", linestyle='-.')\n", + "\n", + "plt.xlabel('Iteration step')\n", + "plt.ylabel('Loss')\n", + "plt.title('Loss Curve')\n", + "plt.legend()\n", + "\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working as designed, it should be nearly impossible to see the differences between the 3 lines. So lets plot the delta against baseline instead." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAHHCAYAAACvJxw8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAD1F0lEQVR4nOydd3gc1dWH3+3SatWr1WVb7nLvBRvcwDRTTEkCDiSkEloghN4SCCQEAiGYhMBHwCQ2zTRjXAH33m3Zsq0uq5fVqm2b74/Rrna1Ratmyfi+z6NHuzN37tyZnZk9e+4556eQJElCIBAIBAKBQOAVZV8PQCAQCAQCgaA/I4wlgUAgEAgEAj8IY0kgEAgEAoHAD8JYEggEAoFAIPCDMJYEAoFAIBAI/CCMJYFAIBAIBAI/CGNJIBAIBAKBwA/CWBIIBAKBQCDwgzCWBAKBQCAQCPwgjCXB95pvvvkGhULBN99809dDEZwjFi1axB133NHXw/he8OSTT6JQKPp6GP0Wb8+XH//4x6Snp/fqftesWYPBYKCioqJX9yNoQxhLgj7n//7v/1AoFM6/oKAgEhMTWbhwIa+88gr19fU9ur/333+fl19+uUf7BJgzZw6jRo3q8X57A5vNxttvv82cOXOIiopCp9ORnp7Obbfdxp49e/p6eF1m69atrF27lgcffLCvh3JB0Zv3lOuzQavVkpGRwc9+9jMKCwt7fH/nC5deeimDBw/mueee6+uhXDAIY0nQb3j66ad59913ef311/nNb34DwD333ENWVhaHDh3qsf301oP9fKGpqYkrrriC22+/HUmSePjhh3n99de59dZb2b59O5MnT6aoqKivh9kl/vznPzN37lwGDx7c10O5oOjNeyo5OZl3332Xd999l2XLlnHdddfx/vvvM3PmTBobG3tln93hX//6FydOnOj1/fz85z/njTfe6PEfkwLvqPt6AAKBg8suu4yJEyc63z/00ENs3LiRK664gquuuorjx48THBzchyP8fvDAAw+wZs0aXnrpJe655x63dU888QQvvfRSj+zHbrdjNpsJCgrqkf46ory8nC+//JJly5adk/31Z5qbm9FqtSiV5//v4fDwcH70ox+5LcvIyODOO+9k69atzJ8/v49G5h2NRnNO9nPdddfxm9/8hg8++IDbb7/9nOzzQub8v5ME32suueQSHnvs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s2fPDvhYA6GkpMRtPEajkf/85z+MHTvWmRavUqk8PFIffPBBwPEyEyZMYNCgQfzlL39xMyocOO4TlUrFwoULWbVqFQUFBc71x48f5+uvvw5oX77uqd46r5s2bcJkMrl5Jr2dr1dffdXDC1pVVeX23mAwMHjwYOd9093nS1fpyn737t3LtGnTemU8AneEZ0nQb/jqq6/Izs7GarVSVlbGxo0bWbduHWlpaXz22WduxQ1fe+01Zs6cSVZWFnfccQcDBw6krKyM7du3U1RU5FGLxpUJEyawYsUK7rvvPiZNmoTBYODKK6/kiiuu4OOPP+aaa67h8ssvJzc3l2XLljFixAivXzbeqKiocHp+XHEYew899BBPPfUUl156KVdddRUnTpzgH//4B5MmTXIW3tu4cSN33nknS5YsYciQIVitVt59911UKhXXXXcdIMddfPfdd1x++eWkpaVRXl7OP/7xD5KTk5k5c6bfMb744oucPn2au+66i48//pgrrriCyMhICgoK+OCDD8jOznam89900008+OCDXHPNNdx11100Njby+uuvM2TIkE4Hvd944428+uqrPPHEE2RlZTnjVhzccsstrFy5kl/84hds2rSJGTNmYLPZyM7OZuXKlXz99dduRUvbc/nll6NWq1m/fj0/+9nPnMsfeOABPvzwQ5YsWcLtt9/OhAkTqK6u5rPPPmPZsmWMGTOGn/3sZ7zxxhv8+Mc/Zu/evaSnp/Phhx+ydetWXn755R4PiB8yZAg/+clP2L17N/Hx8bz11luUlZXx9ttvO9tcccUVPP3009x2221Mnz6dw4cPs3z5cjevpD+USiVvvvkml112GSNHjuS2224jKSmJ4uJiNm3aRFhYGJ9//jkATz31FGvWrGHWrFn86le/cho0I0eODKh6vq97qifOa11dnbPGmtVqdZbbCA4O5ve//73b+Xr33XcJDw9nxIgRbN++nfXr1xMdHe3W34gRI5gzZw4TJkwgKiqKPXv28OGHH3LnnXc623Tn+dIdOrPf8vJyDh06xK9//eteGYugHX2SgycQuOAoHeD402q1UkJCgjR//nzpb3/7m8/04tOnT0u33nqrlJCQIGk0GikpKUm64oorpA8//NDZxltqr8lkkn7wgx9IEREREuBM87Xb7dKzzz4rpaWlSTqdTho3bpz0xRdf+Eyfb4+vNGdAmjt3rrPd3//+d2nYsGGSRqOR4uPjpV/+8pdSTU2Nc/2ZM2ek22+/XRo0aJAUFBQkRUVFSRdffLG0fv16Z5sNGzZIV199tZSYmChptVopMTFRuvnmm6WTJ08GdM6tVqv05ptvSrNmzZLCw8MljUYjpaWlSbfddptHWYG1a9dKo0aNkrRarTR06FDpvffe81k64Ne//rXPfdrtdiklJUUCpD/84Q9e25jNZun555+XRo4cKel0OikyMlKaMGGC9NRTT0l1dXUdHtdVV13ldq4dVFVVSXfeeaeUlJQkabVaKTk5WVq6dKlUWVnpbFNWVibddtttUkxMjKTVaqWsrCzp7bffduvHkQb+5z//2W254zprX+7BW1mMtLQ06fLLL5e+/vprafTo0ZJOp5OGDRvmsW1zc7P029/+VhowYIAUHBwszZgxQ9q+fbs0e/Zsafbs2R3u28H+/fula6+9VoqOjpZ0Op2UlpYm3XDDDdKGDRvc2n377bfShAkTJK1WKw0cOFBatmyZ18/ZG77uKUkK7Lz6ov09pVAopKioKOmqq66S9u7d69a2pqbGuR+DwSAtXLhQys7OltLS0qSlS5c62/3hD3+QJk+eLEVEREjBwcHSsGHDpD/+8Y+S2Wx266+rzxdfpQPaXzOSJN8zTzzxRKf3K0mS9Prrr0t6vb7D8guCnkEhSV2IPBQIBIJ+yObNm5kzZw7Z2dles7v6A+np6YwaNYovvviir4ciOI8ZN24cc+bM6TF5IoF/RMySQCD43jBr1iwWLFjACy+80NdDEQh6jTVr1pCTk8NDDz3U10O5YBCeJYFAIDiHCM+SQHD+ITxLAoFAIBAIBH4QniWBQCAQCAQCPwjPkkAgEAgEAoEfhLEkEAgEAoFA4AdRlLIHsNvtlJSUEBoaKgQNBQKBQCA4T5Akifr6ehITEz0En10RxlIPUFJS0qHIp0AgEAgEgv5JYWEhycnJPtcLY6kHcJTsLywsJCwsrMf6tVgsrF27lgULFqDRaHqsX4E74jyfG8R5PneIc31uEOf53NCb59loNJKSktKh9I4wlnoAx9RbWFhYjxtLer2esLAwcSP2IuI8nxvEeT53iHN9bhDn+dxwLs5zRyE0IsBbIBAIBAKBwA/CWBIIBAKBQCDwgzCWBAKBQCAQCPwgjCWBQCAQCAQCPwhjSSAQCAQCgcAPwlgSCAQCgUAg8IMwlgQCgUAgEAj8IIwlgUAgEAgEAj8IY0kgEAgEAoHAD8JYEggEAoFAIPCDMJYEAoFAIBAI/CCMJYFAIBAIBAI/CGNJIOgCjY1gsfT1KAQCwYWE0QiS5GOl3Q4mU9c7N5uhubnr27siSR59GeskjEXGnum/DxDGkkDQSfLz4f774eGH5eeLQCAQ9DZr1sADD8C//+2jwZ/+JD+Y9uzpfOeNjfDgg/Db38LZs90aJwAtLfJgq6oAWLUKPlr8Hw7Mf4Bdj33e/f77AGEsCQSdpKgIbDb5V15NTV+PRiAQXAjkvreViaf+R/76HO8N8vNlj87Ro53vvKJCNpisVigp6d5AAT7+WP4l2Wp4rVkDA8u2A3ByR3X3++8D1H09AIGgz8jOhpdeQmm3o77kkr4ejUAgEPgkvuIIMSX7qNMPADL7ejj+yctzeytJYNQPILyhhDNxU/tmTN1EeJYEFy7Vbb9wVC0tfTgQgUAg8E9oQykAk0+9771BbKz8Pzj4HI3owkIYSwKBQCAQ9HM0lkb/DcaMkf+ruzBhlJICycmd384bZ87IU4LtUNvkgO8g8/kZ5C2m4QQCgUAgON+JioK0NIiM7Py2SiX8/vfyfFlXjC1XrFavi0OaZU/+lBPvAJO6t48+QBhLAoFAIBCc7xgMMHcujB/fte01mp4dz/cMYSwJBAKBQHC+89Zb8v8RIzpv+FRVwerVEBIC117b82MDjPp4whrLaNR1wfPVDxAxSwKBQCAQXMiYTLBlC3z9tUcmW7dISXG+PJp8qbyr4Lie6/8cIowlgUAgEAj6OQeG3wxAszbUf8M1a7q3o9ZCkt1mwAAID++ZvvoBYhpOcOEybRpkZmI3mzHv3NnXoxEIBAKftOjCALCqgvw3bOwga66PCLbIWXBKu/cA8P6OMJYEFy4KhVybxGJBUqn6ejQCgUDgk+rwDJbPWgbAoj4ei190Ovn/2bNQV+f0Lo3N/QSAGOPpvhpZtxDTcAKBQCAQ9HNSzu5iXN4nxNTn9vVQ/JOWJv8BFBZ6rC6JyjrHA+oZhGdJcOFy8iS8+KIsdzJ3bl+PRiAQCHySWH6AmMJ9mHTRwMC+Hk6nqQtJJLyhhJykOX09lC4hPEuCC5fKSudLVXNzHw5EIBAI/GNoKANg4pkV3hs4gqmDOohpEnQJYSwJBAKBQNDP0VoaAFDabd4bTGqtit2V4pJJSRDXQyn9eXle5U5UNjMAWmv/DEDvCDENJxAIBALB+U5YmJyuH9pBaQFvqNXw0ENgs3VfiNds9rrY0Cx78qcd/zfw9+7tow8QxpJAIBAIBOc7cXFw9dWQ1cUAar2+Z8fzPUNMwwkEAoFAcL6zbJn819TU+W2rq2HlSvjii54fVysNQVEANGvPz0KVwlgSCAQCgeBCpr4eNmyAzz+HgoKe6zcpyfnyUOqVABj1CT3X/zlEGEsCgUAgEPRzDg+9HgCzuoPpsvXru7ejiorube9gwACIPD9Fc71x3hlLr732Gunp6QQFBTFlyhR27drlt/0HH3zAsGHDCAoKIisri9WrV3u0OX78OFdddRXh4eGEhIQwadIkCnrSuhb0TyZPht//Hvvvfoc5LKyvRyMQCAQ+aQyOBsCsCfHf0Gg8B6PpPFqbPD2okHxk8/VzzitjacWKFdx333088cQT7Nu3jzFjxrBw4ULKy8u9tt+2bRs333wzP/nJT9i/fz+LFy9m8eLFHDlyxNnm9OnTzJw5k2HDhvHNN99w6NAhHnvsMYJErYrvP2o1ZGRAerqQOxEIBP2amvB0Vkz/G1+Of6yvh+IfrVb+f/asPL3XyoTTKwGIrTvVF6PqNueVsfTXv/6VO+64g9tuu40RI0awbNky9Ho9b731ltf2f/vb37j00kt54IEHGD58OM888wzjx4/n739vS1t85JFHWLRoES+88ALjxo1j0KBBXHXVVcT1VM0JwXmBpdqM3Wrv62F0i6YmsFj6ehQCwfeE5mb5pvKRCt9l6uu7dKMmlu1nePF6whpLsVvt1JfU+27c3AwtLd0YpBdMJrAH8IxMT0dKTcNsBntuPiaT++qyyOGd2q3RCJLUqU16hfOmdIDZbGbv3r089NBDzmVKpZJ58+axfft2r9ts376d++67z23ZwoULWbVqFQB2u50vv/yS3/3udyxcuJD9+/eTkZHBQw89xOLFi32OpaWlhRaXC9HY6va0WCxYevDbytFXT/YpcOH0aZQvvkh5qUTwgUa2rDzNRZ/9tsPNrFYFdrsCAIvF3i8MlIIC+POflej18PTTdqeWZX9CXM/nDnGuu4kkoXjvPRQ7d4Jej/3pp72m1nf2PCt27kTxzjvYf/UrGDWqU0NKLNlFbNF+mtR6vr16Bcozpwi/6xZG/nQqAEqHIVNWBvfdByoV9ieflOsvdYTF4tzebrV6GnP79qH8978hJQX7gw/KIuR+OHzATv0RifI7VrNuzHAkCWr1CYQ3nuVY4sUBn69PPlGwbp2C6dPtREX1zvUcaJ/njbFUWVmJzWYjPj7ebXl8fDzZ2dletyktLfXavrS0FIDy8nJMJhN/+tOf+MMf/sDzzz/PmjVruPbaa9m0aROzZ8/22u9zzz3HU0895bF87dq16HuhVsW6det6vE8BRGZnk1pQQEFBKKCl+cghrzFt7Tl+PIqCghQANmzIJiKih3/BdYHs7Ehyc1MB+OCDbKKi+n5MvhDX87lDnOuuoS8tJfPjj53vT65cSZOf2YZAz3Pili3EFhRQt2wZeYsWdWpMluITmEwmBh9+l0a7fH8XL/+K/MRqAEaVlqIym6nW69E1NqKrrSVv5UoaEhM77Du4vJwhrXG6eVu2UNf6HekgZdMmovLzIT+fg1lZHRpLlQdNJDSZ0JsOEGt5l4PR06itM6JqMVFSUsLq1TkBHfO//z0GkH8M/upXvXM9NzYGVlH8vDGWegN7qyV99dVXc++99wIwduxYtm3bxrJly3waSw899JCbx8poNJKSksKCBQsI68FAYYvFwrp165g/fz6arpSwF/hFERmJ4tQp6usl6k2NhISEMCOAB1hEhILTp+WHxdy5SbSzx/uEROMJphY8C8DAyc+RMKT/BayL6/ncIc51Nzl1CuWePc63SRdfDGlpHs06e54VJhOK2lqSFyxgRCeNpS1/3IJSMrS+k/cVkpjofGYpGhtRbNxI8owZKA4dAo2GtNmzITOz484tFpQnTkBdHUkzZ8L48e7jbmpC0dAAgweTtGiRf2MpP59tqi/BII91QdM2jIlXE1kVgqHJQEpCLIsWef9ubY/phWUkVx+mMDILSO2V69kYYED8eWMsxcTEoFKpKCsrc1teVlZGQoL3ug0JCQl+28fExKBWqxkxYoRbm+HDh7NlyxafY9HpdOi8zHNoNJpeeTD1Vr8XPGo1KJUoFPKEuEKhCOg8t24GgEaj6pIUU08T1GikCfkBprWY+/X1Iq7nc4c4111Eo2m7yQGVRuNXcy3g8+x4eKjVndZwUyiUKFrv8aLoMSRXHcSsj2zbb3g4xMTIcicqFSiVHY7b5QDg8cfBYkFlMHhuo9XK4x44EJUjgNsXdrtznA5Gnt1EeFMFoOCi4/9CowlM7iSl+gigIKXmMLWk9sr1HGh/502At1arZcKECWzYsMG5zG63s2HDBqZNm+Z1m2nTprm1B9mN52iv1WqZNGkSJ06ccGtz8uRJ0rz8ihB8v7EpxZeKQCAA3n67d/tfvRo6KHvjj9oQudijpHTJ4k1Lgx/9CMaMgXbTaAERFgbR0fRGwGNwS22P93muOW88SwD33XcfS5cuZeLEiUyePJmXX36ZhoYGbrvtNgBuvfVWkpKSeO655wC4++67mT17Ni+++CKXX345//vf/9izZw///Oc/nX0+8MAD3HjjjVx00UVcfPHFrFmzhs8//5xvvvmmLw5R0EecDBuNMmUUl/T1QAQCQd/T3Nz7+wgwVsYbNqUGsyYEu9rFy/PKK/L/pUs732FNDXz7rRzEvmCB53pHRuD69XD99R3GLHmjWRtKkLmeZk3/CxEIhPPKWLrxxhupqKjg8ccfp7S0lLFjx7JmzRpnEHdBQQFKF9fp9OnTef/993n00Ud5+OGHyczMZNWqVYxyyUK45pprWLZsGc899xx33XUXQ4cO5aOPPmLmzJnn/PgEfcf+6Jnokyb29TAEAkF/4+KLITm5r0fhhoSC7MRL0IyY2zMdGo3w1Vfy6xEjPI9X2flJqDr9AMIbzzrf70+/lmkn38EYMqA7I+0zzitjCeDOO+/kzjvv9LrOmzdoyZIlLFmyxG+ft99+O7fffntPDE9wnnJj7j/IDVoCXNPXQxEIBP2JoiI5BqgnCO+6iOzRzMVk7f0/rCodWQVforJbyLFMB4LdG27a1Pa6K+MuK/M0lhYtkrXjLmDOm5glgaDHmTgR7ryT5hBZDTuioaSPByQQCPoFvZXieumlMGFClzY1hchjatZ2MI1VUyP/T0uDgQO7tK/eQOmQOekPFSa7gDCWBBcuWi1kZWGKkH9FpVQf7OMBCQSCfkFoaNvrnByoquq7sbRSG5bKR1P/zJoxD6Kyy4UUk05u6mCrPkAtT1i5TsGZ1Xqm5LwHQFzdyT4ZVnc576bhBAKBJ/WjpvHppEwUSPw2OqqvhyMQfL8wmeRMsT4kvvIolJdTGjHMuSy4vszPFj3It98G3nbgQLYM+ykzs98EZE9Yi8bgXF0RPjjgrlbMeAV9SzVWlMxhR+Bj6AWEsSS4cMnNheefJ6bYTkNfj6W7KBSYgmPl1+KuFgi6R0hI7/S7ejXs3Su/7qRYe2rJDmIK9rFr8A8C2yA/X4636ong9C561soihrJ+tFzAOa1yL+ENJRxLvSzg7a0qHUb9AOx2W5f235OIaTjBhcvZs+ft/LlAIOhFpk/vnX7rW8VvFy2CqVM7tam+qRKA0QVfeG/gyFhzLbLc1NTZEfYo8bUnGFq8EbWt/8ovBYowlgSC7wFBBSf54Xc/54ff/RxFfWDl+wUCwflDUIt8XweZfdzfl7RWiYuIAB+qFj4ZMACCg32vd6wLpFhzYaFzCg5g4ukVXTaWZmS/yQ+/+zkzTvRykdAAEA57geB7gKau0vla0dgAnJ+F3wQCQceURg4noeY4liCX+1ynk/XYOpIj8YZWC489JhefjIz0XO8oQZCZ2XFBSi/erKElmwhvzTaeffhVIDC5k/Ty3QBkVOyilssD2qa3EMaSQNCKkDsRCAQAvPde7/a/ejUkJcnlS7pAZWgGCTXHsStdvsJHjJD/QkPh888732kvBrCHNPd9NmF3EdNwAgFwxjCcY0nz+noYAoGgP+CILepNTKYubyoplNiVandtuD//Wf47fbrzHdbVyQbcJh+lCCxyqQI2buxynKdVJWvOuWbGnU8IY0kgALbFLeBQ6hV9PQyBQNDfmDNH9gL1I8xqPQfSF5OXdWXPdFhbC59+Cv/7H5R4Kc5rt7v/DwCj3j1uavegmwCoC+lf5zJQhLEkEAA/OvM331kmAoHgwqW42Flosdt0oyTB8UHyjzm7Us3Y3E8Yf+ZD1GYvYrybN7e97oLgLWfPei67svNGmUQX9t2PEcaS4MJl/HhYuhSrRq53YvgezKsLBIIeIC6ud/q94oouy50YQ2WPTKPOSwC2KxUV8v+0NBgceAFIgX+EsSS4cAkKgunTqY0bAsgZFwKBQECYS5ZZTk6b3lofUhuawqrJf2Rd1n1OuZPEU9/18ai80Frvqb3cybST7wAQVyvkTgQCQR9RP3wya8YOAIWCzOjYvh6OQPD9wmj0nlJ/DompyUGqqaQ8rM1bpK87R+LfW7cG3nbwYDe5E6tKh0XdVq28OjSAWk2tfDjtRUKbymhRaJnFvsDH0AsIY0lw4ZKfD6++Skyx8fyXO1GrqQrLaH3dt0MRCM57OilFEjBr17bJnWg6V6oko2hz5+VOSkogMbGTg/RCWdc06FzlTlKqDhLeUMLh9Cu5JsDtWzQGWjSGVrmTvjWWxDSc4MKluPjcpAgLBILzi1mzeqdfx3TeokUwY0anNtU3yTGVI4rW+m84rE1ol4a+/RkYX3uCQaVbUNnMfTqOnkD8BhUIvgfoik7zw+9ewKzWozA9DYT29ZAEAkEPEtRSB4ChudJ7g3nzYP16iIqS5U5KSwPvPCFBjjXyVRrAIXcyYEDHfRUVucmdTD35LsVRowMfiwtTT/6HQaVbOZkwk75WJRCeJYHge4C2RnaTa62NKBq6XuxOIBD0fyrCBgG4y52oVPLUnkrlYys/6HTwxBPw0EPuninXvgFGjuy4HEGjZzmDwaWbnXInM48uC3hYg0rlWKnM0s0dtOx9hGdJIGhFyJ0IBAJALs7Ym6xeDampMG5clzYvixhKrPG0u9zJpEnyX1CQ3H9n6az4bicIa2yLeXJk8p1vCM+SQAAUhgzmZMJFfT0MgUDQHzgXpQLq6nq2vz/8Qf7Lyen8tkYjbNjgO+vNapX/b93aZbkTSSGbG2Z11wtz9iXCsyQQAN8kXEnowPF9PQyBQNDfmDWrZzLKepAGXRS7B9+MYczUnumwpgZWrpRfDxrk6WUytwZoNzUF3GWjLhJ9S5vRuSPzFqadfIdaQ3J3R9snCM+SQADccvolRud3QalbIBB8vykt7XSav0+6UZLgRMalgOyhmXh6BZNO/de73Mm2bV3eByBnCbdn8eJOd2NR9VL5hT5CGEuCC5cxY+C665xv9eYedosLBILzk5iY3un36qu7LHdSGy4Xc2wIivbf0JEFJ+ROehRhLAkuXEJCYMECKpPktNbBZZ2oUisQCL6/RES0vc7JgdravhqJkzpDEl9OeJyNI3/jDJJOONOBF6krQrrdpXWfrnInFnWwU+4kpu7UuR9TDyBilgSC7wGmYRPZNCoUCSWZUb30q1gguFCpq3M3oPqASGM+NlM1laEZzmWGmoJzs/MdOwJvm5npJnciKRRYlVrn6np94Fl3qyY/S2RDEY0qPVM5FvgYegFhLAkuXIqK4N//Jqa4+LyXO5E0WkqisuQ3ogKCQNA9eipGqT0bNrTJnXSyHtKggk2dlzs5ezawQpIdUdI1DTpXuZOkmiOEN5RwYOC1XBXg9g1B0TQERbfKnfStsSSm4QQXLgUFXX4ICASC7zFz5vROv5Wt1bcXLeq0pEpwczUAQ0s2+W+Ymdn22tS3BWrja0+QVr4b5XlaW8kVYSwJBN8DdCW5/GDzL7h61yMoGs93P5lAIGhPcHMt4B4L5Ma8efL/2NjOF5iMi/O/3pHFFxXVcV8lJW5yJzOz30RrDbzkgCsTT6/gh9/9nPG5H3Vp+55EGEsCwfcAbdVZFJKEobkSRb2xr4cjEAh6kRpDCgBWnaFnOgwOhkcfhd/+FoYM8Vyvbo3YGT++46BxL96sgWXbnXIn04+96bHeF0OLNwIwonh9wNv0FiJmSSBoRcidCAQCAD7qZU/G6tWQkQGjuyYwWxyVRaSpEJuqLXCaWbPkP40Gvv66852mpHRpLIEQ0dBWu0lj65qXqa8RniWBACgNTuVM7JS+HoZAIOgPlJf3/j6qq3u2vyeekP9OnOj8tvX1sHkz7N7tfb1D7mT37i7LnTiwqIK7tX1fIYwlgQBYl3gdOzN/2NfDEAgE/Y2ZM3tVZLYrmIJi2D34ZvKyruyZDqur4b334M03vRuKzc3y/07o2Zk17hpw24csBaAmNLXLw+xLhLEkECDLnYwq/KqvhyEQCPobZWWg0/VMX+quR76cSpvrfD3p1H+ZdOq/qKwtng137eryPgAoLPRc1gW5kyZNWPfG0c8QxpLgwiUrCxYudL4NsvRtmq1AIOgnRHcgKdJVrruuy3InVZGydIkpONZ/w6Ii+f+AAbIobk+gFKaCOAOCC5fQULj2WqfcybCSjX08IIFA0C+IjGx7nZMDxr7PMDUaEvl67IN8N/znTrmT+LydvjfQavvUyPEtd3K6r4bULUQ2nEDwPcA0ZDzbh4BdqSIzIoBaKAKBIHBqaiCsb6eVwkwlWMy11IS0Za2FVuWem537Cvz2RmYm24bexvQTbzsXuWYadygE7MLnE58kru4URm0kE+lbI0sYS4ILl5IS+O9/iSk+cf7LneiCOJMwXX7TQ+EVAsEFS295ZL79tk3upJNk5q3rvNxJWRnEx3dpf254i2PyhUKBXSFLuVSED2Z91j1IKEmsOUp4Qwn7Bt/AFQF2ZdQPwKgf0Cp30rfG0nk3Dffaa6+Rnp5OUFAQU6ZMYVcHwWwffPABw4YNIygoiKysLFavXu2z7S9+8QsUCgUvv/xyD49a0C/Jy4OTJ/t6FAKBoL8xd27HbbpCaan8f9GiTkuqBLXUAjC4bKv/hq5xSn08fRhbd4rEmmMosPfpOHqC88pYWrFiBffddx9PPPEE+/btY8yYMSxcuJByHzUxtm3bxs0338xPfvIT9u/fz+LFi1m8eDFHjhzxaPvJJ5+wY8cOEhMTe/swBIIeR1eaz3U77uey/c8KuROB4HuIvkmuyxRVn++9gUPuJD6+86UOYjsIGnfInYSE+G8HcPYsM0782/l29tF/dFnuZEzeKm7YdjejC77o0vY9yXllLP31r3/ljjvu4LbbbmPEiBEsW7YMvV7PW2+95bX93/72Ny699FIeeOABhg8fzjPPPMP48eP5+9//7tauuLiY3/zmNyxfvhxNb6lNCwTtaGlpK1/SXbQVxQSZ64mqzz+v5E6Mxm7XuOszmmubaTF6Sd12QZKgrlaitrC+RzVNLY0WGisbne+tzVa3974wFhlpqvb/xWWxQGODhLHIiGSX5INocDfA6+vB7sVZ0FufZ31JPXZr4N4JyS5RX1Lv9t6YV91WXLEDLI0WLK1NLVb5/HYGyS5hLG3EVGrCbrW3ncsA6ejzNOrlqTWrzuDs226XPztroxmrqeMHi+uY6mtt2O//HdKv76Q+2ItOnFqN3Q7N46aBQkFTdROWRotbP3a7fF1QX4+i3UWQXr7LKXcyJVsO9PZ3rdjtsmrKqIKv0FibGV3wJUajBputw8PqNc6bmCWz2czevXt56KGHnMuUSiXz5s1j+/btXrfZvn079913n9uyhQsXsmrVKud7u93OLbfcwgMPPMDIkSMDGktLSwstLW0PSWOrq9NisWCx9Jy6sqOvnuxT0IbCakVhtyO13rFWhTqgc221KrDbZX0ki8VOVz6e+np44gklNhs89pidmJjO9+GKzWZFQmodU89ehz1F++v5q68UfP65gsmTJX784/PLYqo6UUn2zX8ApYrRnz5BaJL34N9331UQ/OZrJNYcZdfAG5n9xEWMG9e9fbcYW9i98AmUTY2k/eO3JExMZtv8p1DV1jDgT78m47JhXp8dh1/bQv0b/wWlivRl95M41bM4oMUCjz+uZMi+FQw9+w2qBZcw5YVrUN53H/Zf/QpGjGDXLgXvvKMgIwPuv7/NgOmtz/Pomzuoe+Vd7AMHM3PVvQFts+X6V1GezCb05zeT9euZbP3xmyj27SdpVARp/3nKb70jS6OFgz96CYsF0tMl8vIUaG94njFb/oY6yH07X8/orbf8i4bsQgwtVc5lilkzmD5bjcJuhy++wJ6WBl6+c2xmm8fnCSBJduc9nhc9jqzGr1Dv2sL++Vtg2lT2xC2isnEcl/7xBZQKGDtWIshiwdsDavejn2P5bA2KGdMInzyE2pf+gy09A1VcNOzajW7JlUx47FKXA7Wyb4/EgVw7mfZcVC+8gD04mKAFF2H+ZDXS+HHsGvMzcnLgjtltzyIH48+sdC7Rmev48ksrq1YpmDBB4ic/8bxWnn9eydnTjdzQupUkSbz33ghmzrSQnOztU+s6gT4rzxtjqbKyEpvNRny7YLX4+Hiys7O9blNaWuq1falj3hh4/vnnUavV3HXXXQGP5bnnnuOpp57yWL527Vr0en3A/QTKunXrerxPAURmZ5NaUEBNTSiVulQqlQmY/MS0OTh+PIqCAjkjZcOGbCIi/HsXvHH2bAgnT8p1U1auzCU9vXveoPojxUS2ui62bNlCcEkA7vI+wnE9v/32SJqa1BQUQFzcwT4eVecwbasgorYGgDXvfE7I2Eiv7VasGMNdhTsxASMO/ZuP39Vx9myV17aB0pzfiKFMTsve/N+1BJ2KRV8oT83s/Ggjx6Uzzrauzw7TVweJaL1Gvv3fOsKrB3j0bTRqOXx4OBfnfIEJ4OPP2BN2lAF5eZR88gkVeXmsXZtGfn4E+fkwYkTb59Zbn2fD8p2Em0xw6IDfmFNX1Pv2AHB2+WoKM4w0bT9CqMVE7l4jJz/+GIvBtwBtc2EThhr5PJ3MsdHSIgcrf/7fz9DFB3ndpv0zunnnYQzWOhzOxOzwcRQeDCU4fDuxBQUAFH3xBVX5nlNq5kqz18/TXluHtknusbKiApOrq3LdeoYhi806lp7JNVHx7bc05OR47KNm1XYMLRK5O6tJPLWGCFM9HDnUtv79T1k9oc0Qjtm2l9pKEwbjFr55184UYx0Y62h8d6Xc4LvNbCmbg87WxNeVOYz340Zt0ejZ+vJqomuMbDk5kAEDKjzaVHxuZ0bFBkwute9+dOpldq6ezqHkns1gaWzs2CML55Gx1Bvs3buXv/3tb+zbtw9FR0rKLjz00ENuHiuj0UhKSgoLFiwgrAfTSy0WC+vWrWP+/PlierAXUERGojh1ivp6iX9obyZk0FjuWtTxdhERCk6flq+XuXOTupRscuoU7N0rz4LPnJnUVT1NJ0eLt1O36QAAY2bOJH6s5xdhX9P+et60Semc3Vm0KKlvB9dJcpoOUfGZnFwydPJk0uZlem2nfOopDC5fzFlZWSxa1L0fVBVHysh5fRMAiaNGknrVVDa9cZrY+jPEDRvG2EWXeH12bP+8GqmgiANpVzHuxkuZNs3zF31lUTMpzz6AwmXMk9LTUZSWkjxpEtKCBYR8+j80BZupNqSyaNGDznb2F18hquIEebGTWLTox906Rlc2fNJAcFUlh1Mu4+eLArhBgW2GLwHQx8cxc9Ei7lo1j5t23EuQDsbPn+9eR6kdVdkVnHhNrrmm14Pju3TKJZcQnhbh1tbXM3r941vRm9vmjCbacmhJmMG4sWNR1NYCkDx1KtLs2R77ry82cvgvsvHl+DwBtvxxC0rZbkOXOpJjiYOQlCqmnHqf+qBYQpvdjY6E+BBGzJ4NmZ7X5kcv5BJbXUfOwKkkGQ6hKCtzWy8F65nhcq7NJVXsMdRgoIWG5GQMxQZKIkYQ3lRKSIscS3WdeQvpFbvRaeNo8WOMNsSMZLqimJiG/eyKH8AiL59pyaufkGQ0g07uR5IkaChn1KRJJI7rWdeSMcAg+PPGWIqJiUGlUlHW7kMtKysjwUcwW0JCgt/2mzdvpry8nNTUNne0zWbjt7/9LS+//DJ5eXle+9XpdOi8lL/XaDS9YtT0Vr8XPGo1KJUoFBK3nH6Jk8G3oNFcFuhmAGg0Krry0Wg03e/DFZVKjQJFa3/9+3pxjE+pdD8H5xNqtcZ5vklI8Xm+w5sqgLYfYqH15Wg03g2rQNFo2vatUqnR6HQ0BMcRV5+LSqVyG4vrtaBUqrCjQKFQoVarvV5zWnMdSiS3MasdF7xaDRoNWmszoCDaVOi2r8iGYhQoyKjYg0ZzR7eO0RWlUokCBUqFMuDr2nF+FK3b2LUaJKUGhcIq9+GnH9fPVqloOxP+7qv26xQKZdv14VimVKF2vfFbz6e//bt+nrmpFzP46KcATD31X1R2C9uHLEWBAkml9difUqnweazK1vEpFCqUChW029auVLsdT8vli1G8stM5JgUKFEoluzJv4ZIjr9CiMZBRsQdQENxchxnfzgeFQkmEqQQFCqacWYlG45l5OLJ4g/uYWl/2xrMt0P7OmwBvrVbLhAkT2LBhg3OZ3W5nw4YNTJs2zes206ZNc2sPsrvU0f6WW27h0KFDHDhwwPmXmJjIAw88wNdff917ByPoH4wYAdOnO992NWNDcOFSFZqOZAgNuH306W7qdgF2QxiNOtkzYjOEd7s/f+zPuBa2bWvd8fmT/u0ofFg4+OI+2b++pcZjWVbBl3DDDR3Lnej1VIemAWDTtXkhK6Ll2KUO5U5cycjwujjILHtTBtQco3DUpR7rq8IHui/Qar324xDLtao6NzXmqEB+PnHeeJYA7rvvPpYuXcrEiROZPHkyL7/8Mg0NDdx2220A3HrrrSQlJfHcc88BcPfddzN79mxefPFFLr/8cv73v/+xZ88e/vnPfwIQHR1NdDsNII1GQ0JCAkOHDj23Byc490REwNKlVH5ZDwXbGFW0Bri2r0clOA+wB4dQET6YOn0fTHcGB/PJlD8BcOtAoLmZjHI/shftGJu3iuC8dJg+3G+7XZk/JD9mAvBx18faA2ha5Ky2UQWrgasD2mbV5GcBGNI6YzMu92OU9s5ltPU0YY1lHTcCUKv5atzDACxxif82hgxg/eh7sSm1LDzwPIBTQsSRaeaKXavzGcge0VAMQEb5TrKjbuercQ9z2X75nB1IX0xpxjSu72CYidVHOZUwM7BjciHamAtB3o2v/sx5ZSzdeOONVFRU8Pjjj1NaWsrYsWNZs2aNM4i7oKAApUvl1enTp/P+++/z6KOP8vDDD5OZmcmqVasYNWpUXx2CQNArNAwew76B12FTasgM9x2PIegZzCmDOJyyCLW9BYWpHgjcu9TzgzE7X0p+pj8aolMIbn2trvf0fPRXlLbueyHSKuSA79qwVJ9ekv5OSFMlZruN+qAIv+3MmhC0lgYs0Z2stdRKfXAcze32oTy432vbGGMu2UlzKYwZx/yDfwGgLnoQu8LHMzlnuddtWjQGgjF7XdeekqiRnEqYyaxjywI/gF7ivDKWAO68807uvPNOr+u++eYbj2VLlixhyZIlAffvK05J8D2krAxWrSKm+NB5L3diDw7hePIC+Y33hB1BDzPxzArCGstQV97POTWWWlpIqjrRKinR5nqQFApqxvuuPF02/GK03x0hsdqzKK83Rud/hsbaBCkdt+1NCkYuIu1g57LrQhvLCG88S2hcNK4HcGDkD1nQQWFFKVjPseQFDDn7LdD5TFe/bN3asdyJ2Uzm2R2tby5yLh52ZrVPuZPdg29m0qn/AqC1yE8z3dl8KC+HOM+6SbUhSUTUyxImkSVHCc3f5Fw36/g/2RjzBNBWoFmZ36ZBdzZhHJnIHq2kmiOEN5RQ7zI1KClVmFXBzvfN2lCCzG01r3YP+SEXnW7TjfNHsyaMwpjxmNXBtOX59Q3nTcySQNDjnD4N+/b19SgEFxCSovuPXKWxljlHX+OSI69gOBr49FtnCTLXMy7XZQrOR2xob2PWyYaoqxhrR1y153FmH3udzEMfdn6HISEURY9BbXM3lCRt4HE5BbFtcUmOGKO6kEQoKpIXzpsHF13kbVNobmZyznIm5ywn7NgO5+KgljoAMio8496sSh/esro6r4v3D7wOkI2muNydJFUfdlufWbjRe3+AVR1Ei8Z3tpvHEPSJ7Mz8UcDtvdGgi6JeEwmqvksEEcaSQPA9QFtexBV7n+LiI6+05ToLeg3dmeOBx6C4YNMGd9yoEyhs5zAOp7UsSlOY9+mdOkP/K/+gaBeUrrOYuhSobgqOheDAP7uKsDZ9NoeR5xCXBeSpwADEetXNbd4UfZNcnyu27pTXtseT5wU8Ple8XUNJ5e1+RLZmf7c3WEObZKmxSaf+51xmDgpjas67zvfxtSfcjx3IHnQ5IGfd+WNg2XZ++N3P2Zt+HW9nPoA9qpvVe7uBMJYEgu8BurICwhtKSKw+irLe+69JQc+hsAYWR/PxlOd7eSRtKCQJw6kDPtdnbFve4RScZAhly3D/af9FIxawd9AN7B58k9vynaN+ys7MH3W4fWeJLpG9Hj2RQTVtz6s+vS1OrFbCG892e18OvAVfdxdHNqSDsfmf9vg+XJHUspF0MnE24cZC2egEt6D5Y8kLyE6aS2XiaA+vXGplm/E16eRyasLTaAiKoio0PaD9j89f1b0D6AGEsSQQtNIZN79AEAhNugi39zVpY3t1f1pjpc91CnsAwlo6HfmxE72vy5XjVuwaHdlJczmZ6J6W36wL59SAWb637yKRpcd6tL+OUNTWMCXnPbdldfoBnfJIpVR6BkRHmgrb3qxeDcePd3mMZ+Ldp0SDW2rJTpzLlmE/DWj7GcffBNqy4jpDqNH7NvsHXsfeQTdg1XnGhLlO8+lbqqkLS2XV5OdYO+YBr319POV5No3yHpvcVwhjSSAAarXRlEQGpg0oEHSV5jAvIqX9HUctslPep38uBJKqDnVKoNrQ7Gm07h3YLtGorPPTuP64ZtdDzMx+M6C2TVq5PldR9JjAOm81tBNqs1HgXfdPbWtBZ65HZfEv4mtTaomtPE7m2e98et3i6nIYm7fK+T7KVMBNZ15DWdM9qaDuIIwlgQD4POVWvh3+874ehuB7xmX7/ui+wJfMencICaHGELgExIH0xdRnTfe+sqWF63bc73f7gXtW8sPvfs7cQy+5LZ9x4DV++N3PfaaMd5UWfRQAR1IDkzrxxpqxv++p4XSZZm3PZUzWhiSxe/DN7B10AwCmoM7F8jg8ngUx4wNqr2iSC/ZGmoqcy0qiRjqLfwJMOL2S63fcz+AD/oPqq8IyyCj6jsk5y4mvO+m1TbQp321fAHHNxWDtu1pZwlgSCIBbTr/EsOINHTcUCNphi/EtDhhlKnB7H2zsWW8CACoVtfqeCa5WmOrd0ry9oWmSY34Sat0FzKPrTgOQefa7HhlLT9KsDeswmLi/k5/UZuBOO/F/TDr1X2eKvk3Vu7WjrPO9y0DtGXQjAGa1nsGlWwDQNXVcwyusXvYoOcodtGd4Uf8TjxfGkuDCZdgwXBVsddbzvdqS4FxTFZqO3RC4eHZMzvZu79MeEuqUl7Dpe7e+0+G0K85LuROzWpYJKc7ofIXpnsCb3MmIorVw/fV0qJqt1zs9RXZNW7mC0tgsoJNyJ+npXhc7ArTjjKcoHu6ZRVcZMdh9gY9MQMd0nkXduSzP9gHg5wPCWBJcuERFwa9/TWWS/PDKKvyqjwckOF+w64KpMaRgDPbtVeo19HpWzHiF5Re9QePg0dDS0mm5k6D8Ex2225X5Q7ITL+nOSHsETYv8xS7LnQTGB9NfYvlFb1CaNgWArPwv+lzuJNJUJNcJ6ki4Va3m08l/ZPlFb1CbNcu5uF4fzzcjf82OzB85MwP9yZ1Iat+CwY5g88FnN1MfO9AprwLydOfBITd0eDyJ1UfRt1R32K49UfX5nd6mPyCMJYHge0DDwCyOpSzkUNqV2IXcSa9jTstkz6AbyYubjKKxjz2SLYH9Sm8Kb6uPpDH2XaBsZ1HaApPG8MegMtk7ZgqJP2/lToLMRizqYIzB/mVMHLFR5thEv+18UROSTEOwewyU8sghr22jTIVkJ81l+5ClzmXG6IGewewu+Cyg6YXSiGFsG3pbwO17E2EsCS5cKipg+XJiir0/CM4n7CGh7M+4Vp42CRJ6J+eCKTnvcvGRV1GX93wdHb+0tBBfm01crWdwbPU433InZ7MWUBIVuC7myMI1pHupFn2uKRy2oNPbhDRXMqDmGCF17p/NntG3Q0dyJ0HBnEi8uHfigHbs6FjuxGIho2wHGWU73BaPOPUZ8w/+heQqT+mXfQPbZG8dMWe6s/lQ6b2URH1wW1ZmeGm2PEXYyqzj/yTU5F5nSnmmLROyNL4tgy6l6gDDijcQ3th2nu1KtXN6DnBOGTvYOWwpgdKoiyQ3fmqr3EnfIowlwYVLTg581/+CUQXfX3pK7mTeoZeYf+hFDNl7XPpWgMK3kG5nCWmucqvMzOTJPdZ3Z2jRy57SztRBW7zrES45/DeGHlzR+R0aDOTHTkTVzqMlaQI3noqjspyvHQUkjfoEyG+dgrroIpgxw/vGTU1MP/E200+8TVh2m7GqazWCUqs8azi1qH0YgDXeg633tBYUrQ1JIv70dqfQsINBxb6fixaNvlNyJxVhgzwKmHaWFrWBJlVIQFXPewthLAkE3wM0FSXMO/QiM7LfhGb/dU4E3UeXm90/5E7M5zBQNlL+0m82eA8wNgX3vxpS7eVOVDZzl8o3mIJjQa8PuH1p5HDna0fws5uxZzB0HLsEqBvbajuFNFYAkFDjvZhlV+VOlDbPyuippe1i4HTedfEc9aQmnGkrF2DRGZh4ZqXz/YCaY1iV7tufzFgItBr4fnDInWzPvIV/DX0Ee3Qngtt7GGEsCQTfA4JK84ivPUl6+W6UdR2n7gq6h8ISWBzNqsnP9vJI2lBIEiG5h32uT9/xv47lTkIM7Bhyq982RaMu5UD6Yg5kXOO2fNvoX7B34BK3+JWeIKq1gndPyJ3M2vUi1Nb6b2SzEdLSczFdvSF34sj2c5BVGHjwe1dwyJ0cT55HWH2xM5vO4X1T2q2cTJzDqYSZVCaNIcjsXsAzubot1GH8qZVURwzErAmhxpAa0P4n5nZBELmHEcaSQNCKkDsR9DSuRfsAalOyfLTsGXQ1vr1dSmsABl5QEKcTfEwPFcg1o2yaII6mXsbRlEvdVjcHRZCdPI8zCT4KXnaRqBLfBmBvoKipZkb2W27LavWJnfJIJVV5xkF6yJ2c9F6QMRBOJs5xe29oquB40ny2DvtJQNtPPSFn0XVF7iSsrtDr8t2Db2bnkFuw6Dyn6FzlX0KbyqgNT+ODaX91y8Jz5bNJz/S4xmB3Ob+rdAkEPUSDOhRjWKbH8hajPM2hC/Puhr4QMZvlkjvOOHKLRf7rxDSFXyQJ6uudKveBUF9SjyHBgELZ5tY3Vpqxq7UolW1duX6eplIT+hg9SrUSSQKTCUJDwWiEUINEfUk9Yclhbn03NMgzEsqGtsKNNpvsrNBKLegj5evE2mxt3Zd7LIk5OBxjkZHQxFAUSoXcd6QGhUZNo1mNSrLSUFJH5KAomktrUUcY0Og1GIuMEBpKaJj7tIVj3E7sdhorG0EDVquCxkYIC5UwFhmxGU04tq6vh9qSRuwNTahU8jGodGpsagPBLe2KUk6fjvmbbVg278OqiEDRqEFtVaGxNVObKxGWEk5tbg2W2iAUqiD05lrq8uVO1YYgrE2yRyg8LUL+XGpsSMZ658mz2UAfG0JzbTNERGCzAS0tKBpMqLQqLMYmHNFCzbXNtNQ1YzPb0IeqaKyXZTjUwRqUEWHo9WCscJmarKqitrptKs5iAWNuFdZKO1KIAZVe/rzstUZ5JWAqqnW2b27tKrnqIHX7z6BIbx0fshfOolRiMqmpzq1D0zqlpNKqPAp2glw5ffzZYtSts+TK/UdpUMWgVCuxSiqC40KxWqGpuqltvKZmqlqdXC0t4JjEDWn29Hxdu/NBt/fNzWAsa8ISJVcsoLkZe30DKq0KjaURkKtwR9W10D4lRGExU32qGilSrp4uGeWDTqk8QHlchMe+AfTN1diVahQ1/ssJSDaJhLwdxDSaMQbHUZ0TiyZEi2SX5GtFpSKuLsetMGWUqYDrjf9EUXsPJPfNdK8wlgQC4OO0nxKaOZ6bXZbVFdRx4MrHQJLI+uhJojKjfW5/odDYCI88IhtMjzwCibEWePRR2cJ44AEYOLD7O3n3Xdi6FS6/HK66qsPm+1/cSP2bK5CyRjN75a8B2PPHr9nzbQP7068BhYJrr4Wpw2o5cNXjIEmE3HgFjcs/wZ6azpw1v+dvf5N1TaOjoaoKZh3/F6kVe7FHRqOsqUIaMZL4P97F3/4Gk43rubLlAxyTK9ue/YYtwwZz9e6nyfrbT0mansaW+U+hrKrgh+28EfGvPMKBV0A9/2JChiRR99p7RESA4dmHeeG/KVy1+wkMzZXodGC2gC04FP1ls2n+8AsKYieg+fXPuMRFwvDrryF3v54rg2MxNFWg/+oj9ry3CosumOUJP2HtWiUL8t8kNn+P01A6nHo5h09M4Qdzf+X1fF7b7v3J/Q2U7gB2fA3Pfs0QYEjrukMuCiSuyeIH3Z1OAOiuvZy62Vex7V/ZXHLkFa/7PpaykP0Z1zKodA9TT/4HwGkoFUWPgWl3e90O5GrSJ5IuIa38EI5SlMqaKtZd/jLbR9/H4l2PYLPBgR/+GYBtQ28jN34qAAsOvkFsnaf2nc2lNFP+r1/AtULQdyN+Tn7UGAoKRqJ/6XWiG4o8tnelISiKfW+saluwaw2wxvl2+axloFAw/sx3OCKeWj74nIdLL5evYZe+wprK2D34ZrTWRsbkfep1f7m5kPfIbrYOG014QwmX73sGhSQbjo4v/rzYySSeeNtjW4XFwoHFT7Jihvw5DS2OZiJyjJJhnzwlVh6eSX1wHINKtwKyNl0gKO1Wxh9s2+cRL7f4VC/bJTbmBTz93RuIaTiBAPjBmVcZUvKN27Kqo6UozC3yr6xjpX0zsH5GZaVsMFmtUFIC1NXJbhW7HYr8f1kETH2r1+GgZ4q0N+pWyw9rxeG2qY/GY3lE1+cyqvArkqoOUbk3n6pjZc7P0/TJWpAklPm5ANRuO8aE0yud2WWpFXJ6t0O4U3HsKAX5Eukl2xi07wOnRJWkULBl+B2MLviCYIuR6kNFNFU3oaws9zttY123iZr18r5qa8G24kO0lgbnl3dLC0h22YNl/HSTc0xHPslx62fqyf8w+9jrVIamA9DQgOzRaaxH3diE3Q4hpafdtrEpNQwsd09L95Wlp4iMoECZjlmt73YmX+VZC4WnWphz7B8+2wwvWkdIcyVKlbsHrVkbxqkE79W4FQqwqINIrj5EVH0+qZX7nOvy4iaxedgdNLTTTrMpNW7HY1OokTQa558v7Eq1vK1Gg1qtcFvefrsaQwrl4ZnYlBpMQTFUhA2mcMAkOaHLS1yzUpK9N65p9wDjcj/GYDcS3FLrXBbRUExaxR5ODphNnX4ANqUGm1LjFlgOcoV5gCv2PuU0lBw06iKpDPP940ZSa9C01rUsSmzLhFSqFFjUQeTGTWH3IO9ZbjaVlsKYsc73rlIz/sIdFIq2hLee1NLrCYRnSXDhMmSI7Ak5chqVZCXYEriquKAVdS88QsaPh0OHIDy847Z+iK89SbyjFpFuPIyb41xnVocQhMlZdyi6Po9hxRs4ZTeTHzvRo68DGdcwjLaKyQ5qQ5JZvOshQpo7X8nYrtI6f63qKgq5/ph3AdsmbThai1z4cv7BvxD0gft0cWL1EbYPWUp6+W7nsuqQFJae+iuG0hAUXr6Zta3SPqWRw9k46i4mW7cxePu7Hvs9duVTTM3+P85EDKUoarTH8QfK9iFLWXTiHQaeWkuFH9UUhWRnYNkObl2+kAMz5X3ZlBoOpV3JnKOvebTPHnwFGXddyekXPmJE0VrSQlIoiRrlNJgKYsZz2YHnaNBFObcpjBnHdyN+AchVwQeVbiVnwEXcsP1eZ5vcneUU/vgxAOyGMJQm+dnw3xl/B4WCN96A2cA/5n3I2OIj7M26mWdXDuXb8feiaJKnuK7e/ShFRfDMM3Kft98OU6b8FPgp79x7gIw1r7sdS1bBlzTqIjmevICm0VPJ3PRP4upyGEY2N/xuDke2yEaI8rVXuXi2vI1cXelJZx9PPAEb2v2uc53OatKGE2yWtf0W7HmWhUoFm1s9lVU/e4hr7k1329ZZtcsE/Lb19fXX8dt3xxLWVMbI2HKPz2Tkqj8SPTSG9eth+Qfysj//2X1WveCbM+T98nlMQTHkxU12VmdPS4fUFGjRhnKX+S8kVh/h4iOveuyjLxCeJcGFS0wMPPggFUlykTUhd9IFIiJg3Lg+HcLhMT8CwKzpuNig87VSBbQG7oJzKsObppeDyEPfeixr0oZ3yVCqDMugJTjC+V7V0uS7cTuUleUsv+gNll/0hnNZeyNGJVkB756tsXmrGH/mI0Aev6RQYtUE0xAU5dbucNoVKCUbUQX73QJ0fdEVT0BZxBCPzK7R+Z9DU5MzrbwgZjyTc5b77cfxQ2dE0VqGF68HoDh6dOvnU4XeXOt1O53FhKG50uNzt0XHURmW0eH4E2uPkm46SUJdx/IxHTGqYLXzOM1BYR4B9F0lqTqwAPnm0ADT8ufN4+rdj3LxkVcZeuQjp/eqJ2iJku9HKbFnhKF7EmEsCS54FD6+VBzU6QfQMmjEORpN12hMH8HphOmcSLwYe2j3PDJ9jmM6rykwA8Lh1rcrVH7bWRNTqe4gVVlll2MiCmM8DUBv2WS9pTfWrA3jdMJ0CmLGd3hcrnRkMPribOIEPpv4tN82eXGTOZh+tc/1LRp3Y2l/RvvoJ08OpC/m2xG/9LrOqB8AyJIXvmjWhKIwt7hNUTnQWUxMPvW+x3LXaaCgViNraMkmn/uwquXw57rW8bgS2ZpNNqbgC5/be6Orn5PKZkbVWN9xQxdcq2u7TYH1QAFTtaWJI6mLOm7oA0NzJRqb77pwdfoB7Br8gy7335MIY0lw4VJVBZ9+6lPuxJI6iI+mvsC60b/t0crIvYEtNIIdQ5bKlXl7Kiutr1gvewac1Y57kAMZ17Bl+B1O5XZXmQdXvhvxC1mItfWLemzuJ17bect6IiiItWMeYO2YB7o11h1DlrJ5xM+dU2ZOrBZijGeIrs9zWywpFBwfcR0A4Y3uchW+yCjb4VMBfnLOcmatbgvalRRKr4Zbky6CT6b8CZPOPQGiNGIYZyPlHxldnb7zhVmtJzduCqeTLiLy8HdePweNrVkWr21l1+AfUBWa3qHBDIDdjtYqT6c54m3ORo7o8Dmwd9gPOZh+NavHP+q3XW1sJqcGzPJqgIFsmLuVGnDBcHKf1+WBYGiuxK5UyQUs2x1LaPlpH1v1LuGNZ2kIiuZk4hxqRrbGpbUWE20IiiYncXa/kDsRMUuCC5cTJ+R6J75Qq2nWnudemt6mqgr2t07RDPPtAehNImvOUBAznry4SXSkIub48k5r8mLkeEFt70L2jUpFRfhgv01KI4YTExlFV/wLiqZGFh54vgtbgikoxll12YFcWNB7aQyVtQVcnBFWlY4mXYSbJ+ebEb8itu6Ux3RPTH0uuXFTCGsq85rq3hGO2JqIRs+ijjaVlm3Dbkfnx3ZpXwwyJ3E2OYmzA9q3pvCMs0L7qZSLKUjPoFnT8TRjYfxEGgOcjdyZ+SMmnF7p1bA1NJQxNm9VYB11kv/O9B5gH1l4CBjdcQf73adkO+P59MbJAbOdntwFm38OKaA8dbItDRKwKbVYFZo+/dEqPEsCgR/G5X7MzOP/Qn3W+6+8/oKmuoxZx95g0qn/nlu5E0fGl04HcT1c/yTTs+6VNyKrT5NauQ9DB1/ImoLTXLfjAeYf/AtHB8n5yr7kFiJMRcQYT3Mi8eLOjbmVrPwvuGy/7+rd1YYUqmOH+ulB4qJjrxNhKvI7DeWKQpKoivJ/znyJwyaU7OPyfc/43Ta27hSxrefEVYi1OjSN+Lq2AouOQpxDSzbRqIvklK8il8DUnPeYf+hFr+sOpC8GvMfc+PuCrg/qWUmMxqAookz5JNYc6ZJUSn8jwlREhKmoc8eidbluKircVo0sXENPI4VHAPJUanxtNt8M/wX/GP4U9pi+k9QRxpJA4ANVZRkjCr8mrWIPqob+nSkXVCwbDENKvjn/5U6SWoM7L7usy12Up3sRfbVaCTIbiavLcXotfHH5vmdYeOAFZmT/Gwg8xqQpORMsFkbnf05UfT6nBszq9NhBjv9JqTzA5fueodxLsVRfTN/2F4+AaVd8SW9oLI2ENZZRHD2ar8f+zmsbQ3Ml6eW7iK89wY7MWwA5qHts7idknpWFVw+lXUl2kpxDFdZYyrxDfyW9nUhroNgU8sSHt5IFIc1VLN71sFfB17Jwz6BxgJu23MkPNv/CbxB/e+qD46gOz2DqyXeZevLdDtsPqDjE4l0PyxqNfogpPcJ1Ox5gWPGGDvvMHdQ1zTdfXL7vGdkwbjWWKsIGAXJldp9otTBtmvy6I++ODx05N9r1kVaxh/FnPnC+t9wsS+5E1+cx79BLTDn934777GWEsSQQtNK+/ofSWNs3AzkfaWmRizD1AcFNcjbaeBcxz6pU9wDts4PdjZaIeu+ewkNpHRfB9IclOkGu2NmKKSjGa5ZYUvVh9PWdF+IFkILbDIG6kMQu9dFdrCr5CzHIXN+hZ6E3tNFANpg6MnodGIPjUNktKCRJzrZrpX1QujfiagLPdJty7G1Cmqvcyjh4Q2m3euineaNJF0FJyhSkqGgKYsYHPI6AUSic2WyODNHuUBgzDsnQ8Tm1pmQ4jbThReuYefxfDC9a3+399ybCWBIIALMyiCpDWl8P4/zm2LGe6ccxPWD3U5DHBYd0Q3scQdzHkhdQm+iezZhRtBmQp66gTZi0SeNdYkVracAaHEqNIdnnOFwL73XEoNJtpOa4fzm46si5Ghhqu3sAdtPtd/rsN6ilzhmY/J9B9/LezNexqP14DNoR2lTujNVxcPSyB/jvzNecHp4BNcfIKvjSZx8jO1GCw6chFRTEuDw5qD4swGB1Bw1BUW6xZlaVjk2j7nK+d5wfgKPJCwHfRTkB4qt8X9ffDJfrNVX2UPp8V6d9/bF1aGB6cX6x26G4VUfOZfquJGUKcXU5PjYKDK2t46zXKFMBVxX8H4ravvOaC2NJIABWZPyStaN/23FDQe9T0voF+ve/d7mLIFMlh1Kv4JuRv/Zar8bQ5F5M74PpL7H8ojeo18f77LNuxDRWj38MY7s21aFpWNRBKO1W1PXuD/OxuZ8QZA4s1dsRo9OeSaf+53z92aRnkELahEpPx0/niwlPcCzZd2i7xuoew3Y8eR5fTHjCa9uwxlKPzDW7Uu1hCCZXea+uPjr/c5/HW50wkq0/eM1rWQYHRn08K6e/BFqt0/MiKVR8MO2v7Bhyi8/tAHLjprD8ojfQWpsCLulgU2ooiJ1AfuwEr+tDm8qJqfYteGsMjmdnzCWcju++ePA3I3/NsZSFbsuCW2oJreteZfw6/QDfNaMkyTkVqLBZfHfS2OgUUgb4cNqLfDj1LxRkuAfMKyVbj8R1ad73zJ5MN50UcicCQV+zJO8NMks39/UwBNCmLxcT47+dHzL2fcT0E28TU3+GyIZC9DX+1dXja08wJm+V/+KLkkRaxR43z0u1IZU1Y3/vDMLWnznSpfGaI+Mpih7D4dTLPda5eoZ0FndDZFzux4zO/9yrbIXUWrm7vdekRW2Qg5UDwBSWiF3tPSi8s5gikpFUar/n2NBchdbq7mmQUGDWhFAUPdbrNi3RiVSFpqOzNhDR4P45b8y626dhCHIs2ubhP2PrsJ/6bKOx+vZ8GPUJ7IybR05C12LTXDkbOYJGXaTH8tH734H6emdV8ub4znnAm3QRxBhzO2yn8lJHzBctGgMt2tA2bZJWkqoOoajuOPNRVVFKrFEuVWAM9gzaVhgDm149l4jSAYILl0GDIDYWKCfI1tipwE9BK6ruxzl4cNFFcOZMt4wlB6MKvmJUwVegHg9j5jiXO+ROysPl4OlY42lGFXzFqQGzvHo+HHInM4//y2PdZfv/6FbPJ1Bc5U5UTSZu3HOX13aNuijCrbK3beGBFwj6pE3/SyHZSa3cR3FUlts21YZUbs79B1Flaq9yJw4qwwbKweteHDEWdTB7L/k9kw8vZ/opPHTHOsP2IUtZlP0OA3O+psJPO6XdSmrlXrBe4rZ8YNl2pp34P6/bNKSPpCw8mxFFa6nVJ2LUJzjXqW0tXHzkVY/q5A6GF61lUNl2TsXPANoCqe0hgeX/j87/nFFFxyiNWAIEHojvdSzF62nShnMmfhotujCqDalEmWRvjsOjYlNpaRmQ3ql+XTUvXeVO2lMxeFrAfeqbqzG0VKGv9z5t3REOSRhTUAx1+kRSOOC2XgoJAT+Orr5AeJYEFy7x8fCHP1CRPBYQciddIjKyz+VOjmbJYp4dxeZI2rYsHUcwa2WoPD3hkDvxVgnaQcSRLR7LLOrgLhlKHnInzQ2+G7dDWVrSsdyJ3YLW7r2EhKvcSX1wHJJCiU2to0VjcGu3P+NalHYrMWd2klG+s8PpFUfQd2eoDMvwmOIbf+YjedqnlaLoMT4NJQdBrR63EUVrGVqyEXDInYQR3niWsCZPDTOQazmFN5R46ELaYuIDkjtJqT7E4PojxBlPddi2I8bmfsLUk/8BoCUo3G+19M6QUnUgoHZN4QkdNwKYP59rdj3E/IN/YfihFdSG9Jw0iVPuJCmlx/rsKYSxJLjgaa/G3Z6GoChaBnb9V/W5oCltGMXRo8mNm4IU2rVfe/2GstZprgDrRVlaq/valP6ni6zJHVdvdgRTe6ttpDJ7TsdYVIEHT3cGsyaEwphxlESN7FTRP3+K7v4oSZrEx1P+5LdNfuxEv3plrgHqAAfTO84s3DtwCRtG3e11nSPTryRypM/tzWo9CpsVnUuVc2Xr/ay1NDiNQldsLsaZw8syovBrn/twyJ20Pz6AyAbZUB6f573Cuy8sPipSd/QsUtnMKJu9JzT4IqKhzZjvEbkTl+00lsZuGXUhLVVOiSFv1OkT2Dfw+i7335MIY0lw4VJbCxs3+pY7SRnIp5P+wNrRD3jMzfc3rGFRfDPy12wbdjuSvmu6U/2Gr1o9fHl5Pd714bQr2D5kKQ3B8hTf8OJ1XtttGH1vQHInXgOddTo2Zt3NxizvRkAg2BUqvhvxCzaNustT7sRmJaKh2COTTFIoOJJ1M9BzcifT1z7ZNial2mv9IrNaz2cTn6ZB5z7VVRI5qtfkTizqIApjxpGTNIfIA5tIqvK8h7W2JmdcDMDeQTdQpx9ArT4AT4gkobTbgLYsx8LosR0aGPszb+B48nyftaoc1MQNJTduijNjsz1Km4WwJu+lJUKz/Zcl8Iejent20lyPYzFU9by8UEcoJIkoUwEWdTC5cVOoHuke+9UQFMPx5PlC7kQg6FOOHYMVK3yv12h8PswErVRXt8kfDBnSJ0MIr82nIGY8BTHjO5Q7KYoeA0BavpzhpOhgaqlLcidqtdNI8EV5WCbR4dFdkztpbODyvf5Fb33RqIv0iM3zJ3eibTaCy/eUTanBrNa7pd9/M/LXRDSWkFjtHjQe2VBIQcx4IhsKfWbISSgBm9d1OosJgNBmzygnqyqI70b8Ap2f3zDtjcnspLnOgpkdoSk47YwXOpN8EYWpqTQFIH2UnziNxoiAdsG2Ybcz4fRKr4UpDaZSJpxeGVhHneT9Wa97XR6Vtw8IQDD8kLth2lVvpoMTiZc44wQvdsidnMx2kzvpD/Tvn8sCQR8zOv9zpp58B3WZ/2yqvkZdU8GkU+/LBfdavHsKegVHLSSdDhICjHkIlIyOY0YAoqtOklq5D7251m87TeEZrt71CBcfeYVDg68FfMudhDRXEtpYFvCXa3tGFnzF/IN/8bm+MiyDqnh/X0wS07PfIryhJOAK3gpJojLGvzSKr+mf+NKDXNqB3lx0fS4RjSUcTrvCTe6kInwwA2raahE5vE/DijdSY0ghO8l3BeqpOe/6lDtx1EBKrdzrsc7upy5Se0Hf7tIYHI2huYpY45nvhdxJSHOVrNXXmWPRuBhEpaVuq0YV+NHX7CJSiPwzQmNtJNqYy9dZ9/PKiGexx/ou7dHbCM+SQOADVXUFWflfyK/rJwI9F8jY0wQX5TCk5FsAlLUTAe9q5ucFSUlyAbwrr+xyF5Wp44nZ106d3WLB0FyJobmSEx3UPlq86xG392ZNSEBeoOakQWCxOEVQTyfMYFDp1k6MXKZFE0pGuRxYvX3oj+UA6wCYseV5mtR6NO2n7lrxVQRS21JPpKmQ4ujRHEm5lIUHXvBoE9ZYxuCzmzkbOYLdg27ikiOvYFbrGVWw2k3uxKIOZsLplUQ0FHPp/uf8VhlX4PsL22F0SV5itkKaq7ls3x/JTZsD7bovjRhGrPG0m/cLYMn2+1DarXw+8SmvKfreqA+OozJ8EJfuvA+AvNhJftvHVWcz7Pgn1BhSgB/5bBdVdpyrdy/H0OQvN1AmP2NOIPK2AXP17kflF9LroFBQY0gm0lTkX+5Ep5PlTrZv7zjWSdt5l1By5QHZk9f6UVtu+Qm8BbHGM1x85FWqDCkcjvJ9Ps8FwrMkELTiIXdSW91HIzkPaWmBmr4pvRDUXAu0ZbQBVKS7f6mVDZzq9j6q3nt8hrc6R53BHJPoJndSHxznVe4koTab4MaO69EAnh4Addt1agrqfnmFruDInNNaG93OuzdCOhA47ipRpgJCWgK7Rxu1EWgtDahtLW6eEIuq41iYmNrAM92mH36D6Po8Bp/1X7NNbWsJyFBq0kVQlDYDKTKKkqhRAY8jYBQKysJlQecekzsJIMHEVe5kaMkmZh973W9V+P7AeWcsvfbaa6SnpxMUFMSUKVPYtWuX3/YffPABw4YNIygoiKysLFavdrlRLBYefPBBsrKyCAkJITExkVtvvZWSEh8l+AXfWySU1OnPY29Mf+Cwpzr8uUBrlmNbVHb3wiyO7KUTSZdQnTzGbV16yTbAU+6kUevd46C1NGALCnGbfmpPZ+ROhpR8S1q2u6aaq1Hl6gFS4J4h1fize5yvbSr3X/He5E4CFQEGOTtM3658Qvb8u/hg2l/d5E5GFvnOHmsfg+MrgBz8yJ3odIwukL26YY2l3tv4oL3XyKrSsW7M/c73QS6FPR3GsT+5kwGVvq/rza1SIh1lWQbKqYSZ3lcoFFg7yPb0xY7MW7sxolbs9jbtRxfjvTRxfNfkTly8U0GWjivcR5kKWFT4Poq62s7vq4c4r4ylFStWcN999/HEE0+wb98+xowZw8KFCykv915DY9u2bdx888385Cc/Yf/+/SxevJjFixdz5IgciNjY2Mi+fft47LHH2LdvHx9//DEnTpzgqqu6J6YpOP94b9DdrB77UF8PQwBtGlSvvdblLrSNtRxIv5rvRvycwymLPNaHNrhni3085Xn+N+NVv8ZQ7cgZfDbpGU+5E0MqNqUGpd2KyuRe8K8zcif7MrynSLuq3X854XE3odLcuCmsGft7TifM8Nmv1uI+JZcz4CI+n/ik17ZR9fnMOv5Pt2UWbYiHwZVa4RlHBHKMny9PUk38cHbc8FdnkL03GnWRfDT1z6DTOfuRFAo+mfwcewbd6HM7aJM70diaPabgfGFTaiiJGuXTaxPaVE50jW/PUq0+kX1RMzkTNyWg/fljy/A7OJLqfq0Gt9QSYuqa4LKDmpBk37WQJIkhZ+Xp+w7lTnLajKJPpvyJVZOfJX/QJb636QaaD973WDa4/ggK8zmMx2zHeWUs/fWvf+WOO+7gtttuY8SIESxbtgy9Xs9bb73ltf3f/vY3Lr30Uh544AGGDx/OM888w/jx4/l7q+ZUeHg469at44YbbmDo0KFMnTqVv//97+zdu5cCFx0cwfefxQVvM7Bse18PQwCQ0lqQLiKiy10M2rOCGdlvEWkqIrS5gmCj/y+cKFMBw4vXk1hz1HcjSSKx+rCb3IlRH8/aMQ9QEiXXAgo57b0MRUeYI+PJj53goQ0G7sUe5cy1NkYVrGbo2W/8GiDtadBFkVQdmBewKSQaSdUzoa0N4YlYdSE+deUAdNYGWV/MBQkljUFR5MdO9LqNOTKeGkMKWlsToe1EgL8d8Uu+Guf7R5BZE8KmUb/hm5G/9tmmvbHpSl1IIlsSFpGd2H2joTB6rNdaTmP3vOkmd9IS61vM2RuNQVEeMjCuOHT0OiN30qiLpCHI89pIqdyPoqqyw+2VleXOsg7eppID6eNcc94EeJvNZvbu3ctDD7Vd+Eqlknnz5rF9u/cvue3bt3Pfffe5LVu4cCGrVq3yuZ+6ujoUCgURfh7ULS0ttLhkHBmNcvVXi8WCxdJzNdodffVknwIXkpNR6nRIUiOhlloMjWVu59pqtSC1BqBarW2frdWqwG6X3cgWi52ufDwWC9jtym714YrNZnWOtaevQ1dcx221SljsdpStGXGS1YrkZ7/tr2e7XelMprNY2qaaFLNno/jPfyAqCnsAx2G3252Bwm19y8tGFXzBqIIvkBiHddgs5zkyq4LQUU+1IRWLxUJs7XFG539OTvxMiiKGO9s52J92NUOsVuYceRUJkOwSEgosCg1zDv+NeGMOEmCz2bBYLB7be8OGsi3AuamBm/bIX9jttzTpIp11kxYeeA71qlHO/lW2ZtLLtnM2bDASEnZJ3r4yJIVr898ivvSfHhl/kmRDsoOERE1IEs2qIOxWm8eY7Qo1Wy55lIlHP2DSKQUVYQMDOi5vbM+8hUXZ75J2ah0VfuRXlLYWEiv2YWma7tyXhERy+S4uyn7TY+92u43a1BGUhJ9gRPE6aoPiqAuOb9vWbmV69r9p0Ea2LZPs2FtrKA0r3kBGxW5Ox03FYrnI2a9Zo3Vr73htt9tAoXBeryPy1zC05ATl4VdjsaQjSXYcn6B8H7a7XyzyOpvN83wPKvmGZk0o+bETaVLrqQuOJaypHLvdjrWxAQkJm1KLJT7N5/1ts7XdUw4Gl25x7qtJE+asVm6xWFAoFc51ZWnjfT83LBa3+1zXXE1wSy1aY4jHcTieP/6ek3ZjDRISJl00VfpEElsNaMkuYbODTReM3WbDbpfPkyT13rMt0P7OG2OpsrISm81GfLy7Czw+Pp7s7Gyv25SWlnptX1rqfQ68ubmZBx98kJtvvpmwMN9Bas899xxPPfWUx/K1a9ei13sWbesu69Z5L5wn6AHmzsW0fzcRnGHgiY9YvbrtlmjYV0O4SY6HKdq7jxNqOSj4+PEoCgpk78eGDdlERHTeNXz2bAgFBYMB2LIll6IiYwdb+Kf+SDGRrWPdsmULwSW9U5iyoiKYggK5ntLWrfmUldWSrlYTfuYMRTt2UFXf8ZST43rOzR1Jc7N8vlevbvM2RGZnk1pQQD1wZnXHacmb9RO42HQCm0LtjElsKCl2fnYAdSXFFO3f7zxHdVIw4Q0mjuiiUa5ezeCjKzABzeRRoCvE5LKtfNyVhH78Fgmty8vKTJhMBqptDSQ0HcfRuuDoEc5EVBLcbvv2lAanYKttIqm1XXVeGSaT98+s1mJE1dLWX/G2zTyb+mcA7jr2MABZ+1/HBFgsNlpaVDRYqom21tHgRfNt8FF5isMEnFbpyS8sJt5+lriGZlRS2wYbE67GdPwI0w5+xoBaHUcTr/M4L4FSVlZOjbEGlVLCZGqLvanUJRDT4v48HnHo32z8ohp9677OhI5g/J6X8bbn8vIKynbtQl9agMlkIvXEJ5QHJWFqNpFrGMaZygYmlB6jSROFqbVuU7WihoKCQgDSSnPQVR+lyRLN6tVtezh7NgSNLZKEpkIsVjua1qrZBQWFoFA4r9eI3C3ENRdTnpvE6tXHoM6I2iI/D1avXk1lZRAFBXIA9bZtBVRWykkQeXlW4tudy+GH3sKmULF5+DOYTM3kBc3i6op3aKiq5JtvvsFgMmFVaDiyYwcmk/epzlOnhlJT457VNj5/I6YGeV8NagU2q8k5PoVSgaZ1HDuLqlH5uN9UTU2Map1tOdTczLxNd6OSbFSfyaDIrCPC3Dae7777Ft3pYA4ejKWgQE5VXLv2KHp927XVcLiOcJMJY4uGSkWF87o63aRHKiikOi6VgvJCFPWlbtfcjh07CDrbs9+xjY2BTdmeN8ZSb2OxWLjhhhuQJInXX/detMvBQw895OaxMhqNpKSksGDBAr9GVlfGtG7dOubPn49G073CXwLfbH43n6a8M4SEhDBjUVvMQK7yBGdXbsOs1jPy2psZOUa+XSIiFJw+Lf9imjs3ifgulP44dQr27pV/cc6cmcTobuYG71ZUcXZPHWa1npmXLSJhUO8YSwUFsHOnPO4ZM5KZMEFCWVQEVivJU6cizfKtvt7+et60SUlD6wzHokVtMRUKhQLFqVMweDDDFnnGG7Xn9LclGM4YaNaEcklr+63/K0HhEssYkphEzLU3kfNZHlENhagiIghWNBETE8OiRYvYZpAzceLCgklNTaGleiTRpraMudjYGLIylDQZ5Cyw+PgQ6owK1DEDMVS2ZWQNGDmKgfPGcvBPa/2OOSI0nKDEJAxlZ+T9xoVgamjzuNiUGqoMaSgkO2F2M4aGtqmgtLRQUq2ysW4ocNdz0+vl8BJrcChUlBESEoLCT6p3VHQUqakpKAaksDp1MTdvaxPzjY+PI2noMKILo7BaFTSPuJSiEDPDzm7y2ledfoBb5fDDKZc59Rbj4+OIVEaiVkvY7G3j2Tr6F+RINuYffsmtr2lzL2HLP44Q3niWhsGzMeR4D4uIHpDEwEmTKF9/BINNPhc2vR6D2kBCqJZLrXsxGAwQFIahWZ5mCo+OJTVVPn8pjRoMZgOzW/YxfVFbjNypU3DsrV0YVDWYw2PR1lXQog6Rt1MonNfr1ge/oAFYVL+RGYv+wdYnN6JolmVxpi9aRFER7Ngh3y/TpyczebLsISn/9gSGHPfPzkFqagoDBoDC3IKhxkBwdAwj58wh+1VZ8276+LHMnOe9iOju3UqnWpCDgWfrCVLI+1LoIglpkccw9fLLUShg+8OygZSVlcWiRT4MEZMJ5QY5cD/pyivZ9qgc4B8cEcLm5OuYc3yZs+mEi2YTPTQGnU5BYaH8WS9YkITrV2NhyBkKl28hSKmkNjoSQ7M8voSkAaSEKIhNG0pqUAqGJh1nQm8kK/8LGhoamDp1KonjOjcN2RGOmaGOOG+MpZiYGFQqFWXtroSysjISfBTDS0hICKi9w1DKz89n48aNHRo8Op0Onc7zYtVoNL1i1PRWvxc8RiOcOEFs6TEKkL+k3c5zeiarxz+OTanhtuBgZ102tbpN/USjUdGVj0aj6X4fbsQksLY1NmNOON3vzweu41arW/ejUskLnQs66kO+npVK93Pg5Msv5RX5+agC6E+pVKFAgUKhdH5+SqUSXKZ7FEp53fHUy9BZ6sloOIq+tpQhZVvQaJagaG2rUCpRKlV8PV6uszT38Msk1BxnfP5nqGZf59JOfpVRuddtPyqVCo3BwOYRvwTgomNtXyKuKBRKlEqlsz+lUuE2OWVV61nfKpmxeNdDuK5VShJhLdVICoXbckmh4PDYWxi87T9ENJViotXw9DPtNah8F3syf4RKpUOhtLu1nXr6f2ib1qNQKlEAkiaY5qAoj/7sSjVrxj7I2LxVRLhkrhXHjCfWVMCAmmNMz3kPRZSidTwu50GpQmHHo0+1WoNCoWz9XFUe620qLWXhmZxMXcjUQxsJcfkcHNvp7C3E1edC67Wxf+D1DC35hvqQRJStafIKl8/A9d7XaNr6kVRaFCjIi5+GsjVGx3G9OgxRx7Pj8ODrCKs4TW7sZGZrNN7vF6B2wCgKYyYQbcojpNm9/IFSqUKNlWCLEQUKlK3XrmOckSf3orlsttfP03EruuI4DgBDSw2gIDtpLrO0WhRIznWhxjI0Gh9V+F0OROUyFmXr/eL6+Tjub3/PSbVa7kNjNxNXn4sCBSVRowgeOQxVwYeoVCqUShUNIQM4EnI1w0o2Ag298l0YaH/njbGk1WqZMGECGzZsYPHixYAcl7BhwwbuvPNOr9tMmzaNDRs2cM899ziXrVu3jmnTpjnfOwylnJwcNm3aRHR0z1Z/FfRjjhyBd97xKXkhaXXUGnr2V8z3jpqaNrmTwYP7ZAhhxiIKYsZTFD2mQ7kTR5Bwcl4uABqrf7Fef2nvvjdSO+UbfFEZOpCosJguy504Cwt2kmZtGEFm91/S/uROghsq3eROJIUSu1LtDAoG2DTyToLNdSRWuwfHhzeepSh6NLHG0z7Poz+5E41V9tB4q8xuVuvZNOquTsmdHE9ewPHkjq4QGXX+aWKM8jWSlzSD4qQkD+07b5xJvojGqIs6bAewecTPfcqdhJrOMiHnvYD66Swrp7/sJibsIObMLiAAyaKj7p9zZ4SevXE8eT5rY+QfBtO3CrmTHuG+++7jX//6F++88w7Hjx/nl7/8JQ0NDdx2220A3HrrrW4B4HfffTdr1qzhxRdfJDs7myeffJI9e/Y4jSuLxcL111/Pnj17WL58OTabjdLSUkpLSzGbA88MEHx/GVH4NZNO/Rd1RWDCpH2Fuq6K0XmfyQ/ec5kQYGv9otPpINF3peYukRyYoRpTcZzUyn0d1mtRF+Vx+d6nuejY6065E18EmY0Et9RyInFOoKN1Y1jRei4+8orP9eXhg6lM8F1kUCHZmZLzHmGNpVQZ0gPeb0XMcL/rHcUk2xNXdph5h17yus5BVH0++pYa9gy60a3EQmnkcJJdhGwdNYuGFW+gLHwoh9J8V2KffPq/zD3ystd1JwfI3pNBZdv8jqs9DQFW5/aHa2VxU3AsaruZ8KbS74XcicpulksrdFXuxFHaoxVvxl53kVpnbtTWZiIailmXdR//GPYk9hjfpT16m/PGswRw4403UlFRweOPP05paSljx45lzZo1ziDugoKCVve7zPTp03n//fd59NFHefjhh8nMzGTVqlWMGiU/pIqLi/nss88AGDt2rNu+Nm3axJw5c87JcQn6J8qaKsblfgyAqm40/VlCJLjghLMCrrJ6BKT237F2iEPu5Fr/Bo0/qpNHE9VO7kRhbiGioZiIhmJyrIsB39pw1+14wO19wHInCelgtTIu7xOUdiv5sRNJq9jT6fE3a8MYfHYzg89uZtvQ25xp4/5QSBIztr5AcxfkTnTNdcQaT/uVOwlvPMuw4g2cjRzB3oFLmHP0NawqHcOL1nmVO4kyFXDF3qf8yp2o7BaUdu+eJYdwrTeh1uCWWuYf/AsFqTM95E7ORowgxpjrUWvpmp2/RylZWT3uUZp0ET7H5Ep9cByVEYO5dJcco7p8lvdpVQfRdWeYfGJ1ay2uJT7bRZVns2jfB0SaijocQ1Hq9B6VO7luh+zFccid1AfHEdpUjk3t3bsI+JU7aV8MtisxAInVR4hsaDsXltt+Dm9BnPGUU+7kYNSPOpZa6UXOK2MJ4M477/Q57fbNN994LFuyZAlLlni/aNPT050piQJB+4eyqqb/1frot7S0QF0dhHeszN7T6JrlQpCyjMV8AMoGTiOK/3O2qUibiKufKrp1iqU9x5I96xx1BnN8CrQ0OKepagwpxNed8ChMGWs8jbbZUwbFGwqpXS64QoEjPb1JG06wuc53217CYciobS2MP/Oh37a6ACo0d4W4uhyqm4YCfjTNWmlRhxBdnwfAiKK17B10AwC2AKpiR9V5v1a8MevAqyiaGlvrWPk2ltTW5oAMpSZdBPkDL0aKsFMWMYT42pMBjyUgFAqKo7IYVryhR+ppFcaMY0RYx88Aa3K6U5NucOnmtincwLSz+4TzahpOIOhNAolJEPjhoO9ig72JrtUQae9JcMhenBowi8q0CW7rUkplmaT2cif1QbFe96G1NGDXBvn1SHRG7mR40Xoyjn3htsy1+KRPGRCg8edtmbjtK2u7yp28N/Buls94jWZt4Bm6GmuTx3k8efEv+GTKn9zkTvxNvbTXRfNXwdyf3MmIIjmjMLTJu0KDL9ofr1WlY41LYUpXPbmDabJagz+5k6SKAz7XbRuyFJCrZPcEeXGTva9QKmlRe59C7Yhdg3/QjRG1IklyQozjdSvlCaOJNQaunedEqcSqlK/3kJaONSWjTAUsKP4ARX33Sqx0B2EsCQTAu4Pu5bMJT/b1MATQFhPxz3/6b+cHdbOJfRnXsXXY7Rz0EjMTUV/o9v6zSc/w4dS/YAr2biwB1GRdxMdTnveQO6kxpGBXqlDarSgb3WvndEbuZPegm7wun3byHefrNeMeQnL55Z4XO5H1o+/1GlBuVyiRFEqPgO7c+Kk+5U7i6nK4+Mjf3Za16CM99NYyynd63X50/udu5QNcqYkfzq5r/0RxtO9JJbMmhFWTnwWdztmPQrLz+cSnOJBxjc/toE3uRCnZApY7sSvVlEUMoSzce2BzaFM5UbVnfG5fE5LM4cgp5PmoLt4Zdgy51SO+K7illqDG7gl6VxvSfAsuS5JTucCv3ElDg1tg92cTn+bziU+Sm7nAZ4JMd9Cs+sBj2bC6/c6yDH2BMJYEAuDywuWkl/sXZRacIxylPYI7VoT3Reau5czMfhNDcyVBFhM6H0X8HBiaK8mo2EV87QnfjSSJuNqTbnInjbpI1mfdS3FUltxPzv4ujdccGU9e3CROJF7ssc51elhql0I/tGQTqZX7OB0/PeB91QUnBCx3YtaF9ogaPUCTIRZzSCRJLsHg7VHarR7ZVXaFCqM+gTNxU72PMSKWupBE1HYzIc2VblORW4fdzrrRv/W5vxaNgfWjf8uG0ff6bKPzY+zWhCSzacDVHO3m9C3Ixp43bcIJu16HhgZSquRryxzduXjEhqBoQlp8X/8Ow7Izcif1+niM+gHe5U6q/d9rAMqqCqfciTePvqK0/yXUCGNJcOGS2qYUHmUul7NdBJ2jNwIuL71U/t+Vap/tGJP3GZfvfZqB+9zjaiyt0251evmLZ0DNMSacXklapXeB2MNpVwAw/9CLbsubtWFMzXmXlMoDnR6b5DJtp7CYuXnLnQwt8Sz46Ortumz/s+jWfOp8H2SuZ0jJt+gs7h6takMqVxa+x4+2/NLvGOqD45xTkN7YfNmzxJ7ewfgzH7hliHWW7UOWMuDMFma++3OfQfUgx0ANqD3elmXZSmL1Ya7d+aDXbUyDxlIcOYqUyv0MKfnWbZ1VqWN87ofMyP63120zS75l3qG/ekwd2oMCqxI9vHg9c85+RqSpsOPGHZBRvtNpSJq1BjdvnqKlGYUkYVNpaUoJIL3ftd+yHU7vjyPWzBvV6eMD7lNnMRHWeBZdU63nygA8TcoG2QA1BcVQbUj1WC95qWPY1whjSXDhkpwMb7xBeYo8heGoNizoBNHRMM5/TaHe5sTwxYD/uBNArgrYiiO+yOERGpMnGyDtp6wc2JQawk94eh4Vkp2Uys57kyrDMmjWt/2i1pg6jttwoMo9xfKL3mD5RW84l03Nede9jd1CpLnC6/Zj81Yx/sxHreMYiKRUeT13uzJ/iMpuYcCx9QwvWt/ttHmHx8d12qb9lCbAtBP/By4Vy8sihnpMDbZH1yrhMaJoLYNLtwBQHD2aZm0o8bUnian3HqQd2lxOfO0JQpvdz5UtPpHKsI6jjdMq9zK6ZodbtfeuMvXkf5iZ/SYAzcGR7Mz8Ubf7BEiv2B1QO1N0WmAdzp7NVbsf48o9TzJy/3seU7TdoSVKTm2U0vpfpLcwlgQXPL5Slx3YlBrMaZnnaDRdozlpkJzmHJaBFNK1QNB+g0NfzupF2MwLTUHyw9pXDSEHltRBXn/FuqKxyTER3r7E1Q11Hss66q87GPXx1IUkYlN0HDje3Sy4otTp/Hemf4OkMGYspxNm+FzfvkTAsQAKQG4fstTnNJmjv/yYCV7XA85z43oPa2xyoVGttZGRhV97bOM6zRfcahyP8NLOgbU1pd6m8syci2nNsJt6arnP7b2O20s5BOi4CKrKZkZh7VwdtSgXQ84tCaGrXmGdzjl1pzWb2D345q71A6jtZr/XrikohmMp3Z/i7Am6bSzZbDYOHDhATU3gv4wEgn5BQwMcP05YlfcATmtiKl+PfZCvxz6IpOln5WTbYYmK57NJz/D12N8jGQJLSe+3fCR7PTjVhSybDjiReDH7M66lMUj26gws3+G13ecTn2b5RW9QEjUSkAO1vTGodKvnQp2OrcNuZ+uw27s8zmZtGJ9PfJovJjzh9Jo4sdsJMhs9vGCSQsHBMbcC+Ayybk9G2Y7WCt6eTM5ZzsRv/uJ8b1UFYQz2PjW6bsz9NGoj3Jblx07kbOQIwD1IvSeQFEoqwgeTnbqAqP0bvAaca62NJFe1ZWgeSF9MszaUercg/o69ZfZWwyYnYVaHBsaxjMspiRrJ5uE/89uuKmEkJVGjfE+L2e0+g9TDjnSuSKcrIc1yPFF20lyPYwmuO/dhCEFmIwm12YDs5awdOsVtvVGfwP6MazGrux6/2FN0urDCPffcQ1ZWFj/5yU+w2WzMnj2bbdu2odfr+eKLL0QhR8H5w8GD8M47aJt9yJ0EBVMZNvAcD+o8o7a2Te4ko29c5wbTWQpixlMSNapDuZMzCXIgdEKenHHna9rNgdbahewbtZq8OPmhPyP7La9NqgzpRBmiuyZ30lDPdbsf6LihF8yaELQW94KVsjfD+48Bg7HETe7EG9+M/DVKu5UBNcfcloc2V3A2crjHcnf8xy8BnsYi0KiLYO2YB2S5E7t3z0T7sgRHUy/jaOplfsbisu+CM065k4IBUzibkOA3U9LBydR5NMbMC2gfm0b9xqfcSVh9MRN8xFl1l4+nPO9WpsJB7KntwKCOO8jOdnvbPumgsxxNudSZzfnI9la5k5wT0M/kUDvtWfrwww8ZM2YMAJ9//jm5ublkZ2dz77338sgjj/T4AAWCvmRo8UbG5X6MqrKs48Z9iKq+lqHFG8ko2xHw9FWP4NiXTgcpKT3btw+B7PbElR0htXJfh+ni6uJ8Fh54nhnZb3Jk0NX+21qb0VgbZW9CFxhS8g2zjr3hc31ZxBAqEsf4XK+UbEw4vZLQpnJqO1HDpzJ6qN/1vjwZMeXHmHP0H363jTQVorU2sjPzR26p6MXRo71WGB9etI6CmPHOApDeGJ/7EXOOveZ1XW6rwTm05BuPdUo/UzdNmsDrSvnCdWqoXh+PVaWTDevvQRFjiypINnA6cywu8X4UFLitcsSI9SitXi+VTc5wXJd1H/8a8jD26I4N1t6i08ZSZWUlCa0PsdWrV7NkyRKGDBnC7bffzuHDgaWjCgTnA8q6GiaeXsGIwq9R1/bvat76vGNMPL2C6SfeRlnlPbD3vCEpSf5/g+8v2Y6oHeCpkaZoaSbGeIb08t3OCtu+MrNu3HY3N2y7l6k5/wE8iz/6oiUuBaxWxuR9SmrlPmcAeWdp0oYzrHgDV+1+LOAaPgpJYsrOV/xmt/kqAhncVM2AmmMUR49m3Zj7vbaJaChmZOEaUiv3sW/gdYAcA5N59js3uROHcRRdn8fiXY/4/TLVWht9ihk7CoR684IEt9Ry8ZFXSC3zDF4ujsryeg6u3PM4V+96hOCWWp/j8RhDcBwVkUOYe/hl5h5+ucP24fVFTD35Dln5X/htF1lxkoUHng9IV60kaVKgww2IG7fdzY3b7nYaS45Cq37lToKCZLkT8Ji+8/iRou58JfD42myGuGSCmn8mq3TE151k8a5HmJbzLk1qAyj7Lsy603uOj4/n2LFj2Gw21qxZw/z5srxAY2MjKlXP1OMQCPoCqd3toKrqXOXgC5qWlrbA7HOMrkWeShtevN657Gymu/J7VcpYt/cxdae99pWdONftfWcL7rUMSIeWFucXSEX4YJq1njFkUaYCtGbP6SVv+EtAsLSL5VD7MDw6g72jrEKgQRcNyHWRJuf4D27uKGi5qyRWHyWsMbA4G5tSQ1hjGYbmSjcDpf097432BUz9cfG+FxlUuo3R+Z/7baexNBJj9F3s0kGTLoLczAVIEZFUhwaYrdYZFApnAH1PyZ1I4REdtrMmpjprSg0q28a8Qy8x6dT/ur3/3qTTxtJtt93GDTfcwKhRo1AoFMybJ8/P7ty5k2HDhvX4AAWCc0VjgOKaAh/s71pBxu7iMJbaewwcU0658VMpz3APHE0uk+sptZc7cdRdao/W0oBdpfEwTlzpjNzJqIKvGHjkU5/r/Ul8uMqdtE/bdpU7WZHxK1ZM/WvAorEACsnmYZydmnU7n0182k3uZMjZb71tDshB4644goq9EeYrEF2rddacMjR1zlPa3gtoVen4YsITzveuZQL2Z8hizf7KTqSU+RZC3jlIzgTzdd10Fm+V2AFQKjG1GqidZe/ArntonUgSNDe3vW6lMn4kMfUdG30eqNU0a+QfEYbmjr32UaYCLj77aZ/KnXTalHzyyScZNWoUhYWFLFmyBF1r8SiVSsXvf//7Hh+gQHAueHfQvYRmjmdRXw9E0CZ38tZb8MILXepCZWlm76AbUNnMlEYOp/3PuEhjntv7L8c/hgLJI6PLlZqxF/PR6Yu5cs/jQFsMW40hmYiGEtnQaHafkvCVReeN7UOWOrPGHNOE4J5Jtm7M/QwPb4vJKYgeR3X6YoYVr/cQWW1R6tCpgz2MyMKYcRxIv5or9zzpMYbE6qNtoqatNIXFU6+Pd6tV5DULEPx6VGrihlEw8weoP15JYvURwNNzZ1eq+WL844wNCiLKJMfGKCUrX417mJSqA61iyd7JjZvCtmG3k16+M3C5E4WKqtB0n8ZSaFM5qjrf01NVoelkh49DG9O5QpHe2D34Jkoj3KePg1tq0bbUA13PcK0MzaBZG+Y9mUGSnPFmCpufWMeGBrcfQ6vHP4pSshExJIm4Xf6nHLuC+otPgJFuy7JqdqJovq7H9xUoXfK7XX/99W7va2trWbp0aY8MSCDoCxYWr6QoEqBn4wMEXSA6GqqqoBvT+kO2v8OQ4/s4kL4YhWRD0+T/F6nOaiK6Ph+jPoHycB81tSSJ6Pp8N7kTsyaEjaPuYvKp90mpPIDhxF4YE3glZAeW0CgKQiYQZzzlYYjYlWqn8WRRBbmtG1i+A7XdzLHkBQEr0lcZ0gKWO7GpdT1Wpb05JIqmsHiGthpKXvenVGNRux+jXaGmOjSNZk2oV2PJEhqFUR+PSrIS3FKLysXQ3Jn5I4x634kCLdpQp8jutT7aBLV41tdyUG1I5UDSElJTu5/ccCphllfv5KTtr8BP7yG5urW6d2TnKtubgmP9Go/6ViFblTXw6dIag3y8Ye1u0ZTK/ShqqiHGvyi5srrSKXfSqI3wiKVTFhX6StDsMzo9Dff888+zYsUK5/sbbriB6OhokpOTOXTIt+aPQNDvSG7LMoprLiayoagPB3Oe0htyJ1e2iokO6P7Uxti8VXKQ8e7/ui13TKc1BMlTG0nVR5iS855PgVhHgcVL9z/nttwUFMPYvE+7JnfiUhxRUiq5ZufvvXpsXPXCFu37A9r1bQZDSHMVw4vWeYj11gUncGnxyg7lTpq04X6nFr+54i9EFRxgTN6n3ZY7iSk5zLT/3e13yktjbSau7pRHOYD42myu2PeU123qh0ygKGoMqRV7PQKmmzWhjCxcw9ST//G67aDSLcw58ncGlrrXLrJrg7y2b8+Qs98ys+yrHnl2pFTuJ6HmOAAWjd5tOlHR0ozSbpXlTtI6F+6SWrHXaWz7kzupSfEtcNwejbUJfXM1GnOD50ofpRxcUZrkHy+moBiqQtO97KCf1Q2gC8bSsmXLSGlNEV63bh3r1q3jq6++4tJLL+X++71nUQgE/ZLU1Fa5E9kTIOROukA/kDvJGXpFYA1dMmkchQYdwa2j8z8DQGfxHqRu1oQQluOpG6eyW3xOSfmjMiyD5pC2GBRtXWXAU0fqnOMecifj8j52b6RQENdc7HV7V7mT0sjhPmOtHHInSYdWyx6dbqbNa1rqUVma3dLyvUllzDr+TzC1Bb9XhA1i3qGXfGbNAeis8pf2iKK1DCzbDrTJnSRWHyG+zrvXLbzxLEnVhz10IW0DkgOSO8ko38X4qs1ENHg/151hZvabXHRc/kyb9NFsHdr1oqauOM5HR9THBVBjCWDmTK7c+yTX7HqIrL3/5zWBoas45E7sGQGO5RzSaWOptLTUaSx98cUX3HDDDSxYsIDf/e537N4dmAaNQNCfcI0P8YU5pf/dvK40D8jAog6mPjgOSd+VUof9iJbW6YAAfqECNOjlFPNmrf/6Opb0TJ/yJI7YGYfB4i0oWlNf7bGsLLz7sSq+MGtCaAiKDkjupL1nqbMUps5gxYxX/LYpjsoiL873NHV7uZMTSZd0uN/Nw+/oUO7EUW/JH673sMNw0libvNZocvVsOc6bP7kTbzInDmJbg5tnnPy/DsfoiqvkiiuaDoqgKu2WgO8LB9GmvLb99oTciV7vjIPTttSzM/OWrvUTAA26KE4kXtxr/XeGThtLkZGRFBbKqZRr1qxxZsNJkoTN5jvFVSDodzQ1QWEh+nrvBSetCcmsH32vLHeiC8wt31dYYgawcvrLfDbpGaTQ7hfl61P+2zpldjKwGJzOcGrALA6nXeH0aHgrpghylWNZ7mQU4DtQe4iXL2O0WnZm/qhbQqjN2jA+mPZXVk1+1rOCtSShtjZ7lAnoqtyJ0m4BhcKjZMDknOWM2/Kq871ZE0JNiPfYnI2j7vKY4jkTN7XX5E5Ajps5mraIyAObvE6f6qwNpJe3iR8fTrsCm0rrllWmoGPDw2EseZMIac+J1PlUh6axfYj/GN7KAVmURQz1rWcoSV5/xCkkifBDmzscsy/8yZ0E1Z/7+myG5kqSWmOx6vQDqMt0rylWF5LInsE3nZ9yJ9deey0/+MEPyMzMpKqqissuk8vH79+/n8GDB/f4AAWCXmP/fnjnHfRGH3In+hDKIkQ5DL+4yp2k9p6orD9CGsopiBlPaeTwDuVOcgbI9Zdi8mQZko7SlgOdGnNDo+HUALny95Sc97w2qQlJAX0X5U5MRm7cfXcXtgSLOshjOkt+7z1GJLw6t0O5k83Df4ZNqXHG2zjQt9RQHp7ZgdyJbxzGgtruGXhcHxzH6vGPolP6zuJqHzR8KO1KDqVdGdC+1UV5TrmTwviJlMfFYAzuuKL88YxF7I0PLKd2/ej7fMudGIuYcOz1gPrpLJ9NegazyvNDjTu5BUjvuIOcnB4dz+HUK9rkTna2yp2cOtnF9LPeo9OepZdeeok777yTESNGsG7dOgwG2TI+e/Ysv/rVr3p8gAJBXzL47Gay8r/o9wUqVQ1G0sp3yynZfSV3kp7es31HB1ZXJr70IKmV+zosfqg+W8jcQy8x9eQ7HMu43G9bpd2K0m7lVMKMgIfryuCzm5l+4m2f689GDqc82XfWnFKyMSbvUwxNFdT7EK/1RnWU/x+sjTrvWUrRFdnMzH7T77YRDcWo7WZ2Zf7QbZqyIHYC6RWeIRgjitaSkzDLryr9mLzPmJX9T6/riqLHOPtpj9ruXfwXoNmXt6YTuBpgRkMipqAYlJL1eyF3YgqKkYPHuyp3kpvrtsrVe9djtE41Ku1WgsxG1o26l7cHP4A9KqaDDXuPTttuGo3GayD3vffe2yMDEgj6C0pjrdMzoK7JAOL8b9CH6M8cYWZ2a42eqichpWeK5PUJSUlyraUf/rDLXdTFDyEc9yk2RVMjCbXZSAoFecNkj7gvuZObt/waaJuCMWtCAvICmWOTwGolq+BLp2clrq7zv8SbtOGMKpADq7cO+4mH18YbCkliwt5/Ylbr0Vi9ZCnhW+5E31hJSuUBiqNHk514iVdpj0hTIVn5X3A2cgT7Mq5lRvZbSAolGWU7GFQmB7kfSrsSizqYCadXEms8zfU77veIZXIl2GL0GW9Vq5e3s6o8p8CDW2q56NgyipMmQ7vui6LGEGkq8vAKLtr3B5SSjfVZ99DsJyvMlYagaKoiB7Nwrfydt3zWMr/tDY3lDM3d0qpP51tQN6LqNHMPfUZCbbbPNg7KBowNaKyB8oPNrRmS0uugUGBRB6OxNmFT+8nVd8idbN/uMX0XbG5XWqELciexdacIayoDhRKwY/7FXfAWJNRmc/GRV6kypHAw6kfdKifSXboktHL69Gl+85vfMG/ePObNm8ddd93FmTNdqOIpEPRj+rt4br+ipQUauzBl1QNoW79sHfpkACVD3YNCqxNHOV8rJImY2lNe+8oZMNvtvcrm24PhjebEgdDS4qxdUxI1ymu2UHjj2YDr2vhLQLAr3b885AKG3cPqJ6DZgWNKSiHZZT1CP5IsvUVK5f5OZaFFmgoJbyhxVgYPBPv/t3fncVFV/R/AP7OzzcKOKAiuoOK+YaaWuJZp+ssyn9Ly0SytzDZtMW1Tn9JKs9UesydLW63UTNx3RVxB3EVUNlmHAYbZzu+PYS4MszDAMMPA9/168ZK599w73zmDzJdzzz1fngDSUsdKqgBAQtJSdLn5D/pc+9luO3FFiUOJUrlEgSud7wOTyZ22SrgZHg9XQwcBAJig4bfrO1zupFUENzoZnXsMI898YFzewU6BZHerc7L0zz//oEuXLjh+/Di6d++O7t2749ixY9xlOUI8VYXQw+8ic7cTtstCNCYvtfEv25olQkxJSkZwH+R0ML+cFp57GoBluZMCGxOYxdpSMB7fIjmpzt6+mnqk/4mOZ3+xud9esdeyWVWj+DUv0VUvd/Jr23/jl/7LubWk6ut6/FRs6/26WbkT00iSNTUnzdsazQIAabmNP0jEYq4Ar71yKdbUXDdKJ5Dgj37vVsVTrZ7cqWjjitC2RhgBIDLL+tpbAHAi2rhAs7IOl0rtMd1QYEEorHeydDrqwQZEVImxqst21S7fFQR1QmBJet3PJxJxE+1ltn4GqglQZWBwzt/gqdxTfxKox2W4BQsW4IUXXsCyZcsstr/66qtcYV1CPImp3EltE4SJC5jKnfzvf8B779XrFDyDHsc7PAqJthRZ/l3Qucb+wBqFdP/p+SoAZjexKOidgF+vJ1iUOynybQ1F6W3wmAE8jfloUfcbfzm0NAVgXu6k+iWkAVeqCtXuipuHWEXV2kQ3A3sgJWIMutz6B/4q84URS4VSCMQyi2QjV94Rye0ewphT71vE0Dr/LFrnmy8urAqIRGF+JBTVkp5OmdZrw9VW7uTWgEng/7WZK6libURqax9juRPTCs8CgwaJPV5Cm/zTiL2106K9iancSds7JxyemK/nGZMQW4mutDwXfKXtGe53ZO0hlHaDKLDmT1jdnYqeiNsBcWbbRLpyCLRqAPW/GzdX3tHqxH4AAGMIL6wsPVNbuZOjVTX//un5CvgGPWQxbTEg2fayC/Ul3L4FNcud9M4/AF75OAD2VwdvLHUeWUpLS8OMGTMstj/55JM4f75+dz0Q4m7Ds35Hm/wz7g6DAICscumDBixFEnNwLYac/xIifTn0fBGEGvsfnjxmQIAqA/4qOxXmGYO8NNOs3ImBL8TernNwM6gneIxBmmY+2dXRREnv5YubQT1xI7ivxb7qizjWXEsqIu80ZOU5dRo9yPTvitDiiw63dxatlxSlgZEWteeq04h8uQKrJgaeELnyjjbX29H5yqHyCgIPBkg0JWYT/ZPbT8b+2KdsPl+FWIotfRdjW+83bbbxVhfa3JcvjcK2iEdxKmqCzTaOutB6uMX8LqG+AgMPrQDKyrgSNVp53SY5l3iHWNTgq87081yXcid5svbIVXQylsOpJiLvFHhFtvvLhF9UwCXDxvldNfanN71pPXVOloKDg3H69GmL7adPn0ZISNOdAEuIhfCqX0zhZekIVN1wYzCEM7GySle47YnBjup97VdMOvoyOh79n9l206Rh06W6iPzTuOvCf9HBxuWlS+HDAAD3J5uX3CjybY3OmXvqVe4E1dY10nv7YfTpZWh7x/JSZvXaZvclvw3xvqrpDvKyLMTd2GJRJLVUEoDhWZtrLXeiFXrZLXey68FPochKQ9eMvxtc7sSvMAN9/njT5orhgPFyZ4Aqw2LhxSDlNQw/94nVY5Qx/ZER1BtRuUkWd86VeAWjQ/ZB9L2y0eqx0TlHMTjta4s7upjYdvHc6trnHMaA3J0Or2tlT6vC8wiqTCC0Qm+zfuKpyyEwaKEXiFEW3dXWKaxqk3+GSyDtlTspau34eQV6DSRaVeWoVw0O/JHDVxYBMN6ZlydrZ9mgHpPEG1udk6WZM2di1qxZWL58OQ4cOIADBw5g2bJleOqppzBz5szGiJGQxhEVZSx3EmkseUHlTuohKMjt5U6udBztWMNq81JMd7ldC4kHAHS9uR0AINGqLI+DsSyH9Oppi+0Cgxaxt+o+VzNfGoVy36oRAnFhjtmIlT3C82fxw+DP8OPgNdy2rre2m7XRCSRoXXa95qEAzMud3Arsab/ciV6DiJOb0TN9c4Nvm/cpyYG3MtdstM3aooz3pKw2K3eSL43CqNPLLeakVVe93Ikp8clWxEAj9EFk3km0LrRevNe/9Cba3jlhUdtN1yrCoXIn7XOOYEDebqckS8NS1+CeVON7Wu4bhH1d7Ce6jnK0HI8yzMHV6OPjcd/Jd/B/R15E9xP/tSh83BBcuZN2TW/NxjonS2+++SYWLVqE1atXY+jQoRg6dCg+/fRTLF68GG++aXsok5Cmiq/X1tpG07r2X5zuVBFqXBBSI/L1/HIndSznoPIzTnyttdxJdCeb5U5Mf3mLKz90dQLLkQVxseUKx9ny+s1VsTehuDqNyNdqaQzGF5glOY4mWrbcajMQvwz80G6bzICu3NpH1tS8hGRaANSevV2fqbXcieluLXuqJ2DeWuMoGw8GtMs9atGWoarvG1ruJERpvKtyyIWva43RVgzVibXWl3xoiKCSqktadbkJwSaplEtcJRVKHHZSDTtrysQKXA2r/f13hTonSzweDy+88AJu3bqF4uJiFBcX49atW5g5cyYOHz5c+wkIaSoqKoDCQogqrI8m6EJbY1/XZ7Cz+3wwbx8XB1c3mpA22DDkS/wcv9Lzy518V1kh/kLtt1bX1fWQAUhrMwLlEuPlCFsjDpvuWmVW7sRUaLcmq7ehi8VIbvcQkts9VO841WIZ935aTFZmzDiZvMZt1vUpdxKVewx8gxZMILQYIeh35Qd0P1JVrLdCJMUdmfUaifu7zLaYe3IlbHCjljsp9QpAWuQoKM7ut1ruxEurQoesqtIgKZHGtbWqL6jp7HInV1oPRalXAJLbT7bb7k54D+TJoqHn1+12fYFeA/lp65PrHeGrNtY3vNB6uFlhaQCQlNU+18jZqpc7KRfLoWxvPkpd5NcGRztN88xyJ9VJpVUT8S5fvoy7776b6sMRz5GcDKxfD3keQ5GV3czXz+5f0gSAUllV7qRNG7eE4FOej4yg3shRdKr1bsYLbYwLBd5bWe7E3m3tQNVdaXVaR0gk4p7H1no7xT7h4HsrHCx3Yn75i6dS4tGk+l2i0fNFEBiqRlJ5jNksd8JjDAF3LtZa7uRw5ydQLpZbrBsk0aqQL42qd7kTUzLIZ5Z9X+wbji193oJEAPC11icm13xvz0RNwBkHJ2ILb9/gyp1khvTEncB7UeTbutbjUjpMwPFwx57jn54L0Ovar1ZXKJcV30SflNVWjmq4rb3ftHr5MzRtLwAH6hk6eU3Fc5H342ZgTwDA60mzjeVOrl2p5yqQjaeJhUNI0xKdcxSxt3ZAUGi/hpi78ctLEVaYhiDltTpfxmoQTeWijRIJ0M7KRM2GkDu2ynJY5klE5p2EoJY7z4TZtzAsdQ36XfkRF6Icm+fkSMV7a6JzjqL/5Q02998O6IbsiH429/MNOnTN+Bu+6nyUShxfJ6nQ3/57oPIOtro9IP8y4i99Z/dYWVk2+EyPpA5TzD5sr4cORLucIxbtu97ajtSI0XYLCsdlbMNdF/9rdV92ZV3G7hlbLPbZWxrAWt2zuuLpqhLKQmkk8qTR0PHFTi93Yi0RbGxFfm3MRtccUn3C9RXzBV2t3ZRQZzye+ahdZRklHjNAqFNjZ7d5+L79PBj8G7ZmWEM0vSnnhDQRfJWSq+8lzG8NwH11iWrje+UMhp+rLHdyZzHQuhmUO5lmv3K7PSVB0ZDWLHdSVorW+WehE0iQ0dm4HpytuUNT9xtvNzctVulwuZOAMECvR7eb2yAry0GBX6Tx7q46Kpco0DPdOLH6YMy/HSqZwmMMPc58V69yJ76qHETlHsftwO64HHY3hqWusWgTWJKOHul/IMu/C05FTzSuuAwg8k4yVxsuNWI0KkR+6H3tF4QWXcLDh56zW+7Et6KAW+28pny/tgCM70HNRTq9K4ow6OI6ZLXqbVHuJCOoN+RlWRYJ1cgzH4Bv0GFv1zm1zm8zqRD5oUDRDvclvgKg9nInPuoCRGccM9Zeg+05W/L8axiaut2h5UruhNTt7rfamEr5wLAa4PPAeHzwmKHe5U4s3r96lCQJLEmHX/mdqnInM54G/me8Q9BU7uR0wL/cepccjSwRYoMgt+F3uLQYFRWA2sptxC4g1hjnnEVXm8x7q4v5Bbmi0KqJ2EJ9BYILL1k919VQ85W+HV3c0EQd0RFQq7kJ1xnBfayWO/FT5zm8BlP1y2a18S6r22rX1lSIak8LC32rLrnenfYVRLpyAMbLfIznmo+V6Jyj9tfFqiG4+AoCS9LNyuLURiP0gU+5432acPw99EzfbHdUETBOjHYkUSqXKHCpywQwmbzBK7GbmIpEAwB4PG79KqeVO6m2aKoturA23JIVbe+cwOhTS42FnE3z8EQNj8XZHE7T/vzT+gRHk+vXrd+mSoinqOtkS1LD8ePAkNrvgHI2L3URAFisYK0R+UKsLcXtwO5Qdh6GbqhaiDEsr3LV4mrlTsS6MuRJrd/16MhdSga+AI7+Td372q8wiGwvzmgvSSt/ci6Q9CkA49yd6qNFkgol9DoGBuDPiMfh064nRqSuhp+6/peRb/R7CAcy2nIrgbcqPG+39IZp8UQT++VObCwHIBJxk7ZtjTwBsLr2U8271xiPh7/6vIUpB+cCgNkyAaejJiAqN8nm+QEgKtP2jUunoiagY8r3KPEyXt7kN7C2WY7Cxu37QiHy/drWufQLAJyNHIf+V35oUFy2FAa2R8CtA7U3rEksRpFPOIKVV6Eosz9vEDCWOxmg2wle6SQAtSdjjcHhZGnChAm1tuE5eDssIU2NqdzJve4OhFSVO9m4EVi8uN6nOdZhKrw1xbgdEIeaH0HBheYrWO/s/gL4zIBSL9ulFPJ7JeC3a8PxwIlFAKqSD1PCwmMGs7kugHHdH0dvB69e7qT6Zad+V6sWVNzX9RnEBlUt/nvbvxsuhN+LuIyt8KkoNEseisSBMHgHWyRKxb7hON7hUYw4Y7lUgLVyJ8qQDsgtjkJ0tQ/qmNu7rL4Ge+VOikI6I7PvA8DWrdykb2uja3/3eg09vb25CeMiXTl2d3sOEfmn7Y4KXQ8ZgMOdn0BE/mmzZFPPF8Ng4w8hPV+MUq9Aq8szAMZkjldi+07YHFlHiPw6QRgQY7ONo861rZrobMJjevAMesDhNNxStiIGjMezvoo3YwgtNo6y8uzdxKBSGS/BVR6zK24e+EwPn5gOGHDSdgma+hLu+gc1y50MyNsNXtlouCtZcni81GAw1PpFd8IRT3V3zlaEF1i/jZy4mFflLexldbsEVl3Mga8x+MLX4IFBLZLWupaWji+Bd0WRWZFVCzwefDRF8NEUmW3eH/tUVbmTVPN1fRxNlAxCEW4HdsftwO4W+wQGDfe90tu8SkJY8UWIdWU42vExh54HAK4H90dgieuvBGhFPlCGdLB7d1yFyA+lEvOEVc8XISugK9LaWK87qveRckmuSF9uliidiRqPw52fsPl8arEMm/u/jz/7vWOzjU95gc19ebJ2+DNyOk40YJkIk5SIMSj0My/k7KUpwaD9y4DycoQXGkciddK6JQslPqHQ2pn0brqUaXU1bhuy/WORGdANepH5chMReafAKy6q9Xh+cSFX7kRt5c48/mXXl+OpDc1ZIi1XaFWl8CjVJQSXNL16RC3SI48Y/23AUgTGdYgY+lz9CQ8ffh6dD5nfcWUqd2K6ZNM2LxlDz3+OTlnW17AxLYw34fhrZqMhBdK2iMw7Wb9yJ9UWJtRJA3DvuU8QXuMSFgAoq13yGndiMUSHqtZ2Cii5gV7Xf4O3ptjsGLVIiiE5W2std8J4fLsrMO99YCVkuVfQ+fbuBpc78SorQM9t79u93C3RqoxrRNUYBVGobnE3W9RUHDsQN4L6Ijr3GLplmK/CX+AXgTb5Z9CrcsXymtrmJmHgpfWIyDO/GYAJHbskH3UnCb3z9kPawEVBASBYeQUBJcaSS7oa7wmvvAxCfQX0AjFK21sm1Pa0KkjlEkhrSwaYFLdyfHSMZ9CDb9BaL76rq30uHr/YeGlV5RWEOzIrq3Xzm15q0vQiqsWaNWsQFRUFLy8vDBgwAMePH7fb/ueff0ZMTAy8vLwQFxeHbdu2me1njGHRokVo1aoVvL29kZCQgMuXa7/zhDQD7dsDX36JnEhj8VIqd1IPgYFAD/euRXW93fA6H2NKki62GgYA6Jy5G4DtkaAS71D4XbdMZAQGLXqk/1Hn5y/wi0S5X9Vt/OLCHASoMuwWPDURnT2JTYM+wc/xK7ltHbPN541UiPwQpbI+ib16uZP0kP42L1Ed7zgVANA26Wf0vbqpwbfNSwtvwC//htmEdWsrpY84uwIoKeEeF/q1wX0n3zEui2GDKRnocmsHIvOSAQB5smjoBF5ol3MEkfmnrB4XqEpH++zDCCpJN9uua93WoXInnbL2Y3DudviX3a61bW0Szn6Ee1KNc9HKfIOxp9uzDT4nAHTMrrp0aetyIwAUh8c6dsL+/TH21HuYcnAuepxY65xVwStx5U46OFh6xYU8KlnatGkT5s+fj7feegsnT55Ejx49MGrUKOTmWp8kePjwYUyZMgUzZszAqVOnMGHCBEyYMAEpKVWXW/7zn/9g1apV+OKLL3Ds2DH4+vpi1KhRULvpzh7iegK9ptY2mvCoxg+kASqCq0ZhmJcLV7vl8dz+V2Cx3FjCxJFyJ4V+1kerTGUvJDrrq7kDgKTQ8hJdlsLBD5gaHP2AYTw+DFbuLtMJvSpvTzeyl0g44nbr/tjc/z27bbL9Y7m1j6ypuUSAI2UqdsU9X2u5k8thtd80UD0B862cEK7nixCRZ5kkmZU7qawF6OpyJ7bULIjsDKbLXQCcc6eiQgFFqTE59CovwoHYpxp+ThvKxXLcCO7baOevC49aZ2nlypWYOXMmnnjCeA36iy++wNatW/Hf//4XCxYssGj/ySefYPTo0Xj55ZcBAO+88w4SExPx6aef4osvvgBjDB9//DHeeOMNjB8/HgDw3XffITQ0FJs3b8YjpssBblJUBJRna1BwOR+iardS8iUi6HlC8NTlNo9lMnnVmhTl5eCV257/waSyqls11WrwymzPszBrW1EBXqntDxfm62dcrLCubTUa8FQlVtvxfb2hl1ROuNTpwFNWu/wgEHAVr5lYAvhVDjkzBl6hlXkHOh3A40FckA3TKy64XDWJtdCrFQ7G/Bs6gQRj8tUouGxMoCsyAd/KXFp5HRCqHXgu0+sUiQGpFEqlsa1vRQHKbwEFVvIbU1sTXoHtO2GKeQr8NMRYmmJ+cRHEl220FQjA5IqqcyqLLYbN+UI+mIHB4OVTNX+osq9V2VWvvfwWUCAHJLcLIawA1MWALh+ASmW8ZFBjCqNWq4X6djny7xggkhjXsxRrSyHSq1FQbTDX54tvjd8kp6LU9DLs9KugqOq15ucDUKvBKjRm1beYugKlNwtwOyAOedJ2CNDlwhuZaJd7FAWXh3HtRDo1fNX5xvV0eDzck7Ia4QUp6Hn9d+h6jKn2Woz/1pzorClQoUApxJmo8eAxg90Jz9pq06i0Na5cGPgC/Dj4MwDAQ4dfMNtXUVIBb36RxeUsxuPhZLfH0PnYd5CXZcH2/7YqEXmnwO/4GAxCsUVF+t7XfoGWlwLTvN9ysRxZ/l0sVuoGjKt4x1SOzplcajUMPhVFaFV4HvGX1sOgAPROvAdIzxfhYkQCeqYegsRauRNNCWKKqt6flMgx6Jbxt3m5EzuLQppWbdcLxBDBsXIn6a3iEZm+HymRY+2ssgTktuqBgBp3MtZUs5wNYPzDTnr2IDB0sN04bDHdWXih9XAM5vNRfXV4sVoJOLimvLMYy50YR2y1Qi+URHcHcqv6pNAvAgdjZ+JhB5ZZaGwekyxpNBokJydj4cKF3DY+n4+EhAQcOWK5eiwAHDlyBPPnzzfbNmrUKGzevBmAcbmD7OxsJCQkcPvlcjkGDBiAI0eO2EyWKioqUFFRtcS+Umn8a0Cr1UKrdXxNlNqsXAl0/uUY0j7aYXGnYc2yBTVt67EABVLjom5db+5Grxu2LxXsiJuPXHlHAEDnzIPod+0nm213d52LTH/jXQrts48h/sr3Ntvuj5mJjKDeAICoO6cw2MZKvQBwuNM0XAsZCABonZ+Ke9I+t9rOwBPgn+4vIV8aBUVpJu4/9a7VdldDB+FI5aRXoU6NR44utNoOMF6KNf177oGqdj8OWgV9UG94aZQoe+FVmC7CCACMr/w+8zhwoA7PdSOoDw7E/BuA8Zfh+OMLoT4OWF7gAW4FxGFvl2e4x48eehN8Zn0+QJ68Mwxx8wAAl57+ENk2bslWSQKxuV9Vn409tQoBpdbXqjkZ9SDOtzGuVxSkvI7RZz8AUPXaDTXi3lEWgtw/9bjr4kZE37G8PM4Yg19pKZYcHQ2dxPirZ8D139Ax+wDOPWA1BHy/wPiBxWMGTD1kvV+7A7it6IIs/1j8vEBf+TN8znyGzfkUlDy3EMWdpuFa5DjE3t6JgDtpkGiKzd5zf9UNjD++0Pje80UoF/qAVZ5JvbnqEr6tig9lP/6OZdfugqbNKAh1asTZqClX7BUMVaEv5JXnvnHDfD/PoIOh8sNapCs1ey3nksrxIIyLJJq9RgbcUknRCczsZ7p61mjgCcxWjRbo1RBoVNDrpWAGPfdauX2XTsP0k2Qw6FEsCUS2rANClVXZ7bEOj6LQOxQ8vYY7/lTUBECvQYFPOMIqJyYXFVn2g5YnBI/HM3teANDptGDMgHzfNtDwRRb7c2UdsKP7i5DwAZSWmO1nzAAGBllZJreVMQPOtBmDs61HGUfrKvvWwMAdW/13N8u4CX/VDTAAmUFdkS+PR6FfBHecVmsw63/GGLRaLVK6TMLB8Enc+bRawGDgV74mBq3WeITewMefvd5Ajxt/Wlz+Nxj08Cm8jf6pn4LBeHOVVqvl4jRoNTY/Z/h8vsUC/lqeCJJq/fNP95dQLpZDq9XC2PPGfcHnEqHVTrF6Xmi14BsMgFQKw5Ur3DFMwIeaLzHrf9PnoE7Hg8HA4/qresg6XdXrOdd6BG4HxMHAE+Dl829AH2AAy7rN9TUAXA3qi3DlDqd/xpridYTHJEt5eXnQ6/UIrTYpFwBCQ0NxwUbBzezsbKvts7Ozuf2mbbbaWLN06VIsWbLEYvuOHTvg4+O8gqs3bnRCJ4EAJeqqxIxv0HNzBwx8IWwUr0ZObibuVA7OhBbkQVlu+7Jidm4WskuNQ82B+bl22+bkZiGz3DiKIi/Msds29042MjXGTwGf4lra5uUiU2dsK1JmW23Lr5xMePehN/FZ93ehVledU1h9HgRfhPyiQmRmVp5PX2HzuYUGLRgzdmJpaSkMgqr/EpmZN1BhkMBHV2JxvOmPPh4fDj8XABQUF3Ft9VqguFQNWyPjhcXFXFsAKC4vh8DGX8KF/GJkZBiTniJVKaCxHoNSV2Z2ziKVCsJql5x5hmoFWm+dRSbfuJijviyTe13VX7vpcZq8F04Ue0GgysCdgmIElKrN2nAEQuTk3EKF0Ac6HR/R+UUIqdEHpvfyujSGi5XHDDb7lRkAgfoCTor7ozDzBvczzK82+dT0vmbl3EGG+iZu8zuis0rF7TO1ZTBe9srIuAk9X4QCQV88qdpl0Y7PYzjpfxfal5yHVFtk9jxZWRkohR9E+gqoVFXjOwI+g97AQ7EoAH8J+kHN94WP/ijCyjPA5zEYWNV/5rPBg7j385AoDj0Kq/4grNnW5KKsB06U+6F/tecsLa0aJc71ao0U/34YnPM3xIYKGPhC3PaOQqYyF+0Up3H+fDgy9L4IKM9BBd8bEkM5129XfWNx4+Zt3EAQvDQiZPGiEFF6Fan+fXHUEImIGxfACjOQLxZBHRSIyPO/4mqrB7BZ3g97wtph4o3/Qq4zjgyaYs/1ao0z+QwAH901XlBojEscqEJaofDUAZR0kCL9gg8OlQYiQidDsLpqxOGArCMyM28gJqYAV0V58NIxiNXG1/qPoi+GFG4DT+4FxufBOy8PJ72ikH6rapHZuLg88HgMB/VRkJYfhbpDG7P5rDqVDkwoAU+vR0l/bxxIaofyYiEk6nT06JGLbduMKaRyYDfI9p3Czf5dsW3bNgQF+ePixdaIi7uDbdtyoNfzUF7eARUVQly7dgV5ecafbY0mCFlZraAr90crDYOXphQVfG+cDjS+752HXUOOxBtexUUoDvNDcdoRaHylEJeUIIuXjVs15t6a+PkpkJHRlnvs5aVDartYdE3aDgC43GsYzlfw0TooC9u3G+/cVIWFwfdmJkrDDCi0cV4whnaMwSs9Hdf37UNu+yhI066gJMYfEnk+Dl7sjp4Fh6EKbYWCi0fBv8rHnTteyM9vB39/NQ4cuGY2KKcv00MvkkBfbkB+gBbZhcbLepciFOClX0Rm/ygYrp9HVpYf9Hoe1MLOuD/kLJJvnMLprLPWY6ynMgfvuuUxVrdZe3q9Hh999BF++uknZGRkQKMxn+9RUGD7EkRDZGZmonXr1jh8+DDi4+O57a+88gr27duHY8csh2HFYjHWr1+PKVOqsuXPPvsMS5YsQU5ODg4fPoy77roLmZmZaNWq6o6TyZMng8fjYdOmTVZjsTayFBERgby8PMhkzqv4rtVqkZiYiBEjRnCX4c58vA+l//0JN4L6YPSvT8LfPUtOuMXyf1/F3cdXQukdgtHH3jLbx3+mcgQmKgqGV16p03mt9XNLdXHjKeS/vxYAEPHpS4gYUvsk11df5XPzcT/4wICXXzZmPuPGMYwZY/4XJ/Wza1Bfuwb1s2s0Zj8rlUoEBQWhuLjY7ud3nUeWlixZgrVr1+LFF1/EG2+8gddffx3p6enYvHkzFi1a1KCg7QkKCoJAIEBOjvktmjk5OQgLC7N6TFhYmN32pn9zcnLMkqWcnBz07NnTZiwSiQQSieVdHCKRqFH+w1Q/b1lsfxzt5GOs/8TnQyRy3p0ITR2fLwAPPPB4fMt+Nk0yFgggqOd70FjvnyfRdu4FxheBb9A53B98flX3i0QC7nuh0HrVAupn16G+dg3qZ9dojH529Hx1nhq/YcMGfP3113jxxRchFAoxZcoUrF27FosWLcLRo0drP0E9icVi9OnTB7t2VU3YMxgM2LVrl9lIU3Xx8fFm7QEgMTGRax8dHY2wsDCzNkqlEseOHbN5TnfT+8ow4Mr3GHr+c/BKnH/nBGnhRCKUiRXujoIQQpqUOidL2dnZiIuLAwD4+fmhuNh4N9L999+PrVu3Oje6GubPn4+vv/4a69evR1paGp5++mmUlpZyd8c9/vjjZhPAn3/+eWzfvh0rVqzAhQsXsHjxYpw4cQJz5xprBPF4PMybNw/vvvsu/vzzT5w7dw6PP/44wsPDHSrvQlwrNt04EVJmbQG4YcOMd6QNHOjaoAghhDR7db4M16ZNG2RlZSEyMhLt27fHjh070Lt3byQlJVm9NOVMDz/8MO7cuYNFixYhOzsbPXv2xPbt27kJ2hkZGeBXW/Nl0KBB+OGHH/DGG2/gtddeQ8eOHbF582Z069aNa/PKK6+gtLQUs2bNQlFREQYPHozt27fDy3TLdBMjycmAzl4Nn2bMX5lue+eUKcYv0iCinFsNKrpKCCHNUZ2TpQcffBC7du3CgAED8Oyzz+Jf//oXvvnmG2RkZOCFF16o/QQNNHfuXG5kqKa9e/dabHvooYfw0EO26/bweDy8/fbbePvtt50VYqPyzrwK6ysQEdJwwsI73Pf6gGA7LQkhpOWoc7K0bNky7vuHH34Ybdu2xeHDh9GxY0eMGzfOqcERUp3d1WeTkoyFV3v0ABQKl8XUXN2RtUeEr+06UoQQ0pLUec7S/v37oau24u/AgQMxf/58jBkzBvv377dzJCENky9vBwA41vFfljvXrgV++AH44gsXR0UIIaS5q3OydM8991hdS6m4uBj33HOPU4IihLhXsPKq3RI5hBDSktQ5WWKMWZTeAID8/Hz4+rq2rkxLx8SNO6GetGyCPCt3HRJCSAvk8JyliRMnAjBOiJ4+fbrZnW96vR5nz57FoEG1V5kmznEjuC/inFhaxRPIVcYl8Qdc/h7A3e4NhhBCSIvhcLIklxsrUjPGIJVK4e1dVSZdLBZj4MCBmDlzpvMjJKTSiS7TcNfRFSjxDnF3KIQQQloQh5OldevWAQCioqLw0ksv0SU3N1F16ImjncRQi6Qwlpeu85VUj8UqqwYzK5eBiXOoo2PdHQIhhDQ5dV464K233qq9EWk0Oqk/+l/ZAL5BD55yGRDYgirpkkbHJF5QeQXRwpSEEFKNQ8lSr169rE7qtubkyZMNCogQWzplJAKwUe5kwADg2DGgd28XR0UIIaS5cyhZojppTYf4zm3oW2i5k6CiK7Z3Pvmk8Ys0iPBOJo0qEUJIDQ4lS3TprenwuXWJyp2QRiPKrxq10/sHuTESQghpOuo1O7ioqAhr167FwoULuQUqT548idu3bzs1OEIclpICJCcDpaXujqRZuCNrD+YndXcYhBDSJNR5gvfZs2eRkJAAuVyO9PR0zJw5EwEBAfjtt9+QkZGB7777rjHiJAR5ig4IKTuDYx3/hSE1d65ebfw3OhpYsMDVoRFCCGnG6jyyNH/+fEyfPh2XL1+Gl5cXt33s2LFUG46QZiJYeRU8dbm7wyCEkCahzslSUlISnnrqKYvtrVu3RnZ2tlOCIo6hciekMQnu0P9nQggB6pEsSSQSKJVKi+2XLl1CcHCwU4IitbsR3BdoYeVOZKVZAIB+Vze6ORJCCCEtSZ2TpQceeABvv/02tFotAGOtuIyMDLz66quYNGmS0wMkxORUp0cAAOViuZsjIYQQ0pLUOVlasWIFVCoVQkJCUF5ejqFDh6JDhw6QSqV47733GiNGUk1puzgc7fQ4roYOqix30nLoBWLjv/w635dAHKRu29ndIRBCSJNT508duVyOxMREHDx4EGfPnoVKpULv3r2RkJDQGPGRGrTyIPS/sojKnZBGwbx9qNwJIYTUUO8/0QcPHozBgwc7MxZC7Opway8AG+VOuncHzp4F4uJcGxQhhJBmr07JksFgwLfffovffvsN6enp4PF4iI6Oxv/93//hsccec7h+HKk/cX5Wiy13ElKQZnvnnDmuC6QZE+Zl06gSIYTU4PCcJcYYHnjgAfz73//G7du3ERcXh65du+LGjRuYPn06HnzwwcaMk1Tyybjg7hBIMybKy+K+18sD3BgJIYQ0HQ6PLH377bfYv38/du3ahXvuucds3+7duzFhwgR89913ePzxx50eJCG1unIF0OuBqChAQutPNdQdWXtEyOiuQ0IIAeowsvTjjz/itddes0iUAODee+/FggULsGHDBqcGR0h1+fL2AICkDlMsd37wAbByJfDxx64NihBCSLPncLJ09uxZjB492ub+MWPG4MyZM04JihBrWOWcOANPYKcRc1E0zVtQyTXwKtTuDoMQQpoEh5OlgoIChIaG2twfGhqKwsJCpwRFHMNEYneHQJopHmMQ5GbV3pAQQloAh5MlvV4PodD2FCeBQACdTueUoEjtbgT3BXx93R2GS0lLjUsG9L7+q5sjIYQQ0pI4PMGbMYbp06dDYmPybEVFhdOCIsSacx0nov+Jz6AT0ARuQgghruNwsjRt2rRa29CdcI2vtG0XHO30OEolAZXzc1rO2lYaobFwsJaSpUZT0baTu0MghJAmx+Fkad26dY0ZB3GQNiAU/a8sMZY7KV4GBFC5E+I8Bm9fKndCCCE11LmQLiHuEp15EICNciedKkdEYmNdGBEhhJCWgMq3exhRYS4MLbTcSau8c7Z3vvii6wJpxoQFuTSqRAghNdDIkofxTU91dwikGRPl3ua+N8jpEi8hhACULJHmIiMDSE8HtFp3R9Is3JG1h0GmcHcYhBDSJNBlOOIxCmTRCCpLwcl2kzCk5s733jP+26kTXZIjhBDiVDSyRDyGgW8sc6IVeNtuRCNLTuFfegugtdMIIQQAJUsejcqdkMYi1FdAmJvp7jAIIaRJ8JhkqaCgAFOnToVMJoNCocCMGTOgUqnsHqNWqzFnzhwEBgbCz88PkyZNQk5O1W3nZ86cwZQpUxAREQFvb2/Exsbik08+aeyX4hQtstxJWS4AoMeNP90cCSGEkJbEY5KlqVOnIjU1FYmJidiyZQv279+PWbNm2T3mhRdewF9//YWff/4Z+/btQ2ZmJiZOnMjtT05ORkhICL7//nukpqbi9ddfx8KFC/Hpp5829ssh9ZAafb+7QyCEENICecQE77S0NGzfvh1JSUno27cvAGD16tUYO3YsPvzwQ4SHh1scU1xcjG+++QY//PAD7r33XgDGVchjY2Nx9OhRDBw4EE8++aTZMe3atcORI0fw22+/Ye7cuY3/wuqhLDIGRzs9DpVXkLtDcTm1RA4A0AjtzFkiDVLRpr27QyCEkCbHI5KlI0eOQKFQcIkSACQkJIDP5+PYsWN48MEHLY5JTk6GVqtFQkICty0mJgaRkZE4cuQIBg4caPW5iouLERAQYDeeiooKs8LBSqUSAKDVaqF14gRj07mqn7NMHox+l98Gn+mhu/MutH4tZy0cg0EPBgbGDBb9zDcYjN/o9TDU8T2w1s8tVYXEGyWSAPhV5Dv882ww8GHqfq3WAIPBOGCt0zFotYxrR/3sOtTXrkH97BqN2c+OntMjkqXs7GyEhISYbRMKhQgICEB2drbNY8RiMRQKhdn20NBQm8ccPnwYmzZtwtatW+3Gs3TpUixZssRi+44dO+Dj42P32PpITEzkvj93Lgg9SlTgQ4+9e/dAnObl9OdrqnzOXYFKpQJfpcK2bdvM9nUqK4N3Xh7u+Psjs8Y+R1Xv55bq2jU5wpRKQKvCsWNHcU6V5sAxXVFebvxV8s8/KcjI6AYASErKAmO5Fu2pn12H+to1qJ9dozH6uayszKF2bk2WFixYgOXLl9ttk5ZW+y9rZ0hJScH48ePx1ltvYeTIkXbbLly4EPPnz+ceK5VKREREYOTIkZDJZE6LSavVIjExESNGjIBIJAIAyHUF4PkZL0P1H3YPFNEtZ2Tp0JKXwfPzAwAMGjvWfGfl49YAetbxvNb6uaU6tycPJRItIPFD7ICBiBgSXesx+/bxUVJi/H7UqNbYudM4stSvXxuMGWM+skT97BrU165B/ewajdnPpitDtXFrsvTiiy9i+vTpdtu0a9cOYWFhyM01/wtVp9OhoKAAYWFhVo8LCwuDRqNBUVGR2ehSTk6OxTHnz5/H8OHDMWvWLLzxxhu1xi2RSCCRSCy2i0SiRvkPU/288hvnUQJeoz5fk8Xjg1fttTtbi+tPK3zys6Gq7GNBYLBD/cHnG78AQCQScN8LhYC1w6mfXYf62jWon12jMfrZ0fO5NVkKDg5GcHBwre3i4+NRVFSE5ORk9OnTBwCwe/duGAwGDBgwwOoxffr0gUgkwq5duzBp0iQAwMWLF5GRkYH4+HiuXWpqKu69915MmzYN75lWgSaeJysLYAwIDrb+CU3q5I6sPSKoNhwhhADwkKUDYmNjMXr0aMycORPHjx/HoUOHMHfuXDzyyCPcnXC3b99GTEwMjh8/DgCQy+WYMWMG5s+fjz179iA5ORlPPPEE4uPjucndKSkpuOeeezBy5EjMnz8f2dnZyM7Oxp07d9z2WolthbIoAMDZtuMsdy5eDCxZAqxZ49KYCCGENH8eMcEbADZs2IC5c+di+PDh4PP5mDRpElatWsXt12q1uHjxotlkrY8++ohrW1FRgVGjRuGzzz7j9v/yyy+4c+cOvv/+e3z//ffc9rZt2yI9Pd0lr4s4Ts83/riWi+W2G6nVLoqmeZOqcytLx9AoHSGEeEyyFBAQgB9++MHm/qioKDDGzLZ5eXlhzZo1WGNjtGHx4sVYvHixM8N0KSakDzLSOLw0JRBm3wI61T7BmxBCmjuPuAxHLN0I7gtU3hnWUviV5wEAut7c7uZICCGEtCSULBGPcbGtcUkHsb7czZEQQghpSTzmMhwxKm/TEUkdHkGJV0jtjZuZUq9AAIBa1LJG1FxJ05ouuxFCSE00suRhKoLboGf6Zgw9/zl4xUXuDoc0M3qpokXWHSSEEHsoWfJAAoMWAoPWuK5QC9ImNxkAICvLsdwZVPkBHxnpwogIIYS0BHQZzsMIVUVgBr27w3CLyOzjtnfSgqJOIVAWwk+d5+4wCCGkSaGRJQ/jd/mUu0MgzZg4M5373uDnvDqHhBDiyShZIs1Dfj6QlwfodO6OpFm4I2sPg3+gu8MghJAmgS7DEY9RJI1EQFkaUiNGY0jNna+9Zvw3Lg6YO9fVoRFCCGnGaGSJeAydQAwA9u/WUqlcFE3z5q0pplE6QgipRMmSB2MCGhgkjcNPnQdh1k13h0EIIU0CJUse6kZwX0AqdXcYLuVbng8AiLm9y82REEIIaUkoWSIe40qbYQAAH02RW+MghBDSstB1HA9T3qodTkVPhNInzN2huFyJr/E1l4vplvbGomnV1t0hEEJIk0MjSx6mIqwtYm7vwsBL31G5E+J0enkAlTshhJAaKFnyQBKdChKtqsWVOwnPOwvARrkTX9/KRuEujKh5EjC6C44QQqqjy3AeRlCqBFpouZOozEO2d65c6bpAmjFBSRGU3iF1OkYiAUpKGikgQghpAmhkycNILyW7OwTSjLVtCwQLCiEJ9ENIT8dG6caNA3x8gLFjGzk4QghxExpZIs2DaWjD1xfg098A9SVvq8Cwg+/W6ZiBA41fAFBa2ghBEUKIm9GnCvEYRdIIAMCF1sMtd770kvHrq69cHBUhhJDmjpIl4jF0AgkAoNinle1GRUWuCYYQQkiLQcmSB2N8gbtDIIQQQpo9SpY81I3gvoCsZS3O6KMuBAB0zD7g5kgIIYS0JJQsEY+RHj4IACAry3ZzJIQQQloSuhvOw6hD2+Jc5H0o9m15iy8W+bUBAJRJFO4NhBBCSItCyZKHUYe3Q9SddeDn6gFlR8Bf7u6QCCGEkGaNkiUP5FuRD75BD57B4O5QXCq04DwAG+VO+HzAYACCqK4ZIYQQ56JkycPwy0vBa6HlTtrf2md75+efuy4QQgghLQpN8PYwsgvH3R0CIYQQ0qLQyBJpHioqjP+KxQCP595YCCGENCs0skQ8RrFfawDAlVZ3W+587jnj1zffuDgqQgghzR0lS8RjaIXeAIB8v7a2G+XluSgaQgghLQUlSx6Myp0QQgghjY+SJQ/VEsudeFcUAQDa5R51byCEEEJaFEqWiMe4GdoXABBYku7eQAghhLQodDech6kIiUBamxEo8ItwdyguVyCLBgCovALdHAkhhJCWhEaWPEx56w4IK0pDt4y/AaXS3eEQQgghzZ7HJEsFBQWYOnUqZDIZFAoFZsyYAZVKZfcYtVqNOXPmIDAwEH5+fpg0aRJycqyUygCQn5+PNm3agMfjoaioqBFegfPIy7IgL8tqcSt5BxdeAgBIy3NtN5JTrTxCCCHO5THJ0tSpU5GamorExERs2bIF+/fvx6xZs+we88ILL+Cvv/7Czz//jH379iEzMxMTJ0602nbGjBno3r17Y4TuVHyNGvwWliSZdLy5CwDAY8xy55dfGr+eftrFURFCCGnuPCJZSktLw/bt27F27VoMGDAAgwcPxurVq7Fx40ZkZmZaPaa4uBjffPMNVq5ciXvvvRd9+vTBunXrcPjwYRw9an431eeff46ioiK89NJLrng5DSJLPeLuEAghhJAWxSMmeB85cgQKhQJ9+/bltiUkJIDP5+PYsWN48MEHLY5JTk6GVqtFQkICty0mJgaRkZE4cuQIBg4cCAA4f/483n77bRw7dgzXrl1zKJ6KigpUmMprAFBWzh3SarXQarX1eo3WmM5V/Zx6vR4MrFGer8ljBrPXbr6v2mhTHcudWOtnUj9aLWAwGP8G0+kYtFpWbR/1s6tQX7sG9bNrNGY/O3pOj0iWsrOzERISYrZNKBQiICAA2dnZNo8Ri8VQKBRm20NDQ7ljKioqMGXKFHzwwQeIjIx0OFlaunQplixZYrF9x44d8PHxcegcdZGYmMh9r0zLQEDlXK29e/dAnObl9OdrqgoqvBCiysUFeS8Ubdtmtq/HZ58Z23TujJvDh9fr/NX7mdSPWi1ARkY3AEBSUhYYs5xfRv3sOtTXrkH97BqN0c9lZWUOtXNrsrRgwQIsX77cbpu0tLRGe/6FCxciNjYW//rXv+p83Pz587nHSqUSERERGDlyJGROXChSq9UiMTERI0aMgEgkAgCcubQPpUfOAQD6D7sHimh/pz1fU7f545vwMxRAH90PY8feZbaPv2ULACAiNBRxY8fW6bzW+pnUT2kpsHOncWSpX782GDPGfGSJ+tk1qK9dg/rZNRqzn5UO3lXu1mTpxRdfxPTp0+22adeuHcLCwpCba/4Xqk6nQ0FBAcLCwqweFxYWBo1Gg6KiIrPRpZycHO6Y3bt349y5c/jll18AAKzyUk5QUBBef/11q6NHACCRSCCRSCy2i0SiRvkPU/28AoEAPBgvMwklkhb1H5TH54MHHng8geXr5ldOvxMIIKhnnzTW+9eSiERVb4VQaHxs2Yb62VWor12D+tk1GqOfHT2fW5Ol4OBgBAcH19ouPj4eRUVFSE5ORp8+fQAYEx2DwYABAwZYPaZPnz4QiUTYtWsXJk2aBAC4ePEiMjIyEB8fDwD49ddfUV5ezh2TlJSEJ598EgcOHED79u0b+vIa1Y3gvoiTtazb5L0qjH8BROadBHC3e4MhhBDSYnjEnKXY2FiMHj0aM2fOxBdffAGtVou5c+fikUceQXh4OADg9u3bGD58OL777jv0798fcrkcM2bMwPz58xEQEACZTIZnn30W8fHx3OTumglRXmXF+tjYWIu5TsT9soK7Q5Z/HWFFjXdplhBCCKnJI5IlANiwYQPmzp2L4cOHg8/nY9KkSVi1ahW3X6vV4uLFi2aTtT766COubUVFBUaNGoXPKicCe6qKwHBcbjUE+dK27g7F5e4oOqIzgBLvkFrbEkIIIc7iMclSQEAAfvjhB5v7o6KiuDlHJl5eXlizZg3WrFnj0HMMGzbM4hxNTXlkZ/iXbkag6gag7A74O29COSGEEEIseUyyRKoEqG6Ab9C3uHInAcrrAAA/db7tRr6+LoqGEEJIS0HJkofh6bQtttxJTPp2AADfoLPc+eWXLo6GEEJIS+ER5U5IFfm5g+4OgRBCCGlRKFkihBBCCLGDLsMRj1HiEwZ52VVkBPW23PnUU8Z/hwwBpk51bWCEEEKaNRpZIh6jQuwHAMjy72K70c2bLoqGEEJIS0HJkifj8dwdASGEENLsUbLkoW4E9wWTK9wdhkt5aUoAAK0Lzrk5EkIIIS0JJUvEY+QExAIA2uSfcXMkhBBCWhJKljyMJiAM10MHIlfe0d2huJwpWVL6hLo5EkIIIS0JJUsepqxtLLwrihCZlwyUlLg7HEIIIaTZo6UDPFCI8rKx3IneykrWzZiixHinm29Foe1GYrGLoiGEENJSULLkaQyGFlvupMv1LQAAgV5jufOLL1wcDSGEkJaCLsN5GMWZfe4OoWni8aq+CCGEECeiZIkQQgghxA66DEc8hsonFLKya7gdEGe501TuZPhwYPJk1wZGCCGkWaORJeIx1GIpAOBWYA/bja5dc1E0hBBCWgpKljwZzc8hhBBCGh0lSx6qJZY7kWhLAQBhRRfcHAkhhJCWhJIl4jHy5e0AAG3vnHBzJIQQQloSSpY8jFYRjIyg3siTRrs7FJfLDOoOgMqdEEIIcS1KljxMaXQ3CJgOrYrSAJXK3eEQQgghzR4tHeCBWhWmGsud6LTuDsWlZKVZAABvTbHtRiKRi6IhhBDSUlCyRDxGt6ubAQAindpy55o1gE4HCASuDYoQQkizR8mSh1Gc2oOSFlobzi6h0PhFCCGEOBnNWSKEEEIIsYP+FCceo9Q7GNKyUmQrYix3msqdjB4NPPigawMjhBDSrNHIEvEY5RI5AOOCnDZdvOiiaAghhLQUNLJECCEtmMFggEajcXcYHkmr1UIoFEKtVkOvp7mkjaUh/SwSiSBwwo0/lCx5qBvBfRGn8Hd3GC4l0pUDAIJKrgG4273BENIMaDQaXL9+HQaDwd2heCTGGMLCwnDz5k3wqFZno2loPysUCoSFhTXoPaJkiXiMYr828M+9hPbZhwFMc3c4hHg0xhiysrIgEAgQEREBPp9mZdSVwWCASqWCn58f9V8jqm8/M8ZQVlaG3NxcAECrVq3qHQMlSx5GKwtAZkBXFPq2cXcoLncrpDeiru2mcieEOIFOp0NZWRnCw8Ph4+Pj7nA8kukSppeXFyVLjagh/ezt7Q0AyM3NRUhISL0vydG762FK2/eARuiDAFUGUFrq7nAIIR7KNPdDLBa7ORJCGpfpjwGttv5VL2hkyQNF5p00ljvRTgbg6+5wXMa3PA8A4KW1UxOPFqYkpE5org1p7pzxM04jS8Rj9Lj8MwBArLUyorZqFfDBB8CcOS6OihBCXGPYsGGYN28e9zgqKgoff/yx2+JpSShZ8jDyM/vBp3InliQSQCYDKq9PE0Kap+nTp2PChAkW3/N4PLtfixcvrvdzLl682Oxccrkcd999N/bt29fwF9QASUlJmDVrlltjaCnomoWH4VGiRAghFrKysrjvN23ahEWLFuFitUVq/fz8GnT+rl27YufOnQCAgoICfPjhh3jggQeQkpICmUzWoHPXV3BwsFuetyXymJGlgoICTJ06FTKZDAqFAjNmzIBKZWfuCgC1Wo05c+YgMDAQfn5+mDRpEnJycizaffvtt+jevTu8vLwQEhKCOXQpp0kq9Q4CAOTJ2lnufOop49eWLS6OihDSFISFhXFfcrkcPB7PbFtDkyWhUMidq0uXLnj77behUqlw9epVrs3KlSsRFxcHX19fRERE4JlnnjH7nLpx4wbGjRsHf39/+Pr6omvXrti2bRu3PyUlBWPGjIGfnx9CQ0Px2GOPIS8vz2ZMNS/D8Xg8rF27Fg8++CB8fHzQsWNH/Pnnn2bH1PU5iJHHJEtTp05FamoqEhMTsWXLFuzfv7/W4ccXXngBf/31F37++Wfs27cPmZmZmDhxolmblStX4vXXX8eCBQuQmpqKnTt3YtSoUY35Ukg9lUsUAICroYNsN0pJcU0whDQzjAEVFe75Yszdr75uKioqsG7dOigUCnTo0IHbzufzsWrVKqSmpmL9+vXYvXs3XnnlFW7/nDlzUFFRgf379+PcuXNYvnw5l8QVFRXh3nvvRa9evXDixAls374dOTk5mDx5cp1iW7JkCSZPnoyzZ89i7NixmDp1KgoKCpz6HC2RR1yGS0tLw/bt25GUlIS+fY11wVavXo2xY8fiww8/RHh4uMUxxcXF+Oabb/DDDz/g3nvvBQCsW7cOsbGxOHr0KAYOHIjCwkK88cYb+OuvvzB8+HDu2O7du7vmhRFCSBOh0QDPPeee5161yjjtsCk7d+4cl9iUlZVBKpXixx9/NLsEV3Py9bvvvovZs2fjs88+AwBkZGRg0qRJiIuLAwC0a1c1Sv7pp5+iV69eeP/997lt//3vfxEREYFLly6hU6dODsU5ffp0TJkyBQDw/vvvY9WqVTh+/DhGjx7ttOdoiTwiWTpy5AgUCgWXKAFAQkIC+Hw+jh07hgetVJlPTk6GVqtFQkICty0mJgaRkZE4cuQIBg4ciMTERBgMBty+fRuxsbEoKSnBoEGDsGLFCkRERNiMp6KiAhUVFdxjpVIJwLiGQ0PWcajJdK7q59Tr9WBguBUQhxgfX6c+X1Mn4OlxKfQuiDXFFq+bbyrXwOPBUMc+sdbPpH60WsBgMA5Y63QMWi2rto/62VUc6WutVgvGGAwGQ+UXwJh7lhEwGBgcrbjCGOPirv69+fkMZv/asnTpUixdupR7nJKSgsjISKvP2blzZ2zevBkAUFJSgp9++gkPP/ww/vzzTwwZMgQGgwE7d+7E8uXLceHCBSiVSuh0OqjVaqhUKvj4+GDu3LmYM2cOduzYgeHDh2PixIncH+enT5/Gnj17rF4uvHz5MjeCVfP11nzcrVs37rG3tzdkMhmys7NhMBgcfo6mhlUOPVp7rx1h+lnRarUWi1I6+vvII5Kl7OxshISEmG0TCoUICAhAdna2zWPEYjEUCoXZ9tDQUO6Ya9euwWAw4P3338cnn3wCuVyON954AyNGjMDZs2dtLta2dOlSLFmyxGL7jh07GmUl3MTERO57ZVoGAlQq3OGrkLhzJ/z8Ws4HT2knAYK374Gkdxds22Y+0b21XA7F5cu41aULiqvNAaiL6v1M6ketFiAjoxsAICkpC4zlWrShfnYde31tmoOjUqmg0WjAGPDOOy4Mrhq12ng5zhFarRY6nQ5KpdLse/PzqcEYs9he06OPPooxY8Zwj/38/KweU1FRAYFAwH0OhYSEYOHChfj999/x+eefo1evXsjIyMADDzyAJ598EgsWLIC/vz+OHj2KZ599Fvn5+dDpdJg8eTIGDRqEHTt2YM+ePVi2bBneffddzJo1C0VFRRg9erTVu/ZCQ0O55Euj0XAxGgwGqNVqs5it9UdZWRmUSqVDz9GUlZSU1Os4jUaD8vJy7N+/HzqdzmxfWVmZQ+dwa7K0YMECLF++3G6btLS0Rnt+g8EArVaLVatWYeTIkQCAH3/8EWFhYdizZ4/NuUsLFy7E/PnzucdKpRIREREYOXKkU++K0Gq1SExMxIgRIyASiQAAybdP4WZqOQTyThgxYgT8W1It3bEAMNPGvrEAgLb1OK21fib1U1oK7NxpHFnq168NxowxH1mifnYNR/parVbj5s2b8PPzg5eXl4sjrD+RSAShUAiZTGb2fXVeXl7g8Xi1/j6WyWRo27b23xoSiQQCgcDifCKRCGq1GlKpFBcvXoTBYMCqVau4khx///03AEAqlXLHdunSBV26dMG8efPw2muv4fvvv8dLL72E/v3747fffkO3bt0gtLG4rlAohFgs5s7F5/Ph5eVlFpdpNMmEx+NxbRx5jqaIMYaSkhJIpdJ6LTCpVqvh7e2NIUOGWPysO5ogurW3XnzxRUyfPt1um3bt2iEsLIwrhGei0+lQUFCAsLAwq8eFhYVBo9GgqKjIbHQpJyeHO8ZUVK9Lly7c/uDgYAQFBSEjI8NmTBKJBBIrF9hFIlGjfAhUP295bH+ofC5AqimCSKOBSNRyVvBubI31/rUkIhFgKt0kFBofW7ahfnYVe32t1+vB4/HA5/M9qq6Zaa0jPp9v9n11psfOel08Hg86nY77HCopKcGmTZtw/vx5PPvss+DxeOjUqRO0Wi3WrFmDcePG4dChQ/jyyy+5OPh8PubNm4cxY8agU6dOKCwsxN69exEbGws+n4+5c+di7dq1mDp1Kl555RUEBATgypUr2LhxI9auXctdPqr5ems+tvZ+mrY5+hxNjenSm7X32hGmnxVr/x8c/V3k1mQpODjYoXUi4uPjUVRUhOTkZPTp0wcAsHv3bhgMBgwYMMDqMX369IFIJMKuXbswadIkAMDFixeRkZGB+Ph4AMBdd93FbW/TxliYtqCgAHl5eQ79teEu0blHK8udjEdLKndCCCEGg8EtoyKpqancH9g+Pj5o37491qxZg0ceeQQA0KNHD6xcuRLLly/HwoULMWTIECxduhSPP/44dw69Xo85c+bg1q1bkMlkGD16ND766CMAQHh4OA4dOoRXX30VI0eOREVFBdq2bYvRo0c7LelzxXM0W8xDjB49mvXq1YsdO3aMHTx4kHXs2JFNmTKF23/r1i3WuXNnduzYMW7b7NmzWWRkJNu9ezc7ceIEi4+PZ/Hx8WbnHT9+POvatSs7dOgQO3fuHLv//vtZly5dmEajcTi24uJiBoAVFxc3/IVWo9Fo2ObNm81i2b2bsT1dnmb7YmaxwmsFTn2+lspaP5P6UakYmzXL+LV1q/k+6mfXcaSvy8vL2fnz51l5ebkLI2u4UaNGsTlz5rg7DMYYY3q9nhUWFjK9Xu/uUJq1hvazvZ91Rz+/PSaV3LBhA2JiYjB8+HCMHTsWgwcPxldffcXt12q1uHjxotlkrY8++gj3338/Jk2ahCFDhiAsLAy//fab2Xm/++47DBgwAPfddx+GDh0KkUiE7du3N9nLBPJzB6ncCSGkxSksLMSWLVuwd+9es7ucCXEFj5nhFRAQgB9++MHm/qioKO72QhMvLy+sWbMGa9assXmcTCbDN998g2+++cZpsTYmnq7l3P1GCCEmTz75JJKSkvDiiy9i/Pjx7g6HtDAekywRQghpuX7//Xd3h0BaMI+5DEcIIYQQ4g6ULBFCCCGE2EHJkofKVsSAyeTuDoMQQghp9ihZ8lAVIr+q1f8IIYQQ0mjo09bD6H2kKJC2RYl37Yt5EkIIIaThKFnyMCWd++KOtB3EujLAwQKAhBBCCKk/SpY8UMfs/eiUuQ88jYNlugkhhDQJ3377rVm90sWLF6Nnz55ui8fVpk+fjgkTJnCPhw0bhnnz5rktHkdRskQIIcQjmArn2vpavHgxAODUqVN46KGHEBoaCi8vL3Ts2BEzZ87EpUuX3PsCADz88MNuiePbb7816ys/Pz/06dPHoqqFq/32229455133BqDIyhZ8jCy1CNU7oQQ0iJlZWVxXx9//DFkMpnZtpdeeglbtmzBwIEDUVFRgQ0bNiAtLQ3ff/895HI53nzzTXe/BHh7eyMkJMQtz129v06dOoVRo0Zh8uTJuHjxolviAYzVOaRSqdue31GULHkYvkbt7hAIIcQtwsLCuC+5XA4ej2e2jc/n44knnsDYsWPx559/IiEhAdHR0RgwYAA+/PBDfPnll9y59u3bh/79+0MikaBVq1ZYsGABdDodt3/YsGF49tlnMW/ePPj7+yM0NBRff/01SktL8cQTT0AqlaJTp05ITEzkjtm7dy94PB62bt2K7t27w8vLCwMHDkRKSgrXpuZlOGvWrl2L2NhYeHl5ISYmBp999plT+q96f3Xs2BHvvvsu+Hw+zp49y7X53//+h759+0IqlSIsLAyPPvoocnNzuf2FhYWYOnUqgoOD4e3tjY4dO2LdunXc/ps3b2Ly5MlQKBQICAjA+PHjkZ6ebjOmmpfhoqKi8P777+PJJ5+EVCpFZGSkWR3Y+jyHM1CyRAghpEpFhe0vrdb5bZ3on3/+QV5eHl555RWr+01Jyu3btzF27Fj069cPZ86cweeff45vvvkG7777rln79evXIygoCMePH8ezzz6Lp59+Gg899BAGDRqEkydPYsSIEZg9e7ZZAXcAePnll7FixQokJSUhODgY48aNg7Zmf9iwYcMGLFq0CO+99x7S0tLw/vvv480338T69evr3iF26PV67py9e/fmtmu1Wrzzzjs4c+YMNm/ejPT0dEyfPp3b/+abb+L8+fP4+++/kZaWhs8//xxBQUHcsaNGjYJUKsWBAwdw6NAh+Pn5YfTo0dBoNA7HtmLFCvTt2xenTp3CM888gzlz5uDy5ctOfY66otpwhBBCqjz3nO193boBzz5b9fillwBbH1CdOgEvvlj1+LXXAJXKsl210Z6GMn2gxsTE2G332WefISIiAp9++il4PB5iYmKQmZmJV199FYsWLQK/cg27Hj164I033gAALFy4EMuWLUNQUBBmzpwJwJg4fPHFFzh79iwGDRrEnf+tt97CiBEjABgTrjZt2uD333/H5MmTa30Nb731FlasWIGJEycCAKKjo3H+/Hl8+eWXmDZtWh17xFxxcTH8/PwAAOXl5RCJRPjqq6/Qvn17rs2TTz7Jfd+uXTusWrUK/fr1g0qlgp+fHzIyMtCrVy/07dsXgHEkyGTTpk0wGAxYu3YteDweAGDdunVQKBTYu3cvRo4c6VCcY8eOxTPPPAMAePXVV/HRRx/hwIED6NOnj9Oeo64oWSKEENIsMMYcapeWlob4+HjuwxYA7rrrLqhUKty6dQuRkZEAgO7du3P7BQIBAgMDERcXx20LDQ0FALPLVAAQHx/PfR8QEIDOnTsjLS2t1rhKS0tx9epVzJgxg0vIAECn00Eut16xYcOGDXjqqae4x3///Tfuvvtuq22lUilOnjwJACgrK8POnTsxe/ZsBAYGYty4cQCA5ORkLF68GGfOnEFhYSEMBgMAICMjA126dMHTTz+NSZMm4eTJkxg5ciQmTJjAJYpnzpzBlStXLOYgqdVqXL16tdbXb1K9302XDvPy8pz6HHVFyZKHypNFU7kTQojzrVple1/NqgEffuh42/ffr39MDurUqRMA4MKFC2YJS32JRCKzxzwez2ybKdkyJRQNpaocefv6668xYMAAs30CgcDqMQ888IBZ29atW9s8P5/PR4cOHbjH3bt3x44dO7B8+XKMGzcOpaWlGDVqFEaNGoUNGzYgODgYGRkZGDVqFHeJa8yYMbhx4wa2bduGxMREDB8+HHPmzMGHH34IlUqFPn36YMOGDRbPHRzs+ELK1vrd1MfOeo66omTJQ5VKAqncCSHE+SQS97etp5EjRyIoKAj/+c9/8Pvvv1vsLyoqgkKhQGxsLH799VcwxriE59ChQ5BKpWjTpk2D4zh69Cg3OlVYWIhLly4hNja21uNCQ0MRHh6Oa9euYerUqQ49l1QqbdDdZAKBAOXl5QCMSWZ+fj6WLVuGiIgIAMCJEycsjgkODsa0adMwbdo03H333Xj55Zfx4Ycfonfv3ti0aRNCQkIgk8nqHZM9rngOa+jT1sMYvHyg9AlDmUTh7lAIIaRJ8fX1xdq1a7F161Y88MAD2LlzJ9LT03HixAm88sormD17NgDgmWeewc2bN/Hss8/iwoUL+OOPP/DWW29h/vz53Hylhnj77bexa9cupKSkYPr06QgKCjJbiNGeJUuWYOnSpVi1ahUuXbqEc+fOYd26dVi5cmWD42KMITs7G9nZ2bh+/Tq++uor/PPPPxg/fjwAIDIyEmKxGKtXr8a1a9fw559/WqyBtGjRIvzxxx+4cuUKUlNTsWXLFi4RnDp1KoKCgjB+/HgcOHAA169fx969e/Hcc8/h1q1bDY7fVc9hDSVLHiZs/AAcHLEEqtEPoZa7TwlxOR8foGtXQC43/kuIq40fPx6HDx+GSCTCo48+ipiYGEyZMgXFxcXc3W6tW7fGtm3bcPz4cfTo0QOzZ8/GjBkzuMncDbVs2TI8//zz6NOnD7Kzs/HXX39BLBY7dOy///1vrF27FuvWrUNcXByGDh2Kb7/9FtHR0Q2OS6lUolWrVmjVqhViY2OxYsUKvP3223j99dcBGEeMvv32W/z888/o0qULli1bhg9rXGoVi8VYuHAhunfvjiFDhkAgEGDjxo0AAB8fH+zfvx+RkZGYOHEiYmNjMWPGDKjVaqeNArniOazhMUdnxBGblEol5HI5iouLnfpmabVabNu2DWPHjrW4hkuch/rZNaifXceRvlar1bh+/Tqio6Ph5eXl4gibB4PBAKVSCZlMBj6fj7179+Kee+5BYWFhrWspEcfV7Oe6svez7ujnN40sEUIIIYTYQckSIYQQQogddDccIYQQ4gTDhg1zeK0n4lloZIkQQgghxA5KlgghhBBC7KBkiRBCWjC6bESaO2f8jFOyRAghLZCpfEZjVmonpCkoKysDYFlGpS5ogjchhLRAQqEQPj4+uHPnDkQikVNWrm5pDAYDNBoN1Go19V8jqm8/M8ZQVlaG3NxcKBQKm/X1HEHJEiGEtEA8Hg+tWrXC9evXcePGDXeH45EYYygvL4e3tzdXY444X0P7WaFQICwsrEExULJECCEtlFgsRseOHelSXD1ptVrs378fQ4YMoVXpG1FD+lkkEjVoRMmEkiVCCGnB+Hw+lTupJ4FAAJ1OBy8vL0qWGlFT6Ge6yEoIIYQQYgclS4QQQgghdlCyRAghhBBiB81ZcgLTgldKpdKp59VqtSgrK4NSqaTr4Y2I+tk1qJ9dh/raNaifXaMx+9n0uV3bwpWULDlBSUkJACAiIsLNkRBCCCGkrkpKSiCXy23u5zFa677BDAYDMjMzIZVKnbrWhlKpREREBG7evAmZTOa08xJz1M+uQf3sOtTXrkH97BqN2c+MMZSUlCA8PNzugpc0suQEfD4fbdq0abTzy2Qy+o/oAtTPrkH97DrU165B/ewajdXP9kaUTGiCNyGEEEKIHZQsEUIIIYTYQclSEyaRSPDWW29BIpG4O5RmjfrZNaifXYf62jWon12jKfQzTfAmhBBCCLGDRpYIIYQQQuygZIkQQgghxA5KlgghhBBC7KBkiRBCCCHEDkqWmqg1a9YgKioKXl5eGDBgAI4fP+7ukDzK0qVL0a9fP0ilUoSEhGDChAm4ePGiWRu1Wo05c+YgMDAQfn5+mDRpEnJycszaZGRk4L777oOPjw9CQkLw8ssvQ6fTufKleJRly5aBx+Nh3rx53DbqZ+e4ffs2/vWvfyEwMBDe3t6Ii4vDiRMnuP2MMSxatAitWrWCt7c3EhIScPnyZbNzFBQUYOrUqZDJZFAoFJgxYwZUKpWrX0qTptfr8eabbyI6Ohre3t5o37493nnnHbPaYdTXdbd//36MGzcO4eHh4PF42Lx5s9l+Z/Xp2bNncffdd8PLywsRERH4z3/+45wXwEiTs3HjRiYWi9l///tflpqaymbOnMkUCgXLyclxd2geY9SoUWzdunUsJSWFnT59mo0dO5ZFRkYylUrFtZk9ezaLiIhgu3btYidOnGADBw5kgwYN4vbrdDrWrVs3lpCQwE6dOsW2bdvGgoKC2MKFC93xkpq848ePs6ioKNa9e3f2/PPPc9upnxuuoKCAtW3blk2fPp0dO3aMXbt2jf3zzz/sypUrXJtly5YxuVzONm/ezM6cOcMeeOABFh0dzcrLy7k2o0ePZj169GBHjx5lBw4cYB06dGBTpkxxx0tqst577z0WGBjItmzZwq5fv85+/vln5ufnxz755BOuDfV13W3bto29/vrr7LfffmMA2O+//2623xl9WlxczEJDQ9nUqVNZSkoK+/HHH5m3tzf78ssvGxw/JUtNUP/+/dmcOXO4x3q9noWHh7OlS5e6MSrPlpubywCwffv2McYYKyoqYiKRiP38889cm7S0NAaAHTlyhDFm/M/N5/NZdnY21+bzzz9nMpmMVVRUuPYFNHElJSWsY8eOLDExkQ0dOpRLlqifnePVV19lgwcPtrnfYDCwsLAw9sEHH3DbioqKmEQiYT/++CNjjLHz588zACwpKYlr8/fffzMej8du377deMF7mPvuu489+eSTZtsmTpzIpk6dyhijvnaGmsmSs/r0s88+Y/7+/ma/N1599VXWuXPnBsdMl+GaGI1Gg+TkZCQkJHDb+Hw+EhIScOTIETdG5tmKi4sBAAEBAQCA5ORkaLVas36OiYlBZGQk189HjhxBXFwcQkNDuTajRo2CUqlEamqqC6Nv+ubMmYP77rvPrD8B6mdn+fPPP9G3b1889NBDCAkJQa9evfD1119z+69fv47s7GyzfpbL5RgwYIBZPysUCvTt25drk5CQAD6fj2PHjrnuxTRxgwYNwq5du3Dp0iUAwJkzZ3Dw4EGMGTMGAPV1Y3BWnx45cgRDhgyBWCzm2owaNQoXL15EYWFhg2KkQrpNTF5eHvR6vdkHBwCEhobiwoULborKsxkMBsybNw933XUXunXrBgDIzs6GWCyGQqEwaxsaGors7GyujbX3wbSPGG3cuBEnT55EUlKSxT7qZ+e4du0aPv/8c8yfPx+vvfYakpKS8Nxzz0EsFmPatGlcP1nrx+r9HBISYrZfKBQiICCA+rmaBQsWQKlUIiYmBgKBAHq9Hu+99x6mTp0KANTXjcBZfZqdnY3o6GiLc5j2+fv71ztGSpZIszdnzhykpKTg4MGD7g6l2bl58yaef/55JCYmwsvLy93hNFsGgwF9+/bF+++/DwDo1asXUlJS8MUXX2DatGlujq55+emnn7Bhwwb88MMP6Nq1K06fPo158+YhPDyc+roFo8twTUxQUBAEAoHF3UI5OTkICwtzU1Sea+7cudiyZQv27NmDNm3acNvDwsKg0WhQVFRk1r56P4eFhVl9H0z7iPEyW25uLnr37g2hUAihUIh9+/Zh1apVEAqFCA0NpX52glatWqFLly5m22JjY5GRkQGgqp/s/d4ICwtDbm6u2X6dToeCggLq52pefvllLFiwAI888gji4uLw2GOP4YUXXsDSpUsBUF83Bmf1aWP+LqFkqYkRi8Xo06cPdu3axW0zGAzYtWsX4uPj3RiZZ2GMYe7cufj999+xe/dui6HZPn36QCQSmfXzxYsXkZGRwfVzfHw8zp07Z/YfNDExETKZzOKDq6UaPnw4zp07h9OnT3Nfffv2xdSpU7nvqZ8b7q677rJY+uLSpUto27YtACA6OhphYWFm/axUKnHs2DGzfi4qKkJycjLXZvfu3TAYDBgwYIALXoVnKCsrA59v/tEoEAhgMBgAUF83Bmf1aXx8PPbv3w+tVsu1SUxMROfOnRt0CQ4ALR3QFG3cuJFJJBL27bffsvPnz7NZs2YxhUJhdrcQse/pp59mcrmc7d27l2VlZXFfZWVlXJvZs2ezyMhItnv3bnbixAkWHx/P4uPjuf2mW9pHjhzJTp8+zbZv386Cg4PplvZaVL8bjjHqZ2c4fvw4EwqF7L333mOXL19mGzZsYD4+Puz777/n2ixbtowpFAr2xx9/sLNnz7Lx48dbvfW6V69e7NixY+zgwYOsY8eOLfp2dmumTZvGWrduzS0d8Ntvv7GgoCD2yiuvcG2or+uupKSEnTp1ip06dYoBYCtXrmSnTp1iN27cYIw5p0+LiopYaGgoe+yxx1hKSgrbuHEj8/HxoaUDmrPVq1ezyMhIJhaLWf/+/dnRo0fdHZJHAWD1a926dVyb8vJy9swzzzB/f3/m4+PDHnzwQZaVlWV2nvT0dDZmzBjm7e3NgoKC2Isvvsi0Wq2LX41nqZksUT87x19//cW6devGJBIJi4mJYV999ZXZfoPBwN58800WGhrKJBIJGz58OLt48aJZm/z8fDZlyhTm5+fHZDIZe+KJJ1hJSYkrX0aTp1Qq2fPPP88iIyOZl5cXa9euHXv99dfNbkenvq67PXv2WP2dPG3aNMaY8/r0zJkzbPDgwUwikbDWrVuzZcuWOSV+HmPVliUlhBBCCCFmaM4SIYQQQogdlCwRQgghhNhByRIhhBBCiB2ULBFCCCGE2EHJEiGEEEKIHZQsEUIIIYTYQckSIYQQQogdlCwRQlq8qKgofPzxx+4OgxDSRFGyRAhxmenTp2PChAnc42HDhmHevHkue/5vv/0WCoXCYntSUhJmzZrlsjhq2rt3L3g8nkXBYUJI0yB0dwCEENJQGo0GYrG43scHBwc7MRpCSHNDI0uEELeYPn069u3bh08++QQ8Hg88Hg/p6ekAgJSUFIwZMwZ+fn4IDQ3FY489hry8PO7YYcOGYe7cuZg3bx6CgoIwatQoAMDKlSsRFxcHX19fRERE4JlnnoFKpQJgHL154oknUFxczD3f4sWLAVhehsvIyMD48ePh5+cHmUyGyZMnIycnh9u/ePFi9OzZE//73/8QFRUFuVyORx55BCUlJTZf740bNzBu3Dj4+/vD19cXXbt2xbZt25Ceno577rkHAODv7w8ej4fp06cDAAwGA5YuXYro6Gh4e3ujR48e+OWXX7hzmkaktm7diu7du8PLywsDBw5ESkpKvd8XQoglSpYIIW7xySefID4+HjNnzkRWVhaysrIQERGBoqIi3HvvvejVqxdOnDiB7du3IycnB5MnTzY7fv369RCLxTh06BC++OILAACfz8eqVauQmpqK9evXY/fu3XjllVcAAIMGDcLHH38MmUzGPd9LL71kEZfBYMD48eNRUFCAffv2ITExEdeuXcPDDz9s1u7q1avYvHkztmzZgi1btmDfvn1YtmyZzdc7Z84cVFRUYP/+/Th37hyWL18OPz8/RERE4NdffwUAXLx4EVlZWfjkk08AAEuXLsV3332HL774AqmpqXjhhRfwr3/9C/v27TM798svv4wVK1YgKSkJwcHBGDduHLRabR3fEUKITU4px0sIIQ6YNm0aGz9+PPd46NCh7Pnnnzdr884777CRI0eabbt58yYDwFUhHzp0KOvVq1etz/fzzz+zwMBA7vG6deuYXC63aNe2bVv20UcfMcYY27FjBxMIBCwjI4Pbn5qaygCw48ePM8YYe+utt5iPjw9TKpVcm5dffpkNGDDAZixxcXFs8eLFVveZKrIXFhZy29RqNfPx8WGHDx82aztjxgw2ZcoUs+M2btzI7c/Pz2fe3t5s06ZNNmMhhNQNzVkihDQpZ86cwZ49e+Dn52ex7+rVq+jUqRMAoE+fPhb7d+7ciaVLl+LChQtQKpXQ6XRQq9UoKyuDj4+PQ8+flpaGiIgIREREcNu6dOkChUKBtLQ09OvXD4Dx0p1UKuXatGrVCrm5uTbP+9xzz+Hpp5/Gjh07kJCQgEmTJqF79+4221+5cgVlZWUYMWKE2XaNRoNevXqZbYuPj+e+DwgIQOfOnZGWlubQ6yWE1I6SJUJIk6JSqTBu3DgsX77cYl+rVq247319fc32paen4/7778fTTz+N9957DwEBATh48CBmzJgBjUbjcLLkKJFIZPaYx+PBYDDYbP/vf/8bo0aNwtatW7Fjxw4sXboUK1aswLPPPmu1vWmu1datW9G6dWuzfRKJpIHRE0LqgpIlQojbiMVi6PV6s229e/fGr7/+iqioKAiFjv+KSk5OhsFgwIoVK8DnG6dj/vTTT7U+X02xsbG4efMmbt68yY0unT9/HkVFRejSpYvD8VgTERGB2bNnY/bs2Vi4cCG+/vprPPvss9ydfNVj69KlCyQSCTIyMjB06FC75z169CgiIyMBAIWFhbh06RJiY2MbFCshpApN8CaEuE1UVBSOHTuG9PR05OXlwWAwYM6cOSgoKMCUKVOQlJSEq1ev4p9//sETTzxhN9Hp0KEDtFotVq9ejWvXruF///sfN/G7+vOpVCrs2rULeXl5KCsrszhPQkIC4uLiMHXqVJw8eRLHjx/H448/jqFDh6Jv3771fq3z5s3DP//8g+vXr+PkyZPYs2cPl9C0bdsWPB4PW7ZswZ07d6BSqSCVSvHSSy/hhRdewPr163H16lWcPHkSq1evxvr1683O/fbbb2PXrl1ISUnB9OnTERQUZLaeFSGkYShZIoS4zUsvvQSBQIAuXbogODgYGRkZCA8Px6FDh6DX6zFy5EjExcVh3rx5UCgU3IiRNT169MDKlSuxfPlydOvWDRs2bMDSpUvN2gwaNAizZ8/Gww8/jODgYPznP/+xOA+Px8Mff/wBf39/DBkyBAkJCWjXrh02bdrUoNeq1+sxZ84cxMbGYvTo0ejUqRM+++wzAEDr1q2xZMkSLFiwAKGhoZg7dy4A4J133sGbb76JpUuXcsdt3boV0dHRZudetmwZnn/+efTp0wfZ2dn466+/GrTuFCHEHI8xxtwdBCGEkLrbu3cv7rnnHhQWFlpdmZwQ4hw0skQIIYQQYgclS4QQQgghdtBlOEIIIYQQO2hkiRBCCCHEDkqWCCGEEELsoGSJEEIIIcQOSpYIIYQQQuygZIkQQgghxA5KlgghhBBC7KBkiRBCCCHEDkqWCCGEEELsoGSJEEIIIcSO/wfjsMT0do4IwQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "\n", + "# Convert lists to numpy arrays for easier manipulation\n", + "loss_baseline_np = np.array(loss_baseline)\n", + "loss_jit_np = np.array(loss_jit)\n", + "loss_tcompile_np = np.array(loss_tcompile)\n", + "\n", + "# Calculate deltas\n", + "delta_jit_baseline = (loss_jit_np - loss_baseline_np)\n", + "delta_tcompile_baseline = (loss_tcompile_np - loss_baseline_np)\n", + "\n", + "# Plot deltas\n", + "plt.plot(it_jit, delta_jit_baseline, label=\"JIT - Baseline\", linestyle='-', color='blue', alpha=0.6)\n", + "plt.plot(it_tcompile, delta_tcompile_baseline, label=\"TCompile - Baseline\", linestyle='--', color='red', alpha=0.6)\n", + "\n", + "plt.xlabel('Iteration step')\n", + "plt.ylabel('Delta Loss')\n", + "plt.title('Delta Loss Curve (compared to Baseline)')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working as per designed, the differences between \"Delta Loss\" should be within margin of error, of run-by-run varience" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Plot the time charts!\n", + "\n", + "Lets start with a basic iteration step over cummulative time" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Extract the 'it' and 'time' values from each dictionary in each list\n", + "it_baseline = [x['it'] for x in step_baseline]\n", + "time_baseline = [x['time'] for x in step_baseline]\n", + "\n", + "it_jit = [x['it'] for x in step_jit]\n", + "time_jit = [x['time'] for x in step_jit]\n", + "\n", + "it_tcompile = [x['it'] for x in step_tcompile]\n", + "time_tcompile = [x['time'] for x in step_tcompile]\n", + "\n", + "# Plot cumulative time for each iteration\n", + "plt.plot(it_baseline, time_baseline, label='Baseline')\n", + "plt.plot(it_jit, time_jit, label='Jit')\n", + "plt.plot(it_tcompile, time_tcompile, label='TCompile')\n", + "\n", + "# Label the axes\n", + "plt.xlabel('Iteration')\n", + "plt.ylabel('Cumulative Time')\n", + "\n", + "# Add a legend\n", + "plt.legend(loc='upper left')\n", + "\n", + "# Display the plot\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working correctly it should show that\n", + "\n", + "- baseline: lowest starting time, highest accumulative rate\n", + "- JIT: similar starting time, lower accumulative rate\n", + "- TCompile: slowest starting time, lowest accumulative rate\n", + "\n", + "This can be observed by getting the average time per iteration for the first 200 steps and the following 2 x 400 steps" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Average delta time for the first 200 iterations ('warmup'):\n", + "Baseline: 875.0 ms\n", + "Jit: 860.0 ms\n", + "TCompile: 1125.0 ms\n", + "\n", + "Average delta time after 'warmup' for 400 iterations:\n", + "Baseline: 715.0 ms\n", + "Jit: 685.0 ms\n", + "TCompile: 652.5 ms\n", + "\n", + "Average delta time for last 400 iterations:\n", + "Baseline: 717.5 ms\n", + "Jit: 687.5 ms\n", + "TCompile: 655.0 ms\n" + ] + } + ], + "source": [ + "# Compute the average time for the first `n` iterations and for the rest\n", + "def compute_average_time_delta(data, start, end):\n", + " time = [x['time'] for x in data]\n", + " if start == -1:\n", + " return (time[end-1]) / (end)\n", + " else:\n", + " return (time[end-1] - time[start]) / (end - start)\n", + "\n", + "# PS, [0] pos shows the timing for the first step, so we use -1 to start from \"0\"\n", + "first_R = 200\n", + "first_R_baseline = compute_average_time_delta(step_baseline, -1, first_R)\n", + "first_R_jit = compute_average_time_delta(step_jit, -1, first_R)\n", + "first_R_tcompile = compute_average_time_delta(step_tcompile, -1, first_R)\n", + "\n", + "next_W = 400\n", + "next_W_baseline = compute_average_time_delta(step_baseline, first_R, first_R + next_W)\n", + "next_W_jit = compute_average_time_delta(step_jit, first_R, first_R + next_W)\n", + "next_W_tcompile = compute_average_time_delta(step_tcompile, first_R, first_R + next_W)\n", + "\n", + "next_K = 400\n", + "next_K_baseline = compute_average_time_delta(step_baseline, first_R + next_W, first_R + next_W + next_K)\n", + "next_K_jit = compute_average_time_delta(step_jit, first_R + next_W, first_R + next_W + next_K)\n", + "next_K_tcompile = compute_average_time_delta(step_tcompile, first_R + next_W, first_R + next_W + next_K)\n", + "\n", + "print(f\"Average delta time for the first {first_R} iterations ('warmup'):\")\n", + "print(f\"Baseline: {first_R_baseline * 1000} ms\")\n", + "print(f\"Jit: {first_R_jit * 1000} ms\")\n", + "print(f\"TCompile: {first_R_tcompile * 1000} ms\")\n", + "print(\"\")\n", + "\n", + "print(f\"Average delta time after 'warmup' for {next_W} iterations:\")\n", + "print(f\"Baseline: {next_W_baseline * 1000} ms\")\n", + "print(f\"Jit: {next_W_jit * 1000} ms\")\n", + "print(f\"TCompile: {next_W_tcompile * 1000} ms\")\n", + "print(\"\")\n", + "\n", + "print(f\"Average delta time for last {next_K} iterations:\")\n", + "print(f\"Baseline: {next_K_baseline * 1000} ms\")\n", + "print(f\"Jit: {next_K_jit * 1000} ms\")\n", + "print(f\"TCompile: {next_K_tcompile * 1000} ms\")\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "rwkv-infctx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebook/trainer-validation/torch-compile-perf.ipynb b/notebook/trainer-validation/torch-compile-perf.ipynb new file mode 100644 index 00000000..83d3115f --- /dev/null +++ b/notebook/trainer-validation/torch-compile-perf.ipynb @@ -0,0 +1,1747 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# torch.compile performance uplift validation\n", + "The following trainer validation, is used to compare performance differences between the following optimizations\n", + "\n", + "- torch native\n", + "- torch + JIT\n", + "- torch + torch.compile\n", + "\n", + "It presumes that basic setup has been done as per\n", + "- `./baseline-setup.ipynb`\n", + "\n", + "To simplify the benchmarking, we are intentionally only performing\n", + "- training & data ctx len fixed at 4096\n", + "- a 100 trainer/global_step\n", + "- of 10 gradient accumulation (per GPU)\n", + "- no checkpoint save to disk (reduce the influence of random diskio in timings)\n", + "\n", + "This would (on a single GPU) perform the run over\n", + "- a 1000 data samples\n", + "\n", + "\n", + "The following experiments were executed on a single `a10g` gpu `g5.8xlarge` AWS instance for consistency. With `deepspeed_stage_2_offload`" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Install the nightly build within conda\n", + "(Skip if you already have 2.1.0, or already done the setup)\n", + "\n", + "For torch.compile, as of 8th July 2023, you will need the torch nightly build for several fixes we depend on. This is expected to be resolved when merged in for torch 2.1.0 release (you will need to perform this setup outside the notebook)\n", + "\n", + "```bash\n", + "conda activate rwkv-infctx\n", + "conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch-nightly -c nvidia\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure and apply your preferred settings\n", + "\n", + "Adjust your desired deepspeed settings, and gpu device count.\n", + "Enable/Disable WANDB here as well (recommended disabled, to reduce perf impact)\n", + "\n", + "( note you will need to rerun this cell, if you restart your env )" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DEEPSPEED_STRAT: deepspeed_stage_2_offload\n", + "ENABLE_WANDB: False\n", + "GPU_DEVICES: auto\n" + ] + } + ], + "source": [ + "DEEPSPEED_STRAT=\"deepspeed_stage_2_offload\"\n", + "GPU_DEVICES=\"auto\"\n", + "ENABLE_WANDB=False\n", + "\n", + "print(\"DEEPSPEED_STRAT:\", DEEPSPEED_STRAT)\n", + "print(\"ENABLE_WANDB:\", ENABLE_WANDB)\n", + "print(\"GPU_DEVICES:\", GPU_DEVICES)\n", + "\n", + "if ENABLE_WANDB:\n", + " WANDB_MODE=\"online\"\n", + "else:\n", + " WANDB_MODE=\"disabled\"\n", + "\n", + "# Ensure logs dir is initialized\n", + "!mkdir -p ./logs/" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Preload your data\n", + "The data has minor differences from baseline, and needs to be preloaded here" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found cached dataset parquet (/home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 977.69it/s]\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-0b77c6df8d77d6b6_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-f32adc0b9b83547d_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-9a2bc99bc09b7d14_*_of_00032.arrow\n", + " \r" + ] + } + ], + "source": [ + "!cd ../../RWKV-v4neo && python3 preload_dataset.py ../notebook/trainer-validation/config/torch-compile-perf.yaml" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Perform baseline benchmark (no JIT / no toch compile)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2023-07-08 17:51:59,139] [INFO] [real_accelerator.py:110:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n", + "[RWKV.model] Running RWKV model via the following optimization mode : torch-native\n", + "Global seed set to 3941088705\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/wkv_4096_bf16/build.ninja...\n", + "Building extension module wkv_4096_bf16...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module wkv_4096_bf16...\n", + "/home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages/lightning/fabric/connector.py:555: UserWarning: bf16 is supported for historical reasons but its usage is discouraged. Please set your precision to bf16-mixed instead!\n", + " rank_zero_warn(\n", + "GPU available: True (cuda), used: True\n", + "TPU available: False, using: 0 TPU cores\n", + "IPU available: False, using: 0 IPUs\n", + "HPU available: False, using: 0 HPUs\n", + "Found cached dataset parquet (/home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7)\n", + "100%|████████████████████████████████████████████| 1/1 [00:00<00:00, 945.09it/s]\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-0b77c6df8d77d6b6_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-f32adc0b9b83547d_*_of_00032.arrow\n", + "Loading cached processed dataset at /home/ubuntu/.cache/huggingface/datasets/teven___parquet/teven--enwiki_10k-de63a925546e70ab/0.0.0/14a00e99c0d15a23649d0db8944380ac81082d4b021f398733dd84f3a6c569a7/cache-9a2bc99bc09b7d14_*_of_00032.arrow\n", + "[rank: 0] Global seed set to 3941088705 \n", + "initializing deepspeed distributed: GLOBAL_RANK: 0, MEMBER: 1/1\n", + "[2023-07-08 17:52:12,529] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented\n", + "[2023-07-08 17:52:12,530] [WARNING] [deepspeed.py:638:_auto_select_batch_size] Tried to infer the batch size for internal deepspeed logging from the `train_dataloader()`. To ensure DeepSpeed logging remains correct, please manually pass the plugin with the batch size, `Trainer(strategy=DeepSpeedStrategy(logging_batch_size_per_gpu=batch_size))`.\n", + "Enabling DeepSpeed BF16.\n", + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", + "[WARNING]: it is highly recommended to enable bptt_learning when used to deepspeed 2/3/offloading, otherwise an exception will occur when training with dataset records, larger then the configured context length (4096)\n", + "Using /home/ubuntu/.cache/torch_extensions/py311_cu118 as PyTorch extensions root...\n", + "Detected CUDA files, patching ldflags\n", + "Emitting ninja build file /home/ubuntu/.cache/torch_extensions/py311_cu118/cpu_adam/build.ninja...\n", + "Building extension module cpu_adam...\n", + "Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N)\n", + "ninja: no work to do.\n", + "Loading extension module cpu_adam...\n", + "Time to load cpu_adam op: 2.326359748840332 seconds\n", + "Rank: 0 partition count [1, 1, 1] and sizes[(1515008000, False), (49152, False), (49152, False)] \n", + "\n", + " | Name | Type | Params\n", + "--------------------------------------\n", + "0 | emb | Embedding | 102 M \n", + "1 | blocks | ModuleList | 1.3 B \n", + "2 | ln_out | LayerNorm | 4.1 K \n", + "3 | head | Linear | 102 M \n", + "--------------------------------------\n", + "1.5 B Trainable params\n", + "0 Non-trainable params\n", + "1.5 B Total params\n", + "6,060.425 Total estimated model params size (MB)\n", + "Epoch 0: 0%| | 0/1315 [00:00=1.0.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.1.0)\n", + "Requirement already satisfied: cycler>=0.10 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (0.11.0)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (4.40.0)\n", + "Requirement already satisfied: kiwisolver>=1.0.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.4.4)\n", + "Requirement already satisfied: numpy>=1.20 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (1.25.0)\n", + "Requirement already satisfied: packaging>=20.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (22.0)\n", + "Requirement already satisfied: pillow>=6.2.0 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (9.3.0)\n", + "Requirement already satisfied: pyparsing<3.1,>=2.3.1 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (3.0.9)\n", + "Requirement already satisfied: python-dateutil>=2.7 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from matplotlib) (2.8.2)\n", + "Requirement already satisfied: six>=1.5 in /home/ubuntu/anaconda3/envs/rwkv-infctx/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n" + ] + } + ], + "source": [ + "# Install matlab plotting library\n", + "!python3 -m pip install matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First step figures ...\n", + "Baseline: {'it': 1, 'time': 9, 's_time': '00:09', 'loss': 10.9}\n", + "JIT: {'it': 1, 'time': 13, 's_time': '00:13', 'loss': 10.9}\n", + "Torch Compile: {'it': 1, 'time': 72, 's_time': '01:12', 'loss': 10.9}\n", + "\n", + "First 200 step figures ...\n", + "Baseline: {'it': 101, 'time': 175, 's_time': '02:55', 'loss': 8.38}\n", + "JIT: {'it': 101, 'time': 172, 's_time': '02:52', 'loss': 8.38}\n", + "Torch Compile: {'it': 101, 'time': 225, 's_time': '03:45', 'loss': 8.38}\n", + "\n", + "Last step figures ...\n", + "Baseline: {'it': 1000, 'time': 1464, 's_time': '24:24', 'loss': 6.62}\n", + "JIT: {'it': 1000, 'time': 1407, 's_time': '23:27', 'loss': 6.66}\n", + "Torch Compile: {'it': 1000, 'time': 1399, 's_time': '23:19', 'loss': 6.66}\n" + ] + } + ], + "source": [ + "# First we need to extract the numbers from the logs\n", + "import re\n", + "\n", + "def convert_time_to_seconds(time_str):\n", + " t = list(map(int, time_str.split(':')))\n", + " return sum([a*b for (a,b) in zip(t[::-1], (1, 60, 3600))])\n", + "\n", + "def extract_from_training_logs(log_file):\n", + " result = []\n", + " with open(log_file, 'r') as file:\n", + " for line in file.readlines():\n", + " # Check if the line starts with \"Epoch 0:\"\n", + " if line.startswith(\"Epoch 0:\"):\n", + " iteration = re.search(r'(?<=\\| )(\\d+)', line) # Extracts the iteration number\n", + " time_spent = re.search(r'(?<=\\[)(.*?)(?=<)', line) # Extracts the time spent so far\n", + " loss = re.search(r'(?<=train/loss=)(\\d+.\\d+)', line) # Extracts the train/loss number\n", + " \n", + " if iteration and time_spent and loss:\n", + " result.append({\n", + " \"it\": int(iteration.group(0)), \n", + " \"time\": convert_time_to_seconds(time_spent.group(0)),\n", + " \"s_time\": time_spent.group(0),\n", + " \"loss\": float(loss.group(0))\n", + " })\n", + " return result\n", + "\n", + "\n", + "# Extract the numbers\n", + "step_baseline = extract_from_training_logs(\"./logs/torch-compile-perf_baseline.log\")\n", + "step_jit = extract_from_training_logs(\"./logs/torch-compile-perf_jit.log\")\n", + "step_tcompile = extract_from_training_logs(\"./logs/torch-compile-perf_torch-compile.log\")\n", + "\n", + "# Print the high level numbers (quick debugging, if log has issues)\n", + "print(\"First step figures ...\")\n", + "print(\"Baseline: \", step_baseline[0])\n", + "print(\"JIT: \", step_jit[0])\n", + "print(\"Torch Compile: \", step_tcompile[0])\n", + "print(\"\")\n", + "print(\"First 200 step figures ...\")\n", + "print(\"Baseline: \", step_baseline[200])\n", + "print(\"JIT: \", step_jit[200])\n", + "print(\"Torch Compile: \", step_tcompile[200])\n", + "print(\"\")\n", + "print(\"Last step figures ...\")\n", + "print(\"Baseline: \", step_baseline[-1])\n", + "print(\"JIT: \", step_jit[-1])\n", + "print(\"Torch Compile: \", step_tcompile[-1])\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Check if the loss plot is similar\n", + "\n", + "No point having a faster JIT / torch.compile, if the loss curve does not fall at the same rate" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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jEZjVzdDCCHEXiZDS91fR/0Oe1zPjBBCCCH2L10azFitVlatWhWsH5Ofn8+qVavYuXMnAFVVVaxatYoNGzYAsGnTJlatWkVJSUlXNVkIIYTo1gYMGMBjjz0WfB6rzlt306XBzPLlyxk/fjzjx48H4LrrrmP8+PHcdtttAHz88ceMHz+emTNnAnDOOecwfvx4nnnmmS5rsxBCCNFeF110EYqiBH8yMjI44YQTWLNmTZe1qbi4uNkyKd1Bl+bMTJ06FVVV4+6/6KKLuOiiizqvQW1Q5/RQUlGI3VYUsX1g7wOwJKV3UauEEELs60444QTmz58PBKaY33LLLZx00knBUYnOlpOT0yXX7UiSM9NOr/62g7veuJ4Lfrsi4ueUt46k1lrV1c0TQgixjzIajeTk5JCTk8O4ceO46aabKCwspLy8HIAbb7yRYcOGkZCQwKBBg7j11lsjZvusXr2aadOmkZycTEpKCgcffDDLly8P7v/555858sgjMZvN9O3bl2uuuQabzRa3PeHDTAUFBSiKwvvvv8+0adNISEhg7NixLF68OOKctl5jb5Ngpp10GgUNGox+NfgDUKHTsG3n2i5unRBC7F9UVcXu9nbJT3MjDC2xWq28+uqrDBkyJFgzJzk5mZdeeokNGzbwn//8h+eff55HH300eM75559Pnz59WLZsGb///js33XQTer0egG3btnHCCSdw+umns2bNGt566y1+/vlnrrrqqja1a968eVx//fWsWrWKYcOGce655+L1ejv0Gh2px03N7iyXTxnM5VPejdg2Yf6BODQSHwohRGdzeHwccNuXXXLtDXdNJ8HQ+tvpp59+SlJSEhBYgzA3N5dPP/0UTcP945ZbbgkeO2DAAK6//nrefPNN/vnPfwKwc+dObrjhBkaMGAHA0KFDg8fff//9nH/++cydOze47/HHH+eoo47i6aefxmQytaqN119/fTBf9c477+TAAw9k69atjBgxosOu0ZHkziuEEEJ0omnTpgVn8i5dupTp06czY8YMduzYAcBbb73FEUccQU5ODklJSdxyyy0R+TTXXXcdl156KcceeywPPPAA27ZtC+5bvXo1L730EklJScGf6dOn4/f7yc/Pb3Ubx4wZE3zcuNRA49IDHXWNjiQ9Mx3IgRHw4EvK7uqmCCHEfsWs17Lhrulddu22SExMZMiQIcHnL7zw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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the loss curve\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Extract iteration and loss values for each method\n", + "it_baseline = [entry['it'] for entry in step_baseline]\n", + "loss_baseline = [entry['loss'] for entry in step_baseline]\n", + "\n", + "it_jit = [entry['it'] for entry in step_jit]\n", + "loss_jit = [entry['loss'] for entry in step_jit]\n", + "\n", + "it_tcompile = [entry['it'] for entry in step_tcompile]\n", + "loss_tcompile = [entry['loss'] for entry in step_tcompile]\n", + "\n", + "# Plot loss curves\n", + "plt.plot(it_baseline, loss_baseline, label=\"Baseline\", linestyle='-')\n", + "plt.plot(it_jit, loss_jit, label=\"JIT\", linestyle='--')\n", + "plt.plot(it_tcompile, loss_tcompile, label=\"TCompile\", linestyle='-.')\n", + "\n", + "plt.xlabel('Iteration step')\n", + "plt.ylabel('Loss')\n", + "plt.title('Loss Curve')\n", + "plt.legend()\n", + "\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working as designed, it should be nearly impossible to see the differences between the 3 lines. So lets plot the delta against baseline instead." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAHHCAYAAACvJxw8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAD1F0lEQVR4nOydd3gc1dWH3+3SatWr1WVb7nLvBRvcwDRTTEkCDiSkEloghN4SCCQEAiGYhMBHwCQ2zTRjXAH33m3Zsq0uq5fVqm2b74/Rrna1Ratmyfi+z6NHuzN37tyZnZk9e+4556eQJElCIBAIBAKBQOAVZV8PQCAQCAQCgaA/I4wlgUAgEAgEAj8IY0kgEAgEAoHAD8JYEggEAoFAIPCDMJYEAoFAIBAI/CCMJYFAIBAIBAI/CGNJIBAIBAKBwA/CWBIIBAKBQCDwgzCWBAKBQCAQCPwgjCXB95pvvvkGhULBN99809dDEZwjFi1axB133NHXw/he8OSTT6JQKPp6GP0Wb8+XH//4x6Snp/fqftesWYPBYKCioqJX9yNoQxhLgj7n//7v/1AoFM6/oKAgEhMTWbhwIa+88gr19fU9ur/333+fl19+uUf7BJgzZw6jRo3q8X57A5vNxttvv82cOXOIiopCp9ORnp7Obbfdxp49e/p6eF1m69atrF27lgcffLCvh3JB0Zv3lOuzQavVkpGRwc9+9jMKCwt7fH/nC5deeimDBw/mueee6+uhXDAIY0nQb3j66ad59913ef311/nNb34DwD333ENWVhaHDh3qsf301oP9fKGpqYkrrriC22+/HUmSePjhh3n99de59dZb2b59O5MnT6aoqKivh9kl/vznPzN37lwGDx7c10O5oOjNeyo5OZl3332Xd999l2XLlnHdddfx/vvvM3PmTBobG3tln93hX//6FydOnOj1/fz85z/njTfe6PEfkwLvqPt6AAKBg8suu4yJEyc63z/00ENs3LiRK664gquuuorjx48THBzchyP8fvDAAw+wZs0aXnrpJe655x63dU888QQvvfRSj+zHbrdjNpsJCgrqkf46ory8nC+//JJly5adk/31Z5qbm9FqtSiV5//v4fDwcH70ox+5LcvIyODOO+9k69atzJ8/v49G5h2NRnNO9nPdddfxm9/8hg8++IDbb7/9nOzzQub8v5ME32suueQSHnvs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s2fPDvhYA6GkpMRtPEajkf/85z+MHTvWmRavUqk8PFIffPBBwPEyEyZMYNCgQfzlL39xMyocOO4TlUrFwoULWbVqFQUFBc71x48f5+uvvw5oX77uqd46r5s2bcJkMrl5Jr2dr1dffdXDC1pVVeX23mAwMHjwYOd9093nS1fpyn737t3LtGnTemU8AneEZ0nQb/jqq6/Izs7GarVSVlbGxo0bWbduHWlpaXz22WduxQ1fe+01Zs6cSVZWFnfccQcDBw6krKyM7du3U1RU5FGLxpUJEyawYsUK7rvvPiZNmoTBYODKK6/kiiuu4OOPP+aaa67h8ssvJzc3l2XLljFixAivXzbeqKiocHp+XHEYew899BBPPfUUl156KVdddRUnTpzgH//4B5MmTXIW3tu4cSN33nknS5YsYciQIVitVt59911UKhXXXXcdIMddfPfdd1x++eWkpaVRXl7OP/7xD5KTk5k5c6bfMb744oucPn2au+66i48//pgrrriCyMhICgoK+OCDD8jOznam89900008+OCDXHPNNdx11100Njby+uuvM2TIkE4Hvd944428+uqrPPHEE2RlZTnjVhzccsstrFy5kl/84hds2rSJGTNmYLPZyM7OZuXKlXz99dduRUvbc/nll6NWq1m/fj0/+9nPnMsfeOABPvzwQ5YsWcLtt9/OhAkTqK6u5rPPPmPZsmWMGTOGn/3sZ7zxxhv8+Mc/Zu/evaSnp/Phhx+ydetWXn755R4PiB8yZAg/+clP2L17N/Hx8bz11luUlZXx9ttvO9tcccUVPP3009x2221Mnz6dw4cPs3z5cjevpD+USiVvvvkml112GSNHjuS2224jKSmJ4uJiNm3aRFhYGJ9//jkATz31FGvWrGHWrFn86le/cho0I0eODKh6vq97qifOa11dnbPGmtVqdZbbCA4O5ve//73b+Xr33XcJDw9nxIgRbN++nfXr1xMdHe3W34gRI5gzZw4TJkwgKiqKPXv28OGHH3LnnXc623Tn+dIdOrPf8vJyDh06xK9//eteGYugHX2SgycQuOAoHeD402q1UkJCgjR//nzpb3/7m8/04tOnT0u33nqrlJCQIGk0GikpKUm64oorpA8//NDZxltqr8lkkn7wgx9IEREREuBM87Xb7dKzzz4rpaWlSTqdTho3bpz0xRdf+Eyfb4+vNGdAmjt3rrPd3//+d2nYsGGSRqOR4uPjpV/+8pdSTU2Nc/2ZM2ek22+/XRo0aJAUFBQkRUVFSRdffLG0fv16Z5sNGzZIV199tZSYmChptVopMTFRuvnmm6WTJ08GdM6tVqv05ptvSrNmzZLCw8MljUYjpaWlSbfddptHWYG1a9dKo0aNkrRarTR06FDpvffe81k64Ne//rXPfdrtdiklJUUCpD/84Q9e25jNZun555+XRo4cKel0OikyMlKaMGGC9NRTT0l1dXUdHtdVV13ldq4dVFVVSXfeeaeUlJQkabVaKTk5WVq6dKlUWVnpbFNWVibddtttUkxMjKTVaqWsrCzp7bffduvHkQb+5z//2W254zprX+7BW1mMtLQ06fLLL5e+/vprafTo0ZJOp5OGDRvmsW1zc7P029/+VhowYIAUHBwszZgxQ9q+fbs0e/Zsafbs2R3u28H+/fula6+9VoqOjpZ0Op2UlpYm3XDDDdKGDRvc2n377bfShAkTJK1WKw0cOFBatmyZ18/ZG77uKUkK7Lz6ov09pVAopKioKOmqq66S9u7d69a2pqbGuR+DwSAtXLhQys7OltLS0qSlS5c62/3hD3+QJk+eLEVEREjBwcHSsGHDpD/+8Y+S2Wx266+rzxdfpQPaXzOSJN8zTzzxRKf3K0mS9Prrr0t6vb7D8guCnkEhSV2IPBQIBIJ+yObNm5kzZw7Z2dles7v6A+np6YwaNYovvviir4ciOI8ZN24cc+bM6TF5IoF/RMySQCD43jBr1iwWLFjACy+80NdDEQh6jTVr1pCTk8NDDz3U10O5YBCeJYFAIDiHCM+SQHD+ITxLAoFAIBAIBH4QniWBQCAQCAQCPwjPkkAgEAgEAoEfhLEkEAgEAoFA4AdRlLIHsNvtlJSUEBoaKgQNBQKBQCA4T5Akifr6ehITEz0En10RxlIPUFJS0qHIp0AgEAgEgv5JYWEhycnJPtcLY6kHcJTsLywsJCwsrMf6tVgsrF27lgULFqDRaHqsX4E74jyfG8R5PneIc31uEOf53NCb59loNJKSktKh9I4wlnoAx9RbWFhYjxtLer2esLAwcSP2IuI8nxvEeT53iHN9bhDn+dxwLs5zRyE0IsBbIBAIBAKBwA/CWBIIBAKBQCDwgzCWBAKBQCAQCPwgjCWBQCAQCAQCPwhjSSAQCAQCgcAPwlgSCAQCgUAg8IMwlgQCgUAgEAj8IIwlgUAgEAgEAj8IY0kgEAgEAoHAD8JYEggEAoFAIPCDMJYEAoFAIBAI/CCMJYFAIBAIBAI/CGNJIOgCjY1gsfT1KAQCwYWE0QiS5GOl3Q4mU9c7N5uhubnr27siSR59GeskjEXGnum/DxDGkkDQSfLz4f774eGH5eeLQCAQ9DZr1sADD8C//+2jwZ/+JD+Y9uzpfOeNjfDgg/Db38LZs90aJwAtLfJgq6oAWLUKPlr8Hw7Mf4Bdj33e/f77AGEsCQSdpKgIbDb5V15NTV+PRiAQXAjkvreViaf+R/76HO8N8vNlj87Ro53vvKJCNpisVigp6d5AAT7+WP4l2Wp4rVkDA8u2A3ByR3X3++8D1H09AIGgz8jOhpdeQmm3o77kkr4ejUAgEPgkvuIIMSX7qNMPADL7ejj+yctzeytJYNQPILyhhDNxU/tmTN1EeJYEFy7Vbb9wVC0tfTgQgUAg8E9oQykAk0+9771BbKz8Pzj4HI3owkIYSwKBQCAQ9HM0lkb/DcaMkf+ruzBhlJICycmd384bZ87IU4LtUNvkgO8g8/kZ5C2m4QQCgUAgON+JioK0NIiM7Py2SiX8/vfyfFlXjC1XrFavi0OaZU/+lBPvAJO6t48+QBhLAoFAIBCc7xgMMHcujB/fte01mp4dz/cMYSwJBAKBQHC+89Zb8v8RIzpv+FRVwerVEBIC117b82MDjPp4whrLaNR1wfPVDxAxSwKBQCAQXMiYTLBlC3z9tUcmW7dISXG+PJp8qbyr4Lie6/8cIowlgUAgEAj6OQeG3wxAszbUf8M1a7q3o9ZCkt1mwAAID++ZvvoBYhpOcOEybRpkZmI3mzHv3NnXoxEIBAKftOjCALCqgvw3bOwga66PCLbIWXBKu/cA8P6OMJYEFy4KhVybxGJBUqn6ejQCgUDgk+rwDJbPWgbAoj4ei190Ovn/2bNQV+f0Lo3N/QSAGOPpvhpZtxDTcAKBQCAQ9HNSzu5iXN4nxNTn9vVQ/JOWJv8BFBZ6rC6JyjrHA+oZhGdJcOFy8iS8+KIsdzJ3bl+PRiAQCHySWH6AmMJ9mHTRwMC+Hk6nqQtJJLyhhJykOX09lC4hPEuCC5fKSudLVXNzHw5EIBAI/GNoKANg4pkV3hs4gqmDOohpEnQJYSwJBAKBQNDP0VoaAFDabd4bTGqtit2V4pJJSRDXQyn9eXle5U5UNjMAWmv/DEDvCDENJxAIBALB+U5YmJyuH9pBaQFvqNXw0ENgs3VfiNds9rrY0Cx78qcd/zfw9+7tow8QxpJAIBAIBOc7cXFw9dWQ1cUAar2+Z8fzPUNMwwkEAoFAcL6zbJn819TU+W2rq2HlSvjii54fVysNQVEANGvPz0KVwlgSCAQCgeBCpr4eNmyAzz+HgoKe6zcpyfnyUOqVABj1CT3X/zlEGEsCgUAgEPRzDg+9HgCzuoPpsvXru7ejiorube9gwACIPD9Fc71x3hlLr732Gunp6QQFBTFlyhR27drlt/0HH3zAsGHDCAoKIisri9WrV3u0OX78OFdddRXh4eGEhIQwadIkCnrSuhb0TyZPht//Hvvvfoc5LKyvRyMQCAQ+aQyOBsCsCfHf0Gg8B6PpPFqbPD2okHxk8/VzzitjacWKFdx333088cQT7Nu3jzFjxrBw4ULKy8u9tt+2bRs333wzP/nJT9i/fz+LFy9m8eLFHDlyxNnm9OnTzJw5k2HDhvHNN99w6NAhHnvsMYJErYrvP2o1ZGRAerqQOxEIBP2amvB0Vkz/G1+Of6yvh+IfrVb+f/asPL3XyoTTKwGIrTvVF6PqNueVsfTXv/6VO+64g9tuu40RI0awbNky9Ho9b731ltf2f/vb37j00kt54IEHGD58OM888wzjx4/n739vS1t85JFHWLRoES+88ALjxo1j0KBBXHXVVcT1VM0JwXmBpdqM3Wrv62F0i6YmsFj6ehQCwfeE5mb5pvKRCt9l6uu7dKMmlu1nePF6whpLsVvt1JfU+27c3AwtLd0YpBdMJrAH8IxMT0dKTcNsBntuPiaT++qyyOGd2q3RCJLUqU16hfOmdIDZbGbv3r089NBDzmVKpZJ58+axfft2r9ts376d++67z23ZwoULWbVqFQB2u50vv/yS3/3udyxcuJD9+/eTkZHBQw89xOLFi32OpaWlhRaXC9HY6va0WCxYevDbytFXT/YpcOH0aZQvvkh5qUTwgUa2rDzNRZ/9tsPNrFYFdrsCAIvF3i8MlIIC+POflej18PTTdqeWZX9CXM/nDnGuu4kkoXjvPRQ7d4Jej/3pp72m1nf2PCt27kTxzjvYf/UrGDWqU0NKLNlFbNF+mtR6vr16Bcozpwi/6xZG/nQqAEqHIVNWBvfdByoV9ieflOsvdYTF4tzebrV6GnP79qH8978hJQX7gw/KIuR+OHzATv0RifI7VrNuzHAkCWr1CYQ3nuVY4sUBn69PPlGwbp2C6dPtREX1zvUcaJ/njbFUWVmJzWYjPj7ebXl8fDzZ2dletyktLfXavrS0FIDy8nJMJhN/+tOf+MMf/sDzzz/PmjVruPbaa9m0aROzZ8/22u9zzz3HU0895bF87dq16HuhVsW6det6vE8BRGZnk1pQQEFBKKCl+cghrzFt7Tl+PIqCghQANmzIJiKih3/BdYHs7Ehyc1MB+OCDbKKi+n5MvhDX87lDnOuuoS8tJfPjj53vT65cSZOf2YZAz3Pili3EFhRQt2wZeYsWdWpMluITmEwmBh9+l0a7fH8XL/+K/MRqAEaVlqIym6nW69E1NqKrrSVv5UoaEhM77Du4vJwhrXG6eVu2UNf6HekgZdMmovLzIT+fg1lZHRpLlQdNJDSZ0JsOEGt5l4PR06itM6JqMVFSUsLq1TkBHfO//z0GkH8M/upXvXM9NzYGVlH8vDGWegN7qyV99dVXc++99wIwduxYtm3bxrJly3waSw899JCbx8poNJKSksKCBQsI68FAYYvFwrp165g/fz6arpSwF/hFERmJ4tQp6usl6k2NhISEMCOAB1hEhILTp+WHxdy5SbSzx/uEROMJphY8C8DAyc+RMKT/BayL6/ncIc51Nzl1CuWePc63SRdfDGlpHs06e54VJhOK2lqSFyxgRCeNpS1/3IJSMrS+k/cVkpjofGYpGhtRbNxI8owZKA4dAo2GtNmzITOz484tFpQnTkBdHUkzZ8L48e7jbmpC0dAAgweTtGiRf2MpP59tqi/BII91QdM2jIlXE1kVgqHJQEpCLIsWef9ubY/phWUkVx+mMDILSO2V69kYYED8eWMsxcTEoFKpKCsrc1teVlZGQoL3ug0JCQl+28fExKBWqxkxYoRbm+HDh7NlyxafY9HpdOi8zHNoNJpeeTD1Vr8XPGo1KJUoFPKEuEKhCOg8t24GgEaj6pIUU08T1GikCfkBprWY+/X1Iq7nc4c4111Eo2m7yQGVRuNXcy3g8+x4eKjVndZwUyiUKFrv8aLoMSRXHcSsj2zbb3g4xMTIcicqFSiVHY7b5QDg8cfBYkFlMHhuo9XK4x44EJUjgNsXdrtznA5Gnt1EeFMFoOCi4/9CowlM7iSl+gigIKXmMLWk9sr1HGh/502At1arZcKECWzYsMG5zG63s2HDBqZNm+Z1m2nTprm1B9mN52iv1WqZNGkSJ06ccGtz8uRJ0rz8ihB8v7EpxZeKQCAA3n67d/tfvRo6KHvjj9oQudijpHTJ4k1Lgx/9CMaMgXbTaAERFgbR0fRGwGNwS22P93muOW88SwD33XcfS5cuZeLEiUyePJmXX36ZhoYGbrvtNgBuvfVWkpKSeO655wC4++67mT17Ni+++CKXX345//vf/9izZw///Oc/nX0+8MAD3HjjjVx00UVcfPHFrFmzhs8//5xvvvmmLw5R0EecDBuNMmUUl/T1QAQCQd/T3Nz7+wgwVsYbNqUGsyYEu9rFy/PKK/L/pUs732FNDXz7rRzEvmCB53pHRuD69XD99R3GLHmjWRtKkLmeZk3/CxEIhPPKWLrxxhupqKjg8ccfp7S0lLFjx7JmzRpnEHdBQQFKF9fp9OnTef/993n00Ud5+OGHyczMZNWqVYxyyUK45pprWLZsGc899xx33XUXQ4cO5aOPPmLmzJnn/PgEfcf+6Jnokyb29TAEAkF/4+KLITm5r0fhhoSC7MRL0IyY2zMdGo3w1Vfy6xEjPI9X2flJqDr9AMIbzzrf70+/lmkn38EYMqA7I+0zzitjCeDOO+/kzjvv9LrOmzdoyZIlLFmyxG+ft99+O7fffntPDE9wnnJj7j/IDVoCXNPXQxEIBP2JoiI5BqgnCO+6iOzRzMVk7f0/rCodWQVforJbyLFMB4LdG27a1Pa6K+MuK/M0lhYtkrXjLmDOm5glgaDHmTgR7ryT5hBZDTuioaSPByQQCPoFvZXieumlMGFClzY1hchjatZ2MI1VUyP/T0uDgQO7tK/eQOmQOekPFSa7gDCWBBcuWi1kZWGKkH9FpVQf7OMBCQSCfkFoaNvrnByoquq7sbRSG5bKR1P/zJoxD6Kyy4UUk05u6mCrPkAtT1i5TsGZ1Xqm5LwHQFzdyT4ZVnc576bhBAKBJ/WjpvHppEwUSPw2OqqvhyMQfL8wmeRMsT4kvvIolJdTGjHMuSy4vszPFj3It98G3nbgQLYM+ykzs98EZE9Yi8bgXF0RPjjgrlbMeAV9SzVWlMxhR+Bj6AWEsSS4cMnNheefJ6bYTkNfj6W7KBSYgmPl1+KuFgi6R0hI7/S7ejXs3Su/7qRYe2rJDmIK9rFr8A8C2yA/X4636ong9C561soihrJ+tFzAOa1yL+ENJRxLvSzg7a0qHUb9AOx2W5f235OIaTjBhcvZs+ft/LlAIOhFpk/vnX7rW8VvFy2CqVM7tam+qRKA0QVfeG/gyFhzLbLc1NTZEfYo8bUnGFq8EbWt/8ovBYowlgSC7wFBBSf54Xc/54ff/RxFfWDl+wUCwflDUIt8XweZfdzfl7RWiYuIAB+qFj4ZMACCg32vd6wLpFhzYaFzCg5g4ukVXTaWZmS/yQ+/+zkzTvRykdAAEA57geB7gKau0vla0dgAnJ+F3wQCQceURg4noeY4liCX+1ynk/XYOpIj8YZWC489JhefjIz0XO8oQZCZ2XFBSi/erKElmwhvzTaeffhVIDC5k/Ty3QBkVOyilssD2qa3EMaSQNCKkDsRCAQAvPde7/a/ejUkJcnlS7pAZWgGCTXHsStdvsJHjJD/QkPh888732kvBrCHNPd9NmF3EdNwAgFwxjCcY0nz+noYAoGgP+CILepNTKYubyoplNiVandtuD//Wf47fbrzHdbVyQbcJh+lCCxyqQI2buxynKdVJWvOuWbGnU8IY0kgALbFLeBQ6hV9PQyBQNDfmDNH9gL1I8xqPQfSF5OXdWXPdFhbC59+Cv/7H5R4Kc5rt7v/DwCj3j1uavegmwCoC+lf5zJQhLEkEAA/OvM331kmAoHgwqW42Flosdt0oyTB8UHyjzm7Us3Y3E8Yf+ZD1GYvYrybN7e97oLgLWfPei67svNGmUQX9t2PEcaS4MJl/HhYuhSrRq53YvgezKsLBIIeIC6ud/q94oouy50YQ2WPTKPOSwC2KxUV8v+0NBgceAFIgX+EsSS4cAkKgunTqY0bAsgZFwKBQECYS5ZZTk6b3lofUhuawqrJf2Rd1n1OuZPEU9/18ai80Frvqb3cybST7wAQVyvkTgQCQR9RP3wya8YOAIWCzOjYvh6OQPD9wmj0nlJ/DompyUGqqaQ8rM1bpK87R+LfW7cG3nbwYDe5E6tKh0XdVq28OjSAWk2tfDjtRUKbymhRaJnFvsDH0AsIY0lw4ZKfD6++Skyx8fyXO1GrqQrLaH3dt0MRCM57OilFEjBr17bJnWg6V6oko2hz5+VOSkogMbGTg/RCWdc06FzlTlKqDhLeUMLh9Cu5JsDtWzQGWjSGVrmTvjWWxDSc4MKluPjcpAgLBILzi1mzeqdfx3TeokUwY0anNtU3yTGVI4rW+m84rE1ol4a+/RkYX3uCQaVbUNnMfTqOnkD8BhUIvgfoik7zw+9ewKzWozA9DYT29ZAEAkEPEtRSB4ChudJ7g3nzYP16iIqS5U5KSwPvPCFBjjXyVRrAIXcyYEDHfRUVucmdTD35LsVRowMfiwtTT/6HQaVbOZkwk75WJRCeJYHge4C2RnaTa62NKBq6XuxOIBD0fyrCBgG4y52oVPLUnkrlYys/6HTwxBPw0EPuninXvgFGjuy4HEGjZzmDwaWbnXInM48uC3hYg0rlWKnM0s0dtOx9hGdJIGhFyJ0IBAJALs7Ym6xeDampMG5clzYvixhKrPG0u9zJpEnyX1CQ3H9n6az4bicIa2yLeXJk8p1vCM+SQAAUhgzmZMJFfT0MgUDQHzgXpQLq6nq2vz/8Qf7Lyen8tkYjbNjgO+vNapX/b93aZbkTSSGbG2Z11wtz9iXCsyQQAN8kXEnowPF9PQyBQNDfmDWrZzLKepAGXRS7B9+MYczUnumwpgZWrpRfDxrk6WUytwZoNzUF3GWjLhJ9S5vRuSPzFqadfIdaQ3J3R9snCM+SQADccvolRud3QalbIBB8vykt7XSav0+6UZLgRMalgOyhmXh6BZNO/de73Mm2bV3eByBnCbdn8eJOd2NR9VL5hT5CGEuCC5cxY+C665xv9eYedosLBILzk5iY3un36qu7LHdSGy4Xc2wIivbf0JEFJ+ROehRhLAkuXEJCYMECKpPktNbBZZ2oUisQCL6/RES0vc7JgdravhqJkzpDEl9OeJyNI3/jDJJOONOBF6krQrrdpXWfrnInFnWwU+4kpu7UuR9TDyBilgSC7wGmYRPZNCoUCSWZUb30q1gguFCpq3M3oPqASGM+NlM1laEZzmWGmoJzs/MdOwJvm5npJnciKRRYlVrn6np94Fl3qyY/S2RDEY0qPVM5FvgYegFhLAkuXIqK4N//Jqa4+LyXO5E0WkqisuQ3ogKCQNA9eipGqT0bNrTJnXSyHtKggk2dlzs5ezawQpIdUdI1DTpXuZOkmiOEN5RwYOC1XBXg9g1B0TQERbfKnfStsSSm4QQXLgUFXX4ICASC7zFz5vROv5Wt1bcXLeq0pEpwczUAQ0s2+W+Ymdn22tS3BWrja0+QVr4b5XlaW8kVYSwJBN8DdCW5/GDzL7h61yMoGs93P5lAIGhPcHMt4B4L5Ma8efL/2NjOF5iMi/O/3pHFFxXVcV8lJW5yJzOz30RrDbzkgCsTT6/gh9/9nPG5H3Vp+55EGEsCwfcAbdVZFJKEobkSRb2xr4cjEAh6kRpDCgBWnaFnOgwOhkcfhd/+FoYM8Vyvbo3YGT++46BxL96sgWXbnXIn04+96bHeF0OLNwIwonh9wNv0FiJmSSBoRcidCAQCAD7qZU/G6tWQkQGjuyYwWxyVRaSpEJuqLXCaWbPkP40Gvv66852mpHRpLIEQ0dBWu0lj65qXqa8RniWBACgNTuVM7JS+HoZAIOgPlJf3/j6qq3u2vyeekP9OnOj8tvX1sHkz7N7tfb1D7mT37i7LnTiwqIK7tX1fIYwlgQBYl3gdOzN/2NfDEAgE/Y2ZM3tVZLYrmIJi2D34ZvKyruyZDqur4b334M03vRuKzc3y/07o2Zk17hpw24csBaAmNLXLw+xLhLEkECDLnYwq/KqvhyEQCPobZWWg0/VMX+quR76cSpvrfD3p1H+ZdOq/qKwtng137eryPgAoLPRc1gW5kyZNWPfG0c8QxpLgwiUrCxYudL4NsvRtmq1AIOgnRHcgKdJVrruuy3InVZGydIkpONZ/w6Ii+f+AAbIobk+gFKaCOAOCC5fQULj2WqfcybCSjX08IIFA0C+IjGx7nZMDxr7PMDUaEvl67IN8N/znTrmT+LydvjfQavvUyPEtd3K6r4bULUQ2nEDwPcA0ZDzbh4BdqSIzIoBaKAKBIHBqaiCsb6eVwkwlWMy11IS0Za2FVuWem537Cvz2RmYm24bexvQTbzsXuWYadygE7MLnE58kru4URm0kE+lbI0sYS4ILl5IS+O9/iSk+cf7LneiCOJMwXX7TQ+EVAsEFS295ZL79tk3upJNk5q3rvNxJWRnEx3dpf254i2PyhUKBXSFLuVSED2Z91j1IKEmsOUp4Qwn7Bt/AFQF2ZdQPwKgf0Cp30rfG0nk3Dffaa6+Rnp5OUFAQU6ZMYVcHwWwffPABw4YNIygoiKysLFavXu2z7S9+8QsUCgUvv/xyD49a0C/Jy4OTJ/t6FAKBoL8xd27HbbpCaan8f9GiTkuqBLXUAjC4bKv/hq5xSn08fRhbd4rEmmMosPfpOHqC88pYWrFiBffddx9PPPEE+/btY8yYMSxcuJByHzUxtm3bxs0338xPfvIT9u/fz+LFi1m8eDFHjhzxaPvJJ5+wY8cOEhMTe/swBIIeR1eaz3U77uey/c8KuROB4HuIvkmuyxRVn++9gUPuJD6+86UOYjsIGnfInYSE+G8HcPYsM0782/l29tF/dFnuZEzeKm7YdjejC77o0vY9yXllLP31r3/ljjvu4LbbbmPEiBEsW7YMvV7PW2+95bX93/72Ny699FIeeOABhg8fzjPPPMP48eP5+9//7tauuLiY3/zmNyxfvhxNb6lNCwTtaGlpK1/SXbQVxQSZ64mqzz+v5E6Mxm7XuOszmmubaTF6Sd12QZKgrlaitrC+RzVNLY0WGisbne+tzVa3974wFhlpqvb/xWWxQGODhLHIiGSX5INocDfA6+vB7sVZ0FufZ31JPXZr4N4JyS5RX1Lv9t6YV91WXLEDLI0WLK1NLVb5/HYGyS5hLG3EVGrCbrW3ncsA6ejzNOrlqTWrzuDs226XPztroxmrqeMHi+uY6mtt2O//HdKv76Q+2ItOnFqN3Q7N46aBQkFTdROWRotbP3a7fF1QX4+i3UWQXr7LKXcyJVsO9PZ3rdjtsmrKqIKv0FibGV3wJUajBputw8PqNc6bmCWz2czevXt56KGHnMuUSiXz5s1j+/btXrfZvn079913n9uyhQsXsmrVKud7u93OLbfcwgMPPMDIkSMDGktLSwstLW0PSWOrq9NisWCx9Jy6sqOvnuxT0IbCakVhtyO13rFWhTqgc221KrDbZX0ki8VOVz6e+np44gklNhs89pidmJjO9+GKzWZFQmodU89ehz1F++v5q68UfP65gsmTJX784/PLYqo6UUn2zX8ApYrRnz5BaJL34N9331UQ/OZrJNYcZdfAG5n9xEWMG9e9fbcYW9i98AmUTY2k/eO3JExMZtv8p1DV1jDgT78m47JhXp8dh1/bQv0b/wWlivRl95M41bM4oMUCjz+uZMi+FQw9+w2qBZcw5YVrUN53H/Zf/QpGjGDXLgXvvKMgIwPuv7/NgOmtz/Pomzuoe+Vd7AMHM3PVvQFts+X6V1GezCb05zeT9euZbP3xmyj27SdpVARp/3nKb70jS6OFgz96CYsF0tMl8vIUaG94njFb/oY6yH07X8/orbf8i4bsQgwtVc5lilkzmD5bjcJuhy++wJ6WBl6+c2xmm8fnCSBJduc9nhc9jqzGr1Dv2sL++Vtg2lT2xC2isnEcl/7xBZQKGDtWIshiwdsDavejn2P5bA2KGdMInzyE2pf+gy09A1VcNOzajW7JlUx47FKXA7Wyb4/EgVw7mfZcVC+8gD04mKAFF2H+ZDXS+HHsGvMzcnLgjtltzyIH48+sdC7Rmev48ksrq1YpmDBB4ic/8bxWnn9eydnTjdzQupUkSbz33ghmzrSQnOztU+s6gT4rzxtjqbKyEpvNRny7YLX4+Hiys7O9blNaWuq1falj3hh4/vnnUavV3HXXXQGP5bnnnuOpp57yWL527Vr0en3A/QTKunXrerxPAURmZ5NaUEBNTSiVulQqlQmY/MS0OTh+PIqCAjkjZcOGbCIi/HsXvHH2bAgnT8p1U1auzCU9vXveoPojxUS2ui62bNlCcEkA7vI+wnE9v/32SJqa1BQUQFzcwT4eVecwbasgorYGgDXvfE7I2Eiv7VasGMNdhTsxASMO/ZuP39Vx9myV17aB0pzfiKFMTsve/N+1BJ2KRV8oT83s/Ggjx6Uzzrauzw7TVweJaL1Gvv3fOsKrB3j0bTRqOXx4OBfnfIEJ4OPP2BN2lAF5eZR88gkVeXmsXZtGfn4E+fkwYkTb59Zbn2fD8p2Em0xw6IDfmFNX1Pv2AHB2+WoKM4w0bT9CqMVE7l4jJz/+GIvBtwBtc2EThhr5PJ3MsdHSIgcrf/7fz9DFB3ndpv0zunnnYQzWOhzOxOzwcRQeDCU4fDuxBQUAFH3xBVX5nlNq5kqz18/TXluHtknusbKiApOrq3LdeoYhi806lp7JNVHx7bc05OR47KNm1XYMLRK5O6tJPLWGCFM9HDnUtv79T1k9oc0Qjtm2l9pKEwbjFr55184UYx0Y62h8d6Xc4LvNbCmbg87WxNeVOYz340Zt0ejZ+vJqomuMbDk5kAEDKjzaVHxuZ0bFBkwute9+dOpldq6ezqHkns1gaWzs2CML55Gx1Bvs3buXv/3tb+zbtw9FR0rKLjz00ENuHiuj0UhKSgoLFiwgrAfTSy0WC+vWrWP+/PlierAXUERGojh1ivp6iX9obyZk0FjuWtTxdhERCk6flq+XuXOTupRscuoU7N0rz4LPnJnUVT1NJ0eLt1O36QAAY2bOJH6s5xdhX9P+et60Semc3Vm0KKlvB9dJcpoOUfGZnFwydPJk0uZlem2nfOopDC5fzFlZWSxa1L0fVBVHysh5fRMAiaNGknrVVDa9cZrY+jPEDRvG2EWXeH12bP+8GqmgiANpVzHuxkuZNs3zF31lUTMpzz6AwmXMk9LTUZSWkjxpEtKCBYR8+j80BZupNqSyaNGDznb2F18hquIEebGTWLTox906Rlc2fNJAcFUlh1Mu4+eLArhBgW2GLwHQx8cxc9Ei7lo1j5t23EuQDsbPn+9eR6kdVdkVnHhNrrmm14Pju3TKJZcQnhbh1tbXM3r941vRm9vmjCbacmhJmMG4sWNR1NYCkDx1KtLs2R77ry82cvgvsvHl+DwBtvxxC0rZbkOXOpJjiYOQlCqmnHqf+qBYQpvdjY6E+BBGzJ4NmZ7X5kcv5BJbXUfOwKkkGQ6hKCtzWy8F65nhcq7NJVXsMdRgoIWG5GQMxQZKIkYQ3lRKSIscS3WdeQvpFbvRaeNo8WOMNsSMZLqimJiG/eyKH8AiL59pyaufkGQ0g07uR5IkaChn1KRJJI7rWdeSMcAg+PPGWIqJiUGlUlHW7kMtKysjwUcwW0JCgt/2mzdvpry8nNTUNne0zWbjt7/9LS+//DJ5eXle+9XpdOi8lL/XaDS9YtT0Vr8XPGo1KJUoFBK3nH6Jk8G3oNFcFuhmAGg0Krry0Wg03e/DFZVKjQJFa3/9+3pxjE+pdD8H5xNqtcZ5vklI8Xm+w5sqgLYfYqH15Wg03g2rQNFo2vatUqnR6HQ0BMcRV5+LSqVyG4vrtaBUqrCjQKFQoVarvV5zWnMdSiS3MasdF7xaDRoNWmszoCDaVOi2r8iGYhQoyKjYg0ZzR7eO0RWlUokCBUqFMuDr2nF+FK3b2LUaJKUGhcIq9+GnH9fPVqloOxP+7qv26xQKZdv14VimVKF2vfFbz6e//bt+nrmpFzP46KcATD31X1R2C9uHLEWBAkml9difUqnweazK1vEpFCqUChW029auVLsdT8vli1G8stM5JgUKFEoluzJv4ZIjr9CiMZBRsQdQENxchxnfzgeFQkmEqQQFCqacWYlG45l5OLJ4g/uYWl/2xrMt0P7OmwBvrVbLhAkT2LBhg3OZ3W5nw4YNTJs2zes206ZNc2sPsrvU0f6WW27h0KFDHDhwwPmXmJjIAw88wNdff917ByPoH4wYAdOnO992NWNDcOFSFZqOZAgNuH306W7qdgF2QxiNOtkzYjOEd7s/f+zPuBa2bWvd8fmT/u0ofFg4+OI+2b++pcZjWVbBl3DDDR3Lnej1VIemAWDTtXkhK6Ll2KUO5U5cycjwujjILHtTBtQco3DUpR7rq8IHui/Qar324xDLtao6NzXmqEB+PnHeeJYA7rvvPpYuXcrEiROZPHkyL7/8Mg0NDdx2220A3HrrrSQlJfHcc88BcPfddzN79mxefPFFLr/8cv73v/+xZ88e/vnPfwIQHR1NdDsNII1GQ0JCAkOHDj23Byc490REwNKlVH5ZDwXbGFW0Bri2r0clOA+wB4dQET6YOn0fTHcGB/PJlD8BcOtAoLmZjHI/shftGJu3iuC8dJg+3G+7XZk/JD9mAvBx18faA2ha5Ky2UQWrgasD2mbV5GcBGNI6YzMu92OU9s5ltPU0YY1lHTcCUKv5atzDACxxif82hgxg/eh7sSm1LDzwPIBTQsSRaeaKXavzGcge0VAMQEb5TrKjbuercQ9z2X75nB1IX0xpxjSu72CYidVHOZUwM7BjciHamAtB3o2v/sx5ZSzdeOONVFRU8Pjjj1NaWsrYsWNZs2aNM4i7oKAApUvl1enTp/P+++/z6KOP8vDDD5OZmcmqVasYNWpUXx2CQNArNAwew76B12FTasgM9x2PIegZzCmDOJyyCLW9BYWpHgjcu9TzgzE7X0p+pj8aolMIbn2trvf0fPRXlLbueyHSKuSA79qwVJ9ekv5OSFMlZruN+qAIv+3MmhC0lgYs0Z2stdRKfXAcze32oTy432vbGGMu2UlzKYwZx/yDfwGgLnoQu8LHMzlnuddtWjQGgjF7XdeekqiRnEqYyaxjywI/gF7ivDKWAO68807uvPNOr+u++eYbj2VLlixhyZIlAffvK05J8D2krAxWrSKm+NB5L3diDw7hePIC+Y33hB1BDzPxzArCGstQV97POTWWWlpIqjrRKinR5nqQFApqxvuuPF02/GK03x0hsdqzKK83Rud/hsbaBCkdt+1NCkYuIu1g57LrQhvLCG88S2hcNK4HcGDkD1nQQWFFKVjPseQFDDn7LdD5TFe/bN3asdyJ2Uzm2R2tby5yLh52ZrVPuZPdg29m0qn/AqC1yE8z3dl8KC+HOM+6SbUhSUTUyxImkSVHCc3f5Fw36/g/2RjzBNBWoFmZ36ZBdzZhHJnIHq2kmiOEN5RQ7zI1KClVmFXBzvfN2lCCzG01r3YP+SEXnW7TjfNHsyaMwpjxmNXBtOX59Q3nTcySQNDjnD4N+/b19SgEFxCSovuPXKWxljlHX+OSI69gOBr49FtnCTLXMy7XZQrOR2xob2PWyYaoqxhrR1y153FmH3udzEMfdn6HISEURY9BbXM3lCRt4HE5BbFtcUmOGKO6kEQoKpIXzpsHF13kbVNobmZyznIm5ywn7NgO5+KgljoAMio8496sSh/esro6r4v3D7wOkI2muNydJFUfdlufWbjRe3+AVR1Ei8Z3tpvHEPSJ7Mz8UcDtvdGgi6JeEwmqvksEEcaSQPA9QFtexBV7n+LiI6+05ToLeg3dmeOBx6C4YNMGd9yoEyhs5zAOp7UsSlOY9+mdOkP/K/+gaBeUrrOYuhSobgqOheDAP7uKsDZ9NoeR5xCXBeSpwADEetXNbd4UfZNcnyu27pTXtseT5wU8Ple8XUNJ5e1+RLZmf7c3WEObZKmxSaf+51xmDgpjas67zvfxtSfcjx3IHnQ5IGfd+WNg2XZ++N3P2Zt+HW9nPoA9qpvVe7uBMJYEgu8BurICwhtKSKw+irLe+69JQc+hsAYWR/PxlOd7eSRtKCQJw6kDPtdnbFve4RScZAhly3D/af9FIxawd9AN7B58k9vynaN+ys7MH3W4fWeJLpG9Hj2RQTVtz6s+vS1OrFbCG892e18OvAVfdxdHNqSDsfmf9vg+XJHUspF0MnE24cZC2egEt6D5Y8kLyE6aS2XiaA+vXGplm/E16eRyasLTaAiKoio0PaD9j89f1b0D6AGEsSQQtNIZN79AEAhNugi39zVpY3t1f1pjpc91CnsAwlo6HfmxE72vy5XjVuwaHdlJczmZ6J6W36wL59SAWb637yKRpcd6tL+OUNTWMCXnPbdldfoBnfJIpVR6BkRHmgrb3qxeDcePd3mMZ+Ldp0SDW2rJTpzLlmE/DWj7GcffBNqy4jpDqNH7NvsHXsfeQTdg1XnGhLlO8+lbqqkLS2XV5OdYO+YBr319POV5No3yHpvcVwhjSSAAarXRlEQGpg0oEHSV5jAvIqX9HUctslPep38uBJKqDnVKoNrQ7Gm07h3YLtGorPPTuP64ZtdDzMx+M6C2TVq5PldR9JjAOm81tBNqs1HgXfdPbWtBZ65HZfEv4mtTaomtPE7m2e98et3i6nIYm7fK+T7KVMBNZ15DWdM9qaDuIIwlgQD4POVWvh3+874ehuB7xmX7/ui+wJfMencICaHGELgExIH0xdRnTfe+sqWF63bc73f7gXtW8sPvfs7cQy+5LZ9x4DV++N3PfaaMd5UWfRQAR1IDkzrxxpqxv++p4XSZZm3PZUzWhiSxe/DN7B10AwCmoM7F8jg8ngUx4wNqr2iSC/ZGmoqcy0qiRjqLfwJMOL2S63fcz+AD/oPqq8IyyCj6jsk5y4mvO+m1TbQp321fAHHNxWDtu1pZwlgSCIBbTr/EsOINHTcUCNphi/EtDhhlKnB7H2zsWW8CACoVtfqeCa5WmOrd0ry9oWmSY34Sat0FzKPrTgOQefa7HhlLT9KsDeswmLi/k5/UZuBOO/F/TDr1X2eKvk3Vu7WjrPO9y0DtGXQjAGa1nsGlWwDQNXVcwyusXvYoOcodtGd4Uf8TjxfGkuDCZdgwXBVsddbzvdqS4FxTFZqO3RC4eHZMzvZu79MeEuqUl7Dpe7e+0+G0K85LuROzWpYJKc7ofIXpnsCb3MmIorVw/fV0qJqt1zs9RXZNW7mC0tgsoJNyJ+npXhc7ArTjjKcoHu6ZRVcZMdh9gY9MQMd0nkXduSzP9gHg5wPCWBJcuERFwa9/TWWS/PDKKvyqjwckOF+w64KpMaRgDPbtVeo19HpWzHiF5Re9QePg0dDS0mm5k6D8Ex2225X5Q7ITL+nOSHsETYv8xS7LnQTGB9NfYvlFb1CaNgWArPwv+lzuJNJUJNcJ6ki4Va3m08l/ZPlFb1CbNcu5uF4fzzcjf82OzB85MwP9yZ1Iat+CwY5g88FnN1MfO9AprwLydOfBITd0eDyJ1UfRt1R32K49UfX5nd6mPyCMJYHge0DDwCyOpSzkUNqV2IXcSa9jTstkz6AbyYubjKKxjz2SLYH9Sm8Kb6uPpDH2XaBsZ1HaApPG8MegMtk7ZgqJP2/lToLMRizqYIzB/mVMHLFR5thEv+18UROSTEOwewyU8sghr22jTIVkJ81l+5ClzmXG6IGewewu+Cyg6YXSiGFsG3pbwO17E2EsCS5cKipg+XJiir0/CM4n7CGh7M+4Vp42CRJ6J+eCKTnvcvGRV1GX93wdHb+0tBBfm01crWdwbPU433InZ7MWUBIVuC7myMI1pHupFn2uKRy2oNPbhDRXMqDmGCF17p/NntG3Q0dyJ0HBnEi8uHfigHbs6FjuxGIho2wHGWU73BaPOPUZ8w/+heQqT+mXfQPbZG8dMWe6s/lQ6b2URH1wW1ZmeGm2PEXYyqzj/yTU5F5nSnmmLROyNL4tgy6l6gDDijcQ3th2nu1KtXN6DnBOGTvYOWwpgdKoiyQ3fmqr3EnfIowlwYVLTg581/+CUQXfX3pK7mTeoZeYf+hFDNl7XPpWgMK3kG5nCWmucqvMzOTJPdZ3Z2jRy57SztRBW7zrES45/DeGHlzR+R0aDOTHTkTVzqMlaQI3noqjspyvHQUkjfoEyG+dgrroIpgxw/vGTU1MP/E200+8TVh2m7GqazWCUqs8azi1qH0YgDXeg633tBYUrQ1JIv70dqfQsINBxb6fixaNvlNyJxVhgzwKmHaWFrWBJlVIQFXPewthLAkE3wM0FSXMO/QiM7LfhGb/dU4E3UeXm90/5E7M5zBQNlL+0m82eA8wNgX3vxpS7eVOVDZzl8o3mIJjQa8PuH1p5HDna0fws5uxZzB0HLsEqBvbajuFNFYAkFDjvZhlV+VOlDbPyuippe1i4HTedfEc9aQmnGkrF2DRGZh4ZqXz/YCaY1iV7tufzFgItBr4fnDInWzPvIV/DX0Ee3Qngtt7GGEsCQTfA4JK84ivPUl6+W6UdR2n7gq6h8ISWBzNqsnP9vJI2lBIEiG5h32uT9/xv47lTkIM7Bhyq982RaMu5UD6Yg5kXOO2fNvoX7B34BK3+JWeIKq1gndPyJ3M2vUi1Nb6b2SzEdLSczFdvSF34sj2c5BVGHjwe1dwyJ0cT55HWH2xM5vO4X1T2q2cTJzDqYSZVCaNIcjsXsAzubot1GH8qZVURwzErAmhxpAa0P4n5nZBELmHEcaSQNCKkDsR9DSuRfsAalOyfLTsGXQ1vr1dSmsABl5QEKcTfEwPFcg1o2yaII6mXsbRlEvdVjcHRZCdPI8zCT4KXnaRqBLfBmBvoKipZkb2W27LavWJnfJIJVV5xkF6yJ2c9F6QMRBOJs5xe29oquB40ny2DvtJQNtPPSFn0XVF7iSsrtDr8t2Db2bnkFuw6Dyn6FzlX0KbyqgNT+ODaX91y8Jz5bNJz/S4xmB3Ob+rdAkEPUSDOhRjWKbH8hajPM2hC/Puhr4QMZvlkjvOOHKLRf7rxDSFXyQJ6uudKveBUF9SjyHBgELZ5tY3Vpqxq7UolW1duX6eplIT+hg9SrUSSQKTCUJDwWiEUINEfUk9Yclhbn03NMgzEsqGtsKNNpvsrNBKLegj5evE2mxt3Zd7LIk5OBxjkZHQxFAUSoXcd6QGhUZNo1mNSrLSUFJH5KAomktrUUcY0Og1GIuMEBpKaJj7tIVj3E7sdhorG0EDVquCxkYIC5UwFhmxGU04tq6vh9qSRuwNTahU8jGodGpsagPBLe2KUk6fjvmbbVg278OqiEDRqEFtVaGxNVObKxGWEk5tbg2W2iAUqiD05lrq8uVO1YYgrE2yRyg8LUL+XGpsSMZ658mz2UAfG0JzbTNERGCzAS0tKBpMqLQqLMYmHNFCzbXNtNQ1YzPb0IeqaKyXZTjUwRqUEWHo9WCscJmarKqitrptKs5iAWNuFdZKO1KIAZVe/rzstUZ5JWAqqnW2b27tKrnqIHX7z6BIbx0fshfOolRiMqmpzq1D0zqlpNKqPAp2glw5ffzZYtSts+TK/UdpUMWgVCuxSiqC40KxWqGpuqltvKZmqlqdXC0t4JjEDWn29Hxdu/NBt/fNzWAsa8ISJVcsoLkZe30DKq0KjaURkKtwR9W10D4lRGExU32qGilSrp4uGeWDTqk8QHlchMe+AfTN1diVahQ1/ssJSDaJhLwdxDSaMQbHUZ0TiyZEi2SX5GtFpSKuLsetMGWUqYDrjf9EUXsPJPfNdK8wlgQC4OO0nxKaOZ6bXZbVFdRx4MrHQJLI+uhJojKjfW5/odDYCI88IhtMjzwCibEWePRR2cJ44AEYOLD7O3n3Xdi6FS6/HK66qsPm+1/cSP2bK5CyRjN75a8B2PPHr9nzbQP7068BhYJrr4Wpw2o5cNXjIEmE3HgFjcs/wZ6azpw1v+dvf5N1TaOjoaoKZh3/F6kVe7FHRqOsqUIaMZL4P97F3/4Gk43rubLlAxyTK9ue/YYtwwZz9e6nyfrbT0mansaW+U+hrKrgh+28EfGvPMKBV0A9/2JChiRR99p7RESA4dmHeeG/KVy1+wkMzZXodGC2gC04FP1ls2n+8AsKYieg+fXPuMRFwvDrryF3v54rg2MxNFWg/+oj9ry3CosumOUJP2HtWiUL8t8kNn+P01A6nHo5h09M4Qdzf+X1fF7b7v3J/Q2U7gB2fA3Pfs0QYEjrukMuCiSuyeIH3Z1OAOiuvZy62Vex7V/ZXHLkFa/7PpaykP0Z1zKodA9TT/4HwGkoFUWPgWl3e90O5GrSJ5IuIa38EI5SlMqaKtZd/jLbR9/H4l2PYLPBgR/+GYBtQ28jN34qAAsOvkFsnaf2nc2lNFP+r1/AtULQdyN+Tn7UGAoKRqJ/6XWiG4o8tnelISiKfW+saluwaw2wxvl2+axloFAw/sx3OCKeWj74nIdLL5evYZe+wprK2D34ZrTWRsbkfep1f7m5kPfIbrYOG014QwmX73sGhSQbjo4v/rzYySSeeNtjW4XFwoHFT7Jihvw5DS2OZiJyjJJhnzwlVh6eSX1wHINKtwKyNl0gKO1Wxh9s2+cRL7f4VC/bJTbmBTz93RuIaTiBAPjBmVcZUvKN27Kqo6UozC3yr6xjpX0zsH5GZaVsMFmtUFIC1NXJbhW7HYr8f1kETH2r1+GgZ4q0N+pWyw9rxeG2qY/GY3lE1+cyqvArkqoOUbk3n6pjZc7P0/TJWpAklPm5ANRuO8aE0yud2WWpFXJ6t0O4U3HsKAX5Eukl2xi07wOnRJWkULBl+B2MLviCYIuR6kNFNFU3oaws9zttY123iZr18r5qa8G24kO0lgbnl3dLC0h22YNl/HSTc0xHPslx62fqyf8w+9jrVIamA9DQgOzRaaxH3diE3Q4hpafdtrEpNQwsd09L95Wlp4iMoECZjlmt73YmX+VZC4WnWphz7B8+2wwvWkdIcyVKlbsHrVkbxqkE79W4FQqwqINIrj5EVH0+qZX7nOvy4iaxedgdNLTTTrMpNW7HY1OokTQa558v7Eq1vK1Gg1qtcFvefrsaQwrl4ZnYlBpMQTFUhA2mcMAkOaHLS1yzUpK9N65p9wDjcj/GYDcS3FLrXBbRUExaxR5ODphNnX4ANqUGm1LjFlgOcoV5gCv2PuU0lBw06iKpDPP940ZSa9C01rUsSmzLhFSqFFjUQeTGTWH3IO9ZbjaVlsKYsc73rlIz/sIdFIq2hLee1NLrCYRnSXDhMmSI7Ak5chqVZCXYEriquKAVdS88QsaPh0OHIDy847Z+iK89SbyjFpFuPIyb41xnVocQhMlZdyi6Po9hxRs4ZTeTHzvRo68DGdcwjLaKyQ5qQ5JZvOshQpo7X8nYrtI6f63qKgq5/ph3AdsmbThai1z4cv7BvxD0gft0cWL1EbYPWUp6+W7nsuqQFJae+iuG0hAUXr6Zta3SPqWRw9k46i4mW7cxePu7Hvs9duVTTM3+P85EDKUoarTH8QfK9iFLWXTiHQaeWkuFH9UUhWRnYNkObl2+kAMz5X3ZlBoOpV3JnKOvebTPHnwFGXddyekXPmJE0VrSQlIoiRrlNJgKYsZz2YHnaNBFObcpjBnHdyN+AchVwQeVbiVnwEXcsP1eZ5vcneUU/vgxAOyGMJQm+dnw3xl/B4WCN96A2cA/5n3I2OIj7M26mWdXDuXb8feiaJKnuK7e/ShFRfDMM3Kft98OU6b8FPgp79x7gIw1r7sdS1bBlzTqIjmevICm0VPJ3PRP4upyGEY2N/xuDke2yEaI8rVXuXi2vI1cXelJZx9PPAEb2v2uc53OatKGE2yWtf0W7HmWhUoFm1s9lVU/e4hr7k1329ZZtcsE/Lb19fXX8dt3xxLWVMbI2HKPz2Tkqj8SPTSG9eth+Qfysj//2X1WveCbM+T98nlMQTHkxU12VmdPS4fUFGjRhnKX+S8kVh/h4iOveuyjLxCeJcGFS0wMPPggFUlykTUhd9IFIiJg3Lg+HcLhMT8CwKzpuNig87VSBbQG7oJzKsObppeDyEPfeixr0oZ3yVCqDMugJTjC+V7V0uS7cTuUleUsv+gNll/0hnNZeyNGJVkB756tsXmrGH/mI0Aev6RQYtUE0xAU5dbucNoVKCUbUQX73QJ0fdEVT0BZxBCPzK7R+Z9DU5MzrbwgZjyTc5b77cfxQ2dE0VqGF68HoDh6dOvnU4XeXOt1O53FhKG50uNzt0XHURmW0eH4E2uPkm46SUJdx/IxHTGqYLXzOM1BYR4B9F0lqTqwAPnm0ADT8ufN4+rdj3LxkVcZeuQjp/eqJ2iJku9HKbFnhKF7EmEsCS54FD6+VBzU6QfQMmjEORpN12hMH8HphOmcSLwYe2j3PDJ9jmM6rykwA8Lh1rcrVH7bWRNTqe4gVVlll2MiCmM8DUBv2WS9pTfWrA3jdMJ0CmLGd3hcrnRkMPribOIEPpv4tN82eXGTOZh+tc/1LRp3Y2l/RvvoJ08OpC/m2xG/9LrOqB8AyJIXvmjWhKIwt7hNUTnQWUxMPvW+x3LXaaCgViNraMkmn/uwquXw57rW8bgS2ZpNNqbgC5/be6Orn5PKZkbVWN9xQxdcq2u7TYH1QAFTtaWJI6mLOm7oA0NzJRqb77pwdfoB7Br8gy7335MIY0lw4VJVBZ9+6lPuxJI6iI+mvsC60b/t0crIvYEtNIIdQ5bKlXl7Kiutr1gvewac1Y57kAMZ17Bl+B1O5XZXmQdXvhvxC1mItfWLemzuJ17bect6IiiItWMeYO2YB7o11h1DlrJ5xM+dU2ZOrBZijGeIrs9zWywpFBwfcR0A4Y3uchW+yCjb4VMBfnLOcmatbgvalRRKr4Zbky6CT6b8CZPOPQGiNGIYZyPlHxldnb7zhVmtJzduCqeTLiLy8HdePweNrVkWr21l1+AfUBWa3qHBDIDdjtYqT6c54m3ORo7o8Dmwd9gPOZh+NavHP+q3XW1sJqcGzPJqgIFsmLuVGnDBcHKf1+WBYGiuxK5UyQUs2x1LaPlpH1v1LuGNZ2kIiuZk4hxqRrbGpbUWE20IiiYncXa/kDsRMUuCC5cTJ+R6J75Qq2nWnudemt6mqgr2t07RDPPtAehNImvOUBAznry4SXSkIub48k5r8mLkeEFt70L2jUpFRfhgv01KI4YTExlFV/wLiqZGFh54vgtbgikoxll12YFcWNB7aQyVtQVcnBFWlY4mXYSbJ+ebEb8itu6Ux3RPTH0uuXFTCGsq85rq3hGO2JqIRs+ijjaVlm3Dbkfnx3ZpXwwyJ3E2OYmzA9q3pvCMs0L7qZSLKUjPoFnT8TRjYfxEGgOcjdyZ+SMmnF7p1bA1NJQxNm9VYB11kv/O9B5gH1l4CBjdcQf73adkO+P59MbJAbOdntwFm38OKaA8dbItDRKwKbVYFZo+/dEqPEsCgR/G5X7MzOP/Qn3W+6+8/oKmuoxZx95g0qn/nlu5E0fGl04HcT1c/yTTs+6VNyKrT5NauQ9DB1/ImoLTXLfjAeYf/AtHB8n5yr7kFiJMRcQYT3Mi8eLOjbmVrPwvuGy/7+rd1YYUqmOH+ulB4qJjrxNhKvI7DeWKQpKoivJ/znyJwyaU7OPyfc/43Ta27hSxrefEVYi1OjSN+Lq2AouOQpxDSzbRqIvklK8il8DUnPeYf+hFr+sOpC8GvMfc+PuCrg/qWUmMxqAookz5JNYc6ZJUSn8jwlREhKmoc8eidbluKircVo0sXENPI4VHAPJUanxtNt8M/wX/GP4U9pi+k9QRxpJA4ANVZRkjCr8mrWIPqob+nSkXVCwbDENKvjn/5U6SWoM7L7usy12Up3sRfbVaCTIbiavLcXotfHH5vmdYeOAFZmT/Gwg8xqQpORMsFkbnf05UfT6nBszq9NhBjv9JqTzA5fueodxLsVRfTN/2F4+AaVd8SW9oLI2ENZZRHD2ar8f+zmsbQ3Ml6eW7iK89wY7MWwA5qHts7idknpWFVw+lXUl2kpxDFdZYyrxDfyW9nUhroNgU8sSHt5IFIc1VLN71sFfB17Jwz6BxgJu23MkPNv/CbxB/e+qD46gOz2DqyXeZevLdDtsPqDjE4l0PyxqNfogpPcJ1Ox5gWPGGDvvMHdQ1zTdfXL7vGdkwbjWWKsIGAXJldp9otTBtmvy6I++ODx05N9r1kVaxh/FnPnC+t9wsS+5E1+cx79BLTDn934777GWEsSQQtNK+/ofSWNs3AzkfaWmRizD1AcFNcjbaeBcxz6pU9wDts4PdjZaIeu+ewkNpHRfB9IclOkGu2NmKKSjGa5ZYUvVh9PWdF+IFkILbDIG6kMQu9dFdrCr5CzHIXN+hZ6E3tNFANpg6MnodGIPjUNktKCRJzrZrpX1QujfiagLPdJty7G1Cmqvcyjh4Q2m3euineaNJF0FJyhSkqGgKYsYHPI6AUSic2WyODNHuUBgzDsnQ8Tm1pmQ4jbThReuYefxfDC9a3+399ybCWBIIALMyiCpDWl8P4/zm2LGe6ccxPWD3U5DHBYd0Q3scQdzHkhdQm+iezZhRtBmQp66gTZi0SeNdYkVracAaHEqNIdnnOFwL73XEoNJtpOa4fzm46si5Ghhqu3sAdtPtd/rsN6ilzhmY/J9B9/LezNexqP14DNoR2lTujNVxcPSyB/jvzNecHp4BNcfIKvjSZx8jO1GCw6chFRTEuDw5qD4swGB1Bw1BUW6xZlaVjk2j7nK+d5wfgKPJCwHfRTkB4qt8X9ffDJfrNVX2UPp8V6d9/bF1aGB6cX6x26G4VUfOZfquJGUKcXU5PjYKDK2t46zXKFMBVxX8H4ravvOaC2NJIABWZPyStaN/23FDQe9T0voF+ve/d7mLIFMlh1Kv4JuRv/Zar8bQ5F5M74PpL7H8ojeo18f77LNuxDRWj38MY7s21aFpWNRBKO1W1PXuD/OxuZ8QZA4s1dsRo9OeSaf+53z92aRnkELahEpPx0/niwlPcCzZd2i7xuoew3Y8eR5fTHjCa9uwxlKPzDW7Uu1hCCZXea+uPjr/c5/HW50wkq0/eM1rWQYHRn08K6e/BFqt0/MiKVR8MO2v7Bhyi8/tAHLjprD8ojfQWpsCLulgU2ooiJ1AfuwEr+tDm8qJqfYteGsMjmdnzCWcju++ePA3I3/NsZSFbsuCW2oJreteZfw6/QDfNaMkyTkVqLBZfHfS2OgUUgb4cNqLfDj1LxRkuAfMKyVbj8R1ad73zJ5MN50UcicCQV+zJO8NMks39/UwBNCmLxcT47+dHzL2fcT0E28TU3+GyIZC9DX+1dXja08wJm+V/+KLkkRaxR43z0u1IZU1Y3/vDMLWnznSpfGaI+Mpih7D4dTLPda5eoZ0FndDZFzux4zO/9yrbIXUWrm7vdekRW2Qg5UDwBSWiF3tPSi8s5gikpFUar/n2NBchdbq7mmQUGDWhFAUPdbrNi3RiVSFpqOzNhDR4P45b8y626dhCHIs2ubhP2PrsJ/6bKOx+vZ8GPUJ7IybR05C12LTXDkbOYJGXaTH8tH734H6emdV8ub4znnAm3QRxBhzO2yn8lJHzBctGgMt2tA2bZJWkqoOoajuOPNRVVFKrFEuVWAM9gzaVhgDm149l4jSAYILl0GDIDYWKCfI1tipwE9BK6ruxzl4cNFFcOZMt4wlB6MKvmJUwVegHg9j5jiXO+ROysPl4OlY42lGFXzFqQGzvHo+HHInM4//y2PdZfv/6FbPJ1Bc5U5UTSZu3HOX13aNuijCrbK3beGBFwj6pE3/SyHZSa3cR3FUlts21YZUbs79B1Flaq9yJw4qwwbKweteHDEWdTB7L/k9kw8vZ/opPHTHOsP2IUtZlP0OA3O+psJPO6XdSmrlXrBe4rZ8YNl2pp34P6/bNKSPpCw8mxFFa6nVJ2LUJzjXqW0tXHzkVY/q5A6GF61lUNl2TsXPANoCqe0hgeX/j87/nFFFxyiNWAIEHojvdSzF62nShnMmfhotujCqDalEmWRvjsOjYlNpaRmQ3ql+XTUvXeVO2lMxeFrAfeqbqzG0VKGv9z5t3REOSRhTUAx1+kRSOOC2XgoJAT+Orr5AeJYEFy7x8fCHP1CRPBYQciddIjKyz+VOjmbJYp4dxeZI2rYsHUcwa2WoPD3hkDvxVgnaQcSRLR7LLOrgLhlKHnInzQ2+G7dDWVrSsdyJ3YLW7r2EhKvcSX1wHJJCiU2to0VjcGu3P+NalHYrMWd2klG+s8PpFUfQd2eoDMvwmOIbf+YjedqnlaLoMT4NJQdBrR63EUVrGVqyEXDInYQR3niWsCZPDTOQazmFN5R46ELaYuIDkjtJqT7E4PojxBlPddi2I8bmfsLUk/8BoCUo3G+19M6QUnUgoHZN4QkdNwKYP59rdj3E/IN/YfihFdSG9Jw0iVPuJCmlx/rsKYSxJLjgaa/G3Z6GoChaBnb9V/W5oCltGMXRo8mNm4IU2rVfe/2GstZprgDrRVlaq/valP6ni6zJHVdvdgRTe6ttpDJ7TsdYVIEHT3cGsyaEwphxlESN7FTRP3+K7v4oSZrEx1P+5LdNfuxEv3plrgHqAAfTO84s3DtwCRtG3e11nSPTryRypM/tzWo9CpsVnUuVc2Xr/ay1NDiNQldsLsaZw8syovBrn/twyJ20Pz6AyAbZUB6f573Cuy8sPipSd/QsUtnMKJu9JzT4IqKhzZjvEbkTl+00lsZuGXUhLVVOiSFv1OkT2Dfw+i7335MIY0lw4VJbCxs3+pY7SRnIp5P+wNrRD3jMzfc3rGFRfDPy12wbdjuSvmu6U/2Gr1o9fHl5Pd714bQr2D5kKQ3B8hTf8OJ1XtttGH1vQHInXgOddTo2Zt3NxizvRkAg2BUqvhvxCzaNustT7sRmJaKh2COTTFIoOJJ1M9BzcifT1z7ZNial2mv9IrNaz2cTn6ZB5z7VVRI5qtfkTizqIApjxpGTNIfIA5tIqvK8h7W2JmdcDMDeQTdQpx9ArT4AT4gkobTbgLYsx8LosR0aGPszb+B48nyftaoc1MQNJTduijNjsz1Km4WwJu+lJUKz/Zcl8Iejent20lyPYzFU9by8UEcoJIkoUwEWdTC5cVOoHuke+9UQFMPx5PlC7kQg6FOOHYMVK3yv12h8PswErVRXt8kfDBnSJ0MIr82nIGY8BTHjO5Q7KYoeA0BavpzhpOhgaqlLcidqtdNI8EV5WCbR4dFdkztpbODyvf5Fb33RqIv0iM3zJ3eibTaCy/eUTanBrNa7pd9/M/LXRDSWkFjtHjQe2VBIQcx4IhsKfWbISSgBm9d1OosJgNBmzygnqyqI70b8Ap2f3zDtjcnspLnOgpkdoSk47YwXOpN8EYWpqTQFIH2UnziNxoiAdsG2Ybcz4fRKr4UpDaZSJpxeGVhHneT9Wa97XR6Vtw8IQDD8kLth2lVvpoMTiZc44wQvdsidnMx2kzvpD/Tvn8sCQR8zOv9zpp58B3WZ/2yqvkZdU8GkU+/LBfdavHsKegVHLSSdDhICjHkIlIyOY0YAoqtOklq5D7251m87TeEZrt71CBcfeYVDg68FfMudhDRXEtpYFvCXa3tGFnzF/IN/8bm+MiyDqnh/X0wS07PfIryhJOAK3gpJojLGvzSKr+mf+NKDXNqB3lx0fS4RjSUcTrvCTe6kInwwA2raahE5vE/DijdSY0ghO8l3BeqpOe/6lDtx1EBKrdzrsc7upy5Se0Hf7tIYHI2huYpY45nvhdxJSHOVrNXXmWPRuBhEpaVuq0YV+NHX7CJSiPwzQmNtJNqYy9dZ9/PKiGexx/ou7dHbCM+SQOADVXUFWflfyK/rJwI9F8jY0wQX5TCk5FsAlLUTAe9q5ucFSUlyAbwrr+xyF5Wp44nZ106d3WLB0FyJobmSEx3UPlq86xG392ZNSEBeoOakQWCxOEVQTyfMYFDp1k6MXKZFE0pGuRxYvX3oj+UA6wCYseV5mtR6NO2n7lrxVQRS21JPpKmQ4ujRHEm5lIUHXvBoE9ZYxuCzmzkbOYLdg27ikiOvYFbrGVWw2k3uxKIOZsLplUQ0FHPp/uf8VhlX4PsL22F0SV5itkKaq7ls3x/JTZsD7bovjRhGrPG0m/cLYMn2+1DarXw+8SmvKfreqA+OozJ8EJfuvA+AvNhJftvHVWcz7Pgn1BhSgB/5bBdVdpyrdy/H0OQvN1AmP2NOIPK2AXP17kflF9LroFBQY0gm0lTkX+5Ep5PlTrZv7zjWSdt5l1By5QHZk9f6UVtu+Qm8BbHGM1x85FWqDCkcjvJ9Ps8FwrMkELTiIXdSW91HIzkPaWmBmr4pvRDUXAu0ZbQBVKS7f6mVDZzq9j6q3nt8hrc6R53BHJPoJndSHxznVe4koTab4MaO69EAnh4Addt1agrqfnmFruDInNNaG93OuzdCOhA47ipRpgJCWgK7Rxu1EWgtDahtLW6eEIuq41iYmNrAM92mH36D6Po8Bp/1X7NNbWsJyFBq0kVQlDYDKTKKkqhRAY8jYBQKysJlQecekzsJIMHEVe5kaMkmZh973W9V+P7AeWcsvfbaa6SnpxMUFMSUKVPYtWuX3/YffPABw4YNIygoiKysLFavdrlRLBYefPBBsrKyCAkJITExkVtvvZWSEh8l+AXfWySU1OnPY29Mf+Cwpzr8uUBrlmNbVHb3wiyO7KUTSZdQnTzGbV16yTbAU+6kUevd46C1NGALCnGbfmpPZ+ROhpR8S1q2u6aaq1Hl6gFS4J4h1fize5yvbSr3X/He5E4CFQEGOTtM3658Qvb8u/hg2l/d5E5GFvnOHmsfg+MrgBz8yJ3odIwukL26YY2l3tv4oL3XyKrSsW7M/c73QS6FPR3GsT+5kwGVvq/rza1SIh1lWQbKqYSZ3lcoFFg7yPb0xY7MW7sxolbs9jbtRxfjvTRxfNfkTly8U0GWjivcR5kKWFT4Poq62s7vq4c4r4ylFStWcN999/HEE0+wb98+xowZw8KFCykv915DY9u2bdx888385Cc/Yf/+/SxevJjFixdz5IgciNjY2Mi+fft47LHH2LdvHx9//DEnTpzgqqu6J6YpOP94b9DdrB77UF8PQwBtGlSvvdblLrSNtRxIv5rvRvycwymLPNaHNrhni3085Xn+N+NVv8ZQ7cgZfDbpGU+5E0MqNqUGpd2KyuRe8K8zcif7MrynSLuq3X854XE3odLcuCmsGft7TifM8Nmv1uI+JZcz4CI+n/ik17ZR9fnMOv5Pt2UWbYiHwZVa4RlHBHKMny9PUk38cHbc8FdnkL03GnWRfDT1z6DTOfuRFAo+mfwcewbd6HM7aJM70diaPabgfGFTaiiJGuXTaxPaVE50jW/PUq0+kX1RMzkTNyWg/fljy/A7OJLqfq0Gt9QSYuqa4LKDmpBk37WQJIkhZ+Xp+w7lTnLajKJPpvyJVZOfJX/QJb636QaaD973WDa4/ggK8zmMx2zHeWUs/fWvf+WOO+7gtttuY8SIESxbtgy9Xs9bb73ltf3f/vY3Lr30Uh544AGGDx/OM888w/jx4/l7q+ZUeHg469at44YbbmDo0KFMnTqVv//97+zdu5cCFx0cwfefxQVvM7Bse18PQwCQ0lqQLiKiy10M2rOCGdlvEWkqIrS5gmCj/y+cKFMBw4vXk1hz1HcjSSKx+rCb3IlRH8/aMQ9QEiXXAgo57b0MRUeYI+PJj53goQ0G7sUe5cy1NkYVrGbo2W/8GiDtadBFkVQdmBewKSQaSdUzoa0N4YlYdSE+deUAdNYGWV/MBQkljUFR5MdO9LqNOTKeGkMKWlsToe1EgL8d8Uu+Guf7R5BZE8KmUb/hm5G/9tmmvbHpSl1IIlsSFpGd2H2joTB6rNdaTmP3vOkmd9IS61vM2RuNQVEeMjCuOHT0OiN30qiLpCHI89pIqdyPoqqyw+2VleXOsg7eppID6eNcc94EeJvNZvbu3ctDD7Vd+Eqlknnz5rF9u/cvue3bt3Pfffe5LVu4cCGrVq3yuZ+6ujoUCgURfh7ULS0ttLhkHBmNcvVXi8WCxdJzNdodffVknwIXkpNR6nRIUiOhlloMjWVu59pqtSC1BqBarW2frdWqwG6X3cgWi52ufDwWC9jtym714YrNZnWOtaevQ1dcx221SljsdpStGXGS1YrkZ7/tr2e7XelMprNY2qaaFLNno/jPfyAqCnsAx2G3252Bwm19y8tGFXzBqIIvkBiHddgs5zkyq4LQUU+1IRWLxUJs7XFG539OTvxMiiKGO9s52J92NUOsVuYceRUJkOwSEgosCg1zDv+NeGMOEmCz2bBYLB7be8OGsi3AuamBm/bIX9jttzTpIp11kxYeeA71qlHO/lW2ZtLLtnM2bDASEnZJ3r4yJIVr898ivvSfHhl/kmRDsoOERE1IEs2qIOxWm8eY7Qo1Wy55lIlHP2DSKQUVYQMDOi5vbM+8hUXZ75J2ah0VfuRXlLYWEiv2YWma7tyXhERy+S4uyn7TY+92u43a1BGUhJ9gRPE6aoPiqAuOb9vWbmV69r9p0Ea2LZPs2FtrKA0r3kBGxW5Ox03FYrnI2a9Zo3Vr73htt9tAoXBeryPy1zC05ATl4VdjsaQjSXYcn6B8H7a7XyzyOpvN83wPKvmGZk0o+bETaVLrqQuOJaypHLvdjrWxAQkJm1KLJT7N5/1ts7XdUw4Gl25x7qtJE+asVm6xWFAoFc51ZWnjfT83LBa3+1zXXE1wSy1aY4jHcTieP/6ek3ZjDRISJl00VfpEElsNaMkuYbODTReM3WbDbpfPkyT13rMt0P7OG2OpsrISm81GfLy7Czw+Pp7s7Gyv25SWlnptX1rqfQ68ubmZBx98kJtvvpmwMN9Bas899xxPPfWUx/K1a9ei13sWbesu69Z5L5wn6AHmzsW0fzcRnGHgiY9YvbrtlmjYV0O4SY6HKdq7jxNqOSj4+PEoCgpk78eGDdlERHTeNXz2bAgFBYMB2LIll6IiYwdb+Kf+SDGRrWPdsmULwSW9U5iyoiKYggK5ntLWrfmUldWSrlYTfuYMRTt2UFXf8ZST43rOzR1Jc7N8vlevbvM2RGZnk1pQQD1wZnXHacmb9RO42HQCm0LtjElsKCl2fnYAdSXFFO3f7zxHdVIw4Q0mjuiiUa5ezeCjKzABzeRRoCvE5LKtfNyVhH78Fgmty8vKTJhMBqptDSQ0HcfRuuDoEc5EVBLcbvv2lAanYKttIqm1XXVeGSaT98+s1mJE1dLWX/G2zTyb+mcA7jr2MABZ+1/HBFgsNlpaVDRYqom21tHgRfNt8FF5isMEnFbpyS8sJt5+lriGZlRS2wYbE67GdPwI0w5+xoBaHUcTr/M4L4FSVlZOjbEGlVLCZGqLvanUJRDT4v48HnHo32z8ohp9677OhI5g/J6X8bbn8vIKynbtQl9agMlkIvXEJ5QHJWFqNpFrGMaZygYmlB6jSROFqbVuU7WihoKCQgDSSnPQVR+lyRLN6tVtezh7NgSNLZKEpkIsVjua1qrZBQWFoFA4r9eI3C3ENRdTnpvE6tXHoM6I2iI/D1avXk1lZRAFBXIA9bZtBVRWykkQeXlW4tudy+GH3sKmULF5+DOYTM3kBc3i6op3aKiq5JtvvsFgMmFVaDiyYwcmk/epzlOnhlJT457VNj5/I6YGeV8NagU2q8k5PoVSgaZ1HDuLqlH5uN9UTU2Map1tOdTczLxNd6OSbFSfyaDIrCPC3Dae7777Ft3pYA4ejKWgQE5VXLv2KHp927XVcLiOcJMJY4uGSkWF87o63aRHKiikOi6VgvJCFPWlbtfcjh07CDrbs9+xjY2BTdmeN8ZSb2OxWLjhhhuQJInXX/detMvBQw895OaxMhqNpKSksGDBAr9GVlfGtG7dOubPn49G073CXwLfbH43n6a8M4SEhDBjUVvMQK7yBGdXbsOs1jPy2psZOUa+XSIiFJw+Lf9imjs3ifgulP44dQr27pV/cc6cmcTobuYG71ZUcXZPHWa1npmXLSJhUO8YSwUFsHOnPO4ZM5KZMEFCWVQEVivJU6cizfKtvt7+et60SUlD6wzHokVtMRUKhQLFqVMweDDDFnnGG7Xn9LclGM4YaNaEcklr+63/K0HhEssYkphEzLU3kfNZHlENhagiIghWNBETE8OiRYvYZpAzceLCgklNTaGleiTRpraMudjYGLIylDQZ5Cyw+PgQ6owK1DEDMVS2ZWQNGDmKgfPGcvBPa/2OOSI0nKDEJAxlZ+T9xoVgamjzuNiUGqoMaSgkO2F2M4aGtqmgtLRQUq2ysW4ocNdz0+vl8BJrcChUlBESEoLCT6p3VHQUqakpKAaksDp1MTdvaxPzjY+PI2noMKILo7BaFTSPuJSiEDPDzm7y2ledfoBb5fDDKZc59Rbj4+OIVEaiVkvY7G3j2Tr6F+RINuYffsmtr2lzL2HLP44Q3niWhsGzMeR4D4uIHpDEwEmTKF9/BINNPhc2vR6D2kBCqJZLrXsxGAwQFIahWZ5mCo+OJTVVPn8pjRoMZgOzW/YxfVFbjNypU3DsrV0YVDWYw2PR1lXQog6Rt1MonNfr1ge/oAFYVL+RGYv+wdYnN6JolmVxpi9aRFER7Ngh3y/TpyczebLsISn/9gSGHPfPzkFqagoDBoDC3IKhxkBwdAwj58wh+1VZ8276+LHMnOe9iOju3UqnWpCDgWfrCVLI+1LoIglpkccw9fLLUShg+8OygZSVlcWiRT4MEZMJ5QY5cD/pyivZ9qgc4B8cEcLm5OuYc3yZs+mEi2YTPTQGnU5BYaH8WS9YkITrV2NhyBkKl28hSKmkNjoSQ7M8voSkAaSEKIhNG0pqUAqGJh1nQm8kK/8LGhoamDp1KonjOjcN2RGOmaGOOG+MpZiYGFQqFWXtroSysjISfBTDS0hICKi9w1DKz89n48aNHRo8Op0Onc7zYtVoNL1i1PRWvxc8RiOcOEFs6TEKkL+k3c5zeiarxz+OTanhtuBgZ102tbpN/USjUdGVj0aj6X4fbsQksLY1NmNOON3vzweu41arW/ejUskLnQs66kO+npVK93Pg5Msv5RX5+agC6E+pVKFAgUKhdH5+SqUSXKZ7FEp53fHUy9BZ6sloOIq+tpQhZVvQaJagaG2rUCpRKlV8PV6uszT38Msk1BxnfP5nqGZf59JOfpVRuddtPyqVCo3BwOYRvwTgomNtXyKuKBRKlEqlsz+lUuE2OWVV61nfKpmxeNdDuK5VShJhLdVICoXbckmh4PDYWxi87T9ENJViotXw9DPtNah8F3syf4RKpUOhtLu1nXr6f2ib1qNQKlEAkiaY5qAoj/7sSjVrxj7I2LxVRLhkrhXHjCfWVMCAmmNMz3kPRZSidTwu50GpQmHHo0+1WoNCoWz9XFUe620qLWXhmZxMXcjUQxsJcfkcHNvp7C3E1edC67Wxf+D1DC35hvqQRJStafIKl8/A9d7XaNr6kVRaFCjIi5+GsjVGx3G9OgxRx7Pj8ODrCKs4TW7sZGZrNN7vF6B2wCgKYyYQbcojpNm9/IFSqUKNlWCLEQUKlK3XrmOckSf3orlsttfP03EruuI4DgBDSw2gIDtpLrO0WhRIznWhxjI0Gh9V+F0OROUyFmXr/eL6+Tjub3/PSbVa7kNjNxNXn4sCBSVRowgeOQxVwYeoVCqUShUNIQM4EnI1w0o2Ag298l0YaH/njbGk1WqZMGECGzZsYPHixYAcl7BhwwbuvPNOr9tMmzaNDRs2cM899ziXrVu3jmnTpjnfOwylnJwcNm3aRHR0z1Z/FfRjjhyBd97xKXkhaXXUGnr2V8z3jpqaNrmTwYP7ZAhhxiIKYsZTFD2mQ7kTR5Bwcl4uABqrf7Fef2nvvjdSO+UbfFEZOpCosJguy504Cwt2kmZtGEFm91/S/uROghsq3eROJIUSu1LtDAoG2DTyToLNdSRWuwfHhzeepSh6NLHG0z7Poz+5E41V9tB4q8xuVuvZNOquTsmdHE9ewPHkjq4QGXX+aWKM8jWSlzSD4qQkD+07b5xJvojGqIs6bAewecTPfcqdhJrOMiHnvYD66Swrp7/sJibsIObMLiAAyaKj7p9zZ4SevXE8eT5rY+QfBtO3CrmTHuG+++7jX//6F++88w7Hjx/nl7/8JQ0NDdx2220A3HrrrW4B4HfffTdr1qzhxRdfJDs7myeffJI9e/Y4jSuLxcL111/Pnj17WL58OTabjdLSUkpLSzGbA88MEHx/GVH4NZNO/Rd1RWDCpH2Fuq6K0XmfyQ/ec5kQYGv9otPpINF3peYukRyYoRpTcZzUyn0d1mtRF+Vx+d6nuejY6065E18EmY0Et9RyInFOoKN1Y1jRei4+8orP9eXhg6lM8F1kUCHZmZLzHmGNpVQZ0gPeb0XMcL/rHcUk2xNXdph5h17yus5BVH0++pYa9gy60a3EQmnkcJJdhGwdNYuGFW+gLHwoh9J8V2KffPq/zD3ystd1JwfI3pNBZdv8jqs9DQFW5/aHa2VxU3AsaruZ8KbS74XcicpulksrdFXuxFHaoxVvxl53kVpnbtTWZiIailmXdR//GPYk9hjfpT16m/PGswRw4403UlFRweOPP05paSljx45lzZo1ziDugoKCVve7zPTp03n//fd59NFHefjhh8nMzGTVqlWMGiU/pIqLi/nss88AGDt2rNu+Nm3axJw5c87JcQn6J8qaKsblfgyAqm40/VlCJLjghLMCrrJ6BKT237F2iEPu5Fr/Bo0/qpNHE9VO7kRhbiGioZiIhmJyrIsB39pw1+14wO19wHInCelgtTIu7xOUdiv5sRNJq9jT6fE3a8MYfHYzg89uZtvQ25xp4/5QSBIztr5AcxfkTnTNdcQaT/uVOwlvPMuw4g2cjRzB3oFLmHP0NawqHcOL1nmVO4kyFXDF3qf8yp2o7BaUdu+eJYdwrTeh1uCWWuYf/AsFqTM95E7ORowgxpjrUWvpmp2/RylZWT3uUZp0ET7H5Ep9cByVEYO5dJcco7p8lvdpVQfRdWeYfGJ1ay2uJT7bRZVns2jfB0SaijocQ1Hq9B6VO7luh+zFccid1AfHEdpUjk3t3bsI+JU7aV8MtisxAInVR4hsaDsXltt+Dm9BnPGUU+7kYNSPOpZa6UXOK2MJ4M477/Q57fbNN994LFuyZAlLlni/aNPT050piQJB+4eyqqb/1frot7S0QF0dhHeszN7T6JrlQpCyjMV8AMoGTiOK/3O2qUibiKufKrp1iqU9x5I96xx1BnN8CrQ0OKepagwpxNed8ChMGWs8jbbZUwbFGwqpXS64QoEjPb1JG06wuc53217CYciobS2MP/Oh37a6ACo0d4W4uhyqm4YCfjTNWmlRhxBdnwfAiKK17B10AwC2AKpiR9V5v1a8MevAqyiaGlvrWPk2ltTW5oAMpSZdBPkDL0aKsFMWMYT42pMBjyUgFAqKo7IYVryhR+ppFcaMY0RYx88Aa3K6U5NucOnmtincwLSz+4TzahpOIOhNAolJEPjhoO9ig72JrtUQae9JcMhenBowi8q0CW7rUkplmaT2cif1QbFe96G1NGDXBvn1SHRG7mR40Xoyjn3htsy1+KRPGRCg8edtmbjtK2u7yp28N/Buls94jWZt4Bm6GmuTx3k8efEv+GTKn9zkTvxNvbTXRfNXwdyf3MmIIjmjMLTJu0KDL9ofr1WlY41LYUpXPbmDabJagz+5k6SKAz7XbRuyFJCrZPcEeXGTva9QKmlRe59C7Yhdg3/QjRG1IklyQozjdSvlCaOJNQaunedEqcSqlK/3kJaONSWjTAUsKP4ARX33Sqx0B2EsCQTAu4Pu5bMJT/b1MATQFhPxz3/6b+cHdbOJfRnXsXXY7Rz0EjMTUV/o9v6zSc/w4dS/YAr2biwB1GRdxMdTnveQO6kxpGBXqlDarSgb3WvndEbuZPegm7wun3byHefrNeMeQnL55Z4XO5H1o+/1GlBuVyiRFEqPgO7c+Kk+5U7i6nK4+Mjf3Za16CM99NYyynd63X50/udu5QNcqYkfzq5r/0RxtO9JJbMmhFWTnwWdztmPQrLz+cSnOJBxjc/toE3uRCnZApY7sSvVlEUMoSzce2BzaFM5UbVnfG5fE5LM4cgp5PmoLt4Zdgy51SO+K7illqDG7gl6VxvSfAsuS5JTucCv3ElDg1tg92cTn+bziU+Sm7nAZ4JMd9Cs+sBj2bC6/c6yDH2BMJYEAuDywuWkl/sXZRacIxylPYI7VoT3Reau5czMfhNDcyVBFhM6H0X8HBiaK8mo2EV87QnfjSSJuNqTbnInjbpI1mfdS3FUltxPzv4ujdccGU9e3CROJF7ssc51elhql0I/tGQTqZX7OB0/PeB91QUnBCx3YtaF9ogaPUCTIRZzSCRJLsHg7VHarR7ZVXaFCqM+gTNxU72PMSKWupBE1HYzIc2VblORW4fdzrrRv/W5vxaNgfWjf8uG0ff6bKPzY+zWhCSzacDVHO3m9C3Ixp43bcIJu16HhgZSquRryxzduXjEhqBoQlp8X/8Ow7Izcif1+niM+gHe5U6q/d9rAMqqCqfciTePvqK0/yXUCGNJcOGS2qYUHmUul7NdBJ2jNwIuL71U/t+Vap/tGJP3GZfvfZqB+9zjaiyt0251evmLZ0DNMSacXklapXeB2MNpVwAw/9CLbsubtWFMzXmXlMoDnR6b5DJtp7CYuXnLnQwt8Sz46Ortumz/s+jWfOp8H2SuZ0jJt+gs7h6takMqVxa+x4+2/NLvGOqD45xTkN7YfNmzxJ7ewfgzH7hliHWW7UOWMuDMFma++3OfQfUgx0ANqD3elmXZSmL1Ya7d+aDXbUyDxlIcOYqUyv0MKfnWbZ1VqWN87ofMyP63120zS75l3qG/ekwd2oMCqxI9vHg9c85+RqSpsOPGHZBRvtNpSJq1BjdvnqKlGYUkYVNpaUoJIL3ftd+yHU7vjyPWzBvV6eMD7lNnMRHWeBZdU63nygA8TcoG2QA1BcVQbUj1WC95qWPY1whjSXDhkpwMb7xBeYo8heGoNizoBNHRMM5/TaHe5sTwxYD/uBNArgrYiiO+yOERGpMnGyDtp6wc2JQawk94eh4Vkp2Uys57kyrDMmjWt/2i1pg6jttwoMo9xfKL3mD5RW84l03Nede9jd1CpLnC6/Zj81Yx/sxHreMYiKRUeT13uzJ/iMpuYcCx9QwvWt/ttHmHx8d12qb9lCbAtBP/By4Vy8sihnpMDbZH1yrhMaJoLYNLtwBQHD2aZm0o8bUnian3HqQd2lxOfO0JQpvdz5UtPpHKsI6jjdMq9zK6ZodbtfeuMvXkf5iZ/SYAzcGR7Mz8Ubf7BEiv2B1QO1N0WmAdzp7NVbsf48o9TzJy/3seU7TdoSVKTm2U0vpfpLcwlgQXPL5Slx3YlBrMaZnnaDRdozlpkJzmHJaBFNK1QNB+g0NfzupF2MwLTUHyw9pXDSEHltRBXn/FuqKxyTER3r7E1Q11Hss66q87GPXx1IUkYlN0HDje3Sy4otTp/Hemf4OkMGYspxNm+FzfvkTAsQAKQG4fstTnNJmjv/yYCV7XA85z43oPa2xyoVGttZGRhV97bOM6zRfcahyP8NLOgbU1pd6m8syci2nNsJt6arnP7b2O20s5BOi4CKrKZkZh7VwdtSgXQ84tCaGrXmGdzjl1pzWb2D345q71A6jtZr/XrikohmMp3Z/i7Am6bSzZbDYOHDhATU3gv4wEgn5BQwMcP05YlfcATmtiKl+PfZCvxz6IpOln5WTbYYmK57NJz/D12N8jGQJLSe+3fCR7PTjVhSybDjiReDH7M66lMUj26gws3+G13ecTn2b5RW9QEjUSkAO1vTGodKvnQp2OrcNuZ+uw27s8zmZtGJ9PfJovJjzh9Jo4sdsJMhs9vGCSQsHBMbcC+Ayybk9G2Y7WCt6eTM5ZzsRv/uJ8b1UFYQz2PjW6bsz9NGoj3Jblx07kbOQIwD1IvSeQFEoqwgeTnbqAqP0bvAaca62NJFe1ZWgeSF9MszaUercg/o69ZfZWwyYnYVaHBsaxjMspiRrJ5uE/89uuKmEkJVGjfE+L2e0+g9TDjnSuSKcrIc1yPFF20lyPYwmuO/dhCEFmIwm12YDs5awdOsVtvVGfwP6MazGrux6/2FN0urDCPffcQ1ZWFj/5yU+w2WzMnj2bbdu2odfr+eKLL0QhR8H5w8GD8M47aJt9yJ0EBVMZNvAcD+o8o7a2Te4ko29c5wbTWQpixlMSNapDuZMzCXIgdEKenHHna9rNgdbahewbtZq8OPmhPyP7La9NqgzpRBmiuyZ30lDPdbsf6LihF8yaELQW94KVsjfD+48Bg7HETe7EG9+M/DVKu5UBNcfcloc2V3A2crjHcnf8xy8BnsYi0KiLYO2YB2S5E7t3z0T7sgRHUy/jaOplfsbisu+CM065k4IBUzibkOA3U9LBydR5NMbMC2gfm0b9xqfcSVh9MRN8xFl1l4+nPO9WpsJB7KntwKCOO8jOdnvbPumgsxxNudSZzfnI9la5k5wT0M/kUDvtWfrwww8ZM2YMAJ9//jm5ublkZ2dz77338sgjj/T4AAWCvmRo8UbG5X6MqrKs48Z9iKq+lqHFG8ko2xHw9FWP4NiXTgcpKT3btw+B7PbElR0htXJfh+ni6uJ8Fh54nhnZb3Jk0NX+21qb0VgbZW9CFxhS8g2zjr3hc31ZxBAqEsf4XK+UbEw4vZLQpnJqO1HDpzJ6qN/1vjwZMeXHmHP0H363jTQVorU2sjPzR26p6MXRo71WGB9etI6CmPHOApDeGJ/7EXOOveZ1XW6rwTm05BuPdUo/UzdNmsDrSvnCdWqoXh+PVaWTDevvQRFjiypINnA6cywu8X4UFLitcsSI9SitXi+VTc5wXJd1H/8a8jD26I4N1t6i08ZSZWUlCa0PsdWrV7NkyRKGDBnC7bffzuHDgaWjCgTnA8q6GiaeXsGIwq9R1/bvat76vGNMPL2C6SfeRlnlPbD3vCEpSf5/g+8v2Y6oHeCpkaZoaSbGeIb08t3OCtu+MrNu3HY3N2y7l6k5/wE8iz/6oiUuBaxWxuR9SmrlPmcAeWdp0oYzrHgDV+1+LOAaPgpJYsrOV/xmt/kqAhncVM2AmmMUR49m3Zj7vbaJaChmZOEaUiv3sW/gdYAcA5N59js3uROHcRRdn8fiXY/4/TLVWht9ihk7CoR684IEt9Ry8ZFXSC3zDF4ujsryeg6u3PM4V+96hOCWWp/j8RhDcBwVkUOYe/hl5h5+ucP24fVFTD35Dln5X/htF1lxkoUHng9IV60kaVKgww2IG7fdzY3b7nYaS45Cq37lToKCZLkT8Ji+8/iRou58JfD42myGuGSCmn8mq3TE151k8a5HmJbzLk1qAyj7Lsy603uOj4/n2LFj2Gw21qxZw/z5srxAY2MjKlXP1OMQCPoCqd3toKrqXOXgC5qWlrbA7HOMrkWeShtevN657Gymu/J7VcpYt/cxdae99pWdONftfWcL7rUMSIeWFucXSEX4YJq1njFkUaYCtGbP6SVv+EtAsLSL5VD7MDw6g72jrEKgQRcNyHWRJuf4D27uKGi5qyRWHyWsMbA4G5tSQ1hjGYbmSjcDpf097432BUz9cfG+FxlUuo3R+Z/7baexNBJj9F3s0kGTLoLczAVIEZFUhwaYrdYZFApnAH1PyZ1I4REdtrMmpjprSg0q28a8Qy8x6dT/ur3/3qTTxtJtt93GDTfcwKhRo1AoFMybJ8/P7ty5k2HDhvX4AAWCc0VjgOKaAh/s71pBxu7iMJbaewwcU0658VMpz3APHE0uk+sptZc7cdRdao/W0oBdpfEwTlzpjNzJqIKvGHjkU5/r/Ul8uMqdtE/bdpU7WZHxK1ZM/WvAorEACsnmYZydmnU7n0182k3uZMjZb71tDshB4644goq9EeYrEF2rddacMjR1zlPa3gtoVen4YsITzveuZQL2Z8hizf7KTqSU+RZC3jlIzgTzdd10Fm+V2AFQKjG1GqidZe/ArntonUgSNDe3vW6lMn4kMfUdG30eqNU0a+QfEYbmjr32UaYCLj77aZ/KnXTalHzyyScZNWoUhYWFLFmyBF1r8SiVSsXvf//7Hh+gQHAueHfQvYRmjmdRXw9E0CZ38tZb8MILXepCZWlm76AbUNnMlEYOp/3PuEhjntv7L8c/hgLJI6PLlZqxF/PR6Yu5cs/jQFsMW40hmYiGEtnQaHafkvCVReeN7UOWOrPGHNOE4J5Jtm7M/QwPb4vJKYgeR3X6YoYVr/cQWW1R6tCpgz2MyMKYcRxIv5or9zzpMYbE6qNtoqatNIXFU6+Pd6tV5DULEPx6VGrihlEw8weoP15JYvURwNNzZ1eq+WL844wNCiLKJMfGKCUrX417mJSqA61iyd7JjZvCtmG3k16+M3C5E4WKqtB0n8ZSaFM5qjrf01NVoelkh49DG9O5QpHe2D34Jkoj3KePg1tq0bbUA13PcK0MzaBZG+Y9mUGSnPFmCpufWMeGBrcfQ6vHP4pSshExJIm4Xf6nHLuC+otPgJFuy7JqdqJovq7H9xUoXfK7XX/99W7va2trWbp0aY8MSCDoCxYWr6QoEqBn4wMEXSA6GqqqoBvT+kO2v8OQ4/s4kL4YhWRD0+T/F6nOaiK6Ph+jPoHycB81tSSJ6Pp8N7kTsyaEjaPuYvKp90mpPIDhxF4YE3glZAeW0CgKQiYQZzzlYYjYlWqn8WRRBbmtG1i+A7XdzLHkBQEr0lcZ0gKWO7GpdT1Wpb05JIqmsHiGthpKXvenVGNRux+jXaGmOjSNZk2oV2PJEhqFUR+PSrIS3FKLysXQ3Jn5I4x634kCLdpQp8jutT7aBLV41tdyUG1I5UDSElJTu5/ccCphllfv5KTtr8BP7yG5urW6d2TnKtubgmP9Go/6ViFblTXw6dIag3y8Ye1u0ZTK/ShqqiHGvyi5srrSKXfSqI3wiKVTFhX6StDsMzo9Dff888+zYsUK5/sbbriB6OhokpOTOXTIt+aPQNDvSG7LMoprLiayoagPB3Oe0htyJ1e2iokO6P7Uxti8VXKQ8e7/ui13TKc1BMlTG0nVR5iS855PgVhHgcVL9z/nttwUFMPYvE+7JnfiUhxRUiq5ZufvvXpsXPXCFu37A9r1bQZDSHMVw4vWeYj11gUncGnxyg7lTpq04X6nFr+54i9EFRxgTN6n3ZY7iSk5zLT/3e13yktjbSau7pRHOYD42myu2PeU123qh0ygKGoMqRV7PQKmmzWhjCxcw9ST//G67aDSLcw58ncGlrrXLrJrg7y2b8+Qs98ys+yrHnl2pFTuJ6HmOAAWjd5tOlHR0ozSbpXlTtI6F+6SWrHXaWz7kzupSfEtcNwejbUJfXM1GnOD50ofpRxcUZrkHy+moBiqQtO97KCf1Q2gC8bSsmXLSGlNEV63bh3r1q3jq6++4tJLL+X++71nUQgE/ZLU1Fa5E9kTIOROukA/kDvJGXpFYA1dMmkchQYdwa2j8z8DQGfxHqRu1oQQluOpG6eyW3xOSfmjMiyD5pC2GBRtXWXAU0fqnOMecifj8j52b6RQENdc7HV7V7mT0sjhPmOtHHInSYdWyx6dbqbNa1rqUVma3dLyvUllzDr+TzC1Bb9XhA1i3qGXfGbNAeis8pf2iKK1DCzbDrTJnSRWHyG+zrvXLbzxLEnVhz10IW0DkgOSO8ko38X4qs1ENHg/151hZvabXHRc/kyb9NFsHdr1oqauOM5HR9THBVBjCWDmTK7c+yTX7HqIrL3/5zWBoas45E7sGQGO5RzSaWOptLTUaSx98cUX3HDDDSxYsIDf/e537N4dmAaNQNCfcI0P8YU5pf/dvK40D8jAog6mPjgOSd+VUof9iJbW6YAAfqECNOjlFPNmrf/6Opb0TJ/yJI7YGYfB4i0oWlNf7bGsLLz7sSq+MGtCaAiKDkjupL1nqbMUps5gxYxX/LYpjsoiL873NHV7uZMTSZd0uN/Nw+/oUO7EUW/JH673sMNw0libvNZocvVsOc6bP7kTbzInDmJbg5tnnPy/DsfoiqvkiiuaDoqgKu2WgO8LB9GmvLb99oTciV7vjIPTttSzM/OWrvUTAA26KE4kXtxr/XeGThtLkZGRFBbKqZRr1qxxZsNJkoTN5jvFVSDodzQ1QWEh+nrvBSetCcmsH32vLHeiC8wt31dYYgawcvrLfDbpGaTQ7hfl61P+2zpldjKwGJzOcGrALA6nXeH0aHgrpghylWNZ7mQU4DtQe4iXL2O0WnZm/qhbQqjN2jA+mPZXVk1+1rOCtSShtjZ7lAnoqtyJ0m4BhcKjZMDknOWM2/Kq871ZE0JNiPfYnI2j7vKY4jkTN7XX5E5Ajps5mraIyAObvE6f6qwNpJe3iR8fTrsCm0rrllWmoGPDw2EseZMIac+J1PlUh6axfYj/GN7KAVmURQz1rWcoSV5/xCkkifBDmzscsy/8yZ0E1Z/7+myG5kqSWmOx6vQDqMt0rylWF5LInsE3nZ9yJ9deey0/+MEPyMzMpKqqissuk8vH79+/n8GDB/f4AAWCXmP/fnjnHfRGH3In+hDKIkQ5DL+4yp2k9p6orD9CGsopiBlPaeTwDuVOcgbI9Zdi8mQZko7SlgOdGnNDo+HUALny95Sc97w2qQlJAX0X5U5MRm7cfXcXtgSLOshjOkt+7z1GJLw6t0O5k83Df4ZNqXHG2zjQt9RQHp7ZgdyJbxzGgtruGXhcHxzH6vGPolP6zuJqHzR8KO1KDqVdGdC+1UV5TrmTwviJlMfFYAzuuKL88YxF7I0PLKd2/ej7fMudGIuYcOz1gPrpLJ9NegazyvNDjTu5BUjvuIOcnB4dz+HUK9rkTna2yp2cOtnF9LPeo9OepZdeeok777yTESNGsG7dOgwG2TI+e/Ysv/rVr3p8gAJBXzL47Gay8r/o9wUqVQ1G0sp3yynZfSV3kp7es31HB1ZXJr70IKmV+zosfqg+W8jcQy8x9eQ7HMu43G9bpd2K0m7lVMKMgIfryuCzm5l+4m2f689GDqc82XfWnFKyMSbvUwxNFdT7EK/1RnWU/x+sjTrvWUrRFdnMzH7T77YRDcWo7WZ2Zf7QbZqyIHYC6RWeIRgjitaSkzDLryr9mLzPmJX9T6/riqLHOPtpj9ruXfwXoNmXt6YTuBpgRkMipqAYlJL1eyF3YgqKkYPHuyp3kpvrtsrVe9djtE41Ku1WgsxG1o26l7cHP4A9KqaDDXuPTttuGo3GayD3vffe2yMDEgj6C0pjrdMzoK7JAOL8b9CH6M8cYWZ2a42eqichpWeK5PUJSUlyraUf/rDLXdTFDyEc9yk2RVMjCbXZSAoFecNkj7gvuZObt/waaJuCMWtCAvICmWOTwGolq+BLp2clrq7zv8SbtOGMKpADq7cO+4mH18YbCkliwt5/Ylbr0Vi9ZCnhW+5E31hJSuUBiqNHk514iVdpj0hTIVn5X3A2cgT7Mq5lRvZbSAolGWU7GFQmB7kfSrsSizqYCadXEms8zfU77veIZXIl2GL0GW9Vq5e3s6o8p8CDW2q56NgyipMmQ7vui6LGEGkq8vAKLtr3B5SSjfVZ99DsJyvMlYagaKoiB7Nwrfydt3zWMr/tDY3lDM3d0qpP51tQN6LqNHMPfUZCbbbPNg7KBowNaKyB8oPNrRmS0uugUGBRB6OxNmFT+8nVd8idbN/uMX0XbG5XWqELciexdacIayoDhRKwY/7FXfAWJNRmc/GRV6kypHAw6kfdKifSXboktHL69Gl+85vfMG/ePObNm8ddd93FmTNdqOIpEPRj+rt4br+ipQUauzBl1QNoW79sHfpkACVD3YNCqxNHOV8rJImY2lNe+8oZMNvtvcrm24PhjebEgdDS4qxdUxI1ymu2UHjj2YDr2vhLQLAr3b885AKG3cPqJ6DZgWNKSiHZZT1CP5IsvUVK5f5OZaFFmgoJbyhxVgYPBPv/t3fncVFV/R/AP7OzzcKOKAiuoOK+YaaWuJZp+ssyn9Ly0SytzDZtMW1Tn9JKs9UesydLW63UTNx3RVxB3EVUNlmHAYbZzu+PYS4MszDAMMPA9/168ZK599w73zmDzJdzzz1fngDSUsdKqgBAQtJSdLn5D/pc+9luO3FFiUOJUrlEgSud7wOTyZ22SrgZHg9XQwcBAJig4bfrO1zupFUENzoZnXsMI898YFzewU6BZHerc7L0zz//oEuXLjh+/Di6d++O7t2749ixY9xlOUI8VYXQw+8ic7cTtstCNCYvtfEv25olQkxJSkZwH+R0ML+cFp57GoBluZMCGxOYxdpSMB7fIjmpzt6+mnqk/4mOZ3+xud9esdeyWVWj+DUv0VUvd/Jr23/jl/7LubWk6ut6/FRs6/26WbkT00iSNTUnzdsazQIAabmNP0jEYq4Ar71yKdbUXDdKJ5Dgj37vVsVTrZ7cqWjjitC2RhgBIDLL+tpbAHAi2rhAs7IOl0rtMd1QYEEorHeydDrqwQZEVImxqst21S7fFQR1QmBJet3PJxJxE+1ltn4GqglQZWBwzt/gqdxTfxKox2W4BQsW4IUXXsCyZcsstr/66qtcYV1CPImp3EltE4SJC5jKnfzvf8B779XrFDyDHsc7PAqJthRZ/l3Qucb+wBqFdP/p+SoAZjexKOidgF+vJ1iUOynybQ1F6W3wmAE8jfloUfcbfzm0NAVgXu6k+iWkAVeqCtXuipuHWEXV2kQ3A3sgJWIMutz6B/4q84URS4VSCMQyi2QjV94Rye0ewphT71vE0Dr/LFrnmy8urAqIRGF+JBTVkp5OmdZrw9VW7uTWgEng/7WZK6libURqax9juRPTCs8CgwaJPV5Cm/zTiL2106K9iancSds7JxyemK/nGZMQW4mutDwXfKXtGe53ZO0hlHaDKLDmT1jdnYqeiNsBcWbbRLpyCLRqAPW/GzdX3tHqxH4AAGMIL6wsPVNbuZOjVTX//un5CvgGPWQxbTEg2fayC/Ul3L4FNcud9M4/AF75OAD2VwdvLHUeWUpLS8OMGTMstj/55JM4f75+dz0Q4m7Ds35Hm/wz7g6DAICscumDBixFEnNwLYac/xIifTn0fBGEGvsfnjxmQIAqA/4qOxXmGYO8NNOs3ImBL8TernNwM6gneIxBmmY+2dXRREnv5YubQT1xI7ivxb7qizjWXEsqIu80ZOU5dRo9yPTvitDiiw63dxatlxSlgZEWteeq04h8uQKrJgaeELnyjjbX29H5yqHyCgIPBkg0JWYT/ZPbT8b+2KdsPl+FWIotfRdjW+83bbbxVhfa3JcvjcK2iEdxKmqCzTaOutB6uMX8LqG+AgMPrQDKyrgSNVp53SY5l3iHWNTgq87081yXcid5svbIVXQylsOpJiLvFHhFtvvLhF9UwCXDxvldNfanN71pPXVOloKDg3H69GmL7adPn0ZISNOdAEuIhfCqX0zhZekIVN1wYzCEM7GySle47YnBjup97VdMOvoyOh79n9l206Rh06W6iPzTuOvCf9HBxuWlS+HDAAD3J5uX3CjybY3OmXvqVe4E1dY10nv7YfTpZWh7x/JSZvXaZvclvw3xvqrpDvKyLMTd2GJRJLVUEoDhWZtrLXeiFXrZLXey68FPochKQ9eMvxtc7sSvMAN9/njT5orhgPFyZ4Aqw2LhxSDlNQw/94nVY5Qx/ZER1BtRuUkWd86VeAWjQ/ZB9L2y0eqx0TlHMTjta4s7upjYdvHc6trnHMaA3J0Or2tlT6vC8wiqTCC0Qm+zfuKpyyEwaKEXiFEW3dXWKaxqk3+GSyDtlTspau34eQV6DSRaVeWoVw0O/JHDVxYBMN6ZlydrZ9mgHpPEG1udk6WZM2di1qxZWL58OQ4cOIADBw5g2bJleOqppzBz5szGiJGQxhEVZSx3EmkseUHlTuohKMjt5U6udBztWMNq81JMd7ldC4kHAHS9uR0AINGqLI+DsSyH9Oppi+0Cgxaxt+o+VzNfGoVy36oRAnFhjtmIlT3C82fxw+DP8OPgNdy2rre2m7XRCSRoXXa95qEAzMud3Arsab/ciV6DiJOb0TN9c4Nvm/cpyYG3MtdstM3aooz3pKw2K3eSL43CqNPLLeakVVe93Ikp8clWxEAj9EFk3km0LrRevNe/9Cba3jlhUdtN1yrCoXIn7XOOYEDebqckS8NS1+CeVON7Wu4bhH1d7Ce6jnK0HI8yzMHV6OPjcd/Jd/B/R15E9xP/tSh83BBcuZN2TW/NxjonS2+++SYWLVqE1atXY+jQoRg6dCg+/fRTLF68GG++aXsok5Cmiq/X1tpG07r2X5zuVBFqXBBSI/L1/HIndSznoPIzTnyttdxJdCeb5U5Mf3mLKz90dQLLkQVxseUKx9ny+s1VsTehuDqNyNdqaQzGF5glOY4mWrbcajMQvwz80G6bzICu3NpH1tS8hGRaANSevV2fqbXcieluLXuqJ2DeWuMoGw8GtMs9atGWoarvG1ruJERpvKtyyIWva43RVgzVibXWl3xoiKCSqktadbkJwSaplEtcJRVKHHZSDTtrysQKXA2r/f13hTonSzweDy+88AJu3bqF4uJiFBcX49atW5g5cyYOHz5c+wkIaSoqKoDCQogqrI8m6EJbY1/XZ7Cz+3wwbx8XB1c3mpA22DDkS/wcv9Lzy518V1kh/kLtt1bX1fWQAUhrMwLlEuPlCFsjDpvuWmVW7sRUaLcmq7ehi8VIbvcQkts9VO841WIZ935aTFZmzDiZvMZt1vUpdxKVewx8gxZMILQYIeh35Qd0P1JVrLdCJMUdmfUaifu7zLaYe3IlbHCjljsp9QpAWuQoKM7ut1ruxEurQoesqtIgKZHGtbWqL6jp7HInV1oPRalXAJLbT7bb7k54D+TJoqHn1+12fYFeA/lp65PrHeGrNtY3vNB6uFlhaQCQlNU+18jZqpc7KRfLoWxvPkpd5NcGRztN88xyJ9VJpVUT8S5fvoy7776b6sMRz5GcDKxfD3keQ5GV3czXz+5f0gSAUllV7qRNG7eE4FOej4yg3shRdKr1bsYLbYwLBd5bWe7E3m3tQNVdaXVaR0gk4p7H1no7xT7h4HsrHCx3Yn75i6dS4tGk+l2i0fNFEBiqRlJ5jNksd8JjDAF3LtZa7uRw5ydQLpZbrBsk0aqQL42qd7kTUzLIZ5Z9X+wbji193oJEAPC11icm13xvz0RNwBkHJ2ILb9/gyp1khvTEncB7UeTbutbjUjpMwPFwx57jn54L0Ovar1ZXKJcV30SflNVWjmq4rb3ftHr5MzRtLwAH6hk6eU3Fc5H342ZgTwDA60mzjeVOrl2p5yqQjaeJhUNI0xKdcxSxt3ZAUGi/hpi78ctLEVaYhiDltTpfxmoQTeWijRIJ0M7KRM2GkDu2ynJY5klE5p2EoJY7z4TZtzAsdQ36XfkRF6Icm+fkSMV7a6JzjqL/5Q02998O6IbsiH429/MNOnTN+Bu+6nyUShxfJ6nQ3/57oPIOtro9IP8y4i99Z/dYWVk2+EyPpA5TzD5sr4cORLucIxbtu97ajtSI0XYLCsdlbMNdF/9rdV92ZV3G7hlbLPbZWxrAWt2zuuLpqhLKQmkk8qTR0PHFTi93Yi0RbGxFfm3MRtccUn3C9RXzBV2t3ZRQZzye+ahdZRklHjNAqFNjZ7d5+L79PBj8G7ZmWEM0vSnnhDQRfJWSq+8lzG8NwH11iWrje+UMhp+rLHdyZzHQuhmUO5lmv3K7PSVB0ZDWLHdSVorW+WehE0iQ0dm4HpytuUNT9xtvNzctVulwuZOAMECvR7eb2yAry0GBX6Tx7q46Kpco0DPdOLH6YMy/HSqZwmMMPc58V69yJ76qHETlHsftwO64HHY3hqWusWgTWJKOHul/IMu/C05FTzSuuAwg8k4yVxsuNWI0KkR+6H3tF4QWXcLDh56zW+7Et6KAW+28pny/tgCM70HNRTq9K4ow6OI6ZLXqbVHuJCOoN+RlWRYJ1cgzH4Bv0GFv1zm1zm8zqRD5oUDRDvclvgKg9nInPuoCRGccM9Zeg+05W/L8axiaut2h5UruhNTt7rfamEr5wLAa4PPAeHzwmKHe5U4s3r96lCQJLEmHX/mdqnInM54G/me8Q9BU7uR0wL/cepccjSwRYoMgt+F3uLQYFRWA2sptxC4g1hjnnEVXm8x7q4v5Bbmi0KqJ2EJ9BYILL1k919VQ85W+HV3c0EQd0RFQq7kJ1xnBfayWO/FT5zm8BlP1y2a18S6r22rX1lSIak8LC32rLrnenfYVRLpyAMbLfIznmo+V6Jyj9tfFqiG4+AoCS9LNyuLURiP0gU+5432acPw99EzfbHdUETBOjHYkUSqXKHCpywQwmbzBK7GbmIpEAwB4PG79KqeVO6m2aKoturA23JIVbe+cwOhTS42FnE3z8EQNj8XZHE7T/vzT+gRHk+vXrd+mSoinqOtkS1LD8ePAkNrvgHI2L3URAFisYK0R+UKsLcXtwO5Qdh6GbqhaiDEsr3LV4mrlTsS6MuRJrd/16MhdSga+AI7+Td372q8wiGwvzmgvSSt/ci6Q9CkA49yd6qNFkgol9DoGBuDPiMfh064nRqSuhp+6/peRb/R7CAcy2nIrgbcqPG+39IZp8UQT++VObCwHIBJxk7ZtjTwBsLr2U8271xiPh7/6vIUpB+cCgNkyAaejJiAqN8nm+QEgKtP2jUunoiagY8r3KPEyXt7kN7C2WY7Cxu37QiHy/drWufQLAJyNHIf+V35oUFy2FAa2R8CtA7U3rEksRpFPOIKVV6Eosz9vEDCWOxmg2wle6SQAtSdjjcHhZGnChAm1tuE5eDssIU2NqdzJve4OhFSVO9m4EVi8uN6nOdZhKrw1xbgdEIeaH0HBheYrWO/s/gL4zIBSL9ulFPJ7JeC3a8PxwIlFAKqSD1PCwmMGs7kugHHdH0dvB69e7qT6Zad+V6sWVNzX9RnEBlUt/nvbvxsuhN+LuIyt8KkoNEseisSBMHgHWyRKxb7hON7hUYw4Y7lUgLVyJ8qQDsgtjkJ0tQ/qmNu7rL4Ge+VOikI6I7PvA8DWrdykb2uja3/3eg09vb25CeMiXTl2d3sOEfmn7Y4KXQ8ZgMOdn0BE/mmzZFPPF8Ng4w8hPV+MUq9Aq8szAMZkjldi+07YHFlHiPw6QRgQY7ONo861rZrobMJjevAMesDhNNxStiIGjMezvoo3YwgtNo6y8uzdxKBSGS/BVR6zK24e+EwPn5gOGHDSdgma+hLu+gc1y50MyNsNXtlouCtZcni81GAw1PpFd8IRT3V3zlaEF1i/jZy4mFflLexldbsEVl3Mga8x+MLX4IFBLZLWupaWji+Bd0WRWZFVCzwefDRF8NEUmW3eH/tUVbmTVPN1fRxNlAxCEW4HdsftwO4W+wQGDfe90tu8SkJY8UWIdWU42vExh54HAK4H90dgieuvBGhFPlCGdLB7d1yFyA+lEvOEVc8XISugK9LaWK87qveRckmuSF9uliidiRqPw52fsPl8arEMm/u/jz/7vWOzjU95gc19ebJ2+DNyOk40YJkIk5SIMSj0My/k7KUpwaD9y4DycoQXGkciddK6JQslPqHQ2pn0brqUaXU1bhuy/WORGdANepH5chMReafAKy6q9Xh+cSFX7kRt5c48/mXXl+OpDc1ZIi1XaFWl8CjVJQSXNL16RC3SI48Y/23AUgTGdYgY+lz9CQ8ffh6dD5nfcWUqd2K6ZNM2LxlDz3+OTlnW17AxLYw34fhrZqMhBdK2iMw7Wb9yJ9UWJtRJA3DvuU8QXuMSFgAoq13yGndiMUSHqtZ2Cii5gV7Xf4O3ptjsGLVIiiE5W2std8J4fLsrMO99YCVkuVfQ+fbuBpc78SorQM9t79u93C3RqoxrRNUYBVGobnE3W9RUHDsQN4L6Ijr3GLplmK/CX+AXgTb5Z9CrcsXymtrmJmHgpfWIyDO/GYAJHbskH3UnCb3z9kPawEVBASBYeQUBJcaSS7oa7wmvvAxCfQX0AjFK21sm1Pa0KkjlEkhrSwaYFLdyfHSMZ9CDb9BaL76rq30uHr/YeGlV5RWEOzIrq3Xzm15q0vQiqsWaNWsQFRUFLy8vDBgwAMePH7fb/ueff0ZMTAy8vLwQFxeHbdu2me1njGHRokVo1aoVvL29kZCQgMuXa7/zhDQD7dsDX36JnEhj8VIqd1IPgYFAD/euRXW93fA6H2NKki62GgYA6Jy5G4DtkaAS71D4XbdMZAQGLXqk/1Hn5y/wi0S5X9Vt/OLCHASoMuwWPDURnT2JTYM+wc/xK7ltHbPN541UiPwQpbI+ib16uZP0kP42L1Ed7zgVANA26Wf0vbqpwbfNSwtvwC//htmEdWsrpY84uwIoKeEeF/q1wX0n3zEui2GDKRnocmsHIvOSAQB5smjoBF5ol3MEkfmnrB4XqEpH++zDCCpJN9uua93WoXInnbL2Y3DudviX3a61bW0Szn6Ee1KNc9HKfIOxp9uzDT4nAHTMrrp0aetyIwAUh8c6dsL+/TH21HuYcnAuepxY65xVwStx5U46OFh6xYU8KlnatGkT5s+fj7feegsnT55Ejx49MGrUKOTmWp8kePjwYUyZMgUzZszAqVOnMGHCBEyYMAEpKVWXW/7zn/9g1apV+OKLL3Ds2DH4+vpi1KhRULvpzh7iegK9ptY2mvCoxg+kASqCq0ZhmJcLV7vl8dz+V2Cx3FjCxJFyJ4V+1kerTGUvJDrrq7kDgKTQ8hJdlsLBD5gaHP2AYTw+DFbuLtMJvSpvTzeyl0g44nbr/tjc/z27bbL9Y7m1j6ypuUSAI2UqdsU9X2u5k8thtd80UD0B862cEK7nixCRZ5kkmZU7qawF6OpyJ7bULIjsDKbLXQCcc6eiQgFFqTE59CovwoHYpxp+ThvKxXLcCO7baOevC49aZ2nlypWYOXMmnnjCeA36iy++wNatW/Hf//4XCxYssGj/ySefYPTo0Xj55ZcBAO+88w4SExPx6aef4osvvgBjDB9//DHeeOMNjB8/HgDw3XffITQ0FJs3b8YjpssBblJUBJRna1BwOR+iardS8iUi6HlC8NTlNo9lMnnVmhTl5eCV257/waSyqls11WrwymzPszBrW1EBXqntDxfm62dcrLCubTUa8FQlVtvxfb2hl1ROuNTpwFNWu/wgEHAVr5lYAvhVDjkzBl6hlXkHOh3A40FckA3TKy64XDWJtdCrFQ7G/Bs6gQRj8tUouGxMoCsyAd/KXFp5HRCqHXgu0+sUiQGpFEqlsa1vRQHKbwEFVvIbU1sTXoHtO2GKeQr8NMRYmmJ+cRHEl220FQjA5IqqcyqLLYbN+UI+mIHB4OVTNX+osq9V2VWvvfwWUCAHJLcLIawA1MWALh+ASmW8ZFBjCqNWq4X6djny7xggkhjXsxRrSyHSq1FQbTDX54tvjd8kp6LU9DLs9KugqOq15ucDUKvBKjRm1beYugKlNwtwOyAOedJ2CNDlwhuZaJd7FAWXh3HtRDo1fNX5xvV0eDzck7Ia4QUp6Hn9d+h6jKn2Woz/1pzorClQoUApxJmo8eAxg90Jz9pq06i0Na5cGPgC/Dj4MwDAQ4dfMNtXUVIBb36RxeUsxuPhZLfH0PnYd5CXZcH2/7YqEXmnwO/4GAxCsUVF+t7XfoGWlwLTvN9ysRxZ/l0sVuoGjKt4x1SOzplcajUMPhVFaFV4HvGX1sOgAPROvAdIzxfhYkQCeqYegsRauRNNCWKKqt6flMgx6Jbxt3m5EzuLQppWbdcLxBDBsXIn6a3iEZm+HymRY+2ssgTktuqBgBp3MtZUs5wNYPzDTnr2IDB0sN04bDHdWXih9XAM5vNRfXV4sVoJOLimvLMYy50YR2y1Qi+URHcHcqv6pNAvAgdjZ+JhB5ZZaGwekyxpNBokJydj4cKF3DY+n4+EhAQcOWK5eiwAHDlyBPPnzzfbNmrUKGzevBmAcbmD7OxsJCQkcPvlcjkGDBiAI0eO2EyWKioqUFFRtcS+Umn8a0Cr1UKrdXxNlNqsXAl0/uUY0j7aYXGnYc2yBTVt67EABVLjom5db+5Grxu2LxXsiJuPXHlHAEDnzIPod+0nm213d52LTH/jXQrts48h/sr3Ntvuj5mJjKDeAICoO6cw2MZKvQBwuNM0XAsZCABonZ+Ke9I+t9rOwBPgn+4vIV8aBUVpJu4/9a7VdldDB+FI5aRXoU6NR44utNoOMF6KNf177oGqdj8OWgV9UG94aZQoe+FVmC7CCACMr/w+8zhwoA7PdSOoDw7E/BuA8Zfh+OMLoT4OWF7gAW4FxGFvl2e4x48eehN8Zn0+QJ68Mwxx8wAAl57+ENk2bslWSQKxuV9Vn409tQoBpdbXqjkZ9SDOtzGuVxSkvI7RZz8AUPXaDTXi3lEWgtw/9bjr4kZE37G8PM4Yg19pKZYcHQ2dxPirZ8D139Ax+wDOPWA1BHy/wPiBxWMGTD1kvV+7A7it6IIs/1j8vEBf+TN8znyGzfkUlDy3EMWdpuFa5DjE3t6JgDtpkGiKzd5zf9UNjD++0Pje80UoF/qAVZ5JvbnqEr6tig9lP/6OZdfugqbNKAh1asTZqClX7BUMVaEv5JXnvnHDfD/PoIOh8sNapCs1ey3nksrxIIyLJJq9RgbcUknRCczsZ7p61mjgCcxWjRbo1RBoVNDrpWAGPfdauX2XTsP0k2Qw6FEsCUS2rANClVXZ7bEOj6LQOxQ8vYY7/lTUBECvQYFPOMIqJyYXFVn2g5YnBI/HM3teANDptGDMgHzfNtDwRRb7c2UdsKP7i5DwAZSWmO1nzAAGBllZJreVMQPOtBmDs61HGUfrKvvWwMAdW/13N8u4CX/VDTAAmUFdkS+PR6FfBHecVmsw63/GGLRaLVK6TMLB8Enc+bRawGDgV74mBq3WeITewMefvd5Ajxt/Wlz+Nxj08Cm8jf6pn4LBeHOVVqvl4jRoNTY/Z/h8vsUC/lqeCJJq/fNP95dQLpZDq9XC2PPGfcHnEqHVTrF6Xmi14BsMgFQKw5Ur3DFMwIeaLzHrf9PnoE7Hg8HA4/qresg6XdXrOdd6BG4HxMHAE+Dl829AH2AAy7rN9TUAXA3qi3DlDqd/xpridYTHJEt5eXnQ6/UIrTYpFwBCQ0NxwUbBzezsbKvts7Ozuf2mbbbaWLN06VIsWbLEYvuOHTvg4+O8gqs3bnRCJ4EAJeqqxIxv0HNzBwx8IWwUr0ZObibuVA7OhBbkQVlu+7Jidm4WskuNQ82B+bl22+bkZiGz3DiKIi/Msds29042MjXGTwGf4lra5uUiU2dsK1JmW23Lr5xMePehN/FZ93ehVledU1h9HgRfhPyiQmRmVp5PX2HzuYUGLRgzdmJpaSkMgqr/EpmZN1BhkMBHV2JxvOmPPh4fDj8XABQUF3Ft9VqguFQNWyPjhcXFXFsAKC4vh8DGX8KF/GJkZBiTniJVKaCxHoNSV2Z2ziKVCsJql5x5hmoFWm+dRSbfuJijviyTe13VX7vpcZq8F04Ue0GgysCdgmIElKrN2nAEQuTk3EKF0Ac6HR/R+UUIqdEHpvfyujSGi5XHDDb7lRkAgfoCTor7ozDzBvczzK82+dT0vmbl3EGG+iZu8zuis0rF7TO1ZTBe9srIuAk9X4QCQV88qdpl0Y7PYzjpfxfal5yHVFtk9jxZWRkohR9E+gqoVFXjOwI+g97AQ7EoAH8J+kHN94WP/ijCyjPA5zEYWNV/5rPBg7j385AoDj0Kq/4grNnW5KKsB06U+6F/tecsLa0aJc71ao0U/34YnPM3xIYKGPhC3PaOQqYyF+0Up3H+fDgy9L4IKM9BBd8bEkM5129XfWNx4+Zt3EAQvDQiZPGiEFF6Fan+fXHUEImIGxfACjOQLxZBHRSIyPO/4mqrB7BZ3g97wtph4o3/Qq4zjgyaYs/1ao0z+QwAH901XlBojEscqEJaofDUAZR0kCL9gg8OlQYiQidDsLpqxOGArCMyM28gJqYAV0V58NIxiNXG1/qPoi+GFG4DT+4FxufBOy8PJ72ikH6rapHZuLg88HgMB/VRkJYfhbpDG7P5rDqVDkwoAU+vR0l/bxxIaofyYiEk6nT06JGLbduMKaRyYDfI9p3Czf5dsW3bNgQF+ePixdaIi7uDbdtyoNfzUF7eARUVQly7dgV5ecafbY0mCFlZraAr90crDYOXphQVfG+cDjS+752HXUOOxBtexUUoDvNDcdoRaHylEJeUIIuXjVs15t6a+PkpkJHRlnvs5aVDartYdE3aDgC43GsYzlfw0TooC9u3G+/cVIWFwfdmJkrDDCi0cV4whnaMwSs9Hdf37UNu+yhI066gJMYfEnk+Dl7sjp4Fh6EKbYWCi0fBv8rHnTteyM9vB39/NQ4cuGY2KKcv00MvkkBfbkB+gBbZhcbLepciFOClX0Rm/ygYrp9HVpYf9Hoe1MLOuD/kLJJvnMLprLPWY6ynMgfvuuUxVrdZe3q9Hh999BF++uknZGRkQKMxn+9RUGD7EkRDZGZmonXr1jh8+DDi4+O57a+88gr27duHY8csh2HFYjHWr1+PKVOqsuXPPvsMS5YsQU5ODg4fPoy77roLmZmZaNWq6o6TyZMng8fjYdOmTVZjsTayFBERgby8PMhkzqv4rtVqkZiYiBEjRnCX4c58vA+l//0JN4L6YPSvT8LfPUtOuMXyf1/F3cdXQukdgtHH3jLbx3+mcgQmKgqGV16p03mt9XNLdXHjKeS/vxYAEPHpS4gYUvsk11df5XPzcT/4wICXXzZmPuPGMYwZY/4XJ/Wza1Bfuwb1s2s0Zj8rlUoEBQWhuLjY7ud3nUeWlixZgrVr1+LFF1/EG2+8gddffx3p6enYvHkzFi1a1KCg7QkKCoJAIEBOjvktmjk5OQgLC7N6TFhYmN32pn9zcnLMkqWcnBz07NnTZiwSiQQSieVdHCKRqFH+w1Q/b1lsfxzt5GOs/8TnQyRy3p0ITR2fLwAPPPB4fMt+Nk0yFgggqOd70FjvnyfRdu4FxheBb9A53B98flX3i0QC7nuh0HrVAupn16G+dg3qZ9dojH529Hx1nhq/YcMGfP3113jxxRchFAoxZcoUrF27FosWLcLRo0drP0E9icVi9OnTB7t2VU3YMxgM2LVrl9lIU3Xx8fFm7QEgMTGRax8dHY2wsDCzNkqlEseOHbN5TnfT+8ow4Mr3GHr+c/BKnH/nBGnhRCKUiRXujoIQQpqUOidL2dnZiIuLAwD4+fmhuNh4N9L999+PrVu3Oje6GubPn4+vv/4a69evR1paGp5++mmUlpZyd8c9/vjjZhPAn3/+eWzfvh0rVqzAhQsXsHjxYpw4cQJz5xprBPF4PMybNw/vvvsu/vzzT5w7dw6PP/44wsPDHSrvQlwrNt04EVJmbQG4YcOMd6QNHOjaoAghhDR7db4M16ZNG2RlZSEyMhLt27fHjh070Lt3byQlJVm9NOVMDz/8MO7cuYNFixYhOzsbPXv2xPbt27kJ2hkZGeBXW/Nl0KBB+OGHH/DGG2/gtddeQ8eOHbF582Z069aNa/PKK6+gtLQUs2bNQlFREQYPHozt27fDy3TLdBMjycmAzl4Nn2bMX5lue+eUKcYv0iCinFsNKrpKCCHNUZ2TpQcffBC7du3CgAED8Oyzz+Jf//oXvvnmG2RkZOCFF16o/QQNNHfuXG5kqKa9e/dabHvooYfw0EO26/bweDy8/fbbePvtt50VYqPyzrwK6ysQEdJwwsI73Pf6gGA7LQkhpOWoc7K0bNky7vuHH34Ybdu2xeHDh9GxY0eMGzfOqcERUp3d1WeTkoyFV3v0ABQKl8XUXN2RtUeEr+06UoQQ0pLUec7S/v37oau24u/AgQMxf/58jBkzBvv377dzJCENky9vBwA41vFfljvXrgV++AH44gsXR0UIIaS5q3OydM8991hdS6m4uBj33HOPU4IihLhXsPKq3RI5hBDSktQ5WWKMWZTeAID8/Hz4+rq2rkxLx8SNO6GetGyCPCt3HRJCSAvk8JyliRMnAjBOiJ4+fbrZnW96vR5nz57FoEG1V5kmznEjuC/inFhaxRPIVcYl8Qdc/h7A3e4NhhBCSIvhcLIklxsrUjPGIJVK4e1dVSZdLBZj4MCBmDlzpvMjJKTSiS7TcNfRFSjxDnF3KIQQQloQh5OldevWAQCioqLw0ksv0SU3N1F16ImjncRQi6Qwlpeu85VUj8UqqwYzK5eBiXOoo2PdHQIhhDQ5dV464K233qq9EWk0Oqk/+l/ZAL5BD55yGRDYgirpkkbHJF5QeQXRwpSEEFKNQ8lSr169rE7qtubkyZMNCogQWzplJAKwUe5kwADg2DGgd28XR0UIIaS5cyhZojppTYf4zm3oW2i5k6CiK7Z3Pvmk8Ys0iPBOJo0qEUJIDQ4lS3TprenwuXWJyp2QRiPKrxq10/sHuTESQghpOuo1O7ioqAhr167FwoULuQUqT548idu3bzs1OEIclpICJCcDpaXujqRZuCNrD+YndXcYhBDSJNR5gvfZs2eRkJAAuVyO9PR0zJw5EwEBAfjtt9+QkZGB7777rjHiJAR5ig4IKTuDYx3/hSE1d65ebfw3OhpYsMDVoRFCCGnG6jyyNH/+fEyfPh2XL1+Gl5cXt33s2LFUG46QZiJYeRU8dbm7wyCEkCahzslSUlISnnrqKYvtrVu3RnZ2tlOCIo6hciekMQnu0P9nQggB6pEsSSQSKJVKi+2XLl1CcHCwU4IitbsR3BdoYeVOZKVZAIB+Vze6ORJCCCEtSZ2TpQceeABvv/02tFotAGOtuIyMDLz66quYNGmS0wMkxORUp0cAAOViuZsjIYQQ0pLUOVlasWIFVCoVQkJCUF5ejqFDh6JDhw6QSqV47733GiNGUk1puzgc7fQ4roYOqix30nLoBWLjv/w635dAHKRu29ndIRBCSJNT508duVyOxMREHDx4EGfPnoVKpULv3r2RkJDQGPGRGrTyIPS/sojKnZBGwbx9qNwJIYTUUO8/0QcPHozBgwc7MxZC7Opway8AG+VOuncHzp4F4uJcGxQhhJBmr07JksFgwLfffovffvsN6enp4PF4iI6Oxv/93//hsccec7h+HKk/cX5Wiy13ElKQZnvnnDmuC6QZE+Zl06gSIYTU4PCcJcYYHnjgAfz73//G7du3ERcXh65du+LGjRuYPn06HnzwwcaMk1Tyybjg7hBIMybKy+K+18sD3BgJIYQ0HQ6PLH377bfYv38/du3ahXvuucds3+7duzFhwgR89913ePzxx50eJCG1unIF0OuBqChAQutPNdQdWXtEyOiuQ0IIAeowsvTjjz/itddes0iUAODee+/FggULsGHDBqcGR0h1+fL2AICkDlMsd37wAbByJfDxx64NihBCSLPncLJ09uxZjB492ub+MWPG4MyZM04JihBrWOWcOANPYKcRc1E0zVtQyTXwKtTuDoMQQpoEh5OlgoIChIaG2twfGhqKwsJCpwRFHMNEYneHQJopHmMQ5GbV3pAQQloAh5MlvV4PodD2FCeBQACdTueUoEjtbgT3BXx93R2GS0lLjUsG9L7+q5sjIYQQ0pI4PMGbMYbp06dDYmPybEVFhdOCIsSacx0nov+Jz6AT0ARuQgghruNwsjRt2rRa29CdcI2vtG0XHO30OEolAZXzc1rO2lYaobFwsJaSpUZT0baTu0MghJAmx+Fkad26dY0ZB3GQNiAU/a8sMZY7KV4GBFC5E+I8Bm9fKndCCCE11LmQLiHuEp15EICNciedKkdEYmNdGBEhhJCWgMq3exhRYS4MLbTcSau8c7Z3vvii6wJpxoQFuTSqRAghNdDIkofxTU91dwikGRPl3ua+N8jpEi8hhACULJHmIiMDSE8HtFp3R9Is3JG1h0GmcHcYhBDSJNBlOOIxCmTRCCpLwcl2kzCk5s733jP+26kTXZIjhBDiVDSyRDyGgW8sc6IVeNtuRCNLTuFfegugtdMIIQQAJUsejcqdkMYi1FdAmJvp7jAIIaRJ8JhkqaCgAFOnToVMJoNCocCMGTOgUqnsHqNWqzFnzhwEBgbCz88PkyZNQk5O1W3nZ86cwZQpUxAREQFvb2/Exsbik08+aeyX4hQtstxJWS4AoMeNP90cCSGEkJbEY5KlqVOnIjU1FYmJidiyZQv279+PWbNm2T3mhRdewF9//YWff/4Z+/btQ2ZmJiZOnMjtT05ORkhICL7//nukpqbi9ddfx8KFC/Hpp5829ssh9ZAafb+7QyCEENICecQE77S0NGzfvh1JSUno27cvAGD16tUYO3YsPvzwQ4SHh1scU1xcjG+++QY//PAD7r33XgDGVchjY2Nx9OhRDBw4EE8++aTZMe3atcORI0fw22+/Ye7cuY3/wuqhLDIGRzs9DpVXkLtDcTm1RA4A0AjtzFkiDVLRpr27QyCEkCbHI5KlI0eOQKFQcIkSACQkJIDP5+PYsWN48MEHLY5JTk6GVqtFQkICty0mJgaRkZE4cuQIBg4caPW5iouLERAQYDeeiooKs8LBSqUSAKDVaqF14gRj07mqn7NMHox+l98Gn+mhu/MutH4tZy0cg0EPBgbGDBb9zDcYjN/o9TDU8T2w1s8tVYXEGyWSAPhV5Dv882ww8GHqfq3WAIPBOGCt0zFotYxrR/3sOtTXrkH97BqN2c+OntMjkqXs7GyEhISYbRMKhQgICEB2drbNY8RiMRQKhdn20NBQm8ccPnwYmzZtwtatW+3Gs3TpUixZssRi+44dO+Dj42P32PpITEzkvj93Lgg9SlTgQ4+9e/dAnObl9OdrqnzOXYFKpQJfpcK2bdvM9nUqK4N3Xh7u+Psjs8Y+R1Xv55bq2jU5wpRKQKvCsWNHcU6V5sAxXVFebvxV8s8/KcjI6AYASErKAmO5Fu2pn12H+to1qJ9dozH6uayszKF2bk2WFixYgOXLl9ttk5ZW+y9rZ0hJScH48ePx1ltvYeTIkXbbLly4EPPnz+ceK5VKREREYOTIkZDJZE6LSavVIjExESNGjIBIJAIAyHUF4PkZL0P1H3YPFNEtZ2Tp0JKXwfPzAwAMGjvWfGfl49YAetbxvNb6uaU6tycPJRItIPFD7ICBiBgSXesx+/bxUVJi/H7UqNbYudM4stSvXxuMGWM+skT97BrU165B/ewajdnPpitDtXFrsvTiiy9i+vTpdtu0a9cOYWFhyM01/wtVp9OhoKAAYWFhVo8LCwuDRqNBUVGR2ehSTk6OxTHnz5/H8OHDMWvWLLzxxhu1xi2RSCCRSCy2i0SiRvkPU/288hvnUQJeoz5fk8Xjg1fttTtbi+tPK3zys6Gq7GNBYLBD/cHnG78AQCQScN8LhYC1w6mfXYf62jWon12jMfrZ0fO5NVkKDg5GcHBwre3i4+NRVFSE5ORk9OnTBwCwe/duGAwGDBgwwOoxffr0gUgkwq5duzBp0iQAwMWLF5GRkYH4+HiuXWpqKu69915MmzYN75lWgSaeJysLYAwIDrb+CU3q5I6sPSKoNhwhhADwkKUDYmNjMXr0aMycORPHjx/HoUOHMHfuXDzyyCPcnXC3b99GTEwMjh8/DgCQy+WYMWMG5s+fjz179iA5ORlPPPEE4uPjucndKSkpuOeeezBy5EjMnz8f2dnZyM7Oxp07d9z2WolthbIoAMDZtuMsdy5eDCxZAqxZ49KYCCGENH8eMcEbADZs2IC5c+di+PDh4PP5mDRpElatWsXt12q1uHjxotlkrY8++ohrW1FRgVGjRuGzzz7j9v/yyy+4c+cOvv/+e3z//ffc9rZt2yI9Pd0lr4s4Ts83/riWi+W2G6nVLoqmeZOqcytLx9AoHSGEeEyyFBAQgB9++MHm/qioKDDGzLZ5eXlhzZo1WGNjtGHx4sVYvHixM8N0KSakDzLSOLw0JRBm3wI61T7BmxBCmjuPuAxHLN0I7gtU3hnWUviV5wEAut7c7uZICCGEtCSULBGPcbGtcUkHsb7czZEQQghpSTzmMhwxKm/TEUkdHkGJV0jtjZuZUq9AAIBa1LJG1FxJ05ouuxFCSE00suRhKoLboGf6Zgw9/zl4xUXuDoc0M3qpokXWHSSEEHsoWfJAAoMWAoPWuK5QC9ImNxkAICvLsdwZVPkBHxnpwogIIYS0BHQZzsMIVUVgBr27w3CLyOzjtnfSgqJOIVAWwk+d5+4wCCGkSaGRJQ/jd/mUu0MgzZg4M5373uDnvDqHhBDiyShZIs1Dfj6QlwfodO6OpFm4I2sPg3+gu8MghJAmgS7DEY9RJI1EQFkaUiNGY0jNna+9Zvw3Lg6YO9fVoRFCCGnGaGSJeAydQAwA9u/WUqlcFE3z5q0pplE6QgipRMmSB2MCGhgkjcNPnQdh1k13h0EIIU0CJUse6kZwX0AqdXcYLuVbng8AiLm9y82REEIIaUkoWSIe40qbYQAAH02RW+MghBDSstB1HA9T3qodTkVPhNInzN2huFyJr/E1l4vplvbGomnV1t0hEEJIk0MjSx6mIqwtYm7vwsBL31G5E+J0enkAlTshhJAaKFnyQBKdChKtqsWVOwnPOwvARrkTX9/KRuEujKh5EjC6C44QQqqjy3AeRlCqBFpouZOozEO2d65c6bpAmjFBSRGU3iF1OkYiAUpKGikgQghpAmhkycNILyW7OwTSjLVtCwQLCiEJ9ENIT8dG6caNA3x8gLFjGzk4QghxExpZIs2DaWjD1xfg098A9SVvq8Cwg+/W6ZiBA41fAFBa2ghBEUKIm9GnCvEYRdIIAMCF1sMtd770kvHrq69cHBUhhJDmjpIl4jF0AgkAoNinle1GRUWuCYYQQkiLQcmSB2N8gbtDIIQQQpo9SpY81I3gvoCsZS3O6KMuBAB0zD7g5kgIIYS0JJQsEY+RHj4IACAry3ZzJIQQQloSuhvOw6hD2+Jc5H0o9m15iy8W+bUBAJRJFO4NhBBCSItCyZKHUYe3Q9SddeDn6gFlR8Bf7u6QCCGEkGaNkiUP5FuRD75BD57B4O5QXCq04DwAG+VO+HzAYACCqK4ZIYQQ56JkycPwy0vBa6HlTtrf2md75+efuy4QQgghLQpN8PYwsgvH3R0CIYQQ0qLQyBJpHioqjP+KxQCP595YCCGENCs0skQ8RrFfawDAlVZ3W+587jnj1zffuDgqQgghzR0lS8RjaIXeAIB8v7a2G+XluSgaQgghLQUlSx6Myp0QQgghjY+SJQ/VEsudeFcUAQDa5R51byCEEEJaFEqWiMe4GdoXABBYku7eQAghhLQodDech6kIiUBamxEo8ItwdyguVyCLBgCovALdHAkhhJCWhEaWPEx56w4IK0pDt4y/AaXS3eEQQgghzZ7HJEsFBQWYOnUqZDIZFAoFZsyYAZVKZfcYtVqNOXPmIDAwEH5+fpg0aRJycqyUygCQn5+PNm3agMfjoaioqBFegfPIy7IgL8tqcSt5BxdeAgBIy3NtN5JTrTxCCCHO5THJ0tSpU5GamorExERs2bIF+/fvx6xZs+we88ILL+Cvv/7Czz//jH379iEzMxMTJ0602nbGjBno3r17Y4TuVHyNGvwWliSZdLy5CwDAY8xy55dfGr+eftrFURFCCGnuPCJZSktLw/bt27F27VoMGDAAgwcPxurVq7Fx40ZkZmZaPaa4uBjffPMNVq5ciXvvvRd9+vTBunXrcPjwYRw9an431eeff46ioiK89NJLrng5DSJLPeLuEAghhJAWxSMmeB85cgQKhQJ9+/bltiUkJIDP5+PYsWN48MEHLY5JTk6GVqtFQkICty0mJgaRkZE4cuQIBg4cCAA4f/483n77bRw7dgzXrl1zKJ6KigpUmMprAFBWzh3SarXQarX1eo3WmM5V/Zx6vR4MrFGer8ljBrPXbr6v2mhTHcudWOtnUj9aLWAwGP8G0+kYtFpWbR/1s6tQX7sG9bNrNGY/O3pOj0iWsrOzERISYrZNKBQiICAA2dnZNo8Ri8VQKBRm20NDQ7ljKioqMGXKFHzwwQeIjIx0OFlaunQplixZYrF9x44d8PHxcegcdZGYmMh9r0zLQEDlXK29e/dAnObl9OdrqgoqvBCiysUFeS8Ubdtmtq/HZ58Z23TujJvDh9fr/NX7mdSPWi1ARkY3AEBSUhYYs5xfRv3sOtTXrkH97BqN0c9lZWUOtXNrsrRgwQIsX77cbpu0tLRGe/6FCxciNjYW//rXv+p83Pz587nHSqUSERERGDlyJGROXChSq9UiMTERI0aMgEgkAgCcubQPpUfOAQD6D7sHimh/pz1fU7f545vwMxRAH90PY8feZbaPv2ULACAiNBRxY8fW6bzW+pnUT2kpsHOncWSpX782GDPGfGSJ+tk1qK9dg/rZNRqzn5UO3lXu1mTpxRdfxPTp0+22adeuHcLCwpCba/4Xqk6nQ0FBAcLCwqweFxYWBo1Gg6KiIrPRpZycHO6Y3bt349y5c/jll18AAKzyUk5QUBBef/11q6NHACCRSCCRSCy2i0SiRvkPU/28AoEAPBgvMwklkhb1H5TH54MHHng8geXr5ldOvxMIIKhnnzTW+9eSiERVb4VQaHxs2Yb62VWor12D+tk1GqOfHT2fW5Ol4OBgBAcH19ouPj4eRUVFSE5ORp8+fQAYEx2DwYABAwZYPaZPnz4QiUTYtWsXJk2aBAC4ePEiMjIyEB8fDwD49ddfUV5ezh2TlJSEJ598EgcOHED79u0b+vIa1Y3gvoiTtazb5L0qjH8BROadBHC3e4MhhBDSYnjEnKXY2FiMHj0aM2fOxBdffAGtVou5c+fikUceQXh4OADg9u3bGD58OL777jv0798fcrkcM2bMwPz58xEQEACZTIZnn30W8fHx3OTumglRXmXF+tjYWIu5TsT9soK7Q5Z/HWFFjXdplhBCCKnJI5IlANiwYQPmzp2L4cOHg8/nY9KkSVi1ahW3X6vV4uLFi2aTtT766COubUVFBUaNGoXPKicCe6qKwHBcbjUE+dK27g7F5e4oOqIzgBLvkFrbEkIIIc7iMclSQEAAfvjhB5v7o6KiuDlHJl5eXlizZg3WrFnj0HMMGzbM4hxNTXlkZ/iXbkag6gag7A74O29COSGEEEIseUyyRKoEqG6Ab9C3uHInAcrrAAA/db7tRr6+LoqGEEJIS0HJkofh6bQtttxJTPp2AADfoLPc+eWXLo6GEEJIS+ER5U5IFfm5g+4OgRBCCGlRKFkihBBCCLGDLsMRj1HiEwZ52VVkBPW23PnUU8Z/hwwBpk51bWCEEEKaNRpZIh6jQuwHAMjy72K70c2bLoqGEEJIS0HJkifj8dwdASGEENLsUbLkoW4E9wWTK9wdhkt5aUoAAK0Lzrk5EkIIIS0JJUvEY+QExAIA2uSfcXMkhBBCWhJKljyMJiAM10MHIlfe0d2huJwpWVL6hLo5EkIIIS0JJUsepqxtLLwrihCZlwyUlLg7HEIIIaTZo6UDPFCI8rKx3IneykrWzZiixHinm29Foe1GYrGLoiGEENJSULLkaQyGFlvupMv1LQAAgV5jufOLL1wcDSGEkJaCLsN5GMWZfe4OoWni8aq+CCGEECeiZIkQQgghxA66DEc8hsonFLKya7gdEGe501TuZPhwYPJk1wZGCCGkWaORJeIx1GIpAOBWYA/bja5dc1E0hBBCWgpKljwZzc8hhBBCGh0lSx6qJZY7kWhLAQBhRRfcHAkhhJCWhJIl4jHy5e0AAG3vnHBzJIQQQloSSpY8jFYRjIyg3siTRrs7FJfLDOoOgMqdEEIIcS1KljxMaXQ3CJgOrYrSAJXK3eEQQgghzR4tHeCBWhWmGsud6LTuDsWlZKVZAABvTbHtRiKRi6IhhBDSUlCyRDxGt6ubAQAindpy55o1gE4HCASuDYoQQkizR8mSh1Gc2oOSFlobzi6h0PhFCCGEOBnNWSKEEEIIsYP+FCceo9Q7GNKyUmQrYix3msqdjB4NPPigawMjhBDSrNHIEvEY5RI5AOOCnDZdvOiiaAghhLQUNLJECCEtmMFggEajcXcYHkmr1UIoFEKtVkOvp7mkjaUh/SwSiSBwwo0/lCx5qBvBfRGn8Hd3GC4l0pUDAIJKrgG4273BENIMaDQaXL9+HQaDwd2heCTGGMLCwnDz5k3wqFZno2loPysUCoSFhTXoPaJkiXiMYr828M+9hPbZhwFMc3c4hHg0xhiysrIgEAgQEREBPp9mZdSVwWCASqWCn58f9V8jqm8/M8ZQVlaG3NxcAECrVq3qHQMlSx5GKwtAZkBXFPq2cXcoLncrpDeiru2mcieEOIFOp0NZWRnCw8Ph4+Pj7nA8kukSppeXFyVLjagh/ezt7Q0AyM3NRUhISL0vydG762FK2/eARuiDAFUGUFrq7nAIIR7KNPdDLBa7ORJCGpfpjwGttv5VL2hkyQNF5p00ljvRTgbg6+5wXMa3PA8A4KW1UxOPFqYkpE5org1p7pzxM04jS8Rj9Lj8MwBArLUyorZqFfDBB8CcOS6OihBCXGPYsGGYN28e9zgqKgoff/yx2+JpSShZ8jDyM/vBp3InliQSQCYDKq9PE0Kap+nTp2PChAkW3/N4PLtfixcvrvdzLl682Oxccrkcd999N/bt29fwF9QASUlJmDVrlltjaCnomoWH4VGiRAghFrKysrjvN23ahEWLFuFitUVq/fz8GnT+rl27YufOnQCAgoICfPjhh3jggQeQkpICmUzWoHPXV3BwsFuetyXymJGlgoICTJ06FTKZDAqFAjNmzIBKZWfuCgC1Wo05c+YgMDAQfn5+mDRpEnJycizaffvtt+jevTu8vLwQEhKCOXQpp0kq9Q4CAOTJ2lnufOop49eWLS6OihDSFISFhXFfcrkcPB7PbFtDkyWhUMidq0uXLnj77behUqlw9epVrs3KlSsRFxcHX19fRERE4JlnnjH7nLpx4wbGjRsHf39/+Pr6omvXrti2bRu3PyUlBWPGjIGfnx9CQ0Px2GOPIS8vz2ZMNS/D8Xg8rF27Fg8++CB8fHzQsWNH/Pnnn2bH1PU5iJHHJEtTp05FamoqEhMTsWXLFuzfv7/W4ccXXngBf/31F37++Wfs27cPmZmZmDhxolmblStX4vXXX8eCBQuQmpqKnTt3YtSoUY35Ukg9lUsUAICroYNsN0pJcU0whDQzjAEVFe75Yszdr75uKioqsG7dOigUCnTo0IHbzufzsWrVKqSmpmL9+vXYvXs3XnnlFW7/nDlzUFFRgf379+PcuXNYvnw5l8QVFRXh3nvvRa9evXDixAls374dOTk5mDx5cp1iW7JkCSZPnoyzZ89i7NixmDp1KgoKCpz6HC2RR1yGS0tLw/bt25GUlIS+fY11wVavXo2xY8fiww8/RHh4uMUxxcXF+Oabb/DDDz/g3nvvBQCsW7cOsbGxOHr0KAYOHIjCwkK88cYb+OuvvzB8+HDu2O7du7vmhRFCSBOh0QDPPeee5161yjjtsCk7d+4cl9iUlZVBKpXixx9/NLsEV3Py9bvvvovZs2fjs88+AwBkZGRg0qRJiIuLAwC0a1c1Sv7pp5+iV69eeP/997lt//3vfxEREYFLly6hU6dODsU5ffp0TJkyBQDw/vvvY9WqVTh+/DhGjx7ttOdoiTwiWTpy5AgUCgWXKAFAQkIC+Hw+jh07hgetVJlPTk6GVqtFQkICty0mJgaRkZE4cuQIBg4ciMTERBgMBty+fRuxsbEoKSnBoEGDsGLFCkRERNiMp6KiAhUVFdxjpVIJwLiGQ0PWcajJdK7q59Tr9WBguBUQhxgfX6c+X1Mn4OlxKfQuiDXFFq+bbyrXwOPBUMc+sdbPpH60WsBgMA5Y63QMWi2rto/62VUc6WutVgvGGAwGQ+UXwJh7lhEwGBgcrbjCGOPirv69+fkMZv/asnTpUixdupR7nJKSgsjISKvP2blzZ2zevBkAUFJSgp9++gkPP/ww/vzzTwwZMgQGgwE7d+7E8uXLceHCBSiVSuh0OqjVaqhUKvj4+GDu3LmYM2cOduzYgeHDh2PixIncH+enT5/Gnj17rF4uvHz5MjeCVfP11nzcrVs37rG3tzdkMhmys7NhMBgcfo6mhlUOPVp7rx1h+lnRarUWi1I6+vvII5Kl7OxshISEmG0TCoUICAhAdna2zWPEYjEUCoXZ9tDQUO6Ya9euwWAw4P3338cnn3wCuVyON954AyNGjMDZs2dtLta2dOlSLFmyxGL7jh07GmUl3MTERO57ZVoGAlQq3OGrkLhzJ/z8Ws4HT2knAYK374Gkdxds22Y+0b21XA7F5cu41aULiqvNAaiL6v1M6ketFiAjoxsAICkpC4zlWrShfnYde31tmoOjUqmg0WjAGPDOOy4Mrhq12ng5zhFarRY6nQ5KpdLse/PzqcEYs9he06OPPooxY8Zwj/38/KweU1FRAYFAwH0OhYSEYOHChfj999/x+eefo1evXsjIyMADDzyAJ598EgsWLIC/vz+OHj2KZ599Fvn5+dDpdJg8eTIGDRqEHTt2YM+ePVi2bBneffddzJo1C0VFRRg9erTVu/ZCQ0O55Euj0XAxGgwGqNVqs5it9UdZWRmUSqVDz9GUlZSU1Os4jUaD8vJy7N+/HzqdzmxfWVmZQ+dwa7K0YMECLF++3G6btLS0Rnt+g8EArVaLVatWYeTIkQCAH3/8EWFhYdizZ4/NuUsLFy7E/PnzucdKpRIREREYOXKkU++K0Gq1SExMxIgRIyASiQAAybdP4WZqOQTyThgxYgT8W1It3bEAMNPGvrEAgLb1OK21fib1U1oK7NxpHFnq168NxowxH1mifnYNR/parVbj5s2b8PPzg5eXl4sjrD+RSAShUAiZTGb2fXVeXl7g8Xi1/j6WyWRo27b23xoSiQQCgcDifCKRCGq1GlKpFBcvXoTBYMCqVau4khx///03AEAqlXLHdunSBV26dMG8efPw2muv4fvvv8dLL72E/v3747fffkO3bt0gtLG4rlAohFgs5s7F5/Ph5eVlFpdpNMmEx+NxbRx5jqaIMYaSkhJIpdJ6LTCpVqvh7e2NIUOGWPysO5ogurW3XnzxRUyfPt1um3bt2iEsLIwrhGei0+lQUFCAsLAwq8eFhYVBo9GgqKjIbHQpJyeHO8ZUVK9Lly7c/uDgYAQFBSEjI8NmTBKJBBIrF9hFIlGjfAhUP295bH+ofC5AqimCSKOBSNRyVvBubI31/rUkIhFgKt0kFBofW7ahfnYVe32t1+vB4/HA5/M9qq6Zaa0jPp9v9n11psfOel08Hg86nY77HCopKcGmTZtw/vx5PPvss+DxeOjUqRO0Wi3WrFmDcePG4dChQ/jyyy+5OPh8PubNm4cxY8agU6dOKCwsxN69exEbGws+n4+5c+di7dq1mDp1Kl555RUEBATgypUr2LhxI9auXctdPqr5ems+tvZ+mrY5+hxNjenSm7X32hGmnxVr/x8c/V3k1mQpODjYoXUi4uPjUVRUhOTkZPTp0wcAsHv3bhgMBgwYMMDqMX369IFIJMKuXbswadIkAMDFixeRkZGB+Ph4AMBdd93FbW/TxliYtqCgAHl5eQ79teEu0blHK8udjEdLKndCCCEGg8EtoyKpqancH9g+Pj5o37491qxZg0ceeQQA0KNHD6xcuRLLly/HwoULMWTIECxduhSPP/44dw69Xo85c+bg1q1bkMlkGD16ND766CMAQHh4OA4dOoRXX30VI0eOREVFBdq2bYvRo0c7LelzxXM0W8xDjB49mvXq1YsdO3aMHTx4kHXs2JFNmTKF23/r1i3WuXNnduzYMW7b7NmzWWRkJNu9ezc7ceIEi4+PZ/Hx8WbnHT9+POvatSs7dOgQO3fuHLv//vtZly5dmEajcTi24uJiBoAVFxc3/IVWo9Fo2ObNm81i2b2bsT1dnmb7YmaxwmsFTn2+lspaP5P6UakYmzXL+LV1q/k+6mfXcaSvy8vL2fnz51l5ebkLI2u4UaNGsTlz5rg7DMYYY3q9nhUWFjK9Xu/uUJq1hvazvZ91Rz+/PSaV3LBhA2JiYjB8+HCMHTsWgwcPxldffcXt12q1uHjxotlkrY8++gj3338/Jk2ahCFDhiAsLAy//fab2Xm/++47DBgwAPfddx+GDh0KkUiE7du3N9nLBPJzB6ncCSGkxSksLMSWLVuwd+9es7ucCXEFj5nhFRAQgB9++MHm/qioKO72QhMvLy+sWbMGa9assXmcTCbDN998g2+++cZpsTYmnq7l3P1GCCEmTz75JJKSkvDiiy9i/Pjx7g6HtDAekywRQghpuX7//Xd3h0BaMI+5DEcIIYQQ4g6ULBFCCCGE2EHJkofKVsSAyeTuDoMQQghp9ihZ8lAVIr+q1f8IIYQQ0mjo09bD6H2kKJC2RYl37Yt5EkIIIaThKFnyMCWd++KOtB3EujLAwQKAhBBCCKk/SpY8UMfs/eiUuQ88jYNlugkhhDQJ3377rVm90sWLF6Nnz55ui8fVpk+fjgkTJnCPhw0bhnnz5rktHkdRskQIIcQjmArn2vpavHgxAODUqVN46KGHEBoaCi8vL3Ts2BEzZ87EpUuX3PsCADz88MNuiePbb7816ys/Pz/06dPHoqqFq/32229455133BqDIyhZ8jCy1CNU7oQQ0iJlZWVxXx9//DFkMpnZtpdeeglbtmzBwIEDUVFRgQ0bNiAtLQ3ff/895HI53nzzTXe/BHh7eyMkJMQtz129v06dOoVRo0Zh8uTJuHjxolviAYzVOaRSqdue31GULHkYvkbt7hAIIcQtwsLCuC+5XA4ej2e2jc/n44knnsDYsWPx559/IiEhAdHR0RgwYAA+/PBDfPnll9y59u3bh/79+0MikaBVq1ZYsGABdDodt3/YsGF49tlnMW/ePPj7+yM0NBRff/01SktL8cQTT0AqlaJTp05ITEzkjtm7dy94PB62bt2K7t27w8vLCwMHDkRKSgrXpuZlOGvWrl2L2NhYeHl5ISYmBp999plT+q96f3Xs2BHvvvsu+Hw+zp49y7X53//+h759+0IqlSIsLAyPPvoocnNzuf2FhYWYOnUqgoOD4e3tjY4dO2LdunXc/ps3b2Ly5MlQKBQICAjA+PHjkZ6ebjOmmpfhoqKi8P777+PJJ5+EVCpFZGSkWR3Y+jyHM1CyRAghpEpFhe0vrdb5bZ3on3/+QV5eHl555RWr+01Jyu3btzF27Fj069cPZ86cweeff45vvvkG7777rln79evXIygoCMePH8ezzz6Lp59+Gg899BAGDRqEkydPYsSIEZg9e7ZZAXcAePnll7FixQokJSUhODgY48aNg7Zmf9iwYcMGLFq0CO+99x7S0tLw/vvv480338T69evr3iF26PV67py9e/fmtmu1Wrzzzjs4c+YMNm/ejPT0dEyfPp3b/+abb+L8+fP4+++/kZaWhs8//xxBQUHcsaNGjYJUKsWBAwdw6NAh+Pn5YfTo0dBoNA7HtmLFCvTt2xenTp3CM888gzlz5uDy5ctOfY66otpwhBBCqjz3nO193boBzz5b9fillwBbH1CdOgEvvlj1+LXXAJXKsl210Z6GMn2gxsTE2G332WefISIiAp9++il4PB5iYmKQmZmJV199FYsWLQK/cg27Hj164I033gAALFy4EMuWLUNQUBBmzpwJwJg4fPHFFzh79iwGDRrEnf+tt97CiBEjABgTrjZt2uD333/H5MmTa30Nb731FlasWIGJEycCAKKjo3H+/Hl8+eWXmDZtWh17xFxxcTH8/PwAAOXl5RCJRPjqq6/Qvn17rs2TTz7Jfd+uXTusWrUK/fr1g0qlgp+fHzIyMtCrVy/07dsXgHEkyGTTpk0wGAxYu3YteDweAGDdunVQKBTYu3cvRo4c6VCcY8eOxTPPPAMAePXVV/HRRx/hwIED6NOnj9Oeo64oWSKEENIsMMYcapeWlob4+HjuwxYA7rrrLqhUKty6dQuRkZEAgO7du3P7BQIBAgMDERcXx20LDQ0FALPLVAAQHx/PfR8QEIDOnTsjLS2t1rhKS0tx9epVzJgxg0vIAECn00Eut16xYcOGDXjqqae4x3///Tfuvvtuq22lUilOnjwJACgrK8POnTsxe/ZsBAYGYty4cQCA5ORkLF68GGfOnEFhYSEMBgMAICMjA126dMHTTz+NSZMm4eTJkxg5ciQmTJjAJYpnzpzBlStXLOYgqdVqXL16tdbXb1K9302XDvPy8pz6HHVFyZKHypNFU7kTQojzrVple1/NqgEffuh42/ffr39MDurUqRMA4MKFC2YJS32JRCKzxzwez2ybKdkyJRQNpaocefv6668xYMAAs30CgcDqMQ888IBZ29atW9s8P5/PR4cOHbjH3bt3x44dO7B8+XKMGzcOpaWlGDVqFEaNGoUNGzYgODgYGRkZGDVqFHeJa8yYMbhx4wa2bduGxMREDB8+HHPmzMGHH34IlUqFPn36YMOGDRbPHRzs+ELK1vrd1MfOeo66omTJQ5VKAqncCSHE+SQS97etp5EjRyIoKAj/+c9/8Pvvv1vsLyoqgkKhQGxsLH799VcwxriE59ChQ5BKpWjTpk2D4zh69Cg3OlVYWIhLly4hNja21uNCQ0MRHh6Oa9euYerUqQ49l1QqbdDdZAKBAOXl5QCMSWZ+fj6WLVuGiIgIAMCJEycsjgkODsa0adMwbdo03H333Xj55Zfx4Ycfonfv3ti0aRNCQkIgk8nqHZM9rngOa+jT1sMYvHyg9AlDmUTh7lAIIaRJ8fX1xdq1a7F161Y88MAD2LlzJ9LT03HixAm88sormD17NgDgmWeewc2bN/Hss8/iwoUL+OOPP/DWW29h/vz53Hylhnj77bexa9cupKSkYPr06QgKCjJbiNGeJUuWYOnSpVi1ahUuXbqEc+fOYd26dVi5cmWD42KMITs7G9nZ2bh+/Tq++uor/PPPPxg/fjwAIDIyEmKxGKtXr8a1a9fw559/WqyBtGjRIvzxxx+4cuUKUlNTsWXLFi4RnDp1KoKCgjB+/HgcOHAA169fx969e/Hcc8/h1q1bDY7fVc9hDSVLHiZs/AAcHLEEqtEPoZa7TwlxOR8foGtXQC43/kuIq40fPx6HDx+GSCTCo48+ipiYGEyZMgXFxcXc3W6tW7fGtm3bcPz4cfTo0QOzZ8/GjBkzuMncDbVs2TI8//zz6NOnD7Kzs/HXX39BLBY7dOy///1vrF27FuvWrUNcXByGDh2Kb7/9FtHR0Q2OS6lUolWrVmjVqhViY2OxYsUKvP3223j99dcBGEeMvv32W/z888/o0qULli1bhg9rXGoVi8VYuHAhunfvjiFDhkAgEGDjxo0AAB8fH+zfvx+RkZGYOHEiYmNjMWPGDKjVaqeNArniOazhMUdnxBGblEol5HI5iouLnfpmabVabNu2DWPHjrW4hkuch/rZNaifXceRvlar1bh+/Tqio6Ph5eXl4gibB4PBAKVSCZlMBj6fj7179+Kee+5BYWFhrWspEcfV7Oe6svez7ujnN40sEUIIIYTYQckSIYQQQogddDccIYQQ4gTDhg1zeK0n4lloZIkQQgghxA5KlgghhBBC7KBkiRBCWjC6bESaO2f8jFOyRAghLZCpfEZjVmonpCkoKysDYFlGpS5ogjchhLRAQqEQPj4+uHPnDkQikVNWrm5pDAYDNBoN1Go19V8jqm8/M8ZQVlaG3NxcKBQKm/X1HEHJEiGEtEA8Hg+tWrXC9evXcePGDXeH45EYYygvL4e3tzdXY444X0P7WaFQICwsrEExULJECCEtlFgsRseOHelSXD1ptVrs378fQ4YMoVXpG1FD+lkkEjVoRMmEkiVCCGnB+Hw+lTupJ4FAAJ1OBy8vL0qWGlFT6Ge6yEoIIYQQYgclS4QQQgghdlCyRAghhBBiB81ZcgLTgldKpdKp59VqtSgrK4NSqaTr4Y2I+tk1qJ9dh/raNaifXaMx+9n0uV3bwpWULDlBSUkJACAiIsLNkRBCCCGkrkpKSiCXy23u5zFa677BDAYDMjMzIZVKnbrWhlKpREREBG7evAmZTOa08xJz1M+uQf3sOtTXrkH97BqN2c+MMZSUlCA8PNzugpc0suQEfD4fbdq0abTzy2Qy+o/oAtTPrkH97DrU165B/ewajdXP9kaUTGiCNyGEEEKIHZQsEUIIIYTYQclSEyaRSPDWW29BIpG4O5RmjfrZNaifXYf62jWon12jKfQzTfAmhBBCCLGDRpYIIYQQQuygZIkQQgghxA5KlgghhBBC7KBkiRBCCCHEDkqWmqg1a9YgKioKXl5eGDBgAI4fP+7ukDzK0qVL0a9fP0ilUoSEhGDChAm4ePGiWRu1Wo05c+YgMDAQfn5+mDRpEnJycszaZGRk4L777oOPjw9CQkLw8ssvQ6fTufKleJRly5aBx+Nh3rx53DbqZ+e4ffs2/vWvfyEwMBDe3t6Ii4vDiRMnuP2MMSxatAitWrWCt7c3EhIScPnyZbNzFBQUYOrUqZDJZFAoFJgxYwZUKpWrX0qTptfr8eabbyI6Ohre3t5o37493nnnHbPaYdTXdbd//36MGzcO4eHh4PF42Lx5s9l+Z/Xp2bNncffdd8PLywsRERH4z3/+45wXwEiTs3HjRiYWi9l///tflpqaymbOnMkUCgXLyclxd2geY9SoUWzdunUsJSWFnT59mo0dO5ZFRkYylUrFtZk9ezaLiIhgu3btYidOnGADBw5kgwYN4vbrdDrWrVs3lpCQwE6dOsW2bdvGgoKC2MKFC93xkpq848ePs6ioKNa9e3f2/PPPc9upnxuuoKCAtW3blk2fPp0dO3aMXbt2jf3zzz/sypUrXJtly5YxuVzONm/ezM6cOcMeeOABFh0dzcrLy7k2o0ePZj169GBHjx5lBw4cYB06dGBTpkxxx0tqst577z0WGBjItmzZwq5fv85+/vln5ufnxz755BOuDfV13W3bto29/vrr7LfffmMA2O+//2623xl9WlxczEJDQ9nUqVNZSkoK+/HHH5m3tzf78ssvGxw/JUtNUP/+/dmcOXO4x3q9noWHh7OlS5e6MSrPlpubywCwffv2McYYKyoqYiKRiP38889cm7S0NAaAHTlyhDFm/M/N5/NZdnY21+bzzz9nMpmMVVRUuPYFNHElJSWsY8eOLDExkQ0dOpRLlqifnePVV19lgwcPtrnfYDCwsLAw9sEHH3DbioqKmEQiYT/++CNjjLHz588zACwpKYlr8/fffzMej8du377deMF7mPvuu489+eSTZtsmTpzIpk6dyhijvnaGmsmSs/r0s88+Y/7+/ma/N1599VXWuXPnBsdMl+GaGI1Gg+TkZCQkJHDb+Hw+EhIScOTIETdG5tmKi4sBAAEBAQCA5ORkaLVas36OiYlBZGQk189HjhxBXFwcQkNDuTajRo2CUqlEamqqC6Nv+ubMmYP77rvPrD8B6mdn+fPPP9G3b1889NBDCAkJQa9evfD1119z+69fv47s7GyzfpbL5RgwYIBZPysUCvTt25drk5CQAD6fj2PHjrnuxTRxgwYNwq5du3Dp0iUAwJkzZ3Dw4EGMGTMGAPV1Y3BWnx45cgRDhgyBWCzm2owaNQoXL15EYWFhg2KkQrpNTF5eHvR6vdkHBwCEhobiwoULborKsxkMBsybNw933XUXunXrBgDIzs6GWCyGQqEwaxsaGors7GyujbX3wbSPGG3cuBEnT55EUlKSxT7qZ+e4du0aPv/8c8yfPx+vvfYakpKS8Nxzz0EsFmPatGlcP1nrx+r9HBISYrZfKBQiICCA+rmaBQsWQKlUIiYmBgKBAHq9Hu+99x6mTp0KANTXjcBZfZqdnY3o6GiLc5j2+fv71ztGSpZIszdnzhykpKTg4MGD7g6l2bl58yaef/55JCYmwsvLy93hNFsGgwF9+/bF+++/DwDo1asXUlJS8MUXX2DatGlujq55+emnn7Bhwwb88MMP6Nq1K06fPo158+YhPDyc+roFo8twTUxQUBAEAoHF3UI5OTkICwtzU1Sea+7cudiyZQv27NmDNm3acNvDwsKg0WhQVFRk1r56P4eFhVl9H0z7iPEyW25uLnr37g2hUAihUIh9+/Zh1apVEAqFCA0NpX52glatWqFLly5m22JjY5GRkQGgqp/s/d4ICwtDbm6u2X6dToeCggLq52pefvllLFiwAI888gji4uLw2GOP4YUXXsDSpUsBUF83Bmf1aWP+LqFkqYkRi8Xo06cPdu3axW0zGAzYtWsX4uPj3RiZZ2GMYe7cufj999+xe/dui6HZPn36QCQSmfXzxYsXkZGRwfVzfHw8zp07Z/YfNDExETKZzOKDq6UaPnw4zp07h9OnT3Nfffv2xdSpU7nvqZ8b7q677rJY+uLSpUto27YtACA6OhphYWFm/axUKnHs2DGzfi4qKkJycjLXZvfu3TAYDBgwYIALXoVnKCsrA59v/tEoEAhgMBgAUF83Bmf1aXx8PPbv3w+tVsu1SUxMROfOnRt0CQ4ALR3QFG3cuJFJJBL27bffsvPnz7NZs2YxhUJhdrcQse/pp59mcrmc7d27l2VlZXFfZWVlXJvZs2ezyMhItnv3bnbixAkWHx/P4uPjuf2mW9pHjhzJTp8+zbZv386Cg4PplvZaVL8bjjHqZ2c4fvw4EwqF7L333mOXL19mGzZsYD4+Puz777/n2ixbtowpFAr2xx9/sLNnz7Lx48dbvfW6V69e7NixY+zgwYOsY8eOLfp2dmumTZvGWrduzS0d8Ntvv7GgoCD2yiuvcG2or+uupKSEnTp1ip06dYoBYCtXrmSnTp1iN27cYIw5p0+LiopYaGgoe+yxx1hKSgrbuHEj8/HxoaUDmrPVq1ezyMhIJhaLWf/+/dnRo0fdHZJHAWD1a926dVyb8vJy9swzzzB/f3/m4+PDHnzwQZaVlWV2nvT0dDZmzBjm7e3NgoKC2Isvvsi0Wq2LX41nqZksUT87x19//cW6devGJBIJi4mJYV999ZXZfoPBwN58800WGhrKJBIJGz58OLt48aJZm/z8fDZlyhTm5+fHZDIZe+KJJ1hJSYkrX0aTp1Qq2fPPP88iIyOZl5cXa9euHXv99dfNbkenvq67PXv2WP2dPG3aNMaY8/r0zJkzbPDgwUwikbDWrVuzZcuWOSV+HmPVliUlhBBCCCFmaM4SIYQQQogdlCwRQgghhNhByRIhhBBCiB2ULBFCCCGE2EHJEiGEEEKIHZQsEUIIIYTYQckSIYQQQogdlCwRQlq8qKgofPzxx+4OgxDSRFGyRAhxmenTp2PChAnc42HDhmHevHkue/5vv/0WCoXCYntSUhJmzZrlsjhq2rt3L3g8nkXBYUJI0yB0dwCEENJQGo0GYrG43scHBwc7MRpCSHNDI0uEELeYPn069u3bh08++QQ8Hg88Hg/p6ekAgJSUFIwZMwZ+fn4IDQ3FY489hry8PO7YYcOGYe7cuZg3bx6CgoIwatQoAMDKlSsRFxcHX19fRERE4JlnnoFKpQJgHL154oknUFxczD3f4sWLAVhehsvIyMD48ePh5+cHmUyGyZMnIycnh9u/ePFi9OzZE//73/8QFRUFuVyORx55BCUlJTZf740bNzBu3Dj4+/vD19cXXbt2xbZt25Ceno577rkHAODv7w8ej4fp06cDAAwGA5YuXYro6Gh4e3ujR48e+OWXX7hzmkaktm7diu7du8PLywsDBw5ESkpKvd8XQoglSpYIIW7xySefID4+HjNnzkRWVhaysrIQERGBoqIi3HvvvejVqxdOnDiB7du3IycnB5MnTzY7fv369RCLxTh06BC++OILAACfz8eqVauQmpqK9evXY/fu3XjllVcAAIMGDcLHH38MmUzGPd9LL71kEZfBYMD48eNRUFCAffv2ITExEdeuXcPDDz9s1u7q1avYvHkztmzZgi1btmDfvn1YtmyZzdc7Z84cVFRUYP/+/Th37hyWL18OPz8/RERE4NdffwUAXLx4EVlZWfjkk08AAEuXLsV3332HL774AqmpqXjhhRfwr3/9C/v27TM798svv4wVK1YgKSkJwcHBGDduHLRabR3fEUKITU4px0sIIQ6YNm0aGz9+PPd46NCh7Pnnnzdr884777CRI0eabbt58yYDwFUhHzp0KOvVq1etz/fzzz+zwMBA7vG6deuYXC63aNe2bVv20UcfMcYY27FjBxMIBCwjI4Pbn5qaygCw48ePM8YYe+utt5iPjw9TKpVcm5dffpkNGDDAZixxcXFs8eLFVveZKrIXFhZy29RqNfPx8WGHDx82aztjxgw2ZcoUs+M2btzI7c/Pz2fe3t5s06ZNNmMhhNQNzVkihDQpZ86cwZ49e+Dn52ex7+rVq+jUqRMAoE+fPhb7d+7ciaVLl+LChQtQKpXQ6XRQq9UoKyuDj4+PQ8+flpaGiIgIREREcNu6dOkChUKBtLQ09OvXD4Dx0p1UKuXatGrVCrm5uTbP+9xzz+Hpp5/Gjh07kJCQgEmTJqF79+4221+5cgVlZWUYMWKE2XaNRoNevXqZbYuPj+e+DwgIQOfOnZGWlubQ6yWE1I6SJUJIk6JSqTBu3DgsX77cYl+rVq247319fc32paen4/7778fTTz+N9957DwEBATh48CBmzJgBjUbjcLLkKJFIZPaYx+PBYDDYbP/vf/8bo0aNwtatW7Fjxw4sXboUK1aswLPPPmu1vWmu1datW9G6dWuzfRKJpIHRE0LqgpIlQojbiMVi6PV6s229e/fGr7/+iqioKAiFjv+KSk5OhsFgwIoVK8DnG6dj/vTTT7U+X02xsbG4efMmbt68yY0unT9/HkVFRejSpYvD8VgTERGB2bNnY/bs2Vi4cCG+/vprPPvss9ydfNVj69KlCyQSCTIyMjB06FC75z169CgiIyMBAIWFhbh06RJiY2MbFCshpApN8CaEuE1UVBSOHTuG9PR05OXlwWAwYM6cOSgoKMCUKVOQlJSEq1ev4p9//sETTzxhN9Hp0KEDtFotVq9ejWvXruF///sfN/G7+vOpVCrs2rULeXl5KCsrszhPQkIC4uLiMHXqVJw8eRLHjx/H448/jqFDh6Jv3771fq3z5s3DP//8g+vXr+PkyZPYs2cPl9C0bdsWPB4PW7ZswZ07d6BSqSCVSvHSSy/hhRdewPr163H16lWcPHkSq1evxvr1683O/fbbb2PXrl1ISUnB9OnTERQUZLaeFSGkYShZIoS4zUsvvQSBQIAuXbogODgYGRkZCA8Px6FDh6DX6zFy5EjExcVh3rx5UCgU3IiRNT169MDKlSuxfPlydOvWDRs2bMDSpUvN2gwaNAizZ8/Gww8/jODgYPznP/+xOA+Px8Mff/wBf39/DBkyBAkJCWjXrh02bdrUoNeq1+sxZ84cxMbGYvTo0ejUqRM+++wzAEDr1q2xZMkSLFiwAKGhoZg7dy4A4J133sGbb76JpUuXcsdt3boV0dHRZudetmwZnn/+efTp0wfZ2dn466+/GrTuFCHEHI8xxtwdBCGEkLrbu3cv7rnnHhQWFlpdmZwQ4hw0skQIIYQQYgclS4QQQgghdtBlOEIIIYQQO2hkiRBCCCHEDkqWCCGEEELsoGSJEEIIIcQOSpYIIYQQQuygZIkQQgghxA5KlgghhBBC7KBkiRBCCCHEDkqWCCGEEELsoGSJEEIIIcSO/wfjsMT0do4IwQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "\n", + "# Convert lists to numpy arrays for easier manipulation\n", + "loss_baseline_np = np.array(loss_baseline)\n", + "loss_jit_np = np.array(loss_jit)\n", + "loss_tcompile_np = np.array(loss_tcompile)\n", + "\n", + "# Calculate deltas\n", + "delta_jit_baseline = (loss_jit_np - loss_baseline_np)\n", + "delta_tcompile_baseline = (loss_tcompile_np - loss_baseline_np)\n", + "\n", + "# Plot deltas\n", + "plt.plot(it_jit, delta_jit_baseline, label=\"JIT - Baseline\", linestyle='-', color='blue', alpha=0.6)\n", + "plt.plot(it_tcompile, delta_tcompile_baseline, label=\"TCompile - Baseline\", linestyle='--', color='red', alpha=0.6)\n", + "\n", + "plt.xlabel('Iteration step')\n", + "plt.ylabel('Delta Loss')\n", + "plt.title('Delta Loss Curve (compared to Baseline)')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working as per designed, the differences between \"Delta Loss\" should be within margin of error, of run-by-run varience" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Plot the time charts!\n", + "\n", + "Lets start with a basic iteration step over cummulative time" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAGwCAYAAABIC3rIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAACI6klEQVR4nOzdd3RU1drH8e9Meg9JSEIgQOi9I0SKlEgHqdKkC4oEpEqvoiAovQmIiHQUkK5ILwFC6L2Fngbpfcp5/5jL+EYQE0kyCXk+a7GuM2efM8+OXuaXc3ZRKYqiIIQQQgiRh6lNXYAQQgghhKlJIBJCCCFEnieBSAghhBB5ngQiIYQQQuR5EoiEEEIIkedJIBJCCCFEnieBSAghhBB5nrmpC8gN9Ho9T58+xcHBAZVKZepyhBBCCJEOiqIQFxeHl5cXavXr7wFJIEqHp0+f4u3tbeoyhBBCCPEfPHr0iEKFCr22jQSidHBwcAAMP1BHR0cTVyOEEEKI9IiNjcXb29v4Pf46EojS4cVjMkdHRwlEQgghRC6TnuEuMqhaCCGEEHmeBCIhhBBC5HkSiIQQQgiR58kYokyk0+nQaDSmLkP8BxYWFpiZmZm6DCGEECYigSgTKIpCaGgo0dHRpi5FvAFnZ2c8PT1lrSkhhMiDJBBlghdhyN3dHVtbW/lCzWUURSExMZHw8HAAChQoYOKKhBBCZDcJRG9Ip9MZw5Crq6upyxH/kY2NDQDh4eG4u7vL4zMhhMhjZFD1G3oxZsjW1tbElYg39eLfoYwDE0KIvEcCUSaRx2S5n/w7FEKIvEsCkRBCCCHyPAlEQgghhMjzJBAJkypatCjz5s0zvlapVGzfvt1k9QghhMibJBDlYb1790alUhn/uLq60qxZMy5dumSymkJCQmjevLnJPl8IIUT2O3nnGYmpWpPWIIEoj2vWrBkhISGEhIRw4MABzM3NadWqlcnq8fT0xMrKymSfL4QQIntdeRJD79WBNJt3jPDYZJPVIYEoCyiKQmKq1iR/FEXJUK1WVlZ4enri6elJlSpVGDNmDI8ePSIiIgKA0aNHU6pUKWxtbSlWrBgTJ05MMy394sWLNGzYEAcHBxwdHalevTpnz541Hj9+/Dj16tXDxsYGb29vhgwZQkJCwj/W8/8fmd2/fx+VSsXWrVtp2LAhtra2VK5cmYCAgDTnZPQzhBBCmJ5Or7D13GO6LD9FqlZPUTc78juY7hdiWZgxCyRpdJSb9LtJPvvatKbYWv63f63x8fGsXbuWEiVKGBeZdHBwYPXq1Xh5eXH58mX69++Pg4MDX3zxBQDdu3enatWqLF26FDMzMy5cuICFhQUAd+/epVmzZkyfPp1Vq1YRERGBv78//v7+/Pjjj+mua/z48Xz77beULFmS8ePH07VrV+7cuYO5uXmmfYYQQojs8ygykeGbLxB4PwqAyt7OfNuxkkmXP5FAlMft2rULe3t7ABISEihQoAC7du1CrTbcPJwwYYKxbdGiRRk5ciQbN240BqKHDx8yatQoypQpA0DJkiWN7WfMmEH37t0ZOnSo8diCBQt47733WLp0KdbW1umqceTIkbRs2RKAqVOnUr58ee7cuUOZMmUy7TOEEEJkj/WnHzJ5xxU0OgU7SzMGNijOx/WKYW1h2h0CJBBlARsLM65Na2qyz86Ihg0bsnTpUgCioqJYsmQJzZs358yZMxQpUoRNmzaxYMEC7t69S3x8PFqtFkdHR+P5w4cP5+OPP+bnn3/Gz8+PTp06Ubx4ccDwOO3SpUusW7fO2F5RFPR6PcHBwZQtWzZdNVaqVMn4zy/2GQsPD6dMmTKZ9hlCCCGyllanZ0vQY6bsuIpGp1C7mAtT21SgtKeDqUsDJBBlCZVK9Z8fW2U3Ozs7SpQoYXy9cuVKnJycWLFiBS1btqR79+5MnTqVpk2b4uTkxMaNG/nuu++M7adMmUK3bt3YvXs3e/fuZfLkyWzcuJF27doRHx/PJ598wpAhQ1763MKFC6e7xheP4OCv1aT1ej1Apn2GEEKIrBP8LIEhG85z+UkMAM0reLKke7UctUNA7vjWFtlGpVKhVqtJSkri5MmTFClShPHjxxuPP3jw4KVzSpUqRalSpRg2bBhdu3blxx9/pF27dlSrVo1r166lCVyZLTs+QwghxH+jKArz/rzNokN30OkVnGws8G9Ygl7vFs1RYQhkllmel5KSQmhoKKGhoVy/fp3BgwcTHx9P69atKVmyJA8fPmTjxo3cvXuXBQsWsG3bNuO5SUlJ+Pv7c/jwYR48eMCJEycIDAw0PqYaPXo0J0+exN/fnwsXLnD79m1+++03/P39M63+7PgMIYQQGZei1bHgwB3mH7iNTq/QqIw72wfVoX/9Ylia57z4IXeI8rh9+/YZx+U4ODhQpkwZtmzZQoMGDQAYNmwY/v7+pKSk0LJlSyZOnMiUKVMAMDMz4/nz5/Ts2ZOwsDDc3Nxo3749U6dOBQxjf44cOcL48eOpV68eiqJQvHhxOnfunGn1Z8dnCCGEyJiboXH4rz/H7fB4AAY3KsGIJqVNXNXrqZSMLlyTB8XGxuLk5ERMTEyaAcUAycnJBAcH4+PjIzOacjn5dymEEG8mVatn1YlgZu27gV4BVztLPvcryUe1iqBWZ/8jstd9f/+d3CESQgghxBtL0er45OcgDt80LOzbuIw7Uz8oT6F8tiauLH0kEAkhhBDijVx5EsOk365w7mE0ZmoVk1uXo0ftIjlu4PTrmHRU09GjR2ndujVeXl7/usv5p59+ikqlSrMzOkBkZCTdu3fH0dERZ2dn+vXrR3x8fJo2ly5dol69elhbW+Pt7c2sWbOyoDdCCCFE3pKs0TFn/y1aLTzOuYfR2FmasbhbNXr6ZnAWWeQ9MPEIHpMGooSEBCpXrszixYtf227btm2cOnUKLy+vl451796dq1evsn//fnbt2sXRo0cZMGCA8XhsbCxNmjShSJEiBAUFMXv2bKZMmcLy5cszvT9CCCFEXvE0OonG3x1hwYHbALSsWIDdQ+rRrIJnxi4UHwErGsOaNpDwPAsqTR+TPjJr3rw5zZs3f22bJ0+eMHjwYH7//Xfj9g0vXL9+nX379hEYGEiNGjUAWLhwIS1atODbb7/Fy8uLdevWkZqayqpVq7C0tKR8+fJcuHCBOXPmpAlOQgghhEifoAdRTNx+hSfRSeR3sGJ0szJ0qFYw44/Inl6APSO5qI+ncNJz8lm/fuBzVsp5CwH8P3q9nh49ejBq1CjKly//0vGAgACcnZ2NYQjAz88PtVrN6dOnjW3q16+PpaWlsU3Tpk25efMmUVFRr/zclJQUYmNj0/wRQggh8rqEFC1f77lOh6UnuRYSi7OtBZsG1KZj9UIZC0OaJPjNH5a/x/mIi/T39KBffmciNXFZV/y/yNGDqr/55hvMzc1fuS0DQGhoKO7u7mneMzc3x8XFhdDQUGMbHx+fNG08PDyMx/Lly/fSdWfMmGFcS0cIIYQQcCc8jk9+DuJuRAIAHaoVYniTUhR0tsnghf6E7YOISApnpUs+tjg5okHBzaEQdhZ2WVB5+uTYQBQUFMT8+fM5d+5cto9SHzt2LMOHDze+jo2NxdvbO1trEEIIIXKKs/cjGbjuHBFxKeR3sGJy63K0qvTyuN7XUhQ4+wPK7+NZbWfBYu9CpKgAFN4r9B6z35uNlZlVVpSfLjk2EB07dozw8PA0G3TqdDpGjBjBvHnzuH//Pp6enoSHh6c5T6vVEhkZiaenYVCXp6cnYWFhadq8eP2izd9ZWVlhZWW6fymm0KBBA6pUqfLSLD4hhBB5V2yyhuVH7rHk8B30ChTKZ8PmT3zxyuhdobBrsH8S+jv7mezmwnYHewCq5K+Cf1V/3vF8x+RT9HNsIOrRowd+fn5p3mvatCk9evSgT58+APj6+hIdHU1QUBDVq1cH4ODBg+j1emrVqmVsM378eDQajXHX9P3791O6dOlXPi7LS3r37k10dDTbt29n69ataXaVL1q0KEOHDmXo0KGmK1AIIYTJnL73nBFbLvI4KgkwzCKb3KYc7g4ZWMlfUeDMcvR/TuWAhZ4lBQtwx9LwXTOyxkh6lutp8iD0gkkDUXx8PHfu3DG+Dg4O5sKFC7i4uFC4cGFcXV3TtLewsMDT05PSpQ37oZQtW5ZmzZrRv39/li1bhkajwd/fny5duhin6Hfr1o2pU6fSr18/Ro8ezZUrV5g/fz5z587Nvo7mAi4uLqYuQQghRA6x7fxjhm++iKJAQWcbxrcsS/MKnhkLLylxcGgGYYHLmJDfhVM2hrtKDhYODK0+lA9Lf5hF1f83Jg1EZ8+epWHDhsbXL8bt9OrVi9WrV6frGuvWrcPf35/GjRujVqvp0KEDCxYsMB53cnLijz/+YNCgQVSvXh03NzcmTZokU+7/5v8/MmvQoAEPHjxg2LBhDBs2DADZ8k4IId5+UQmpLD50h5XHgwF4v5wHM9pXxM0+g8NIHp6CX/tzLSmEfoUKEK9WY21mTc/yPelZridOVk5ZUP2bMWkgatCgQYa+aO/fv//Sey4uLqxfv/6151WqVIljx45ltLz/TlFAk5h9n/f/WdjCG95+3Lp1K5UrV2bAgAH0798/kwoTQgiRUymKwuFbEYz59RJhsSkAfFijEF+2rYCVuVn6L5QYCds+JeLefr53duJXL0+0KhUlnIszve5XlHd9eQmdnCLHjiHK1TSJ8HUGR99nlnFPwfLNpi26uLhgZmaGg4PDPw48F0II8fYYt+0KG848BMDHzY4JLcvSqIx7xh6RJUWh39CFP59f4quCBYg0MwSpWgVqMbPeTNxs3LKi9EwjgUgIIYTIo8Ljkllw4LYxDPWt48PnjUviZGvxL2f+P4oCp5ehOzSDCY7m7PLID0Bxp+KMrz2emp41s6L0TCeBKCtY2Bru1Jjqs4UQQojXUBSF/dfCGP3rJaISNQCMalqaQQ1LZOxCj86g/DmF/RHnWOzmzL3/zSAbUGkAfSv0NelCixklgSgrqFRv/NjK1CwtLdHpdKYuQwghRCZL1eqZvOMKG848AqC0hwMTW5WjbskMPtK6d5jQ9R2Zm8+RPf+7K+Ro6ciIGiNoX7J9Zped5SQQiVcqWrQoR48epUuXLlhZWeHmlrOf/QohhPh3z+NTGLftMr9fNSxQ3L+eD5/7lcLeKgNxICkKTi7iUtD39C/oQaLasC1q/4r96VOhDw6WDllRepaTQJSH6fV6zM1f/Z/AtGnT+OSTTyhevDgpKSky7V4IIXIxRVHYdSmEmXtv8CTasNDirI6V+LBGBralUhS4d5iYHf7MN09gm7szWpWKUs4lGF97ItU8qmVR9dlDAlEeFh4eTokShufFhw8fTnOsdu3aXLx40QRVCSGEyEzhcclM23mNXZdCAMNCi3M7V+EdnwwsyKso6HcN548bG1mQz4lHFoa7QO8WeJcZ9WfgYp37F/eVQJQHRUVFceLECQ4fPsynn35q6nKEEEJkkZCYJLouP8X954moVDC4YQn61y+Gg3UGZpHFhaH7tS+jE67zu7th+ISbtQvf1J/NOwXeyaLKs58Eojyob9++BAYGMmLECD744ANTlyOEECKT6fUK284/4Zt9NwiPS8HFzpLlPapTo2gG7uRoU+DILC6dW8F4Z1vu29uhAj6p/Cm9yvXC3tI+y+o3BQlEedC2bdtMXYIQQogs8uB5Al/uusaf18MBKOZmx7Ie1SnlkYHBzomRhKxrz/fJD/gtvyNalQonC3u+qDWWNsXbZFHlpiWBSAghhHhLBN6PpPuK06Tq9JirVQx7vxR96hTF1jIDX/d3D3L+j1F8Yp1MkqPhLlBD74ZMrzsdR0vHLKrc9CQQCSGEEG+BLWcfMWPvDVJ1eqoWdmZamwpULJSBTVTjI9Acnc13dzaz0dEenUpNWfvCjKn7Za6fQZYeEoiEEEKIXCz4WQKzf7/BnsuhAJQr4MhPfd/BMQMDp3V3DrBv58csdbDigZPh0Vpdz1rMeO9bnK2ds6LsHEcCkRBCCJFL7b8WxvBNF4hL0QIwpFEJPmtYAmuLdO5Qr9ejvfILI09M4ICL4fGYs7kdU+pOp3ERv6wqO0eSQCSEEELkMoqisPbUA6btuoZGp1DF25kZ7StStkAGxviEXeP+9n4MU0dyx9YKNTCw0qf0qNA7V+1BllkkEAkhhBC5yK2wOGbuvcHBG4ZZZHVKuPJDr5rpvyukTeXpH2P4PngHv9lZo1NZ4qS2ZGztibQs2TbrCs/h1KYuQIj/avXq1Tg7OxtfT5kyhSpVqpisHiGEyEp6vcLqE8G0WXScgzfCUatgdLMy/Nj7nQyEoRQCf+nGB2G/s9XeBp1KRV2Pd9jSbleeDkMggSjPUqlUr/0zZcoUAM6fP0+nTp3w8PDA2tqakiVL0r9/f27dumXaDgCdO3fOEXUIIURW0+sVpu26xpSd10jW6PEt5sofw95jYIPiWJqn46tcUdBe+YVlq2rTP/kGyWo15W08+Ln5zyxt9gMF7AtkfSdyOHlklkeFhIQY/3nTpk1MmjSJmzdvGt+zt7dn165ddOjQgaZNm7Ju3TqKFy9OeHg4W7ZsYeLEiWzatMkUpRvZ2NhgY2Nj0hqEECKrXXkSw4y91zlx5zkAQxqXZHCjEliYpe+ehi4uhD27P2VZ/E0eWlkAKuo7l+HrZitxssrAtPy3nNwhyqM8PT2Nf5ycnFCpVGneU6vV9OnThxYtWrBjxw78/Pzw8fGhVq1afPvtt3z//ffGax05coR33nkHKysrChQowJgxY9BqtcbjDRo0YPDgwQwdOpR8+fLh4eHBihUrSEhIoE+fPjg4OFCiRAn27t1rPOfw4cOoVCp2795NpUqVsLa2pnbt2ly5csXY5u+PzF5l5cqVlC1bFmtra8qUKcOSJUsy74cohBBZKClVx5LDd2i/5CQn7jzHwkzF9LYVGOZXMt1hSPv8Lp9vasq4lHs8tLAgn9qKSTVGsfiDLRKG/kbuEGUBRVFI0iaZ5LNtzG1QqVRvfJ3ff/+dZ8+e8cUXX7zy+Isg8uTJE1q0aEHv3r1Zs2YNN27coH///lhbWxsfuwH89NNPfPHFF5w5c4ZNmzYxcOBAtm3bRrt27Rg3bhxz586lR48ePHz4EFtbW+N5o0aNYv78+Xh6ejJu3Dhat27NrVu3sLD49/U11q1bx6RJk1i0aBFVq1bl/Pnz9O/fHzs7O3r16vVGPx8hhMhKGp2eritOceFRNAANS+dnapsKFHa1ff2JL+h1PDizhKkXFxFobYmZojCoWFu6+47D1iKd18hjJBBlgSRtErXW1zLJZ5/udjpT/mO/ffs2AGXKlHltuyVLluDt7c2iRYtQqVSUKVOGp0+fMnr0aCZNmoRabfgtpnLlykyYMAGAsWPHMnPmTNzc3Ojfvz8AkyZNYunSpVy6dInatWsbrz958mTef/99wBCqChUqxLZt2/jwww//tQ+TJ0/mu+++o3379gD4+Phw7do1vv/+ewlEQogc61ZYHOO2XubCo2jsLM2Y+kEF2lUtiJk6fb/sPr53gGUHR7DLXIvO2hIbRcW0qkNpVrlfFleeu0kgEq+kKEq62l2/fh1fX980d6Xq1KlDfHw8jx8/pnDhwgBUqlTJeNzMzAxXV1cqVqxofM/DwwOA8PDwNNf39fU1/rOLiwulS5fm+vXr/1pXQkICd+/epV+/fsbQBaDVanFyktvEQoicJ1mj4/sj91h+9C4JqToszdUs6laNhmXc032NU0HLGHR5EakWKkDFe7beDGkwm1L5y2dd4W8JCURZwMbchtPdTpvsszNDqVKlALhx40aaUPJf/f0Rl0qlSvPei0Cl1+vf+LMA4uPjAVixYgW1aqW9W2dmls7pqUIIkU2exafQf81Zzj+MBqB6kXws6FqVgs7p+ztdkxLPrzt68U3CTbQqFZUUC0Y3mk+lwvWysOq3iwSiLKBSqXL9M9omTZrg5ubGrFmz2LZt20vHo6OjcXZ2pmzZsvz6668oimIMNSdOnMDBwYFChQq9cR2nTp0y3mWKiori1q1blC1b9l/P8/DwwMvLi3v37tG9e/c3rkMIIbLKlScxDN98gVth8dhamvF1u4q0qeyFOh2PyLSaZHYfm8qy+7t4bAaoVPiq7Pmu3S84OBbM+uLfIhKIxCvZ2dmxcuVKOnXqRJs2bRgyZAglSpTg2bNnbN68mYcPH7Jx40Y+++wz5s2bx+DBg/H39+fmzZtMnjyZ4cOHG8cPvYlp06bh6uqKh4cH48ePx83NjbZt26br3KlTpzJkyBCcnJxo1qwZKSkpnD17lqioKIYPH/7GtQkhxJtISNGy+NAdfjgeTIpWj72VOes+rkVlb+d0na/o9Xy+oSFHlXgwAxe9wsfF2tK13hTM1fL1nlHyExP/6IMPPuDkyZPMmDGDbt26ERsbi7e3N40aNWL69OkAFCxYkD179jBq1CgqV66Mi4sL/fr1Mw6gflMzZ87k888/5/bt21SpUoWdO3diaWmZrnM//vhjbG1tmT17NqNGjcLOzo6KFSsydOjQTKlNCCH+qwuPohm79TLXQ2IBqFvCjTkfVsbd0Tpd5wcHH2L+8QkcVeIxVxQGudagW+NvsbV1y8qy32oqJb2jZ/Ow2NhYnJyciImJwdEx7cZ5ycnJBAcH4+Pjg7V1+v5DFv/u8OHDNGzYkKioqH9dayizyL9LIUR2OBMcSZ8fz5CQqsPR2pxZHSvTtLxHupZMeRrzgMV/DmFX3F30KhUqReHLwq34oNHMbKg893nd9/ffyR0iIYQQIhvEJGlYeOA2PwXcR6NTqFDQkVW9a+LukL5fwG7dP0S/Q0OIVgMqFQ1U9gyqPZYypdtkbeF5hAQiIYQQIosduhHOl7uvcS8iAYD3y3nwbafKONn8+yKzGp2GbWcXsOjaj0SrVZTV6Jhc+iPK1x0LmbAQrzCQQCRypAYNGqR7LSQhhMjJtp57zPDNFwFws7didqdKNCiVP12PyPbf2MJ3Z2byREkFtYpyWoXlrTbh5FnxX88VGSOBSAghhMgCKVodM/bc4KeA+wC0rFSALz+ogItd+iaGLNw/hOVPDwHgqtXR36YoHdv/gJWD7EyfFSQQZRK5m5H7yb9DIURmOXQjnK/2XOdOuGGR2Aal8zO7YyVsLf/9a/fu8+ssPjyG/fH3AOieAp+3WI1NoXeytOa8TgLRG3qx2nJiYiI2NpmzSrQwjcTERODlVbWFECIjFhy4zZz9twBwsrFgdsdKNCnv+a/nRSVH8c3Rsex5egLlf0/TBpKPz/r8ARYy8zWrSSB6Q2ZmZjg7Oxv34LK1tc2U3eZF9lEUhcTERMLDw3F2dpatPYQQ/0lSqo7JO66w+exjALrU9GZsi7LpGjj9IPoeA3Z25qk+GVTQOCmVz8r3pZTvMDBP3yM28WZMGoiOHj3K7NmzCQoKIiQkhG3bthlXIdZoNEyYMIE9e/Zw7949nJyc8PPzY+bMmXh5eRmvERkZyeDBg9m5cydqtZoOHTowf/587O3tjW0uXbrEoEGDCAwMJH/+/AwePJgvvvgi0/rh6WlI/n/fmFTkLs7OzsZ/l0IIkRF7L4cwc98NHjw33Gn+9L3ijGle5l/P0+g0bL2xgSVB84hUNLhrtcyzq0DFVjPBtXhWly3+H5MGooSEBCpXrkzfvn1p3759mmOJiYmcO3eOiRMnUrlyZaKiovj8889p06YNZ8+eNbbr3r07ISEh7N+/H41GQ58+fRgwYADr168HDIsyNWnSBD8/P5YtW8bly5fp27cvzs7ODBgwIFP6oVKpKFCgAO7u7mg0mky5psheFhYWcmdICJFh8Slapu64ypYgw10hVztL5nWpQr2S+f/13MDQQCYcGs7T1GgACmq0/FhxMAVqfZaVJYt/kGNWqlapVGnuEL1KYGAg77zzDg8ePKBw4cJcv36dcuXKERgYSI0aNQDYt28fLVq04PHjx3h5ebF06VLGjx9PaGioccuHMWPGsH37dm7cuJGu2jKy0qUQQoi8ITZZw4A1Zzl1LxKAPnWKMrJJaeys/v1ew9xjE/nx3nYUIL9Wy8epFnT0HYNllW5ZXHXekpHv7zfffTMbxcTEoFKpjFs5BAQE4OzsbAxDAH5+fqjVak6fPm1sU79+/TT7XzVt2pSbN28SFRX1ys9JSUkhNjY2zR8hhBDihSO3Img+7xin7kViYabih141mNy6/L+GoTtRdxi6/1NW/S8MNY9PZJdHU7r1PythyMRyzaDq5ORkRo8eTdeuXY0pLzQ0FHd39zTtzM3NcXFxITQ01NjGx8cnTRsPDw/jsXz58r30WTNmzGDq1KlZ0Q0hhBC52KPIRL794yY7Lj5FUcDD0Yol3atTvcjL3yX/X4ouha8DprHt7g4UQKUo+KeYMaDzPnArmT3Fi9fKFYFIo9Hw4YcfoigKS5cuzfLPGzt2LMOHDze+frHLuxBCiLwrJlFDh6UnCY9LAaBj9UJ8+UEFbCxfP/7wXvQ9Bv7el6fJzwF4PyGRgeSjZOdNMnA6B8nxgehFGHrw4AEHDx5M8wzQ09PzpZldWq2WyMhI42whT09PwsLC0rR58fqfZhRZWVlhZWWVmd0QQgiRi+27EsKE7Vd5Fp+Cq50lP/V9hwoFnV57TqoulV9u/cLSoHlE65Jw1eqYHp1I3cYzoNKHoJaJHDlJjg5EL8LQ7du3OXToEK6urmmO+/r6Eh0dTVBQENWrVwfg4MGD6PV6atWqZWwzfvx4NBqNccG9/fv3U7p06Vc+LhNCCCFeCIlJYuqOa+y7ahiGUdDZhjkfVv7XMHQq5BQTj48nNNHwS3thjYZVthXxaP8t5CuS5XWLjDNpIIqPj+fOnTvG18HBwVy4cAEXFxcKFChAx44dOXfuHLt27UKn0xnHBbm4uGBpaUnZsmVp1qwZ/fv3Z9myZWg0Gvz9/enSpYtxraJu3boxdepU+vXrx+jRo7ly5Qrz589n7ty5JumzEEKI3OHKkxh6/xjIs/gUVCroUbsI41uWxcr89Xd2ZgfO5udra1AAd62WATFxtC/dBYtmM8BMVsLPqUw67f7w4cM0bNjwpfd79erFlClTXhoM/cKhQ4do0KABYFiY0d/fP83CjAsWLPjHhRnd3NwYPHgwo0ePTnedMu1eCCHylm3nHzPpt6vEJWsp4mrL9z2qU8bz9X//34y8yaLzCzn8+AgAreMSmIgrNs1mQAm/7Chb/E1Gvr9zzDpEOZkEIiGEyBsePk9kys6rHLxheNRV0t2ejQNq42r/z+NKU3QpLL2wlB+u/AAYZpANjYqmb82R8O5gGStkQhn5/s7RY4iEEEKI7LLl7CO+2nOd6EQNZmoV/esVY0STUliY/fOSfbeibjHoz4HGsUJN4hMYFJtEsSYzoXqv7CpdZAIJREIIIfK8NQH3mfTbVQDKFnBkcbeqFMtv/4/tU3QpbLm5haUXFhOriSe/VsuwyGhau1WDj5aDU8HsKl1kEglEQggh8qzn8SkM23yRo7ciAGhXtSCzO1bC/DV3ha49v8aIwyN4HG/Yv6xoqoYfEy1wa7EUyrYBda7aBEL8jwQiIYQQeY6iKPx44j7z/rxFbLIWCzMVgxuVZFDDEpipVf94zowzM9hwYwNg2IPs0+hY2mnMsPj4ILiVyM4uiEwmgUgIIUSeoigKS4/cZda+m4Bh4PTCblVfO4vsRuQNFpxbwLEnxwBoFp/A6MhY3Gr2h7rDwN79H88VuYMEIiGEEHlGaEwyQzae50ywYYf6YX6l8G/0z3eFUnQpLDq/iNVXVwOgVhRGRkbTw9YHuv8Ixd7LrtJFFpNAJIQQ4q2n1xvuCi05dIeEVB1W5mr61fVhcKMSqP8hDN2IvMGgA4MI/98MsmbxCQyMjqFYpR7Qco6MFXrLSCASQgjxVtPq9Az4Oci4tlB5L0cWdauGj5vdK9un6FLYfHMzSy8sIU4Tj7tWy8jIaJqnAo2nQ61PQfXqECVyLwlEQggh3loPnicwaP05rjyJRa2CaR9UoNs7hf/xrtD159eZFjCNK8+vAFA8NZVVIeG4VOwM738J9vmzs3yRjSQQCSGEeOvo9Apz999i5fF7JGv02FiY8W2nyrSsVOCV7RVFYfqp6Wy+tRkAB73C8MhIPohLxKLd94bd6eWu0FtNApEQQoi3yv1nCQzecJ7LT2IAqFbYmYXdqlHQ2eaV7a8/v868c/M4+fQkAC3iE/CPisHbwRt6LQSfetlWuzAdCURCCCHeGrfD4uj9YyBPopOwtTTjq3YVaFulIKpX3N1J1iaz9vpaFp5fiF7Ro1YUxjyPomuyHnw/h3eHgI1z9ndCmIQEIiGEELnei1lk8/+8TapOT34HK3799F0Ku9q+sv3VZ1cZfHAwEUmGFaobJiYz4nkkRWw9oP9WcC+TneWLHEACkRBCiFztypMYRm65yI3QOAB8i7myoGtV8ju8vEO9XtGz9tpall5cSrwmHg+9ikHPn/FBfALqInWh9TxwK5nNPRA5gQQiIYQQudad8Dh6/HCaqEQNDlbmjGpWmh61i7zyEdnV51eZFzSPUyGnACiRmsrqkHCcLByg8zoo01IGTudhEoiEEELkOlqdnvkHbrP08F20eoWyBRxZ/3Et8tlZvtRWURSmBExh6+2tAJijYuTzSDrHxmH+zgBoOA5s8mV3F0QOI4FICCFErhJ4P5LRv17iXkQCAPVL5eerthVeGYbuRN3hm8BvjHeFWick80lkJEW0WqjZH5rPkrtCApBAJIQQIhf57cIThm++iE6v4GxrwfgWZelUw/uldknaJDbe2Mj3l74nQZOAmQLjnz+nU1wCFKoJTaZD4dom6IHIqSQQCSGEyPFStXpm7r3BqhPBADQq4868LlVwtLZ4qe3FiIt8fvBznic/B6Cq3pzpTx5SWDGDhhOgzhAwf3nAtcjbJBAJIYTI0Y7djmDctss8ikwCoE1lL+Z8WBlzs5c3V912exszz8wkUZtIAbU1n4WH0CouDnMrJ+i4Ckr6ZXf5IpeQQCSEECJHUhSFKTuusubUAxQF3OytmNqm/Cu337jy7AqLzi/ixNMTAJTRwQ8PbuOoV6DE+9D0a8hfKru7IHIRCURCCCFynGSNjnFbL7P1/BMA2lcryPS2FbC1TPu1pVf0TDwxkR13dwBgjpp+8Sl8GhGCuY0LtFsGpZpme/0i95FAJIQQIkc5/zAK//XneRJteEQ2tU15er1b9KV24YnhjD02ljOhZwBoo87Hpw+u4K3VQb6i0PcPcPDIxspFbiaBSAghRI7w97tCno7WfN2+Ao3KpA01iZpE1t9Yz49XfiQ2NRZz1Ex69px2cQ8BFTQcD77+YPnqbTuEeBUJREIIIUwuKVXHyF8usvtSCACtK3sxvW0FnGzSziI7F3aOYYeHEZkcCUBxy3zMuXeNYhqNYaxQowngVSW7yxdvAQlEQgghTCrg7nOGbDxPRFwKAD/2qUnD0u4vtdtyawuzA2eTpE2ioLUbg54/o0XwRcwAqnSHDxbLIoviP5NAJIQQwiRikzWM/uUSe6+EAlAonw1jm5d9KQxdirjEovOLCAgJAKCc2o5VNy5gp+jB3gPqj4LqvSUMiTcigUgIIUS2C49LptOyAB48T0StgvbVCjG1TXnsrP76WtLpdYw7Po49wXsAMFeZMUBxYMDdS4a7QmXbQOv5YOtimk6It4oEIiGEENnq0I1whm2+QHSiBjd7S5b3rEG1wmk3V41NjWXcsXEceXwEgHbO5fnk7nkKxgaDuTX02A5FfE1QvXhbSSASQgiRLSITUhmx+QKHbkYAUMzNjkXdqlHOy9HYJkGTwLrr61h9dTVxqXGYq8yYpvak9fm9hgZO3tBmgYQhkekkEAkhhMhyx25HMHjDeaITNZirVXR5x5sJLcthbWFmbBMYGsiIwyOISokCoJhtASY/uEm1+GBQqaHxJKj9mexDJrKEBCIhhBBZRlEUjt95xucbDY/IfNzsWPy3u0IABx4eYOyxsSRpkyhkX5BBVoVpfnaTYayQZ0VovwLcy5qkDyJvkEAkhBAiS0QnpjJ262XjLLLyXo78OvDdNHeFLoRfYNH5RZwOPQ1ARTtvVgbfwTbeMKOMcm2hxbdgnz+7yxd5jAQiIYQQme63C0+YsO0KcSlazNUqPqpdhKF+JY1hSKvXMvroaP548AcA5mpzOjuWZcT53VgAOBWGBmOgSjeZTi+yhQQiIYQQmUZRFHZdCmH45ovo9AplPB2Y2qY8tYq5GtvEpMQw+thoTjw5gQoV7Yo045PHt/A6v9vQoEp3aDVXxgqJbKU25YcfPXqU1q1b4+XlhUqlYvv27WmOK4rCpEmTKFCgADY2Nvj5+XH79u00bSIjI+nevTuOjo44OzvTr18/4uPj07S5dOkS9erVw9raGm9vb2bNmpXVXRNCiDznWXwKfVYHMnjDeXR6hRYVPdk9pJ4xDMWnxrPs4jKa/9qcE09OYK42Z5ZHQ6ae3oLXnUOgMoNaAw0rTksYEtnMpIEoISGBypUrs3jx4lcenzVrFgsWLGDZsmWcPn0aOzs7mjZtSnJysrFN9+7duXr1Kvv372fXrl0cPXqUAQMGGI/HxsbSpEkTihQpQlBQELNnz2bKlCksX748y/snhBB5gaIorAm4T/1Zhzh8MwJLczWf1C/Gd52qYKY2PO4KeBpAs63NWHxhMXGaOEo4l+BHnRvNTq2GpEhwLQkDT0DzmfKITJiESlEUxdRFAKhUKrZt20bbtm0Bw//BvLy8GDFiBCNHjgQgJiYGDw8PVq9eTZcuXbh+/TrlypUjMDCQGjVqALBv3z5atGjB48eP8fLyYunSpYwfP57Q0FAsLS0BGDNmDNu3b+fGjRvpqi02NhYnJydiYmJwdHT89xOEECKP0OsVvtx9jR9P3AegUiEnvvygApW9nY1tToWc4osjXxCVEkVhh8L4ezej6aWdqB+dBksHQwiq1AXMZBSHyFwZ+f426R2i1wkODiY0NBQ/Pz/je05OTtSqVYuAAMPsg4CAAJydnY1hCMDPzw+1Ws3p06eNberXr28MQwBNmzbl5s2bREVFvfKzU1JSiI2NTfNHCCFEWqExyXRZccoYhj5vXJLfBtUxhqFzYefo+3tf+v/Rn6iUKMo4l+RXh+o03z3BEIbUFvDBQqj6kYQhYXI59r/A0FDDNE0PD48073t4eBiPhYaG4u6edhNAc3NzXFxc0rTx8fF56RovjuXLl3a5eIAZM2YwderUzOmIEEK8ZfR6he0XnjBu22WSNXpsLMwY0aQUH9crBoBGp2HU0VEceHgAAAu1BR09fBl0YQ/WiYb3qNQZGk0A58Km6oYQaeTYQGRKY8eOZfjw4cbXsbGxeHt7m7AiIYTIGRJStPT44TTnHkYDULWwMzPaV6SMp+FxRExKDLMDZ3Pg4QHUKjXtS7ZngHVRCuz+ArTJ4FLMEITKt5exQiJHybGByNPTE4CwsDAKFChgfD8sLIwqVaoY24SHh6c5T6vVEhkZaTzf09OTsLCwNG1evH7R5u+srKywspIZDkII8f89jkpk0m9XOfcwGitzNZ++Vxz/RiWwMFMTlxrH2mtrWXNtDfEaw0zfbyr50+zCb3B/juEChd6Bnr+Bpa0JeyHEq+XYMUQ+Pj54enpy4MAB43uxsbGcPn0aX1/Dpn6+vr5ER0cTFBRkbHPw4EH0ej21atUytjl69CgajcbYZv/+/ZQuXfqVj8uEEEKkpdMrrD31gEbfHuHgjXAszFT82Lsmw94vhYWZmpuRN2m1rRVLLi4hXhNPSeeSLPFqRrPdk+H+MTCzBF9/6LNHwpDIsd7oDlFycjLW1tb/+fz4+Hju3LljfB0cHMyFCxdwcXGhcOHCDB06lOnTp1OyZEl8fHyYOHEiXl5exploZcuWpVmzZvTv359ly5ah0Wjw9/enS5cueHl5AdCtWzemTp1Kv379GD16NFeuXGH+/PnMnTv3TbouhBB5QkhMEn1+DORGaBwAtXxcGNuiLFW8nVEUhYCQAMYeG0tkciRFHIvgX3EATW6dQH1imeECRepAu+/BWYYdiBxOySCdTqdMmzZN8fLyUszMzJS7d+8qiqIoEyZMUFauXJmhax06dEgBXvrTq1cvRVEURa/XKxMnTlQ8PDwUKysrpXHjxsrNmzfTXOP58+dK165dFXt7e8XR0VHp06ePEhcXl6bNxYsXlbp16ypWVlZKwYIFlZkzZ2aozpiYGAVQYmJiMnSeEELkZvci4pVm844qRUbvUipO3qcsOXRH0er0iqIoSmBIoNJrby+lwuoKSoXVFZROOzopMTd3K8rSuooy2dHw5/cJiqLTmbgXIi/LyPd3htchmjZtGj/99BPTpk2jf//+XLlyhWLFirFp0ybmzZtnnBL/NpF1iIQQeYlGp+enk/eZsfcGOr2CvZU5ez+vh7eLLXpFz1envmLzrc0AWKot+bBEWwY+uYfjla2GC1g6GKbTl2srA6eFSWXk+zvDj8zWrFnD8uXLady4MZ9++qnx/cqVK6d7oUMhhBA5062wOD79OYh7zxIAqF8qP+NalMHbxZbo5Gi+Pfstv939DbVKTadSnfi4eAc8d48yjBVSqaFmf6g3HBxePWlFiJwqw4HoyZMnlChR4qX39Xp9moHLQgghcpez9yPp8cMZkjQ6XOwsGdyoBL3fLUqCJoFF5xex9vpaEjQJqFAxvc50Wofdh+WNQZNgWGSxyzoo1dTU3RDiP8lwICpXrhzHjh2jSJEiad7/5ZdfqFq1aqYVJoQQInukaHV8f+Qec/+8haJAxYJOrOpdk/wOVtyLucfQQ0MJjgkGoIxLGYYVfJ93D86DJ2cNF/CqCk2mQ9G6puuEEG8ow4Fo0qRJ9OrViydPnqDX69m6dSs3b95kzZo17Nq1KytqFEIIkUVuhcUxbNMFrj41bFHUpJwHMztUIp+tBSeenGDyycmEJYbhau3KuFrj8MMO9U+tQNGDuQ00ngi1P5OxQiLX+0+bux47doxp06Zx8eJF4uPjqVatGpMmTaJJkyZZUaPJyaBqIcTbaOWxe3y15zqKAs62FoxpVobONb05G3aWhecXcj78PAAeth6seW8+XufXw5kVoEuBEn7wwRJw8PiXTxHCdDLy/Z1jdrvPySQQCSHeJskaHT+dvM/s32+i1Sv4lfVgYquyFHaxZcnFJSy7aFhDyMrMig9LfUg/Wx9c/5gCsY8NFyjWADqvBSsHk/VBiPTI0llm/198fDx6vT7NexIYhBAi57ryJIahmy5wJ9ywvUb7qgX57sPKRKdEM+3Ut/xy6xcA2hRvw+dVh+B+5Fs485Xh5HxFoeV3ULyxPCITb50MB6Lg4GD8/f05fPgwycnJxvcVRUGlUqHT6TK1QCGEEG9OURSm777OD8cNg6Pd7K0Y1bQUTSs6s/D8QtZdX0eiNhGAz6p8xqdF26Da/QVc2264QO3PoP4osHUxUQ+EyFoZDkQfffQRiqKwatUqPDw8UMlvCUIIkaMlpGiZ9+ctYxhqW8WLL5qVIVF5wkd7u/Eg9gEAZV3K4l/5M+o/OAcLqhrGCqnMoMmX4DvIlF0QIstlOBBdvHiRoKAgSpcunRX1CCGEyERBDyIZuukCjyKTABjVtDSfNSjOsSfHmHJyChFJEbjbuDOu1jgauddAta4DPA40nFzYFxpPhiK+JuyBENkjw4GoZs2aPHr0SAKREELkYEmpOib9doUtQYaB0F5O1nzRrAzFCj2nx94eXIy4aHjfzoufmv+EZ0wIrGgIkXcN0+mbfAk1P5axQiLPyHAgWrlyJZ9++ilPnjyhQoUKWFhYpDleqVKlTCtOCCFExsUkafjk57OcuheJSgUfVvdmWJMSbAv+iS/3rSRVn4q1mTVdynShb9HW5Dv0DZz7GfQasHaGbpugcG1Td0OIbJXhQBQREcHdu3fp06eP8T2VSiWDqoUQIgc4efcZwzZdICw2BUszNUs/qkaVoubMOzeD7Xe2A1CvYD2m1ZmG2/MH8NMHEPfUcHLJJtDuexk4LfKkDAeivn37UrVqVTZs2CCDqoUQIoeISdIw/8/brDphGDhdxNWWyW1KcSVhE2O3riVJaxhD9Hm1z+lXrjeqK7/A3tGQHA0uxaDNQtl6Q+RpGQ5EDx48YMeOHa/c4FUIIUT2exSZSLslJ3gWnwpAl5redPQ1Y/a54Vx7fg2A8q7l8a/qT12bgvBjs78GTruVhr775K6QyPMyHIgaNWrExYsXJRAJIYSJKYrCkVsRfLnrGs/iUymUz4YJLcti43SLEccmEZkciY25DdPqTKNpocao9k+AwJWg14KVI9QdBu8MACt7U3dFCJPLcCBq3bo1w4YN4/Lly1SsWPGlQdVt2rTJtOKEEEK8WmRCKrN/v8GGM48AyO9gxcQOdqy5OZJLzy4BUMi+EKubrcbD2gUOTIXThi05KN4Ims2E/DJbWIgXMryXmVqt/ueLvaWDqmUvMyFETnL2fiR9VgcSl6wFoJdvYew8D7Lh1mq0ei025jZ0LdOVPuX74Hz/JPw+FqLuG05u+Z1hOr0QeUCW7mX2973LhBBCZA9FUdh/LYzRv14iLllLGU8HBvl5cCp6DT/f2AFAA+8GTPadjJtWB3vHwMUNhpPt8kOjiVC9lwl7IETO9UabuwohhMge4bHJfLXnOr9dMEyRL+5uReN3z/LlxY3GGWQjqo+gV/leqJ7fhY3d4NlNw8k1+kKT6WBpZ6ryhcjx0hWIFixYwIABA7C2tmbBggWvbTtkyJBMKUwIIYTBrktPGbXlEkkaHWoVdPRVc0dZxprrhsBT0a0i/lX9edejJpxdBX9MAE0iWDtB91/A+x0T90CInC9dY4h8fHw4e/Ysrq6u+Pj4/PPFVCru3buXqQXmBDKGSAhhKmtPPWDC9isAVCrkSPN3Ill/71uiU6Kxs7Djyzpf4lfYD1XoJdjcC6IM6xBR2Bdaz5eB0yJPy/QxRMHBwRw9epR3332X4ODgTClSCCHEPwuNSWbu/ltsOmuYRfZ+JRVxjotZcv0qAEUdi7Kq6Sry2+aHe0dgXSfD7vR2+aHeCKjRD8wtTdkFIXKVdI8hatiwISEhIbi7u2dlPUIIkafp9Qq7Locw+bcrRCVqAB01qwZyQbOP5OfJ2Jjb0L1sd3qX742T2hJ+GwTn1xpOLvSOYR8yWWRRiAxLdyDK4Ox8IYQQ/8HwzRfY/r+B0yUL6Cla6hCnwv8EoJp7NWa/Nxt3m/xw7ic4/M1f+5CVbwet5oJNPlOVLkSulqFZZrJvmRBCZI1HkYl8+8dNfrvwFJVKT/2al7iauJ3Q8GQARtccTfey3Q1/Dx+YBse+M5zoWBBaL4CSfiasXojcL0OBqHfv3lhZWb22zdatW9+oICGEyEu0Oj1bzz/hy53XiEvRorZ+jE+ZvZyLuwtA5fyV8a/qT+0CtSH8uiEM3dxjOLnRRPD1BwtrE/ZAiLdDhgKRg4MDNjY2WVWLEELkKckaHb1WneF0cCSgUKLofeId1hOeEoetuS0jaoygU6lOqLQpELAYDnwJ2iRQqaHOUKg/0tRdEOKtkaFAtGDBAhlULYQQmeBuRDxTdlzldHAkdnbP8CixlbDUe6CFYk7F+KHpD7jZuEH0Q1jd0vC/AEXrQcs5kL+UaTsgxFsm3YFIxg8JIcSb0+kV1p95yFe7r5Gs0WDl/gdWbgFEpKZia27LR+U+olf5XjhaOsKjM7CpB8SHgp07NBoPVbqDmcW/f5AQIkNklpkQQmSTR5GJTPrtCoduRqAyj8Wr1B/EmZ1Fo0ANjxrMfm+24a5QfDj8+slfY4WcC0OP7eBa3KT1C/E2S3cgOnToEC4usraFEEL8Fw+eJ9BtxWmeRCdgnf8A1vmPEaekAjC+1ng6l+5suBN/YzfsGAKJzwxjhSp1MexDZudq4h4I8XZLdyB67733srIOIYR4K2l0etaeesD8A7eJ1d/FsfhvKJZP0ClQ1b0qg6sOpqZnTVAUCFgC+yeBXgMuxaHzz+BR3tRdECJPkN3uhRAii1x7GsuXu64RcC8Cc4er2BfeiqJKws7Cji9qfkG7Eu0Md4UenzVMpw8+YjjR5z3Dpqyy9YYQ2UYCkRBCZIGTd57RY9UZ9Ooo7IpuQG3zAAUoma8kK5usxMXaBfR6OPINHJ5hOEltDu9Pg1qfgtrMpPULkddIIBJCiEyUrNGx+uR9Fh+8gbnbbqxcAlBUWmzNbelZvic9y/XEwdIBkmPgzylwdpXhxIqdoNEEyFfUlOULkWep/8tJd+/eZcKECXTt2pXw8HAA9u7dy9WrVzO1OJ1Ox8SJE/Hx8cHGxobixYvz5ZdfppnxpigKkyZNokCBAtjY2ODn58ft27fTXCcyMpLu3bvj6OiIs7Mz/fr1Iz4+PlNrFUKIi4+i6bbiFN/sP43G7WcsXY+hqLRUc6/G+pbrGVRlkCEMBR+DxbX+CkMNx0P7FRKGhDChDAeiI0eOULFiRU6fPs3WrVuNweLixYtMnjw5U4v75ptvWLp0KYsWLeL69et88803zJo1i4ULFxrbzJo1iwULFrBs2TJOnz6NnZ0dTZs2JTk52dime/fuXL16lf3797Nr1y6OHj3KgAEDMrVWIUTetv70Qz5YfIzLcXuxKz4bC0fDL4iTfSezutlqijsXh/AbsOYD+KkVxIUYAlCnn+C9L0DWehPCpFRKBhcY8vX1pVOnTgwfPhwHBwcuXrxIsWLFOHPmDO3bt+fx48eZVlyrVq3w8PDghx9+ML7XoUMHbGxsWLt2LYqi4OXlxYgRIxg50rCEfUxMDB4eHqxevZouXbpw/fp1ypUrR2BgIDVq1ABg3759tGjRgsePH+Pl5fXS56akpJCSkmJ8HRsbi7e3NzExMTg6OmZa/4QQuV9iqpblR++x6OSfWHpsw8w6FDDsTD+k2hCqe1Q3NIwLg+UNDLvTqy2gWg/DXmS2spyJEFklNjYWJyendH1/Z/gO0eXLl2nXrt1L77u7u/Ps2bOMXu613n33XQ4cOMCtW7cAw12o48eP07x5cwCCg4MJDQ3Fz++vXZ6dnJyoVasWAQEBAAQEBODs7GwMQwB+fn6o1WpOnz79ys+dMWMGTk5Oxj/e3t6Z2i8hxNvhwqNoOiw9waLTv2Bd6AfMrEOxt7BnaLWhrG622hCGNElw6GtYWN0QhpwLg38gtJorYUiIHCTDg6qdnZ0JCQnBx8cnzfvnz5+nYMGCmVYYwJgxY4iNjaVMmTKYmZmh0+n46quv6N69OwChoYbfxDw8PNKc5+HhYTwWGhr60v5r5ubmuLi4GNv83dixYxk+fLjx9Ys7REIIAYbtN5YcusOCo2ewKLAOG+dHAJRxKcOK91fgbO1saHj/BPw+DkIuGF57VIROq8HF51WXFUKYUIYDUZcuXRg9ejRbtmxBpVKh1+s5ceIEI0eOpGfPnpla3ObNm1m3bh3r16+nfPnyXLhwgaFDh+Ll5UWvXr0y9bP+PysrK6ysrLLs+kKI3Eur0zN66zl2PV6JVdFTqNQ6bM3t6F2hFz3L9cTOws7Q8MJ62D7Q8M+WDtBmPpRrB+r/NJdFCJHFMhyIvv76awYNGoS3tzc6nY5y5cqh0+no1q0bEyZMyNTiRo0axZgxY+jSpQsAFStW5MGDB8yYMYNevXrh6ekJQFhYGAUKFDCeFxYWRpUqVQDw9PQ0zoR7QavVEhkZaTxfCCHS4/S950zbd5K7+rVYulwDDHuQTfKdhI/T/+76JDyH43MgYJHhdZlW0GI2OL48XlEIkXNkOBBZWlqyYsUKJk6cyJUrV4iPj6dq1aqULFky04tLTExE/bffpszMzNDr9QD4+Pjg6enJgQMHjAEoNjaW06dPM3Cg4TczX19foqOjCQoKonp1w+DGgwcPotfrqVWrVqbXLIR4+8QkaVhy6DY/XtyGpcdWLMxSUaFiWp1pfFD8A8Nq04oCV36FnUMhNc5wYrWe0OI7WXFaiFwgw4Ho+PHj1K1bl8KFC1O4cOGsqMmodevWfPXVVxQuXJjy5ctz/vx55syZQ9++fQFQqVQMHTqU6dOnU7JkSXx8fJg4cSJeXl60bdsWgLJly9KsWTP69+/PsmXL0Gg0+Pv706VLl1fOMBNCiP8vRauj3Q8/E2qxHiuvMABK5yvH+NpjqOpe1dBIUQyPxy5uMLz2rAgNJ0CppjKdXohcIsPT7i0tLSlYsCBdu3blo48+oly5cllVG3FxcUycOJFt27YRHh6Ol5cXXbt2ZdKkSVhaGn7jUhSFyZMns3z5cqKjo6lbty5LliyhVKlSxutERkbi7+/Pzp07UavVdOjQgQULFmBvb5+uOjIybU8I8fY4fDOMyQfW8dxmLSq1BmszO/pV7E3v8r2xNrc2NIp5Alt6w+Mzhtd1PodGk8BMNgIQwtQy8v2d4UD07NkzNm7cyIYNGwgICKBSpUp0796drl27UqhQoTcqPKeSQCRE3vI8PoVv/gxg5+PFmDvcAKCofRnWtlqJk5WToVFqomEPsjMrQJsEFrbQ9Guo0ceElQsh/r8sDUT/X3BwMOvXr2fDhg3cuHGD+vXrc/Dgwf96uRxLApEQeceDyGjabRhHqt1JVCodKszpU+5jPqnSB1sLW0Oj+HBY2wFCLxleF6wB7b4HtxKmK1wI8ZJsC0Rg2G9s7969TJw4kUuXLqHT6d7kcjmSBCIh8ob9N28z+shENFaGbTdKOVZlct2RVMpfydBAUeDGbtg/CSLvGqbTt1sGZVrKWCEhcqCMfH//54fcJ06cYN26dfzyyy8kJyfzwQcfMGPGjP96OSGEMJnIhGSG7f6RoNi1qKxiQVExtPJk+lXt8FejuFDYNxaubjW8tnaGXjugQGWT1CyEyFwZDkRjx45l48aNPH36lPfff5/58+fzwQcfYGtrmxX1CSFElvoxaD/zL8xCZx6KygKscWde42+o4/3Xdj+cXg77J4I2GVRmhoHT7w6WrTeEeItkOBAdPXqUUaNG8eGHH+Lm5pYVNQkhRLb47uRGfrz5DSpzLeht+KBoN8bW7f/XatN6vWEq/b7RoOihUE3wmwpF65i2cCFEpstwIDpx4kRW1CGEENnmSlgwI/6cxVPtcVRqsNYVZ1uHVRRy+n93fJ5egO2fQbhhPBGVuhjGC8lYISHeSukKRDt27KB58+ZYWFiwY8eO17Zt06ZNphQmhBCZLVGTyODfv+TMsz2gMqx4X9SsFas7jcPV1sHQSJNsGDR9dhXoNWDlZHg8VneohCEh3mLpmmWmVquNu8b/fSuNNBdTqWSWmRAiR0rUJNJ5+2fcTwwCwCylNGNrD6Fzpfp/NYoLg51D4NY+w+sS70P75TJWSIhcKtNnmb3YO+zv/yyEEDmdTq9j/dXfWHhuMUmEoygqatsPYX6X3thZ/e+vQL0OrmyFPydD7BNAZVhXqHJnk9YuhMg+/3y75x+sWbOGlJSUl95PTU1lzZo1mVKUEEJkhoCnAby/uTWzzk0miXD0Wnvq2Y9nRYd+f4Wh2Kewqhls/dgQhvL5QN/fJQwJkcdkeGFGMzMzQkJCcHd3T/P+8+fPcXd3l0dmQogc4ejjoww+8Dl6tChaW+ySG7O41WBqFCnwV6Nnd+DnthDzyLDIYp3PofanYOVgsrqFEJknSxdmVBQF1SsGFj5+/BgnJ6eMXk4IITLVo7hHLDy3lL33dwEK2gQfPiw0ibHNq2JtYWZopNPC8TlweCYoOrD3hJ6/gXsZk9YuhDCddAeiqlWrolKpUKlUNG7cGHPzv07V6XQEBwfTrFmzLClSCCH+TaImkW/Pfsuvt7aix3CnWhNdnU8rjGJo4/J/Nby5F34fb9h6AwwDp5vNlH3IhMjj0h2I2rZtC8CFCxdo2rQp9vb2xmOWlpYULVqUDh06/MPZQgiRdTR6DeOPTebPR4bZYdr4Ujglt2JJp7ZUK5zvr4Y39sDGboACtq7QaKLsTi+EADIQiCZPngxA0aJF6dy5M9bW1llWlBBCpIdWr2XXvV0subCMkIQnKIqK5Cfd+eyddvg3LIGl+f/mjcSGGGaQXdoMKFDxQ2g1R8YKCSGMMjyGqFevXllRhxBCZMj159cZdXQUD2IfAKDX2qOPaMPPXT7Gt7iroZFOY9h64+BXEB9qeK9cW2g9Hyxl/0UhxF8yHIh0Oh1z585l8+bNPHz4kNTU1DTHIyMjM604IYR4lavPr/Lx7wOI18Si19qS+vw9Cqobs6SnL+W8/jeTRJMMa9vDg/9tN+RSDDquAq+qpitcCJFjZXgdoqlTpzJnzhw6d+5MTEwMw4cPp3379qjVaqZMmZIFJQohhMHD2IeMOzaObru6Ea+JRZdYmOTgLxhR6xP+HPb+X2Eo/DqsbmEIQ2ZW0GQ6fHpCwpAQ4h9leB2i4sWLs2DBAlq2bImDgwMXLlwwvnfq1CnWr1+fVbWajKxDJIRpKYrCT1d/Yt65eeiU/80giy2Pl7YXP/Soj4/b/3an1yTDnpFwfi2gGPYh67ASSjUxXfFCCJPJ0nWIQkNDqVixIgD29vbExMQA0KpVKyZOnPgfyhVCiH+m0WmYEzSHtdfXAoYZZCkRTSjpVJaVvWrg7fK/sUARN2FtR4h5aHhdtg00nizT6YUQ6ZLhQFSoUCFCQkIoXLgwxYsX548//qBatWoEBgZiZWWVFTUKIfIgrV7Lzrs7+f7S9zyJfwJASkRjlKj3mdKqPN1rFcFM/b9FYq/tgJ2fQ1Ik2OWHtsugpJ8JqxdC5DYZDkTt2rXjwIED1KpVi8GDB/PRRx/xww8/8PDhQ4YNG5YVNQoh8phHsY8Yengot6JuAaBoHUiJ8MPHqjErh9eksOv/uyt08Eu4vtPw2qUY9N4Njl4mqlwIkVtleAzR3wUEBBAQEEDJkiVp3bp1ZtWVo8gYIiGyz83ImwzYP4DI5EjUih2J4e+hiapN5ULurOn7Dk42FoaGl3+B3/xBmwSo4J3+hsHT5nKnWghhkJHv7zcORHmBBCIhst6D2AcsubCEvcF7UVBQNK4kPOiHpeLGkMYlGfhecdRqFWiS4PT3cGAqKHooUhdafgvuZU3dBSFEDpPpg6p37NiR7g9v06ZNutsKIYRe0bP19la+OfMNybpkwDCDLCWsFdULFmNht6oUcLIxNH56HnYOhZALhtdlWkGn1WBmYYrShRBvkXQFohf7mP0blUqFTqd7k3qEEHlIqi6V2YGz2XhzIwBW2hJEPmyOPqUg3WsVZnrbCqhUKkiMhB2D4cYuw4nWzobHY5W7glmGh0IKIcRL0vU3iV6vz+o6hBB5iFav5bc7v/H9pe8JSQgxvPe8MXHhDbG1tGJkq9L0qVPUEIZS4mBrf7jzJ6CCSh9Cw3GQr6hJ+yCEeLvIr1ZCiGz1KPYRU09N5XTIaQAscSb2aWM0MTWoVzI/cztXwc3eChQFTi2Do7Mg8TmYWULP36DIuybugRDibZThQDRt2rTXHp80adJ/LkYI8Xa79vwaA/YPICYlBku1FbYJrXj0oAoqLJjbuTJtqxQ03BUKuwp/TIC7Bw0nuhSHlt9JGBJCZJkMB6Jt27alea3RaAgODsbc3JzixYtLIBJCvCQkPoS5QXPZd38fCgoOZgV4frcLz5M8cLAyZ1LrcrSrWsjQ+EkQrGkLKbGgMoP3p0KtgTJWSAiRpTL8N8z58+dfei82NpbevXvTrl27TClKCPF2eDGDbOH5hUQmRwLgqKvO09tNULRO1PJxYW7nKng52xjGCp1aCsfmGNYWci8PnX8G1+Im7oUQIi/ItHWILl++TOvWrbl//35mXC5HkXWIhMi4VF0qM87M4JdbvwBQyK4oCY878zA0H5ZmamZ3qkSbyl6GR2T3T8Cv/SDOMMAan/egww9gn9+EPRBC5HZZurnrP4mJiTFu9CqEyNsOPzrM9FPTCUsMA6CsdUfOna+CVmeOs60Fcz6sTKMyHobGp7+HvV8Y/tm5CDSeBOXbgdrMNMULIfKkDAeiBQsWpHmtKAohISH8/PPPNG/ePNMKE0LkPg9iH7Dw/EJ+v/87AC5W+dE8a8KZ6xUBaFA6P7M7Via/gxXEhRmm0wcfMZxcvh20nAO2LqYqXwiRh2U4EM2dOzfNa7VaTf78+enVqxdjx47NtMKEELnLlWdXGLB/AHGpcQA0KvgBJ07X4VmcHicbC77tVJn3y3kYptOfWABHv4WUGMN0+ncGwPvT5K6QEMJk1Bk9ITg4OM2fu3fvcurUKb7++mscHBwyvcAnT57w0Ucf4erqio2NDRUrVuTs2bPG44qiMGnSJAoUKICNjQ1+fn7cvn07zTUiIyPp3r07jo6OODs7069fP+Lj4zO9ViHyovjUeL448gVdd3clLjUOH8di1LH5mp0HfHkWp6egsw2/D61vCEN6PWzuAfsnGsKQe3n49Dg0/UrCkBDCpDIciLJTVFQUderUwcLCgr1793Lt2jW+++478uXLZ2wza9YsFixYwLJlyzh9+jR2dnY0bdqU5ORkY5vu3btz9epV9u/fz65duzh69CgDBgwwRZeEeGvo9Do239zMB9s/YO/9vQBUzteAZ3d6s++cGr0CTct7sGdIPTydrCH4KKxsDNd3Aipo9o0hDOUvbdJ+CCEE/IdZZsnJySxcuJBDhw4RHh7+0rYe586dy7TixowZw4kTJzh27NgrjyuKgpeXFyNGjGDkyJGAYXC3h4cHq1evpkuXLly/fp1y5coRGBhIjRo1ANi3bx8tWrTg8ePHeHl5vXTdlJQUUlJSjK9jY2Px9vaWWWZC/E+KLoXpp6az/c52ADztPOlZbAKTt8SjV8DN3op5natQt6SbYR+y43Pg5ELDyeY20GYhVOpkug4IIfKELJ1l1q9fP/744w86duzIO++8Y5gym0V27NhB06ZN6dSpE0eOHKFgwYJ89tln9O/fHzA8vgsNDcXPz894jpOTE7Vq1SIgIIAuXboQEBCAs7OzMQwB+Pn5oVarOX369CvXTpoxYwZTp07Nsn4JkZtdCL/AqKOjCE0IBeCzyoN5+uAdJm5+AoBfWQ8Wdq2KjaUZ3D8OG7oZHo8BVOlumEXm4Gmq8oUQ4pUyHIh27drFnj17qFOnTlbUk8a9e/dYunQpw4cPZ9y4cQQGBjJkyBAsLS3p1asXoaGGv5A9PDzSnOfh4WE8Fhoairu7e5rj5ubmuLi4GNv83dixYxk+fLjx9Ys7RELkZfdi7rHo/CL2P9gPgIetB00L9OGnPZ6ExhrCUNsqXsxoXwkbCzXc+t2wQ31KDLiVBr/JULoFZOEvUUII8V9lOBAVLFgwSwZPv4per6dGjRp8/fXXAFStWpUrV66wbNkyevXqlWWfa2VlhZWVVZZdX4jc5mLERT7Z/wkJmgRUqGju05wyFr2Z+ts9IJkCTtZMalWO5hULQGwIrO0DDwMMJ7uXg377wcrepH0QQojXyfCg6u+++47Ro0fz4MGDrKgnjQIFClCuXLk075UtW5aHDx8C4OlpuO0eFhaWpk1YWJjxmKenJ+Hh4WmOa7VaIiMjjW2EEK+WrE3my4Av+WjPRyRoEiiVrxTrmm9GH9btf2EIWlUqwKGRDQxh6MR8WFjdEIbMbaDO59Bnj4QhIUSOl+E7RDVq1CA5OZlixYpha2uLhYVFmuORkZGZVlydOnW4efNmmvdu3bpFkSJFAPDx8cHT05MDBw5QpUoVwPB46/Tp0wwcOBAAX19foqOjCQoKonr16gAcPHgQvV5PrVq1Mq1WId4mWr2WLbe2sOLSCiKSIgBo7tOcGg696LP8Mc/iU1CpoOs7hfnygwqY6ZJhzyQ4s9xwAa+q0H4FuJU0YS+EECL9MhyIunbtypMnT/j666/x8PDI0kHVw4YN49133+Xrr7/mww8/5MyZMyxfvpzlyw1/6apUKoYOHcr06dMpWbIkPj4+TJw4ES8vL9q2bQsY7ig1a9aM/v37s2zZMjQaDf7+/nTp0uWVM8yEyOuStclMDZjKrnu7AChgV4DRNcew+5QLX+y5D0BhF1umflCehqXyG8YKHZgG4VcNF/D1hybTZayQECJXyfC0e1tbWwICAqhcuXJW1ZTGrl27GDt2LLdv38bHx4fhw4cbZ5mBYer95MmTWb58OdHR0dStW5clS5ZQqlQpY5vIyEj8/f3ZuXMnarWaDh06sGDBAuzt03cbXzZ3FXnFtefXGH98PHei7wAwvPpw2vh8yNhfr/PHNcOj6d7vFmVci7JY6pNgxxC4Yti8FSsnaLdUBk4LIXKMjHx/ZzgQVatWjSVLllC7du03KjI3kUAk3nZ3o++y8PxCDjw8AICLtQtj3hlDUlRFpu26RnSiBjO1ipntK9KphjfEPoVtnxr2IVOZwbv+UGeo7EMmhMhRsnQdopkzZzJixAi++uorKlas+NIYIgkMQuQulyIu8fEfH5OkTUKFihbFWtC5+ADm7I3g2O2LABTLb8dXbSvi65MPLm6EnUNBm2QIQ13WQWnZ2FkIkbtl+A6RWm2YmPb3sUOKoqBSqdDpdJlXXQ4hd4jE2yhJm8SmG5tYfGExybpkyrqUZUa9GbhaetPrx0AuPorGXK2if/1ijHi/FObhl2H7IAi7bLhAoZrQ5CsoLJMThBA5U5beITp06NB/LkwIYXoavYbNNzez8vJKniU9A6CWZy1m1pvJ+fs62m0+RGyyFgcrc7YM9KWMpyNE3II1bSEpEiwdDI/I6o0AM4vXf5gQQuQSGQ5E7733XlbUIYTIBhqdhnHHx7Hv/j4ACtoX5JNKn/CuRxOGrr/C8TuGgFTKw55ZHStTxtUCdo+AoNWg14JHBei5A+xcTdgLIYTIfBkOREePHn3t8fr16//nYoQQWefqs6vMCpzFuXDDBsyjaoyia5muhMVqaLs4gJCYZCzN1HxUuwhfNC2F9a0dsP1reH7bcIFiDaHVXAlDQoi3UoYDUYMGDV567/+PJ3obxxAJkZvdjrrNwvMLOfTI8LjbysyKae9Oo7lPc3ZcfMrYrZdJTNVRwMmaVb1rUtbTAfaNhdNLDRewyWdYZLHk+ybshRBCZK0MB6KoqKg0rzUaDefPn2fixIl89dVXmVaYEOLN3Yu5R7fd3UjWJaNWqWlVrBWfVvoUCyU/nZYFcPaB4f/PFQo6Mq9zVUpYPIPNn8H1nYYLvDsE6o8EaycT9kIIIbJehgORk9PLfzG+//77WFpaMnz4cIKCgjKlMCHEf5eoSWTjzY38cPkHknXJVHCtwFf1vqKYUzH2XwtjyIbDJGl0WFuo6VvHh2GNi2Nxch4cmWkYK6RSG1ab9h1k6q4IIUS2yHAg+iceHh4v7TsmhMh++x/sZ/qp6UQmG/YVLJWvFAsbL8TFypWNZx4yYfsVtHqFcgUcWdStKsUcgdVN4cn/fpkp1hAaTYRC1U3XCSGEyGYZDkSXLl1K81pRFEJCQpg5c6Zxg1UhhGmsurKKuUFzAcMMsoGVB9KyWEueRqXSe+VxrjyJBaBeSTd+6FUTy7ALsLQ3RD8ACztoOh1q9DVdB4QQwkQyHIiqVKmCSqXi7+s51q5dm1WrVmVaYUKI9LsccZlFFxZx8ulJADqW6si4d8ZhrjZn7v5bLDt6j1StHnsrcwbUL4Z/DTvUOwfBpY2g6MEuP3RaDUXrmrYjQghhIhkORMHBwWleq9Vq8ufPj7W1daYVJYRIn0RNIrPPzuaXW4YNVs1V5vQo14Nh1YehV2DZkXssOGjYqPWdoi7M7VKFggnXYWVriAsxXKRMK/hgkWE2mRBC5FEZDkRFihTJijqEEBkUnhhOz709eRL/BIAPin/AJ5U/wdvBm0eRiQzffIHA+4ZZZJ83LsnQxsVRnf8Z/pwCSVGQzwc6/CBjhYQQAlCnt+HBgwcpV64csbGxLx2LiYmhfPnyHDt2LFOLE0K8LFGTyMrLK2n3WzuexD/B1dqVhY0WMr3udAraFWLxoTs0+u4wgfejsLM0Y3yLsgytAqqN3WHn54Yw5FYKPj4gYUgIIf4n3XeI5s2bR//+/V+5OZqTkxOffPIJc+bMoV69eplaoBDiL4GhgXxx9AvjHmQ+Tj589953lMxXEo1Oz4RtV9h09hEAdUq4MqlVeUqH7oRln4Mu1TCdvvFkqPUpWMhjbiGEeCHdgejixYt88803/3i8SZMmfPvtt5lSlBDiZcsvLWfh+YUAFLIvxGdVPqOFTwvM1Gbci4hnyMbzxllkE1qW5ePaXnBqMRyYZriAz3vQ9GvwrGCqLgghRI6V7kAUFhaGhcU/72xtbm5OREREphQlhPjLxYiLLDq/iFMhpwBoWawlE2pNwN7SHo1Oz9zfb7L0yF10egUnGwvGNC9D18IxsLIxhF0xXKRyV2izCMwybekxIYR4q6T7b8eCBQty5coVSpQo8crjly5dokCBAplWmBB53YuxQisurwDAXG1On/J9GFx1MCqViphEDZ2XB3AjNA6ARmXcmdS0KEVPjoM9mw0XsXWFRhOgWi9Qm5mqK0IIkeOlOxC1aNGCiRMn0qxZs5em2CclJTF58mRatWqV6QUKkReFJoTSY28PQhNCAWjh04Ih1YZQ0L4gADdD4/hsXRB3IxJwsDJncpvydKyYD7Z98tc+ZOXbg99kyFfURL0QQojcQ6X8fYXFfxAWFka1atUwMzPD39+f0qVLA3Djxg0WL16MTqfj3LlzeHh4ZGnBphAbG4uTkxMxMTGvHFQuRGZJ1CSy9vpaVl9ZTZwmjvw2+RlZYyTNfZqjUqlI0eqYufcGq0/eR1HA1c6Slb1qUDV6P/w+HhLCARX02ArFG5m6O0IIYVIZ+f5O9x0iDw8PTp48ycCBAxk7dqxxpWqVSkXTpk1ZvHjxWxmGhMguF8IvMOnkJIJjDIufFncqzpyGcyjmVAyAwPuRDN14gSfRSQA0r+DJ5FrgeXwg3NpruIhzEWjypYQhIYTIoAyNsCxSpAh79uwhKiqKO3fuoCgKJUuWJF8+WeFWiDex+MJill1cBkB+m/yMqDGCZkWbYfa/cT+XH8cwaN05wuNScHewYnLr8rR0Coaf24E22TCd/t0hhvFCZv88+UEIIcSr/acpJ/ny5aNmzZqZXYsQec7V51eZc3YOZ0LPANCmeBuGVB2Ch53hbmtSqo6lR+6y4MBtAEq427P148o4XlwFv80EXQoUrAHtloFbSZP1QwghcjuZgyuECcSnxrP2+lpWXl5Jii4FC7UF/Sr2Y1CVQcY2Fx9F8+naIEJikgFoWbEA06vF4rj8HYgPMzQq4QftV4Ctiym6IYQQbw0JREJksyfxT+i5tyfhieEA1PGqw2TfyRSw/2vZiqO3Ivj4p7Ok6vQUdLZh2Pul6JCwEdWmLw0NnItAg7FQ6UOZTi+EEJlAApEQ2SRVl8qqK6v46epPxGvicbd1Z2SNkTQt2hS1yrCtYEKKlnl/3mLFMcPA6ppF87Gicymc/xgG13cYLlSxE7T8DqydTNUVIYR460ggEiIbBIUFMSdoDpciLgFQwrkE8xrOo4hjEWObk3efMWTDeZ7FpwLQsaoXX3ocwub7rpAcDWpzeHewYS8ylcoU3RBCiLeWBCIhspCiKMw/N58frvwAgI25DRNrT6RlsZbGu0IAc/ffYv7/Bk4XcbVljF8xml8bCYf/MDRwKw2t50MR32zvgxBC5AUSiITIIpcjLvNd0HcEhQUB0K5EOwZWHphmrFBMkoZZ+26w7vRDADpUK8SXVWOwPdwHngSBygyafwM1+spYISGEyEISiITIZHGpcfx87WdWXl6JRq/BQm3BJ5U+4ZPKn6RpF3D3OaN+ucjjKMNCi8PreTLEfDOsW2RoYGYFnVZDmRbZ3AMhhMh7JBAJkYkexT6i576ePEt6BkD9QvWZWHsinnaexjYpWh2frT3HgRuGWWYFnW1YXDOcKoGfGcYKAVT9CBqMA6eC2d0FIYTIkyQQCZEJFEVhzbU1LL24lARNAgXsCjCixgjeL/J+mrFCUQmpTNl51RiGetYuzIjij3Ha/QUkx4BrSWg8Ccq1MVVXhBAiT5JAJMQbCgwNZNH5RZwLPwdA6XylmdtwLt4O3sY2iqJw+FYEY369RFhsCgBzm7nSLng0/HrC0KjQO9B7N5hbZnsfhBAir5NAJMR/pCgK3579ljXX1gBgqbZkaPWhdC/bPc1dodhkDaN/ucTeK6EA+LjasrLYEYqfXAmpcYaxQjX7QYMxEoaEEMJEJBAJ8R88iH3ApBOTjHeFOpTswKeVP00zVgggPC6ZT34O4vzDaMzVKnr7FmYUa7AK+t7QoEBl6PQTuPhkdxeEEEL8P+p/b5JzzJw5E5VKxdChQ43vJScnM2jQIFxdXbG3t6dDhw6EhYWlOe/hw4e0bNkSW1tb3N3dGTVqFFqtNpurF2+D2NRYFp1fxIc7P+Rc+Dks1ZZ8Xu1zprw7JU0YUhSFfVdCaTr3KOcfRmNlrua3ZilMCPH/Kwy9Nwb6H5YwJIQQOUCuuUMUGBjI999/T6VKldK8P2zYMHbv3s2WLVtwcnLC39+f9u3bc+KEYVyGTqejZcuWeHp6cvLkSUJCQujZsycWFhZ8/fXXpuiKyKWCY4Lpva83kcmRAFR0q8h3732XZl0hgPDYZEb9cokjtyIAqOqu5vuCe3E/+JOhgYWtYW2haj2ztX4hhBD/TKUoimLqIv5NfHw81apVY8mSJUyfPp0qVaowb948YmJiyJ8/P+vXr6djx44A3Lhxg7JlyxIQEEDt2rXZu3cvrVq14unTp3h4eACwbNkyRo8eTUREBJaW/z5mIzY2FicnJ2JiYnB0dMzSvoqcR1EUdt7byVenviJRm0hB+4KMqDGCxoUbpxkrBHDtaSydlwcQl6zFylzN57Uc+SRkEmZPzxoa1OhrmE5vn98EPRFCiLwlI9/fueKR2aBBg2jZsiV+fn5p3g8KCkKj0aR5v0yZMhQuXJiAgAAAAgICqFixojEMATRt2pTY2FiuXr36ys9LSUkhNjY2zR+RN50OOU2vfb0Yf3w8idpEyrqUZVXTVS9Np1cUhd8uPKHz94YwVCK/HfsbPuKzSx0NYcjcGrqsh1ZzJQwJIUQOlOMfmW3cuJFz584RGBj40rHQ0FAsLS1xdnZO876HhwehoaHGNv8/DL04/uLYq8yYMYOpU6dmQvUit1IUhRlnZrDhxgYArMys6FmuJ4OqDMLsb1toPI1O4us919l1KQQAvwLJLLWajcWx84YGBatDs5ng/U629kEIIUT65ehA9OjRIz7//HP279+PtbV1tn3u2LFjGT58uPF1bGws3t7erzlDvE0ikyOZFTiL3fd2A9C5dGcGVBqAu637S21/CXrMuK2XSdXpUalg6jt6etwchioqBizsDLvTv/eF7EMmhBA5XI4OREFBQYSHh1OtWjXjezqdjqNHj7Jo0SJ+//13UlNTiY6OTnOXKCwsDE9Pw4wfT09Pzpw5k+a6L2ahvWjzd1ZWVlhZWWVyb0ROF5MSw09Xf2Ld9XUkahNRq9QMqzaM3hV6v9RWr1fYev4JY7deQqNTeLeQJXPz78LjynrQpRp2p+++BfIVyf6OCCGEyLAcHYgaN27M5cuX07zXp08fypQpw+jRo/H29sbCwoIDBw7QoUMHAG7evMnDhw/x9fUFwNfXl6+++orw8HDc3Q2/4e/fvx9HR0fKlSuXvR0SOdb9mPv03NuTqJQoAMq6lGVEjRHUKlDr5bbPEpi++xp/Xg8HFAbkv8ZYtqC6fsvQoEhd6LASHAu8dK4QQoicKUcHIgcHBypUqJDmPTs7O1xdXY3v9+vXj+HDh+Pi4oKjoyODBw/G19eX2rVrA9CkSRPKlStHjx49mDVrFqGhoUyYMIFBgwbJXSCBoigce3KMWYGziEqJopB9IUbWHEkj70aoVKqX2m8KfMiE7VfQ6BTM1Sq2F/mVCiG/Qhxg4wLtV0CJxvCKc4UQQuRcOToQpcfcuXNRq9V06NCBlJQUmjZtypIlS4zHzczM2LVrFwMHDsTX1xc7Ozt69erFtGnTTFi1yAlOhZxi4fmFXIq4BIC7rTurmq56aV0hAK1Oz7Ijd/n2D8NdoFaFdUxz3oXLrV8NDeoOgzqfg02+bKtfCCFE5skV6xCZmqxD9Pb56epPfHv2WwCszazpWqYrfSr0IZ/1y4HmTngck3dc5cSd56jQ813xi7QLnY9Kl2po0Ggi1B+ZneULIYRIh4x8f+f6O0RCZMTzpOesuLyCddfXAdCxVEcGVRmEm43bS201Oj0/ngjmm3030ekV3M0T2JPvO9ye3DA0KPwuNJ4ERXyzswtCCCGygAQikSek6FJYdnEZ666vI0mbBED/iv0ZXHXwK8cKpWr1fPLzWQ7dNGy/8XHRCL5I+A7LuIdgaQ/1hkOdoTKdXggh3hISiMRbLzo5ms8OfMblZ4YZi+Vdy+Nf1Z+6Beu+sv2tsDjGbr1M0IMovNRRrC76JyVDdqBSdGDrCh/9Cl5Vs7MLQgghspgEIvHWUhSFI4+PMCdoDsExwdiY2/BlnS9pUqTJK+8KJWt0rDv9kNm/3yBZo6ee5S1W2izC6ukzQ4MyraDtErB2yuaeCCGEyGoSiMRb6X7MfcYfH8+lZ4YZZPYW9nz//vdUyl/ple0TU7V0XX6Ki49jUKNntOc5PklYjjol3rDIYpuFUPjlNYmEEEK8HSQQibfOr7d+5ZvAb0jSJmFjbmOYQVa+D87Wzq9sf+VJDJN3XOXi4xgqWD/j+/xbKBhxzHDQsxL03iV3hYQQ4i0ngUi8NZ4lPeOHyz+w9vpaACrnr8y3732Lp92rt2hJTNXy44n7zP/zNqk6HSMtfmWQ6jdUETpQW0CjCfDOALC0zc5uCCGEMAEJRCLXUxSFlZdXsuLyCuMMslbFWvF13a9fOVYI4E54PAPXBnE7PB4LtMzz2E/bmK2gACWbGMJQgcrZ2AshhBCmJIFI5GqRyZEMPjjYuNp0RbeK+Ffxx9fL9x/DUNCDSD5de46IuBT87O4y33IpdjFPDQcbjIUGY7KrfCGEEDmEBCKRKymKwqFHh5gbNJf7sfexNrNmRI0RdC7d+R+DUFyyhhXHgll08DYeynOW227hfd0xVEkK2HtAvZFQ8+Ns7okQQoicQAKRyHUiEiP44ugXnA07C4CDpQMrmqygvGv5fzwn8H4kIzZf5GFkIoVUEWy3n4mbNsRwsEIHaD0frByyo3whhBA5kAQikatsvrmZ2YGzSdYlY21mzUflPqJ3+d44Wf3zLLDfLjxh6KYLWCga/O2PM1j9K1apkWCXH7pthoLVsrEHQgghciIJRCJXiEiMYMXlFWy4sQGASm6VmOQ7idIupf/xnIQULQsO3Ob7o/coqXrMKsdleKfeMxzMXxa6rAPX4tlRvhBCiBxOApHI0RRFYevtrcw8M5NkXTIAbUu0Zdq70/5xrBDA8dvPmL77GjdC42ioPs8Kq7mYp2rBxgUajoNqPcHcKru6IYQQIoeTQCRyrGdJzxh8YDBXnl8BoFL+SgyuOphanrVeG4ZWHQ9m2q5rWJHKVOtf6cVOw3T6InXgg8Xg4pNNPRBCCJFbSCASOY6iKBx8eJA5QXN4GPcQG3Mb+lboy4BKA1Cr1P94XkyShgUHbvPD8WDaqE8w3XYjjtrnhoMVP4RWc2TgtBBCiFeSQCRylPDEcL458w1/PPgDACcrJ35o8sNrxwoBHLwRxvTd17kXkcAX5hv5zHwHaAGnwuA3GSp2zIbqhRBC5FYSiESOse76OuYGzSVFl4KZyoy+FfrSq3yv184gS9XqmbLzKutPP6SQKpy1Nmuoq5wzHPT1h8aTwdwym3oghBAit5JAJEwuPDGc5ZeWs+nmJgCq5K/CsOrDqObx+unwkQmpjN92mUNXHtDfbD/DrHdhq4sFlZlhten3vsiO8oUQQrwFJBAJk9Erev548AfTTk4jThMHQKdSnZhYe+JrB00risLeK6HM2HsddVQwh6ymU0AVCTrAowJ0+gncSmRTL4QQQrwNJBAJkwhLCGPwwcFcj7wOQFmXsoyqOYqanjVfe15EXApf7rrGjotPqaa6xbfWP1BAiQSHAoYNWSt1ATP5z1oIIUTGyDeHyHYHHx5kVuAsnsQ/wcbchp7letK3Ql9sLWxfe15Sqo6uK04RGh7OYosVtDQ7bZhOb5cf+v4O+YpkTweEEEK8dSQQiWwTlhDG0otL+fX2rwDks8rHD01/oGS+kv967t7LIczcd4OKUQfYYr2afMQZxgpV7Q7vjQGnglldvhBCiLeYBCKRLX66+hMLzi0gVZ8KQLcy3RhUdRCOlo6vPe9pdBJz9t/il6DHdDQ7wjeWKzBDDy7F4YNFUOTd7ChfCCHEW04CkchSqbpUZgXOMs4gq+ZeDf+q/v86VgjgUWQibRefoGDiddZbbOBds2uGA6WaQed1MlZICCFEppFvFJElXswgW3JhCcExwQB0LdOVse+Mfe0Mshe2nnvMrD1X6ZL8C59bbcUSLZhZwrtDDHuRqc2yugtCCCHyEAlEItOFxIcw5NAQbkTeAAyrTX9V5yve837vX8998DyB2b/f5Oil20yyWEtHi6OGAyWbQsvvwNk7K0sXQgiRR0kgEpkqMDSQCccn8DThKXYWdvQq14uPyn2Eg+W/7yF24HoYQzedp0rqeQ5aLcFNFWs48P408B0M6n/ex0wIIYR4ExKIRKYITQjl+0vfs+32NnSKDhdrF35s9iPFnIr967mKorDu9EPm7DzDd+qlNLEMMhxwLWkIQ2VaZHH1Qggh8joJROKN/XD5BxZfWIxGrwGgadGmTPadnK67QiExSUzcfpUL12+x3vJryqgfoagtUNXoY1ho0fqf9zETQgghMosEIvGf6fQ6Fl9YzIrLKwCo4VED/6r+VPeo/q/nKorC2tMPWbD/Bl2TNzPfaid2qhQUK0dU3X+BwrWyunwhhBDCSAKRyDC9ouf3+7+z5MIS7sfeB6BnuZ6MrDEyXTPIAJYcvsuJ/b+y3HwzVS3uGN4sUAVVyzlQ6N8DlRBCCJGZJBCJDHkc95ghh4ZwO+o2AM5WzgyvPpx2Jdul6/yHzxOZsvMq9re2s95yEQCKuQ2q5t9AtZ6QzkAlhBBCZCYJRCLdbkfdxv+AP08TnmJvYU/v8r35qNxH2FnY/eu5Gp2e1Sfus/5gEN20W+ll8TsASoUOqJrOAAePrC5fCCGE+EcSiMS/ehr/lOWXlrP9znZ0ig43Gzd+avYThR0Lp/saX2y5SNylnfxisRxX8zjDm2VaoWr3PZhZZFHlQgghRPrk6IVdZsyYQc2aNXFwcMDd3Z22bdty8+bNNG2Sk5MZNGgQrq6u2Nvb06FDB8LCwtK0efjwIS1btsTW1hZ3d3dGjRqFVqvNzq7kWt9f/J6W21ry6+1f0Sk66hasy5bWW9Idhu6Ex9Ht+5P4Xf2ClZbf4aqKQ8lfBrr/Cp3XShgSQgiRI+ToO0RHjhxh0KBB1KxZE61Wy7hx42jSpAnXrl3Dzs7wmGbYsGHs3r2bLVu24OTkhL+/P+3bt+fEiRMA6HQ6WrZsiaenJydPniQkJISePXtiYWHB119/bcru5WhavZYF5xbw49UfAajlWQv/qv5Uca+SrvNTtDpWHgvmt8MBfKd8S0Wz+yioUNUZgqreSLB+/aauQgghRHZSKYqimLqI9IqIiMDd3Z0jR45Qv359YmJiyJ8/P+vXr6djx44A3Lhxg7JlyxIQEEDt2rXZu3cvrVq14unTp3h4GMapLFu2jNGjRxMREYGlpeW/fm5sbCxOTk7ExMTg6Ph2f5Hr9Dr23t/LsovLeBD7AIB+FfoxtPrQdF/jeXwKQ346RsOQlfQw+xMrlQa9hR3qVnOgcpcsqlwIIYRIKyPf3zn6DtHfxcTEAODi4gJAUFAQGo0GPz8/Y5syZcpQuHBhYyAKCAigYsWKxjAE0LRpUwYOHMjVq1epWrXqS5+TkpJCSkqK8XVsbGxWdSlHiUmJ4bM/P+PSs0sA5LPKx8iaI2lTvE26r3H1aQwzNvzJpJhJlDZ/DIDi7Yu6/TLIVzQryhZCCCHeWK4JRHq9nqFDh1KnTh0qVKgAQGhoKJaWljg7O6dp6+HhQWhoqLHN/w9DL46/OPYqM2bMYOrUqZncg5ztYexDRh8dzZXnV3CwcKBPhT50K9stXTPIAPR6hSWH73D90AZmqNbgrY5Aa+mEeceVqEq+L9PphRBC5Gi5JhANGjSIK1eucPz48Sz/rLFjxzJ8+HDj69jYWLy9385d1p/GP2XpxaXsvLsTnaLD2cqZVU1XUTJfyXRf4+KjaBZtP0KjsB9ZbH4IAL2NK+Z990L+0llVuhBCCJFpckUg8vf3Z9euXRw9epRChQoZ3/f09CQ1NZXo6Og0d4nCwsLw9PQ0tjlz5kya672Yhfaizd9ZWVlhZWWVyb3IeQ4/OszYY2OJ18QDUL9QfUbUGJGuDVlfuP8sgZ9XzmURi7EyN+xlptT6FHWDsWDjnAVVCyGEEJkvR0+7VxQFf39/tm3bxsGDB/Hx8UlzvHr16lhYWHDgwAHjezdv3uThw4f4+voC4Ovry+XLlwkPDze22b9/P46OjpQrVy57OpLDaPQaNt/czNBDQ4nXxFPBtQJrW6xlcePF6Q5DOr3Cd/uusWrBJGayACuVhtSCtaD3bsOq0xKGhBBC5CI5+g7RoEGDWL9+Pb/99hsODg7GMT9OTk7Y2Njg5OREv379GD58OC4uLjg6OjJ48GB8fX2pXbs2AE2aNKFcuXL06NGDWbNmERoayoQJExg0aFCeuAv0/+kVPbvv7WbpxaU8insEQJ2CdZjXYB7W5tbpvk7A3ees2vknwyOnU1b9EICkcp2x6bgM1Dk6YwshhBCvlKOn3f/TRqE//vgjvXv3BgwLM44YMYINGzaQkpJC06ZNWbJkSZrHYQ8ePGDgwIEcPnwYOzs7evXqxcyZMzE3T18efBum3celxjHu2DgOPz4MgIu1C/0q9KNLmS5Ymv370gMvBNx4yL11w/hQfQgLlY5UC0cs6g9HVWcIqM2yqHohhBAi4zLy/Z2jA1FOkdsDUXBMMFNOTuFc+DnM1eYMqjKIbmW6YWthm+5rpGr1zN0dxLtBw6mnNkzLTy3yHpbtFoFz+rfwEEIIIbLLW7sOkciYZ0nPmBs0l133dqFX9FioLVjceDG+Xr4Zus7h6yGc3vE9XRPWUlgdgQ41qe1XYVMpfTvcCyGEEDmdBKK31MGHB/n69NeEJRpm1DUo1AD/qv6UdsnYNPjVe47hHTCR0WbnQQ0pVm5YdlmNjU+9rChbCCGEMAkJRG8ZjV7DL7d+YeaZmegVPYXsC/FN/W+olL9Shq6TlKpj2S+76H5zCO5m0WhV5mjrjcG67mdgmb7FGoUQQojcQgLRW+Tk05NMC5jGk/gngOGu0Df1v8nQWCGAs/fCOLlxNv4pq7BQ6Yi29MSp10bMC768zYkQQgjxNpBA9BaISYlhVuAsdt7diYKCq7UrH1f8mA9Lf5ihGWQJKVp+3ryR5nemMkQVDiqI9KyDy4eLwcXn3y8ghBBC5FISiHK5e9H3mHhyIpciDDO/WhdrzYTaEzJ8V0ij07PhxwV8HPIl5io9MWb5sGowEpc6A2U6vRBCiLeeBKJcKkmbxNenv2bH3R3oFT2WaksW+y2mdoHaGb7WmQsXids5jo91x0EFzzzr49ZnPVg5ZEHlQgghRM4jgSgX2v9gP98GfsvThKcANPJuhH9V/wxtyArwPCaOgxvm0jBkBW6qWACeFG5DwZ4rwTxvreIthBAib5NAlItodBo23dzErMBZKCi42bgxo96M/3RXKCExkYgFjemkuwkqCLUqivNHayjoXTkLKhdCCCFyNglEucTxJ8eZfmq6cQZZ48KNmVFvBjbmNhm+1skThzH7cxK1lJskYkVkrTEU8vsMLNK/n5kQQgjxNpFAlMNFJ0czM3Ame+7tMd4V+rjix3xY6kMszCwydK3Q59FcXvsF70dtAkCDOfcbLKZcg05ZUboQQgiRa0ggysHuRt9lwvEJXHl+BYC2Jdoyrta4/3RX6O6lk9hv/Yj3eQ7AZedGlOr8NeUKlM3UmoUQQojcSAJRDpSqS2XBuQWsubYGBQVrM2uW+C2hpmfN/3S94/u3UeGEP87E80yVj+SGU6lYv1cmVy2EEELkXhKIcph99/cx5+wcQhJCAPAr7Id/VX+KOxfP8LXiQu8QvMafuokBADxQF8Lh0z8o5F4wU2sWQgghcjsJRDlIii6FsUfHolW05LfJz6iao2ju0/w/XStw+2JKXphBJeLQKSqu5G9BuX7LsLBxzOSqhRBCiNxPAlEOEpUchVbRYq42Z0/7PVib/4dZX6kJ3PntG2penQ/AHVVRUtqvpHKl//a4TQghhMgLJBDlIFHJUQDks8r3n8JQzO0AYjcPpIQmGIBAh8ZUGbwBC0tZZFEIIYR4HQlEOUhUiiEQOVs7Z+g8RZPE/ZU98Qn7AycgUnHgUJHPafXR51hYpn9zVyGEECKvkkCUg0QnRwOGO0TppSRFc2/VxxSP2I9OUfGHRSOKf/gVHUrJdHohhBAivSQQ5RCKovDnwz8BcLZyTtc5MQE/YfbHOIor8QDsKDeXNp16Y6ZWZVWZQgghxFtJAlEOEJoQyrxz89j/YD8AhRwKvba98vQCj7d8gXfUaQDuKl6cLzWU9p16o5YwJIQQQmSYBCITepb0jBWXVrDl1hY0eg0A/Sv2p3+l/v94ji74BNo17fFWkklVzNhq04Gafb6lo4dTdpUthBBCvHUkEJlQdHI0G25sQEGhhkcNBlcdTDWPaq9unBRNzKH52JxZiBUaLumLcafBIj5s8K7cFRJCCCHekAQiEyqRrwSDqgyisntlannWQqV6dbBR7h4meVMfnFIjATisVCWlzRLa1yiXneUKIYQQby0JRCb2SeVP/vmgohD1xzfkC5iBDXBP78kW57507z2IQi722VajEEII8baTQJRTJUaS/OtA8t3dB8B2fT0i6n3JF35V/vFOkhBCCCH+GwlEOY1ej/7Yd2iPzsVal0CqYsYaVRv8Bi+iaH65KySEEEJkBQlEOYmiELu6E44P/8QSuKovwga3wXz0YWcJQ0IIIUQWkkCUg+iSonH83+KMXyr9KNRkEF/WKSaPyIQQQogsJoEoB4l5HooLkKBY8enIGeR3kE1ZhRBCiOygNnUB4i8JkWEARKscJQwJIYQQ2UgCUQ6SGBMOQJxaVp0WQgghspMEohwkNTYCgERzZ9MWIoQQQuQxEohyivDreN7ZBECKhbNpaxFCCCHyGAlEppaaiHJ8PprvG5E/+iJaRU2waz1TVyWEEELkKXkqEC1evJiiRYtibW1NrVq1OHPmjGkLehKEdm4lVH9OwkKXyBl9aT5xWkaNlv1MW5cQQgiRx+SZQLRp0yaGDx/O5MmTOXfuHJUrV6Zp06aEh4ebrKZbOi/ikpJ5qM/PGN2nnGvwMyuGfkgpDweT1SSEEELkRSpFURRTF5EdatWqRc2aNVm0aBEAer0eb29vBg8ezJgxY157bmxsLE5OTsTExODo6JhpNYXGJDNh2UYi7XxY0qMWnk7WmXZtIYQQIq/LyPd3nliYMTU1laCgIMaOHWt8T61W4+fnR0BAwEvtU1JSSElJMb6OjY3Nkro8naz5+rMuWJmb4WRjkSWfIYQQQoh/lycemT179gydToeHh0ea9z08PAgNDX2p/YwZM3BycjL+8fb2zrLa3B2sJQwJIYQQJpYnAlFGjR07lpiYGOOfR48embokIYQQQmShPPHIzM3NDTMzM8LCwtK8HxYWhqen50vtrayssLKSrTOEEEKIvCJP3CGytLSkevXqHDhwwPieXq/nwIED+Pr6mrAyIYQQQuQEeeIOEcDw4cPp1asXNWrU4J133mHevHkkJCTQp08fU5cmhBBCCBPLM4Goc+fOREREMGnSJEJDQ6lSpQr79u17aaC1EEIIIfKePLMO0ZvIqnWIhBBCCJF1MvL9nSfGEAkhhBBCvI4EIiGEEELkeRKIhBBCCJHnSSASQgghRJ4ngUgIIYQQeZ4EIiGEEELkeRKIhBBCCJHn5ZmFGd/Ei6WaYmNjTVyJEEIIIdLrxfd2epZclECUDnFxcQB4e3ubuBIhhBBCZFRcXBxOTk6vbSMrVaeDXq/n6dOnODg4oFKpMu26sbGxeHt78+jRI1kBO4vJzzp7yM85e8jPOfvIzzp7ZNXPWVEU4uLi8PLyQq1+/SghuUOUDmq1mkKFCmXZ9R0dHeX/aNlEftbZQ37O2UN+ztlHftbZIyt+zv92Z+gFGVQthBBCiDxPApEQQggh8jwJRCZkZWXF5MmTsbKyMnUpbz35WWcP+TlnD/k5Zx/5WWePnPBzlkHVQgghhMjz5A6REEIIIfI8CURCCCGEyPMkEAkhhBAiz5NAJIQQQog8TwKRCS1evJiiRYtibW1NrVq1OHPmjKlLylVmzJhBzZo1cXBwwN3dnbZt23Lz5s00bZKTkxk0aBCurq7Y29vToUMHwsLC0rR5+PAhLVu2xNbWFnd3d0aNGoVWq83OruQqM2fORKVSMXToUON78nPOHE+ePOGjjz7i/9q7/5io6z8O4M+D4/ghcgeCd0CHh0kichlCGmjq4iaRGdWWym4E5HQoLKhMLWdzKwRtMdGmVptiRpIuxWKmowMxHMKBgPwKTCBY48eQjh/TBd69vn/49fP1wm/fvnpw0L0e223wfr/vPq/Pk/G51z6f+8CMGTPg7OwMtVqNyspKYZ6I8MEHH8Db2xvOzs7QaDS4fv262Wv09/dDq9XCzc0NMpkM69evx/Dw8ETvyqRlNBqxc+dO+Pv7w9nZGY8//jg+/PBDs/91xTk/nEuXLmH16tXw8fGBSCRCfn6+2bylcr127RqeffZZODk5QalUYu/evZbZAWJWkZeXRxKJhI4cOUINDQ20YcMGkslk1NPTY+3SpoyoqCg6evQo1dfXU01NDb3wwgvk5+dHw8PDwpqkpCRSKpWk0+mosrKSnnnmGYqIiBDm79y5Q8HBwaTRaKi6uprOnTtHnp6e9N5771ljlya9iooKUqlU9OSTT1Jqaqowzjk/uv7+fpo1axYlJCRQeXk5tba20oULF+iXX34R1mRmZpJUKqX8/Hyqra2ll156ifz9/en27dvCmueff54WLFhAV65coZ9++onmzJlDsbGx1tilSSk9PZ1mzJhBBQUF1NbWRqdOnSJXV1fKzs4W1nDOD+fcuXO0Y8cOOn36NAGgM2fOmM1bIteBgQGSy+Wk1Wqpvr6eTpw4Qc7OzvTZZ589cv3cEFnJokWLKDk5WfjeaDSSj48PZWRkWLGqqa23t5cAUElJCRERGQwGcnBwoFOnTglrmpqaCACVlZUR0d1fYDs7O+ru7hbWHDp0iNzc3OiPP/6Y2B2Y5IaGhiggIIAKCwtp+fLlQkPEOVvGtm3baOnSpf913mQykUKhoI8//lgYMxgM5OjoSCdOnCAiosbGRgJAer1eWPPDDz+QSCSi3377bfyKn0JWrVpFb7zxhtnYq6++Slqtlog4Z0v5c0NkqVwPHjxI7u7uZseNbdu20dy5cx+5Zr5kZgUjIyOoqqqCRqMRxuzs7KDRaFBWVmbFyqa2gYEBAICHhwcAoKqqCqOjo2Y5BwYGws/PT8i5rKwMarUacrlcWBMVFYXBwUE0NDRMYPWTX3JyMlatWmWWJ8A5W8p3332HsLAwvPbaa5g5cyZCQkLwxRdfCPNtbW3o7u42y1kqlWLx4sVmOctkMoSFhQlrNBoN7OzsUF5ePnE7M4lFRERAp9OhpaUFAFBbW4vS0lJER0cD4JzHi6VyLSsrw7JlyyCRSIQ1UVFRaG5uxu+///5INfI/d7WCvr4+GI1GszcHAJDL5fj555+tVNXUZjKZkJaWhiVLliA4OBgA0N3dDYlEAplMZrZWLpeju7tbWPOgn8O9OXZXXl4erl69Cr1eP2aOc7aM1tZWHDp0CG+//Tbef/996PV6vPnmm5BIJIiPjxdyelCO9+c8c+ZMs3mxWAwPDw/O+d+2b9+OwcFBBAYGwt7eHkajEenp6dBqtQDAOY8TS+Xa3d0Nf3//Ma9xb87d3f2ha+SGiP0jJCcno76+HqWlpdYu5R+ns7MTqampKCwshJOTk7XL+ccymUwICwvD7t27AQAhISGor6/H4cOHER8fb+Xq/jlOnjyJ3NxcfP3115g/fz5qamqQlpYGHx8fztnG8SUzK/D09IS9vf2Yu3B6enqgUCisVNXUlZKSgoKCAhQXF+Oxxx4TxhUKBUZGRmAwGMzW35+zQqF44M/h3hy7e0mst7cXCxcuhFgshlgsRklJCfbv3w+xWAy5XM45W4C3tzeCgoLMxubNm4eOjg4A/8npr44bCoUCvb29ZvN37txBf38/5/xv7777LrZv345169ZBrVYjLi4Ob731FjIyMgBwzuPFUrmO57GEGyIrkEgkCA0NhU6nE8ZMJhN0Oh3Cw8OtWNnUQkRISUnBmTNnUFRUNOY0amhoKBwcHMxybm5uRkdHh5BzeHg46urqzH4JCwsL4ebmNubNyVZFRkairq4ONTU1wiMsLAxarVb4mnN+dEuWLBnzZyNaWlowa9YsAIC/vz8UCoVZzoODgygvLzfL2WAwoKqqSlhTVFQEk8mExYsXT8BeTH63bt2CnZ35W5+9vT1MJhMAznm8WCrX8PBwXLp0CaOjo8KawsJCzJ0795EulwHg2+6tJS8vjxwdHSknJ4caGxtp48aNJJPJzO7CYX9t06ZNJJVK6eLFi9TV1SU8bt26JaxJSkoiPz8/KioqosrKSgoPD6fw8HBh/t7t4CtXrqSamho6f/48eXl58e3g/8P9d5kRcc6WUFFRQWKxmNLT0+n69euUm5tLLi4u9NVXXwlrMjMzSSaT0dmzZ+natWsUExPzwNuWQ0JCqLy8nEpLSykgIMDmbwe/X3x8PPn6+gq33Z8+fZo8PT1p69atwhrO+eEMDQ1RdXU1VVdXEwDKysqi6upq+vXXX4nIMrkaDAaSy+UUFxdH9fX1lJeXRy4uLnzb/VR34MAB8vPzI4lEQosWLaIrV65Yu6QpBcADH0ePHhXW3L59mzZv3kzu7u7k4uJCr7zyCnV1dZm9Tnt7O0VHR5OzszN5enrSO++8Q6OjoxO8N1PLnxsiztkyvv/+ewoODiZHR0cKDAykzz//3GzeZDLRzp07SS6Xk6OjI0VGRlJzc7PZmps3b1JsbCy5urqSm5sbJSYm0tDQ0ETuxqQ2ODhIqamp5OfnR05OTjR79mzasWOH2W3cnPPDKS4ufuAxOT4+nogsl2ttbS0tXbqUHB0dydfXlzIzMy1Sv4jovj/PyRhjjDFmg/gzRIwxxhizedwQMcYYY8zmcUPEGGOMMZvHDRFjjDHGbB43RIwxxhizedwQMcYYY8zmcUPEGGOMMZvHDRFjjDHGbB43RIwx9jeoVCrs27fP2mUwxsYJN0SMsUknISEBL7/8MgBgxYoVSEtLm7Bt5+TkQCaTjRnX6/XYuHHjhNXBGJtYYmsXwBhjE2FkZAQSieShn+/l5WXBahhjkw2fIWKMTVoJCQkoKSlBdnY2RCIRRCIR2tvbAQD19fWIjo6Gq6sr5HI54uLi0NfXJzx3xYoVSElJQVpaGjw9PREVFQUAyMrKglqtxrRp06BUKrF582YMDw8DAC5evIjExEQMDAwI29u1axeAsZfMOjo6EBMTA1dXV7i5uWHNmjXo6ekR5nft2oWnnnoKx48fh0qlglQqxbp16zA0NDS+oTHGHgo3RIyxSSs7Oxvh4eHYsGEDurq60NXVBaVSCYPBgOeeew4hISGorKzE+fPn0dPTgzVr1pg9/9ixY5BIJLh8+TIOHz4MALCzs8P+/fvR0NCAY8eOoaioCFu3bgUAREREYN++fXBzcxO2t2XLljF1mUwmxMTEoL+/HyUlJSgsLERrayvWrl1rtu7GjRvIz89HQUEBCgoKUFJSgszMzHFKizH2KPiSGWNs0pJKpZBIJHBxcYFCoRDGP/30U4SEhGD37t3C2JEjR6BUKtHS0oInnngCABAQEIC9e/eaveb9n0dSqVT46KOPkJSUhIMHD0IikUAqlUIkEplt7890Oh3q6urQ1tYGpVIJAPjyyy8xf/586PV6PP300wDuNk45OTmYPn06ACAuLg46nQ7p6emPFgxjzOL4DBFjbMqpra1FcXExXF1dhUdgYCCAu2dl7gkNDR3z3B9//BGRkZHw9fXF9OnTERcXh5s3b+LWrVt/e/tNTU1QKpVCMwQAQUFBkMlkaGpqEsZUKpXQDAGAt7c3ent7/699ZYxNDD5DxBibcoaHh7F69Wrs2bNnzJy3t7fw9bRp08zm2tvb8eKLL2LTpk1IT0+Hh4cHSktLsX79eoyMjMDFxcWidTo4OJh9LxKJYDKZLLoNxphlcEPEGJvUJBIJjEaj2djChQvx7bffQqVSQSz++4exqqoqmEwmfPLJJ7Czu3uC/OTJk/9ze382b948dHZ2orOzUzhL1NjYCIPBgKCgoL9dD2Ns8uBLZoyxSU2lUqG8vBzt7e3o6+uDyWRCcnIy+vv7ERsbC71ejxs3buDChQtITEz8y2Zmzpw5GB0dxYEDB9Da2orjx48LH7a+f3vDw8PQ6XTo6+t74KU0jUYDtVoNrVaLq1evoqKiAq+//jqWL1+OsLAwi2fAGBt/3BAxxia1LVu2wN7eHkFBQfDy8kJHRwd8fHxw+fJlGI1GrFy5Emq1GmlpaZDJZMKZnwdZsGABsrKysGfPHgQHByM3NxcZGRlmayIiIpCUlIS1a9fCy8trzIeygbuXvs6ePQt3d3csW7YMGo0Gs2fPxjfffGPx/WeMTQwREZG1i2CMMcYYsyY+Q8QYY4wxm8cNEWOMMcZsHjdEjDHGGLN53BAxxhhjzOZxQ8QYY4wxm8cNEWOMMcZsHjdEjDHGGLN53BAxxhhjzOZxQ8QYY4wxm8cNEWOMMcZsHjdEjDHGGLN5/wIpeWwx+a9dRwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Extract the 'it' and 'time' values from each dictionary in each list\n", + "it_baseline = [x['it'] for x in step_baseline]\n", + "time_baseline = [x['time'] for x in step_baseline]\n", + "\n", + "it_jit = [x['it'] for x in step_jit]\n", + "time_jit = [x['time'] for x in step_jit]\n", + "\n", + "it_tcompile = [x['it'] for x in step_tcompile]\n", + "time_tcompile = [x['time'] for x in step_tcompile]\n", + "\n", + "# Plot cumulative time for each iteration\n", + "plt.plot(it_baseline, time_baseline, label='Baseline')\n", + "plt.plot(it_jit, time_jit, label='Jit')\n", + "plt.plot(it_tcompile, time_tcompile, label='TCompile')\n", + "\n", + "# Label the axes\n", + "plt.xlabel('Iteration')\n", + "plt.ylabel('Cumulative Time')\n", + "\n", + "# Add a legend\n", + "plt.legend(loc='upper left')\n", + "\n", + "# Display the plot\n", + "plt.show()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If everything is working correctly it should show that\n", + "\n", + "- baseline: lowest starting time, highest accumulative rate\n", + "- JIT: similar starting time, lower accumulative rate\n", + "- TCompile: slowest starting time, lowest accumulative rate\n", + "\n", + "This can be observed by getting the average time per iteration for the first 200 steps and the following 2 x 400 steps" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Average delta time for the first 200 iterations ('warmup'):\n", + "Baseline: 875.0 ms\n", + "Jit: 860.0 ms\n", + "TCompile: 1125.0 ms\n", + "\n", + "Average delta time after 'warmup' for 400 iterations:\n", + "Baseline: 715.0 ms\n", + "Jit: 685.0 ms\n", + "TCompile: 652.5 ms\n", + "\n", + "Average delta time for last 400 iterations:\n", + "Baseline: 717.5 ms\n", + "Jit: 687.5 ms\n", + "TCompile: 655.0 ms\n" + ] + } + ], + "source": [ + "# Compute the average time for the first `n` iterations and for the rest\n", + "def compute_average_time_delta(data, start, end):\n", + " time = [x['time'] for x in data]\n", + " if start == -1:\n", + " return (time[end-1]) / (end)\n", + " else:\n", + " return (time[end-1] - time[start]) / (end - start)\n", + "\n", + "# PS, [0] pos shows the timing for the first step, so we use -1 to start from \"0\"\n", + "first_R = 200\n", + "first_R_baseline = compute_average_time_delta(step_baseline, -1, first_R)\n", + "first_R_jit = compute_average_time_delta(step_jit, -1, first_R)\n", + "first_R_tcompile = compute_average_time_delta(step_tcompile, -1, first_R)\n", + "\n", + "next_W = 400\n", + "next_W_baseline = compute_average_time_delta(step_baseline, first_R, first_R + next_W)\n", + "next_W_jit = compute_average_time_delta(step_jit, first_R, first_R + next_W)\n", + "next_W_tcompile = compute_average_time_delta(step_tcompile, first_R, first_R + next_W)\n", + "\n", + "next_K = 400\n", + "next_K_baseline = compute_average_time_delta(step_baseline, first_R + next_W, first_R + next_W + next_K)\n", + "next_K_jit = compute_average_time_delta(step_jit, first_R + next_W, first_R + next_W + next_K)\n", + "next_K_tcompile = compute_average_time_delta(step_tcompile, first_R + next_W, first_R + next_W + next_K)\n", + "\n", + "print(f\"Average delta time for the first {first_R} iterations ('warmup'):\")\n", + "print(f\"Baseline: {first_R_baseline * 1000} ms\")\n", + "print(f\"Jit: {first_R_jit * 1000} ms\")\n", + "print(f\"TCompile: {first_R_tcompile * 1000} ms\")\n", + "print(\"\")\n", + "\n", + "print(f\"Average delta time after 'warmup' for {next_W} iterations:\")\n", + "print(f\"Baseline: {next_W_baseline * 1000} ms\")\n", + "print(f\"Jit: {next_W_jit * 1000} ms\")\n", + "print(f\"TCompile: {next_W_tcompile * 1000} ms\")\n", + "print(\"\")\n", + "\n", + "print(f\"Average delta time for last {next_K} iterations:\")\n", + "print(f\"Baseline: {next_K_baseline * 1000} ms\")\n", + "print(f\"Jit: {next_K_jit * 1000} ms\")\n", + "print(f\"TCompile: {next_K_tcompile * 1000} ms\")\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "rwkv-infctx", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}