From b6ee52642d4174c53d0d139010ffe7bdec484557 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:00:23 +0530 Subject: [PATCH 01/35] added utils --- trailmet/algorithms/quantize/__init__.py | 50 --------- trailmet/algorithms/quantize/utils.py | 136 +++++++++++++++++++++++ 2 files changed, 136 insertions(+), 50 deletions(-) create mode 100644 trailmet/algorithms/quantize/utils.py diff --git a/trailmet/algorithms/quantize/__init__.py b/trailmet/algorithms/quantize/__init__.py index 4a7ff40..8870151 100644 --- a/trailmet/algorithms/quantize/__init__.py +++ b/trailmet/algorithms/quantize/__init__.py @@ -19,53 +19,3 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -from .bitsplit import BitSplit -from .brecq import BRECQ -from .lapq import LAPQ -from .methods import ( - UniformAffineQuantizer, - AdaRoundQuantizer, - BitSplitQuantizer, - ActQuantizer, - QuantizationBase, - UniformQuantization, - ClippedUniformQuantization, - FixedClipValueQuantization, - MaxAbsStaticQuantization, - LearnedStepSizeQuantization, - LpNormQuantization, -) -from .qmodel import ( - QuantBasicBlock, - QuantBottleneck, - QuantInvertedResidual, - QuantModule, - BaseQuantBlock, - QBasicBlock, - QBottleneck, - QInvertedResidual, - ActivationModuleWrapper, - ParameterModuleWrapper, -) -from .quantize import ( - BaseQuantization, - StraightThrough, - RoundSTE, - Conv2dFunctor, - LinearFunctor, - FoldBN, -) -from .reconstruct import ( - StopForwardException, - DataSaverHook, - GetLayerInpOut, - save_inp_oup_data, - GradSaverHook, - GetLayerGrad, - save_grad_data, - LinearTempDecay, - LayerLossFunction, - layer_reconstruction, - BlockLossFunction, - block_reconstruction, -) diff --git a/trailmet/algorithms/quantize/utils.py b/trailmet/algorithms/quantize/utils.py new file mode 100644 index 0000000..92d57bf --- /dev/null +++ b/trailmet/algorithms/quantize/utils.py @@ -0,0 +1,136 @@ +# MIT License +# +# Copyright (c) 2023 Transmute AI Lab +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import os +from plotly import graph_objects + +class StopForwardException(Exception): + """ + Used to throw and catch an exception to stop traversing the graph. + """ + pass + +class DataSaverHook: + """ + Forward hook that stores the input and output of a layer. + """ + def __init__(self, store_input=False, store_output=False, stop_forward=False): + self.store_input = store_input + self.store_output = store_output + self.stop_forward = stop_forward + + self.input_store = None + self.output_store = None + + def __call__(self, module, input_batch, output_batch): + if self.store_input: + self.input_store = input_batch + if self.store_output: + self.output_store = output_batch + if self.stop_forward: + raise StopForwardException + +class GradSaverHook: + """ + Backward hook that stores the gradients of a layer. + """ + def __init__(self, store_grad=True): + self.store_grad = store_grad + self.stop_backward = False + self.grad_out = None + + def __call__(self, module, grad_input, grad_output): + if self.store_grad: + self.grad_out = grad_output[0] + if self.stop_backward: + raise StopForwardException + + +class LinearTempDecay: + """ + Class to implement a linear temperature decay scheduler for a given maximum time step. + + :param t_max: maximum number of time steps to decay temperature over. + :param rel_start_decay: relative point in time to start the decay from the maximum time step. [default=.2] + :param start_b: initial temperature value. [default=10] + :param end_b: final temperature value. [default=2] + + """ + def __init__(self, t_max: int, rel_start_decay: float = 0.2, start_b: int = 10, end_b: int = 2): + self.t_max = t_max + self.start_decay = rel_start_decay * t_max + self.start_b = start_b + self.end_b = end_b + + def __call__(self, t): + """ + Cosine annealing scheduler for temperature b. + :param t: the current time step + :return: scheduled temperature + """ + if t < self.start_decay: + return self.start_b + else: + rel_t = (t - self.start_decay) / (self.t_max - self.start_decay) + return self.end_b + (self.start_b - self.end_b) * max(0.0, (1 - rel_t)) + +class Node: + def __init__(self, cost=0, profit=0, bit=None, parent=None, left=None, middle=None, right=None, position='middle'): + self.parent = parent + self.left = left + self.middle = middle + self.right = right + self.position = position + self.cost = cost + self.profit = profit + self.bit = bit + + def __str__(self): + return 'cost: {:.2f} profit: {:.2f}'.format(self.cost, self.profit) + + def __repr__(self): + return self.__str__() + + +class GraphPlotter: + def __init__(self, save_dir: str = './'): + self.save_dir = save_dir + + def line_plotter(self, columns, names, name_fmt: str = '{}', + title: str = '', xlabel: str = '', ylabel: str = '', ytype: str = '-'): + data = [graph_objects.Scatter( + y = columns[i], + mode = 'lines + markers', + name = name_fmt.format(column_name), + ) for i, column_name in enumerate(names)] + layout = graph_objects.Layout( + title = title, + xaxis = dict(title=xlabel), + yaxis = dict(title=ylabel, type=ytype) + ) + fig = graph_objects.Figure(data, layout) + self.save_plot(title, fig) + + def save_plot(self, title, fig: graph_objects.Figure): + if not os.path.exists(self.save_dir): + os.makedirs(self.save_dir) + fig.write_image('{}/{}_plot.png'.format(self.save_dir, title)) \ No newline at end of file From 55f74c6a2432b616b748b255a511b5592b232928 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:00:44 +0530 Subject: [PATCH 02/35] removed reconstruct --- trailmet/algorithms/quantize/reconstruct.py | 834 -------------------- 1 file changed, 834 deletions(-) delete mode 100644 trailmet/algorithms/quantize/reconstruct.py diff --git a/trailmet/algorithms/quantize/reconstruct.py b/trailmet/algorithms/quantize/reconstruct.py deleted file mode 100644 index b5857bd..0000000 --- a/trailmet/algorithms/quantize/reconstruct.py +++ /dev/null @@ -1,834 +0,0 @@ -# MIT License -# -# Copyright (c) 2023 Transmute AI Lab -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# source: https://github.com/yhhhli/BRECQ/tree/main/quant - -import torch -import torch.distributed as dist -import torch.nn.functional as F -from typing import Union -from tqdm import tqdm -from trailmet.algorithms.quantize.quantize import ( - StraightThrough, - BaseQuantization as BQ, -) -from trailmet.algorithms.quantize.qmodel import QuantModule, BaseQuantBlock -from trailmet.algorithms.quantize.methods import AdaRoundQuantizer -from trailmet.utils import lp_loss - -__all__ = [ - 'StopForwardException', - 'DataSaverHook', - 'GetLayerInpOut', - 'save_inp_oup_data', - 'GradSaverHook', - 'GetLayerGrad', - 'save_grad_data', - 'LinearTempDecay', - 'LayerLossFunction', - 'layer_reconstruction', - 'BlockLossFunction', - 'block_reconstruction', -] - -optimizer_map = { - 'sgd': torch.optim.SGD, - 'adam': torch.optim.Adam, - 'adagrad': torch.optim.Adagrad, - 'adadelta': torch.optim.Adadelta, -} - - -class StopForwardException(Exception): - """Used to throw and catch an exception to stop traversing the graph.""" - - pass - - -class DataSaverHook: - """Forward hook that stores the input and output of a layer. - - Parameters - ---------- - store_input (bool): If True, input of a layer will be saved, default=False - store_output (bool): If True, output of a layer will be saved, default=False - stop_forward (bool): If True, forward prop will be stopped, default=False. - """ - - def __init__(self, - store_input=False, - store_output=False, - stop_forward=False): - self.store_input = store_input - self.store_output = store_output - self.stop_forward = stop_forward - - self.input_store = None - self.output_store = None - - def __call__(self, module, input_batch, output_batch): - if self.store_input: - self.input_store = input_batch - if self.store_output: - self.output_store = output_batch - if self.stop_forward: - raise StopForwardException - - -class GetLayerInpOut: - """Get the input and output of a specified layer in a quantized model. - - model: quantized model for which the input and output needs to be extracted. - layer: the layer for which input and output needs to be extracted. - device: the device on which the computation needs to be performed. - asym: save quantized input and full precision output. [default=False] - act_quant: use activation quantization. [default=False] - """ - - def __init__( - self, - model, - layer: Union[QuantModule, BaseQuantBlock], - device: torch.device, - asym: bool = False, - act_quant: bool = False, - ): - self.model = model - self.layer = layer - self.asym = asym - self.device = device - self.act_quant = act_quant - self.data_saver = DataSaverHook(store_input=True, - store_output=True, - stop_forward=True) - - def __call__(self, model_input): - """ - Parameters - ---------- - model_input: calibration data samples - return: tuple of layer input and output - """ - self.model.eval() - self.model.set_quant_state(False, False) - - handle = self.layer.register_forward_hook(self.data_saver) - with torch.no_grad(): - try: - _ = self.model(model_input.to(self.device)) - except StopForwardException: - pass - - if self.asym: - self.data_saver.store_output = False - self.model.set_quant_state(weight_quant=True, - act_quant=self.act_quant) - try: - _ = self.model(model_input.to(self.device)) - except StopForwardException: - pass - self.data_saver.store_output = True - - handle.remove() - - self.model.set_quant_state(False, False) - self.layer.set_quant_state(True, self.act_quant) - self.model.train() - - return ( - self.data_saver.input_store[0].detach(), - self.data_saver.output_store.detach(), - ) - - -def save_inp_oup_data( - model, - layer: Union[QuantModule, BaseQuantBlock], - cali_data: torch.Tensor, - asym: bool = False, - act_quant: bool = False, - batch_size: int = 32, - keep_gpu: bool = True, -): - """Function to save input data and output data of a particular layer/block - over calibration dataset. - - Parameters - ---------- - model: quantized model for which the input and output needs to be extracted. - layer: the layer for which input and output needs to be extracted. - cali_data: calibration dataset - asym: save quantized input and full precision output. [default=False] - act_quant: use activation quantization. [default=False] - batch_size: mini-batch size for calibration. [default=32] - keep_gpu: put saved data on GPU for faster optimization. [default=True] - :return: input and output data - """ - device = next(model.parameters()).device - get_inp_out = GetLayerInpOut(model, - layer, - device=device, - asym=asym, - act_quant=act_quant) - cached_batches = [] - torch.cuda.empty_cache() - - for i in range(int(cali_data.size(0) / batch_size)): - cur_inp, cur_out = get_inp_out(cali_data[i * batch_size:(i + 1) * - batch_size]) - cached_batches.append((cur_inp.cpu(), cur_out.cpu())) - - cached_inps = torch.cat([x[0] for x in cached_batches]) - cached_outs = torch.cat([x[1] for x in cached_batches]) - torch.cuda.empty_cache() - if keep_gpu: - cached_inps = cached_inps.to(device) - cached_outs = cached_outs.to(device) - return cached_inps, cached_outs - - -class GradSaverHook: - """Backward hook that stores the gradients of a layer. - - Parameters - ---------- - store_grad (bool): if True, gradient of the layer will be stored - """ - - def __init__(self, store_grad=True): - self.store_grad = store_grad - self.stop_backward = False - self.grad_out = None - - def __call__(self, module, grad_input, grad_output): - if self.store_grad: - self.grad_out = grad_output[0] - if self.stop_backward: - raise StopForwardException - - -class GetLayerGrad: - """Get the gradient a specified layer in a quantized model. - - Parameters - ---------- - model: quantized model for which the input and output needs to be extracted. - layer: the layer for which input and output needs to be extracted. - device: the device on which the computation needs to be performed. - asym: if True, save quantized input and full precision output. [default=False] - act_quant: use activation quantization. [default=False] - """ - - def __init__( - self, - model, - layer: Union[QuantModule, BaseQuantBlock], - device: torch.device, - act_quant: bool = False, - ): - self.model = model - self.layer = layer - self.device = device - self.act_quant = act_quant - self.data_saver = GradSaverHook(True) - - def __call__(self, model_input): - """Compute the gradients of layer output, note that we compute the - gradient by calculating the KL loss between fp model and quant model. - - Parameters - ---------- - model_input: calibration data samples - :return: gradients for the layer - """ - self.model.eval() - - handle = self.layer.register_backward_hook(self.data_saver) - with torch.enable_grad(): - try: - self.model.zero_grad() - inputs = model_input.to(self.device) - self.model.set_quant_state(False, False) - out_fp = self.model(inputs) - self.model.quantize_model_till(self.layer, self.act_quant) - out_q = self.model(inputs) - loss = F.kl_div( - F.log_softmax(out_q, dim=1), - F.softmax(out_fp, dim=1), - reduction='batchmean', - ) - loss.backward() - except StopForwardException: - pass - - handle.remove() - self.model.set_quant_state(False, False) - self.layer.set_quant_state(True, self.act_quant) - self.model.train() - return self.data_saver.grad_out.data - - -def save_grad_data( - model, - layer: Union[QuantModule, BaseQuantBlock], - cali_data: torch.Tensor, - damping: float = 1.0, - act_quant: bool = False, - batch_size: int = 32, - keep_gpu: bool = True, -): - """Function to save gradient data of a particular layer/block over - calibration dataset. - - Parameters - ---------- - model: quantized model for which the input and output needs to be extracted. - layer: the layer for which input and output needs to be extracted. - cali_data: calibration dataset - damping: damping the second-order gradient by adding some constant in the FIM diagonal - act_quant: use activation quantization. [default=False] - batch_size: mini-batch size for calibration. [default=32] - keep_gpu: put saved data on GPU for faster optimization. [default=True] - :return: gradient data - """ - device = next(model.parameters()).device - get_grad = GetLayerGrad(model, layer, device, act_quant=act_quant) - cached_batches = [] - torch.cuda.empty_cache() - - for i in range(int(cali_data.size(0) / batch_size)): - cur_grad = get_grad(cali_data[i * batch_size:(i + 1) * batch_size]) - cached_batches.append(cur_grad.cpu()) - - cached_grads = torch.cat([x for x in cached_batches]) - cached_grads = cached_grads.abs() + 1.0 - # scaling to make sure its mean is 1 - # cached_grads = cached_grads * torch.sqrt(cached_grads.numel() / cached_grads.pow(2).sum()) - torch.cuda.empty_cache() - if keep_gpu: - cached_grads = cached_grads.to(device) - return cached_grads - - -# ================================ -# ****** Reconstruct Layer ******* -# ================================ - - -class LinearTempDecay: - """Class to implement a linear temperature decay scheduler for a given - maximum time step. - - Parameters - ---------- - t_max: maximum number of time steps to decay temperature over. - rel_start_decay: relative point in time to start the decay from the maximum time step. [default=.2] - start_b: initial temperature value. [default=10] - end_b: final temperature value. [default=2] - """ - - def __init__( - self, - t_max: int, - rel_start_decay: float = 0.2, - start_b: int = 10, - end_b: int = 2, - ): - self.t_max = t_max - self.start_decay = rel_start_decay * t_max - self.start_b = start_b - self.end_b = end_b - - def __call__(self, t): - """Cosine annealing scheduler for temperature b. - - Parameters - ---------- - t: the current time step - :return: scheduled temperature - """ - if t < self.start_decay: - return self.start_b - else: - rel_t = (t - self.start_decay) / (self.t_max - self.start_decay) - return self.end_b + (self.start_b - self.end_b) * max( - 0.0, (1 - rel_t)) - - -class LayerLossFunction: - """ - Parameters - ---------- - layer (object): layer to be quantized - Round_loss (str): type of regularization term used to optimize rounding policy (options: relaxation, none) - Weight (float): weight of rounding loss in total loss - Rec_loss (str): type of output reconstruction loss (options: mse, fisher_diag, fisher_full) - max_count (int): number of iterations - b_range (tuple): range of rounding relaxation factor (b) with linear temp decay scheduler - decay_start (float): starting point for temp decay of b - warmup (float): fraction of iterations used for warmup before applying rounding loss - p (float): power in lp-norm computation of reconstruction loss - """ - - def __init__( - self, - layer: QuantModule, - round_loss: str = 'relaxation', - weight: float = 1.0, - rec_loss: str = 'mse', - max_count: int = 2000, - b_range: tuple = (10, 2), - decay_start: float = 0.0, - warmup: float = 0.0, - p: float = 2.0, - ): - self.layer = layer - self.round_loss = round_loss - self.weight = weight - self.rec_loss = rec_loss - self.loss_start = max_count * warmup - self.p = p - self.count = 0 - # self.pbar = tqdm(total=max_count) - self.pbar = tqdm( - total=max_count, - desc='Reconstructing Layer: Loss (X.X) b (X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - ) - self.temp_decay = LinearTempDecay( - max_count, - rel_start_decay=warmup + (1 - warmup) * decay_start, - start_b=b_range[0], - end_b=b_range[1], - ) - - def __call__(self, pred, tgt, grad=None): - """ - Compute the total loss for adaptive rounding: - rec_loss is the quadratic output reconstruction loss, round_loss is - a regularization term to optimize the rounding policy - - Parameters - ---------- - pred: output from quantized model - tgt: output from FP model - grad: gradients to compute fisher information - :return: total loss function - """ - self.count += 1 - if self.rec_loss == 'mse': - rec_loss = lp_loss(pred, tgt, p=self.p) - elif self.rec_loss == 'fisher_diag': - rec_loss = ((pred - tgt).pow(2) * grad.pow(2)).sum(1).mean() - elif self.rec_loss == 'fisher_full': - a = (pred - tgt).abs() - grad = grad.abs() - batch_dotprod = torch.sum(a * grad, (1, 2, 3)).view(-1, 1, 1, 1) - rec_loss = (batch_dotprod * a * grad).mean() / 100 - else: - raise ValueError( - 'Not supported reconstruction loss function: {}'.format( - self.rec_loss)) - - b = self.temp_decay(self.count) - if self.count < self.loss_start or self.round_loss == 'none': - b = round_loss = 0 - elif self.round_loss == 'relaxation': - round_loss = 0 - round_vals = self.layer.weight_quantizer.get_soft_targets() - round_loss += (self.weight * - (1 - ((round_vals - 0.5).abs() * 2).pow(b)).sum()) - else: - raise NotImplementedError - - total_loss = rec_loss + round_loss - - if self.count % 100 == 0: - self.pbar.set_description( - 'Reconstructing Layer: Loss ({:.3f}) b ({:.1f})'.format( - float(total_loss), b)) - # self.pbar.set_postfix(loss=float(total_loss), b=b) - self.pbar.update(1) - return total_loss - - -def layer_reconstruction( - model, - layer: QuantModule, - cali_data: torch.Tensor, - batch_size: int = 32, - iters: int = 20000, - weight: float = 0.001, - opt_mode: str = 'mse', - asym: bool = False, - include_act_func: bool = True, - b_range: tuple = (20, 2), - warmup: float = 0.0, - act_quant: bool = False, - lr: float = 4e-5, - p: float = 2.0, - multi_gpu: bool = False, - optim='adam', -): - """Block reconstruction to optimize the output from each layer. - - Parameters - ---------- - model: QuantModel - layer: QuantModule that needs to be optimized - cali_data: data for calibration, typically 1024 training images, as described in AdaRound - batch_size: mini-batch size for reconstruction - iters: optimization iterations for reconstruction, - weight: the weight of rounding regularization term - opt_mode: optimization mode - asym: asymmetric optimization designed in AdaRound, use quant input to reconstruct fp output - include_act_func: optimize the output after activation function - b_range: temperature range - warmup: proportion of iterations that no scheduling for temperature - act_quant: use activation quantization or not. - lr: learning rate for act delta learning - p: L_p norm minimization - multi_gpu: use multi-GPU or not, if enabled, we should sync the gradients - """ - - model.set_quant_state(False, False) - layer.set_quant_state(True, act_quant) - round_mode = 'learned_hard_sigmoid' - - if not include_act_func: - org_act_func = layer.activation_function - layer.activation_function = StraightThrough() - - if not act_quant: - # Replace weight quantizer to AdaRoundQuantizer - layer.weight_quantizer = AdaRoundQuantizer( - uaq=layer.weight_quantizer, - round_mode=round_mode, - weight_tensor=layer.org_weight.data, - ) - layer.weight_quantizer.soft_targets = True - - # Set up optimizer - opt_params = [layer.weight_quantizer.alpha] - optimizer = optimizer_map[optim](opt_params) - scheduler = None - else: - # Use UniformAffineQuantizer to learn delta - opt_params = [layer.act_quantizer.delta] - optimizer = optimizer_map[optim](opt_params, lr=lr) - scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, - T_max=iters, - eta_min=0.0) - - loss_mode = 'none' if act_quant else 'relaxation' - rec_loss = opt_mode - - loss_func = LayerLossFunction( - layer, - round_loss=loss_mode, - weight=weight, - max_count=iters, - rec_loss=rec_loss, - b_range=b_range, - decay_start=0, - warmup=warmup, - p=p, - ) - - # Save data before optimizing the rounding - cached_inps, cached_outs = save_inp_oup_data(model, layer, cali_data, asym, - act_quant, batch_size) - if opt_mode != 'mse': - cached_grads = save_grad_data(model, - layer, - cali_data, - act_quant, - batch_size=batch_size) - else: - cached_grads = None - device = 'cuda' - for i in range(iters): - idx = torch.randperm(cached_inps.size(0))[:batch_size] - cur_inp = cached_inps[idx] - cur_out = cached_outs[idx] - cur_grad = cached_grads[idx] if opt_mode != 'mse' else None - - optimizer.zero_grad() - out_quant = layer(cur_inp) - - err = loss_func(out_quant, cur_out, cur_grad) - err.backward(retain_graph=True) - if multi_gpu: - for p in opt_params: - dist.all_reduce(p.grad) - optimizer.step() - if scheduler: - scheduler.step() - - torch.cuda.empty_cache() - - # Finish optimization, use hard rounding. - layer.weight_quantizer.soft_targets = False - - # Reset original activation function - if not include_act_func: - layer.activation_function = org_act_func - - -# ================================= -# ******* Reconstruct Block ******* -# ================================= - - -class BlockLossFunction: - """ - Parameters - ---------- - Module (object): module or block being quantized - Round_loss (str): type of regularization term used to optimize rounding policy (options: relaxation, none) - Weight (float): weight of rounding loss in total loss - Rec_loss (str): type of output reconstruction loss (options: mse, fisher_diag, fisher_full) - max_count (int): number of iterations - b_range (tuple): range of rounding relaxation factor (b) with linear temp decay scheduler - decay_start (float): starting point for temp decay of b - warmup (float): fraction of iterations used for warmup before applying rounding loss - p (float): power in lp-norm computation of reconstruction loss - """ - - def __init__( - self, - block: BaseQuantBlock, - round_loss: str = 'relaxation', - weight: float = 1.0, - rec_loss: str = 'mse', - max_count: int = 2000, - b_range: tuple = (10, 2), - decay_start: float = 0.0, - warmup: float = 0.0, - p: float = 2.0, - ): - self.block = block - self.round_loss = round_loss - self.weight = weight - self.rec_loss = rec_loss - self.loss_start = max_count * warmup - self.p = p - self.count = 0 - # self.pbar = tqdm(total=max_count) - self.pbar = tqdm( - total=max_count, - desc='Reconstructing Block: Loss (X.X) b (X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - ) - self.temp_decay = LinearTempDecay( - max_count, - rel_start_decay=warmup + (1 - warmup) * decay_start, - start_b=b_range[0], - end_b=b_range[1], - ) - - def __call__(self, pred, tgt, grad=None): - """ - Compute the total loss for adaptive rounding: - rec_loss is the quadratic output reconstruction loss, round_loss is - a regularization term to optimize the rounding policy - - Parameters - ---------- - pred: output from quantized model - tgt: output from FP model - grad: gradients to compute fisher information - :return: total loss function - """ - self.count += 1 - if self.rec_loss == 'mse': - rec_loss = lp_loss(pred, tgt, p=self.p) - elif self.rec_loss == 'fisher_diag': - rec_loss = ((pred - tgt).pow(2) * grad.pow(2)).sum(1).mean() - elif self.rec_loss == 'fisher_full': - a = (pred - tgt).abs() - grad = grad.abs() - batch_dotprod = torch.sum(a * grad, (1, 2, 3)).view(-1, 1, 1, 1) - rec_loss = (batch_dotprod * a * grad).mean() / 100 - else: - raise ValueError( - 'Not supported reconstruction loss function: {}'.format( - self.rec_loss)) - - b = self.temp_decay(self.count) - if self.count < self.loss_start or self.round_loss == 'none': - b = round_loss = 0 - elif self.round_loss == 'relaxation': - round_loss = 0 - for name, module in self.block.named_modules(): - if isinstance(module, QuantModule): - round_vals = module.weight_quantizer.get_soft_targets() - round_loss += (self.weight * (1 - ( - (round_vals - 0.5).abs() * 2).pow(b)).sum()) - else: - raise NotImplementedError - - total_loss = rec_loss + round_loss - if self.count % 100 == 0: - self.pbar.set_description( - 'Reconstructing Block: Loss ({:.3f}) b ({:.1f})'.format( - float(total_loss), b)) - # self.pbar.set_postfix(loss=float(total_loss), b=b) - self.pbar.update(1) - return total_loss - - -def block_reconstruction( - model, - block: BaseQuantBlock, - cali_data: torch.Tensor, - batch_size: int = 32, - iters: int = 20000, - weight: float = 0.01, - opt_mode: str = 'mse', - asym: bool = False, - include_act_func: bool = True, - b_range: tuple = (20, 2), - warmup: float = 0.0, - act_quant: bool = False, - lr: float = 4e-5, - p: float = 2.0, - multi_gpu: bool = False, - optim='adam', -): - """Block reconstruction to optimize the output from each block. - - Parameters - ---------- - model: QuantModel - block: BaseQuantBlock that needs to be optimized - cali_data: data for calibration, typically 1024 training images, as described in AdaRound - batch_size: mini-batch size for reconstruction - iters: optimization iterations for reconstruction, - weight: the weight of rounding regularization term - opt_mode: optimization mode - asym: asymmetric optimization designed in AdaRound, use quant input to reconstruct fp output - include_act_func: optimize the output after activation function - b_range: temperature range - warmup: proportion of iterations that no scheduling for temperature - act_quant: use activation quantization or not. - lr: learning rate for act delta learning - p: L_p norm minimization - multi_gpu: use multi-GPU or not, if enabled, we should sync the gradients - """ - model.set_quant_state(False, False) - block.set_quant_state(True, act_quant) - round_mode = 'learned_hard_sigmoid' - - if not include_act_func: - org_act_func = block.activation_function - block.activation_function = StraightThrough() - - if not act_quant: - # Replace weight quantizer to AdaRoundQuantizer - for name, module in block.named_modules(): - if isinstance(module, QuantModule): - module.weight_quantizer = AdaRoundQuantizer( - uaq=module.weight_quantizer, - round_mode=round_mode, - weight_tensor=module.org_weight.data, - ) - module.weight_quantizer.soft_targets = True - - # Set up optimizer - opt_params = [] - for name, module in block.named_modules(): - if isinstance(module, QuantModule): - opt_params += [module.weight_quantizer.alpha] - optimizer = optimizer_map[optim](opt_params) - scheduler = None - else: - # Use UniformAffineQuantizer to learn delta - if hasattr(block.act_quantizer, 'delta'): - opt_params = [block.act_quantizer.delta] - else: - opt_params = [] - for name, module in block.named_modules(): - if isinstance(module, QuantModule): - if module.act_quantizer.delta is not None: - opt_params += [module.act_quantizer.delta] - optimizer = optimizer_map[optim](opt_params, lr=lr) - scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, - T_max=iters, - eta_min=0.0) - - loss_mode = 'none' if act_quant else 'relaxation' - rec_loss = opt_mode - - loss_func = BlockLossFunction( - block, - round_loss=loss_mode, - weight=weight, - max_count=iters, - rec_loss=rec_loss, - b_range=b_range, - decay_start=0, - warmup=warmup, - p=p, - ) - - # Save data before optimizing the rounding - cached_inps, cached_outs = save_inp_oup_data(model, block, cali_data, asym, - act_quant, batch_size) - if opt_mode != 'mse': - cached_grads = save_grad_data(model, - block, - cali_data, - act_quant, - batch_size=batch_size) - else: - cached_grads = None - device = 'cuda' - for i in range(iters): - idx = torch.randperm(cached_inps.size(0))[:batch_size] - cur_inp = cached_inps[idx].to(device) - cur_out = cached_outs[idx].to(device) - cur_grad = cached_grads[idx].to(device) if opt_mode != 'mse' else None - - optimizer.zero_grad() - out_quant = block(cur_inp) - - err = loss_func(out_quant, cur_out, cur_grad) - err.backward(retain_graph=True) - if multi_gpu: - for p in opt_params: - dist.all_reduce(p.grad) - optimizer.step() - if scheduler: - scheduler.step() - - torch.cuda.empty_cache() - - # Finish optimization, use hard rounding. - for name, module in block.named_modules(): - if isinstance(module, QuantModule): - module.weight_quantizer.soft_targets = False - - # Reset original activation function - if not include_act_func: - block.activation_function = org_act_func From 88713290bcff115ee6742acd40f303631eb834e2 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:01:09 +0530 Subject: [PATCH 03/35] refactored quant modules --- trailmet/algorithms/quantize/modules.py | 354 +++++++++++++ trailmet/algorithms/quantize/qmodel.py | 651 ------------------------ 2 files changed, 354 insertions(+), 651 deletions(-) create mode 100644 trailmet/algorithms/quantize/modules.py delete mode 100644 trailmet/algorithms/quantize/qmodel.py diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py new file mode 100644 index 0000000..529be9c --- /dev/null +++ b/trailmet/algorithms/quantize/modules.py @@ -0,0 +1,354 @@ +# MIT License +# +# Copyright (c) 2023 Transmute AI Lab +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import torch +import torch.nn as nn +import torch.nn.functional as F +from typing import Union +from trailmet.models.resnet import BasicBlock, Bottleneck +from trailmet.models.mobilenet import InvertedResidual +from trailmet.algorithms.quantize.methods import UniformAffineQuantizer, ActQuantizer + + +#============================================ +#***** Quantization Modules for BRECQ ******* +#============================================ +""" +Supported quantization wrappers for pytorch modules :- + - BasicBlock(nn.Module) -> QuantBasicBlock(BaseQuantBlock(nn.Module)) + - Bottleneck(nn.Module) -> QuantBottleneck(BaseQuantBlock(nn.Module)) + - InvertedResidual(nn.Module) -> QuantInvertedResidual(BaseQuantBlock(nn.Module)) + - nn.Conv2d, nn.Linear -> QuantModule(nn.Module) +""" +class StraightThrough(nn.Module): + """Identity Layer""" + def __int__(self): + super().__init__() + pass + + def forward(self, input): + return input + +class QuantModule(nn.Module): + """ + Quantized Module that can perform quantized convolution or normal convolution. + To activate quantization, please use set_quant_state function. + """ + def __init__(self, org_module: Union[nn.Conv2d, nn.Linear], weight_quant_params: dict = {}, + act_quant_params: dict = {}, disable_act_quant: bool = False, se_module = None): + super(QuantModule, self).__init__() + if isinstance(org_module, nn.Conv2d): + self.fwd_kwargs = dict(stride=org_module.stride, padding=org_module.padding, + dilation=org_module.dilation, groups=org_module.groups) + self.fwd_func = F.conv2d + else: + self.fwd_kwargs = dict() + self.fwd_func = F.linear + self.weight = org_module.weight + self.org_weight = org_module.weight.data.clone() + if org_module.bias is not None: + self.bias = org_module.bias + self.org_bias = org_module.bias.data.clone() + else: + self.bias = None + self.org_bias = None + + # de-activate the quantized forward default + self.use_weight_quant = False + self.use_act_quant = False + self.disable_act_quant = disable_act_quant + + # initialize quantizer + self.weight_quantizer = weight_quant_params.get('method', UniformAffineQuantizer)(**weight_quant_params) + self.act_quantizer = act_quant_params.get('method', UniformAffineQuantizer)(**act_quant_params) + + self.activation_function = StraightThrough() + self.ignore_reconstruction = False + + self.se_module = se_module + self.extra_repr = org_module.extra_repr + + def forward(self, input: torch.Tensor): + if self.use_weight_quant: + weight = self.weight_quantizer(self.weight) + bias = self.bias + else: + weight = self.org_weight + bias = self.org_bias + out = self.fwd_func(input, weight, bias, **self.fwd_kwargs) + # disable act quantization is designed for convolution before elemental-wise operation, + # in that case, we apply activation function and quantization after ele-wise op. + if self.se_module is not None: + out = self.se_module(out) + out = self.activation_function(out) + if self.disable_act_quant: + return out + if self.use_act_quant: + out = self.act_quantizer(out) + return out + + def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): + self.use_weight_quant = weight_quant + self.use_act_quant = act_quant + + +class BaseQuantBlock(nn.Module): + """ + Base implementation of block structures for all networks. + Due to the branch architecture, we have to perform activation function + and quantization after the elemental-wise add operation, therefore, we + put this part in this class. + """ + def __init__(self, act_quant_params: dict = {}): + super().__init__() + self.use_weight_quant = False + self.use_act_quant = False + self.act_quantizer = act_quant_params.get('method', UniformAffineQuantizer)(**act_quant_params) + self.activation_function = StraightThrough() + self.ignore_reconstruction = False + + def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): + # setting weight quantization here does not affect actual forward pass + self.use_weight_quant = weight_quant + self.use_act_quant = act_quant + for m in self.modules(): + if isinstance(m, QuantModule): + m.set_quant_state(weight_quant, act_quant) + +class QuantBasicBlock(BaseQuantBlock): + """ + Implementation of Quantized BasicBlock used in ResNet-18 and ResNet-34. + """ + def __init__(self, basic_block: BasicBlock, weight_quant_params: dict = {}, act_quant_params: dict = {}): + super().__init__(act_quant_params) + self.conv1 = QuantModule(basic_block.conv1, weight_quant_params, act_quant_params) + self.conv1.activation_function = basic_block.activ + self.conv2 = QuantModule(basic_block.conv2, weight_quant_params, act_quant_params, disable_act_quant=True) + self.activation_function = basic_block.activ + + if basic_block.downsample is None: + self.downsample = None + else: + self.downsample = QuantModule(basic_block.downsample[0], weight_quant_params, act_quant_params, + disable_act_quant=True) + # copying all attributes in original block + self.stride = basic_block.stride + + def forward(self, x): + residual = x if self.downsample is None else self.downsample(x) + out = self.conv1(x) + out = self.conv2(out) + out += residual + out = self.activation_function(out) + if self.use_act_quant: + out = self.act_quantizer(out) + return out + +class QuantBottleneck(BaseQuantBlock): + """ + Implementation of Quantized Bottleneck Block used in ResNet-50, -101 and -152. + """ + + def __init__(self, bottleneck: Bottleneck, weight_quant_params: dict = {}, act_quant_params: dict = {}): + super().__init__(act_quant_params) + self.conv1 = QuantModule(bottleneck.conv1, weight_quant_params, act_quant_params) + self.conv1.activation_function = bottleneck.activ + self.conv2 = QuantModule(bottleneck.conv2, weight_quant_params, act_quant_params) + self.conv2.activation_function = bottleneck.activ + self.conv3 = QuantModule(bottleneck.conv3, weight_quant_params, act_quant_params, disable_act_quant=True) + + # modify the activation function to ReLU + self.activation_function = bottleneck.activ + + if bottleneck.downsample is None: + self.downsample = None + else: + self.downsample = QuantModule(bottleneck.downsample[0], weight_quant_params, act_quant_params, + disable_act_quant=True) + # copying all attributes in original block + self.stride = bottleneck.stride + + def forward(self, x): + residual = x if self.downsample is None else self.downsample(x) + out = self.conv1(x) + out = self.conv2(out) + out = self.conv3(out) + out += residual + out = self.activation_function(out) + if self.use_act_quant: + out = self.act_quantizer(out) + return out + +class QuantInvertedResidual(BaseQuantBlock): + """ + Implementation of Quantized Inverted Residual Block used in MobileNetV2. + Inverted Residual does not have activation function. + """ + + def __init__(self, inv_res: InvertedResidual, weight_quant_params: dict = {}, act_quant_params: dict = {}): + super().__init__(act_quant_params) + self.stride = inv_res.stride + self.inp = inv_res.inp + self.oup = inv_res.oup + self.exp = inv_res.exp + self.conv1 = QuantModule(inv_res.conv1, weight_quant_params, act_quant_params) + self.conv1.activation_function = nn.ReLU6(inplace=True) + self.conv2 = QuantModule(inv_res.conv2, weight_quant_params, act_quant_params) + self.conv2.activation_function = nn.ReLU6(inplace=True) + self.conv3 = QuantModule(inv_res.conv3, weight_quant_params, act_quant_params) + self.shortcut = nn.Sequential() + if self.stride==1 and self.inp!=self.oup: + self.shortcut = nn.Sequential( + QuantModule(inv_res.shortcut[0], weight_quant_params, act_quant_params) + ) + # self.use_res_connect = inv_res.use_res_connect + # self.expand_ratio = inv_res.exp + # if self.expand_ratio == 1: + # self.conv = nn.Sequential( + # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), + # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params, disable_act_quant=True), + # ) + # self.conv[0].activation_function = nn.ReLU6() + # else: + # self.conv = nn.Sequential( + # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), + # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params), + # QuantModule(inv_res.conv[6], weight_quant_params, act_quant_params, disable_act_quant=True), + # ) + # self.conv[0].activation_function = nn.ReLU6() + # self.conv[1].activation_function = nn.ReLU6() + + def forward(self, x): + out = self.conv1(x) + out = self.conv2(out) + out = self.conv3(out) + out = out + self.shortcut(x) if self.stride==1 else out + return out + # if self.use_res_connect: + # out = x + self.conv(x) + # else: + # out = self.conv(x) + # out = self.activation_function(out) + # if self.use_act_quant: + # out = self.act_quantizer(out) + # return out + + +#=============================================== +#***** Quantization Modules for BitSplit ******* +#=============================================== +""" +Supported quantization wrappers for pytorch modules :- + - BasicBlock(nn.Module) -> QBasicBlock(nn.Module) + - Bottleneck(nn.Module) -> QBottleneck(nn.Module) + - InvertedResidual(nn.Module) -> QInvertedResidual(nn.Module) +""" + +class QBasicBlock(nn.Module): + expansion = 1 + def __init__(self, basic_block: BasicBlock): + super().__init__() + self.quant1 = ActQuantizer() + self.conv1 = basic_block.conv1 + self.bn1 = basic_block.bn1 + self.activ = basic_block.activ + self.quant2 = ActQuantizer() + self.conv2 = basic_block.conv2 + self.bn2 = basic_block.bn2 + self.downsample = basic_block.downsample + self.stride = basic_block.stride + + def forward(self, x): + residual = x + x = self.quant1(x) + out = self.activ(self.bn1(self.conv1(x))) + out = self.quant2(out) + out = self.bn2(self.conv2(out)) + if self.downsample is not None: + residual = self.downsample(x) + out += residual + out = self.activ(out) + return out + + +class QBottleneck(nn.Module): + expansion = 4 + def __init__(self, bottleneck: Bottleneck): + super().__init__() + self.quant1 = ActQuantizer() + self.conv1 = bottleneck.conv1 + self.bn1 = bottleneck.bn1 + self.quant2 = ActQuantizer() + self.conv2 = bottleneck.conv2 + self.bn2 = bottleneck.bn2 + self.quant3 = ActQuantizer() + self.conv3 = bottleneck.conv3 + self.bn3 = bottleneck.bn3 + self.activ = bottleneck.activ + self.downsample = bottleneck.downsample + self.stride = bottleneck.stride + + def forward(self, x): + residual = x + x = self.quant1(x) + out = self.activ(self.bn1(self.conv1(x))) + out = self.quant2(out) + out = self.activ(self.bn2(self.conv2(out))) + out = self.quant3(out) + out = self.bn3(self.conv3(out)) + if self.downsample is not None: + residual = self.downsample(x) + out += residual + out = self.activ(out) + return out + + +class QInvertedResidual(nn.Module): + def __init__(self, inv_res: InvertedResidual): + super().__init__() + self.stride = inv_res.stride + self.inp = inv_res.inp + self.oup = inv_res.oup + self.exp = inv_res.exp + self.quant1 = ActQuantizer(islinear=1) + self.conv1 = inv_res.conv1 + self.bn1 = inv_res.bn1 + self.quant2 = ActQuantizer(islinear=1) + self.conv2 = inv_res.conv2 + self.bn2 = inv_res.bn2 + self.quant3 = ActQuantizer(islinear=0) + self.conv3 = inv_res.conv3 + self.bn3 = inv_res.bn3 + self.shortcut = inv_res.shortcut + + def forward(self, x): + x = self.quant1(x) + out = F.relu(self.bn1(self.conv1(x))) + out = self.quant2(out) + out = F.relu(self.bn2(self.conv2(out))) + out = self.quant3(out) + out = self.bn3(self.conv3(out)) + out = out + self.shortcut(x) if self.stride==1 else out + return out + + + \ No newline at end of file diff --git a/trailmet/algorithms/quantize/qmodel.py b/trailmet/algorithms/quantize/qmodel.py deleted file mode 100644 index 8fd2862..0000000 --- a/trailmet/algorithms/quantize/qmodel.py +++ /dev/null @@ -1,651 +0,0 @@ -# MIT License -# -# Copyright (c) 2023 Transmute AI Lab -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -import torch -import torch.nn as nn -import torch.nn.functional as F -from typing import Union -from trailmet.models.resnet import BasicBlock, Bottleneck -from trailmet.models.mobilenet import InvertedResidual -from trailmet.algorithms.quantize.quantize import StraightThrough -from trailmet.algorithms.quantize.methods import ( - MaxAbsStaticQuantization, - LpNormQuantization, -) -from trailmet.algorithms.quantize.methods import UniformAffineQuantizer -from trailmet.algorithms.quantize.methods import ActQuantizer - -__all__ = [ - 'QuantBasicBlock', - 'QuantBottleneck', - 'QuantInvertedResidual', - 'QuantModule', - 'BaseQuantBlock', - 'QBasicBlock', - 'QBottleneck', - 'QInvertedResidual', - 'ActivationModuleWrapper', - 'ParameterModuleWrapper', -] -# ============================================ -# ***** Quantization Modules for BRECQ ******* -# ============================================ -""" -Supported quantization wrappers for pytorch modules :- - - BasicBlock(nn.Module) -> QuantBasicBlock(BaseQuantBlock(nn.Module)) - - Bottleneck(nn.Module) -> QuantBottleneck(BaseQuantBlock(nn.Module)) - - InvertedResidual(nn.Module) -> QuantInvertedResidual(BaseQuantBlock(nn.Module)) - - nn.Conv2d, nn.Linear -> QuantModule(nn.Module) -""" - - -class QuantModule(nn.Module): - """Quantized Module that can perform quantized convolution or normal - convolution. - - To activate quantization, please use set_quant_state function. - - Parameters - ---------- - org_module (nn.Module): Module to be used - weight_quant_params (dict): Weight parameters - act_quant_params (dict): Activation Parameters - disable_act_quant (bool): if True, activation layer will be disabled - se_module (nn.Module): SE Module to be used - """ - - def __init__( - self, - org_module: Union[nn.Conv2d, nn.Linear], - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - disable_act_quant: bool = False, - se_module=None, - ): - super(QuantModule, self).__init__() - if isinstance(org_module, nn.Conv2d): - self.fwd_kwargs = dict( - stride=org_module.stride, - padding=org_module.padding, - dilation=org_module.dilation, - groups=org_module.groups, - ) - self.fwd_func = F.conv2d - else: - self.fwd_kwargs = dict() - self.fwd_func = F.linear - self.weight = org_module.weight - self.org_weight = org_module.weight.data.clone() - if org_module.bias is not None: - self.bias = org_module.bias - self.org_bias = org_module.bias.data.clone() - else: - self.bias = None - self.org_bias = None - # de-activate the quantized forward default - self.use_weight_quant = False - self.use_act_quant = False - self.disable_act_quant = disable_act_quant - # initialize quantizer - self.weight_quantizer = UniformAffineQuantizer(**weight_quant_params) - self.act_quantizer = UniformAffineQuantizer(**act_quant_params) - - self.activation_function = StraightThrough() - self.ignore_reconstruction = False - - self.se_module = se_module - self.extra_repr = org_module.extra_repr - - def forward(self, input: torch.Tensor): - if self.use_weight_quant: - weight = self.weight_quantizer(self.weight) - bias = self.bias - else: - weight = self.org_weight - bias = self.org_bias - out = self.fwd_func(input, weight, bias, **self.fwd_kwargs) - # disable act quantization is designed for convolution before elemental-wise operation, - # in that case, we apply activation function and quantization after ele-wise op. - if self.se_module is not None: - out = self.se_module(out) - out = self.activation_function(out) - if self.disable_act_quant: - return out - if self.use_act_quant: - out = self.act_quantizer(out) - return out - - def set_quant_state(self, - weight_quant: bool = False, - act_quant: bool = False): - self.use_weight_quant = weight_quant - self.use_act_quant = act_quant - - -class BaseQuantBlock(nn.Module): - """Base implementation of block structures for all networks. - - Due to the branch architecture, we have to perform activation function and - quantization after the elemental-wise add operation, therefore, we put this - part in this class. - - Parameters - ---------- - act_quant_params (dict): Activation parameters - """ - - def __init__(self, act_quant_params: dict = {}): - super().__init__() - self.use_weight_quant = False - self.use_act_quant = False - # initialize quantizer - - self.act_quantizer = UniformAffineQuantizer(**act_quant_params) - self.activation_function = StraightThrough() - - self.ignore_reconstruction = False - - def set_quant_state(self, - weight_quant: bool = False, - act_quant: bool = False): - # setting weight quantization here does not affect actual forward pass - self.use_weight_quant = weight_quant - self.use_act_quant = act_quant - for m in self.modules(): - if isinstance(m, QuantModule): - m.set_quant_state(weight_quant, act_quant) - - -class QuantBasicBlock(BaseQuantBlock): - """Implementation of Quantized BasicBlock used in ResNet-18 and ResNet-34. - - Parameters - ---------- - basic_block (object): BasicBlock which is to be used - weight_quant_params (dict): Weight parameters - act_quant_params (dict): Activation Parameters - """ - - def __init__( - self, - basic_block: BasicBlock, - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - ): - super().__init__(act_quant_params) - self.conv1 = QuantModule(basic_block.conv1, weight_quant_params, - act_quant_params) - self.conv1.activation_function = basic_block.active - self.conv2 = QuantModule( - basic_block.conv2, - weight_quant_params, - act_quant_params, - disable_act_quant=True, - ) - - # modify the activation function to ReLU - self.activation_function = basic_block.active - - if basic_block.downsample is None: - self.downsample = None - else: - self.downsample = QuantModule( - basic_block.downsample[0], - weight_quant_params, - act_quant_params, - disable_act_quant=True, - ) - # copying all attributes in original block - self.stride = basic_block.stride - - def forward(self, x): - residual = x if self.downsample is None else self.downsample(x) - out = self.conv1(x) - out = self.conv2(out) - out += residual - out = self.activation_function(out) - if self.use_act_quant: - out = self.act_quantizer(out) - return out - - -class QuantBottleneck(BaseQuantBlock): - """ - Implementation of Quantized Bottleneck Block used in ResNet-50, -101 and - -152. - - Parameters - ---------- - bottleneck (object): Bottleneck to be used - weight_quant_params (dict): Weight parameters - act_quant_params (dict): Activation Parameters - """ - - def __init__( - self, - bottleneck: Bottleneck, - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - ): - super().__init__(act_quant_params) - self.conv1 = QuantModule(bottleneck.conv1, weight_quant_params, - act_quant_params) - self.conv1.activation_function = bottleneck.active - self.conv2 = QuantModule(bottleneck.conv2, weight_quant_params, - act_quant_params) - self.conv2.activation_function = bottleneck.active - self.conv3 = QuantModule( - bottleneck.conv3, - weight_quant_params, - act_quant_params, - disable_act_quant=True, - ) - - # modify the activation function to ReLU - self.activation_function = bottleneck.active - - if bottleneck.downsample is None: - self.downsample = None - else: - self.downsample = QuantModule( - bottleneck.downsample[0], - weight_quant_params, - act_quant_params, - disable_act_quant=True, - ) - # copying all attributes in original block - self.stride = bottleneck.stride - - def forward(self, x): - residual = x if self.downsample is None else self.downsample(x) - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - out += residual - out = self.activation_function(out) - if self.use_act_quant: - out = self.act_quantizer(out) - return out - - -class QuantInvertedResidual(BaseQuantBlock): - """Implementation of Quantized Inverted Residual Block used in MobileNetV2. - - Inverted Residual does not have activation function. - - Parameters - ---------- - inv_res (object): Inverted Residual block to be used - weight_quant_params (dict): Weight parameters - act_quant_params (dict): Activation Parameters - """ - - def __init__( - self, - inv_res: InvertedResidual, - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - ): - super().__init__(act_quant_params) - self.stride = inv_res.stride - self.inp = inv_res.inp - self.oup = inv_res.oup - self.exp = inv_res.exp - self.conv1 = QuantModule(inv_res.conv1, weight_quant_params, - act_quant_params) - self.conv1.activation_function = nn.ReLU6(inplace=True) - self.conv2 = QuantModule(inv_res.conv2, weight_quant_params, - act_quant_params) - self.conv2.activation_function = nn.ReLU6(inplace=True) - self.conv3 = QuantModule(inv_res.conv3, weight_quant_params, - act_quant_params) - self.shortcut = nn.Sequential() - if self.stride == 1 and self.inp != self.oup: - self.shortcut = nn.Sequential( - QuantModule(inv_res.shortcut[0], weight_quant_params, - act_quant_params)) - # self.use_res_connect = inv_res.use_res_connect - # self.expand_ratio = inv_res.exp - # if self.expand_ratio == 1: - # self.conv = nn.Sequential( - # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params, disable_act_quant=True), - # ) - # self.conv[0].activation_function = nn.ReLU6() - # else: - # self.conv = nn.Sequential( - # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[6], weight_quant_params, act_quant_params, disable_act_quant=True), - # ) - # self.conv[0].activation_function = nn.ReLU6() - # self.conv[1].activation_function = nn.ReLU6() - - def forward(self, x): - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - out = out + self.shortcut(x) if self.stride == 1 else out - return out - # if self.use_res_connect: - # out = x + self.conv(x) - # else: - # out = self.conv(x) - # out = self.activation_function(out) - # if self.use_act_quant: - # out = self.act_quantizer(out) - # return out - - -# =============================================== -# ***** Quantization Modules for BitSplit ******* -# =============================================== -""" -Supported quantization wrappers for pytorch modules :- - - BasicBlock(nn.Module) -> QBasicBlock(nn.Module) - - Bottleneck(nn.Module) -> QBottleneck(nn.Module) - - InvertedResidual(nn.Module) -> QInvertedResidual(nn.Module) -""" - - -class QBasicBlock(nn.Module): - """ - Parameters - ---------- - basic_block (object): BasicBlock which is to be used - """ - - expansion = 1 - - def __init__(self, basic_block: BasicBlock): - super().__init__() - self.quant1 = ActQuantizer() - self.conv1 = basic_block.conv1 - self.bn1 = basic_block.bn1 - self.active = basic_block.active - self.quant2 = ActQuantizer() - self.conv2 = basic_block.conv2 - self.bn2 = basic_block.bn2 - self.downsample = basic_block.downsample - self.stride = basic_block.stride - - def forward(self, x): - residual = x - x = self.quant1(x) - out = self.active(self.bn1(self.conv1(x))) - out = self.quant2(out) - out = self.bn2(self.conv2(out)) - if self.downsample is not None: - residual = self.downsample(x) - out += residual - out = self.active(out) - return out - - -class QBottleneck(nn.Module): - """ - Parameters - ---------- - bottleneck (object): Bottleneck to be used - """ - - expansion = 4 - - def __init__(self, bottleneck: Bottleneck): - super().__init__() - self.quant1 = ActQuantizer() - self.conv1 = bottleneck.conv1 - self.bn1 = bottleneck.bn1 - self.quant2 = ActQuantizer() - self.conv2 = bottleneck.conv2 - self.bn2 = bottleneck.bn2 - self.quant3 = ActQuantizer() - self.conv3 = bottleneck.conv3 - self.bn3 = bottleneck.bn3 - self.active = bottleneck.active - self.downsample = bottleneck.downsample - self.stride = bottleneck.stride - - def forward(self, x): - residual = x - x = self.quant1(x) - out = self.active(self.bn1(self.conv1(x))) - out = self.quant2(out) - out = self.active(self.bn2(self.conv2(out))) - out = self.quant3(out) - out = self.bn3(self.conv3(out)) - if self.downsample is not None: - residual = self.downsample(x) - out += residual - out = self.active(out) - return out - - -class QInvertedResidual(nn.Module): - """ - Parameters - ---------- - inv_res (object): Inverted Residual block to be used - """ - - def __init__(self, inv_res: InvertedResidual): - super().__init__() - self.stride = inv_res.stride - self.inp = inv_res.inp - self.oup = inv_res.oup - self.exp = inv_res.exp - self.quant1 = ActQuantizer(islinear=1) - self.conv1 = inv_res.conv1 - self.bn1 = inv_res.bn1 - self.quant2 = ActQuantizer(islinear=1) - self.conv2 = inv_res.conv2 - self.bn2 = inv_res.bn2 - self.quant3 = ActQuantizer(islinear=0) - self.conv3 = inv_res.conv3 - self.bn3 = inv_res.bn3 - self.shortcut = inv_res.shortcut - - def forward(self, x): - x = self.quant1(x) - out = F.relu(self.bn1(self.conv1(x))) - out = self.quant2(out) - out = F.relu(self.bn2(self.conv2(out))) - out = self.quant3(out) - out = self.bn3(self.conv3(out)) - out = out + self.shortcut(x) if self.stride == 1 else out - return out - - -# =========================================== -# ***** Quantization Modules for LAPQ ******* -# =========================================== -""" -Supported quantization wrappers for pytorch modules :- - - nn.ReLU, nn.ReLU6 -> ActivationModuleWrapper(nn.Module) - - nn.Conv2d, nn.Linear -> ParameterModuleWrapper(nn.Module) -""" - -quantization_mapping = { - 'max_static': MaxAbsStaticQuantization, - 'lp_norm': LpNormQuantization, -} - - -def is_positive(module): - return isinstance(module, nn.ReLU) or isinstance(module, nn.ReLU6) - - -class ActivationModuleWrapper(nn.Module): - """ - Parameters - ---------- - name (str): Name of the wrapped module - wrapped_module (object): Module to be used - kwargs (object): A yaml safe loaded file with information like bits_out and qtype - """ - - def __init__(self, name, wrapped_module, **kwargs): - super(ActivationModuleWrapper, self).__init__() - self.name = name - self.wrapped_module = wrapped_module - self.bits_out = kwargs['bits_out'] - self.qtype = kwargs['qtype'] - self.post_relu = True - self.enabled = True - self.active = True - if self.bits_out is not None: - self.out_quantization = self.out_quantization_default = None - - def __init_out_quantization__(tensor): - self.out_quantization_default = quantization_mapping[ - self.qtype]( - self, - tensor, - self.bits_out, - symmetric=(not is_positive(wrapped_module)), - uint=True, - kwargs=kwargs, - ) - self.out_quantization = self.out_quantization_default - - self.out_quantization_init_fn = __init_out_quantization__ - - def __enabled__(self): - return self.enabled and self.active and self.bits_out is not None - - def forward(self, *input): - if self.post_relu: - out = self.wrapped_module(*input) - # Quantize output - if self.__enabled__(): - self.verify_initialized(self.out_quantization, out, - self.out_quantization_init_fn) - out = self.out_quantization(out) - else: - # Quantize output - if self.__enabled__(): - self.verify_initialized(self.out_quantization, *input, - self.out_quantization_init_fn) - out = self.out_quantization(*input) - else: - out = self.wrapped_module(*input) - return out - - @staticmethod - def verify_initialized(quantization_handle, tensor, init_fn): - if quantization_handle is None: - init_fn(tensor) - - def get_quantization(self): - return self.out_quantization - - def set_quantization(self, qtype, kwargs): - self.out_quantization = qtype( - self, - self.bits_out, - symmetric=(not is_positive(self.wrapped_module)), - uint=True, - kwargs=kwargs, - ) - - -class ParameterModuleWrapper(nn.Module): - """ - Parameters - ---------- - name (str): Name of the wrapped module - wrapped_module (object): Module to be used - kwargs (object): A yaml safe loaded file with information like bits_out, qtype, forward functor, bit_weight, etc. - """ - - def __init__(self, name, wrapped_module, **kwargs): - super(ParameterModuleWrapper, self).__init__() - self.name = name - self.wrapped_module = wrapped_module - self.forward_functor = kwargs['forward_functor'] - self.bit_weights = kwargs['bit_weights'] - self.bits_out = kwargs['bits_out'] - self.qtype = kwargs['qtype'] - self.bcorr_w = kwargs['bcorr_w'] - self.bn = kwargs['bn'] if 'bn' in kwargs else None - self.enabled = True - self.active = True - self.centroids_hist = {} - self.log_weights_hist = False - self.log_weights_mse = False - self.log_clustering = False - self.dynamic_weight_quantization = True - setattr(self, 'weight', wrapped_module.weight) - delattr(wrapped_module, 'weight') - if hasattr(wrapped_module, 'bias'): - setattr(self, 'bias', wrapped_module.bias) - delattr(wrapped_module, 'bias') - if self.bit_weights is not None: - self.weight_quantization_default = quantization_mapping[ - self.qtype]( - self, - self.weight, - self.bit_weights, - symmetric=True, - uint=True, - kwargs=kwargs, - ) - self.weight_quantization = self.weight_quantization_default - if not self.dynamic_weight_quantization: - self.weight_q = self.weight_quantization(self.weight) - self.weight_mse = torch.mean( - (self.weight_q - self.weight)**2).item() - - def __enabled__(self): - return self.enabled and self.active and self.bit_weights is not None - - def bias_corr(self, x, xq): - bias_q = xq.view(xq.shape[0], -1).mean(-1) - bias_orig = x.view(x.shape[0], -1).mean(-1) - bcorr = bias_q - bias_orig - return (xq - bcorr.view(bcorr.numel(), 1, 1, 1) - if len(x.shape) == 4 else xq - bcorr.view(bcorr.numel(), 1)) - - def forward(self, *input): - w = self.weight - if self.__enabled__(): - # Quantize weights - if self.dynamic_weight_quantization: - w = self.weight_quantization(self.weight) - if self.bcorr_w: - w = self.bias_corr(self.weight, w) - else: - w = self.weight_q - out = self.forward_functor( - *input, - weight=w, - bias=(self.bias if hasattr(self, 'bias') else None)) - return out - - def get_quantization(self): - return self.weight_quantization - - def set_quantization(self, qtype, kwargs): - self.weight_quantization = qtype(self, - self.bit_weights, - symmetric=True, - uint=True, - kwargs=kwargs) From fcff9335e468bff4f54a1faae023ceb532469b46 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:01:33 +0530 Subject: [PATCH 04/35] modified quant methods --- trailmet/algorithms/quantize/methods.py | 905 +++++++----------------- 1 file changed, 271 insertions(+), 634 deletions(-) diff --git a/trailmet/algorithms/quantize/methods.py b/trailmet/algorithms/quantize/methods.py index 7858ef5..28ae66d 100644 --- a/trailmet/algorithms/quantize/methods.py +++ b/trailmet/algorithms/quantize/methods.py @@ -19,119 +19,122 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + + import torch import torch.nn as nn import numpy as np import scipy.optimize as optim -import warnings -from trailmet.algorithms.quantize.quantize import BaseQuantization, RoundSTE -from trailmet.utils import lp_loss - -__all__ = [ - 'UniformAffineQuantizer', - 'AdaRoundQuantizer', - 'BitSplitQuantizer', - 'ActQuantizer', - 'QuantizationBase', - 'UniformQuantization', - 'ClippedUniformQuantization', - 'FixedClipValueQuantization', - 'MaxAbsStaticQuantization', - 'LearnedStepSizeQuantization', - 'LpNormQuantization', -] -"""Quantization classes:- - -[BRECQ] - - UniformAffineQuantizer - - AdaRoundQuantizer -[BitSplit] - - BitSplitQuantizer - - ActQuantizer -[LAPQ] - - QuantizationBase - - UniformQuantization - - ClippedUniformQuantization - - FixedClipValueQuantization - - MaxAbsStaticQuantization - - LearnedStepSizeQuantization - - LpNormQuantization -""" - - -class UniformAffineQuantizer(nn.Module): - """PyTorch Function that can be used for asymmetric quantization (uniform - affine quantization). + +class RoundSTE(torch.autograd.Function): + """grad enabled round function""" + @staticmethod + def forward(ctx, input): + return torch.round(input) + + @staticmethod + def backward(ctx, grad_output): + return grad_output + +class FloorSTE(torch.autograd.Function): + """grad enabled floor function""" + @staticmethod + def forward(ctx, input): + return torch.floor(input) + + @staticmethod + def backward(ctx, grad_output): + return grad_output + + +class BaseQuantizer(nn.Module): + def __init__(self, n_bits, symm, channel_wise, delta, zero_point, inited): + super(BaseQuantizer, self).__init__() + self._supported_bits = [2, 3, 4, 8, 16, 32] + assert n_bits in self._supported_bits, 'bitwidth not supported' + self.n_bits = n_bits + self.n_levels = 2 ** self.n_bits + self.symmetric = symm + self.channel_wise = channel_wise + self.delta = delta + self.zero_point = zero_point + self.inited = inited + + def __register_buffer__(self, name, value): + if hasattr(self, name): + delattr(self, name) + self.register_buffer(name, value) + + def __register_parameter__(self, name, value): + if hasattr(self, name): + delattr(self, name) + self.register_parameter(name, nn.Parameter(value)) + + def __quantize__(self, x, mode): + if mode == 'nearest': + x_int = torch.round(x / self.delta) + elif mode == 'nearest_ste': + x_int = RoundSTE.apply(x / self.delta) + elif mode == 'stochastic': + x_floor = FloorSTE.apply(x / self.delta) + x_int = x_floor + torch.bernoulli((x / self.delta) - x_floor) + else: ValueError('wrong rounding mode') + x_quant = torch.clamp(x_int + self.zero_point, 0, self.n_levels-1) + return x_quant + + def __dequantize__(self, xq): + xq_float = (xq - self.zero_point) * self.delta + return xq_float + + + +class UniformAffineQuantizer(BaseQuantizer): + """ + PyTorch Function that can be used for asymmetric quantization (uniform affine quantization). Quantizes its argument in the forward pass, passes the gradient 'straight through' on the backward pass, ignoring the quantization that occurred. - Based on - https://arxiv.org/abs/1806.08342. - Parameters - ---------- - n_bits: number of bit for quantization - symmetric: if True, the zero_point should always be 0 - channel_wise: if True, compute scale and zero_point in each channel - scale_method: determines the quantization scale and zero point + Based on https://arxiv.org/abs/1806.08342. + :param n_bits: number of bit for quantization + :param symmetric: if True, the zero_point should always be 0 + :param channel_wise: if True, compute scale and zero_point in each channel + :param scale_method: determines the quantization scale and zero point """ - - def __init__( - self, - n_bits: int = 8, - symmetric: bool = False, - channel_wise: bool = False, - scale_method: str = 'max', - leaf_param: bool = False, - ): - super(UniformAffineQuantizer, self).__init__() - self.sym = symmetric - assert 2 <= n_bits <= 8, 'bitwidth not supported' - self.n_bits = n_bits - self.n_levels = 2**self.n_bits - self.delta = None - self.zero_point = None - self.inited = False + def __init__(self, n_bits: int = 8, symmetric: bool = False, channel_wise: bool = False, scale_method: str = 'max', + leaf_param: bool = False, **kwargs): + super(UniformAffineQuantizer, self).__init__(n_bits, symmetric, channel_wise, + delta=None, zero_point=None, inited=False) self.leaf_param = leaf_param - self.channel_wise = channel_wise self.scale_method = scale_method def forward(self, x: torch.Tensor): - if self.inited is False: + if not self.inited: + delta, zero_point = self.init_quantization_scale(x, self.channel_wise) if self.leaf_param: - delta, self.zero_point = self.init_quantization_scale( - x, self.channel_wise) - self.delta = torch.nn.Parameter(delta) - # self.zero_point = torch.nn.Parameter(self.zero_point) + self.__register_parameter__('delta', delta) else: - self.delta, self.zero_point = self.init_quantization_scale( - x, self.channel_wise) + self.__register_buffer__('delta', delta) + self.__register_buffer__('zero_point', zero_point) self.inited = True - - # start quantization - # x_int = BQ.round_ste(x / self.delta) + self.zero_point - x_int = RoundSTE.apply(x / self.delta) + self.zero_point - x_quant = torch.clamp(x_int, 0, self.n_levels - 1) - x_dequant = (x_quant - self.zero_point) * self.delta + # apply fake quantization + x_quant = self.__quantize__(x, 'nearest_ste') + x_dequant = self.__dequantize__(x_quant) return x_dequant - def init_quantization_scale(self, - x: torch.Tensor, - channel_wise: bool = False): + def init_quantization_scale(self, x: torch.Tensor, channel_wise = False): delta, zero_point = None, None if channel_wise: x_clone = x.clone().detach() n_channels = x_clone.shape[0] if len(x.shape) == 4: - x_max = x_clone.abs().max(dim=-1)[0].max(dim=-1)[0].max( - dim=-1)[0] + x_max = x_clone.abs().max(dim=-1)[0].max(dim=-1)[0].max(dim=-1)[0] else: x_max = x_clone.abs().max(dim=-1)[0] delta = x_max.clone() zero_point = x_max.clone() # determine the scale and zero point channel-by-channel for c in range(n_channels): - delta[c], zero_point[c] = self.init_quantization_scale( - x_clone[c], channel_wise=False) + delta[c], zero_point[c] = self.init_quantization_scale(x_clone[c], channel_wise=False) if len(x.shape) == 4: delta = delta.view(-1, 1, 1, 1) zero_point = zero_point.view(-1, 1, 1, 1) @@ -140,186 +143,195 @@ def init_quantization_scale(self, zero_point = zero_point.view(-1, 1) else: if 'max' in self.scale_method: - x_min = min(x.min().item(), 0) - x_max = max(x.max().item(), 0) + x_max, x_min = x.max(), x.min() if 'scale' in self.scale_method: x_min = x_min * (self.n_bits + 2) / 8 x_max = x_max * (self.n_bits + 2) / 8 - - x_absmax = max(abs(x_min), x_max) - if self.sym: + if self.symmetric: + x_absmax = torch.max(x_min.abs(), x_max) x_min, x_max = -x_absmax if x_min < 0 else 0, x_absmax - - delta = float(x_max - x_min) / (self.n_levels - 1) - if delta < 1e-8: - warnings.warn( - 'Quantization range close to zero: [{}, {}]'.format( - x_min, x_max)) - delta = 1e-8 - + delta = (x_max - x_min) / (self.n_levels - 1) zero_point = torch.round(-x_min / delta) - delta = torch.tensor(delta).type_as(x) - elif self.scale_method == 'mse': + elif 'mse' in self.scale_method: # For Lp norm minimization as described in LAPQ - # https://arxiv.org/abs/1911.07190 - x_max = x.max() - x_min = x.min() - best_score = 1e10 - for i in range(80): - new_max = x_max * (1.0 - (i * 0.01)) - new_min = x_min * (1.0 - (i * 0.01)) - x_q = self.quantize(x, new_max, new_min) - score = lp_loss(pred=x, tgt=x_q, p=2.4, reduction='all') - if score < best_score: - best_score = score - delta = (new_max - new_min) / (2**self.n_bits - 1) - zero_point = torch.round(-new_min / delta) + x_max, x_min = x.max(), x.min() + with torch.no_grad(): + optim_alpha = optim.minimize_scalar( + lambda alpha: self.estimate_quant_error(x, x_max, x_min, alpha), + bounds=(0.2, 1.0)).x + delta = optim_alpha * (x_max - x_min) / (self.n_levels - 1) + zero_point = torch.round( -optim_alpha * x_min / delta) else: raise NotImplementedError - return delta, zero_point - def quantize(self, x, max, min): - delta = (max - min) / (2**self.n_bits - 1) - zero_point = torch.round(-min / delta) - # we assume weight quantization is always signed - x_int = torch.round(x / delta) + def estimate_quant_error(self, x: torch.Tensor, x_max, x_min, alpha, p=2.4): + delta = alpha * (x_max - x_min) / (self.n_levels - 1) + zero_point = torch.round( -alpha * x_min / delta) + x_int = torch.round(x / delta) # we assume weight quantization is always signed x_quant = torch.clamp(x_int + zero_point, 0, self.n_levels - 1) - x_float_q = (x_quant - zero_point) * delta - return x_float_q + x_dequant = (x_quant - zero_point) * delta + err = torch.mean(torch.abs(x_dequant - x) ** p) + return err.item() def bitwidth_refactor(self, refactored_bit: int): - assert 2 <= refactored_bit <= 8, 'bitwidth not supported' + assert refactored_bit in [2,3,4,8,16,32], 'bitwidth not supported' self.n_bits = refactored_bit - self.n_levels = 2**self.n_bits + self.n_levels = 2 ** self.n_bits + self.inited = False def extra_repr(self): - s = ( - 'bit={n_bits}, scale_method={scale_method}, symmetric={sym}, channel_wise={channel_wise},' - ' leaf_param={leaf_param}') + s = 'bit={n_bits}, scale_method={scale_method}, symmetric={symmetric}, channel_wise={channel_wise},' \ + ' leaf_param={leaf_param}' return s.format(**self.__dict__) -class AdaRoundQuantizer(nn.Module): - """Adaptive Rounding Quantizer, used to optimize the rounding policy by - reconstructing the intermediate output. - - Based on Up or Down? Adaptive Rounding for Post-Training Quantization: - https://arxiv.org/abs/2004.10568 - https: //arxiv.org/abs/2004.10568 - Parameters - ---------- - uaq: UniformAffineQuantizer, used to initialize quantization parameters in this quantizer - round_mode: controls the forward pass in this quantizer - weight_tensor: initialize alpha +class AdaRoundQuantizer(BaseQuantizer): + """ + Adaptive Rounding Quantizer, used to optimize the rounding policy + by reconstructing the intermediate output. + Based on + Up or Down? Adaptive Rounding for Post-Training Quantization: https://arxiv.org/abs/2004.10568 + :param uaq: UniformAffineQuantizer, used to initialize quantization parameters in this quantizer + :param round_mode: controls the forward pass in this quantizer + :param weight_tensor: initialize alpha """ - def __init__( - self, - uaq: UniformAffineQuantizer, - weight_tensor: torch.Tensor, - round_mode='learned_round_sigmoid', - ): - super(AdaRoundQuantizer, self).__init__() + def __init__(self, uaq: UniformAffineQuantizer, weight_tensor: torch.Tensor, + round_mode='learned_hard_sigmoid', **kwargs): # copying all attributes from UniformAffineQuantizer - self.n_bits = uaq.n_bits - self.sym = uaq.sym - self.delta = uaq.delta - self.zero_point = uaq.zero_point - self.n_levels = uaq.n_levels - + super(AdaRoundQuantizer, self).__init__(uaq.n_bits, uaq.symmetric, + uaq.channel_wise, uaq.delta, uaq.zero_point, inited=True) self.round_mode = round_mode - self.alpha = None self.soft_targets = False + self.__register_buffer__('delta', uaq.delta) + self.__register_buffer__('zero_point', uaq.zero_point) # params for sigmoid function + self.alpha = None + self.beta = 2/3 self.gamma, self.zeta = -0.1, 1.1 - self.beta = 2 / 3 - self.init_alpha(x=weight_tensor.clone()) + self.init_alpha(x = weight_tensor.clone()) - def forward(self, x): - if self.round_mode == 'nearest': - x_int = torch.round(x / self.delta) - elif self.round_mode == 'nearest_ste': - # x_int = BQ.round_ste(x / self.delta) - x_int = RoundSTE.apply(x / self.delta) - elif self.round_mode == 'stochastic': - x_floor = torch.floor(x / self.delta) - rest = (x / self.delta) - x_floor # rest of rounding - x_int = x_floor + torch.bernoulli(rest) - print('Draw stochastic sample') - elif self.round_mode == 'learned_hard_sigmoid': - x_floor = torch.floor(x / self.delta) + def forward(self, x: torch.tensor): + if self.round_mode == 'learned_hard_sigmoid': + x_floor = FloorSTE.apply(x / self.delta) if self.soft_targets: x_int = x_floor + self.get_soft_targets() else: x_int = x_floor + (self.alpha >= 0).float() + x_quant = torch.clamp(x_int + self.zero_point, 0, self.n_levels - 1) else: - raise ValueError('Wrong rounding mode') - - x_quant = torch.clamp(x_int + self.zero_point, 0, self.n_levels - 1) - x_float_q = (x_quant - self.zero_point) * self.delta - - return x_float_q + x_quant = self.__quantize__(x, mode = self.round_mode) + x_dequant = self.__dequantize__(x_quant) + return x_dequant def get_soft_targets(self): - return torch.clamp( - torch.sigmoid(self.alpha) * (self.zeta - self.gamma) + self.gamma, - 0, 1) + return torch.clamp(torch.sigmoid(self.alpha) * (self.zeta - self.gamma) + self.gamma, 0, 1) def init_alpha(self, x: torch.Tensor): - x_floor = torch.floor(x / self.delta) + x_floor = FloorSTE.apply(x / self.delta) if self.round_mode == 'learned_hard_sigmoid': - # print('Init alpha to be FP32') rest = (x / self.delta) - x_floor # rest of rounding [0, 1) - alpha = -torch.log( - (self.zeta - self.gamma) / - (rest - self.gamma) - 1) # => sigmoid(alpha) = rest - self.alpha = nn.Parameter(alpha) + alpha = -torch.log((self.zeta - self.gamma) / (rest - self.gamma) - 1) # => sigmoid(alpha) = rest + self.__register_parameter__('alpha', alpha) else: raise NotImplementedError + + def extra_repr(self): + s = 'bit={n_bits}, round_mode={round_mode}, symmetric={symmetric}, channel_wise={channel_wise}' + return s.format(**self.__dict__) -class BitSplitQuantizer(object): - """ - Parameters - ---------- - W (np.ndarray): Weight vector - bitwidth (int): bitwidth to be used - """ +class MaxAbsQuantizer(BaseQuantizer): + def __init__(self, n_bits, inited=False, **kwargs): + super().__init__(n_bits, symm=True, channel_wise=False, delta=None, + zero_point=None, inited=inited) + self.alpha = None + + def forward(self, x: torch.Tensor): + if not self.inited: + self.init_alpha(x) + x_quant = self.__quantize__(x, 'nearest_ste') + x_dequant = self.__dequantize__(x_quant) + return x_dequant + + def init_alpha(self, x: torch.Tensor): + alpha = x.abs().max().item() + self.set_params_from_alpha(alpha) + self.inited = True + def set_params_from_alpha(self, alpha): + self.delta = max((2 * alpha) / (self.n_levels - 1), 1e-8) + self.zero_point = alpha / self.delta + self.__register_buffer__('alpha', torch.tensor(alpha)) + + def extra_repr(self): + s = 'bit={n_bits}, alpha={alpha}, inited={inited}' + return s.format(**self.__dict__) + +class LpNormQuantizer(MaxAbsQuantizer): + def __init__(self, n_bits, p_val, inited=False, **kwargs): + super().__init__(n_bits, inited, **kwargs) + self.p = p_val + + def init_alpha(self, weight_tensor: torch.Tensor): + with torch.no_grad(): + optim_alpha = optim.minimize_scalar(lambda alpha: self.estimate_quant_error(weight_tensor, alpha), + bounds=(weight_tensor.min().item(), weight_tensor.max().item())).x + self.set_params_from_alpha(optim_alpha) + self.inited = True + + def estimate_quant_error(self, x, alpha): + delta = max((2 * alpha) / (self.n_levels - 1), 1e-8) + zero_point = round(alpha / delta) + x_int = torch.round(x / delta) # we assume weight quantization is always signed + x_quant = torch.clamp(x_int + zero_point, 0, self.n_levels - 1) + x_dequant = (x_quant - zero_point) * delta + err = torch.mean(torch.abs(x_dequant - x) ** self.p) + return err.item() + + + + + +class BitSplitQuantizer(object): def __init__(self, W: np.ndarray, bitwidth): self.W = W self.bitwidth = bitwidth @staticmethod def splitWeightInteger(Q, bitwidth): - """Split low-bit weight integers into a list of ternary weights.""" + """ + Split low-bit weight integers into a list of ternary weights. + """ Q_sign = np.sign(Q) Q_abs = np.abs(Q) B_sav = [] - for idx in range(bitwidth - 1): - B = Q_abs - Q_abs.astype(np.int) // 2 * 2 # get current last bit + for idx in range(bitwidth-1): + B = (Q_abs - Q_abs.astype(np.int)//2*2) # get current last bit B *= Q_sign B_sav.append(B) - Q_abs = (Q_abs.astype(np.int) // 2).astype( - np.float32) # Q_abs >> 1 + Q_abs = (Q_abs.astype(np.int)//2).astype(np.float32) # Q_abs >> 1 return B_sav[::-1] @staticmethod def splitWeightVector(W, alpha): - """Get the optimal ternary vector, given the quantization scale - alpha.""" - B = W.copy() - B = (B >= 0).astype(np.float32) * 2 - 1 + """ + Get the optimal ternary vector, given the quantization scale alpha + """ + B=W.copy() + B=(B>=0).astype(np.float32)*2-1 abs_W2 = np.abs(W) * 2 - B[abs_W2 < alpha[:, np.newaxis]] = 0 + B[abs_W2 1e-9: + alpha_old = alpha*1.1 + while(np.linalg.norm(alpha-alpha_old)>1e-9): q = self.W / alpha[:, np.newaxis] q = np.round(q) q = np.clip(q, -max_val, max_val) alpha_old = alpha - alpha = np.sum(self.W * q, axis=1) / np.sum(q * q, axis=1) + alpha = np.sum(self.W*q, axis=1) / np.sum(q*q, axis=1) return q, alpha def ofwa(self, max_epoch=50): - """Optimal Fixed Point Weight Approximation Method. - + """ + Optimal Fixed Point Weight Approximation Method. Minimize weight matrix reconstruction error using bit-split strategy. - Given quantization scale, we find the 'optimal' low-bit weights that + Given quantization scale, we find the 'optimal' low-bit weights that minimizes the weight quantization error (instead of using round-off). Initialized by "fwa". """ - assert 2 <= self.bitwidth <= 16 + assert(2 <= self.bitwidth <= 16) Q, alpha = self.fwa() B_sav = self.splitWeightInteger(Q, self.bitwidth) - alpha *= 2**(self.bitwidth - 2) - # NOTE: the position of the decimal point is not at the end. + alpha *= (2**(self.bitwidth-2)) + # NOTE: the position of the decimal point is not at the end. # E.g. 4-bit fixed-point numbers could be something like: # +1.01, -0.11, +1.10, ... instead of +101, -011, +110, ... . ### iterative optimization @@ -379,23 +389,20 @@ def ofwa(self, max_epoch=50): alpha_old = np.copy(alpha) B_sum = self.stitch(B_sav) # given Ws, optimize alpha - alpha = np.sum(self.W * B_sum, axis=1) / np.sum(B_sum * B_sum, - axis=1) - if np.linalg.norm(alpha_old - alpha) <= 1e-9: + alpha = np.sum(self.W*B_sum, axis=1) / np.sum(B_sum*B_sum, axis=1) + if np.linalg.norm(alpha_old-alpha) <= 1e-9: break # given alpha, optimize Ws - for bit in range(self.bitwidth - 1): - W_res = self.W - self.stitchExclusive( - B_sav, bit) * alpha[:, np.newaxis] - B = self.splitWeightVector(W_res * (2**bit), alpha) + for bit in range(self.bitwidth-1): + W_res = self.W - self.stitchExclusive(B_sav, bit) * alpha[:, np.newaxis] + B = self.splitWeightVector(W_res*(2**bit), alpha) B_sav[bit] = B B_sum = self.stitch(B_sav) return B_sav, B_sum, alpha def ofwa_rr(self, X: np.ndarray, Y: np.ndarray, max_epoch=100): - """Optimal Fixed Point Weight Approximation with Response - Reconstruction. - + """ + Optimal Fixed Point Weight Approximation with Response Reconstruction. Minimize activation matrix reconstruction error using bit-split strategy. Initialized by "ofwa". :X: K,C,d,d @@ -408,93 +415,80 @@ def ofwa_rr(self, X: np.ndarray, Y: np.ndarray, max_epoch=100): B_sav, _, alpha = self.ofwa() X = X.reshape(X.shape[0], -1) K, N = X.shape - A = np.dot(X.T, X) # N,N + A = np.dot(X.T, X) # N,N for epoch in range(max_epoch): # given Bi, optimize alpha B_sum = self.stitch(B_sav) - XB = np.dot(X, B_sum.T) # k,m - alpha = np.einsum('ij,ij->j', Y, XB) - alpha = alpha / np.einsum('ij,ij->j', XB, XB) + XB = np.dot(X, B_sum.T) # k,m + alpha = np.einsum("ij,ij->j", Y, XB) + alpha = alpha / np.einsum("ij,ij->j", XB, XB) # given alpha, optimize Bi - for bit in range(self.bitwidth - 1): + for bit in range(self.bitwidth-1): B = B_sav[bit] - B_others = self.stitchExclusive(B_sav, bit) * alpha[:, - np.newaxis] + B_others = self.stitchExclusive(B_sav, bit) * alpha[:, np.newaxis] Y_res = Y - np.dot(X, B_others.T) - T = np.dot(Y_res.T, X) # M,N + T = np.dot(Y_res.T, X) # M,N ## fix alpha, optimize B # parallel degree: M for n in range(N): B[:, n] = 0 ABn = np.dot(A[n], B.T) - lump = 2 * (ABn * (alpha / (2**bit)) - T[:, n]) # M + lump = 2 * (ABn * (alpha/(2**bit))- T[:, n]) # M B[:, n] = -np.sign(lump) - B[np.abs(lump) < (alpha / (2**bit)) * A[n, n], n] = 0 + B[np.abs(lump) < (alpha/(2**bit)) * A[n,n], n] = 0 B_sum = self.stitch(B_sav) return B_sum, alpha def ofwa_rr_dw(self, X: np.ndarray, Y: np.ndarray, max_epoch=100): - """ + ''' # X: K,M,d,d # Y: K,M # B: M,N M kernels objective: min(Y-XWA)^2 - """ + ''' # X: M,K,9 (N=d*d) B_sav, _, alpha = self.ofwa() - X = np.transpose(X.reshape(X.shape[0], X.shape[1], -1), - (1, 0, 2)) # M, K, 9 - As = np.matmul(np.transpose(X, (0, 2, 1)), X) # M, 9, 9 + X = np.transpose(X.reshape(X.shape[0], X.shape[1], -1), (1, 0, 2)) # M, K, 9 + As = np.matmul(np.transpose(X, (0, 2, 1)), X) # M, 9, 9 alpha_bk = alpha for epoch in range(max_epoch): # given Bi, optimize alpha B_sum = self.stitch(B_sav) - XB = np.matmul(X, np.expand_dims(B_sum, axis=2)) # M, K, 1 - XB = np.squeeze(XB, axis=2) # M, K + XB = np.matmul(X, np.expand_dims(B_sum, axis=2)) # M, K, 1 + XB = np.squeeze(XB, axis=2) # M, K XB = XB.T - alpha = np.einsum('ij,ij->j', Y, XB) - alpha = alpha / np.einsum('ij,ij->j', XB, XB) + alpha = np.einsum("ij,ij->j", Y, XB) + alpha = alpha / np.einsum("ij,ij->j", XB, XB) nan_pos = np.isnan(alpha) alpha[nan_pos] = alpha_bk[nan_pos] # given alpha, optimize Bi - for bit in range(self.bitwidth - 1): + for bit in range(self.bitwidth-1): B = B_sav[bit] - B_others = self.stitchExclusive(B_sav, bit) * alpha[:, - np.newaxis] - Y_res = (Y - np.squeeze( - np.matmul(X, np.expand_dims(B_others, axis=2)), axis=2).T - ) # Y_res = Y - np.dot(X, B_others.T) - - T = np.squeeze(np.matmul(np.expand_dims(Y_res.T, axis=1), X), - axis=1) # T = np.dot(Y_res.T, X) # M,N + B_others = self.stitchExclusive(B_sav, bit) * alpha[:, np.newaxis] + Y_res = Y - np.squeeze(np.matmul(X, np.expand_dims(B_others, axis=2)), axis=2).T # Y_res = Y - np.dot(X, B_others.T) + + T = np.squeeze(np.matmul(np.expand_dims(Y_res.T, axis=1), X), axis=1) #T = np.dot(Y_res.T, X) # M,N ## fix alpha, optimize B # parallel degree: M - for n in range(9): # N=9 + for n in range(9): # N=9 B[:, n] = 0 - ABn = np.diagonal(np.dot( - As[:, n], B.T)) # M #ABn = np.dot(A[n], B.T) - lump = 2 * (ABn * (alpha / (2**bit)) - T[:, n]) # M + ABn = np.diagonal(np.dot(As[:,n], B.T)) # M #ABn = np.dot(A[n], B.T) + lump = 2 * (ABn * (alpha/(2**bit))- T[:, n]) # M B[:, n] = -np.sign(lump) - B[np.abs(lump) < (alpha / (2**bit)) * As[:, n, n], n] = 0 + B[np.abs(lump) < (alpha/(2**bit)) * As[:,n,n], n] = 0 B_sum = self.stitch(B_sav) return B_sum, alpha + class ActQuantizer(nn.Module): - """ - Parameters - ---------- - islinear (bool): - bit_width (int): bit width to be used - """ - def __init__(self, islinear=False, bit_width=8): super(ActQuantizer, self).__init__() # self.scale = None @@ -508,7 +502,7 @@ def set_bitwidth(self, bit_width): self.bit_width = bit_width if self.signed: self.max_val = (1 << (self.bit_width - 1)) - 1 - self.min_val = -self.max_val + self.min_val = - self.max_val else: self.max_val = (1 << self.bit_width) - 1 self.min_val = 0 @@ -532,387 +526,30 @@ def set_outscale(self, out_scale): self.out_scale = torch.tensor(self.out_scale).view(1, -1, 1, 1) def init_quantization(self, x): - assert np.min(x) >= 0 - circle_detection_queue = [ - 0, - ] * 5 + assert(np.min(x)>=0) + circle_detection_queue = [0,]*5 alpha = np.max(np.fabs(x)) / self.max_val alpha_old = alpha * 0 n_iter = 0 circle_detection_queue[n_iter] = alpha - while np.sum(alpha != alpha_old): + while(np.sum(alpha!=alpha_old)): q = x / alpha q = np.clip(np.round(q), self.min_val, self.max_val) alpha_old = alpha - alpha = np.sum(x * q) / np.sum(q * q) + alpha = np.sum(x*q) / np.sum(q*q) if alpha in circle_detection_queue: break n_iter += 1 - circle_detection_queue[n_iter % 5] = alpha + circle_detection_queue[n_iter%5] = alpha return alpha def forward(self, x): if self.in_scale is None: - assert self.out_scale is None + assert(self.out_scale is None) return x if not isinstance(self.in_scale, (float, np.float32, np.float64)): self.in_scale = self.in_scale.to(x.device) if not isinstance(self.out_scale, (float, np.float32, np.float64)): self.out_scale = self.out_scale.to(x.device) # return torch.clamp(torch.round(x/self.in_scale), self.min_val, self.max_val) * self.out_scale - return (torch.clamp(RoundSTE.apply(x / self.in_scale), self.min_val, - self.max_val) * self.out_scale) - - -class QuantizationBase(object): - """ - Parameters - ---------- - module (object): Module to be used - num_bits (int): Number of bits to be used - """ - - def __init__(self, module, num_bits): - self.module = module - self.num_bits = num_bits - self.num_bins = int(2**num_bits) - self.opt_params = {} - self.named_params = [] - - def register_buffer(self, name, value): - if hasattr(self.module, name): - delattr(self.module, name) - self.module.register_buffer(name, value) - setattr(self, name, getattr(self.module, name)) - - def register_parameter(self, name, value): - if hasattr(self.module, name): - delattr(self.module, name) - self.module.register_parameter(name, nn.Parameter(value)) - setattr(self, name, getattr(self.module, name)) - - self.named_params.append((name, getattr(self.module, name))) - - def __add_optim_params__(self, optim_type, dataset, params): - learnable_params = [ - d for n, d in params if n in self.learned_parameters() - ] - self.opt_params[optim_type + '_' + dataset] = learnable_params - - def optim_parameters(self): - return self.opt_params - - def loggable_parameters(self): - return self.named_parameters() - - def named_parameters(self): - named_params = [(n, p) for n, p in self.named_params - if n in self.learned_parameters()] - return named_params - - @staticmethod - def learned_parameters(): - return [] - - -class UniformQuantization(QuantizationBase): - """ - Parameters - ---------- - module (object): Module to be used - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - tails (bool): - """ - - def __init__(self, - module, - num_bits, - symmetric, - uint=False, - stochastic=False, - tails=False): - super(UniformQuantization, self).__init__(module, num_bits) - if not symmetric and not uint: - raise RuntimeError( - "Can't perform integer quantization on non symmetric distributions." - ) - self.symmetric = symmetric - self.uint = uint - self.stochastic = stochastic - self.tails = tails - if uint: - self.qmax = 2**self.num_bits - 1 - self.qmin = 0 - else: - self.qmax = 2**(self.num_bits - 1) - 1 - self.qmin = -self.qmax - 1 - if tails: - self.qmax -= 0.5 + 1e-6 - self.qmin -= 0.5 - - def __quantize__(self, tensor, alpha): - delta = (2 if self.symmetric else 1) * alpha / (self.num_bins - 1) - delta = max(delta, 1e-8) - # quantize - if self.uint and self.symmetric: - t_q = (tensor + alpha) / delta - else: - t_q = tensor / delta - # stochastic rounding - if self.stochastic and self.module.training: - with torch.no_grad(): - noise = t_q.new_empty(t_q.shape).uniform_(-0.5, 0.5) - t_q += noise - # clamp and round - t_q = torch.clamp(t_q, self.qmin, self.qmax) - t_q = RoundSTE.apply(t_q) - assert torch.unique(t_q).shape[0] <= self.num_bins - # de-quantize - if self.uint and self.symmetric: - t_q = t_q * delta - alpha - else: - t_q = t_q * delta - return t_q - - def __quantize_gemmlowp__(self, tensor, min_, max_): - assert self.uint is True - delta = (max_ - min_) / (self.num_bins - 1) - delta = max(delta, 1e-8) - # quantize - t_q = (tensor - min_) / delta - # stochastic rounding - if self.stochastic and self.module.training: - with torch.no_grad(): - noise = t_q.new_empty(t_q.shape).uniform_(-0.5, 0.5) - t_q += noise - # clamp and round - t_q = torch.clamp(t_q, self.qmin, self.qmax) - t_q = RoundSTE.apply(t_q) - assert torch.unique(t_q).shape[0] <= self.num_bins - # de-quantize - t_q = t_q * delta + min_ - return t_q - - def __for_repr__(self): - return [ - ('bits', self.num_bits), - ('symmetric', self.symmetric), - ('tails', self.tails), - ] - - def __repr__(self): - s = '{} - ['.format(type(self).__name__) - for name, value in self.__for_repr__(): - s += '{}: {}, '.format(name, value) - return s + ']' - - -class ClippedUniformQuantization(UniformQuantization): - """ - Parameters - ---------- - module (object): Module to be used - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - tails (bool): - """ - - alpha_param_name = 'alpha' - - def __init__(self, - module, - num_bits, - symmetric, - uint=False, - stochastic=False, - tails=False): - super(ClippedUniformQuantization, - self).__init__(module, num_bits, symmetric, uint, stochastic, - tails) - - def __call__(self, tensor): - t_q = self.__quantize__(tensor, self.alpha) - return t_q - - def __for_repr__(self): - rpr = super(ClippedUniformQuantization, self).__for_repr__() - return [( - self.alpha_param_name, - '{:.4f}'.format(getattr(self, self.alpha_param_name).item()), - )] + rpr - - -class FixedClipValueQuantization(ClippedUniformQuantization): - """ - Parameters - ---------- - module (object): Module to be used - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - tails (bool): - kwargs (object): A yaml safe loaded file with information like clip_value, device. - """ - - def __init__(self, - module, - num_bits, - symmetric, - uint=False, - stochastic=False, - kwargs={}): - super(FixedClipValueQuantization, - self).__init__(module, num_bits, symmetric, uint, stochastic) - self.clip_value = kwargs['clip_value'] - self.device = kwargs['device'] - with torch.no_grad(): - self.register_buffer( - self.alpha_param_name, - torch.tensor([self.clip_value], - dtype=torch.float32).to(self.device), - ) - - -class MaxAbsStaticQuantization(ClippedUniformQuantization): - """ - Parameters - ---------- - module (object): Module to be used - tensor (torch.Tensor): Tensor which wpuld be quantized - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - """ - - def __init__( - self, - module, - tensor, - num_bits, - symmetric, - uint=False, - stochastic=False, - kwargs={}, - ): - super(MaxAbsStaticQuantization, - self).__init__(module, num_bits, symmetric, uint, stochastic) - - with torch.no_grad(): - self.register_buffer(self.alpha_param_name, - tensor.new_tensor([tensor.abs().max()])) - - -class LearnedStepSizeQuantization(ClippedUniformQuantization): - """ - Parameters - ---------- - module (object): Module to be used - tensor (torch.Tensor): Tensor which wpuld be quantized - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - """ - - def __init__(self, - module, - tensor, - num_bits, - symmetric, - uint=False, - stochastic=False, - **kwargs): - super(LearnedStepSizeQuantization, - self).__init__(module, num_bits, symmetric, uint, stochastic) - - with torch.no_grad(): - maxabs = tensor.abs().max() - - self.register_parameter(self.alpha_param_name, - tensor.new_tensor([maxabs])) - - self.__create_optim_params__() - - def __create_optim_params__(self): - # TODO: create default configuration - self.__add_optim_params__( - 'SGD', - 'imagenet', - [( - self.alpha_param_name, - { - 'params': [getattr(self, self.alpha_param_name)], - 'lr': 1e-3, - 'momentum': 0, - 'weight_decay': 0, - }, - )], - ) - self.__add_optim_params__( - 'SGD', - 'cifar10', - [( - self.alpha_param_name, - { - 'params': [getattr(self, self.alpha_param_name)], - 'lr': 1e-1, - 'momentum': 0, - 'weight_decay': 0, - }, - )], - ) - - @staticmethod - def learned_parameters(): - return [LearnedStepSizeQuantization.alpha_param_name] - - -class LpNormQuantization(ClippedUniformQuantization): - """ - Parameters - ---------- - module (object): Module to be used - tensor (torch.Tensor): Tensor which wpuld be quantized - num_bits (int): Number of bits to be used - symmetric (bool): Whether the distribution is symmetric or not - uint (bool): - stochastic (bool): if True, stochastic rounding will be done - tails (bool): - kwargs (object): A yaml safe loaded file with information like lp - """ - - def __init__( - self, - module, - tensor, - num_bits, - symmetric, - uint=False, - stochastic=False, - tails=False, - kwargs={}, - ): - super(LpNormQuantization, self).__init__(module, num_bits, symmetric, - uint, stochastic, tails) - - self.p = kwargs['lp'] - with torch.no_grad(): - opt_alpha = optim.minimize_scalar( - lambda alpha: self.estimate_quant_error(alpha, tensor), - bounds=(tensor.min().item(), tensor.max().item()), - ).x - - self.register_buffer(self.alpha_param_name, - tensor.new_tensor([opt_alpha])) - - def estimate_quant_error(self, alpha, x): - xq = self.__quantize__(x, alpha) - err = torch.mean(torch.abs(xq - x)**self.p) - return err.item() + return torch.clamp(RoundSTE.apply(x/self.in_scale), self.min_val, self.max_val) * self.out_scale \ No newline at end of file From 678b45e5771d1919c95a7ff95fa96b02dc4922ae Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:01:47 +0530 Subject: [PATCH 05/35] modified quant base --- trailmet/algorithms/quantize/quantize.py | 569 ++++++++++++++++------- 1 file changed, 408 insertions(+), 161 deletions(-) diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index 7579fc1..a459dc8 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -19,142 +19,139 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + +import copy import torch import torch.nn as nn -import torch.nn.init as init -from tqdm import tqdm_notebook -from ..algorithms import BaseAlgorithm - -__all__ = [ - 'BaseQuantization', - 'StraightThrough', - 'RoundSTE', - 'Conv2dFunctor', - 'LinearFunctor', - 'FoldBN', -] - - -class BaseQuantization(BaseAlgorithm): - """Base class for quantization algorithms.""" - - def __init__(self, **kwargs): - super(BaseQuantization, self).__init__(**kwargs) - pass - - def quantize(self, model, dataloaders, method, **kwargs): - pass - - def round_ste(x: torch.Tensor): - """Implement Straight-Through Estimator for rounding operation.""" - return (x.round() - x).detach() + x - - def get_calib_samples(self, train_loader, num_samples): - """Get calibration-set samples for finetuning weights and clipping - parameters.""" - calib_data = [] - for batch in train_loader: - calib_data.append(batch[0]) - if len(calib_data) * batch[0].size(0) >= num_samples: - break - return torch.cat(calib_data, dim=0)[:num_samples] - - def absorb_bn(self, module, bn_module): - w = module.weight.data - if module.bias is None: - zeros = torch.Tensor(module.out_channels).zero_().type(w.type()) - module.bias = nn.Parameter(zeros) - b = module.bias.data - invstd = bn_module.running_var.clone().add_(bn_module.eps).pow_(-0.5) - w.mul_(invstd.view(w.size(0), 1, 1, 1).expand_as(w)) - b.add_(-bn_module.running_mean).mul_(invstd) - - if bn_module.affine: - w.mul_(bn_module.weight.data.view(w.size(0), 1, 1, 1).expand_as(w)) - b.mul_(bn_module.weight.data).add_(bn_module.bias.data) - - bn_module.register_buffer('running_mean', - torch.zeros(module.out_channels).cuda()) - bn_module.register_buffer('running_var', - torch.ones(module.out_channels).cuda()) - bn_module.register_parameter('weight', None) - bn_module.register_parameter('bias', None) - bn_module.affine = False - - def is_bn(self, m): - return isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.BatchNorm1d) - - def is_absorbing(self, m): - return (isinstance(m, nn.Conv2d) and m.groups == 1) or isinstance( - m, nn.Linear) - - def search_absorbe_bn(self, model): - prev = None - for m in model.children(): - if self.is_bn(m) and self.is_absorbing(prev): - m.absorbed = True - self.absorb_bn(prev, m) - self.search_absorbe_bn(m) - prev = m - - -class StraightThrough(nn.Module): - """Used to place an identity function in place of a non-differentail - operator for gradient calculation.""" - - def __int__(self): +import torch.nn.functional as F +from tqdm import tqdm +from typing import Union +from trailmet.models.resnet import BasicBlock, Bottleneck +from trailmet.models.mobilenet import InvertedResidual +from trailmet.algorithms.quantize.utils import StopForwardException, DataSaverHook, GradSaverHook +from trailmet.algorithms.quantize.utils import LinearTempDecay, Node, GraphPlotter +from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, BaseQuantBlock +from trailmet.algorithms.quantize.modules import QuantBasicBlock, QuantBottleneck, QuantInvertedResidual +from trailmet.algorithms.algorithms import BaseAlgorithm + + +supported = { + BasicBlock: QuantBasicBlock, + Bottleneck: QuantBottleneck, + InvertedResidual: QuantInvertedResidual, +} + +class BaseQuantModel(nn.Module): + """base model wrapping class for quantization algorithms""" + def __init__(self, model: nn.Module, weight_quant_params: dict = {}, + act_quant_params: dict = {}, fold_bn = True): super().__init__() - pass + self.model = copy.deepcopy(model) + self.weight_quant_params = weight_quant_params + self.act_quant_params = act_quant_params + if fold_bn: + self.model.eval() + self.search_fold_remove_bn(self.model) + self.quant_module_refactor(self.model) + self.quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] + + + def search_fold_remove_bn(self, module: nn.Module): + """ + Recursively search for BatchNorm layers, fold them into the previous + Conv2d or Linear layers and set them as a StraightThrough layer. + """ + prev_module = None + for name, child_module in module.named_children(): + if self._is_bn(child_module) and self._is_absorbing(prev_module): + self._fold_bn_into_conv(prev_module, child_module) + setattr(module, name, StraightThrough()) + elif self._is_absorbing(child_module): + prev_module = child_module + else: + prev_module = self.search_fold_remove_bn(child_module) + return prev_module + + def quant_module_refactor(self, module: nn.Module): + """ + Recursively replace Conv2d and Linear layers with QuantModule and other + supported network blocks to their respective wrappers, to enable weight + and activations quantization. + """ + prev_quant_module: QuantModule = None + for name, child_module in module.named_children(): + if type(child_module) in supported: + setattr(module, name, supported[type(child_module)]( + child_module, self.weight_quant_params, self.act_quant_params + )) + elif isinstance(child_module, (nn.Conv2d, nn.Linear)): + setattr(module, name, QuantModule( + child_module, self.weight_quant_params, self.act_quant_params + )) + prev_quant_module = getattr(module, name) + elif isinstance(child_module, (nn.ReLU, nn.ReLU6)): + if prev_quant_module is not None: + prev_quant_module.activation_function = child_module + else: + continue + elif isinstance(child_module, StraightThrough): + continue + else: + self.quant_module_refactor(child_module) + + + def set_quant_state(self, weight_quant: bool = True, act_quant: bool = True): + """ + :param weight_quant: set True to enable weight quantization + :param act_quant: set True to enable activation quantization + """ + for module in self.model.modules(): + if isinstance(module, (QuantModule, BaseQuantBlock)): + module.set_quant_state(weight_quant, act_quant) + + def quantize_model_till(self, layer, act_quant: bool = False): + """ + :param layer: layer upto which model is to be quantized. + :param act_quant: set True for activation quantization + """ + self.set_quant_state(False, False) + for name, module in self.model.named_modules(): + if isinstance(module, (QuantModule, BaseQuantBlock)): + module.set_quant_state(True, act_quant) + if module == layer: + break + + def set_layer_precision(self, weight_bits: list, act_bit: int): + """ + :param weight_bits: list of bitwidths for layer weights + :param act_bit: bitwidth for activations + """ + assert len(weight_bits)==len(self.quant_modules) + for idx, module in enumerate(self.quant_modules): + module.weight_quantizer.bitwidth_refactor(weight_bits[idx]) + if module is not self.quant_modules[-1]: + module.act_quantizer.bitwidth_refactor(act_bit) def forward(self, input): - return input - - -class RoundSTE(torch.autograd.Function): - - @staticmethod - def forward(ctx, input): - output = torch.round(input) - return output - - @staticmethod - def backward(ctx, grad_output): - return grad_output - - -class Conv2dFunctor: - - def __init__(self, conv2d): - self.conv2d = conv2d - - def __call__(self, *input, weight, bias): - res = torch.nn.functional.conv2d(*input, weight, bias, - self.conv2d.stride, - self.conv2d.padding, - self.conv2d.dilation, - self.conv2d.groups) - return res - - -class LinearFunctor: - - def __init__(self, linear): - self.linear = linear - - def __call__(self, *input, weight, bias): - res = torch.nn.functional.linear(*input, weight, bias) - return res - - -# TODO : To migrate all BN-layer folding function calls to the ones defined inside BaseQuantization class -class FoldBN: - """Used to fold batch norm to prev linear or conv layer which helps reduce - comutational overhead during quantization.""" - - def __init__(self): - pass + return self.model(input) + + def _is_bn(self, module): + return isinstance(module, (nn.BatchNorm1d, nn.BatchNorm2d)) + + def _is_absorbing(self, module): + return isinstance(module, (nn.Conv2d, nn.Linear)) + + def _fold_bn_into_conv(self, conv_module, bn_module): + w, b = self._get_folded_params(conv_module, bn_module) + if conv_module.bias is None: + conv_module.bias = nn.Parameter(b) + else: + conv_module.bias.data = b + conv_module.weight.data = w + bn_module.running_mean = bn_module.bias.data + bn_module.running_var = bn_module.weight.data ** 2 - def _fold_bn(self, conv_module, bn_module): + def _get_folded_params(self, conv_module, bn_module): w = conv_module.weight.data y_mean = bn_module.running_mean y_var = bn_module.running_var @@ -176,35 +173,285 @@ def _fold_bn(self, conv_module, bn_module): bias = beta return weight, bias - def fold_bn_into_conv(self, conv_module, bn_module): - w, b = self._fold_bn(conv_module, bn_module) - if conv_module.bias is None: - conv_module.bias = nn.Parameter(b) +class BaseQuantization(BaseAlgorithm): + """base class for quantization algorithms""" + def __init__(self, **kwargs): + super(BaseQuantization, self).__init__(**kwargs) + pass + + def quantize(self, model, dataloaders, method, **kwargs): + pass + + def get_calib_samples(self, train_loader, num_samples): + """ + Get calibration-dataset samples for finetuning quantized weights and + quantization parameters + """ + calib_data = [] + for batch in train_loader: + calib_data.append(batch[0]) + if len(calib_data)*batch[0].size(0) >= num_samples: + break + return torch.cat(calib_data, dim=0)[:num_samples] + + + def sensitivity_analysis(self, qmodel: BaseQuantModel, dataloader, test_bits, + budget, save_path, exp_name): + qmodel.set_quant_state(False, False) + inputs = None + fp_outputs = None + with torch.no_grad(): + for batch_idx, (inputs, outputs) in enumerate(dataloader): + inputs = inputs.to(self.device) + fp_outputs = qmodel(inputs) + fp_outputs = F.softmax(fp_outputs, dim=1) + break + sensitivities = [[0 for i in range(len(qmodel.quant_modules))] + for j in range(len(test_bits))] + for i, layer in enumerate(qmodel.quant_modules): + for j, bit in enumerate(test_bits): + layer.set_quant_state(True, True) + layer.weight_quantizer.bitwidth_refactor(bit) + layer.weight_quantizer.inited = False + layer.weight_quantizer.scale_method = 'max' + with torch.no_grad(): + tmp_outputs = qmodel(inputs) + tmp_outputs = F.softmax(tmp_outputs, dim=1) + kld = (F.kl_div(tmp_outputs, fp_outputs, reduction='batchmean') + + F.kl_div(fp_outputs, tmp_outputs, reduction='batchmean')) / 2 + sensitivities[j][i] = kld.item() + layer.set_quant_state(False, False) + layer.weight_quantizer.scale_method = 'mse' + + gp = GraphPlotter(save_path+'/logs/plots') + gp.line_plotter(sensitivities, test_bits, '{} bit', f'{exp_name}_layer_sensitivity', + 'layer', 'sensitivity', 'log') + + weight_numels = [qmodule.weight.numel() for qmodule in qmodel.quant_modules] + node_list = self.dp_most_profit_over_cost(sensitivities, len(qmodel.quant_modules), weight_numels, test_bits) + constraint = sum(weight_numels)*32*budget / (8*1024*1024) + good_nodes = [node for node in node_list if node.cost <= constraint] + bits = [] + node = good_nodes[-1] + while(node is not None): + bits.append(node.bit) + node = node.parent + bits.reverse() + bits = bits[1:] + assert len(bits)==len(qmodel.quant_modules) + gp.line_plotter([bits], ['weight bits'], title=f'{exp_name}_layer_precisions', + xlabel='layer', ylabel='bits') + qmodel_size = 0 + for i, layer in enumerate(qmodel.quant_modules): + qmodel_size += layer.weight.numel()*bits[i]/(8*1024*1024) + return bits, qmodel_size, constraint + + def dp_most_profit_over_cost(self, sensitivities, num_layers, weight_numels, bits, constraint=100): + cost = bits + profits = [] + for line in sensitivities: + profits.append([-i for i in line]) + root = Node(cost=0, profit=0, parent=None) + current_list = [root] + for layer_id in range(num_layers): + next_list = [] + for n in current_list: + n.left = Node(n.cost + cost[0]*weight_numels[layer_id]/(8*1024*1024), + n.profit + profits[0][layer_id], + bit = bits[0], parent=n, position='left') + n.middle = Node(n.cost + cost[1]*weight_numels[layer_id]/(8*1024*1024), + n.profit + profits[1][layer_id], + bit = bits[1], parent=n, position='middle') + n.right = Node(n.cost + cost[2]*weight_numels[layer_id]/(8*1024*1024), + n.profit + profits[2][layer_id], + bit = bits[2], parent=n, position='right') + next_list.extend([n.left, n.middle, n.right]) + next_list.sort(key=lambda x: x.cost, reverse=False) + pruned_list = [] + for node in next_list: + if (len(pruned_list)==0 or pruned_list[-1].profit < node.profit) and node.cost <= constraint: + pruned_list.append(node) + else: + node.parent.__dict__[node.position] = None + current_list = pruned_list + return current_list + + +class BaseQuantLoss: + def __init__(self, module: Union[QuantModule, BaseQuantBlock], + round_loss: str = 'relaxation', weight: float = 1., rec_loss: str = 'mse', + max_count: int = 2000, b_range: tuple = (10, 2), decay_start: float = 0.0, + warmup: float = 0.0, p: float = 2.): + + self.module = module + self.round_loss = round_loss + self.weight = weight + self.rec_loss = rec_loss + self.loss_start = max_count * warmup + self.p = p + self.count = 0 + self.pbar = tqdm(total=max_count) + self.temp_decay = LinearTempDecay(max_count, + rel_start_decay=warmup + (1 - warmup) * decay_start, + start_b=b_range[0], end_b=b_range[1]) + + def __call__(self, pred, tgt, grad=None): + """ + Compute the total loss for adaptive rounding: + rec_loss is the quadratic output reconstruction loss, round_loss is + a regularization term to optimize the rounding policy + :param pred: output from quantized model + :param tgt: output from FP model + :param grad: gradients to compute fisher information + :return: total loss function + """ + self.count += 1 + if self.rec_loss == 'mse': + rec_loss = self.lp_norm(pred, tgt, self.p, reduction='none') + elif self.rec_loss == 'fisher_diag': + rec_loss = self.fisher_diag(pred, tgt, grad) + elif self.rec_loss == 'fisher_full': + rec_loss = self.fisher_full(pred, tgt, grad) else: - conv_module.bias.data = b - conv_module.weight.data = w - # set bn running stats - bn_module.running_mean = bn_module.bias.data - bn_module.running_var = bn_module.weight.data**2 - - def is_bn(self, m): - return isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.BatchNorm1d) - - def is_absorbing(self, m): - return (isinstance(m, nn.Conv2d)) or isinstance(m, nn.Linear) - - def search_fold_and_remove_bn(self, model: nn.Module): - """Method to recursively search for batch norm layers, absorb them into - the previous linear or conv layers, and set it to an identity layer.""" - model.eval() - prev = None - for n, m in model.named_children(): - if self.is_bn(m) and self.is_absorbing(prev): - self.fold_bn_into_conv(prev, m) - # set the bn module to straight through - setattr(model, n, StraightThrough()) - elif self.is_absorbing(m): - prev = m - else: - prev = self.search_fold_and_remove_bn(m) - return prev + raise ValueError('Not supported reconstruction loss function: {}'.format(self.rec_loss)) + + b = self.temp_decay(self.count) + if self.count < self.loss_start or self.round_loss == 'none': + b = round_loss = 0 + elif self.round_loss == 'relaxation': + round_loss = 0 + if isinstance(self.module, QuantModule): + round_vals = self.module.weight_quantizer.get_soft_targets() + round_loss += self.weight * (1 - ((round_vals - .5).abs() * 2).pow(b)).sum() + if isinstance(self.module, BaseQuantBlock): + for name, submodule in self.module.named_modules(): + if isinstance(submodule, QuantModule): + round_vals = submodule.weight_quantizer.get_soft_targets() + round_loss += self.weight * (1 - ((round_vals - .5).abs() * 2).pow(b)).sum() + else: + raise NotImplementedError + + total_loss = rec_loss + round_loss + if self.count % 100 == 0: + self.pbar.set_postfix(loss=float(total_loss), b=b) + self.pbar.update(1) + return total_loss + + @staticmethod + def lp_norm(pred, tgt, p=2.0, reduction = 'mean'): + if reduction == 'mean': + return (pred-tgt).abs().pow(p).mean() + elif reduction == 'none': + return (pred-tgt).abs().pow(p).sum(1).mean() + else: + raise KeyError + + @staticmethod + def fisher_diag(pred, tgt, grad): + return ((pred - tgt).pow(2) * grad.pow(2)).sum(1).mean() + + @staticmethod + def fisher_full(pred, tgt, grad): + a = (pred - tgt).abs() + grad = grad.abs() + batch_dotprod = torch.sum(a * grad, (1, 2, 3)).view(-1, 1, 1, 1) + return (batch_dotprod * a * grad).mean() / 100 + +class GetLayerInpOut: + """ + Get the input and output of a specified layer in a quantized model. + + :param model: quantized model for which the input and output needs to be extracted. + :param layer: the layer for which input and output needs to be extracted. + :param device: the device on which the computation needs to be performed. + :param asym: save quantized input and full precision output. [default=False] + :param act_quant: use activation quantization. [default=False] + """ + def __init__(self, model: BaseQuantModel, layer: Union[QuantModule, BaseQuantBlock], + device: torch.device, asym: bool = False, act_quant: bool = False): + self.model = model + self.layer = layer + self.asym = asym + self.device = device + self.act_quant = act_quant + self.data_saver = DataSaverHook(store_input=True, store_output=True, stop_forward=True) + + def __call__(self, model_input): + """ + :param model_input: calibration data samples + :return: tuple of layer input and output + """ + self.model.eval() + self.model.set_quant_state(False, False) + + handle = self.layer.register_forward_hook(self.data_saver) + with torch.no_grad(): + try: + _ = self.model(model_input.to(self.device)) + except StopForwardException: + pass + + if self.asym: + self.data_saver.store_output = False + self.model.set_quant_state(weight_quant=True, act_quant=self.act_quant) + try: + _ = self.model(model_input.to(self.device)) + except StopForwardException: + pass + self.data_saver.store_output = True + + handle.remove() + + self.model.set_quant_state(False, False) + self.layer.set_quant_state(True, self.act_quant) + self.model.train() + + return self.data_saver.input_store[0].detach(), self.data_saver.output_store.detach() + +class GetLayerGrad: + """ + Get the gradient a specified layer in a quantized model. + + :param model: quantized model for which the input and output needs to be extracted. + :param layer: the layer for which input and output needs to be extracted. + :param device: the device on which the computation needs to be performed. + :param asym: if True, save quantized input and full precision output. [default=False] + :param act_quant: use activation quantization. [default=False] + """ + def __init__(self, model: BaseQuantModel, layer: Union[QuantModule, BaseQuantBlock], + device: torch.device, act_quant: bool = False): + self.model = model + self.layer = layer + self.device = device + self.act_quant = act_quant + self.data_saver = GradSaverHook(True) + + def __call__(self, model_input): + """ + Compute the gradients of layer output, note that we compute the + gradient by calculating the KL loss between fp model and quant model + + :param model_input: calibration data samples + :return: gradients for the layer + """ + self.model.eval() + + handle = self.layer.register_backward_hook(self.data_saver) + with torch.enable_grad(): + try: + self.model.zero_grad() + inputs = model_input.to(self.device) + self.model.set_quant_state(False, False) + out_fp = self.model(inputs) + self.model.quantize_model_till(self.layer, self.act_quant) + out_q = self.model(inputs) + loss = F.kl_div(F.log_softmax(out_q, dim=1), F.softmax(out_fp, dim=1), reduction='batchmean') + loss.backward() + except StopForwardException: + pass + + handle.remove() + self.model.set_quant_state(False, False) + self.layer.set_quant_state(True, self.act_quant) + self.model.train() + return self.data_saver.grad_out.data \ No newline at end of file From a13775fb8813f19ea6c1e2ddee041f106eece7b3 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:01:56 +0530 Subject: [PATCH 06/35] modified lapq --- trailmet/algorithms/quantize/lapq.py | 482 ++++++--------------------- 1 file changed, 102 insertions(+), 380 deletions(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index cc70bd9..63c6f74 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -19,49 +19,45 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import copy + import torch import torch.nn as nn +import numpy as np import scipy.optimize as optim +from tqdm import tqdm from itertools import count from trailmet.utils import seed_everything -from trailmet.algorithms.quantize.quantize import ( - BaseQuantization, - Conv2dFunctor, - LinearFunctor, -) -from trailmet.algorithms.quantize.methods import ( - LearnedStepSizeQuantization, - FixedClipValueQuantization, -) -from trailmet.algorithms.quantize.qmodel import ( - ParameterModuleWrapper, - ActivationModuleWrapper, -) - -import logging -from datetime import datetime -from tqdm import tqdm -import wandb -import pandas as pd -import numpy as np -import os -import time - -from trailmet.utils import AverageMeter, accuracy, save_checkpoint - -logger = logging.getLogger(__name__) - +from trailmet.algorithms.quantize.quantize import BaseQuantModel, BaseQuantization +from trailmet.algorithms.quantize.modules import QuantModule, BaseQuantBlock + + +class QuantModel(BaseQuantModel): + def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params: dict, fold_bn=True): + super().__init__(model, weight_quant_params, act_quant_params, fold_bn) + self.weight_quantizers = [] + self.act_quantizers = [] + for module in self.model.modules(): + if isinstance(module, QuantModule): + self.weight_quantizers.append(module.weight_quantizer) + if not module.disable_act_quant: + self.act_quantizers.append(module.act_quantizer) + elif isinstance(module, BaseQuantBlock): + self.act_quantizers.append(module.act_quantizer) + + def get_alphas_np(self, weight=True, act=True): + alphas = [] + quantizers = (self.weight_quantizers if weight else []) + (self.act_quantizers if act else []) + for quantizer in quantizers: + alphas.append(quantizer.alpha) + return torch.tensor(alphas).numpy() + + def set_alphas_np(self, alphas: np.ndarray, weight=True, act=True): + quantizers = (self.weight_quantizers if weight else []) + (self.act_quantizers if act else []) + for i, quantizer in enumerate(quantizers): + quantizer.set_params_from_alpha(alphas[i]) + class LAPQ(BaseQuantization): - """ - Parameters - ---------- - model (nn.Module): Model to be used - dataloaders (dict): Dictionary with dataloaders for train, test, val - kwargs (object): A yaml safe loaded file with information like W_BITS, A_BITS. CALIB_BATCHES, etc. - """ - def __init__(self, model: nn.Module, dataloaders, **kwargs): super(LAPQ, self).__init__(**kwargs) self.model = model @@ -82,245 +78,103 @@ def __init__(self, model: nn.Module, dataloaders, **kwargs): seed_everything(self.seed) self.device = torch.device('cuda:{}'.format(self.gpu_id)) if self.verbose: - print('==> Using seed: {} and device: cuda:{}'.format( - self.seed, self.gpu_id)) - self.calib_data = self.get_calib_samples(self.train_loader, - 64 * self.calib_batches) + print("==> Using seed: {} and device: cuda:{}".format(self.seed, self.gpu_id)) + self.calib_data = self.get_calib_samples(self.train_loader, 64*self.calib_batches) self.eval_count = count(0) self.min_loss = 1e6 - self.wandb_monitor = self.kwargs.get('WANDB', 'False') - self.dataset_name = dataloaders['train'].dataset.__class__.__name__ - self.save = './checkpoints/' - - self.name = '_'.join([ - self.dataset_name, - f'{self.a_bits}', - datetime.now().strftime('%b-%d_%H:%M:%S'), - ]) - - os.makedirs(f'{os.getcwd()}/logs/LAPQ', exist_ok=True) - os.makedirs(self.save, exist_ok=True) - self.logger_file = f'{os.getcwd()}/logs/LAPQ/{self.name}.log' - - logging.basicConfig( - filename=self.logger_file, - format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', - datefmt='%m/%d/%Y %H:%M:%S', - level=logging.INFO, - ) - - logger.info(f'Experiment Arguments: {self.kwargs}') - - if self.wandb_monitor: - wandb.init(project='Trailmet LAPQ', name=self.name) - wandb.config.update(self.kwargs) - def compress_model(self): self.model.to(self.device) - self.search_absorbe_bn(self.model) - args = { - 'bit_weights': self.w_bits, - 'bit_act': self.a_bits, - 'bcorr_w': True, - 'qtype': 'lp_norm', - 'lp': 2.0, + self.model.eval() + + weight_quant_params = { + 'n_bits': self.w_bits, + 'bcorr': True, + 'method': 'max_abs', + 'p_val': 2.0, + } + act_quant_params = { + 'n_bits': self.a_bits, + 'bcorr': True, + 'method': 'max_abs', + 'p_val': 2.0, } - layers = [] - layers += [ - n for n, m in self.model.named_modules() - if isinstance(m, nn.Conv2d) - ][1:-1] - if self.act_quant: - layers += [ - n for n, m in self.model.named_modules() - if isinstance(m, nn.ReLU) - ][1:-1] - layers += [ - n for n, m in self.model.named_modules() - if isinstance(m, nn.ReLU6) - ][1:-1] if self.test_before_calibration: - args['qtype'] = 'max_static' - cnn = copy.deepcopy(self.model) - qm = QuantModel(cnn, args, layers) - - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - qm.model, self.test_loader) - - print( - '==> Quantization (W{}A{}) accuracy before LAPQ: {:.4f} | {:.4f}' - .format(self.w_bits, self.a_bits, valid_top1_acc, - valid_top5_acc)) - logger.info( - '==> Quantization (W{}A{}) accuracy before LAPQ: {:.4f} | {:.4f}' - .format(self.w_bits, self.a_bits, valid_top1_acc, - valid_top5_acc)) - del qm, cnn - - ps = np.linspace(2, 4, 10) + qnn = QuantModel(self.model, weight_quant_params, act_quant_params) + qnn.set_quant_state(True, True) + acc1, acc5 = self.test(qnn, self.test_loader, device=self.device) + print('==> Quantization (W{}A{}) accuracy before LAPQ: {:.4f} | {:.4f}'.format( + self.w_bits, self.a_bits, acc1, acc5)) + del qnn + + weight_quant_params['method'] = 'lp_norm' + act_quant_params['method'] = 'lp_norm' + p_vals = np.linspace(2,4,10) losses = [] - - tk1 = tqdm(ps, total=len(ps)) - - for p in tk1: - args['qtype'] = 'lp_norm' - args['lp'] = p - cnn = copy.deepcopy(self.model) - qm = QuantModel(cnn, args, layers) - loss = self.evaluate_loss(model=qm.model, device=self.device) + pbar = tqdm(p_vals, total=len(p_vals)) + for p in pbar: + weight_quant_params['p_val'] = p + act_quant_params['p_val'] = p + qnn = QuantModel(self.model, weight_quant_params, act_quant_params) + qnn.set_quant_state(True, True) + loss = self.evaluate_loss(qnn, self.device) losses.append(loss.item()) - tk1.set_postfix(p_val=p, loss=loss.item()) - del qm, cnn + pbar.set_postfix(p_val=p, loss=loss.item()) + del qnn # using quadratic interpolation to approximate the optimal quantization step size ∆p∗ - z = np.polyfit(ps, losses, 2) + z = np.polyfit(p_vals, losses, 2) y = np.poly1d(z) p_intr = y.deriv().roots[0] + print("==> using p val : {:.2f} with lp-loss : {:.2f}".format(p_intr, min(losses))) - print('==> using p intr : {:.2f}'.format(p_intr)) - logger.info('==> using p intr : {:.2f}'.format(p_intr)) - args['lp'] = p_intr - quant_model = QuantModel(self.model, args, layers) - - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - quant_model.model, self.test_loader) - lp_point = quant_model.get_clipping() - - print( - '==> Quantization (W{}A{}) accuracy before Optimization: {:.4f} | {:.4f}' - .format(self.w_bits, self.a_bits, valid_top1_acc, valid_top5_acc)) - print('==> Loss after LpNormQuantization: {:.4f}'.format(valid_loss)) - print('==> Starting Powell Optimization') - - logger.info( - '==> Quantization (W{}A{}) accuracy before Optimization: {:.4f} | {:.4f}' - .format(self.w_bits, self.a_bits, valid_top1_acc, valid_top5_acc)) - logger.info( - '==> Loss after LpNormQuantization: {:.4f}'.format(valid_loss)) - logger.info('==> Starting Powell Optimization') - - min_method = 'Powell' - min_options = {'maxiter': self.maxiter, 'maxfev': self.maxfev} - init_scale = lp_point.cpu().numpy() + weight_quant_params['p_val'] = p_intr + act_quant_params['p_val'] = p_intr + self.qnn = QuantModel(self.model, weight_quant_params, act_quant_params) + self.qnn.set_quant_state(weight_quant=True, act_quant=True) + lp_acc1, lp_acc5 = self.test(self.qnn, self.test_loader, device=self.device) + if self.verbose: + print('==> Quantization (W{}A{}) accuracy before Optimization: {:.4f} | {:.4f}'.format( + self.w_bits, self.a_bits, lp_acc1, lp_acc5)) + print("==> Starting Powell Optimization") + + init_alphas = self.qnn.get_alphas_np() + + min_method = "Powell" + min_options = { + 'maxiter' : self.maxiter, + 'maxfev' : self.maxfev + } count_iter = count(0) - def local_search_callback(x): it = next(count_iter) - quant_model.set_clipping(x, self.device) - loss = self.evaluate_loss(quant_model.model, self.device) + self.qnn.set_alphas_np(x) + loss = self.evaluate_loss(self.qnn.model, self.device) if self.verbose: - print('\n==> Loss at end of iter [{}] : {:.4f}\n'.format( - it, loss.item())) + print('\n==> Loss at end of iter [{}] : {:.4f}\n'.format(it, loss.item())) self.pbar = tqdm(total=min(self.maxiter, self.maxfev)) res = optim.minimize( - lambda scales: self.evaluate_calibration(scales, quant_model, self. - device), - init_scale, - method=min_method, - options=min_options, - callback=local_search_callback, + lambda alphas: self.evaluate_calibration(alphas, self.qnn, self.device), init_alphas, + method=min_method, options=min_options, callback=local_search_callback ) self.pbar.close() - scales = res.x - print('==> Layer-wise Scales :\n', scales) - logger.info(f'==> Layer-wise Scales :{scales}') - - quant_model.set_clipping(scales, self.device) - - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - quant_model.model, self.test_loader) + alphas = res.x + if self.verbose: + print('==> Layer-wise Scales :\n', alphas) + self.qnn.set_alphas_np(alphas) print('==> Full quantization (W{}A{}) accuracy: {}'.format( - self.w_bits, self.a_bits, valid_top1_acc)) - - logger.info('==> Full quantization (W{}A{}) accuracy: {}'.format( - self.w_bits, self.a_bits, valid_top1_acc)) - self.qnn = copy.deepcopy(quant_model.model) + self.w_bits, self.a_bits, + self.test(self.qnn, self.test_loader, device=self.device))) return self.qnn - def test(self, model, dataloader, loss_fn=nn.CrossEntropyLoss()): - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - - epoch_iterator = tqdm( - dataloader, - desc= - 'Validating network (X / X Steps) (batch time=X.Xs) (loss=X.X) (top1=X.X) (top5=X.X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - disable=False, - ) - - model.eval() - model.to(self.device) - - with torch.no_grad(): - end = time.time() - - for i, (images, labels) in enumerate(epoch_iterator): - images = images.to(self.device, dtype=torch.float) - labels = labels.to(self.device) - - preds = model(images) - - loss = loss_fn(preds, labels) - - pred1, pred5 = accuracy(preds, labels, topk=(1, 5)) - n = images.size(0) - losses.update(loss.item(), n) - top1.update(pred1[0], n) - top5.update(pred5[0], n) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - epoch_iterator.set_description( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - logger.info( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - if self.wandb_monitor: - wandb.log({ - 'val_loss': losses.val, - 'val_top1_acc': top1.val, - 'val_top5_acc': top5.val, - }) - - print(' * acc@1 {top1.avg:.3f} acc@5 {top5.avg:.3f}'.format( - top1=top1, top5=top5)) - return losses.avg, top1.avg, top5.avg - - def evaluate_calibration(self, scales, QM, device): + def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel, device): eval_count = next(self.eval_count) - QM.set_clipping(scales, device) - loss = self.evaluate_loss(QM.model, device).item() + qmodel.set_alphas_np(alphas) + loss = self.evaluate_loss(qmodel, device).item() if loss < self.min_loss: self.min_loss = loss - # if self.verbose and eval_count%self.print_freq==0: - # print("==> iteration: {}, minimum loss so far: {:.4f}".format( - # eval_count, self.min_loss)) self.pbar.set_postfix(curr_loss=loss, min_loss=self.min_loss) self.pbar.update(1) return loss @@ -332,147 +186,15 @@ def evaluate_loss(self, model: nn.Module, device): if not hasattr(self, 'cal_set'): self.cal_set = [] for i, (images, target) in enumerate(self.train_loader): - if (i >= self.calib_batches - ): # TODO: make this robust for variable batch size + if i>=self.calib_batches: # TODO: make this robust for variable batch size break images = images.to(device, non_blocking=True) target = target.to(device, non_blocking=True) self.cal_set.append((images, target)) - res = torch.tensor([0.0]).to(device) + res = torch.tensor([0.]).to(device) for i in range(len(self.cal_set)): images, target = self.cal_set[i] output = model(images) loss = criterion(output, target) res += loss - return res / len(self.cal_set) - - -class QuantModel: - """ - Parameters - ---------- - model (nn.Module): Model to be used - args (object): A yaml safe loadec file with information like bit_weights, bit_act, etc. - quantizable_layers (list): A list of the quantizable layers. - optimizer_bridge (): - """ - - def __init__(self, model, args, quantizable_layers, optimizer_bridge=None): - self.model = model - self.args = args - self.bit_weights = args['bit_weights'] - self.bit_act = args['bit_act'] - self.post_relu = True - - self.replacement_factory = { - nn.ReLU: ActivationModuleWrapper, - nn.ReLU6: ActivationModuleWrapper, - nn.Conv2d: ParameterModuleWrapper, - } - self.functor_map = { - nn.Conv2d: Conv2dFunctor, - nn.Linear: LinearFunctor, - } - self.optimizer_bridge = optimizer_bridge - - self.quantization_wrappers = [] - self.quantizable_modules = [] - self.quantizable_layers = quantizable_layers - self._pre_process_container(model) - self._create_quantization_wrappers() - self.quantization_params = LearnedStepSizeQuantization.learned_parameters( - ) - - def load_state_dict(self, state_dict): - for name, qwrapper in self.quantization_wrappers: - qwrapper.load_state_dict(state_dict) - - def freeze(self): - for n, p in self.model.named_parameters(): - # TODO: hack, make it more robust - if not np.any([qp in n for qp in self.quantization_params]): - p.requires_grad = False - - @staticmethod - def has_children(module): - try: - next(module.children()) - return True - except StopIteration: - return False - - def _create_quantization_wrappers(self): - for qm in self.quantizable_modules: - # replace module by it's wrapper - fn = (self.functor_map[type(qm.module)](qm.module) - if type(qm.module) in self.functor_map else None) - args = { - 'bits_out': self.bit_act, - 'bits_weight': self.bit_weights, - 'forward_functor': fn, - 'post_relu': self.post_relu, - 'optim_bridge': self.optimizer_bridge, - } - args.update(self.args) - if hasattr(qm, 'bn'): - args['bn'] = qm.bn - module_wrapper = self.replacement_factory[type(qm.module)]( - qm.full_name, qm.module, **args) - setattr(qm.container, qm.name, module_wrapper) - self.quantization_wrappers.append((qm.full_name, module_wrapper)) - - def _pre_process_container(self, container, prefix=''): - prev, prev_name = None, None - for name, module in container.named_children(): - # if is_bn(module) and is_absorbing(prev) and prev_name in self.quantizable_layers: - # # Pass BN module to prev module quantization wrapper for BN folding/unfolding - # self.quantizable_modules[-1].bn = module - - full_name = prefix + name - if full_name in self.quantizable_layers: - self.quantizable_modules.append( - type( - '', - (object, ), - { - 'name': name, - 'full_name': full_name, - 'module': module, - 'container': container, - }, - )()) - - if self.has_children(module): - # For container we call recursively - self._pre_process_container(module, full_name + '.') - - prev = module - prev_name = full_name - - def get_qwrappers(self): - return [ - qwrapper for (name, qwrapper) in self.quantization_wrappers - if qwrapper.__enabled__() - ] - - def set_clipping(self, clipping, - device): # TODO: handle device internally somehow - qwrappers = self.get_qwrappers() - for i, qwrapper in enumerate(qwrappers): - qwrapper.set_quantization( - FixedClipValueQuantization, - { - 'clip_value': clipping[i], - 'device': device - }, - ) - - def get_clipping(self): - clipping = [] - qwrappers = self.get_qwrappers() - for i, qwrapper in enumerate(qwrappers): - q = qwrapper.get_quantization() - clip_value = getattr(q, 'alpha') - clipping.append(clip_value.item()) - - return qwrappers[0].get_quantization().alpha.new_tensor(clipping) + return res / len(self.cal_set) \ No newline at end of file From 4ce88721952f47ec878f15b2d795b619ee68cb8c Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:02:24 +0530 Subject: [PATCH 07/35] modified brecq --- trailmet/algorithms/quantize/brecq.py | 654 ++++++++++---------------- 1 file changed, 260 insertions(+), 394 deletions(-) diff --git a/trailmet/algorithms/quantize/brecq.py b/trailmet/algorithms/quantize/brecq.py index f94c64c..59d4c08 100644 --- a/trailmet/algorithms/quantize/brecq.py +++ b/trailmet/algorithms/quantize/brecq.py @@ -19,75 +19,69 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import copy + import torch import torch.nn as nn -import torch.distributed as dist +from typing import Union from trailmet.utils import seed_everything -from trailmet.algorithms.quantize.quantize import ( - BaseQuantization, - FoldBN, - StraightThrough, -) -from trailmet.models.resnet import BasicBlock, Bottleneck -from trailmet.models.mobilenet import InvertedResidual -from trailmet.algorithms.quantize.qmodel import ( - QuantBasicBlock, - QuantBottleneck, - QuantInvertedResidual, - QuantModule, - BaseQuantBlock, -) -from trailmet.algorithms.quantize.reconstruct import ( - layer_reconstruction, - block_reconstruction, -) - -import logging -from datetime import datetime -from tqdm import tqdm -import wandb -import pandas as pd -import numpy as np -import os -import time - -from trailmet.utils import AverageMeter, accuracy, save_checkpoint - -logger = logging.getLogger(__name__) - -supported = { - BasicBlock: QuantBasicBlock, - Bottleneck: QuantBottleneck, - InvertedResidual: QuantInvertedResidual, -} +from trailmet.algorithms.quantize.quantize import BaseQuantization, BaseQuantModel +from trailmet.algorithms.quantize.quantize import GetLayerGrad, GetLayerInpOut, BaseQuantLoss +from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, BaseQuantBlock +from trailmet.algorithms.quantize.methods import UniformAffineQuantizer, AdaRoundQuantizer + + +class QuantModel(BaseQuantModel): + def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params: dict): + super(QuantModel, self).__init__(model, weight_quant_params, act_quant_params, fold_bn=True) + + def reset_scale_method(self, scale_method = 'mse', act_quant_reset = False): + for module in self.quant_modules: + module.weight_quantizer.scale_method = scale_method + module.weight_quantizer.inited = False + if act_quant_reset: + module.act_quantizer.scale_method = scale_method + module.act_quantizer.inited = False + + def set_head_stem_precision(self, bitwidth): + """ + Set the precision (bitwidth) for weights and activations for the first and last + layers of the model. Also ignore reconstruction for the first layer. + """ + assert len(self.quant_modules) >= 2, 'Model has less than 2 quantization modules' + self.quant_modules[0].weight_quantizer.bitwidth_refactor(bitwidth) + self.quant_modules[0].act_quantizer.bitwidth_refactor(bitwidth) + self.quant_modules[-1].weight_quantizer.bitwidth_refactor(bitwidth) + self.quant_modules[-2].act_quantizer.bitwidth_refactor(bitwidth) + self.quant_modules[0].ignore_reconstruction = True + def disable_network_output_quantization(self): + """ + Disable Network Output Quantization + """ + self.quant_modules[-1].disable_act_quant = True + + class BRECQ(BaseQuantization): """ - Class for post-training quantization using block reconstruction method - based on - BRECQ: PUSHING THE LIMIT OF POST-TRAINING QUANTIZATION + Class for post-training quantization using block reconstruction method + based on - BRECQ: PUSHING THE LIMIT OF POST-TRAINING QUANTIZATION BY BLOCK RECONSTRUCTION [https://arxiv.org/abs/2102.05426] - Parameters - ---------- - model (nn.Module): Model to be used - dataloaders (dict): Dictionary with dataloaders for train, test, val - W_BITS: bitwidth for weight quantization - A_BITS: bitwidth for activation quantization - CHANNEL_WISE: apply channel_wise quantization for weights - ACT_QUANT: apply activation quantization - SET_8BIT_HEAD_STEM: Set the first and the last layer to 8-bit - NUM_SAMPLES: size of calibration dataset - WEIGHT: weight of rounding cost vs the reconstruction loss - ITERS_W: number of iteration for AdaRound - ITERS_A: number of iteration for LSQ - LR: learning rate for LSQ + :param W_BITS: bitwidth for weight quantization + :param A_BITS: bitwidth for activation quantization + :param CHANNEL_WISE: apply channel_wise quantization for weights + :param ACT_QUANT: apply activation quantization + :param SET_8BIT_HEAD_STEM: Set the first and the last layer to 8-bit + :param NUM_SAMPLES: size of calibration dataset + :param WEIGHT: weight of rounding cost vs the reconstruction loss + :param ITERS_W: number of iteration for AdaRound + :param ITERS_A: number of iteration for LSQ + :param LR: learning rate for LSQ """ - def __init__(self, model: nn.Module, dataloaders, **kwargs): super(BRECQ, self).__init__(**kwargs) - self.model = copy.deepcopy(model) + self.model = model self.train_loader = dataloaders['train'] self.test_loader = dataloaders['test'] self.kwargs = kwargs @@ -96,399 +90,271 @@ def __init__(self, model: nn.Module, dataloaders, **kwargs): self.channel_wise = self.kwargs.get('CHANNEL_WISE', True) self.act_quant = self.kwargs.get('ACT_QUANT', True) self.set_8bit_head_stem = self.kwargs.get('SET_8BIT_HEAD_STEM', False) - self.precision_config = self.kwargs.get('PREC_CONFIG', []) + self.w_budget = self.kwargs.get('W_BUDGET', None) + self.use_bits = self.kwargs.get('USE_BITS', [2,4,8]) + self.arch = self.kwargs.get('ARCH', '') + self.save_path = self.kwargs.get('SAVE_PATH', './runs/') self.num_samples = self.kwargs.get('NUM_SAMPLES', 1024) - self.weight = self.kwargs.get('WEIGHT', 0.01) + self.scale_method = self.kwargs.get('SCALE_METHOD', 'mse') + self.iters_w = self.kwargs.get('ITERS_W', 10000) self.iters_a = self.kwargs.get('ITERS_A', 10000) - self.optimizer = self.kwargs.get('OPTIMIZER', 'adam') - self.lr = self.kwargs.get('LR', 4e-4) + self.optim = self.kwargs.get('OPTIMIZER', torch.optim.adam) + self.weight = self.kwargs.get('WEIGHT', 0.01) + self.lr = self.kwargs.get('LR', 4e-5) + self.p = self.kwargs.get('P_VAL', 2.4) # Lp norm minimization for LSQ + self.gpu_id = self.kwargs.get('GPU_ID', 0) - self.calib_bs = self.kwargs.get('CALIB_BS', 64) + self.batch_size = self.kwargs.get('BATCH_SIZE', 64) self.seed = self.kwargs.get('SEED', 42) - self.p = 2.4 # Lp norm minimization for LSQ - self.b_start = 20 # temperature at the beginning of calibration - self.b_end = 2 # temperature at the end of calibration + self.b_start = 20 # temperature at the beginning of calibration + self.b_end = 2 # temperature at the end of calibration self.test_before_calibration = True self.device = torch.device('cuda:{}'.format(self.gpu_id)) torch.cuda.set_device(self.gpu_id) + self.calib_data = self.get_calib_samples(self.train_loader, self.num_samples) seed_everything(self.seed) - print('==> Using seed :', self.seed) - - self.wandb_monitor = self.kwargs.get('WANDB', 'False') - self.dataset_name = dataloaders['train'].dataset.__class__.__name__ - self.save = './checkpoints/' - - self.name = '_'.join([ - self.dataset_name, - f'{self.a_bits}', - f'{self.lr}', - datetime.now().strftime('%b-%d_%H:%M:%S'), - ]) - - os.makedirs(f'{os.getcwd()}/logs/BRECQ', exist_ok=True) - os.makedirs(self.save, exist_ok=True) - self.logger_file = f'{os.getcwd()}/logs/BRECQ/{self.name}.log' - - logging.basicConfig( - filename=self.logger_file, - format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', - datefmt='%m/%d/%Y %H:%M:%S', - level=logging.INFO, - ) - - logger.info(f'Experiment Arguments: {self.kwargs}') + print('==> Using seed :',self.seed) - if self.wandb_monitor: - wandb.init(project='Trailmet BRECQ', name=self.name) - wandb.config.update(self.kwargs) def compress_model(self): - """Method to build quantization parameters and finetune weights and/or - activations.""" - wq_params = { - 'n_bits': self.w_bits, - 'channel_wise': self.channel_wise, - 'scale_method': 'mse', + """ + method to build quantization parameters and finetune weights and/or activations + """ + self.model.to(self.device) + self.model.eval() + weight_quant_params = { + 'n_bits': self.w_bits, + 'channel_wise': self.channel_wise, + 'method': UniformAffineQuantizer, + 'scale_method': self.scale_method, } - aq_params = { - 'n_bits': self.a_bits, - 'channel_wise': False, - 'scale_method': 'mse', + act_quant_params = { + 'n_bits': self.a_bits, + 'channel_wise': False, + 'method': UniformAffineQuantizer, + 'scale_method': self.scale_method, 'leaf_param': self.act_quant, } - self.model = self.model.to(self.device) - self.model.eval() - self.qnn = QuantModel(model=self.model, - weight_quant_params=wq_params, - act_quant_params=aq_params) - self.qnn = self.qnn.to(self.device) + self.qnn = QuantModel(self.model, weight_quant_params, act_quant_params) + self.qnn.to(self.device) self.qnn.eval() - for i in range(len(self.precision_config)): - conf = self.precision_config[i] - self.qnn.set_layer_precision(conf[2], conf[3], conf[0], conf[1]) - print( - f'==> Layers from {conf[0]} to {conf[1]} set to precision w{conf[2]}a{conf[3]}' - ) - logger.info( - f'==> Layers from {conf[0]} to {conf[1]} set to precision w{conf[2]}a{conf[3]}' - ) - + w_compr = self.w_bits/32 if self.w_budget is None else self.w_budget + if self.w_budget is not None: + w_bits, qm_size, max_size = self.sensitivity_analysis( + self.qnn, self.test_loader, self.use_bits, self.w_budget, + self.save_path, '{}_{}_{}'.format(self.arch, w_compr, self.a_bits)) + print('==> Found optimal config for approx model size: {:.2f} MB ' \ + ' (orig {:.2f} MB)'.format(qm_size, max_size/self.w_budget)) + self.qnn.set_layer_precision(w_bits, self.a_bits) + self.qnn.reset_scale_method(self.scale_method, True) + if self.set_8bit_head_stem: print('==> Setting the first and the last layer to 8-bit') - logger.info('==> Setting the first and the last layer to 8-bit') - self.qnn.set_first_last_layer_to_8bit() - - self.cali_data = self.get_calib_samples(self.train_loader, - self.num_samples) - # device = next(self.qnn.parameters()).device + self.qnn.set_head_stem_precision(8) - # Initialize weight quantization parameters self.qnn.set_quant_state(True, False) print('==> Initializing weight quantization parameters') - logger.info('==> Initializing weight quantization parameters') - _ = self.qnn(self.cali_data[:self.calib_bs].to(self.device)) + _ = self.qnn(self.calib_data[:self.batch_size].to(self.device)) if self.test_before_calibration: - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - self.qnn, self.test_loader, nn.CrossEntropyLoss()) - print('Quantized accuracy before brecq: {}'.format(valid_top1_acc)) - logger.info( - 'Quantized accuracy before brecq: {}'.format(valid_top1_acc)) - - # Start weight calibration + print('Quantized accuracy before brecq: {}'.format(self.test(self.qnn, self.test_loader, device=self.device))) + + # Start quantized weight calibration kwargs = dict( - cali_data=self.cali_data, - iters=self.iters_w, - weight=self.weight, + iters=self.iters_w, + opt_mode='mse', + act_quant=False, asym=True, - b_range=(self.b_start, self.b_end), - warmup=0.2, - act_quant=False, - opt_mode='mse', - optim=self.optimizer, + b_range=(self.b_start, self.b_end), + warmup=0.2, ) - print('==> Starting weight calibration') - logger.info('==> Starting weight calibration') + print('==> Starting quantized-weight rounding parameter (alpha) calibration') self.reconstruct_model(self.qnn, **kwargs) self.qnn.set_quant_state(weight_quant=True, act_quant=False) - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - self.qnn, self.test_loader, nn.CrossEntropyLoss()) - print('Weight quantization accuracy: {}'.format(valid_top1_acc)) + print('Weight quantization accuracy: {}'.format(self.test(self.qnn, self.test_loader, device=self.device))) if self.act_quant: # Initialize activation quantization parameters self.qnn.set_quant_state(True, True) with torch.no_grad(): - _ = self.qnn(self.cali_data[:self.calib_bs].to(self.device)) - - # Disable output quantization because network output - # does not get involved in further computation + _ = self.qnn(self.calib_data[:self.calib_bs].to(self.device)) self.qnn.disable_network_output_quantization() - + # Start activation rounding calibration kwargs = dict( - cali_data=self.cali_data, - iters=self.iters_a, - act_quant=True, - opt_mode='mse', - lr=self.lr, - p=self.p, - optim=self.optimizer, + iters=self.iters_a, + opt_mode='mse', + act_quant=True, ) + print('==> Starting quantized-activation scaling parameter (delta) calibration') self.reconstruct_model(self.qnn, **kwargs) self.qnn.set_quant_state(weight_quant=True, act_quant=True) - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - self.qnn, self.test_loader, nn.CrossEntropyLoss()) - print('Full quantization (W{}A{}) accuracy: {}'.format( - self.w_bits, self.a_bits, valid_top1_acc)) - logger.info('Full quantization (W{}A{}) accuracy: {}'.format( - self.w_bits, self.a_bits, valid_top1_acc)) + # torch.save(self.qnn.state_dict(), f'{self.save_path}/weights/{self.arch}_{w_compr}_{self.a_bits}.pth') + print('Full quantization (W{}A{}) accuracy: {}'.format(w_compr, self.a_bits, + self.test(self.qnn, self.test_loader, device=self.device))) return self.qnn - def reconstruct_model(self, model: nn.Module, **kwargs): - """Method for model parameters reconstruction. - Takes in quantized model and optimizes weights by applying layer-wise - reconstruction for first and last layer, and block reconstruction - otherwise. + def reconstruct_model(self, module: nn.Module, **kwargs): """ - for name, module in model.named_children(): - if isinstance(module, QuantModule): - if module.ignore_reconstruction is True: + Method for model parameters reconstruction. Takes in quantized model + and optimizes weights by applying layer-wise reconstruction for first + and last layer, and block reconstruction otherwise. + """ + for name, child_module in module.named_children(): + if isinstance(child_module, QuantModule): + if child_module.ignore_reconstruction is True: print('Ignore reconstruction of layer {}'.format(name)) - logger.info( - 'Ignore reconstruction of layer {}'.format(name)) continue else: print('Reconstruction for layer {}'.format(name)) - logger.info('Reconstruction for layer {}'.format(name)) - layer_reconstruction(self.qnn, module, **kwargs) - elif isinstance(module, BaseQuantBlock): - if module.ignore_reconstruction is True: - print('Ignore reconstruction of block {}'.format(name)) - logger.info( - 'Ignore reconstruction of block {}'.format(name)) + self.reconstruct_module(self.qnn, child_module, **kwargs) + elif isinstance(child_module, BaseQuantBlock): + if child_module.ignore_reconstruction is True: + print('Ignore reconstruction of {} block {}'.format(self._parent_name, name)) continue else: - print('Reconstruction for block {}'.format(name)) - logger.info('Reconstruction for block {}'.format(name)) - block_reconstruction(self.qnn, module, **kwargs) - else: - self.reconstruct_model(module, **kwargs) - - def test(self, model, dataloader, loss_fn): - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - - epoch_iterator = tqdm( - dataloader, - desc= - 'Validating network (X / X Steps) (batch time=X.Xs) (loss=X.X) (top1=X.X) (top5=X.X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - disable=False, - ) - - model.eval() - model.to(self.device) - - with torch.no_grad(): - end = time.time() - - for i, (images, labels) in enumerate(epoch_iterator): - images = images.to(self.device, dtype=torch.float) - labels = labels.to(self.device) - - preds = model(images) - - loss = loss_fn(preds, labels) - - pred1, pred5 = accuracy(preds, labels, topk=(1, 5)) - - n = images.size(0) - losses.update(loss.item(), n) - top1.update(pred1[0], n) - top5.update(pred5[0], n) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - epoch_iterator.set_description( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - logger.info( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - if self.wandb_monitor: - wandb.log({ - 'val_loss': losses.val, - 'val_top1_acc': top1.val, - 'val_top5_acc': top5.val, - }) - - print(' * acc@1 {top1.avg:.3f} acc@5 {top5.avg:.3f}'.format( - top1=top1, top5=top5)) - return losses.avg, top1.avg, top5.avg - - -class QuantModel(nn.Module): - """Recursively replace the normal conv2d and Linear layer to QuantModule, - to enable calculating activation statistics and storing scaling factors. - - Parameters - ---------- - model (nn.Module): nn.Module with nn.Conv2d or nn.Linear in its children - weight_quant_params (dict): quantization parameters like n_bits for weight - quantizer - act_quant_params(dict): quantization parameters like n_bits for activation - quantizer - """ - - def __init__( - self, - model: nn.Module, - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - ): - super().__init__() - self.model = model - bn = FoldBN() - bn.search_fold_and_remove_bn(self.model) - self.quant_module_refactor(self.model, weight_quant_params, - act_quant_params) - self.quant_modules = [ - m for m in self.model.modules() if isinstance(m, QuantModule) - ] - - def quant_module_refactor( - self, - module: nn.Module, - weight_quant_params: dict = {}, - act_quant_params: dict = {}, - ): - prev_quantmodule = None - for name, child_module in module.named_children(): - if type(child_module) in supported: - setattr( - module, - name, - supported[type(child_module)](child_module, - weight_quant_params, - act_quant_params), - ) - - elif isinstance(child_module, (nn.Conv2d, nn.Linear)): - setattr( - module, - name, - QuantModule(child_module, weight_quant_params, - act_quant_params), - ) - prev_quantmodule = getattr(module, name) - - elif isinstance(child_module, (nn.ReLU, nn.ReLU6)): - if prev_quantmodule is not None: - prev_quantmodule.activation_function = child_module - setattr(module, name, StraightThrough()) - else: - continue - - elif isinstance(child_module, StraightThrough): - continue - + print('Reconstruction for {} block {}'.format(self._parent_name, name)) + self.reconstruct_module(self.qnn, child_module, **kwargs) else: - self.quant_module_refactor(child_module, weight_quant_params, - act_quant_params) - - def set_quant_state(self, - weight_quant: bool = False, - act_quant: bool = False): + self._parent_name = name + self.reconstruct_model(child_module, **kwargs) + + + def reconstruct_module(self, + model: BaseQuantModel, module: Union[QuantModule, BaseQuantBlock], + iters: int = 10000, opt_mode: str = 'mse', act_quant: bool = False, + asym: bool = False, include_act_func: bool = True, b_range: tuple = (20, 2), + warmup: float = 0.0): + + model.set_quant_state(False, False) + module.set_quant_state(True, act_quant) + round_mode = 'learned_hard_sigmoid' + opt_params = [] + + if not include_act_func: + org_act_func = module.activation_function + module.activation_function = StraightThrough() + + if not act_quant: + # Replace weight quantizer to AdaRoundQuantizer and learn alpha + if isinstance(module, QuantModule): + module.weight_quantizer = AdaRoundQuantizer( + uaq = module.weight_quantizer, round_mode = round_mode, + weight_tensor = module.org_weight.data) + module.weight_quantizer.soft_targets = True + opt_params.append(module.weight_quantizer.alpha) + + if isinstance(module, BaseQuantBlock): + for name, submodule in module.named_modules(): + if isinstance(submodule, QuantModule): + submodule.weight_quantizer = AdaRoundQuantizer( + uaq = submodule.weight_quantizer, round_mode = round_mode, + weight_tensor = submodule.org_weight.data) + submodule.weight_quantizer.soft_targets = True + opt_params.append(submodule.weight_quantizer.alpha) + + optimizer = self.optim(opt_params) + scheduler = None + else: + # Use UniformAffineQuantizer to learn delta for activations + if hasattr(module.act_quantizer, 'delta'): + opt_params.append(module.act_quantizer.delta) + if isinstance(module, BaseQuantBlock): + for name, submodule in module.named_modules(): + if isinstance(submodule, QuantModule) and submodule.act_quantizer.delta is not None: + opt_params.append(submodule.act_quantizer.delta) + + optimizer = self.optim(opt_params, lr = self.lr) + scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=iters, eta_min=0.) + + + loss_mode = 'none' if act_quant else 'relaxation' + # rec_loss = opt_mode + loss_func = BaseQuantLoss( + module, round_loss=loss_mode, weight=self.weight, max_count=iters, + rec_loss=opt_mode, b_range=b_range, decay_start=0, warmup=warmup, p=self.p) + + # Save data before optimizing the rounding + cached_inps, cached_outs = self.save_inp_oup_data(model, module, asym, act_quant) + if opt_mode != 'mse': + cached_grads = self.save_grad_data(model, module, act_quant) + else: + cached_grads = None + + for i in range(iters): + idx = torch.randperm(cached_inps.size(0))[:self.batch_size] + cur_inp = cached_inps[idx].to(self.device) + cur_out = cached_outs[idx].to(self.device) + cur_grad = cached_grads[idx].to(self.device) if opt_mode != 'mse' else None + + optimizer.zero_grad() + out_quant = module(cur_inp) + + err = loss_func(out_quant, cur_out, cur_grad) + err.backward(retain_graph=True) + + optimizer.step() + if scheduler: + scheduler.step() + + torch.cuda.empty_cache() + + # Finish optimization, use hard rounding. + if isinstance(module, QuantModule): + module.weight_quantizer.soft_targets = False + if isinstance(module, BaseQuantBlock): + for name, submodule in module.named_modules(): + if isinstance(submodule, QuantModule): + submodule.weight_quantizer.soft_targets = False + + # Reset original activation function + if not include_act_func: + module.activation_function = org_act_func + + + def save_inp_oup_data(self, model, layer: Union[QuantModule, BaseQuantBlock], + asym: bool = False, act_quant: bool = False): """ - :param weight_quant: set True for weight quantization - :param act_quant: set True for activation quantization + Function to save input data and output data of a particular layer/block over calibration dataset. """ - for m in self.model.modules(): - if isinstance(m, (QuantModule, BaseQuantBlock)): - m.set_quant_state(weight_quant, act_quant) + get_inp_out = GetLayerInpOut(model, layer, device=self.device, asym=asym, act_quant=act_quant) + cached_batches = [] + torch.cuda.empty_cache() - def quantize_model_till(self, layer, act_quant: bool = False): - """ - :param layer: block/layer upto which model is to be quantized. - :param act_quant: set True for activation quantization - """ - self.set_quant_state(False, False) - for name, module in self.model.named_modules(): - if isinstance(module, (QuantModule, BaseQuantBlock)): - module.set_quant_state(True, act_quant) - if module == layer: - break + for i in range(int(self.calib_data.size(0) / self.batch_size)): + cur_inp, cur_out = get_inp_out(self.calib_data[i * self.batch_size:(i + 1) * self.batch_size]) + cached_batches.append((cur_inp.cpu(), cur_out.cpu())) - def forward(self, input): - return self.model(input) + cached_inps = torch.cat([x[0] for x in cached_batches]) + cached_outs = torch.cat([x[1] for x in cached_batches]) + torch.cuda.empty_cache() - def set_first_last_layer_to_8bit(self): - """Set the precision (bitwidth) used for quantizing weights and - activations to 8-bit for the first and last layers of the model. + cached_inps = cached_inps.to(self.device) + cached_outs = cached_outs.to(self.device) + return cached_inps, cached_outs + - Also ignore reconstruction for the first layer. + def save_grad_data(self, model: QuantModel, layer: Union[QuantModule, BaseQuantBlock], + act_quant: bool = False): """ - assert (len(self.quant_modules) - >= 2), 'Model has less than 2 quantization modules' - self.quant_modules[0].weight_quantizer.bitwidth_refactor(8) - self.quant_modules[0].act_quantizer.bitwidth_refactor(8) - self.quant_modules[-1].weight_quantizer.bitwidth_refactor(8) - self.quant_modules[-2].act_quantizer.bitwidth_refactor(8) - self.quant_modules[0].ignore_reconstruction = True - - def disable_network_output_quantization(self): - self.quant_modules[-1].disable_act_quant = True - - def set_layer_precision(self, weight_bit=8, act_bit=8, start=0, end=None): - """Set the precision (bitwidth) used for quantizing weights and - activations for a range of layers in the model. - - :param weight_bit: number of bits to use for quantizing weights - :param act_bit: number of bits to use for quantizing activations - :param start: index of the first layer to set the precision for - (default: 0) - :param end: index of the last layer to set the precision for (default: - None, i.e., the last layer) + Function to save gradient data of a particular layer/block over calibration dataset. """ - assert start >= 0 and end >= 0, 'layer index cannot be negative' - assert start < len(self.quant_modules) and end < len( - self.quant_modules), 'layer index out of range' - - for module in self.quant_modules[start:end + 1]: - module.weight_quantizer.bitwidth_refactor(weight_bit) - if module is not self.quant_modules[-1]: - module.act_quantizer.bitwidth_refactor(act_bit) - - def synchorize_activation_statistics(self): - """Synchronize the statistics of the activation quantizers across all - distributed workers.""" - for m in self.modules(): - if isinstance(m, QuantModule): - if m.act_quantizer.delta is not None: - m.act_quantizer.delta.data /= dist.get_world_size() - dist.all_reduce(m.act_quantizer.delta.data) + get_grad = GetLayerGrad(model, layer, self.device, act_quant=act_quant) + cached_batches = [] + torch.cuda.empty_cache() + + for i in range(int(self.calib_data.size(0) / self.batch_size)): + cur_grad = get_grad(self.calib_data[i * self.batch_size:(i + 1) * self.batch_size]) + cached_batches.append(cur_grad.cpu()) + + cached_grads = torch.cat([x for x in cached_batches]) + cached_grads = cached_grads.abs() + 1.0 + # scaling to make sure its mean is 1 + # cached_grads = cached_grads * torch.sqrt(cached_grads.numel() / cached_grads.pow(2).sum()) + torch.cuda.empty_cache() + + cached_grads = cached_grads.to(self.device) + return cached_grads \ No newline at end of file From d214aa42012fa468880ed2acef9eaaed96961393 Mon Sep 17 00:00:00 2001 From: homebrow Date: Thu, 31 Aug 2023 21:02:34 +0530 Subject: [PATCH 08/35] modified bitsplit --- trailmet/algorithms/quantize/bitsplit.py | 735 ++++++----------------- 1 file changed, 199 insertions(+), 536 deletions(-) diff --git a/trailmet/algorithms/quantize/bitsplit.py b/trailmet/algorithms/quantize/bitsplit.py index 19c1206..fa5300e 100644 --- a/trailmet/algorithms/quantize/bitsplit.py +++ b/trailmet/algorithms/quantize/bitsplit.py @@ -19,113 +19,81 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + + +import os, time import copy, random, pickle +import numpy as np import torch import torch.nn as nn from collections import OrderedDict +from tqdm import tqdm from trailmet.utils import seed_everything from trailmet.algorithms.quantize.quantize import BaseQuantization from trailmet.models.resnet import BasicBlock, Bottleneck from trailmet.models.mobilenet import InvertedResidual -from trailmet.algorithms.quantize.qmodel import ( - QBasicBlock, - QBottleneck, - QInvertedResidual, -) +from trailmet.algorithms.quantize.modules import QBasicBlock, QBottleneck, QInvertedResidual from trailmet.algorithms.quantize.methods import BitSplitQuantizer, ActQuantizer -import logging -from datetime import datetime -from tqdm import tqdm -import wandb -import pandas as pd -import numpy as np -import os -import time - -from trailmet.utils import AverageMeter, accuracy, save_checkpoint - -logger = logging.getLogger(__name__) global feat, prev_feat, conv_feat - - def hook(module, input, output): global feat feat = output.data.cpu().numpy() - - def current_input_hook(module, inputdata, outputdata): global prev_feat - prev_feat = inputdata[0].data - - + prev_feat = inputdata[0].data#.cpu()#.numpy() def conv_hook(module, inputdata, outputdata): global conv_feat - conv_feat = outputdata.data - + conv_feat = outputdata.data#.cpu()#.numpy() class QuantModel(nn.Module): - """ - Parameters - ---------- - model (nn.Module): Model to be used. - arch (str): Architecture to be used. - """ - def __init__(self, model: nn.Module, arch='ResNet50'): super().__init__() self.supported = { - BasicBlock: QBasicBlock, - Bottleneck: QBottleneck, - InvertedResidual: QInvertedResidual, + BasicBlock : QBasicBlock, + Bottleneck : QBottleneck, + InvertedResidual : QInvertedResidual, } - if arch == 'ResNet50': + if arch=='ResNet50': setattr(model, 'quant', ActQuantizer()) setattr(model, 'fc', nn.Sequential(ActQuantizer(), model.fc)) - if arch == 'MobileNetV2': + if arch=='MobileNetV2': + # setattr(model, 'quant1', ActQuantizer()) + # setattr(model, 'quant2', ActQuantizer()) setattr(model, 'conv2', nn.Sequential(ActQuantizer(), model.conv2)) - setattr(model, 'linear', nn.Sequential(ActQuantizer(), - model.linear)) + setattr(model, 'linear', nn.Sequential(ActQuantizer(), model.linear)) self.quant_block_refactor(model) def quant_block_refactor(self, module: nn.Module): - """Recursively modify the supported conv-blocks to add activation - quantization layers :param module: nn.Module with supported conv-block - classes in its children.""" + """ + Recursively modify the supported conv-blocks to add activation quantization layers + :param module: nn.Module with supported conv-block classes in its children + """ for name, child_module in module.named_children(): if type(child_module) in self.supported: - setattr(module, name, - self.supported[type(child_module)](child_module)) - elif isinstance(child_module, - (nn.Conv2d, nn.Linear, nn.ReLU, nn.ReLU6)): + setattr(module, name, self.supported[type(child_module)](child_module)) + elif isinstance(child_module, (nn.Conv2d, nn.Linear, nn.ReLU, nn.ReLU6)): continue - else: - self.quant_block_refactor(child_module) - + else: self.quant_block_refactor(child_module) class BitSplit(BaseQuantization): """ - Class for post-training quantization using bit-split and stitching method - based on - Towards accurate post-training network quantization via + Class for post-training quantization using bit-split and stitching method + based on - Towards accurate post-training network quantization via bit-split and stitching [https://dl.acm.org/doi/abs/10.5555/3524938.3525851] - Parameters - ---------- - model (nn.Module): Model to be used - dataloaders (dict): Dictionary with dataloaders for train, test, val - W_BITS: bitwidth for weight quantization - A_BITS: bitwidth for activation quantization - CHANNEL_WISE: apply channel-wise quantization for weights - ACT_QUANT: apply activation quantization - HEAD_STEM_PRECISION: bitwidth for first and last layer - PREC_CONFIG: list of bitwidths of the body for mixed precision - CALIB_BATCHES: num of batches in calibration dataset - LOAD_ACT_SCALES: load precomputed weight scales - LOAD_WEIGHT_SCALES: load precomputed activation scales - SAVE_PATH: path for storing quantized weights and scales + :param W_BITS: bitwidth for weight quantization + :param A_BITS: bitwidth for activation quantization + :param CHANNEL_WISE: apply channel-wise quantization for weights + :param ACT_QUANT: apply activation quantization + :param HEAD_STEM_PRECISION: bitwidth for first and last layer + :param PREC_CONFIG: list of bitwidths of the body for mixed precision + :param CALIB_BATCHES: num of batches in calibration dataset + :param LOAD_ACT_SCALES: load precomputed weight scales + :param LOAD_WEIGHT_SCALES: load precomputed activation scales + :param SAVE_PATH: path for storing quantized weights and scales """ - def __init__(self, model: nn.Module, dataloaders, **kwargs): super(BitSplit, self).__init__(**kwargs) self.model = model @@ -143,10 +111,9 @@ def __init__(self, model: nn.Module, dataloaders, **kwargs): self.dataset = self.kwargs.get('DATASET', '') self.precision_config = self.kwargs.get('PREC_CONFIG', []) if self.precision_config: - w_prefix = str(self.precision_config[0]) + '_mix' - else: - w_prefix = str(self.w_bits) - self.prefix = self.save_path + self.arch + '_' + self.dataset + '/W' + w_prefix + w_prefix = str(self.precision_config[0])+'_mix' + else: w_prefix = str(self.w_bits) + self.prefix = self.save_path+self.arch+'_'+self.dataset+'/W'+w_prefix if not os.path.exists(self.prefix): os.makedirs(self.prefix) self.load_act_scales = self.kwargs.get('LOAD_ACT_SCALES', False) @@ -155,33 +122,7 @@ def __init__(self, model: nn.Module, dataloaders, **kwargs): self.act_quant = self.kwargs.get('ACT_QUANT', True) self.head_stem_precision = self.kwargs.get('HEAD_STEM_PRECISION', None) - self.wandb_monitor = self.kwargs.get('WANDB', 'False') - self.dataset_name = dataloaders['train'].dataset.__class__.__name__ - self.save = './checkpoints/' - - self.name = '_'.join([ - self.dataset_name, - str(self.a_bits), - datetime.now().strftime('%b-%d_%H:%M:%S'), - ]) - - os.makedirs(f'{os.getcwd()}/logs/BitSplit', exist_ok=True) - os.makedirs(self.save, exist_ok=True) - self.logger_file = f'{os.getcwd()}/logs/BitSplit/{self.name}.log' - - logging.basicConfig( - filename=self.logger_file, - format='%(asctime)s - %(levelname)s - %(name)s - %(message)s', - datefmt='%m/%d/%Y %H:%M:%S', - level=logging.INFO, - ) - - logger.info(f'Experiment Arguments: {self.kwargs}') - - if self.wandb_monitor: - wandb.init(project='Trailmet BitSplit', name=self.name) - wandb.config.update(self.kwargs) - + def compress_model(self): self.model.to(self.device) self.qmodel = copy.deepcopy(self.model) @@ -195,378 +136,200 @@ def compress_model(self): self.act_quant_modules[-1].set_bitwidth(max(8, self.a_bits)) assert self.arch in ['MobileNetV2', 'ResNet50'] - print('==> Starting weight quantization') - logger.info('==> Starting weight quantization') + print("==> Starting weight quantization") self.weight_quantizer(load_only=self.load_weight_scales) if self.act_quant: if self.load_act_scales: - scales = np.load(self.prefix + '/act_' + str(self.a_bits) + - '_scales.npy') + scales = np.load(self.prefix+'/act_'+str(self.a_bits)+'_scales.npy') for index, q_module in enumerate(self.act_quant_modules): q_module.set_scale(scales[index]) else: - print("==> Starting '{}-bit' activation quantization".format( - self.a_bits)) - logger.info( - "==> Starting '{}-bit' activation quantization".format( - self.a_bits)) - self.act_quantizer(self.qmodel, - prefix=self.prefix, - n_batches=self.calib_batches) - - save_checkpoint( - { - 'state_dict': self.qmodel.module.state_dict(), - }, - is_best=False, - save=self.save, - ) - # save_state_dict(self.qmodel.state_dict(), self.prefix, filename='state_dict.pth') - - print('testing quantized model') - logger.info('testing quantized model') - - val_top1_acc_list = [] - val_top5_acc_list = [] - - valid_loss, valid_top1_acc, valid_top5_acc = self.test( - self.qmodel, self.dataloaders['val'], nn.CrossEntropyLoss()) - val_top1_acc_list.append(valid_top1_acc.cpu().numpy()) - val_top5_acc_list.append(valid_top5_acc.cpu().numpy()) - - df_data = np.array([ - val_top1_acc_list, - val_top5_acc_list, - ]).T - df = pd.DataFrame( - df_data, - columns=[ - 'Validation Top1', - 'Validation Top5', - ], - ) - df.to_csv( - f'{os.getcwd()}/logs/BitSplit/{self.name}.csv', - index=False, - ) - - # TODO : Use functions to process submodules of respective models so that adding new models in future is easier + print("==> Starting '{}-bit' activation quantization".format(self.a_bits)) + self.act_quantizer(self.qmodel, prefix=self.prefix, n_batches=self.calib_batches) + save_state_dict(self.qmodel.state_dict(), self.prefix, filename='state_dict.pth') + return self.qmodel + + +# TODO : Use functions to process submodules of respective models so that adding new models in future is easier def weight_quantizer(self, load_only=False): - """Find optimum weight quantization scales for ResNet & Mobilenet.""" + """ + Find optimum weight quantization scales for ResNet & Mobilenet + """ #### Quantizer for MobilenetV2 #### - if self.arch == 'MobileNetV2': + if self.arch=='MobileNetV2': count = 3 for i in range(len(self.model.layers)): - if len(self.model.layers[i].shortcut) > 0: - count += 4 - else: - count += 3 + if len(self.model.layers[i].shortcut)>0: count+=4 + else: count+=3 pbar = tqdm(total=count) - layer_to_block = [ - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4 - ] - assert (len(self.precision_config) == 0 or len( - self.precision_config) == 7), 'config list must be of length 7' + layer_to_block = [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,4] + assert len(self.precision_config)==0 or len(self.precision_config)==7, 'config list must be of length 7' # quantize first conv layer conv = self.model.conv1 conv_quan = self.qmodel.conv1 w_bit = self.w_bits - if self.head_stem_precision is not None: - w_bit = self.head_stem_precision - if self.precision_config: - w_bit = self.precision_config[0] + if self.head_stem_precision is not None: w_bit = self.head_stem_precision + if self.precision_config: w_bit = self.precision_config[0] if w_bit == 32: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=self.prefix + '/conv1', - device=self.device, - ec=False, - ) - load_ofwa(conv, conv_quan, prefix=self.prefix + '/conv1') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=self.prefix+'/conv1', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=self.prefix+'/conv1') pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # quantize blocks for layer_idx in range(len(self.model.layers)): current_layer_pretrained = self.model.layers[layer_idx] current_layer_quan = self.qmodel.layers[layer_idx] - w_bit = (self.precision_config[layer_to_block[layer_idx]] - if self.precision_config else self.w_bits) - skip = w_bit == 32 - pkl_path = self.prefix + '/layer' + str(layer_idx) + w_bit = self.precision_config[layer_to_block[layer_idx]] if self.precision_config else self.w_bits + skip = (w_bit==32) + pkl_path = self.prefix+'/layer'+str(layer_idx) # conv layers - for idx in range(1, 4): + for idx in range(1,4): conv = eval('current_layer_pretrained.conv{}'.format(idx)) conv_quan = eval('current_layer_quan.conv{}'.format(idx)) if skip: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=pkl_path + '_conv{}'.format(idx), - device=self.device, - dw=(idx == 2), - ec=False, - ) - load_ofwa(conv, - conv_quan, - prefix=pkl_path + '_conv' + str(idx)) + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, + w_bit, self.calib_batches, prefix=pkl_path+'_conv{}'.format(idx), + device=self.device, dw=(idx==2), ec=False) + load_ofwa(conv, conv_quan, prefix=pkl_path+'_conv'+str(idx)) pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # shortcut layer - if len(current_layer_pretrained.shortcut) > 0: + if len(current_layer_pretrained.shortcut)>0: conv = current_layer_pretrained.shortcut[0] conv_quan = current_layer_quan.shortcut[0] if skip: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=pkl_path + '_shortcut'.format(idx), - device=self.device, - ec=False, - ) - load_ofwa(conv, - conv_quan, - prefix=pkl_path + '_shortcut') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=pkl_path+'_shortcut'.format(idx), device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=pkl_path+'_shortcut') pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # quantize last conv layer conv = self.model.conv2 conv_quan = self.qmodel.conv2[1] - if self.precision_config: - w_bit = self.precision_config[-2] - if w_bit == 32: + if self.precision_config: w_bit = self.precision_config[-2] + if w_bit==32: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=self.prefix + '/conv2', - device=self.device, - ec=False, - ) - load_ofwa(conv, conv_quan, prefix=self.prefix + '/conv2') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=self.prefix+'/conv2', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=self.prefix+'/conv2') pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # quantize last linear layer conv = self.model.linear conv_quan = self.qmodel.linear[1] w_bit = self.w_bits - if self.head_stem_precision is not None: - w_bit = self.head_stem_precision - if self.precision_config: - w_bit = self.precision_config[-1] + if self.head_stem_precision is not None: w_bit = self.head_stem_precision + if self.precision_config: w_bit = self.precision_config[-1] if w_bit == 32: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=self.prefix + '/linear', - device=self.device, - ec=False, - ) - load_ofwa(conv, conv_quan, prefix=self.prefix + '/linear') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=self.prefix+'/linear', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=self.prefix+'/linear') pbar.update(1) pbar.close() - #### Quantizer for Resnet50 #### - elif self.arch == 'ResNet50': + #### Quantizer for Resnet50 #### + elif self.arch=='ResNet50': count = 2 - for i in range(1, 5): + for i in range(1,5): layer = eval('self.model.layer{}'.format(i)) for j in range(len(layer)): - count += 3 - if layer[j].downsample is not None: - count += 1 + count+=3 + if(layer[j].downsample is not None): count+=1 pbar = tqdm(total=count) - # quantize first conv layer + # quantize first conv layer conv = self.model.conv1 conv_quan = self.qmodel.conv1 w_bit = self.w_bits - if self.head_stem_precision is not None: - w_bit = self.head_stem_precision - if self.precision_config: - w_bit = self.precision_config[0] - if w_bit == 32: + if self.head_stem_precision is not None: w_bit = self.head_stem_precision + if self.precision_config: w_bit = self.precision_config[0] + if w_bit==32: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=self.prefix + '/conv1', - device=self.device, - ec=False, - ) - load_ofwa(conv, conv_quan, prefix=self.prefix + '/conv1') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=self.prefix+'/conv1', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=self.prefix+'/conv1') pbar.update(1) - time.sleep(0.1) - # quantize blocks + time.sleep(.1) + # quantize blocks for layer_idx in range(1, 5): - current_layer_pretrained = eval( - 'self.model.layer{}'.format(layer_idx)) - current_layer_quan = eval( - 'self.qmodel.layer{}'.format(layer_idx)) - w_bit = (self.precision_config[layer_idx] - if self.precision_config else self.w_bits) - skip = w_bit == 32 + current_layer_pretrained = eval('self.model.layer{}'.format(layer_idx)) + current_layer_quan = eval('self.qmodel.layer{}'.format(layer_idx)) + w_bit = self.precision_config[layer_idx] if self.precision_config else self.w_bits + skip = w_bit==32 for block_idx in range(len(current_layer_pretrained)): - current_block_pretrained = current_layer_pretrained[ - block_idx] + current_block_pretrained = current_layer_pretrained[block_idx] current_block_quan = current_layer_quan[block_idx] - pkl_path = (self.prefix + '/layer' + str(layer_idx) + - '_block' + str(block_idx)) + pkl_path = self.prefix+'/layer'+str(layer_idx)+'_block'+str(block_idx) # conv layers for idx in range(1, 4): - conv = eval( - 'current_block_pretrained.conv{}'.format(idx)) - conv_quan = eval( - 'current_block_quan.conv{}'.format(idx)) + conv = eval('current_block_pretrained.conv{}'.format(idx)) + conv_quan = eval('current_block_quan.conv{}'.format(idx)) if skip: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=pkl_path + '_conv{}'.format(idx), - device=self.device, - ec=False, - ) - load_ofwa(conv, - conv_quan, - prefix=pkl_path + '_conv' + str(idx)) + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=pkl_path+'_conv{}'.format(idx), device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=pkl_path+'_conv'+str(idx)) pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # downsample if current_block_pretrained.downsample is not None: conv = current_block_pretrained.downsample[0] conv_quan = current_block_quan.downsample[0] if skip: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=pkl_path + '_downsample', - device=self.device, - ec=False, - ) - load_ofwa(conv, - conv_quan, - prefix=pkl_path + '_downsample') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=pkl_path+'_downsample', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=pkl_path+'_downsample') pbar.update(1) - time.sleep(0.1) + time.sleep(.1) # quantize last fc layer conv = self.model.fc conv_quan = self.qmodel.fc[1] w_bit = self.w_bits - if self.head_stem_precision is not None: - w_bit = self.head_stem_precision - if self.precision_config: - w_bit = self.precision_config[-1] - if w_bit == 32: + if self.head_stem_precision is not None: w_bit = self.head_stem_precision + if self.precision_config: w_bit = self.precision_config[-1] + if w_bit==32: conv_quan.weight.data.copy_(conv.weight.data) - else: - if not load_only: - conduct_ofwa( - self.train_loader, - self.model, - self.qmodel, - conv, - conv_quan, - w_bit, - self.calib_batches, - prefix=self.prefix + '/fc', - device=self.device, - ec=False, - ) - load_ofwa(conv, conv_quan, prefix=self.prefix + '/fc') + else: + if not load_only: conduct_ofwa(self.train_loader, self.model, self.qmodel, conv, conv_quan, w_bit, + self.calib_batches, prefix=self.prefix+'/fc', device=self.device, ec=False) + load_ofwa(conv, conv_quan, prefix=self.prefix+'/fc') pbar.update(1) pbar.close() - else: - raise NotImplementedError + else: raise NotImplementedError - # TODO : Write this in a more cleaner way +# TODO : Write this in a more cleaner way def act_quantizer(self, model, prefix, n_batches): - """Find optimum activation quantization scale for ResNet model based on - feature map.""" - + """ + Find optimum activation quantization scale for ResNet model based on feature map + """ # train_batches = iter(self.train_loader) # per_batch = len(next(train_batches)[1]) # act_sta_len = (n_batches+1)*per_batch def get_safe_len(x): - x /= 10 - y = 1 - while x >= 10: - x /= 10 - y *= 10 - return int(y) - + x/=10 + y=1 + while(x>=10): + x/=10 + y*=10 + return int(y) act_sta_len = 3000000 feat_buf = np.zeros(act_sta_len) scales = np.zeros(len(self.act_quant_modules)) - - pbar = tqdm( - self.act_quant_modules, - desc= - 'Activation quantization, q_module [X] (X / X Steps) (prev_layer_scale=X.X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - disable=False, - ) + + pbar = tqdm(self.act_quant_modules, total=len(self.act_quant_modules)) with torch.no_grad(): for index, q_module in enumerate(pbar): batch_iterator = iter(self.train_loader) @@ -578,138 +341,58 @@ def get_safe_len(x): model(images) feat_len = feat.size per_batch = min(get_safe_len(feat_len), 100000) - n_batches = int(act_sta_len / per_batch) + n_batches = int(act_sta_len/per_batch) repeat = True - while repeat: + while(repeat): repeat = False for batch_idx in range(0, n_batches): - pbar.set_description( - 'Activation quantization, q_module [%d] (%d / %d Steps) (prev_layer_scale=%2.5f)' - % ( - index, - batch_idx + 1, - n_batches, - scales[index - 1], - )) + pbar.set_postfix(batch=f'{batch_idx+1}/{n_batches}', prev_layer_scale=scales[index-1]) images, targets = next(batch_iterator) - images = images.cuda(device=self.device, - non_blocking=True) + images = images.cuda(device=self.device, non_blocking=True) model(images) if q_module.signed: feat_tmp = np.abs(feat).reshape(-1) else: - feat_tmp = feat[feat > 0].reshape(-1) + feat_tmp = feat[feat>0].reshape(-1) if feat_tmp.size < per_batch: - per_batch = int(per_batch / 10) - n_batches = int(n_batches * 10) + per_batch = int(per_batch/10) + n_batches = int(n_batches*10) repeat = True break np.random.shuffle(feat_tmp) - feat_buf[batch_idx * per_batch:(batch_idx + 1) * - per_batch] = feat_tmp[0:per_batch] - if not repeat: + feat_buf[batch_idx*per_batch:(batch_idx+1)*per_batch] = feat_tmp[0:per_batch] + if(not repeat): scales[index] = q_module.init_quantization(feat_buf) handle.remove() + # for batch_idx in range(0, n_batches): + # images, targets = next(batch_iterator) + # images = images.cuda(device=self.device, non_blocking=True) + # model(images) + # if q_module.signed: + # feat_tmp = np.abs(feat).reshape(-1) + # else: + # feat_tmp = feat[feat>0].reshape(-1) + # np.random.shuffle(feat_tmp) + # feat_buf[batch_idx*per_batch:(batch_idx+1)*per_batch] = feat_tmp[0:per_batch] + + # scales[index] = q_module.init_quantization(feat_buf) + # pbar.set_postfix(curr_layer_scale=scales[index]) + # np.save(os.path.join(prefix, 'act_'+str(self.a_bits)+'_scales.npy'), scales) + # handle.remove() + pbar.close() - np.save( - os.path.join(prefix, 'act_' + str(self.a_bits) + '_scales.npy'), - scales) + np.save(os.path.join(prefix, 'act_' + str(self.a_bits) + '_scales.npy'), scales) for index, q_module in enumerate(self.act_quant_modules): q_module.set_scale(scales[index]) - def test(self, model, dataloader, loss_fn): - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - - epoch_iterator = tqdm( - dataloader, - desc= - 'Validating network (X / X Steps) (batch time=X.Xs) (loss=X.X) (top1=X.X) (top5=X.X)', - bar_format='{l_bar}{r_bar}', - dynamic_ncols=True, - disable=False, - ) - model.eval() - model.to(self.device) - - with torch.no_grad(): - end = time.time() - - for i, (images, labels) in enumerate(epoch_iterator): - images = images.to(self.device, dtype=torch.float) - labels = labels.to(self.device) - - preds = model(images) - - loss = loss_fn(preds, labels) - - pred1, pred5 = accuracy(preds, labels, topk=(1, 5)) - - n = images.size(0) - losses.update(loss.item(), n) - top1.update(pred1[0], n) - top5.update(pred5[0], n) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - epoch_iterator.set_description( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - logger.info( - 'Validating network (%d / %d Steps) (batch time=%2.5fs) (loss=%2.5f) (top1=%2.5f) (top5=%2.5f)' - % ( - (i + 1), - len(dataloader), - batch_time.val, - losses.val, - top1.val, - top5.val, - )) - - if self.wandb_monitor: - wandb.log({ - 'val_loss': losses.val, - 'val_top1_acc': top1.val, - 'val_top5_acc': top5.val, - }) - - print(' * acc@1 {top1.avg:.3f} acc@5 {top5.avg:.3f}'.format( - top1=top1, top5=top5)) - return losses.avg, top1.avg, top5.avg - - -def conduct_ofwa( - train_loader, - model_pretrained, - model_quan, - conv, - conv_quan, - bitwidth, - n_batches, - device, - num_epochs=100, - prefix=None, - dw=False, - ec=False, -): +def conduct_ofwa(train_loader, model_pretrained, model_quan, conv, conv_quan, + bitwidth, n_batches, device, num_epochs=100, prefix=None, dw=False, ec=False): # for fc if not hasattr(conv, 'kernel_size'): - W = conv.weight.data # .cpu() + W = conv.weight.data#.cpu() W_shape = W.shape B_sav, B, alpha = BitSplitQuantizer(W.cpu().numpy(), bitwidth).ofwa() # B_sav, B, alpha = ofwa(W.cpu().numpy(), bitwidth) @@ -731,11 +414,11 @@ def conduct_ofwa( batch_iterator = iter(train_loader) # weights and bias - W = conv.weight.data # .cpu() + W = conv.weight.data#.cpu() if conv.bias is None: bias = torch.zeros(W.shape[0]).to(conv.weight.device) else: - bias = conv.bias.data # .cpu() + bias = conv.bias.data#.cpu() # feat extract per_batch = 400 @@ -747,9 +430,8 @@ def conduct_ofwa( [prev_feat_n, prev_feat_c, prev_feat_h, prev_feat_w] = prev_feat.shape [conv_feat_n, conv_feat_c, conv_feat_h, conv_feat_w] = conv_feat.shape - X = torch.zeros(n_batches * per_batch, prev_feat_c, kernel_h, - kernel_w).to(device) - Y = torch.zeros(n_batches * per_batch, conv_feat_c).to(device) + X = torch.zeros(n_batches*per_batch, prev_feat_c, kernel_h, kernel_w).to(device) + Y = torch.zeros(n_batches*per_batch, conv_feat_c).to(device) for batch_idx in range(0, n_batches): input, target = next(batch_iterator) @@ -757,52 +439,34 @@ def conduct_ofwa( model_pretrained(input_pretrained) input_quan = input.cuda(device=device, non_blocking=True) model_quan(input_quan) - - prev_feat_pad = torch.zeros(prev_feat_n, prev_feat_c, - prev_feat_h + 2 * pad_h, - prev_feat_w + 2 * pad_w).to(device) - prev_feat_pad[:, :, pad_h:pad_h + prev_feat_h, - pad_w:pad_w + prev_feat_w] = prev_feat - prev_feat_pad = (prev_feat_pad.unfold(2, kernel_h, stride_h).unfold( - 3, kernel_w, stride_w).permute(0, 2, 3, 1, 4, 5)) - [ - feat_pad_n, - feat_pad_h, - feat_pad_w, - feat_pad_c, - feat_pad_hh, - feat_pad_ww, - ] = prev_feat_pad.shape - assert feat_pad_hh == kernel_h - assert feat_pad_ww == kernel_w - - prev_feat_pad = prev_feat_pad.reshape( - feat_pad_n * feat_pad_h * feat_pad_w, feat_pad_c, kernel_h, - kernel_w) + + prev_feat_pad = torch.zeros(prev_feat_n, prev_feat_c, prev_feat_h+2*pad_h, prev_feat_w+2*pad_w).to(device) + prev_feat_pad[:, :, pad_h:pad_h+prev_feat_h, pad_w:pad_w+prev_feat_w] = prev_feat + prev_feat_pad = prev_feat_pad.unfold(2, kernel_h, stride_h).unfold(3, kernel_w, stride_w).permute(0,2,3,1,4,5) + [feat_pad_n, feat_pad_h, feat_pad_w, feat_pad_c, feat_pad_hh, feat_pad_ww] = prev_feat_pad.shape + assert(feat_pad_hh==kernel_h) + assert(feat_pad_ww==kernel_w) + + prev_feat_pad = prev_feat_pad.reshape(feat_pad_n*feat_pad_h*feat_pad_w, feat_pad_c, kernel_h, kernel_w) rand_index = list(range(prev_feat_pad.shape[0])) random.shuffle(rand_index) rand_index = rand_index[0:per_batch] - X[per_batch * batch_idx:per_batch * - (batch_idx + 1), :] = prev_feat_pad[rand_index, :] - conv_feat_tmp = conv_feat.permute(0, 2, 3, 1).reshape( - -1, conv_feat_c) - bias - Y[per_batch * batch_idx:per_batch * - (batch_idx + 1), :] = conv_feat_tmp[rand_index, :] - + X[per_batch*batch_idx:per_batch*(batch_idx+1),:] = prev_feat_pad[rand_index, :] + conv_feat_tmp = conv_feat.permute(0,2,3,1).reshape(-1, conv_feat_c) - bias + Y[per_batch*batch_idx:per_batch*(batch_idx+1),:] = conv_feat_tmp[rand_index, :] + handle_prev.remove() handle_conv.remove() - + ## ofwa init W_shape = W.shape X = X.cpu().numpy() Y = Y.cpu().numpy() W = W.reshape(W_shape[0], -1) if dw: - B, alpha = BitSplitQuantizer(W.cpu().numpy(), - bitwidth).ofwa_rr_dw(X, Y, num_epochs) - else: - B, alpha = BitSplitQuantizer(W.cpu().numpy(), - bitwidth).ofwa_rr(X, Y, num_epochs) + B, alpha = BitSplitQuantizer(W.cpu().numpy(), bitwidth).ofwa_rr_dw(X, Y, num_epochs) + else: + B, alpha = BitSplitQuantizer(W.cpu().numpy(), bitwidth).ofwa_rr(X, Y, num_epochs) with open(prefix + '_rr_b30x400_e100.pkl', 'wb') as f: pickle.dump({'B': B, 'alpha': alpha}, f, pickle.HIGHEST_PROTOCOL) @@ -810,7 +474,7 @@ def conduct_ofwa( def load_ofwa(conv, conv_quan, prefix=None): # for fc if not hasattr(conv, 'kernel_size'): - W = conv.weight.data # .cpu() + W = conv.weight.data#.cpu() W_shape = W.shape with open(prefix + '_fwa.pkl', 'rb') as f: B_alpha = pickle.load(f) @@ -821,7 +485,7 @@ def load_ofwa(conv, conv_quan, prefix=None): return # weights and bias - W = conv.weight.data # .cpu() + W = conv.weight.data#.cpu() W_shape = W.shape with open(prefix + '_rr_b30x400_e100.pkl', 'rb') as f: @@ -837,8 +501,7 @@ def save_state_dict(state_dict, path, filename='state_dict.pth'): new_state_dict = OrderedDict() for key in state_dict.keys(): if '.module.' in key: - new_state_dict[key.replace('.module.', - '.')] = state_dict[key].cpu() + new_state_dict[key.replace('.module.', '.')] = state_dict[key].cpu() else: new_state_dict[key] = state_dict[key].cpu() - torch.save(new_state_dict, saved_path) + torch.save(new_state_dict, saved_path) \ No newline at end of file From a0597b8b8fdc79d4daeea041d235e4376252d9f3 Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:55:23 +0530 Subject: [PATCH 09/35] added qconfig helpers --- trailmet/algorithms/quantize/utils.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/trailmet/algorithms/quantize/utils.py b/trailmet/algorithms/quantize/utils.py index 92d57bf..8c58b73 100644 --- a/trailmet/algorithms/quantize/utils.py +++ b/trailmet/algorithms/quantize/utils.py @@ -21,8 +21,50 @@ # SOFTWARE. import os +import torch from plotly import graph_objects +__all__ = [ + 'get_qscheme', + 'get_dtype', + 'replace_activation_with_identity', + 'StopForwardException', + 'DataSaverHook', + 'GradSaverHook', + 'LinearTempDecay' + 'Node', + 'GraphPlotter' +] + +def get_qscheme(per_channel=False, symmetric=False): + if per_channel and symmetric: + return torch.per_channel_symmetric + elif per_channel and not symmetric: + return torch.per_channel_affine + elif not per_channel and symmetric: + return torch.per_tensor_symmetric + else: + return torch.per_tensor_affine + +def get_dtype(quant_min: int, quant_max: int): + # bit capacity for qint and quint is reduced by 1 for 'x86' backend + if quant_min>=0 and quant_max<=127: + return torch.quint8 + elif quant_min>=-64 and quant_max<=63: + return torch.qint8 + else: + return torch.qint32 + +def replace_activation_with_identity(module: torch.nn.Module, activations: list) -> None: + reassign = {} + for name, child_module in module.named_children(): + replace_activation_with_identity(child_module, activations) + for activation in activations: + if isinstance(child_module, activation): + reassign[name] = torch.nn.Identity() + for key, value in reassign.items(): + module._modules[key] = value + class StopForwardException(Exception): """ Used to throw and catch an exception to stop traversing the graph. From c7e7e2d06e0475d27ba1710d66efd99d81cb553b Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:56:23 +0530 Subject: [PATCH 10/35] added temp torch.ao.quantizer modules --- trailmet/algorithms/quantize/nnq/__init__.py | 0 .../algorithms/quantize/nnq/convert_model.py | 130 ++++++++++++++++++ .../algorithms/quantize/nnq/resnet_modules.py | 80 +++++++++++ 3 files changed, 210 insertions(+) create mode 100644 trailmet/algorithms/quantize/nnq/__init__.py create mode 100644 trailmet/algorithms/quantize/nnq/convert_model.py create mode 100644 trailmet/algorithms/quantize/nnq/resnet_modules.py diff --git a/trailmet/algorithms/quantize/nnq/__init__.py b/trailmet/algorithms/quantize/nnq/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trailmet/algorithms/quantize/nnq/convert_model.py b/trailmet/algorithms/quantize/nnq/convert_model.py new file mode 100644 index 0000000..2868631 --- /dev/null +++ b/trailmet/algorithms/quantize/nnq/convert_model.py @@ -0,0 +1,130 @@ +import copy +from typing import Dict, Callable, Any +from torch import nn as nn +from torch.nn.utils.parametrize import type_before_parametrizations as _type +from torch.ao.nn import quantized as nnq +from torch.ao.nn import intrinsic as nni +from torch.ao.nn.intrinsic import quantized as nniq +from torch.ao.nn.intrinsic.modules.fused import _FusedModule +from torch.ao.quantization.stubs import QuantStub, DeQuantStub + +DEFAULT_STATIC_QUANT_MODULE_MAPPING: Dict[Callable, Callable] = { + QuantStub: nnq.Quantize, + DeQuantStub: nnq.DeQuantize, + nn.BatchNorm2d: nnq.BatchNorm2d, + nn.Dropout: nnq.Dropout, + nn.Conv2d: nnq.Conv2d, + nn.Linear: nnq.Linear, + nn.ReLU6: nnq.ReLU6, + nn.LeakyReLU: nnq.LeakyReLU, + # Wrapper Modules: + nnq.FloatFunctional: nnq.QFunctional, + # Intrinsic modules: + nni.BNReLU2d: nniq.BNReLU2d, + nni.ConvReLU2d: nniq.ConvReLU2d, + nni.ConvAdd2d: nniq.ConvAdd2d, + nni.ConvAddReLU2d: nniq.ConvAddReLU2d, + nni.LinearReLU: nniq.LinearReLU, + nni.LinearLeakyReLU: nniq.LinearLeakyReLU, +} + +def get_qparam_dict(observer): + qparams = dict() + qparams["qscheme"] = getattr(observer, "qscheme", None) + qparams["dtype"] = observer.dtype + qparams["scale"], qparams["zero_point"] = observer.calculate_qparams() + if hasattr(observer, "quant_min"): + qparams["quant_min"] = observer.quant_min + if hasattr(observer, "quant_max"): + qparams["quant_max"] = observer.quant_max + return qparams + + +def _observer_forward_hook(self, input, output): + """forward hook that calls observer on the output""" + return self.activation_post_process(output) + +def _observer_forward_pre_hook(self, input): + r"""Forward pre hook that calls observer on the input + """ + return self.activation_post_process(input[0]) + + +def _remove_qconfig(module): + for child_module in module.children(): + _remove_qconfig(child_module) + + if hasattr(module, 'qconfig'): + del module.qconfig + + if hasattr(module, 'activation_post_process'): + del module.activation_post_process + + + +def convert_model(model, inplace=True, remove_qconfig=True): + if not inplace: + model = copy.deepcopy(model) + mapping = DEFAULT_STATIC_QUANT_MODULE_MAPPING + _convert(model, mapping, inplace) + if remove_qconfig: + _remove_qconfig(model) + return model + +def _replace_relu(module: nn.Module) -> None: + """replace all ReLU6 with ReLU""" + reassign = {} + for name, child_module in module.named_children(): + _replace_relu(child_module) + if type(child_module) is nn.ReLU or type(child_module) is nn.ReLU6: + reassign[name] = nn.ReLU(inplace=False) + + for key, value in reassign.items(): + module._modules[key] = value + +def _convert(module: nn.Module, mapping, inplace=True): + """recursively convert modules to their quantized counterparts""" + if not inplace: + module = copy.deepcopy(module) + reassign = {} + for name, child_module in module.named_children(): + if not isinstance(child_module, _FusedModule): # fused modules are swapped as one unit + _convert(child_module, mapping, True) + reassign[name] = swap_module(child_module, mapping) + + for name, quantized_module in reassign.items(): + module._modules[name] = quantized_module + + return module + + +def swap_module(module, mapping): + """ + swaps the module if it has a quantized counterpart and + if it has an `observer` attached. + Args: + module: input module + mapping: a dict that maps from nn/nni module to nnq/nniq module + Return: + corresponding quantized counterpart of `module` + """ + new_module = module + + if hasattr(module, 'qconfig') and module.qconfig is not None: + swapped = False + if _type(module) in mapping: + qmod = mapping[_type(module)] + new_module = qmod.from_float(module) + swapped = True + + if swapped: + # Preserve module's pre forward hooks. They'll be called on quantized input + for pre_hook_fn in module._forward_pre_hooks.values(): + new_module.register_forward_pre_hook(pre_hook_fn) + # Preserve module's post forward hooks except _observer_forward_hook + # After convert they'll work with quantized output + for hook_fn in module._forward_hooks.values(): + if hook_fn is not _observer_forward_hook: + new_module.register_forward_hook(hook_fn) + + return new_module diff --git a/trailmet/algorithms/quantize/nnq/resnet_modules.py b/trailmet/algorithms/quantize/nnq/resnet_modules.py new file mode 100644 index 0000000..de98836 --- /dev/null +++ b/trailmet/algorithms/quantize/nnq/resnet_modules.py @@ -0,0 +1,80 @@ +from typing import Any, Optional, Union, List +from torch import nn, Tensor +from torch.ao.nn import quantized as nnq +from torch.ao.quantization import fuse_modules, fuse_modules_qat, \ + QuantStub, DeQuantStub +from torchvision.models.resnet import BasicBlock, Bottleneck, ResNet + + +def _fuse_modules(model: nn.Module, modules_to_fuse: Union[List[str], List[List[str]]], + is_qat: Optional[bool], **kwargs: Any): + if is_qat is None: + is_qat = model.training + fuse_method = fuse_modules_qat if is_qat else fuse_modules + return fuse_method(model, modules_to_fuse, **kwargs) + +class QBottleneck(Bottleneck): + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.skip_add_relu = nnq.FloatFunctional() + self.relu1 = nn.ReLU(inplace=False) + self.relu2 = nn.ReLU(inplace=False) + + def forward(self, x: Tensor) -> Tensor: + indentity = x + out = self.conv1(x) + out = self.bn1(out) + out = self.relu1(out) + out = self.conv2(out) + out = self.bn2(out) + out = self.relu2(out) + + out = self.conv3(out) + out = self.bn3(out) + + if self.downsample is not None: + identity = self.downsample(x) + out = self.skip_add_relu.add_relu(out, identity) + + return out + + def fuse_model(self, is_qat: Optional[bool] = None) -> None: + _fuse_modules(self, + [["conv1", "bn1", "relu1"], + ["conv2", "bn2", "relu2"], + ["conv3", "bn3"]], + is_qat, + inplace=True + ) + if self.downsample: + _fuse_modules(self.downsample, + ["0", "1"], + is_qat, + inplace=True + ) + + class QResNet(ResNet): + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.quant = QuantStub() + self.dequant = DeQuantStub() + + def forward(self, x: Tensor) -> Tensor: + x = self.quant(x) + x = self._forward_impl(x) + x = self.dequant(x) + return x + + def fuse_model(self, is_qat: Optional[bool] = None) -> None: + """ + Fuse conv+bn+relu / conv+bn / conv+relu modules + to prepare for quantization + """ + _fuse_modules(self, + ["conv1", "bn1", "relu"], + is_qat, + inplace = True + ) + for module in self.modules(): + if type(module)==QBottleneck: + module.fuse_model() \ No newline at end of file From 2d7e239339ff017038e213aa148701e9a0bc071e Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:57:07 +0530 Subject: [PATCH 11/35] updated quant model with bn act fusion --- trailmet/algorithms/quantize/quantize.py | 128 ++++++++++++++++------- 1 file changed, 89 insertions(+), 39 deletions(-) diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index a459dc8..89f11db 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -24,16 +24,26 @@ import torch import torch.nn as nn import torch.nn.functional as F +import torch.ao.nn.intrinsic as nni from tqdm import tqdm from typing import Union from trailmet.models.resnet import BasicBlock, Bottleneck from trailmet.models.mobilenet import InvertedResidual from trailmet.algorithms.quantize.utils import StopForwardException, DataSaverHook, GradSaverHook -from trailmet.algorithms.quantize.utils import LinearTempDecay, Node, GraphPlotter +from trailmet.algorithms.quantize.utils import LinearTempDecay, Node, GraphPlotter, replace_activation_with_identity from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, BaseQuantBlock from trailmet.algorithms.quantize.modules import QuantBasicBlock, QuantBottleneck, QuantInvertedResidual from trailmet.algorithms.algorithms import BaseAlgorithm +from torch.ao.quantization.stubs import QuantStub, DeQuantStub +from torch.ao.quantization.fuse_modules import fuse_modules +__all__ = [ + 'BaseQuantModel', + 'BaseQuantization', + 'BaseQuantLoss', + 'GetLayerInpOut', + 'GetLayerGrad' +] supported = { BasicBlock: QuantBasicBlock, @@ -44,33 +54,59 @@ class BaseQuantModel(nn.Module): """base model wrapping class for quantization algorithms""" def __init__(self, model: nn.Module, weight_quant_params: dict = {}, - act_quant_params: dict = {}, fold_bn = True): + act_quant_params: dict = {}, inplace = False, fuse_model=True): super().__init__() - self.model = copy.deepcopy(model) + if not inplace: + self.model = copy.deepcopy(model) + else: + self.model = model self.weight_quant_params = weight_quant_params self.act_quant_params = act_quant_params - if fold_bn: - self.model.eval() - self.search_fold_remove_bn(self.model) + self.model.eval() + if not fuse_model: + self.search_fold_conv_bn(self.model) # Do Not Use + else: + replace_activation_with_identity(self.model, [nn.ReLU, nn.ReLU6]) + self.add_fused_conv_bn_act(self.model) + setattr(self.model, 'quant', QuantStub()) + setattr(self.model, 'dequant', DeQuantStub()) self.quant_module_refactor(self.model) self.quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] - - def search_fold_remove_bn(self, module: nn.Module): - """ - Recursively search for BatchNorm layers, fold them into the previous - Conv2d or Linear layers and set them as a StraightThrough layer. - """ - prev_module = None - for name, child_module in module.named_children(): - if self._is_bn(child_module) and self._is_absorbing(prev_module): - self._fold_bn_into_conv(prev_module, child_module) - setattr(module, name, StraightThrough()) - elif self._is_absorbing(child_module): - prev_module = child_module - else: - prev_module = self.search_fold_remove_bn(child_module) - return prev_module + def forward(self, x): + x = self.model.quant(x) #TODO check functionality + x = self.model._forward_impl(x) + x = self.model.dequant(x) + return x + + def add_fused_conv_bn_act(self, model: nn.Module): + # same functionality as torchvision.models.quantization.resnet.QuantizableResNet.fuse_model + setattr(model, "relu1", nn.ReLU(inplace=True)) + model.relu1.eval() + fuse_modules(model, ["conv1", "bn1", "relu1"], inplace=True) + for module in model.modules(): + if type(module) is BasicBlock: + setattr(module, "relu1", nn.ReLU(inplace=True)) + module.relu1.eval() + fuse_modules( + module, + [["conv1", "bn1", "relu1"], ["conv2", "bn2"]], + inplace=True + ) + if module.downsample is not None: + fuse_modules(module.downsample, ["0", "1"], inplace=True) + if type(module) is Bottleneck: + setattr(module, "relu1", nn.ReLU(inplace=True)) + setattr(module, "relu2", nn.ReLU(inplace=True)) + module.relu1.eval() + module.relu2.eval() + fuse_modules( + module, + [["conv1", "bn1", "relu1"], ["conv2", "bn2", "relu2"], ["conv3", "bn3"]], + inplace=True + ) + if module.downsample is not None: + fuse_modules(module.downsample, ["0", "1"], inplace=True) def quant_module_refactor(self, module: nn.Module): """ @@ -78,23 +114,23 @@ def quant_module_refactor(self, module: nn.Module): supported network blocks to their respective wrappers, to enable weight and activations quantization. """ - prev_quant_module: QuantModule = None + # prev_quant_module: QuantModule = None for name, child_module in module.named_children(): if type(child_module) in supported: setattr(module, name, supported[type(child_module)]( child_module, self.weight_quant_params, self.act_quant_params )) - elif isinstance(child_module, (nn.Conv2d, nn.Linear)): + elif isinstance(child_module, (nn.Conv2d, nni.ConvReLU2d, nn.Linear, nni.LinearReLU)): setattr(module, name, QuantModule( child_module, self.weight_quant_params, self.act_quant_params )) - prev_quant_module = getattr(module, name) - elif isinstance(child_module, (nn.ReLU, nn.ReLU6)): - if prev_quant_module is not None: - prev_quant_module.activation_function = child_module - else: - continue - elif isinstance(child_module, StraightThrough): + # prev_quant_module = getattr(module, name) + # elif isinstance(child_module, (nn.ReLU, nn.ReLU6)): + # if prev_quant_module is not None: + # prev_quant_module.activation_function = child_module + # else: + # continue + elif isinstance(child_module, (StraightThrough, nn.Identity, nn.ReLU)): continue else: self.quant_module_refactor(child_module) @@ -107,7 +143,7 @@ def set_quant_state(self, weight_quant: bool = True, act_quant: bool = True): """ for module in self.model.modules(): if isinstance(module, (QuantModule, BaseQuantBlock)): - module.set_quant_state(weight_quant, act_quant) + module.set_quantization_state(weight_quant, act_quant) def quantize_model_till(self, layer, act_quant: bool = False): """ @@ -117,7 +153,7 @@ def quantize_model_till(self, layer, act_quant: bool = False): self.set_quant_state(False, False) for name, module in self.model.named_modules(): if isinstance(module, (QuantModule, BaseQuantBlock)): - module.set_quant_state(True, act_quant) + module.set_quantization_state(True, act_quant) if module == layer: break @@ -127,13 +163,26 @@ def set_layer_precision(self, weight_bits: list, act_bit: int): :param act_bit: bitwidth for activations """ assert len(weight_bits)==len(self.quant_modules) - for idx, module in enumerate(self.quant_modules): + for idx, module in enumerate(self.quant_modules): module.weight_quantizer.bitwidth_refactor(weight_bits[idx]) if module is not self.quant_modules[-1]: module.act_quantizer.bitwidth_refactor(act_bit) - def forward(self, input): - return self.model(input) + def search_fold_conv_bn(self, module: nn.Module): + """ + Recursively search for BatchNorm layers, fold them into the previous + Conv2d or Linear layers and set them as a StraightThrough layer. + """ + prev_module = None + for name, child_module in module.named_children(): + if self._is_bn(child_module) and self._is_absorbing(prev_module): + self._fold_bn_into_conv(prev_module, child_module) + setattr(module, name, StraightThrough()) + elif self._is_absorbing(child_module): + prev_module = child_module + else: + prev_module = self.search_fold_conv_bn(child_module) + return prev_module def _is_bn(self, module): return isinstance(module, (nn.BatchNorm1d, nn.BatchNorm2d)) @@ -141,9 +190,10 @@ def _is_bn(self, module): def _is_absorbing(self, module): return isinstance(module, (nn.Conv2d, nn.Linear)) - def _fold_bn_into_conv(self, conv_module, bn_module): + def _fold_bn_into_conv(self, conv_module: nn.Conv2d, bn_module: nn.BatchNorm2d): + # same as torch.nn.utils.fusion.fuse_conv_bn_eval w, b = self._get_folded_params(conv_module, bn_module) - if conv_module.bias is None: + if conv_module.bias is None: conv_module.bias = nn.Parameter(b) else: conv_module.bias.data = b @@ -151,7 +201,7 @@ def _fold_bn_into_conv(self, conv_module, bn_module): bn_module.running_mean = bn_module.bias.data bn_module.running_var = bn_module.weight.data ** 2 - def _get_folded_params(self, conv_module, bn_module): + def _get_folded_params(self, conv_module: nn.Conv2d, bn_module: nn.BatchNorm2d): w = conv_module.weight.data y_mean = bn_module.running_mean y_var = bn_module.running_var From 3a4462ed951c5be8c31a14b855d4df1b2f84e4d7 Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:57:33 +0530 Subject: [PATCH 12/35] added new quantizer modules --- trailmet/algorithms/quantize/modules.py | 301 +++++++++++++++++++++--- 1 file changed, 267 insertions(+), 34 deletions(-) diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index 529be9c..652c0d0 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -27,6 +27,247 @@ from trailmet.models.resnet import BasicBlock, Bottleneck from trailmet.models.mobilenet import InvertedResidual from trailmet.algorithms.quantize.methods import UniformAffineQuantizer, ActQuantizer +from trailmet.algorithms.quantize.utils import get_qscheme, get_dtype +from torch.ao.quantization import QConfig, FixedQParamsObserver +import torch.ao.nn.quantized as nnq +import torch.ao.nn.intrinsic as nni + +__all__ = [ + 'StraightThrough', + 'QuantModule', + 'BaseQuantBlock', + 'QuantBasicblock', + 'QuantBottleneck', + 'QuantInvertedResidual', + # legacy modules soon to be phased out + 'QModule', + 'BaseQBlock', + 'QBasicblock' + 'QBottleneck', + 'QInvertedResidual', + '_QBasicBlock', + '_QBottleneck', + '_QInvertedResidual' +] + +class StraightThrough(nn.Module): + """ + Identity Layer, same as torch.nn.modules.linear.Identity + """ + def __int__(self, *args, **kwargs) -> None: + super().__init__() + + def forward(self, input: torch.Tensor) -> torch.Tensor: + return input + +class QuantModule(nn.Module): + """ + Wrapper Module to simulate fake quantization + """ + def __init__(self, + orig_module: Union[nni.ConvReLU2d, nn.Conv2d, nn.Linear], + weight_qparams: dict, act_qparams: dict, + ) -> None: + super().__init__() + self.orig_module = orig_module + if isinstance(orig_module, nni.modules.fused._FusedModule): + assert len(orig_module)==2 + if type(orig_module[0]) == nn.Conv2d: + self.fwd_kwargs = dict( + stride = orig_module[0].stride, + padding = orig_module[0].padding, + dilation = orig_module[0].dilation, + groups = orig_module[0].groups + ) + self.fwd_func = F.conv2d + elif type(orig_module[1]) == nn.Linear: + self.fwd_kwargs = dict() + self.fwd_func = F.linear + else: + raise NotImplementedError + + if type(orig_module[1]) == nn.ReLU: + self.fwd_post = F.relu + else: + raise NotImplementedError + + self.weight = orig_module[0].weight + self.orig_weight = orig_module[0].weight.data.clone() + self.bias = orig_module[0].bias + + if isinstance(orig_module, (nn.Conv2d, nn.Linear)): + if type(orig_module) == nn.Conv2d: + self.fwd_kwargs = dict( + stride = orig_module.stride, + padding = orig_module.padding, + dilation = orig_module.dilation, + groups = orig_module.groups + ) + self.fwd_func = F.conv2d + elif type(orig_module) == nn.Linear: + self.fwd_kwargs = dict() + self.fwd_func = F.linear + else: + raise NotImplementedError + + self.fwd_post = self.identity + + self.weight = orig_module.weight + self.orig_weight = orig_module.weight.data.clone() + self.bias = orig_module.bias + + self.use_weight_quant = False + self.use_act_quant = False + self.weight_quantizer = weight_qparams.get( + 'method', UniformAffineQuantizer)(**weight_qparams) + self.act_quantizer = act_qparams.get( + 'method', UniformAffineQuantizer)(**act_qparams) + + self.ignore_reconstruction = False + self.extra_repr = orig_module.extra_repr + + + def forward(self, input: torch.Tensor): + if self.use_weight_quant: + weight = self.weight_quantizer(self.weight) + bias = self.bias + else: + weight = self.orig_weight + bias = self.bias + out = self.fwd_func(input, weight, bias, **self.fwd_kwargs) + out = self.fwd_post(out) + if self.use_act_quant: + out = self.act_quantizer(out) + return out + + + def identity(self, x: torch.Tensor): + return x + + + def set_quantization_state(self, weight: bool = False, act: bool = False): + self.use_weight_quant = weight + self.use_act_quant = act + + + def get_quantization_parameters(self): + return { + 'weight': self.weight_quantizer.get_qparams(), #TODO + 'act': self.act_quantizer.get_qparams() #TODO + } + + +class BaseQuantBlock(nn.Module): + def __init__(self, act_quant_params: dict = {}) -> None: + super().__init__() + self.use_act_quant = False + self.act_quantizer = act_quant_params.get( + 'method', UniformAffineQuantizer)(**act_quant_params) + self.disable_fake_quantization = False + self.ignore_reconstruction = False + + def set_quantization_state(self, weight: bool = False, act: bool = False): + self.use_act_quant = act + for module in self.modules(): + if isinstance(module, QuantModule): + module.set_quantization_state(weight, act) + + def _convert_quant_modules_to_quantizable(self): + module_qparams = dict() + for name, module in self.named_children(): + if isinstance(module, QuantModule): + module_qparams[name] = module.get_quantization_parameters() + setattr(self, name, module.orig_module) #TODO: test it out + self._attach_qconfig_to_quantizable(module_qparams) + + def _attach_qconfig_to_quantizable(self, module_qparams: dict): + for name, qparams in module_qparams.items(): + fixed_qparam_obs = dict() + for type in ["weight", "act"]: + fixed_qparam_obs[type] = FixedQParamsObserver.with_args( + qscheme = get_qscheme( + per_channel=qparams[type]['per_channel'], + symmetric=qparams[type]['symmetric'] + ), + dtype = get_dtype( + quant_min=qparams[type]['quant_min'], + quant_max=qparams[type]['quant_max'] + ), + quant_min = qparams[type]['quant_min'], + quant_max = qparams[type]['quant_max'], + scale = qparams[type]['scale'], + zero_point = qparams[type]['zero_point'] + ) + if isinstance(eval(f"self.{name}"), nni.ConvReLU2d): # propagate qconfig + setattr(eval(f"self.{name}[0]"), "qconfig", QConfig( + weight=fixed_qparam_obs["weight"])) + + setattr(eval(f"self.{name}"), "qconfig", QConfig( + weight=fixed_qparam_obs["weight"], + activation=fixed_qparam_obs["act"] + )) + eval(f"self.{name}.add_module")( + "activation_post_process", + eval(f"self.{name}.qconfig.activation()") + ) + + +class QuantBasicBlock(BaseQuantBlock): + def __init__(self, act_quant_params: dict = {}) -> None: + super().__init__(act_quant_params) + + +class QuantBottleneck(BaseQuantBlock): + def __init__(self, bottleneck: Bottleneck, weight_qparams: dict, act_qparams: dict) -> None: + super().__init__(act_qparams) + # assuming all bn and relu are fused in conv + self.weight_qparams = weight_qparams + self.act_qparams = act_qparams + self.orig_module = bottleneck + self.quant_conv1 = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d + self.quant_conv2 = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d + self.quant_conv3 = QuantModule(bottleneck.conv3, weight_qparams, act_qparams) # ConvReLU2d + if bottleneck.downsample is not None: + self.quant_downsample = QuantModule(bottleneck.downsample[0], weight_qparams, act_qparams) # Conv2d + else: + self.quant_downsample = None + self.residual_add_out = nnq.FloatFunctional() + + def forward(self, x: torch.Tensor): + residual = x + out = self.quant_conv1(x) + out = self.quant_conv2(out) + out = self.quant_conv3(out) + if self.quant_downsample is not None: + residual = self.quant_downsample(x) + out = self.residual_add_out.add_relu(out, residual) + if self.disable_fake_quantization: + return out + if self.use_act_quant: + out = self.act_quantizer(out) + return out + + def convert_to_quantizable_with_config(self): + self._convert_quant_modules_to_quantizable() + self.disable_fake_quantization = True + act_qparams = self.act_quantizer.get_qparams() #TODO + self.residual_add_out.qconfig = QConfig( + weight=None, + activation = FixedQParamsObserver.with_args( + qscheme = None, + dtype = None, + quant_min = act_qparams['quant_min'], + quant_max = act_qparams['quant_max'], + scale = act_qparams['scale'], + zero_point = act_qparams['zero_point'] + ) + ) + + +class QuantInvertedResidual(BaseQuantBlock): + def __init__(self, act_quant_params: dict = {}) -> None: + super().__init__(act_quant_params) + #============================================ @@ -39,23 +280,15 @@ - InvertedResidual(nn.Module) -> QuantInvertedResidual(BaseQuantBlock(nn.Module)) - nn.Conv2d, nn.Linear -> QuantModule(nn.Module) """ -class StraightThrough(nn.Module): - """Identity Layer""" - def __int__(self): - super().__init__() - pass - def forward(self, input): - return input - -class QuantModule(nn.Module): +class QModule(nn.Module): """ Quantized Module that can perform quantized convolution or normal convolution. To activate quantization, please use set_quant_state function. """ def __init__(self, org_module: Union[nn.Conv2d, nn.Linear], weight_quant_params: dict = {}, act_quant_params: dict = {}, disable_act_quant: bool = False, se_module = None): - super(QuantModule, self).__init__() + super(QModule, self).__init__() if isinstance(org_module, nn.Conv2d): self.fwd_kwargs = dict(stride=org_module.stride, padding=org_module.padding, dilation=org_module.dilation, groups=org_module.groups) @@ -111,7 +344,7 @@ def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): self.use_act_quant = act_quant -class BaseQuantBlock(nn.Module): +class BaseQBlock(nn.Module): """ Base implementation of block structures for all networks. Due to the branch architecture, we have to perform activation function @@ -131,24 +364,24 @@ def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): self.use_weight_quant = weight_quant self.use_act_quant = act_quant for m in self.modules(): - if isinstance(m, QuantModule): + if isinstance(m, QModule): m.set_quant_state(weight_quant, act_quant) -class QuantBasicBlock(BaseQuantBlock): +class QBasicBlock(BaseQBlock): """ Implementation of Quantized BasicBlock used in ResNet-18 and ResNet-34. """ def __init__(self, basic_block: BasicBlock, weight_quant_params: dict = {}, act_quant_params: dict = {}): super().__init__(act_quant_params) - self.conv1 = QuantModule(basic_block.conv1, weight_quant_params, act_quant_params) + self.conv1 = QModule(basic_block.conv1, weight_quant_params, act_quant_params) self.conv1.activation_function = basic_block.activ - self.conv2 = QuantModule(basic_block.conv2, weight_quant_params, act_quant_params, disable_act_quant=True) + self.conv2 = QModule(basic_block.conv2, weight_quant_params, act_quant_params, disable_act_quant=True) self.activation_function = basic_block.activ if basic_block.downsample is None: self.downsample = None else: - self.downsample = QuantModule(basic_block.downsample[0], weight_quant_params, act_quant_params, + self.downsample = QModule(basic_block.downsample[0], weight_quant_params, act_quant_params, disable_act_quant=True) # copying all attributes in original block self.stride = basic_block.stride @@ -163,18 +396,18 @@ def forward(self, x): out = self.act_quantizer(out) return out -class QuantBottleneck(BaseQuantBlock): +class QBottleneck(BaseQBlock): """ Implementation of Quantized Bottleneck Block used in ResNet-50, -101 and -152. """ def __init__(self, bottleneck: Bottleneck, weight_quant_params: dict = {}, act_quant_params: dict = {}): super().__init__(act_quant_params) - self.conv1 = QuantModule(bottleneck.conv1, weight_quant_params, act_quant_params) + self.conv1 = QModule(bottleneck.conv1, weight_quant_params, act_quant_params) self.conv1.activation_function = bottleneck.activ - self.conv2 = QuantModule(bottleneck.conv2, weight_quant_params, act_quant_params) + self.conv2 = QModule(bottleneck.conv2, weight_quant_params, act_quant_params) self.conv2.activation_function = bottleneck.activ - self.conv3 = QuantModule(bottleneck.conv3, weight_quant_params, act_quant_params, disable_act_quant=True) + self.conv3 = QModule(bottleneck.conv3, weight_quant_params, act_quant_params, disable_act_quant=True) # modify the activation function to ReLU self.activation_function = bottleneck.activ @@ -182,7 +415,7 @@ def __init__(self, bottleneck: Bottleneck, weight_quant_params: dict = {}, act_q if bottleneck.downsample is None: self.downsample = None else: - self.downsample = QuantModule(bottleneck.downsample[0], weight_quant_params, act_quant_params, + self.downsample = QModule(bottleneck.downsample[0], weight_quant_params, act_quant_params, disable_act_quant=True) # copying all attributes in original block self.stride = bottleneck.stride @@ -198,7 +431,7 @@ def forward(self, x): out = self.act_quantizer(out) return out -class QuantInvertedResidual(BaseQuantBlock): +class QInvertedResidual(BaseQBlock): """ Implementation of Quantized Inverted Residual Block used in MobileNetV2. Inverted Residual does not have activation function. @@ -210,29 +443,29 @@ def __init__(self, inv_res: InvertedResidual, weight_quant_params: dict = {}, ac self.inp = inv_res.inp self.oup = inv_res.oup self.exp = inv_res.exp - self.conv1 = QuantModule(inv_res.conv1, weight_quant_params, act_quant_params) + self.conv1 = QModule(inv_res.conv1, weight_quant_params, act_quant_params) self.conv1.activation_function = nn.ReLU6(inplace=True) - self.conv2 = QuantModule(inv_res.conv2, weight_quant_params, act_quant_params) + self.conv2 = QModule(inv_res.conv2, weight_quant_params, act_quant_params) self.conv2.activation_function = nn.ReLU6(inplace=True) - self.conv3 = QuantModule(inv_res.conv3, weight_quant_params, act_quant_params) + self.conv3 = QModule(inv_res.conv3, weight_quant_params, act_quant_params) self.shortcut = nn.Sequential() if self.stride==1 and self.inp!=self.oup: self.shortcut = nn.Sequential( - QuantModule(inv_res.shortcut[0], weight_quant_params, act_quant_params) + QModule(inv_res.shortcut[0], weight_quant_params, act_quant_params) ) # self.use_res_connect = inv_res.use_res_connect # self.expand_ratio = inv_res.exp # if self.expand_ratio == 1: # self.conv = nn.Sequential( - # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params, disable_act_quant=True), + # QModule(inv_res.conv[0], weight_quant_params, act_quant_params), + # QModule(inv_res.conv[3], weight_quant_params, act_quant_params, disable_act_quant=True), # ) # self.conv[0].activation_function = nn.ReLU6() # else: # self.conv = nn.Sequential( - # QuantModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[3], weight_quant_params, act_quant_params), - # QuantModule(inv_res.conv[6], weight_quant_params, act_quant_params, disable_act_quant=True), + # QModule(inv_res.conv[0], weight_quant_params, act_quant_params), + # QModule(inv_res.conv[3], weight_quant_params, act_quant_params), + # QModule(inv_res.conv[6], weight_quant_params, act_quant_params, disable_act_quant=True), # ) # self.conv[0].activation_function = nn.ReLU6() # self.conv[1].activation_function = nn.ReLU6() @@ -263,7 +496,7 @@ def forward(self, x): - InvertedResidual(nn.Module) -> QInvertedResidual(nn.Module) """ -class QBasicBlock(nn.Module): +class _QBasicBlock(nn.Module): expansion = 1 def __init__(self, basic_block: BasicBlock): super().__init__() @@ -290,7 +523,7 @@ def forward(self, x): return out -class QBottleneck(nn.Module): +class _QBottleneck(nn.Module): expansion = 4 def __init__(self, bottleneck: Bottleneck): super().__init__() @@ -322,7 +555,7 @@ def forward(self, x): return out -class QInvertedResidual(nn.Module): +class _QInvertedResidual(nn.Module): def __init__(self, inv_res: InvertedResidual): super().__init__() self.stride = inv_res.stride From e1b6108cc2202ebc939c1a86b8237c9b7083877b Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:59:08 +0530 Subject: [PATCH 13/35] updated quantizer methods --- trailmet/algorithms/quantize/methods.py | 226 +++++++++++++++--------- 1 file changed, 139 insertions(+), 87 deletions(-) diff --git a/trailmet/algorithms/quantize/methods.py b/trailmet/algorithms/quantize/methods.py index 28ae66d..0722b13 100644 --- a/trailmet/algorithms/quantize/methods.py +++ b/trailmet/algorithms/quantize/methods.py @@ -26,6 +26,16 @@ import numpy as np import scipy.optimize as optim +__all__ = [ + 'RoundSTE', + 'FloorSTE', + 'BaseQuantizer', + 'UniformAffineQuantizer', + 'AdaRoundQuantizer', + 'UniformSymmetricQuantizer', + 'LpNormQuantizer', + 'BitSplitQuantizer' +] class RoundSTE(torch.autograd.Function): """grad enabled round function""" @@ -49,17 +59,21 @@ def backward(ctx, grad_output): class BaseQuantizer(nn.Module): - def __init__(self, n_bits, symm, channel_wise, delta, zero_point, inited): + def __init__(self, n_bits: int, reduce_range: bool, unsigned: bool, + scale, zero_point): super(BaseQuantizer, self).__init__() self._supported_bits = [2, 3, 4, 8, 16, 32] assert n_bits in self._supported_bits, 'bitwidth not supported' - self.n_bits = n_bits - self.n_levels = 2 ** self.n_bits - self.symmetric = symm - self.channel_wise = channel_wise - self.delta = delta + if reduce_range: # handle qint overflow in x86 backend + n_bits -= 1 + if unsigned: # use unsigned int + self.q_max = (2 ** n_bits) - 1 + self.q_min = 0 + else: + self.q_max = (2 ** (n_bits-1)) - 1 + self.q_min = -(2 ** (n_bits-1)) + self.scale = scale self.zero_point = zero_point - self.inited = inited def __register_buffer__(self, name, value): if hasattr(self, name): @@ -71,21 +85,30 @@ def __register_parameter__(self, name, value): delattr(self, name) self.register_parameter(name, nn.Parameter(value)) - def __quantize__(self, x, mode): - if mode == 'nearest': - x_int = torch.round(x / self.delta) - elif mode == 'nearest_ste': - x_int = RoundSTE.apply(x / self.delta) - elif mode == 'stochastic': - x_floor = FloorSTE.apply(x / self.delta) - x_int = x_floor + torch.bernoulli((x / self.delta) - x_floor) + def quantize(self, x: torch.Tensor, round_mode: str): + assert None not in [self.scale, self.zero_point] + if round_mode == 'nearest': + x_int = torch.round(x / self.scale) + elif round_mode == 'nearest_ste': + x_int = RoundSTE.apply(x / self.scale) + elif round_mode == 'stochastic': + x_floor = FloorSTE.apply(x / self.scale) + x_int = x_floor + torch.bernoulli((x / self.scale) - x_floor) else: ValueError('wrong rounding mode') - x_quant = torch.clamp(x_int + self.zero_point, 0, self.n_levels-1) + x_quant = torch.clamp(x_int + self.zero_point, self.q_min, self.q_max) return x_quant - def __dequantize__(self, xq): - xq_float = (xq - self.zero_point) * self.delta + def dequantize(self, xq: torch.Tensor): + xq_float = (xq - self.zero_point) * self.scale return xq_float + + def get_qparams(self) -> dict: + return { + "scale": self.scale, + "zero_point": self.zero_point, + "quant_max": self.q_max, + "quant_min": self.q_min, + } @@ -100,29 +123,37 @@ class UniformAffineQuantizer(BaseQuantizer): :param channel_wise: if True, compute scale and zero_point in each channel :param scale_method: determines the quantization scale and zero point """ - def __init__(self, n_bits: int = 8, symmetric: bool = False, channel_wise: bool = False, scale_method: str = 'max', - leaf_param: bool = False, **kwargs): - super(UniformAffineQuantizer, self).__init__(n_bits, symmetric, channel_wise, - delta=None, zero_point=None, inited=False) + def __init__(self, n_bits: int = 8, unsigned: bool = False, reduce_range: bool = False, + channel_wise: bool = False, scale_method: str = 'max', leaf_param: bool = False, + inited: bool = False, **kwargs): + super(UniformAffineQuantizer, self).__init__(n_bits=n_bits, reduce_range=reduce_range, + unsigned=unsigned,scale=None, zero_point=None) + self.symmetric = False + self.n_bits = n_bits + self.unsigned = unsigned + self.reduce_range = reduce_range + self.channel_wise = channel_wise self.leaf_param = leaf_param self.scale_method = scale_method + self.inited = inited + self.eps = torch.finfo(torch.float32).eps def forward(self, x: torch.Tensor): if not self.inited: - delta, zero_point = self.init_quantization_scale(x, self.channel_wise) + scale, zero_point = self.init_quantization_params(x, self.channel_wise) if self.leaf_param: - self.__register_parameter__('delta', delta) + self.__register_parameter__('scale', scale) else: - self.__register_buffer__('delta', delta) + self.__register_buffer__('scale', scale) self.__register_buffer__('zero_point', zero_point) self.inited = True # apply fake quantization - x_quant = self.__quantize__(x, 'nearest_ste') - x_dequant = self.__dequantize__(x_quant) + x_quant = self.quantize(x, 'nearest_ste') + x_dequant = self.dequantize(x_quant) return x_dequant - def init_quantization_scale(self, x: torch.Tensor, channel_wise = False): - delta, zero_point = None, None + def init_quantization_params(self, x: torch.Tensor, channel_wise = False): + scale, zero_point = None, None if channel_wise: x_clone = x.clone().detach() n_channels = x_clone.shape[0] @@ -130,32 +161,28 @@ def init_quantization_scale(self, x: torch.Tensor, channel_wise = False): x_max = x_clone.abs().max(dim=-1)[0].max(dim=-1)[0].max(dim=-1)[0] else: x_max = x_clone.abs().max(dim=-1)[0] - delta = x_max.clone() + scale = x_max.clone() zero_point = x_max.clone() # determine the scale and zero point channel-by-channel for c in range(n_channels): - delta[c], zero_point[c] = self.init_quantization_scale(x_clone[c], channel_wise=False) + scale[c], zero_point[c] = self.init_quantization_params(x_clone[c], channel_wise=False) if len(x.shape) == 4: - delta = delta.view(-1, 1, 1, 1) + scale = scale.view(-1, 1, 1, 1) zero_point = zero_point.view(-1, 1, 1, 1) else: - delta = delta.view(-1, 1) + scale = scale.view(-1, 1) zero_point = zero_point.view(-1, 1) else: if 'max' in self.scale_method: - x_max, x_min = x.max(), x.min() - if 'scale' in self.scale_method: - x_min = x_min * (self.n_bits + 2) / 8 - x_max = x_max * (self.n_bits + 2) / 8 - if self.symmetric: - x_absmax = torch.max(x_min.abs(), x_max) - x_min, x_max = -x_absmax if x_min < 0 else 0, x_absmax - delta = (x_max - x_min) / (self.n_levels - 1) - zero_point = torch.round(-x_min / delta) + x_min, x_max = torch.aminmax(x) + scale = (x_max - x_min) / float(self.q_max - self.q_min) + scale = torch.max(scale, self.eps) + zero_point = self.q_min - torch.round(x_min/scale).to(torch.int) + zero_point = torch.clamp(zero_point, self.q_min, self.q_max) elif 'mse' in self.scale_method: # For Lp norm minimization as described in LAPQ - x_max, x_min = x.max(), x.min() + x_min, x_max = torch.aminmax(x) with torch.no_grad(): optim_alpha = optim.minimize_scalar( lambda alpha: self.estimate_quant_error(x, x_max, x_min, alpha), @@ -167,24 +194,41 @@ def init_quantization_scale(self, x: torch.Tensor, channel_wise = False): return delta, zero_point def estimate_quant_error(self, x: torch.Tensor, x_max, x_min, alpha, p=2.4): - delta = alpha * (x_max - x_min) / (self.n_levels - 1) - zero_point = torch.round( -alpha * x_min / delta) - x_int = torch.round(x / delta) # we assume weight quantization is always signed - x_quant = torch.clamp(x_int + zero_point, 0, self.n_levels - 1) - x_dequant = (x_quant - zero_point) * delta - err = torch.mean(torch.abs(x_dequant - x) ** p) - return err.item() + scale = alpha * (x_max - x_min) / float(self.q_max - self.q_min) + scale = torch.max(scale, self.eps) + zero_point = self.q_min - torch.round(alpha * x_min / scale).to(torch.int) + zero_point = torch.clamp(zero_point, self.q_min, self.q_max) + # we simulate fake quantization and calculate error + x_int = torch.round(x / scale) + x_quant = torch.clamp(x_int + zero_point, self.q_min, self.q_max) + x_dequant = (x_quant - zero_point) * scale + q_err = torch.mean(torch.abs(x_dequant - x) ** p) + return q_err.item() def bitwidth_refactor(self, refactored_bit: int): assert refactored_bit in [2,3,4,8,16,32], 'bitwidth not supported' - self.n_bits = refactored_bit - self.n_levels = 2 ** self.n_bits + if self.reduce_range: + n_bits = refactored_bit - 1 + else: + n_bits = refactored_bit + if self.unsigned: + self.q_max = (2 ** n_bits) - 1 + self.q_min = 0 + else: + self.q_max = (2 ** (n_bits-1)) - 1 + self.q_min = -((2 ** (n_bits-1)) - 1) self.inited = False def extra_repr(self): - s = 'bit={n_bits}, scale_method={scale_method}, symmetric={symmetric}, channel_wise={channel_wise},' \ - ' leaf_param={leaf_param}' + s = 'bits={n_bits}, unsigned={unsigned}, symmetric={symmetric}, channel_wise={channel_wise}, ' \ + 'scale_method={scale_method}' return s.format(**self.__dict__) + + def get_qparams(self) -> dict: + return super().get_qparams().update({ + "symmetric": self.symmetric, + "channel_wise": self.channel_wise + }) class AdaRoundQuantizer(BaseQuantizer): @@ -201,11 +245,11 @@ class AdaRoundQuantizer(BaseQuantizer): def __init__(self, uaq: UniformAffineQuantizer, weight_tensor: torch.Tensor, round_mode='learned_hard_sigmoid', **kwargs): # copying all attributes from UniformAffineQuantizer - super(AdaRoundQuantizer, self).__init__(uaq.n_bits, uaq.symmetric, - uaq.channel_wise, uaq.delta, uaq.zero_point, inited=True) + super(AdaRoundQuantizer, self).__init__(uaq.n_bits, uaq.reduce_range, + uaq.unsigned, uaq.scale, uaq.zero_point) self.round_mode = round_mode self.soft_targets = False - self.__register_buffer__('delta', uaq.delta) + self.__register_buffer__('scale', uaq.scale) self.__register_buffer__('zero_point', uaq.zero_point) # params for sigmoid function @@ -216,25 +260,25 @@ def __init__(self, uaq: UniformAffineQuantizer, weight_tensor: torch.Tensor, def forward(self, x: torch.tensor): if self.round_mode == 'learned_hard_sigmoid': - x_floor = FloorSTE.apply(x / self.delta) + x_floor = FloorSTE.apply(x / self.scale) if self.soft_targets: x_int = x_floor + self.get_soft_targets() else: x_int = x_floor + (self.alpha >= 0).float() x_quant = torch.clamp(x_int + self.zero_point, 0, self.n_levels - 1) else: - x_quant = self.__quantize__(x, mode = self.round_mode) - x_dequant = self.__dequantize__(x_quant) + x_quant = self.quantize(x, mode = self.round_mode) + x_dequant = self.dequantize(x_quant) return x_dequant def get_soft_targets(self): return torch.clamp(torch.sigmoid(self.alpha) * (self.zeta - self.gamma) + self.gamma, 0, 1) def init_alpha(self, x: torch.Tensor): - x_floor = FloorSTE.apply(x / self.delta) + x_floor = FloorSTE.apply(x / self.scale) if self.round_mode == 'learned_hard_sigmoid': - rest = (x / self.delta) - x_floor # rest of rounding [0, 1) - alpha = -torch.log((self.zeta - self.gamma) / (rest - self.gamma) - 1) # => sigmoid(alpha) = rest + rest = (x / self.scale) - x_floor # rest of rounding [0, 1) + alpha = -torch.log((self.zeta - self.gamma) / (rest - self.gamma) - 1) # sigmoid(alpha) = rest self.__register_parameter__('alpha', alpha) else: raise NotImplementedError @@ -244,55 +288,63 @@ def extra_repr(self): return s.format(**self.__dict__) -class MaxAbsQuantizer(BaseQuantizer): - def __init__(self, n_bits, inited=False, **kwargs): - super().__init__(n_bits, symm=True, channel_wise=False, delta=None, - zero_point=None, inited=inited) +class UniformSymmetricQuantizer(BaseQuantizer): + def __init__(self, n_bits, reduce_range=True, unsigned=False, inited=False, **kwargs): + super().__init__(n_bits=n_bits, reduce_range=reduce_range, unsigned=unsigned, + scale=None, zero_point=None) + self.inited = inited + self.symmetric = True + self.channel_wise = False # channel wise not supported for now self.alpha = None + self.eps = torch.finfo(torch.float32).eps def forward(self, x: torch.Tensor): if not self.inited: - self.init_alpha(x) - x_quant = self.__quantize__(x, 'nearest_ste') - x_dequant = self.__dequantize__(x_quant) + self.init_quantization_params(x) + x_quant = self.quantize(x, 'nearest_ste') + x_dequant = self.dequantize(x_quant) return x_dequant - def init_alpha(self, x: torch.Tensor): + def init_quantization_params(self, x: torch.Tensor): alpha = x.abs().max().item() self.set_params_from_alpha(alpha) self.inited = True def set_params_from_alpha(self, alpha): - self.delta = max((2 * alpha) / (self.n_levels - 1), 1e-8) - self.zero_point = alpha / self.delta + self.scale = torch.max((2 * alpha) / float(self.q_max - self.q_min), self.eps) + self.zero_point = (self.q_max + self.q_min)//2 self.__register_buffer__('alpha', torch.tensor(alpha)) def extra_repr(self): - s = 'bit={n_bits}, alpha={alpha}, inited={inited}' + s = 'bits={n_bits}, alpha={alpha}, scale={scale}, zero_point={zero_point} inited={inited}' return s.format(**self.__dict__) -class LpNormQuantizer(MaxAbsQuantizer): +class LpNormQuantizer(UniformSymmetricQuantizer): def __init__(self, n_bits, p_val, inited=False, **kwargs): super().__init__(n_bits, inited, **kwargs) self.p = p_val - def init_alpha(self, weight_tensor: torch.Tensor): + def init_quantization_params(self, x: torch.Tensor): with torch.no_grad(): - optim_alpha = optim.minimize_scalar(lambda alpha: self.estimate_quant_error(weight_tensor, alpha), - bounds=(weight_tensor.min().item(), weight_tensor.max().item())).x + optim_alpha = optim.minimize_scalar(lambda alpha: self.estimate_quant_error(x, alpha), + bounds=(x.abs().min().item(), x.abs().max().item())).x self.set_params_from_alpha(optim_alpha) self.inited = True def estimate_quant_error(self, x, alpha): - delta = max((2 * alpha) / (self.n_levels - 1), 1e-8) - zero_point = round(alpha / delta) - x_int = torch.round(x / delta) # we assume weight quantization is always signed - x_quant = torch.clamp(x_int + zero_point, 0, self.n_levels - 1) - x_dequant = (x_quant - zero_point) * delta - err = torch.mean(torch.abs(x_dequant - x) ** self.p) - return err.item() - - + scale = max((2 * alpha) / (self.q_max - self.q_min), 1e-8) + zero_point = (self.q_max + self.q_min)//2 + x_int = torch.round(x / scale) + x_quant = torch.clamp(x_int + zero_point, self.q_min, self.q_max) + x_dequant = (x_quant - zero_point) * scale + q_err = torch.mean(torch.abs(x_dequant - x) ** self.p) + return q_err.item() + + def get_qparams(self) -> dict: + return super().get_qparams().update({ + "symmetric": self.symmetric, + "channel_wise": self.channel_wise + }) From be251a8cbd8b6b7e2085e6eab8712be2604683b6 Mon Sep 17 00:00:00 2001 From: homebrow Date: Sun, 3 Sep 2023 22:59:30 +0530 Subject: [PATCH 14/35] fixed lapq method name bug --- trailmet/algorithms/quantize/lapq.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index 63c6f74..7a9aea0 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -29,6 +29,7 @@ from trailmet.utils import seed_everything from trailmet.algorithms.quantize.quantize import BaseQuantModel, BaseQuantization from trailmet.algorithms.quantize.modules import QuantModule, BaseQuantBlock +from trailmet.algorithms.quantize.methods import UniformSymmetricQuantizer, LpNormQuantizer class QuantModel(BaseQuantModel): @@ -90,13 +91,13 @@ def compress_model(self): weight_quant_params = { 'n_bits': self.w_bits, 'bcorr': True, - 'method': 'max_abs', + 'method': UniformSymmetricQuantizer, 'p_val': 2.0, } act_quant_params = { 'n_bits': self.a_bits, 'bcorr': True, - 'method': 'max_abs', + 'method': UniformSymmetricQuantizer, 'p_val': 2.0, } @@ -108,8 +109,8 @@ def compress_model(self): self.w_bits, self.a_bits, acc1, acc5)) del qnn - weight_quant_params['method'] = 'lp_norm' - act_quant_params['method'] = 'lp_norm' + weight_quant_params['method'] = LpNormQuantizer + act_quant_params['method'] = LpNormQuantizer p_vals = np.linspace(2,4,10) losses = [] pbar = tqdm(p_vals, total=len(p_vals)) From 8a6b95ff3d9a6deabbc8c541d5a181fb1492afcc Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 4 Sep 2023 01:34:22 +0530 Subject: [PATCH 15/35] fixed lapq refactoring errors --- trailmet/algorithms/quantize/__init__.py | 5 +++++ trailmet/algorithms/quantize/lapq.py | 9 +++++---- trailmet/algorithms/quantize/methods.py | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/trailmet/algorithms/quantize/__init__.py b/trailmet/algorithms/quantize/__init__.py index 8870151..9c56851 100644 --- a/trailmet/algorithms/quantize/__init__.py +++ b/trailmet/algorithms/quantize/__init__.py @@ -19,3 +19,8 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. + +from . import quantize +from . import lapq +from . import bitsplit +from . import brecq \ No newline at end of file diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index 7a9aea0..61d2886 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -33,15 +33,16 @@ class QuantModel(BaseQuantModel): - def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params: dict, fold_bn=True): - super().__init__(model, weight_quant_params, act_quant_params, fold_bn) + def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params: dict, + inplace=False, fuse_model=True): + super().__init__(model, weight_quant_params, act_quant_params, inplace, fuse_model) self.weight_quantizers = [] self.act_quantizers = [] for module in self.model.modules(): if isinstance(module, QuantModule): self.weight_quantizers.append(module.weight_quantizer) - if not module.disable_act_quant: - self.act_quantizers.append(module.act_quantizer) + # if not module.disable_act_quant: + self.act_quantizers.append(module.act_quantizer) elif isinstance(module, BaseQuantBlock): self.act_quantizers.append(module.act_quantizer) diff --git a/trailmet/algorithms/quantize/methods.py b/trailmet/algorithms/quantize/methods.py index 0722b13..340d24a 100644 --- a/trailmet/algorithms/quantize/methods.py +++ b/trailmet/algorithms/quantize/methods.py @@ -311,7 +311,7 @@ def init_quantization_params(self, x: torch.Tensor): self.inited = True def set_params_from_alpha(self, alpha): - self.scale = torch.max((2 * alpha) / float(self.q_max - self.q_min), self.eps) + self.scale = max((2 * alpha) / float(self.q_max - self.q_min), self.eps) self.zero_point = (self.q_max + self.q_min)//2 self.__register_buffer__('alpha', torch.tensor(alpha)) From a51eaf968de3f184c81217df4155cc5984cd05dc Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 4 Sep 2023 16:32:32 +0530 Subject: [PATCH 16/35] customized model forward pass --- trailmet/algorithms/quantize/utils.py | 8 +++++++- trailmet/models/resnet.py | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/trailmet/algorithms/quantize/utils.py b/trailmet/algorithms/quantize/utils.py index 8c58b73..5ba96da 100644 --- a/trailmet/algorithms/quantize/utils.py +++ b/trailmet/algorithms/quantize/utils.py @@ -56,7 +56,7 @@ def get_dtype(quant_min: int, quant_max: int): return torch.qint32 def replace_activation_with_identity(module: torch.nn.Module, activations: list) -> None: - reassign = {} + reassign = dict() for name, child_module in module.named_children(): replace_activation_with_identity(child_module, activations) for activation in activations: @@ -65,6 +65,12 @@ def replace_activation_with_identity(module: torch.nn.Module, activations: list) for key, value in reassign.items(): module._modules[key] = value +def quantized_forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.inp_quant(x) + x = self._forward_impl(x) + x = self.out_dequant(x) + return x + class StopForwardException(Exception): """ Used to throw and catch an exception to stop traversing the graph. diff --git a/trailmet/models/resnet.py b/trailmet/models/resnet.py index 841325a..b40e55d 100644 --- a/trailmet/models/resnet.py +++ b/trailmet/models/resnet.py @@ -316,7 +316,7 @@ def _make_layer(self, block, planes, blocks, stride=1): return nn.Sequential(*layers) - def forward(self, x): + def _forward_impl(self, x): x = self.conv1(x) x = self.bn1(x) x = self.active(x) @@ -336,6 +336,9 @@ def forward(self, x): else: return x + def forward(self, x): + return self._forward_impl(x) + def get_bn_layers(self): bn_layers = [] for l_blocks in [self.layer1, self.layer2, self.layer3, self.layer4]: From 761515f2ada4a4535286f15d2a47bd65d9ff5316 Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 4 Sep 2023 16:33:13 +0530 Subject: [PATCH 17/35] modified qconfig generation --- trailmet/algorithms/quantize/modules.py | 55 ++++++++++++------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index 652c0d0..7bd0105 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -150,11 +150,25 @@ def set_quantization_state(self, weight: bool = False, act: bool = False): self.use_act_quant = act - def get_quantization_parameters(self): - return { - 'weight': self.weight_quantizer.get_qparams(), #TODO - 'act': self.act_quantizer.get_qparams() #TODO - } + def get_quantization_params_config(self): + fixed_qparams_config = dict() + for type in ["weight", "act"]: + qparams = eval(f"self.{type}_quantizer.get_qparams()") + fixed_qparams_config[type] = FixedQParamsObserver.with_args( + qscheme = get_qscheme( + per_channel = qparams['per_channel'], + symmetric = qparams['symmetric'] + ), + dtype = get_dtype( + quant_min = qparams['quant_min'], + quant_max = qparams['quant_max'] + ), + quant_min = qparams['quant_min'], + quant_max = qparams['quant_max'], + scale = qparams['scale'], + zero_point = qparams['zero_point'] + ) + return fixed_qparams_config class BaseQuantBlock(nn.Module): @@ -172,39 +186,22 @@ def set_quantization_state(self, weight: bool = False, act: bool = False): if isinstance(module, QuantModule): module.set_quantization_state(weight, act) - def _convert_quant_modules_to_quantizable(self): + def convert_to_quantizable_with_config(self): module_qparams = dict() - for name, module in self.named_children(): + for name, module in self.named_modules(): if isinstance(module, QuantModule): - module_qparams[name] = module.get_quantization_parameters() + module_qparams[name] = module.get_quantization_params_config() setattr(self, name, module.orig_module) #TODO: test it out self._attach_qconfig_to_quantizable(module_qparams) def _attach_qconfig_to_quantizable(self, module_qparams: dict): for name, qparams in module_qparams.items(): - fixed_qparam_obs = dict() - for type in ["weight", "act"]: - fixed_qparam_obs[type] = FixedQParamsObserver.with_args( - qscheme = get_qscheme( - per_channel=qparams[type]['per_channel'], - symmetric=qparams[type]['symmetric'] - ), - dtype = get_dtype( - quant_min=qparams[type]['quant_min'], - quant_max=qparams[type]['quant_max'] - ), - quant_min = qparams[type]['quant_min'], - quant_max = qparams[type]['quant_max'], - scale = qparams[type]['scale'], - zero_point = qparams[type]['zero_point'] - ) if isinstance(eval(f"self.{name}"), nni.ConvReLU2d): # propagate qconfig setattr(eval(f"self.{name}[0]"), "qconfig", QConfig( - weight=fixed_qparam_obs["weight"])) - + weight = qparams["weight"])) setattr(eval(f"self.{name}"), "qconfig", QConfig( - weight=fixed_qparam_obs["weight"], - activation=fixed_qparam_obs["act"] + weight = qparams["weight"], + activation = qparams["act"] )) eval(f"self.{name}.add_module")( "activation_post_process", @@ -248,7 +245,7 @@ def forward(self, x: torch.Tensor): return out def convert_to_quantizable_with_config(self): - self._convert_quant_modules_to_quantizable() + super().convert_to_quantizable_with_config() self.disable_fake_quantization = True act_qparams = self.act_quantizer.get_qparams() #TODO self.residual_add_out.qconfig = QConfig( From c4dd4b7f26df166182ae5c2caa6b975f245c781f Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 4 Sep 2023 16:33:51 +0530 Subject: [PATCH 18/35] added base true quant --- trailmet/algorithms/quantize/quantize.py | 154 ++++++++++++++++++----- 1 file changed, 120 insertions(+), 34 deletions(-) diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index 89f11db..6777edf 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -25,18 +25,25 @@ import torch.nn as nn import torch.nn.functional as F import torch.ao.nn.intrinsic as nni +import torch.ao.nn.quantized as nnq +import torch.ao.nn.intrinsic.quantized as nniq from tqdm import tqdm -from typing import Union +from typing import Union, Callable, Dict from trailmet.models.resnet import BasicBlock, Bottleneck from trailmet.models.mobilenet import InvertedResidual -from trailmet.algorithms.quantize.utils import StopForwardException, DataSaverHook, GradSaverHook -from trailmet.algorithms.quantize.utils import LinearTempDecay, Node, GraphPlotter, replace_activation_with_identity -from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, BaseQuantBlock -from trailmet.algorithms.quantize.modules import QuantBasicBlock, QuantBottleneck, QuantInvertedResidual +from trailmet.algorithms.quantize.utils import StopForwardException, DataSaverHook, \ + GradSaverHook, LinearTempDecay, Node, GraphPlotter, replace_activation_with_identity, \ + get_qscheme, get_dtype, quantized_forward +from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, \ + BaseQuantBlock, QuantBasicBlock, QuantBottleneck, QuantInvertedResidual from trailmet.algorithms.algorithms import BaseAlgorithm +from torch.nn.utils.parametrize import type_before_parametrizations as _type +from torch.ao.nn.intrinsic.modules.fused import _FusedModule +from torch.ao.quantization import QConfig, FixedQParamsObserver from torch.ao.quantization.stubs import QuantStub, DeQuantStub from torch.ao.quantization.fuse_modules import fuse_modules + __all__ = [ 'BaseQuantModel', 'BaseQuantization', @@ -45,12 +52,27 @@ 'GetLayerGrad' ] -supported = { - BasicBlock: QuantBasicBlock, - Bottleneck: QuantBottleneck, - InvertedResidual: QuantInvertedResidual, +FLOAT_TO_FAKE_QUANT_MAPPING: Dict[Callable, Callable] = { + nn.Conv2d : QuantModule, + nn.Linear : QuantModule, + nni.ConvReLU2d : QuantModule, + BasicBlock : QuantBasicBlock, + Bottleneck : QuantBottleneck, + InvertedResidual : QuantInvertedResidual +} + +FLOAT_TO_TRUE_QUANT_MAPPING: Dict[Callable, Callable] = { + QuantStub : nnq.Quantize, + DeQuantStub : nnq.DeQuantize, + nn.Conv2d : nnq.Conv2d, + nn.Linear : nnq.Linear, + # Intrinsic modules: + nni.ConvReLU2d : nniq.ConvReLU2d, + # Wrapper Modules: + nnq.FloatFunctional : nnq.QFunctional } + class BaseQuantModel(nn.Module): """base model wrapping class for quantization algorithms""" def __init__(self, model: nn.Module, weight_quant_params: dict = {}, @@ -62,23 +84,27 @@ def __init__(self, model: nn.Module, weight_quant_params: dict = {}, self.model = model self.weight_quant_params = weight_quant_params self.act_quant_params = act_quant_params + self.quant_modules = None + setattr(self.model, 'inp_quant', StraightThrough()) + setattr(self.model, 'out_dequant', StraightThrough()) self.model.eval() + self.convert_model_to_fake_quantized(fuse_model) + + def forward(self, x): + return self.model.forward(x) + + def convert_model_to_fake_quantized(self, fuse_model=True): if not fuse_model: self.search_fold_conv_bn(self.model) # Do Not Use else: replace_activation_with_identity(self.model, [nn.ReLU, nn.ReLU6]) self.add_fused_conv_bn_act(self.model) - setattr(self.model, 'quant', QuantStub()) - setattr(self.model, 'dequant', DeQuantStub()) - self.quant_module_refactor(self.model) + self.input_quantizer = self.act_quant_params.get('method')(**self.act_quant_params) + setattr(self.model, 'inp_quant', self.input_quantizer) + self._quant_module_refactor(self.model) + self.model.forward = quantized_forward #TODO check functionality self.quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] - def forward(self, x): - x = self.model.quant(x) #TODO check functionality - x = self.model._forward_impl(x) - x = self.model.dequant(x) - return x - def add_fused_conv_bn_act(self, model: nn.Module): # same functionality as torchvision.models.quantization.resnet.QuantizableResNet.fuse_model setattr(model, "relu1", nn.ReLU(inplace=True)) @@ -108,33 +134,93 @@ def add_fused_conv_bn_act(self, model: nn.Module): if module.downsample is not None: fuse_modules(module.downsample, ["0", "1"], inplace=True) - def quant_module_refactor(self, module: nn.Module): + def _quant_module_refactor(self, module: nn.Module): """ Recursively replace Conv2d and Linear layers with QuantModule and other supported network blocks to their respective wrappers, to enable weight and activations quantization. """ - # prev_quant_module: QuantModule = None for name, child_module in module.named_children(): - if type(child_module) in supported: - setattr(module, name, supported[type(child_module)]( + if type(child_module) in FLOAT_TO_FAKE_QUANT_MAPPING: + setattr(module, name, FLOAT_TO_FAKE_QUANT_MAPPING[type(child_module)]( child_module, self.weight_quant_params, self.act_quant_params )) - elif isinstance(child_module, (nn.Conv2d, nni.ConvReLU2d, nn.Linear, nni.LinearReLU)): - setattr(module, name, QuantModule( - child_module, self.weight_quant_params, self.act_quant_params - )) - # prev_quant_module = getattr(module, name) - # elif isinstance(child_module, (nn.ReLU, nn.ReLU6)): - # if prev_quant_module is not None: - # prev_quant_module.activation_function = child_module - # else: - # continue elif isinstance(child_module, (StraightThrough, nn.Identity, nn.ReLU)): continue else: - self.quant_module_refactor(child_module) - + self._quant_module_refactor(child_module) + + def convert_model_to_quantized(self, inplace=True, remove_qconfig=True): + if not inplace: + model = copy.deepcopy(self.model) + inp_qparams = self.input_quantizer.get_qprams() + model.inp_quant = QuantStub(qconfig=QConfig( + weight = None, + activation = FixedQParamsObserver.with_args( + qscheme = get_qscheme(inp_qparams['per_channel'], inp_qparams['symmetric']), + dtype = get_dtype(inp_qparams['quant_min'], inp_qparams['quant_max']), + quant_min = inp_qparams['quant_min'], + quant_max = inp_qparams['quant_max'], + scale = inp_qparams['scale'], + zero_point = inp_qparams['zero_point'] + ) + )) + #TODO attach activation_post_process to QuantStub + model.inp_dequant = DeQuantStub() + self._attach_qconfig_to_quantizable(model) + self._convert_quantizable(model, FLOAT_TO_TRUE_QUANT_MAPPING, inplace) + if remove_qconfig: + self._remove_qconfig_from_quantizable(model) + return model + + def _convert_quantizable(self, module: nn.Module, mapping: dict, inplace = True): + if not inplace: + module = copy.deepcopy(module) + reassign = dict() + for name, child_module in module.named_children(): + if not isinstance(child_module, _FusedModule): # fused modules are swapped as one unit + self._convert_quantizable(child_module, mapping, True) + reassign[name] = self._swap_module(child_module, mapping) + for name, quantized_module in reassign.items(): + module._modules[name] = quantized_module + return module + + def _attach_qconfig_to_quantizable(self, module: nn.Module): + for name, child_module in module.named_children: + if isinstance(child_module, QuantModule): + qparams_config = child_module.get_quantization_params_config() + setattr(module, name, child_module.orig_module) + child_module.qconfig = QConfig( + weight = qparams_config['weight'], + activation = qparams_config['act'] + ) + child_module.add_module( + 'activation_post_process', + child_module.qconfig.activation() + ) + elif isinstance(child_module, BaseQuantBlock): + child_module.convert_to_quantizable_with_config() + else: + self._attach_qconfig_to_quantizable(child_module) + + def _remove_qconfig_from_quantizable(self, module: nn.Module): + for child_module in module.children(): + self._remove_qconfig_from_quantizable(child_module) + if hasattr(module, 'activation_post_process'): + delattr(module, 'activation_post_process') + if hasattr(module, 'qconfig'): + delattr(module, 'qconfig') + + def _swap_module(self, module: nn.Module, mapping: dict): + new_module = module + if hasattr(module, 'qconfig') and module.qconfig is not None: + swapped = False + if _type(module) in mapping: + new_module = mapping[_type(module)].from_float(module) + swapped = True + if swapped: + pass #TODO: hook management + return new_module def set_quant_state(self, weight_quant: bool = True, act_quant: bool = True): """ From d0cf17bc2be9884eb8fca97d58fdddb153e34789 Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 4 Sep 2023 16:34:08 +0530 Subject: [PATCH 19/35] added true quant to lapq --- trailmet/algorithms/quantize/lapq.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index 61d2886..4836339 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -168,7 +168,8 @@ def local_search_callback(x): print('==> Full quantization (W{}A{}) accuracy: {}'.format( self.w_bits, self.a_bits, self.test(self.qnn, self.test_loader, device=self.device))) - return self.qnn + quantized_model = self.qnn.convert_model_to_quantized(inplace = False) + return quantized_model def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel, device): From d5ef9dccc5da5ed0c35c96bab864b79397315b2d Mon Sep 17 00:00:00 2001 From: sydarb Date: Tue, 5 Sep 2023 21:57:09 +0530 Subject: [PATCH 20/35] debug lapq true quant --- trailmet/algorithms/quantize/lapq.py | 4 +- trailmet/algorithms/quantize/methods.py | 22 +++++--- trailmet/algorithms/quantize/modules.py | 49 +++++++++------- trailmet/algorithms/quantize/quantize.py | 72 ++++++++++++++++-------- 4 files changed, 95 insertions(+), 52 deletions(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index 4836339..d673b12 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -38,6 +38,7 @@ def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params super().__init__(model, weight_quant_params, act_quant_params, inplace, fuse_model) self.weight_quantizers = [] self.act_quantizers = [] + self.act_quantizers.append(self.model.inp_quant) for module in self.model.modules(): if isinstance(module, QuantModule): self.weight_quantizers.append(module.weight_quantizer) @@ -98,6 +99,7 @@ def compress_model(self): act_quant_params = { 'n_bits': self.a_bits, 'bcorr': True, + 'unsigned': True, 'method': UniformSymmetricQuantizer, 'p_val': 2.0, } @@ -163,7 +165,7 @@ def local_search_callback(x): self.pbar.close() alphas = res.x if self.verbose: - print('==> Layer-wise Scales :\n', alphas) + print('==> Layer-wise Alphas :\n', alphas) self.qnn.set_alphas_np(alphas) print('==> Full quantization (W{}A{}) accuracy: {}'.format( self.w_bits, self.a_bits, diff --git a/trailmet/algorithms/quantize/methods.py b/trailmet/algorithms/quantize/methods.py index 340d24a..6e1035b 100644 --- a/trailmet/algorithms/quantize/methods.py +++ b/trailmet/algorithms/quantize/methods.py @@ -63,7 +63,7 @@ def __init__(self, n_bits: int, reduce_range: bool, unsigned: bool, scale, zero_point): super(BaseQuantizer, self).__init__() self._supported_bits = [2, 3, 4, 8, 16, 32] - assert n_bits in self._supported_bits, 'bitwidth not supported' + # assert n_bits in self._supported_bits, 'bitwidth not supported' if reduce_range: # handle qint overflow in x86 backend n_bits -= 1 if unsigned: # use unsigned int @@ -71,7 +71,7 @@ def __init__(self, n_bits: int, reduce_range: bool, unsigned: bool, self.q_min = 0 else: self.q_max = (2 ** (n_bits-1)) - 1 - self.q_min = -(2 ** (n_bits-1)) + self.q_min = -(2 ** (n_bits-1)) + 1 self.scale = scale self.zero_point = zero_point @@ -206,7 +206,7 @@ def estimate_quant_error(self, x: torch.Tensor, x_max, x_min, alpha, p=2.4): return q_err.item() def bitwidth_refactor(self, refactored_bit: int): - assert refactored_bit in [2,3,4,8,16,32], 'bitwidth not supported' + # assert refactored_bit in [2,3,4,8,16,32], 'bitwidth not supported' if self.reduce_range: n_bits = refactored_bit - 1 else: @@ -225,10 +225,12 @@ def extra_repr(self): return s.format(**self.__dict__) def get_qparams(self) -> dict: - return super().get_qparams().update({ + qparams = super().get_qparams() + qparams.update({ "symmetric": self.symmetric, "channel_wise": self.channel_wise }) + return qparams class AdaRoundQuantizer(BaseQuantizer): @@ -292,6 +294,7 @@ class UniformSymmetricQuantizer(BaseQuantizer): def __init__(self, n_bits, reduce_range=True, unsigned=False, inited=False, **kwargs): super().__init__(n_bits=n_bits, reduce_range=reduce_range, unsigned=unsigned, scale=None, zero_point=None) + self.n_bits = n_bits self.inited = inited self.symmetric = True self.channel_wise = False # channel wise not supported for now @@ -316,8 +319,11 @@ def set_params_from_alpha(self, alpha): self.__register_buffer__('alpha', torch.tensor(alpha)) def extra_repr(self): - s = 'bits={n_bits}, alpha={alpha}, scale={scale}, zero_point={zero_point} inited={inited}' - return s.format(**self.__dict__) + s = 'bits={n_bits}, scale={scale}, zero_point={zero_point}' + return s.format(**self.__dict__) + + def get_qparams(self) -> dict: + return super().get_qparams() class LpNormQuantizer(UniformSymmetricQuantizer): def __init__(self, n_bits, p_val, inited=False, **kwargs): @@ -341,10 +347,12 @@ def estimate_quant_error(self, x, alpha): return q_err.item() def get_qparams(self) -> dict: - return super().get_qparams().update({ + qparams = super().get_qparams() + qparams.update({ "symmetric": self.symmetric, "channel_wise": self.channel_wise }) + return qparams diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index 7bd0105..7a19b4f 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import copy import torch import torch.nn as nn import torch.nn.functional as F @@ -156,7 +157,7 @@ def get_quantization_params_config(self): qparams = eval(f"self.{type}_quantizer.get_qparams()") fixed_qparams_config[type] = FixedQParamsObserver.with_args( qscheme = get_qscheme( - per_channel = qparams['per_channel'], + per_channel = qparams['channel_wise'], symmetric = qparams['symmetric'] ), dtype = get_dtype( @@ -186,27 +187,31 @@ def set_quantization_state(self, weight: bool = False, act: bool = False): if isinstance(module, QuantModule): module.set_quantization_state(weight, act) - def convert_to_quantizable_with_config(self): + def convert_to_quantizable_with_config(self, module: nn.Module): module_qparams = dict() - for name, module in self.named_modules(): - if isinstance(module, QuantModule): - module_qparams[name] = module.get_quantization_params_config() - setattr(self, name, module.orig_module) #TODO: test it out - self._attach_qconfig_to_quantizable(module_qparams) - - def _attach_qconfig_to_quantizable(self, module_qparams: dict): + module_reassign = dict() + for name, child_module in module.named_modules(): + if isinstance(child_module, QuantModule): + module_qparams[name] = child_module.get_quantization_params_config() + module_reassign[name] = child_module.orig_module + for name, orig_module in module_reassign.items(): #TODO: test it out + delattr(module, name) + setattr(module, name, orig_module) + self._attach_qconfig_to_quantizable(module, module_qparams) + + def _attach_qconfig_to_quantizable(self, module: nn.Module, module_qparams: dict): for name, qparams in module_qparams.items(): - if isinstance(eval(f"self.{name}"), nni.ConvReLU2d): # propagate qconfig - setattr(eval(f"self.{name}[0]"), "qconfig", QConfig( - weight = qparams["weight"])) - setattr(eval(f"self.{name}"), "qconfig", QConfig( + submodule = getattr(module, name, None) + assert submodule is not None + if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig + setattr(submodule[0], "qconfig", QConfig( + weight = qparams["weight"], + activation = None)) + setattr(submodule, "qconfig", QConfig( weight = qparams["weight"], activation = qparams["act"] )) - eval(f"self.{name}.add_module")( - "activation_post_process", - eval(f"self.{name}.qconfig.activation()") - ) + submodule.add_module("activation_post_process", submodule.qconfig.activation()) class QuantBasicBlock(BaseQuantBlock): @@ -220,7 +225,7 @@ def __init__(self, bottleneck: Bottleneck, weight_qparams: dict, act_qparams: di # assuming all bn and relu are fused in conv self.weight_qparams = weight_qparams self.act_qparams = act_qparams - self.orig_module = bottleneck + # self.orig_module = bottleneck self.quant_conv1 = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d self.quant_conv2 = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d self.quant_conv3 = QuantModule(bottleneck.conv3, weight_qparams, act_qparams) # ConvReLU2d @@ -245,20 +250,22 @@ def forward(self, x: torch.Tensor): return out def convert_to_quantizable_with_config(self): - super().convert_to_quantizable_with_config() + super().convert_to_quantizable_with_config(self) self.disable_fake_quantization = True act_qparams = self.act_quantizer.get_qparams() #TODO self.residual_add_out.qconfig = QConfig( weight=None, activation = FixedQParamsObserver.with_args( - qscheme = None, - dtype = None, + qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), + dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max']), quant_min = act_qparams['quant_min'], quant_max = act_qparams['quant_max'], scale = act_qparams['scale'], zero_point = act_qparams['zero_point'] ) ) + self.residual_add_out.add_module("activation_post_process", + self.residual_add_out.qconfig.activation()) class QuantInvertedResidual(BaseQuantBlock): diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index 6777edf..5451109 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -102,7 +102,7 @@ def convert_model_to_fake_quantized(self, fuse_model=True): self.input_quantizer = self.act_quant_params.get('method')(**self.act_quant_params) setattr(self.model, 'inp_quant', self.input_quantizer) self._quant_module_refactor(self.model) - self.model.forward = quantized_forward #TODO check functionality + self.model.forward = quantized_forward.__get__(self.model, nn.Module) #TODO check functionality self.quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] def add_fused_conv_bn_act(self, model: nn.Module): @@ -151,13 +151,15 @@ def _quant_module_refactor(self, module: nn.Module): self._quant_module_refactor(child_module) def convert_model_to_quantized(self, inplace=True, remove_qconfig=True): + model = self.model if not inplace: - model = copy.deepcopy(self.model) - inp_qparams = self.input_quantizer.get_qprams() + model = copy.deepcopy(model) + model.to(torch.device('cpu')) + inp_qparams = self.input_quantizer.get_qparams() model.inp_quant = QuantStub(qconfig=QConfig( weight = None, activation = FixedQParamsObserver.with_args( - qscheme = get_qscheme(inp_qparams['per_channel'], inp_qparams['symmetric']), + qscheme = get_qscheme(inp_qparams['channel_wise'], inp_qparams['symmetric']), dtype = get_dtype(inp_qparams['quant_min'], inp_qparams['quant_max']), quant_min = inp_qparams['quant_min'], quant_max = inp_qparams['quant_max'], @@ -165,10 +167,10 @@ def convert_model_to_quantized(self, inplace=True, remove_qconfig=True): zero_point = inp_qparams['zero_point'] ) )) - #TODO attach activation_post_process to QuantStub - model.inp_dequant = DeQuantStub() + model.inp_quant.add_module("activation_post_process", model.inp_quant.qconfig.activation()) + model.out_dequant = DeQuantStub() self._attach_qconfig_to_quantizable(model) - self._convert_quantizable(model, FLOAT_TO_TRUE_QUANT_MAPPING, inplace) + model = self._convert_quantizable(model, FLOAT_TO_TRUE_QUANT_MAPPING, inplace) if remove_qconfig: self._remove_qconfig_from_quantizable(model) return model @@ -180,43 +182,67 @@ def _convert_quantizable(self, module: nn.Module, mapping: dict, inplace = True) for name, child_module in module.named_children(): if not isinstance(child_module, _FusedModule): # fused modules are swapped as one unit self._convert_quantizable(child_module, mapping, True) - reassign[name] = self._swap_module(child_module, mapping) + if type(child_module) in mapping: + reassign[name] = self._swap_module(child_module, mapping) for name, quantized_module in reassign.items(): - module._modules[name] = quantized_module + # module._modules[name] = quantized_module + delattr(module, name) + setattr(module, name, quantized_module) + # print(f"***{name}: {quantized_module}") + # print(eval(f"{module}.{name}")) return module def _attach_qconfig_to_quantizable(self, module: nn.Module): - for name, child_module in module.named_children: + module_qconfig = dict() + module_reassign = dict() + for name, child_module in module.named_children(): if isinstance(child_module, QuantModule): - qparams_config = child_module.get_quantization_params_config() - setattr(module, name, child_module.orig_module) - child_module.qconfig = QConfig( - weight = qparams_config['weight'], - activation = qparams_config['act'] - ) - child_module.add_module( - 'activation_post_process', - child_module.qconfig.activation() - ) + module_qconfig[name] = child_module.get_quantization_params_config() + module_reassign[name] = child_module.orig_module + # setattr(module, name, child_module.orig_module) + # child_module.qconfig = QConfig( + # weight = qparams_config['weight'], + # activation = qparams_config['act'] + # ) + # child_module.add_module( + # 'activation_post_process', + # child_module.qconfig.activation() + # ) elif isinstance(child_module, BaseQuantBlock): child_module.convert_to_quantizable_with_config() else: self._attach_qconfig_to_quantizable(child_module) + for name in module_reassign.keys(): + delattr(module, name) + setattr(module, name, module_reassign[name]) + submodule = getattr(module, name) + if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig + setattr(submodule[0], "qconfig", QConfig( + weight = module_qconfig[name]["weight"], + activation = None)) + setattr(submodule, "qconfig", QConfig( + weight = module_qconfig[name]["weight"], + activation = module_qconfig[name]["act"] + )) + submodule.add_module("activation_post_process", submodule.qconfig.activation()) def _remove_qconfig_from_quantizable(self, module: nn.Module): for child_module in module.children(): self._remove_qconfig_from_quantizable(child_module) - if hasattr(module, 'activation_post_process'): - delattr(module, 'activation_post_process') + # if hasattr(module, 'activation_post_process'): + # delattr(module, 'activation_post_process') if hasattr(module, 'qconfig'): delattr(module, 'qconfig') def _swap_module(self, module: nn.Module, mapping: dict): new_module = module + swapped = False if hasattr(module, 'qconfig') and module.qconfig is not None: swapped = False if _type(module) in mapping: - new_module = mapping[_type(module)].from_float(module) + qmod = mapping[_type(module)] + new_module = qmod.from_float(module) + print(f"swapped {type(module)}: {type(new_module)}") swapped = True if swapped: pass #TODO: hook management From a12445240a00694d8ac4acdc1487c1f5e8034053 Mon Sep 17 00:00:00 2001 From: sydarb Date: Wed, 6 Sep 2023 00:00:59 +0530 Subject: [PATCH 21/35] made test progress bar as optional --- trailmet/algorithms/algorithms.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/trailmet/algorithms/algorithms.py b/trailmet/algorithms/algorithms.py index 6b63cf1..bee4926 100644 --- a/trailmet/algorithms/algorithms.py +++ b/trailmet/algorithms/algorithms.py @@ -180,7 +180,7 @@ def accuracy(self, output, target, topk=(1, )): res.append(correct_k.mul_(100.0 / batch_size)) return res - def test(self, model, dataloader, loss_fn=None, device=None): + def test(self, model, dataloader, loss_fn=None, device=None, progress=True): """This method is used to test the performance of the trained model.""" if device is None: device = next(model.parameters()).device @@ -188,12 +188,12 @@ def test(self, model, dataloader, loss_fn=None, device=None): model.to(device) model.eval() counter = 0 - tk1 = tqdm_notebook(dataloader, total=len(dataloader)) running_acc1 = 0 running_acc5 = 0 running_loss = 0 + pbar = tqdm_notebook(dataloader, total=len(dataloader)) if progress else dataloader with torch.no_grad(): - for images, targets in tk1: + for images, targets in pbar: counter += 1 images = images.to(device) targets = targets.to(device) @@ -204,13 +204,15 @@ def test(self, model, dataloader, loss_fn=None, device=None): if loss_fn is not None: loss = loss_fn(outputs, targets) running_loss += loss.item() - tk1.set_postfix( - loss=running_loss / counter, - acc1=running_acc1 / counter, - acc5=running_acc5 / counter, - ) + if progress: + pbar.set_postfix( + loss=running_loss / counter, + acc1=running_acc1 / counter, + acc5=running_acc5 / counter, + ) else: - tk1.set_postfix(acc1=running_acc1 / counter, + if progress: + pbar.set_postfix(acc1=running_acc1 / counter, acc5=running_acc5 / counter) if loss_fn is not None: return running_acc1 / counter, running_loss / counter From 1fde13eb52809dbfe2c1185539b8e76fc3ce792c Mon Sep 17 00:00:00 2001 From: sydarb Date: Wed, 6 Sep 2023 01:50:13 +0530 Subject: [PATCH 22/35] modified quant dtype with reduced byte length --- trailmet/algorithms/quantize/utils.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/trailmet/algorithms/quantize/utils.py b/trailmet/algorithms/quantize/utils.py index 5ba96da..bdcc57f 100644 --- a/trailmet/algorithms/quantize/utils.py +++ b/trailmet/algorithms/quantize/utils.py @@ -46,11 +46,15 @@ def get_qscheme(per_channel=False, symmetric=False): else: return torch.per_tensor_affine -def get_dtype(quant_min: int, quant_max: int): - # bit capacity for qint and quint is reduced by 1 for 'x86' backend - if quant_min>=0 and quant_max<=127: +def get_dtype(quant_min: int, quant_max: int, reduce_range: bool = True): + # byte width for qint and quint is reduced by 1 for 'x86' backend + assert quant_min < quant_max + byte_width = 8 + if reduce_range: + byte_width = 7 + if quant_min >= 0 and quant_max < (2**byte_width): return torch.quint8 - elif quant_min>=-64 and quant_max<=63: + elif quant_min >= -(2**(byte_width-1)) and quant_max < (2**(byte_width-1)): return torch.qint8 else: return torch.qint32 From e31290ec2d86447c219f203d23e80c87ef98609b Mon Sep 17 00:00:00 2001 From: sydarb Date: Wed, 6 Sep 2023 14:45:47 +0530 Subject: [PATCH 23/35] made base mobilenetv2 model class cleaner --- trailmet/models/mobilenet.py | 144 ++++++++++++++++------------------- 1 file changed, 67 insertions(+), 77 deletions(-) diff --git a/trailmet/models/mobilenet.py b/trailmet/models/mobilenet.py index 1e3c3f5..53a68d0 100644 --- a/trailmet/models/mobilenet.py +++ b/trailmet/models/mobilenet.py @@ -38,49 +38,54 @@ class InvertedResidual(nn.Module): """Expand + depthwise + pointwise.""" - def __init__(self, in_planes, out_planes, expansion, stride): + def __init__(self, in_planes: int, out_planes: int, expansion: int, stride: int): super(InvertedResidual, self).__init__() + if stride not in [1, 2]: + raise ValueError(f"stride should be either 1 or 2 instead of {stride}") self.stride = stride self.is_shortcut = False planes = expansion * in_planes - self.conv1 = nn.Conv2d(in_planes, - planes, - kernel_size=1, - stride=1, - padding=0, - bias=False) - self.bn1 = nn.BatchNorm2d(planes) - # self.conv1, self.bn1 = ModuleInjection.make_prunable(self.conv1, self.bn1) + self.conv1 = nn.Conv2d( + in_channels=in_planes, + out_channels=planes, + kernel_size=1, + stride=1, + padding=0, + bias=False + ) + self.bn1 = nn.BatchNorm2d(num_features=planes) self.conv2 = nn.Conv2d( - planes, - planes, + in_channels=planes, + out_channels=planes, kernel_size=3, - stride=stride, - padding=1, - groups=planes, - bias=False, + stride=stride, + padding=1, + groups=planes, + bias=False + ) + self.bn2 = nn.BatchNorm2d(num_features=planes) + self.conv3 = nn.Conv2d( + in_channels=planes, + out_channels=out_planes, + kernel_size=1, + stride=1, + padding=0, + bias=False ) - self.bn2 = nn.BatchNorm2d(planes) - self.conv3 = nn.Conv2d(planes, - out_planes, - kernel_size=1, - stride=1, - padding=0, - bias=False) - self.bn3 = nn.BatchNorm2d(out_planes) - # self.conv3, self.bn3 = ModuleInjection.make_prunable(self.conv3, self.bn3) + self.bn3 = nn.BatchNorm2d(num_features=out_planes) self.shortcut = nn.Sequential() if stride == 1 and in_planes != out_planes: self.is_shortcut = True - conv_module = nn.Conv2d(in_planes, - out_planes, - kernel_size=1, - stride=1, - padding=0, - bias=False) - bn_module = nn.BatchNorm2d(out_planes) - # conv_module, bn_module = ModuleInjection.make_prunable(conv_module, bn_module) + conv_module = nn.Conv2d( + in_channels=in_planes, + out_channels=out_planes, + kernel_size=1, + stride=1, + padding=0, + bias=False + ) + bn_module = nn.BatchNorm2d(num_features=out_planes) if hasattr(bn_module, 'is_imp'): bn_module.is_imp = True self.shortcut = nn.Sequential(conv_module, bn_module) @@ -131,10 +136,10 @@ def get_flops(self, inp): class MobileNetv2(BaseModel): - # (expansion, out_planes, num_blocks, stride) + # CFG -> (expansion, out_planes, num_blocks, stride) cfg = [ (1, 16, 1, 1), - (6, 24, 2, 2), # NOTE: change stride 2 -> 1 for CIFAR10 + (6, 24, 2, 2), # NOTE: change layers[1] stride 2->1 for CIFAR10 (6, 32, 3, 2), (6, 64, 4, 2), (6, 96, 3, 1), @@ -142,36 +147,39 @@ class MobileNetv2(BaseModel): (6, 320, 1, 1), ] - def __init__(self, num_classes=10, cfg=None): + def __init__(self, num_classes, cfg=None): super(MobileNetv2, self).__init__() if cfg: + if len(cfg)==0 or len(cfg[0])!=4: + raise ValueError(f"cfg should be a 4-element list, got {cfg}") self.cfg = cfg - # NOTE: change conv1 stride 2 -> 1 for CIFAR10 - self.conv1 = nn.Conv2d(3, - 32, - kernel_size=3, - stride=2, - padding=1, - bias=False) - self.bn1 = nn.BatchNorm2d(32) - # self.conv1, self.bn1 = ModuleInjection.make_prunable(self.conv1, self.bn1) + self.conv1 = nn.Conv2d( + in_channels=3, + out_channels=32, + kernel_size=3, + stride=2, # NOTE: change conv1 stride 2->1 for CIFAR10 + padding=1, + bias=False + ) + self.bn1 = nn.BatchNorm2d(num_features=32) if hasattr(self.bn1, 'is_imp'): self.bn1.is_imp = True self.layers = self._make_layers(in_planes=32) - self.conv2 = nn.Conv2d(self.cfg[-1][1], - 1280, - kernel_size=1, - stride=2, - padding=0, - bias=False) - self.bn2 = nn.BatchNorm2d(1280) - # self.conv2, self.bn2 = ModuleInjection.make_prunable(self.conv2, self.bn2) + self.conv2 = nn.Conv2d( + in_channels=self.cfg[-1][1], + out_channels=1280, + kernel_size=1, + stride=2, + padding=0, + bias=False + ) + self.bn2 = nn.BatchNorm2d(num_features=1280) if hasattr(self.bn2, 'is_imp'): self.bn2.is_imp = True self.avgpool = nn.AdaptiveAvgPool2d(output_size=1) self.linear = nn.Linear(1280, num_classes) - def _make_layers(self, in_planes): + def _make_layers(self, in_planes: int): layers = [] for expansion, out_planes, num_blocks, stride in self.cfg: strides = [stride] + [1] * (num_blocks - 1) @@ -181,16 +189,19 @@ def _make_layers(self, in_planes): in_planes = out_planes return nn.Sequential(*layers) - def forward(self, x): + # TorchScript doesn't support inheritance, so the superclass method should have + # name other than 'forward' that can be accessed in a subclass + def _forward_impl(self, x: torch.Tensor) -> torch.Tensor: out = F.relu(self.bn1(self.conv1(x))) out = self.layers(out) out = F.relu(self.bn2(self.conv2(out))) - # NOTE: change pooling kernel_size 7 -> 4 for CIFAR10 - # out = F.avg_pool2d(out, 7) out = self.avgpool(out) out = out.view(out.size(0), -1) out = self.linear(out) return out + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self._forward_impl(x) def get_flops(self, insize): flops = 0 @@ -222,24 +233,6 @@ def get_flops(self, insize): flops += (1 + self.linear.in_features) * self.linear.out_features return flops - def removable_orphans(self): - num_removed = 0 - for b in self.layers: - m1, m2 = b.bn1, b.bn3 - if self.is_all_pruned(m1) or self.is_all_pruned(m2): - num_removed += self.n_remaining(m1) + self.n_remaining(m2) - return num_removed - - def remove_orphans(self): - num_removed = 0 - for b in self.layers: - m1, m2 = b.bn1, b.bn3 - if self.is_all_pruned(m1) or self.is_all_pruned(m2): - num_removed += self.n_remaining(m1) + self.n_remaining(m2) - m1.pruned_zeta.data.copy_(torch.zeros_like(m1.pruned_zeta)) - m2.pruned_zeta.data.copy_(torch.zeros_like(m2.pruned_zeta)) - return num_removed - def get_mobilenet(model, num_classes, cfg=None): """Returns the requested model, ready for training/pruning with the @@ -250,9 +243,6 @@ def get_mobilenet(model, num_classes, cfg=None): :param num_classes: int, num classes in the dataset :return: A prunable MobileNet model """ - # ModuleInjection.pruning_method = method - # ModuleInjection.prunable_modules = [] if model == 'mobilenetv2': net = MobileNetv2(num_classes, cfg) - # net.prunable_modules = ModuleInjection.prunable_modules return net From 3c9b170c8cee0a8315b35efbe0c6ac50e22e486e Mon Sep 17 00:00:00 2001 From: sydarb Date: Wed, 6 Sep 2023 19:32:41 +0530 Subject: [PATCH 24/35] fixed quant module refactor bugs --- trailmet/algorithms/quantize/modules.py | 31 ++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index 7a19b4f..d10ffd3 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -import copy import torch import torch.nn as nn import torch.nn.functional as F @@ -40,7 +39,7 @@ 'QuantBasicblock', 'QuantBottleneck', 'QuantInvertedResidual', - # legacy modules soon to be phased out + # old modules kept temporarily for BC 'QModule', 'BaseQBlock', 'QBasicblock' @@ -162,7 +161,8 @@ def get_quantization_params_config(self): ), dtype = get_dtype( quant_min = qparams['quant_min'], - quant_max = qparams['quant_max'] + quant_max = qparams['quant_max'], + reduce_range = qparams['reduce_range'] ), quant_min = qparams['quant_min'], quant_max = qparams['quant_max'], @@ -225,24 +225,23 @@ def __init__(self, bottleneck: Bottleneck, weight_qparams: dict, act_qparams: di # assuming all bn and relu are fused in conv self.weight_qparams = weight_qparams self.act_qparams = act_qparams - # self.orig_module = bottleneck - self.quant_conv1 = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d - self.quant_conv2 = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d + self.quant_conv1_relu = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d + self.quant_conv2_relu = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d self.quant_conv3 = QuantModule(bottleneck.conv3, weight_qparams, act_qparams) # ConvReLU2d if bottleneck.downsample is not None: self.quant_downsample = QuantModule(bottleneck.downsample[0], weight_qparams, act_qparams) # Conv2d else: self.quant_downsample = None - self.residual_add_out = nnq.FloatFunctional() + self.quant_add_skip = nnq.FloatFunctional() def forward(self, x: torch.Tensor): - residual = x - out = self.quant_conv1(x) - out = self.quant_conv2(out) + skip = x + out = self.quant_conv1_relu(x) + out = self.quant_conv2_relu(out) out = self.quant_conv3(out) if self.quant_downsample is not None: - residual = self.quant_downsample(x) - out = self.residual_add_out.add_relu(out, residual) + skip = self.quant_downsample(skip) + out = self.quant_add_skip.add_relu(out, skip) if self.disable_fake_quantization: return out if self.use_act_quant: @@ -253,19 +252,19 @@ def convert_to_quantizable_with_config(self): super().convert_to_quantizable_with_config(self) self.disable_fake_quantization = True act_qparams = self.act_quantizer.get_qparams() #TODO - self.residual_add_out.qconfig = QConfig( + self.quant_add_skip.qconfig = QConfig( weight=None, activation = FixedQParamsObserver.with_args( qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), - dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max']), + dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max'], act_qparams['reduce_range']), quant_min = act_qparams['quant_min'], quant_max = act_qparams['quant_max'], scale = act_qparams['scale'], zero_point = act_qparams['zero_point'] ) ) - self.residual_add_out.add_module("activation_post_process", - self.residual_add_out.qconfig.activation()) + self.quant_add_skip.add_module("activation_post_process", + self.quant_add_skip.qconfig.activation()) class QuantInvertedResidual(BaseQuantBlock): From 7765fd5763d94962aef4289f1d319f6e1ea69562 Mon Sep 17 00:00:00 2001 From: sydarb Date: Wed, 6 Sep 2023 20:07:43 +0530 Subject: [PATCH 25/35] added quantized basicblock --- trailmet/algorithms/quantize/modules.py | 334 ++++++------------------ 1 file changed, 73 insertions(+), 261 deletions(-) diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index d10ffd3..bc864f7 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -40,14 +40,9 @@ 'QuantBottleneck', 'QuantInvertedResidual', # old modules kept temporarily for BC - 'QModule', - 'BaseQBlock', 'QBasicblock' 'QBottleneck', 'QInvertedResidual', - '_QBasicBlock', - '_QBottleneck', - '_QInvertedResidual' ] class StraightThrough(nn.Module): @@ -171,23 +166,27 @@ def get_quantization_params_config(self): ) return fixed_qparams_config - + + class BaseQuantBlock(nn.Module): - def __init__(self, act_quant_params: dict = {}) -> None: + def __init__(self, act_qparams: dict = {}) -> None: super().__init__() self.use_act_quant = False - self.act_quantizer = act_quant_params.get( - 'method', UniformAffineQuantizer)(**act_quant_params) - self.disable_fake_quantization = False + self.act_quantizer = act_qparams.get( + 'method', UniformAffineQuantizer)(**act_qparams) + self._fake_quantization = True self.ignore_reconstruction = False + def set_quantization_state(self, weight: bool = False, act: bool = False): self.use_act_quant = act for module in self.modules(): if isinstance(module, QuantModule): module.set_quantization_state(weight, act) + def convert_to_quantizable_with_config(self, module: nn.Module): + self._fake_quantization = False module_qparams = dict() module_reassign = dict() for name, child_module in module.named_modules(): @@ -199,6 +198,7 @@ def convert_to_quantizable_with_config(self, module: nn.Module): setattr(module, name, orig_module) self._attach_qconfig_to_quantizable(module, module_qparams) + def _attach_qconfig_to_quantizable(self, module: nn.Module, module_qparams: dict): for name, qparams in module_qparams.items(): submodule = getattr(module, name, None) @@ -214,45 +214,35 @@ def _attach_qconfig_to_quantizable(self, module: nn.Module, module_qparams: dict submodule.add_module("activation_post_process", submodule.qconfig.activation()) -class QuantBasicBlock(BaseQuantBlock): - def __init__(self, act_quant_params: dict = {}) -> None: - super().__init__(act_quant_params) - -class QuantBottleneck(BaseQuantBlock): - def __init__(self, bottleneck: Bottleneck, weight_qparams: dict, act_qparams: dict) -> None: +class QuantBasicBlock(BaseQuantBlock): + def __init__(self, basicblock: BasicBlock, weight_qparams: dict, act_qparams: dict): super().__init__(act_qparams) - # assuming all bn and relu are fused in conv - self.weight_qparams = weight_qparams - self.act_qparams = act_qparams - self.quant_conv1_relu = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d - self.quant_conv2_relu = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d - self.quant_conv3 = QuantModule(bottleneck.conv3, weight_qparams, act_qparams) # ConvReLU2d - if bottleneck.downsample is not None: - self.quant_downsample = QuantModule(bottleneck.downsample[0], weight_qparams, act_qparams) # Conv2d + # assuming all bn and relu are fused in conv + self.conv1 = QuantModule(basicblock.conv1, weight_qparams, act_qparams) + self.conv2 = QuantModule(basicblock.conv2, weight_qparams, act_qparams) + if basicblock.downsample is not None: + self.downsample = QuantModule(basicblock.downsample[0], weight_qparams, act_qparams) else: - self.quant_downsample = None - self.quant_add_skip = nnq.FloatFunctional() - - def forward(self, x: torch.Tensor): - skip = x - out = self.quant_conv1_relu(x) - out = self.quant_conv2_relu(out) - out = self.quant_conv3(out) - if self.quant_downsample is not None: - skip = self.quant_downsample(skip) - out = self.quant_add_skip.add_relu(out, skip) - if self.disable_fake_quantization: - return out - if self.use_act_quant: + self.downsample = None + self.add_skip = nnq.FloatFunctional() + + + def forward(self, inp: torch.Tensor) -> torch.Tensor: + skip = inp if self.downsample is None else self.downsample(inp) + out = self.conv1(inp) + out = self.conv2(out) + out = self.add_skip.add_relu(out, skip) + if self._fake_quantization and self.use_act_quant: out = self.act_quantizer(out) return out + def convert_to_quantizable_with_config(self): super().convert_to_quantizable_with_config(self) - self.disable_fake_quantization = True - act_qparams = self.act_quantizer.get_qparams() #TODO - self.quant_add_skip.qconfig = QConfig( + self._fake_quantization = False + act_qparams = self.act_quantizer.get_qparams() + self.add_skip.qconfig = QConfig( weight=None, activation = FixedQParamsObserver.with_args( qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), @@ -263,243 +253,65 @@ def convert_to_quantizable_with_config(self): zero_point = act_qparams['zero_point'] ) ) - self.quant_add_skip.add_module("activation_post_process", - self.quant_add_skip.qconfig.activation()) - - -class QuantInvertedResidual(BaseQuantBlock): - def __init__(self, act_quant_params: dict = {}) -> None: - super().__init__(act_quant_params) - + self.add_skip.add_module("activation_post_process", + self.add_skip.qconfig.activation()) -#============================================ -#***** Quantization Modules for BRECQ ******* -#============================================ -""" -Supported quantization wrappers for pytorch modules :- - - BasicBlock(nn.Module) -> QuantBasicBlock(BaseQuantBlock(nn.Module)) - - Bottleneck(nn.Module) -> QuantBottleneck(BaseQuantBlock(nn.Module)) - - InvertedResidual(nn.Module) -> QuantInvertedResidual(BaseQuantBlock(nn.Module)) - - nn.Conv2d, nn.Linear -> QuantModule(nn.Module) -""" -class QModule(nn.Module): - """ - Quantized Module that can perform quantized convolution or normal convolution. - To activate quantization, please use set_quant_state function. - """ - def __init__(self, org_module: Union[nn.Conv2d, nn.Linear], weight_quant_params: dict = {}, - act_quant_params: dict = {}, disable_act_quant: bool = False, se_module = None): - super(QModule, self).__init__() - if isinstance(org_module, nn.Conv2d): - self.fwd_kwargs = dict(stride=org_module.stride, padding=org_module.padding, - dilation=org_module.dilation, groups=org_module.groups) - self.fwd_func = F.conv2d - else: - self.fwd_kwargs = dict() - self.fwd_func = F.linear - self.weight = org_module.weight - self.org_weight = org_module.weight.data.clone() - if org_module.bias is not None: - self.bias = org_module.bias - self.org_bias = org_module.bias.data.clone() +class QuantBottleneck(BaseQuantBlock): + def __init__(self, bottleneck: Bottleneck, weight_qparams: dict, act_qparams: dict) -> None: + super().__init__(act_qparams) + # assuming all bn and relu are fused in conv + self.conv1 = QuantModule(bottleneck.conv1, weight_qparams, act_qparams) # ConvReLU2d + self.conv2 = QuantModule(bottleneck.conv2, weight_qparams, act_qparams) # ConvReLU2d + self.conv3 = QuantModule(bottleneck.conv3, weight_qparams, act_qparams) # ConvReLU2d + if bottleneck.downsample is not None: + self.downsample = QuantModule(bottleneck.downsample[0], weight_qparams, act_qparams) # Conv2d else: - self.bias = None - self.org_bias = None - - # de-activate the quantized forward default - self.use_weight_quant = False - self.use_act_quant = False - self.disable_act_quant = disable_act_quant + self.downsample = None + self.add_skip = nnq.FloatFunctional() - # initialize quantizer - self.weight_quantizer = weight_quant_params.get('method', UniformAffineQuantizer)(**weight_quant_params) - self.act_quantizer = act_quant_params.get('method', UniformAffineQuantizer)(**act_quant_params) - - self.activation_function = StraightThrough() - self.ignore_reconstruction = False - - self.se_module = se_module - self.extra_repr = org_module.extra_repr - def forward(self, input: torch.Tensor): - if self.use_weight_quant: - weight = self.weight_quantizer(self.weight) - bias = self.bias - else: - weight = self.org_weight - bias = self.org_bias - out = self.fwd_func(input, weight, bias, **self.fwd_kwargs) - # disable act quantization is designed for convolution before elemental-wise operation, - # in that case, we apply activation function and quantization after ele-wise op. - if self.se_module is not None: - out = self.se_module(out) - out = self.activation_function(out) - if self.disable_act_quant: - return out - if self.use_act_quant: + def forward(self, inp: torch.Tensor) -> torch.Tensor: + skip = inp if self.downsample is None else self.downsample(inp) + out = self.conv1(inp) + out = self.conv2(out) + out = self.conv3(out) + out = self.add_skip.add_relu(out, skip) + if self._fake_quantization and self.use_act_quant: out = self.act_quantizer(out) return out - def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): - self.use_weight_quant = weight_quant - self.use_act_quant = act_quant - - -class BaseQBlock(nn.Module): - """ - Base implementation of block structures for all networks. - Due to the branch architecture, we have to perform activation function - and quantization after the elemental-wise add operation, therefore, we - put this part in this class. - """ - def __init__(self, act_quant_params: dict = {}): - super().__init__() - self.use_weight_quant = False - self.use_act_quant = False - self.act_quantizer = act_quant_params.get('method', UniformAffineQuantizer)(**act_quant_params) - self.activation_function = StraightThrough() - self.ignore_reconstruction = False - - def set_quant_state(self, weight_quant: bool = False, act_quant: bool = False): - # setting weight quantization here does not affect actual forward pass - self.use_weight_quant = weight_quant - self.use_act_quant = act_quant - for m in self.modules(): - if isinstance(m, QModule): - m.set_quant_state(weight_quant, act_quant) -class QBasicBlock(BaseQBlock): - """ - Implementation of Quantized BasicBlock used in ResNet-18 and ResNet-34. - """ - def __init__(self, basic_block: BasicBlock, weight_quant_params: dict = {}, act_quant_params: dict = {}): - super().__init__(act_quant_params) - self.conv1 = QModule(basic_block.conv1, weight_quant_params, act_quant_params) - self.conv1.activation_function = basic_block.activ - self.conv2 = QModule(basic_block.conv2, weight_quant_params, act_quant_params, disable_act_quant=True) - self.activation_function = basic_block.activ + def convert_to_quantizable_with_config(self): + super().convert_to_quantizable_with_config(self) + self._fake_quantization = False + act_qparams = self.act_quantizer.get_qparams() + self.add_skip.qconfig = QConfig( + weight=None, + activation = FixedQParamsObserver.with_args( + qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), + dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max'], act_qparams['reduce_range']), + quant_min = act_qparams['quant_min'], + quant_max = act_qparams['quant_max'], + scale = act_qparams['scale'], + zero_point = act_qparams['zero_point'] + ) + ) + self.add_skip.add_module("activation_post_process", + self.add_skip.qconfig.activation()) - if basic_block.downsample is None: - self.downsample = None - else: - self.downsample = QModule(basic_block.downsample[0], weight_quant_params, act_quant_params, - disable_act_quant=True) - # copying all attributes in original block - self.stride = basic_block.stride - def forward(self, x): - residual = x if self.downsample is None else self.downsample(x) - out = self.conv1(x) - out = self.conv2(out) - out += residual - out = self.activation_function(out) - if self.use_act_quant: - out = self.act_quantizer(out) - return out -class QBottleneck(BaseQBlock): - """ - Implementation of Quantized Bottleneck Block used in ResNet-50, -101 and -152. - """ - - def __init__(self, bottleneck: Bottleneck, weight_quant_params: dict = {}, act_quant_params: dict = {}): +class QuantInvertedResidual(BaseQuantBlock): + def __init__(self, act_quant_params: dict = {}) -> None: super().__init__(act_quant_params) - self.conv1 = QModule(bottleneck.conv1, weight_quant_params, act_quant_params) - self.conv1.activation_function = bottleneck.activ - self.conv2 = QModule(bottleneck.conv2, weight_quant_params, act_quant_params) - self.conv2.activation_function = bottleneck.activ - self.conv3 = QModule(bottleneck.conv3, weight_quant_params, act_quant_params, disable_act_quant=True) - # modify the activation function to ReLU - self.activation_function = bottleneck.activ - - if bottleneck.downsample is None: - self.downsample = None - else: - self.downsample = QModule(bottleneck.downsample[0], weight_quant_params, act_quant_params, - disable_act_quant=True) - # copying all attributes in original block - self.stride = bottleneck.stride - def forward(self, x): - residual = x if self.downsample is None else self.downsample(x) - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - out += residual - out = self.activation_function(out) - if self.use_act_quant: - out = self.act_quantizer(out) - return out -class QInvertedResidual(BaseQBlock): - """ - Implementation of Quantized Inverted Residual Block used in MobileNetV2. - Inverted Residual does not have activation function. - """ - def __init__(self, inv_res: InvertedResidual, weight_quant_params: dict = {}, act_quant_params: dict = {}): - super().__init__(act_quant_params) - self.stride = inv_res.stride - self.inp = inv_res.inp - self.oup = inv_res.oup - self.exp = inv_res.exp - self.conv1 = QModule(inv_res.conv1, weight_quant_params, act_quant_params) - self.conv1.activation_function = nn.ReLU6(inplace=True) - self.conv2 = QModule(inv_res.conv2, weight_quant_params, act_quant_params) - self.conv2.activation_function = nn.ReLU6(inplace=True) - self.conv3 = QModule(inv_res.conv3, weight_quant_params, act_quant_params) - self.shortcut = nn.Sequential() - if self.stride==1 and self.inp!=self.oup: - self.shortcut = nn.Sequential( - QModule(inv_res.shortcut[0], weight_quant_params, act_quant_params) - ) - # self.use_res_connect = inv_res.use_res_connect - # self.expand_ratio = inv_res.exp - # if self.expand_ratio == 1: - # self.conv = nn.Sequential( - # QModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QModule(inv_res.conv[3], weight_quant_params, act_quant_params, disable_act_quant=True), - # ) - # self.conv[0].activation_function = nn.ReLU6() - # else: - # self.conv = nn.Sequential( - # QModule(inv_res.conv[0], weight_quant_params, act_quant_params), - # QModule(inv_res.conv[3], weight_quant_params, act_quant_params), - # QModule(inv_res.conv[6], weight_quant_params, act_quant_params, disable_act_quant=True), - # ) - # self.conv[0].activation_function = nn.ReLU6() - # self.conv[1].activation_function = nn.ReLU6() - def forward(self, x): - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - out = out + self.shortcut(x) if self.stride==1 else out - return out - # if self.use_res_connect: - # out = x + self.conv(x) - # else: - # out = self.conv(x) - # out = self.activation_function(out) - # if self.use_act_quant: - # out = self.act_quantizer(out) - # return out - - -#=============================================== -#***** Quantization Modules for BitSplit ******* -#=============================================== -""" -Supported quantization wrappers for pytorch modules :- - - BasicBlock(nn.Module) -> QBasicBlock(nn.Module) - - Bottleneck(nn.Module) -> QBottleneck(nn.Module) - - InvertedResidual(nn.Module) -> QInvertedResidual(nn.Module) -""" - -class _QBasicBlock(nn.Module): +class QBasicBlock(nn.Module): expansion = 1 def __init__(self, basic_block: BasicBlock): super().__init__() @@ -526,7 +338,7 @@ def forward(self, x): return out -class _QBottleneck(nn.Module): +class QBottleneck(nn.Module): expansion = 4 def __init__(self, bottleneck: Bottleneck): super().__init__() @@ -558,7 +370,7 @@ def forward(self, x): return out -class _QInvertedResidual(nn.Module): +class QInvertedResidual(nn.Module): def __init__(self, inv_res: InvertedResidual): super().__init__() self.stride = inv_res.stride From ec445c9920924ceb5d45d971216a671784574d6d Mon Sep 17 00:00:00 2001 From: sydarb Date: Thu, 7 Sep 2023 00:43:43 +0530 Subject: [PATCH 26/35] Revert "made base mobilenetv2 model class cleaner" This reverts commit e31290ec2d86447c219f203d23e80c87ef98609b. --- trailmet/models/mobilenet.py | 144 +++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 67 deletions(-) diff --git a/trailmet/models/mobilenet.py b/trailmet/models/mobilenet.py index 53a68d0..1e3c3f5 100644 --- a/trailmet/models/mobilenet.py +++ b/trailmet/models/mobilenet.py @@ -38,54 +38,49 @@ class InvertedResidual(nn.Module): """Expand + depthwise + pointwise.""" - def __init__(self, in_planes: int, out_planes: int, expansion: int, stride: int): + def __init__(self, in_planes, out_planes, expansion, stride): super(InvertedResidual, self).__init__() - if stride not in [1, 2]: - raise ValueError(f"stride should be either 1 or 2 instead of {stride}") self.stride = stride self.is_shortcut = False planes = expansion * in_planes - self.conv1 = nn.Conv2d( - in_channels=in_planes, - out_channels=planes, - kernel_size=1, - stride=1, - padding=0, - bias=False - ) - self.bn1 = nn.BatchNorm2d(num_features=planes) + self.conv1 = nn.Conv2d(in_planes, + planes, + kernel_size=1, + stride=1, + padding=0, + bias=False) + self.bn1 = nn.BatchNorm2d(planes) + # self.conv1, self.bn1 = ModuleInjection.make_prunable(self.conv1, self.bn1) self.conv2 = nn.Conv2d( - in_channels=planes, - out_channels=planes, + planes, + planes, kernel_size=3, - stride=stride, - padding=1, - groups=planes, - bias=False - ) - self.bn2 = nn.BatchNorm2d(num_features=planes) - self.conv3 = nn.Conv2d( - in_channels=planes, - out_channels=out_planes, - kernel_size=1, - stride=1, - padding=0, - bias=False + stride=stride, + padding=1, + groups=planes, + bias=False, ) - self.bn3 = nn.BatchNorm2d(num_features=out_planes) + self.bn2 = nn.BatchNorm2d(planes) + self.conv3 = nn.Conv2d(planes, + out_planes, + kernel_size=1, + stride=1, + padding=0, + bias=False) + self.bn3 = nn.BatchNorm2d(out_planes) + # self.conv3, self.bn3 = ModuleInjection.make_prunable(self.conv3, self.bn3) self.shortcut = nn.Sequential() if stride == 1 and in_planes != out_planes: self.is_shortcut = True - conv_module = nn.Conv2d( - in_channels=in_planes, - out_channels=out_planes, - kernel_size=1, - stride=1, - padding=0, - bias=False - ) - bn_module = nn.BatchNorm2d(num_features=out_planes) + conv_module = nn.Conv2d(in_planes, + out_planes, + kernel_size=1, + stride=1, + padding=0, + bias=False) + bn_module = nn.BatchNorm2d(out_planes) + # conv_module, bn_module = ModuleInjection.make_prunable(conv_module, bn_module) if hasattr(bn_module, 'is_imp'): bn_module.is_imp = True self.shortcut = nn.Sequential(conv_module, bn_module) @@ -136,10 +131,10 @@ def get_flops(self, inp): class MobileNetv2(BaseModel): - # CFG -> (expansion, out_planes, num_blocks, stride) + # (expansion, out_planes, num_blocks, stride) cfg = [ (1, 16, 1, 1), - (6, 24, 2, 2), # NOTE: change layers[1] stride 2->1 for CIFAR10 + (6, 24, 2, 2), # NOTE: change stride 2 -> 1 for CIFAR10 (6, 32, 3, 2), (6, 64, 4, 2), (6, 96, 3, 1), @@ -147,39 +142,36 @@ class MobileNetv2(BaseModel): (6, 320, 1, 1), ] - def __init__(self, num_classes, cfg=None): + def __init__(self, num_classes=10, cfg=None): super(MobileNetv2, self).__init__() if cfg: - if len(cfg)==0 or len(cfg[0])!=4: - raise ValueError(f"cfg should be a 4-element list, got {cfg}") self.cfg = cfg - self.conv1 = nn.Conv2d( - in_channels=3, - out_channels=32, - kernel_size=3, - stride=2, # NOTE: change conv1 stride 2->1 for CIFAR10 - padding=1, - bias=False - ) - self.bn1 = nn.BatchNorm2d(num_features=32) + # NOTE: change conv1 stride 2 -> 1 for CIFAR10 + self.conv1 = nn.Conv2d(3, + 32, + kernel_size=3, + stride=2, + padding=1, + bias=False) + self.bn1 = nn.BatchNorm2d(32) + # self.conv1, self.bn1 = ModuleInjection.make_prunable(self.conv1, self.bn1) if hasattr(self.bn1, 'is_imp'): self.bn1.is_imp = True self.layers = self._make_layers(in_planes=32) - self.conv2 = nn.Conv2d( - in_channels=self.cfg[-1][1], - out_channels=1280, - kernel_size=1, - stride=2, - padding=0, - bias=False - ) - self.bn2 = nn.BatchNorm2d(num_features=1280) + self.conv2 = nn.Conv2d(self.cfg[-1][1], + 1280, + kernel_size=1, + stride=2, + padding=0, + bias=False) + self.bn2 = nn.BatchNorm2d(1280) + # self.conv2, self.bn2 = ModuleInjection.make_prunable(self.conv2, self.bn2) if hasattr(self.bn2, 'is_imp'): self.bn2.is_imp = True self.avgpool = nn.AdaptiveAvgPool2d(output_size=1) self.linear = nn.Linear(1280, num_classes) - def _make_layers(self, in_planes: int): + def _make_layers(self, in_planes): layers = [] for expansion, out_planes, num_blocks, stride in self.cfg: strides = [stride] + [1] * (num_blocks - 1) @@ -189,19 +181,16 @@ def _make_layers(self, in_planes: int): in_planes = out_planes return nn.Sequential(*layers) - # TorchScript doesn't support inheritance, so the superclass method should have - # name other than 'forward' that can be accessed in a subclass - def _forward_impl(self, x: torch.Tensor) -> torch.Tensor: + def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layers(out) out = F.relu(self.bn2(self.conv2(out))) + # NOTE: change pooling kernel_size 7 -> 4 for CIFAR10 + # out = F.avg_pool2d(out, 7) out = self.avgpool(out) out = out.view(out.size(0), -1) out = self.linear(out) return out - - def forward(self, x: torch.Tensor) -> torch.Tensor: - return self._forward_impl(x) def get_flops(self, insize): flops = 0 @@ -233,6 +222,24 @@ def get_flops(self, insize): flops += (1 + self.linear.in_features) * self.linear.out_features return flops + def removable_orphans(self): + num_removed = 0 + for b in self.layers: + m1, m2 = b.bn1, b.bn3 + if self.is_all_pruned(m1) or self.is_all_pruned(m2): + num_removed += self.n_remaining(m1) + self.n_remaining(m2) + return num_removed + + def remove_orphans(self): + num_removed = 0 + for b in self.layers: + m1, m2 = b.bn1, b.bn3 + if self.is_all_pruned(m1) or self.is_all_pruned(m2): + num_removed += self.n_remaining(m1) + self.n_remaining(m2) + m1.pruned_zeta.data.copy_(torch.zeros_like(m1.pruned_zeta)) + m2.pruned_zeta.data.copy_(torch.zeros_like(m2.pruned_zeta)) + return num_removed + def get_mobilenet(model, num_classes, cfg=None): """Returns the requested model, ready for training/pruning with the @@ -243,6 +250,9 @@ def get_mobilenet(model, num_classes, cfg=None): :param num_classes: int, num classes in the dataset :return: A prunable MobileNet model """ + # ModuleInjection.pruning_method = method + # ModuleInjection.prunable_modules = [] if model == 'mobilenetv2': net = MobileNetv2(num_classes, cfg) + # net.prunable_modules = ModuleInjection.prunable_modules return net From 7afa24a68593a2ea4571573635b53a98f9087308 Mon Sep 17 00:00:00 2001 From: sydarb Date: Thu, 7 Sep 2023 00:46:33 +0530 Subject: [PATCH 27/35] fixed lapq bugs --- trailmet/algorithms/quantize/lapq.py | 181 ++++++++++++++--------- trailmet/algorithms/quantize/methods.py | 44 +++--- trailmet/algorithms/quantize/quantize.py | 2 +- 3 files changed, 130 insertions(+), 97 deletions(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index d673b12..a591843 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -31,6 +31,10 @@ from trailmet.algorithms.quantize.modules import QuantModule, BaseQuantBlock from trailmet.algorithms.quantize.methods import UniformSymmetricQuantizer, LpNormQuantizer +supported = [ + "resnet", + "mobilenetv2" +] class QuantModel(BaseQuantModel): def __init__(self, model: nn.Module, weight_quant_params: dict, act_quant_params: dict, @@ -61,129 +65,158 @@ def set_alphas_np(self, alphas: np.ndarray, weight=True, act=True): class LAPQ(BaseQuantization): - def __init__(self, model: nn.Module, dataloaders, **kwargs): + def __init__(self, network: str, dataloaders: dict, **kwargs): super(LAPQ, self).__init__(**kwargs) - self.model = model + if network not in supported: + raise ValueError(f"Network architecture '{network}' not in supported: {supported}") self.train_loader = dataloaders['train'] self.test_loader = dataloaders['test'] self.kwargs = kwargs - self.w_bits = kwargs.get('W_BITS', 8) - self.a_bits = kwargs.get('A_BITS', 8) - self.calib_batches = kwargs.get('CALIB_BATCHES', 16) - self.act_quant = kwargs.get('ACT_QUANT', True) - self.test_before_calibration = kwargs.get('DRY_RUN', True) - self.maxiter = kwargs.get('MAX_ITER', 1) - self.maxfev = kwargs.get('MAX_FEV', 1) - self.verbose = kwargs.get('VERBOSE', True) - self.print_freq = kwargs.get('PRINT_FREQ', 20) - self.gpu_id = kwargs.get('GPU_ID', 0) - self.seed = kwargs.get('SEED', 42) + self.w_bits = kwargs.get('w_bits', 8) + self.a_bits = kwargs.get('a_bits', 8) + self.reduce_range = kwargs.get('reduce_range', True) + self.fake_quantize = kwargs.get('fake_quantize', False) + self.calib_batches = kwargs.get('calib_batches', 16) + self.act_quant = kwargs.get('act_quant', True) + self.test_min_max_quant = kwargs.get('test_min_max_quant', True) + self.p_val = kwargs.get('p_val', None) + self.max_iter = kwargs.get('max_iter', 2000) + self.max_fev = kwargs.get('max_fev', 2000) + self.eval_freq = kwargs.get('eval_freq', 500) + self.verbose = kwargs.get('verbose', True) + self.gpu_id = kwargs.get('gpu_id', 0) + self.seed = kwargs.get('seed', 42) seed_everything(self.seed) + assert torch.cuda.is_available(), "GPU is required for calibration" self.device = torch.device('cuda:{}'.format(self.gpu_id)) if self.verbose: - print("==> Using seed: {} and device: cuda:{}".format(self.seed, self.gpu_id)) - self.calib_data = self.get_calib_samples(self.train_loader, 64*self.calib_batches) - self.eval_count = count(0) - self.min_loss = 1e6 + print("==> Using seed:{} and device cuda:{}".format(self.seed, self.gpu_id)) + - def compress_model(self): - self.model.to(self.device) - self.model.eval() + def compress_model(self, model: nn.Module, inplace: bool = False): + model.to(self.device) + model.eval() weight_quant_params = { 'n_bits': self.w_bits, - 'bcorr': True, - 'method': UniformSymmetricQuantizer, + 'reduce_range': self.reduce_range, + 'unsigned': False, 'p_val': 2.0, + 'method': UniformSymmetricQuantizer, } act_quant_params = { 'n_bits': self.a_bits, - 'bcorr': True, + 'reduce_range': self.reduce_range, 'unsigned': True, - 'method': UniformSymmetricQuantizer, 'p_val': 2.0, + 'method': UniformSymmetricQuantizer, } - if self.test_before_calibration: - qnn = QuantModel(self.model, weight_quant_params, act_quant_params) - qnn.set_quant_state(True, True) - acc1, acc5 = self.test(qnn, self.test_loader, device=self.device) - print('==> Quantization (W{}A{}) accuracy before LAPQ: {:.4f} | {:.4f}'.format( - self.w_bits, self.a_bits, acc1, acc5)) - del qnn + if self.test_min_max_quant: + acc1, acc5 = self.test(model, self.test_loader, device=self.device, progress=True) + if self.verbose: + print('==> Full Precision Model: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) + qmodel = QuantModel(model, weight_quant_params, act_quant_params) + qmodel.set_quant_state(True, True) + acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) + if self.verbose: + print('==> Quantization accuracy before LAPQ: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) + del qmodel weight_quant_params['method'] = LpNormQuantizer act_quant_params['method'] = LpNormQuantizer - p_vals = np.linspace(2,4,10) - losses = [] - pbar = tqdm(p_vals, total=len(p_vals)) - for p in pbar: - weight_quant_params['p_val'] = p - act_quant_params['p_val'] = p - qnn = QuantModel(self.model, weight_quant_params, act_quant_params) - qnn.set_quant_state(True, True) - loss = self.evaluate_loss(qnn, self.device) - losses.append(loss.item()) - pbar.set_postfix(p_val=p, loss=loss.item()) - del qnn - # using quadratic interpolation to approximate the optimal quantization step size ∆p∗ - z = np.polyfit(p_vals, losses, 2) - y = np.poly1d(z) - p_intr = y.deriv().roots[0] - print("==> using p val : {:.2f} with lp-loss : {:.2f}".format(p_intr, min(losses))) + if self.p_val is None: + p_vals = np.linspace(2,3.9,20) + losses = [] + pbar = tqdm(p_vals, total=len(p_vals)) + for p in pbar: + weight_quant_params['p_val'] = p + act_quant_params['p_val'] = p + qmodel = QuantModel(model, weight_quant_params, act_quant_params) + qmodel.set_quant_state(True, True) + loss = self.evaluate_loss(qmodel, self.device) + losses.append(loss.item()) + pbar.set_postfix(p_val=p, loss=loss.item()) + del qmodel + # using quadratic interpolation to approximate the optimal quantization step size ∆p∗ + z = np.polyfit(p_vals, losses, 2) + y = np.poly1d(z) + p_intr = y.deriv().roots[0] + min_loss = min(losses) + else: + weight_quant_params['p_val'] = self.p_val + act_quant_params['p_val'] = self.p_val + qmodel = QuantModel(model, weight_quant_params, act_quant_params) + qmodel.set_quant_state(True, True) + p_intr = self.p_val + min_loss = self.evaluate_loss(qmodel, self.device) + del qmodel + + if self.verbose: + print("==> using p-val : {:.3f} with lp-loss : {:.3f}".format(p_intr, min_loss)) weight_quant_params['p_val'] = p_intr act_quant_params['p_val'] = p_intr - self.qnn = QuantModel(self.model, weight_quant_params, act_quant_params) - self.qnn.set_quant_state(weight_quant=True, act_quant=True) - lp_acc1, lp_acc5 = self.test(self.qnn, self.test_loader, device=self.device) + qmodel = QuantModel(model, weight_quant_params, act_quant_params, inplace=inplace) + qmodel.set_quant_state(weight_quant=True, act_quant=True) + acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) if self.verbose: - print('==> Quantization (W{}A{}) accuracy before Optimization: {:.4f} | {:.4f}'.format( - self.w_bits, self.a_bits, lp_acc1, lp_acc5)) + print('==> Quantization accuracy before optimization: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) print("==> Starting Powell Optimization") - init_alphas = self.qnn.get_alphas_np() - + init_alphas = qmodel.get_alphas_np() min_method = "Powell" - min_options = { - 'maxiter' : self.maxiter, - 'maxfev' : self.maxfev - } + min_options = {'maxiter' : self.max_iter, 'maxfev' : self.max_fev} + count_iter = count(0) + self.eval_acc = 0 + self.eval_iter = 0 + def local_search_callback(x): it = next(count_iter) - self.qnn.set_alphas_np(x) - loss = self.evaluate_loss(self.qnn.model, self.device) - if self.verbose: - print('\n==> Loss at end of iter [{}] : {:.4f}\n'.format(it, loss.item())) + print(it) + if self.verbose and it%self.eval_freq==0: + qmodel.set_alphas_np(x) + self.eval_acc, _ = self.test(qmodel, self.test_loader, device=self.device, progress=False) + self.eval_iter = it + # print('\n==> Quantization accuracy at iter [{}]: acc@1 {:.2f} | acc@5 {:.2f}\n'.format(it, acc1, acc5)) - self.pbar = tqdm(total=min(self.maxiter, self.maxfev)) + self.min_loss = 1e6 + self.pbar = tqdm(total=min(self.max_iter, self.max_fev)) res = optim.minimize( - lambda alphas: self.evaluate_calibration(alphas, self.qnn, self.device), init_alphas, + lambda alphas: self.evaluate_calibration(alphas, qmodel, self.device), init_alphas, method=min_method, options=min_options, callback=local_search_callback ) self.pbar.close() alphas = res.x + status = res.success if self.verbose: - print('==> Layer-wise Alphas :\n', alphas) - self.qnn.set_alphas_np(alphas) - print('==> Full quantization (W{}A{}) accuracy: {}'.format( - self.w_bits, self.a_bits, - self.test(self.qnn, self.test_loader, device=self.device))) - quantized_model = self.qnn.convert_model_to_quantized(inplace = False) + print('==> Optimization completed with success status:', status) + print('==> Optimized alphas :\n', alphas) + qmodel.set_alphas_np(alphas) + + acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) + if self.verbose: + print('==> Final LAPQ quantization accuracy: {:.3f} | {:.3f}'.format(acc1, acc5)) + + if self.fake_quantize: + quantized_model = qmodel + else: + quantized_model = qmodel.convert_model_to_quantized(inplace=inplace) + return quantized_model def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel, device): - eval_count = next(self.eval_count) qmodel.set_alphas_np(alphas) loss = self.evaluate_loss(qmodel, device).item() if loss < self.min_loss: self.min_loss = loss - self.pbar.set_postfix(curr_loss=loss, min_loss=self.min_loss) + self.pbar.set_postfix(curr_loss=loss, min_loss=self.min_loss, eval_acc=self.eval_acc, eval_iter=self.eval_iter) self.pbar.update(1) return loss + def evaluate_loss(self, model: nn.Module, device): criterion = torch.nn.CrossEntropyLoss().to(device) model.eval() @@ -191,7 +224,7 @@ def evaluate_loss(self, model: nn.Module, device): if not hasattr(self, 'cal_set'): self.cal_set = [] for i, (images, target) in enumerate(self.train_loader): - if i>=self.calib_batches: # TODO: make this robust for variable batch size + if i>=self.calib_batches: break images = images.to(device, non_blocking=True) target = target.to(device, non_blocking=True) diff --git a/trailmet/algorithms/quantize/methods.py b/trailmet/algorithms/quantize/methods.py index 6e1035b..ebfacee 100644 --- a/trailmet/algorithms/quantize/methods.py +++ b/trailmet/algorithms/quantize/methods.py @@ -62,8 +62,7 @@ class BaseQuantizer(nn.Module): def __init__(self, n_bits: int, reduce_range: bool, unsigned: bool, scale, zero_point): super(BaseQuantizer, self).__init__() - self._supported_bits = [2, 3, 4, 8, 16, 32] - # assert n_bits in self._supported_bits, 'bitwidth not supported' + assert 2 <= n_bits <= 32, "n_bits is outside allowed range [2, 32]" if reduce_range: # handle qint overflow in x86 backend n_bits -= 1 if unsigned: # use unsigned int @@ -74,6 +73,7 @@ def __init__(self, n_bits: int, reduce_range: bool, unsigned: bool, self.q_min = -(2 ** (n_bits-1)) + 1 self.scale = scale self.zero_point = zero_point + self.reduce_range = reduce_range def __register_buffer__(self, name, value): if hasattr(self, name): @@ -108,6 +108,7 @@ def get_qparams(self) -> dict: "zero_point": self.zero_point, "quant_max": self.q_max, "quant_min": self.q_min, + "reduce_range": self.reduce_range } @@ -127,7 +128,7 @@ def __init__(self, n_bits: int = 8, unsigned: bool = False, reduce_range: bool = channel_wise: bool = False, scale_method: str = 'max', leaf_param: bool = False, inited: bool = False, **kwargs): super(UniformAffineQuantizer, self).__init__(n_bits=n_bits, reduce_range=reduce_range, - unsigned=unsigned,scale=None, zero_point=None) + unsigned=unsigned, scale=None, zero_point=None) self.symmetric = False self.n_bits = n_bits self.unsigned = unsigned @@ -187,11 +188,11 @@ def init_quantization_params(self, x: torch.Tensor, channel_wise = False): optim_alpha = optim.minimize_scalar( lambda alpha: self.estimate_quant_error(x, x_max, x_min, alpha), bounds=(0.2, 1.0)).x - delta = optim_alpha * (x_max - x_min) / (self.n_levels - 1) - zero_point = torch.round( -optim_alpha * x_min / delta) + scale = optim_alpha * (x_max - x_min) / float(self.q_max - self.q_min) + zero_point = torch.round( -optim_alpha * x_min / scale) else: raise NotImplementedError - return delta, zero_point + return scale, zero_point def estimate_quant_error(self, x: torch.Tensor, x_max, x_min, alpha, p=2.4): scale = alpha * (x_max - x_min) / float(self.q_max - self.q_min) @@ -291,13 +292,12 @@ def extra_repr(self): class UniformSymmetricQuantizer(BaseQuantizer): - def __init__(self, n_bits, reduce_range=True, unsigned=False, inited=False, **kwargs): - super().__init__(n_bits=n_bits, reduce_range=reduce_range, unsigned=unsigned, - scale=None, zero_point=None) + def __init__(self, n_bits, reduce_range, unsigned, **kwargs): + super().__init__(n_bits, reduce_range, unsigned, scale=None, zero_point=None) self.n_bits = n_bits - self.inited = inited + self.inited = False self.symmetric = True - self.channel_wise = False # channel wise not supported for now + self.channel_wise = False #TODO: add support for channel wise self.alpha = None self.eps = torch.finfo(torch.float32).eps @@ -319,15 +319,22 @@ def set_params_from_alpha(self, alpha): self.__register_buffer__('alpha', torch.tensor(alpha)) def extra_repr(self): - s = 'bits={n_bits}, scale={scale}, zero_point={zero_point}' + s = 'alpha={alpha}, scale={scale}, zero_point={zero_point}, q_min={q_min}, q_max={q_max}, '\ + 'symmetric={symmetric}, channel_wise={channel_wise}' return s.format(**self.__dict__) def get_qparams(self) -> dict: - return super().get_qparams() + qparams = super().get_qparams() + qparams.update({ + "symmetric": self.symmetric, + "channel_wise": self.channel_wise + }) + return qparams + class LpNormQuantizer(UniformSymmetricQuantizer): - def __init__(self, n_bits, p_val, inited=False, **kwargs): - super().__init__(n_bits, inited, **kwargs) + def __init__(self, n_bits, reduce_range, unsigned, p_val, **kwargs): + super().__init__(n_bits, reduce_range, unsigned) self.p = p_val def init_quantization_params(self, x: torch.Tensor): @@ -346,13 +353,6 @@ def estimate_quant_error(self, x, alpha): q_err = torch.mean(torch.abs(x_dequant - x) ** self.p) return q_err.item() - def get_qparams(self) -> dict: - qparams = super().get_qparams() - qparams.update({ - "symmetric": self.symmetric, - "channel_wise": self.channel_wise - }) - return qparams diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index 5451109..d292124 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -160,7 +160,7 @@ def convert_model_to_quantized(self, inplace=True, remove_qconfig=True): weight = None, activation = FixedQParamsObserver.with_args( qscheme = get_qscheme(inp_qparams['channel_wise'], inp_qparams['symmetric']), - dtype = get_dtype(inp_qparams['quant_min'], inp_qparams['quant_max']), + dtype = get_dtype(inp_qparams['quant_min'], inp_qparams['quant_max'], inp_qparams['reduce_range']), quant_min = inp_qparams['quant_min'], quant_max = inp_qparams['quant_max'], scale = inp_qparams['scale'], From f8506bd1bf60006a40971757e2b10bfe15d9102a Mon Sep 17 00:00:00 2001 From: sydarb Date: Fri, 29 Sep 2023 17:52:57 +0530 Subject: [PATCH 28/35] modified lapq expt nb --- experiments/quantization/LAPQ/lapq_demo.ipynb | 1166 ++++++++++------- 1 file changed, 669 insertions(+), 497 deletions(-) diff --git a/experiments/quantization/LAPQ/lapq_demo.ipynb b/experiments/quantization/LAPQ/lapq_demo.ipynb index bc5fb0a..1c01af6 100644 --- a/experiments/quantization/LAPQ/lapq_demo.ipynb +++ b/experiments/quantization/LAPQ/lapq_demo.ipynb @@ -1,554 +1,726 @@ { - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "498871cf", - "metadata": {}, - "source": [ - "## LAPQ\n", - "This notebook demonstrates the implimentation of the paper [Loss Aware Post-training Quantization](https://arxiv.org/abs/1911.07190)\n", - "\n", - "### Steps to quantize the pretrained model\n", - "- Load the dataset and create dataloader. A subset of training data is used for calibration.\n", - "- Load the pretrained full precision model.\n", - "- Load the configurations from the YAML file.\n", - "- Create a `LAPQ` object and pass the full precision model, dataloaders and configurations.\n", - "- Quantize the model by calling the `compress_model` method." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "dafbd1b3", - "metadata": {}, - "outputs": [], - "source": [ - "import sys\n", - "sys.path.append(\"../../../\")\n", - "\n", - "import os\n", - "os.environ[\"CUDA_DEVICE_ORDER\"]=\"PCI_BUS_ID\" \n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"]=\"1\"" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "417e9692", - "metadata": {}, - "outputs": [ + "cells": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/conda/envs/py117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n" - ] - } - ], - "source": [ - "import yaml\n", - "import torch\n", - "from torch.utils.data import DataLoader\n", - "from torchvision import transforms\n", - "from trailmet.datasets.classification import DatasetFactory\n", - "from trailmet.models import ModelsFactory\n", - "from trailmet.algorithms import quantize" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "c67e2359", - "metadata": {}, - "source": [ - "## Datasets" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "64a12f9a", - "metadata": {}, - "source": [ - "### Augmentations" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "4c8c6192", - "metadata": {}, - "outputs": [], - "source": [ - "stats = ((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761))\n", - "\n", - "train_transform = transforms.Compose([\n", - " transforms.RandomCrop(32, padding=4, padding_mode='reflect'),\n", - " transforms.RandomHorizontalFlip(),\n", - " transforms.ToTensor(),\n", - " transforms.Normalize(*stats, inplace=True)\n", - "])\n", - "val_transform = transforms.Compose([\n", - " transforms.ToTensor(),\n", - " transforms.Normalize(*stats)\n", - "])\n", - "test_transform = transforms.Compose([\n", - " transforms.ToTensor(),\n", - " transforms.Normalize(*stats)\n", - "])\n", - "\n", - "input_transforms = {\n", - " 'train': train_transform, \n", - " 'val': val_transform, \n", - " 'test': test_transform}\n", - "\n", - "target_transforms = {\n", - " 'train': None, \n", - " 'val': None, \n", - " 'test': None}" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "0c41f2b1", - "metadata": {}, - "source": [ - "### Load Datasets" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "b377f3bb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Files already downloaded and verified\n", - "Files already downloaded and verified\n", - "Files already downloaded and verified\n", - "Train samples: 40000\n", - "Val samples: 10000\n", - "Test samples: 10000\n" - ] - } - ], - "source": [ - "cifar100_dataset = DatasetFactory.create_dataset(\n", - " name = 'CIFAR100', \n", - " root = './data',\n", - " split_types = ['train', 'val', 'test'],\n", - " val_fraction = 0.2,\n", - " transform = input_transforms,\n", - " target_transform = target_transforms)\n", - "\n", - "# getting the size of the different splits\n", - "print('Train samples: ',cifar100_dataset['info']['train_size'])\n", - "print('Val samples: ',cifar100_dataset['info']['val_size'])\n", - "print('Test samples: ',cifar100_dataset['info']['test_size'] )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "eec91853", - "metadata": {}, - "source": [ - "### Define Dataloaders" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "464c2e93", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "No. of training batches: 313\n", - "No. of validation batches: 79\n", - "No. of test batches: 79\n" - ] - } - ], - "source": [ - "train_loader = DataLoader(\n", - " cifar100_dataset['train'], batch_size=128, \n", - " sampler=cifar100_dataset['train_sampler'],\n", - " num_workers=2)\n", - "val_loader = DataLoader(\n", - " cifar100_dataset['val'], batch_size=128, \n", - " sampler=cifar100_dataset['val_sampler'],\n", - " num_workers=2)\n", - "test_loader = DataLoader(\n", - " cifar100_dataset['test'], batch_size=128, \n", - " sampler=cifar100_dataset['test_sampler'],\n", - " num_workers=2)\n", - "\n", - "dataloaders = {\"train\": train_loader, \"val\": val_loader, \"test\": test_loader}\n", - "\n", - "print('No. of training batches: ', len(dataloaders['train']))\n", - "print('No. of validation batches: ', len(dataloaders['val']))\n", - "print('No. of test batches: ', len(dataloaders['test']))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "85812739", - "metadata": {}, - "source": [ - "### Load Pretrained Model" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "e4db07ac", - "metadata": {}, - "outputs": [], - "source": [ - "res50_model = ModelsFactory.create_model(name='resnet50', num_classes=100, pretrained=False, insize=32)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "0ca3e796", - "metadata": {}, - "source": [ - "### Load Method Config" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5b9625ad", - "metadata": {}, - "outputs": [ + "cell_type": "markdown", + "id": "498871cf", + "metadata": { + "id": "498871cf" + }, + "source": [ + "## LAPQ\n", + "This notebook demonstrates the implimentation of the paper [Loss Aware Post-training Quantization](https://arxiv.org/abs/1911.07190)\n", + "\n", + "### Steps to quantize the pretrained model\n", + "- Load the dataset and create dataloader. A subset of training data is used for calibration.\n", + "- Load the pretrained full precision model.\n", + "- Load the configurations from the YAML file.\n", + "- Create a `LAPQ` object and pass the full precision model, dataloaders and configurations.\n", + "- Quantize the model by calling the `compress_model` method." + ] + }, { - "data": { - "text/plain": [ - "{'GPU_ID': 0,\n", - " 'SEED': 42,\n", - " 'W_BITS': 4,\n", - " 'A_BITS': 8,\n", - " 'ACT_QUANT': True,\n", - " 'CALIB_BATCHES': 4,\n", - " 'MAX_ITER': 1000,\n", - " 'MAX_FEV': 1000,\n", - " 'VERBOSE': True}" + "cell_type": "code", + "source": [ + "USE_COLAB = True\n", + "\n", + "if USE_COLAB:\n", + " from google.colab import drive\n", + " drive.mount(\"/content/drive\")\n", + " base_path = \"/content/drive/MyDrive/trail\"\n", + "else:\n", + " base_path = \"../../../..\"\n", + "\n", + "library_path = base_path + \"/trailmet\"\n", + "requirements_path = library_path + \"/requirements.txt\"\n", + "config_path = library_path + \"/experiments/quantization/LAPQ/lapq_config.yaml\"\n", + "weights_path = base_path + \"/weights/resnet50_cifar100_pretrained.pth\"" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "skKWRRtMsfRM", + "outputId": "ada0dc11-61c2-4637-cf0e-a4f25ad28b3c" + }, + "id": "skKWRRtMsfRM", + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" + ] + } ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "with open('./lapq_config.yaml', 'r') as f:\n", - " config = yaml.safe_load(f)\n", - " kwargs = config['GENERAL']\n", - " \n", - "kwargs" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "87e6c554", - "metadata": {}, - "source": [ - "### Quantization Method: BRECQ" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "e21d5073", - "metadata": {}, - "outputs": [ + }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "==> Using seed: 42 and device: cuda:0\n" - ] + "cell_type": "code", + "source": [ + "%pip install -q -r $requirements_path" + ], + "metadata": { + "id": "P7Kar046xSEd" + }, + "id": "P7Kar046xSEd", + "execution_count": null, + "outputs": [] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33manimesh-007\u001b[0m. Use \u001b[1m`wandb login --relogin`\u001b[0m to force relogin\n" - ] + "cell_type": "code", + "execution_count": null, + "id": "dafbd1b3", + "metadata": { + "id": "dafbd1b3" + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.append(library_path)" + ] }, { - "data": { - "text/html": [ - "wandb version 0.15.4 is available! To upgrade, please run:\n", - " $ pip install wandb --upgrade" - ], - "text/plain": [ - "" + "cell_type": "code", + "execution_count": null, + "id": "417e9692", + "metadata": { + "id": "417e9692" + }, + "outputs": [], + "source": [ + "import yaml\n", + "import torch\n", + "from torch.utils.data import DataLoader\n", + "from torchvision import transforms\n", + "from trailmet.datasets.classification import DatasetFactory\n", + "from trailmet.models import resnet, mobilenet\n", + "from trailmet.algorithms import quantize" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "data": { - "text/html": [ - "Tracking run with wandb version 0.14.0" - ], - "text/plain": [ - "" + "cell_type": "markdown", + "id": "c67e2359", + "metadata": { + "id": "c67e2359" + }, + "source": [ + "## Datasets" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "data": { - "text/html": [ - "Run data is saved locally in /workspace/animesh_trailmet/experiments/quantization/LAPQ/wandb/run-20230625_230422-w4sdlkw4" - ], - "text/plain": [ - "" + "cell_type": "markdown", + "id": "64a12f9a", + "metadata": { + "id": "64a12f9a" + }, + "source": [ + "### Augmentations" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "data": { - "text/html": [ - "Syncing run CIFAR100_8_Jun-25_23:04:20 to Weights & Biases (docs)
" - ], - "text/plain": [ - "" + "cell_type": "code", + "execution_count": null, + "id": "4c8c6192", + "metadata": { + "id": "4c8c6192" + }, + "outputs": [], + "source": [ + "stats = ((0.5071, 0.4867, 0.4408), (0.2675, 0.2565, 0.2761))\n", + "\n", + "train_transform = transforms.Compose([\n", + " transforms.RandomCrop(32, padding=4, padding_mode='reflect'),\n", + " transforms.RandomHorizontalFlip(),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(*stats, inplace=True)\n", + "])\n", + "val_transform = transforms.Compose([\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(*stats)\n", + "])\n", + "test_transform = transforms.Compose([\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(*stats)\n", + "])\n", + "\n", + "input_transforms = {\n", + " 'train': train_transform,\n", + " 'val': val_transform,\n", + " 'test': test_transform}\n", + "\n", + "target_transforms = {\n", + " 'train': None,\n", + " 'val': None,\n", + " 'test': None}" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "data": { - "text/html": [ - " View project at https://wandb.ai/animesh-007/Trailmet%20LAPQ" - ], - "text/plain": [ - "" + "cell_type": "markdown", + "id": "0c41f2b1", + "metadata": { + "id": "0c41f2b1" + }, + "source": [ + "### Load Datasets" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "data": { - "text/html": [ - " View run at https://wandb.ai/animesh-007/Trailmet%20LAPQ/runs/w4sdlkw4" + "cell_type": "code", + "execution_count": null, + "id": "b377f3bb", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "b377f3bb", + "outputId": "3e9a49d0-bdcf-45d7-f79d-714f81395080" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Downloading https://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz to ./data/cifar-100-python.tar.gz\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 169001437/169001437 [00:12<00:00, 13715362.31it/s]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Extracting ./data/cifar-100-python.tar.gz to ./data\n", + "Files already downloaded and verified\n", + "Files already downloaded and verified\n", + "Train samples: 40000\n", + "Val samples: 10000\n", + "Test samples: 10000\n" + ] + } ], - "text/plain": [ - "" + "source": [ + "cifar100_dataset = DatasetFactory.create_dataset(\n", + " name = 'CIFAR100',\n", + " root = './data',\n", + " split_types = ['train', 'val', 'test'],\n", + " val_fraction = 0.2,\n", + " transform = input_transforms,\n", + " target_transform = target_transforms)\n", + "\n", + "# getting the size of the different splits\n", + "print('Train samples: ',cifar100_dataset['info']['train_size'])\n", + "print('Val samples: ',cifar100_dataset['info']['val_size'])\n", + "print('Test samples: ',cifar100_dataset['info']['test_size'] )" ] - }, - "metadata": {}, - "output_type": "display_data" }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "testing pretrained model before quantization\n" - ] + "cell_type": "markdown", + "id": "eec91853", + "metadata": { + "id": "eec91853" + }, + "source": [ + "### Define Dataloaders" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "Validating network (79 / 79 Steps) (batch time=0.01544s) (loss=9.17796) (top1=0.00000) (top5=0.00000): 100%|| 79/79 [00:04<00:00, 17.72it/s] \n" - ] + "cell_type": "code", + "execution_count": null, + "id": "464c2e93", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "464c2e93", + "outputId": "499a7028-ebe1-4b26-89ba-3206fda6c59e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "No. of training batches: 313\n", + "No. of validation batches: 79\n", + "No. of test batches: 79\n" + ] + } + ], + "source": [ + "train_loader = DataLoader(\n", + " cifar100_dataset['train'], batch_size=128,\n", + " sampler=cifar100_dataset['train_sampler'],\n", + " num_workers=0)\n", + "val_loader = DataLoader(\n", + " cifar100_dataset['val'], batch_size=128,\n", + " sampler=cifar100_dataset['val_sampler'],\n", + " num_workers=0)\n", + "test_loader = DataLoader(\n", + " cifar100_dataset['test'], batch_size=128,\n", + " sampler=cifar100_dataset['test_sampler'],\n", + " num_workers=0)\n", + "\n", + "dataloaders = {\"train\": train_loader, \"val\": val_loader, \"test\": test_loader}\n", + "\n", + "print('No. of training batches: ', len(dataloaders['train']))\n", + "print('No. of validation batches: ', len(dataloaders['val']))\n", + "print('No. of test batches: ', len(dataloaders['test']))" + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - " * acc@1 1.040 acc@5 5.190\n", - "top-1 acc: 1.04%, top-5 acc: 5.19%\n" - ] + "cell_type": "markdown", + "id": "85812739", + "metadata": { + "id": "85812739" + }, + "source": [ + "### Load Pretrained Model" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "Validating network (79 / 79 Steps) (batch time=0.04852s) (loss=11.44887) (top1=0.00000) (top5=0.00000): 100%|| 79/79 [00:04<00:00, 17.18it/s] \n" - ] + "cell_type": "code", + "execution_count": null, + "id": "e4db07ac", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "e4db07ac", + "outputId": "c7625367-ce16-4139-a7f1-9b50369ccfe7" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ], + "source": [ + "model = resnet.make_resnet50(100,32)\n", + "checkpoint = torch.load(weights_path, map_location='cuda:0')\n", + "model.load_state_dict(checkpoint['state_dict'])" + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - " * acc@1 1.010 acc@5 5.040\n", - "==> Quantization (W4A8) accuracy before LAPQ: 1.0100 | 5.0400\n" - ] + "cell_type": "markdown", + "id": "0ca3e796", + "metadata": { + "id": "0ca3e796" + }, + "source": [ + "### Load Method Config" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 10/10 [00:07<00:00, 1.30it/s, loss=9.16, p_val=4] \n" - ] + "cell_type": "code", + "execution_count": null, + "id": "5b9625ad", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "5b9625ad", + "outputId": "e34c1fe3-1037-4460-afe8-eb67d5599600" + }, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'GPU_ID': 0,\n", + " 'SEED': 42,\n", + " 'W_BITS': 7,\n", + " 'A_BITS': 7,\n", + " 'ACT_QUANT': True,\n", + " 'CALIB_BATCHES': 4,\n", + " 'MAX_ITER': 2000,\n", + " 'MAX_FEV': 2000,\n", + " 'VERBOSE': True}" + ] + }, + "metadata": {}, + "execution_count": 35 + } + ], + "source": [ + "with open(config_path, 'r') as f:\n", + " config = yaml.safe_load(f)\n", + " kwargs = config['GENERAL']\n", + "\n", + "kwargs['MAX_ITER']=2000\n", + "kwargs['MAX_FEV']=2000\n", + "kwargs['A_BITS']=7\n", + "kwargs['W_BITS']=7\n", + "\n", + "kwargs" + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "==> using p intr : 4.09\n" - ] + "cell_type": "markdown", + "id": "87e6c554", + "metadata": { + "id": "87e6c554" + }, + "source": [ + "### Quantization Method: LAPQ" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "Validating network (79 / 79 Steps) (batch time=0.04860s) (loss=9.68071) (top1=0.00000) (top5=0.00000): 100%|| 79/79 [00:04<00:00, 16.46it/s] \n" - ] + "cell_type": "code", + "execution_count": null, + "id": "e21d5073", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "e21d5073", + "outputId": "50e0b908-b8a7-49f4-93e4-e11fd6752220" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> Using seed: 42 and device: cuda:0\n", + "testing pretrained model before quantization\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [00:10<00:00, 7.57it/s, acc1=72.5, acc5=91.5]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "top-1 acc: 72.52%, top-5 acc: 91.52%\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [00:08<00:00, 8.84it/s, acc1=69.5, acc5=90]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> Quantization (W7A7) accuracy before LAPQ: 69.5115 | 90.0316\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 10/10 [00:20<00:00, 2.00s/it, loss=0.176, p_val=4]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> using p val : 3.66 with lp-loss : 0.18\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [00:10<00:00, 7.89it/s, acc1=72.3, acc5=91.3]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> Quantization (W7A7) accuracy before Optimization: 72.2508 | 91.3370\n", + "==> Starting Powell Optimization\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 2000/2000 [09:21<00:00, 3.56it/s, curr_loss=0.176, min_loss=0.152]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> Layer-wise Scales :\n", + " [ 0.33818299 0.62134768 0.82564299 1.02090729 0.95200617 0.36689557\n", + " 0.56235786 0.83859347 0.14576932 0.61901607 1.22165686 0.47066361\n", + " 0.26149886 0.74342126 0.45708764 0.14837253 0.15520184 1.14811294\n", + " 0.17855284 0.39177551 1.10277545 0.2693316 0.21350731 0.71349451\n", + " 0.36680011 0.12632736 0.51384439 0.2863148 0.12838054 0.18741796\n", + " 0.85134318 0.10731246 0.16548798 0.66784387 0.09932491 0.16292682\n", + " 0.85598874 0.12488759 0.20705417 0.68615477 0.18071352 0.27441487\n", + " 0.54972186 0.30531706 0.2248336 1.19240661 0.4168146 0.04306774\n", + " 0.33290503 0.80163794 0.01937079 0.19003982 0.72733849 0.34951356\n", + " 1.99468306 1.23356115 0.83784936 0.51849612 0.43591889 0.5504359\n", + " 0.84351204 0.81898661 0.38176331 0.57372303 0.48332823 0.81326441\n", + " 0.30857745 0.38395615 0.6832149 0.65068425 0.63195158 0.52181466\n", + " 0.65721197 0.64087668 0.65638089 0.24518578 0.48958696 0.70771214\n", + " 0.7810806 0.36986201 0.37629303 0.68606285 0.71880917 0.48262717\n", + " 0.45337911 0.37663389 0.68937862 0.7618183 0.55862383 0.57610431\n", + " 0.47111681 0.6936263 0.32051978 0.35080028 0.6339107 0.80058439\n", + " 0.34578153 0.34025314 0.3652297 0.80349561 0.35078868 0.34667977\n", + " 0.51684356 0.97855669 0.35530103 0.43259362 0.493544 0.7734252\n", + " 0.54179977 0.55423125 0.59282164 2.02728408 0.61292773 0.68140569\n", + " 1.75588362 0.81362313 3.61825858 0.41211504 0.69931554 2.21552974\n", + " 4.88437368 0.2972496 0.3892928 2.21019835 10.95171503]\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [00:08<00:00, 9.15it/s, acc1=72, acc5=91.2]\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "==> Full quantization (W7A7) accuracy: (72.03322784810126, 91.18868670886076)\n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n", + "swapped : \n" + ] + } + ], + "source": [ + "quantizer = quantize.lapq.LAPQ(model, dataloaders, **kwargs)\n", + "qmodel = quantizer.compress_model()" + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - " * acc@1 0.960 acc@5 5.070\n", - "==> Quantization (W4A8) accuracy before Optimization: 0.9600 | 5.0700\n", - "==> Loss after LpNormQuantization: 9.4259\n", - "==> Starting Powell Optimization\n" - ] + "cell_type": "code", + "execution_count": null, + "id": "c6edd9e9", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "c6edd9e9", + "outputId": "1e9224a6-7bf5-42d2-cc44-0456a742bcfa" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "testing quantized model\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [01:15<00:00, 1.04it/s, acc1=72.3, acc5=91.1]\n" + ] + } + ], + "source": [ + "print('testing quantized model')\n", + "qmodel.to(torch.device('cpu'))\n", + "acc1, acc5 = quantizer.test(model=qmodel, dataloader=dataloaders['test'], device=torch.device('cpu'))" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 1000/1000 [03:28<00:00, 4.80it/s, curr_loss=4.62, min_loss=4.61]\n" - ] + "cell_type": "code", + "source": [ + "print('testing full precision model')\n", + "model.to(torch.device('cpu'))\n", + "acc1, acc5 = quantizer.test(model=model, dataloader=dataloaders['test'], device=torch.device('cpu'))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "GMg5Wvv-P5Z9", + "outputId": "083d9b2d-4845-4045-8fda-d1df44bdc509" + }, + "id": "GMg5Wvv-P5Z9", + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "testing full precision model\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "100%|██████████| 79/79 [02:54<00:00, 2.21s/it, acc1=72.5, acc5=91.5]\n" + ] + } + ] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - "==> Layer-wise Scales :\n", - " [-2.71854830e+00 -3.08051988e-01 9.95627994e-01 3.81617464e+00\n", - " -9.40671566e-01 -3.61076604e+00 -1.81663796e+00 1.21657309e+00\n", - " 1.91811575e+00 2.52682898e+00 -1.42890691e+00 -1.70284810e+00\n", - " 3.04076019e+00 -1.71109412e+00 -4.41954680e-01 -2.75285367e-01\n", - " 4.77568090e+00 -8.70588564e-01 -1.46963710e+01 -6.32294023e-01\n", - " -1.39139490e+00 4.28594499e+00 -1.21911043e+02 -1.34789206e+00\n", - " 1.03977837e+00 1.19332061e+01 -1.46906333e+01 -4.85501959e-01\n", - " 1.23643283e+00 1.34744476e+01 -7.74482854e-01 -1.09169621e+00\n", - " 3.03794852e-01 1.49893110e+01 -1.44991452e+00 -6.44897627e+00\n", - " -9.93479876e-01 1.35904461e-01 2.40335316e+01 2.86178112e-01\n", - " 9.66371353e-02 1.44008197e-01 2.28464613e+01 2.84444329e-01\n", - " 9.55632382e-02 1.41487494e-01 3.59558318e+01 2.82226657e-01\n", - " 9.38017642e-02 1.43612936e-01 5.25450935e+01 2.79624492e-01\n", - " 9.47439224e-02 1.43324569e-01 1.15084450e+02 2.01696590e-01\n", - " 6.74792528e-02 1.00485601e-01 9.49488449e+01 1.02076188e-01\n", - " 2.02921063e-01 6.77159503e-02 1.01089455e-01 1.21774887e+02\n", - " 2.03220874e-01 6.74693212e-02]\n" - ] + "cell_type": "code", + "execution_count": null, + "id": "56e04513", + "metadata": { + "id": "56e04513", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "ed654fbd-a03a-44a9-da52-3ac42c159db5" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Size: 23.84 MB\n", + "Size: 95.12 MB\n" + ] + } + ], + "source": [ + "import os\n", + "def print_model_size(model):\n", + " torch.save(model.state_dict(), \"temp.p\")\n", + " print(f'Size: {os.path.getsize(\"temp.p\")/1e6:.2f} MB')\n", + " os.remove('temp.p')\n", + "\n", + "print_model_size(qmodel)\n", + "print_model_size(model)" + ] }, { - "name": "stderr", - "output_type": "stream", - "text": [ - "Validating network (79 / 79 Steps) (batch time=0.04774s) (loss=4.62941) (top1=0.00000) (top5=0.00000): 100%|| 79/79 [00:04<00:00, 16.54it/s]\n" - ] + "cell_type": "code", + "source": [ + "torch.save(qmodel.state_dict(), \"quantized_res50_c100.pth\")" + ], + "metadata": { + "id": "TxsdFuMrPleV" + }, + "id": "TxsdFuMrPleV", + "execution_count": null, + "outputs": [] }, { - "name": "stdout", - "output_type": "stream", - "text": [ - " * acc@1 1.090 acc@5 4.920\n", - "==> Full quantization (W4A8) accuracy: 1.0899999141693115\n" - ] + "cell_type": "code", + "source": [], + "metadata": { + "id": "JJ4iwacl2pQw" + }, + "id": "JJ4iwacl2pQw", + "execution_count": null, + "outputs": [] } - ], - "source": [ - "quantizer = quantize.lapq.LAPQ(res50_model, dataloaders, **kwargs)\n", - "\n", - "print('testing pretrained model before quantization')\n", - "_, acc1, acc5 = quantizer.test(model=res50_model, dataloader=dataloaders['test'], loss_fn=torch.nn.CrossEntropyLoss())\n", - "print(f'top-1 acc: {acc1:.2f}%, top-5 acc: {acc5:.2f}%')\n", - "\n", - "qmodel = quantizer.compress_model()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "c6edd9e9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "testing quantized model\n" - ] + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "name": "python3" }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Validating network (79 / 79 Steps) (batch time=0.05487s) (loss=4.62941) (top1=0.00000) (top5=0.00000): 100%|| 79/79 [00:04<00:00, 18.34it/s]" - ] + "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.8.13" }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * acc@1 1.090 acc@5 4.920\n", - "top-1 acc: 1.09%, top-5 acc: 4.92%\n" - ] + "colab": { + "provenance": [], + "gpuType": "T4" }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "print('testing quantized model')\n", - "_, acc1, acc5 = quantizer.test(model=qmodel, dataloader=dataloaders['test'], loss_fn=torch.nn.CrossEntropyLoss())\n", - "print(f'top-1 acc: {acc1:.2f}%, top-5 acc: {acc5:.2f}%')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" + "accelerator": "GPU" }, - "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.10.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From a37928a2645876884cd688b8c4da2b48912b28d7 Mon Sep 17 00:00:00 2001 From: sydarb Date: Fri, 29 Sep 2023 17:53:38 +0530 Subject: [PATCH 29/35] added quant procedure info --- trailmet/algorithms/quantize/info.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 trailmet/algorithms/quantize/info.md diff --git a/trailmet/algorithms/quantize/info.md b/trailmet/algorithms/quantize/info.md new file mode 100644 index 0000000..fa1b19b --- /dev/null +++ b/trailmet/algorithms/quantize/info.md @@ -0,0 +1,13 @@ +- The following quantization configuration schema has been adopted throughout all quantizable modules to ensure compatibility with `torch.ao.quantization`. + - **qscheme**: enum[per_tensor_affine, per_tensor_symmetric, per_channel_affine, per_channel_symmetric] + - **dtype**: enum[qint8, quint8, qint32] + - **scale**: type[float] + - **zero_point**: type[int] + - **quant_min**: type[int] + - **quant_max**: type[int] + + for each quantized module `qscheme` is set according to the quantization algorithm and module under consideration, then `quant_min` and `quant_max` are determined based on the compression requirement and approximate precision importance for the given module. `dtype` is set such that it satisfies the given `quant_min` and `quant_max` range. `scale` and `zero_point` are finally determined dynamically during calibration using the applied algorithm. + +- current implementation for deployment (x86 cpu only) stores model weights in `int8`/`int32` along with scale (`float32`) and zero_point (`int64`), effectively reducing required memory space (by about a factor of 4 for layer-wise granularity, and slightly lower for channel-wise granularity). Activations are quantized to `uint8` based on scaling factors determined during calibration (static during inference). + +- when using the `x86 backend`, we need to use 7 bits instead of 8 bits. Make sure you reduce the range for the `quant_min`, `quant_max`, ie. if dtype is `torch.quint8`, we need to set `quant_min` to be 0 and `quant_max` to be 127 (255 / 2) and if dtype is `torch.qint8`, make sure to set `quant_min` to be -64 (-128 / 2) and `quant_max` to be 63 (127 / 2). This functionality is implemented and can be enabled by setting the configuration argument `reduce_range` to True. However, no need for this in `qnnpack backend`. \ No newline at end of file From 797567ad07d1f512335ab0f2203e256b95032f98 Mon Sep 17 00:00:00 2001 From: sydarb Date: Fri, 29 Sep 2023 17:54:12 +0530 Subject: [PATCH 30/35] removed nnq files --- trailmet/algorithms/quantize/nnq/__init__.py | 0 .../algorithms/quantize/nnq/convert_model.py | 130 ------------------ .../algorithms/quantize/nnq/resnet_modules.py | 80 ----------- 3 files changed, 210 deletions(-) delete mode 100644 trailmet/algorithms/quantize/nnq/__init__.py delete mode 100644 trailmet/algorithms/quantize/nnq/convert_model.py delete mode 100644 trailmet/algorithms/quantize/nnq/resnet_modules.py diff --git a/trailmet/algorithms/quantize/nnq/__init__.py b/trailmet/algorithms/quantize/nnq/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/trailmet/algorithms/quantize/nnq/convert_model.py b/trailmet/algorithms/quantize/nnq/convert_model.py deleted file mode 100644 index 2868631..0000000 --- a/trailmet/algorithms/quantize/nnq/convert_model.py +++ /dev/null @@ -1,130 +0,0 @@ -import copy -from typing import Dict, Callable, Any -from torch import nn as nn -from torch.nn.utils.parametrize import type_before_parametrizations as _type -from torch.ao.nn import quantized as nnq -from torch.ao.nn import intrinsic as nni -from torch.ao.nn.intrinsic import quantized as nniq -from torch.ao.nn.intrinsic.modules.fused import _FusedModule -from torch.ao.quantization.stubs import QuantStub, DeQuantStub - -DEFAULT_STATIC_QUANT_MODULE_MAPPING: Dict[Callable, Callable] = { - QuantStub: nnq.Quantize, - DeQuantStub: nnq.DeQuantize, - nn.BatchNorm2d: nnq.BatchNorm2d, - nn.Dropout: nnq.Dropout, - nn.Conv2d: nnq.Conv2d, - nn.Linear: nnq.Linear, - nn.ReLU6: nnq.ReLU6, - nn.LeakyReLU: nnq.LeakyReLU, - # Wrapper Modules: - nnq.FloatFunctional: nnq.QFunctional, - # Intrinsic modules: - nni.BNReLU2d: nniq.BNReLU2d, - nni.ConvReLU2d: nniq.ConvReLU2d, - nni.ConvAdd2d: nniq.ConvAdd2d, - nni.ConvAddReLU2d: nniq.ConvAddReLU2d, - nni.LinearReLU: nniq.LinearReLU, - nni.LinearLeakyReLU: nniq.LinearLeakyReLU, -} - -def get_qparam_dict(observer): - qparams = dict() - qparams["qscheme"] = getattr(observer, "qscheme", None) - qparams["dtype"] = observer.dtype - qparams["scale"], qparams["zero_point"] = observer.calculate_qparams() - if hasattr(observer, "quant_min"): - qparams["quant_min"] = observer.quant_min - if hasattr(observer, "quant_max"): - qparams["quant_max"] = observer.quant_max - return qparams - - -def _observer_forward_hook(self, input, output): - """forward hook that calls observer on the output""" - return self.activation_post_process(output) - -def _observer_forward_pre_hook(self, input): - r"""Forward pre hook that calls observer on the input - """ - return self.activation_post_process(input[0]) - - -def _remove_qconfig(module): - for child_module in module.children(): - _remove_qconfig(child_module) - - if hasattr(module, 'qconfig'): - del module.qconfig - - if hasattr(module, 'activation_post_process'): - del module.activation_post_process - - - -def convert_model(model, inplace=True, remove_qconfig=True): - if not inplace: - model = copy.deepcopy(model) - mapping = DEFAULT_STATIC_QUANT_MODULE_MAPPING - _convert(model, mapping, inplace) - if remove_qconfig: - _remove_qconfig(model) - return model - -def _replace_relu(module: nn.Module) -> None: - """replace all ReLU6 with ReLU""" - reassign = {} - for name, child_module in module.named_children(): - _replace_relu(child_module) - if type(child_module) is nn.ReLU or type(child_module) is nn.ReLU6: - reassign[name] = nn.ReLU(inplace=False) - - for key, value in reassign.items(): - module._modules[key] = value - -def _convert(module: nn.Module, mapping, inplace=True): - """recursively convert modules to their quantized counterparts""" - if not inplace: - module = copy.deepcopy(module) - reassign = {} - for name, child_module in module.named_children(): - if not isinstance(child_module, _FusedModule): # fused modules are swapped as one unit - _convert(child_module, mapping, True) - reassign[name] = swap_module(child_module, mapping) - - for name, quantized_module in reassign.items(): - module._modules[name] = quantized_module - - return module - - -def swap_module(module, mapping): - """ - swaps the module if it has a quantized counterpart and - if it has an `observer` attached. - Args: - module: input module - mapping: a dict that maps from nn/nni module to nnq/nniq module - Return: - corresponding quantized counterpart of `module` - """ - new_module = module - - if hasattr(module, 'qconfig') and module.qconfig is not None: - swapped = False - if _type(module) in mapping: - qmod = mapping[_type(module)] - new_module = qmod.from_float(module) - swapped = True - - if swapped: - # Preserve module's pre forward hooks. They'll be called on quantized input - for pre_hook_fn in module._forward_pre_hooks.values(): - new_module.register_forward_pre_hook(pre_hook_fn) - # Preserve module's post forward hooks except _observer_forward_hook - # After convert they'll work with quantized output - for hook_fn in module._forward_hooks.values(): - if hook_fn is not _observer_forward_hook: - new_module.register_forward_hook(hook_fn) - - return new_module diff --git a/trailmet/algorithms/quantize/nnq/resnet_modules.py b/trailmet/algorithms/quantize/nnq/resnet_modules.py deleted file mode 100644 index de98836..0000000 --- a/trailmet/algorithms/quantize/nnq/resnet_modules.py +++ /dev/null @@ -1,80 +0,0 @@ -from typing import Any, Optional, Union, List -from torch import nn, Tensor -from torch.ao.nn import quantized as nnq -from torch.ao.quantization import fuse_modules, fuse_modules_qat, \ - QuantStub, DeQuantStub -from torchvision.models.resnet import BasicBlock, Bottleneck, ResNet - - -def _fuse_modules(model: nn.Module, modules_to_fuse: Union[List[str], List[List[str]]], - is_qat: Optional[bool], **kwargs: Any): - if is_qat is None: - is_qat = model.training - fuse_method = fuse_modules_qat if is_qat else fuse_modules - return fuse_method(model, modules_to_fuse, **kwargs) - -class QBottleneck(Bottleneck): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - self.skip_add_relu = nnq.FloatFunctional() - self.relu1 = nn.ReLU(inplace=False) - self.relu2 = nn.ReLU(inplace=False) - - def forward(self, x: Tensor) -> Tensor: - indentity = x - out = self.conv1(x) - out = self.bn1(out) - out = self.relu1(out) - out = self.conv2(out) - out = self.bn2(out) - out = self.relu2(out) - - out = self.conv3(out) - out = self.bn3(out) - - if self.downsample is not None: - identity = self.downsample(x) - out = self.skip_add_relu.add_relu(out, identity) - - return out - - def fuse_model(self, is_qat: Optional[bool] = None) -> None: - _fuse_modules(self, - [["conv1", "bn1", "relu1"], - ["conv2", "bn2", "relu2"], - ["conv3", "bn3"]], - is_qat, - inplace=True - ) - if self.downsample: - _fuse_modules(self.downsample, - ["0", "1"], - is_qat, - inplace=True - ) - - class QResNet(ResNet): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - self.quant = QuantStub() - self.dequant = DeQuantStub() - - def forward(self, x: Tensor) -> Tensor: - x = self.quant(x) - x = self._forward_impl(x) - x = self.dequant(x) - return x - - def fuse_model(self, is_qat: Optional[bool] = None) -> None: - """ - Fuse conv+bn+relu / conv+bn / conv+relu modules - to prepare for quantization - """ - _fuse_modules(self, - ["conv1", "bn1", "relu"], - is_qat, - inplace = True - ) - for module in self.modules(): - if type(module)==QBottleneck: - module.fuse_model() \ No newline at end of file From 82bce33f07580ed67c8e5de07c65022ee61042fa Mon Sep 17 00:00:00 2001 From: sydarb Date: Sat, 30 Sep 2023 17:03:15 +0530 Subject: [PATCH 31/35] changed class structure --- experiments/quantization/LAPQ/lapq_demo.ipynb | 448 +++++++----------- trailmet/algorithms/quantize/lapq.py | 83 ++-- trailmet/algorithms/quantize/quantize.py | 45 +- 3 files changed, 233 insertions(+), 343 deletions(-) diff --git a/experiments/quantization/LAPQ/lapq_demo.ipynb b/experiments/quantization/LAPQ/lapq_demo.ipynb index 1c01af6..a93d691 100644 --- a/experiments/quantization/LAPQ/lapq_demo.ipynb +++ b/experiments/quantization/LAPQ/lapq_demo.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "id": "498871cf", "metadata": { "id": "498871cf" }, @@ -16,10 +15,28 @@ "- Load the configurations from the YAML file.\n", "- Create a `LAPQ` object and pass the full precision model, dataloaders and configurations.\n", "- Quantize the model by calling the `compress_model` method." - ] + ], + "id": "498871cf" }, { "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "skKWRRtMsfRM", + "outputId": "a1265ade-b421-4bc1-f456-63b88c69fdbb" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" + ] + } + ], "source": [ "USE_COLAB = True\n", "\n", @@ -35,41 +52,23 @@ "config_path = library_path + \"/experiments/quantization/LAPQ/lapq_config.yaml\"\n", "weights_path = base_path + \"/weights/resnet50_cifar100_pretrained.pth\"" ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "skKWRRtMsfRM", - "outputId": "ada0dc11-61c2-4637-cf0e-a4f25ad28b3c" - }, - "id": "skKWRRtMsfRM", - "execution_count": null, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" - ] - } - ] + "id": "skKWRRtMsfRM" }, { "cell_type": "code", - "source": [ - "%pip install -q -r $requirements_path" - ], + "execution_count": null, "metadata": { "id": "P7Kar046xSEd" }, - "id": "P7Kar046xSEd", - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [ + "%pip install -q -r $requirements_path" + ], + "id": "P7Kar046xSEd" }, { "cell_type": "code", "execution_count": null, - "id": "dafbd1b3", "metadata": { "id": "dafbd1b3" }, @@ -77,12 +76,12 @@ "source": [ "import sys\n", "sys.path.append(library_path)" - ] + ], + "id": "dafbd1b3" }, { "cell_type": "code", "execution_count": null, - "id": "417e9692", "metadata": { "id": "417e9692" }, @@ -95,32 +94,32 @@ "from trailmet.datasets.classification import DatasetFactory\n", "from trailmet.models import resnet, mobilenet\n", "from trailmet.algorithms import quantize" - ] + ], + "id": "417e9692" }, { "cell_type": "markdown", - "id": "c67e2359", "metadata": { "id": "c67e2359" }, "source": [ "## Datasets" - ] + ], + "id": "c67e2359" }, { "cell_type": "markdown", - "id": "64a12f9a", "metadata": { "id": "64a12f9a" }, "source": [ "### Augmentations" - ] + ], + "id": "64a12f9a" }, { "cell_type": "code", "execution_count": null, - "id": "4c8c6192", "metadata": { "id": "4c8c6192" }, @@ -152,49 +151,35 @@ " 'train': None,\n", " 'val': None,\n", " 'test': None}" - ] + ], + "id": "4c8c6192" }, { "cell_type": "markdown", - "id": "0c41f2b1", "metadata": { "id": "0c41f2b1" }, "source": [ "### Load Datasets" - ] + ], + "id": "0c41f2b1" }, { "cell_type": "code", "execution_count": null, - "id": "b377f3bb", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "b377f3bb", - "outputId": "3e9a49d0-bdcf-45d7-f79d-714f81395080" + "outputId": "b0d816c7-cbe2-4a50-d9a2-bf9d443e9715" }, "outputs": [ { - "output_type": "stream", "name": "stdout", - "text": [ - "Downloading https://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz to ./data/cifar-100-python.tar.gz\n" - ] - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - "100%|██████████| 169001437/169001437 [00:12<00:00, 13715362.31it/s]\n" - ] - }, - { "output_type": "stream", - "name": "stdout", "text": [ - "Extracting ./data/cifar-100-python.tar.gz to ./data\n", + "Files already downloaded and verified\n", "Files already downloaded and verified\n", "Files already downloaded and verified\n", "Train samples: 40000\n", @@ -216,33 +201,33 @@ "print('Train samples: ',cifar100_dataset['info']['train_size'])\n", "print('Val samples: ',cifar100_dataset['info']['val_size'])\n", "print('Test samples: ',cifar100_dataset['info']['test_size'] )" - ] + ], + "id": "b377f3bb" }, { "cell_type": "markdown", - "id": "eec91853", "metadata": { "id": "eec91853" }, "source": [ "### Define Dataloaders" - ] + ], + "id": "eec91853" }, { "cell_type": "code", "execution_count": null, - "id": "464c2e93", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "464c2e93", - "outputId": "499a7028-ebe1-4b26-89ba-3206fda6c59e" + "outputId": "1f95a9d9-3165-427b-c7cc-52377559a9ba" }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "No. of training batches: 313\n", "No. of validation batches: 79\n", @@ -269,338 +254,244 @@ "print('No. of training batches: ', len(dataloaders['train']))\n", "print('No. of validation batches: ', len(dataloaders['val']))\n", "print('No. of test batches: ', len(dataloaders['test']))" - ] + ], + "id": "464c2e93" }, { "cell_type": "markdown", - "id": "85812739", "metadata": { "id": "85812739" }, "source": [ "### Load Pretrained Model" - ] + ], + "id": "85812739" }, { "cell_type": "code", "execution_count": null, - "id": "e4db07ac", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e4db07ac", - "outputId": "c7625367-ce16-4139-a7f1-9b50369ccfe7" + "outputId": "7a942a3e-837e-4081-e6cf-26a1910646ae" }, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "" ] }, + "execution_count": 8, "metadata": {}, - "execution_count": 8 + "output_type": "execute_result" } ], "source": [ "model = resnet.make_resnet50(100,32)\n", "checkpoint = torch.load(weights_path, map_location='cuda:0')\n", "model.load_state_dict(checkpoint['state_dict'])" - ] + ], + "id": "e4db07ac" }, { "cell_type": "markdown", - "id": "0ca3e796", "metadata": { "id": "0ca3e796" }, "source": [ "### Load Method Config" - ] + ], + "id": "0ca3e796" }, { "cell_type": "code", "execution_count": null, - "id": "5b9625ad", "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "5b9625ad", - "outputId": "e34c1fe3-1037-4460-afe8-eb67d5599600" + "id": "5b9625ad" }, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'GPU_ID': 0,\n", - " 'SEED': 42,\n", - " 'W_BITS': 7,\n", - " 'A_BITS': 7,\n", - " 'ACT_QUANT': True,\n", - " 'CALIB_BATCHES': 4,\n", - " 'MAX_ITER': 2000,\n", - " 'MAX_FEV': 2000,\n", - " 'VERBOSE': True}" - ] - }, - "metadata": {}, - "execution_count": 35 - } - ], + "outputs": [], "source": [ - "with open(config_path, 'r') as f:\n", - " config = yaml.safe_load(f)\n", - " kwargs = config['GENERAL']\n", - "\n", - "kwargs['MAX_ITER']=2000\n", - "kwargs['MAX_FEV']=2000\n", - "kwargs['A_BITS']=7\n", - "kwargs['W_BITS']=7\n", + "# with open(config_path, 'r') as f:\n", + "# config_all = yaml.safe_load(f)\n", + "# config = config_all['GENERAL']\n", "\n", - "kwargs" - ] + "config = {\n", + " 'w_bits' : 8,\n", + " 'a_bits' : 8,\n", + " 'reduce_range': True,\n", + " 'act_quant': True,\n", + " 'max_iter': 2000,\n", + " 'max_fev': 2000,\n", + " 'calib_bs': 256,\n", + " 'calib_size': 1024,\n", + " 'seed': 42,\n", + " 'gpu_id': 0\n", + "}" + ], + "id": "5b9625ad" }, { "cell_type": "markdown", - "id": "87e6c554", "metadata": { "id": "87e6c554" }, "source": [ "### Quantization Method: LAPQ" - ] + ], + "id": "87e6c554" }, { "cell_type": "code", "execution_count": null, - "id": "e21d5073", "metadata": { "colab": { + "background_save": true, "base_uri": "https://localhost:8080/" }, "id": "e21d5073", - "outputId": "50e0b908-b8a7-49f4-93e4-e11fd6752220" + "outputId": "a3022343-845b-43b3-a9c1-5a1497b26408" }, "outputs": [ { - "output_type": "stream", - "name": "stdout", - "text": [ - "==> Using seed: 42 and device: cuda:0\n", - "testing pretrained model before quantization\n" - ] - }, - { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 79/79 [00:10<00:00, 7.57it/s, acc1=72.5, acc5=91.5]\n" + "100%|██████████| 79/79 [00:15<00:00, 4.99it/s, acc1=72.5, acc5=91.5]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "top-1 acc: 72.52%, top-5 acc: 91.52%\n" + "==> Full Precision Model: acc@1 72.518 | acc@5 91.525\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 79/79 [00:08<00:00, 8.84it/s, acc1=69.5, acc5=90]\n" + "100%|██████████| 79/79 [00:08<00:00, 9.10it/s, acc1=71.8, acc5=91.1]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "==> Quantization (W7A7) accuracy before LAPQ: 69.5115 | 90.0316\n" + "==> Quantization accuracy before LAPQ: acc@1 71.756 | acc@5 91.149\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 10/10 [00:20<00:00, 2.00s/it, loss=0.176, p_val=4]\n" + "100%|██████████| 20/20 [01:00<00:00, 3.02s/it, loss=0.0998, p_val=3.9]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "==> using p val : 3.66 with lp-loss : 0.18\n" + "==> using p-val : 3.481 with lp-loss : 0.093\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 79/79 [00:10<00:00, 7.89it/s, acc1=72.3, acc5=91.3]\n" + "100%|██████████| 79/79 [00:11<00:00, 6.91it/s, acc1=72.2, acc5=91.5]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "==> Quantization (W7A7) accuracy before Optimization: 72.2508 | 91.3370\n", + "==> Quantization accuracy before optimization: acc@1 72.241 | acc@5 91.535\n", "==> Starting Powell Optimization\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 2000/2000 [09:21<00:00, 3.56it/s, curr_loss=0.176, min_loss=0.152]\n" + "100%|██████████| 2000/2000 [04:43<00:00, 7.06it/s, curr_loss=0.092, min_loss=0.092]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "==> Layer-wise Scales :\n", - " [ 0.33818299 0.62134768 0.82564299 1.02090729 0.95200617 0.36689557\n", - " 0.56235786 0.83859347 0.14576932 0.61901607 1.22165686 0.47066361\n", - " 0.26149886 0.74342126 0.45708764 0.14837253 0.15520184 1.14811294\n", - " 0.17855284 0.39177551 1.10277545 0.2693316 0.21350731 0.71349451\n", - " 0.36680011 0.12632736 0.51384439 0.2863148 0.12838054 0.18741796\n", - " 0.85134318 0.10731246 0.16548798 0.66784387 0.09932491 0.16292682\n", - " 0.85598874 0.12488759 0.20705417 0.68615477 0.18071352 0.27441487\n", - " 0.54972186 0.30531706 0.2248336 1.19240661 0.4168146 0.04306774\n", - " 0.33290503 0.80163794 0.01937079 0.19003982 0.72733849 0.34951356\n", - " 1.99468306 1.23356115 0.83784936 0.51849612 0.43591889 0.5504359\n", - " 0.84351204 0.81898661 0.38176331 0.57372303 0.48332823 0.81326441\n", - " 0.30857745 0.38395615 0.6832149 0.65068425 0.63195158 0.52181466\n", - " 0.65721197 0.64087668 0.65638089 0.24518578 0.48958696 0.70771214\n", - " 0.7810806 0.36986201 0.37629303 0.68606285 0.71880917 0.48262717\n", - " 0.45337911 0.37663389 0.68937862 0.7618183 0.55862383 0.57610431\n", - " 0.47111681 0.6936263 0.32051978 0.35080028 0.6339107 0.80058439\n", - " 0.34578153 0.34025314 0.3652297 0.80349561 0.35078868 0.34667977\n", - " 0.51684356 0.97855669 0.35530103 0.43259362 0.493544 0.7734252\n", - " 0.54179977 0.55423125 0.59282164 2.02728408 0.61292773 0.68140569\n", - " 1.75588362 0.81362313 3.61825858 0.41211504 0.69931554 2.21552974\n", - " 4.88437368 0.2972496 0.3892928 2.21019835 10.95171503]\n" + "==> Optimization completed with status: False\n", + "==> Optimized alphas :\n", + " [ 0.32192663 0.4921856 0.44087177 0.9391082 0.95024213 0.35209557\n", + " 0.56010642 0.8362113 0.14528238 0.6173208 1.22021341 0.46791642\n", + " 0.25910885 0.74059974 0.45257379 0.14750679 0.15402703 1.13943211\n", + " 0.17752448 0.38750959 1.09536373 0.26694447 0.21156799 0.70860321\n", + " 0.36488586 0.12406421 0.50658086 0.28335763 0.12680141 0.18381498\n", + " 0.83998023 0.10583398 0.16331125 0.65832013 0.09808584 0.16091051\n", + " 0.84497283 0.12403724 0.20360942 0.679278 0.17891735 0.26773851\n", + " 0.54199507 1.34550151 0.21835104 1.16213213 0.40100812 0.04182439\n", + " 0.32693615 0.75804108 0.01931836 0.23854705 0.77586533 0.35659174\n", + " 1.99467082 1.18234275 0.75984839 0.50286948 0.43017 0.54280295\n", + " 0.80808552 0.7176247 0.37142049 0.5562059 0.46602321 0.71515874\n", + " 0.30534324 0.37335814 0.67148537 0.62658289 0.61451279 0.52567379\n", + " 0.63642817 0.61713725 0.63287643 0.24550927 0.4923878 0.70035124\n", + " 0.75159778 0.36112166 0.37687481 0.66791642 0.7132149 0.49287515\n", + " 0.45697315 0.36587468 0.68228734 0.75030695 0.53571547 0.56328548\n", + " 0.47901733 0.68669396 0.31868012 0.36477025 0.611461 0.77932724\n", + " 0.33648931 0.33574072 0.35906766 0.78264685 0.34599894 0.33887686\n", + " 0.49970291 0.94860415 0.35073394 0.42563926 0.48520955 0.74453487\n", + " 0.51277885 0.53216721 0.57372373 1.96872515 0.60519236 0.67802123\n", + " 1.73508274 0.78461236 3.43784676 0.39349705 0.66659818 2.10375101\n", + " 4.73006429 0.28074448 0.38541939 2.15557389 10.93467115]\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 79/79 [00:08<00:00, 9.15it/s, acc1=72, acc5=91.2]\n" + "100%|██████████| 79/79 [00:08<00:00, 8.95it/s, acc1=72, acc5=91.2]\n" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "==> Full quantization (W7A7) accuracy: (72.03322784810126, 91.18868670886076)\n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n", - "swapped : \n" + "==> Final LAPQ quantization accuracy: 72.004 | 91.228\n" ] } ], "source": [ - "quantizer = quantize.lapq.LAPQ(model, dataloaders, **kwargs)\n", - "qmodel = quantizer.compress_model()" - ] + "quantizer = quantize.lapq.LAPQ('resnet', dataloaders, **config)\n", + "qmodel = quantizer.compress_model(model)" + ], + "id": "e21d5073" }, { "cell_type": "code", "execution_count": null, - "id": "c6edd9e9", "metadata": { "colab": { - "base_uri": "https://localhost:8080/" + "background_save": true }, "id": "c6edd9e9", - "outputId": "1e9224a6-7bf5-42d2-cc44-0456a742bcfa" + "outputId": "3781a5d3-b56b-470a-afb5-3ff166ec5d94" }, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "testing quantized model\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ - "100%|██████████| 79/79 [01:15<00:00, 1.04it/s, acc1=72.3, acc5=91.1]\n" + "100%|██████████| 79/79 [01:26<00:00, 1.10s/it, acc1=72, acc5=91.2]\n" ] } ], @@ -608,28 +499,26 @@ "print('testing quantized model')\n", "qmodel.to(torch.device('cpu'))\n", "acc1, acc5 = quantizer.test(model=qmodel, dataloader=dataloaders['test'], device=torch.device('cpu'))" - ] + ], + "id": "c6edd9e9" }, { "cell_type": "code", - "source": [ - "print('testing full precision model')\n", - "model.to(torch.device('cpu'))\n", - "acc1, acc5 = quantizer.test(model=model, dataloader=dataloaders['test'], device=torch.device('cpu'))" - ], + "execution_count": 12, "metadata": { + "id": "GMg5Wvv-P5Z9", "colab": { "base_uri": "https://localhost:8080/" }, - "id": "GMg5Wvv-P5Z9", - "outputId": "083d9b2d-4845-4045-8fda-d1df44bdc509" + "outputId": "5e33b0a4-ac58-4e16-b884-ec2a0eaa224f" }, - "id": "GMg5Wvv-P5Z9", - "execution_count": null, "outputs": [ { - "output_type": "stream", + "metadata": { + "tags": null + }, "name": "stdout", + "output_type": "stream", "text": [ "testing full precision model\n" ] @@ -638,21 +527,26 @@ "output_type": "stream", "name": "stderr", "text": [ - "100%|██████████| 79/79 [02:54<00:00, 2.21s/it, acc1=72.5, acc5=91.5]\n" + "100%|██████████| 79/79 [03:25<00:00, 2.61s/it, acc1=72.5, acc5=91.5]\n" ] } - ] + ], + "source": [ + "print('testing full precision model')\n", + "model.to(torch.device('cpu'))\n", + "acc1, acc5 = quantizer.test(model=model, dataloader=dataloaders['test'], device=torch.device('cpu'))" + ], + "id": "GMg5Wvv-P5Z9" }, { "cell_type": "code", - "execution_count": null, - "id": "56e04513", + "execution_count": 13, "metadata": { "id": "56e04513", "colab": { "base_uri": "https://localhost:8080/" }, - "outputId": "ed654fbd-a03a-44a9-da52-3ac42c159db5" + "outputId": "966c5bcd-d964-44cc-a82a-16ed5b30b1df" }, "outputs": [ { @@ -673,32 +567,37 @@ "\n", "print_model_size(qmodel)\n", "print_model_size(model)" - ] + ], + "id": "56e04513" }, { "cell_type": "code", - "source": [ - "torch.save(qmodel.state_dict(), \"quantized_res50_c100.pth\")" - ], + "execution_count": 14, "metadata": { "id": "TxsdFuMrPleV" }, - "id": "TxsdFuMrPleV", - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [ + "torch.save(qmodel.state_dict(), \"quantized_res50_c100.pth\")" + ], + "id": "TxsdFuMrPleV" }, { "cell_type": "code", - "source": [], + "execution_count": 14, "metadata": { "id": "JJ4iwacl2pQw" }, - "id": "JJ4iwacl2pQw", - "execution_count": null, - "outputs": [] + "outputs": [], + "source": [], + "id": "JJ4iwacl2pQw" } ], "metadata": { + "accelerator": "GPU", + "colab": { + "provenance": [] + }, "kernelspec": { "display_name": "Python 3", "name": "python3" @@ -714,12 +613,7 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" - }, - "colab": { - "provenance": [], - "gpuType": "T4" - }, - "accelerator": "GPU" + } }, "nbformat": 4, "nbformat_minor": 5 diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index a591843..3f9610c 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -65,35 +65,34 @@ def set_alphas_np(self, alphas: np.ndarray, weight=True, act=True): class LAPQ(BaseQuantization): - def __init__(self, network: str, dataloaders: dict, **kwargs): - super(LAPQ, self).__init__(**kwargs) - if network not in supported: - raise ValueError(f"Network architecture '{network}' not in supported: {supported}") - self.train_loader = dataloaders['train'] - self.test_loader = dataloaders['test'] + def __init__(self, arch: str, dataloaders: dict, **kwargs): + super(LAPQ, self).__init__(dataloaders, **kwargs) + if arch not in supported: + raise ValueError(f"Network architecture '{arch}' not in supported: {supported}") self.kwargs = kwargs self.w_bits = kwargs.get('w_bits', 8) self.a_bits = kwargs.get('a_bits', 8) self.reduce_range = kwargs.get('reduce_range', True) - self.fake_quantize = kwargs.get('fake_quantize', False) - self.calib_batches = kwargs.get('calib_batches', 16) self.act_quant = kwargs.get('act_quant', True) - self.test_min_max_quant = kwargs.get('test_min_max_quant', True) self.p_val = kwargs.get('p_val', None) self.max_iter = kwargs.get('max_iter', 2000) self.max_fev = kwargs.get('max_fev', 2000) self.eval_freq = kwargs.get('eval_freq', 500) self.verbose = kwargs.get('verbose', True) - self.gpu_id = kwargs.get('gpu_id', 0) + calib_bs = kwargs.get('calib_bs', 256) + calib_size = kwargs.get('calib_size', 1024) + self.calib_data = self.get_calib_data(calib_bs, calib_size) self.seed = kwargs.get('seed', 42) seed_everything(self.seed) assert torch.cuda.is_available(), "GPU is required for calibration" - self.device = torch.device('cuda:{}'.format(self.gpu_id)) - if self.verbose: - print("==> Using seed:{} and device cuda:{}".format(self.seed, self.gpu_id)) + gpu_id = kwargs.get('gpu_id', 0) + self.device = torch.device('cuda:{}'.format(gpu_id)) - def compress_model(self, model: nn.Module, inplace: bool = False): + def compress_model(self, model: nn.Module, inplace: bool = False, + test_before_calibration: bool = True, + return_fake_quantized: bool = False, + ) -> nn.Module: model.to(self.device) model.eval() @@ -112,13 +111,13 @@ def compress_model(self, model: nn.Module, inplace: bool = False): 'method': UniformSymmetricQuantizer, } - if self.test_min_max_quant: - acc1, acc5 = self.test(model, self.test_loader, device=self.device, progress=True) + if test_before_calibration: + acc1, acc5 = self.test(model, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Full Precision Model: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) qmodel = QuantModel(model, weight_quant_params, act_quant_params) qmodel.set_quant_state(True, True) - acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) + acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Quantization accuracy before LAPQ: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) del qmodel @@ -135,9 +134,9 @@ def compress_model(self, model: nn.Module, inplace: bool = False): act_quant_params['p_val'] = p qmodel = QuantModel(model, weight_quant_params, act_quant_params) qmodel.set_quant_state(True, True) - loss = self.evaluate_loss(qmodel, self.device) - losses.append(loss.item()) - pbar.set_postfix(p_val=p, loss=loss.item()) + loss = self.evaluate_loss(qmodel, self.calib_data, self.device) + losses.append(loss) + pbar.set_postfix(p_val=p, loss=loss) del qmodel # using quadratic interpolation to approximate the optimal quantization step size ∆p∗ z = np.polyfit(p_vals, losses, 2) @@ -150,7 +149,7 @@ def compress_model(self, model: nn.Module, inplace: bool = False): qmodel = QuantModel(model, weight_quant_params, act_quant_params) qmodel.set_quant_state(True, True) p_intr = self.p_val - min_loss = self.evaluate_loss(qmodel, self.device) + min_loss = self.evaluate_loss(qmodel, self.calib_data, self.device) del qmodel if self.verbose: @@ -159,7 +158,7 @@ def compress_model(self, model: nn.Module, inplace: bool = False): act_quant_params['p_val'] = p_intr qmodel = QuantModel(model, weight_quant_params, act_quant_params, inplace=inplace) qmodel.set_quant_state(weight_quant=True, act_quant=True) - acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) + acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Quantization accuracy before optimization: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) print("==> Starting Powell Optimization") @@ -177,62 +176,40 @@ def local_search_callback(x): print(it) if self.verbose and it%self.eval_freq==0: qmodel.set_alphas_np(x) - self.eval_acc, _ = self.test(qmodel, self.test_loader, device=self.device, progress=False) + self.eval_acc, _ = self.test(qmodel, self.test_data, device=self.device, progress=False) self.eval_iter = it # print('\n==> Quantization accuracy at iter [{}]: acc@1 {:.2f} | acc@5 {:.2f}\n'.format(it, acc1, acc5)) self.min_loss = 1e6 self.pbar = tqdm(total=min(self.max_iter, self.max_fev)) res = optim.minimize( - lambda alphas: self.evaluate_calibration(alphas, qmodel, self.device), init_alphas, + lambda alphas: self.evaluate_calibration(alphas, qmodel), init_alphas, method=min_method, options=min_options, callback=local_search_callback ) self.pbar.close() alphas = res.x status = res.success if self.verbose: - print('==> Optimization completed with success status:', status) + print('==> Optimization completed with status:', status) print('==> Optimized alphas :\n', alphas) qmodel.set_alphas_np(alphas) - acc1, acc5 = self.test(qmodel, self.test_loader, device=self.device, progress=True) + acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Final LAPQ quantization accuracy: {:.3f} | {:.3f}'.format(acc1, acc5)) - if self.fake_quantize: + if return_fake_quantized: quantized_model = qmodel else: quantized_model = qmodel.convert_model_to_quantized(inplace=inplace) - - return quantized_model + return quantized_model - def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel, device): + def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel): qmodel.set_alphas_np(alphas) - loss = self.evaluate_loss(qmodel, device).item() + loss = self.evaluate_loss(qmodel, self.calib_data, self.device) if loss < self.min_loss: self.min_loss = loss - self.pbar.set_postfix(curr_loss=loss, min_loss=self.min_loss, eval_acc=self.eval_acc, eval_iter=self.eval_iter) + self.pbar.set_postfix(curr_loss=loss, min_loss=self.min_loss) self.pbar.update(1) return loss - - - def evaluate_loss(self, model: nn.Module, device): - criterion = torch.nn.CrossEntropyLoss().to(device) - model.eval() - with torch.no_grad(): - if not hasattr(self, 'cal_set'): - self.cal_set = [] - for i, (images, target) in enumerate(self.train_loader): - if i>=self.calib_batches: - break - images = images.to(device, non_blocking=True) - target = target.to(device, non_blocking=True) - self.cal_set.append((images, target)) - res = torch.tensor([0.]).to(device) - for i in range(len(self.cal_set)): - images, target = self.cal_set[i] - output = model(images) - loss = criterion(output, target) - res += loss - return res / len(self.cal_set) \ No newline at end of file diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index d292124..3256555 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -242,7 +242,7 @@ def _swap_module(self, module: nn.Module, mapping: dict): if _type(module) in mapping: qmod = mapping[_type(module)] new_module = qmod.from_float(module) - print(f"swapped {type(module)}: {type(new_module)}") + # print(f"swapped {type(module)}: {type(new_module)}") swapped = True if swapped: pass #TODO: hook management @@ -337,25 +337,44 @@ def _get_folded_params(self, conv_module: nn.Conv2d, bn_module: nn.BatchNorm2d): class BaseQuantization(BaseAlgorithm): """base class for quantization algorithms""" - def __init__(self, **kwargs): + def __init__(self, dataloaders, **kwargs): super(BaseQuantization, self).__init__(**kwargs) - pass + self.train_data = dataloaders['train'] + self.test_data = dataloaders['test'] - def quantize(self, model, dataloaders, method, **kwargs): + def quantize(self, model, method, **kwargs): pass - def get_calib_samples(self, train_loader, num_samples): + def get_calib_data(self, num_samples: int, batch_size: int): """ - Get calibration-dataset samples for finetuning quantized weights and - quantization parameters + Get samples for calibrating quantization parameters """ - calib_data = [] - for batch in train_loader: - calib_data.append(batch[0]) - if len(calib_data)*batch[0].size(0) >= num_samples: + inp, out = [], [] + for batch in self.train_data: + inp.extend(batch[0]) + out.extend(batch[1]) + if len(inp) >= num_samples: break - return torch.cat(calib_data, dim=0)[:num_samples] - + batches = [] + for i in range(0, num_samples, batch_size): + batch_inp = inp[i: i+batch_size] + batch_out = out[i: i+batch_size] + batches.append([ + torch.stack(batch_inp, dim=0).to(torch.device('cuda')), + torch.stack(batch_out, dim=0).to(torch.device('cuda')) + ]) + return batches + + def evaluate_loss(self, model, dataloader, device): + criterion = torch.nn.CrossEntropyLoss().to(device) + model.eval() + res = 0 + with torch.no_grad(): + for inputs, targets in dataloader: + outputs = model(inputs) + loss = criterion(outputs, targets) + res += loss.item() + return res/len(dataloader) def sensitivity_analysis(self, qmodel: BaseQuantModel, dataloader, test_bits, budget, save_path, exp_name): From a96122d6ca4d27afaba7ba242bf05d7de94b61db Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 2 Oct 2023 18:03:44 +0530 Subject: [PATCH 32/35] added diagrams to info --- .../quantize/assets/quantization_pipeline.png | Bin 0 -> 352754 bytes .../quantize/assets/quantizer_flow.png | Bin 0 -> 216903 bytes trailmet/algorithms/quantize/info.md | 6 +++++- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 trailmet/algorithms/quantize/assets/quantization_pipeline.png create mode 100644 trailmet/algorithms/quantize/assets/quantizer_flow.png diff --git a/trailmet/algorithms/quantize/assets/quantization_pipeline.png b/trailmet/algorithms/quantize/assets/quantization_pipeline.png new file mode 100644 index 0000000000000000000000000000000000000000..28f3de9b0721865c4dcbf0baedbeef9d91d0ef6b GIT binary patch literal 352754 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

QlMu_ozv(u?i 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 z zyGKLv7dBDGC=^6y*$`hk5(y;%^l$r}ndNX{Dx`qo8;%$S*7tjt*NnVnRB`_Ad! zhA1%eap~$G8B>_hngFdb8zWx#>`>2yaCB+X(AO~y+?ySPsXQ3(cjJM0D8|Uo;R48l zW+77i6Qx(u7BwkR#NKU^PchMHPu&k})Q8Nv<^J>`BA_2Qj8jy(erZYRWa&EPa%-AI zQxARvpoB=LYVwXzy_O-4$K0)aF)?)6XwdiX?sb^VbYD6(eMZd4u?~pkd*x~@U_#Tj zWTY39({}gw^8!mLAAT24vBmy(XRJ>Q>PBf>QPl=lvf_>?a{|$B)KqZ5o${s=Q%MogAyL7P{g| zACw{CVOlcODfj(d0pc9?sh*82InTDqqk;Y$BVSk)gP)##J`=D{r4;z>k2FgkYSH^J z{wm1DzO#6utL4_J?iqAfq;8iqPy5nTTi?U5jw}pGMMh%O`kwjK)-+xL90PCaNd@E{ zS=(3IP{q3gkD3g!M=yhuWX`}0w7XDOP&eeJeZFns39v)xJ_r6v;Tcjo>uX1!^c&C7 z*624cH!BQ^Uf5XKIHsl-j>1beRHNf1!PRZ{hu#0jbu{+tEWssz&!L}65~EWOY46h~ z8+Sd*KlR+~R#(;YLMYky&bH&jZKH*zfX$Cj!>uZA5|Z^k2TYzP3~mCdF2R-amY0-< z)V<6Wvc9%tDTrKx;tKb-;Y4x{Z3(`ZxpzN}_a}+Cbym!80dnp}uB@ry0j_gP$Z)J` z(e16{icWesd$hX?Q48n&Bpg=37`UGxV^?`8Cx2_dsZvUNf~4HT5_*wwTr9ZPI3T~d z%$R0QFW>Tn^O#=%T17(M@zk2&$nID_r(JS}vwWgejEG3jfv%mwrhCIVImJ~Ca>}qJ za!m_+Q@MRtao+v2ihV-^7mf-qoRiyY+%aJWp2LklF% z>c|+&^%aQqq;3e9$t4JLufrKCh22a}0U23+{~a)lA0O&-E)aaR?t})74kz6D)yD7PAo$~5vEzc@kHg?!Xtwo1${wnnr`OVZOg_m4wmX~Q1QZN=L*%J z)-mN=pAf9Hwhd;MidiAf7W2$?TRK&83ezDJC~Fe{PF|tagE3{z-XZz#mOeRFuvpuy zYhc8HDrMPWqYn<6cL1UKF*q*mJhUC15;moWI`qk=P$W5&2y5Hh<4=HAYF_|yYJd7b zegC#VE|PI7w}>->dgVVQsz7+SUv;4$JB^eF`dNR0t4aN*_1@L&V-DM;Opj3nRp@dH zQ|}XoIrx;~kG33*TMx5wf88}7%7v26iB#G8#vQyl88czqM}Fr+z1!aViU|!HLBSwu z0s5Nz`WZGXbNPyHCs=tf^C?J4{Pp2H{SONdx`7`s`bHJ&{3lNHH6iSzM{E1huD7#! zt=M^y+HBkPcqvUv>l)Xb`6Z<|*X66L6vvo~=-syxj341Ez!Mq+Lc-GN{Rg`*UtwLI zCs#4R6sqG7s;mVf<{wcbS)IX?m=+1B-51-njKQqSR zc)A(h_>t^RpKvsfacL;dDWyv}>PkH;Cg-&+4l^3w7|+)=%}3rJds??pea$2$1 zPiV1Uggr1W!7jb2BwlG?hcZ^qLXIwuLc&H8Epz?0;s;`44X4~pXe7&x8|W_nH?R$f zh$Gw5zZ1s1D&ngzyqIJZnzfWRiHK{Di`#V2m!>j|oP0!+EbbQfkzFS0J&X1>C#GM_CZ&``qOh<_{?q{8DJuR_YfmWIp zPe-j(W;)_ga4K8VxCN|DRB3?k^Q6Pv*~$Dgm)~dk z?diTmx|UXE`jnl5vg(ixnaKNg3MUI87*at%v$7Fbb)Z}(zcl*6>cAnus%udeF74%& ztn^$?4$Uk!%GlCrX*+O!vo%yxBZ2$#248eyfvHTRsG(N(9SA>GOGb;Z6& zl*~w%FEwMVMU!OLJRDE{RG_dZl*%?&0gat~?{`}4fdAT|{EUn?@0+orf^cY&$fn9Z zand7Bm%}?nh?Dqw=)gD$HNv^jZ(FqrW9gMsK&*+Jtx%HZZ{t>Tprjlj;V8QAXrpx|^QRI?bt_vz#Z>gibk9Mlt<-6Jv^Lrkb zTR}J8*iw=kJwg7hoF}5U1N%7iWgQFi;5;E<(0F}$nXH9QpNp4&SZSzoU#U!GNkh#_ z)%meo636V;{zadp&l}k=akW`T58a|7^RAG^vS6^-v<9BO<#UfxAY+*yb`~>)b-UWH zP9Hk>O45L9sl(+R9l0)S}c{)Wz(>7E*3f9yy4F_A;UtZh1e~s{++}$7jfQB!k!!EZbyNDhK{uk&+0>t?(UIgND#$t_ak@LZ$!A!4 zz)S3w#Vox)Y_(ZlM_u{!wd4ZY)rB2(>> z45I^z^*B?QS8%vf(CeB!SE{O13`eyf)t zV--P6+A-34GibfcRMuGE+PdHtGo7#=AyJ;lXL^oJpF~0ZUk(?I%uM)a_757)6Y3Tn zMJ^^JFXRz3jb@#KCQ%m@vLbc#WpDDhPOf(1G8iEL1x(GNOPK%b4}acE-EllV=#IEW zF`_O|{Ayw{Nsi0ndZx5}M&OCOb z{eU6&$+`Ve1MGJdsg;JT{KW9k&R*Vq2}XC>TelYmIEN)k1EDn`I6Q9s&Uv4p zw~8ldb28Iezu$Vcm02Iy^8eWS>bNMou4`flgA%0?FhB`WxpO$q_v7=t-#_z1WM;1G#M*1Gz4p0u&&N$fz`UHXr<03uB(*Wu z4&}pRg%b^_^AKm#OX@}sRuh>X%HvU8^}yQ`T0cchY%FKYja(9xUfVZZGUSP;T-pKqvMknCgIx@y>DWnJ9UH0BYlo#<}MK}ro^+c zE&|#bI34ZhcNyg3w}($_J=USO$DDX@%v5eFOp}pKm#<|e4}{+|fzdXTT<;a>Q*7_| zj72Asjcq29p1%^H_t$8?x?}y=s?1#bg7k#E&NR%Nx%!PTAqM6B3&zN_Yl(KtnU5yl z3c&68+VR1*K>^iYFH`aL0o>zA<)kKWPt5A<;G)ZYOo*EzqHE-jV?#SVJfNzx0B_f~ zXVMtrfF)JxW#>9(kLhGhUiZc6@tj-ei5ZI4E5%Ugx<)18G8_5gyX0Zm3^Uw6|=(sU^_EqDp=-;H)u) zSW&m*Yw|Bnp2jD3%?P-ww&<_xACZHp0unjcPlInYPR$AbbIabU7?t&n1c=1q#B4uH zB*vBS&6|hrV^VVD;+!zLf%ZBtMh6O?eVwA{A^YiA1-qoWf8P1;uuTc0aHrQCZ?QWu zx46%Y-!W^~L0kM10+YBPxb_)%4y9z(^FG$0AjFZUXMa8+vm@j_XN|A@@`!4vB0tgT6fSY& z*qE>lKJB@~VuB}mmlMOa`OjCx;+H8R1S2HA#EB1!{sZ{GR}0v$*;kQwzQyFeIm$|l zaQxvByB|^8?e}}^20ntYSduIk`}>~|X%U7RMU1=FpVxved}*le%J;+>Sn2K|hC1Hc zjHKkhB;1skx-e(zNZ_$i#HZn9bUDKD_r{hF8_`->4G!1us3&BZs0`2l9ugDtHcoMH z&K2%DoG*ypVt(V+1UEZb%0T3^g^pAyz#Xbrg{?)dnyU$3_50%A?WLrktN+!;1MyRw zJGi)5|1MgJm?BVm`(DQ|&<{*{n~?vBVuZK_-i8*#2S+ML&S&k6K9p2dg;qT(C+$ZR zyTQCujun+!F~J^vFCW^Ma*{QaXp*>R<9`?zXk9NffbxXVAP-FRgw~!D(*n zR$#9t5oImV38C_#8!fFEwXiq(;uYLS;}!04Vru~6X< z)BL>4&Kf5;Z`Dr(rwW^r(Ym+vYMr48?4X&{Z3h*~K0KbNbhNo@Y&`nyvjx_Oj*7Do zD{T@+z*|ZR!aQ=i=Q3X5?82wI1m3MxJIs`rMcHKV!CxuV(Zl7sQ;yGd?P zR=Ab&?y*12E$a8oSpBJan@KOd8$V*bPyRP;`ga#W2yyA4=x5lkz79@Tt_zA8-?P7k z`a;@JfGY)46PBYK-ILjg&t=p^JM$VYH?)WZMnzQ_B`c@AbO!Qf;K?%)21uR2#$vnu z9sc`;SX7vlTvj9MZ%VQ8Op!xrVVVYmH>=MdE7tvrGVLFV=q9{vH4!F0z)>xLK{0lP1pdMEx^qkHX1R%gn|qu}iEoxiMH`_>H=(wdf{d`FI$1v9<}QLaD19J0g2ZD{@2g zQ)NB{MXgU%wwI7E^)*JC{L+L9?@D#!K7A>I@H&nNNua;$OYr2Qg2HYt75{$8>iAxT z`B-gJ_WTCy|S*_aM?WLo0MO~(tG}d3&M{Wl&Y*-WOGR)l#=ps zbZepPSyUz1kBgnBY{+flV%rN$@@_dBT~UdlOLmd3$e3Rm+>ImTfU**-JD6tMXr>q& zLazQ-p#B}V>w7RLI)h=%FR#|I93CZEWP2f)(>)x2FQ9@@uw_&#De*m?$;gmsy(!r| zeA)Mnzr5fxDtJw))oWH1XxCIG$WLV;Aj?Amg*f+OB0QB89&{0_P1o<@!Z#?!3${{& z3;-5WqGtxq+Fv&}M&#j*P*B+nmwxj$^nm4eCQMkI#XgAHqqDj|Pp`*epY`dyIkr(Q ze$WM zEa*`v;%GTSJK;uP%hw&a2f<&Rm>RE z{re{IU>qKj!V;6cE?$|gLS|}SgKZ@2?$sAiHGRtly~BTohu(sRY{RLji)r@tX5*Tn zUHvw|H@*2b6Q#8?{~#+ zD!Qc_0n~biXt>KVDpUCZwSsi9pu`e7loPPe={G?pS5bd4LT|Ksw5aW}Fhc6zHendh zyQilwauGW>>Tmx{Mz&OT;4tmz27(BeA05xVl>*jt$jEZ`($S-~rFFmH&8%d4l5YZh zFBoUNN+Wc%438fZ`~4r9HFRUR*z$uWkJnJHlGwUy>)LAvd}F~pD1JaJJq7x;n4{#Z zlmPDX)6 zm+OB1znVt*Fesl6z_{Fcx06D>v=dMvN()A|S536dwj4D&AZe)+8Dce`h2f0227KHg}m73^-HH8eQ(taf?rSh7)6d$22bv2`5r){v5O#ql(6 z&AyB30mui_B%$2LcBS()UJ*edpJj^PPsMg|O5*6FGn7G#;)am)h6>{|dR) zymZHru%N*Ek&5*gi#}uFCQFLhA3QKtu}H^{qW%P4K{~*5mjM z4I)@z@xMY-8uQJ6CiA2+i3T6(i{-Fvoo#xO024w@pE4BF&52yAV|B18OY55s?)&%k zzx>h)0SPT##asC{r}??22gJ#cG3<+vQ`l9wlp*wlw;ZAc$C|`uTgXHS^6R!DZ<5>^ zDTG;Y)^ZH5m!*E}=<+%4xPQ8K!^DcH+3#}lMC!42kC47*k(DLvjBcg@^s@Xa84cIf zb-E+*Y@583L&HbgRw^AZiVb5oZ+@B{{%E=K&7IoMb3)kUyDD*~!!1wv=jF09j!6}b z9OTaplUb|mLJN=X)71et{msoEw@HU8vJBi@+6>rEGl>z-gTnA9%jcsJe&h7D2*;@X zkvdfJn|_ru>27#p8koI@D?y7?p?6JfPU^s0WihQH z$`D$n5MJZ`kE^{0?ZQK6vW9{?;ridwN9ZMj8|ZQ@1$;6iy~%eARwuaim#VDV3zEhB zU27jc2u?TZ4s9q43Xi|2s#15bBl?ZfxU>o(-iA!pEPKn`kLg*fZs)go9!&bo{V*aS z3p=T4n@I}GN1W{xZTIN_1z1(wGr}Q)H$*r5Pm+G#)WZQ-CL@*f< zYQ|i|c=t9-S4V!R8NRqZuS97$alBJ#vvZUSWOxs?rx#dzKa=6g9mgCc;2~{E5lZ_H6C09?bs+y6{zF?`*Kj&ehG_kkzHlUP8-DAAQz6+PR^P<@+JkcI^Eh`0o}Sq`>n?hmodWZ+ zeU7jXX5Ni~EHuuYXwy8}@U>Hq`Dg~}paXJ_aT~bR*uo5f;fK2Q@&0lD){SHBv9O&V z$dh(v3jI(ZfNj;n^Z=Xe_;J_8azg^|-r>6bn+WuW6yK82*%O|d9`}q$uKeN%uG~wx zZ?xlDR=Vrz;Wc^D`l9S0*{mjS!*0icI;uARQMQK84fW#CyGJ_1p0}?BB(m?QMZ4s= z+OK-1_C(+FtajF(bazQs!$Vw-_}}dJ8uY=~J5uUUMSU;NykgT4M&{<9w3mO-sOl|( za}6=JQt8BnL2Y|rzH`)c?;3$$-sRvPzMNXo!|@-re`+#O`O-5dI*Sn33cYJ)bC%CfL&E1bgo7OEEZgU`J z&X;OnV-@iiUj{w^ux}nr@f~UVevO;VRgtPRS-Tn}itm9P5Da3w-Li&Xq=iJ0L@Q=c zM?>|5BsOjfvAsKgnfU|ZmaPxZOHnCPjR&4}#sh_?s;L+KFAj1D5=Q&mHuJzJ@+Bt9 zdR2R-nQ?~p?kz@OOlapUpvQ-AQ1IONltVPQs-3I3KOJKrx8b+i#(sZc`*nIP((NU? zL-pYt&q>9?m5my9`DVFzi}gwmI2N}67BA8brlg?`#U4bS$g(r>kl^KP?h4rpNFnMH zJkKvS+n<+tU*DNDbBl>@-$;(B1s558_W{{3lVo0e2u0m9E|2kf?%xi%7o;#{o}{e8);K zRg;mR^n3n9rgki7$WspiPki$@21edkU2)3`NyC@=X*|Kx>-+2VTC2DxL>jjWr4UR` z*DD712^XV6{2E({HhsL$uLn>GiCZ4YMs^;~nvWzDi6tcP%9NTAz_-6Jpj zSP2Vtsoq#vU%Vc0x!xLsxv>4fs-g(h>bo+M@MUGrLVgjl{8}QcMi7g)d_P&s_M-s6 z_cC3ac*tahs#m_SCKrQ_>fm>5H31%rKmq=}+v#~Z+NJd@1y6;C*Bw0~mAKF>q&A>s zlcuwLPqY{saArnI^QJal7jJ}UcOFO>G_aa}JJ@k5nhf_{x5XFfokHtUQS80vySGs{ zFPWo8#ds|cR>@KRv?#V5djff);G@gv>SgSB6%HPf6>TYsAGm1jHk!ETDcrnNlOg&f z-F(C7EPAu_YxENixA(5f1M*fYvzPUhe|cO|DP-5GhB#fW{YQS_CR%8u zP2feS})vMzD9_dbP_Pjn?sGtUwCV}}9E#Ty7@fnD-Vd+WLn?e0ZWehgg z?xq3e5b|sK*P`L`F)md%4?%`I-Xen-G1G5`*yYr zoWr6$7uH>hElq_RJGnxFm_u#wypg+cjHerca;rmjUC%aMUo&{P#lR+ioCNF};TdZ2 zm%2|msNl$RsfkI&Dj)5+1+vI^>pgqEvRY2rJ4Wouo!+R6MJ&m%R)t-PG(&M}Jz6OC zkMdfhl|d`o17WuQoWed3fT#p*J}LzV)e9ZjgH%w6?R(DF3D}PhTfxWQdT|2q6ydAnD#)eIwO^gDJRQ zvx1lB%Qykw(P9YLIJQrf@9{plPN8i=8OZ7g_-=Momy^Jp&C@FEH^@1McyG(dxUQ9I zeEUs(JBKQcBE~uoI4vH$lPGsI(nxw=<1U?g2zIY?tc!?`Sf>O>=QPP};pHc=H%{I3 zJ2y`brVj+w4MaYi>5qM^t<&_e6wAy3?R4tU zS2Vd_O3GRA{6zM@6UH3IBq*NCiJigX#d^5KSXn!-Z`~60NsiY>nR&c9RTgQ#h^Irz zPWyV`Vj(CjO|t}7oh-h16f>>lcfJnJy=a-rcyIW*uSSEQqEwFogQoF>r2$D;Pz>-c zvR3fUndPztgzqrs&iG7IirXd2@Fav0yem01goy|bNZ!JIUsvzurKR_xbSUJ;9O3yv zERnhx?Oj1xLxH3BFT9QkwzsQ~Y-jNVEzn)R36(TYB$Hl#3iPHmo-1;+#&@^9T6A<+ zr7`7@Ucr5#cns_Kjl0FIc-@V!D3XetrpQ} z3`j#|utz83xo?2fC?bt(@8sh7En1)_;-;SvtAOXOcZiEh;+19a)amR<3LU-z%Xqg| zi?Yc_CT%9Ca#ud{%Q6t*5};prH4@%_6iF@t;(y;xV@X(WoyM1nwvA z^N=@rn$C7Ab>79IX}IrW>k&hik3a4X&-u2^5n6IbZM{~fEi!Tf&!zJ-?-`+^@i={` zM$PO|hNMD877dkS;RM|kb8sE0xeo6r7LdAIvH{rxnX%f;3k&H9%YARwtRxQgJp;vq)>R^vIzP+ zD5GJ7FeQo3xb5t>Q(Ccxo*h-l5gy0U-mj@DmTe0@T*x&&?X1tV1u_xsDi#NShUd~w z^zNf*+m#HPl%3F8Ax9CQw-^w(KV}y~+N}fqv9Fyhb#l35-G#mBFdDEyQG1Qaw7d+RoH_1!+oCV-wQER zB)G@=zZq+(O*#zz_>y;UV52qIS;BF?k+qZ8l0AB%9IIa@;)~Kls&ba=c49fqw3YYd z^4)Ch`5N9x3Bv}iUkQw6vgOJTtM!rMi<_^_T;w6iZBkme+G3YgRRh9@TvVz2?1li= z%N>#M4LOoZfWn#oqfNN|0vg}pH69$(D7+b z^?aCL7mMtUgsSaY)yMi8$S9gJ=)Eg+iQ7Pt5n%|&CW>inr9lZQMLNDaFx>;8W7a7o zdWkMsE#-ylAyHd7eG^TWA`TeEDSDv3P=4OS|8~JA`!6{9u(y>oH;K}X# zBO?xxSYLOACG4+7-G?94h9u#bA-FOhTzl$Jsg>_pJZ3N{cZhGV;+GeVX|Pv#w0~{_ z6Ehg0-{own$E{IV!4>ZvoYNeutkhDcjk#LE7t687g7%#rbKp9`NSRaavs?RS0i7&u z`&vPit_Y_^^H6}v+$u!XQ;#cJX0beZkUhHi!uGz5e{p>g+D3=~7SBLYZi=Vgko8hu zcA_dd-CckGX}})PusE*eVhbSQAitX{B2euB+S&8zGAy>O-YZY*#n84gDWJHdhZ66D zgztUydKS;Oz3HRpUz?|0N_+441;gcn!eB@ewK{%dx${$e$(@C$7aI0`!TQFhFO>sA zaj7k}g;qsiF*Xpj_6U>3eKbaeSul8nB*TXd>MrKnkc!L$hwal#%l{Ka%fqz0oYK%T5=9 z+<7`R@8T5*9#SC<0a~g0acT~tpqFtXndUMa0ksH73c-VQWdb~&{_dp)c0aKNjlbB# zZC9=HR+7~xf-DBgRmKR!XP5KPA%XXudbnD&($@e3h}+*&mp|xU`ewR5hf)9xE)@Xj z$!BdylHh5x?;)cPVjk*`9*)fcE!Zs8W%PF~^`C0myGNiqYNOie8_`r!0C%8FxNmyh zTL?ICTkw;}MG}IDLLBsNL3WQ44V|s=oXf4o1uqHjezc>3Vf9AX(dD#z@g}VC^q1cAS2&Y8_s66SG6x zrGOINc))ZL^df;xwp)jX=4s9M?BB!kT4t*LT+?NAKP}C}_h!XeX)?-z^m&^QO*c2; zB%eDI9DImK$d$Y0=~SqY=PzT;r=r21mPTrpz2sf$2K2BQvR5f!W7V3W`N&BMdlc4Z zvI3^czjk70gjnp}_)z*#ziKx+Q zdd)m>=vlGVg`G*bvw9cD$$nnKqj@q6BBsr==(jGe3wHZk>1p>mkX2Hn2Y(@1h9G*^ z^3nEblmQ^2k_@|6c@0f1pRl$S0wk z-UtJgI^SIabf#;BNZt9W*}gJQ?!8h$?>GZ@<6@&0!)F_zOSV8pL@n28=Bck;)6+QM zqZ?j=QjIG{hiV?%qkF^2uAZ77yty$b<~FB(N=f+m{q~S0-%p~+xh>!<5=g~&@94-S zG%<={(OgaPVFH$Vsp;C$2Q(^&>#m=IF|8R}G&;LCA@(VHUY#z*C z3n19xjBNtqE6z7OMhV&*kdJuOZ?7x)P=j{IP!_G3ppeJr&7VXRu&#cojfl0PHYBih zc5hD=wMcBf{1kUm*k`Mbs7E1Hl9P05XKo#OVGOM)@Wqb6xZHgLHIMuVCX9y)uU_en zr_z<_lOI@2jB-NF^Hf$WVLEw_OeGM1ky!1J#+@NVG!51&Axg3-Ar)oX8&d=iDx0;(*V2 zF$=!$F7qdHjLNsuK(wat(K=kFD&!S!wlE4uzX4;$XHRf%%+OMesq+}tDs()MIH@>)d<}NKkH0MEIAbsn^6bGaguBsAj{TjE%GFF&|SQmc0UEFT7;A zh~vLYj-X(`E_}1YC#oYLptAMT=pH z!xCZ`C}3$4nAIFG8O&M~lmcjlw$ZG~cEl-JpvO;T5o-ybnP($^ssD}1Jxj0lH zsouXV1}Qelg}gs>CglyvD2beEQoH)akkz4YNP}oqwy;>( zZC3@hzJBIOw@Or!DE{4B?&f5 zuxd>09mRe6C*8fAFo=wZ50$-y9m_Elt=smC^HMw#p*4U8xmS?mL#T2vsOakVjxR|j zMPa+w>@>eM`DsK@;;3Ux22~)UO%=-+e;DN%L#(wY#sOFUr733s*c?dS-ecLPyw9V} zL=|<@EGIGuZ{ul6)w^O)w4#J;qRn8zW9?KQip?bQ+iWMhWx2s8A8+3DFsljdzY8%{ z6Ddl3adxI;+h30$Bd6kEe{O$97QHn`TnNfUpoTJkBDRAjZ|+JykL9wsYpduX@v%WD4?O+TL(gDP2i^|+)MN+u6n*4&n+jfz zC{0*G4Qo8s5A;mKM?`(7IQZY2k$WOiZB4>Y5YvF&R3$LxMdOXjS@RY!Eb2wwy`yE( zK&8Sgs7YUF7VMihm*2y@dsM8q*vj1R*ad<{2 zLk-eaMvNFi$74Ug0CTQIb8-jHVQ43Qvh4wq0i%RLBuQ*-1fF3Kk361Pjh3W7rW*(9 zK4(^t-(`9M9tcLWTMJb9R6Ue!YK)~pjjqS_#x5?j{+e-pQ|q+Y9L>r(eUPl@@aqt5 z4Xs++2>k_}fP{PYUS{!5swK^W8W_FH{nAZ#}!A%ny30ae=qa@}Bm z^>(I!Kgu~(P+bqs(l=;jQB!<1C-6{>e=^OCVC>#;M6>wuimO2=Z*k|cUTD} zmxQ~u&q^*VVph;V5cc_?zZtQx!>$;gbFrS7xCbmLYhTr_X`Uq0v~mW@*z=wCjv6%o z^h)=+wQB4w(!H=}nQv&nw&vJ*6$eFEDXjo!LK%+J*E6Hj>j~4tObcfDdbL!&Qz7z6 z5*?+M8$Q=c3BGaaHjJUFb$9K)V7DR{DSG5;q)^;tY#uNFlO6weILg|vR=$FMmh&wI z?fP2&`RQd${;fEIDT3-=>-1VvRx3BI?KMvny^AV8ZeD*h%njWK2nBo^Q)vzO$L`8L z)Yt@VH@Y0fP-zq64O&?8ooGUy$#kdh<8cuNyRVdvH@$@*mK0j3G{PN7ajtt}<6n{3 zh1Qc)Gc9UfyQA0?C&evUmvKK<^hT{Pr?r0T}cjW02ZM9JYUX#9Uy} zPk~AeQ^@Hw{p5xdH>=t&@M(aWEEi>R0%(5LHhHd4)8NjodkdTM;p@bAkVkRCi_R|f zWmSgw_NKFdVoki`6fmf?uFSyZrwE^k5uC}2Tr*R+8>J#OmEfCTTlE5ygkv~4tMmFi zI_`X!D-{#Ui4<7XTxw`-gGb*-%5`q>d8}dq-9qOixejM{F*{-H!Up6ool$Fupxf;w zmkIMFo&Ws;5d$a}na|jBFH;o1ERa!W^)Z=6KgyM+D}jD@_)YhXlN2suns|`{pIcTp zJ)YLz!Ej*iBdB~S3uW-S$N*1=l1CM#Kd{OX%bIynPzUmG2!Pt^i6 zsgDA~lLUsAP<@7@znIqp(whLwl7o#gRm*BRr9QzH zrxi7XryAROgYVZD8}!80n63nQ8y=~}X7GfQDa@*hnW%JK^jt|y(p?z_UX*@35C?=z zRH^n+cpRrnSbh#Kp6%uWd3N+*gUxmg`D!qT6Zg^_B2_Gu#80xbVWhW(8C!yGZ+;bg z%3y!cU71>FSy8hO6u&Y(r~nM;2CCbcJN`i7UXnaNu>c{4`>ywxK( z0ixq$UG@ByQGOvBO>W2FYp>Fhc*>%Wezgo2XB#vU;BJg$f?|b(j(75zFqh3v_RTq~ zOx!O(jUg29PUG)4{+kyP8l$(+;+#=tY)pkfEkln1972N$VZ3?ARF2(Bvl5A%rUgyQ z%4TUVn}&mt!to$MpStq+u8{K(y2;XwG1k*EZ7=1#x`!QyAMy#7KA+;@az>!Yjwmtg z*1C2qdzbM>@|NEHOpmdo5?L`Ii#MK)Yuae}Ym3cFF3aASN*vhgx#>O<@uR-O?zlP@Jw^9#-e5`_wWjF_d8 zeOF?E&He5B_aCpH;la9eakLJ9^}lz^RrkT~ywbgJkQKAb)!LA=h$`o)p7XS25{%}N zo4-j=9dTlJd!O$IH{O(d>?fxVuT`1LWl}um!`3;zI4TW_laqh8v0mIGw+UGX@=QhH zvv*2Uex-S$*m=+^5qr-O>=Ck?OQ1Pu&U|EQKcPSI30|em^=cc7#Rd~Qf7-iv#?~yO zJq+~MIq}V!eSat!RV6f{+&lj$y_BM1>sli=ql@FXO*#&axRnS8n3 zP3d>V5%M8G(*@FIA6WtPbaj4S_+BMh=2hx*7ksuY1^Xqe`gWJGsiRU?7V3S&-$M;#FLM-&&Pj1e4 zG%;KzZ#9l~qxRt=BK0&F$DYg&m~Y^j4kvm^Z|`q#zq1h-w7}-l|E6;{SN;6UK`O(& zK$KyE?t#Lo*pD3bX@MU~MOT8`=r+0guUjG`Tzra6#6H%F_<_oAIIv%eGc*F%j)}g~ zW~r=J*I8**Gi6wEO-*yZ3*Sii&zn1!D-tvnxAUv53 zW&TAal&BXBM(gH%&F<^AKq`RnLc(L)i9~3xLpX-tZ1?9=*nRIFNx&4^+T}Rv_uIjU z5#_o*Ooo9$bQf?vvWaD(8us}zr@&y8zbc3JJ5AnE+=}T8J3Ug9;@Y7d+^Ih zP6p+Y#|8X=VQ*P#Osb!6iNeHLB2Gv6LH}aG@t%@N=G?~EePL~ZjUh+#+3&Uv{0Me8 zi8(nGsNP}MuV1j&%}G-Da2x(+u2-g3x*1{Cr#aBfybjNvKzknYZZZF z2;yUQ5JM{XLoYtqe3|XhJXOxU&zNOdg6UR_*X5p~b6lk5e463zwXAW{Q#^$DNn);~ zw)r0W?o!mbdjiu#u4CkqlZdRKmd8_zI-A+%BmzG`!gaf?6#}>KJ*V_}LeQuR-=ha-Wn=_aU&Uf*P1U=rh_~ zd$C1ed+H3O;&T_@r{SRmfHpUNbYoTqlde-2*N)Z@P5kZCcOmFA%PP6|vMj^zHFLAe zPrE^I!z0e5aZcilKKc6x=n+?r)`k;r=r}tTLW4XfwXncgC>FqpL*xnzvSpAuHKC-aV< zW|AyKu5`%z+LsGRC+&@kL1|eiVZp^XR?7CpkXk?2?qX4)_a`*Ri9Y2-zO8_?6RE}j z>=HuU`_M%lS8d=TFTgV54!%+s+q6@zQ0cM@+6_##M0}`$Y5h&7n^vu9rsmj>Fn!Ii zmn&x}n7}Dm1ze^Bd0rywPS+isExI{+!@ItTUi%ZlIY~Be&RI*O4pYEoumBB|g-ZUw zlc?j^@lj*c2+{GO^+&^f*n|B>ThDU?6j^^{5|5OC5KM+pOGD`5Mqhm0fcE*NZO`|n zDk|De;=X_Qkascitf@b#)0>R#opawb8Hj|0(HJzIo6!Dx&R8*5J{oME&`Od1Lr=#Bij*Cbu^oC%uafHmd04+YNSC1}-v%fe*0<^5EgXX?d|YZt+jbsn&Z<(GGKozJO#?sT^8E|@KRbF~u&9fAIxHy1q1y;vU{51D*2guQc7@KNZT zG249S67R{)Zf|V(@$1)PTZe3w8_L}6EV#{E6s4D$I-&Kg2aJs2cBQ(eEuk^Tc3clz zX3c%0(4y}*u6VLhfN`T8#(;EUX~cm{^PfP{_-yI}Zx4AB5H}@`@o$sMiRm$;;24Gl z&X?Msi)Pc?egL`wn9Sh$Avx$i?NqQJd?BB*m7r&ecwV# zjbDlVil=&R@Vgn>QwdUDLuG5h^ek^e_)g6THzpYsrgSImN9k)6Tg`rUm$z$5U*NPs zDtBvlE$UYasob5AA3GCmPZKUAnsW`qQMVib@nmEv(UGr@i+_jr&ng4sf_v20ysVScJ^r)nxfdlLxoxWB3v^b+|2Jz^rM zdpI&n{|r>Qw|~A*W@B{Avfq#mj|~cs3k3K-Ae}U)^J{x1Y<6z94I?$dw>c=HN^(M! z-j^cN_6Y{=t9uH!A#@jA*b29=Pk+7DSe;kAE5*ChM9^%x^h@z*8~JkQ{@60Eula>1 z^N$VH$lNJ_-|9}ZI z)aU3(PPRnmx$USCLp9c@lXM8?iCx-ZrwImid6B|cN6iTM52 zOTJEMf>8;ZzGj!m{ZSAk?Y*BXe(%x?T;%Bx0i2nAL9Od>wx4Y!dgMIwtNJC&03(z+ zrhL{-Ut+~{@%kX)#nD+m%FGfVT{b>3HlJ`szCG>b%fbAwOqYwh`o?gnNx)W>sywPG z3Y9Y-S4E?08Uv*$l_QiaEt;-f2Ke$~V@r2~&Q`|~xY~br9oxEPW_4aQG`v!F4b#5< zN!Yt|ddBv9Z?OHGD?g%`2l$NF%1KF^l<9eCXwVpJvZe!uhb?cz!GsK{)$*z>&R81EZsdmwsHAB;*D>#zEIox13~ zvFeJmLvGTUjD4(7f!<1YgyaC(&1Y}@S-tD4GRyGJSbmMklNAb3zhoXMGs=EJ=@lC? z9;-m)hCYhD6E0)K{HRxY?47O`sF%y= z-MFRs2M>QR?)e*i_?@oh0Y8 zXW}hKO<{ch!G=3BQ=J6A3f%`4^^oE5E)XJkDv5HP2aix#>Gpp!_|N)Z$!wK%F1q_+SD2yb~`=v`dnh`Y5MzeEZ5@%Zhf2RzY3ev}eJ3Oly`}`wcOQ&DA3? zq9i4r0pZZ!bg_E(-KD32umBalNa{qP>j`p|XDyWn;tbQKy*GtXZHYTZvUF2)u)~2M zVDG*^MK+ZbZOfq-h#gvUzNo4{IX~*>dp;w)Mru zC%58zY)~@@jk$8Ye9tl!qmXZ)GbEb`R|2GwPq*@pDta7NB+0|9;knu-1kNyJM5nhe zXtF%2kjN4P2;3+&#W409540LSVdLS!<}q%L>!QgG>4t}EaU<4O z#dj%J2U2Ozq63=)C0NhQAe4LnK1pc`w9V-0qG~YU3FwV>!TzYS(mz*@hRb7UM+VeL zbYm#v<>JxAYF(aU1kyyv-TJVO)(W_CV6n^FcSM_;vZBcX!cGb9$0I7e-Z*Djs&&xu zubi5dyUPquqFPkcNEuMzFwG2FBlkUOm4UBQF_8Mvg@{7Sn81^lp8Tfe;{q9VnvK3b z)2Afh;NHLR)Z5zti_d9|p5M0g`TF`=A1FX}?1x=uw73I#BIlFwk~o!)OWIY`$qxTs zJm4oUrt;0sO?O`x@fOP%PB#%&dDw%B%G1{(MSSk%hMC4HzQ8r}Y>dl7%$dWU8XZ!7 zix$?Pk%`OK^JHqeX3%VI%_)jv$xoFvmi0L8LScj5xV%`d^5d=<(Qd772CjG|suB5k z82!k7OseoKtVE6qlmyt$p}qQ6){1ZbyAB}&4hiV%%X<76Y~g3y0CFeZkmARH|7$V%#= zWq)je7oNs(FUX=;+|DahBbhJ!LguGI{6y)7HAO(py>~yA5=!7m1Tct}3es8s5!Dnn zLb>adsMouSS4YmFVA;LQpvrNlKOhxv?7v1I*p3(oX%cmO zFwa!-eF!@*OuG%qVXT+0P~PzWaP07T%?mp|zw2@BBW>o0HGapom_5pXB%HPHdH9Rv zPc>0N#b8DM2v`9#RfR`!y{)O_K<}inJ@ut&8V_1n$aXY+5+)~0n#jxYD_ve1EE?PC zr=O|#<5qSnD^eTqqHA2G5tLTJ-}YbJe4=%T;vIjjH(eHJ?OCDzERLChd^Z^E*DFIX zN^tq0906?Qy1S{s@$Ea4NZKaYXgaW zDYsR=zNXmscI(PIa8j>4NT-|?r(b`-02}>T;$(DlRKhOULGHCD*G38*ssuMhFBoPh zP8HsKsJ@KIuj{XyqZ+yIF_e&=QA_`|!!Ma@{W1oy_x0l1w~kb6Ti$NYQcZkgd9% zaOK=0N#ft(1XrFRLMtdJmST~u9$&;Fy*=Mh)AuM^IhQeM<}oVF+koe+QnRTD4nWht zf0r0Pyz5e5={!>3Ahre(%wM6~S?Dg^Kw16%OsqnMcOF%qgz63WtzW-GP03wU->76# z(|){0T5<8Kl$6)yrH<>6+<)b~C%H(|#pARFf}4<2mf*O_!QA$0L0-!ip1&g4KVKkT zDFUQSec%(`268a2{ij`S%vqG~Nd?)Tb2nez0}f1w<;^F_n0T>&t+iK-n{|mBY})XM zpMS23fzZw+2lTau_cL6ZtDnZycgU#G5beN)NKBE6ntYJ_2b}){(|>+?NB>w?*9ChB zbm2!NnrEy3sk1#`Vq#Yjc=cJdj{G|AKcj)VfkRrLo2$&Of}*s0`4^>2c*meaRW4rU zlD{YU#FYUeYz`eDW}NGoHGe|F|M}KadH@ZyTU(zcJwTECC|8^DGWOwWLE|;J$l`6*60fw*aeMo1-ILa zxu=h9|5{pEbk_&Tl*2*!;ElWc5% zz4NcZ|D+4u-M!wcT*VqE%(TEbNz~Z@Lvh?sB(MttH{IuyO#^<^Mjg9+;TO;|DKT2Qrly?D^#6|Dt*Y-XhwQLaC(S@G)i>W##4KO~NqT z97%5SMFV=~V-i{zoxjy1F%-A>zuyRLC4nhdwJj5lY@kb`?giDWDVNAh8;fa$l0^P_ zQ`SQT;PSVb2bJFpLp)93!30GMD=1S82Yc3dop29AS&0VZ7SgDOzKQFV|4Rk`8Kgrc z5miuzUfu+HrEqroqswpb`zL4Sc74W$B1wiQGCacc;K59E8TJ1o>?^~f?zXq3 zK_wKC4n+h>r8`tWL>MHcQM$VY98eIIP`XP%q#3#qDd`+Kq`R9L-aRP#obx~DykEG6 zm|_3+UcK&hZy$WjZ%=>%-K|Kv{BN{W! zFPTb2j>s($5&Fy0&B1@SiU_w-e5zzN#8`>59IN`C#@TLe$k2glc3Y(LM8e*ppu7~S zOb*1#VU0vY^3T8f*M0xWb{BM9Zvx5G4P>0f35$0xC;l<_kC<{N=|5M0Gis?|}2B<*e$wu@g5QV1A zg(+a5Wa^bJmLg|)OSOn5LW42v#;aFFDAJe#L?YjRTc$WxeDpmfD_Y@49dTkTxhJ-t zK+nzlRk8H!**ofpT~^&U(lJr?1Q>FFjqk7JewcmsX%Zx$z31;iQm@X@ z_K}Hm53_$_DWE@_lA&abvl-ccID9$NISToEdoQ4e6E(MX!XAn(V4^lcyaD}~a8B*y zW-fUB2%wXRdP;&i=>OwUq442A*_*#h|4?&8f_P^LrVm>Wv-vekYKTcNw;B!vf)YXQ zG4ae4sEFZ_)IX5FM7V}%?QdnyP9?8cyhYtpP4k$bTL|+j2WTnnu9jZ?muLPf_PFX$ zCAIfb0f?hSO*@Ei)y^qivU# za))opPSj!U3nk_G0IT%6?82!X{x)UX#=mOXnYx_`?+?s1>NvLJ{rMIsqO8DV&B4`X zmsY-cob;yhs zMbok}l2kaw@2jxH=W%ACHWGlTM#4Vd{z9wJxM^H1&wle@c z4Z&bg=N6d9Wc7TSs%jD&TwxreBrW7r(`{N)E_77w_TrmDdaF{ed-GrhEG{q~btI^n z4`2~CB5v*e(+a(U1MvObpB?Ti^8gAZiK3G5s7a#?bTrr26g!lb%e?$!7wUxfgU;lv zYX;Q$zG5xU;8ZF(F|HGCi;zq@NN}!V;@Z7^UC~B%E~#J&$;7EC-BMQr*9|w&l}_^x z3rh$H1P8q-!&??Zuyptwr%u%A>F$FXf1)3Xq%pEpzbeOvIGY~j@2P~ekoJ~)O8~*t zE?50)YlsvD#tTLQhuNpV<|b%aLJfl zZRsI5r+_lXN7=tZEPRn@XYwP10YUgl<};m_cCipNf_Q9WY>^oY9S%bImvr5U}VLT4+PLYasIK-&2iI||$_BP1?#RY2%O zupnQ5ZQI}b7CDqki4r_vVO85Y9i6hGrfi_7}X%H^u2m! z16Oeueq;gcgif(n!N5W-Ff`3oDX_yaEuj)0)jy|{M@qMFqtGf}U)(`b1R}ToymAM$ zdbh?h?t|)~Y9MtBF}}ry^3DNFY5hu^$vCLDK+8{*B$OYbaGjL z(;SeDN@u|27I1xZ>?(hj`j5jxiCq#?u!vFYLwL|f$=uF}e`}2>P!V{bf~Wf$wT^}Z z-TMJy0CMWP6S*M#$1sU6;1ccVt-9|5!jXVC%)+|`BfIK$+6i@GMurC&h00Fz76twJ zZTh^p?M%*7CjyH?ku?&+M0&mLP6 zdPegGgveTC#w!wikwc4n9UePcEv5aoe5HUwyR!jF$^`n7r;jtPoE!HIMRCS%q#*r+ zG*M2Ojv>`ecc6c&o7+8sXY`L=Uz9ffTA!jAH!yWgl#uB7H`I?X>!%*(511HY*i zJBx703(CeLWkSYdX>l$AREbK{aM!|1=tDgJgJA~a(yBSP$(}Dv^!h$IvFiu>e$%dC zA|rym>PV(-cGOs!l*P(CvC=#|5R86i4XPadVpRg%mu=14@BBl~g&CTF)d-2bi5krJ z)Eiq0>kpr+WoGC%hy)bi@pf0l+= za2M>+5j_^cAZhF=nGpA;@pjP%5C#+BbX&^;FgMo{FAUS@wCt%c_)*`h`w>NGoIP-G zjN%TnY7zj&nG`>}IKj{BeuAvS3kKiL=uO2<@PNbD*nj_vm*Tgj6X(H1O~Qb|fd0}? z|IlU!#Z?rrc~&-pEQAy|1m@$l31&d;6E?2yyz%^w^%ZbFwL$2HhK67c6FVJGHf5cX zCED=U&$dTE`c(hOxgJDrRwU_Z`zXy+Pci0+ z#`=kr;aZKFZIjw@?EZ@X^b4I)-c->v7T-p zKwz{HgmQnjpU-;>Z|R_!8n=cy1y6)00Y#~VlwX3t;5#BvTsv*{S4y85%+F0VY|Z@e zl+SFiYfoXTAQ8;Pcn>-C8AiyY4ElOn!l@>l(`zDFD0QFrjTOoekJJz74t$}`-e1Vi zo%#0Wy;M~lcjnWkvNPf%RJfRjw{UAj6mirtN*W&mLSxiK>K1@0bGrS!+)Y^bE3fAv z=8r7V46i|YqnZ!OpVg_-p2QhxQb+is^MuTr{Zg#^5OKzPv_ekG$TIhmnfZBgFP}H# zObhw_m|%>II+Xp&4v~uyeqgl?GE4J8$r#T#2NWZECwW{JE&gh!! zHg7lt7(s&&4wdp;1fzHLzL>;}UyJKP3?e!_4(nN18e;VJFZ+a zDrUJXr6Bz=pkVs2yz8+E>RkY4byL7;P+<9uKE{zKEr8PZ9|>&jRi&>k@&o>9ofPA* zN3c8q(ry{5tp1U}WeM>TixguF)Xy=g;Do^ENsXv4oqp1{+5)w0qKz1EzMd(cZ~nGD zZ?8e;@LrZu-Pw<}6}&_xc#>LK<&rToOC4-KFB_|SvaSPIk4Bx>$36|gDw^Qtb~Y^q zDg_=*@}T{_t{NaV%+sW%puhyYt(D~h)JnUe*;+avxY#mh@1Q*0hhlW&Bv$Q~^{Hpj zu4=kGWYy*@Lq#1kuCF-Aqg>~LV6!l`7(?KZN08bssyfm4>JB#C2R(xN7V69Nb`n6P z`T`ou#Zq~qx1fl0Ti#PSXL)w)AuUUwzoOL_{F~ zJu@9XCBf)Zf$e5O%kwHlaEK07>f<#(%?TMrXmcli%kP6BEEik9J2jct1D+41Y1I3h zDnP5iZf8<7>SQNV)X=3X(Fb6mx4+_Bwl+taUwYh~Faie3-4WZV@TKFEBGNQ+$AxOX z1`7xVjg*1dT<@UPGCaZ7gXRe;{qSZ0(L~;7(|;uRP$H5p|D)Wh&0<#Fvadg`n7pdp zNk63ncW;GBGs@+Ogl4E?V_J5_?6o`j;ZxrPc~5phLJp$|QNuS$>rxu0kqJPwv$LGv zLMS`%%F`;hf`$pu_uYm>&E4a#7lvoquWiE^=tbIv+nmqcSZxow;9;@(KFwBR@|yy) z2E}O%19Tczk5&|g!ZU?ho?3|tet^N{TBqvT`9n>$s_5w_1;Dt9 zPQ5~L)=ev7Q80_)Ki=>6DneKmwc*~*9UJcwM28Z;wdxWFc)HsW+7z)XlTb>T)q$*# zp>|fAKoJzfeqaU9_yFEkwZYx47C0&da!7V@eC)^=X|9Pfh+qQlAtTJaAmfV|MdgOH zX4)Gt4QwNnYCb1UACobC35;;L#<_mm6x6nzDAF41I8DH#`7yTI_W}Eh!ozXUhJ~Zy zE~Ty~k%vgPtiT6cNM22v+XPLEpsMAX6I;UAqx|v4R?D4HB@&c#Jb@EDlT&>m6U{pU zvXvAu(?uYxr^Xa0{h9{~EKpRzt?L`A19=`MiQ`^cc!=oMZ**^aNCc4WpF&37r(edU zM0)M5VTyj;dbx98&*S;^%GJj&NFI5!2|+RCuHC;NQT&<+lQdY)Tw5WpP+a2Ld+}La zEh187n@pC{B4wiQBrKSD-@-7x6B9o@ypDB?wR^nLeO(x*^X`1x6V8w}gW`$f!|wv? z0_(03>raS2?F)1+^-E#<_>qn>w#djWGi)5oD2ZTSjGV48iriozt9Rt2csP~q1$Ww; zcApnpi0lod@Db=+`}z^?*5;W+&eYSR7?6kuTbEI?CdPM4{F85dyh%h#$~bKmuV>Nh zF?Cp@j!v`VZ;QAjEhE2v;wEx~RgpE45$wfe<}0gQa`v zN;J3kB8E6!>EGZCz2dLZ3>>Cc@wTJMCHO`YCdyMj$4_W{{VM;cK`lYHCGBPjW6v`7 zwkaRUk19yk#`3(3AHhl(WT47?s4WMQ)7jh+7OGpq(nYCoyBCK-yBZZJ#?-l(JPrLQd zVTEQ9H^|jRK6^+NQyn=aoY?$~oIbkRTGLsSU2RM$ro|v~gn!R^_n>^OYIf_}i_TM8 zc&A><_uE@Byo(*~aG|5V3zYEWUGfs0J6!WM3d{34HJvN_=DOuM)mZc&*6+dAJ7vX4 zc=B*)7mam%KIN3nI>9m^xj0l4jJnk)uOXJEsQ3_5k#6I(>GI6V!lm=57FBAv&%Cj6 zNp{qmYHoDbc+u@?_%u#WdVFb0%#j$<0QRxHE;i3d-DPWWerC@!q)o}Q#%j2-fvs5r z#(TNOE|THZ{U&&sS)z{^7){7{p=p|7s1w)IJIeuEE8Njl-3)kAqo3Ar-$y`ENuxRP zX+7J13}}gW>xUWjyX+b`Z*)CB+|H^9a5c%p_!Bt33vU14!O~< zi@h9yysxR0mu~EYf597l=vUi>b4e-)XGA0lnb2;1Z;MR@u3Lj=Ttv zosW##W1mi^x#F93J#iZ%bqoX73Kz(X>KY7J;ElRASr)j%=dI>3JZ^H-D6p@>bvd~z zFb%n!6Xz*S5w1T7y7Fb=!R-3mzC2bEmjrK&b$K-m;#t`X)u_1ZW0YZgFNbWeLN9Qz zRjV~Z_7PKht>LV8dr6eljGY=LhbxON8b>5LtDB|=xnd<c`jt(UBSLKeB9mRLKmUXBc_a-zn*mZmP#U!vH4rfA#f;7U%b{D@$n!ELC%COp>SBxt1%EVm{MpZABjpi@R&_@Uzqp;2GhQ7vqdA6Wl$5c<6nq zPHgAudy?#n5rtPOQ>IO8TZswV^0eTSemWSw{-%0m3#rLbj9Oy)M~G~(?cKTQR7!bN zYUc^cYLk5Ae19|>G~y`HDTMV1DY`yj45_bWDDx~Nbux&2_<)%cv&%y^Nmw#&f%k4h zdVSaMw2+%NG=dRaFl;T5PC`8)Y@GnpoKAqaXe0o9%g^TfS4f@9XN$R|#p|~_g>P6_ zAp%W!abT<-vyNqM2P9UjJWAhxs949ee^A4>Q=oV6{y-{dq|GTic%1yFf%{rf9D@d% zkmjbVtIy|Bm-oWQCFvjJgpNY*Zbz8rK;&dihoW^~zuCgqw*Zky^eZc;FM}{yr%;Ql z9?5CTQWvNT_0unxE&aIC*eJ=1iMeW-sQ=6Sd{a#Y%mAve?yOy zuC$K*YGrwu?TF)R-IApR4a*IE4?z$~U9z*WOs~T{y5{bl=VLWD@C3Ko>Km_|*@#Q_ zDYA#|EgrplnSA}A@Y(eZ5qGbE`sfl*-8=YxKmW=oWay z3UQA8Bq}2Rf=UN=yQg*j`1l((pSPF@a37|=GP-5M7A;e!6zpS8StYvWyKK0r1QCLm ziy0AlZ+|Alp?IrM=;@O>+t)(O=IAcjq^?#t{>im&yfJG8KF`)%XOUY+_y+4xs{gW6 z*9UyfcO~Uz3j%Npg5i>MIvjZQ`~;U8HUW)U{LeEMbX3gv_8A&tR!>#6cvEH8rDqU_ zwvsWos`4Q-^N$a@1e7(`jt_IAjV2$YG~)H}BG3;TqBdy~oUZ4SJpnD8WF2w7da7*U zTL}@KOM{a(efoMnHy4PbwzqIv4eQzGP1~NHX6QkGd14pRXO#<2U3X_AMk#Lb^Wy7> ztr^kV#EL)Sqmh4|aiI=>YP<2Z-GgIeO+MGrmDM{TK8*Lk1kUpwDp#ApUFTOZ@S1h_ zZHv{Bi1gOwgnSC3%?`WegodMa!HSgh54h185Wc`;#p(l#_nNRZ5A2G#OW*xhHM3$S zxj2@{-&&<42TjOFPW9HSVqYd_;9!k6R)--qbuoyANgzX1+#x<3l45?u>n`F*8%r@+ z`}PZVNVXEqjwljvw6gPATE};ScE>R|oG&>r4JjKKsBXGEz-ROeD33~*7?`YQ03u%r zjupz6D*gLd-`YXJH5?kMrKtv)sq$D*lPh_~Ql*6@yNkES2cr1$5*WH9jx%Hv>yOPv z3om~h5ouzx_fDg zHVSnhyya8EWRkEerQumXUo-Ey$42${nkRZwOVWOO!GW_EHUc4cgrJE=^GIMgzhpZ) zEWjBv!45XB#1u5)z1n^^X|}5l!)~EgC!wh~e`h}1NELfk|8!jB=%-rulN%ra*j%Qe zK-t}0fJ{oN_8vWt81FH5ed!(w=b;r)G|fM_y?=EKKAX~29N?P|bZ&@7ZFIw7lIS7j&UYJzzJFm+V zEuxpVl&GzXHb#s(Rd8)g#aLH=?CHr?)G2OiK1y76K%~Z$S;4IU(rHB5e4vOPprAa&u|Eq#BXLx!3u@ zqle4?nG@R^x3YHsND z4ptqr$m*8oPbB=Lz)jruaGw+c;UsgAhR<7#qN5^+QkVGq;U9JNer$5wA>LvP_v(%u zrmBwjH3#M?W|9y`oQ#(9%M?Xye}g6mG_H-h>cDsJlpv2s3TBm#4VQ2a*zzWkuHo*t z5vJup<^U*c^gg1}Wb38@2 zFJ8QLoSgG1YN%m8eMb7nQKa!CrUO@v2h2g6Z`*lYqVe(7 zDkMEs&X3({enR)~aW<4d_hoUzYW24(e5EK0s4bLrOtK@g!BZhg*GM=o`sq{WuB#go zGihaS!__qY=g4}2Hsj2l(&Uq6?T%O2@Zu>Otq8q9n@B!;U=f;8=~Tgln9;d*+#uqw zzj9}SlTB_fH16H_gp%qSe-lUXgAJ#<2Emwtv|`u0;`dkK+|g@dxLKw|?y9e&hmYLl zFgUbYi+dCoT^GgSN{*s?p=`+=aklj5$42CXo)hD%9i$)Z&4BZ$wmQRNWAX;tQk2zs zVHM>y)y4VHAg8?svh?0mtW?V19@c{Sy0P@!Li71krIvaF@~2|>keK8LWefEai|eOZ z4ah#1WtCGikZO=@PG#(t=Zig)#J~pD-_mud+URD#*o67T+Xn_?6;?`H*SMz!z7Q}z zF0m*aO_iVz4M8`;eqHXiGEvbqogH7$jht^{K6KIzYuZD`o=m+ytx1Qo5@~Qh`Zj_X zANbih>N)nK#*hA}m(LPqf~`>)w2-MkHFgCb@rbr3z|?niI$v2(@F9)x<_PZMe|pkh zJ}HA&dT0sPKJJ+=>{Gt;>BulL&sZ`q=xM@HOYQrk9lffO($eoy-F5M7--bV( zwerr>Tkg-b0BS;E$KUvmws7suJhxqD0k@U6v!ijax!{(%oA()%(J}d6KdxSzc60mr za&xZ8as4i?Gw)*y#dMvKw1gkA^VT@f%Q+j|POAIWC{<1&rxbMP*y|g`^=3NKdovr2 zE!%gE?78WRaf7I;2P=X~Fe@fugf)A78)nR!kx?%Op?cbDn2;N0!TgB^VdnX$DM&?S zYii^)_*47xC}+}vumUxO+Y#3nf-##*sDv~ERW!5h{!^pmztfc|&F8A$aIx&O8YD_^ zQPrF3K<~8{7>S=76Jasge)Pm*MQtMEPCLR3@;h|=Egy7b=wkeyo68z@<@*lVcIVy+ z7zMx({*}s$w8)sWVybcTQ`oGlzD3vV`%So|xJ09q-dB?R0x0-CP8VPJYNPSPdiXPr zg&@Gb;Xl*eU0gU(U2Ry)A*Zaw5;P%tU1gH@@b0_ATV62hIAaeOS)_;L(Xwm1Cbl77 z*o5C&5=FF(K}*QKzep(q)1_1;5CqUY0nI_&5I%3y^P0H<-p=Bf(zw>%MKpqsyT$iL z+;BtH_!aAqp1$LKxgu@eDW{~Q__;Fq+jhf+gw@b^cF?U%?WnrVXSq}f-yL-QgmE4+ zq9Qj`HhKO98hO=4e@KjVxgUQ{EueJRF7P5c{++vv5HS4K6FezFk*PA$@uKr*V$9fs z{4&IL55%YNN646GnSCY%VQese)R!X~a6}sT$xxQY-YJQ)U3!eaUq2ih-y6iE>f$~O z-cOPHjb7^I?UhVUv>U;|8Lzt6dlM)A@bWAaRi+mo8yF72e%2PnIWRBIh!`!yc3(lh z%Wjm`~|4 zOcjaT)0cg(9>@vpi~DWmI={Kqm1KE@C851n#@6FKTq71Yztd5IDY#G-T~-(0FOg7c z?KSMVFY1FJ|B+kF5Cc~qPIq23%1|;T1CE63u7R>Rwya=DS(E471W%oQqPNi|8Sj!& z_j;3VEIEgN&CZE2LVw#TQ;qIXrqcidg9em(P;!6^%mF4^82fp2hFWqfvsxBgjag;jlq+f@LZ(TdrNf6;OK_?)i}3OP&y$}Ez&B03 z`3`Ekoxv-ux3;&i)tAn~xpLgX&gSd+jZa&SS#&>U#fmyEvQO?)*%(B8k4{O4D^LQ86FrV9933k$lHhV|m6dVz7mF++Fc8J2dZI@& zeA5v&gmiaG26;YMk;70uwOGF0YTUWvQXAZ@Xw%?mXY{htmDwa0#FyCF)`F<+quEvd z?6mh<{{X=yilTd96MVF)I%@SGWDm8j5qg%8Q(6MWS{cHBH(*UPmbEV1?KC`Ibc@m5 z)9$r7<*}_*;4Y4B4DWF`a&H>KJ5phnnc!8ui+5K#NaY;|+EpuRR{>NIZD%N(Z=K;d z;o%i9E6V&kE&u}fZ?8TwZcIh*vxRiDa@>mXk$epRWqm4isj0{H4GyphtJee$LzT}1 z7L+DycIjO}q>_$~b`k{v<*egg;YmwM2HuRK&Q_^FSYdY?K83}k2KPZ-(Sp*3PZ8c2 zjdBu{td649QI3kQvi6-?yd5R?e$V}~7b}|TfVmbtCZxl1O=H(ht01F!nMar7 zBu&mOTTaAK)&`&VAph%Q)Xwd&kxgmfFKq6y(P|#GRyKDBDX ztmo)HN3eR3OoPA}sNtY4GveAz6|n?61{FuOCz)i9{sOtasMONz*tD*vHwSh)_q);J z->1KONLW*H`D6#yc^uk5g({eg8m~9m<@-L4XzK{ioFySq1jV!2*sA0@oRP<}tLY*G ztJ@ko-zQ#bOhkKShk&wc$aA%T(5G-M4i?qw*@4s4DtGmcY^`0VY;yX6>*_GQXM&0U z4R}dMbPs)`B<$JT@Yk?o;z2h2FDR4fi93T&Jw2eocLRqr(+69CO3dlIKp?hoC35t> z@tAPe2do@PK7(anFR#`kLbbB79^qNI)%<zWvZ4mov~MVXM_ zk6t4Kwaa}!F{U+Ijos+AtO9|eoe=3;;=QaJMhTXJ4)+MnJ@97|@QVnfP>zJI7A1FN zp=*ET?j>p(L5=< zCNQoBGa0~KO=o9dUvnTAcu_h#pn3brR;W^iN)LpTnyftk$M{AGaqmTTHIA%KhNAc})iz|9=q7U+a6z1bz3;uJxsoV$Z{b z+Ou2-ogp#m+6o%>aEXy4?suixQ{=Z4t0=s})9&fC#rLU&X2u>iQ93(?QxkR}*~!o= zdyE5oW}^?UdPNzSlOLHScxSSPbX_KxliJx=tA0_I7RBeiJ6}`XxyQJ24BH&z>}JX~ zv60UMR~cDZY3HgRMvs&Y%P$x=ot(IsyB}0|SVim{Pb74zCURAm%Dp89+9FPbLTlV) z*ZzyvIJmtraf*yc#F_X)Q5hz(48<1G+OCM1X<*3x5g4aSCV^9as0*VoA^P50` z?O8LMOi1Exgo#hqrH76GrEBtn{YuSvMJ<0WTqrf2QdiW0V;gB4m>QJ>Ifn0=o>J`S z1>Qq+sB<1gPpA*iJ9TbSG~Z*gPE5@nlSlN)9rs_pqOk&{4ktL1x-*sj_b;!jY9lJL zqOyb>oxGOp2RXd)K(Tl5(uvcz%OwI!jr#&hjRP#O`ttqoR-sm1yJh#4(nT5!!izbj z9og9)^);FpBX|(#m9gV%gBow7`<3q2ktSH)D|j~O!{dfecD+z$efW7R)y#b3exe+! zl;B=y#sdtN6MXKTwmZa9d!O9bE7f=0J9`lng9aQ(1Nm+Xg1tmCm>6U_3hsi!l6;eV z6})NV${2|vb^c|{U)|6Hbh*WTTpj%Nn+7LNoOTDZiqC@m6mT)Qm+QQb*KDo6!|#|} z_i2ELtR8%Iy>GvE1Ou1aM6U}ws<{Ho;Mwn}?&apbgS^L!^kkVaMsH{nrqRz#c`7 z=8zzc&^x_GZ}&1Kbsas5NbtXux(_5&@ltY`m8RtChr13Kq$2`oovTu-;2mZE*T4K; zCQ&%LbPz49Ez@V(xCVtsr0YU2KXe`ZvRPo!q92|UL@RWYup^2I!}mita3|Y`8SBw1 z&u1r2=k7I6jT)KuWP^b$exup80~dW(_$2Pw>umKKIb=e07IV8Qd>YF}*6xc#)^8EY z&-!-n9GNYbkArdxi%PNBF%NyiVfHYNWk;$euf|bF^V0JSCA^$h>7CHPQWxaqC}Hy? z$b>V+U?RCh;lln0&&B=WSU+9fjxwZl=ZFspw>T3^dXPC+i9SeD&FY?%Y|r80M`mOb z!q{@bvx$GfY+fK@c5VEP^npea4=Sm$A4zTkt^=B4tC8EzZL##^>Sdfu!!cBlTHRH5 zoWjd*UttTex?5&|q4tBm1gk;#o(DT#8)09Y-X&dZueB)2tF&I>w{G7$>KQdjsk@fT z<{{5579^YQAwo|WKkvyy~La@f{w=b91x%~if_-N_solKv= z+&Tgt62MY(`5Hy+l!hG#+cgLz-`SG*$26!(vDGgdIl5nek9?EDYKg9WkFPlfp)0U&Ks=6jcmV+*B87VBnuDlO_of*$1=YRvHFcCb z&9B~iSEZ<`!!8-vc2lE`?kyB?EYmp}s{uD2-P!g66f$}A^!{UV7!(d`Y6O(b+MGf{ z$FV1V6Rp*VW37s_V)=h{2jCZcXdZ4S#QUAWsF*5ek$5t}MbCHprI9LResis}q#TQk zp9A?aQQ}&)aGVZI(B%hvQXN49nBi%A@AkNfU7O*~p%w^)Z;rRJ`?EvyS9$YEJxF{tQvwdm&!cQs_PQ<3hQbTGvBRjVv&lHK(c3HNUvgLMhl7 zg{WJ3B4$sK_;~{EaWRLpx<-@((RVOjaO!F^GTP8+nG^MB=e4I-j(NyhtUi;N^j!Iw zDO>?gdrTnkt*x98#*pxKl@3i%ue1;kw_}AgI(K) zhI^#`(3EX<>-ihb7YDOfz2>62%S=YT0&DlylgFTY1#7PK4c6}QR4n%OgAqS$O_Ok3 zT~5i!?Hzb}&VD~{;7~4y`9LDU6~y1$8PARJzbf9OHXS>=d?Tc$srg49FmvOSf;oeH zV(`8}I2{g*u$?`rK@?|fCp#u{l`^aSSWDNj&EHvAL4OYyzLz9C@Bx3XD0;iw@fMQP zrRMl_g7Vamz_4-&8xZ|sf|5iyxG|SLs4dO{?`1a~8NzdW*IgdQrp0R)3zsyx;GM2_ zvnr|B7RkT;JQwYjAOzla^}Vj zM6~U?4DlZ>$#%;4?O9gxZP?8Er^km#(}>kJxR5KTagrt)EEGykU?H z(EJn;P+@trmzt12o#yUgSIx1{=Rny$ILX$PWL@_*Q9j*Z zTTu3NQM()@eH5zVHEL_FFUsI;%th@|7-VhYNzuc5ER`D7W4deMLrH1w+|3d`_u7)x zxz?iYbzBX7t}~5l1mUWo2C{bJp6i^uEfsXrO55(2p;luWe!F&!M;EXlLef}vQt&ZX=HXPLt_iI{?cv#HG6sW)0 zdc^4_4x2K?D`{M~AbvsSp@edyuYF9azfo3R1W@i_2v(Mkw)W~?JRsAY@VSh^OD<@4 zF)~U;bfjEHwQ?(T#C^u%U>oY`gz5zijUBf{ZEo(h(ku%$@|28Py-Z*~Sym285ZRV$ zCwdA}S}Tv`gew3FKxbWf^7?>#9zl_$|I=pyqt6^Xd{gd6jqOAmP0n_|>*DQ~ z9``Ff5zkZ@q*(~bd)ZFiB2c&n`z6a>j$lxJur73tzg!Eo8m$It=JfK22P19QzUyLo zN4%2fnCj2z&K!G%hM(}I{R-W&73~R8hkN!koydo zT(R{K?8Cm21Frb=d~SDdPgC(9Q|o&zNj^9;UC=72-p}?ivWi<}pMoQ2uD_bh;IN+G z5$WoT7w|pwu=LdB5lN3SQFvXFoIr{nNz@d9Es6L^YU~;dp%boZzd<(N+k@MO>&xPC zlZXI){Pf`^zoC0LATk2l2*RVsn7-OPQhTA21BA6VqmUoCI)ZaZ4O?kFz1|mEj|@N8 zW%u#J;*&JF<$muEM(XUH|KW=b=_6T7a$6`tPG(mk#Bo!{H>3%iZD_h&IZE>P8!xMr%E8TAaa7LJMRrqI1J}Z+hfBhw z0y=UQc}>SF)dS!n+OhXM3Km>Wvyn2@h&3VEkP+jyaN5)Dlv%Aj=DkT@y?_Tb|Jk_y z4K;~0(N$C!UzpcrT?bqD_5yUeDNw4GH44N-eW>xyqXk=zb1|DtsWp6n-Qp9(`sqiC z^ammC(y0MWtKh6l70u*4pYeC{-AjzvdKD#WD3W76oGKS0!Ut*uCR}(XX zMUGcsvpurxAI%$eEDfx1f6zI+`&X;~cVXwR?y)Is_RrgSX71gyto;dg4QfLS8WsaK zF;}<2aO4HlAd#Lz`Jb|oFrLZX`ZjVUL-R$avP0kHSSVWjuw9N38opKO&#l&(;cm6o z+zy$XvU_TOj^JEy{=@PAF+4Zr!EU^DZ;eDvH=`E!@N4ZWPmhN+Ovp>13S2|({5z-k z*9X$OxN?UjqOM*lQUz6!Rxh2TF^>C31-26%j9Y~#2bj+u4DtIwAVL*|cR+S0s5TkiiLHdE!pH28T|8V{-wER+` z$@sU@!`3*><#9acv&jlfNxl7!t0@yR_8oYSPf-VwL<$-4KY>I{vwYfvIs!zK5fljj#VdXY&>h&3=1jQ(yYUiz-&sG#7x&o}N52e8N*Csqy(q zlq*O*sX^uZ3kF5W-*f5Hp7d%t{UjgPWB8fg{J}(ZRm-S?^W!xXC-MJ%h`&FB(p~)C z)FkA7>ZDtC@>TsStmAAXOMC$n6>gCUvlSUG+^%Z|U>gS%(WHFag}-W-Q-}Ws%k|aY zMf|r{S8jCO5qVG?7Tyd@Bp6VC>-<3mJOwK*l?`TsX-j)cz?<0uDa;qDVACQ!mev0d zQV_ia{P()xW>mR1lfILhT0n=!cR={P(n^}+l~EunbO*>5~A zW$D6tO4H?*i#;b=0cQ}A0D8J)hjP^U9rGX)`i!UL+|J}pb#qltzxv-l`QM*y@>=Q6 zr|QQ1vWx*&=$X_*gKCoA39AhBr=}A3%Rs0`%r@e5rIe#~^hx=cQ+9x$ThO z%01ODJ1Hp_)QD&)|6j*{CJ4~T>s@k%il7WY6~z~YO6v7_yPz<=H1vtPWmL>qfj zF({$1Q+JWvaay^X6)-M<$AkKk9=Poj2zai{h{g?MYw(?5l7ZnH3guTdwmeLHKIap6 zg}B!uLZ5}(dA4%P#$80Oz8I?VQr|Rsv@qj)Q-Yy@nr3SG5#vyWR}D=4MBP{hq?N{F za14CGFGo{2#@pq4(<`-p7}U8Y2y9vn?A#WR*Rk3+w=XV{eGvDX^zZ#M0`s5bok$&h zb)+cbb)($O7k&FxP*M6w5a;^N#h}Wk4cOXb$;lMwaB^94ftTD8#@$0FEmV3zT}B)2uP4iVpF^UPeAW_geeNZ^Bs5Kquu>Bhw*OEfFJFORGxrXT`pXw=$i?<#o<5RLZ>M~P` zA;0&mEaX4VH-4ALy`hlt^{DRZOrqQt_TF~aCnd)#gZbN+)bqF4rZd_1?Fs+qBE?Ox zwyJDquy?^3?4Wr?#)MNYkvT3Y%LB$|T|_iV3|7Nb_4_KP25`}*wI$w=a+hY80C zq~Oo{=O0|6CH1f_x^_MG|%RO`uh{+A!abs0~@n@G}uaGjP z}Mr;;s&C^K1Y5QBl%(JV~-%Fi-F6A&y)};=4XnOHO>wf28uS?cF8r z^1IKbWdlJ7PFel6D`lHUww(4Im(`06J~}LmG;eNj7Ef&Eqg0yW{v<#~CzCrCMv^;G zywGX{%G`A^_WJM?IqFRL@7%R8kx*b_XPNPDk$|2xqAx&SUEFDI&)?Z!mm65Q82-Na zhcqq8P)BT5bkq%DogJH=c#@w#S6B(N`Bg~K@TJafqxrkWe}DC`TD)^jgqrZ4`AyI( z{}@1<^X>#IA01`)?qlkBStZ@;9kmhxVx<6n!VA2^+kpKjm77F+=&p!k?3aOTy`X@v z@bH(vpc}^gM_)Bk&D8e7QW>6kgleb+o}(z~U@0 zo8w4$t+9wD=!&t1i!G^bUL`%i#;Jq|{t7Dqu3#_G8(_2qfHl6w$dheb3i`AUx%eU_ zF>e3((Hb|;Yl&1IE-}~F**ntEddXRpGDKJ69!TH5wrJEporx{IfQ_`S9%30OwvH$$ zumhcKo?)k@!KXlpGaZq`&)^%#Xu^Qw9WhXsyA9+h*3lYgX?quLm^{Sc&|W5>&A`R= z0O-v#t0AE6hcDpl^JUc@Zn7^=)H~cPar*nkT85MHxArR5$>mC{#@OS8oVgp#d&`T| zba(G*zvq2vL2lIWql9%gdTwSoXuL4n!B3ec`x;M2M|th?K{(o%zuNPkUSU3=^O~en z-|4$4u++S?F*G0tfXz;|M``qDqUwwWkfo+~821@UOMYGk1|$VUy4?pk1-CJ8DokFM z{(fxu=FL{)I})@QgyEY*wB`4|Tb#IQudqoR9z&e5nHHXDmRLrJM(ljC9b8RVE!0{c zOp4RT@Z>WV%T%pl)0e_8Dcn@fxBgB$Sd)-$)F^;|_W&T+2M>}sn@jcLc&E|Yua8;N;a*h z4*HT}nw6tO?X?BLOI)J2meAf8?uS_*82Kinw~>fMi;)KvUI9jdJ9>!jE5A&9-F321 zW5nrXV~|*eLL%NUsDHot%TJ(HTVU5e(xK$Dg-y`};so3HUX1o51ts6t z+7&g0h45GYGoRDK?KL)wH@#-wPJN2*86EQMUvg%H5>Z$r)m;e^E3e&rfMY&@J})Oq zW#Wr5cCxO)?f#%H5o%}a6n?TaYX5=tBDmANt#o7XXS#OG@ykk}J}4Znl>6?&#}RG8 zLTkqM4k5Mb!6MnVdu;@c0ZY?MS?UyNa)&A1-{b4*gssODMt4H@HLYu=uTLhbvkN+| zEHn>x4LqA)8`Jg2{+7iutk+_ZG{hKQRopjyY#i9Y^1pW%f%S8GdUlS|>U#Uq#ZVi)8MT zu{f=c=&K+UMA^qmyqCLzhpKCF z2`n_aaLLwJtmo!i)bfqQ8r8m@{hYE@`ygl#(t>KgEm!2x=?JgBBJ@@gF~1)MPSVZ8M@gHFS(fX7g=&O);5chC2nhA z&(5|0lsk2XFT{ELEA*CNVN@sUzMDHc}7e0~Ab{2E^trQO~nao{)Z*@yc=BTu8`UcQyE@f*X8r3`71;VKB zCmiW2sTUn7tKwSDQ`~(%o({#xiCNsO1c-fDmDM*d%SHR1J0fGk3>3l&D!V?gwN44g zUC0YUjjqdA;yEEEHPPzNNAY(@R&wiZQs_-m%uEW-1C%ml-Ss(v-R{YdqiYpG*!Cug zZ%UHw-CgQhXjdXF2S~E{2wl&|^v`y}Puw+X_c_+z(X!uqPV@-sY7ar?q`7Qs9J=iX ziaW{af?tV0xm20&kdFc_Y`P!bw%ZL;YbwNgFHIK?I^b_-ofC@a0r`SDsZ+*&mM=cr z7iZeD-RQez1OH&UHCLb(tJ@yKmzf~|C)!Y->>00OwS3QOQP`)=B1tI^5O?CxW#5xn zt8{c~?ilY9{DboRahlph@=GfX@$Jt$w7r~KXY^_qMUkv!03#pXdwO6zR={g{XWVR2 z8g6bRo2O-yp(S#1F(UfZZ`!&#e;`IGu(YRVZnEw{czI2jk6$+Qs;TLnBB!J}npPc6 zW)6|l4_SywOIcNa4ePYOv@QQy68e3fRhT`BiiR^A-BPrm5wX(TtgW4kEF}kWA};=+ zHs3kC#z3JhVgHrB*h4D7aSco#rr`Gl%Fco-xN1-?Dz7^&ZOvccJ6lKl*>J=t3a;39 z+eY5*(?e=%;x_b~=%40V+ zQm-77$)@Hj^&;9|ceTtO1H|yPVVM^%^ksE*SB4EUjx|j^$6doUcMzwD&lxmg7&-X6 zh#a3MT7vany!)V>3}LS1Undn9Jb6AtdE#H2teP*CZ!SN7n}EuIlW2w z-Bqj((c_gzvAp(Y%wvD;1g<`sN6*1@5G$|Ivr5Hvd-`fRAfKJwy|;ga=1bGp3YIpaq8y`P^a4GgYcOmjeA1l|nm8qKR zB#-bR6tfdfN(_MI;J9@Z4dyQMz&*K-eXz+Ez)h3|ISar_h)m=^5Q4WhZUR^!EH*PM zE0ly~q98UiLs3=Ls;tua)UyUgsH{p;v@>PSfLw9WjnNqH-(9~+p#bm^){CtZKdhSq ziw%~$jsfXR0gKc-?A(Rp;oW3b{~)o}i5$~&toJ{T`yU>k=oYjvR5^;*w0yKeFTOI* zB_1?5#Xb93xe4JHd#)~`s-U>#wM&K^Ki1+H8uA2xpllry(#97sziGV^!}@lD z|H2LTdvfhipqzgcIk}>i-4+KMl5A#oeHmgu{EK~w$O*mNf2=5rMS}y3wXM57-icLT zA-~YJz30h&>9x7|_qqpul3c8jl3YA4!@@Pzr=l?bO%0u=H}*Tcy6o5oNyZk|HGXz( zS%!FRZ+F;NvE2;Z6`^ph-z_-ENN3yb-+zpu*G3l!f+y*{AgJA8*ZrXNm|3I$ju<@K z4hd3}laQo*_t|7xqs+LGKT6;fOXkE-v8&1O0?-6H3QSawDV)up8xw>-&(U= zN1b!#?7i=}_OfB6>y5bP?H{x-i9amBbOj zdh4pQ^5SgQeBRTQZG&!0{cuH)Lbn)iyr1B*&$P{s2xs|^mG@DantCnF=CQ_WavH6} zmp%4*q>KAcwIlFlU)V*kHtD+HLEX+Pj&gjj?J}~mOKk^NQE!=;a9tsFjHxjW?2*CN za5St@FD180I#*Ik{FTWG+ciD{Ni0JZ)()SD`t?{J3naIN>({GHy61+I{v3NYc1qL} zl``=8;2Tl|K+P|)`A;MOGAK9N>mlCd^RoMzALoN#j>YBspZWRsUvZRu=W-;)3Y!Y2 zpA~zUpfzF%4&*oh%wz;wJSE(J@-FJCxIYQmD|tON>iV<}QXu`w_%Gy^5LL!u0q}Jl zx-_j-Y26SsS?XFt58cFXK!AYk`4-;lnYxO}f499VLrD;=s&Sl&&)%U!IN}3{6VdFl zIbSh~Yz6^zYF)Rk5t+UT(iFXavp>6^BTs*S?ZYx#GBxdk_kCV<6X57IabEwV;^&jE z+w$$LxVdbO30{cI*X>Bv%f4%a!gi(^4cmn4*}sS91J}C>LRA{Qu!&PZ8#Y9|$@21Y z1D22t5F9uZqXLDCn%!C`QW#nvF9QaLsD>${eFVxhx}#~SB&=_rHU;7ze2)wKC1)aj zJ{CAlAR`+QArlq#8bteZomy+N+LL*3_k?YNWbTysvs$wfyBf3Y+%5Opw=XrwMrL@2Ti-u2|vtK-y1^UC-ry6%p2M!laJ}c3NDs;zgUc$SuSh#x? z2hvF>D?j#tGQof15hz-q#jLH)C_Fc8bS#XVDTXOq_@PYTOT6gA{v@d$M^{5aL$`3Txa%Q*(Vf=&2+F;y1K7k{B&`-?yQQb3jeG5CBU8+1fOjVaR1)y`p!#mPAXv@%HB(X+Ua-E^pY2Z5Kl=y1I#AQ1Bh_Y zwf9aezohY4W32ZV&EzX_9pwAJ(>Q&oE0AsjRLY20+Frfk!mZ+h z(tbAG@6>f0H-B1FhWCa>c!L|mI(NbX+#GCP+=q2vcLG_l+R$SG#+HG>j zQLt4ux+@M?`7RDb7B4%`ms4!s6?ZB2yo{V{q;V~X6p;%%3;qCYKX}$F3I=bU0BHN| zt&^rnHMW4O?t}NN_Je$+S-CE8QJG&{tD3nk+e^gl%S?cB{|a+H*j^zFpVW^fAofPR zM#vl=M)JjYk~`lX`2T=vALBxG-lu_4yxmd1m64CuKWxay3tv-}ZR*PnW2)*=UX`YpqP;X~ft z@Ld7!TygyGbY3Xe>{I*v6`;sk$th3J9DCdlP)YYi2J&r08huYIpz}4Z0ee!pdMD^2`ZlM#a4^9+a4LMXg{IXPSpG0hj2< zXscmcor?$~NI!#|9_!3}i~-w-8lBk-dX33flWv?grKF0d9vpe0TF@Vb+4%wrtOdoJ z$6o*$-TgzkPY6gYU)A;~uz&}kV7;iGb}xT`$e+eq8Nn-kZC&?t>Cl9lCqHz|>nynk z=_;x26$0LyAY_l!0Ypa&U+&SvTy_==Jyjg|?gn@Qi zXO0IxHlbLr2-unw#Ln?6NUXZgHuQ^bIJwen4#~>;RC=@pR<6 z^p)cd=9c-y#~ezH7Sd@kAd#D+Yu?y5{a}?XHnd-xD-Ops)jm^hOP$(%m47 zV@Z(2*)l$BO<;2&EQn*>23=pyr#9(`L}MIu|A)2-p>?eY=dx!1y7O)p<2qER0AR(C-hrj)}gfuMT=|l-WhF zp7+9$IQmMIWasz)Z)ca8Lq*8ui|KK)uusbQQr&=A~Mhb#J%{p{j zaO>cG-BK=}M6E<8{}O=Fc0hf81;`~?$EXZV!c+UqW{ml!vcih=d$j{Y1Z+*su5B36Ax7pQ7<4TgsqOfsVR17 zLaITSeu4l&rbIyYkWj7IfyF;uP5600m?VBr4meb8L}*Va(LR_V2`C^23yqvws|uwh zel({4{;{47$klkv_{=YNQm%XefQxrVV)7?*rtsqdYy`c`IY!4WN6qM`)+rj)0n3TWim0>`#W@pyK0A;k;R=-xi}dLFD3kg_l`y}UnjaQg-J?=+Pns*T*Qcux>HPw~|SrOIm_Q~H%&qtpvr z+j`(wZf@cbJMrI#`$i_y7PXIwdg?;L$p~A8JK&I#sGR1RD3c3evC;XZ1 zU~gXp&kl$a;7M&+oClT%5HbECA!y&;7>a+fFzl7VCW20DaA)VXg9=pI@^+W5y z!Ncs6BsK<+kG`2*Zk`kL;vLyH{@Y+P=w$v>7IWMl5rw-!pYDsPyE?%#R_@6JqWwQY zA1-26j=Q(Ts%p__bK@D!<3=L(GYUZOA#IW-;L;Mgb8Z8iQ${=K$LnE>p8sA79An6R z6Pb9B2Gk1nYhABi31WitM$Ya^GHP&+c(~u;#P|7c=?TPIh`jRQkF5b^jz)AM-eI{N z`e({Ko4>TI7vD+pIXiag7%+VC0U?GC1NQ2NgHm7CyTS?7$zI4{OUu3I21YD-j7ql4 zD(((Ly)|RKrF%H_Sv1nQ>9I^98FZO(1LUo6Id1rna2Kl9on$CGd#SA852qVuai8&m zaF~}nt9|mVpe2LT8tBRJ6e!$=cxV|Ir#|ZD6 z182uDjSB*9{car=89%iq={fDh!FpKnd(#5k1BAA<8h1kwY4;#M!lSNL9pF!Q(n0)pgZJ$Biu<%vx>)#bZZ^Z*KbcL+kz)EH26Ax(!!Fz1K(L-s-alA(!`TTk9 zqvGOLtrq$7{qr^u85%cqUc}3G3x}pePQsLFb+qh(O6H@g1!}xqavB@vb_DqNq(cEx z6&aXX<4=6A7)fucjFdl3vt%5nj1`xE;zj@tnRhxmajm2;N3(%=k=D8jiuzzvv3D-zba3 zs4~Jq!o9i96nZgeCAdEU$l>Iq9r_IOgmtU4F$@jU3QBJwBV&9*$2 zt?v4kXD6hvAh7@oNP>g1f$cBD$v?at=aEN&t}-yccERzeEta7YjFzuf}pY(bx%l=wNW zx93_gtZ9iYn*z-h-O&~^80}l3!prMZeaWlRecSBcf-;31q|8BD-~HK)TPymP5ewc~YxA35xfc)SGy^6mA~ZeN}0 zDiA{wneV;bvY&W(nxjrmD@Q;F!adO3ZLiM#t%&hUvMvyF`UGU;mdkE+1oTUHz}QEN z^?k4J{~qYS%}gUAa-j6}Z?1abm6Y-p&72jeeLfulmA}#e?SB#V}td2;I45g z1%@lSEht`5dPB=DWs%kbC}Kbme1ri-Y z;x+8)P3LdP zu3&>^J0lYN9kjTt+>8q;&Rv;fEd&uYuNNlnKTyJ(!@)7;7NnShBx;M^=k0Jicyc(~ z5i}3dU|R@?R(f*JaeAj{{&)Pz8EkGId+&|gI=`2fx%ln>`&DpEU4h>xnn=dILccM& zZ0>eS-kz=b!Fvmc4iO)KcW}Kbp>*V{Akpjrgv>gTSCxpvnhL}Q5;RH^HSdf!3S)BO z1zsw)^Jk2J?)F7KJmi>Ce{1f~6Ta@6*LyTH* zijJ#}v)fJ&@}}r$cy>I^M5M%O3rmLmVmJw{Pzp zu9U16+e}U<$oUr$!x0t29yZWli|WZM$}%w`IH!eQxxBVix;|+$;%6QNF^sMYwV)Yk z8DY!l?$`AuF+k8C6(Mue3S492zH@aazC-mz3I!kOnNYKeL0qKezE8_=EJ+UpDFvi!@}$qI9cvx+e`dO&Cg#4LXt%; zO9l+&%wQqwXT^XTF*Z&gJL-=45#@&rB|2yBZib`I$(-qrD%c>;QuL%l5??KyX6)dkK?5OxuO(y2P)`@TFHYk5WrvJe~NDy3VfRO52;6WW7EV!jaIf#sz zeqDGP(K)O59-^ggfLwY;hSu6Eu#K`|ERvb2>Azu?G$N_tVs67F4@UzhqWgto+wh!KJ{8}14n%Dp?CdC8a>$i{S`r2Ef~=2r`QR;5s;&-S3j+jDLmTb za)`+vnAgl<&Pv|r-|D@FXrs2iyGJ;()%yLbqT5dJHL?dnz&vWduSu3+!98tZbGtlA zzqMWh0xJKJ5Wo7Cl`%8d9ituewVm}wC%x2P+fF2uKDv3g{_6I6%z#abXF^)In_vV9 zA*VrJX?1$Z>^e>E!)A7ZE53QR7Voo9REV3H-f;5fTd%78Zyl*RB@H;CU0k4p{cC}^#E z5jP0Dn=s<7)lQpvPn>Mh^;FQY={{If1NkYC&Hu`IpNbF|<)Qdj3XjbMrx}?6BCoc~pNaYSpVfr|bdP!4 zR!0M)a(44LOK->4u;J={cT6^G?eJay`+s#GVJiAHL2#Hm-Z#O!SJ_*qTQq5jgiRxx z=F~B0Hsd85Nuuij`i4M3y#c|%Fd~}{Wq;BZEtis$q0J_Pe?8}~6Uu=r_EAepO5V?J zv5?zO4X2~~qTcoBuaH2PK|E#5nQQ+2*69z@_+LNpl%nn2-2n_4Kdkw43XAIbnY&40 zlaf3??aiC>{NE+8*UBSO5rQ3)pVeL!%OH}ZUJC8w`l#HgiCG`M56(p5yxSo`+eXN3j@_ifBRNS$Lo+LbL?l1JasE& zPs2_SIE!fMeq{`$c&z;L>+(SUaxY%_WylK`2E7e?aN1r>$HSNQNbP5t@xnaVO5EFS z8qys&350>QEQ4zKlTN4=2_aO(61h<0^7Q_(BOef|PEAA8Sus(h6bQ1XJgnOPb|VCF zN#vdzslAPQkJ|JUB)kJum@a!cy|U_~FOg zcf8cwdJ2~xc=57%+7zr$3wsv{@ulJO)z{I zgbx+_uKU0{EFPCN*e94HqQm1~+4V(ixD=vylxz^u5Jte%Ad-JTqpYtb_)=P0TD8a7 zfCCA}M8{+j@M2?1!1sO8?NA{8sy_50GWd_M{4I0zro5p-la5#r3$cR+ zY4h+%;abrpkkf!y0WyDq@`RPk+~~Z1ajyC2=0ENm1Q=)KNJhu&(r<2V7GX9n|Mndq zMoHImv+`ab3fH2sIl?dH!iT(TUxZkVX^^Di8L9j;NiYgM*hYmXKTMx;qkmH8!JpxJu?*(irn6HKv`p8#kv?cDhnh z7OI`PIl}RXIN~Ntt(i@@yj4Iz-$iN@Vz3~sChTYE3*!QwkNeqfDPtfXg&Gxv1#F*w z4~DYkjtd7OY%)) zJ>!IVuKG#Wb-w-Y4io!NQH|D;7kDXR`l?4x!fHyCz= zZpt4+d@Kc#pf9A-Us9XH$OU4IUyut8WwTc1KIM(z4|ng*GfcmagM|D)KYh5ZHA#|$ zK)~-cRc293N!IG5`@H6in)}|KQIT2noaN>I&Dd|@Ou-x5+qrKa=cD5WBx&B{#A6ix z#1Hd9y7>6``PgJ4eXc8VexF(`@@4;vf@jAgDS6rZD&>o)(3Mnp{e=GW`hAa`Wno|6 zu+>yFq~ACGzC9bqr>9YIEg+?3Q$oX+(X*d3%Ima&!hHN*hnysZ6?kvM>$dNwgl@NV zrOTU$^z1E~n)g+4Ijs>`c2M@*`tusUp7!@oA6$U)=O3Ayqo3~2fgOmHGA`-jGJiuo zcPy)~%V*O+wE))PyH{$mtO$GGz4Z{acW@Z2$V!Y~ZhN=CelAJ)YM*`d^ZEYUj5Qe{ zq9;$rVJkqMy8|OUC+;9F{l+x&dXaE83Cboh9f}{p9U;6Y8qN1 z4hv`N;PJ``XPX1L{EFB5Kk>y#u~U3~_;4$n_#SUMWS{KwpN9!}ig13kB!%ji@YPaA zGF}>zkLYzUJ5)BIr_j%g1ttqdQ87l?XFmd7?Zt4iT}8&Z%Z03a-qO!yiL*LZ~XHnWZr_||&bS*swmAkV|hCTP~S+eo&;}{klsdy1W7aC*{^v}(-p$|v| z>i5<{RJ8gsp5SoUj7UANrxZL$Z}20C~JyhvJdv^~}t{ivUR zaO~}_oHe&KB_qwR`>cLx^=RC84oLs+Nk@W8B_bJn#_f<6&Tf9l&3Ya?NZ7d8`b^=| z*ro^a8-JfSuo^ZBFzR6%=;P4%f~-wLu~+8wI~f1RT&4TNH8k#gCgTo_CtcHUGY_n_P>Jh##ok6O!sMt zulqhMrY>@?G_VKv_9Y4Yt5M(<4quF0U44yL&R^G7J4YS0wJ=$_(lAAyEURR@dy{F9 z;=iMGa}M0tF1Vv(Uo%8AEqwCygVd)W_EB6fp}8(=?BZGBad+hYTo(cJ@1=wy*lg?w z)Aeidlwp=S#bWR7bjM<9mZz7S$oP5qqf?Uj_$dtB_c;I z@?VO~H2IfNqmM)iz`8oqD5->duogt>$VW37?WxurltYAa3I^=sgQHlKzAWR(B zGx+o)MES4S{O3Xjo=#yWtY(U5@Fg&=(?Y$VP>|ecMXd2d>UdJmju{{Q(s#`1gF-KH z-t4Ri+;IH9bEl6!i-P1CrdNKiz@Dg23W>ATFsN_)U|##)^eD)o*2F2i24Qk_J>PaK zb!`)OT((Wd;juiWOw_tlr6%SR4EaZl!TYQPfYCVHXEHN%f~sJBxzby7MA&F)egkw& zOFt;^aS9(nnDU73mu8km>ww(Xr#{>+*UEZjqVWIs+9kxpb#%y1x7xjroVUfKq}z4B zi-r4q#`HR7e{9Da**(&(;_OMVr$Jox^j!XEX#uKn+^LV*E8N=t`o>@_>fu4d>9EcO zaVy^Mm+VK=;&TZp^R5$9b|LM*MTP1F=R`rikEd7ERB`x-eKySQ(+H)x1~s$#bJ5)n zPvW~Im)^@K1rJ!Yu1O@CsIxuNY6c#<&^xM|89!F5UW&j7z)v)E!FboF;7so{%IzO8 z>y%v=LglGGm$>z>8T!3w4F}MfS@~~e>-E{dW!*_Bsdz0dfy80193~b2NfoEfmV`77 zPY!!!FEYw5!g+;Pw79Qng0HvvgZ-0srOC4^OR;2pUj^NBp8d6$dIHcm`6T9Ot3Kv{ zqX;r)Gci`G{Hc*a0Y?mW%%yBHA!)4rD!#K&h9$92?MQIK{J4j<{% zZy?6YyHU4T95@z8AlN_)D=ci2Jjyt5mqI5!-p!Jo3!wgw;Qbj=GL%f(x|X-dWO3?@ z-OMvUXl`m=J>*9hnM8d{XZli~yFy9M1P<2?dqXYl_UqNWmgo9Rrw6B;?oPJEcA{Oi zOd6-3?a^1iMg8b}MN?^%h5rpt&i~Jg4nur_-F=ywNUKQ5#_}CsQ3#7d?>@AxS|v+g zY2xPLJ9RX1)TGKH3FxKiZny)3FY4Va|LW}ba-77q*p7J;r7VVk4H+4y&=tb;&YbZ3 z)UNOC;a5AbG^AUau77j`Q%w zX5iy(`|Kh^p#X(|tGAg*raxg}3#0C5zFC*2b?$+K-}{AS3bi4`x1Lf)8$LvJz9Wu! z4JL@-ICrRzT7u{FC%1NVtlod)3`~T~1=_sN&dyo+(PKCzQNg7)iYdfPp@#~s+H==7 zLQ_TMsTh&Ky)^1S#tEK23{{&dwExUD&C&QqHfA9(=?fmwfXKGf20SP2K z`x&>|U8-u{Qna^>+~GV#j3n&Cl2`mtXA8wxfBRrPNoXd3NromUC z@F`tLwiKVRHtPJj=h}fCamByh90`^X0&IaXBuqaTi{wT2N-~qd!yuq6NN5P1N=QNa z;M2!t8A;%>w24134-7ZvyT2c@N`?qq~$ObkrO&8>|xL+yVqBNm&>ccID<48K z`Vq7ENGtM>{DWT}X7l|5jB4Tlqa^-A+xJYiu1}>1I4qW}+TUneTEBn)BqZhj1PQK8 zz6yD|&EOY$C^o=)J7=hm=4O??7|e?6{e@J|@D7*{GfZy`=RBDXvwHVg_^Tij<199D zJNnY_9bdrL$YsSju!gd&8%Ilvda9b{?-RLQHW_MI$S_i-1)X6>YTj1~bT=K$_7&xm zx^8|2Us8L3?Ci9$hnCKG>$<7O4jIwrkzP9%K`;0(f-ofc!U-}`S9U%2cwwWZ);hL^$p9q&1^@K-AoozQdor#%Ff8bl1tUX(u2+MU17nJKy#R{@)3iUiBJl0F`rmui5H|9Gm74rYo9|!qj|5RCbTQkG=3uXCM@r;#XR|u>#1z4D z)%5X+Lfe>}&aYQv@k(75SDH+d+1#WHMcza z7h}Zn)u_X4Ui!(v@baZ+>dEpTLmpQbSj=IVFA(Tby)K!1OYVJf1yuRvO+jN4&JtIk zOc6+-Bw`UM5=<;JTLZV+^BfsGp&x5_o(2E)94oO1&+fIg={WP1%l?p}81t@_K^=!>I#)kK+6b*oGQ{06H?i4 z<9AaFQ$MH-%u)`ef>ff>$XlzN=q!xl$s z(L}J~>_T_KGZNz&3r@FWr$04XlK`v!j0g1teY*kvKMy#jwB7wqGd)ESNx{^vQh=YwsJ(Bb6alSj&uJ($dneafMOw zcots&$K2gW0~Y(ya~Ny4!tur->t3g~en$ zg*NOhyQSSF{eb%g7NkrTbV3%Tq%~+1W_~KLY3aE*<$Z%ZO+dA!tVG=TuMtID=xIQ3 zxD(=7-Q!^-FSwXE4>(M*$S(fl9+da(z>OlK1tZ+Lo}z>?KRCR>5;{CG9iNsFLZ`ny zms*LzpRF2HD+#Q95;Mv*D5Olp=a~=_fx$FRb++vravV6S_k`d;4X+i$p} z1b>;dpz*Mg;ouHc1?Dr3Ke)q%{fQk$sFnd1+1-K2#lL7gJpji0@@&wCl~@%u8@c}4mXTqf{e7ftz+lKJttyq;$q zQji+Oltw2k^6?SH(c6zcg(E%DL#=E&--=l}(e@)*znvOL=f(SZLYJX)@}GEJ=?6Xi4XDAp zg;F>81>t_c&M~}q970OwD(cRXRA!ki_yJ3)f_Gzim!3lJ1C)(z9eq=NNc9MPKjyah zEc7`bQa&|KH+1vlIegLc`0QVUaLNr-FiuWRH4zffaRQz`hqfWI=jLGCo3)ACoT1Fx zEwwYdKO0O}mpOb38UN!u9gY`b5$L!fC9wDM5eikd(=}ecaD=_S&`^KqaHsxIU;$N$ zi*X$`9V&6n7m2U#XfIs~B${$+7_Y09*gxB)^=thX7)TF5dwFMi^IlCD9%o7~&T{y_(B9kpGz~+!U_$Vwt_bcVpy^6AFUj#Pb;0BgGwJgX znvr?m6f#~u-aP46=^I;$;`UB&)M}7{{Zr%g-M+=r%Zh4fI<%J74CR`))%9?~* zMf2y4%`d_R>UZD!Ut5D40Zwgp#E*89#bnn+B8O&Jm?S{3I8$`;;Y4*zaURr zW_Uw_6f80X?PYY`T!Gf-Q0qyl*Sux}#8d!oZako*#sOfkGwA`X_jrApxcE$X-$UZE zo>u`-N_VwNcg)RvEp?OS(Rmv4QO?NaqoYWF;aAr~Z(Z^Cxd$t>5S|$^;&wiPu1-{| zX11#e3BS>dm%A~XhfLdM)+2ZorpAh#ijzcrO73!UaF5%aQ|0;tK3onp8d{519efO=YwUA;gov~ZP;~wr4^HE(&W7B_!^M;#;=UcM; zkrMDvqlp<^SZD`_D%olKaye)*50qpq*_eT0h7o-UPYa%8bw2QhxBZ%$L3tlK1&5{W z!JmU^*VvGdiK!KUQR;uNLo;2o)qa*n=~&q4@#5uWZIqEmntbspwP-wiL!wwbUi!1t z<2mgMhN>Y0R#B;nClrK7C$BGR9$IxDh5}^@LaOEku!KoxIU^|9W2DrqU1f77cw`kY zgmF0hYF(?s)X#7f@E?%yU(cN$ZHO2Ct^gBBMnPtz-cUQL>GBKw6o3gxxz?|hytQiW z5pA4tpQ%t(TtDCzJK?mpSIe8JvMR3Ck{qoHQDslou<+;F?*K>DZ1M94CKVw*f2n0} z;sw(FdWw7%`V!4@v@liWX_1z)8z6Hz^2H(nGdWK?jEYRDc4j%PceM4BK%>|aB#`0B zn&5T!eEQrzMeVqmTQHfc!cFiTk{2vJPZocmslzrQ;k3E)E#BH>Q!+(fnK-i)zq z_d#o~rCGcs>fzq$4SqsJAz;Po9&&5&dp{X9_P`Y&Jz8FqNfgDfNHt0+19HUf#5(w4D{;oAH?yKziH1=6O*ZP`Rg^uOH*WzDw0Jzn{5D z@#w-uD55Fbx2HLJ?rJ>G4h*hfifq_<<*=k6^Ny+*Z2$Gx3jG34S6;F_mP)*#C|=VN zK`07%u!NUPw2_P$mS*fVYwH6lDM3`87OKejeIG@| zzJR=G%WrN{ydEkryV6}&3}Ov-3z?4=L(Ku4R*?#*5EU5;R@R6?ukD+w;~%B3KYYT# z_J%2hPy@vU?-NRdIY;(+=ti&vGAa*+9wk&KZ$|QDYu84mHt-Ibk<(Vw^J?-mw46N$LnA?hQFWjN_29<1luflcM10Jw+_4&Ig`dq`)Z zd!I|vZPSx1*_V;7VG~&7Vh*>MTGp>K)_;JJUpU$Ze%SZ!O1kR>q*Es3Xt$+t3Jo9# zepxAKc5!D(35Q#4(@SLWvN5F*Mw&E;zvfa+z`?wl(^_Kxn6u<`A9A zm8a7%fdmr)^J)Mq924Ho3HvOK&#zUTDzwn0o8@05eq$z~L{hSubzbrPyZeX7L)q?5 zKNSbwuFb7#`&0NR&<1#EL)CgB?eK2(6`N0+qS#+2vFn>{(P(0bh}U^6gf- zEYU-1&Toq%&+sVpcA-YTO@p1pH!3+}nOQ@Ks}unhkY%;&Dk{8!fQZz{3+OC2hN;wQ zQ0neQbtMO9pRbGxsj^T9ORmMVh{NK8rf+|G^W-O}Eyc9OLi8}Nqxuy)i@{5rTH9{M zI83_Kif{-d5XaVuSvp@8GZWXwo1q!&q}r&N*rv}%&>wRN#p+uJju+gg@LDR^OZ`?UpXZC5(fvvK_laQ9qzS$nH_`R2IO=)G~?o=3>a(g*4 zE&tfws<^YWh>y0KQSTKVzLm+!SBTRi+8TKP0PUj-&0G&8(9xFs(maU0bPHScn|m5( zN&*n1!zr7VJ(1(bUdyPsH)w^1l%b??EMxMM?;>#J?wxRPc+Sx)VTYalozv$MQ;G)m zxF4FI0Ac(=J2j`Ja_!a2fM@$1on*8BB8&t8Y<_o6reTS~>-GyyGNm+N;25eOF$;N8 z=qW+(R94~C4<8D$?5{685;LYv;dFccUOInMw>B=r_NfAlLgEI7VBla@@Z+falF)O7Ts*i z10VS7q``Muf=Zdj3VKs9^#Xz&03+vF?P%JdNBM(YsYZ!8bo1>AJ%s`ZgvptJhc+NN zh1B$GaqaVZhGCk(&yW8B+?N&ipKCp9h%2|1^$Y>_zrglO*arIX$=e^<%YHN%6f9ab zGF)8yi+U@#ZEbBi_tDUv=RZM(x#e?iu7~Fap}L)peP9aAn^AeDlcyzF>O&!vl3*9{ z1o_Io`+VEuw$9pIoO`y~8Kuiaq3S!#R%6gdZYGlbI8)+eWNXTw3)rBTN1udwa0=~y zQ*PVM&Bk)ESFvh?>V$E2M-Rfp-6_(=eCVjk*9gQq$DAJF^2!jA3o>h<0B{)7nw=3k z`k1ry0b(-}vd$2XbiQnG(>paCXlV=8-Ib3IqIvWm6LFb`;qWB$B}s(xYoizW7a?Vm z|4a4$GJk(AYSE^MacUpE)_;Unq3q1MoL$k?hPEl;L3Z}IGN)i31|@JL!Ma+GA(V4+ zv7)$L^T}^gbx99jvcEnH;q+r9ZF@H@dF67S0URUIq;=kEQ==d; zQ@^hdDXs!OujOQE^xo<)+)mt(;l0T_YUczYN=og!`Xf@4*f?BjOJOCS3X?c?a{!Z# zQFP@z<=)=73x#vxr{myApnCvM4Cy|7BqMVzJ2zKpwk7P1Tnb%x%e9}9E(OuB^|^^R zbyIT$S*QZeK9C9vEw5-bfK8aF!dRC5VDFXiMK?CrYCYUCT^LjcU!9!(G`C`{mNeyi zqx^;?Pk}po=zSHE;E?FZ$o`_Geeq!5Gc=)69c77ZCcVgUf{IEe16y0$bgB1h>XkSF zoR|=b^k+!boM4lxoV;{z!)lpelsqQ>rbyuxaQ5tnP|8PPo6{WB*EG9O-GA*>CcjX~21A=N0nQ9KfWA{38taAE^|IvKlxk`bCXgA+} zvY^+E!GpF~MuThCL+OJ4256*bhYRF0LrU^|G&;}1!nXfW%U_$t-&@8ou_TeqFl^QN`qQ{!n?xU>;s%sW=bD%=U%6Oxd1OvlANqS{Yx^$MNaL4Dx(Y z=SSVn_RzPgPq)gA!j^TEJNuOGdB(J0-aH0}D#2G7F3gagCFG>isMpV})J48@adeE% z=hK&N>IHNhS;8caqbtaolp7#OCvj&J{doirJRko@b;An+?tmPz&h!R2Z(m{H@wF&_ zj_)*MFK`V|$7(*bwt1s%lsr!v+Zu-^KvK=#*4>(!nOWSJZpvVjwU^MYuzlV83@d_+ zF9X5Y1lBwb6RN*m=iHS{hqW9-C*N|~k4>s^*rE+LAsK!L^=JF5?9UF2OhNIejbcz^fvmF0;{KP`Sq>*I#oz!~GmNOcVF;R<5d+ z1sZf26~*kkrgSjIJvCYY=@0Qf#b!2{ue7lj+E^j>=E1u5oB5jJ6Es$zV4o$;7NXck z_JF}?du(tHwj3{G9ON@~-bbd;%*}o(!zSa+T3N9ay>DV-a!2Wh+h;p{o;Er3(NTBT z3ZJ@b26?n~b#={rLziDhMG49#vfry}6okk&!$j$f8XYd%2+Vy)nIFs;MYw{7#ltGpqZ1+f4jKJQsuG4NnFXwwx; z4#u&0OpiK7?hJ%%ia!pwyU?gIIk+2#4gQaaa4m^}+O*(4OTMRb2v9`=Svg~~nsy&O z_{=+VRiMmz0&dbx`z=F09;i1-v)JmhtJX@iFK&Ve4L#-3#SS=R*&ryEG49bp>m!ss zzaI$w)f<71mRU(Zdi2N<^bVzTw6(V{9`-p0iXJ=MAMsdj<}#&q>H1wlL!Sx>j}R(y z34#NyiY;N_U-MCKVQiytS^s`Lzqe!zss79}!Nx=LWu4_=Vs;7bsJ;7z$B}`CHoOUS$l;m7uW$iyurkkO@xO>d0>gV&#CXx~+X-@|eL;RI34MU;`BcK2JJg-hG&H z_4J#1UJILj3P5YlK>g&ZfNShZ?Q{U&;85Q+=V08>R;W6&!5v9D!3r0ZyY`!mj~9fuUAhUwdY-`L#U z`9mZSFO*d58mUnJ(EHo*&skJr{0mUp)(SiYfFU2?v8;9bY7i8aIT&0o|JL1AvD`ZD zXMkmG7A_ZTn9NuA>1izBvKg*h^rRyLc&vT<>-X#VS+o*%d7gLmY>#pJ zMY{KNV64N^DuY9RzVr#_^jy^Sh(-;Fo=bQOGtakeEUdxnY#=BLr;q}|sPZ)Xx-17P z>lQG0*;uIH7jx(~03F|l?FYhT5&RpBK9qzz2r~otTy?lI3>o}e9Bjj(#0+Dw_r)gf z8-5G}R1Dz2?e&5%>&Uyh!b|nmknS*7+NS&XWaEHnntcDUo`*jTO+mPXa`y9TcEa+a z?0_JU5ej8`iG)E=ceYWV*B1OB9vLC>F$&=ouAna#7uNAYUgcf@$9ZZ(Ts~;j-xZLsD z{3=0hnt7EPZ|boo~{tA>L|>8#{gSx9A=9 zHots&hQYwa^~&|6zhAjGjl{y$l@pK!a=3I0A5D9yD038)rFga%x>e_zK4HU1UoPqW z+Nxi&8y8cT2%ze9i#m_sacbyWk0D%xKpXxvQE~4O6~fy9EW{d0b5+>i>s1sgs^HZ4 zh&@mdq05qL9p!g3)IZ1vJV6;|>fn%YGy#o$z1pM zu0}b|Ly}3+XP+!@KkB1;)`SwVJ^lk`wrlpT)zbXO;-oFa@JoP#%H99Z!efFfzzFs49thTwo^WVJ=0ImkIAjZ%EF?fqeXPd z$jA)Z&$VjZWBCu~@J0*uukg8Uz#nxB1?=oNZW=s<;xiP&_2*ingn}s^c6|N%=tcJo zZ1)otD!!2AWL?VH*|E)MGiNKk1(g;ofhmCryRbx z?c{fI9!1;lD=fW*`og{Kt7GLi@7-}}7ecF~Utk&1|35+=2c-bfWKru7JT?afM8YG( z|BtS(0IG6b!=`C zt^a%Dsn7Qjm=k(RiqE?HHsV&T@+fG^Rf@zb@7;km`134peYqWlxrk-1F7HTVXUaO%TcM$&o zD2bE8I;uyxC0ars3nY|e93yI~3>(h@JlUr)u%GRpW9%sOdUJJ+!v!QDt!L85v<47Oq2TeXhFKA=-kD+(sRikN3Mdn_Zc z!Tj!NCZ)#p$kn#U7;luB8ifp?k#R_oaB-<{p`Py#Xzx$FUL+bD8#gyMa|e=1Z>z`n z8&A)G87#hJccxU`{_fmBR=HA7*mQ~Q#VuVV^8L6`hQ}vukE?hjSgx1Hi!RkH!{KBB zvZ$CCf%fNn%1V{>i987=vl*&l?RFkud=}61(uBG>SuJ3<+a5#YeI!V(Xz)qHaCdk2 zPXWIfB?|r3A30fN@Wb9AM{cz7yIO5%u~Mlx@DSy_V>U&CW2ez*;G=?Erw8UIQGAcf zXzOU}sMI0#dP_;5NBiP8vke#kEetmOkmldAhJW5k;F~&uOy}xaivX~55Kw9em7l-_ z*b*4rF&47SmG$s5L}j7PgrrhNK=}-ipClYL0Z6)HQk33F-PPq{fIDW;(vtaCnszM~ zdDqOn?{Y7|-bm5EfWS5*u_N`0q7oTyIa30PzT~#6kO1($%w zD8k1Q0``Mlw5WG&Roi z;^#Ld5*k7OVu|}cAmMw(U<_waHyz@#KoddfcL{3)Z{Zu1wb5UX@CJRigmJ{w#q>0K zXr*_q+&l%CqQlOlz#Vi{wke!$1h2B9mXUE(puL0eqN=uu*-P@CU z8YOu%H$i}^6LiGhn$4C;8jYss{rvfPePHanDx z+=6shaTk@+2P(EGVT2_DCZ@Q)NPJpby?WT=i~t0D&)X~{1>+;3(wJWCva&Lwe4uGa zjIiAuqfu?@oOJ_rJ)j$$Q`B0Mj}HVWb8*Dd$$w(ICOSL9rksl9I(KAxF1KMw^!RO+qNeWfhy?}&Z_`(9-;^L?Ui z#!_Nd0O{bxrq|Wrfh{kU>)LFzc6Nv`BKS&Drky~uyClE*`;$p*WR4VT+*IOrpaoFR zKsal~M=A3!*V#1caUExzNS71lpgH8PgaEr2PJ2>8Y~}gw`Gf9i#MjFaw+n?H=%J&y z8%C?usr$CIo9q^%99uVwhlLe&DtjH-p$+N2A~yX(ZQ4~@4C+&gs3G5glUZuYQzQP7 zoAX9SCeM3@5}R5XBX9i&f)4G?NPPXaRlI9{bk$d}@$WA>(DY3X6Zhwx4;bu87Z4yZXgnyRpF^cFxBvd$Sl@JOKR1qucsL{|YyMc4kRbcVcxTk3d2ncLys?}TK85nFeXVjZa27Z)Ir@}?qgrvgVov$X{+T0uq zMke;R>l)>Kp<EKq4pHcBHiQ|Rx_bX;U}_iOOG)x> zKb_3TMi_cJgLrhHG@2~FiyoT(xVR&B`ol;XBO6?k2WOjPTeSKidj%;=IZ-F0P@_4P=jt^ z!$WZtyHoGCh9R$vV>mybY7!DEYR<$~o5w>Bz4UEluyd7Yg2pK6>r$o14}pmxWxqSd zfB5orvkDAWydfUXMr$2DYQ1oWOC38}&g*Z+ub-bDdZds7&@pIn*-kf|)XTM66@(Cm zW}S`};(dL6<4Ww0fk9-lM*zwo+HWao8GE7LiWYw&1eFx+;s07&Eg){O<;B&CwP>#n z;F_gcxg-9=N~c1s?dnJ^VErhDKHapu>WY=TB&Pyd8@$^OXeT&E;{e)D0&(KdaS!F` ziz9i6GrC*)TB(N0mrm3kaCHbu<*+AAk4JQeJ=StFjUP4~?Cg{ay9?{QwhpD2qh)WI zJq{+rY9H^JUt|+>^XFGNJD21 zSk{smJ~t*Oj3kRPVpu5^F>Zr0rau}cN%{Dtx{=fu+mk*)lJwxuP>|`I{jd;=)7||- zx?Ng6z^A-|qcoxzlCg?&l>#Bwg**y&GMi^tP!#TmTG=7kSRokn*!DWa5Nl&B;Xdv` z!S2zk+%X*fqn!S|Bn|^*|1B^i=82W53Svs^AN3CUiWo{k6XUioZFt3~n!5!s<>q%yBV`9EKo1YlgW z`=#US8*YKV3nrYbyS1JR#lo8GCS{9d7R?Un{V;!bW;$k2cQZZHuH98rnC}{y9PBBm zdt-_>_>Q*OO&=55*)8+8KX{0hk2UEhSySjhK|9z$NF%+NA9=cJxsH`+#F2Vmh`(^b zXf?L5P{e3OeaymCstNhMQkAu8DPza#Z)RIiVNkblT2!v+L1~p{z=iSL!r1|?s1228 zk?l?zh<(({MyZrj!M3^z3xMwJi9L*GukP@_h_R#kjwm>K;W51(mlgKS-Aa`zC!H4` zs_u|4HK@(tVOudY|7Q!(lN1)qv$D(d@+d+*EI5^EK2mHLflA)qe#<>HC0eDmILVXL z{#o$Q$R27r?FIQ|d%^aJ-Icf!4$2Ej@PE-Eb7=P$mnE*Uw8cF%l|d$L@oWfoBm53P*MPIl9aI(Y{N6eiS# zD{8L24ALcO^$ID$O@f@EbT@_j8LvPB?Jb?J55_184SgN zrvnuBfgP6;YOk`F^J=n{UCqt2Z(FH~cfJT1ode}v{t#87eycAn#owz2_z`>`#_Bex zR%!1%?M9kBJ=v76Zg{l&Bar^Do^kNokTNrTr_FV0Bx2!Zx5xqh8;fg%xMfG?MO|Y6 zh*y>G-L^TkWdndR92OKtgxggC8VHN3ErUR!hBhXwa37Rem+GP+3B&j~IRT~!jGNa| z1Rp*K`K$r>l%Chi^V4Pf%aimWQ0x`Wo9*|A>JIO%Z%=hAy-wHoE4RF~T=z(N+nS&= zwOU;jstqO600|Q!EHrc`P#R>nhT_qmb{Fn;GQ1R|&_7761qOJW5IHHSG#jP6e6kGv zUy;YIaHhv1f@>{fu51B98oWuwKe{h_Fcpf$UD5HZTI4mDWA^!P_VjykH3G|@HU{VS zg|!B?TD2C>0N#|j_-UVYvT#yqJa6>C{v(eUI_uqI+9l3;*?3(fKJP~@dhJGqvJH}t zC79Pb@yqY0(jb$tIaPN#34_vbFHLYhz)(*054Cv2irRLOnd&-)`&fPc;P^v^2H5ze ztfar?Xeb^&sSJ_}w8Fz=WXrE*tt7kw0l4pCXgPR;VUMZ`f6|X=j#ktC$~+OyUb;TB zcB}iA*ymS=L|Mm6gc-5*z>;9xaueoOzSUOwZ^1kWs02wztRqiE^2e@U?F9}Ye$>pK zJ#PR+^a0}bf~T3YN|01q!w@R@G&;we*9O&SV01e>e~UK-7EnL+}Y#v2uBtqtZnM&`~Jjfd+swTcSXLr_tgpy9eD2JYN6( z(%}JfaNmzIQlu4c&0@bPEtH+QDpH@4u)+H~)?x*`s(w0yrKrB~IcIEm$PQ4h<1mOl zrrm7I8unSB#MY3|wQGt`>_ugclmd=Jy-uI1xeZp6?B+_i@;KV^DcYN5h6Z&X)cGw( zDm0ys`(XY(x5PaWhym#7_S!${`E`eTTpaOaXkkdNa73Osw)E4vdN$$#7X;cg6`gK< zaM#C8N}4f!ku+rOi3S4^?lSj@4}exwJk>o=Q&7Ma-gBZbiW|cbO=Pp<`)wPhlGgXF zg6U3yjMUmz(pw{uj2i`An{}?gKh2*}U4_EOK!PU+cW^kI7wUZV==YJ<34w5~gw?9q z0M?8ypM0}=y7SX9cSHSB7*FLiLRq^TFPuiW{ z=K<6Ut>4|ruHT}!Pg$Yljt3E0)-OCwoTC25Q>?d4|e?#XTVT%7zx6AP>i4S;!bD_ z>#y4D0(E-wGOfMoHO~cH8)fS-?Vc`|`fNiDtpes#bP^N;h!n)ezDZ`db1kC?2*3kJ z2gT?6ck^T(yE-IxIwTCvq-LO*Ccnoh_LaF~rSQkd41s@2c{ zbU(sB4H!g182c>=M-?*|fT?1XOkN~5Xx_I-9oFek3eOLE+W`=~#W76N`IgvTV2$!| zftqADTQMgsS+geDjoB_w`KLMkwM9VGfr`%9tO3yQa>45GN7Ahx`?Wvz6{o6}V}mZ= zkvb??r|#3>2L@{=Ww0RoM6A~+H8&{DsFiE&skY|3qF4S9lnoowv2-L z*3_h&XYns4YVWIjXudokFS6g*ECTD_h#zVw^zu>85@3JFYpCEeyYb<_haM}%n@cvy zed)c{f3g60?G`3>B=zkCynuHwK~M+q4l@}Vi|k!!!5%F&`ZbA-Adm$juf1W}Tz#?d z-IpssxPm_bDdq1Fhpvzq+>j2ExzU0n2h`-fxLka%_8PHEXjBOEL_QK_%vW7km0da& zL(iyU*m+AcTil$5?sTzYb{N2=gi(i~e*yJhVui!!x!)yTZ>umIekVH&77PF|KP1r> zLBS!%0Q6@s!|OQ<0CMHK1K;j_WnCe_ARpKQQYkLG5qZbLu^GuoNrQ&s$OWGsZW5(2 z8}OKnqmbw-GS_y;bC|rI-QV$ga=Ey;j05YWW6 zVV{Z>iuA(E#{Z)W{XNUYqgt2l3ZyHxl3jfguVge?sxZD#2<4{Z_z$rD%6F1=c9cCK ztqrb9NsZ)=3Yl7V)26$3Y47e=b9nH7xPu#RcCy?vk4Z_f@+hhHfst~ay=LVvUud3k znrLxnUL}=}kH~u3+x1DyrAnWx*9U(iCWR}EZaYxP)8Hk&qG---I;C`oQ`Jp_KSY0C zi%0@z=&=&E!qeMc->aK7yww@CG`w7=9_bl?aHqQ&N91u98~u%3=?8^92=&`JftEr6 zD6OoL!n{I(psSR&X(ZHL9B?=>fUv%_C^POS3d-KTzhcEP-VB}%V=5y8c~#Z@{qhEd zaQ3B>M%(VnVEiMyd+$VHHKTTCJcHaDziAwzpjs$sXbpf0m(8c{uTYH zDH9av0g=q`k9a^mpGETHdIIp?0V=#qJ=y_1&DT*6;Lsf{{EXe~Ylzr9%S<);Nr{0+!h=gH<+JaL(M7oo*N^ZR5Z2g#YQA=goV1LX+lEEWoB-La3 zSxNbLRpSBZ3e2-IYW?IRxh|!67&$R%2!UTivQ^~+i!Q6|XM~a~ovX#uvY=k4kA|Mk zPT8EYLUdp*b!|nYRHk2Y;bZ^k_&_E#zI`r}`fN=NofO)UU&=ccJPVal?Dp>%2w1R3 z_GnUQyLFiEd*~!|Ons==x+$K-XE#`C3&4jP*t1PmZP};M*8P(=39rzd@Wlltaj;meQ0GXuP>M^@VUN zXy^#ieO3Sk+uPSi(WH|IbM_Ms#;t)g+lilUJ&-B6 zF7`^Tb^}{&--uf}B%K-U-7Cl~XD(P25!(qpJBkG1G^h~l-*(UjWD8#P_}G6j8om(Z zwdoeS+|dLoifx$gKU16}g!6bXsMTjALaXH#etOlhWLvT#m7ILx&@AxBl2>!HI0bw- z9GD@AjM{x#rTL(l-p^LI?7gml3qw47KR|q9jAA^;cjZ<-S%Aun^DQfI8Ex}?N?uwv zk!FDx#{pQuEI-x_%@(CbAv8n+bWW7($f49F;Sh=OY^l3CXx06rz83H*jF3 z0FGv=#l)*oVN8>sVL!#;0-$R_4&7}Srifb6COQxDG2 z6U7N7jm&~9Pk9S1D>k=l4U&0G`*%gp zM^t&`CiQ01VnaA8u#xx@)$7 z5(Ndwo*>l=Rw96T1Vtc6;81;u{s9O%ifn#FeA3jsYTUuwJbt?X$z&;fNG2C2w^*(# zOViDa0-6p|Udm*m!IWP{L&Nbf#S&qg78KMBbm@ntbGkxQa2&+eZsYw-k))JVM2|ij2gcD(C0XVAe|7UnQ7~l9?3Y+;diWz`ZZXvf2TovARB?76(r+? z;G#KHwMHD9XWzT*f!=hmew-){xT8E66!U0w=4jJIkk7_4fS$vz=TNncr`0{7L=4kz{qp{W0wXbC_Y z*s-ADhXH_^DgmUKqauvFnFAgl8DU)s)G1Wh5?@3Tl^W=_gvzs3Z)*C;kt!s?V*8x3 z1nCFk5)uS}Ft<$0j^V2Ac@WZQ!q;ssKqGCL8ShHs}vM;} z^0-nok;Nlj&+QO^!jQ9W^m^ebRj-#iyx;{EyikvoBH5h45qgDp;!tgEZExxfNW&xW zI8nm*85kJ+_210exC17>qu(hJ-7Qc=U!iU;3d1Kh6wm!#?Ka8!3Hwi51hFYj)W&fI z)i<%I^yV6F;W!-Fq=?&G)Z5W~Au;&e*&pP4?|>+efH8i4aL(8FPDcx@7n#CY=}PYL ztJz8+{ky-TjWJ+5<&T9i<>L!@b;3~eyIXJRWq-m`1~9pz>A_b)_tpD*gjSinQ<$ly z`xy=$WQzGBFyUA}oiLsAYZ#eEufuHXqal}x>-S@a{Iz|9^UkrCcGVedl7$g^iy|wv zPZpf~UjQB2e^(M^h_!7U<$9b!U+-a58Ak^lWXzA$2W?wb1H(Y3Mj*UpQ8VF)xA$9A zYkT(yqLsbR_`^$|%#=K(09`LZRMq;!*D0zDkmfTAI6Pb1V^z;F;oztM=tqW6jZP=; zhrcn31b>`sU615_j`B@SSi&Mhf z`0|lP)K5W?8Dg<3@QN@_gFkJUjHVI%+MV@xB8c0CN-hJy|6Tck?;l94w||-pMf03g z+NoYRY93-jFaVXm0voKVq&qpD5_lOl$``piL1EjY7)HdaZUI1E&M#-YLKzDv2!Uqi z+}c&#{J1I38UV6}#V>kcwBzjXLwh}TsUV!BHCC(Xp7(pCO?Ep7)G8I;z%%^mkgZby z>Y4Xtq1MbEKq1%nUo}DU#>QkoF&*t<6m%w#IR|1?P60#x8(6rhoR+vGp~u(UE3wlt zU&v1_vQ(YmoUHEbZk0*}U{{rQNdZ_~EbU8N+=Zj+<*#=8TISksO>=1vOhO2$Zt^Ynj&29h4TKQKJKM%gqk|(; zz^)QTxCsZQuC{{j1#nO$(5!QfAOXS4G_LUODS%kBtfR9l_GvtYJhxv*IE{zX0QZL} zlSHedDy=f&6`Y+NvoiH~Kb}x4{;P}Zzl#DOMZxvazJ8&Cw8CDR)**Bl6#g3h%A^7J zjl4!bh+)_O0^W3YcP33)2W<;{Bc40wCef)M)hG`8GNU{(pArZ%{XpP6Rx(gN5sQe$ zg0Wg016L=j z87m$)n#DksnPDjeo;m`(AaCiFWHJc2-gTST%qcSXlyjOlPG0kCWu8x4bkr^{#D3+m zv^qOLK|086drcV2HR2f^C@?o|cDPffxV!W)V+%kyDv|4lqUNY40a7AD@6XH7|6vj7 zczrSxgzXFq_cSLTJN1PAK8R!dfR+ePN9HZq@3fUzmc%z#A=~p_UxpG3%}d-4UPw+F zdtxbOllS>j7D4()QJ=1;aZAF?41_OiM`+%4A@+(KIH^yr^P%_{j zVBvQl|H$%9iAq}>-;1Fiq3Tm8P}AxJ2*}8SU-vOkP*D5*Df0Ehj$?%R`FTJ&Bm|Hv z8;SsC_m0b%&c)4bQG9;@93ouGyZz-+XVZqf1sF$Uo^?pj?PNwn&@IUta;I|0} z()oZ%5D0PT7(Hq7_n$a!y<3&uMU^bs=2!VHhA;Cs%}j^oHJRZpGh~$#n8_@ynSYr@ z_FV?z1=GSbBGYH==Do1HcOFUEUAz_XpXzO(Zg!8(vY(zL`tr+fcZcFML-?L zEuJsbrNe6z5eHScIv-wsZ|}f>(PW~Za$u2^PtZAY;&c@pqYH4il@rAPvUH}m?)usM z_|P#UxU;+IcJ{NAhIp=Ut0J{gyZRGeZK1{ z3{Mlk4Cv4*H?TPC_`TCUtL}E_l~w+F>$a_n17UB}8Qai!ntN=jRn~;F0T0N(eQZtw zp|il@d{mGifH){OZ~{%F3R^HhM@jS*n=!CVtChkZ0pP>p;^T!4ek3SD<1H;M?amuz z)SiDv283)09ZU4`%>H0p8@tjxnfXV+sT|RR^1Nd+UlcXaULHP zF~c7^a(-zZZJ$A6XN$MX7t0vVeb-hyl>%5*l$%@>(Vw(|khSfI5Cvoq4e`&}K9cZ3U;shgzD8CI8N%x(4p3?K`(uN2S%PrG>;^2pU?zVmlM4B(W9+hz z(EI{Phc$?nH*5my^P-TQBa;j*z-AUJ?{OIh`7hSX)uivRIfJ!T!g8`!KnuFmdOFer z5_^?$!ZIzf8ROYp2hy(`@(O?vno+o(!lMcf3XWAJi2&14aZQW}z_8WpovRlD2c8Ix#g<)z%}T(^hkDpmDpXg`4p*;e0CO-mI8Z7xz}T& zC+ly!KKOuK%{%4>#v4XxXraL$w)&t#g727MJl;rMSq=K99Rb2^FdxWgK;fVB#vcLl zOhErnQJh4jTlr}+*&m9`*YO>~d8?BaQ+k$yXN+ZBW3fAQ$xYQB7^XI8J>Vz+s3UJW zEPv0us|+RJD$Bi+Cw9@V`C1m4;}mmZwOsuZ;GdN{7T3=Z##~4xHFchyHZCdcn#+D` zp^ueQb}~k9zb*7Vl(?H^Pd7eCp1rmCWZ}T!ZI<9=!ZcuQ^wH`<$7m-DlXcc{459m? zC%P~l2HEO#DJ3-;c;ABQ;Bci!&8t};1EeGTGr0jS3qbqdconz&upNKr@KUZNgf+5I}@AH`vHK!jI@KO z%mOEIvdzPd(Ej$uP%Sh?@KYamQ^t)^^om{t!f14f**uY^Itr$y^q>s(%yb?VI|omJ zobr<2!_7->_)j;AWvuSfZiS~}h+@YMeTpz#Ky_16OLs&FeAGWMTmQCX?>rP8(!gb$ zHhGxQ;Yq)h7x(lPFz~Ig`6u0#8Cny)Ro$WK%cIcR%f6{f3WsyhQBak4MHHuBqQT)v z;i(T9==Z84_r6|pE6_aI41e6`b!`w&s{@Z90n)uVZdM_h(p+OLwWLXIOw$$SC)2bF z)dJk#-5>M{AB(*2o?e#RY68+=Vjg;JhKAcnLl|O;61+5RZD}OhzJj4ip`X{DC!E9| zZbsSO6>Ct}HO{lgrP~VTNxhfnP5@f#C5DG}#!ug{vN^WIAQwb5{pxPWKMxjPCxo-^ zG7VvtYa>ToY`SK%64T+GQ)kXEs=sr{KgmMo!64FIMzWoE{;?ZyY8FLj;xA1flS`UE zoL)7zKZUNOGl-}wXGds)O)0Y}WGs!G?V@lvPZgGqI|1@Zg{RURCg6qyHYk@~?#6Ud zABA$&L@;$@ZI8&i@5%T@gwJa&wJ_Y9p7Hg7lOr3m*qK6Eb(3d@@f09dVr5ktx`1c+ zW*kVR8`^y57^s4Eh43{@O)YcIM;IYvBzO!fRKF@;ZbAUgOfNv?-{rtOwxiMRF2eco zPGWUbvQDh4MfFYHVdk0YPnmUYT8&IClwXliStHQp9YO@}IxwGnQnnxuCc&vN#l~GFlaDmN3M#WM6#G zs@yeQZJiZ}m&X^n&IAHp3a8L-)(SFEcXPfiDm2jt!ub~6E5axot(nUuiw{%kzEzBn z^Z-$Yl1KgY^7nA)e1p()I?h>2HIHA@N?}qnkZT(f<3@1K=7d9+!i$iviI{Ip3=D^x zy~jS=v2rr)p`+V)+glrWe7ZAM=64Sp1nrm)jXf3%mdr{~fs_8d{1}2zJ2Mq(_U)fZ zO_itA0jK^1sWR4IL*=nk!~Say7i9lWy|-7RlT@}cm{9{y)x<&f>@J_LRA9q0^dD`n z_2M5$BfA$_mIVs+%Po5l-f2uVmU3Rl7WVW0dC_lBcaawaX|n`p6VDEtbYj^4D8gk> zfc=CFW*=+vJH(W-_U0go zT(4CFl86YO>CSqb8UZa1eY}nJ#O^Nu%djghrz z4}3R^=&bMC_r+DqAV#^#e7-EKA&?Yy^NUd^&)hhlM>a1bHpW?&D>RGEPhUjCEcZxw z$N>WoWx;B zD!fX)4@ldF43nWE$25x&zH>pBKEFAwczi?idC+Y#@GAQO7!L=rN}f^}lsq1!L|Z;R zs#S##0PF0w`$PsXKF-|O)>QL>HQ(^Kd>meX!&0n!O%|_-_nHa_rxecgz}?|}Es^Oo zO1FUt3q6Md`rMxT^TJ?&|Gw>QuPqGVV>mUN$eaVMmf?3f=W!Z9J+6g;&~q%73O9-t zve5)}ZNGZwfX~AxNR>%l3C?>gi%eo{mZQ-R2I;6Dob=?g;v4mI(J2@YV+DszPH-w~ ziS?w~Sl9e!)_6Qp`vATD{;HSVFj`QTzREa28;Cd~^ene-vDIZo`s;vtf}T1n5RQIxn%TD|W25k>fOJ zk%eZK!$tErOc>#?D(Xq()#iDAg)ej|k6ZqDU8t8qI#9yNcq)d$Ip7P$vrYRL-|oE4 z@&07kh7mm$tRVtUx@XqO_63M?HuTz!#?NzkehVa>e{988+w8o3KHZFAk6x!BLcZhX z$GJL4URAb|N-EOU$1#a_qwW91!2j;wP3-#f+V1)z`iSagxSkf+;XvVIBir4jjh{b4 z%dWSp?zk`E2-1QEq3Iol7fO(;#zMq&2B@)_{*l8h4W?I~tC^7w`PmO%tI8lCV3gmF znuMylKN^TNb-UT5gsd(&*CITaJ-AG#^l8^U5d%);d+zPCz-;3nHj4z znCkp^YXyX>%VVc5Fpg&rJ&*4DUe8E*n}T5cqbgLs*NQ!t0PwUP*NF}^D+)010^1P<%FMEC>Jw`>LDMtvf5 z`k~pXZXuajsZEtKD!i3eZ9<)I+^$tfoC8PB>Uqf?VTbXmf80KogdLV|0c{vrg$cOV z1y?f-9dzn{5E5pvCL{9_<{m=mIZB_GYNz*WiVEth+M^z4(-Pi7Fo_9)aUk?Ct)%ww zB+&>0h1mpI&>Bem$TCQ1VE#m)LVK_jF(9n4q5fkK5GY{&*-`$EFrvoF83zyCtKZp2 zbPc6=*$qb6U!J&v7~Mu`%wDcPd@-EyqFoVgKdE3Hn6r%PORB)qJDyr+2_bid$0~KI zJM{wWvEo>wt9jpEe#!B$h#0C=8wYkpYk96L(T6dre9<*?i`b;o>oPBC6lJmYhn5y^ zdEdfArBKOQX*c+&XcEU|7d{P!a;HM|i5_#1UrX7npMTnP-eQ8*h261USn%%$|A$Q- z0|Q-=m0KVrC#wm>_Ur>RoG`6_1mrfa_t35bKO z_wlVflQB&0Fj!(u4*a#jI5E1I)vd}yZ9iA>EFbMIYW=33Eka$*vCeE@O(~&xZ!}|s z=7VFfk&PdRjen5IiFppmU>l{m?#J2k)yYk@l39s#S_;=pmC2b(aZ+X%O(T57-PKeE z#MHdf46AH@zo1US>G_Uv-q#v%3*u94RArKIx(+e!SBKHEwm}OC8892kL{?qz4LD2+ z5zh6CMk!qqa|NHA#B$hoIjgKYMzN=epd9xzuFpguHv*pZwX>G=3xd-g@_O|A!8zL* zk*q{_wpJ(Ds6?HehKYoGU@^QZb~h(o$n|m|itt1hceyGOR}#ECc8oWCzisTL+|3%> zuCB`|%5D;*O=2!MR}kLm2MqXFJn3ABZ`kBb5Q#dXktq~m@yXLZCQ+JtP(>d5U3*IG z8+P`=h89h8S5Pz;ww3w3j$gi=KZ_5|wMAd& zTGg4R-QHud*}_)Nb;--`O?al8avc5>c=~&VM?oDJo?%z6@P0pXMABzs2ZcO7M7QWJ z-7kw)+Sq@8bsn2m=Axq|NPbQjhWULNp722^q3bxmwAC)isrQ3sQuItufS?{3Dun4& z1j=ZI{CTi{82iQh;39wqND-eO;r3AaEU<5ywHr zw*CMilE?AZ{^rB^vx)|R7whmi%4P^Lc>~}(9K`6A$rnP9%M0$i>Vbx|t?Zsb&yf3E zFXc+_t1vrPPrvT15ZQ>B!V%#)!u1^!ry|O?muz~U?Zrw^D>00{F@}AkUJZBw_h2Q_>K~i7u*)WaMz?&Nfs5CnveCw73KH2r^7P_z$@jgFbD#G?<4v``jj-it#Ohh5*y^DoyAC|=Lh6pf=j6L*V4>a11A z+WNojzSW9ZaK4xm{ZB@KHz{g^<59A)r-EP$fptGe6{DX$#aV6>%TLUeZu^Oi19BD7>Au15rOgziX3E|I95NHM_2Vcl-F+ zCnvfvfI|+ihW)xwNBoYmxz3I-}zOcZ;lvSd?$a?bC?PGLIwKN8Po z=t5yc+CGP@ZEF9Uj8T_kLw!e|F&SdzVEAM7r;kF6&gX4s_ljE{w(}rfiAd`YtC}fw z6n*b*Iv2ZExwiw}13nOb{|~SgB*lV>KCS5E$Y_3W*zcPi9>ZXpRl+x5v%1qQIMKIz z9K))O4>Ci_C&P8??tI7~`Tyvk`97T5wu8ns83xF{t1MN+p%x+hJ5x2J0BVV2Ezs~2 z8L+0r;sqCi-UyIGQJqpoA9^eK6x@Pz!y43ZW9zQic zv#S*zsKq8~V^W3M2*u2_fAE+eQs+?;>vx)27_{i2|NEc(frlDm_$)0W*fhRXZE3Jm z^~E6TM2BdYN4f0>E8eseMBay?S!qFuy4*LoStAF{UrZFc*nk}l9%>oy3g+A;2Dq)@zwD6}R9TT0hI=v0I`S-f~ z=imHB|59K!w|D&!YKivUE|{3P>mi5Znq>yxz~{s76oMe)FHL4_U%{1>*?Y=_VO_=> zKp9En#cu_x)i57_>41A8&4$-4}kCm>ndtU-$&?+4eqt|Fws4%RmqrEeF4Oip=bT*2EneG|PTX6bUo7(cWinNH0X5aCT=m@T zLbG#$%MCVo1_5L=*D5V-adP!zX+7Wky$c zMFohcO<*xvbM)MbBl-n(6Z+L*=ahk5AYiJ}HA1fOp0jQ-Y@g`w6*J~QXr@p#Y}q@# zv0}v^Sbhv>f2kjDCE#*|%=mb3yg#3mC2>cDfass^|Ng#a40iKkn?So$o;KhYk)AX2 z@N2-vz<;?gw+9RogCR+R7k|E-jaoS4*YbXzJ(XFcz47@2aN~BUU2P7$Q=wrrco@`X zG<5DKTw$O7O+*pDDAEWDdbbIJ4KgGWNh(`97M{o-vdC;rzCBTI5UCVyM{}S;bxYAN zPE{tJFmK4ecCK=1yKJx@-|x%2Aag%`Hi`Y5gnUEnF{G?;{JCfs8oL0=xy{gj?xb-^ zqu{c9OUi5Mrq%ep2&eVU@$JaALZz>6Ts9o0l^SjWF-(QGuEGQ{HsKVxQJT_BB9vjn1*%KBKs}nVN-|xDcK?*YNXGiNpk<}Rr z%EsVR{-Jh2keZIJzw=$EZlRW&cGRb{EtCU@Ujmk5 zKZIb057Pj{P+L;kb{^VvVcv?Eb~yamz4`>X-^s@6FYH3xs$(}-3IqWc&8LDJ{pzSAwnm-$k2dQn2k?Rs%y^G5|DNzi9Akr

qPI#w+#RTM70 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 EFBQf=O#lD@ literal 0 HcmV?d00001 diff --git a/trailmet/algorithms/quantize/assets/quantizer_flow.png b/trailmet/algorithms/quantize/assets/quantizer_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..f7d5f4db65e08b89e068fecd0f2555e3cc71ceb6 GIT binary patch literal 216903 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 Lfd*>7&AI;o{vu>S literal 0 HcmV?d00001 diff --git a/trailmet/algorithms/quantize/info.md b/trailmet/algorithms/quantize/info.md index fa1b19b..9fc278f 100644 --- a/trailmet/algorithms/quantize/info.md +++ b/trailmet/algorithms/quantize/info.md @@ -1,3 +1,5 @@ +![quantization](./assets/quantization_pipeline.png) + - The following quantization configuration schema has been adopted throughout all quantizable modules to ensure compatibility with `torch.ao.quantization`. - **qscheme**: enum[per_tensor_affine, per_tensor_symmetric, per_channel_affine, per_channel_symmetric] - **dtype**: enum[qint8, quint8, qint32] @@ -10,4 +12,6 @@ - current implementation for deployment (x86 cpu only) stores model weights in `int8`/`int32` along with scale (`float32`) and zero_point (`int64`), effectively reducing required memory space (by about a factor of 4 for layer-wise granularity, and slightly lower for channel-wise granularity). Activations are quantized to `uint8` based on scaling factors determined during calibration (static during inference). -- when using the `x86 backend`, we need to use 7 bits instead of 8 bits. Make sure you reduce the range for the `quant_min`, `quant_max`, ie. if dtype is `torch.quint8`, we need to set `quant_min` to be 0 and `quant_max` to be 127 (255 / 2) and if dtype is `torch.qint8`, make sure to set `quant_min` to be -64 (-128 / 2) and `quant_max` to be 63 (127 / 2). This functionality is implemented and can be enabled by setting the configuration argument `reduce_range` to True. However, no need for this in `qnnpack backend`. \ No newline at end of file +- when using the `x86 backend`, we need to use 7 bits instead of 8 bits. Make sure you reduce the range for the `quant_min`, `quant_max`, ie. if dtype is `torch.quint8`, we need to set `quant_min` to be 0 and `quant_max` to be 127 (255 / 2) and if dtype is `torch.qint8`, make sure to set `quant_min` to be -64 (-128 / 2) and `quant_max` to be 63 (127 / 2). This functionality is implemented and can be enabled by setting the configuration argument `reduce_range` to True. However, no need for this in `qnnpack backend`. + +![quantizer](./assets/quantizer_flow.png) From fb5b7981aea3a5820dcbe221eb19ddd64d9456be Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 2 Oct 2023 18:04:39 +0530 Subject: [PATCH 33/35] added observer methods --- trailmet/algorithms/quantize/_methods.py | 105 +++++++++++ trailmet/algorithms/quantize/observers.py | 217 ++++++++++++++++++++++ trailmet/algorithms/quantize/utils.py | 26 +++ 3 files changed, 348 insertions(+) create mode 100644 trailmet/algorithms/quantize/_methods.py create mode 100644 trailmet/algorithms/quantize/observers.py diff --git a/trailmet/algorithms/quantize/_methods.py b/trailmet/algorithms/quantize/_methods.py new file mode 100644 index 0000000..6c61b5f --- /dev/null +++ b/trailmet/algorithms/quantize/_methods.py @@ -0,0 +1,105 @@ +import torch +import torch.nn as nn +from typing import Dict, Callable +from trailmet.algorithms.quantize.observers import BaseObserver, MinMaxObserver, LpNormObserver +from trailmet.algorithms.quantize.utils import reshape_qparams_by_channel + + + +OBSERVER_MAPPING: Dict[str, Callable] = { + 'min_max': MinMaxObserver, + 'lp_norm': LpNormObserver +} + + +class RoundSTE(torch.autograd.Function): + """grad enabled round function""" + @staticmethod + def forward(ctx, input): + return torch.round(input) + + @staticmethod + def backward(ctx, grad_output): + return grad_output + + +class FloorSTE(torch.autograd.Function): + """grad enabled floor function""" + @staticmethod + def forward(ctx, input): + return torch.floor(input) + + @staticmethod + def backward(ctx, grad_output): + return grad_output + + +class BaseQuantizer(nn.Module): + def __init__(self, kwargs: dict): + self.observer: BaseObserver = OBSERVER_MAPPING[kwargs.get( + 'observer', 'min_max')](**kwargs) + self.quant_min = self.observer.quant_min + self.quant_max = self.observer.quant_max + self.per_channel = kwargs.get('per_channel', False) + self.ch_axis = kwargs.get('ch_axis', 0) + self.enable_observation = True + self.enable_quantization = True + + def __register_buffer__(self, name, value): + if hasattr(self, name): + delattr(self, name) + self.register_buffer(name, value) + + def __register_parameter__(self, name, value): + if hasattr(self, name): + delattr(self, name) + self.register_parameter(name, nn.Parameter(value)) + + def quantize(self, x: torch.Tensor, scale: torch.Tensor, zero_point: torch.Tensor, + round_mode: str = 'nearest'): + if self.per_channel: + scale, zero_point = reshape_qparams_by_channel( + x, scale, zero_point, self.ch_axis) + if round_mode == 'nearest': + x_int = RoundSTE.apply(x / scale) + elif round_mode == 'stochastic': + x_floor = FloorSTE.apply(x / scale) + x_int = x_floor + torch.bernoulli((x / scale) - x_floor) + else: + raise NotImplementedError + x_quant = torch.clamp(x_int + zero_point, self.quant_min, self.quant_max) + return x_quant + + def dequantize(self, x_quant: torch.Tensor, scale: torch.Tensor, zero_point: torch.Tensor): + x_dequant = (x_quant - zero_point) * scale + return x_dequant + + def reset_bitwidth(self, n_bits: int): + self.observer.reset_bitwidth(n_bits) + self.quant_min = self.observer.quant_min + self.quant_max = self.observer.quant_max + + +class UniformQuantizer(BaseQuantizer): + def __init__(self, kwargs: dict): + super().__init__(kwargs) + self.__register_buffer__('scale', torch.tensor([1.0], dtype=torch.float)) + self.__register_buffer__('zero_point', torch.tensor([0], dtype=torch.int)) + + def forward(self, x: torch.Tensor): + if self.enable_observation: + x = self.observer(x) + + if self.enable_quantization: + self.scale, self.zero_point = self.observer.calculate_qparams() + self.scale, self.zero_point = self.scale.to(x.device), self.zero_point.to(x.device) + x_quant = self.quantize(x, self.scale, self.zero_point) + x_dequant = self.dequantize(x_quant, self.scale, self.zero_point) + return x_dequant + + return x + + +class AdaRoundQuantizer(BaseQuantizer): + def __init__(self, kwargs: dict): + super().__init__(kwargs) \ No newline at end of file diff --git a/trailmet/algorithms/quantize/observers.py b/trailmet/algorithms/quantize/observers.py new file mode 100644 index 0000000..4a93213 --- /dev/null +++ b/trailmet/algorithms/quantize/observers.py @@ -0,0 +1,217 @@ +import torch +import torch.nn as nn +import scipy.optimize as optim +from trailmet.algorithms.quantize.utils import get_dtype, get_qscheme, \ + transform_and_flatten_tensor_by_channel, reshape_qparams_by_channel, \ + fake_quantize + +class BaseObserver(nn.Module): + def __init__(self, n_bits: int = 8, reduce_range: bool = True, unsigned: bool = False, + symmetric: bool = False, per_channel: bool = False): + super(BaseObserver, self).__init__() + self.n_bits = n_bits + assert 2 <= n_bits <= 32, "n_bits is outside allowed range [2, 32]" + + if reduce_range: + n_bits -= 1 + if unsigned: + self.quant_min = 0 + self.quant_max = (2 ** n_bits) - 1 + else: + self.quant_min = -(2 ** (n_bits - 1)) + self.quant_max = (2 ** (n_bits - 1)) - 1 + + self.reduce_range = reduce_range + self.unsigned = unsigned + self.symmetric = symmetric + self.per_channel = per_channel + + self.eps = torch.tensor(1e-8, dtype=torch.float32) + self.dtype = get_dtype(self.quant_min, self.quant_max, self.reduce_range) + self.qscheme = get_qscheme(self.per_channel, self.symmetric) + self.register_buffer("min_val", torch.tensor(float("inf"))) + self.register_buffer("max_val", torch.tensor(float("-inf"))) + if (unsigned and symmetric and per_channel and reduce_range): + raise NotImplementedError( + "cannot reduce range for per-channel-symmetric unsigned quantization" + ) + self.inited = False + + def reset_bitwidth(self, n_bits): + self.n_bits = n_bits + assert 2 <= n_bits <= 32, "n_bits is outside allowed range [2, 32]" + if self.reduce_range: + n_bits -= 1 + if self.unsigned: + self.quant_min = 0 + self.quant_max = (2 ** n_bits) - 1 + else: + self.quant_min = -(2 ** (n_bits - 1)) + self.quant_max = (2 ** (n_bits - 1)) - 1 + + def reset_min_max_vals(self): + self.min_val.copy_(torch.tensor(float("inf"))) + self.max_val.copy_(torch.tensor(float("-inf"))) + self.inited = False + + def forward(self, x: torch.Tensor): + # update min_val and max_val from x and make inited true + return x + + @torch.jit.export + def _calculate_qparams(self, min_val: torch.Tensor, max_val: torch.Tensor): + quant_min, quant_max = self.quant_min, self.quant_max + + min_val_neg = torch.min(min_val, torch.zeros_like(min_val)) + max_val_pos = torch.max(max_val, torch.zeros_like(max_val)) + + device = min_val.device + scale = torch.ones(min_val.size(), dtype=torch.float32, device=device) + zero_point = torch.zeros(min_val.size(), dtype=torch.int64, device=device) + + if self.symmetric: + abs_max_val = torch.max(-min_val_neg, max_val_pos) + scale = (2 * abs_max_val) / float(quant_max - quant_min) + scale = torch.max(scale, self.eps) + if self.unsigned: + zero_point = zero_point.new_full(zero_point.size(), (quant_min + quant_max) // 2) + else: + scale = (max_val_pos - min_val_neg) / float(quant_max - quant_min) + scale = torch.max(scale, self.eps) + zero_point = quant_min - torch.round(min_val_neg / scale).to(torch.int) + zero_point = torch.clamp(zero_point, quant_min, quant_max) + + # for scalar values, cast them to tensors of size 1 to keep the shape consistent + if len(scale.shape) == 0: + scale = torch.tensor([float(scale)], dtype=scale.dtype, device=device) + if len(zero_point.shape) == 0: + zero_point = torch.tensor([int(zero_point)], dtype=zero_point.dtype, device=device) + + return scale, zero_point + + @torch.jit.export + def calculate_qparams(self): + assert self.inited, "need to run observation atleast once" + return self._calculate_qparams(self.min_val, self.max_val) + + + +class MinMaxObserver(BaseObserver): + def __init__(self, n_bits: int = 8, reduce_range: bool = True, unsigned: bool = False, + symmetric: bool = False, per_channel: bool = False, ch_axis: int = 0, **kwargs): + super().__init__(n_bits, reduce_range, unsigned, symmetric, per_channel) + self.ch_axis = ch_axis + + def forward(self, x_orig: torch.Tensor): + if x_orig.numel() == 0: + return x_orig + # dtype must match because updates to buffers are done inplace + x = x_orig.clone().detach().to(self.min_val.dtype) + + if self.per_channel: + y = transform_and_flatten_tensor_by_channel(x, self.ch_axis) + min_val_cur, max_val_cur = torch.aminmax(y, dim=1) + else: + min_val_cur, max_val_cur = torch.aminmax(x) + + if not self.inited: + self.min_val = min_val_cur + self.max_val = max_val_cur + self.inited = True + else: + self.min_val = torch.min(self.min_val, min_val_cur) + self.max_val = torch.max(self.max_val, max_val_cur) + + return x_orig + + + +class LpNormObserver(BaseObserver): + def __init__(self, n_bits: int = 8, reduce_range: bool = True, unsigned: bool = False, + symmetric: bool = False, per_channel: bool = False, ch_axis: int = 0, + p_val: float = 2.4, num_iters: int = 1000, pos_dist: bool = False, **kwargs): + super().__init__(n_bits, reduce_range, unsigned, symmetric, per_channel) + self.pos_dist = pos_dist + self.ch_axis = ch_axis + self.num_iters = num_iters + self.p = p_val + + def lp_loss(self, pred: torch.Tensor, trgt: torch.Tensor, + p: float = 2.4, per_channel: bool = False): + err = (pred - trgt).abs().pow(p) + if per_channel: + err_ = transform_and_flatten_tensor_by_channel(err, self.ch_axis) + return err_.mean(1) + else: + return err.mean() + + def get_quant_loss_from_range(self, x, min_val, max_val): + scale, zero_point = self._calculate_qparams(min_val, max_val) + if self.per_channel: + scale, zero_point = reshape_qparams_by_channel(x, scale, zero_point, self.ch_axis) + x_q = fake_quantize(x, scale, zero_point, self.quant_min, self.quant_max) + loss = self.lp_loss(x_q, x, self.p, self.per_channel) + return loss + + def get_quant_loss_from_alpha(self, x, alpha, x_min, x_max): + min_val, max_val = x_min * alpha, x_max * alpha + scale, zero_point = self._calculate_qparams(min_val, max_val) + x_q = fake_quantize(x, scale, zero_point, self.quant_min, self.quant_max) + loss = self.lp_loss(x_q, x, self.p, False) + return loss.item() + + def perform_linear_1D_search(self, x: torch.Tensor): + pass + + def perform_fast_1D_search(self, x: torch.Tensor): + if self.per_channel: + alphas = [] + x_ = transform_and_flatten_tensor_by_channel(x, self.ch_axis) + x_min, x_max = torch.aminmax(x_, dim=1) + if self.pos_dist: + x_min = torch.zeros_like(x_min) + + for ch in range(len(x_)): + x_ch = x_[ch] + ch_min, ch_max = x_min[ch], x_max[ch] + optim_alpha = optim.minimize_scalar( + lambda alpha: self.get_quant_loss_from_alpha(x_ch, alpha, ch_min, ch_max), + bounds=(0.2, 1.0)).x + alphas.append(optim_alpha) + + alphas = torch.tensor(alphas, dtype=torch.float32, device=x.device) + min_val, max_val = x_min * alphas, x_max * alphas + + else: + x_min, x_max = torch.aminmax(x) + if self.pos_dist: + x_min = torch.zeros_like(x_min) + optim_alpha = optim.minimize_scalar( + lambda alpha: self.get_quant_loss_from_alpha(x, alpha, x_min, x_max), + bounds=(0.2, 1.0)).x + min_val, max_val = x_min * optim_alpha, x_max * optim_alpha + + return min_val, max_val + + + def forward(self, x_orig: torch.Tensor): + if x_orig.numel() == 0: + return x_orig + x = x_orig.clone().detach().to(self.min_val.dtype) + + if self.symmetric or self.pos_dist: + min_val_cur, max_val_cur = self.perform_fast_1D_search(x) + else: + raise NotImplementedError + + if not self.inited: + self.min_val = min_val_cur + self.max_val = max_val_cur + self.inited = True + else: + self.min_val = torch.min(self.min_val, min_val_cur) + self.max_val = torch.max(self.max_val, max_val_cur) + + return x_orig + + diff --git a/trailmet/algorithms/quantize/utils.py b/trailmet/algorithms/quantize/utils.py index bdcc57f..a82e694 100644 --- a/trailmet/algorithms/quantize/utils.py +++ b/trailmet/algorithms/quantize/utils.py @@ -59,6 +59,32 @@ def get_dtype(quant_min: int, quant_max: int, reduce_range: bool = True): else: return torch.qint32 +def round_ste(x: torch.Tensor): + return (x.round() - x).detach() + x + +def fake_quantize(x: torch.Tensor, scale: torch.Tensor, zero_point: torch.Tensor, + quant_min: int, quant_max: int): + x_int = round_ste(x / scale) + zero_point + x_quant = torch.clamp(x_int, quant_min, quant_max) + x_dequant = (x_quant - zero_point) * scale + return x_dequant + +def reshape_qparams_by_channel(x: torch.Tensor, scale: torch.Tensor, + zero_point: torch.Tensor, ch_axis: int): + new_shape = [1] * len(x.shape) + new_shape[ch_axis] = x.shape[ch_axis] + scale = scale.reshape(new_shape) + zero_point = zero_point.reshape(new_shape) + return scale, zero_point + +def transform_and_flatten_tensor_by_channel(x: torch.Tensor, ch_axis: int): + new_axis_list = list(range(len(x.shape))) + new_axis_list[ch_axis] = 0 + new_axis_list[0] = ch_axis + x_tran = x.permute(new_axis_list) + x_flat = torch.flatten(x_tran, start_dim=1) + return x_flat + def replace_activation_with_identity(module: torch.nn.Module, activations: list) -> None: reassign = dict() for name, child_module in module.named_children(): From e76018280cd4c2d9c8be008212475f13784033f5 Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 2 Oct 2023 18:05:07 +0530 Subject: [PATCH 34/35] refactoring for observer approach --- trailmet/algorithms/quantize/lapq.py | 60 ++++---- trailmet/algorithms/quantize/modules.py | 179 ++++++++++------------- trailmet/algorithms/quantize/quantize.py | 128 ++++++++-------- 3 files changed, 179 insertions(+), 188 deletions(-) diff --git a/trailmet/algorithms/quantize/lapq.py b/trailmet/algorithms/quantize/lapq.py index 3f9610c..4d13752 100644 --- a/trailmet/algorithms/quantize/lapq.py +++ b/trailmet/algorithms/quantize/lapq.py @@ -100,30 +100,43 @@ def compress_model(self, model: nn.Module, inplace: bool = False, 'n_bits': self.w_bits, 'reduce_range': self.reduce_range, 'unsigned': False, - 'p_val': 2.0, - 'method': UniformSymmetricQuantizer, + 'symmetric': True, + 'per_channel': False, + 'quantizer': 'uniform', + 'observer': 'min_max' } act_quant_params = { 'n_bits': self.a_bits, 'reduce_range': self.reduce_range, 'unsigned': True, - 'p_val': 2.0, - 'method': UniformSymmetricQuantizer, + 'symmetric': False, + 'quantizer': 'uniform', + 'observer': 'min_max' } if test_before_calibration: - acc1, acc5 = self.test(model, self.test_data, device=self.device, progress=True) + qmodel = QuantModel(model, weight_quant_params, act_quant_params) + qmodel.set_quantization_state(False, False) + acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Full Precision Model: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) - qmodel = QuantModel(model, weight_quant_params, act_quant_params) - qmodel.set_quant_state(True, True) + qmodel.set_quantization_state(True, True) + _ = self.evaluate_loss(qmodel, self.calib_data, self.device) + qmodel.set_observation_state(False, False) acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Quantization accuracy before LAPQ: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) del qmodel - weight_quant_params['method'] = LpNormQuantizer - act_quant_params['method'] = LpNormQuantizer + weight_quant_params.update({ + 'observer': 'lp_norm', + 'p_val': self.p_val, + }) + act_quant_params.update({ + 'observer': 'lp_norm', + 'p_val': self.p_val, + 'pos_dist': True, + }) if self.p_val is None: p_vals = np.linspace(2,3.9,20) @@ -133,31 +146,25 @@ def compress_model(self, model: nn.Module, inplace: bool = False, weight_quant_params['p_val'] = p act_quant_params['p_val'] = p qmodel = QuantModel(model, weight_quant_params, act_quant_params) - qmodel.set_quant_state(True, True) + qmodel.set_quantization_state(True, True) loss = self.evaluate_loss(qmodel, self.calib_data, self.device) losses.append(loss) pbar.set_postfix(p_val=p, loss=loss) del qmodel - # using quadratic interpolation to approximate the optimal quantization step size ∆p∗ + # using quadratic interpolation to approximate the optimal ∆p∗ z = np.polyfit(p_vals, losses, 2) y = np.poly1d(z) - p_intr = y.deriv().roots[0] - min_loss = min(losses) - else: - weight_quant_params['p_val'] = self.p_val - act_quant_params['p_val'] = self.p_val - qmodel = QuantModel(model, weight_quant_params, act_quant_params) - qmodel.set_quant_state(True, True) - p_intr = self.p_val - min_loss = self.evaluate_loss(qmodel, self.calib_data, self.device) - del qmodel + self.p_val = y.deriv().roots[0] - if self.verbose: - print("==> using p-val : {:.3f} with lp-loss : {:.3f}".format(p_intr, min_loss)) - weight_quant_params['p_val'] = p_intr - act_quant_params['p_val'] = p_intr + weight_quant_params['p_val'] = self.p_val + act_quant_params['p_val'] = self.p_val qmodel = QuantModel(model, weight_quant_params, act_quant_params, inplace=inplace) - qmodel.set_quant_state(weight_quant=True, act_quant=True) + qmodel.set_quantization_state(True, True) + min_loss = self.evaluate_loss(qmodel, self.calib_data, self.device) + if self.verbose: + print("==> using p-val : {:.3f} with lp-loss : {:.3f}".format(self.p_val, min_loss)) + + qmodel.set_observation_state(False, False) acc1, acc5 = self.test(qmodel, self.test_data, device=self.device, progress=True) if self.verbose: print('==> Quantization accuracy before optimization: acc@1 {:.3f} | acc@5 {:.3f}'.format(acc1, acc5)) @@ -205,6 +212,7 @@ def local_search_callback(x): return quantized_model + def evaluate_calibration(self, alphas: np.ndarray, qmodel: QuantModel): qmodel.set_alphas_np(alphas) loss = self.evaluate_loss(qmodel, self.calib_data, self.device) diff --git a/trailmet/algorithms/quantize/modules.py b/trailmet/algorithms/quantize/modules.py index bc864f7..9ab23f5 100644 --- a/trailmet/algorithms/quantize/modules.py +++ b/trailmet/algorithms/quantize/modules.py @@ -23,10 +23,11 @@ import torch import torch.nn as nn import torch.nn.functional as F -from typing import Union +from typing import Union, Dict, Callable from trailmet.models.resnet import BasicBlock, Bottleneck from trailmet.models.mobilenet import InvertedResidual from trailmet.algorithms.quantize.methods import UniformAffineQuantizer, ActQuantizer +from trailmet.algorithms.quantize._methods import BaseQuantizer, UniformQuantizer, AdaRoundQuantizer from trailmet.algorithms.quantize.utils import get_qscheme, get_dtype from torch.ao.quantization import QConfig, FixedQParamsObserver import torch.ao.nn.quantized as nnq @@ -45,6 +46,10 @@ 'QInvertedResidual', ] +QUANTIZER_MAPPING: Dict[str, Callable] = { + 'uniform': UniformQuantizer, + 'adaround': AdaRoundQuantizer +} class StraightThrough(nn.Module): """ Identity Layer, same as torch.nn.modules.linear.Identity @@ -59,25 +64,22 @@ class QuantModule(nn.Module): """ Wrapper Module to simulate fake quantization """ - def __init__(self, - orig_module: Union[nni.ConvReLU2d, nn.Conv2d, nn.Linear], - weight_qparams: dict, act_qparams: dict, - ) -> None: + def __init__(self, orig_module: nn.Module, weight_qparams: dict, act_qparams: dict): super().__init__() self.orig_module = orig_module - if isinstance(orig_module, nni.modules.fused._FusedModule): + if isinstance(orig_module, (nni.ConvReLU2d, nni.LinearReLU)): assert len(orig_module)==2 if type(orig_module[0]) == nn.Conv2d: + self.fwd_func = F.conv2d self.fwd_kwargs = dict( stride = orig_module[0].stride, padding = orig_module[0].padding, dilation = orig_module[0].dilation, groups = orig_module[0].groups ) - self.fwd_func = F.conv2d - elif type(orig_module[1]) == nn.Linear: - self.fwd_kwargs = dict() + elif type(orig_module[0]) == nn.Linear: self.fwd_func = F.linear + self.fwd_kwargs = dict() else: raise NotImplementedError @@ -90,34 +92,36 @@ def __init__(self, self.orig_weight = orig_module[0].weight.data.clone() self.bias = orig_module[0].bias - if isinstance(orig_module, (nn.Conv2d, nn.Linear)): + elif isinstance(orig_module, (nn.Conv2d, nn.Linear)): if type(orig_module) == nn.Conv2d: + self.fwd_func = F.conv2d self.fwd_kwargs = dict( stride = orig_module.stride, padding = orig_module.padding, dilation = orig_module.dilation, groups = orig_module.groups ) - self.fwd_func = F.conv2d elif type(orig_module) == nn.Linear: - self.fwd_kwargs = dict() self.fwd_func = F.linear + self.fwd_kwargs = dict() else: raise NotImplementedError self.fwd_post = self.identity - self.weight = orig_module.weight self.orig_weight = orig_module.weight.data.clone() self.bias = orig_module.bias - self.use_weight_quant = False - self.use_act_quant = False - self.weight_quantizer = weight_qparams.get( - 'method', UniformAffineQuantizer)(**weight_qparams) - self.act_quantizer = act_qparams.get( - 'method', UniformAffineQuantizer)(**act_qparams) + else: + raise NotImplementedError + + self.weight_quantizer: BaseQuantizer = QUANTIZER_MAPPING[weight_qparams.get( + 'quantizer', 'uniform')](weight_qparams) + self.act_quantizer: BaseQuantizer = QUANTIZER_MAPPING[act_qparams.get( + 'quantizer', 'uniform')](act_qparams) + self.use_act_quant = False + self.use_weight_quant = False self.ignore_reconstruction = False self.extra_repr = orig_module.extra_repr @@ -139,79 +143,66 @@ def forward(self, input: torch.Tensor): def identity(self, x: torch.Tensor): return x + def set_observation_state(self, weight_obs: bool, act_obs: bool): + self.weight_quantizer.enable_observation = weight_obs + self.act_quantizer.enable_observation = act_obs + + def set_quantization_state(self, weight_quant: bool, act_quant: bool): + self.use_weight_quant = weight_quant + self.use_act_quant = act_quant - def set_quantization_state(self, weight: bool = False, act: bool = False): - self.use_weight_quant = weight - self.use_act_quant = act - - - def get_quantization_params_config(self): - fixed_qparams_config = dict() - for type in ["weight", "act"]: - qparams = eval(f"self.{type}_quantizer.get_qparams()") - fixed_qparams_config[type] = FixedQParamsObserver.with_args( - qscheme = get_qscheme( - per_channel = qparams['channel_wise'], - symmetric = qparams['symmetric'] - ), - dtype = get_dtype( - quant_min = qparams['quant_min'], - quant_max = qparams['quant_max'], - reduce_range = qparams['reduce_range'] - ), - quant_min = qparams['quant_min'], - quant_max = qparams['quant_max'], - scale = qparams['scale'], - zero_point = qparams['zero_point'] - ) - return fixed_qparams_config - class BaseQuantBlock(nn.Module): - def __init__(self, act_qparams: dict = {}) -> None: + def __init__(self, act_qparams: dict) -> None: super().__init__() + self.act_quantizer: BaseQuantizer = QUANTIZER_MAPPING[act_qparams.get( + 'quantizer', 'uniform')](act_qparams) self.use_act_quant = False - self.act_quantizer = act_qparams.get( - 'method', UniformAffineQuantizer)(**act_qparams) self._fake_quantization = True self.ignore_reconstruction = False + def set_observation_state(self, weight_obs: bool, act_obs: bool): + self.act_quantizer.enable_observation = act_obs + for module in self.modules(): + if isinstance(module, QuantModule): + module.set_observation_state(weight_obs, act_obs) - def set_quantization_state(self, weight: bool = False, act: bool = False): - self.use_act_quant = act + def set_quantization_state(self, weight_quant: bool, act_quant: bool): + self.use_act_quant = act_quant for module in self.modules(): if isinstance(module, QuantModule): - module.set_quantization_state(weight, act) + module.set_quantization_state(weight_quant, act_quant) - def convert_to_quantizable_with_config(self, module: nn.Module): + def _convert_to_quantizable_with_qconfig(self, module: nn.Module): self._fake_quantization = False - module_qparams = dict() + module_attach = dict() module_reassign = dict() - for name, child_module in module.named_modules(): - if isinstance(child_module, QuantModule): - module_qparams[name] = child_module.get_quantization_params_config() - module_reassign[name] = child_module.orig_module - for name, orig_module in module_reassign.items(): #TODO: test it out + + for name, submodule in module.named_modules(): + if isinstance(submodule, QuantModule): + module_attach[name]['weight'] = submodule.weight_quantizer.observer + module_attach[name]['activation'] = submodule.act_quantizer.observer + module_reassign[name] = submodule.orig_module + + for name, orig_module in module_reassign.items(): delattr(module, name) setattr(module, name, orig_module) - self._attach_qconfig_to_quantizable(module, module_qparams) - - - def _attach_qconfig_to_quantizable(self, module: nn.Module, module_qparams: dict): - for name, qparams in module_qparams.items(): + + for name, observers in module_attach.items(): submodule = getattr(module, name, None) assert submodule is not None - if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig - setattr(submodule[0], "qconfig", QConfig( - weight = qparams["weight"], - activation = None)) - setattr(submodule, "qconfig", QConfig( - weight = qparams["weight"], - activation = qparams["act"] + if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig + setattr(submodule[0], 'qconfig', QConfig( + weight = observers['weight'], + activation = None + )) + setattr(submodule, 'qconfig', QConfig( + weight = observers['weight'], + activation = observers['activation'] )) - submodule.add_module("activation_post_process", submodule.qconfig.activation()) + submodule.add_module('activation_post_process', submodule.qconfig.activation()) @@ -238,22 +229,13 @@ def forward(self, inp: torch.Tensor) -> torch.Tensor: return out - def convert_to_quantizable_with_config(self): - super().convert_to_quantizable_with_config(self) - self._fake_quantization = False - act_qparams = self.act_quantizer.get_qparams() - self.add_skip.qconfig = QConfig( - weight=None, - activation = FixedQParamsObserver.with_args( - qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), - dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max'], act_qparams['reduce_range']), - quant_min = act_qparams['quant_min'], - quant_max = act_qparams['quant_max'], - scale = act_qparams['scale'], - zero_point = act_qparams['zero_point'] - ) - ) - self.add_skip.add_module("activation_post_process", + def _convert_to_quantizable_with_qconfig(self): + super()._convert_to_quantizable_with_qconfig(self) + setattr(self.add_skip, 'qconfig', QConfig( + weight = None, + activation = self.act_quantizer.observer + )) + self.add_skip.add_module('activation_post_process', self.add_skip.qconfig.activation()) @@ -283,22 +265,13 @@ def forward(self, inp: torch.Tensor) -> torch.Tensor: return out - def convert_to_quantizable_with_config(self): - super().convert_to_quantizable_with_config(self) - self._fake_quantization = False - act_qparams = self.act_quantizer.get_qparams() - self.add_skip.qconfig = QConfig( - weight=None, - activation = FixedQParamsObserver.with_args( - qscheme = get_qscheme(act_qparams['channel_wise'], act_qparams['symmetric']), - dtype = get_dtype(act_qparams['quant_min'], act_qparams['quant_max'], act_qparams['reduce_range']), - quant_min = act_qparams['quant_min'], - quant_max = act_qparams['quant_max'], - scale = act_qparams['scale'], - zero_point = act_qparams['zero_point'] - ) - ) - self.add_skip.add_module("activation_post_process", + def _convert_to_quantizable_with_qconfig(self): + super()._convert_to_quantizable_with_qconfig(self) + setattr(self.add_skip, 'qconfig', QConfig( + weight = None, + activation = self.act_quantizer.observer + )) + self.add_skip.add_module('activation_post_process', self.add_skip.qconfig.activation()) diff --git a/trailmet/algorithms/quantize/quantize.py b/trailmet/algorithms/quantize/quantize.py index 3256555..876aa55 100644 --- a/trailmet/algorithms/quantize/quantize.py +++ b/trailmet/algorithms/quantize/quantize.py @@ -36,6 +36,7 @@ get_qscheme, get_dtype, quantized_forward from trailmet.algorithms.quantize.modules import StraightThrough, QuantModule, \ BaseQuantBlock, QuantBasicBlock, QuantBottleneck, QuantInvertedResidual +from trailmet.algorithms.quantize._methods import BaseQuantizer, UniformQuantizer from trailmet.algorithms.algorithms import BaseAlgorithm from torch.nn.utils.parametrize import type_before_parametrizations as _type from torch.ao.nn.intrinsic.modules.fused import _FusedModule @@ -52,7 +53,7 @@ 'GetLayerGrad' ] -FLOAT_TO_FAKE_QUANT_MAPPING: Dict[Callable, Callable] = { +FAKE_QUANT_MAPPING: Dict[Callable, Callable] = { nn.Conv2d : QuantModule, nn.Linear : QuantModule, nni.ConvReLU2d : QuantModule, @@ -61,14 +62,12 @@ InvertedResidual : QuantInvertedResidual } -FLOAT_TO_TRUE_QUANT_MAPPING: Dict[Callable, Callable] = { +TRUE_QUANT_MAPPING: Dict[Callable, Callable] = { QuantStub : nnq.Quantize, DeQuantStub : nnq.DeQuantize, nn.Conv2d : nnq.Conv2d, nn.Linear : nnq.Linear, - # Intrinsic modules: nni.ConvReLU2d : nniq.ConvReLU2d, - # Wrapper Modules: nnq.FloatFunctional : nnq.QFunctional } @@ -99,11 +98,12 @@ def convert_model_to_fake_quantized(self, fuse_model=True): else: replace_activation_with_identity(self.model, [nn.ReLU, nn.ReLU6]) self.add_fused_conv_bn_act(self.model) - self.input_quantizer = self.act_quant_params.get('method')(**self.act_quant_params) - setattr(self.model, 'inp_quant', self.input_quantizer) + + self.input_quantizer: BaseQuantizer = self.act_quant_params.get( + 'method', UniformQuantizer)(self.act_quant_params) + self.model.inp_quant = self.input_quantizer self._quant_module_refactor(self.model) self.model.forward = quantized_forward.__get__(self.model, nn.Module) #TODO check functionality - self.quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] def add_fused_conv_bn_act(self, model: nn.Module): # same functionality as torchvision.models.quantization.resnet.QuantizableResNet.fuse_model @@ -141,8 +141,8 @@ def _quant_module_refactor(self, module: nn.Module): and activations quantization. """ for name, child_module in module.named_children(): - if type(child_module) in FLOAT_TO_FAKE_QUANT_MAPPING: - setattr(module, name, FLOAT_TO_FAKE_QUANT_MAPPING[type(child_module)]( + if type(child_module) in FAKE_QUANT_MAPPING: + setattr(module, name, FAKE_QUANT_MAPPING[type(child_module)]( child_module, self.weight_quant_params, self.act_quant_params )) elif isinstance(child_module, (StraightThrough, nn.Identity, nn.ReLU)): @@ -154,23 +154,16 @@ def convert_model_to_quantized(self, inplace=True, remove_qconfig=True): model = self.model if not inplace: model = copy.deepcopy(model) + model.to(torch.device('cpu')) - inp_qparams = self.input_quantizer.get_qparams() - model.inp_quant = QuantStub(qconfig=QConfig( - weight = None, - activation = FixedQParamsObserver.with_args( - qscheme = get_qscheme(inp_qparams['channel_wise'], inp_qparams['symmetric']), - dtype = get_dtype(inp_qparams['quant_min'], inp_qparams['quant_max'], inp_qparams['reduce_range']), - quant_min = inp_qparams['quant_min'], - quant_max = inp_qparams['quant_max'], - scale = inp_qparams['scale'], - zero_point = inp_qparams['zero_point'] - ) - )) - model.inp_quant.add_module("activation_post_process", model.inp_quant.qconfig.activation()) + model.inp_quant = QuantStub(qconfig=QConfig(weight = None, + activation = self.input_quantizer.observer)) + model.inp_quant.add_module('activation_post_process', + model.inp_quant.qconfig.activation()) model.out_dequant = DeQuantStub() + self._attach_qconfig_to_quantizable(model) - model = self._convert_quantizable(model, FLOAT_TO_TRUE_QUANT_MAPPING, inplace) + model = self._convert_quantizable(model, TRUE_QUANT_MAPPING, inplace) if remove_qconfig: self._remove_qconfig_from_quantizable(model) return model @@ -185,52 +178,47 @@ def _convert_quantizable(self, module: nn.Module, mapping: dict, inplace = True) if type(child_module) in mapping: reassign[name] = self._swap_module(child_module, mapping) for name, quantized_module in reassign.items(): - # module._modules[name] = quantized_module delattr(module, name) setattr(module, name, quantized_module) - # print(f"***{name}: {quantized_module}") - # print(eval(f"{module}.{name}")) return module def _attach_qconfig_to_quantizable(self, module: nn.Module): - module_qconfig = dict() + module_attach = dict() module_reassign = dict() + for name, child_module in module.named_children(): if isinstance(child_module, QuantModule): - module_qconfig[name] = child_module.get_quantization_params_config() + module_attach[name]['weight'] = child_module.weight_quantizer.observer + module_attach[name]['activation'] = child_module.act_quantizer.observer module_reassign[name] = child_module.orig_module - # setattr(module, name, child_module.orig_module) - # child_module.qconfig = QConfig( - # weight = qparams_config['weight'], - # activation = qparams_config['act'] - # ) - # child_module.add_module( - # 'activation_post_process', - # child_module.qconfig.activation() - # ) - elif isinstance(child_module, BaseQuantBlock): - child_module.convert_to_quantizable_with_config() + if isinstance(child_module, BaseQuantBlock): + child_module._convert_to_quantizable_with_qconfig() else: self._attach_qconfig_to_quantizable(child_module) - for name in module_reassign.keys(): + + for name, orig_module in module_reassign.items(): delattr(module, name) - setattr(module, name, module_reassign[name]) - submodule = getattr(module, name) - if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig - setattr(submodule[0], "qconfig", QConfig( - weight = module_qconfig[name]["weight"], - activation = None)) - setattr(submodule, "qconfig", QConfig( - weight = module_qconfig[name]["weight"], - activation = module_qconfig[name]["act"] + setattr(module, name, orig_module) + + for name, observers in module_attach.items(): + submodule = getattr(module, name, None) + assert submodule is not None + if isinstance(submodule, nni.ConvReLU2d): # propagate qconfig + setattr(submodule[0], 'qconfig', QConfig( + weight = observers['weight'], + activation = None + )) + setattr(submodule, 'qconfig', QConfig( + weight = observers['weight'], + activation = observers['activation'] )) - submodule.add_module("activation_post_process", submodule.qconfig.activation()) - + submodule.add_module('activation_post_process', submodule.qconfig.activation()) + def _remove_qconfig_from_quantizable(self, module: nn.Module): for child_module in module.children(): self._remove_qconfig_from_quantizable(child_module) - # if hasattr(module, 'activation_post_process'): - # delattr(module, 'activation_post_process') + if hasattr(module, 'activation_post_process'): + delattr(module, 'activation_post_process') if hasattr(module, 'qconfig'): delattr(module, 'qconfig') @@ -242,13 +230,32 @@ def _swap_module(self, module: nn.Module, mapping: dict): if _type(module) in mapping: qmod = mapping[_type(module)] new_module = qmod.from_float(module) - # print(f"swapped {type(module)}: {type(new_module)}") swapped = True + # print(f">> swapped {type(module)}: {type(new_module)}") if swapped: pass #TODO: hook management return new_module - def set_quant_state(self, weight_quant: bool = True, act_quant: bool = True): + def get_weight_quantizers(self): + weight_quantizers = [] + for module in self.model.modules(): + if isinstance(module, (QuantModule, BaseQuantBlock)): + weight_quantizers.append(module.weight_quantizer) + return weight_quantizers + + def get_act_quantizers(self): + act_quantizers = [] + for module in self.model.modules(): + if isinstance(module, (QuantModule, BaseQuantBlock)): + act_quantizers.append(module.act_quantizer) + return act_quantizers + + def set_observation_state(self, weight_obs: bool = True, act_obs: bool = True): + for module in self.model.modules(): + if isinstance(module, (QuantModule, BaseQuantBlock)): + module.set_observation_state(weight_obs, act_obs) + + def set_quantization_state(self, weight_quant: bool = True, act_quant: bool = True): """ :param weight_quant: set True to enable weight quantization :param act_quant: set True to enable activation quantization @@ -262,6 +269,7 @@ def quantize_model_till(self, layer, act_quant: bool = False): :param layer: layer upto which model is to be quantized. :param act_quant: set True for activation quantization """ + # TODO self.set_quant_state(False, False) for name, module in self.model.named_modules(): if isinstance(module, (QuantModule, BaseQuantBlock)): @@ -274,11 +282,13 @@ def set_layer_precision(self, weight_bits: list, act_bit: int): :param weight_bits: list of bitwidths for layer weights :param act_bit: bitwidth for activations """ - assert len(weight_bits)==len(self.quant_modules) - for idx, module in enumerate(self.quant_modules): - module.weight_quantizer.bitwidth_refactor(weight_bits[idx]) + # TODO + quant_modules = [m for m in self.model.modules() if isinstance(m, QuantModule)] + assert len(weight_bits)==len(quant_modules) + for idx, module in enumerate(quant_modules): + module.weight_quantizer.reset_bitwidth(weight_bits[idx]) if module is not self.quant_modules[-1]: - module.act_quantizer.bitwidth_refactor(act_bit) + module.act_quantizer.reset_bitwidth(act_bit) def search_fold_conv_bn(self, module: nn.Module): """ From 77ff4e8808f598c9992c15e53fb0d74c4c5c265f Mon Sep 17 00:00:00 2001 From: sydarb Date: Mon, 2 Oct 2023 18:17:26 +0530 Subject: [PATCH 35/35] modified diagram --- .../quantize/assets/quantizer_flow.png | Bin 216903 -> 232661 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/trailmet/algorithms/quantize/assets/quantizer_flow.png b/trailmet/algorithms/quantize/assets/quantizer_flow.png index f7d5f4db65e08b89e068fecd0f2555e3cc71ceb6..724d6e26a5d863e81916faf44ae344a84db261ad 100644 GIT binary patch literal 232661 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

9Z^jQaXb}Za(B(~U?LPX=mC<>~ z20DQHGW&nG{tUPQnogys0i?gbR#8MP=%@6BQV}6;;`Kpo2bH9x>X_hHr5poP_h-UY z+0e`S_bHMcPQs&IbX)>?b+Go^+yK9i)&RQn9lQ2Rq=Jlv#ndZOs4>I0vx?ZkJo()3 zStdhkAx_!nPscnEauo$`JqZt6NS)*+^+=dpBkasZm}WXD0JECyA#BB55h&5ysZ&N| zthHP5sb0=~CLsoN*qg}*mFht@_z(*~hpl|KMTB%DV4q)^4AxHRwRTg|c=re$qd6Ze zt=t7HsK?*FS71;ai@^i&*K=)3SML#9iC;oT2fJ3X$Cm9=)vl-gy)hC`?E5)yi(=Th|J7KX+uSRO3H#A(tk~Q4|albX+{!wK)%L^f-mL((J zskrP+#k3<%zI@^9l|I7;yq<=|q_8Vl!Hn`u^*BF&o!$9&VOw$h2JVtOa5+@F@z4zC z{Xk>C9o_@+WM(NK4Ge3JQnbVeTOZ3tJh{wrAU5({`a|UV4@l0 zsha=SL{U&P+|vz^Ebz8=zNY|zhoQo4uoyI zUK#vaX_xj8@3LYbhQt|+wnq%56fbT*^StutAgTF`TJ5+>ORuT+w%?$tyf2^HLKmqL z!8Zl3)W$M+eXFbeom5R4{4v*j=W>JFbLB#HCNE*Ti7Kaytp^I(O;k-$2j*Pj(Wlko z15aD*SX+V|u^|qGy)Zh6(3-P@&NnTf9N(zY*Zb!lQ&e+r8OXMt-_*jtCubpiD^E4O zy0*%>YPu1>i-Os*NrF$*bo#A%XL;AaG2hEPaEI6gM+YGOCbqZ8>-&%FQ0sh58MqWV zf*vPD?|!`nHITUw5!4BYBcIq`RhY-^r>h;U1sToQMAqzmDFk>AX>-qZJ?g_(-8Fa+ z_K9!H+aPj8#J|mHXC4ykblmFCiMdNb^JGDq_U5JMgi+YRTe{wU%DYP?FY2%q`9??` zM+Hvl_E7SZDF!+?#NGHDHgjLb`cBx{?O*#YQ(vVpn4^NQWKl+AY?7|Wm$)}Rjap;p z1_8|HHhodX8tK?g6c^<00CMK|6nUm26XljA6B9N%{IU%WRIG$w6uHOpWJ);`8myS| z?B!L@umH2S#c`wqh)UxJT7D+qpaP?OvN6pj&%?%sxVh}@#iN(6#i^L1uTnB*LWZ9Q z`M#jJ+H3%zJ_0=SzMLo;%vWzcB`L#*vfQtZJ{gTwP*`^{u&0H4%&KF*Vgy^@i@g>a z!;PU$H|4vc(Mk2|zxBniv-PYQ=nTCw{@kwuSglV17obFKWEsdBfBM7T^vQfq4A%{= z5STTvW;XHhzh1|mJ4ZcJ7t4;=Bo=$#5;4yIObyig^q?Q=G|zF(@+7`*H2l?z0zcQ-?q`~+okvb$#FY%8Jt=;V0+lXaD{7Ki7oIzO_Y`@9e;Hz957h&=i%(k zaupdF?v&ql1ee|wo`MEFvR*w{U$D*}pS-)bO?FkagGGI5B+uX6@-!Ovrd{TNsUSV^ z)iwPBKq~s?UG|%+zY{2X3v6Xd(}xEJx|dk%uG*0l94Pch#Ws;90JCgqBJZ5~w;w=) zng=pyrW}is!MyGWJ6DeX?t2RCUHwB$;hDN1 z59ZsJBUK_aLskseMomHSE=!FwA>ZGf&6m%uQ26@O+$V;=4;TM> z|H+;=HVl)wohNVtg z13rVAm*Pt$QXlbwKAM`FyCW}UMjWoUNQPHXLj3!5poibTm;jA00r2Xc6pN=h!NQ+P z1sy78I_*X+*x2xXu(}zo_n#>;6g)`Hq13T!}Z%~4HvmJAAMx-^ZS*^Pjbz=ToI6q3Ok($jMz{c`r$7NZqN+A_m(?&wZR-Flm1jU5o24I z2gc(WAcg8)d|JUr9{6vvK^jPsMWOq~53ZiNFQ&ROw-{))(trf{^HqBHgS_9i`pTPm zdcc7wp@4xB^sx3D?wVd%qu*V4TH0gI1bdb9lV+5$67x^f6rsTWB)rt(I;8OAGp2&r zC7$c5vPj6`7oi5+^bGLg+;c%SHZeawUJQ9X9BXT6OMMYvI0vK#bE~r=bKJVBH$y5c zrp@Z@Eb;Cv_vQOexc?^aPcz1Wy!UuI2e?mH2M@mtcnE=TFiiRKgKgSgL{ln=rYCr@ zJFTHmxtf;6U!HG}=Fdb`1W-#bHg$UP(}TB6wn`*da{*pLxTrgUfbGdH0`D*1q_3i{ z!3|^Jg`pP1aX0XBJ|S>-O_VB#sp}eCJUK~~iu;%$;B1h35YOS64m2@sX zbTbcW`pbK?`+Amv8gPE}&rO@TPZ|bK3GmcQK17dyTc$yr@QI>_$^PMdczvkhfSy%IFSd(lpKd8Q(tXBdVQd{!^CSc;Up7R3@WyhOC&mNuU{-+nA1iuQYe47tfL zJJfEiT5UD(ZCWeTE!iTx zj+_7GO_1IL$^omYd}qeN0}9sM`!Z^?nzuKvT^d+&04PEJg#U{SC^$kG9(ox7Q#=NuU1iUYPEDd4+LcHf52l?;NZl& zYB|i9q0p=OWliz}MFVoA%h=7dtLoO8N>*VnoQLHU&9+t#%Rhdg8wS<_ue=LzzKZox zx(+Qhiz(>08_>oE+YpSdHJo8C_s26(6i@;JJ+=N~lw((57U@w0pMILrL1$~9C z&iQJ~9W6hEn4|xdf!$2nvn@z=L`;W1k@0vo{!#pe2Nm(p9K%R=Wp7VHvb2#;n(S}) zxcXPc3hDp*&{x5k{CPrR;Ci)TuT)@`MXZ)XeP;Tdm3Dm(tggo}tWgvJS=~YzQ)KRw zfXK=ATZpvVSKmOTLIz!u-BBakuf)6?C*y596Myk`dSggz@Mzb(QuU@efKo)b@IjqB zxHz+ApZe}e|LXOvgT4Iu6$G1NX9JS^*S16R((Erw8v6ubXoiAeZ*)caaaZ+HV?!g7 z42K& zEB2Wq(M0s7ewrTtnQ1{0g&bg+S=y#@oqMHu@)@((^zRznR;sNK-@`J$enN!LQ?&l_ z^O%*5<+(R`c#MAu*nq5G>!v?9B9&KOUMEg^7_nT2oT`O_a`W1#XE;wZ)r9s=YKY2ULlnFJnvFU`J73>N;LfCdcaLW+zMx+Sw& zWxL^;IEz z-NxR@z^ZJa$bW4O2We~HRrPSMEN4^{mfTt)S16stB@g|`e@(6nz>fjU()VAvM4%K; zbel+Rol66ZqS>zY2~#oU%a_)K7Y3k*R7!_e(W6rN8cIb4zDoBRhP-B;ug0D;88F7a z)$ps63QUYc6%-NAl6g-qC-QiD;-T&NuZfjvvfUH{M)p$v=q|C&kGsOr;2Ln^yDHT> zktFzOKb)ZmPPw&TqsRIj$OF%SlK|A<8y-d9Osk0#qe?eJt@UaG=EJ*3&FE96jhFTf zr9$EpZ3k=l_PH|ubFifeL7P3tFxdU7SO5dv5O?$k=N5yWmFLFNo;`ZV78gj##;0Y6 z2kg_@t^>j@POkfs2L?Q`#AeZ#61SAm>ZiFx;g?A4c z-?k5XA()Rk&zb+6%!SFcIWVmi7Fc}o` zU(#T8fG4iGUp*wK4eDi#>w5VHybK-o-nOQ(T7w&m~@&m&1}TQY*Q)n!KKWE7b7he)~E#Z@UP^1Oew$gDP{X~Q{b0*8swBhKzuczi%r4e z1nKAH(WO%X88S9{Hs{r!APfU4HYv-GNE>@3d;z_2vd4aHyOt<;Wa{7$X2{UGW0!)` z4LMZolR?ULxST;nIi%Ia#I*iSk{*H?@f@IQ-xZkkU5YWT>;e<0iBm$CP6oKH{1C9KA{zMi^N|FCz~lFZOo@_W z+Ih(H`&Sfp6OC0{_9h0ar`24>BGMGnNV2ah8V&(%KtFrMf@ws;Y{E5=#Q7%!jC%QS zuXmGm?_@Y_q(<}bKTf<6iLQ^X2lhU?-bhKSRbt4KXSL8=-URfYbp={8y+ z*BA{Xt0XM%K9kUVp=Y&{y@{z-zP>i@dp(DgvzNa@oki32iEsEmWpRfxI42PGv>>*+phyKZ}q_ z!hGsGDx^-k^Noo^s1rSVJc<_+kD1RUkc0090W)u2GHV7gi)3B!*YM{bx#8Z5q@?up zjP}&r9Nw!uae;X}`Y$xWjfsCx$F~&r=qd)m8mYDQ@tiES(MO_@h_=2oZMsb8YWUpc zGXhGK)-HZ3AXC-nk>Zuw+1bssiF{=%?NH+Nv*lR-9&%f1!L|^#4fJ$FnICB~vrw!+ zV^0q8!0P`B!3rJgHa@YWXfk^|TG~YWZ|pQjqJeJcMvtz~(-}5E6xtG)XMn$Hk@{}3 z5W#$cdW>)z=v+p_ytUoY0>;w78VMjuFI!W5eURh%I{8ei*Y5|dQE)xuzCLNsu#uVz z03WelxW}HY(W82EY(MEYL>0W(+lXIxzVCvIa7$^p|KGy93=LB; zx1f0Mc)g2kHT~IY{eqd$d3vpAz`qdx_TrF4tKvLukZbfZt<}DblK6B1pno=KAB+l- zV2IaisYuWUA59P6gIul)ZiBgY=9-OEf$;3~?Twvza=u&G(>aVR=|Nk5}oa0{aGxNQ+Z8k^yLo6h7#TX% zKTm1E*gI?j%Eh>bM@VjP+z{4>;7u8{bjPnSo4O~n+#=@|_AAHf)1dwZ!d1*<)T?ug zZx!h2Xw?e7*yd z5b|d^dKSrbHa+59|MUHl*Z_v_fq5xh3w=Hy!6fm`DQyOkdCwDSy zigZoiwakC}qfG7(YSxSEyTC-cWzU?^D>xZ>(zMZhLDhU+NYA&XYAoDcLaHhpO2xzj zG7e5#S{aK5Q?mPR-4QaH5Ju%-@+B*)BD&5WWE{_;*CvnQvAoD}(0iG}EPg;gB@D(`(BiF3>+!_y z;;03Glt$*t(sz+ZGF!%jikt65hSX>*CSCJ#TOR(tM##ZPGqBr~U|eRL z5DAA4Haw)*N{-|v|n?)e!dy~M-{#6o& zm`nGcgD}jdb&b~8qWR6uFCxcwk`(?eHX;hkl9B_1UV<{*5f3t@^WUNdaLhsnB!Kob z4LK8Re$%5TvUITMpgRa^;XM% zfPvnJI?CfXfhUWtC~cgzTEVWx638hr2KdD#ekzIztVu?e<9kYCd2uvSaskQX#-l0l zCuej`#2l_u<^2>JfVeQWs~Ns_ZiLsNcoI?6;#Q@Pe&J6Bp-oaU4p zY$KnZwey=T5x_}e=MG5OCGx9G&r$|p>TKr~y`G|7kW2qBezzAGMxyumls0K>f5zw) z7Jma02KcK_?tC5m*AA*6=*4|}q7ZyMHx)yYruwSB>jJ#!ejn@jcN+tzjZyU2NQW}E zx=fwrWc?%?BAW`i1&OFD>?TjkSI%Esn8Z8=uFRm+Plb9@cMb8SkiL!aE6DJ33fM86PG>zmxD6Z1(+zGEk&&*>2K2zpM*j6r~^s zZ_7Isz6On9DIXy1kJFMDo(FtjrHyY@{uL7E^=Omj;_Srxc*{#;VQ!l-5%EmsA^YiJ zl$$BvdkAs@DvStwDZV=>t_<@aPyY>up=#43Iz1F?;-l-)q6QO3C7l%QQS;|@5K^R1 z`s~?)6ZGK3CZHuuxaWDW9mnZ)aJ&J}0D~_+L&fO?uVOV^l2De705OV@L|${yJy_7Y z!GKRwpW{}g8BtqVJi&G~P4sHZ>l=3nJ35?2j~$!b0v@Oi~y z;uoNQM?#yzm|=7#+xI@r`s06U#f-PWAu8a=^Z(zU`S+`OwT*XWqGJlBU5!_UO^wDK zHo~?MsW*XhXN8dRLxYWY`YNxwvdC0L4ouS({rWNIU(g171jojFX)lSk#c|c=08vl$ zb0b^`qia`!h^u_R!M3ceLsx0zNuL}Zg!5U-w$Q9!Knr0I<9`xBib#+EX2?ZXUsnm& z8PT;rhf&O;Ep#TX@1-inOJ_NKN({?Wd0x6t`rqCD z-<$tphjRMd-7WXxbpO4P+A_N*&g0Nb2&qgf(dSI|Xp1Y@Bh&!Elwze11a1FW+;v8D z`R8YMVa&&yBD@Q)dZgza8Nea8L^+=NO zoNs<4-!kqS4fa9U$IiP&V}j72z?S&a*VEBXi7Cz3+ZlR*e13@MY5zpS|1XP`9fM>; z1kmV}8698bTJFlXqnV`31~| z+uGb|gxmy0kanW9p6;+87=bN`sb0Qg8nst|Em)u!0r1wefeQaQW|!yvKmQqfoC5P( zjApQ_9=Pc48|%-nJfZX|@3{E7w~7vbk@TK z>u#S+O)VHUrc_N9x)Nkx5Wl*e_uH{*O8vbtOSp%{tFi{uLig?nmiCu_UwpM)x!ZB) zq5On>vHCvbbb4BKKdALPkx}g%S-+M?K|**qq?H~^D`IV{&zc-;hpGz#J_FSbrxw&MwXfS)ZF@= zt28qd*^z)=W-`#05SccU{&oG`Qtm2?In)mLBVv|^!G)@mBj#|7YWphFbE2WQ@W?wCsgK(SuX_U) zfPnTn{xDJV3SRmj_W`?wQ+u+)%(5Fs`v#58T-|cdc5ME6SEq=fFCMNxb;|c)`(KGd zQWq$xEVpPV=7QBQgmF8If|Oo<+TG2bCv5+lit$ILi{78qJ8iWaN-PG zW8eTjvUj)l^j-5;Lg^pXd$qI((wOf=`5N`3YtuD9Y(Kg@i$=}%-(K@8>8}+ItExD> zQED(2o5J$^u=Y=dADnIHLi>Lc;YZz+**$wkBjQ$_!NxM9fu=#eXZ4*zZ{pM} z4ySKnlr+26_NO|Dh8hZ^O{JF zLjU1ZFZ1;W|F8(~C&eVqW)5L1YKkO97YRwIn-sk94!H z=7(g$%PF3%nL(R%&U>QP{0B)aBq(NX${It%oCnR(nlHJgiS+Ln_vghL4`j7k*k}&D z@PPS!cr*TO)yQ2|LGP<_p#`)&sDZDXUam1<@iC>6T|Go;LKsfZYC3{#;rvz4;-#!` z?5mUWvgla(oigKbXvG>(d(v3rh#Ly)oNOyPVki*dP{l>WWzVG+`<8mo$&G5uI`|Pv# zdDg;(=G1=#?qdY99#AKYe~zmG=3tjERcLmXCOuALna zYk@**9u?*L8bn%2O=cWL!AgF)o8)d@fZ?bGx$FFU6=@;!7XjrX2=!7}m| z!z@tfp~n&|{*C_8T1UM(Yk|JAopv6^b(PvR`Vz=s|7ZbjKqiGh(A)Y3iT^q&m$Z@eSIn{4(?+1ULEk9e->4#l4ZZ|M=1ABGEt z^>sCbVB8iU>ocXBBrMY?)(^)UJbd6OIG zfp<8cLfzy~^J-eH%UagC%6${kx8??)*4V-Ohn?CUV)^91QWk4J$7J5wobhhE$-d(ly z0Fe+MVy1x7t5N4jt`awggU?1bGY~03}j`YzHkXB)eb*+3B^8^f*vJjcTnRkLt`sqQUzeu{3k<~YZaA3&y5?CPQN=TvP+dr zpDWzKgXyR?PxdlsYmO7k?-++~yOE&3yK?*92bJ%43ZaHM`Rv{IZ>n!G#(;CcnmH5~i`ZIlc)TY1(;nO= zCp;*3@!Yh(*g?72CSnS7wJc0{g@UgDiEQO!4rb9t8*pT!AIw1nfck0W-x63_5u+z< zdbw#Q_ch-laBo`rOfl$siX`vWA5CW2hkpI-NyWT-Yp|DT5>20KSj`dO2}J z8*^yU(F2?Y)zQxjqBT4WQ!<}0o3{GY*9wo}uQ9qxY&WRPetcg_XE4*(x_Wm$#kP+< zo>k07*^rL8?2HlYf@KrU)i)?R;2E^9W|?nDHdeMvdu*m~U_z*MzRdX=^9s|A_BOGL z!HI~PA&zR7N$b6w(BIeIB%sxuBQuigFU$4c%7NxJYO-GkvHXNnXGu_MD_#T3_{8-k z+_U1H?nH_7chz`X2^3mfA-=J5M{~@fP^^=|6LzaCA&p$<9f_VYKdjX zSMc!QP`Mqnf)+Wjlh_Un_H7&mK3c1GzN>dWcijn@PCc>3+8hkBcMs*VjSS?BOZui4 zxA%A`TMXCKq+AkrncFlpkmgEq#%~zW>!Rg`kiJ}~47WV4cbqFqhjcNkWw^xrSkJ&^ z>IpDWoWAMzYIu{SX^QEH5tCn`g!1V0aea$w#v9@;{E=Zhr+&@#SY0MJii#DLQdq{# zpGz#}1du+jOX;eAms03vw-fpRnJCdpp zHK_uPl6p>-pP9>!QmW&d+$!Uk)jvh62STWKWoirTZ_X9donbW1r~FHK?^JFDi_&+9 z!lLrNF=_)4f+gz9G~+}%?=11xXB=fZ`*N)*sIGDM3bRdN{;UUTS(inv(XXDV#dJ?= zl1K|YV}egPc16i*O}+jj3VqC} zQYRUi-AUGDI*|7?B{)}}pia>!(H2~IT-K{$t(}mU;q$Gr!P%QeEa!;BaaMHbQvSSq zmvf@f3)F%!?|wm%&t*4XzfG*D^8@vzRUY}k~DA9yAqzXa% zxR&QhY^OwBBSjaVj-CTG6N9SScB*FCaA%j2?U8->*s$;XIgE`<`hEtfbF{A`pNIWy zXGi7k0N-#fJ7iJ3i7t-C1Tjz9zZTcG_FlYwxz6PWwRPvCNLjLs{(Ev8|Gvb5PXvto z$#zQp-Q)X9Vf=#3Ci!BAF>lSLPqfx6dIoYgYxIV0=Z_VAPWcLtVCRKx*~+YoP-)(I zpriP>tQ&0@p4XJRlP5r9a{S|7DAz~l3N^zKa0NVw>Lrt^IBPuO{D)xtrwb~(!jCQv z$~00OVc@7kMLlQb95dyj@yqr*m8;X<&lscjZ?%-&yLCiK>{KmvZ=djOy+NJY$$Z7g z=Hwwm!iA#2AN)>Jhgt_CS8&?P|J7ssAMp;a>kW!2&d@+XYY;^9^9=*uheNBnUJ3wE zOFg)z|M0SNMx{tfz9BJgV&UpSe1*l~px>;)U+($HR>TU7sh5OXS4xc}uB`?cq zW#bTGh|ZfgpIxaQFU_Zgsu7Iv0|S?fq{3@k3(=M?XY}igfPlKjiDmhoePqk z6Jo7MW%M*b--{}(lht;!cJiL0#ck7sVx6+L@p^)z!9))U7!B!0zb-*+=c@W0VZb}H z?mmn)MfZ+n!MR8HTADSK(Yt4Hu9UeFe{h$QCGfJHs^zFIU>^V9m+_T73i=1#xw>#t z=Y3xVGdy?eci3lubiY$K5=uumO?=zv(76h-}CcNfOA^b>pHqcZT9P`~dJ8#4tCEhOkcIuZIF?U< z$9Agfh`7-Hk6(crMV@G+X5p6k_QM%QQ#|Ft4>J1t>B>^L=;8Ts&6ORTO%att@Qe~2 z*}kRr41OJ*n&!ueNyfl+N`F$eH$PViHBdJD7)I<5j>U!VVMFq=U7h{RFn4|2Lq-hI zr8a%j!oMhw5chKtLG}Sc#FRw!qHycw3)ARYpwt=xUvqR& z-+KyBj@^VnrtC!3dJvbC1Kd63N=HImQZtRRHxF>G`1~4~Z+(Z<=?tW|Wj>(HTWKfK z^WGJH64=1j(D=pE=5%(k-aE^!WEwi=)Z@I-duk(iGv+wp#mwZoo$A?DypoZuiI3wE z3Y0%O+v6p&w_ZQZ#hIx&Z{ZPSv6})LzpobZ>}x89shjmx1h-)s=rnh^?2WN8h;v}6 z@G->%cNuV*_6|$VKNrJo^%t@63C@#0G+-L77aV+f8BHOAw_RRaqc>bzE>oFa>~T)2 z2ozz@p%3|ga@i{rx*IS$1*TnmA6KsNli+ljRcq+BjzA?#ASBFo49kppIK=l?Th@(y z&5R%aKMeOjOwbeqJAjN6bui{_%tSaka9Em!+0kWJBgnnsP|Q2;Ugee#Ub5_qi#D*_ z{Sxu0tht`K7HZ&Ox|Jc6Vpo6I%X@tdvs-BHb1wE?W3w;iOyTir>ATTiBp>x^rBEDF z<9{L@jh&voWufMtn;n3M4(TdaETfXziR&fdb0}w)_#T|V({t7TbTTNMTyLHK*ktjz z@w_iS-8Qt?2Ds6)uGX5zM^~MZffBQ8lO!R+ZP?SAJ_D;Vn0LSKS&V^W^@@)sD8I}{ zybk5*qMXeUn0DVHRTX>1SotoW63Zs@JDXwWGeLz8gWKjnF(!#lIO#)kU~hJrCPSd|d+26m31)>UDgy;F@Dmct>rY)+|6(1A1>0&`qkVI=qz_0cQCu3ScKO9Y9MfLdIa&to^eJ zYUOL)t3ylDO+wZ5;nIz58c-}3Xf_?S8xMn$c-tfD{RIM{)oVTfd#u*tBPnNG~j{n(~?Che+_BGN;j`Tg@Lr64-k*z)0BC5Dt{@r{%1p)t#%iVrrkCy+d;RC2*VV|OTKsXtwEx3s{bzO+R$ zNYZBjw_4Se*7zcM1;Kah2brkL|Hzv-VCUXq)tzKQ5?NNi0rg|Jl=U;J)jz&o?; z94$*$)(?~S{cL;vMfA@pj3Gne2+sWxj~vJFzhXV8iqK=RtpE(rf@{+duQ4Zc?WAYn zBwncOE}5t=%tQnPP4Hg&EuxGyZmbK6Q$l5k${#QSRGVN3#cpo!-&p|3Jhox8Ap$Uk z^rLb*>yZ0Ol*j3*D+SWPWQ7*b<9mD(ml}&_!DURH&*HH*`m1y=6&Vya0kgGUcz^Wle=~4A$2z^L=TTfE3qR`MXpBbCynDnfiZg3 zU_`*+!Z%Ig*kHCsLJmVo*L;0+`^f-&bW?gINm%`5X7A%eV!g|bFFmQ&A=WLWSvLi^ z+icGS(eC@7CXIYNW~*fv6i{o^$DtCQB6ym$P3YnXpoV@IhM~fRrpi${GVZ~%+b>G@ zgj>%zHMnZKQn+7|K6_zWUp}Gc(0cWW!ENlgP>wv5(6n;XxhH0^z$z&1h_-g9I&%lD_tbo|<{?=}#K~OwHw~Sxnu*o0Ngr`OL9?_EvBBf!p$R*3H(#e&%z`%r*HF zdCpOQMvZ0pp8g~}VMEkTQ=*wM-{NBbJ%5|17d49>SLg05nL)WhR~V;94rRu!M|_)J z*4AIFC5gmZk_Wnf9oYX#&iOJZ=sfg%zzZd}8MY9lXOJ_XM=uvi#w`ci9=n|++K9`O zQ>~7xIfp_G=@$U)d{0)F=scgv-Fa^vUdq2de;F~P_~GaxgVj&8Hv1Ni(5OA-Wks0N0fA8jf>hvZ~~EUp^_jm<;GMv$KQ? zBnF13poz?k^|eLAll=XBzuDlJ93Ef<NpnUQl(nz3Apn_l1s6O9Dvi(QzSCVk5y=5tmqtLbm5 z(bKw3Qnn-K^%-}3U2Ns!a{{o5^csMYfC|IZZfmr<<`AQ9v$-K0x-h*K-iJGVGdOis zX0FZ&jd)g{5v@S>KuD7H5)S1OrRJGetw9Yu-J5!=Z*UlB-c8!HF@0zHbC2Xo>^vP= znHS9DB2CwiZP5MqwE#*s`lrhL{lA~K{U6b%;$`bkp9gp6Uzr^Qm2fI&hoxt1y6$;m zDTQ(;cBHpkuVYdmDr^|>5o)wa6S1q+Z*Wf}(BE%jVck*!C7T<(@W*>v1pWN#9(CALTxAluVAh?Xp9t?Xxz28=?N_igV<&CBZMEyxiZGALNP0a zK-gZl?1Q*nDCEJK`BOB&gn4mDAHRu+oX;U7l zPjr=)p#-Aa?#vIZ?EA`g-@EjSca|7Ud|M7J#%*mZ))O<2AwQj#&)n!kgN~}zn}nv= zTh2X$hPT3aw&$nn$G}fAC=bvc#iv=O!rPi+WgnXrR&<&j7yUZ(eZF7p@8;$N+@k@A z`XMAyPosex5T_ot@}DFB-@sCY<_4YKI_VURf34xl0qUn`Hvu|L5rIVb3|Kg|_T3|o zIN#OosIKFnd!2=&k`l%(vO;ggmQKK(QSZ!NGF23}23smJN7wb&!^i|coJ$AWbU%Vh)=!PmUe3`3BwdyJ|g*bhDA# zMc7|C#pYJHcZO|>sA}kCqOKNXC6=m9Sb=Xy*j1tNz`+R$1X=-F`fh2Eo4W)EXY{_(vj z-Jqsazpw0|J|j%QxtsEv$%U%HB-x zh^~KXRePQl2Ch<88ekeo@Thn{X-woWwDI{-e-$%y;fV{|_MJcpw>Z1Irv|>KGYnlT z-(*vgHZpv^kMNF>m&hkuNi_p)LQ;;0FX6?q11W*5kiNPrt4=yWef8ju^d|3Ka{DH` zd0>7r#Z?uvq4nD$k_b!_(j1zY5>$-)lw1RBT5n3dBiUdIIqJ|`zW}=>eXBv#$N_lp z=|6A_v`d(1!0`+kB`GNF?=eQbgX}c`QVMh|ohtSeo>E*Yr3(X{-m$a>vjj8x zDeRQtgSco`*l9!Fb4=F=|CD~^)*u!Lix+)Hm-ox-WG?Hks%a&%Oj#8M--qYlM18f@ zEDwR5(;ny}wmq~oLM-62Ejr(iE`tNL03il(Vn3aBlU2g>>Zxl>0zNn7x^G<*?p;=a zs^e-8*_$=f_rB()!^>s7tx|D5KU~v`uatT2tk}o9fsYff#TzyLI3NHp=iasdD_un1 zC`NHH|JJb@l)ajVv93Q)^}J|{7`Ksv-3pD&@~H}V|Kh{SL^XtHEh zdb`apKl2X!Ig!?QOG+drHIB;1`W0c`B-__!dWWYH;^@%UK#zfFH=peN5Ve+s>}o** zxb>{n!`h4jdMv&vmHLh=&pxZlx5r6_(`vfm0uQ=gf`~y240rGT{4OY+@<2=sbpiC- zI{gQ?F-m9pChWxeW%2Blz4l5|L-tTjQd+C$8ocYP0Qk0%0!@!B28xt^EP96oq&y+F zQmpU?19}qko5t3wqtZv~_49gt?_RH9-hI8ni)ve>25M=%*7%|y9gZYX3kU& zkI(nlQArSM=%4EwmUPzDVT9xt7;_o${gRNiCCFnc&DbimQ{}mPkew zx{b#%@~FuoTT9Z^Jb+we0Bkozf`-@S2=pnPuI`D!|3$BiiZoNIU4ZUrZBDQhPyi&c z4VGNO%;sawQIC=3XO;Cr8@=H>;McEXIB08zJ6EnCwWAywVk;Vz;6q=aOs=i@=b)?> z5g3@+AT0S%;~yPNZG=eNdFNs=k;TC}z>Ta{;_d=fugsf*-&WXP`v4k5{h9jWeSz@{ z@=9b+g+BA)mMJ~ZkGv%YP6d!IK z=G~v*1~~(jM-GdF;+*DC8^y5;N~87mO1ZLh6Vj8`a^U-uJ_AUahK`P zU>wy>lM6x6De%&zDYhEG07f*LM*s!l+2R+NVeY=7cT)59okXDE?%RC$kLo%m6xAOW zt-e&hvb$IpR`^ysQLZtls*Vwzt7N$HIO93Mm$6Mm5C^l!4G~GMK`N0)uj?tW{v2C& zLmL0ajR=xgz$gSc%Gg7DbmV*4>NF0n8>|Yqx;}Ma3u{i)`%PExoAirpP&fm;RIlfT z@4{+^cj*S71~9!|&QNwskW}`t1#v05j=0M3=XOQSaMfY8oc_jogyg1jzXbd!*wg6| zEglcr<(>DMD}Gb`P0fushIhfMJ=OU%>8qLpYBO`7Clr7>bPMTS_nIfs1{70&E20k6lG0t1apq%@n24GNpohjd zugdq!{Y*on1a#(B7IATge#n#eh}t;bUk3`Q#Rq^HkafTdTsE4o#Wd0&b_ong??K6gk?y>I8AMcTSNzSi zbL~^*{6LO$B=^Sn&uH9Gq+SceMF=3Jd-hoJf5cqKrMCkC*Sx?%>D9`5NhNvcFY7D= zp_1V%*fw|X)kZo`o+82?tL)_%KthzFo`W!iq;KQWAfvb#?OpnZFHJA@^S-z`yF;gw z#`kg@?|y$gxET1}Y;-P%;J!oH8W{!BYpMnT3YU16e%QYl!%2TJTdGeEsq%=WYnJQE zZjbg#Y81L*$iSnbLxu?y5R&=hRE$TsF(KV#zZOoqR_zaS zF4;WNbh~ooQ62>1fLNvqIw2m%Y5Ie=WuE=~=U@fD=5q{Ev~OfzpSYt(`Cis3eU6l4 z0anDo`KpNRC;q1b-WazhF)OGW6D8JMzMX?@?Y&50qQSgh5AyW$pKXC;66%g2M$Y|H z8&CJ@le3L?yBuE^v5kiT+oVDy$f}oSJz8u@rsq^(`DQTFh;r2i_#QNU$fnaV`OD*f z7py`x^YO2M{Y9n4rPuiZF@eB(fA1Os%co?I@&+=|#I&JKxY+Gi-H0YI z4=n1ZT3#R}qQD91jT*iOHlCO_cPmF~nsSqXVCg?3u?xDsBOnUg+CAIpsk!0XT(SGjQuL<_nkMaPD}`2B88Y%Ll~QsPy3huvKK@V_KtqIj_o*Zx{>)|n=gAY~ zMjc{46+lLh?;E{Cz|I8_@d30rsi<9q-o54zW9l!)(`;sG5B z)x6%%!z}9q)*31IQYOr`H7)))itpx%0iQ#dsq%NE5At)q-hImP>vJCWJVzc#Pf(aEGctl1dd)Qboq*&-fgDecD;JSfRjnnT>5h!PBS+b z5uY+jV8_w3W_;z!=i3H^l)dLN@E@6-t zY-dA1Zwq)l$fQcFaYX|lvl;5MyJmSWL@NFEq>fit6jN?|F%q@82l_2A$o{^ecZeCo z@Kl8DA2%&>`z=u;Q);4$N~Pp=k}FXcE`Hm%zSCuLZ6hTy&clF;YE8==NRdv8i`&4Fte&1LIp>3s6>NQ4jHJT#NGIYTY z0OMafFsur!>`5bA71p1B0KNbQ+DS>tebH@Gp2i0{WDC|_^QpHPf0-X&HH&Te+a9WU z0Wzsbl_DhBhJv}fuyc=00-3R2@q*MMRC&Zq3|m0!`<+qAW7Zl;_fqD0_Mt{{ay6HV z-oJM}KOcDRPE9T5_}`3+mmkm?Pw7u_JQZBBoMA`1-p!930Mlgz;dN-PW1vBysKvfDYPudH>*neKegYE$SzoAeGrw!MkLy*ww`$j#cJ*X+uma;x3<`R`ZV~c-lEgwFX}$0JcKU`|sDamz;9#Zq0ekz!ygKvRwh(*0{TUs< zYN@_T`64Dk((4%rpr}5=csZ#8$jXv{QsCQzHTNwqB%c8&+AOB4T7D4fdN54scXNJy zhK36a}F|(g+ zffO08AFl{2O*jXtL&yLj-iwVBYj0e3(JccxhgXe>6dB{F{bzCGEV+(<79s|Uy6_r) zXISLVcS8oV3OzA~a&m54Qb@{PgD$ljwcy_vhk}MrvN>29i=^a01P(N0mWH6{gFUXRPvjL3FN}qZ%>xNHFBgWPz#@&{9aX(LgI)hA56I(kWEZD8<%1VR zX*Ml|rG1uiWn^FbvSF4W|7=BIX-f;9lC=V^hm?O1GsBuZ{28U0G=;7G+wB8DP6j{< zp83v97B9}-~x0Y<=1d#%QotuuujkI(I6M}2qnBO6BKyuDpeUro#H={ zi_rj}F5>O`iT?8)?lRz6VUdEPFkg2_{a#WIsm1eP?A}s6!L(CiVhH;+22O7xWJ5-R zTz7Dg0!NPe*wb*EAO-YT^PK#{WM)8Kfz@)#WaALpn!96 zq+?|l(_4S=7f1qZFyV=gFVzbX)VuTRav-36Uoo)#vo#JFTsq3*dVBw#DU0P0SVC^< zlJMOTptrxHqdnSe?SPdsCn(z|Xy0O{K!q5d63z6mnG_fUBclZMzW2anfrJQRm%!QY z8av3=X@auR@I&w`+u+mY&@I{*mli4PPX zwU0i3eFrS?d-)2*#84gqWJFmYlk?9v=wv*#03nZ5sqvE%W(RzTrRzo|D%L^>O3!q> z(~obGNRryEA}M@1(scqTb>l=fTdF*noL6T;HtW|(GW-h@VkAK%$xySEdZM)pYN5B* z4nK8gyv0UOnP^^WDce}8cm$6uShkR=uoCn{F5uu&tf$cqLtblSg^kqM1H7?Xt~?L~ z*vnW9R`(A4_!X>a zRZEd;{dHDB9CTJzk7uIFfpB*}QkIeIuWK5J-q`@r9h*Vq324j^GCv0*jDo|50z~y~GnHLa4N)Un( z#PNc1Wx;GF*V&jw8sYbyp5AyXn}0q4&j1}u?BmCra#c&E&0a9i#SlMx+EP@az=T@yL zb%s^@_8N>c--F1L8kSzX<&8yLdr58B_&A$7WNeS_bEK7BT6RUSKO5=v4irbmPfGbb+;_?@w0R>v!s>w0Ac~qEx4*6)%urAGuxyNV>hcdGz;S zkl$cR7Zs3$yWhkVipH!jr=B{#1s-es^~0nzgZ{0pjFxNQNb%j2q6ny=Oc0c!9?agyD1f@)$39ggGuaYEeD3f_Q^j^q& zXTw1pV0xv?tkx<9$mXMKz*X|@s-_;5cUDq$B!6?^)IB1Vkmq)Ig<)-)i$X4s-qc~I z0^}ZLUbeIUuzfjTfjL=Z^QQE_zL?7a>L9RJq;|R(vHQY)I(yFuM%oC(8J8|LL@@J< z%ZhehX~lT_wdOuI{Q2|+Kv8$|7xn|*3xO%QIOXreb=FwqrkcI+%QrstodvpEqQ7T# z0JY{SQo(SC%Avh`8s%_O*TKDo}NCEUZii z64R~^UnY0t5=9mWY_3 z^^>)cl-!gegm@E&_R~rWvd`W0-T4Q*E3v`}Dh9}A)fAY>^!TBgQ2$ivVlbeS%{I$W zg5UuODcMX?i`$67*N&8oJ18V|*;X|no!2wa5Kxqjyh&c67};BBH)mI&y)VzS(!ZUR z341kibCw2gY2mceiTn6e`}{S+XoO)=7qEaywb9jSaLoZ(g6^Lzq4WSWdzqjnS;hBP zEl{D+3O23wCmf?b2ND>^q`|dvk6#Z{?MHMp6^6w=i?nVgWnR>^W=pTvBg7!Cjp~SI zy`m7pYO4)t-#4gFQ0tf-P9~L)2gGD9U&^Gl#!-!B=YG??_D3vZAGcxblbia}-<5N9 zY(pnWlx1xi)rxYPQw2dNu}9yA_iGNF^3K1p=1rl#&bOX~oXsc|xv@BlXQuy%Oi6Se z5FA+5Y#V*Lbn)fBCF6TQcAJD?W#JA17;KSB)4}_(?GeW8SzbS;22@8WAY`w_ zUelpkDssBbl!e|xSmhAI=H10y-QqHBI-^aDd~L)tfj2NI>!Q42W}UC9*A_niP5>hU z9CEpjy;A=gwn*tRG0;Lprp)7@nhRK$SCxu#jH(aKDe&$ARdFieL7q0eOo#9bgJx@& z=Z1kHtL-?)c8&g?XXE3TJybx-YQ|$L$IR5;HMG(Tn+Umq)KMKM0_KxOxZNrP3bfWa ze@m3+s-~If>^a~TYMVI#TDpDnK%ZoAc_wJ4YOo$gw1#?*u>4^0He7md!8DXMByaTwfHqHG5FOv1f=DrP+XdBc4fX-=eK z`8zfi6hSaZJ<2V5>^%cX1VCQ&!&^?CZ?g(0&&GGw67+~YO14g_9T&-K#|r6gFj^yS z=K$|s#f+d{!u?GY(uI~D0)$gEKOk4De7ge93=Nc=MR_9AQ)*9W0Bg5H3q^~6BSyoI zx`c}VVoYTJC%*!5XlN{L$d!gqzBAQTbZ8cjH-y2#WOh?|E%31rhHpc5Ydi|?f(2NJ zqn*oDSQppTrVz5V;0w4St|rL62ksIuW`3h0VWnw@!dn;@vvuJ5W~;)+MyK$JCH)DQ z^t^DRu3`A)Ll)_s5QN8g4))3BIKbyM&F)SqCs&F;0@SF{_lY_mbRrySWj_kblXhhj zp+jdDeN$K-P4m08fUUR2>3lL%h5MVgIo**aM4*I^02_vKue=u)9WFw(B4GGh#W3Xk zWy@)qk|pRThc2rVLzVz8?cmt z3W|}j>-<;n1(wncbpfsUQN8sg@$p3%iO@04%=_^|tr?fy!G2x+$zJ-+oVP*Pj4+)N z2<0z_=@u>EoC`FJ^@8nE>5BMXAd&|}5JK!k?b2rO^d_^7hKAk-5Cd}@*(@b}w#({8 zQ1iN@~R0h0F=XUx2xW`}BuGN0(D#iqZ4Gu}=kFk6Pk$wvu zfe_!TA?fvNVebgr5HQmaKcH!8oF!y{%&RrekLJ}F>oDP!kJl`)fL~XdMU6ph{ki@1 zn}!KYvI4>!_I#}LL+K2Exf(eS)3G|xIxT(zaol47(gl9vq{h&*HkJz1oFJO%gqCA1X>Pg(>FRg zbo3@G^_nYKj9n%o@B6O)2#wJny5o(Q zC^VLiofc@wc9@v{yn7_7)XB(N2xS_0M(ktDm1)paxn(86)8(6>=9|Q_^Nkr-Xg?Qc zl1rtf^$XOma+29$vg;yH%)3KXY*`gny=j~?BlpqmdVO3VblAb*@H&XM`@jhY)>9?7 zXeHNrrqQaWSbQJi#*A;MGaNJU?^ZlC1f)pEHa%sr`*Q8si`eK|lSjj!I@Y49FICP9 zGYMhV^UlY@;tc5M_fi?WsM0TD=q8`22@>H{njC&J^^VSE3QW?WvuVk8bJ)i zEoGnbud(Qbn0FZ6)VcP+BwBQy?T9y4*gsXtHk~Y=VkI2?^vW!>BxO8FQc+|Vt(JDU zSuHg-%C_QKZv0Xl7U^qPIy6e}uT?qvt_L+|V3B~c8{DMg_E8s`Z~W}ZZGgMyXS%}p zi}GG60n`-Q65n6>{jkKMeF$zc%sK(RMcG7WEHjfP#tbGfvR7ZaK6@qL#`(L}==-xa>x^SrQkJQ@;l0}~B z9()jG&j!T(4}ydU33DQD53g(3R?O*MENa;xIQ!V(f+hX0B~!Aizi^xy zjOHiRZ6?5zbf6Rjr#+MqN}iyuIRdjJphn$YFZLTd%gH{ZpG9C-kOlPrsd&YP(VJsW z$O`@r7sty-10l(Zss$X!8+LQmUdAV{4k=sMWet4hnJ-pU`z2&hUobA2IbZ_!j)o>v z^bJY1r7e_PaJX2fa=6#W!)g(CDmW@qWk^)O@?D*~gMALhbD2m5ahe3QC@R72pSf9L zxajon7zfyN7pHay@Rp~}_hc@k(gIV6l(I9UUP(?w$IY!q@{W5cOq}oy$!xGrc-%jn zSei=8jt5#hZ*TLtyheAdEg_`Hp`md93SyZCUu2`}SnS5;u|SXaARY!p?+CUYWr`+l zs2Wf&H&JzZqhHJ`oh~jY%q`BP_*!4+(l;bD&~J)pnf6skrWYdnpq2VlOx=MME+5^K zSnvQDFdFirtpZli!OCD#ll0?|S#( zIyEHRt$BxPu0Dwl!9G*$VTuW&(Q>WX!T~~7VL-(Pda+g9=stFTKi2|+^1RljSP(|} zg&9<@#*OSaEsqklxRhvk^Q;WOqMCNyiOb%!npAe3(v>Pvcm36e)ksX)RYrLENl;zB&fdT;51V!Rxc24*nwSl z>lp%e$G92d{r5V>uvp;v zES)BLK|YnjQ2^inJtq1GAWYjZhIcEt|pN%_1u3{ z@q)zs8j(Usm=zES2pvRPvNaFP@=BWs?k`W)Tk0LS^LaDbQy&U8B=VHqFf(M4fxn(t zugzOJyr4|jxz!E2FZRLBl)r%R3x{XZ8 z8;(k~T;Ei3z0A$9Y{T^wTsQl0zZb+5z;G0sI{i)euQd~_Of|y8cZ5gB2^|%CAMW$- zPS4*q>h@dWFTmGGr3s>+n7Uf;c2e!%_4hZAt2A2h1z694HuBpO;TkVYozAZ+IZ=Fv z`W0b*riP9rrZ=glDUZNs;8U~RMSU~aFgkSZZ9CMA@dwD(IcOKJyzNnsW-*6zhQ|*~ zR3D4kz5bebnCnQr~3q&1A^W51d||pf-i*! z{Kbk#($5Aecf201r62vUi{7ZtY`qj?Pj^=JEEXk~Wh_-M)4x_zlTC|f9z?9`$o*{O zN6xd6J0_k&IA~~*-ic1uWlfZ5NwCC z+<)-$D=>hUe~#wq z%@fduVP$T^6VcRuL3L~WUjb6LD~V{hl#`2o10BfdRzD&|j`3tsh&id#C}U--@l;cE z{eAZn`{mcgp_Ycr1rx%iazXFsF#-=qW4n!?m>OHoO<$JtjRR~*S}2dOVlm7~cMR*Q z3a*%zi6@*n5%+naY$DT&Tn$rm0^yA0B70N#+hR#2M!Io!{HrZTtG)oq8J&a|6Adu? zYr6nc?Jv8eX$_$K-n^B@X|=qYkMb;jPQpWTxqh;;}~{nez8QAYK8 z=(jNW(X5rlx3AVfksSk<(&?sUuuwiPu{kYOIql0=Ev8HiEdsg-T(c=9u`a+ofP`A3d}IdA2;}nB?=aS8SBcNK#x!AV2RM zOd1z%!|1N>qzs5&KefnjrRcO*)(R&Sb2%zv>p7n}J*_jf(7-TfxC@+pg?t+2omQql z35+J@L#sPJf2i}{?l8y%b93ouDg*oug5DjVXS6PskI~*e#s2jW6bOev$t_=0$ z^9qSV4=i(KzIFB(Fl@!X70#-wqt6V$b2t1BxR*H2n;G6_*U`&{uwZo!w!||waN%Bg z_Y%uL$=RhF3PU_}ryS~+AHNxPhrBG20Z~Dh`?r@`G<6_0Zq#IMp72t=bl)2@_YZOX9uYy&*(+T)`vFus}kjxOelB&*Lw^EG>l}AIb0BlPwCsn;}8>pdV~E zAk59Y^}v0|aXUn2V&{@yoD6#XQyV&2UBl^{-qP$~JABA^JFF92EPn&}UJ1Rg_I1ND z?6GO2a;trQcEFRC7GZ_`4uHp>9xL`9J2UFrt&Md}``2^(1&F@|Dt@fLyBlJ5*cSDP zfD;1?{BG=aD+px&;g{eA%}IxbZNH%(fg3ih`xZ)CRE*u(2Q=^9n z4H8yB;hcUBIi+;J&uu$R*fBQ>gk7{9Ww9Tpdo$VNIRO#!R;YadG2n=nd1eurZK;D3JUxwHa)UGUU{2aG@eU2xw1AzL=so+8KwVVOt2tOMDo2 zVH-bmLcA}sGv6a!D%EAIJTnVg`)}xDLn>S+j{rXL_+;f1*!*9TTA%CscE8>WjVw1ipG&z#g$2Lc-F5d#1%w_F zX3L}lp4{hvfp%_fq9tupza(z$+qX^JG|k3(W+PF?FIl8s9}TXq?sGcz-bHFsMvmXl zRNO38A$YbBHOb(YqL9WWH!X)SeA|)s%P@tqm6rES8jJ=l24$ew2a*#?G2ea(03tnJ~vvZFCK?| zB>?D=EIrwCqxqiB?%Cb`|JeHKuqe0gZ5csI5D-B?N~IN4 z29O4k?iML&kWx~b0RyGGLk5NtknRvvq+{q-y1QZc_5hx9e&6-}b1p9M%shKPtJl5m z<@9jh6-?@1i8j(zdiC}`UTOJMzbI_!R&l&f{$kzk!cFb$+YcJ_jzD=l5s;JE=yNgn z*Ci%a=@>a<>)#-PyP3BF5V3soXp@-26ntga)*oU4#tTg~*;YzSSDw%0sWQTZ&Bcu~0}QW2Rj)&-0K64$oX4ktzj zuA+W)UiMl)$SdmbIyc-nOeqUL;<&60J$V*HnbHsUfAe6flygYseBk*#+_Ae%)>V9e zbrWQ7ZH~J6PPU&ak3nNXu!&jw*Q`j56CWj(&i07~hbr5;^>G84i5C5`(B4NRq7x4U znhL`%eQ-HS?s-w`a>vPb1*&1^W#b^))1Kww3gq>xsipG?**F1RC4F94^UM#Pii=W~ zSSDMKk5!Cae+>5s9p-)AW2|`T`-h%PeX^~G4VZ9&^uq1k1Tcnv#&Xm zm%d;YQ6MfVUW%TPWxrC`Tpd!pC-b!j(91dQ%_nq_{i!Q)eKCP0Efb@bIjCyg98U=gSp@g z%tj=gk|}SwHHx&qd@bD)dp23vhH;Fu>v-kWK^s=+;tN_xEL{qA9;lLW5g9+|KB)W=Wu!SeqI2}CsPQ`L8jz;LRybrxP02Sba(BNyEt3za_;mHh{~Yc2%Le@aJ!dzGBd$8ED~lvyG~O zG|S58^5LgB2?~l5$e=O%HQTnTDyP_qpz@(nL4&Ap8-el4$22fwoZcMGiDs$LfXZV> zbgU{eM%@;to)bWGe8g$bOaup<0<%ABPi|ki>&_9v^#q1rYA)Ds2T;1E&B;+8tbE&b zRGtks=#133edqq}TJwn}W4D9FW%$_HBFo71vUvoT7=^;8ylPg&B!$WF8>?L%GuF8K z+T78tgoZ`$bsW{T;g%Atn*~2=tjZ21#0o}f_fD>=XDn)j1Qcf6^EmkNf-bbitU#x+ zGog(!djRuo zgqh*latx7MkdDUT*lU1u@YWRO`*|2CjQ;f{J98DR?McBQ3cgVSwcU@X%N_1_PJ6Rd z0TO`F@P4*ftR%_(&%^5+r<)wG0NaHFGX{D6siX!8(~UP3iKOel2@fB;E}M^j<5)eK z%Nt>5+NAlk2hXLmHx=O=`zPi-7EL04c&X<1|RvnMybk240zin^5hVc!1 zq?AdLkoEz{l?rmu4ZNQT9|Q4h%rIa&WPqDC^|kmE{=ex?IzZI^OL7ZlT7V3ypu*|z zHcgN^peu4xXWf8yBUpV%EB@tcaS(ABeU)<*W0q64D4hou>1c?#w^*TT`cj6Gh#!Re zNu;r>dLQY-&xb!sTgYz;zWid}y`nv^b(&y%V0#nVc9n)}2uyw!Zrb8#KBW`G+P2jQ zyu<3G)7+KUg$A*sdltWlVB5zslJ6(GEi zH&5KJ?_Z6w(XkA|MEuC4iqVrum;QYNp7yK7^=w^7%EJE53wr{}3)HfR($3)xo~J-5-X-VNXO4X?KyWFdbL zN`h#W6d}a9T3a*No9*I6xBlB(tIGW~;r8QQ_M{uXZub^g+QOIVUHdxsE`OsRRuH`e zdxQ~4bxwEuuLF&w2P)p8G)s9=a*C-374BJ+M~_Hy?!qcI5;_V%BNGmx zTqFaUk*Yt$|KKkd07JXug?M40OZUDLt_xoF`j97flSxQ%@Mv_2nAuo8 zNa4NhQ4zk?VTGUBpu>}(&-*C_0pPCxl63?P= z>$vYUjaqV77mVukly^BS4_Br3*$IJR3A$J4X(fAnJ*mmIUm5NkM3)df05<^KBp3!EiQO?jc}H22}29a6qw5!J1-W1Xaj1AMM%~{U@wo zMFXQ-djCR$jkD?(kQwsL+ZzDuJcSSyg;8+6d>XYIaZU(r?Bk7KX9H;-!gyR&AhY!? zl>}9h1|0`SCn+gZO6ye3nRQ7~t1;`bB_?PPTWjQLSpfJ>W1FXWKEnTOBs?8HmYz%PcWK{jhm#^xpMM%6QL!gZV^<#b)ou4+*c3jPu%8h!t$%T04%Mwo@su-M)ACnm9TFs0X~} zqEo&3vUS>q`{G#ZnF==A9O8P|$45lrI;GMVZ9^YYOiN#J!# zj(;tPI@oZca$`{k9pM69xJTSomPZ>e(6b;PY%?YoP3zPamefsf_BSgcrP=HSBqP7> z(E3liB1dGU)jXNUnSGSvgr%~5k~^)voS-2H+DE*oV7Nv9lQ=Lm6$wr%G6nne6Fczw zzemkRAC=YRf}~i43};?@fJyO|bL~4p#t;VdI3n6IRpLS|hX+X~Ht;jF{F4$)!Gr+o zSe%sGnbs7FyZ|)MvzrZ33W|tRo15TueiKZ`$GOXz!qH`ZOR2j&Wdru_%S;DVw0}X+ zzg}R-Q^9R@bLO=N54pL|y${TRbbes(3Nj_79@kiBb94<^@Ui&(^)_OmIZwQfZS3e? zpseht*DnnV9qLQk-vWDT;YF-z}ju|uDXvL$|3@r>)j;7!S7)@H0_ zq*7Y@bkAgEI63Cw_%e{tR5s=NV35n-TWIdEI%j?>|Mh>q(I5Sdc1-3MOP(lhfBiFK zmJr3w%=`e<-aA7ykQYul05A^5DT}~cdc?gR#1RHwND(V0dUgnK#7?W7%%>5{=|=Ux);h{4tQ_Z)%y>e+J8L_4f#%RRJs- z$9Je(eGaex8O{_$CI8`Uum-$0b;vcj1oYI-g4*few6a8mmq{#vs>9G!-bPzEW4EaPHwNP)!le2FHIYsr7{eKQ9k3L}4 zo#ONO90t9yKl0nx6cC&%EWIbJ;FQ;vE;{#0e(XxUh?4O8PbG&fx>J*X5TAR8?;Kzo z*0E^<3=B>Z5ryG8f8_p~!Js$Z$*linO(VwY2O!{O&8U#~SmaLyqAqg9v?}j*vO+M8 zF}uBhTo~6GKI13^!+zWk(lpwO5(6N{SDPo}rIExqIOUhYAsEGQZ1K;pok+?V1i?Kg zgxwe8Dm@}1Svv#wwC9Vb=X|fEiTazLZN&k5NYNzxp!;IOT~|?P82Os}TwIkgNpEhp z__qqEHls&UB8mplQ?HCEow;r;H$C!VA2E)tlC1poM|D8*Jc;`+yl6^-w|wpdFb=>d zm5+K}aC?D4;S<~1Zi`(o_03suP<*y?kFF8Z>L-X!wfQK(sx#**kYYm{T}ADQK@q`2 zZ>K`g<&P{=z5iAEiX*+0i#069=%sV9PECJD1tagJL>$WG<{PT6Xxd#bKU)?I;yB`Y z&#@AOM*DCF?XC-RG>IYW8JcY!xBRkL@e-iFZyT9V=v&~APzNe}2g5^Q$3XA-O;I z&BL5S39~cd=+Ol6E*ef|F%2kiW@iq9Gi-e=C?LG-DV-TY89=E>h{C39aVpQp14XW& znag23fsE%9iAu4MR{fYc9ffP{+v^t#LBS;Jc1=MrG7$vl@wN(yEr>kyP&+VOP;`Li z0bk=hIU;=ZyaE)EIL%sWBw{InGKJ7U4h0tNvpO?A3FRM-E^eK(U!ZmL5n7eyDz%Hx zxpZMNWL=E~0E_-uv*cPkYXz}hvWI!&pC>-DjP)uOhfN;m9cTPn-S=B@DU$tgLpY)@1Aos;dr6E8yNCl5u`IyY_c(Wk7}&zoH@_AkVn$31A?s%_2tGwnew~QXC7K4 zr3Wjoaud6Q3y|E^mld(;CgY!}tyGGE=;f_H4bhOHoacOWpx|$S+W+t&M&W%KHYAcc zWx;T}0y(EBe*U#!@8p?l21Ej2rIi%pgy8T+i5U+of>r%mlN$I^QoW#Tw8IGj1REYN zqw=549Pr+V8UEx0rt!c409nElQ)GNjm=>4gIhKW}$Q$LgJ-9uD@S4Er;049CRXP2Q zvPNv9Jm1S;cKjiRM+a0lK**W(@Ydp1W+%hB{X^$v4zOyuwM#4K`OhU-FV6BvQDfFK z)uwgHklvfBpoj33e6aT9)ND{4%;@6j^StJQ zIz52)KSLrpkwyGPBb-}#b6REyjz0DL#Z`-}HMLw$Rm6DmSAz@%YI)w%$MG*3K2+kH zt9{v_;*N2&9Dh)QO_=ZYe){}EMebu#a=kQ`(Dh6|*kH+sE8q!wSY?FN9JOmdFrDmD zo-IcC2KI*oZ{iH0q@L~*?~I#Ej{R+tyj!1 zFBDJ>OXI{MOS5=&Od;SUv23XhCGYQ@0k-zTKq^kkh_aU^&r1YGp%y*8#Wo%hy!$Da zaW|VYe_jFGZ9YMq)V}1#55#)?lz<;_!z9z+P%5FfW79o?EQa(K-w0o=Y*(wT7+w0R zSFns_-?#79PJch9<@O^2aZ$YIB5+>;_r3Cc=BzQrWedjRKN_gyiWKe0hI9S!76}2u zE6RHBJjhP@j`4trzT8`82rYILYFR`*HwVtpM8m#QTrP*B)k*%nEX1s4Rr>r5GokxwLYHHg? zc~125r=G*#Cp>%+bI=?@96(9(jTS3l>rd~VvJO`{CqVy|J<$a}UR-~4dBn%;E& zU35%Fa;)v{PfrTPCv+1K$_3NzKjbxaeU{_Rd%u6t!oFZ0?g}ACP`NyM%`b(y&zFeN zB|{c7`!ne&e~3s^5Ao;-f!wv?Uh)S9Tg*=?A_IYWv{Xc?OELq%u!|3ks{NgLt|fbs zMx=oC*ISYdqQ1F}7t)MXG2|MFZs5*qZcw@yuU2E3PR|GfbGpM)E29Gch12#Ci|)SG z;m)>N0kLJJ(?UY26(21x6OyFh(Fcfb)h*g8TFRoCu@c_4$S>!?L1vXVHJ9I`@CW{@igbZ|($*dA^-%)OZumx8Ecw?lXi_^@jou330D4C2HW16V*9BNSEJ2h}RN7)%Z-}qjcAAu{_M|{`^jLjcH$z4y+dK6Uhdg2VFn>4 z6;6#LwY#7XbH)$-T^x4v10`@bGSIrumUqkAb8BDD{?(T6an3=2NG{gy%8}+IujbO# zA!67q{CUm6+~=j+9ms2?Hqa*Z_15lN*Tc{Dq=^uoS&8@8Xly!YUX{i=3|J#J+h_DX zl%a$bzR{EG+q1y}d0#R5H;^fLuT5PWk0QF7nq`RAI=Gq8-=!&ZN-~gB4VlRFybGZY z(Mp-6t@=Y%fq}L0uA1cy#>wSp`KqolW=RRwvjPX@0~m|>5fTIk3qS6(n^g(z<^SP? zl#mT>Y&4aOM^h7La=<-$w+FC`VM8#nD*zw-x3IMdOG;A1%R!F8r3X>g{+>J<`A zGgMle9{##WZ*}k@%B*G_ovOakM|wRowyBtP=QP?Rm>tXRs}Q*5LQf=(kvPXU;W)l@ ztZC;f>W~<6F73dXsoVffA{A?w#q+UR5j@xmZS`C(i|r5Lm^3=p${&H09<2eCuRmJ! z7h72AZ4Tk?Ak`jm)Nb2N_Cj%~4u!0Sk88DRX03}nrzBJ>3{4t_P32qV#KrlMpLO|> zM{USOsCXbmBT6$5%2BhK4TRpD^p{~cB%YP8n8$2q$$C`Tmh8S~w_L1i-B_EOF6u)x ziO|TkoPla1C(ml6C-gp{r2)|0Tc@{X1B2!m4b!+eD3QThp@ChNt*D5vtG#*|caQB9MvhnO^w)>GcS@Sn zsgh3g%@~%$LkyOEwNDvj^`)QX9+oea^sK=Tk9?(%XL>zRr9Fj}cfELfX41FT6HC-* zJ97qNvUjKg@~C*U@;McS+Y{CsPviSr$Ab3=?!3rQ7&+8aZzT1GpC=DWvKUmiRBAlp zV;^q)ersVuXsvA1aq~g1gWv)b5tWtBQ6;V@qWb-d-bS{I%WuwEpy3-3)|P*s1}c7_+~mHFj!EB zBLY?jCrc+ncsO9+WE66C&X%pJx-=hUm)0UF%Ep5-d{XXo$S3l$C%5d4>f`j5@EHQO zSL>qKu2}nao#X`CA%op}DfWD`Y&~3jl<6kKT zrd<`j?ccDu%KZNws3GzL>sJ~q{+db{M6%4{dU?XTANL>ZB=NV!ni0rlra>-2Hzg6u z%*E}4OSUo;X`vxmTL#TNC-4{ZgK^}7axJ7pe>%lr^fGu?yZxw?6**1YcYOp3?`IH{ zDg*9wPmjVe!CDXQCQYRd6HOfx#Dtq-KL+Qahc1;DkItMs zm`9fq@1w{LFTC3=_j%M*!GwBtY%$8((4F( z`Rk8dM+tD7oQ2JcugY8gNv`|}8WAJ2M>PojW^RkOA!;U($%s$gQbJ2SR-fe63x!_2 z#S8or+P=+H8sK$0ty<)`ge~1vhD`45T~?r!{<+G(0{hU$smQ1xY&>vdYAKLMQSPQV zqdK*t&|!vBPw7h|d9HBz2Wr_yUj_CcmHo%aOEW0uiRlw7*x;NggIL=E6HC*2!V0VEI7(v7kFk$j*d5=S!;JNkz0((3B$}zauh#1BwBZwFJx< z=XxJX`uO;3<83W=yhtw?QgI~`@N(0Is)^F$xvwj(eO6%&d9kS*9_Awe{n1u~q>XLxDAqx1 z%wG9I%EzA?_vucR>2`VAB$2$u=JZssF&D{?Wu~M6=eMnD$cAEz6W=reA0KaMY5>Fu z9Z@MA&v?CIK~>BJcLvlAP+`f*)f%Oa_w)8~(EnZIrP5TriG*^9W&vk~J7P(N#c@0f&@d)Q*T{p<3wv=nMzHHU z2d!SzRn;@ZuDFTgTH2AtxsWF+F6Kskir;9-_1s;20(G3-k6&w;d=;W(_`Um)Cj+W3 zA`{Li9}am&s`lp^o^-a-TQX)Gvt-31Qd!Hnz@bHea*xq|?R2rK=^sc~zGGB9zl3}_Ow+`p(ywosn zsmQmha0$IABGS|qsNs9B@3?`BU*9zIsD_&JW2K}m)emrUFFfNb+uB(2ato-ebuype zCJRAwlR12CRI?oswo^oSle@`bS?q^zHgmHuKiTRqli6Gz*lSBmNm0AgV%(BnJ79@- zOWuE)5lbwcDpGvpN+3xpi%|pPP*C-;8Llcj%L8!?4TI4}nhz^>ch;LFo9mttgmc2^ z3?eq`+T*x#+P9AwnQobPO@7v!Gi!JvbQZ$j#mT%=JJ4KHEo?vbhC^z)vCiWKxAnMj ze}4X>NL%*3Qq2@URDa&kDKC9^zA*Ho<7Sx<GG!MPp8mG6Ew8TXhn8Z=cqaD;+ zIBUHWyg5x4@6ARqNvb{1$crE$v!qamV|CjT1_y7|%14FlJP;6PhdN4N`WVYcl~F_Q zp4e|CaRm$V-C4LPO!3C4=MmZ2<)x7;h4`VMV*&Db=6!y*EeC2>?q}<0S-dn<70sLY z+F|pj#*>1|Qaqf4_9;%zq$*m^7=f2h#Xs!gy1Y9eBCX%*mK+LRB$<6?rOFQzBRtW|q{hX> z{h?+{WgT?la}wOD$0mKZQqUw3T!r%qfH?b|)oPGr98CH$L3AZ&SVU z^kl*-jz>>7CV$yJZY|1ruj)(w@adt=a+03vmbgOj?@lW*b@dl?eq#z4^tzSqTlmgZ z37Tj#4m-wSrmMdaP%dfiW~IG%XYHa7few8{QfSZ}RBU5H*hSKVLmDU2z8V)GjyhsW zX0+atn8CXaZISGGUyIe(H{vcE&@FY>hDegdDNfV&l$rbP9-k^Gt%NEMDvN|Y5M%H1 zyFZlnbHX~IeU_khrLVx7sP4C)EQfSlHnX~@uTQ$E@J5;zNOm%Y8D=)Kv%k}Yq*&6; zbbQHl#=!FVay;d4`lFD%jfp>8G9W7$;;~~A=<>3E`tY$@N6^@)4J%t9PvX z1l0asVhF*|)m#51&OLWql<48pE8pk3F6t8ABJ{Yo+`C}7KL{wfz)A&_!rt4&!u^y` zDd=5C76hoEJw(#HVK$30AmB2TEkIBdnKH>Kr@8K~jE!8STl~i-7m>x{-%(BAK(&X2VLhD^tFHd zk7p&qWYzp4$BN*8DcRF<<@u|9gAXPi#;3*9T4o_l)X?@z9eujhB<)r4+m9pI2M#uYR&VcE!Z{j<(ouC%ipIH;e*M?Pbfam75T)BINdu%@$@f5kD1?ACM=f%gzwz* z<13i?6hI+v+6Dm=7{ptCAUZzhDNJGPwAL)Jqv$?I@&?ZGMk2V1{xhOIE-H3}Y5W$y zb8RFjvEZbUF!O({SP*{Z2$a$CN5a)$JViem2uWAHdnCM?BD%X|L80@NWCYpX^*e} zds-4q)Oypvb)h9+0tu<-zqMbT3|h*Aq|aS;Yp);%5u?2RM5$gTC+dFtbQNRlW|XAy z+q-mkL(SL5Yi2*ONiwkqcpUa|WHep22-7gFc+n9a{NZK%y&{t>9DEQt$d>7iPY4^$ z4ZbhQS!58I7Di2tAet;L-@X_A42ty*?8g04gqP9wk!$k$xl8(c*Jw3Ux&`WHxB61Z zE`Aw;4_k9DvtTcz4~CF+Z8P{sS4XH_b~eVVDwGbN-ZD9PFYn~oq0e7z8NDU2mG~Rf z&aQd*QE<}A4{Lz3_|~+Q4`G<`BaW^Lf!+7<;Svh54omlWcaDJuo3dZkCQT3-bUJae za=-&ivb>t)w(4#5xT1qAkPeGIMU#uNu>Tr_Gphjp^GVY?^vS0(>#PfscrE;5zC!u_ zqpxDGaYy-AzNINR1ga53WyF{IB^lIfO`TB)b`~~S!Y9(KBJZ&%c~jZZjzOc!Yj-HG zYXm!x#BR0z6tBihcZuv!go67j9$Cv*Sv`#<9lbgOu_xo`jL0>y=Z=9EH!ajKs4fxI zqBx_(=d211Mj%9k6L~{7daw8~OBqi98kZC2iHEi|8=ta{8&j7b8Cw2TslU&DCIoiq zebs~yo6k$yFhk;XXIC=WnoLPow6OEYMzPBeo40l5D?CSFeV}!E*0Z^|Xf54pSCaC> z;C@))^C~CZ7xgkd@AWyJ?ey!bHb#H0$>0 z`+{8V+9SPr>#Yg{rLRgt!Q>HpsXsUv6I-c=%Xr`tIwZv|^CpsI(u4^kr5=*=CqrM? zF$o1zt2N%)^k#l9-L6OV&5F6?+zE3+I>^Rl zzgN?NaB;a+<53T%+U#92F}(bgz1pxkc4rii({pobHUOg$gv!{Y=s zJ^y6!O1Jjh@2cPiqi$_us)%^B)y_hQqHU41DDzOjOSpRx^@14k-98dsTjsz!{!&>E z55Tn9-f2it*38c4MvO2R=w=(4gnxMSWjv}bRF4ENA>-OhDz8`JkSCy$-c~&Kdhid_ zW^|DGS(AL#UT@4yB-@xc#RMCU)ZB4^R#6Qd>uMQA^P-3E4ppPR*AUq%C~LLzlIvI? zglgYj3boo8JR`LJKXM2fT$aEz6*3y3ix}WfGGZ^9nrNdX#AVB)@a~rXS$t>;3QgFo zpavbXFr02b$yc=wYNvx`8=6=zF$3L+C+hcR7rUpbCvoLo@w^_Ud3! zQRc;Goe{kYLO}63t)q&C%v<6P@RJmWJL*Kh*x~nZ)DIS6%cn$G9OcsAuDpcHN%xm2 zRI3{u)ofI8$oLx>zCfWxr&ZgU)n?PfZt}Iza+l(6hm3B|FUB6;)KKKpe^=;0r z8f83E@6eai0fZ|f@vR&c%tjtiy9RVfF>EvVj{F0jxsu3-x~p+vjOq_$l!!j@^^@QC ze3*6B3Fd=E`sR;tkZ$s7$=K_rySe=i^b3ezq4w56n#$em3(xSAPS?^*Rv~@b{djMc zls&3$J+v1Wb+)%YpIeg=0ZJ(cW-?StKSH6l%zSk}=^H%yam0Ofw%?g3;iOJ#yU#_peLaQ z{}D@LSpmnd%M}Z2|MKP06SX?*j0wxtcvMQ&4ujbGUc_+*g)1Y5w z)hUWqv#+XDi?V*?QR}%}0-J*);IV*qd-kWkoK*R$Lz~0g+tW9EOrTlac7>pKBl=_K zPj}E!5O~ihf6Wi`1LUb|0yiCr$!DVf#x8$L^6!{{J9;-@8gcVXsbST4#R4x+9Vpb7 z2Ih7i8`Dr@ILhU09qrX6#yg7m<-U`6s`M4MnI*46L37gA_!)7i^x;^nV3P2ZlqNPP zr^9(A-dbgh)FD*92ZyEc1L39<3!5dG>i}+D`M5bW+^Q!{+xBA>ONzvu_@`XrHSR;@ zS?r2JC_f%b1@5CEYe!W7ZbGrkdK@jR#B#ueqD%;JTNs<}EdTk(==?Ryi^?FhStO1Z zJBN)Z;XtrywgvNJ9H|{si58z{o2Xrq0R1$hjOWeJN0QuNboKMdN2VBU#&KfW#M@&i zJnyfn@WCwZ9&6hH3kMRc_h>6o4EHs63k>?4rSz?xrr6$Ed^Z*=<#~Sc_`{5xb*b57=%_hxxMyU~dl2R7*&T+%aLXn7;Q< zd-m_EI(vQZ*g-h-xr}b+qM6kMp+t-`%8Q4#dSk?M5S&O!&67{ZtKq8iKWf-lD2oNE)(SPvFSD1_Do95zc2DESO*<~n0=(}HF zq_aB9gs<4vG7f6-67(E%R3G?h+xN-d5nJBhH`>}$1bb@JJEk-Wi0`N|$p?}+)byHG zl9l8`WF5ZbY70MDvl(8#k*?m_C|GqT_@1IRN1#e-U8j?WjnMJe;Ub&k#I?ICMaS1T zD%9H!YZkTR1=LE5PM7Z4#u4(f`VQwfF2UP=f1r+13VJZ-7Gq8FsC@$)i-09Ya$J3h z$92w7zMTf1tf8+B1bAdR}FCcay zSnBLPx8{CnA{p$0?ZaHHfqa&}d=+=J%<*pUVqjTk7LDFKiLJ&eG{BLYz6i8>-nSrX3M)+vF1^^*=v=v=SWU z-MCN0IWrAR0OuAG^@d|0J3G+jSK_^k10w1dxoq9AEbVnN%*jGj{zH-b@5TIog|~FN zS6zG0-}H^vWc*aKojA=|P|4(RJX<=?Yz+eq-_1*&gHzi*?^AaF*Mo_JB|%c%P=*^9 z_+@7ZAYFNsSh>CZ$o*ueWz^Rm?+GO8l5FI#wK}YtnV*AU+bHoIk%%i`mGILSz~Q+xtqi71 z`rbv!r8{HY~=N4{}@E4Xpm7XO|Y2Wdl~T6j#$ zr8#HBLN!|#`S^(tR(6>!C#V2Y3qS4h;I9qi!G#Pmyjlm0`k&AhkK0yi*%u%ccFb)y zi<9TBOS6vP(N-Pt5{)ZfF$B-!s;NDYf4cqr9SOZs9pvzX7nUfi-Mqe6whhJFjgjnik{x{q&syFeSkv2emU)9_ zz!KejZQ|M^(wC^g8!uaxZNP>eHsBx((g!clktC##OC}EVa#!**WJA1J&rn+t-rk9P zvt48}h~@fO1|_5H|7;}qTaKbrVub{ds<7Ud7d(F_neV*$-?f1dp9jFUGRZ2w;zPPg z9y?EZ#jcL+Dh8*8l|23;UW_MY0g7AWSTuEfR)9A z7#p3{si^J1AEmQ&mB`LL`>`YW1gK?za@Q1Kgc1Bio9M!Q_gpBabzl5!`yf9P-&!;E zl$SZJ+Jvp>xbKF`9&_>KHkVzCBIAYBUuF8AD*&LvpkrVls)jOI&o_(9?y~~T4#Rpw z*gMnJW8U%KDjv?}F4>Md>Iy+;6(%Bi^s+kBDkawQ_~iDTuAB)MJuNa0mu6tS^M6J7 z`qF*H< zeebh%%%nZfPQY*%s1Ys~xB5A%CWRX!NjoqEwQ%(w0-9c36m^P`8%Te2_FYd^MZN{$ zxvCY4hIHR!Nk`ua5i=RAQ)oi{o;pjj>+(ohr`1tr<=rK{dyxpEnrF`ow-*aM8!LNq zpj>CDwO_GdVrDuZEZ{s_U{-)h1X9K#kFIfb3UfBfxlPh<0SD?|l-hfi+=GUpp8J9c z$Gq~l;3jp4`xS?(24{+WNWQ;rOWV7U0>;!c7OCxj?Gf&5c9U{s^#F$z=%ZAMa`Zp2 z>!h(Qf{)xXqV(FUVjT0#+H7swl#l0$O-x>f-k|1-^S$;mX_qKlw(syHF*Vn#3(@bG zIbM6;=63L=#th>1ukMCYtFf@sfQn}pBP(mko`z1VgTGC{&+CoPZ=MLd3Wd2ldeR)6 zz#o;04^FXlb_$*JqKngm!SZpGCGo?&U!1e2zIeKoSoD;CbY?d*x;+ALa8i-hnKPAF zoZYKAJqb%5AFn6G3~lkZRamcG<`afuDU>2g2~l`+N40dPf$_kxmGC$Qub~)xBRizn z3AhM8trE+idj&Pa_L_6nh@*%yvG=FtguBBX#)ImYWo;sduR7Xu9kzS4MTtQq1;^$1mH< z3N41Oy8n_qdYi>FLZ_q;IdJj$lHc4g*S1N={m6edJVRv2}!4DUcj!ea(Bp zm3%-NbMPy_W*O|yi|uR-xquxb<}8@7Sj$`UX+7Wti7EbM98gt+;_mK(r=cR}L6Do_ zDMx8@K+S8pCmFk&nwocKa#oVwEDkV^LAi2+n0buyYC0SQg&dXA_~PE{I(Q14@+!8q z@)6z1^kkjb@=ronem>3R^0XU@#tBveimp6r@@wu&OrytGopC&@(M*9|pI0&zlE{uu zk)^l?m>yjZnZ~#tvRtdO?kZT}tEt?PDj6*euM&#i+f3S8MoP2W(6G+^l9h}TGTRNL zs#q%W$T#YUIe67mkvg>v00+nW5vqa{RvlQ5i-Mc`_W(R5q4)>I>jh>`_x1INk^SH- zdtGX$Xua33pYT`CrH?4A?l?@f^W5!I#&+sld$5wRWH)QXc|A{58zc6_bXS$d_sXc{ z^P|B-fsO6_%bjcJhL0?JCG#aYsvOWEx z1Ctl+_l{;>gpWY(*5MCwlHqnTrPaA4`y@?8tha+lN&O>7pU3)b=SyqGex5FtdQ@^p zwS$F8?eHQqEPx%#5s(P1W?iXyFdws9iBlQPVq3D;Tb03pC0F4x^k}|MaA3^UmE*S>zjTFcX!CmsN@)STlGS%zkO>dq|Uo^m}t7?*onOaUvlg>;#_8wSkb6ivBe$u zQJ9|pp;CCB-+eL#wNZVzyK4JWpGOEaRI8jaQGB!}`}nOU5}W`TKkSN$Y3d}VC-~5`goElFgxp00!F!3b7-83%8Wh=@SN+(!DWP(Y|?3gXf`I`XostQmam`7~~kb5nV(yETHQO6ws(@DAAumdB0B zDuGcc)*RKwZ(4#Bd1xK^7LQfUbOzHD<{VaTawiX4Wq4m5YGnjfKR#j3#NgFhqo!bK z7f-hJseb9}e}wpgndB;29?(5?$*v(431Q7T=BwlE6P-(0C8&7Zq!vXHeB872LZQ!w z@6L_vH{mz2AU4M5B?5Y#;b}#uxt$N=e|J>O|pAN4?6EU zxDU=e&oJom4fFh*qwkfm^q|{wu}!(@Q~Wmm1R*tRwLXnk#h$D!RhjQo>d=;vQ-61! z;L7TJbA949W}VGV6fs^zvgeJ78trSU{l&4-HT;J@fOh2dc74E64c~}9PV#;-lPhvk z?We@`SNya$?rpW%CK232@Y(hPaiXqTqd2y%qN-BA?&q2j4k+yFz za5QxU8$dPE{D~8&A~BaYQoD%p54sL^>p18*f5#aiMgjP{mC;LrA{ zDYc>+nRwcV($1LR~`4xMrPuTdXm{B`@I_HpPl$ex~|`U18fwJwcIbH zr>y{wnP`s`N2P7WfVUMZD<6fM4Io=O^^hKEWuJG`5@kg>73^VZ9n>MMx@0Pq19XhW z>U??tyie-caf@aCTgvXIdv5U#sF5{D)xD9!%#&?u>QW&}kGs0r)Bp6}*I-HN-WQ6rs${vMBwZe^& zgB*RuqcZ!g=03NP1xjeUc-b?iD*o@)5}8UWOdDdVv~eRc9}7WQ=Nf-}@4SUxX!gno{_Y{c{^+xs#P)W~1a-6ugW z(z~yAy^F&6=*Oy6YBWzqr-e0pUuSqh=AgjfhU~fq&E^Doe5Ldq z{6Tv;Q6gd5ovr7IMtpgz+BTa<3*~vqf=r_xqkA9R*Oc~*6vo+J{3O^_LZCVTwe~Mb zn1#)&c6hLG*hBN5rHR9byV`4Vc(*quf*tjAJU9II4-(HLu&E|L{cFTyH+%2uZ6G!cRrjaW>&qj)MPIq(!=*_#xMT2h$v$-Ce2X6G*# zz(ePkv|~*gxq6YWbhE6y_K}u0#Nmjz?uzu%-g$C7r>_&Ocyv2u1+{a_2gaN`(ekZ3 zHIoW6aDm2z9By-UQASbKyA~CKwFu-x3}pSF-GaJf;U0;{E;f08x=@@(hgUN4;b=sb z&@gxW?(1Y_XuBF>?OxfvYDqd)$SGN*j}qZ|c0uGV0O}QQxfNhQI%Hrz-P()ajbSvzteBcTR~=B`k0s6RW1Apzbo~(}=l9zOi1@*f8Ns zk}inFui<47k8OXK_}*_(EDMxh;rPbaiNaVWzAl|$5UhGGIyi+(FyVx&Bu?N7tur~c zU^^NfMY|-H)Fzq|+6=-v%yTCe&52)>WR_bwqj`_7T<>=GLdi-{b-=F94{+Qct39?PBY zp0B19PNfvRNb`ARRN)j5&}nOUI9nLs;9rL>t=DP%>kiMA~)`@~Ng6)%-Y`MG=_FNgM_w0fqo3?xHI zdY)TftMG8hE;5sgdttbrD~bIeBS`sDMEs%(ZDO*);+ zlJ4=OXcN+b%tnPtKf7b-PMudomBkk$JMD(K6uNhEo~Yj&JF?S_fE2v>vrAK286Ab^4udj}4vU~p*1Vs=DL6i^>Q9?o~ zC1;S*Axa8Jmja^(3=BjXB?Kg-yBh{5A_&5yW0chB(PM0Ezk7hs^Z7o{^ZNa>7cX}2 zKG(U(kPO?O!u~`ts=Q`sR7rj4}8p;6Ws!?jgCR( z2HnJ{V;F4a!==+v$uCOjp1pj};*ha}*Gj@+7sgy(xxIYJgTrR*udti(_F>ZP`zPJw zUow9+Ld(=aT{Q+Pk*AgxA??(mz0pRL50qlu3KvKF+-xY9BIDFLhN$QJ?!+vP_Ah8V zZBAy7gLh%1I@&T)Zbb_Y5?dw*=?+&5LVceD>tCOpA3gr-MG?1Pvr43fS zbQH~5C)=iR1^OFNFzaYqb;?6UaF2cgqOcEA08cN(!Q2y0s&z&R)+ULJIw8Z^7RBKs zb#8NZ;0O7yXZ93NzR=(AM7ew0OI2H_r%165nF!f_ko2TiAPE8|4=I+dW}PclO)}4w zTrT59J`@sC8*Wfro;^Y4aWY0ZDSfebe`gZ#+TB(iwl+K-TS=Z~6paqqN6c7njTUP( zIf!d4G^kZt)Tytu(AYF`0gI z?E%LW;YKx)s##k%lFiOd<{0fV_uE{E?|3p;@#Jfdn7MpbhHY>!H{oW}So!twc`w6k zf_`r;VA^sG*ocpQS1(ROODeV)rHt3_{F*n}Jgqf6XJ!J#1Gr{xPTjLyLjAEudGue zpxHZsB-n#mFwZga79GPc8_p#qodm#l7dbb?^o39J&{7VdXY`!naQS4`a1UD-hs_7|q;QSLK0tIvZEuAz zg`Xa4>XzGlC+AGq-7UvHbg6FXD=LQTgY#-vv(P{|;HNEJzuBcMt|7VLkS1EOQmtW! zj*7zZZuVh|xNPs$HS7Q+Z*>!Z)hdY&u@J?tdFWWpI0G20Z=s4%434cGe}bRoV%f@$ zr59F$%|rL3+8erSZ)7~a&gu<0_P;5_Q)A)=<}fjsbAG?Mk<7x)WP>8j``nU96ohEnTE`G z*G){jqsYcL27L^dW6U8_n|i1>sb z*O^E}mmG$asB^VLT4*#X`B0rLrx-1DB2|&qiE(lZEyhgqFv;m1DnjiR@|%SI)ArZO z5?(0-UU}VG;JrXhtDp3TE8gknrkG3(rpbM6g4sMqBkCTB=qT39K?!b;@jIA3T>DHp zy#oH1?jz>A+i{I?Vy~LAn-E@-+!d&XMsL+3SBmH zldVN7!K!t(d1|!Mvu!9pyG@8e+^@5G1A&4wDJ?$FyIxk&oR79t+%6q@n-zJc&bmgY z%_i>#G&PaHTCC=4)R(&d8spd3ujKv6WlI~BNNor7?r2%vssw9ZdK?JqCj9fu%rtU|`4FCJZ!t>MXB+yIk7a zCJ?^oBW}6HuSiW6?<(?h`{~`e7umNd4cM*X<)+%$S5lX8pL1yv>EgmwK6bRu7h*RG z+N?a$P-6%)?7GeCU}2r6Vd<>{$ywazjr(M3oHHqs*8nDa?5B8I0g;W>bl&&3fRp1< z(H=%gf!5Yvd^)n0@o7fnnD_f*b;He-dQJ>npoce$8tU1_PIiaM`$6-cEosOfo*q2`O4GSV$P~%+g8+^MJ4Lodyt_^h zrCI;^x5BH4z%?HY!)r(Bvserqvu8*W{0J?%OZTIkc}g zu-$AORQ#f{v?pjk`g2e5otK%i`H45<*W-$Jyo&qVwbv-v>-59xa2=roK>Szvt2ndc zwV&;0&qxhywlop2O+zkl9O{B-UPKY>_p7%M=%$}v&sHhj4JK|zg`wnb`6MX3>q(?L zUz}=RDYs>E3pumc{eT-PbkqhN4IzUn?R=Jw?BUENufm z{IxK@_jyh?6ai%dX!u+)oAdx0UN6bn-3C{JwY7^Y;Z-NgCMiQ%DIsQsgC&eWN`x6hjn2Bo+dY18fvT9^1M4D-C6rK#G( zkJh6@#wj7DUW&fKbk&Wm+a_!c2UzN$gLdTQbbktoTvzXbCB3z@Unu+YXSFIn^SR;8 zBr4d3?jlfop4Rt-lO*dbf73`lM^lT4#YiQ+gI>KLQ5@(~?EleT!Sqsb)9CV-#U@ol zkLm_IZreW7>1yh^s(|~7US6s-tL|GPMeyZlcB!LiY$Sg`sl*s7_H8$_t4)Xt zfMCVQhdIhnX*aKW>b6;B@oH=@&*o%1NE&VDTS(OE%-LW@E1m1}xwa+_GAkr4MX1YD zmc4Vf1V5BZMvS{yeWgN_7MuQHvd>ckJz%)OK>L|Ddu)3xD{QUp7m9xr>Z%ra=XyWy z%0$~ecAl=l`0mms=)UsT3194|nDsjg_klcHYAbp53UHQlyG=}rn`wVXQCGjmH(v^K z*Gl=3bneDaOlBGH(=Tdj3F2V6YcPUMo1$_jjtYm2B-FPx`R2iabcHo8KoBUiX_Y{0 zSj@^f`LuX@yV@1^O)K_-?H$GJg4FUf@~oqXDJ{T)XQ`7t^XAOn^R{nNupX^3Jr;?f zwTXrKFA%aNLm+3oe*x)vRW0pq6dR75O&5 zShA|@j+5Xja07IoRknK~W>}){jLpm_PLl9b#QQqyb)B|BAkT2Vie`UmKKI-`>e>`u z%*hXRtyzjZv9qThWaNDqEpL4Pk_*7zxH0h}ajhoKRQk&AQNSTnulDKyuVD&Yuk?X4 zc^z(XL)-QyiW^nxJE7|2cSA1e4V9?`xy7Z~C$DyV^#&r^sep&WHWP#hkKG}6Z3C}x!K*-YgfPAa2VW7)# zi4ur(KPArI?`9Wp#?2pG!Op*{X3|{bCE}y`gGvER$}RPRa{EU8!p^oaTL6V3Z#YlM z_s}p2e!$TuG~y^G0$!>ip=BQ6)O%YVE4R5 zPx0U7*t9b3b|E>zL~;UuUwpT-4=6!G>ow9;<5cvLpE(zrg0z1Nj8MS#|kz zpK&c8U2$W`;(Jmax7B4S#|4ek*$0g(aT!W;yI;(OG`9D!VgE>I==&aPAQ_|6VW)hR?N;co5k zZp8*|{i4UV+fp)U)Y#fH}m{}^-_hNgQVE&!@s#p50EgM?pOA0;#O?{e4)47t`182Ni z2e_ui`0NLNl7Ve7*({IO5y)xm-eg17ie7Pxa+1qF6(#9<#L{N{o2D)68L;lS=N7d| zeQsC3yLc{_fR1AN_+Vq6NH=?ETJBXGrhPU$&S(m}S&IzrYV#eSkssq=jd_SnkkeRA zw=_V8*G!>|+_$>tAW&L=Qo5HN3vyZ55MM&w{$9gs`gT&&Vux@Ep?S{^Je;Rv;>Z&H z?B-(8yEFMO72q|_qtT(rs$EyO9{CkAa;wFU#01xZsydJV)?H+g96Z&2G`W6MY`k`v z=GK!kH?35lV$c3AvH-Hm10^WY8N^1+o}%C(q@IXTZHwt#cro-%LdRItQQ1+)tMk!! zHh~9zl-m?_SrtF!EW4igzIvsFL+Wc{aA;P@N~)utGr3I-36&Y@PHv-wE)a$tlZMM6 z8(z22ToM(%g(uMXc{$%CznByEU8Gos^b;gYl?vLx}{MU7@g3GmYf3&`B=bk{r4=`9h;`3EV?2 z_weI6P}0Mt^+(xlYvW>BcK2gE&RQ0!_nyus^ybW{wdrfW4fpdh)av17PM>cOzjlW-1p{Z3< z!}IX?TRVPz(!fqfS<+oU$U-_N^Cm7v4y)Mgo|BvJvMVc-JQb@ z+%Io%u{Aj7;p;f6wxj9)j_u61*a4_uUJ+n{d?gE$wm_E_FLC&|?DkC*7mlmDV=`{l z`E7?)Cf9wvEP>E(s&48Ynb&7WEGHB^^tM@QnW)fO^ZKwPUEZdJuy0D8;;C25(pP(! z)&piZYyKg8Ihoy{2>YIN;89UQMPjCpUK`|>*n(VJ|C2%vYI4WShm@P^rvn#1t*0xKYyyiz8AZvcuYX(WC9_;MK-87bYH8=uM{8d-d=|%%_>LzurU^2Xn_>On4@>*iv zKCL+n9%&ebgey#ytQK3KoFk@sipy$|p-oN=Obr>!*A_mNSXK@NA2^r}ST#YN%!7b{=#kKOMW#pI~q+U`kDY#Rz#Pa z(mQl~+KFX_Md1hZk4ZSy%$uCpAPAx5ZJJ?>pb+M$c(BS}(qNnu-D2~4@t4;1H-5f_ z=i*Z{!q0;JhfUe}BOf60?{})6=6x>Tq<&6CQXfb;2wl$kkT;IgL6FVO3HEuVZrx4F$cqqY3eUDI+Z#A3 z0<-1|yGnO0_roK$+)=rKJ4G|YlDsyljUO5Yc$3sR2E|n;04)pBF;!ko!@lYkNkT5Z z@4i3IX{3UYIDf$Odl5 z99i)&sI%wK0jgqvzfN`9#}IhPT8JAuB)9YO?MPfRZ4hiKD$ z#XEhVs~JrLmO7Y#T)dgFR&az}ICUPl&;dY~Stq@BP1Scanr(Qjnvs23XDUpeDIwbm z2wfG|_k03hfa~wr!b@q}tDAG>MhPgeSzs>Q<4G_#v`eQr-SUXxhFh?@w(iOZ8K^x3UV?6cnfh8z zOl~G?(av*DN>y~jPgEI|O_w-{@m=Mkr!m&EA^(T?7ZSSS6a?AD1c@$hLpPj$$eE!AQH;ZApaYL*)7?F4d}l z1@wzLqVj#1^JFo0DMq!CG^Ai6>RBCSncPwB3`GXRF9IvSaK=t4_AQqcUwpJ~!C_-q zyY^JMaSBA|yYM}w*yn$PBMPOOE=~AOjw^8a8*OYweGk7)PnK>vUZ1OzJu@Bw_nMgi=^w;w?xwNL0bG!XydKMq9=VP%a{YMHF7y0nbt(I znRS7|PR${wjy&n;K!579i~X6|`oGUqk2_iYOfY7S$&Nkz@($y01;$s1;~6?RVHk(B zwEEhgtu_*nDY4?AuJz;W@v5q*JOu#B=$G=RXv0{`_E!fK0yy>|`y<(1B_Z7s2-$tB z?ZDg*+1x8_$32ArEdgI?ZFDcTX8b{z)LbB?JbMW|BQsyEanRd9JZ7bw8*?YBy2fs9 zT<8N@MJZw4M-2b~2!LpBG$~b#sMttQsRuo+Hq9C<=`k(A4^x41Ws&J#Ei0h%Zkn;L zopb+TOocDP0+D6Vu+7Zt+LrIZF&ogU%ekPd=0Hsx;0JctT zkLZcxsw(X>#P$;B*Sr!O&whS;dxk=p{QF-o<9OA){-vc00R016PNcHN%LeG?=J$If z5&#rM^?Ek`BNKu+a2kKJ5@(Mii^_44b`K@s`E-V+;A*@Ux_gKX0u!PqfT-Q~ZOKf< zp27IwL*n|?K>@F-RU5d(Cl5{uy%ITfR)kXc>anZ}S%$hr@V7cjCEJXViq1(T&@$7oWL&S5*KW1>GgytcJ~!v2jP`ZY;f6eSNy? z1*0)lojSu`9i>4D{#kF#>^|mHsw~DRrVstW6y%TtqKO~a^<9n;4+CgPEl-O}Fyl>| z_8%FPx#ePh+_|s1vm0@5rR&-uS*?5}9w-x6bo8Q0b1LaQ19n7@s@F3*63*7qss2BH z!=H5}E-r^NFss?H*wACfbA*D@fih6r6QW5#x3A?y@t3#8o~1*VYJlpFug|`SAC4k_ zHMQq%H;YRY6HksEHLGL?6^AYd=TV=^v26W4M%j6wZa_+?>Ik*;M1b@e8_9Snc6{L? zeg;25x01sN02F@6=6Vm{y94ZsCX+?%)YfjyzuV}!OT_qN5FUn1tq)h2|MX$btV+9a zNWuU40Ev?V`5)`@JBazmz;EElL0--I?dFlh-SI7E{__cD^VPCSWq|LR@mqz2=_As%g1vfV8XY1Qw1}hGI_(l z_b)KDLv0Wg+`Lb{oTeT9{>JI^B5}{kb!?CH1f?QKrz7XXI!dZKp1jFx7{JdMqdKSM zuY~?k7Z0>P0szDix8J%!?}^)q`%p}`zUjDjO>+x*1#p=E(ltBzHeB>NKBrhqnB&OS z7$vpdUbFyy76>@>QI`O)thMnTCqb1%IC$VKL~*%FMvTFmgvSbCZfdfoU!GhqcG?N* z`h2`lsk@~6bDnuqk&grn6F8A6_UfzPU|UwIE1ZWa;eq1Qodl1c{KWzxU=G1BCKaw% z0OT*v7mgQn6U2D(8_r+2)cLF@H&UI^$wEJ+^iUs*+B^h8U+Sp*r5yo|*$4-WXh_eq zL4Hk{Q9laQmJ`0qndx^*6MD=V)n@8*Pw-3kwl=@sAu28f9omIrKvNuc{Bm=agZFab~GyE0Klr__uQrg3TbV%6RdCXg%kc!!~GGY=|OdqLN&>i)o`gmx(7>{dbfeP{^+vitS%I>J3oB< zt?A~=9itGUdX>>&dFqC`cF0eLs%GxEaNrszpD8(C`0?83oHuMyF}`2;ef&~+xX7Z}$I?%GGFZ9obQ zH;L(4pf}CUb^ApUhOw5a1p=%KfU!V?)4nz-(FI_#zF5IGwd*=#6TJW@Zfu#V!I&4g z#pZ|_fTUW6$3OwT>*O{Bb^`%kuu+I$i|btZ!T*rh{!eD%dMpem@rrj`hE&{N3DO>EL)Ryxco zv#~=Rs+-&=Q_pY7AD3yx>TG77p#L2xF_xEU;CJlruB=I~#^5 z05byub-zlNs92t5nU$87gf6{b@19jqkZa5cUF`=7A7qHORKPt(&B(Sm(=}y2zqt;* ziL!)*aT8(V-c#K#iA`7G#`TG@ifl9Fb9eGR4Zo6l7hM6?af8Zjv3G##Y^}vKnKNHJ zZ{PLA_=ql1##Me*FRxl#@B{w7>GhT_qJ_P8Gl$5GKeGgsi~B0Vq${qW;TzROk4u6u zhv+*f+!wO&dLHWSWWb(#i7YvMyoY|TY(B(>F{pP|msn<-MZ|tdsWorFSl=+m%p?t1 zVNavt!TJ1MZBqF8uxn|r)+Th$6Ucq?Our&4o!m7>kj$S}td7t}ecWw>pw8ffKCA;>jKCoV zO4UkNm@gPt=u z0O;Lto<744Cr<`XLX^tk0`xyhbwwVqnN*Ia90WfEaRp!O`()b0q+fo)$Wh^whqiXS zwM_LD+e<`T!hjsA^-qjD7t(wvW=&EpJ0B@PRVW#bH1l7pNg>+M+$82h_Xon0T4;SP zPK?@=LgmkTQ!oUafa}Ts3epAIC6D#~k>LtVT>&r%(ri`u4y$Q2f!k0MhXyP?c8?7z z;Q2iReTH-@5TNT?t%g z7sK~c*5ThMQvj%-9PpM+>xbQkvP*vDS7X{&{zVAOgkU7S&YxT7KpY9AyIvi#rt;;{ z(SI=C|A(G`k+QprKK%y3O7I94cpQ4X&=efB3eB<_BglMVY{`E?GJ)^_w%Cspfjfu9 zGXyo$DYE{KaT`yNpv?Hja0I0dupubR-#57ouHSQm`>0v)f7lDGkcuL(IK8&^c8B-D zMBYpFZ3~}BAYLTki`~r}4sJc1=;6mA**0q?l9wCn6XOIK{M(%WTTEt6ftTS}T*-*s z4+x?XmCLEM9o#-q9E~7UaZhJv9w$SAbrU6Dag9#S-}aF|421t*qW*yy3nC*^U+U@O zZ_NVdb7?XM|1EUM{=VU5aJ@JBCsqFD+uvWO09BH$Ls|V4L~%&HKzjYt^R()rIx**d zb7%Lz0dz{>TD!HBbpH|=U=D#y96TAn5&ratlY9Vb?uImhwq~+idzO-(W@@hTAN|bH;Q)U!`v&_Dr@-;LSy{&0 z+t9bHe6+!^Qu5nnhd&j46wyWg$#L6b8Nj<#^j{_XtpWa8(;lMJjmkqo(WU|z{juks_EyPXx^A6pOzYk@?!kX; zsGww`+}NK#YFeQsA;H?~D^R@yS!f>aRid8wbRzxrgCb=f+W$Gm|EvuW?2Chn>TqZk z<7PR7_C{ZS0kAVg z42ES#m?^-Vc&JHaXclXgl;O(WCV)ZnH#`6Q^?|%2855Lg;z4MPn0eEd0vCyAIpz2VO@F)kw3K+&e6k?eh zIEb>9xEZFZoJ_7u^b>)Bdx0yNZ+f58?sbhyjySH2{7Z%p$Ls-=*wuZ<2WJjPy22s+ zY?cL_kbW?Tz$ZM{I=)tXxl6x zZU?|h=68uiOt1vdYyA-_5C?(Od#z_HBKg&}^nVH_4=YhPvI}{Rj^&d?xgJ(+bcQM_ z&9PsI2Ov3zo4Kdg|Kgn=`F2A(@-nx~=|!)g|I#Cxw*igBpl+z8eaIaO3RVD?({<4@ zz2UtyAR=DXc3?6U`9HhvM8FuZ7>aNy6>ofxEA4;n-qaG{oaHUpO{+Lw*^9RvYA%U- ze$;=Dy>5K}sS?@f>puqp$O!X8PqCMorPP6`l>iQ1)f75i)k!#TXr_Fjc@8pplX8JIgHnGas`B|0yhTZSv{vDnj3!UiT<_ zMnXm@4}$Z0oAkJbyic~+mQF`9|L1;qLEI0lt4acgWM8==Y(5(^-`lC+mHDLJstO|Lc>C-$n!GU3tsZda3SyTe_Go|tcnBX+&Yllf8-*NlHL!bmJqR$ zaY_)AY4)i_Qn_}D5ugw>siVFgJ0*04uC3-2gpyZ->kv{(wWoi2@=l@puJ4#sFv2eFre|$Tv6`( zx)dSIRRrDPm*l!DYrX30=NeivRMO{e~L$cy3RNWv(O_~$)X^mpydGhp9o0X z^-#w7(nGVqP4aJeJj5Mbp(FmEg!K3U;vZ*I0Db%0UPtT-@fVa7E0seNt<(~Jg~Qg9 zwUxa_&{ghMOC|vkJ0dCcIgfHmFHz z8WnMo?JEBAI|gXVw@Ka&bnt_JkWR}X+(7#BUSPH3Kqzrid{;_5H+rYDiYE3!`7s9U|DwH1%i2lf2g_gar*}MTjca~go#0cVRcoF=iKSwLO3pO?GS*cLcC6x4zbn^=O@>0Kf`@i(76SMhAH?PzoSXT=M}qZX(iJjwR-N5h=Fwq6_|r(Iy^YV8~Rk*D!#B#Hfl zR_=ca*tRmDZ&IFGK0KVG3!NG!v{2&u+ldm*kcy%G$=yMJ(zL)ey7Xn$NOp(4M! zcHM7_2I#T|;LRPw%R&yHJe%F@3YXCzgA(?qLriOmJQu#4uF8Ez_HJck=^$8c%)Tkg zKk8CzK9W`Q=kN>Uw47Q>V^^s-AmNWmt&`VrlV5WChbC4~zn}g70Bnyvv~`L=mFz*t zbQ=p)lzy+Yau2B}!4N_4Y!Sc9VO9!nbPbV%VlTDgv2gw??YhLh{ePME@nQfM4HQq9 zaeAzOK!Eb|JTqTAqtAKxoW+Hp6H#sK(1N|}O8XG8NrF=!N0e1O>Xxf}=`z2&b5$ph z^x?bloKOd0QK=^2T9^k50ZNTXHSoCXRvit8r95pqGM5F;V*YbRC8@&}5i;a2-7@Dn z{#Wl1_ZSF8PWEQIxnGG>1{6(BB=Bq|i0qv-X7+sR{*D}9vX{4g>5G{_^R29u3x-v0 zL!U*XdHCcH=Mt#&w0hi%soV->@-x2Nw6rB$B-m@~9FO}rIEy2a)6PQgXfl6q>r;kL zBVXPN6_Of8C-j~NhHqwI2>Sio1L62+)wFh>_vzJ1e7}wcqlWaxmd^*v!zs?q#fe5c zVS=|<4yVXUDq`K3Hf$MZ%*@BNo*vLb`G2`eoD&ThFsBn*7Y+wbB4`LeWc6(H4dIz2_C;kJZ)x?tO6cwJ@dc@11c zmE-(ReTFThkj=2Or3=}nd!ou}nPum^`N2N>Ko66UiGk_m)t3-Rg?V^!FbI#6fH>=C ze(Ja>9$=l~TUE1MB(-#%{lzz}R^X&qUVc?4T(HC3zpJ_Sg`Sq-*5lR8ivOfOC%QQ% z&Qx0nzR8GmKF{FNIXPzJ1MPxUTAaJH4dfiag+Gkj5srM756NE7g4s1RgCGzWl$kzz zJqUkR6yh8qV{QHD?o?b8PQC>qND2+))*;ZmR}0F}}*`Q1+GpZn)X1^y2` zs&`4a-l%?2&<6zP-%FM!upTm6>?4%V=zbqg5K@2nza*4Ql0q8SexEJ8q`rex4)Y@--$>eWnPa_}uqg!mGZ7>P z+;vRQ5~Iq}l{xSEyyZZq^PvK83b6tDTqnD5Ao?F#i^%l=5<1WIFVrWswObvoJtq%Y zTKt0rFqwc7LpUJ(DR6sHil;I%f|XOXrhbR9ut+>+;S2b9*`_mA?Y`di7*5brb23$S zk(=E`_x@{L1FA^jvRH?W&L~^{D>Bw)Pur@)(g?=(@oKKIC)&ADbqLnq&V3ksZk&|0(LkC+YPZ%_8 z#uVScKZna04#M<)YkN&Ip?}Oo;1>p33!aoCOr(;SFj={Z=Cyj**2dDTn!%PChw4%z zsZmKID~BckcC_-e;|v|XiH+AV!wL1KeJeLRIdA;c52>}0o=+)D?^8Z>Fk`1D-q~7Q znOkL8?n=%kYWin{A6Z^a6-Jk%UQ#ghR=Ub*SM{0XaYc~LfWPDv}PQVw^QE?oiaeH}Sx zx-||-fj^yXnuAC*DM+Q`?i5)M&fSxkh|)8Xn+TJ`j==5iGto&ARB$ z*yO0aqEL4LHCJYN^7EYi1BeWM&!SbvV{)WarUN;@td&f_IujmY)gPh)J!7R{`r0xb zlh?hZ#Ig9F#YwU06CUGWMMtoxr4kaE(zSFxRtSRWY}-y&Ld(~oq+rO+GEu|sl=62z z5n}uyj%3#iL7MH)s{NOVhs?hu_~`=Mx#19h3qMclrD7*|ITcc=a(}=%|@uFz>Pf|OZRsXA%M}!$M%R2 zDp`PAS2S?n%{)1iz%TdQ>^?|+G)}g2NF6a#ZWK{btcT4!NXM*L)`KDA?n7ga)g!H6 zH^4;*7{*ld)o$|t}6MM5*qi&E;`@541 zzT~L3WmIFMywM0CQ#U;@A`q>nMPF7lY5?l%h}dk~s`z6G!vvP&BW@Vo*%aD*;<-}V z`rBE$Y}mdSwl!{H67FK!uz6Cg_)@%rOk5M%SF9S>_)dMsg~PyU7!a=p!}0T_#h)5o z;p3HPwd@||={hQ=%Y9`@ohVdO(~MN51)>rho%zJKV@|_TaI${UB;sH-)Bpz2XzcM{m?q~?~nqW+Li0V@uXQ1@v6Q<*ZxDq03(FF2(X@QMqhj~y&_qgw$-Qu zQu=g0NwH@!n!tPqp3mOd6Tg-0Ix$iaF~?6>koq$f>7e}hE+@3E8-EQmzhjnKr5&&20<$O4n7tU5+`w4K^y_X zPBGTfZML(aHmDlEeC+Mf?C~vDWXf|~uK}XMzH^vq=l1f?CZ4a52Hwpem+E?}evz@S zo@Lt7Xu8>fJb_IY`KgXYsGl7js@zGN?A-(W>Zs)AJ0Bg0#|LM<@OSQ15l)RBy&}DZ z#?|1^T<~;#!MF%LyjxKSuPM-3lH%esQtGpbbp((<)>a-)=g zZF{03;3C}!LGN+9o<&|xGUshA&a&9|SLY2>&_K2dxgl4oO;@8oR$a;L{}JQS_)RFC zu-q;*I{q2c)ptPj&QS$6{^`a9f)*d~iS zcoZ;jDYQ)M=eG?-kC37+UtSViG)oV55ln;%_to~@;(n?4v~(fKlZj#Lk&+o(WoxZn$(u$3A80Y$70IO(JK!hDpw25$$8ZTBZ+%9{$CT`~6EAZzABp=(Qs&B zN$W!oI*;AVg4`&Il3cX7lUcKN_cWVP6Wn}1=VI;EvFSS>Lm5!-aLJ+KcecTA2RbiV zQZ9Q!xm!FV{JJTceS@u3>~kKF$jwsaCjCjGV$V(W8UW+AL(jL z`@I)1&n#KrRV2#kwYuKamk5R@VjFyT9eXqj^{CRaHvlZj#cK&=S%zTfnRo$hActac%=l68dcDbhM@todwOD-7#>9S*!p|akZe|E2 zMUYkE=(tGuKI*r)-zCfC&jA)~!&|LhK&1Q8{d_N}Kl7=6t)Sw=*nN0zf^vd)*!f zXf1NSZwyy+EhI3lZ?14$b#(Un9mSSwvVn_<&`|ek+uJeS|0Au3~XV!}`DMP3^il6N|WTMfCJ3bd0c2lp=_)spp_mO8xx5!Rd#u@p^ z-xmgXU$$DgosO3cN8W<6x82+*#;q;xPN-QbrP$_WR!l63BqM7Sb%K$#Bf5MyU+N_% zz{)KMKq_00C6g=6N~_2^x$SXm-+}2lVXAshg)0=?ur2d%u}WPNT0gGK2)$5$oUxkg z&~rIg(AE$$S}HSPKWEL?XupXzPWDK)##~k%;)N-M#Y(^O0XPPcJ!nYNDy@$09lv0OP>dcl$k#xvd1?l+m5wp>iJVc@S zQ%72#u02j$D49SJ+tEkPb0XrGFb z&V?s!*7iK{>l<=r!;o)=RYD6TIc6FbQah!P;!b0l-9&mYSXHYqi!bV(G5# zgaf3QL#O`cX13`&B-SF~leE~fCLAp{S&RQFN|CQ9S&?p$Kgrv{sNAC(n+lQhC8HZ&>lL=SzI`-FkO*%(omWFTQI1Mj?S}DmRt3?Pb@I zC)U+nb<)(jx2qo}t)Uiz;C(4g2cbTdW|){_AIlbRRhFpikBwX!bLXafOm8S6eM4_C zq^z#BZF*t6y=K!se$O)w1{J#`A=oDKeP5s^z2FJ^TTDs6SCijv`WjX_Ju0$Ub`Rf> z4ewr#7I(aS;F{FUhO%zhnsDuwT28lnFj8Ezq@$+R5paSIbb;jLs-3dizm%$MA)|xeAr~HOX=_eOy_+UbZpo zZF_f%He;L}P(~@yK)dkXqh`J>I&P~+CGCDbLhD2aCe&SK)cwY4>}hj1NY`ZSr|{cL zYHS)Z8?)6FGV_3UYX@AR?X@6!g(|H<2%y%zcJiQ()RlHLA?#_ z0`h}A;M5G19L&}zlK`2=od)BhW*!L$Sd$RAT#}Z>JOeITXFOq#7LPU7% znXxm*J{ijx%lN&g&x7jW>hrt4|9rpKRe!xN-S_)_?sLw4?z6n^GsM5R_}?dY^ic>3 zSe0{fHkBh+DP6qJlcMZgV%RXi2im-SP4d;*0~!PiH(y&Gn8KZ4kN~!|qT(qR*sz(& z1htV>FxckG?bb8*zL}RPd(et9>iz*K;rLp|_P%`A+z9=SOm;DnlqQ^F!$aKUg9?FS zt=IvP3AF2UV_5h^#h3`Zc+vZIDWv-5Y=r8_#`EB)gGCaRg~6>06e3nIKfI@z9){MI z#$z5x5)|pd4#5%3Vy*F)JDRsPi~VM9{Cyp7B-om~Jhwza+mu*~;%;>iCHXj^5;tw} zcs=_pkNS|FKIc$q>VTR4+!8eQP&!yV_wt&2wpCJ-^gV&1p;y@$m=A6sx5iDG&hEa( zHQnS-Y=x`^+RGpolOisR+6-zPobY_D_4=tQ?rHnr~KcoSX^J zHy_NbEw8sa9%rT>EuiXUQ!C2$P*r322I)W@-_{oJQ!Txsu4k?=pl;@axWE=P@iTK8 zq`u1nKInw<&^WlOS)1s5`BVYMva;-x7m%tw4hgP{<_twbXK6hq`~zt2IU_O$!uX?L z=qkaX8Ta^&Rqf^!A9=TF{uY(&nYxwx)crx)#$V>YHen3l1O+oLzy`bx3t#f;wUj4m zm5*ymxg;p+mpo+F(qwwZpNn`LhrCTz-jiXIkEEcyG&QX4m+6@*@finvN(@u;XRo>_ z6bG;<9gr*bKsOAyBC|&8B=xR<=7bVj+ckr{>mC%?@gzRF`a&svEk?n7%GtYoGiC0p zeXI_txm?inV~#|PGlH+Zm6hdaQ-bPzR&(-UbTsFwG0}NxSX#P)@yL^H=yD zO3asyAypL89#;oboD5$73e+pXf7Z`gu&NXXgg=P9&~Ub}WyG>#?9FI3+0l@>B4m!M zNgC@z?FNUZH4kiq*Xk&)fa<$=VaBfY8R^y`ixWUt+LSiamM3OlWI33AsJSyumRg06 zr1+zL|Av>(8xJU|VrXMR_;|X@sjl{W*R3v4ae?Nnb>FUey?OOcn?gAfIM0tfbUnRS zTAV^TO$z!hlH6UEx=w)?uZzr7OBh^RGXJ9#-P@YZ10oORF)S!q&4;MY;RPGw{wy6x zHd}tuoXfd_u)!?c8Cb^SBe#qaHNjtpWwuI22;6h_rTPiCSzRiGMgQbsSG(G5$%8DC z5HM`J$?!Q5p0tuHg4vYo4LPj9$X6YHo@Z>^k?&QmF8 z^0FN|bp2z;L0w);jyU^txkls#lG|A?JO#yDb!U1p2XfqXWdH6$SFNJ#(qi%J-9rqJ zJU50TCmSKckoM?De_!tp(mWaFCXb?yH8VXJAoY&ME=$8EQ0peWun9x0JXFA7nbt5%%Wu7vG>jl?X|K zZmnm23`6E?qYx{0`8crnxn%|DY5|Yj)*JE{sDG zSgxg2r7m9gn1;Da9>19t7TJ~ZfdG^tJfl0u&7YDx$sU<6U2n|+ZnA$2JKlh*d4@u7 z5!QQ!&mwIt-W^ndEcKi6>BN#6QKAv4Y1pBhvmbSfd3 z@3*8&_Pv8c8mww-4!yrWIddW#cGb6@FqslBIzQSwHdKn9Pe!)3XwT`u?*#>53(gaB z*T@9*gz4nDnoF*+q6b7>>Re6*pY)hu_vv?OC^j(M3}|U*_6XW|)5k};P;pPw57s1o zZL<yjQc^lC{5A9k-R=O7`)F0pJau;8tAnw=(E?L_7idvfe_`Eu*> zdt2_F!u#}qbV2iZ_E=?$=L;PxDcyfrFe^s2&Mc$f^p)el&4C*qP(a2y(;?K#wAFB> zb0Fb zVeG-@sARb!5;|u+)q}c+DhjJ+B4tcgtHQ!iXumm0LXxj-et>%sf((wr&i9PG2xd5C-f-i?`QEPlYulgnsMHx2E zzG;3f@|GT`#sVgfwH{&k^IRdGTmVyI6|{6$R43)oy^-V#%M~f?yjc6#591Y1L!Gud zwMF^~?2w_?wDAFNvC0i^){q7rx99TvjgO127j#&ehe#N?Ue6z>@PIfXGC8^*9ypi8 zmUhevW*uMI7tKZU*X7Eqc1prHSLdb)rj~Zc!FgjNy#G-oU3L{8i~7YuGxfncprQtW zArQ&}YWb>Llnc8)S4o|QrEsh1ftJngS9g5|m@ws? zZQdj6Y!8t=-nhY{UZ`nge(Odk0>0(hHDgl~WT(c^*Ehw4nA&Kcm9)f%tc|EAu8O`g z;({vxRS(zN5fmEUS=r8$#F-e2hOy)9JR^*7eQLOI@t#|z+@yyMf%?k>;iS>M>MsCH z0j18E{Ip1mWBjhQaRTo-ux(SklVf~@(Hh)ZnkveTnSpwSSiJLI5|nFDmDCu_i^E2Q z&wAHAn*3@+n9q;%4APoyR>;xCk3_tFGo4r-^H3xiQl|G#;U%?8n8{eWUrU-5NUi*& zG$m>ySpY2WE`qB>cQvUK7wrT5EqyFuwOh00~q!&Vc8~;ydlHzML#*OME0o z!LF4W=Or30z6llR1Qm(_$b^lm(B%^Nn8eJ*m_x(o+Dg)~v>qQ9`&%l@flvpX{zv;Y zqgK9zPn}yEUHbe+(5$E-8PtLDz|X$$_shL)SCL{_cI}@M(lZS3Mo}1tqO;4MZPzew ziXFsybqtp?5e3pM;g~x}vMn=<&37dZ=icS$l_sm){wrvsG@?4>PMc3LPG|GO(|1HX zR^U48!y{u7_OYV_FUUvh#G@n3V_HFe5hgAul$FkqWb;7@^+audHuW~|x|ge}Tz^QE{az@z(r5w?8pgF=cS=$%v~Xh)&6~q=5Qf6t0KbaE>4JMW{QsnWCUh+37Wtme z#j#K+#x(K74p#Y8#VI9|syr+7O~lZ&0N6P>1?2KZp0J=a`=tm|wchPp|I%dfeT0dY zEqrt3IFobxW0rVcAnn3Sn2m-Q7-c;{E|#Ilpi%*=WNru+i4mq{sA}n3HHWuzZK5?} z8(%?gAJV*24)I_p!cF+nuOe1L!wbaVoR;ITCKyaShXxgrDUF>`Ko8tSUYdtd)HRB( zjOxrrjVAPAJ5`p$$8;svjW9WzA1Ym?Lbqhm^8k{e_n~PAo1>asgOhIC7f1Pp;YVkt zad*KNn~YCz-dJB-IBoH1hRH%1)Wi~BSsR-?CQ<0nb!q;&;*>-v>W3v zRt|!r$n;a;?hPhF735=s!G1JXaZ8>4ulPRIe#^))BlGpIQgX4HO_8ZDUH$8jPvy`*7u@a9yjSI_JED(~2tr-P@| z6R$a~a07XszY8Q#>en?!n%exjIOdD_gVBP1+G8)NayAq<2cof!lFgVr+IxK%oUZZV zX3{J!pvP)f5%m6EMxNh-3~SQ1a&iPnUA=KB8uyUruyxi%F+HQvrDlS8&E{ENI>0I^ z5grE2b z8a`9Mo^3Mps4_#X*rU#gu1ygS6lSlBK^F8>9lf)0Mz(wr!&(yX#FA6ZfPCZQG(2?i1>#%K@aK~c9%q_q5BYjk3J5Tr!q@Y8LdaE} zbL7*l&L;YPVv3hu2px_F$FNBXnW&-_N*BdOU(9Lv+NOhHi}o=Nh63PARDNSo^;z)B zRG@W5I+B#5u5_V!nSw!4;w?6`8oFAzkqYyE&6aq7UCzK2lGx?wx)^4{bR;2o%1lVm z5R7d^UUHQ$uV1jK+8WS5jVLt8cfCPR0n2bwwp#?ezruA^@Wcu5xvC{fD>o*k38yIc`FgUI1^^n+n~ohwV|Z=a8#=nr`~H(*g4e|3S3bKDB_eBmhEbuP%b0K$t4?yBFK`?RRu(mS_abj(KBr*Mkm zw4-u#c3it=ldlKUxy0!E>E74o+9aDjin0{I9Br8AQ8cOgsqQ&BgmJ;bOzo=Wx7|pn zFAZ95{pCHZK?r-eNS1|^V$+rnx)Q#^)4$Z6d(}G#Z3jk_$qst>U{THkOQ)9~OI0#x zO#pcg8wL(p`EyJEDa48>rnJ0PyvNCf>C5|zFs*FE8dg!x#$#w ztUvvx{dujt;q?|j-;xwxDi_WAGVW8`u&3%Sy2hZ*V`P3*Y6D)H06(5fi9dNE zht6)bISTzw2c^ba*_8XVK^KQx8xZKZUjXJSRLU>1cWLFf#h^qhC^6|>;gz1u`r=z= zcI!(OX^UQ3tn|B2YDOGww~-qA4SfEDzG zRW3!Qkk_28JVx=jLpyJP*?0UE*nC67y8vfPXEJVlK~d?Rm3xHZe*0Wo^bXgqsh3elEu+ z!5s@qJ8w;$w~bGGW(XkSp3Y#V_l%SQf}fByw}Q*Rl>8}^xBT3syNNy##Tr>Lygn;h zECRTNiz>0(8cBLl4*)ej?LWZ#57hc!qRrwY;@m>w9Q3q!OdNeLn+3s&cy7;%jxkx% z0eK<0%XTk@l8gR&|LC9f@gE@}fa6G=VdwY4q5y*)u~JJjhtl(1`h!<2%^mxRBV>8T zuj|$<5fn#E%lsKfN3wbHi&Z-C17KfS= z)Xwqik#wf3<&uF^dX|k~-{?A)3}jRe=XFOv|49scfU^E37O}}$%XfJ6?~iT&Nf$PFH!*5ynhfcfIK7OwbSEW zdDGMqjls3McPRX8XhpDJWzJCgqQz~#A^G>>oYWTSIcoDcD!*I(8--^=gP6S~$KX5Nky%NE4k^UgkCZ{B+Hz4Pc)3kCGf?&$(i@br~_a*khZ=xy^IsD+Lx-%|Vl z9gZx=loso{tWN_#^W!RqWIOWqMnC_!uoRkLsmQTdUf#h9bM*x*Y))197#FhOm>9139d!kx}rc>2SzdZiY zdk0)!{^8V&rW?C&(j+1DFwwyt?QLvWPpv+(?K`*c*4}x~gX%~M;C|JUK+WU-g$D5w zo7}up-krTSy8*z&N#LZB>4?md{`J^KAXhogxO=jE&x#*;Epv{Q(_E2JLva5gJDO1n z zpza@U-XVS82Y)u;uEv$~$1@rC9kR0qe;|FOnDgha&lXnx^Tg|Kui3P=PvW2H`|fCu zJPP!t5aih_CHB*-Kv}@eioE*T`n%ab4cU?6eLz`C1NXf0urub{!*6B%t*pP5^|xjH zZCQU?*57Wx{|z@_SPp*XhKvUNcb?EKJ^yvzk|Llm5Z?*I4&dTN0SHOlAgsayXgs## z!F>1dh#N?}*Vu_(*ons&SpD(jtusnixI|GMDMb_Wy{G!u03O?wRlAJCJ08;^)~};h zogu<}dL4^Ts^+4fdM2bF+uMsa6(PEY3ZhxxZWR+9nd$=+6$BS@Ttzhb=Q!k|n8iL< zI&0YgPgMk=erd;lIV?3CL3J%7J+$4(bsrAh!MT;fad;9qN$Kb&15eGBDo!nB!GbvK%SqZO|XG$*pjt${>LymtM5`4#z zZxZh!`rIxEeU%*@;W~e>zoXuawDq)-{60DWAuhAa%0_VKl6FR9bsUU`5n^?F z`q{PhS@ATd_h+NkY4 zWGX`T@k#(R(=2e&_|~`n8UKn#mSli1K~fX78(AhD^>0^YGn;^1^;g^6gh{tI$98_%8A0e++bP zcNG_JnG*aLUl`kMl{$qIt+#Vx*zW)SKtNJFut-<%%I<2OvHH`i#c5Y~e0pM+vjP|= z#GSa~`^`QB5Iw+oEpUgVYEp`;aYSoz>Hy~Cp0gM&-cDJZAHQVjQ`ppPrs^}qqLcQ<6EHGd>4252CmkvVaTVcRI|FBvHZ zV2>_+ROkJkp?fdaAL#HynW^anwA1_Ldy|9#6Yn|3N&m}{52R873N*8>(eCb>A2s1S zp8ieTVwH~3NB;{7Gyn>ItMLDB75=TZKPz(5Z?z?*_}^}M|0ilo@LMvE<~MMD@#O&U O?}nVJY|eGlhyM>E3O&F8 literal 216903 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 Lfd*>7&AI;o{vu>S