From ab6391da4f226627b2f827c102d1f28aa21a3cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 26 Apr 2024 11:31:09 +0800 Subject: [PATCH 001/125] resume from step --- funasr/datasets/sense_voice_datasets/datasets.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index 6d9b03505..226342c35 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -159,7 +159,7 @@ class SenseVoiceDataset(torch.utils.data.Dataset): def _filter_badcase(self, outputs, i=0): b, t, _ = outputs["speech"].shape - + if b * t > self.batch_size * 1.25: beg = torch.randint(0, 2, ()).item() if b < 2: @@ -170,7 +170,6 @@ class SenseVoiceDataset(torch.utils.data.Dataset): for key, data_list in outputs.items(): outputs[key] = outputs[key][beg : beg + b : 2] - speech_lengths_max = outputs["speech_lengths"].max().item() outputs["speech"] = outputs["speech"][:, :speech_lengths_max, :] text_lengths_max = outputs["text_lengths"].max().item() From b3d8864bc92045f490a82abef8f2300c2e2828ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 28 Apr 2024 21:20:22 +0800 Subject: [PATCH 002/125] batch --- funasr/schedulers/lambdalr_cus.py | 42 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/funasr/schedulers/lambdalr_cus.py b/funasr/schedulers/lambdalr_cus.py index 19ad7a8a7..e3bb1fb47 100644 --- a/funasr/schedulers/lambdalr_cus.py +++ b/funasr/schedulers/lambdalr_cus.py @@ -2,28 +2,36 @@ import torch from torch.optim.lr_scheduler import _LRScheduler +# class CustomLambdaLR(_LRScheduler): +# def __init__(self, optimizer, warmup_steps, last_epoch=-1): +# self.warmup_steps = warmup_steps +# super().__init__(optimizer, last_epoch) +# +# def get_lr(self): +# if self.last_epoch < self.warmup_steps: +# return [ +# base_lr * min(self.last_epoch / self.warmup_steps, 1) for base_lr in self.base_lrs +# ] +# else: +# return [base_lr for base_lr in self.base_lrs] + + class CustomLambdaLR(_LRScheduler): - def __init__(self, optimizer, warmup_steps, last_epoch=-1): + def __init__( + self, + optimizer, + warmup_steps: int = 25000, + total_steps: int = 500000, + last_epoch=-1, + verbose=False, + ): self.warmup_steps = warmup_steps - super().__init__(optimizer, last_epoch) + self.total_steps = total_steps + super().__init__(optimizer, last_epoch, verbose) def get_lr(self): - if self.last_epoch < self.warmup_steps: - return [ - base_lr * min(self.last_epoch / self.warmup_steps, 1) for base_lr in self.base_lrs - ] - else: - return [base_lr for base_lr in self.base_lrs] - -class CustomLambdaLR(_LRScheduler): - def __init__(self, optimizer, train_config, last_epoch=-1, verbose=False): - self.warmup_steps = train_config.warmup_steps - self.total_steps = train_config.total_steps - super(CustomLambdaLR, self).__init__(optimizer, last_epoch, verbose) - - def get_lr(self): - step = self._step_count + step = self.last_epoch + 1 if step < self.warmup_steps: lr_scale = step / self.warmup_steps else: From b512846c2ca0cb0e28b1cea6c9980b2d04e1d7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 10:51:20 +0800 Subject: [PATCH 003/125] batch --- funasr/models/sense_voice/model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 07fb4eb58..ae20902cf 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -329,6 +329,8 @@ class SenseVoiceRWKV(nn.Module): stats["loss"] = torch.clone(loss.detach()) stats["batch_size"] = batch_size stats["batch_size_x_frames"] = frames * batch_size + stats["batch_size_real_frames"] = speech_lengths.sum().item() + stats["padding_frames"] = stats["batch_size_x_frames"] - stats["batch_size_real_frames"] # force_gatherable: to-device and to-tensor if scalar for DataParallel if self.length_normalized_loss: From 8f596af4be1c2e5c4e4b4a7008ba96f412d40fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 14:32:43 +0800 Subject: [PATCH 004/125] batch --- funasr/datasets/audio_datasets/scp2jsonl.py | 13 ++++++++++--- funasr/tokenizer/abs_tokenizer.py | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/funasr/datasets/audio_datasets/scp2jsonl.py b/funasr/datasets/audio_datasets/scp2jsonl.py index f6ceb6977..f16717301 100644 --- a/funasr/datasets/audio_datasets/scp2jsonl.py +++ b/funasr/datasets/audio_datasets/scp2jsonl.py @@ -7,6 +7,7 @@ from omegaconf import DictConfig, OmegaConf import concurrent.futures import librosa import torch.distributed as dist +from tqdm import tqdm def gen_jsonl_from_wav_text_list( @@ -28,6 +29,7 @@ def gen_jsonl_from_wav_text_list( with open(data_file, "r") as f: data_file_lists = f.readlines() + print("") lines_for_each_th = (len(data_file_lists) - 1) // cpu_cores + 1 task_num = cpu_cores if len(data_file_lists) > cpu_cores else 1 # import pdb;pdb.set_trace() @@ -41,6 +43,7 @@ def gen_jsonl_from_wav_text_list( i * lines_for_each_th : (i + 1) * lines_for_each_th ], data_type, + i, ) for i in range(task_num) ] @@ -69,11 +72,15 @@ def gen_jsonl_from_wav_text_list( dist.barrier() -def parse_context_length(data_list: list, data_type: str): - +def parse_context_length(data_list: list, data_type: str, id=0): + pbar = tqdm(total=len(data_list), dynamic_ncols=True) res = {} for i, line in enumerate(data_list): - key, line = line.strip().split(maxsplit=1) + pbar.update(1) + pbar.set_description(f"cpu: {id}") + lines = line.strip().split(maxsplit=1) + key = lines[0] + line = lines[1] if len(lines) > 1 else "" line = line.strip() if os.path.exists(line): waveform, _ = librosa.load(line, sr=16000) diff --git a/funasr/tokenizer/abs_tokenizer.py b/funasr/tokenizer/abs_tokenizer.py index a629e94ff..e125d292b 100644 --- a/funasr/tokenizer/abs_tokenizer.py +++ b/funasr/tokenizer/abs_tokenizer.py @@ -62,7 +62,7 @@ class BaseTokenizer(ABC): raise RuntimeError(f"Unknown symbol '{unk_symbol}' doesn't exist in the token_list") self.unk_id = self.token2id[self.unk_symbol] - def encode(self, text): + def encode(self, text, **kwargs): tokens = self.text2tokens(text) text_ints = self.tokens2ids(tokens) From f57b68121a526baea43b2e93f4540d8a2995f633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 15:15:24 +0800 Subject: [PATCH 005/125] batch --- funasr/models/sense_voice/model.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index ae20902cf..d06776b40 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -310,6 +310,7 @@ class SenseVoiceRWKV(nn.Module): speech_lengths = speech_lengths[:, 0] batch_size, frames, _ = speech.shape + _, text_tokens = text.shape if self.activation_checkpoint: from torch.utils.checkpoint import checkpoint @@ -331,6 +332,10 @@ class SenseVoiceRWKV(nn.Module): stats["batch_size_x_frames"] = frames * batch_size stats["batch_size_real_frames"] = speech_lengths.sum().item() stats["padding_frames"] = stats["batch_size_x_frames"] - stats["batch_size_real_frames"] + stats["batch_size_x_tokens"] = text_tokens * batch_size + stats["batch_size_real_tokens"] = text_lengths.sum().item() + stats["padding_tokens"] = stats["batch_size_x_tokens"] - stats["batch_size_real_tokens"] + stats["batch_size_x_frames_plus_tokens"] = (text_tokens + frames) * batch_size # force_gatherable: to-device and to-tensor if scalar for DataParallel if self.length_normalized_loss: From dd927baf28266c47acda6ae8d72b206526676201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 17:10:29 +0800 Subject: [PATCH 006/125] batch --- funasr/datasets/audio_datasets/scp2len.py | 121 ++++++++++++++++++ .../datasets/audio_datasets/update_jsonl.py | 64 +++++++++ 2 files changed, 185 insertions(+) create mode 100644 funasr/datasets/audio_datasets/scp2len.py create mode 100644 funasr/datasets/audio_datasets/update_jsonl.py diff --git a/funasr/datasets/audio_datasets/scp2len.py b/funasr/datasets/audio_datasets/scp2len.py new file mode 100644 index 000000000..5d742b17c --- /dev/null +++ b/funasr/datasets/audio_datasets/scp2len.py @@ -0,0 +1,121 @@ +import os +import json +import torch +import logging +import hydra +from omegaconf import DictConfig, OmegaConf +import concurrent.futures +import librosa +import torch.distributed as dist +from tqdm import tqdm + + +def gen_jsonl_from_wav_text_list( + path, data_type_list=("source",), jsonl_file_out: str = None, **kwargs +): + try: + rank = dist.get_rank() + world_size = dist.get_world_size() + except: + rank = 0 + world_size = 1 + + cpu_cores = os.cpu_count() or 1 + print(f"convert wav.scp text to jsonl, ncpu: {cpu_cores}") + if rank == 0: + json_dict = {} + # for data_type, data_file in zip(data_type_list, path): + data_type = data_type_list[0] + data_file = path + json_dict[data_type] = {} + with open(data_file, "r") as f: + + data_file_lists = f.readlines() + print("") + lines_for_each_th = (len(data_file_lists) - 1) // cpu_cores + 1 + task_num = cpu_cores if len(data_file_lists) > cpu_cores else 1 + # import pdb;pdb.set_trace() + if task_num > 1: + with concurrent.futures.ThreadPoolExecutor(max_workers=cpu_cores) as executor: + + futures = [ + executor.submit( + parse_context_length, + data_file_lists[i * lines_for_each_th : (i + 1) * lines_for_each_th], + data_type, + i, + ) + for i in range(task_num) + ] + + for future in concurrent.futures.as_completed(futures): + + json_dict[data_type].update(future.result()) + else: + res = parse_context_length(data_file_lists, data_type) + json_dict[data_type].update(res) + + with open(jsonl_file_out, "w") as f: + for key in json_dict[data_type_list[0]].keys(): + jsonl_line = {"key": key} + for data_file in data_type_list: + jsonl_line.update(json_dict[data_file][key]) + # jsonl_line = json.dumps(jsonl_line, ensure_ascii=False) + source_len = jsonl_line["source_len"] + jsonl_line = f"{key} {source_len}" + f.write(jsonl_line + "\n") + f.flush() + print(f"processed {len(json_dict[data_type_list[0]])} samples") + + else: + pass + + if world_size > 1: + dist.barrier() + + +def parse_context_length(data_list: list, data_type: str, id=0): + pbar = tqdm(total=len(data_list), dynamic_ncols=True) + res = {} + for i, line in enumerate(data_list): + pbar.update(1) + pbar.set_description(f"cpu: {id}") + lines = line.strip().split(maxsplit=1) + key = lines[0] + line = lines[1] if len(lines) > 1 else "" + line = line.strip() + if os.path.exists(line): + waveform, _ = librosa.load(line, sr=16000) + sample_num = len(waveform) + context_len = int(sample_num / 16000 * 1000 / 10) + else: + context_len = len(line.split()) if " " in line else len(line) + res[key] = {data_type: line, f"{data_type}_len": context_len} + return res + + +@hydra.main(config_name=None, version_base=None) +def main_hydra(cfg: DictConfig): + + kwargs = OmegaConf.to_container(cfg, resolve=True) + print(kwargs) + + scp_file_list = kwargs.get("scp_file_list", "/Users/zhifu/funasr1.0/data/list/train_wav.scp") + # if isinstance(scp_file_list, str): + # scp_file_list = eval(scp_file_list) + data_type_list = kwargs.get("data_type_list", ("source",)) + jsonl_file_out = kwargs.get("jsonl_file_out", "/Users/zhifu/funasr1.0/data/list/wav_len.txt") + gen_jsonl_from_wav_text_list( + scp_file_list, data_type_list=data_type_list, jsonl_file_out=jsonl_file_out + ) + + +""" +python -m funasr.datasets.audio_datasets.scp2jsonl \ +++scp_file_list='["/Users/zhifu/funasr1.0/test_local/wav.scp", "/Users/zhifu/funasr1.0/test_local/text.txt"]' \ +++data_type_list='["source", "target"]' \ +++jsonl_file_out=/Users/zhifu/funasr1.0/test_local/audio_datasets.jsonl +""" + +if __name__ == "__main__": + main_hydra() diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py new file mode 100644 index 000000000..3ce96ca78 --- /dev/null +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -0,0 +1,64 @@ +import os +import json +import torch +import logging +import hydra +from omegaconf import DictConfig, OmegaConf +import concurrent.futures +import librosa +import torch.distributed as dist + + +def gen_scp_from_jsonl(jsonl_file, data_type_list, wav_scp_file, text_file): + + wav_f = open(wav_scp_file, "w") + text_f = open(text_file, "w") + with open(jsonl_file, encoding="utf-8") as fin: + for line in fin: + data = json.loads(line.strip()) + + prompt = data.get("prompt", "") + source = data[data_type_list[0]] + target = data[data_type_list[1]] + source_len = data.get("source_len", 1) + target_len = data.get("target_len", 0) + if "aishell" in source: + target = target.replace(" ", "") + key = data["key"] + wav_f.write(f"{key}\t{source}\n") + wav_f.flush() + text_f.write(f"{key}\t{target}\n") + text_f.flush() + + wav_f.close() + text_f.close() + + +@hydra.main(config_name=None, version_base=None) +def main_hydra(cfg: DictConfig): + + kwargs = OmegaConf.to_container(cfg, resolve=True) + print(kwargs) + + scp_file_list = kwargs.get( + "scp_file_list", + ("/Users/zhifu/funasr1.0/test_local/wav.scp", "/Users/zhifu/funasr1.0/test_local/text.txt"), + ) + if isinstance(scp_file_list, str): + scp_file_list = eval(scp_file_list) + data_type_list = kwargs.get("data_type_list", ("source", "target")) + jsonl_file = kwargs.get( + "jsonl_file_in", "/Users/zhifu/funasr1.0/test_local/audio_datasets.jsonl" + ) + gen_scp_from_jsonl(jsonl_file, data_type_list, *scp_file_list) + + +""" +python -m funasr.datasets.audio_datasets.json2scp \ +++scp_file_list='["/Users/zhifu/funasr1.0/test_local/wav.scp", "/Users/zhifu/funasr1.0/test_local/text.txt"]' \ +++data_type_list='["source", "target"]' \ +++jsonl_file_in=/Users/zhifu/funasr1.0/test_local/audio_datasets.jsonl +""" + +if __name__ == "__main__": + main_hydra() From 03040b04e24acc7cd024a258b259841efa5adead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 19:14:13 +0800 Subject: [PATCH 007/125] batch --- funasr/datasets/audio_datasets/scp2jsonl.py | 1 - .../datasets/audio_datasets/update_jsonl.py | 93 +++++++++++++------ 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/funasr/datasets/audio_datasets/scp2jsonl.py b/funasr/datasets/audio_datasets/scp2jsonl.py index f16717301..f4c9d745e 100644 --- a/funasr/datasets/audio_datasets/scp2jsonl.py +++ b/funasr/datasets/audio_datasets/scp2jsonl.py @@ -29,7 +29,6 @@ def gen_jsonl_from_wav_text_list( with open(data_file, "r") as f: data_file_lists = f.readlines() - print("") lines_for_each_th = (len(data_file_lists) - 1) // cpu_cores + 1 task_num = cpu_cores if len(data_file_lists) > cpu_cores else 1 # import pdb;pdb.set_trace() diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index 3ce96ca78..6fe377cf5 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -7,31 +7,68 @@ from omegaconf import DictConfig, OmegaConf import concurrent.futures import librosa import torch.distributed as dist +import threading +from tqdm import tqdm +from concurrent.futures import ThreadPoolExecutor -def gen_scp_from_jsonl(jsonl_file, data_type_list, wav_scp_file, text_file): - - wav_f = open(wav_scp_file, "w") - text_f = open(text_file, "w") +def gen_scp_from_jsonl(jsonl_file, jsonl_file_out, ncpu): + jsonl_file_out_f = open(jsonl_file_out, "w") with open(jsonl_file, encoding="utf-8") as fin: - for line in fin: - data = json.loads(line.strip()) + lines = fin.readlines() - prompt = data.get("prompt", "") - source = data[data_type_list[0]] - target = data[data_type_list[1]] - source_len = data.get("source_len", 1) - target_len = data.get("target_len", 0) - if "aishell" in source: - target = target.replace(" ", "") - key = data["key"] - wav_f.write(f"{key}\t{source}\n") - wav_f.flush() - text_f.write(f"{key}\t{target}\n") - text_f.flush() + num_total = len(lines) + if ncpu > 1: + # 使用ThreadPoolExecutor限制并发线程数 + with ThreadPoolExecutor(max_workers=ncpu) as executor: + # 提交任务到线程池 + futures = {executor.submit(update_data, lines, i) for i in tqdm(range(num_total))} - wav_f.close() - text_f.close() + # 等待所有任务完成,这会阻塞直到所有提交的任务完成 + for future in concurrent.futures.as_completed(futures): + # 这里可以添加额外的逻辑来处理完成的任务,但在这个例子中我们只是等待 + pass + else: + for i in range(num_total): + update_data(lines, i) + print("All audio durations have been processed.") + + for line in lines: + + jsonl_file_out_f.write(line) + jsonl_file_out_f.flush() + + jsonl_file_out_f.close() + + +def update_data(lines, i): + line = lines[i] + data = json.loads(line.strip()) + + wav_path = data["source"].replace("/cpfs01", "/cpfs_speech/data") + waveform, _ = librosa.load(wav_path, sr=16000) + sample_num = len(waveform) + source_len = int(sample_num / 16000 * 1000 / 10) + source_len_old = data["source_len"] + if source_len_old != source_len: + print(f"wav: {wav_path}, old: {source_len_old}, new: {source_len}") + data["source_len"] = source_len + jsonl_line = json.dumps(data, ensure_ascii=False) + lines[i] = jsonl_line + + +def update_wav_len(jsonl_file_list_in, jsonl_file_out_dir, ncpu=1): + + os.makedirs(jsonl_file_out_dir, exist_ok=True) + with open(jsonl_file_list_in, "r") as f: + data_file_lists = f.readlines() + + for i, jsonl in enumerate(data_file_lists): + filename_with_extension = os.path.basename(jsonl.strip()) + jsonl_file_out = os.path.join(jsonl_file_out_dir, filename_with_extension) + print(f"{i}/{len(data_file_lists)}, jsonl: {jsonl}, {jsonl_file_out}") + + gen_scp_from_jsonl(jsonl.strip(), jsonl_file_out, ncpu) @hydra.main(config_name=None, version_base=None) @@ -40,17 +77,13 @@ def main_hydra(cfg: DictConfig): kwargs = OmegaConf.to_container(cfg, resolve=True) print(kwargs) - scp_file_list = kwargs.get( - "scp_file_list", - ("/Users/zhifu/funasr1.0/test_local/wav.scp", "/Users/zhifu/funasr1.0/test_local/text.txt"), + jsonl_file_list_in = kwargs.get( + "jsonl_file_list_in", "/Users/zhifu/funasr1.0/data/list/data_jsonl.list" ) - if isinstance(scp_file_list, str): - scp_file_list = eval(scp_file_list) - data_type_list = kwargs.get("data_type_list", ("source", "target")) - jsonl_file = kwargs.get( - "jsonl_file_in", "/Users/zhifu/funasr1.0/test_local/audio_datasets.jsonl" - ) - gen_scp_from_jsonl(jsonl_file, data_type_list, *scp_file_list) + jsonl_file_out_dir = kwargs.get("jsonl_file_out_dir", "/Users/zhifu/funasr1.0/data_tmp") + ncpu = kwargs.get("ncpu", 1) + update_wav_len(jsonl_file_list_in, jsonl_file_out_dir, ncpu) + # gen_scp_from_jsonl(jsonl_file_list_in, jsonl_file_out_dir) """ From a883f2342aae400552b628bab973d8a30346a613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 29 Apr 2024 22:49:35 +0800 Subject: [PATCH 008/125] batch --- funasr/datasets/audio_datasets/espnet_samplers.py | 7 +++++-- funasr/datasets/audio_datasets/index_ds.py | 2 +- funasr/datasets/audio_datasets/update_jsonl.py | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/funasr/datasets/audio_datasets/espnet_samplers.py b/funasr/datasets/audio_datasets/espnet_samplers.py index cb30a28e2..e155cd7fc 100644 --- a/funasr/datasets/audio_datasets/espnet_samplers.py +++ b/funasr/datasets/audio_datasets/espnet_samplers.py @@ -71,7 +71,7 @@ class EspnetStyleBatchSampler(DistributedSampler): self.max_token_length = kwargs.get("max_token_length", 2048) self.min_token_length = kwargs.get("min_token_length", 0) self.length_scale_source = kwargs.get("length_scale_source", 1.0) - self.start_step = 0 + self.start_step = start_step if self.start_step > 0: logging.info(f"Warning, start_step > 0, dataloader start from step: {self.start_step}") # super().__init__(dataset, num_replicas=num_replicas, rank=rank, @@ -146,7 +146,10 @@ class EspnetStyleBatchSampler(DistributedSampler): start_idx = self.rank * batches_per_rank end_idx = start_idx + batches_per_rank rank_batches = buffer_batches[start_idx + self.start_step : end_idx] - + if self.start_step > 0: + logging.info( + f"Warning, rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num_before: {end_idx-start_idx}, now: {len(rank_batches)}" + ) # Return an iterator over the batches for the current rank return iter(rank_batches) diff --git a/funasr/datasets/audio_datasets/index_ds.py b/funasr/datasets/audio_datasets/index_ds.py index 70581e825..385218ae3 100644 --- a/funasr/datasets/audio_datasets/index_ds.py +++ b/funasr/datasets/audio_datasets/index_ds.py @@ -35,7 +35,7 @@ class IndexDSJsonlRankFull(torch.utils.data.Dataset): with open(path, encoding="utf-8") as fin: file_list_all = fin.readlines() - num_per_slice = (len(file_list_all) - 1) // data_split_num + 1 + num_per_slice = (len(file_list_all) - 1) // data_split_num + 1 # 16 file_list = file_list_all[ data_split_i * num_per_slice : (data_split_i + 1) * num_per_slice ] diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index 6fe377cf5..561811e8e 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -50,8 +50,8 @@ def update_data(lines, i): sample_num = len(waveform) source_len = int(sample_num / 16000 * 1000 / 10) source_len_old = data["source_len"] - if source_len_old != source_len: - print(f"wav: {wav_path}, old: {source_len_old}, new: {source_len}") + if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: + print(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") data["source_len"] = source_len jsonl_line = json.dumps(data, ensure_ascii=False) lines[i] = jsonl_line From f4f545b7243435116f3cedc4f42cb39bfed3331e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 00:06:43 +0800 Subject: [PATCH 009/125] batch --- funasr/models/sense_voice/decoder.py | 202 +++++++++++++++++++++++ funasr/models/sense_voice/model.py | 235 +++++++++++++++++++++++++++ 2 files changed, 437 insertions(+) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 133508fad..4986d5065 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -335,3 +335,205 @@ class SenseVoiceDecoder(nn.Module): x = (x @ torch.transpose(self.token_embedding.weight.to(x.dtype), 0, 1)).float() return x + + +class MultiHeadedAttentionSANMDecoder(nn.Module): + """Multi-Head Attention layer. + + Args: + n_head (int): The number of heads. + n_feat (int): The number of features. + dropout_rate (float): Dropout rate. + + """ + + def __init__(self, n_feat, dropout_rate, kernel_size, sanm_shfit=0): + """Construct an MultiHeadedAttention object.""" + super().__init__() + + self.dropout = nn.Dropout(p=dropout_rate) + + self.fsmn_block = nn.Conv1d( + n_feat, n_feat, kernel_size, stride=1, padding=0, groups=n_feat, bias=False + ) + # padding + # padding + left_padding = (kernel_size - 1) // 2 + if sanm_shfit > 0: + left_padding = left_padding + sanm_shfit + right_padding = kernel_size - 1 - left_padding + self.pad_fn = nn.ConstantPad1d((left_padding, right_padding), 0.0) + self.kernel_size = kernel_size + + def forward(self, inputs, mask, cache=None, mask_shfit_chunk=None): + """ + :param x: (#batch, time1, size). + :param mask: Mask tensor (#batch, 1, time) + :return: + """ + # print("in fsmn, inputs", inputs.size()) + b, t, d = inputs.size() + # logging.info( + # "mask: {}".format(mask.size())) + if mask is not None: + mask = torch.reshape(mask, (b, -1, 1)) + # logging.info("in fsmn, mask: {}, {}".format(mask.size(), mask[0:100:50, :, :])) + if mask_shfit_chunk is not None: + # logging.info("in fsmn, mask_fsmn: {}, {}".format(mask_shfit_chunk.size(), mask_shfit_chunk[0:100:50, :, :])) + mask = mask * mask_shfit_chunk + # logging.info("in fsmn, mask_after_fsmn: {}, {}".format(mask.size(), mask[0:100:50, :, :])) + # print("in fsmn, mask", mask.size()) + # print("in fsmn, inputs", inputs.size()) + inputs = inputs * mask + + x = inputs.transpose(1, 2) + b, d, t = x.size() + if cache is None: + # print("in fsmn, cache is None, x", x.size()) + + x = self.pad_fn(x) + if not self.training: + cache = x + else: + # print("in fsmn, cache is not None, x", x.size()) + # x = torch.cat((x, cache), dim=2)[:, :, :-1] + # if t < self.kernel_size: + # x = self.pad_fn(x) + x = torch.cat((cache[:, :, 1:], x), dim=2) + x = x[:, :, -(self.kernel_size + t - 1) :] + # print("in fsmn, cache is not None, x_cat", x.size()) + cache = x + x = self.fsmn_block(x) + x = x.transpose(1, 2) + # print("in fsmn, fsmn_out", x.size()) + if x.size(1) != inputs.size(1): + inputs = inputs[:, -1, :] + + x = x + inputs + x = self.dropout(x) + if mask is not None: + x = x * mask + return x, cache + + +class ResidualAttentionBlockFSMN(nn.Module): + def __init__(self, n_state: int, n_head: int, cross_attention: bool = False, **kwargs): + super().__init__() + + self.attn = MultiHeadedAttentionSANMDecoder( + n_state, + kwargs.get("self_attention_dropout_rate"), + kwargs.get("kernel_size", 20), + kwargs.get("sanm_shfit", 10), + ) + self.attn_ln = LayerNorm(n_state) + + self.cross_attn = MultiHeadAttention(n_state, n_head) if cross_attention else None + self.cross_attn_ln = LayerNorm(n_state) if cross_attention else None + + n_mlp = n_state * 4 + self.mlp = nn.Sequential(Linear(n_state, n_mlp), nn.GELU(), Linear(n_mlp, n_state)) + self.mlp_ln = LayerNorm(n_state) + + def forward( + self, + x: Tensor, + xa: Optional[Tensor] = None, + mask: Optional[Tensor] = None, + kv_cache: Optional[dict] = None, + **kwargs, + ): + is_pad_mask = kwargs.get("is_pad_mask", False) + is_pad_memory_mask = kwargs.get("is_pad_memory_mask", False) + x = x + self.attn(self.attn_ln(x), mask=None, kv_cache=kv_cache, is_pad_mask=is_pad_mask)[0] + if self.cross_attn: + x = ( + x + + self.cross_attn( + self.cross_attn_ln(x), xa, kv_cache=kv_cache, is_pad_mask=is_pad_memory_mask + )[0] + ) + x = x + self.mlp(self.mlp_ln(x)) + return x + + +@tables.register("decoder_classes", "SenseVoiceDecoderFSMN") +class SenseVoiceDecoderFSMN(nn.Module): + def __init__(self, n_vocab: int, n_ctx: int, n_state: int, n_head: int, n_layer: int, **kwargs): + super().__init__() + + self.token_embedding = nn.Embedding(n_vocab, n_state) + self.positional_embedding = nn.Parameter(torch.empty(n_ctx, n_state)) + + self.blocks = nn.ModuleList( + [ + ResidualAttentionBlockFSMN( + n_state, n_head, cross_attention=True, layer_id=i, **kwargs + ) + for i in range(n_layer) + ] + ) + self.ln = LayerNorm(n_state) + + mask = torch.empty(n_ctx, n_ctx).fill_(-np.inf).triu_(1) + self.register_buffer("mask", mask, persistent=False) + + self.use_padmask = kwargs.get("use_padmask", True) + + def forward( + self, + x: torch.Tensor, + xa: torch.Tensor, + kv_cache: Optional[dict] = None, + **kwargs, + ): + """Forward decoder. + + Args: + hs_pad: encoded memory, float32 (batch, maxlen_in, feat) + hlens: (batch) + ys_in_pad: + input token ids, int64 (batch, maxlen_out) + if input_layer == "embed" + input tensor (batch, maxlen_out, #mels) in the other cases + ys_in_lens: (batch) + Returns: + (tuple): tuple containing: + + x: decoded token score before softmax (batch, maxlen_out, token) + if use_output_layer is True, + olens: (batch, ) + """ + # import pdb;pdb.set_trace() + use_padmask = self.use_padmask + hlens = kwargs.get("hlens", None) + + ys_in_lens = kwargs.get("ys_in_lens", None) + + offset = next(iter(kv_cache.values())).shape[1] if kv_cache else 0 + tgt, memory = x, xa + tgt[tgt == -1] = 0 + tgt = self.token_embedding(tgt) + self.positional_embedding[offset : offset + tgt.size(1)] + # tgt = self.dropout(tgt) + + x = tgt.to(memory.dtype) + + if use_padmask and hlens is not None: + memory_mask = (~make_pad_mask(hlens)[:, None, :]).to(memory.device) + else: + memory_mask = None + + for layer, block in enumerate(self.blocks): + x = block( + x, + memory, + mask=self.mask, + memory_mask=memory_mask, + is_pad_mask=False, + is_pad_memory_mask=True, + ) + + x = self.ln(x) + x = (x @ torch.transpose(self.token_embedding.weight.to(x.dtype), 0, 1)).float() + + return x diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index d06776b40..c12107e7a 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -476,3 +476,238 @@ class SenseVoiceRWKV(nn.Module): results.append(result_i) return results, meta_data + + +@tables.register("model_classes", "SenseVoiceFSMN") +class SenseVoiceFSMN(nn.Module): + def __init__(self, *args, **kwargs): + super().__init__() + + dims = kwargs.get("dims", {}) + dims = whisper.model.ModelDimensions(**dims) + model = whisper.model.Whisper(dims=dims) + + # encoder + model.encoder.downsample_rate = kwargs.get("downsample_rate", 4) + model.encoder.use_padmask = kwargs.get("use_padmask", True) + from .encoder import sense_voice_encode_forward + + model.encoder.forward = types.MethodType(sense_voice_encode_forward, model.encoder) + + # decoder + del model.decoder + decoder = kwargs.get("decoder", "SenseVoiceDecoder") + decoder_conf = kwargs.get("decoder_conf", {}) + decoder_class = tables.decoder_classes.get(decoder) + decoder = decoder_class( + vocab_size=dims.n_vocab, + encoder_output_size=dims.n_audio_state, + **decoder_conf, + ) + model.decoder = decoder + + self.model = model + + self.encoder_output_size = self.model.dims.n_audio_state + + self.activation_checkpoint = kwargs.get("activation_checkpoint", False) + self.ignore_id = kwargs.get("ignore_id", -1) + self.vocab_size = kwargs.get("vocab_size", -1) + self.length_normalized_loss = kwargs.get("length_normalized_loss", True) + self.criterion_att = LabelSmoothingLoss( + size=self.vocab_size, + padding_idx=self.ignore_id, + smoothing=kwargs.get("lsm_weight", 0.0), + normalize_length=self.length_normalized_loss, + ) + + specaug = kwargs.get("specaug", None) + if specaug is not None: + specaug_class = tables.specaug_classes.get(specaug) + specaug = specaug_class(**kwargs.get("specaug_conf", {})) + self.specaug = specaug + + def forward( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + text: torch.Tensor, + text_lengths: torch.Tensor, + **kwargs, + ): + target_mask = kwargs.get("target_mask", None) + + # import pdb; + # pdb.set_trace() + if len(text_lengths.size()) > 1: + text_lengths = text_lengths[:, 0] + if len(speech_lengths.size()) > 1: + speech_lengths = speech_lengths[:, 0] + + batch_size, frames, _ = speech.shape + _, text_tokens = text.shape + + if self.activation_checkpoint: + from torch.utils.checkpoint import checkpoint + + encoder_out, encoder_out_lens = checkpoint( + self.encode, speech, speech_lengths, use_reentrant=False + ) + else: + encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) + + loss_att, acc_att, cer_att, wer_att = self._calc_att_loss( + encoder_out, encoder_out_lens, text, text_lengths, target_mask=target_mask + ) + loss = loss_att + stats = {} + stats["acc"] = acc_att + stats["loss"] = torch.clone(loss.detach()) + stats["batch_size"] = batch_size + stats["batch_size_x_frames"] = frames * batch_size + stats["batch_size_real_frames"] = speech_lengths.sum().item() + stats["padding_frames"] = stats["batch_size_x_frames"] - stats["batch_size_real_frames"] + stats["batch_size_x_tokens"] = text_tokens * batch_size + stats["batch_size_real_tokens"] = text_lengths.sum().item() + stats["padding_tokens"] = stats["batch_size_x_tokens"] - stats["batch_size_real_tokens"] + stats["batch_size_x_frames_plus_tokens"] = (text_tokens + frames) * batch_size + + # force_gatherable: to-device and to-tensor if scalar for DataParallel + if self.length_normalized_loss: + batch_size = int((text_lengths + 1).sum()) + loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) + return loss, stats, weight + + def encode( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + **kwargs, + ): + """Encoder. Note that this method is used by asr_inference.py + Args: + speech: (Batch, Length, ...) + speech_lengths: (Batch, ) + ind: int + """ + with autocast(False): + # Data augmentation + if self.specaug is not None and self.training: + speech, speech_lengths = self.specaug(speech, speech_lengths) + + # Forward encoder + encoder_out, encoder_out_lens = self.model.encoder(speech.permute(0, 2, 1), speech_lengths) + + return encoder_out, encoder_out_lens + + def _calc_att_loss( + self, + encoder_out: torch.Tensor, + encoder_out_lens: torch.Tensor, + ys_pad: torch.Tensor, + ys_pad_lens: torch.Tensor, + **kwargs, + ): + target_mask = kwargs.get("target_mask", None) + stats = {} + + # 1. Forward decoder + decoder_out = self.model.decoder( + x=ys_pad, xa=encoder_out, hlens=encoder_out_lens, ys_in_lens=ys_pad_lens + ) + # decoder_out, _ = self.model.decoder(encoder_out, encoder_out_lens, ys_pad, ys_pad_lens) + # 2. Compute attention loss + mask = torch.ones_like(ys_pad) * (-1) + ys_pad_mask = (ys_pad * target_mask + mask * (1 - target_mask)).to(torch.int64) + ys_pad_mask[ys_pad_mask == 0] = -1 + loss_att = self.criterion_att(decoder_out[:, :-1, :], ys_pad_mask[:, 1:]) + + with torch.no_grad(): + preds = torch.argmax(decoder_out, -1) + acc_att = compute_accuracy( + preds[:, :-1], ys_pad_mask[:, 1:], ignore_label=self.ignore_id + ) + + return loss_att, acc_att, None, None + + def inference( + self, + data_in, + data_lengths=None, + key: list = None, + tokenizer=None, + frontend=None, + **kwargs, + ): + if kwargs.get("batch_size", 1) > 1: + raise NotImplementedError("batch decoding is not implemented") + + if frontend is None and not hasattr(self, "frontend"): + frontend_class = tables.frontend_classes.get("WhisperFrontend") + frontend = frontend_class( + n_mels=self.model.dims.n_mels, do_pad_trim=kwargs.get("do_pad_trim", True) + ) + self.frontend = frontend + else: + frontend = frontend if frontend is not None else self.frontend + + meta_data = {} + if ( + isinstance(data_in, torch.Tensor) and kwargs.get("data_type", "sound") == "fbank" + ): # fbank + speech, speech_lengths = data_in, data_lengths + if len(speech.shape) < 3: + speech = speech[None, :, :] + if speech_lengths is None: + speech_lengths = speech.shape[1] + else: + # extract fbank feats + time1 = time.perf_counter() + audio_sample_list = load_audio_text_image_video( + data_in, + fs=frontend.fs if hasattr(frontend, "fs") else 16000, + audio_fs=kwargs.get("fs", 16000), + data_type=kwargs.get("data_type", "sound"), + tokenizer=tokenizer, + ) + time2 = time.perf_counter() + meta_data["load_data"] = f"{time2 - time1:0.3f}" + speech, speech_lengths = extract_fbank( + audio_sample_list, data_type=kwargs.get("data_type", "sound"), frontend=frontend + ) + time3 = time.perf_counter() + meta_data["extract_feat"] = f"{time3 - time2:0.3f}" + frame_shift = frontend.frame_shift if hasattr(frontend, "frame_shift") else 10 + lfr_n = frontend.lfr_n if hasattr(frontend, "lfr_n") else 1 + meta_data["batch_data_time"] = speech_lengths.sum().item() * frame_shift * lfr_n / 1000 + + speech = speech.to(device=kwargs["device"])[0, :, :] + speech_lengths = speech_lengths.to(device=kwargs["device"]) + + DecodingOptions = kwargs.get("DecodingOptions", {}) + task = DecodingOptions.get("task", "ASR") + if isinstance(task, str): + task = [task] + task = "".join([f"<|{x}|>" for x in task]) + initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") + DecodingOptions["initial_prompt"] = initial_prompt + + language = DecodingOptions.get("language", None) + language = None if language == "auto" else language + DecodingOptions["language"] = language + + DecodingOptions["vocab_path"] = kwargs["tokenizer_conf"].get("vocab_path", None) + + if "without_timestamps" not in DecodingOptions: + DecodingOptions["without_timestamps"] = True + + options = whisper.DecodingOptions(**DecodingOptions) + + result = whisper.decode(self.model, speech, options) + text = f"{result.text}" + results = [] + result_i = {"key": key[0], "text": text} + + results.append(result_i) + + return results, meta_data From 0454015357a69bad81002b24b3806aa98ae2ef14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 00:28:14 +0800 Subject: [PATCH 010/125] batch --- funasr/models/sense_voice/decoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 4986d5065..f5b882595 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -365,7 +365,7 @@ class MultiHeadedAttentionSANMDecoder(nn.Module): self.pad_fn = nn.ConstantPad1d((left_padding, right_padding), 0.0) self.kernel_size = kernel_size - def forward(self, inputs, mask, cache=None, mask_shfit_chunk=None): + def forward(self, inputs, mask, cache=None, mask_shfit_chunk=None, **kwargs): """ :param x: (#batch, time1, size). :param mask: Mask tensor (#batch, 1, time) From db89040b78c927c3a98d97bb4adbcec2dbea7a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 01:23:51 +0800 Subject: [PATCH 011/125] batch --- data/list/data_jsonl.list | 2 ++ data_tmp/train.jsonl | 0 funasr/datasets/audio_datasets/update_jsonl.py | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 data/list/data_jsonl.list create mode 100644 data_tmp/train.jsonl diff --git a/data/list/data_jsonl.list b/data/list/data_jsonl.list new file mode 100644 index 000000000..d13808bf7 --- /dev/null +++ b/data/list/data_jsonl.list @@ -0,0 +1,2 @@ +/Users/zhifu/funasr1.0/data/list/train.jsonl +/Users/zhifu/funasr1.0/data/list/val.jsonl \ No newline at end of file diff --git a/data_tmp/train.jsonl b/data_tmp/train.jsonl new file mode 100644 index 000000000..e69de29bb diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index 561811e8e..0a3e0ec42 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -35,7 +35,7 @@ def gen_scp_from_jsonl(jsonl_file, jsonl_file_out, ncpu): for line in lines: - jsonl_file_out_f.write(line) + jsonl_file_out_f.write(line + "\n") jsonl_file_out_f.flush() jsonl_file_out_f.close() @@ -53,6 +53,7 @@ def update_data(lines, i): if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: print(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") data["source_len"] = source_len + data["source"] = wav_path jsonl_line = json.dumps(data, ensure_ascii=False) lines[i] = jsonl_line From 1ac23a0cc12d53f76e016df5339bbf4d3fdfde6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 01:24:19 +0800 Subject: [PATCH 012/125] batch --- data/list/data_jsonl.list | 2 -- data_tmp/train.jsonl | 0 2 files changed, 2 deletions(-) delete mode 100644 data/list/data_jsonl.list delete mode 100644 data_tmp/train.jsonl diff --git a/data/list/data_jsonl.list b/data/list/data_jsonl.list deleted file mode 100644 index d13808bf7..000000000 --- a/data/list/data_jsonl.list +++ /dev/null @@ -1,2 +0,0 @@ -/Users/zhifu/funasr1.0/data/list/train.jsonl -/Users/zhifu/funasr1.0/data/list/val.jsonl \ No newline at end of file diff --git a/data_tmp/train.jsonl b/data_tmp/train.jsonl deleted file mode 100644 index e69de29bb..000000000 From 0de8b6447cba6f17bb101b57bdd2d91f129443f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 10:35:12 +0800 Subject: [PATCH 013/125] batch --- funasr/datasets/audio_datasets/update_jsonl.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index 0a3e0ec42..ad47e1285 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -31,7 +31,7 @@ def gen_scp_from_jsonl(jsonl_file, jsonl_file_out, ncpu): else: for i in range(num_total): update_data(lines, i) - print("All audio durations have been processed.") + logging.info("All audio durations have been processed.") for line in lines: @@ -51,7 +51,7 @@ def update_data(lines, i): source_len = int(sample_num / 16000 * 1000 / 10) source_len_old = data["source_len"] if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: - print(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") + logging.info(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") data["source_len"] = source_len data["source"] = wav_path jsonl_line = json.dumps(data, ensure_ascii=False) @@ -67,7 +67,7 @@ def update_wav_len(jsonl_file_list_in, jsonl_file_out_dir, ncpu=1): for i, jsonl in enumerate(data_file_lists): filename_with_extension = os.path.basename(jsonl.strip()) jsonl_file_out = os.path.join(jsonl_file_out_dir, filename_with_extension) - print(f"{i}/{len(data_file_lists)}, jsonl: {jsonl}, {jsonl_file_out}") + logging.info(f"{i}/{len(data_file_lists)}, jsonl: {jsonl}, {jsonl_file_out}") gen_scp_from_jsonl(jsonl.strip(), jsonl_file_out, ncpu) @@ -76,7 +76,7 @@ def update_wav_len(jsonl_file_list_in, jsonl_file_out_dir, ncpu=1): def main_hydra(cfg: DictConfig): kwargs = OmegaConf.to_container(cfg, resolve=True) - print(kwargs) + logging.info(kwargs) jsonl_file_list_in = kwargs.get( "jsonl_file_list_in", "/Users/zhifu/funasr1.0/data/list/data_jsonl.list" From 9a8086bdf5c15d45087175f170ac33d574c0ed79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 10:48:31 +0800 Subject: [PATCH 014/125] batch --- funasr/bin/train.py | 3 ++- funasr/datasets/audio_datasets/update_jsonl.py | 4 ++-- funasr/train_utils/trainer.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index 97516eb8b..d20915c57 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -205,7 +205,6 @@ def main(**kwargs): dataloader_tr, dataloader_val = dataloader.build_iter( epoch, data_split_i=data_split_i, start_step=trainer.start_step ) - trainer.start_step = 0 trainer.train_epoch( model=model, @@ -218,7 +217,9 @@ def main(**kwargs): writer=writer, data_split_i=data_split_i, data_split_num=dataloader.data_split_num, + start_step=trainer.start_step, ) + trainer.start_step = 0 torch.cuda.empty_cache() diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index ad47e1285..05870fe1f 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -50,8 +50,8 @@ def update_data(lines, i): sample_num = len(waveform) source_len = int(sample_num / 16000 * 1000 / 10) source_len_old = data["source_len"] - if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: - logging.info(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") + # if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: + # logging.info(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") data["source_len"] = source_len data["source"] = wav_path jsonl_line = json.dumps(data, ensure_ascii=False) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index e86420cdf..a28ca5183 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -456,7 +456,7 @@ class Trainer: batch_num_epoch = len(dataloader_train) self.log( epoch, - batch_idx, + batch_idx + kwargs.get("start_step", 0), step_in_epoch=self.step_in_epoch, batch_num_epoch=batch_num_epoch, lr=lr, From 98376eaab4f9d15fd7dbe862e870fcac21749668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 11:13:51 +0800 Subject: [PATCH 015/125] batch --- examples/README.md | 8 ++++---- examples/aishell/branchformer/run.sh | 3 +++ examples/aishell/conformer/run.sh | 3 +++ examples/aishell/e_branchformer/run.sh | 3 +++ examples/aishell/paraformer/run.sh | 3 +++ examples/aishell/transformer/run.sh | 3 +++ 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/examples/README.md b/examples/README.md index f87d5fa65..0191a2d8a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -248,10 +248,10 @@ funasr/bin/train.py \ export CUDA_VISIBLE_DEVICES="0,1" gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') -torchrun --nnodes 1 --nproc_per_node ${gpu_num} \ +torchrun --nnodes 1 --nproc_per_node ${gpu_num} --master_port 12345 \ ../../../funasr/bin/train.py ${train_args} ``` ---nnodes represents the total number of participating nodes, while --nproc_per_node indicates the number of processes running on each node. +--nnodes represents the total number of participating nodes, while --nproc_per_node indicates the number of processes running on each node. --master_port indicates the port is 12345 ##### Multi-Machine Multi-GPU Training @@ -260,7 +260,7 @@ On the master node, assuming the IP is 192.168.1.1 and the port is 12345, and yo export CUDA_VISIBLE_DEVICES="0,1" gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') -torchrun --nnodes 2 --node_rank 0 --nproc_per_node ${gpu_num} --master_addr=192.168.1.1 --master_port=12345 \ +torchrun --nnodes 2 --node_rank 0 --nproc_per_node ${gpu_num} --master_addr 192.168.1.1 --master_port 12345 \ ../../../funasr/bin/train.py ${train_args} ``` On the worker node (assuming the IP is 192.168.1.2), you need to ensure that the MASTER_ADDR and MASTER_PORT environment variables are set to match those of the master node, and then run the same command: @@ -269,7 +269,7 @@ On the worker node (assuming the IP is 192.168.1.2), you need to ensure that the export CUDA_VISIBLE_DEVICES="0,1" gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') -torchrun --nnodes 2 --node_rank 1 --nproc_per_node ${gpu_num} --master_addr=192.168.1.1 --master_port=12345 \ +torchrun --nnodes 2 --node_rank 1 --nproc_per_node ${gpu_num} --master_addr 192.168.1.1 --master_port 12345 \ ../../../funasr/bin/train.py ${train_args} ``` diff --git a/examples/aishell/branchformer/run.sh b/examples/aishell/branchformer/run.sh index 918aa9bd1..5b649546f 100755 --- a/examples/aishell/branchformer/run.sh +++ b/examples/aishell/branchformer/run.sh @@ -27,6 +27,8 @@ data_url=www.openslr.org/resources/33 tag="exp1" workspace=`pwd` +master_port=12345 + . utils/parse_options.sh || exit 1; # Set bash to 'debug' mode, it will exit on : @@ -115,6 +117,7 @@ if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then torchrun \ --nnodes 1 \ --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ ../../../funasr/bin/train.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ diff --git a/examples/aishell/conformer/run.sh b/examples/aishell/conformer/run.sh index ba8b43c60..0c8ab508a 100755 --- a/examples/aishell/conformer/run.sh +++ b/examples/aishell/conformer/run.sh @@ -27,6 +27,8 @@ data_url=www.openslr.org/resources/33 tag="exp1" workspace=`pwd` +master_port=12345 + . utils/parse_options.sh || exit 1; # Set bash to 'debug' mode, it will exit on : @@ -114,6 +116,7 @@ if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then torchrun \ --nnodes 1 \ --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ ../../../funasr/bin/train.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ diff --git a/examples/aishell/e_branchformer/run.sh b/examples/aishell/e_branchformer/run.sh index be185998f..452ec80ba 100755 --- a/examples/aishell/e_branchformer/run.sh +++ b/examples/aishell/e_branchformer/run.sh @@ -27,6 +27,8 @@ data_url=www.openslr.org/resources/33 tag="exp1" workspace=`pwd` +master_port=12345 + . utils/parse_options.sh || exit 1; # Set bash to 'debug' mode, it will exit on : @@ -115,6 +117,7 @@ if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then torchrun \ --nnodes 1 \ --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ ../../../funasr/bin/train.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ diff --git a/examples/aishell/paraformer/run.sh b/examples/aishell/paraformer/run.sh index a957b937b..ffef61e32 100755 --- a/examples/aishell/paraformer/run.sh +++ b/examples/aishell/paraformer/run.sh @@ -27,6 +27,8 @@ data_url=www.openslr.org/resources/33 tag="exp1" workspace=`pwd` +master_port=12345 + . utils/parse_options.sh || exit 1; # Set bash to 'debug' mode, it will exit on : @@ -113,6 +115,7 @@ if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then torchrun \ --nnodes 1 \ --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ ../../../funasr/bin/train.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ diff --git a/examples/aishell/transformer/run.sh b/examples/aishell/transformer/run.sh index 98c282952..3fb846519 100755 --- a/examples/aishell/transformer/run.sh +++ b/examples/aishell/transformer/run.sh @@ -27,6 +27,8 @@ data_url=www.openslr.org/resources/33 tag="exp1" workspace=`pwd` +master_port=12345 + . utils/parse_options.sh || exit 1; # Set bash to 'debug' mode, it will exit on : @@ -115,6 +117,7 @@ if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then torchrun \ --nnodes 1 \ --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ ../../../funasr/bin/train.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ From 3f2d83c67298b40d906260138c2df798f55276e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 12:50:41 +0800 Subject: [PATCH 016/125] batch --- examples/README_zh.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/README_zh.md b/examples/README_zh.md index b016f9e3b..b0a666512 100644 --- a/examples/README_zh.md +++ b/examples/README_zh.md @@ -256,10 +256,10 @@ funasr/bin/train.py \ export CUDA_VISIBLE_DEVICES="0,1" gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') -torchrun --nnodes 1 --nproc_per_node ${gpu_num} \ +torchrun --nnodes 1 --nproc_per_node ${gpu_num} --master_port 12345 \ ../../../funasr/bin/train.py ${train_args} ``` ---nnodes 表示参与的节点总数,--nproc_per_node 表示每个节点上运行的进程数 +--nnodes 表示参与的节点总数,--nproc_per_node 表示每个节点上运行的进程数,--master_port 表示端口号 ##### 多机多gpu训练 @@ -280,7 +280,7 @@ torchrun --nnodes 2 --node_rank 1 --nproc_per_node ${gpu_num} --master_addr 192. ../../../funasr/bin/train.py ${train_args} ``` ---nnodes 表示参与的节点总数,--node_rank 表示当前节点id,--nproc_per_node 表示每个节点上运行的进程数(通常为gpu个数) +--nnodes 表示参与的节点总数,--node_rank 表示当前节点id,--nproc_per_node 表示每个节点上运行的进程数(通常为gpu个数),--master_port 表示端口号 #### 准备数据 From 09b9bc0c87f66cc8903ac06606f3339ecb04d18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 13:21:24 +0800 Subject: [PATCH 017/125] train_loss_avg train_acc_avg --- funasr/train_utils/trainer.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index a28ca5183..dd0ac7ace 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -169,6 +169,8 @@ class Trainer: "data_split_i": kwargs.get("data_split_i", 0), "data_split_num": kwargs.get("data_split_num", 1), "batch_total": self.batch_total, + "train_loss_avg": kwargs.get("train_loss_avg", 0), + "train_acc_avg": kwargs.get("train_acc_avg", 0), } step = step_in_epoch if hasattr(model, "module"): @@ -306,7 +308,12 @@ class Trainer: checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 ) self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch - + self.train_acc_avg = ( + checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 + ) + self.train_loss_avg = ( + checkpoint["train_loss_avg"] if "train_loss_avg" in checkpoint else 0 + ) model.to(self.device) print(f"Checkpoint loaded successfully from '{ckpt}'") else: @@ -400,12 +407,13 @@ class Trainer: speed_stats["backward_time"] = f"{time4 - time3:0.3f}" self.train_loss_avg = ( - self.train_loss_avg * batch_idx + loss.detach().cpu().item() - ) / (batch_idx + 1) + self.train_loss_avg * (self.step_in_epoch - 1) + loss.detach().cpu().item() + ) / self.step_in_epoch if "acc" in stats: self.train_acc_avg = ( - self.train_acc_avg * batch_idx + stats["acc"].detach().cpu().item() - ) / (batch_idx + 1) + self.train_acc_avg * (self.step_in_epoch - 1) + + stats["acc"].detach().cpu().item() + ) / self.step_in_epoch if self.use_ddp or self.use_fsdp: train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( self.device @@ -490,6 +498,8 @@ class Trainer: step_in_epoch=self.step_in_epoch, data_split_i=kwargs.get("data_split_i", 0), data_split_num=kwargs.get("data_split_num", 1), + train_loss_avg=self.train_loss_avg, + train_acc_avg=self.train_acc_avg, ) time_beg = time.perf_counter() From 9bbb47690868147def965e10b342bfec84b44c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 15:46:38 +0800 Subject: [PATCH 018/125] train_loss_avg train_acc_avg --- funasr/bin/train.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index d20915c57..7695e51c5 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -198,7 +198,7 @@ def main(**kwargs): writer = None dataloader_tr, dataloader_val = None, None - for epoch in range(trainer.start_epoch, trainer.max_epoch + 1): + for epoch in range(trainer.start_epoch, trainer.max_epoch): time1 = time.perf_counter() for data_split_i in range(trainer.start_data_split_i, dataloader.data_split_num): From f5958e96da05220c9e07d0af63df339cae4cc6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 30 Apr 2024 23:09:26 +0800 Subject: [PATCH 019/125] train_loss_avg train_acc_avg --- funasr/datasets/sense_voice_datasets/datasets.py | 2 +- funasr/train_utils/trainer.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index 1d269ddc8..dfadbab76 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -186,7 +186,7 @@ class SenseVoiceDataset(torch.utils.data.Dataset): ) if self.batch_type != "example": - for i in range(3): + for i in range(10): outputs = self._filter_badcase(outputs, i=i) return outputs diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index dd0ac7ace..e0b6def54 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -308,6 +308,7 @@ class Trainer: checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 ) self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch + print(checkpoint["train_acc_avg"]) self.train_acc_avg = ( checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 ) From f690741b9aa31a27d6620b02eb1c754d6fe27237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 1 May 2024 01:05:59 +0800 Subject: [PATCH 020/125] log step --- funasr/train_utils/trainer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index e0b6def54..01e2924d9 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -465,7 +465,8 @@ class Trainer: batch_num_epoch = len(dataloader_train) self.log( epoch, - batch_idx + kwargs.get("start_step", 0), + batch_idx, + log_step=batch_idx + kwargs.get("start_step", 0), step_in_epoch=self.step_in_epoch, batch_num_epoch=batch_num_epoch, lr=lr, @@ -634,11 +635,12 @@ class Trainer: tag="train", data_split_i=0, data_split_num=1, + log_step=None, **kwargs, ): if (batch_idx + 1) % self.log_interval == 0: - + batch_idx = log_step if log_step is not None else batch_idx gpu_info = ( "GPU, memory: usage: {:.3f} GB, " "peak: {:.3f} GB, " From 0f7ce31c2a4ed194b2104d4cdddb5469b45c0e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 2 May 2024 13:03:24 +0800 Subject: [PATCH 021/125] wav is not exist --- funasr/datasets/sense_voice_datasets/datasets.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index dfadbab76..5d80956b1 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -2,7 +2,7 @@ import logging import torch import random - +import traceback from funasr.register import tables from funasr.utils.load_utils import extract_fbank, load_audio_text_image_video @@ -73,15 +73,17 @@ class SenseVoiceDataset(torch.utils.data.Dataset): if idx == 0: index_cur = index else: - if index <= self.retry: - index_cur = index + idx - else: - index_cur = torch.randint(0, index, ()).item() + index_cur = torch.randint(0, len(self.index_ds), ()).item() item = self.index_ds[index_cur] source = item["source"] - data_src = load_audio_text_image_video(source, fs=self.fs) + try: + data_src = load_audio_text_image_video(source, fs=self.fs) + except Exception as e: + logging.error(f"Loading wav failed! {str(e)}, {traceback.format_exc()}") + continue + if self.preprocessor_speech: data_src = self.preprocessor_speech(data_src, fs=self.fs) speech, speech_lengths = extract_fbank( From 604c93b42120e498500d615c997b2087e0aa0e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 2 May 2024 13:20:58 +0800 Subject: [PATCH 022/125] wav is not exist --- .../datasets/audio_datasets/update_jsonl.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/funasr/datasets/audio_datasets/update_jsonl.py b/funasr/datasets/audio_datasets/update_jsonl.py index 05870fe1f..bc8470808 100644 --- a/funasr/datasets/audio_datasets/update_jsonl.py +++ b/funasr/datasets/audio_datasets/update_jsonl.py @@ -46,16 +46,17 @@ def update_data(lines, i): data = json.loads(line.strip()) wav_path = data["source"].replace("/cpfs01", "/cpfs_speech/data") - waveform, _ = librosa.load(wav_path, sr=16000) - sample_num = len(waveform) - source_len = int(sample_num / 16000 * 1000 / 10) - source_len_old = data["source_len"] - # if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: - # logging.info(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") - data["source_len"] = source_len - data["source"] = wav_path - jsonl_line = json.dumps(data, ensure_ascii=False) - lines[i] = jsonl_line + if os.path.exists(wav_path): + waveform, _ = librosa.load(wav_path, sr=16000) + sample_num = len(waveform) + source_len = int(sample_num / 16000 * 1000 / 10) + source_len_old = data["source_len"] + # if (source_len_old - source_len) > 100 or (source_len - source_len_old) > 100: + # logging.info(f"old: {source_len_old}, new: {source_len}, wav: {wav_path}") + data["source_len"] = source_len + data["source"] = wav_path + jsonl_line = json.dumps(data, ensure_ascii=False) + lines[i] = jsonl_line def update_wav_len(jsonl_file_list_in, jsonl_file_out_dir, ncpu=1): From 898c138f3f24e34b560fa172a5ff1d744064c1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 6 May 2024 13:53:31 +0800 Subject: [PATCH 023/125] decoding --- .../conformer/demo.py | 3 +- .../sense_voice/demo_fsmn.py | 27 ++ funasr/models/sense_voice/decoder.py | 47 +- funasr/models/sense_voice/model.py | 115 ++++- funasr/models/sense_voice/search.py | 453 ++++++++++++++++++ 5 files changed, 626 insertions(+), 19 deletions(-) create mode 100644 examples/industrial_data_pretraining/sense_voice/demo_fsmn.py create mode 100644 funasr/models/sense_voice/search.py diff --git a/examples/industrial_data_pretraining/conformer/demo.py b/examples/industrial_data_pretraining/conformer/demo.py index 43cf67de6..c2d7682bb 100644 --- a/examples/industrial_data_pretraining/conformer/demo.py +++ b/examples/industrial_data_pretraining/conformer/demo.py @@ -8,6 +8,7 @@ from funasr import AutoModel model = AutoModel(model="iic/speech_conformer_asr_nat-zh-cn-16k-aishell2-vocab5212-pytorch") res = model.generate( - input="https://modelscope.oss-cn-beijing.aliyuncs.com/test/audios/asr_example.wav" + input="https://modelscope.oss-cn-beijing.aliyuncs.com/test/audios/asr_example.wav", + decoding_ctc_weight=0.0, ) print(res) diff --git a/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py new file mode 100644 index 000000000..b94cba7f4 --- /dev/null +++ b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# -*- encoding: utf-8 -*- +# Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved. +# MIT License (https://opensource.org/licenses/MIT) + +from funasr import AutoModel + +model = AutoModel( + model="/Users/zhifu/Downloads/modelscope_models/SenseVoiceModelscopeFSMN", + vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", + vad_kwargs={"max_single_segment_time": 30000}, +) + + +input_wav = ( + "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav" +) + +DecodingOptions = { + "task": ("ASR", "AED", "SER"), + "language": "auto", + "fp16": True, + "gain_event": True, +} + +res = model.generate(input=input_wav, batch_size_s=0, DecodingOptions=DecodingOptions) +print(res) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index f5b882595..8a4a2ce6a 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -15,6 +15,7 @@ import numpy as np import torch import torch.nn.functional as F from torch import Tensor, nn +from funasr.models.transformer.utils.mask import subsequent_mask class LayerNorm(nn.LayerNorm): @@ -443,9 +444,19 @@ class ResidualAttentionBlockFSMN(nn.Module): kv_cache: Optional[dict] = None, **kwargs, ): + cache = kwargs.get("cache", {}) + layer = kwargs.get("layer", 0) is_pad_mask = kwargs.get("is_pad_mask", False) is_pad_memory_mask = kwargs.get("is_pad_memory_mask", False) - x = x + self.attn(self.attn_ln(x), mask=None, kv_cache=kv_cache, is_pad_mask=is_pad_mask)[0] + + fsmn_cache = cache[layer]["fsmn_cache"] if len(cache) > 0 else None + # if fsmn_cache is not None: + # x = x[:, -1:] + att_res, fsmn_cache = self.attn(self.attn_ln(x), mask=None, cache=fsmn_cache) + # if len(cache)>1: + # cache[layer]["fsmn_cache"] = fsmn_cache + # x = x[:, -1:] + x = x + att_res if self.cross_attn: x = ( x @@ -510,10 +521,9 @@ class SenseVoiceDecoderFSMN(nn.Module): ys_in_lens = kwargs.get("ys_in_lens", None) - offset = next(iter(kv_cache.values())).shape[1] if kv_cache else 0 tgt, memory = x, xa tgt[tgt == -1] = 0 - tgt = self.token_embedding(tgt) + self.positional_embedding[offset : offset + tgt.size(1)] + tgt = self.token_embedding(tgt) + self.positional_embedding[: tgt.size(1)] # tgt = self.dropout(tgt) x = tgt.to(memory.dtype) @@ -531,9 +541,40 @@ class SenseVoiceDecoderFSMN(nn.Module): memory_mask=memory_mask, is_pad_mask=False, is_pad_memory_mask=True, + cache=kwargs.get("cache", None), + layer=layer, ) x = self.ln(x) x = (x @ torch.transpose(self.token_embedding.weight.to(x.dtype), 0, 1)).float() return x + + def init_state(self, x): + state = {} + for layer, block in enumerate(self.blocks): + state[layer] = { + "fsmn_cache": None, + "memory_key": None, + "memory_value": None, + } + + return state + + def final_score(self, state) -> float: + """Score eos (optional). + + Args: + state: Scorer state for prefix tokens + + Returns: + float: final score + + """ + return 0.0 + + def score(self, ys, state, x): + """Score.""" + ys_mask = subsequent_mask(len(ys), device=x.device).unsqueeze(0) + logp = self.forward(ys.unsqueeze(0), x.unsqueeze(0), cache=state) + return logp.squeeze(0)[-1, :], state diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index c12107e7a..82ccc55e1 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -15,6 +15,7 @@ from funasr.losses.label_smoothing_loss import LabelSmoothingLoss from funasr.train_utils.device_funcs import force_gatherable from . import whisper_lib as whisper from funasr.utils.load_utils import load_audio_text_image_video, extract_fbank +from funasr.utils.datadir_writer import DatadirWriter from funasr.register import tables @@ -497,12 +498,14 @@ class SenseVoiceFSMN(nn.Module): # decoder del model.decoder decoder = kwargs.get("decoder", "SenseVoiceDecoder") - decoder_conf = kwargs.get("decoder_conf", {}) decoder_class = tables.decoder_classes.get(decoder) decoder = decoder_class( - vocab_size=dims.n_vocab, - encoder_output_size=dims.n_audio_state, - **decoder_conf, + n_vocab=dims.n_vocab, + n_ctx=dims.n_text_ctx, + n_state=dims.n_text_state, + n_head=dims.n_text_head, + n_layer=dims.n_text_layer, + **kwargs.get("decoder_conf"), ) model.decoder = decoder @@ -512,7 +515,7 @@ class SenseVoiceFSMN(nn.Module): self.activation_checkpoint = kwargs.get("activation_checkpoint", False) self.ignore_id = kwargs.get("ignore_id", -1) - self.vocab_size = kwargs.get("vocab_size", -1) + self.vocab_size = dims.n_vocab self.length_normalized_loss = kwargs.get("length_normalized_loss", True) self.criterion_att = LabelSmoothingLoss( size=self.vocab_size, @@ -630,6 +633,42 @@ class SenseVoiceFSMN(nn.Module): return loss_att, acc_att, None, None + def init_beam_search( + self, + **kwargs, + ): + from .search import BeamSearch + + from funasr.models.transformer.scorers.length_bonus import LengthBonus + + # 1. Build ASR model + scorers = {} + + scorers.update( + decoder=self.model.decoder, + length_bonus=LengthBonus(self.vocab_size), + ) + + weights = dict( + decoder=1.0, + ctc=0.0, + lm=0.0, + ngram=0.0, + length_bonus=kwargs.get("penalty", 0.0), + ) + beam_search = BeamSearch( + beam_size=kwargs.get("beam_size", 5), + weights=weights, + scorers=scorers, + sos=None, + eos=None, + vocab_size=self.vocab_size, + token_list=None, + pre_beam_score_key="full", + ) + + self.beam_search = beam_search + def inference( self, data_in, @@ -642,6 +681,12 @@ class SenseVoiceFSMN(nn.Module): if kwargs.get("batch_size", 1) > 1: raise NotImplementedError("batch decoding is not implemented") + # init beamsearch + if not hasattr(self, "beam_search") or self.beam_search is None: + logging.info("enable beam_search") + self.init_beam_search(**kwargs) + self.nbest = kwargs.get("nbest", 1) + if frontend is None and not hasattr(self, "frontend"): frontend_class = tables.frontend_classes.get("WhisperFrontend") frontend = frontend_class( @@ -690,24 +735,64 @@ class SenseVoiceFSMN(nn.Module): task = [task] task = "".join([f"<|{x}|>" for x in task]) initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") - DecodingOptions["initial_prompt"] = initial_prompt language = DecodingOptions.get("language", None) language = None if language == "auto" else language - DecodingOptions["language"] = language - DecodingOptions["vocab_path"] = kwargs["tokenizer_conf"].get("vocab_path", None) + sos = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt + sos_int = tokenizer.encode(sos, allowed_special="all") + eos = kwargs.get("model_conf").get("eos") + eos_int = tokenizer.encode(eos, allowed_special="all") + self.beam_search.sos = sos_int + self.beam_search.eos = eos_int[0] - if "without_timestamps" not in DecodingOptions: - DecodingOptions["without_timestamps"] = True + encoder_out, encoder_out_lens = self.encode( + speech[None, :, :].permute(0, 2, 1), speech_lengths + ) - options = whisper.DecodingOptions(**DecodingOptions) + # c. Passed the encoder result and the beam search + nbest_hyps = self.beam_search( + x=encoder_out[0], + maxlenratio=kwargs.get("maxlenratio", 0.0), + minlenratio=kwargs.get("minlenratio", 0.0), + ) + + nbest_hyps = nbest_hyps[: self.nbest] - result = whisper.decode(self.model, speech, options) - text = f"{result.text}" results = [] - result_i = {"key": key[0], "text": text} + b, n, d = encoder_out.size() + for i in range(b): - results.append(result_i) + for nbest_idx, hyp in enumerate(nbest_hyps): + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"{nbest_idx + 1}best_recog"] + + # remove sos/eos and get results + last_pos = -1 + if isinstance(hyp.yseq, list): + token_int = hyp.yseq[1:last_pos] + else: + token_int = hyp.yseq[1:last_pos].tolist() + + # # remove blank symbol id, which is assumed to be 0 + # token_int = list( + # filter( + # lambda x: x != self.eos and x != self.sos and x != self.blank_id, token_int + # ) + # ) + + # Change integer-ids to tokens + # token = tokenizer.ids2tokens(token_int) + text = tokenizer.decode(token_int) + + result_i = {"key": key[i], "text": text} + results.append(result_i) + + if ibest_writer is not None: + # ibest_writer["token"][key[i]] = " ".join(token) + ibest_writer["text"][key[i]] = text return results, meta_data diff --git a/funasr/models/sense_voice/search.py b/funasr/models/sense_voice/search.py new file mode 100644 index 000000000..98d02db9d --- /dev/null +++ b/funasr/models/sense_voice/search.py @@ -0,0 +1,453 @@ +from itertools import chain +import logging +from typing import Any +from typing import Dict +from typing import List +from typing import NamedTuple +from typing import Tuple +from typing import Union + +import torch + +from funasr.metrics.common import end_detect +from funasr.models.transformer.scorers.scorer_interface import PartialScorerInterface +from funasr.models.transformer.scorers.scorer_interface import ScorerInterface + + +class Hypothesis(NamedTuple): + """Hypothesis data type.""" + + yseq: torch.Tensor + score: Union[float, torch.Tensor] = 0 + scores: Dict[str, Union[float, torch.Tensor]] = dict() + states: Dict[str, Any] = dict() + + def asdict(self) -> dict: + """Convert data to JSON-friendly dict.""" + return self._replace( + yseq=self.yseq.tolist(), + score=float(self.score), + scores={k: float(v) for k, v in self.scores.items()}, + )._asdict() + + +class BeamSearch(torch.nn.Module): + """Beam search implementation.""" + + def __init__( + self, + scorers: Dict[str, ScorerInterface], + weights: Dict[str, float], + beam_size: int, + vocab_size: int, + sos=None, + eos=None, + token_list: List[str] = None, + pre_beam_ratio: float = 1.5, + pre_beam_score_key: str = None, + ): + """Initialize beam search. + + Args: + scorers (dict[str, ScorerInterface]): Dict of decoder modules + e.g., Decoder, CTCPrefixScorer, LM + The scorer will be ignored if it is `None` + weights (dict[str, float]): Dict of weights for each scorers + The scorer will be ignored if its weight is 0 + beam_size (int): The number of hypotheses kept during search + vocab_size (int): The number of vocabulary + sos (int): Start of sequence id + eos (int): End of sequence id + token_list (list[str]): List of tokens for debug log + pre_beam_score_key (str): key of scores to perform pre-beam search + pre_beam_ratio (float): beam size in the pre-beam search + will be `int(pre_beam_ratio * beam_size)` + + """ + super().__init__() + # set scorers + self.weights = weights + self.scorers = dict() + self.full_scorers = dict() + self.part_scorers = dict() + # this module dict is required for recursive cast + # `self.to(device, dtype)` in `recog.py` + self.nn_dict = torch.nn.ModuleDict() + for k, v in scorers.items(): + w = weights.get(k, 0) + if w == 0 or v is None: + continue + # assert isinstance( + # v, ScorerInterface + # ), f"{k} ({type(v)}) does not implement ScorerInterface" + self.scorers[k] = v + if isinstance(v, PartialScorerInterface): + self.part_scorers[k] = v + else: + self.full_scorers[k] = v + if isinstance(v, torch.nn.Module): + self.nn_dict[k] = v + + # set configurations + self.sos = sos + self.eos = eos + if isinstance(self.eos, (list, tuple)): + self.eos = eos[0] + self.token_list = token_list + self.pre_beam_size = int(pre_beam_ratio * beam_size) + self.beam_size = beam_size + self.n_vocab = vocab_size + if ( + pre_beam_score_key is not None + and pre_beam_score_key != "full" + and pre_beam_score_key not in self.full_scorers + ): + raise KeyError(f"{pre_beam_score_key} is not found in {self.full_scorers}") + self.pre_beam_score_key = pre_beam_score_key + self.do_pre_beam = ( + self.pre_beam_score_key is not None + and self.pre_beam_size < self.n_vocab + and len(self.part_scorers) > 0 + ) + + def init_hyp(self, x: torch.Tensor) -> List[Hypothesis]: + """Get an initial hypothesis data. + + Args: + x (torch.Tensor): The encoder output feature + + Returns: + Hypothesis: The initial hypothesis. + + """ + init_states = dict() + init_scores = dict() + for k, d in self.scorers.items(): + init_states[k] = d.init_state(x) + init_scores[k] = 0.0 + if not isinstance(self.sos, (list, tuple)): + self.sos = [self.sos] + return [ + Hypothesis( + score=0.0, + scores=init_scores, + states=init_states, + yseq=torch.tensor(self.sos, device=x.device), + ) + ] + + @staticmethod + def append_token(xs: torch.Tensor, x: int) -> torch.Tensor: + """Append new token to prefix tokens. + + Args: + xs (torch.Tensor): The prefix token + x (int): The new token to append + + Returns: + torch.Tensor: New tensor contains: xs + [x] with xs.dtype and xs.device + + """ + x = torch.tensor([x], dtype=xs.dtype, device=xs.device) + return torch.cat((xs, x)) + + def score_full( + self, hyp: Hypothesis, x: torch.Tensor + ) -> Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: + """Score new hypothesis by `self.full_scorers`. + + Args: + hyp (Hypothesis): Hypothesis with prefix tokens to score + x (torch.Tensor): Corresponding input feature + + Returns: + Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: Tuple of + score dict of `hyp` that has string keys of `self.full_scorers` + and tensor score values of shape: `(self.n_vocab,)`, + and state dict that has string keys + and state values of `self.full_scorers` + + """ + scores = dict() + states = dict() + for k, d in self.full_scorers.items(): + scores[k], states[k] = d.score(hyp.yseq, hyp.states[k], x) + return scores, states + + def score_partial( + self, hyp: Hypothesis, ids: torch.Tensor, x: torch.Tensor + ) -> Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: + """Score new hypothesis by `self.part_scorers`. + + Args: + hyp (Hypothesis): Hypothesis with prefix tokens to score + ids (torch.Tensor): 1D tensor of new partial tokens to score + x (torch.Tensor): Corresponding input feature + + Returns: + Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: Tuple of + score dict of `hyp` that has string keys of `self.part_scorers` + and tensor score values of shape: `(len(ids),)`, + and state dict that has string keys + and state values of `self.part_scorers` + + """ + scores = dict() + states = dict() + for k, d in self.part_scorers.items(): + scores[k], states[k] = d.score_partial(hyp.yseq, ids, hyp.states[k], x) + return scores, states + + def beam( + self, weighted_scores: torch.Tensor, ids: torch.Tensor + ) -> Tuple[torch.Tensor, torch.Tensor]: + """Compute topk full token ids and partial token ids. + + Args: + weighted_scores (torch.Tensor): The weighted sum scores for each tokens. + Its shape is `(self.n_vocab,)`. + ids (torch.Tensor): The partial token ids to compute topk + + Returns: + Tuple[torch.Tensor, torch.Tensor]: + The topk full token ids and partial token ids. + Their shapes are `(self.beam_size,)` + + """ + # no pre beam performed + if weighted_scores.size(0) == ids.size(0): + top_ids = weighted_scores.topk(self.beam_size)[1] + return top_ids, top_ids + + # mask pruned in pre-beam not to select in topk + tmp = weighted_scores[ids] + weighted_scores[:] = -float("inf") + weighted_scores[ids] = tmp + top_ids = weighted_scores.topk(self.beam_size)[1] + local_ids = weighted_scores[ids].topk(self.beam_size)[1] + return top_ids, local_ids + + @staticmethod + def merge_scores( + prev_scores: Dict[str, float], + next_full_scores: Dict[str, torch.Tensor], + full_idx: int, + next_part_scores: Dict[str, torch.Tensor], + part_idx: int, + ) -> Dict[str, torch.Tensor]: + """Merge scores for new hypothesis. + + Args: + prev_scores (Dict[str, float]): + The previous hypothesis scores by `self.scorers` + next_full_scores (Dict[str, torch.Tensor]): scores by `self.full_scorers` + full_idx (int): The next token id for `next_full_scores` + next_part_scores (Dict[str, torch.Tensor]): + scores of partial tokens by `self.part_scorers` + part_idx (int): The new token id for `next_part_scores` + + Returns: + Dict[str, torch.Tensor]: The new score dict. + Its keys are names of `self.full_scorers` and `self.part_scorers`. + Its values are scalar tensors by the scorers. + + """ + new_scores = dict() + for k, v in next_full_scores.items(): + new_scores[k] = prev_scores[k] + v[full_idx] + for k, v in next_part_scores.items(): + new_scores[k] = prev_scores[k] + v[part_idx] + return new_scores + + def merge_states(self, states: Any, part_states: Any, part_idx: int) -> Any: + """Merge states for new hypothesis. + + Args: + states: states of `self.full_scorers` + part_states: states of `self.part_scorers` + part_idx (int): The new token id for `part_scores` + + Returns: + Dict[str, torch.Tensor]: The new score dict. + Its keys are names of `self.full_scorers` and `self.part_scorers`. + Its values are states of the scorers. + + """ + new_states = dict() + for k, v in states.items(): + new_states[k] = v + for k, d in self.part_scorers.items(): + new_states[k] = d.select_state(part_states[k], part_idx) + return new_states + + def search(self, running_hyps: List[Hypothesis], x: torch.Tensor) -> List[Hypothesis]: + """Search new tokens for running hypotheses and encoded speech x. + + Args: + running_hyps (List[Hypothesis]): Running hypotheses on beam + x (torch.Tensor): Encoded speech feature (T, D) + + Returns: + List[Hypotheses]: Best sorted hypotheses + + """ + best_hyps = [] + part_ids = torch.arange(self.n_vocab, device=x.device) # no pre-beam + for hyp in running_hyps: + # scoring + weighted_scores = torch.zeros(self.n_vocab, dtype=x.dtype, device=x.device) + scores, states = self.score_full(hyp, x) + for k in self.full_scorers: + weighted_scores += self.weights[k] * scores[k] + # partial scoring + if self.do_pre_beam: + pre_beam_scores = ( + weighted_scores + if self.pre_beam_score_key == "full" + else scores[self.pre_beam_score_key] + ) + part_ids = torch.topk(pre_beam_scores, self.pre_beam_size)[1] + part_scores, part_states = self.score_partial(hyp, part_ids, x) + for k in self.part_scorers: + weighted_scores[part_ids] += self.weights[k] * part_scores[k] + # add previous hyp score + weighted_scores += hyp.score + + # update hyps + for j, part_j in zip(*self.beam(weighted_scores, part_ids)): + # will be (2 x beam at most) + best_hyps.append( + Hypothesis( + score=weighted_scores[j], + yseq=self.append_token(hyp.yseq, j), + scores=self.merge_scores(hyp.scores, scores, j, part_scores, part_j), + states=self.merge_states(states, part_states, part_j), + ) + ) + + # sort and prune 2 x beam -> beam + best_hyps = sorted(best_hyps, key=lambda x: x.score, reverse=True)[ + : min(len(best_hyps), self.beam_size) + ] + return best_hyps + + def forward( + self, x: torch.Tensor, maxlenratio: float = 0.0, minlenratio: float = 0.0 + ) -> List[Hypothesis]: + """Perform beam search. + + Args: + x (torch.Tensor): Encoded speech feature (T, D) + maxlenratio (float): Input length ratio to obtain max output length. + If maxlenratio=0.0 (default), it uses a end-detect function + to automatically find maximum hypothesis lengths + If maxlenratio<0.0, its absolute value is interpreted + as a constant max output length. + minlenratio (float): Input length ratio to obtain min output length. + + Returns: + list[Hypothesis]: N-best decoding results + + """ + # set length bounds + if maxlenratio == 0: + maxlen = x.shape[0] + elif maxlenratio < 0: + maxlen = -1 * int(maxlenratio) + else: + maxlen = max(1, int(maxlenratio * x.size(0))) + minlen = int(minlenratio * x.size(0)) + logging.info("decoder input length: " + str(x.shape[0])) + logging.info("max output length: " + str(maxlen)) + logging.info("min output length: " + str(minlen)) + + # main loop of prefix search + running_hyps = self.init_hyp(x) + ended_hyps = [] + for i in range(maxlen): + logging.debug("position " + str(i)) + best = self.search(running_hyps, x) + # post process of one iteration + running_hyps = self.post_process(i, maxlen, maxlenratio, best, ended_hyps) + # end detection + if maxlenratio == 0.0 and end_detect([h.asdict() for h in ended_hyps], i): + logging.info(f"end detected at {i}") + break + if len(running_hyps) == 0: + logging.info("no hypothesis. Finish decoding.") + break + else: + logging.debug(f"remained hypotheses: {len(running_hyps)}") + + nbest_hyps = sorted(ended_hyps, key=lambda x: x.score, reverse=True) + # check the number of hypotheses reaching to eos + if len(nbest_hyps) == 0: + logging.warning( + "there is no N-best results, perform recognition " "again with smaller minlenratio." + ) + return ( + [] + if minlenratio < 0.1 + else self.forward(x, maxlenratio, max(0.0, minlenratio - 0.1)) + ) + + # report the best result + best = nbest_hyps[0] + for k, v in best.scores.items(): + logging.info(f"{v:6.2f} * {self.weights[k]:3} = {v * self.weights[k]:6.2f} for {k}") + logging.info(f"total log probability: {best.score:.2f}") + logging.info(f"normalized log probability: {best.score / len(best.yseq):.2f}") + logging.info(f"total number of ended hypotheses: {len(nbest_hyps)}") + if self.token_list is not None: + logging.info( + "best hypo: " + "".join([self.token_list[x] for x in best.yseq[1:-1]]) + "\n" + ) + return nbest_hyps + + def post_process( + self, + i: int, + maxlen: int, + maxlenratio: float, + running_hyps: List[Hypothesis], + ended_hyps: List[Hypothesis], + ) -> List[Hypothesis]: + """Perform post-processing of beam search iterations. + + Args: + i (int): The length of hypothesis tokens. + maxlen (int): The maximum length of tokens in beam search. + maxlenratio (int): The maximum length ratio in beam search. + running_hyps (List[Hypothesis]): The running hypotheses in beam search. + ended_hyps (List[Hypothesis]): The ended hypotheses in beam search. + + Returns: + List[Hypothesis]: The new running hypotheses. + + """ + logging.debug(f"the number of running hypotheses: {len(running_hyps)}") + if self.token_list is not None: + logging.debug( + "best hypo: " + "".join([self.token_list[x] for x in running_hyps[0].yseq[1:]]) + ) + # add eos in the final loop to avoid that there are no ended hyps + if i == maxlen - 1: + logging.info("adding in the last position in the loop") + running_hyps = [ + h._replace(yseq=self.append_token(h.yseq, self.eos)) for h in running_hyps + ] + + # add ended hypotheses to a final list, and removed them from current hypotheses + # (this will be a problem, number of hyps < beam) + remained_hyps = [] + for hyp in running_hyps: + if hyp.yseq[-1] == self.eos: + # e.g., Word LM needs to add final score + for k, d in chain(self.full_scorers.items(), self.part_scorers.items()): + s = d.final_score(hyp.states[k]) + hyp.scores[k] += s + hyp = hyp._replace(score=hyp.score + self.weights[k] * s) + ended_hyps.append(hyp) + else: + remained_hyps.append(hyp) + return remained_hyps From 15bb198d4af581356917ec4c96322fefbd1e01d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 6 May 2024 21:55:03 +0800 Subject: [PATCH 024/125] decoding --- .../sense_voice/demo_fsmn.py | 2 +- funasr/models/sense_voice/decoder.py | 23 ++++ funasr/models/sense_voice/model.py | 102 ++++++++++++++++-- 3 files changed, 116 insertions(+), 11 deletions(-) diff --git a/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py index b94cba7f4..e063e1fde 100644 --- a/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py +++ b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py @@ -23,5 +23,5 @@ DecodingOptions = { "gain_event": True, } -res = model.generate(input=input_wav, batch_size_s=0, DecodingOptions=DecodingOptions) +res = model.generate(input=input_wav, batch_size_s=0, DecodingOptions=DecodingOptions, beam_size=5) print(res) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 8a4a2ce6a..19d9c1680 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -337,6 +337,29 @@ class SenseVoiceDecoder(nn.Module): return x + def init_state(self, x): + state = {} + + return state + + def final_score(self, state) -> float: + """Score eos (optional). + + Args: + state: Scorer state for prefix tokens + + Returns: + float: final score + + """ + return 0.0 + + def score(self, ys, state, x): + """Score.""" + ys_mask = subsequent_mask(len(ys), device=x.device).unsqueeze(0) + logp = self.forward(ys.unsqueeze(0), x.unsqueeze(0), cache=state) + return logp.squeeze(0)[-1, :], state + class MultiHeadedAttentionSANMDecoder(nn.Module): """Multi-Head Attention layer. diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 82ccc55e1..d5e4130db 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -396,6 +396,42 @@ class SenseVoiceRWKV(nn.Module): return loss_att, acc_att, None, None + def init_beam_search( + self, + **kwargs, + ): + from .search import BeamSearch + + from funasr.models.transformer.scorers.length_bonus import LengthBonus + + # 1. Build ASR model + scorers = {} + + scorers.update( + decoder=self.model.decoder, + length_bonus=LengthBonus(self.vocab_size), + ) + + weights = dict( + decoder=1.0, + ctc=0.0, + lm=0.0, + ngram=0.0, + length_bonus=kwargs.get("penalty", 0.0), + ) + beam_search = BeamSearch( + beam_size=kwargs.get("beam_size", 5), + weights=weights, + scorers=scorers, + sos=None, + eos=None, + vocab_size=self.vocab_size, + token_list=None, + pre_beam_score_key="full", + ) + + self.beam_search = beam_search + def inference( self, data_in, @@ -408,6 +444,12 @@ class SenseVoiceRWKV(nn.Module): if kwargs.get("batch_size", 1) > 1: raise NotImplementedError("batch decoding is not implemented") + # init beamsearch + if not hasattr(self, "beam_search") or self.beam_search is None: + logging.info("enable beam_search") + self.init_beam_search(**kwargs) + self.nbest = kwargs.get("nbest", 1) + if frontend is None and not hasattr(self, "frontend"): frontend_class = tables.frontend_classes.get("WhisperFrontend") frontend = frontend_class( @@ -456,25 +498,65 @@ class SenseVoiceRWKV(nn.Module): task = [task] task = "".join([f"<|{x}|>" for x in task]) initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") - DecodingOptions["initial_prompt"] = initial_prompt language = DecodingOptions.get("language", None) language = None if language == "auto" else language - DecodingOptions["language"] = language - DecodingOptions["vocab_path"] = kwargs["tokenizer_conf"].get("vocab_path", None) + sos = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt + sos_int = tokenizer.encode(sos, allowed_special="all") + eos = kwargs.get("model_conf").get("eos") + eos_int = tokenizer.encode(eos, allowed_special="all") + self.beam_search.sos = sos_int + self.beam_search.eos = eos_int[0] - if "without_timestamps" not in DecodingOptions: - DecodingOptions["without_timestamps"] = True + encoder_out, encoder_out_lens = self.encode( + speech[None, :, :].permute(0, 2, 1), speech_lengths + ) - options = whisper.DecodingOptions(**DecodingOptions) + # c. Passed the encoder result and the beam search + nbest_hyps = self.beam_search( + x=encoder_out[0], + maxlenratio=kwargs.get("maxlenratio", 0.0), + minlenratio=kwargs.get("minlenratio", 0.0), + ) + + nbest_hyps = nbest_hyps[: self.nbest] - result = whisper.decode(self.model, speech, options) - text = f"{result.text}" results = [] - result_i = {"key": key[0], "text": text} + b, n, d = encoder_out.size() + for i in range(b): - results.append(result_i) + for nbest_idx, hyp in enumerate(nbest_hyps): + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"{nbest_idx + 1}best_recog"] + + # remove sos/eos and get results + last_pos = -1 + if isinstance(hyp.yseq, list): + token_int = hyp.yseq[1:last_pos] + else: + token_int = hyp.yseq[1:last_pos].tolist() + + # # remove blank symbol id, which is assumed to be 0 + # token_int = list( + # filter( + # lambda x: x != self.eos and x != self.sos and x != self.blank_id, token_int + # ) + # ) + + # Change integer-ids to tokens + # token = tokenizer.ids2tokens(token_int) + text = tokenizer.decode(token_int) + + result_i = {"key": key[i], "text": text} + results.append(result_i) + + if ibest_writer is not None: + # ibest_writer["token"][key[i]] = " ".join(token) + ibest_writer["text"][key[i]] = text return results, meta_data From b139b9cfaef2f69b92dc9f59d55216132d690e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 6 May 2024 22:32:00 +0800 Subject: [PATCH 025/125] decoding --- funasr/models/sense_voice/decoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 19d9c1680..dd00ca869 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -472,7 +472,7 @@ class ResidualAttentionBlockFSMN(nn.Module): is_pad_mask = kwargs.get("is_pad_mask", False) is_pad_memory_mask = kwargs.get("is_pad_memory_mask", False) - fsmn_cache = cache[layer]["fsmn_cache"] if len(cache) > 0 else None + fsmn_cache = cache[layer]["fsmn_cache"] if len(cache) > 0 or cache is None else None # if fsmn_cache is not None: # x = x[:, -1:] att_res, fsmn_cache = self.attn(self.attn_ln(x), mask=None, cache=fsmn_cache) From 663b9f58b9586940a111a52489b0f1e4f25581bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 6 May 2024 22:50:55 +0800 Subject: [PATCH 026/125] wechat --- docs/images/wechat.png | Bin 185952 -> 188323 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/wechat.png b/docs/images/wechat.png index ac8fa38d392787d7e75bd9bd68816cf5f2fccbc4..2e2aa6bcb831180cebd9c0713a937d75758ea6c1 100644 GIT binary patch delta 123207 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 BG64Vp delta 120812 zcmZ_0Wmr{f)Hb?Mu|ZKpN|Y`EK@gBq2|-GvyQL&$(J--SrMtVkWKjl!lt?#7NrQC5 z8FRnq{jTr)IR4mMVX@Yn^BK>$W84p^^_TwST`HPCL|g-{Q`&Bd9LJY=zG#`Dy!5Ru z%U;2zSfk(0uV491MCyvh`<&cAr{0$T36xe}uzZvLmL}r##kVxQTc><3mCVew6ibS$ zzH!K9RSWlzO36LH)kuHw$^CkfuJ=YSyV~eN87xIs`&kVbqfHX3=Rv84^5_> z7n2_^Q!=+(9`&W7xQi-$T{b0y(XQA{}tQkcc(f(ZXpVs9EhC)_J$LTh#kWy()t zw*9U+b>EObWHD-M(}hF|>BmO3g~Rg04}9&0%$Cy>n+UrYg3mT$Fi~I0u46Ev*REZo zW6rMasUCeX9%PXs8~b3gpm1m8GfRRTXQoxjjkU$=)C8+88t;9$&nO7)F%p}duW-6< z``~cV>UuKcy6ULsOpB@+}DE8&VQjOqiO!nII7#L2^ta|GFqNu=z0_)8;VcFkVgS zOAHg^dEB$V@5L5$XNytU_OtjkVsAPhMsIIg>aW)YpDWq+SN}-f#g7?T@mi)&VIq{0 zw3n={))`6hnH1}H@4XPZf*eNU+(Ki?@0qotCoFXsKi;fP zoBPX>|Lpf|`wwulPKyimGCu_JsZE-EuQLjczP@%Xt*%aIgy8nhOt0x@U)2Tiku58Q zQN|y^S(2LckCk?$%u@LTMfY&>l5Zy?-g{X|S}EVCq=P4vEbS*6e0@vAKZTBa`m%x; zv3DGjCo(~{*BCrU#ymIcqAPUKnt%xuwdH>G z+MDs;#P*WNkKj92m5dh(Q&=WRDt%Hv($O*1A%}Oy?nGsc$#8x0>Z3|{^l^CEYVO+9 zGqPw5<_<Scu-&crvwR>1d5$A z3UrT^>A&W?;98gnvmNQ4)rR~r`;eTKB3aAV6B=^I$~G&(fg>l!NAnta%WIz;rj(qm zglz^t##O(CtR4It#L7h8eB>_C+-2X^EIv*l*|7^3o^zK?KX)579wA^|`WGNUJJxAN z*>!cEuY7(ahrwsM`RU~7#mphg-PdQzNM7{1SlSC+{;% zt(R{cX{NZgs*-If(c4=mE)YyNS50i=8&Re_D66?@dw_k+-z)U`sIKd$1{DFrGKg$Y3z%L%&Z1r9oZ9ipf`oB!0Rb89GK}l}4SGl!FlL zG1jnMKC~M8PO_ANv!xy?@~LRgW}&gN{-*Y0_)~In`8!_AyvgkueSV(A1v7P;1fn-e zKk93JCjH5?@MO8k|0=sDfAAb)HvgiFhh1x5vCK{#<&KfUTg+ja?5mk2usQQwj!l|J zO-$@A)s-8_C%BV*E!)nFDln%lWsbF^}HQg`CEC$|@;`Cwe?&XbL>J zyW&;75X!hXBj#QkC+Pe_uCH1i`~7zZ+uzl=ExhYLHf3wVXMA=8=O%B>G%YV@r+gMy zSo}eqL-#qInmXG=DR$qhfM><4?g`=A6^S@yY&+mK2!a64F?{gnyPnZ zl!mXYwfZkOj~7x0BEeR=x8&XXl36C7pRP<(IBZyQ=xMSVk+}W?5uk|dx>}^r5INOw zory@whA&MvR?N&%L%^)RKwGqx5retPjCMiv54qr5Ort!A;nY;| zFnaGIwq12pRT*0&*sf=GlP%_OXGc`r#w*kDEiS-dNV9WuL$Ql}&GC+7gLAW5?2*%d z|F-bY#?gNFz7qNP-C3y@FJ4^lEwN>fWVKp2m4wa7&JMmM;BZE!daF;

I42i^Y~; z7gf|Nt>VKXBc+|4tI{$vktUo5Q8v7^{&=hKg@y(T4b5%juvl<=z>u>**+}D?GZ`k2 zM(@;}g3ns)>h&JAGO-V2#l(IIZpbvZw-fB|wX{6T&d(1Y8qyg2Y@6!ilc!evng0r*~P`h@wz9O^|%ZhFFWre^O>hJEC-5`n-Si4 zxy-cm^uZS@va%nir>D=zXqLYG7(mMTq@<+emAZtY`Gr|y%=w$zc9@3nrKMNn;?X`o zYn(S4X6*2f4pRe#b7CEi_hz4_TP64O^!z;B+n}eV6(zZ=c87+hHIgGxN*j~J|9O8Q z7u!w3t~HRR{g8!)1(_~sWe+uOjo@*q<75>Q(q3O*x9^^9i@t6jjWdfOw5eX@j9f~GF~%fpqG%Vs98 zRTLFz{Zf89&&J87+PR{DdrAwDYJpw=C+SIUL@o#buN4z?HjxemP zO~!e(cIQ+^WMm}8@yc+1L4jO`d?Gsy&5s{H&=ud?NIaojTebG^s9Vue*VbmcapOis zWtr(Oc$|ojBQ%1B@MKZ%mWAHj)9eZUetvX}j87fEmfOud8$C?kR~b%*cN9MSCpuW; zTv~{@7>+s5-jb4&>*MjaZu>X!-FR*CN3c?sf^o)$3pI=%< zMc+;(uXjtRyfAaWF5*5glaZO(I#6tg9sNk-FC@AKaWw47U_-J`Oi@FY9W@QhW3=0M~3I2n9--z-{!VDR?CHW9PWCW$qTN% z-&`3L&>Qk1pfH;F_8}wUzT=A4DAVZ<;e$Nl8#jEr=X=5p|1wAHJdqk6uTD#&OPa5A zcz-%ocvPbC(=Arsaktl{R^+!Y$qVnL&Fe{ZBnZuTQCRudeZ0Dg!!9z=)6-LnsH&@H zSNpcMw)&g@ZWr;EsnFVnnD_5IFJPqG7``ozR#&b(F+12^&WH?6NTB-1oeQ@n5lF>G z(@3^!IEb6}WlRYA`tF?cix(mD&Sj5DQ}vlNPeVO+h@8|+xQr7(E_lY z6q6n%V^e(g%rEO`knNc zGfUl+?Fe0UOXhQ!Z;!v6d8CztUG`?#DFp_wW8OGSd={cY(4zU-jx7tmL@UE^d&r1hy-=2c@tUrB6%^<8a ziN10ledogZU&5+g=^NU6x%M{kK)Z9my;$DY@H=Cu_a4GKw=xeH!@S72eg= z{8LwvGEw);jEsu8*c0f#LEl?dR8=V$lnEJVX=&#kz$%t1)n}v-?5j;Ir*y-0=tf3F z-#6L+#hBbT2wTugl4LDly*FEt@w+qOt%t;$LIOPf8|!1WuGsF9(o$L~?TeVUJ9@~e zFJ*f2^dDmaDR|8K7^-sf^S8pKXe#=$GcqK2m)Bc40w2r%?jq%xV)QZRxL*}t7AKbp z@TIv>Fkx3^G*;tm*DcG-qyC4Rmsb_%xXR9|k{2{=Ro%{8Ta0yh81Kb)v9z?*c)lwg zN5TRK$Yt`2l7BI;bo$LXs`I%C`N%|#+vc3YXjxnw<=Z(-%o)7v80gUt+WR{8Mdkzg z8N+?pQ!hE;M!yhB;9Zwc^JBAqlw47vQg^s6T{WBFDuaFPJn74rR#v8j?#T}1xHN#0 zzeEbxWMpg{O;}Q;#m>ym{$R;~4>@+zcF)bpF=`28uIt#D>!i)2p3_9WJM$0x?!f#e zhK=cSNyv5k)#hYgP7cc*X%BOA^DiIr6t2H2^(E4EnNRo3eC17ei;L%WN^1Gcg-7;F z0xV4tb>ke)B13OuCd-?vMTHC0fk6TAV9)^5-^ zvKjDurccwFAXkn(QhI%3BORVPbVPE6*6_WJS&FmLDtT)9q&-s7(xKnJJsG`M0~5EIMe$v`h!>bcBOj0@oXmdS^$lp9S^s$6Zp;~(EfzA& z0(=7yo}(C~hDOCQ8UQtRxH}bS_vZ`Vd|!U-=0b1l_L0v205eo@y5s5?%_M)_(zN!K zRW6*vvbnT@O6r{~L>gZJaBaXPl;UpZ%hyT@3e?@1^1L!vHPqAwOnJk~%D9<1I3f>L zsyprlFO->erXa!9Aa@kWQgiTNrVM=Z^5=X0ecf4ojq~;`)6Jpoygs!qTOpYV zE-Y3FFI>#LwFnv1LYJRXIg3erq67+=$G}|n0%=4+HqmX}cXd_wXh9W^*L94V@7?Iq z-g*seL|MbZ2zmyr^B~Ff@rm>s)$otI7%IfFJ z>5rDBF)`%ob#5SgaBGbeGoJ)j&bw;DihiK{`d!X`i&I5Gf#_fSma3YX>B7z(pj(Ja zp$?mLBztf9&#P-^B9Hev5RC<(K#GP=ZmyaIf_u}Uc1K(N-gh%oQoh;TdV>G9=I^g~ zR@es@f6gdrYO(^yp{{0eF5lcJQD9F2s3z?>^T=Yx2aAs>6O`o?Oo@k@04mn7!*cg- z05<$?G>?VKm+nmzVNQ+@5JR=pi212Nkq91(zFnO$1vX&TfT!x{Gcs-UEVt-?CMWml zu4YBsdI=CzE#zp6%YN>+#A&kf@^X|gM`}Anqu=gt`LV>sAfG^KM@Ewn+XJklB}*ao zvbAZ=Tgy^Ezl+Vy%@=UBDDfMvwC2@z%m*-eFN9e0LH!J+wfc(zX2u%v1N-;qQ=5b` zq64PFtP7si94&@gX*uB8R{^NN%5WsjtxHu)2_*rQC5VVJtAMT@|l#B)K9~)VY`_L@7ocXi5?m|$1yw>4fFQo4xNB- z;S)ahj}CSsEedN@g!kuY2df>ezu0^}=Eug#nf$C#2YT6AZcv(1l^9tY@JZ?>wr~k+7dKcp8 z8F{^qOoz(vYuw#qg}$I&?a&Ogk=%}S9tc*nkZZ-}>bP!W;O#=!dK^weB7l?{`a9UsvmIArLbH&QV=m(sVzPUB zk4C2T@qW9()6nycrpEhT`&IL^O)@f1@dh?XlKee!G2qPX{x>-YbE(?f;RCR|gwD>+ zwmWHTAfui=dv+>=jOS^;M(WGi0I-c6D@g5&#un3{_fl(9nn+@21wk)>~gH?N~sr(Rp3`rKF@p+Q)JK zzGCA?idpGx7Mk^60;@k!%o?5DSspfF!O*4D2eaP28%8DMA}Jx^^=iCM8-$o>MbY^g ze~!A}vZbtN z=dbqcAtNJNNY$UWmr!wsGpq)H`9#S-$y&+$ddkP?SLSNnfmP}ouLz)>7d^ZdxYR&8 zp&+AE>$3M&8*`N%H2v?kQHNnm8k)K!DSiE9nW%fz5z1U)2?+(&W;_?8b{zxF*OguW{e>PMpua5OGGBclaw#?)yeEIgbZWIgXv zK@qU|BwiU~V`H4z*Y$g#*rj3XPjnyk=BjGqnD1*uZf@FZZr5*TwExOH9?D#3|JVz5 z5Dsgx>7Lom4Bhdubr{Nkpz(x6MEqUU+4dGW{A#Cq9Y`>(L;wjU%YtH2n-A^{crDs@L~YG)N5VJM;yo9ar#lU6#Mxx;($|OFMIp?T7Cx88ZY!@KYr(oxq1I$EY+>} z$QVApj07wC-a<)>^WIG4>9K?1@naHhJ-c?E{xg>a$j$j_5>_rkAH>Dt+z+;;jE&Rv zZ{nwBHuY=0mi=w)v*+<5Kf>H%h ze%7qC@*1uHTH&!%J&s=%Ge2HmU&y0wp$HPvmh2MA-5^+A3WtePi05-4ex_SGD8KVB zkxVd6-l~GalNsF|2MYk_*<9y-@YX{Zppt}5gAQ6%_=ih3TRz)P$*?iP7h%s9X!a!t zxjy-8|LE-oDMim+q3V&fD7e5uYfLOyqG;&M`SMrX z{G~jh4W#WpjwtwVM5X{}Zh1^276J15cRElPrkTj1EA3lU6CR*?60497< z+*n##lJK@F>k_HM;T}%=;Clvx;nB@&2p^B`=;njf`rG$vGcqzd8J7W4%MRno@9BB6 z>y=pavv+TRC*r+C9vT)#T!xilg2zW-A$;Fqbu2&jrRp(7Dh3hb_OgfMDiXZmx5 z97Qc5r(Wp&|dTm<{!pw-xy$<~mGZkD5*pR5-2yU4)bORqJT#&Q1mdo}MvyjVXk^Km2 zq}&TOHZ#jEwD?k_|9$#!qob1kUy}R2C9kDLF>KgjkH`SrK|?95*O^00#Dx83A&R!J zjhDbp=%na`CfMBC+AXxl0o;UMI)ZeCHnZD|?=m*)k&cE&Obs}QBz==%z;sap`5y@C zp6vJI@k>o=OAByhrl&V=FAp1o`d;7cmX`+bOZ|EcfyN&MJx0AheRe)GkwNd&mumnY z-w*?CZoMqA;I*8hqI*dzz?dw#gOgPZznf{u7Ww@BkwyR1u0C0Bpr_xEN=#zjvi8c^fWet zx&jL;eKF=WsIykXKp~QU>IlF9fCTO+Iy#!HH@FNO+JeOlbsZh5NH+3vjV|XwR(g7I z)SUr~r!;*$4t-WoK*H^=l;4uK z_-r2WS}qTjKfeBWh?@Ly=W}h|wt^1WV?_TPv)ovR#tl|sXE2Z~RHyKaE{!9m%GH+R zbwcLGyy<`jJo|Nn<9C*4pUh}>o>fcfq@f2Z0&Ot@ji~vI_6QUj!Eq$8K9+v=EM=(c z`;6WETkg(ZRfb4ppPLQ{vm^^}1ejousD&4h00w9T0P1J5^YX$FSXM<|oNpg6FXM0TFGRd$=q!0X`-?$0BbqwO z@T;lV?Og4jDd@L=#~4Pva)Od8(ffL8RM4>L(?@evN}{zH{B_<}14UWv-GupjHI&cH z&2v_E7Uw!sWlLUR*iNJRySJw&O78PZad2Q~CsDFapYWVyKKH}l4=Ee)2Us&vd{k?lL3 zA5B71GZ1!OGJZRwf!4Bj6(7VDefp`Nebg9^a~yN#%<|O%gu1JZQ}Q@D7;l9Iz4dEKy#%Q*%`~~Uu@?c?~%RKmrtuxw!LA;^by|`@5^P_o-(#oT7X5j*I$o)c@rEH z6O$DfL`2|y<#q%t%wVZWAn>tsf;ZZK{fba8eJKUqVaB5~lu>^Bb!kEzLo*y=8>I~69R@}%a=E&f!az$`cH*OvtLmEv|TAU#5M}{=H<{Y$bL1j zofx`#a~PehQ1%Zz=>8N%oKNIagZB{#rW627ZUL?((zJ>vJ`%<rXTExA;|qQXc>!(qNcP7jFJHb)ozb%I6n~uQTD^eW;e-1J_DQek zOAYrM^Jx}Dl_(fz&ET^KY08Y7h$7g)t2=5-6;(su$@~$RzOqbovx9~?6xT@ z>`Z++tRjNR|F5+WQ1U&$c^DdtfS1jE0`)*&hMIFYSjRsPSu-%$`(!a|$JB zfRjZb6n${XVENBLi$XqbS6fQ~YcGgZ0eP3Jk{_aJUCT4)20IjlbC{_Ln}I}r-~+3X z|Hz}W=;pugS6YFS%dnY%YQ&S`l?K~)XhGwSSmxVr{4d&IP# z5=0*~AVLiWj2a9gJn5m=+s5C$Pr5wEqhe%Y!n@xvHYe2wvoz7MfsC{?7O5l$?=Z}{|9n8te$&7*=WB2{d zPFd8sU`%kLnY->_X+d-!mI7NP2^Km7S`eIujikc*g)p+1@6KGzsNAF=O8p|imjgC9 ztW1Vx0HUTJR!PId)2pP{H0LN3GA>&PG#{N&qxQ(h3MRAzcvHDZ!c3WIvA-~~>h&x+ z!@GQ-fRmF3V68_$m)QG$`}ht_>U^?{KRlSP@c9|8szbK90T|jN>#uSt6juKIq0DO` zcw8=CHrk1L`eINT;%LhUKFeT#<=wE+!aEnt|cTfYT(lh2&ZR2Sy9RkRpLI9v2oql|*xV$N{k|`I@Qoq-3{p})g{q~Rr9^#5r<_3d4S@e*H zg){Wf3D{as1!xcleQ4&S<%&#+i|y~M-nQeLf{A1M<;a=|65;prHgS4d6&@k=^;4 zysaC%=OjRs(}HJ4Ffay2(+X~pebfzDY=+&wkJI{zm_|R?cg{eGW|k|*37t=~PFDG{ zv9NFnI-nLrR+c2#UPcqhw-3}$-Ph{h{DND7L1F9OEHv!*w^Hxu6?Fzeduxm3mFLxt zb-S_6%)}G~g~LtGcL|%vGxNI#qd^56;gzzoGQD34X`RW_olqM{Xvl&wWm%mK`0zqY zE3Z0P=6^)eU`c=^&yVMEYkI)LX$&k$+tDYA@K{9DK>c*)s5HRpp>rf)VkV?*rfsx= zf;2FN&N#&YqHcZCpJQP?I*JF1tO{Pw)^U^FGNoCqrMa1Ni~nT2t`T>J6kh_~;>p-t zdn|9qz0Wfu1}#83#TAJ850*+#w+Pt$@yye$AN!YaUug#)nmfFC3F5r*(it3l8AjXo zwze>sq$r9uWPpSLndX*?i5}ds=r7oEU&$-|6$00bD)-B$rzJ*h3+ndGN4c#no-99v zw$|M@uCeTF2OEhflB{sn7z}SeF|ltgq7jjij6mn;)j+?3!W(E2hn*G$Fhf#I z-G^y@%ShF0dT>BkSXpH`7-8y(>Q7)%B~EJwig+>p>^Mo-g{ViQa99ry z#!t47@(JDpV^`CWs7Z*-XJTOq0T28IOt29B1wH`3FfbaT$ra9F$VI=L!Q9;)KRMEc zdb{Ul{lo7D=X}IHgNE~{&6=lKDJLezUNs$(gbm;Y3Re-%1K$EU6%6|2Ij9acbf+jO zEAQD6T_)$2JbQ(T(nir`;=|1rs3(J*Lm(>)R%v+->i0CpKHStn2Id5rnVC_)A)4DP zHanb z#Z+f??r4826s15t#a2xZEPO#aT1xZ7i|VYHj$!bNGD77Tp=v{2o%uiZp+XAnoBQ&6Qf$-O$w!!e|E8B9St~nRVo0i+N~!+Q za=7pCsJW#j1avzyIK*t46+eH)3(WjZ7R9UIK=T^`0RbfA;#VJaQ|q0=kSq;C`kcUK9cs=+au4r>`KA18=H_YX1a2RNdAxhK#@M~PP#U97`JgOK(T|qd(!;+eWGf{`_xCSon zl#dYf7n-g@-FlVqe{#c-55a2%s^}bp&m9aqwYj4s5X&?9miHt8=^BGALpCNuj<0%X zY+}+%AE`wn>UEhDdml!Jh1H!qXQhA9}# zGQg@1^x_<@0d;urPOOQ8N?6rsCe3(=UeS>vFbc@nFf6aw;KGPq2W3HI#;z@rC;9Bz z#m@tqgoE=l1Tkpp3P`I{7d|(2o%I{o+0y{T!DihVQgU)~zb9%(FAbvW?Yh0hnHO96BZAj?d1bWvv~VVYq&h)_Q}yQ$FP=ZY1NVa_ z+I|B4bN5wq-JGMo_0T>DcC+TimdXaWum-=BoE-ASXP8H?K^SYu8YpAdK8~l(**=Uf zf%r`{r=f(_nGYC@tT#9S=pRq7OSFAA{`)J&hqp4B1Fs6N(vuyp9uIlI=dct-304H^ zjn9u%l`{E#VK`ONOxRIxCmC{4E^9Lk`J9F>QKg-J%TYa4hJ%+5Gt zS4Py)ALfU?ODW)Rx6k{+Zv!TP>f(YkzvGTzizmJst5N^k9t%OQBqC(LJ8{~NwE(;a zuLc~#g28Z0L(T(tICc9Z=-h3$dwt4}X;)w*Q3VFnO#R70y`lDvq(OjUu_Qo^mCsY3 z)KpKC9L{hc!SIBdaOCg~tf;FSKz5&@uh$bF%*#mVGe2 zoV^?K5Ss&+DFY^N3N8+rY6@(P;xud!VaR9lTd^hzR?bxsFK1u-lk80u0!lb&*l^^t zEtk!oN8h=C%X5f8J}h;^--j5&29QcLRBOzy99xKOGW7tdraH_{`(mc0}3;EXWK9o)9p88*wa;HquWOz1mx!F^68ML^RQRSvOw5Q3V3k zds$SpAdGpm6IlyB)8t@%%bhp=W&`$RREUFY?uAmGYa!*eii?SgGR+A9j+ou_=~j2R zEi~I0WQ-C0S*=Lel2I|b3dGodf4<`OV6vBzfbCPyNnxUHHSNy$_z?12KOG;1wIv8? zf+tm*y$oxA1v~pIzPP~d`E1+j470> zv5PNr0$_}{1x|2aO9d>tmkXN9jLm7{@L0RlJ8v(MPUXM{Pfixmg~2=d;=);F@cJB< z20D9i;Am&X@>*A5_s~eyP}OUb?r|cWwJn(XgyP)x>@))}B=JDwRV&l~?iH1I=rp*I zla=Mu!fCLbF?523L62BEd-3+SOB_)b33uy>#T5c?i>$CBQwgps#Wg}V#4ltu!HQZ` z1(bFO3nX1Go(eY0G6(-uaqlXan z89y9%+mKZohKNdApXD0J(8{PI@?QkUFq${ewv2~#p-`Ut`j4Bs10{#x>9h_9tGd-a zcr}3NwQ}N>JqQRnt!A?{zzNC6*Lk^kv9E^8q~KtLzH5~^X?F6r=*+4joRzug#-7dW z6~~0<#$u^$fA7W}kq0jE)fp&AlvSA2^w7Ro)8NQe>i90(x-l@(;CmfS@@cj_S+X3f ziSB&udGG2yyt`1yw@C>y@tyyDJ@;eA?gxS+XVdt6b7jq`bn12k-sGFn@ldD3F`o3k zx?>IYNdHb7jUXr|{As+?dXRAW@)n)X_bGd}M{wv;EwcDXw$_qeajc!Rb+x(w!O3uE zhmNY=Q8v50uwJDm?zaBz0z|Lc5c+x&EmJ3XLdafR(CW zB;s+L6TiqeVXdZ9eK0t_%V$6LJTDg$TP&ZNOJ9BuZ<2sbX6Z)Y;_cQugtJW%-tHIG zo&tZl%EOlZK}v8;CK;Rh!M9f9VE;5`6F%(`rD-_LZ)Y0eU~sA1UEd*Xujp* z*DY;t_3LVCc!1;CYhAb3xb4yaQNQ%Rv$L8*RE2f>ISUTe?#3t+tOX{?7QO~X{MnwV zSnE0kbQ5F;ps~870B9MSF-Sc+a5&nBov+4X2zze%#MN87{Jr(1Uayt{HY+;$Y(pAAmocDt^wZXs$vN3=vii{0;*7a7E{eWDV| z8MA9;i&$8Lkkg>XxoWl1LZD8H^+4{`R5g)Vkmw6XJLA@7+6nI4>RaF*5pfK+a5?iN z-o#iCE2ke(>qU&pJLBxKTsn3kxGx>rck|j;?-8{0d}H!DVY zpO2Cdg`(xwKwbdzb+}f4$$!h#G^m>k-f5aX*=)RH0@yhp1m$!P*JU1bXsJ&Iv*hcQ z!=rPDG&FLViok5_H%`C<>B^K(l<24J@qq8=LU6=OD^T}v^5%LWa@0EHWo1x*FuIyn zQu0EKe7q1%1W;Jla7HLw_CR_8m5Mim|LrUS^vz_%T3xKt1!mwjEVGFAS)k(&G_D{- z!D!Y4ZhesH)rCO7#NAJ|jSI!lQ6P8zQA3Dk3zXV{$EBEqRU4Ry12JZwUc-*N@1R38 zw$^|~9{DFvp0pLx#&p*+$|t-c=@)z?E%D_{(U$^$Z$On+Nbj)%4GYsfUXQE@8`J<^ zC@t}koE~h8GD{~!(Bmu~=Dblqk397CX)t)gA?+u(zrAcB9i9KfB+;D#rsqM>>RW(# z>q$pzZD9I>zMnBQfGE71Jn_*UmY9uA}`m`b>9j< zTyd-q-5EzjCQEk7&S35Y-Rc*-scj!z1C`wc2tZ-pC!i|3koufePy>-Mp?K$MqN(Hp>>iX_OH1G-j2v4n5u}v#mC5$a)fA7>T@ES8Pg6XFF);0~&s#xa(2_u-3D_o6m6`*LQ{hK_YgdV zbQhF+=-HE34(AIWZFWbrsMWbSKO%ELvI+}TA-BQSI|UgE9Qamq`q`J4g^O{zkn>LO z>+e4owgxq&!7>FYobGV6i>R~w2b%7Q4gO#O=A7&$o(!fPltTsL+}CF!bv0NFQGLQS z`DS=o1*nFFnYQrp?v$FUfI0A@`_jXc@FwL))qfqTdlB&2G;*3iGFz%wgd3CB!W7mr z`xNN2^tmM ze5@hU-DQg8J>@etpDosqDBFH|cY)|57mfCn-i;*MNtZI>;-Lr!h3(xtc!F61)@TbUDMe=B%IhGSQ0dwZNvxTN(>4KQ0bm$9O(EBjd@? z@Pp~CuXn61+o%5B>;Iou+&}&&a2Y`;uRQ7oZqH54F0tJ7Lv+)ort$Wtoky>(xE2dd z$-h3n_1CFH_q8yU=U+e13%}ogb}G7k^GfIUHF74ZigQh_cPhMV2NH^|H-#QeP6(bU zd+T!ft}#e0h9*rw*3f$M<(@&y4~!NI@{uHPui%li1A zJFs25s+HCho5Dm{>ajFH5*(47!*bB@a;-?0C~;E1zESknw;y|CkNlHP-IEogaf!EW zB>UfuGI?~3KpVl?bJiZd?hxW-!S43gAE(0+g6JI4*awz9B1iM`I4%eurYATInPs$? z_7}wC41V}!<+VcaMcMniehw8FA`9{&M`^56s`dNf^X^^H@xHs*uZ#@ZL$@Qt?OnO` z&}csj%SXAuRymTwY6v~j984YA)&6r-PIuOCAy=DRfTX7#@W42X7Xh_A1TJj%0Sf({ zV|Vpq!7M>}ySes5`?;i*!BWOPY(ZES@}h3#$8exC?rW${gNWws#7m0IDDn zv6>MU+X9^f)|^Y&Mlutz8eNQ9Y8K0c?w35t#7!X6Kf#2w%=w7?gq#&4BtSW98<3I}F_eOi1PJN^_KHcbP)=h+$r_BtH7x&{A0qtl`uEAZ6H4?9i{ z11DTj0EX}ZzY*DYFM`mMos;9lnTIhvFgw_T<_WI_>K_S4E?FHf2s*{q{R3qDgdIc< z&T4<+ySFi@pp2ID6}o^2)QTB07x)q2SjJlmyf?WJkei!3vr@fE$bW)L3umyUWY}0$Q2ki#uzYc^3c$Zb zSyj9D48r3V54q5m#N*A(phTFlgu>N4G~aRperybrPihffuu8}{4c`AxH|FP8hhXO` zX>BnvR38o&8+v~pwHj^-s0awSycc+~du6y~ai}~O=#9A2S?JJ~@AqE+?_`q)oXJZx zwN89f0rzQyJDtNLBav3XZzHhtE5iDT(Szh7BD!ck^4(d2lJqvY_=nxG+U&>+yrjQkizx(FJ2z1 zi>`98$$(>wPS{HzSMJm5_W?8?^7Fd9p#FZgjp1ZDdJeT+y{7D5Hq24bNg{Y7wCt=T zP@rfep`70I$))Q_^TC@pOrJQ!rJ?r^bV0k6Ai~E7o!Pduv`j-X$p@3_dtwCz@Z+xzFr>-FpMW{_}o%^ z&$xoA#nz`xz$_pjFzo`&5<=h3zqw$JW|b2F2aLrng&^`Mpm@+Qao)ql9b9STI zQJcXvxoXSb?%YF{H0URup`KI~a{hkkFz2&hz)r|)g(hdp;blIRPXP=yjT(31ETi84}V!R-A{K)8Vgya4{1K{k4)gLUk;-8X~NA3|dg#XgM3 zGp^bAB@ofF+ivZVx-wor-nV5_rL_Qc%qYF(1Sf`0Nl@(r_wI#D7<@s794+cvYF|-S z?uB-xv<#v--Ng+I5d_Z|wdW%KuJ-0eYG`U&9N@$jfC((X1zDPD!&teHO2DB_RRTJb z%Xb1^HI`J6xZ7AXl;E-t;=SPA_lf6@%R@Jw!}%<%)>nP($?F$z+~Vl_f2LU9}qN1S5wF&73B!}qUVY4`l= zi()vR`cUAq?K450xQaA{gkkNod+ZCr0z{CCv0dF_JR#rxXt{Cwa)apoBxg90%S|m8 z;gjK1!)GbQCNpV!@F3ku>%>V=E~d1vPDt}$pBCq2dX`)MKiqG=)=31)c)q;>b^=YG9PCypIE{53wP<8q6G-Z@KDM$gmzLD-e%*l<#X_GCBB=0>6&}2C7|xFtiA5 zXb{s}e6#yyi{iITHb&-pu#XP%e+qrlrJ>aVqy&*Qe89BNB2nO{+ad)ZYha8&USX+; zg&Rb@Ho#Z~(2lRnwNVnh1;=VS!`GTbjuqf)^Rv0wYyLgi0!^==9x2UU)v#%cg>!53 ze??q2vtojS_05mr6i7CVyycbpU?{Ws9z;r$OczOTY8iVU80f_F7+b4$6sty z!9iYyLx4X)$C3J*$DrXe1!ZNpV`DYsq~5w}hJ+t(9c$c{D55JTu*}VGhfGWUTvkw1 zBQ5WHU|qB3g+{hNvg<0t8j1tm;2b>!C4wHvhJIhX`ub~MCLkfqTPef0ezv!VqwX~X zizw_|2_YT=L$EwnLpXN_tNvfea}Pp7a7a)V5cF0!7Vclw2u`R`S7xR#p@V|&TrCJ7 zGN=#gzz)3w9-Zl#nPzxocY(@X2dUZtb_AL+$Yz}aG7|y67-g{1TKDHNCxou&p#v-R z&43fNv)r%Ox^sMdZkQ1yWDo>jcpf5#4 z&(7L(vQd~OAjIL;RC*d|jMcCL{BYt*%(w=+G5GCYfcV{n^Ets#Msz7$4;_}6AYJX7 zb@@NTf_R=s-p;OsQrL|zg{#79lqFKf#Z1h&0Zw&aLT zNN677wJw}?c6M{n5yIIxq^^~l_xeFGE1UTr?5rvRp{ZJr5^{YoGd(@`KM#2I*KY#ig)m1@NT&j|nF2V4wEWdKF?otoH6f2f zwQxbJQJgrOa?@JggP$i4Ai8y{eU$MgyVgBYS{4>R0T|lzZnoScA?aG5X{|C)D%6Qz z8LQ1T6)=~DqEya${w7zb(sKCaioG%%{8qQCzg?9MXX(x&R%?I0o?aNO=I!5p2($fA zBqN77pDGb)$JdR)Q)5!LqQ9h<{xA&zPP8hPN00>^20@{=ZcKj30 zW6;j58dn-ghf9q8pA(Lajk(BEqX+nq=K)YTzS^H{9(STGq=a|ONt7uNBz*}SI1%6A zbKmFARV_?-P6hw%^DTx0Eh@zZ;>j>;U;6F42G8hX_|C?LA&fyX0Qb5nm=w~inycl5a5A!VMArd$^#>odfV;a8-?ZM zvM*mAO}HSNi~aJ9UZz4mKH?G*EE<8(Q7C#7R135exC4QoJpIg;unHom`eM_00)qdC zvo{Z?vTfUkm+Ed(NugCqlPObHGc74e88U=O=AncV%FNY3!YXA-WKQOJh!816RHBTP zGL@+i6{+8T>VAIjyS?B0ZQHkf{&=?M&a#GUUFUfm$3C5}eLr+{ZR92JiZp|D>V=d; zuW(zG9s{h^hY2yGhb2XgM-Kp^(wHhE0)!_m=+ZR020&d3_SvcozmN!%Y%qw6i&Htn zp%O+5mifg`&5K#|!CpnUer#H#?Stjn>^Y7ECude zKXg1aPnQzEzMS@BvrY7amwdF)1RzokArL$bkiDpWxHjgf!X99sF( z!OVX@+Kqfq;kgEI6UYthmXYfAY_~)f2wr<1-JAu#l2ae&1C)&xmowTfI){ z9vTwYQn-Hq{?4CMQxtp1sivfx&kL3zFoKVdPmZCNZzYhoCjgi=d%6*(ofO>tcsiTb zBf<&^N+H6MlIlq;UL75s6z$Yd_1n_t`)>fhi*rF!db#86Tkl#Z=@k0TTUrXkn5`e{BAO1+my}*hARH$pvJuq+M9ec{^`rUF_G=3a)Xnw2%UgT{HBd zxA%lSpB30f-sboC(Dh-A{h99j_OY$rb#`44zv7N7cn`;O%zX`6=wY&+M^d{TdN`LZ zEr%H7uF`Sv)VKecGv{ni1Nc41sfp92bd2@l4vvn!RxglQk@f4ByLLYj*A07KW3ie< zql1DTV~4GNoe3t^9Hm)1fe%}O5c}fAA@%zM`6pf}Z_d_CR80=7hW@a!_SWVXucIJ| zI{`0(D+B65s_J!={1e=D#*zV7ug)L#B)gm8PYm;KU`fhg;)=Fn3`lZ5ZbhU@ki7R4 zwmD$^^{VP*ar3WrQ8T2BI-n25?Re9$wzM{L%uO))8SE z3@STz&cPubhNK|Vr0msVVq$mk<@P@brP?W4$#r9*%BYGl z@V!5~o{2RR;_5Ez{B>PrRn@~RrWq@Ir>!dSF>P>(aDCp@->(ETPOx&9=dZ$dAr_(i zP%Ad!77H?^e*E~M4kLjg<7)%Q-bL71=7hP9cJ}mGj9wgubVP9N+5C!dA*e5CVk-qz zf*~+EK-%L?SFnC%oWGXerSIxvTYA}zY+D_V=iqVW6T)`CuaJL`$=;p7c0uuMmKI-I zSLLh5#!Y~a9A#FlxOK!*z}!qLL;tqBhljUA_xZ8j!;#9rl$T>Sz*ji; zz5n&=y_3f=!EXQ2xY*kM&u8>|_~Utn6fP`f{td#CL?bC4cg zRxbcQ(Ww&7F973o@h?TDDtC6>Oh`z$9eb}pKv3`sp!1ulYA}LhG8$fd8e|Na;2nHsV0&k-b~zy-b<~ z$MMA%Xqp^HoRzK*Us|wy9I*#>l2NC%Rb25?M{0Wz}^a2!|qGxQYC zt(ub72UnvzIB%M!UlgdFrmG=bRpHIfo$hlKm%?Wp<5QA2`uN8{VvLq`;gMLQXea=_ zoT}10UWNu~STQS68K#z2Y(HG}W|;KSPz)$Jm%2MrnnG1Tj&EPSJln|yNLQ(lw+FBp zIVs$nS!nn~+IT{rH<^hFs+?QF6qr}O<=FS}D%z^c&ls_35U(_%5_r|#+2awOpz4UZgz1bO7e8?1$g-ig z#X3oK7?3{!ixtS+Y*=y#3w^m?Hom#o@qKmJIEWEU&H~ig&Wz|US6hmmHbWb@Ammt{ z<;~{<$S^p9t={P;RJoJjV$T2mg8q!B7CPUA?$6pZEA@}R7Rx%!5_SudWE0-MOIL(r zh>GPq9(^Zwd{UNUi0#di>g5)(GXIY%-T$aYg2~>6%70y`R?e-z;?{}(6z6%$S^T?N zy-%7jFXTTS;coK!@BN0c;@1ysG@Aw2Gh+nZPt7%ku6UOEm6_$ZU*^YG8m(Xs_5bY^ z<=klhwk85gLLD6)&24Qn_wMMmu(b`~Fka;owA-1dYPRlf-k`jLf&8gbec8E>t0id4 zUg9fa7HzWI@+L`RBkKR1S*>BspkoiOU%$Rrb+#dGEg#i+jLu;^B)KU`2LJdCfL+Ay z#XFsjmsK7K1x+WLPCx~ zf;Vs%cxPsA29IZ$qyh@y>Ep-o-RBP-n(uw(%EC%IAhVZ~>#Cpy1feLZbq`8P(DC;y z`CyS0g7zR5L2IlAm$#Tu?a!X=l-R5o`0n>G!ULApJ_?&&QxdkU`lOSS6EV#mpdKAb zR9yq*|2hhrc}=%&Skr9D*>h|E$!{On>6ob;U3=f zW=TdyhG3sXI=tX5z$uH`VlXicLQ(O`pUg^-DO7OBLkTP; zg6Sg75L$`KbiotkSiusYKAzh@aff1{Fh9TiO;P12`~UO>x?^V~vGQS= zFmHB1@kCp++WiYgSeQ}7R>v!ah-k$tEdIdj0^R^R%Th;iyA9@@W6g(tuuz*Fnktq zsy}SavSo1&=cAHKN=rY3l)~fgPRxEe3xmLX$?@(-?d=ixuDNRGUd8GKS}-^La2V}o zKtMo^QOSop^Y*gNQyz0;7`qN_;`mPRg_nH1(IGx#hc4vkJnvXQYgu-ODa;|nvDpz! zg0w>~YtVJio;^+3W(O~S!PH4zJoBz()9Q`8c7@@cZ@3dL0L@?``Y5~f-9SSw|A`I{ zSArNVQ2fi_pbBZ7ei-6|N6J!$I~1@Ul}aBCfWj{H%+N;6*pcYrrQF<==UtpJgDOoQ z3s~lfjW%N(rV`7qiATZC=Q;GLX3!JHQ@6L4QL+gMR6?QXVaTTea@i@j&jSNi>3mzA1gU<;bwZ?zEe<{)Us{%zeWh+;@HxVZ|; z{urWUibj(Rig&aZJ7pTOFgoYJUYtS4n=?gs_R>GwW6BW>>h=se@n7izG1?OO^$sqW z{rfs62twylW)LQL7aNuR8dWCU0RSfxOw2u20l%lGa^XgENYqcc|K2mA*yxtnu{a$B z6htoOV}@C~ySTaKVzKsDUiI}g!H)Q`cH_2f!E5%o>u#>Xd)37Nq$2~=>Zz%zDc334 zs5?e^!Y++EKQ`khXzCx@6XR62rN&hMKBbz(?sCec;z<^?&TlddcE>tGwKumNS!0SU z6z(^Lc4o137`{!jv$Id66}b}iP7@DqavKN%q#4da(oqt)r)=uOw+r+**xT!ZJ@ztf z!v3)aawmQT^kCLVp8Sh+pk+(suR@T5uDbdSbryx4NBEr(?DOl<+Hlo&LCyNgmjSJP z>?j#&5U-+BBB7UMR=tFWP8V+CBh9B%+gw}&-6TE$MXo_6C2I5C9{iY^$_00EE13G) z$!7hoq)45G9_F(OGg`(i6xtRwVTG~YdhXj#m;H>m!lM!<%%N7pChSHP`YhPH(zKAN zZTI7LkO_++4WL;4Hdd|%u3ODOb->!j1m#;^ruq-vZ-Z$O!^}w3%9hih8KvDO(w_gB z2B|B@z!voxTaG{`5Wr6uNaPr%W@Z4lle^FB>8&DzkZ=|9w9cQ&KpvnBQZ@?IS#Y^f z^V45+L30+2B!(k=V8)k=M2Cb_jynh|pX+EG99(Yx+JI(!W;EB#lT|Gim6 zL`hh|)O15-b@iq|rQP-aNd3(gE}TX_P;BP!rJ#MU7c{KfcDu^p^NgzC6{Jd4%l5Zl~W*Brwa+ zbsa!^2M!)YACgLjN5oleb6Q2)F^_;Dqy%l)utAu?Xy{1REde6EieWkjLu15l?$i@C zLIX;gapEf1Vznsx@_B0o)1%Yx_l=D=%eh(F6?cV1MjnQkEe3z(kZ3xxZ29s{8>kJJ zFc;NFF1%3xh+I8?U*A}K$(k^J6lrGbE?BT24?wx!wQJj*M8fep2f@iN7iq-oW`!Z3 zX5hjF8s34IItwOYb-=S;wYq+U;k5KnQ&U?7v%&K};<{OTg%v=kC!w8r1=kMVKHp4_f81qAZ!fUBjTeS`Q|1!Pz@83tmZ;?Dk!N-a| zEbZ9VenddmSYt~Mmo&MAkKB`GBicI`{$=qy^hcCF)hzji4d;^`C6SMlkT6#x^*^rpO7!QOrgoRe#H%Ak8W+5P#D14kG~m;ftdVwGs?4r>7pk(z_)EXlJI`d@xUn>Y zU@$wLJ%7H#sWzdl&~Bqs8Me!#neJ!KNJPj|dvsVJopQp$=%sXU%EVNOSrScPcCpi! z{>nlG;{dr{ts?_I`WfFI_oPEpD;=2I^U!$Y%s|b>j)!lS*eIfkBj=Vf!*%l;2fBNc zp4(|XO{)!ib*t||Vd0I)H4@*JX=rKP{qf>#n#)dX*L%@P<_xs9w+8`md-NSGwJ_8g zJFWmU3)yUBxa**D1s$B4SjKsDd5eF`exVoS=8BH@FL>uEu9Lxw>c7%`^Uj^ONb_Y@ zl4OKuDWZlqYQ@U^gO2%z!3$m33iSs<-UumuOWpoqNJmIWNCX(uN^|o&=&f8wyB9P+ zNEo*^FuRm$Y$Lz z`Q^S;Ab-eY=BI1_9JsUF={ne+$%?WU^mu#?uTUwqo{^p!bEr_nLBK}I@ZqHNj6h=h zbYdQ70|LIdi_@lE5KwTBBt`ZDB2>U#r7bXTL)@C(l;cZ`|K?+s?FHiFP&VW<_aLOH z7Svk38I&s0JEOFZoH!vUZdej_wXV1nS_Bpb^^L`mO_@f~5S`xByg>S;hLdK3muB}9&W>*QN)TRI*pBBfvAd=qn*eNSg!U-g?zqf8|}vI57xe(kJ{ z2gN6bH2DxF-2D}AiGf2~fH0_U;tsH9@OE@`w2(AMB|g0S6Tg4|)^}-2)d_$YLhokT zv-aP*V%BUlMvE1YuBmmDPvsU>K0@w&`#yyGC3+jYZRXem~b3B9sBl;tM>7; zXUZeK@M@jNUdSynzel6g_51+`V^%i0#8_VZv``2W;HqCQE`IIjTi*>UQ8Xa}{o&8wml2)Q}vRFni-RWKT&Q3v<#y`X+vD^2(2G=$=Qy=Q-XH94Am zL?D*w?(R-{%^K=>x2u%#%MDv=tZ|I=}9nL;IqyHtl>Aj7pr;QqH%fZaS9Jz$%s0)O5D_l$0=Ce|(Kqzm3$Z zvof*!<@B5mo|wDjh< zCw+T?;hQ!-n$i*1-H#mSy?9kS!Wn#-8q=lOp+{Ky6=?Boyi8cQ+7&i^lUXr>_#dl^ zk%q}mCeL2pf8WSUEa&>jxx(g1ZtKRLG`uZsRfc3X-w(-jnZk-WP53vt+!OU%oL0r$ zz`Fh@Bt=sw_gZk_0=|BAba&)$_XhI!w`6a`-5<7_o7#}`jw8OX;)!eL%cK^vT*I<3kzy*?`ESZ zZ^zTw+u6lJ0Q|NinI@zdXo-C69b1oWPz-EUE3otSl@R~tn~mo)sA4TvUZY&DCJMI$ z1q{5V#usu5lVPpB<$(gqXXABfnhcs`4QAn1T<(>eCJkS=SiceD;pWyBG(#-Pa=9XH zAjSqI&KeE8e*XSY4?go6r8Au+i>W^k<6Jt*sOZHjx5x_zpmWc`w{&2v@Z9HRn8TOV zcHz(cddul%pkKIZW6vWOUTn`E!v!1apMu z7$GMhx%T(6avogfy=*9XV%Rdo^$Twl6&FWL@Ad5|Q^xveAtVp{pt{(=ZeRCBRS;AR zw7HHA17xzcy)d>m$Y(y(#sf+cLoQDUlY&+F7-*TI$w6SXCTNsXx^G5BJ%1|%Fi2Ct z2Uo9vjO@%=vu5cc`$)tEpjQsWVnL~D$egS|6QEVIaqHF~>*!62%XYi}$P$r~tkOMq zZrk@3=U+dvMWm4Pltl*Ko{?J7%q&bz+M~{>eT+v$YB0@qwi&t&CDjM+g>7myFPB4p;kMDsfnY1GbN`7mLv+4H> zi;Ht1-pRpJyq;*K6&x~M)a(GjWafv-zSHBM|5SLgl>YsRqAn+P(`ZTSHg66fvePLp zcHFoa6z9G#b{P{q3@hV=EiQ2*7S6TW+_bvz?fw!55BQ7UA-&`P@OB;X03ed~Gy3gC_q30BYxtcYv>ma3b_t0|GBHJT7OG%zsP+AqKXPLp4Db^?FoN8|L6r z#H0$24`9#v1pi*p^zn-qFMh+_x;jKC06I^<-@nGxTF3DbRWS%05$B-MBFw6$5@{4o zHytsN84-Dkflu@bY?5{M;8JL(>xB&5^FfUpgeP$8e(|4(X9z$8XP57D|Ni}tYKvTf z!5q~eQj`}H7Jh2X!jT3J?=NJc5~nnEVbOM|{jzg(JOQIyHQmT>+DtDF0(X^-A_lRnz zcqPWuXu|U`$I%w1Y9=oEt~l992{4)ZLUX^&n>u+5joa^W&$q#5#i++_?f;U`)WDde?PtN$QFS;>@F)>D7i6@EoOStT7&XW6B)#mJOV5xTN6-{EEG*`!i+oUp@@vUl~$8HneHg<>~M2JRi!e7X-JwspH%) zIvpFrj5?Vyo%M>BpnL;d8%)vKjs#!ePueG{g#auwt_6)G_UQE zgVrPaFY&ak_%3P~WGerp^vC364p5(gCx_6#%y0*xAt4s`R^5`o z=yLeZE{!A!5OF>qU6_DyanBwQ4geMK`N`6uW++-pJ-2Jy*)iHNKdSS6DH&VxtiE2{ zS3_OB9OJ7Pml-$iZF&S%b=J-cXU>G~z6Jpi#*T})van?Ah2Z6sVnvXv?w}}`_Q+iBNkYlF-w9&lTO`~kM{eA#B zlA=8mba4VaVr1_FK-`E8$NYXXR(At{HtlD#vA&Ee2vdz8iqQPZmd8J4uu@SR8BVNX*9Z2fTXy;WP@ zCKxr|B{5xCps;{#qEg`FsE|CHABJ!^3d7E}qY9H_63B+R@4Kj>X0&NHeSCZdU8@S6 zM>degWd{d3F*wc(MbLF)1j%fgGG-27H}89pc_ka#s{PnioIglILx2%53CW=3S^(Z? zgucW3>QG0KrlXA6;YjHanAX=9zr!Z1Oy)T&m#^<4tihcU@(mU1H2{rI@N3*mr<75T zEODc!^e|4n;-5r9ym@oP9uMhjd@^mFZipng3oN##icFp0UQ~A-q($i5yC3#X)&`&v zX}F8!oHD4EDLcm`ge?pPR1gcecFN48cx*vXSdi8P5;3 zX$uG7QwxV*J_2pES3f5oUxred=UDwtITvy$Q=$=O-4@c!nI?^F3qiwk6giQx%wSKy z1)pF*F~b+SqCcoF`fCWpI~0~t;j{ME*3aVupbxz4ErFCjZ@i0{QczGqxC+zqF&rWh zH*`!__bCh-8-uF>V4b^uO$qW_f-Nnp-G9w2ei_I)VXXi(-v%QNQNZzeR<7I>jJ|I7 zx92VhmfFmsiQ4<@1>W7ue})pnsh5MU7aAih8+!B_Pz=k)iH?3gIrIMn=rOh~H+o)CB0*)rf0 zT0&Qfi;K^)X3ArgjS!H;BY86DMy<8@NKd*g01;^m?k7e>M8ru6SB6dKLrxVZWz$|z zpTxwdsccH3q?S*a(5!tRLZSPf>Soi7bD`_K4|{-;^`fu*_wEHY_KP&f)GsZYru>+B z2Svvv1p`h#)9rVh)t}ovot5m8w7n|-h7ThzuzD=-RaEcO{izEc z-fN*Uz0W`?V6*kAOykI`wX+0Fn48##7SP_%P{9{Yzx?PqUu;EHP|m;bH8snaU*F^shnn7H==cun@p9;Oa9r%EaGpiG&_^b;LxmOc zZfm1#)?`SsZ9iqlG?tyCgy(tn(QzKlSQ*>Z%-;v?N`J&H7$YctecqtYUPV1#HKIQ} zl`X?YlmGWwp4h8>OymA<&r;!hgr|*KPD^7$&189rs^oqDP(zBbdJs?b?1}v`{4AWP z=KPm^UnOLw^rWe_J0STyL+5zXqcCO@-WdB(tT%6PT*w1U0gkLadaWFycKVnUL9TdB_Lu15-~)^ zXC@%;h1`XsXB`~O;Gucx4_NvUz&yx(G4>Ie@MZ<9%c9!loMYqT+6m&|fN!HyZ2o~^ z#tfs4wm<;%tdcm7C8OZ1ot+7W2_1m|2yqz@mt-)8KYy-43Dl~2thJI_xw5XYF(_3A z;7=<$&I~0Yv_0|s`SXtH2gpn=r6Y2s!JmjKNe>KX>}hXaL1 zxqeCt!({ZIUp|1`%*VD@A>fWs3nBH7@s-Yic1z^t5m+<(^xFs8j-@D@4cHg8pP3=& z98r7|73cXW#kkF7zXGvABnDxRnVhq)FDRVX|lH8;N!9vX=@)Gj|UGBR@T%dcyd^mu$`yKxe8pghzJ{m9wMFqmoYO>IXR zD^^1TVJxX&PuXvAVnJ1UnSs-)UT|-el)M2@L+g}3USpN4CsU^k9?aLqWjs7QN6^U? znvxQiU%kx#n>8>JGV5dGHqdvOGjCq%o6I-zca0nz92QrBi)5T~vtTt~04uC=MvY%I zVU51H{`OWMQQ}Wq)xkkT{8^OAiIq5M3vF7$j@ z_(|%qP1u-$_G|)`lB#A1i|^~}*8tLMK}nM_(E%f>;93rj7#9l{pJTL__s|2{z5f|? zwFRlT=ZEv6A|vZb`Q#!M${0MuiL`uI3H?H9T@w$~z@*sz#ged+yhojZEF44nm?8_3 zgsgx)lZS*A%+2|q)z%)#lTgBk``{Vg)YtV)&gD7_px$0$_2DK>F;3_%sUdSC71AC9%$j1YfV}Q%= zt1m&DWdiokug^q0!?3g#fvSb=jnAK7Crq+X6;eLEC;4&bp_lpmqy-5FVAs(sLyZ;^ z{NlxnlSZCD6VzFMZ3N!}>4;mi!NQkgJpA#I9n*x)vW-$wx8YWx*ehEQEb?*M_2;O? zaAFH5XR3PatYZ5fKUEeQ(*>{Nv1(@!GFJlpU`k-`8F@kdZtT?jsd6(c>?xL>NN_b4 zC|5mOIS=Wp3)jB=F_?p>pukbw8p|cr?+ZiMz;L10|Rkh808l<{~ft8Yj~UeH3%>~maSZwY_$$KzR?*)LzJSB^>EGr}F8>df~h4l0(4q1L=pnvwLl<)`GIU?rb3r8j1xqY&8? z4O6)m>n-p%*aV>7&}bjXU7ijX?wcnQZJ13yFwtknFTebqQSw3p9GhkyA0$r-;{$*t zx$DgkfFAxy2Q5Z4;3J8KCffGN@}{tYJrYrwWy^+4YEJu&Xi1y(pQs-)S)$kBBf|Mu zze`@UOY_=v)-qNNl-b-{IO9VmW>Z=G=qhOOoiWzad1vht1q$Br>7~j3t-j}5U8mYG z)`}4vyj)oC*H`nJyq2h4MU55%L$Q^U)^^2g&%8(ON?4yVG8-@vAD@@CedgKFcLWJE zn!0`L1~6VZ5>q)eSL_x~br8?}-Db!7U+6}i9Ng9L@y9Hh3-#~g`R4|EL&X>RZ{-)i zE+l@&scOqTkJA7Mj6G)_rQ4{uh<+t#x55A4_XvG(c>%daSaFpcYN0CrL%vkd?w8Wy zXLcGFNk%n!yM-CMv*~Uidmj+qW0oG^kWi^bTu$5Cstpeh%P}C;Pu4H8m$MM_PE1UE zISDNy(3DtbzN&B5Xd09ZZ;9$$M>+B`1$}cW$4G|BeEM8<@Wyv{SyvaA1tB~044mEE z*eivN9x{sx3+GcIH@iAJ_oDd9S-@!0_nnQ24W2)5kF83Br}jn;aWIj|TFHSg=UFHQ zew)-j=e9ksZ22_}aF&rn6=5F5{{HMz($b+Nj_1zZg&cfg!yv`4uy#LCJWT5~9PbPD%}e?(>t{3jl0UTCh08Zn63%df~Mh&3Ft0O(nEU$v3gJ%~^mwf94u%2+dR_;oO8DbgE>@~LE}^cu z`CXCIs9;NY;7bTOh-4Qc%`;@#mQ9DcI6I%Mw1jTXKOjISK>}*a&fy>|{*=J|V1Edv zTl)yis|TFXDcvTAi6Z!ICdrkg#~Tzob}*1Ykg4+z?; z4j=3*gUEDC>1HD>)L9QYZE2(|6@@lNOJo1w#87QA5L%BG}5r{&xytevodze;A1dLgaV=1#sdB+CJ@6 z|7B!GZ*|4QAGy1^^ZrE?i*2AiHf(ul)P=qc$Wczu+qZ8|p^T;ESE8_f!WGGJK_bje z_$yCK5()Jta2W+MK8sf?;Nzsc_P%e_ha+d)4=l`txZou~75)exbjqa13PF!WeqZ=emf4 z(7+{wOrC2-lHC!^$lo4CI3?VTt68ygG^Y^o9fBiu;FlQInKy6VBu=B!O07odsU<%4 zW~%P;)gv|a>)H#8 zq0i~oQ>%|Sg%d6`?d-A#T?6@VqJ6Y-A^P^Wintdtnv@4z+8f`!Gkm@Kt97hVzMQXT zJ`amQ&L#e+cRw#XHe`tV_d#FJ*9+ebX%9@PTlX(dFSi?_vLJt2{Kn(xLSr@(MFDj| zcW39pm2kO9K$y;bA2tA&p`vmZkGJcYp}BGTz&Fz;RaHlf zjo0b8NfYWyQr>7UXa!;Qf<9xcyVSb2aJsYNjvPPHkUL`34EJtuvw zZRX6Gqi$o9X2^oNViH_$Q5#7o2}TLK65bYyaeopym9iP0h@cmQC@f-k&ylweJt82v zuG{_)ONJ;nQo8MiJEVp^K4DN_OrVi@PAuzYDkJ#_hqe7s+xFp!4zv+PjoQc@Tt&b- z>)i+@lbuF3TCeI#8mscWwJuG)5+cc>FFb1Ub(NLg@N_GWFbQW7d=N$Vn2HK3PU=Z@ zb?yuS#_*Ut2fiG30GJ`tAQq5gERq?i*2100Rr~1eTZ2ZmTMViaYw{SNSFbiR+}LSJ zNl!bHQ$Io^&TZunaRCuz2G4XfTTj#hj!o6sjPLm*@f2WgIFh7>M!5EQw5;uL-nf3L zYsidxTLO)_CNluxUs=Ew9QxKNE<-ZL`*WsgP;MsiL9Jni#JHm+5^p|IuZcjcK}ibZ{1WdTZJ^}Vk-SMB{B{AH0|y+I zMw&Z6FgG_3e)0p-r!am+Ikfvn^7vQ`*r3Gp1HOJeTRHaf61G?R>&zFbUdNW3RrTct z@H|J(MvBZ%%BIB_A4aypQ(yy8OW+;!0X5rd<-RGM^e<9g-rk>|pr)+2jwv|S*&wYF zRHIjQ5#SGEc64_y(P&qM2dzkR9&KYM_-39fr@9{<)vM_`rnWX#NKSP8r4pag)&fII zj>iM>GWj)nZOwZ9CSs7#@hZzaq(l}2DQSltgeK`1zH@SGs6aH!GFv9Z*rqfsUq;1y zV$Sx~$z9pwle5M=_-^`P{C<)8_^KJujhTi-9)DqWcO z&{vbE?Vl#|0bu+CMA;{iH}3+;U!l?ec^^#Ua9^G%M&+?5)w}`5-)wZsQq91UW5%9H zlU(?4lSXKMfl!8|22a~^@*GbYcNO)D*)8+e$&?g;d1Oa*rsIM-F|(s z|A2ksf=X5E9(J^&Zl;^0-vLceA|!6+(BL51AmkYEGpa%@D`&A+1p^i3_2&D;1kbzo zA^%Vml>#4=`pSmsH31mT`v=>54h70%eKh|p1C%^}x*iP%aaXFZJPrs#4*FOwk@%_+ zZFX`j5%C#Ypu*HVe!M?{Mcb>rh*sB+;aq6rhSmdt{5u?aRkZDqBWwzdiM|Vf*pSl* z(V;?^sI8S&Z_;W)4#M=HtFM2@kVW#9>Y#K^l>yRO2UJBnnH;Nu4GVD#8UpjuF>$PB zU$m&(Dgf&1TyW`OyDeT5egfU`R>eT`_KMf9Ly)tk_SYqaCoXKu1yNvwZQ?{y^646k zMWlJ?r*wd-OpLvdC3_Zp0vG?XfJCT`LXZ?#jp)&$wxFvmD58t2=rXR`zI!?YyiRF) z94-b?RH_=F6S&9kVdHuYx?dM3OB7b=K>WP>+@~8wnsaFz628aSaa?H!}Ip z?|T}bm371OXU~d^^REYW(p&D^t`!gxdX~|QqW~8!St4v#E^wv*qbiXA<6l%?UILaHCMr(wA?j_!mFN0E;(Y7H)9lgz=d?p}mVH`^^!$71QO%H!W9~l|> z2GnLnsL+Om^XG#o-~77Y{zJt-q*KAHuKualYXk0(&)BSUT!PVk6DhtDfFF3taCnzU z1bm(=U}~kaI9IGV2peL~&@q5yM{GOXdTO~Tl<(krVm|;7zNo5ms2O+3&B(~#PUJYk za~MiDY-rtuUXBrlW8-+B?yL=UI(s(e<;#~VoUSjx-FFZo$l&_NFl+u$h}nShs)9ev zacN3FehbS&>)B&1O#4Kgcbwzk!GkGAWe*?G5zi|itLU!5%RzB)q-exnc|->bmH+^y zruW0Z!14b2V%v_weW=4X->L!>(ki_v@MS`;t>DDr;f^ArQ_2}4Q3hD=bIqPSd7_S^ zYi-=%av~1oXF0Arpujwit7g{fiH|CB=G|gr2{|Vw8|`p7q@B&zs`1WRaF=8#QA==r z(_k;rcRAPJdG3$;(h7JpCUk;KMQjgriQQ3CyTZT~=A$3E+pJ+I^)-K;W zB4RbM9*E3nRiGcdJar{~=b4U|{&xLMn~s)wdSuYijG5x|x-yVK^$c&X$P~zY4xXZv z4jBs7ISjt;)+(C-oZEAKcNL68DKioPIF~P{@XGlpzt$ zXI;2J%b+79&4hqC*iwqH4y?hy=|nGDBOMI?WcY3iS_HiAH1_JL;K)S(vNGBB5|`XK zDWVUW+O%5@yV3(H3-rUj$}~V&WUNDu=j69jfX4*6W?~7J^Wo#1gyCR?A0f0NAN)eUhGyx2a1~5I=S`s? zQBEqs_cryt>`(e~iU^wI7-av&KAd1#_6~j9Uy=!(0}fqDv*d#(dy;GA?mV%9NEGZ4?V^px*Y)q3_UdfZ~3{p5S`L+I|hm(*<(Q9yiDcg z<%Qox5wEBN9BR*j!WU2wERz1@(&KqY?e{k$22RwM6Y?YIZ@f%(r!>#h4dJQN zfT_uOY%wmU5k`EtiOq&6X~gb4eKhfT3v#XxI21Y#g=@GV-8_xI3j4t|zneF2##$N> z0_x8Gy?ZajNlBj2FH?=!akzn(G;LaZ6x3+qzCjFv~nd$@3pS?QqJ_iz zhh(yhUf7da26}h+|FJMBo=ub7OrQ+i1>&C0Io;rQR_sx+4&V_|+;{9hVh7~EKzFe= zD(&;a<;VX>!Y0wYL0mNux+UG^|Mj=Xc(9p%d>2iUf8H*|g*2M+VKNjM3*`OyP=j0s zwwJ5^*FU1=DfkE7#oqsB&c6ze|M5y^C{R3qf6FtBOUXH-*@ql9$#MzS{yj|A$C6Y~ zw3DG86v(`M`EoMSu;mzY7q61XG$d!yO@eTN3<_%X;&3;uZ4fmRrLpBSv=B&SOplX7 zN`eN)8}C}=j9mi?qGagf<)yBx8>Y^}S40JtmU`3-kSQ2&zc;Z!YxJGRWLQI%4D5$q z&j&~(%FL2MS8%-V4>`q+3%lAXL^p`WZm|bKAcq3TDbkpGQY}TlC?}5SaxX%#=2c5h zC~M#i-hvFn*m0EI!zk^-E<@ej^28|W*MM^|m5Gw6#@cLR2x6ZNPEOwgo3RbW0Zfdg zXO>Qczno+u*GOf_k|iAj%7OCO$~2iA;z@?3(u9vrs+0Xa!jS@cx@G{k7743RXAy!j zox>E1dQ*w*7YtFzrP+s`EJkY)P3#@yz;w&Y%oZx|gn4QBC~TAqOE4fOIa; zkcFuy3!l)gk`8+bQ8kL3$7$djNrJ>Yn9`uXi&t6#v7Q(K!^Mf>nIJqhz$sU!0r){N z!Nn$k^kzbC9K+(lwl6QA1w$E-p@~5gfNA>Va9XMc=MjyYrWut*6&wBe^5^#pV>hv5 zIbOTT`W>&uVX4``njKz49#Bi@DFU~Uy#fZ53}(gS$Hy?1int)t*_*w|&78A51m}AQY(GI$*(v)vOZ`{z(K+PB$G;!gypKW9?ZW4;i`F0_{ zVmI8wfY0W>5AgSohaTwJ?{x6qH=%xOD5{l$z`NNM?z=ZdtK<~XCd6W>eQM}P*gbgV zZxY>x06)Jv4m+8#TP7GXmabl{Oq!pW{vV731co5HxG65K5@J39ixGJwQ&5Wf&1`-_ zCni!y$H^5Y(7ZMf(aW>t8p%3upm1owi<&-@iA? zXF>~bi1a`M*dYS|L~5f4!b_7LX!k?N=ZyNbd7;1wzHwvS6m_4;WReL5@5iBUiH!RX z^&MA`sS1hZO7|}SasIZy=$!e{s6&TSSzPL8Sb4(t%=?FjF}AxB70S)%=;-IKBVPDH z8w0&VYZ+FQc%*2+UKunufAbhnd?9cT-KRkN$|U>R-yh~YYR0oV^Iy)YQVv2io;;;) zX_?eZjg}Xe!u`|Hsg@4hng~e+$F1QDA`#&`ba1p@fBXH+LD$}Izz-d!(-QYnK1*Q3 zkWj{9aCzqkj^^5C!tfFcMa8p>6>w#N&ct8>7dx`R+t{0L^7~?MJ_GliJLI>0efr1~AO>mVCA1>X=_tc+K!=H%%8(v*7`PXj= z9$QHd+8nTca3LYD4eB+UQaV0(*KjkS((u?&i$2V7#F~{VjzPKwm+qS>0YKrbjufS! z*pgZFF6%5#_8^c_su6tY+Qep|>J>ja7hA{xtx>&Uq z)kXY@X{bqaZ6#BZjq5+`9vN0<93n7Db;KJC}^n=XsDl zB*oQ)SToJDY`8@BpWr9D58b7RU&W8a4pp{y5p_`QBgpbSknru-djs4luDW0_;R0Z9 z74fwLUWjABWMb)%WgElVbQH9xGgx^k4J;Qi(yR58C-GBmKZ#JB_n5+wR8L&I8m;Pbrs{epCJPioHoC|Ek?VV3@HxVN_ zPM8o1K8OjKtNtRR3Ni6dWsb?oBSj$U@a-)JgcO{e3)N*vF+|&vygVK=6X2Gk>9xq~ zxF0x*Aj1x|Z*C8OB>3RAFdW(O4{ee0Z-wJ$#Y+!Q2G`}AoH z8jS@ZML03g;>3y2l84lvJ;XXAT!mZzoJ9WhYu9=vUCMKjL+15{>RaFT0w}WnEo*;a z35k0s{PRPK;0}JSc^#GnVseyYAl9T}eCz!j$KStPT7`sUzWkhC^TOiii`wVU@4@{Q z!L<>=2e?TDwC;&vHX$H}`fc0{$-&o75e;GeNhe=AY zJGW_9hD@0)IWJlshfTcsS%$f7;dDKK(9-G1PhmKMHV!>SNXhg1dhU1k-xu0l9yqm& z79)f9S2FPFzW1wIU8hf9{5iXF&GKB=C_+_IWkWd_SS;8AO$R(*D2IQZ)b3;qcfa)SPMd2zK z84kf8AdrbO`wjt0TH!YWrhq;Dh1u_4KjjA8TwPy*o`UZST**DPXbCMrCi4za+9-wQ)Fu@f^bA!I{bJgM(ECun|1=8=Sj*VgPl+V^KhIvo%6w5iz1 zHg=0eER;4CQxnkCB;gK!__KF)?D*_ivn&w-2h{e%hkbwrI7POieOS17vGz8CQECDg z#P#|8v(K-0ulzQEp*gu-e?EPnK7Bd_X5r;e*#-~j@3&hb@m>0lkn{;m`pTFpHn|M- z^c)}>R&^Gtn>ykLylTt;?r~JL!=g7T>9+XrvZeDcezU*T@$2{3gWXi2@)<|l?`OV@ zy6)kddfDapZYt{b+tSjada(;ilC&EnX-Z}390mDGiA(FU&<;ef?7E+F4%5+fY+GqI z(-bUIyl??o4Ri*Qfuj>a8-O>7B{-tvClGW%J?;bMf zJ_~Sac#jm!LNyc#vh2K0sHyl->B#FO!d#yL+(8%N{;%pcv?8=gmuTuHGVz{s(On)- z)W6%(qC4y<1KG$1DUz9qUDzT2B;lw$9B4komH~#kJ#r*(SAsX^6)n!Q9k}6wj6!e62~R)Q`}A^Df={{ugU+4rZVjzj$T)4Xgl#s zr(;CK=j4mn%E&TI4ctRI%Cbg>*JR$S-CE^0s8edFhN0lZvlX`v+V#CWIdGDr`7lj= z+oJz!<`0(2vj3;EZ<#;LF*}P<71nU~#J%~K*15h?v~DkQ5JDsTe(-b-rkHzJl@aa~ zg=Ut(yt(cDuM*g|L;q`^QEm(T^c%#?w+%AEqKSom^|z+U_7)QB+>lI0vy)piL~%X`YA{ME>Jm zbbwUuk)yA~;G;ttLwyF0kvB>?em}$1g=E9)tDUrO^1UBD4(V0{oK=1X2bazPBo+B+ zPQnXh{APXvQ_d((M=+zLj@YUH1QT#cHSAD}o_}dCV5&s4d=YO$W!iz24&k)#L01S< z?_zD)XSfpkFXWZ4g{z=kJBDjiL=tI5cPOs?brSL`F=WD|s>$u&-wOH0 z39c?|+nwQAAy;+r>a9R{C>wRnJ&0rMs3!7!?wSvfEQn#J7WDzXN+Rpx>DUR)kj?QGZ>_Fy*hKBkKm^WK--P2(oUh>auLD~)i z5)J!vY%pDQO(Ep6ATEg+jFQW=SHR8T`0EEXQbC`=S6@;Of+Y;X5wg;f)q8yi4ww$3 zJ5drK0_Uo6;=3`D|89MIi$&Pc)O?fr!-$T$nB=-kN-7(`Mr}BuCPWP$nPwZHn>a$s_jof=7srCK0ZkgK<__|A`E&_l=0{} z&N&xhpg%gnZ0dwtp_A{EGYPj@%{+Y)+jra)l2CKzy13)q2!bkWv4A>R@4Th`3)MF+ z(**!q3m}$-X1_22V_G?`#lkJPnwdSAn)%Qaug)_rN(=LmQlZ%(e)3=(^`?1XoG=yM zIX5L_WuqaWKMH37sS zG8NJn+IJGMidXkY)ZMgSf-@xIz;IMFW1~a5$$?571SLMr?lfNwU5ZYo<%qXj*jMcd2SP0zbA>1-shmfhxs zO{;_z?~_?B9||?sy6qXxl3j^RyA~me>|YlY?e#kpOIvihZq3=QKiHOI(46Ps@=pAgy)ntRF%r}5DwsRd49^dpZeC3+>< z1d>MzXHR)g*DP(DUB1Tz2mH}gD%J>IX*!$jFQu|q(TX`tYpS}rr>i~ZMB{=MxNj%3*;2W<4nV7uT#mt@O|1y1Rw_a3W^M?ybIea9bKUpv z<8SSvWaXWZ>=_zDq%z9LE{YH;tAP;Gt1HQjj3gC>va%zRq_RoMR+NaWN~j3G^Qr5; zKcDY$e82zvuH(3mx-;JEIUbMmaSkwt7l3xW$M^;UTuBtT0j89g?%^+WOl8lvv3rnd;y$84qouP+QCh#Yw-L#Yt;E{R@#p$%E(7 zSLObuz8@mmK(N}b?IB8u1L<3X?!NufhIHD(sfom}9h=&-zO65@Xn=wgKqgpSlG4%* zIBYf3n{%Ot&h$BllUygORU%@KuI{RzInlRoXY5_&fZt&XL*AlLqI=9yCbxZG@u6x_#c7KE?{)ty?;DsW|Nhrd_HXJhHjL}76SrwQHIrM1Qc<&; z4*@kioTEf;FBsIuwNE(U`d0@GE8J}c`QQu!{EpcWLL2b|7%Rb3Z^R(5zJf02WEwsq z2YDlLoM@-x-c=w@&b{8yHm9|ZL1i#A&IW+dC4(`VWYK>C>V2$r8ow_U-G*@Yr;%2m z0fDh+3`0Qde@)y9-AiB_@PsB^o@C+KYp*>$7F%htAnSF2kVX0OF=laa5whSI{W-Xd9vtRbfEg! z^qcoo>6&H{i1zNl(!4T(?$QP@A2xCw!;}|jOfKR5mjS9zVNh33gyAY=&~Ya8i3P$T zGm}eTY<>&%J4fvc1EN1C`AhC407#5bzoTRT2>RIjXJ$JceT)oh2AX{P*;O1DShGOE zHfKA({Ngj<^tjovW9wkZB*6^tY&mp#iF6c9)I6ef86$eL60dxN5a=9lfs5{1{tc$` zKyNi}VP0sBTPhpqYa$)K!mK8q{MImi9y_yueF&CqJ+V&T>`P-~Pv-+0dpC0k zIJo*C@eu$_Rp@fs#l;%)7MUR8<$NH`SS*uH?mgLv0lX&LKn_)B+8nWbV8r`v+iD}D? zJrLS^#9z8}DJFykjM@FD!&~m}TX(SYdn#IkO}LOp&l7C;iZ#(&R*{&3emhT(NM-kk_h z@g3)SJ>ve`{^LVQw$Egb3(PP4`lMkMAXb6)gpqU|28JQyi0vp*Q+=C-P@Buv-F zk+m!=M^^j()Sk$zg*sl$Q5oHpV5+5!jm^<|8`N=Y);pr&V&i#HUtiBh%TQ_R@M8w31IvyqiWkqJZSqEKD3xf3?F|}1e zp-83zlPk#`77Wjn>VR0P>IgBXvflJhooHUIs^u-tvat7P`VNBxOQ|bj%PvY*9@4zu zV$)?Yy+5P>NPa@eAA~_24N<9 zGB~B*9pTT4u=rnJe#v0EK6JaPP>C{b$tPM~|HrStQu^{^4->_G8`r#<_?MA?w(Ion ze={V#?V$)wegW>+3xW>Zx1N=+l~=4gVqIl0RL5ImEA(sKM~al=MC6$BdovE$t*31-qdhwY+9;jHSsF?*;?yyz1nri3pDbvy z_nRFUYcU+i#yBis9;zWMOS)?E+Z=ScK|$n`yx%&+NQM?USek)B&}rDcUIUcz0j78f z*0u;j=@R)CkH&YBf~-1VFcOR-u9sD>ULAwph>b%4S$va^F|7-%xeFK(H%?ae6N{|l z@KP>LA*js}#oM}*k5hJG#7D|r^_kckH^kD;0WLBH6XwCh>!ArJoPr5sG4jp{!!v2k z4(*Ubsr3<7iZ7iAcTu|IiP+jw^!bNH?f$NBE7z6snM08Cs86{;D}|p%epT6V8(gJC z8kjp;b%7y>(BvC# zDflYr$O93*z6y@%12^rwn& z6s{O{9wSOcgel)Q<%LB&euT7SL4DcB8+f^t&StkO5#}fOO9v#G^Ha==HnnmKFJ-29 zjh$9SVr}SSzXYcI8WP^N?GbU&Nf|ybs%XKDl6YMLgMt$9tue~FU|gwU zT|9Iypt++|6~uV=0Vo6s$3!TY?(7P|oZp~N`V4lqd?XhDw(Brn31@R0p1fQ@IP6I= zx=Y-NO6@!>Di zNL6xq_T!8Y^X4_&(Fz~pqYbJn$u0SqkQ5Q z`a-&2gvKD>h9#T~511=?(ARDtKZc$Z?J18iZE|5HPu22iw!hcg-+!n6UtjpozyDu< z%m4Ks|L0emHvZsbb}`pU>AU#SU@+k_H_bPgCUoP_s}~N{swSm=WvDPNPAE z$Y94Nvo2`Xp-gJXml6YALK{Yha>W+tAMK%37Vf^O;3|9@8Q4zqBMTh=YW-Egk1WA5 z-3P{MP~S&UOop_8H*GGay1<-C1-vNSy$;bL_wL`1z49G`EF-)uou`$Zq@QLZ4MB#4 zNCh3?6pirM0z=r3ZX>vC!R*k7IVq$2OzLWCSHS@hKR?5ZD&n{!WOWfAL>pzS@Q2mH5Lp6W1BVE}@W5&4%+8})*EjCN z*gO$!5IN^HOpzjrL{2>k#Hj_FK4E7u{{6`e0HEuxx&;0qO)W)`)g5yDeND zPkoB5OFz${Co~^PZL|{wA{NfQ^Y*xxGIZ*Vx?&x$~X|NM0>U(>D3xWTBr@~ z=XaaC*;o+%D?v!Q8E@rWNOmoxv<7at&5DN!FI2~P6=|O!O1rMitRH{zBDG-6x^=Y} z(u+H+FEh-&j&?j3(;Y+=SPdO+dw@xLpx5)2EIDA&(_a!xYgqgDZ_H}6YeR>BG^-Zf zGk+RMK|Bh6mtP-Xjy6op)XV7*?|9=X9CmYNM^&}DIgU(sK_3E7IzjJV_=~yOpDI&GepbKc?B=$$5GhqZ zK7*UM!GPe@UoeeIplV_g8|~D({pdVA`>9}KR#am7oioEmp5&i>gwu3s#ylGRiG8b z%qe9Phq&=okDHA16o>Wy1Dn z?8{1LFrjNo+`~M2!hQ7J4dVSIuE%@))vddP!Jta|5+H8=I8_t&uEI0|u=f#njBX2C z7EXf?x#uv>zkDpOJ0MA=qO32_eUXF-x)C7ZoFR_=_}4%YpWVURpDBL3@$ zdkOkL0^V`dE~IEteq<0p^CJpT@L!#7FOg3H%E(lOZb)<)*~_#$tCctyqAtx~y1Mh= zs{*)^b>Tpc;9FMSB`3LTfv1<(8c*k&;N%x5+2~wj%TP?KtE+oHC!I-Q$pj6zCd<~1 ztXH2%x5!Gy6_bZXdnJA*_MBewTPhrgb1`MVC6>Sce4|5tQnN#_R0CZA7$NjUQZCBc zFrAOI$dY!M*2B+4Xe5SqFFegABC44>BLQ1ZG}ZwrzkXcD9ig!O=F_NiQ$@!{|LlMF zy=MCNU|-+<-sxy@QPDd95Un5K*Fw+V7#V7IGu3tA$B4wT1w~X*5l4HL%ZHhB(mzA3FF#oaz!EhE?`w6BV?@0buhWU#K za*n?9$wl`PDGNyP1t@q9}J<f5(gJJF~p#eLvHjE%8ztY&C?tO*}yuLXOoJVB|QBi$C<{Uz#>sZCOMob$A-te>& zvf3D#nfp6t(Mg)RyB8RQ;QZNyU7Xjqc$XELlFc_Nf&CRV+$8}jB|Px-g7pg2-Pa|; zI4#cpLp)@uaHZbU;6Ot_Qqi16aBUQ%`vt=w>v#S+ghGhDx-1++Q$KXqf$2oe-GI55 z)9pM=d+{h(e_sZ?kH0XE!8G!aj!C2BLh^| z*b}&30jQ?F^9evy3LQMsEx+F2qHGoYY@zI4=T2{!QAZ%?TZQpIjl z|EUSzg_YJoY4)8VIoMn;Km4W^kN%cs0uew$GVARZwf>!IPDF}ieNv~O>phIKXQHKWaM#CNZ2o@VS?f8USR320<=?MTd@Se17!;~y z<^Pe^8}!{JqR+ZSvn1rD zQ7s{^aa)mct7>gEF<$Emv4$oC14BYhzzLOmRjPXm(D|aHMs-{- zI|9%Z#a^uS%G9{ z_7Pux&ngI%SHdX&YC5!6!_{$0o(X$-BPrp1J)^{(N)#iPgQe${fhTV<@rG9MCaSbf z#iO)h0h!D3r8LQ$BQKU@P7vRxv2WjGraUU>ClG)rp@Aua-^bJWmNmh86yWe? zFKJL2?~=6+IO9ST4|yv_R&k4*@) z1bQgj6LDsc+@QT#t!83ol^kqrs+gu;QyvBB=?fnCSSzH8_Te5$6rz#?af#MdkkFuT zk9*(GKNbJoeij))iX?(^0=&)?Tn0gX8~pJb4B#=2+2c0EXNI!No>j5zKKp59xyxxm zu;}iDgoIePf<0n!{`XNxkqZnD&_Wl^cf>0K;g#IWn2`?x8Yw*N;W(`}{xxIFg0isa zMR|tgU2|#&2H9dj-8OC7B#Nt@ZbNukUYL`KK@t2#TpqN$HvXmBs7s!?kSYX!8nh3c zVug)OFA_#Exk>;a1IlH-{C&{tNU~bpDZD^z$vD zMlJDsCKupoimzV3-tyNR=3?fHRD7hCEg+zJP~SIHQjgEic!hUTHQ+E1NuVjO%Y3>~ zUmuG>BRr^aqG#}*TC9Rx+#|)Dt-Rn^2_8TG$tV>C4|=K_QkLeWNPm9=B~5*_2i9%u zmdRAe7*M=Y8aaJyZF-^QMSm!4lTwbhQVbMHCvOnXi>p*vJUg<=uN@CDz!jmHm~+nJ zjJKEgB{a?eda%b?2}7PFsivRkM3oO-tsXd<$$(#{pksuOs5YjQLN(RZIfr;BHBx7W zK(C6ral?M{&wfNfh(mw+u$qo)SfC=N{Zj@g+`@C_*8=9w`h2-}{iR97TUAi`yCXuNY8Vy!ha_V4ZsQG9oTE$yRG2vNXm-D`A{0*z@Pro zvye$qyM5;dLL$S4F?U-Fis;)fXEbDS3BFKnr#`?|SV+4IWIglFya_|NA<5zFD(B_Lufox{ z^+qL7w8DnFM6@zI0>^)pe@*~|-&K-z$X>mW35SV;GoFGGrT52a-`cZJ9*H!g?5LAORViR%09Kj+_-jf7BjA?imP0A>d6N2 zFklRMs3L1{3BZWyIRb1X(>B5hI&@bEVYEyK|9(q6FqX&yxZ+Qvp1_W08WZW2*554Z zln;aX%CwOQ>^8#mQ!7s~d$f^QEoJ%&c0BRi%t$Vy>;3UhauAD@nLMmi41r^N&%2S2 zVhV_zAfb$FTK9{AkKhFOig@G8os!6xa#0cL$6((UOFY44008=~5Y%;fz#k1L**Gc) zK?gr#U}WXtxodSB%vz3~V6343yzt}gJ&Q!^r0aw6$ospIwIOnwllw9(DEVIR7Zd3A_cnP#0~5 zTv*f1^S~qOW0PGWLxLi(vx4+4K6f4w5oJs!#Bhnm&)*zpp;JT?ce0QL(V*&gwiu_; zOS_f_HwK7iwG?WUB#%l|UDz3l0ipK$i?0F|&zdp$SH;7fhrRc$Xa~j`5 z00^{*wzuz?gciS8bTv03QMuXc787##@ECisFbj13g3+~N_vwSIoPuZ4gmH_`3hlx7 zrL-vPhIm(b3ydTCHg_=W3{0vBj*d7lYxrg;OM`OQu8VVIH$3TxM`e4xRW(S?w+O!# zegI+!3Q0WNvP&1`pF^i51NZV!>A%det7=y)Uyb~>Rtuec*gv&hd@GL#uK9a_GTsu< z$t>9#n(9H~{5b%_Lq4=~X2~|2$*<|KWN6YFbiVkBksufp!9=dRdMb>?Q&F}K3c6kA ze(WRom8x>bCI~8l;HtZRuFG)~m-EFO;ep-Ze8||A zG`)yey^o5hQ<3B5v%k{^&I>-zld@=h%b(s#XWm%RRM}EV!MlcC>hR+z+;dK`{t=6I z-GQkW8qQ>}?b{T2(m{YDgA4Mb_#64rT1M9xd0{hN5yDRcy6Vp>=~)A{15B{?5doOO z_UpI0FQRUpAI@KhAfPZ`AXn+F&L8E=KFc`k6e#NA(d>Zy_I{#1*+ha~6`UJRwsfTl;w0n-EiC5S5pp|L|{LEghx@ta^e%Ue^Gf;71Y9&@%Te~@kg_Gi} zd@n+d=xU_{4@}E=2#HUl4-V$-#Q0^9Xy;H1I?gMcV2yrBLIV%jj!RnVE6r~hj_-sX z)O-}h)L&r(v8S501;snJmxqn*#kIU!wZsG+b-HbJw*_Lf+6G5X21A{oFD4eVIV-B5f;>wG3v=jf*i5XPeB8+c4EiP|Qe7qAqGvI^>D zxQuyV(d0_F4dWOuU3(2h`0@4UzA>1TB8P@QOp}z z%f+RIe-^eee|)BzP!6zifon$^cvjHy>x;h4-5YmAp#YXdt&=Aj4`OmsO?*#?Ls{O; z;K;~6OuGzYsZIx+*IJMt9P1<*xiC{avT4bwQrymwTexaZJr4;EW}DGY62h8P!z4AT zZ!`jPR4>A@!+VV)^8Hd^ggNq~d7+@-<9Odd0HeIT%_R^-5}D7~#6-Sm=7IEkxQ-2x z0Ht#y%?R0ZWVAb3NY4KRf=TsXxq9^~|MVazU@z&Ly`PW-5-9mFZdbOr_Q$CXs=Aji z)$&LvmqL?GakEZ(vmrPf?K2=P=tK8cO)O5~K4)8C36H!lew-HIasa+!(=r8 z+R2i`4RtzGS8zy35{_Df)2Fl5I}4!=QQe{S`yh&v13XuO)rs265J%q&yB{d{YXS^p z`kWI!h>D+m?OOXW<=eV@a6cq~h!I?X>GY8f3X_pWtK}?>Skk!9)Yp`YOnLNl;vzBS z-c#Qs!+?R-1px_#hOUMBRivP48A7WPPR)K4CG#{8NwyYSV9Z2p8HBqLJHbhuPp&k= z^;G@Ti_asi1iFFi%avJWlxbL6*CJ9*}wrPrme>mHq(-mdIuqs{(|pMFtPAdACtq0aNt*R!2P;g3Xz0RtgwRx z;P+DEYYp$cqb^nzETZ`oX`_%b);2Pnn1bC!DpwWWq*q$c>{q26OGoec8Iqc9M znh&jU<9&+VGJ~nfvD)eBX(QA@I!`^I*j9Azx%77i2%cTuQ2X|-AK4M{SAdx&fZG>) zSelRTPE~Os7*Fazk~XbN1YcEs)v>SbdH$fCo{*~umVP?$ZQ(Oonvmxt8_g=-XL4;T z_0mS|B_{cHLuWYL5UbI0XV=2a0ut$q_~SbUAvlh+ai_WJCAiN_xv39s!boWJJP-IB z)%5xNM^ZAuWQIM}U*KTj=?#$4_Bu3xi6@hBz>%GpyP!!&O?hyP$UZyb?#;(E0b)K{ zU1V8$zK*J{POUltc5M!>k%JGf0D_Or!1ed2a3i!Jwpc8=TI<`a1Fu}kFT4`>2z?N7 z0?nU+4kHi9CA~am+bLe+!lP)>4N$**=$kQal%he*gl;N(7a07;)H#n7utQG_?(3{Y zSfzL(2@A0z{+l(4hp2o9Qs9|9P;RmUbK+h9M{q$TB1jKzMdLH-0c0t{F&v3Rt-4*^1XZXH2|KGSmP zID}FP=FK1AN*R)Ks(S~uhLx3HTm$D6$=rJ2c0=BoA0s}_YkSb9uC&G_u*cYw5LS=X z(GL!N+zTM+B?cYp`M`ztt+Xa78`G&gde=eeF}qcq9~S|kpVYx6bo%s9#w)?W+Toor zt;+r-wj0*nGG-zQ17{Q`p)NGN$Ly3-H4}A<0-$(p@zSNiH5)cPCQuPEEayzQtf~M z40oaUmI3mEG>4QO%U7(h2F*cSlEUG;hL?Avcm<>MlV@0|`ziV-qHw`kobVrmj`mLS z9umsPW3LHuoTkCzuCT=L%gxEaNr`_;OW6d1TQb`H=dIWsJyS-vj-y@EoirQCGB4T< zzD`07X03G}wl-w6HlWi!17B%_qgoMgCL$fB+BG7*D;vVhJ%T!r&cUJTq!MeLp&*RF zdCATKs5Nzgc8HD5U{*eem@4(o(-;MeRg0<#)*77;2ml2Q1xIPyiT2G!KeKSL`vdg= zB_BuFN(&Y0WWO^RaSr{Ecj*mCnSgJZ=!OktAG&c~Z4@UVsSraynjd0C{kTn)ko40O z6@j-y6Xw)siRd=hX>?Cu1$g^q!Bl`T{$k}2E*jXyANZw+R+l6f8px7qAesZ?wX|$* z!U|&jahG{=;mit`+?H8{JxaG*|HjdQB~)EmSvfGz^e%M%RMp;|EA|@t1ywkU$aww9 z<6A}nAX6aIBlYj`z#OI3c}volpiCB;`E%TUM%!!phS8hOrPKdbuB@8Bk20@!*JoE6 zc`kb}(Q@X`AF!S@TVf#0=K(w63brL#xB@5!fWX`*;-F2x?ljuj!F(I~zMY_i5C+#( z)SHM*joUFr4G2VrZHcaFZM{yIM8V0z^AE0MjOJj=9(&8wiPKS23!}E62)(+u=EKq* zl6OVvI<7h`1Fe|#i?VtEeHuq@T_c`+H5~ikuwd)y^4bUi23ru_i|Hnia#0lWDBAcH zED$A%m6G|b7El?6F<-`N1RSlHtF?WHU*yn&f_dB1`wFz)4h)KPYol&q_sTCPz;!vFh0t@o~81@myxA-=WN# zk|QQXqcUU_h|p zKn8;1{-}L(fCAO>RbaBERu0HstQa86k>9Y~C6|wZY!{$bcO2mDovJGl`Sc2UUJo-e zlfsUwiK`?zkZF1Zdv!0I7E6CN7IWL-u8(2yK*g_Ir*R8LE zqtiZg3;zGWcM1#E^YEM)V>Cy1LVREpTY7oNJzFqgD-8P$j~%XStq%Dl!SCa|2Ov~p zHtYfjQlGAMtE57Ci0qTyk$Edg&Gm@Cg##&^8@sU$pj6>l%Kr2<+B!O0g2H2CYlwY$ za~4$jN01o`nYPl|XIRKD+}>}&2NVsfxxL=Bo!=o$l7=wp0_(q6eb7nO^yZF@2xb2R(AVcElx0pqo773?5Kj6ts+ekTjC zaTj3VL^O`CvyZ$OKxZdctDZVZ!eibSxk3sJPM0w?L%Yre$k87TaL3$Bu&4D=zwUeb z=vX}$nxLq5Iuu^w(8IR$dRw0Rz8HsAgHs4_l}A+!ySiKlVE2`Z*^~KD&;*#2u_$@l zCs3c*BcB1Z4A;+0sGw_{LJ+IYwfR^`^-oyAY@31?bX|oV95zcPs1~zhtqW<_a{CsE z($S9J{U=k*s#g^EX8@0Py&cgqb<;Jbv z0~ug()&i8Gv&cf0htuVx$#0c=IMUE56bTC)a4@ib-X#6>*K@0}_dU_LR&LxHV4rn` z6U4j{u1=|U zM9NkGJ$QM|7ff5UV4KAejZuX&vYZ2sJ(UBR`XMvZNiR_gX41hlaKa!YD1RwUl!#nd zR{{dXMIZRM5btwZ##?tgP#}(BAe1nbWSnZaL>5P~$Y74YUg?&q4E#fa3&~@`!M2f% z+Y3v_DW${2u!o$%-r&Zfy9%Dp2T>I|XDG?m^q;(v+`F1Zd+*+Cc@swxd4@@qpJ(R~ zU{dhQAH1o&zosZYA`i5((SNFwgR`=-9w^91keU>mDcC^|ygA>>y07nxTR+5nJcx<% zO5S}>aIObWyI~fP5KpmlpaJo|xn%L;zeS^wzD-AKXxDf$M1?8#U0{ z|6|jh1z7xR^Q|7Zs=mPx0yMD7!Om#!Il>9_S@o>{P$PJu-~G;H~Fmr zWH>4G1}bz;BBAL&T!QMxtoHWysQ7qk@yl%uvO?BqB`JLnSISBQ-ya8cQWVlszGLXa zQs{;|Drq};{?Z46&pG;dil=IMO-GMUrHAJ)S%?{H(P!ao5^m@9>B=?~dBC37+`#=J zbsN_e8}rLV8G^O%I8nL1wuEY*{=jiz>t1Eu)91hntSmHS$Yv0;)ct;hf>wI=-i{Wo zms6m7*@2*Opgo!$C2|tF6IK>NgdBhy^?I~u+CkUAQAKr~h&fH8$4U+%#8$xmPGaih zg=8!uJLs3m8+CB(qtMS;zg;F1WuAw9l6XbrpF+QlBXho*%`YPlHk0w{)%SPLo`;=CLc9=;36pfTF$Lm(DmeQCcs1->3b%Ol@OGag!&rP1QsGPN32J7+vRM!;f6XXf~ z$<3qY&XY!Dke9gxb2L(fvdm1!GyuRcGrWaa@*50@SAJgq+HMOe_J9sVvAg0Wk7LJk z)zzOyNCZ(_vj)XL%hLmZN&#`r_XQBnn;DkE_`9*9}_^+SKoQfDbPykP5tu z?%wRg&Cl;p4x)WAk>Btg4_4LOy#EY$1)U(KcDWj$3=^CMGV#DrxKp_+LK4}i7LDS1 z3t;NT?*RcYJ+MPL!p_Adp8CYJ5J@jn0K#@wU;LLulCpAAdLn0%uLYf*J-AV6o?I`` zvrzT`eAUzdpp(Rkh#pwctW&zzD+m}^W-uzeuJ>|(4xJ@FKq zn5L=74KStmA-x30#}|eNLz|u&4vw8$yT^gq`)Kg42RP-qw!1s!c-Wc}lLul?1I+V- z8UPESNCaW(LF$HS&=AclB^lcV`u1I(z;JUNa#H3)5%WKh{c-=xrnxQ0(!!|^T; z{WGjToL!u4#6%M;LjL%gbod+z@Q?O^w+vf|yQD0K$Ah79{4l&y_$qMuA0%|(auSm? z>=qan#(C|9wsgr$Fx&s7bcJ9}m5ZvReaJc$9NAnjBm>fFK^|kWM%;)m7X^ z?1V$YqoXTG{HuZNQ`87V!)Qa!IjRIkDhb37@co^Q5ON)Z4f$#gk{FTu=nF1C^}f{z z|05;iYSm%SBJjb7L8<#o^hSZGRu0uOQ*Bk%)e>de&Uw3o3m_~0*{x3sX%vnR-5v{F zgmjT8vV3w;iSyfhn;gpHG;rDO(!0!rmx9Nq`gvIkbg(8NF#qWsugzERDv85+<2q3d z&2JFV>ouG|lB0%}Bqi9P=sIAVYC~o*SWX^_sf2u<&(8tk{KLBV&Vr47S4*IMX$fK){pmp3?hVqfxGO)vhdL^e){HtLT^JsSZ5EDB`5wyAA_ z@CPAE zA5nvY^JgHqbkB=Uz-d$I)hcc%7VfoLcwdpIz_=d>GS)Pgf=g069g12K#}oM#akY^Y zQI+S(f*q}ggGj=iXV0_FER67kP&foXN{-%6!|F$Ei_I260BST4S-<4sSH1e6UECP`jG5g(2GY=T8$!W)&5cOm4J~#L3ti z#4{Awr}Z8Ku(6MnB?MRMy$A|*jXv~kMbrBe8?yo3(8~$C=EvmZ=b(>0J^a7z1tv*K zH7tS*X2heV;vE~f;xUM-4EvJTFbT~0s|2caY%o;p5Xcv8+I>JHP z;5Vv))0CXz_U(DhJAUm9FF*wIF*2g_JPYq3mAOA}MJq6*j6nrr!US^bBuv272N!&( zng_7HhDobMf0&n#{ib=w`!Z+;PY#=@2qmW+g=2~2wrwVtqoq3Do&e7&7ZW0b#uKUG zTbJl?PlP|kna%lr4TPfwx@IhRwXE;gG^pG-g{CB82Xk*r_7T-aH+zr*cQH{O9v+Rd zf4K)W{X@9yB^=G5OV%80h3VIG`V&1%!^ar>^FSS&&0k_6?X4sHG1^J&sMd=7hsoTY z0ayN+d4839=l$ct^^!0m9F1!a87Ii$gP+^vw zG5-{pYP`0nJ#CaGMDY;#G-B-TrxeadRtkG&T`VF}CwjIB3SL6vmNX#O0UtcIxmD~C zoQporh|tQI=B%m=e>GHi@;?mGq;mnEde(rRuI#{68E~ijYK6kR(;$1>;W)G$JZdx%}St=Z@c2w3aEr{|BF(vEiH25^T zSf3p_lncu92q&pimP}utN*S@X{5$JxEbT{p2O-k|$;3@wVBO#S+5uUam8&`sgIQKu zTv&MZ(W7l>*uymvH)I^p#(U!T6}9R=kRA1(vbZN}(7cKmvpU*Pg8OhE41~j0qps6f_l3 z4D3s%CBXJYsm2$6=)73jbz9H&H0Ahi*yD0eUYSd|XL+I?j5!LpMnHh*wr$tDJo|YF zQIO=PCzP@B78T8fl}xWn@3EU(a$cHmnHI}xjz#Lj$}OT?-d`)?QUqH}f6(_?CurCN zh6OdYS+nj7iA@O%%BjGYmw4~lxhw6$-Wxx|`me3`cRhVP`tU24S3g}3_m3%#*3~O- zHuFFFQwYr)Wk0of+zM_Pu|NA9z069RtW!q}cSj^C{q(n(GPNnYybm^6X_mRRnu&D0XS-!l z79QP_2`LqO5b-4@Se57co5;+gxNy$C`Z+=jn0Bie4TZtY7=L%dNcVwSAgfM9(z%)6 z1qB5J=JR7|PKE&s(Yv1;YJe6rwzxWWueP?0dJy}^(WUFwt=kux<#qMOjcSNq1s+;J z83cEQswyj7l5nNREtAp}jbCu=`0>iyzUbH*3xlY*A5CDp4z$rxxU&mDcQj#RgU)pt z_I8)X;HUU#7v@Y%Ef|g5rH8FoIgrmoYuRbd^s|zom(WHEN4XWwe&fRc(>~$_rsyds zYjXR7)<|h#2Kz>EsrHNQnS|en<3DjuPgCw?{CQz8Y8Bvcgb_;X`{P9#Gt5ihr9R`MQU zX`@>!bt=NB<+GQ+1H_;VI)6CpQ)e|fCmvMdRbO-c3}as%I|~K7oeh(cL@uVPvrdIJTnKcuJ9x zK|N}EQUd%|Jh=PP1W^Y$#t@M4^|F&aTSmaDxd-yio6@;i$5CTrqU(gH)cfh2`2)ha z?Rf6!$1p~v*j7j6iew-q8eJdxKN__-kpM8jlMntJaV|cQxMCw=x+rCqi9@Z(f=*0` zqBkC%swmhSp#~5y2`V{>SNnBw_dt+1eB~%U6|@QZK#I0jZ@`q4kisUN7yo$9Ln|W3 zi4V-{hzwHPFo_B%dTT)ZyNhjrT`>oimClW?%aJ~<>Z@xQ4p>!cyjfnzo`O`Z^!$|xK>=GVK0W5X`j*rA#*vm%8 z#-=%Jhk2wac&vV7h397;ry=^d4O9$27bKd4;HP4u%q*i)QX;e`Y(3~EFz!D(dY3gC zP+FJI&%?*y%2V((ujx^5$_8SnD-FhS4e;rel=UrT?*pP5Sb_&(+kE5Dt>V_9w7q8d zR1>{;@p0F+v_x-Tx@S-2f}&F&!XqM{!}eNqi!cPd*=^g}83xu0>(JQAl=fTo2_Qu) ztx*rE$`f~z{ilK>OoC^>y81G%xnW0cB=ol1iK~QEMo2l{U`QAj6;^koxV>CoSug z@2>e(s#`7}7)?$MktBxE1~>y#P^k2dj_Ts1PC(I-Hntg}xi4Vyjt@3VV1CO&0mkY- zQ~;Ei5Y_jeKWTyYhCDsIH~)ESawof^2EGecL`-o?`tm-CyhxDcGhi>_;=hOE*8mc; zy%B;AATdHq7NQj`sflogQz75+7>H9$!f2!s2CQ%mD7Sl_geHiLYa%C-A>1#aye8fx zcs|cQpUOCsDm5-mV<(Q^`c)m2Q9@;P;Kg^PUc-7-+e6ajNOnEhCEY;2bcD2`_>kt6 zo1b4lHP<>5@6(NIPZQHBAa=x0PNQMZZ#WDLfE)SH`IE*W=vA6C%v!BH0gUC_Mev)J zHu=pqt(oGaXe;<}H1{Un5@GaG@VqLhc{X>$aZe%Hru)gW>_Ji{A7QXqKF~%1rwj8OP9jkh;<(ldqf-ld_(ff>m<#{DppM%br zSn#FwJ42icbw8KKZ_FRxV$QX{L6w<+#5kY?V5df9j$!xomt|5BN*%VdKjL!!n^W&eh2=@%ZB_wW^36?u~k0NW&&&_zCUAgH* zfSk7=XZpGJZpBhVEJ?J~HaIGgctv627;Ol^clhxJP1YF-ctvb4?K3CL9f04-cyQf` zz&y|peTY4J2cp#&J!6OBtO>p`uE}@JumlsaudAcI-=6=48Q2zT_FOxiNE`aSX(K%o#lW|a<*!*=r18ZQIDq(=<5VbJIXO8& z%{S{*@Fx-OxF+9BM?HGz={W@xGh!EkLNvCQNJG$`gx4edYwGjOQxy0H`y!RpDkfm9 zDLfC!ZC}#x<3JP)Ba%ttbGizcOIirYk_q}g)~8Lx-zFh|;EZ7WDtrREqC{39tS%Mh)ZHDm&YCt|T(PGq6@+wAeUh#bJsSGkPLVKq36ZRmm6HUZ`hRK(EP z*QiX0>9MNzZ@4U-Uf&A0Aji=&8M~3uNLVtCI#7$I1Rs}XV3%j2u|qev0t8|3_GT1F z#^YN#dzeq`9)a2h0o05}Tm7*KTS_VFE(u&dh|)aG6ExYtYmx^IMZ>^VSocyM^^?92 zT5op>kqY}e!%;Jn#S}%-j1QhYd-edq)aGMg>8SUX6A4DX6cBK0oF8m8HXvN2eZFH% zqBy&LeGnJ}+#&l@{G=evma$3IQ+V(Vn>{*&adYXW@Sqm5#b~}EZ4PfB%+V$9(g{yC zI5bqwhDzT@Dk8>Z%T_zo0s*SKU7!vKm)E=hw#TIkTP(xRy6f&dD?_Nk?gY-CYAMMFrzt=|rrEd{)ZmM0p5yT5mtTtQ?@NaP!RmQA1zuis^!*f-R#195 zJ^`={vQAO{{R4cH75#jaW<;8TXg)T-x=#S}4yAZJbO(HVM~l1a|Jas8Y>PwMQrUk>1eO ztc$y^%)b3ZACMKX@T%r%h@nY+ah`coTae5-!2Fu+K^R5r!3}@sYJ_hnuinXP&v&(s z9egw8u(3^dr?zS7&W7ys3oZyfBd=a-qp;MMUIxy$gKuo8L*#qBxJ|OTO-r!}9{OPy z`GNAk@qTksSlgmU z(Xtnj3ul=}%m?d^H~){vMi0*U*5Uu(zkdH-e$B(pO$e;U z{jQWK0?FXyz}So`VZ*w0ZXPxm&qJlU;jSWaxcX&*ans!?bbv6JkTTvAie##xAqnG3 zaJ?|+&U@O~*=ZEWDs;&@O4Q&YQm8KtR(&5I#~4NAt|CruEK_#j+dH+r%u4}Yq@4cv ze7Dkcj0Z+wnq=X;&0EV-GO+1oH=}6KlfDYP~o8!*d5}B9;WE?l*IWj z7~on+D@S;HLqNa~!jDAA;R4UVTmmQNBPPjr29`;&z28BA&%t@@+y@Q8i8WkYX_~yy zoc8dxB5E-vq!DN6C>=FTa}p2IM~3S|sdo6$6`43kg1K1dbmBx&$LoRFD`@rhD8#GUgP;rmcAn-JVw;aLAKo1;Oci`jlSeKo8{@un74;2sl}l#^?D zC$^AXp4Fx>o{dkMbd@9qUaXZ048UP|{9C7Y2?=>Y;rt|rCqx$0pnGT^9HT4o)h`&O z<$8im76OWyMSJr7LO7QShE0s#FZa?)OAaTmQX-tjVLQ@r{BV$6>L6b zI2oY%0lWL!i9JByi9u6r{!#G5Nx=F|lEd@+*Dt$h{{X^7$9}B8y~H%-zjuesm(sZz zX;h)LC$j`JLinIaAnysGf1>oa?KF6D))^%QNb@3;?k!Su)QtM4?@!mj4OrE`Cg=u2 zN?EGclPFeo)DD|n3tEog&+$LMUE3!dF>@rON!MgX{SQ{p3AIH4Vu;73w2K!VaZ$z) z7X0hgaZpUr?yxBDuvs9v^zTj8eq%cWjn8ZLkAjH;7F)dwY{98}m|9dt=jG)Y&HR(q z4)XdNRPVO69AbuotxFjzV2W|<*nKA^KzSdRJ{hwPG0@RrGC3$!xnCOX7`eO(%<;Ck z`egHc#Yg=(;`Z$?FV=l6_&hqASyP?@Hu^O&qsveM#Pple+VOXdJRg$%OWvGl@TRF( z6CeAD`0&(sXIEDNGc&V~+@1uB!v$t?(6No#_c1u{L;zcG%hy*mlll1mPq#!iZVW|} zY-?lZ`D&q6W0Mzs1x+*$jG|2c6s#v0^ghsBh3nP{gAjA(m1NZw!zV@96C*zV68O)W zdxr3AZ|QweyOFYdTBj8yTGkv7ZiOVdiwh9>5$SCXu2-7oDlcbvC>?+$W~TFPoRheR zK;QzK7g`zF%vp1cp)vb{uP*q(qq30N_=}$iyK?0yE;*C&oqFfKdA>aknnSG8Gg)#q z0lSj$MHL8Cw-9ShHf%rp+~!EeAqv%(wsHzx#K)}k?xhB8m`2CUM*ie>UF z1d}9zGZ%+@dtV~yKFNz0xEX5=B>+V@DS(@~Np2}50#Z?xVAC+Ingw(HIA9jGAX!|Q z`#a0%Hh7Y2YKX(liLNIHCzQtd@S?V!>M~DJAs9?FU}ug`=xvDZakuQ}SGOInRsu|l zNl#DL4MKh=(oiJm0cPjeX()Dow+bHsX0j_Os7_xIGj5lb9*=zdXy0tBU@Y4^F z8i4GSgpFhj%SkM&R~lvu}P>|ID~3P6^-baZdFXbld^ zVq91bHjNOw4d|Gk2R2<;uoBnNv6s_nWyA5&l$2RooPPw{BoRh7bCY*Q6hTv$9?;P> zaXgi|CaBr$E>lrx`Qqk`O=^~vd9iy&g0l}CLk@%h$ucfH|H>KRZ;7Wvz^_VwvlKfK z5e#|;Dj$5qQp4a91j(qu(V05kGZ7yrM2bNTTh@vULz5Dz1hyn7A1G$t2VT5Zo_IaU zcH2=;=^qHenIfiW3A4$XAX(_bQ8~+~Q{)s;G( zG<7ER;o)eiX+7z2Fbi_=@Yv=dZpA<-FJM*l4h*DtIcax{MrD&O^)O9@WuMdSwtPW#;(}LK0tCuV1HqE}o4?8(IrQl{5 z2iuP14%OXW#ZJR4>Mm4ve#DtePOc-a;NYNpWo<_%^SRUJ3$r)QKZkEOSwH;K{c>$y zPR`wD&vq(;R|&P%;!_O_k$7{7%@Hw&UBSfEbS{^=RF(T^J8w(Z`45RL&MSx3?S!oi z8*MXI>@|I01Kz~3qW#CWpFfi^o=J)IMe9e5UQ={&l~liawQFGsZ=T=r9g0(=1U9cgs`A6;)A z2<7_5jZd5Q9Hp94DoL`WskB%kl@6&0A)+i1N=Suxv`8^hwxlE^qO2(@Z8Aa>Swd;C zZ|2W~p8%BgK z{BUj_A}(_~`$KL!QOsHXr?0WUpR;2?$p_*v8+lPCtG55Pn>Flq?3gwhxqNV(n3+ds z%|&$p$4ATVBn&T-o_t0Gw<5A1ULH(F=LRDQ>#fxnuU^$cPnYA#UWw*^@&i~$wf8r) zwOwgLl?I=)vuDSN6%1x>?0KRn>-^A|h)aJeHB`T+zg3K85yD5wyQ5!=w~ z1~LAhzkS;dyEBPPps|x%rlkc@_Yk~+BFvH`5*Q2_C)t!l)5aN82+p!9<<0u*q*>;h z%(ETFYTp5OPJ1p^^hNL{^Q}-=#A2;hk+amR-q-pgK22t`!pcF2&6>CI7g)wu6hD|C zocI(7QjBlnT;Rp~;9j-rXu*Z;7y&&WT!x_G0ZO-Uj+?}C1$kItCmN!p1D>d-BrIf% z?{NoC+`;T))hr7PicInh5Qz+&MZU!k1lM%jm(CfnICk4XXHno12=r0QIyvoy@r} zURdV7OScvzq`|iYIePj7YTIi)m>;{N9>>Ff;n|IRPAlh8PfVH^&zP0bBwd zT?|)M4*TZ@@O!2uboY16W@&$aCZLX_jqmDa<<2b`-g|238Lfv?zC zm4JrcepzKPe1n@o4mA1*db=8iYtwwGGCQTh@4o&dYl45VK=1MVszAv>b_x;KmmZT*9 zQg-j)NJ-+2vsmHJ9KNuwUw`U3_AZ8Vf9eXBjlj_`mg@Qw|9W2L&l8ik!u9KK>O99{ z+<2;PwwDVKA0QV3PtJ|gFxSM=c#3k887eVaT&GVhHdOd6fps#W{U{+NtOAQg%SZvfN)Pm+UbF7<0*C4_Cx zyY;SpRUlHOBYTx0GsB>Jk#G!@t@U5N1omcw)}{voAVfXpou4jcc7Y4hTs$S#+ycAX z=%e3sMp_->-5I_m=-Z{h;i~un0rn2G$KK`?oC6L_aBnucaXr|oMzM!~y=G1qjA9AF zY%~$eoud)R7Rv5Kfi?iN|5e1nB+!>$V8FVdW{Q~kzs@S!S13Xi7GL=p2kAz|-4Lc| z#d>+_6f;(EIjS7&E$AX8EKqqLnkRw@gZ*+!ILfks#lZHU$1u;|g8-9Ht$w%)Dc~cq zb2D8rb%aRBfQ$II6xg7kp(?(*7sAQUt$qkZJ_*Hli0Gmn7b68yUJH+_UwXM&w&F;Y)m}Ow@0p%_oc7|(m72h0-p>z(4ci=QY?W+ zs7!kL9=zv5{iXBgtJZ0CHDdk>Gt0%s#b}Ly4_*_Tb;1-PU4m%s*TQ|m>Bx~{ANq#T zu+{ZX8*OIx(d3&%ep@O>nNg0Q<~WXRdlt7X>;(%$rGZF=Na{SVPeU4PDYjWli_C`) zbyLlAwUz>3CH8d{n`Rwin|xn}O20IHbZkA|aENTvr%xB!=IUZA!qjb{NDe3@*c!E# zl42emXB8XV{rbkneNI)NoKow)>dbxS{%YXF1)-x@8>n{u^Yd~9#)bd-^Rwdj<5|Lo zX!0_(!{d|zCL{P!D0r8g3=6je@l=h_}D78Kn(8L0Gim@5nC5 zo6bQhd#!EgNAD8=+c5yAY(gOk`hBstX@bM9Cm5tyfA`vv(J5-?thh=740HTV_u=FE zIamiRNHpy30sUL zQ=NfJ2&{^L46bmEvw6> z_R(6hhlc+rE}FCQ9KAsC3K-ae(SA$AxJR{q#08+Q7R7FQyG*)&%rI^x^Se zX%Yv1flZw?FS-V_US_M)9&Rd#M2@|2ckamYHT#3O@6tegam>ht%{xJ(;TemP9}f?? zH@3DGl+VNGvIbh*xNX)yg8?*zi<}Q1u2=Xwo2ae4`RY$R2T!-wR8^&dh76laWg+)L zN7!5;SAO+b@F0Kp*EKZc!k#Lcah>N!oL$)6U(q(k#0z2ETPXrlTM>-@cbFEWx5mZA zrNgjrLaroko*GyK@1$F5Iam%+M5d(>Cg2*07p`7?MJnT!5^#$#$IYZK9{@;lXY|JL zQIvgg@UMkveZj?_m>Z8M@`R2zewmrf8knRkihBILvvcq8@9uyES2DzNPpj{ZLy?rw z2;VN?#a6(-->(IKft(utih;IQtplM_J3LD3Vew4;mzpc3H^SCXOq%a>hykRxIbif> z^&JfL8mPlfI0WA@KF|A_+3nB(7y4v5JSL&0pdG|vJJryv*DAwdVgPM0bf63 z;YBI@`ivsT#GxhsD@u>qRza(=#mtCJtdQmo|AeqOb=SSWJpS&Y8<#`Y{i&vYQniqD3V@j3*6kKOEtI{``#Ej}1O( zf0FL^SYGN@5@yx&84>#$luD0*j^d&qIXY2d&xS?YFqlr(;T5j`*zy zx3dRrH!%MiSGi^7yfB%W;r1x3!eX1I(Ln#0o1bS%T!@I>7WgG|-`~lumru?1I57nN zi4Z*@)QFBad=~08!NGU=&&L$N-49-06eI()et!gS<+M3K7VmXGKb=x)plXSa&_w)x zgF=FwsI((c@6&wgHcVOKkApwhf==so|3N#uEhNRz=At7i0XIFUHya6}D>2_Akdiqs zPWQ3G)7O~WlQJVp0Sp1U_ilx6#xZdVrju$ejjtmezI%Y3^QR1p9(Z{2`Ja4oDZS14 z2$n~e6psy4&E@f6pD``Da9|PBfdM^ygaQ(l$CaOkJ%@f-M@1R|PzC%ItUY%v0EZX` zbbgcgVyMXDK`}S_Xa_ecR9b)ec2-$Ol9M_fN2Xq+VTmsWj1p}-W#dMS8Ky~@0aT+% z^Jl}L?ENjN4v;n;+p(HU*9P2#r+;*Sj9Mls!kWlqsixwtTJi5<5z>#d{NwyRhaqd2 znIY3m4|RUvdQm zfqWeLFXWR@+_Zz=pw8K`V+Wb&W$`jl{o)VS>f}^i1Ij=Y1c0=ASZ-RrPth)4%@ggn{lqe`Zvt z9BJH!-e&-8y-Bs(#54j+j*3MieCrG#G;XUkY&${XNpB5HfPJ_|ASnbToM9mog9~dN zQYbqQG@z}bZ^l;BmI;h;`;kE!Tb7KHFYiIo^alOk$4pO+z>QcW*HL1jl)@dRiRnz* zAZLFmBMu<&s>E6hOy9yNEHJL4JaF{bv2St4rax|~m`6rl2-bLG$sIpULfgryOQdZ} z;6_p+BW*IA+v%qA`{rPzxCWY_lt}u3>mJGEY8sHu* zfz^GBg-U>EkVl(@1$Qo^7z%2e)qRTT)PZbxrH!{I){GB)AT0;d(Il-TdtEZx+)C5H zj@Lv^fo@TY7bb5v1I7~Bsp~AbG^j&Uw{q6Pfwix%+^d9-L?BM>e75U!_*)`jq1mYwF(oKjP|M88tC|GvQ?Qm1JCO}S8->M5}f~^f&P{Mr>4UQR6gGV zhOf7^qtswUjC8d6QR?MS2QKJ}nPb%WMtp2GW0q{B&0BS;A|;v7(p3qm$Sd8M^Z&-vwr z1+RF#Gt%nV2I+pG`jFB=d%ZCbG)~{=ufrwZA2i2|Q||ZPUMpg$_;P@jHDWw9Jq87Z zjF{MSNglAxtos=#1MEs8xtyKw7D}1}SpFSk!8UrsIDLsxYQpgqUh*8JMXZrAOLdrk z#=O3=K`Y{=r2#OrsQy6lR9p*@7l#fX7WUn1VUdGg{X*pKF%!<7XA-IE!xxaSmN+U^ zH8m3(_BuGcru;HnQ7Y`xGcu+ZV74bar`wOQHq0nKW%QZ%9JTn z1UTS@hBY~MfX(^cbItvHJ7*fSIv+apm#t4kL`3VfU~<{}9wxlh{qkK)fJ4M86xv_82hFqZFbC^AYWj)&rT3!#FSCFvhj5DIc2YL8I^Lkldm7u?8^z=*wJU~ z&YXOZvTnqG$S00ntX6nviGxup73z^7p-Ucg z8eQp$swZ$VOz^iuTV({V^@O!(>{GB4Pi&weZD?R%w5=$*L@NyC)Lcz~_0t#Ij#Eo* z?a!Y-Q!vs^#KJ|?MH*0(alLsJ%pK#&d}{(U5h#0)bcC=T+3Q=qVS6?T62}H&m zHbB|3^SI&CLCn(cM&|V1Z;uC(v_(lfcUB0%Du2eh5Y+JUBh8z3?V4?zYVNIV_Pa@C zcrP}4BhJ)m)2gt;iwRp`2-i;FC>?rCF(zsFJ1lsC1Fl{5ou}zlX zTW>@qu`;V2{C7RLKUB>@OC&0PI2Jr@ zaH{vYf-F=5lDSnOO$Siy#A{5!jGeflRZb4orm`9+(OO_8lh!~d1nE5Tt-y`FPVG4x zmBdZzU`%-F^FqbX;R4*kMx3TnXhOln*g9|7XTg8*K?z79D+_5552SUm@j(zy$U`fr z5GOE5yPH<=NE!e|-t)CH#L>LRfI?6Z3LiqjJG&oN)TiNyeTxFs(t=MyMQ&nHAtj*z z?hW$qgsOiB&=0Mpb;?bYKm=c|!cg5WjjyZc^n**lurxNV*DJb$!$G!63H&AU3ad{e z`2fI0D`qD^NizBH?HbK0q{-x;AFnyzC;jKoe7KeW4;M~FWI?ob1m-(su%xSUg02CJ zrh7rm$z)(MFkxI`d=Lmg4-V$bCKY%0GrCFEVzAOb1&>XTn08Tkc~BwWjo(`AI8tD;hB}Vp<1K;Oc@+=e?k&Kc5|=u;(n2MeT)f0)eedd2 z^7_IT35ZN5dNeT>g65n(i==N=%;?h^pvP6kaEMu+WskY!VT^XFC>S^j2gSsuFf-J2 z6#V8|ZHiWM3*nxY%uY15S=Tm2m90i-Io5r!EJS%5(H_fZ*<)f(U1Aj*=bAj^v~XW=kq8Gk79fzF5ycJ#g?!{ zBnH2@5@%wSlP39mkkx|mLDVs1ZCup#<`iDpQQ6=o<~|rJsx)j+FX% z)wp1J5-^ipNBztp_qM{3{>654l$!TD%zbTzEieNjO@#Cr;Cr|T_*E=n#{l3%G5M=| zgXPTDy{-#4AfG3qjS*;oYC2X!6hU@DZ!%#kT_VY&>NhU~|K84EZwtS>X|h;N8-nDm z^oFsSy|1&y8BGauTdPx1*O6W-#3wsj8N*eMF9(JPQI4=^2-V?2rF-Z{9KG_rW3H}_ zdBldCl>7D|!aDRPYw~(wP7mg+I@ospj$>Yqh4{&97U$6oO?}P&71ndJ zU%VOB_e8_xvqF_d;0?($7%%hm0)3|L;+`|*8Rdu7%OB0YtGpO#g>KD)vegGQ2DF`T zi?|ueo$U$onIV&P!0C2Y2TK#DFH1(f&(HoPqbT36+mb(PTWinQnoAAoeI3RBMhaLn zV&+G-w|1KA`48z;FIDdI$&h|oGxIx&x&M05^-*q**tv6oBY>b9nc;90Tnb94roC#} z_@iN}M>50i9wm)`tT!W+O}TKodpTuh zQ0VLG`-*lBDl8T|2mO-Q6yP7im>wCUZx_VD1&e#x1DE(Gr?v01CmKhnrG~bwXsxDHyimrtvq|BH}*}=NOl! zgQhlG7~1=r1BO$e8xU6XYHjM+B*BqDBJj-FK_5K_5JLiVHp>D*5-I4;ZAxb_@@Kgk zpvZDtK|0fuq%;rt{p70P&2zy~qt3y>BC#?F6PcC1CGk2jN)C4Dgx_-ja9b`v^D>Nb zebsyCVd^t?L!kJoL!VRux{=T$-S;1rHiQXK({-8L47@JIqANa3(1oNQNMje;)C^gG&R> z4F0v4%OC_9#D=sw1yH}pA0fX1S1cND-k{H#qN=F%b0QdhiM)KTKd6Gyn7cuc*Pyku z>4T}WNDxL}knP%CGl$j3X*4$TMTosia~LQx0Qn&1uSKM7nh*#Z=Si1pyp3jmC1|j% z3S~{0ObW8TX(Z~F0{@$SbTn3Z87MXG;tC%x(7X(lb1B#-cqk?Vgc}LY8eur&|3Rks z@A{zqRRqf`1MEmp*955!(1G8#H6`|iP`MiRZpECG(s2cv*0k` zMHp64VL#IEa2f8~(}dtHTK3b<^+*lnBpGPc!lH%msjLEVBZvf6ZBO=_yvCFoS2ffh zFtP?J*Nd`oWhh+s1F%SIP(MFM18b;UMo{^zzyBgYZm8d8SJve*0lN4`tt#b+sMGYf zB)Qn^g8jaI7LJa$Fm2ab3W44zXwY{2sWf0=@_g;CD*)R{U;?oiK*zzP+i}nDsyJej5C@7B%1c|e8yX__EWriFX zQo;}Bbl1;s%y1$8Prqn`9DYl@Y$l4=eFU#_kRvT49D^$-gSxH!$RiYcMNGK-7D+y2 zhLvHJ`}f~}?}4IK*f$m98~vKS8ld^U!y$IM-x)ZD3YADpuE6g{n~T9?`rW&C zZ?W3jyVGuZbC*3+A5iK>rBh%fTQz{8S0)F zr3BNs#QwE{P%J_qF$?J5hUPsQJx?aaw;wYz_}P!KxQODB+X)@xCQsH6&I8XR&78y{ znR4P9=8&u;+>5nlUSE4oqm%0S>L|2MTVTNXZ2lP=W~$JYmHPt|Jcw+(sSZ$rtA6*J zi2#c}bC7!faQ&o3gKI%>(XVlY6~HFf-`L`fplt8lys1VyY{uNVcWkZ*jvt@TcdL|~ zU5P@?G8e8Rx0doUFwKAN3PzYguTpRi(}apZ|MkLTNOiiEl1NiB2-6YszhbaSJa@&$ zX4pHVy*vp9yAhDO)ZE*uL-UV>#u2P8Y5`W5PcYpPl78N1(jpaIzf9Zus7=OqTj!NT z+9fGDl@|6}E$JzZ3{A`4HC1_zVA;#{lgG#lW+&Cz_F9_`EQF?>2~q0Ol&ed)q{RAE zM192dQGwzOYtK|K)?Kr9g=NR!-j0sSh4OtOyLh8sPHCI@N1upuT7IdzW9R5y&-<^d zgo%5f+?e0*JvfCGCPK%%%;=@pK+2fcGnP8`wUvt(wax5PWbHW!q@R`YSLU(O(2O5G z7;ywFV>BkX-K?~B9>F?Gps3fBPqQTYt^avhtw6Q)C!y=+OB7knEaKEhqt72Rp8hmO z=wGiz)L4!6ujzX5)hx>v%5U4&>vYm?$$^qBioq}5eEFgwXc0Zr&1iMmbzXn$rF(`G zKpxBnebtv8}2&m?OO8E}kru_abSo&H0L1zsynAPIp_7*Vk z5Hp8a;PQk>IC@GkkbCHVEG|Cp&*rEFJ%(mjge=qxaxnRXumXp+Dbdl~-3i#z8AJxa zjKBVZKm?7fJ=(VLyPz))?E&@T~ih(a-F1dQ*QfKbo^uLdaYl_{kgeRb1*6PVg)(0s{$63*FO7|?$)X&~+zv^c%;8VbDmk^Q(_@O-0!u2$%VXw*KTsa$al zIAf?FEIfOkD@*n3e}N36_~Mp7fWs)d3IF`iSVL8GBeKx_{kK-sY;+nxo%;sI$Z-gJ0>#9gx|D`FRvHPcannu@X>R5@&x^+9E_R>@S@m zujJmxB|eZL19ck5I9Y#96|i?ccO{vq4md=z@|C)zVCw_&OmPT*4#VI`me<;b?hX4!$ndbw7!fiO`DOb?dwivh+l=o& z&&e^uit+Au23`SKjjS|yBC8FF25$Zvbccld4S@F5)(SJyJGCxte-hy5XMxDRnYM+n zi8llwk)^xZ3AOsy`#z6`$Qhzn35NdjgEyc!en;FwJ}Cl8OHb4|fERN4$GmY@D;lHs z4s+cGs~|%rVJetzY8@1z0PSc&!Y~l-RWQtnVq>$h1`cDyVF2`0QE_RGB(KZaXxF8A z_(vo1nJ}+EZu}ZIuo3tar_Hh3<;*9-kso$ym*&kcS(B+@i5Re3DBfS zRyYQR8tnk{Tumd>aFfj)jDgwa6ax*V)gpdI<$pkL6+XJLT+>x-d!a!AlQh zGKOE3FO~O9iakFbZ8%+&8}%EX?pV4@)x%9G^+kVzie}|Burx0mwGBwjNM7t_uhN&p zVm0#RsliuYGcq4hX0Ajlcp8b52gm-M4rGq9G{DJccHuc!0m6S67O!{9+vf&A@pSP6%>l zn(#JY8-ri`Ivm_yv+2jtUz-kpG{sYw=S@edlK{&XjmbG7p~^U%)Q#H=eh@ zV0yJ;nx`bS1l8tN4TQIv<~&rz7&C%2$k_;o?&**&Dkr4g}2-Y zgc}a(UWxB9aq<54_vh(wtwmjTL6+j~pnqJJ)edghT>u$XY+`N#yqM4w7D=vBMDc9E z2;1_|eg9fAJ|%i-mD54^53L095>!|msj?j>FU*dj)W(nnM7|Yv?kIdI`8*pKwNOHn z$-RRg6yT^5>`!J*Cf}YL!q*bE54WvLF%q8)f0KM3IBtrtT&S&IUdx%Ka5(<^ zZrNXy^K}=Vzg12&SvoOlEUp9Vx&ieve}4W?x~^(1c$^Q1=}ym3t$8O zhD-8(CnE#}(28GmCWr|NN^&UI2PKb!1Pa{T-LL!}Mk}sEk`fOQkt-(iCWJxP0yr^^ zQ@b+hI|I2(){x!_$sdmT8xUE5x(Y(xLx?e%yV zZ)m|Xg_Z(**NCdzAeGqA7Y?%CIrtx^HO!ei*V&`_AQZn4YrW(l4^#qM4|Kp_3pj_+ z^rou1x^c;wP>bj8#k%p@Q6}^Leyx~PafrmfuYUd(W@!VN+mb2zg4hE{tKY9j-i0JD zZyRBQipB~sD8lYAq(nxc>=lTuZew;rMz+7068U}USfEK9K!qJJ{EhciR~G=$b%DVo z%s`Kz28m(g!`q{VeJ?m+(&WiS0ZB{Vz!2l5auQI@GI5ehAc{pY$q~wl$N4@B+j23V zGX$MItG}C%rauUW1Ij+sK6SGzu_vU1zkgZL>Vq*Q$j??a)7>Xd}WgCDW!YVlBb%sk3Pg>F-N9WJ0gTqcd`YujFx##mK>R!QNfdQXNPK^jd} zj8QK}D&DmdHuOAM-0b7+-Ej11gWq)No#T4Fv0G7`^m;CaLAxZ?G0LsNicD+8&@}}O z$;4cmJLFH>@G}y3$b?>NY$xw9q_|}}1$UtRi?c#%t|*VSE(Prc>S-}F#0;q&fZY9F z*4v7Wh$a$QZh2PQ>@JL(KRj}M`~FtjPE2aFnNSD@4}5$KngVJaK5+twXC4M(7>_`z zb(?5s9NgVh3h5mv1oUc%1L}0w%U_|%fVx(|n(u2r@D+2giFHUwyb33A)DcWsnE+(@ zu1fU8;&aFN7W%{1vUAGEzN_}$V|n$V=g@xI`S^?6fHlfL0nWy@X&0Z_^&$7xo2X<& zcYX3u+6+9`^_eP)hnx5OwLyc~7QS*xq9;gL(T?R`>dSVJ;lvMXRQ~!!pRvFB^7I3e zXUvF*_sG6x9L)e@+Eh1t>QwWuWiEvf#AT{rRo%9ovi+Kp&dMYpg~j}1U{l^H8s1lj zA~g2%k<83Y_6u13T|30Zf=aBO!V8{jmj3ZGzUJ)Vyjl;R%{sps*0BAA1t(ViJ^wGw z`KPx@macc3j2x_=Vz9f8KI!Fka>4|$-=i6k37*sc+88X6eP*A{nLW+ocU32}EV!XM zwed&Zj|EOyTaGjy{BiKx*Fm>y9zB_tx361~{_y_lqpR)8GGWNNq;>{Nd)^F>F)2>3 z)K))`8aleEJ4LT{7rdR;$@ZkCuC-ZkbkRFa#o&`e+MzQBbOXf`J(QRAx@?ub*%y}` z=`*68nT-DJsbrwIk-`{BfteQf1oP%9O&mCtcK2Om#c@-)+DKkcvi$ugYh=IvqrKT9 zZ2aJC>hw&u?j`s~{qyKIkp-o#tF>fuYik7e+@V%cz2y0o&BoCinJ?yAyLUC4S^Stb zC;8s^x&)b?xCi#JjH9SPid@(-W&|t7=5tYutWLCwBWK^h_Zrt@GkE$&&D&jOy?wIl z`0gB6_S45C65>YZ`mx=8{5Ul}byKc+53a{!toBZxw)@=^)@`yddn$SFu#koHAJw2&pR8D; z4mvc(`g~Gq7{HsbL=~7QAW0>}bnxWKk*namp5!QN_E@PV(=o=BZ%2e(I7w;bs8LlQ zTojea@9fACRH+xOgl=PJ$Q%*`fm84_g#1FPK>OFr-!L9Z4Qp~r=3}*6;t~@eIwVq| zqrV-v2k(HVGqMqBjYTjI8#p%DnKw^A9}ezkdcgsc4gf184G33j?i!a?VQgHpD%msBSwV=*4u^Q-UvH1QGE)Ff2xTN(K1~1uwZ)(L)9AQ72 zaiFAeq;}r^8`uGU>l>uxEhz0wthUTHSj2#fL?D?}A^3r%&aai@c8O}Pfukw%>Vc(w ze5{Q6KWxFmLZlw7+MVsDf6oM!9i?sVd-?JK0zXP|>SPrpxITipa}ZRuOO2B-zA8ih z=Bd{-DG9!CVZI1_RnOv!gCAK2xr8|3e3gLxPmp;$vsMD^q(5aQ`V)-m+)urRJWU%{ z*?tmw8PeY$I?uX3`9JlRq=4PO1;oO2mMx=M?Q<<|H^+&PJXo90H2L{^hl{{2&C{u`Z!2Jjv$O-#^B+c zcaBA`UflrusIUV5@H0%8?RbH+Y{{xsJ68o@5~q!Ire8>Y8$Af%s#1b=$5zOT1uPI- zV0Lev5ZThelvO7g{o*41p0)P0A2By?W-|)*+ez3@-|K5Px8Rsz=g8vmV7KZz@!5zS|TmI zWmN#k92b(49nM)ie;WxTRmSnNk#3&6qT<75>zA>)OAcIY2gU0x%up9z0WW*EIgkmD|b)uy3{G@D=e=nA_fuQl!*c;%mcx@=(KHv=@B)n5;=7 zAq%W&rm4UJRZ=^u2sh3uhuT+!QJZt2|H9fzC=K1d?$>Gey$`9{;a^C1qyl8M;!|Bi zt>ln!mq0`pNIRti!1zc30;u2h6S!{}!P?}oVvc-dH@=7ISBnlHg{#8yC|8SAS>X8G zGGJ8XXU>p;Og0;> z&!=5IA!pwKv#!EUq1Pg)i%XHdy7t(q#JMnaw+E#lbemB(dMBR8BMgI^1T1LYhrI^w zV?9LfX3}6uf|e70Zi+|R-}sTb{!iS2li%a67tJ3Y-hZ~qjEI0ZMl#L0Y|cr<+_dKY z#1mwiRl*Bl?;$NTSU^M}Mw4gr1>vs1#Zz%MwU%$kMnr`#l1?*h1!j7b`{Gk^Fj7n! znuFj7_n*x7s90Tr6b0N}Df4Tm|BgHe1?OJyQM8pvyaWrmlPBMyP@i7(8K3et82xH| zlQrw-b%4qK_|tS2NGD6824cG-|I^zEbQdekGAqtKbFYk!GX@4SsdhxZFwpNtPu;=8 z@U)kOn__6RD@a=>81jpg41fkGf{i+L?GKUexEiQ5Vy2PmQ?0i!M4CKoZcelKbCwPc zR$*Tj?s$#5tpbI0lv4G5hvXIOU17($lgP$wu*(!&34y0GQ<8_BZhFVW*hzENXvfcm z%<1V3jU|wCyv8n@iGqj`U*+CsAHlZZafN12gI2T;w6~TQ$68`9oi-mmdUOi5su}#t z2wkF(FOn%%^g($bocj}igdxCmZ*w3y-Z18xkxLB$T%zujR&Otg%GASsn$@0Q8Xi~)&Otdtgoh4$#jRgG~I|} zTeuxH6;i&Bo~HRj2rk2cKUypUkn-HFB4={*`8h(qj({croJ~(JaP) z?Z?YG=$a(4!^aonz|b!cczOhl3X9v-vzm8(uGq}z(6iPZ?b#~r*@Jrq?*4qRuP85K z>frt&$hm5We6ei8QuDi;Tl_p^AG@ZAyMGgOcTjn^?orYbsX$w#D{Sn6*^s8LJN?8d&)=TH^F(Hd@GavpubMC?ayweoeXuliz=OI5E^TXwM zDQC|0F;(u&JNJQSefv9IibAjd`yE8*uHIg8oO4EA>+b8?fgF_e_XLyes$*Wfc4M)$ zh&w*f4P_s{*ewN{UidZterm%80muA;oSMmAf)Ebaiz8{UL!f;>7=6R@&QDCD0Gmbxh6%t{PdrqBh#oc=WzL^O&qBtvW zq6Ldm0K{GCigDthuJ7NWmiqeeTdR^Mb&#!)v%j@V&c5000P)HRZ7#-~6rv4dz*~@O zOlB`rjW0%0jV4g9O#uuv_Zrv}r~7hTyDTH}aH!K(IiB$H6WXrMu4MmQu=?QpFx*?w zJ62UVU`j_3SYNxKI#`J+HG-L@e18BuW$ENc(cKQwdB@3j7_`Do0m@2BHn1P#k4R#j zAFpV9Ps*vFxH#*QI`qgp@IVHG4~S=*I#I__Xq_5|QU@aPaCC`{9XoVi6x(qW4uzKA z#+}X&uYx7o!e6YB?qAn_?v7YXn-6@3Wb~{-NR+Y~wI_$oGAu*6jbSwv-tVG97&WT#anNl8(^48S~9srRUKl6QBK1L&+03e?z0GDT@Bb9PNaOD-DNl zU%##@#{*80nOBcfV|7>_Ss2Z&!`=-4V|bZX!TBe%`g2=bA^CnEGh5DkN8)8trHPUs z07|L1evWw46djWEhll?C(+N{9$X7VV*Cw%1=orMx1z)&yDUa_qa76FUu8={@%;@}u z;YE(eZN%NY-NQu*=bX3ZNPC#+AOgVpm}g_>9rCw>PNoW6w;uENPngKb^VVIJR>vox zQs0yde5nF{N=aRuk=yceb3+WjRrTQ=i~Mf=fyxK-Qqy~$ z`|J84A4GcG#XAngj$yvWO&W}$Utn1Nz? zDm2m3Wo`}lA;Nb15Lpi30Gm- zl@)s!u6443rXoY$fG7zj@g!T6Odc_svnz2zXd-yErB@!|9Jth$ZJ6NbqJN&md*d5d z*RQ8hSJ&2-SS>H;B}@F&KR>D*oYDXM`8qr2V+hP3gWwVHmZk(QmEO1oZ-wT8JYfTR ze_DerQx?A-=k-om!9}-`vXqt%Fcf|xcV9%N5ksNPVe94Pn`}xn+%rHZ^!4)#lC1=7 z6ISC*8%!FUT4&&}AU}De_qp%8IQxVK4fZU`%5B_NM=#^A+LipRVvVV!>5^Le9!((%(eu(2 z#B>kuOutL}IVz`OiUjRX-yX@V6PVc@vD|9HkCWbjTT)e}?-YW1lR4AyD+n*P6Gz&u zM;b>PVEM|ShOb|XVf?taC3wqSlBn0!<;W+2IAIR{Swej$PsHKSykwMBtJ!r8m&_X1 z2?EhI4mpBE-D`y7{;?%MNK7`H=vbJzV5GvJpqnvk)-6rryC8iInRt9|ZhnbAJ5F;7 z8Z|3;*O|B??mi7LZ+zfbRy?`SuqL>F_MVx!H2T^>gqqpIlgqae5sFXY9|{>^?RYF;|ShEb{J8M~fD^%~<}? z(TQ#kpvy~xtyFF4{|4?pxj<8#qm?m?UFdvB98g1?uP&BQ&}9uu%`$4bVBHg8<< z2@N`EHp{=d39wq9&!!Iv8gaPxFWfF9kB>&&1BeIeBx0L@k&AS=4{pV&lIR@ci-D@T zh(bYR+_ZG05`s;n^lGo&h>fM2Svvw4Ok%Kq!|un&jpC2vyF>$iE7-piXN}9(P#&|P z=Xf4)ERi0V!bB;69jOo?xBG#(9`$8t3K#2b-nM@IiSJp;9F9)Y@k=2gxxL--*0Y=+ zr_aE=>@TUvprD-I^z}j@yWGUrI<6c6fld7yOIS97f0!v=c14Sf_o2peL7-a7Hi8k} zurvZ?B1W>_t#xNq1c42n2uK|mk3{x1z8m@Er;E3<_U!NT6ixd9>qQ`!?PjbB=wIo+ z-t!~UtHym`{l8&H{N2;9DkJXy=sWcwg&ASE7$p|VhPBRhBx_6hkM0ZE@HgCpLT=zB ziYC^7p1ah1pi{z_aYtR|<-vD5VtI|XZ`gWgXZ7A&N_R_#tU0`umoLTIM9F>s_pf_< z;5bohfbj<<{Q5S2YHt1;ec$wiw>Wu0Lr#o#mE4PBs_c=gbCd$`zf#xVIN`Ku1({=m z*%ALpxdow36n0T=gx;J1pjeBBMn(_lW?v6dZxZn3Kz$oe&>vsUp4S6$9kCffB*PJta)H|o*<6Lp z0ipE;v|BP)MhT@-zYp&Q+E73kxtyFVXTTh+O7m8RNw*wPJhJlY(YVjBiFE;BVuhmg zOZ5}##EDDW60EOlX!x??4r2@r2*B7Bbo5)|Ornt@300JClH(xE;opH0qn}>~nDTvI z8ydk$yfvP`*Bs@-P*1=5A{HK55tc_1nFWj@Hx3S=Dk%9gtBFq?8Wa?RUF8cwZFQ|* zzC>4NLP(R2Cdj|7Ufmw z4_Dx7?8g``tpPLvqW%a(K7^O*fxYcS|1{{GO57YpM+AWknnNUyBStui5_g9?>BTIikQQ{&okQOgm`raL#J+QS1 zd-8*HgDt#ep;0Nq)HTrR#ZuM{cI(X~{{HzJV%)5QRarP2K*=f__yPHBlBd)G6S()k z%yC6G34)5eW2Lnlt297`hR(6J0F__=vv9Lq2jdc<=u9CeoM^WN%ij6m$-PiF@>!m;fGbvHhB;u7W#!#KK_k#j1Nx)fOQvob$)1qK zPnKtbD|W^tb<|SEAR`Y&tM2|oaGeTGHTCLs&k2w$8^!z1Z-&MB0*VVpQBoU z79LqGX<#xY2Ku~|-wXr^>ncw#A7@_hz#6#YMoHl~GDK&P=|qka5N0P2;r=vKRb}zV z#;c(A(y#7B`M&~?4(v(+8{x*&Ly(!K54Pd;Aa*r8-t+Y42L?$3fO~Hitb49l(%HWA zcTvWvQ>PBO!-PCL8qQU}OpXdkiduljwuyuAIDcP^b)#$;v?;o41W`0^a)x~o9iIVh zu&KR0Eho%z5L^UbD)isPb13gb_?w_EY@y2Q9Xs$Xeh(u~_hNM{MsJHrvzX-@7oXwO zJ=pW?WOP4q0sRw8Ayo&VRLAw5lm*WPlXc(56!`tc@HVzQOa}6=xkeC%=JdiGVCbLg zTyRe+aJaK7krc04a)hE}|rnxx5SN@fSVeC{Sp-wvygYu zVC^wGS}iPwZrX^pGeOM~dD`JokLu6%&2tdFS;5(766wEJ%Z#m?XQDONz=Bs*=J8&8 zu5Mm=m{J+L5;-U~U&1OUEGo{qxx6o|QccwMs!zz8#*j6pA=kZ!MzdUT)c$qh;>8mW zKfk*`yAm3U*theehX)&L^fb-hRCS3guwZPWRJb3u2furA_vOx-+$}AAHSP>5Nn!e$ zMkx8ooOJp1t0_`8Vx-WL?tOC{uGvSX4xF1I;a;{UvE$1how*B871gJ3wXkgwR^5ww zI5k#Rds3}Z)jBQnmb4#3PsNwm%<5arN*VLdJK9T+1E(@{+j@p`tosJ$g<~aBF(hR6 z1Pb4sG%)QCP=ZsuVp$0WsbldUtN(d9mg*>++uxtgmUv*FvHQ_74ch^X4OuBNbojp; z_sBKP1J7GnJ1{Ef#=Y0!uXEl()jos9n5w6^S#M-a^UD16P1;*`FwrVn{?FJsnUY!) z>ul{O*?F!wF!}DG+xr)cwYZha*fty+!%}?C@)8l+oBnL;et65NF&|;j3EQ^j7nx2C z&}suopzz}eHh?mig+rbh8WN(r{nR+vV|b{~{3!6^G~w)O9D)a6lox-D36om1$QyCA>hZEvt&z9O)-;MzC=w&qy$X7x5AJtwxX~AV5=eETN&HJN2l6gG6YXBoAkR5tc)=1rrDZ8B>p5 z{U{~Cf7flM>~g|Nje5*pwugn}V1t!D?d|q_&ZrWYokf^kO)pxA*&;kiv?T+; zRv;_rO8U^i4z5lSZ19Mt`a*EIhjIpO6!E@alD8mVFj9zAP~oCcta=UZ=eqGM##ED$ z(m}K9bm-~KY|7!@f#~>XPWhV2AhT#=>#?+e;R#HraFRjfaSJ;~8VC07EjU92B8?HM zM;+QKb?k=wG1Cx;yaHbmiph?}=rbGy1z2Yr-n*I#9K9KuBmRj6Za59&b}aJgVR{Zv z7&mU&ev@JN1tY@qqCW+)K7dWyvnJ5BHevj9$-e|@bfP(H%3ACPgnc1<6wn>IqbE$6 zvg+p}Y^#-FFe11B`d_Ux>U<~$l!JJ^D8zbTo>s^M0hfZAPQCWPgmERvCsk~@$3Ml0 zFT<2Aze&L{*gccVNZp58P>b+pTUVQB6tM{_ku-}^z%F$7*}6iJb%tuVDkqTg7iV>8Gv{EvnOHxD03dyx<7ej+T<@S%v(Z)An2(*>AB8`4{Um z#UTGS<3)pI?;rZC7QWod*A{H^d;p#ERd0=-22yx{Th540Gta2$SKc;f$bXzkz{pARvI)w|_`mBHj*RtZ~|3 zL>LJQD+Mtx=*g2OBWG15UF$aHu5hw>XYhNlXF)>5&DLdQ!X`tWs~mNGsk;MHVaRk z8okT-SY9ut#Bdh9VW6^zS>z1{pj~OE)LuZJJ?NVYb{0O5_!pU=5k$M0QM8=VztcX5_nKhSQymtnq-n#LkDq!Q@l=8drdZSb<*&p@{qs-^FOed8v^`WPdE;RN292-gu-lQ>vs2!(joQZ)%# z{?3ehWU&C6y=Kv=vo`3r$vFQMF^@K4XG|L;@}zBLQiSb+5h+HoGUFz)axXl!Z9KCI z>cTCnpEV-cC`@UoEv)mt3=N>bd7H>Y0x<;BA_k%6iXqKIMnJFM3&|3cb)hprIl|Vq_OK0KO!Hi(Z=LxN3|8&nOwyr*z7=@&_Yzx8EyyW zK>8-tK`{24Oqf<{%ki+RPM@#*a`fP+KWFn(_s{xFX=7WPU5muKIq*^r%G<$;I_OwrxD?EfGgaEkZpBOkqhj`Rj;UMAq6jvR z+lB=?y~7VxJyMo50*mj28{FAtRrWaQF1q@O_hWya-b^JBV}Wt1RP}irU@`s9IKej2 z7{|OUllS5UhHQY#{e3%cqxT+1<^no*Rc2W{zkfwSY?b+oak<^g%F(rQX9oep*rnj2 z9}JVUOciX*aj3((zXNiMwNXT3+`+QUb?$!kXsW`GKN{(!B-1}(kNTu1UZb}0n0D#h zwzIrtdLPT!6|c&M>d)<$ozyY$UYdi=BDpO+akDwWYmP2iFI{IVb*Cq8r=jhWO0`Ja zhOn_It5HlWTNrzA%cOgo&-t-qf5^2bUw7&A>`Xp9P!ieq0V4P}RK%=!o*UNn{pOI_ zvF_1*yxIUpD^RKs^Ar}VADbMrM;%Nm(b}@%i4NDwtiBCK<@VJKbOvbbup-V9OLZPv zw^!q4T4+yQRLlKR6huRvyYD<@w|xnlCZQ2x1z>~4^5DN06YhEqR3$bMGk%Qy*T2W+ z_Sto2j$)-O=08N%lxw7DqBVpUQ{B4j{XC$_Kl8+If$ilfD|(d0>Kje&$~SWTICegM z`ON2kzn;6w5Jw|H2JTfA-JemM6-gKy+PVTO4HBP*qKRqRvX~TN?{4G-k*KR+$gH7tSsG{vK9@D zM1bFH0tSaYQE&IQHZ?S)q7iT^hwLf)`}2uz9B^a}5w@6V4xUsRghj2nhW8K7T*Qv$b2XW~%$B5Hsh?H(XiCY$~3QTG%; zYM=O;H~wU#dI!$nuN(y8tYB}jG{K2}Q&SPUP8jy4ADs_yPGytNNCxh6kc;IgF6lI{ z7wwuGhdksyL}IY1AFDEJnn)#>@A08Nw0mR{Y}1HF zN&h2!<+g?`1N-E7e@h(oS?(tA#JD}v0{RfGK=C9tL>n@|z`z=MxBMLEc>Uz3g=O1E zfmJWLcCAsA{aGk=n}PZJ=IUO7atlKq1PbcO+(dBzI_1+FY}=~>-CbQ29K5M>k;eZ= z+CAtRfzlhv}bNmk0p3ME^( z&!@hh@A3QH$9>$#ec#9LK7Rf4d4G!6xUTE@80UFD&d0uKeRMD4SE#N#Z<&cx3!s;P zC6)kU859F7UTJoHin9QIjDG|1VJ8!V24v!QX@k;lW(h|jvdD*aJlq+(<4-{?$(^-R zS{f|VUNj{Iv!H&T;cPOf49s(5%^)y<)ple9Rl&^n(DVsjwM1#uZfYrl6cLBx*!xv= zXEo~)QT;YA*wXF&o3z}pD0c~BZmo|zv8Kgg6Fn$rFND*H!8mL&L^gd;Hr=hZ7S2sE zr27%`0anAbv$@z67m;jIZCPLjZUS>QQVT;;Owq3tY25KwWP)TepvTO0Xn#bSDO&vUdWdjD}c4LtIy_1AC0Hv;H))SQ6BD zQ1@)}qK6nBVi8!>Awkqpi*x!-t^1%YAiIjKSrG?g7h%S<8a>~>JJ@_{;?s<$M1=xI zcg||vjTCHMxk01KDUZ?;ZJ?a54pIH!!tlO+mAxA4M8|QSvzO}*oh|tZ`MM?A}py2KQP}1e?HD=Qq_Ye%kfT$(0xnpYd8o z!_%$1b1O~em7u5i8lg|`ozDjA=r?yF=~{W(Dzw%=Q2a0sRwBEkx3}w@iA&|glGG)^ zCO>%Nm-elRW##1;z*jR3dSZm;CCcR}W^|v{{k4%&lrXk=$NHTFPe+(oWiP;X10P_6 zvjK;d!Q%?1A;Xv<-C|1AheH&Rk;|0EJbQLy9x$7f6PcMKV(B^w$m|}y!K5-zV<0#l zEpeMF=jorj@od9{~;R-eQEX%Lkblmn?v! zP!#aWUZ@p)As`ISS6X(1IbW4#)4yZyOwE7)`Xzkm9t_v~e%DsOAI1hME2^hZ_ge!2 zVd&{E3^Y!_fc~FRCUB!^xNZl@@|A993|B=lBWg2@D9Jsx9}9;0fQpku5+WG}xmnkx~ z8^(-Tpe+yKU3EQ-nJs6F+iMIXK3_8-STgU4`(6#8XQ`pw&6tSE} zcv^15jcwe&e$(Gwb^5KB^wa_ER!N%#{$fo-9lBy6(T!PSXQLmoWIis<_`G=3Yjf&~ zyWDjVfvu%kw)r6}ClVZjDV8;*Yj2nU8NeZPOnV=)^L6d6!MDZR%)<(HElz%MtIh73 zixZwp;xE|n&2iNde<8HT<-N31|Hg^0T^qum7tbS~Qb^3^p)8$3X{Puc8Y?nzxBuM% z`8Of|{WCT9@Gma~veS!L+BRrgNZu$QOEsx&-?noYC|tg>rl!7Y!CM{2vS znDH4+s`F>-Cx}8>Exz>mKtuFKN;cm1JnR^V5(6c{Fmk{#&(fWO$rqy5mGa)WN}?Ef z#flSD{2HcfKl%7aHcqa@jnivGqBj&3@U|>_3$*veA+d5CO&VIxQk?qs! zIWq35L$=s~NfvXZS%2{QBwrG-8eoM4!y0`~Vo&59^xON9@>3VAp{RY{(3B6PHQj?^ zBlON6L00pkSrGmFWItuL zeiF3m8N>Cv)K~o6H{oYTb~m3sy^mW~LxY(l=@@1$Ob#icBHYh?7rIju6O$)fR>Zxn zCzt?;kGnT5gP6+4eOpUc*Pq|O3vVgPKgG7!i? zSqUu9w?M*5efnxg3P4B>%1W@XPXIRh9bfJ8yJvyiviylTvVXrHVR;ydiBlhsnHMf` zJ-AuOoT2F#fn#A42q^T^1X9gz2Yg0UJVYB!HiFuJ|G2Hi7Jkmpprr)-f}u3BsA9WO zeT>{+i8O_x@8*!G9Y#XQ?uDO+zI12B81V}W`ywfGYInj*t#Ic1_S-e!4Qes92X`SD zt%{(oxLt$2cegRk2BSLIJ`h9e+chcB5CEn&G0GpS;BCYs(qc>VOyWQAMQQ0h05J+4 zS9;3m30Wv7oJlSJOKZ|RQ)`|3#e0M9J>h=IpHIt{T7eJ7_qH-MX6_wFn}I*^OMiRk zQZScN(mXwujpO$3l{=ddinB;YhUy1e-Eljv_>=?jRVyd%@0p+qTXujm!qn7R7ngiJ z%;M{WpsZ5Yer-<;NTJ+WqRuRk53v|>`+@47h=K$nc5m-?2E=kEPCJVH2IhpCgJF{D z2{8s=Sb8F??A{(p1qK8HGTL7CqK4!sU#xK{qH;LJ&j(0WLV_KZ)#lZOlwFxISC02+T~B#&OA1GzfIkrfC6 zeZ{xjzHlRyCVYtz5fL>+pA^XqjBQ`u^(pG2iWhoc%(ESgBr6Y1fbe)s-AlkoS_P)X z1selVpJ@?nCOZe?OJ8)#HR%~?W5E;^WS8_2>~WICmb7X_{p)mq5} zDrzIZfq{y;8IV@5a2mzW@2)slVzsG2353-@Y0MRE832;RKBEq6V~E>b3i69gW!SWZ%cU;MW*0?VXZ8*HG(Bg}^%X5+Rr6=B7wiZIG%oh@WR zwQMoT(%Skf-YkB_Y`f_P&2coJR{oF4O_{-q_otA9WLi_X)^*8?5QEYL8kGMQq6uDV*2~U! zX5JVON`3SG^ZbYNoL0m0uhO6+(7453^Pa}QZK)5}c5N_}>)-g2lL~C_%yLY-G+J5& zp#akL|0&16$AcgTdN^8&~}OclyE$Q4;){mzrDKt-8&Mtgf@Fv7|2`~y-02=L(nb~3vyn^5Y-zoTEXdQ(giajT z$WHwCbcR7fl8rI-1A$~4PBPM#j!lAQ21gqV!k(+1ZvxVp>(h(|^gVtA4!9n~o-Ao6 z-heViK25i;2suEen-=Wt?TsP6uT6@;+9X25Fuq67CdK|=@B`>>uHnj6tJ0u37+R8J zYZA`W3u@&IRJGuGX_Uo*4oI%Q5tPtrN?cI@RQfG>(_sgo<=OQq|7_eC2bl257P7WF zok~xa_lPX9c!{2(aBk%Al4C5=8RO!d!DlQ`tP=eKqIuJTEbR+;c43q?$(j{N&EIT; zm2fwgylQeV7|~zMq%Shv4xqgst3J|&aSxC06t{oGZzhLqitd%x)$VOO8S};ZRGCawF8jXPjnJpijWU;aKkfw=Vhrgg9b zdAKFxq?jz^cw8bPjbH7E*DqZE%1X>@pDml{uY3R14rog(fB}DkY77!v@B>?x9ot4? zn8Dzk2hfW^iS&fpLTVITX;WO9m%S*P$)A@OTjzsUy;;rut3=1s%0Yu+7BW8kX}l3| z8))3Ma+UD&bHKlWT7R#2fvdTCaUS*6(h{o9y1KLvG7=f->95>YV`0r{w1U3;X301SV;uv4LP=aTx)K>mL!JZ;7%RpH0cn^V$mY@R=ZmWiRzUjlQtp}rx!B*jRat}w_eB`B+<#j-TsGy5<0ey8wvpeBK&i%E%q{@xvrZ?M(Bx z#6g~E$q)j%^QDnP0!=$ijp!CI!*S9KCQ4r`j3|%@SY>e{;Aj>jQjc{{nXe9UuhDjx z88azhhS_v7vZPM8IM_szbZ-WZwO~CaP(WY`q%y&6MPVzHO12R1A(A~A=_bn!m3qPRjEDa zr^zPnrpq1m9-VHx9JHgO>O7}BLX*Jw6tvDYc!#*nMvx&$34`#cLU*gaM6Z%P1YEMf zjfg#Ylq(sM7&-h}qT`EWH{E$<V8^Q2?74q3i|e%b-s3NonbqfLPWRW6$5Mu6YYys8-!al4Ycm5rT-> zx6BfhKxX~7kg**YY&G5DKS0J@lI5T5YbW6ng=#&ry%Y8G>$2@ITBr?%!&MlZn6!c8 z6D91Sg9k59k#Tp7>1TBjq(jqO9t*Qlr^DU>m#84N<^H8$%&PJ3o`z%*=n^Mf0%Nc( zHfwGiff>~e8eb;%6WfvO^03*g3=su^w_1evf) ziOE`7r#F{|q?|$(lPC$o^ZXVvAt*bnk0)uXb?ya3#7!gc9@5f4O@}IrlJy<}amE++ zn#b|di$6ce@@()L-zTm@0p#)h%^Y1~SE-e)t*wd|0H!X9^#-do#u?vup_m!7elF>e z^ZtC>bB81B3BI?@<)2TkQ*C?4{C;^Qi}Bz>qSnqV(HbE z5R3ndpQHY#_jGx`^0Z-+p9O|j(!pd%tSeosvH8af8Uyd8kM7v8oE=4%2wn`s-w0M>uu;TYeJ~zva)@|#a*yqoB<%;lO1O~nN*22CeJ8hI@#ValY@|^ z%O#7>IRU`o(tJ0Qp5t*YSsoiA`M6%ff85*uKnRxG&p`gs3wVw-bSy41IH$-r`~ zDUni(Mx(=Y#KG1!YH7Y4{tat^LvJ}UIWh4ZnPqLUBRKW)wzj8E~((hqB=LM6jL-j=U8d(-(N;^fNh@z@I4j2AoMF~=!HU``W-p|$U+P)vcu1>$BSp* zV$i22zwssXa;Zi9SXl`lvI%Ms9_}yUu@@@$7?M9EBWu(+&P&@0$ojmof8d#bc`udc zf}|zF9jOdBX>QJSMqd6LyAPt}%_Qvc10j0quR4@NDg0x=J&baa(o4?^HH#Q2tQ^P& z+rL=`Fg6)$RwuUUX-Sm&3k-N;XE1SgRrhMvyY7v>V@dUK*=#^@F)VZ=NfLsv7WA>r_L}L+dpjg-HYS{lrQD5#lmnq z&mm0OWuVWx+^YiJUN!}@9JMhrVZLs|hQKO#IDdkY*P*X^=U6?`eTTB1$6j+~C}!3l4Z>D7vb3P;eOsIMbb|mr(qtT&MYhGW z6^;Cq7DQ35pJVQ(#TG+ajnK~H zHw&BtK+G5$VJH)FrK~%4BAmcVka0-ehymG1$c-xklb|O?9;jWvO*3$7i6}}R)B#-D z)u?sDF*4OO_6inrxWlMrRO232AD}A2ufk)dqP(0t3l`K{cI=QR?pQoZG}noP`LbBW z;OXh<%LPKqB_XSf3WnQQak7D2- zp2}V8{CNNmMG&k&TQSK~nP(WIL{Ups8ihyq8LF;rE*CMa@Sl~4Bd)vI&s>O_XMu5<7-6nU1;bCU zd%jBKs}Z%39F-+9&8>N9xmD}%sy96JrBPbXZE$A-FW#!E8;pAKESZ?2qW}%Jl7Q}} z5_OqcIiUsG*KGykrW3FulZF70D6l8+&XIlO9&usYPgE9E>?&Yo74#Qd_>*nLy zkSt;xS%GkDu6SEjk$r#N!aTxf^bh#<+Me%)yFcYO~S8pBYjX zNeRa)h9zz$Cqrrip|S##&l0bJLnL_0+Kuu@d*?>r4IwWQ1R{ep0}AK{CmHw|=bhBzH;k>#a$|A*i8hgAfTxk2cuARrYYi~iOKytvH!F=on7WY|$*jvo8#R$)n zxDT>|;5ni}C94U}m1@B<`zF+Cd(N4`oR8c`P$1^eX-QorVxO8upi zX1I!%j}LVN_!l8SfOe1eQp7|`3IVDMlbgvnQ3z0QD20OdIa4=qep5&u`dFH=`Ka1} z6?MorRzHk_F?*#!J2Juyc*$cj`jbwf%M;9%Vi^KP8Y(G)jyRO`;?~C_mi?DEjP1NjBgCJm zL+OrUa!Urm`my)7@88dN<)m7h=s3Mtv6qsIf`Kyt1zalsfB^RGWP1$Y4P>7QKpoE5 zQEUx!$_fH6{WDV1lZHA*QH-?M3CO1Dywp`OjRm{0+!S6iOjj!C%^48Apr>5joR^iJ%5V8oYXdoF#rgBmyk*ujUqM zLj;P>+coa@?lk~uGd3bVQ3ThxT?2o%FgzJ3qVd4LTer`XOl`d?3^)WejT%*9m%nQK%^J*>lAGO8-O=*Uhq!hFKqKCYS?qB6*?H7OL$Cz8O%32rxrSH^`It2I z&z^rL^HONq-!+lpLu+VN;fbVIKvkd#ftx1KVQWMPXJNR*)S&$`VN&$p`+yv(osw=k z0SmzgF0qm|iQaWk8TRP)y*Xb^rYH)dNc?PdE%VQrv2@C)Se5?x|OI@7_&(d;;^0WaEVThVbxk zYc%1`!q60zhKN|aVncRjqz`<=7YHj1~(U9zYA+7zq0xPMpm;`M&w%# z>&l(#+W7?qbOHyl@X6v+yvm-`LNe|G&3&UM+@>fY3V%|W@ySeZ=fC%}(r~T*3;Hy^ z)a;DSBz9r*uBcQdG299^B>~mcM+koJw04mR&yzQij<0lfd>=R;ElW2E8=`gDI!8eA z&<}dz%%l+=_mWXZl3oGW9qf#G38s*djQ8|}zj1zz2Z56L^&olGx~)P`ZAD6;y-M0_ zg!w@T(7>X@%?wb=e{GBYis@Ty25F0$B})jqwbBe_ugAxAjX<#bh1*1AisTyTguc_1VC|Wdskej59PBFI%t%PrEBu=qm`l?eYEDmhik)NAk#QEMh2QlaIHz35W?s53CJk4_jLS^ePRZ z1P*QIQ&`TNIg=qBwCuBJGOXyHy~O!j8vs2K*$WqtE)4E~m7Rlwwn-|tS?(3ue&{>NRYWn+5iA!H>+o=gYB*(-d2;*K{BYXOgh@)Qc+x>=^g(%7w%`O zYwkz1F1X_D+c_9SBQzZ-BUZ8!}oo6Swj;`#F{iHm(Ik|&^A;A@1y&YaPmQ( z)V4MO{>gh=DUEc=EXN?B>zzvAv51%>tl<3+%hE*ZjT_tcn`(%!QvM9@8osbwrkZ04 zVqf+$o0hxPbrlyDjB-Lza{XCx_d}*hCEfmwe<`$O(IYtR2jmaC%gSH4jeS;MFIJ}qI+@p0W_?6SPb8?ulpmb250hX>zs`xP>Px9w zlGA5etD_rN+*l<RuMaMkqt`k zH_&NtGzMbJ&plN0TZ`|*+Z{j{gGU-n>(6Uwn7<87G6TpWhpyEMZn@dpKYx< z;(*O*FH!Lq|JKNJNKvL7P%FX5E-8LtG2c9)X=a5+9b02xr*=)|X4F3(Y@Sin@j97n9anwXY##kP!(MRP)kZVjq$SW; zA<$T^QC{Wgy-q3Wpc4476CRCU=iHW+GzA>o@%Ucf)4tylHB)O>F8@XSDWyIR2rvAo zS>P+o%6iUfWM##>&_^xw9Xe8?0Ds*i~6sIk<2%LT~|o08{uy{rM*SVtC3m8d<~txMZGXgS#j


jJcFuny76u}^nwpvph0)BY=ToAhqQCG7sE6?5VEWS~918vE zt760Q*WOz_*+(4ml&-efew&)>re=aDi^2H?&!TD1S2cZSoY(u5ZeHy1Q<6VYQuL>? z=);M~T54N1fH> zX#ck{i4dNZ@d0Eb7Q~ZgVJs5R+A!==GntMfktyKPa02 zMKARK@pY*Gy>CxL{V%?r|8Fk?^iTi4+}Ho7pM(0}`}Ujh{Ed?&Q9~mIiAvN`y?d=FXm`3zj^Fk=eut&9Sgn~+OSpMDDCzI z3jWJc!mNOM`pxvb8_K!zfuqoYFsxtgnJF`)t)cMpW1siCgoN*UIa@VH1+i*hZM?rw$MK4990s3F|=y=vR`xaePf4%UtB)O=T@Zu z$E_%#ZFFP=s`-y=CRk%^eJ6FlCV#GWUU5U}u(#(wn&Its7RB+V_Q&UsDD3saQY=>J#2S!G=()&V#T=wTr z{wp1U83+rNY}!)GZTm9$HT!4=&t=eirXJ(w9gobVo zt>TdU^KIk)FJhbiDf{r@&a}%>tkLyXIyxi0V?!yo&A`B+Ay=kXT>r@beEZMp+vFOD zhKAZg^Oum4QZ=xEYc@DI_+i+As>Dabc8K0T%za^Q_HYVOXniT2ml9i8s5k$^UYvca zXZgZHAymkxu3o)bmwkZ6`+L)nik_YT)N4HNwwi49mR0I?;@f(rq-I2-?aP-y(8g!@ zw)z2Ted??MkB>b^BVIi7X=!LsZ5+M1?dGv#_~t6CdGMSa_3WRdCLPEf(%|C&0Ui6! z=gE_86LwZsNeO-2{QLo@_OiXuFT&kNW5FmP($e03P7-r^5f#^zsSR5C`UiFfuC7j1>TSpp%phva+klJJ! zFg9kJ@Zv=f+$8eFb3NE`Ffm6euCyMG4?6=<2vk6+x%)tke|EN*#idI%&UqQ_*KT^= zd9!kt7tUML`-4Z13Sc&sW@)jrcvqB^+#R^v1sd&1gZmIF$zsDaa@z;y%x7n3tM>{y0hvsY?;9K%@`Ghl zl%!JR%)Fb^Svp)GdQoUsp(r-cr;BbMRPPKD~p|tjgF4)?D_NOe^f~@vih7{W$132 z(GruNuTxP$Rg8sLHr3a&!BLyOs8bM)tLFBwI`ebOZ{7%*jS>~Xo1R@gs;#Zf?Xw?` zi0$ReFpGm0-WH9v>RhP>Id-(}XBVnQrz*dE2~SQ=E`vmQA1jmMnY|3YzkXern8&z= zZ)&Q5YS?Zlp5)%z?qxXS$NeRD$AKElPHL3^!}858Le9?4J&;!g1_c%4g{G%p!AeRW zOoM`??1>Y%5AN9TYsMu#JDUSlSk+wD9v1KL(_tIq8Z0cgBc#y!x3;!2NNw8lqB%)6 z3M(P^{;9f{a|Vww`8b1viQ`jKp@S9^bMrD*wcAWA|NYQ?1wFmO7ato67XltDqjQvM zG5+#bm;1`w$I%}90$RCDwfr`B>-ifQzIxYs`?DdRGZ1t3ZUL1h=NkkZV1%-07^7~mMCJ|eI{uCNA z62umyHmcZAc*0pRDlM(X0T8ZALxbT?}M{!fP zEhZ^MFdPaGG|tj$k{osr3ssme+6H_Q$tYs%QtPib!w!`-Zj%`?-DfN;60q##7$W2! z41d+k>Yy@4*xZXJ8v#FPOpMyIXHVCJv&p4PO4-@j#?H>I*ksXg7OEf-59RHvV%Dy{ zot~f12d&v}fhDgw=yB9%{ZaB^;5{%~UAYD2V+(?1Wn@$7v7E=;r)6Td0fzt zJ1L2xE%k-A;pyl#mKO?12kaRjWsSXc2dm1}c=zmd^_j;><`Wc*lSmz05wFY@GZ<_< z2IFLps!1wnpJJTq>?}2FY-%ctOW%X9wC!H(=#L-qS_-*keHjO4k!RHm7#>I)U%e{Y zJ3PMUH`%8OF#pVJ1y|Ps@yULllwD`%Z%j@)s5Yz@!4d6p$Sdx(WlX;7DK`9OefRJ_ z-7}x9#gK6VLPA)O_O}LAnpoQVSDE@jmsp0iK9RSmdx?pOcAL|`yt=Zdcl7bnC zt!E>-TT6?l&Rit&?y%iiz~WJd++_2OS)dIOtgwAU!S zFQyQZ^&%FIVC&+e;bEJWFJHDMHSr+b$yKU{JdriZSIAa5G;g?j=Sf@~P?8kj%oRf2wgqW4`}`))_y?*tan7SvM4JH9#VP3eAR`&a1gnuN&6 z<78SANRRFO?A5EvN==@-d`e9yNJ`mg6aWN;3E`I#|rwnhQ z^5>joLlcQFQAYfc`m|E$Q>2`Xq|)K$HnWUZuj1Xres|R0qup??yM3y?x9h}p8~mrd z$CPQqmoKT<;w2z(8tR>jpXJoW95V^M{*!Ik*}m1r!xPyPh0S+YivL3$ZG#(ERGs

pF3=N|8q7S;JvclZfPjkv@)1^T*cIvI9sRtSTi$@p zR${sA+!v5Nv92GZqxVd>Cd9{Y!UL)ILOoya1vyYqQc`~VnCoK~E!!wOIop_-%Uz!yI5i=`7pp-&H`>&+6|Q@FZ6(LF!NlYw`RJeY@=;GR1~xV~$ML@uMSYKo zvHsI1he(z~>(;Ha+;XGvLPlCzq_e>6++49`R$>#k2rR)*A37bIoGj1SxE*WKa+!2O zDUbTvT7$$Owe38i31;fMf_u*PAJ{&BKNR0(-9(EOlnr6OMt?c#EDRMboRNMg7?a+i zC*5NvIrk)?@94pU%H9EY@2*y5`Y=17wyV|l&aN>l-q=%nqaGSLs+K)ykS&M0(y*-Wfg5Q`I z;NRn)6sAz_#VAtgPN${RnB6l%ZmfD+6zUCQ;Q$^exu3pMpg3fw@dC?lwupRp;N(^ zTPq&}U_7g)#tu?h_H&i~f}S58feBETE>3fNG?g+8iqcR=5&p zu_-OSs0eFpa&1RWE@vTi$H7rjckpm?m$&{4Bz5h3g?o4Jo(-SIxoqU3E9#8+JxFI} za*evCZgcJW^}NPUpH2%g%X2kq;3HsPDT8NmV`h+H{fjq7*_$FhwfS01$8AmgY@K~; z6^HMsy^$yTGXoip*v#rRN==;}9EuO#mdk)fc3KTQTJ6tDu87_fqNcHI+rqwE9bU)k zQ#$_0&bQkrvt?5^J~vOyJnRcE@mO10P!=lD@7ph4Q@kn1wdHhhH5%?L)s)+S33?%? z3j&Q;4%GWx?W?r3-LMgS1dcG~R!B+0Dn>>|xlzAD^`fMtq4ueN&9*P|moqYo=9$&< zYEBU4K$ph8V*{s4MAlt%JGJb4*k7$+Qbq=#_JbyZf{% z>dsZ%=aUpFQ5bvgU}ZI3e+Kb(^U+;4dt1@zpejBjA%VTQEPy}M8eF6wzSs{TU*ME^ zF@^=-G~^cQEF2Q_A|7foH?w#y3hY<+f}tE%^-z>h9)o7WOGz+q4gKR0nk z7Xk;yte~_J^_-7(hF@mI!p3KH3O_Z}*FWY-XYrO*t3|29;4y-BEPQVH z2P$qii#LZW2dXzzdbDE;B4T2RQr%D9)t|e049_L{N6}T&0}XL&Rh751uoyc!PD_{m zv_5|B>Q!{6oNb3%KHlF2yvO+S?3$4+D#Nf&ep4=yU4%a~VdV!*p7=6C)$vo_j^V;a=0J8}g$C4#LW1Y{s*7 z?507S`S-`^-b-!y-2n8cN!ui&MShjyYyfSw5q*W<^do)k-R6~19y`|La?;83@bVU; z72w+P7%_RRyHuHHoRB#u_KnB?AF4tY)gc#Mo()YQ^KQN)8Wzj22^PA9o+}DeY$XXJrqLx8;WGs;Uj{n!9Cs7M<0@6yuO2lAH?A zp(UzBRTb#!=>-D0V=Fz=ZFz#qE5%}Jf!m22<6#5&Sb!CISoPs*5jkZ8h1nVBR8)L3lV5#-aO3gaZl>D^?5(X@qWmXA4Ig10jEj`7VP1z@6nhb< zBnFn9E$FI6qv}jE*cBEtHTd8M6Se#qO5t1x_cF7x$^l*IV1W}@d1EK1L%oA6t)q#F zRHDEi|CfkrUPr!|uG5TT8NM9y@vhzMz(tfOZofl2WAb&;sCr?6qHBJJ^|%$C&As=# z0i+~O4+1eczI?N9w=WyM{bQuC%+V_ntW4+}kwX#FI;NzT*Wi-md^iW9=T^al^D=YisMW#zucj zgPfckPvjj`wZI|JFZUutCZxWH_}G0=?ef7La(45#-#&YN-`djhY{4pkc>B-|OiWAw z<_r*GI@-~{Qz7v#nn~A+ukSu@kGvE=G;mvhzl>gv(${}4AODzlKHHRc65(O<@<%Q` zc8m5m4FpKtYK3Mt03F(`WS7S^_i5){N#%k_HE;_y9y+gIzmCbvo0Aq*R~%y*cE|(L z`Q1LE!PzFa+DwT(qG^W+ShDU$zXt30p{c{jd1-;g0MP1xB^MPfN*{NUV6CCJh0w&R z%#qbns&1E1BBGlr2c|}_G?)eh;Q;O&^zh+^t2!F``ayt2?$9W%OHAiCbEOAIYrNho zYc!~`w?d<=6~GNT`lRFKAtw}V_3fS#(>3rN{A0X6KFh+Qq=?bEu}pJS z2FeXaiW3i~KR%S&Gba-h863H@j}msZPAHJT<*Wu*ZAGX2%ogkVFJA<3771u^d6`$I+4~*bUm(E zTmO)%o)Wvel|)5Kr?#fAIrcjcB2IUy1ic(Li$-)gF>^7rfk5@o?n%zdQq#>`b^EP9 zlfbMHTDh3@YsU+kczJo(o=6N+G^@7rJ`t%bwTDwXtv)?{-@xEt#lRs1cLsqjaiDgE zH~2ru^rDG-cb$*TlJSP$)&tdXVjgatr<={eH}0bV(2|A@^4X`c^o(rA73yjFq2HlK zbGp=huY{R7Za+|+=J-gdG3NrFXP@2;*|)Z}fhtfSa19!WkdTlbNC(-*s53WLBT1tq zjHc5R7&k^GS7MYZwlgs{mc!^+vLN%3efu7t>$gWsAi?UBnUhnAY1#(rC|UOYZWO_X z;h}IzU%h$f3Op#;j#&<&%3S_qVw~J7lO!iC+&ht>OptiNa)1Z9wMFAvuFe<~a*U2K zuM5pDT~aT)c5p|1dpqA>Xi2@1@fXmq{YMK6zuITlNzJy!+Jz%ev9SrgJ#acvFALY| zO0LdXN>h^?U^qVPyS3)fPG1lW0_o9E86D1vC{5@UwgmN)%sY27=5>S%l^*Fxe}|+z z_--Mub3Qe}_W*9LT!92Y5!Hfzd_v6?n{C3~IPhcvyH8x85Sjbl7z4!d7P7RlsS+2D z%Fh0D?zn0JXl(+|&SHyRkYK35Kbl;KHwuRk0DMt1RF02lBB7W6_>n9fUAI|5yG~!{ z3EefXRXcItpW}%@*9tpOkz=v+@&T3RYjgb1|7H-Q#W8yD3!`v@8=#KAE{p#Hwq*BDgT-lSwV zGBP4C8%9Avx`bbT%ea2EiJ_s?{34Wa&vSCr=NEyW=ex|DMPcXV?X4SZVhUb{_8{XSX6ri}EuW`zB~ZeTTTb93{eqy5cpiT6uk|1;n1Pngg*LTu>y-Isj1w z!bIvH!%$}>1_(aZ)DX%8u_<5R;W*v7jAg~&zD3SLN2&1|HS9=Rb2BF%jxo?tC`nLT zn^;<&#=^$X1~Dp3X8x{Wk(l?D+!mL9pW8EB9}@SuKcgt`n{qH?FE`p!;4?3}f=>OJi^DI7Bdc#+2V)b_yzbRdp4CJfroVqKfftrI6Q&Y(Y4!DhlKw_nqs3TXg9>xPtW%tOIA4* z7L<0&O()x?Wn@GTJ~#(YC6iPNy~*H&HmWCx5~EhDhd4?IG&D3=iktwvMY|d$4mLfi zV^9daY!B3gy(=3*|tIF`2&Cd!@Mdmo`uvU{(oViI#f| z^B8jfZhCb2;8USiX>F5_y|!{Fje+UT3*><%S2uRa0c+Ije29Lu_3EIB)CVP|ItlF+fs_Xf@{EX2aIHhs=g3X_`46j-17gp zp{`T#7VBtjt(a~dm(kB?5)y7pu&<*K6D4*FE$f-SH4Vp-!4C}}MuEu>-r2h09yvr| z8Yg9C1wKCZnq}0nM8W?0wH9Kvv60bu5=0~mO(Atv)sHQJm;of^+yLo2U$j>^0 zKgP4ppgi!{ch%_XRkZ?6bW7=IA-`SLAh}6agz>gm>nW@CZIrbb;6+)f8(;0kdm%I( zgNRdf)xWrZE}S3B#CEa;pll{g+H9_qt&qp zc@i^UrV4{5FOgxP)_^Kng`&=F?;G$`62cV47p4s!fp_-zfm#34so!S2At~Iv6t5rD zsQ1C_0g*>MA|Dbl76b$vPM058bkWx585yc5yIWlWVJkxE+%%gxnjXz@W22M-K(Hl-`3v#F@eU4XO^b;mDe?KtvZeU9|az` zvM7?ab~9;f0UN_HMJ4M97`Tbq*K}zb^0@!0fl5OI1HMSn`&+)~@bmHQ6`>_Wnm})8 z>J-}7{U(pb7Ur){{2rl3E}m7oUDE8^NT1Rl+Kc*_yV`=Ba>v zZ{A!+@J?-=YmSZwBi9^K2g~H`u-{IbUPbk2goG0tm<~b=oljER*_?dd>XVTl?jcw{ zTn%5WIZ7JM-x@;wgSfZ3q`rZ{an)gQ2@KWi4Pq>97-zdDTbN)4cCX!HlGh@$LD%ufAgw+4Aow|C9 zkC#_9;47sopx(NUU{5j6Z+M?=;+cj%jX|ISHJORIdH=cC(EB~Rg3aG|$UGE$NvmtU z9~dd{rp@Phc)*V%6cOB!(B$Yq0QWPx7*`_opb$^|s?_r;{zc(4Bv%D*S_L-W`(T1R ziw)(p!glX;{T!HpK6SQ+D*f2K{Y0pr&QHcXb@ArryNzDF&f6FbXMPxR;SKPT<vyDDk0kX)Kja=af z(Fl{@9NhxF73a-8T+V;3D8*%A>DAKG3c2#ZMZU3$Bn8^vcNy#@8l0Agwk1{yO$bO6{dX) zI6g^Pw#eGt#wLX{nXRoMEEZ?W3@)NMcV}f=JV00avG&jF*W$TYu)(r5zp(J4bL*qR zn;|wM<8s^74XD#HosO(5EaG+Jae$<-gX`nmLaxy7*6Pg>H9?z>vV?u-IW${$sQ9Ua z#(Ln7wsVs(~$$}NxdR^mC*4AN}sNf${f`Qc#+aX}D- zGpA6AwbB?|xNw}*b{LwC+#|cF8GfGgRvGo{>LWLv?-pJnV-UXx3r9Y@0IpRt?z0~D z6^V(7853eQC#M%v5kNqV2WRm23F1!HVxcIc2&?sJZq@DMPGda}fY9Yal&j*&cFD%3 z91J>I8aUW1)n^4S1P2V!Ql>f|0E=1y#Qtg#Esff%7gYfTL@Q)dpuK}b1>Dr$y_JNb z0vte-du+piKWBo0w20 za+R{*laST$CQbX?akV~LZ0jLn2(Vs+H3#D--|WvVD9D6_4D8*+%Ow(7vyUa&Argh)YQaRtyKe&9))oU$@98X6Pr5C~Dh_hJPK2?uB`iT=pa{v0s8(7mWw2(#p!IL{;7jI z9@?q%>+W(1?hu>re+>7RTZOR@?cVumMmnScsd#`1sLHs>gg8sb7E~Sv246qaT*}hw z#c(c3mGEmRACihg>_rh`chO! zH4uvXd0PMdhgV}N9C%#1&G(|7EsS^~D+pmn89K5bqob7wWV8917QQ7~`kYrlhE`uk zcSC?p);5q*Zwg~#K8$lccX5AzfpmG!DZp$GDe$A=+$S!cc&izs&Dc3zsU?|8p&o_y z1VizhaacEdEe8+Kldv#GfJnd|0*UVFkHm$HmLBX**mvj zh~hcGG(Rm=`>u4Z5?DUz;8Lqs>anwiS5mKezTPF3d*Qq%XS;AYn>-<75(QV|R8JfHix{+lQyFBK&5INt-0 zQLi|akd)*{CeD|*`d5+Pp&3EG`cQBak1w}pZtpB}uBExT@{7)42eYRPUx9!&M%34z z-L`%End@yB?|mA}g0Ct{F@ET^4RapV5XK2o#T?3&fTx%UHP+?H*fd__dvVo{{ff2{ z2g}E!ft%JuNUGC)^YEYra}Q-eFJNgv0Jk&y*k3e<+E#oeM_}Fa&HSYA2cHH! z&oE76FOFG;Sq+1w8RLGTPwyCpuUba4*x48W0)o?~FD+lhk?Uv;MJ{|e!87ye57|hf zC3EV!lBe*IlcAOeu-FkYj{vZSGq9eBNl8&aqn3C$$ntfy+>$zlA`-ph4euTUWV@rn zRpi|DC-(x?J?8pMXT~iEJ)4U3w2RRxAE(mB0QLd^TU@s%gXyoPe!XSinmy2=f`~x zvk!QRK>S3H{iGm144_Sl))g&sFZ_4ODSr|X5o9351(k#!_;Sty_14bJn#<5BkikAo zrstwkAZ??6P*C5NN4r>AD{v5@>3G`0a~Nket|ZBA_L#s_=!&ih;EJmUI7AJCL`lnVcVGdQJvH`3qJ|coL$SZ^dcfA&&dUgv=l58MaRh*Z~rtCHN-&^zydwLIPeIWY2}qGYbPcq3Jd)r zqoNSK*xCu(rDbFSSS*j!sVbl!Ky>BowfI)2f^u)cQWB03KIukLf}6I2l8Q=(!&;&l zX||l+RlPj|X%ab|k3nmh;vw;Lb(;(f7!c^qBucZ3fUN})yTJdX1TsM8W^J%6#45yZ z9mZFX#40lHLRlFlHGrWZ836c#IuuTMI=46#t*x!`Kh}Jb)m7-)iFvq$bNlPpVvy2y z!p-TM_N<3acLtkeh~flZiP*(|e2L73(;eph+Fh8(UUQUp)W!cu@_0YO{Pe=mLK_1x0 zI$ANHg&D1R@Buhx%=Vrb{xu*Prfh*gaGaLBBv`ejQ^7^|W=MTv)shW$l3NDS6gKoe z?9Ex&886nFC&THwHVjWSz9LciWFX=*msvLkBgvyF&J%wlamFB+f!|R-&%hsy&tk$< z6b2+JPtFpNBaLH%0vba1R1HT6~ zDDc}#P1c!>8+jR7k@Z6)sP5*vyE!HDR=6knfSH_a0wGF}0vxnXPd&8+Af>d&qK__m zrCGQND*&m3U|;|d%BP<%zgAg!TK25h)x!)p2$#?6Ji4XEg5l-!WF~h?{tyHchR^%f ziQT+NaAmNd&>}VDDfzA0>y2;>M4uc)1x@6`oTMaigqX#(+xsg^5m4feW7wVTaY^^`>{D!s0H@>$v*|Heb4b;Kx_*`VL=rQ5-^k z4aCCbOIlYYjWFX<3$wa1BC8S`?*-f2_wf31j0_FQsse>hwG{xJ%rIPb%edeCkzpbW zGip2+G`2IES?E7B-{+08+iRWKZjMOPUbzq!?H+jCUoh(ZV`x4`5zBtza) zf7K-0lwHSs=1Q9ydBSfXj)ICP!U#_ja#hcqqnpBYajG~(d&Cj{hvtp#YG6z zfj2;S);Bb~@DDDQuJ}qV==eZ;JnzuF&magx>*wOTOa?&5vasD2iK>p<%UyOaLrhD^ zP{`|rjn)u^a@9Hxggqpq_yj($Kr;35q9KFP(xFYv2Geh;7=MHt;+E?$qey8{b1fnLFk1e`BZCuBByVjqW)ZuJ6l7_r%+iSdTrmM)1ZHG> zx`Jw(RDz4i*O`qEP^;eiCNm*nL1g%LBcm9mFizhR18%6AzeZGgHz`>jbWw7jK0JA;VSs8ILc^rV%?u+(5>k?#7Zc06MO1>)8LU;PS z6sr3^{vO4zFity*(-FK;Ej1vRi;T3NVq=sJM2M(^oKpK9@+lYnM5xD7^S43B1D%6a z52-qjPX~2~m}*=?0sc~Qa1)@R4os_nxHvB?E7xg1cdS)o)?0_bz(AL`dn7TDNso)` zRe*Kr5VJ~i@;9sUmorgQVh|?`S~%n)T-m2E3U{Hs;~vm!jx=}?9R=o`Fl5MS3)~OE z2a3;8W1S!p#776{^&{x(rN~)SQ zW)-5)5K+}+WX*|tXmnv=UkP|HA{zn*PiGUj6>v|8Ca&jTgVa|L^*Z z^;iG?7vuha+ih+|7iQ;_y0VQsA=Uk1u|~S mA02Fq5t=cZ~!J3aH?f>R{@Ctc9k6~$NQNF|b_`d*9`sNG( From 87d5f69b819df11969263cf99f7cc2f80bea30da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 7 May 2024 13:43:53 +0800 Subject: [PATCH 027/125] decoding key --- .../fsmn_vad_streaming/demo.py | 4 +-- .../paraformer/demo.py | 10 ++------ funasr/auto/auto_model.py | 25 +++++++++---------- .../datasets/sense_voice_datasets/datasets.py | 2 +- funasr/models/sense_voice/model.py | 11 +++++--- funasr/utils/misc.py | 14 +++++++++++ 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/examples/industrial_data_pretraining/fsmn_vad_streaming/demo.py b/examples/industrial_data_pretraining/fsmn_vad_streaming/demo.py index 0f30a37c7..21ce0cba7 100644 --- a/examples/industrial_data_pretraining/fsmn_vad_streaming/demo.py +++ b/examples/industrial_data_pretraining/fsmn_vad_streaming/demo.py @@ -9,11 +9,9 @@ wav_file = "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audi model = AutoModel(model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch") -mm = model.model -for p in mm.parameters(): - print(f"{p.numel()}") res = model.generate(input=wav_file) print(res) + # [[beg1, end1], [beg2, end2], .., [begN, endN]] # beg/end: ms diff --git a/examples/industrial_data_pretraining/paraformer/demo.py b/examples/industrial_data_pretraining/paraformer/demo.py index f6f4c7530..eb7e72f74 100644 --- a/examples/industrial_data_pretraining/paraformer/demo.py +++ b/examples/industrial_data_pretraining/paraformer/demo.py @@ -14,14 +14,8 @@ model = AutoModel( ) res = model.generate( - input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav" -) -res = model.generate( - input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav" -) - -res = model.generate( - input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav" + input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav", + cache={}, ) print(res) diff --git a/funasr/auto/auto_model.py b/funasr/auto/auto_model.py index 32fd5604f..e77f04ffc 100644 --- a/funasr/auto/auto_model.py +++ b/funasr/auto/auto_model.py @@ -26,6 +26,7 @@ from funasr.utils.load_utils import load_audio_text_image_video from funasr.train_utils.set_all_random_seed import set_all_random_seed from funasr.train_utils.load_pretrained_model import load_pretrained_model from funasr.utils import export_utils +from funasr.utils import misc try: from funasr.models.campplus.utils import sv_chunk, postprocess, distribute_spk @@ -35,14 +36,7 @@ except: def prepare_data_iterator(data_in, input_len=None, data_type=None, key=None): - """ - - :param input: - :param input_len: - :param data_type: - :param frontend: - :return: - """ + """ """ data_list = [] key_list = [] filelist = [".scp", ".txt", ".json", ".jsonl", ".text"] @@ -73,7 +67,8 @@ def prepare_data_iterator(data_in, input_len=None, data_type=None, key=None): key_list.append(key) else: if key is None: - key = "rand_key_" + "".join(random.choice(chars) for _ in range(13)) + # key = "rand_key_" + "".join(random.choice(chars) for _ in range(13)) + key = misc.extract_filename_without_extension(data_in) data_list = [data_in] key_list = [key] elif isinstance(data_in, (list, tuple)): @@ -90,10 +85,14 @@ def prepare_data_iterator(data_in, input_len=None, data_type=None, key=None): else: # [audio sample point, fbank, text] data_list = data_in - key_list = [ - "rand_key_" + "".join(random.choice(chars) for _ in range(13)) - for _ in range(len(data_in)) - ] + key_list = [] + for data_i in data_in: + if isinstance(data_i, str) and os.path.exists(data_i): + key = misc.extract_filename_without_extension(data_i) + else: + key = "rand_key_" + "".join(random.choice(chars) for _ in range(13)) + key_list.append(key) + else: # raw text; audio sample point, fbank; bytes if isinstance(data_in, bytes): # audio bytes data_in = load_bytes(data_in) diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index 5d80956b1..ee2f13dca 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -112,7 +112,7 @@ class SenseVoiceDataset(torch.utils.data.Dataset): eos = self.tokenizer.encode(self.eos, allowed_special="all") # [eos] - ids = prompt_ids + target_ids + eos + ids = prompt_ids + target_ids + eos # [sos, task, lid, text, eos] ids_lengths = len(ids) text = torch.tensor(ids, dtype=torch.int64) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index d5e4130db..bcaaca305 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -378,14 +378,19 @@ class SenseVoiceRWKV(nn.Module): stats = {} # 1. Forward decoder + # ys_pad: [sos, task, lid, text, eos] decoder_out = self.model.decoder( x=ys_pad, xa=encoder_out, hlens=encoder_out_lens, ys_in_lens=ys_pad_lens ) # 2. Compute attention loss - mask = torch.ones_like(ys_pad) * (-1) - ys_pad_mask = (ys_pad * target_mask + mask * (1 - target_mask)).to(torch.int64) - ys_pad_mask[ys_pad_mask == 0] = -1 + mask = torch.ones_like(ys_pad) * (-1) # [sos, task, lid, text, eos]: [-1, -1, -1, -1] + ys_pad_mask = (ys_pad * target_mask + mask * (1 - target_mask)).to( + torch.int64 + ) # [sos, task, lid, text, eos]: [0, 0, 1, 1, 1] + [-1, -1, 0, 0, 0] + ys_pad_mask[ys_pad_mask == 0] = -1 # [-1, -1, lid, text, eos] + # decoder_out: [sos, task, lid, text] + # ys_pad_mask: [-1, lid, text, eos] loss_att = self.criterion_att(decoder_out[:, :-1, :], ys_pad_mask[:, 1:]) with torch.no_grad(): diff --git a/funasr/utils/misc.py b/funasr/utils/misc.py index 5eaa4f871..9f01955fa 100644 --- a/funasr/utils/misc.py +++ b/funasr/utils/misc.py @@ -78,3 +78,17 @@ def prepare_model_dir(**kwargs): # config_json = os.path.join(model_path, "configuration.json") # if os.path.exists(config_json): # shutil.copy(config_json, os.path.join(kwargs.get("output_dir", "./"), "configuration.json")) + + +def extract_filename_without_extension(file_path): + """ + 从给定的文件路径中提取文件名(不包含路径和扩展名) + :param file_path: 完整的文件路径 + :return: 文件名(不含路径和扩展名) + """ + # 首先,使用os.path.basename获取路径中的文件名部分(含扩展名) + filename_with_extension = os.path.basename(file_path) + # 然后,使用os.path.splitext分离文件名和扩展名 + filename, extension = os.path.splitext(filename_with_extension) + # 返回不包含扩展名的文件名 + return filename From 78ff06a45cafdb7c093613cf7ed5c4a4cc26eda9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 7 May 2024 14:22:05 +0800 Subject: [PATCH 028/125] decoding key --- funasr/models/sense_voice/model.py | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index bcaaca305..8198706b7 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -802,6 +802,14 @@ class SenseVoiceFSMN(nn.Module): data_type=kwargs.get("data_type", "sound"), tokenizer=tokenizer, ) + + if len(kwargs.get("data_type", [])) > 1: + audio_sample_list, text_token_int_list = audio_sample_list + text_token_int = text_token_int_list[0] + text_token_int = tokenizer.encode(text_token_int) + else: + text_token_int = None + time2 = time.perf_counter() meta_data["load_data"] = f"{time2 - time1:0.3f}" speech, speech_lengths = extract_fbank( @@ -837,6 +845,35 @@ class SenseVoiceFSMN(nn.Module): speech[None, :, :].permute(0, 2, 1), speech_lengths ) + if text_token_int is not None: + i = 1 + results = [] + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"1best_recog"] + + # 1. Forward decoder + ys_pad = torch.tensor(text_token_int, dtype=torch.int64).to(kwargs["device"])[None, :] + ys_pad_lens = torch.tensor([len(text_token_int)], dtype=torch.int64).to( + kwargs["device"] + )[None, :] + decoder_out = self.model.decoder( + x=ys_pad, xa=encoder_out, hlens=encoder_out_lens, ys_in_lens=ys_pad_lens + ) + + token_int = decoder_out.argmax(-1)[0, :].tolist() + text = tokenizer.decode(token_int) + + result_i = {"key": key[i], "text": text} + results.append(result_i) + + if ibest_writer is not None: + # ibest_writer["token"][key[i]] = " ".join(token) + ibest_writer["text"][key[i]] = text + return results, meta_data + # c. Passed the encoder result and the beam search nbest_hyps = self.beam_search( x=encoder_out[0], From fb0da9f849a5d3bd473dcdbaf6197c6a5ff24a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 7 May 2024 15:53:26 +0800 Subject: [PATCH 029/125] decoding key --- funasr/models/sense_voice/decoder.py | 2 +- funasr/models/sense_voice/model.py | 7 ++++--- funasr/models/sense_voice/whisper_lib/decoding.py | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index dd00ca869..3c62072e5 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -472,7 +472,7 @@ class ResidualAttentionBlockFSMN(nn.Module): is_pad_mask = kwargs.get("is_pad_mask", False) is_pad_memory_mask = kwargs.get("is_pad_memory_mask", False) - fsmn_cache = cache[layer]["fsmn_cache"] if len(cache) > 0 or cache is None else None + fsmn_cache = cache[layer]["fsmn_cache"] if cache is not None and len(cache) > 0 else None # if fsmn_cache is not None: # x = x[:, -1:] att_res, fsmn_cache = self.attn(self.attn_ln(x), mask=None, cache=fsmn_cache) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 8198706b7..dcf18fd88 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -806,7 +806,6 @@ class SenseVoiceFSMN(nn.Module): if len(kwargs.get("data_type", [])) > 1: audio_sample_list, text_token_int_list = audio_sample_list text_token_int = text_token_int_list[0] - text_token_int = tokenizer.encode(text_token_int) else: text_token_int = None @@ -846,7 +845,7 @@ class SenseVoiceFSMN(nn.Module): ) if text_token_int is not None: - i = 1 + i = 0 results = [] ibest_writer = None if kwargs.get("output_dir") is not None: @@ -855,7 +854,9 @@ class SenseVoiceFSMN(nn.Module): ibest_writer = self.writer[f"1best_recog"] # 1. Forward decoder - ys_pad = torch.tensor(text_token_int, dtype=torch.int64).to(kwargs["device"])[None, :] + ys_pad = torch.tensor(sos_int + text_token_int, dtype=torch.int64).to(kwargs["device"])[ + None, : + ] ys_pad_lens = torch.tensor([len(text_token_int)], dtype=torch.int64).to( kwargs["device"] )[None, :] diff --git a/funasr/models/sense_voice/whisper_lib/decoding.py b/funasr/models/sense_voice/whisper_lib/decoding.py index 382a180ae..609d6a607 100644 --- a/funasr/models/sense_voice/whisper_lib/decoding.py +++ b/funasr/models/sense_voice/whisper_lib/decoding.py @@ -62,8 +62,10 @@ def detect_language( else: x = x.to(mel.device) + # FIX(funasr): sense vocie + # logits = model.logits(x[:, :-1], mel)[:, -1] + logits = model.logits(x[:, :], mel)[:, -1] - logits = model.logits(x[:, :-1], mel)[:, -1] # collect detected languages; suppress all non-language tokens mask = torch.ones(logits.shape[-1], dtype=torch.bool) mask[list(tokenizer.all_language_tokens)] = False From 46e5beede954594983ccf01344793a76271f028f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 7 May 2024 22:12:05 +0800 Subject: [PATCH 030/125] decoding key --- funasr/auto/auto_model.py | 4 ++++ funasr/bin/export.py | 3 --- funasr/bin/inference.py | 3 --- funasr/models/sense_voice/model.py | 7 +++++-- funasr/models/sense_voice/search.py | 2 ++ 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/funasr/auto/auto_model.py b/funasr/auto/auto_model.py index e77f04ffc..577c328a6 100644 --- a/funasr/auto/auto_model.py +++ b/funasr/auto/auto_model.py @@ -107,6 +107,10 @@ def prepare_data_iterator(data_in, input_len=None, data_type=None, key=None): class AutoModel: def __init__(self, **kwargs): + + log_level = getattr(logging, kwargs.get("log_level", "INFO").upper()) + logging.basicConfig(level=log_level) + if not kwargs.get("disable_log", True): tables.print() diff --git a/funasr/bin/export.py b/funasr/bin/export.py index 6c9b49fd8..9d0140102 100644 --- a/funasr/bin/export.py +++ b/funasr/bin/export.py @@ -17,9 +17,6 @@ def main_hydra(cfg: DictConfig): return cfg_item kwargs = to_plain_list(cfg) - log_level = getattr(logging, kwargs.get("log_level", "INFO").upper()) - - logging.basicConfig(level=log_level) if kwargs.get("debug", False): import pdb diff --git a/funasr/bin/inference.py b/funasr/bin/inference.py index 2a1b6aaaa..39ee5c067 100644 --- a/funasr/bin/inference.py +++ b/funasr/bin/inference.py @@ -16,9 +16,6 @@ def main_hydra(cfg: DictConfig): return cfg_item kwargs = to_plain_list(cfg) - log_level = getattr(logging, kwargs.get("log_level", "INFO").upper()) - - logging.basicConfig(level=log_level) if kwargs.get("debug", False): import pdb diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index dcf18fd88..023063896 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -803,7 +803,10 @@ class SenseVoiceFSMN(nn.Module): tokenizer=tokenizer, ) - if len(kwargs.get("data_type", [])) > 1: + if ( + isinstance(kwargs.get("data_type", None), (list, tuple)) + and len(kwargs.get("data_type", [])) > 1 + ): audio_sample_list, text_token_int_list = audio_sample_list text_token_int = text_token_int_list[0] else: @@ -857,7 +860,7 @@ class SenseVoiceFSMN(nn.Module): ys_pad = torch.tensor(sos_int + text_token_int, dtype=torch.int64).to(kwargs["device"])[ None, : ] - ys_pad_lens = torch.tensor([len(text_token_int)], dtype=torch.int64).to( + ys_pad_lens = torch.tensor([len(sos_int + text_token_int)], dtype=torch.int64).to( kwargs["device"] )[None, :] decoder_out = self.model.decoder( diff --git a/funasr/models/sense_voice/search.py b/funasr/models/sense_voice/search.py index 98d02db9d..694e569ea 100644 --- a/funasr/models/sense_voice/search.py +++ b/funasr/models/sense_voice/search.py @@ -370,6 +370,8 @@ class BeamSearch(torch.nn.Module): # post process of one iteration running_hyps = self.post_process(i, maxlen, maxlenratio, best, ended_hyps) # end detection + # if len(ended_hyps) > 0: + # print(f"ended_hyps: {ended_hyps}") if maxlenratio == 0.0 and end_detect([h.asdict() for h in ended_hyps], i): logging.info(f"end detected at {i}") break From cfe577f16fef9fb5b0a48f07d4f9e232799cc9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 8 May 2024 00:03:52 +0800 Subject: [PATCH 031/125] decoding key --- funasr/models/sense_voice/decoder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 3c62072e5..03b753246 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -599,5 +599,6 @@ class SenseVoiceDecoderFSMN(nn.Module): def score(self, ys, state, x): """Score.""" ys_mask = subsequent_mask(len(ys), device=x.device).unsqueeze(0) - logp = self.forward(ys.unsqueeze(0), x.unsqueeze(0), cache=state) + logp = self.forward(ys.unsqueeze(0), x.unsqueeze(0), cache=None) + logp = torch.log_softmax(logp, dim=-1) return logp.squeeze(0)[-1, :], state From 9db60837f0acbb53a888481abc0440abd2f6f7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 8 May 2024 17:29:10 +0800 Subject: [PATCH 032/125] decoding key --- docs/images/wechat.png | Bin 188323 -> 161343 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/wechat.png b/docs/images/wechat.png index 2e2aa6bcb831180cebd9c0713a937d75758ea6c1..a0ee69308ea58f27eee7e93fc10d2793f28de09b 100644 GIT binary patch literal 161343 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%0AZQ>|JxSSg^ORC;hK79iw8-Rt_!V4>* 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 -p5e z&Fp~zlvzje?Y)>DCe5s=@TofD%X`9!de^szFJbKQE~PUAx9JF4C@_5P&+vy|9XQ9Q zdeDa14)ihN4M6pry6ci)pulgo#Gye0x~rdL1V(fGufPA`y+wxco(z_k;NF4nmWP&? z%UCn~7#RF$51NL3TQ3Frz^~#oIAdTq0k;qP;C9E;Xs$^}Q08{0o@)|z=loB?6*r+% zgSvWdP!wU9?{W9qgwNUXCcHq5836uvn#(2V3`p4m`lF<#mOyiloY>gRxJyNZ))Q98 zElXrqg`g=W@CZEkm(YAHYe5Fun2u8Q7E9v=YAX_fLK`}?(lL9AmRB1#CaM{M&(BVL z$JN9QE}wM(I{rB~L%@^pPlkOv7*Y8N7EdO8_$64RmE ziGQjqIIpl!hNbbWoW}8#hsJyg;RqZ=j_*q#jh54xF?a;Agr|;EHFg=rh}Fk!j_+2a zb^Cz>ksf+9K)5A24y&UMMkDqic2+fKPF_#8DXOWB9w$vNqFsTmc>DSb zXh+Ne4MBSK9A&N^1Iv%VOFmt^0)ZYGRTv3}=f!QmbTS6V=JYy$ z2N*r6G!t8ne}hvH(#Fa8VPi?893R6}7eK)&o|VkVJ=B($E-*n{eJQ+m+d;a6z{$Aa zKZ8lR9>b^nXxz}F{V^2db=Kzf&znx`qlA@a%O|i#!C}leb_EsNAX9+mbn41~n?c5%-a2qj27mLG#D!iY4u^@m}H}-xK6sf3D-+YgXb) zXxood;RjY<7WI`XlI9eV3=R;3mn>6fIrJ$-TC@ccF|zMe+`V?CFi$z>(Z1T5r`LBr zSow~wdVf)}0}fge?AAOG2d9v-;TZ{LXcs=O4K2(?S@FkP^PxTyvpuBU_+|l=3=qN-D{|gJH$t%f3fu* z@KpZ&|M*dTNC}m4lqiHyI--&pQnE!xGLw&)qnkbFS-pzhC1yUhjtMzwivF)Wr;(C$g@Io4KZfh8p=cL-h7K zCsm^wd#=3OpWy!)Qrro3v3{iXplr@F=nlC@I_AU%7FAC7dbuzjG98dh4T}f&H z(`G+cH8ecbsr-jo|IzF*xFR^)DRy6~;yWl%-~4t--ZEWl`1>{f4I$z0=uw$p%=|-S z+^ayCv=wV7s9cWOel#ts%=c`HZwkQkB#9yzkZ!h(7Hzw#?vebrVHYpYeRLlDJNEN)~ zu~1$9VCuYvBdQ2p&( z5tNXKd}r9#+iUTCu!M+iG2(4+tlE4L+T{ED`}Jp*fBtMj!c*L|L-Whg(WYDs{0SKi{IlkEJzHl|9L^D&3-)W3)Sqf8kzXiP1Au z>2ZH1x-z|!&%UZzc>==h8nkI~e*i71gW`4YLl*deEuQo3ZSa-8Jm}0^<-l3v3oI=W zVbZgkfkdi#elVhh$|iIEX%r~qyc-kY@zy?g^$DmBgSV?*x^m?T)2?00d-m*UG1);! zT~k;0hVQPy5s!QK?h$sO7Y)p;tV$@_k1Y4&0xck?Os0ejTgo6rh%EObBq<>?o_Wyx z_Nt-Nk8)cCe?g$MrrN0$Ep{%l6k8?PrRF0Q|HZ?OPcr;}2@zI%+icu;SO z1>sgd-Q@A~$W@I$zgKd67R9D+?QZI|+@v+Lc3#zZ zs3Q<~C*lU{?y6-QZB3Ge80^#1yxN09hQ{~|BSEL!_gs>aQD|^Z0QNmw`I>N1xf5md zJ`e7k_v?!1ZBU2q49Exs;uVK4DmHFJyIEaBW6R~v^xG{TK1@Vz0JJcy>Ev__e^O#h zqv+!UuJa_Gb0UbK6jS5$wZ-!Xjn){+3QgW1;7#u(78P9}e$rSM^D4535N7urIr27u zr#?s|H#fL|rN8Kwl(yf7ZG4^S7ejKLx1P$%)&Y(8-0}Oo!r8MSUDGfqz0NZ%(K&T$ zy|y!(q)TUiQa^z$=Y~8uc73!{OiOFO-kZVEKs@wrv9{$UsNY^07#_LYUAFBrY>)zn zDj?y~s^#~U0TzDXP{pG?vNz2=Mmo&(d06(i?0>WXPpQTQ9*ks2Y}vYX-|pS+DMc)%V1MPStE=VzNZAaMvap-^ zEAT~L;6YtmoHn~}-+o$8ZwC=AX2GqdG}MyguypkboU&%GHU|U-?h_Y}c&EB%?OJ8( zS(PYpg`wKeZx7WIPH#JQ>vw*+sMx#KR!yt^d{GRj#hA2v_a585kMV+gP#t;-+yEf) zYG8avqHq1qIDXOON^j0_qPCR!{Zsb3K?Qje>(NKZ^%fp=WxJ%@BCI-6>kA5@;0Zlo zkZ&>j2O7R+l$`IkeTKj}7Bfy+R>rf_(;vaNaq4Qp+;;5-1fES$2DT5IKY#M%2~ndp z!?sqw&Gb{*Jwg`=Xn8Q)P|>MZswdEIzIYoq=|(ZhedlIf5umlYk+Lo>`E8EFW~Wb` zO3#zPRlaJF&916C^^w(Se%z8tR-Nf18EkN%0rMqS2p8VZsWEwhNl>WgJbd`JkQdzc?K6Jc)7h8s~K%c84^Q?b1R%Cj!9%Ud@xAGj7SNxNagmeksG<5E8pot89c zJ`U`Q4iD$kkMiln0MK*M)lTbw`aKvW-6X zW|gLw81KNC1ZpMBjR-ZB(T%u%u)f8~Sd=DRLfdd^R_B()m5vgjhP-GRn;YbVROx%h z1%_mue^oxApKnehWq%tTi)0&1tDHC{D3P5g@lo**snU}Q`|y2(hUA;dTeCN9MwPU~ zhBI8LF0_1hGFMDBxYgAZRq;K6#ocr@bs3w}n%TCO2%G1%Fj z#C0i#!SU4%*{S>Yn>|TANM&;)wXi?eY32C2|La?w^ru;FxaLLco@qZf*U&a5xU>5M zxlnkmjnaR8b-XAMFS^Ip!z|4$k?N5BWppld(}X461l3^J>Zj$rFB4g}Zr%EN1lq;r zWn@2I-c!7Hy}fB1ot-xZXZ!ef7Z+)-PDwi-bz5trMn}ro{8$SXt*|!H zvdYSHk=_Q+Jw4Z@^l%*@Rr+ z><~D5G%V%7`3kwV8=+#B;WjIV3oXxzboJxjf-nuPWi<<(xtR7dKYts5s_e@P;FlEf& zadq1vO_z*{&kB{}V*A+e`m^7tNG4^4-BhHMgZjoCkp?}S$PB2pMKqYoUkub2{Dv$~ zsm9sSu^CL}FoYLs``H;8rGXDb$%|z4BburDQI5GTy|HqpV-pX9(jifSjmQJYlgZgU zrhXvZE+4Ld#7OCC{*Sv>i?5fq`PD~DMZ37V?&IO{_L&@r!ruQdvBb7ziwsP4322m( z4j7_ZnMES+;Z!~V4GE8fgF~Lp$2+4-OK6$Y5n#t3bBE&o!d4M@+Tea_+BQDTXMhUt zh8#GrCuFEQp`N6%*J-Byh_cCQZ6%;9^Yrj#jmwSD6SN@oE18J@{`px`O-61AJ~dDHimC(uY;YveH`Ai zORP^QAu;g-n79}{X5cbAj$PwLh4-W^$7zl)>q?(q)_$fFF#t0{dmG=gVBviLu~w30 zt(mNO?|^>JGX*we)>!zF?B>QmJSwxWu!Mj4fxaiO#Ar}YwQyzrTqXsXF1I5KU3S=m zj7uE{CdsH9!ryou5_OnlUHtjeChHqSfD@6alR#fQa4*ZV3Lml@su+zBom>JUl$QP(CDlGsYvhl7Y+^lP8X@ava6p zUJBBqE?Rjn6QwBeCs4w7Wqj?{h22fEzMhjCE#b`vOMutW{6)axeVY6XV(6RYJk!@a&n$( zPjLWccfaLWJCbnMv*R9~-7{z|%}}vqEM>mxd;4jhXhoo3;up`mcl9D^Fs29T?r@on z*F8n@kt-2RzeYwzgv}dRAH2@!g_gi#q$NSd4096>A(gvSj}6@V6PbObkB{jygxv`c z9>oYfG=V8uW`uTYQT(W>>MX-QjVMIfe1i$82=)Br_cUHnMO(DQ)wI`VH z;f|n_pe}E;kF|*EC^t&gPR0Y3p09_q3{TAPNfaf_wOn%6Q52ke9d9^ilP-8^F(8sg zhh{=IyTzaW>+Shg9v4gMe}j9cZjJYR(?f|+?b(#y!#}v_YH5#(Ar0iGyX`0qy-0dU zi=yCYCrVv2F`y5hU(nfL-3hPGa`y^8)k zQaUQ6Vs&E4{3riysfn$0E8oWb%;Ep~E2Kv68#Z3F!@EMZl2+a?S<)GX|L3}HgiOas zyz$^y8Z>YcUo5d(^UP33>OqVIiFNC0lGYBB)}8H4L&ZCpQ0d_+z(X43O)psU?Tmo#+QN~46RwShF3^Pa zmRrP{EQJg3WrM8X85x;7Z4<@^$@tAi_*3+wU-52mhV)Lj`uJU-Pp^lEEmHI3PM&-^ z@d1Tu2D(DCbGhOh>w%hy9#gBVmH%zWh-M zS>bOsv~PNLd|pL+A^Yk;0|zH(ZhHrA;cJ9^#YO!~3$Lg>N^r2-mMz5fd?2ptihom+ zTFMN@WtkY(lH9eh?_8WN`$JkD25|pkP;@LWciKIlDA#%2r{5}5z{$VC43%SUzjC^M zO}VZB&kSFAo&&4nmx&4GP(j19m;KR1oBt$o&65(e|bjg8IMCc1-RR8cZ-jM~3w zs5_(X#eo_g5AoHP(?yA~jD9Y&B&reJ5i zfNk`>Xm<-#ZAs{`uNUI?kNy4qyB2OPYt=sGAIP=$M#u8vSTq4YDm$Fe&$aVHH>&k* z@ zB@F_dhRbo^b!==7YCErHwC&r&%R1AI*E&SQP^T2=1UE^hL%*YU3L6rTdC{-w`wD)j zi!vZ2^yQaFt<(jcKsf0>oz$OShh`QQz9rY9v#sx+y^j0byOL)&bXs}zabRF+zsrnr zs*~nRoyP!yP6mprL>?XmKddeYRqVx?x|CR7tJldgXA5l}YMvOd96Po{!Gs5paVf>1U(P%)<^mlXW)ly#XtLpOaR=}!T2svi%Fc9LcuUQl65&DP5xY+>dp4QB3N3ghLG{LCMf`u>g4V3WXvg>T zYofO86L&M)YYm#BNZloFZ2wbc1TjqfV2>C-DkU&g(ZpsKBXOKtK=prh(Esmm@jo@g zsfvb{`uYdGeSLc`m>Nz_P97~OqM`oaPBUq2Ql~p+CTOABwDW{|#MiLO`b~-FNe|aw zI^e#k`Y8Fq!-vmN*wS`&c0imVjr{%AVMpHW=u1=#y`^Pgne7_~4`>ghqL7V-IsPB# zMB^;H-1p(b>|+m81Q|&4?gSJNU~5AZ7hqZA0D7IOs*)Uq9)iGnz>1`pj{F!jMn099 zS%%Ho+WKYlA6VpAV#vsX2}ETQY|8}mTf9|UGHoym#l*9D3?_nrqM{--KiGFS);E5J z)O1UD5s<-F2%!Ty5C>Y{Ib4k)KiGNXIY2_`7k>L;V7SYtohqRDeAej4pWh2o(?5P} z_HBmYCT7u591xex46vxDD4pWJs-X+B>dAhk_5@Yu;}RoY$6aum&yBWi^`*c*71se= zH4&iS`f}caf-wx4Kw_{9)m}}a{IgHQ@6xew2;aJJA--851GxL#c-I+Td6Xf3*$yGr zJl4L$Bi|BrzjW@dKZiaD~5*9|AR{ za@c9sBE|mo(3i={24LrUdczuL9hA1iJ|$~E z7l^n&Gc)r!xfV=hHFzjx6C?pY=kw>%jc#+#fu#D{ z&*tszof+-6q!1_$Nqr6G=F|tDw6+$&PL5FULtT=wL&ORl*r7)8QlwKQlb7e-J|ynr z&=06a!(P>5f95V<2O{3m6F{jzRX`BOIiu=uWMyMmM@*lbZ4_+V{ zU9kx=<2TNn9}@D%d#ySeY)or?_JpNJTn2|)ey zC2!>66#F$K$_7(%^14B@iMM+R;$da!xYZWo!papKstI^UN4?hU z;zhk}viIwaY;7qMNJ*Fa0oOfUxpnsJb^w<8S@{U7s40|qrB2R5a-acw#i$G6CqmB6 zoWgLD(6LOo{gb+;>QUJ#^Qc6qMK;#f-iPMMYQ6x%>lU9amoGkr8*}Dj24Y# zQUfz)ZGV0HHGic$S&P3u_4MaHHjpoB;HZVGZ~F{`n$}-_f-Dr`IMfa&HF1!Dhn|`N9q-{#%? z5o_g#>ebiJPk6Z>7WrXR$jKDEzdSamR;0go*4Sw*vc5vsbEgl;$)OVu3JV)n)7EW8 zRJh~ekx-6m;-yV^euHuwg6eX;t>Q}C$j=JDkADA&;(_Yiqn26Y5SAXtokwKALB=*uP zy?$IaKmfD(0zj}WkWOfs5>*H!3~9&Mhh@Pd5GK#-g=n1AfXdVrE}(O5f;&jdRM?`) z9mx`Z1Z3%qo?f`ssv>(aGYWg!ex)@T0wDP#QNbg?3*MO3Zcla0%3(=Q`7rjIg(U5B zellXs;Iq~8?C#y}cN#VpW6!;TH(JBC8{R4_ z2u*DRK*-!~d+f-ISC{xo`P1^>_Yn~C;eF9hpVr=`-&NC=hN7APsJST((Nc|h4pR-m z=)c!t49`>U%T#ueXxj;Sy#5L?+bZ)&fYPZ`M$OI5`nBdLKs!-FnQbve=zfVR6BFy9 z*&0U$!A;q|U$2Zn2B&@Q-~SLV!D2e@#cVKWVEC;uI!%}DVNJJdO5M}K_eH2iuRGSQ z9jyDeCfGZ(PxQN>1brBRm7s8%n7BM0?}LcGp?v+OO=chia*4|6wOOraG+k5NNrn+e zI?O!br9o+a7`$T~Ie+agheVv4nvHK1Fio_3c)&6g4i1h^Pyu`e64Ftq1~Z|Fr=7cm zb>G=v;H+rEDt5z9#G*->S02uZE)=N%))5c2(hSb?%A=ThF!~yb`0cE$0!(r6Be(Rt zx%KC_j3}9odLBf~sm9XB_ufPkCC>E6eWIjn@72XwI+WBh^21z3T zIaX*IJxvHC<$z(KfF`vyzm!xoUd5xy4OKs68PNe90KT^LQ)Bj=4;m9i1H&Af+hdjo z7WfJZ#N2)zMX=gf&e+%ggYkUFm4U+gIeXs0#LAV-xKdj#)UE_>Ve@@AJ3ZTPk0Hf# zLfzWe9QR8|g*fDdX4TS!2%7$d=ckRO7>t}(F>_XNY29&KA$pV9roxZ|JV&c;sJvco zYYW|~ohCILjUzBgsRWC6*wcf;d*9Dvw}4?oW6RJwnyvSw!BdfeUy#E+2wuG>CGuMjsZqyE|8d?SEX-N&Fzn@0K zyK&Mu_Lh@{VQ=ZWNmQC&z!_lN^gaR{QiI2#nNz0Z7>GMfP0b5a!tuotN<_W0W&u5- z9oPdiem*|C?#jNNQlfK%MYi9Pl*79Ek3kS3O#5L<>qMk)siJ}c!Lh2{xRG6OrrC3^ z2m8^^ju1bpeV0s))aWL)oE(d%&30+06hP|4)*SW4LOz47=v4!ArnVCsrr2x_FG5tG#jG{*%2hz{GL#*MtxpvIM0K1P z8ahG9&eZ(SxoIdV`Khs_@4t2H)()a&c+%OaGR-H>@AbBy{-V$xudsDHnaul2>P@=q@{Q-b zzN196!&*1jD9p(T+i#E`#xDp|z?DpFc-yRR=vZ{XEOR?z*vyl6h8WOk zq)`aw5993I`Q^cCi`jniRPgijqnn30&}M%RIxrKAdV5QRJAlj?fRZ1l7_wtF&Li%+!Sae-{%(;5QV;H3 zwmXj}VP{|JWxxR^VEiAtllSX)oBCl$dCpg`LBh+o`t$gFWvHmAhy(_uZE7Ke0GuEc zlJ62@e19p$-~K&?!JX`qwTZx6@T2CtIL1pwD&_-BD15nFm}6<7hxLSd z%`Y)vPxaGBuMIPTbpKcw-AIlDaPa}t|3qp{VQ{%N*(=&6?u2=yh~jMm{%}TXXG!_^ zU@o9E3iJ_@=TCpLK5o61g?RIlueQsSrI81hg*Es~H&*!>q5SS(Q_UgBZ z6VP3NsR=!J_HiIKKGRfS`hWMtOBYNwh!rT`6w1saaVLm?AX_oiCukWXt7>$I};}|v6&gBn-U3z=St{eZ+ z0t^lsrHTW2tkBTVz*i`Cr|NZWLCd6UhxwX2E;YygqfL*y4J)#Cpg5}9O5D!(!6y+{ zIzdqE8M1fmVGlG_Chexaw8@?1JoV+EXhjKRM!P&E2LP%qJyS3?-jjkyphi42@FOZ# z1ii*w`0f@SxvraAVXOFE2KEMYq+ZiEaWCV)7L!d0w!EeUWf+DWpR}SUs(IvT<{D06 zVa+9JM2x^N0BdS&KrHzOm`h3@9|lp{b%4T}zl&?sh8A)T~DM;TWimcHg(DSK_FQT6;o@8Q?R z)$=OKDk}7dZ?wU=c!)5Wp039N)k4mfmbS4;FE~T0MteCPxn{HI)Q9x~uR=4ky*UFV zeEw+&D&m$l7br4Ol|e zIj^#o>xr=C7EtRwVw)20@+(Eqs63woXzLz=dX|_vxB3!D)!YKs8c`9-r0+j|#Nf8# z^^c_0nMRvp)}mQN&g8J`4^#)~A#Nk|N(!9Fn=d0H3J~@d+kNCh>8>g%DT((g{)p@= ztp?qRC6LY>%tYdcIRtsZ7lt;ADb3SI$EtZ#58ARFwQOO>yZst3=)XSR`4~0i2`s_4 zm)MMQA3b737!tic)!)~jL^{faZ>3{|%{z<1I-gtQX*3I695KCsTLKjAyh{1r!3|r# z-43)|0n^r?$}rZ484bknin3?-)!{TXl8;`FOy5a_(U^fMGwlu8kSTU$JwcY z==0F*S+QxS8JMl5remxzMf3dY%41W+Fd4`3p0}!2^nR3iT+D`{CctSS5fK6+ z-v8#>^+Q1L`!5jCUybR~?1%u8p%oi!(pmSx@+k1KD`iI`lRT@Q-%`Ad*a>%lafF0~RAAWOH;*vq)6{Q=h%Z`yzKA$ZQO9X6%(hU!UI>JNmQmz-m;Gl-3 zS6{e*(9(np*EB`p8;XdHCLQxMZC~Nkk<`5?iULF{z=bngP&<8y7q5Cb6~JK4%L3<@w15DGTwG01zsX?nYeseq3`Ap=u`4l7c~%^kIw*yJ zOnUSZ@MTa?5SQk2aB~Fi@IdHw9cUP+eC6lPEjaJY=Kpfh}rCyH@N z|Aab9%23St^Q;kF16Ckro{Iyst2u~*B+gG@2G#*}ef@~F|%Aii~-ZbeL2k$)8P0nX3%iiRf!1tQG4c5g|$|I$qMu%gN69tLy05WIYL z15yg<*t5z&b{3EAA?=F(6I4r|M{Dn;bg+|1(wB%^K+3!j;ir3S_|r?|7X8%1h#aRC z{OOy!fTc+X(N?z)P|0e zg>(YE4eV%0B%8CVPt6)+i_DDn3$@#Yi(hv_kfD!R5ti^7LXfdE%n5M)fMXwUYr>`B zWnv8*4U}bG=nkQsrL7-$b?ykEAQGvmu#>$@M@;Nl9}M)z(9fU=-g?l0!}f z7?ZMrmUgr64@@#(DUfuWj#pcRYLS>jqsAfviYN}e5+HXeH*o^Owpx8gO2#=+TS?M+ z5fQA(=ia7{?w#?CZ2~KIIVjkSSnvdXGwMPN{8f$;?;3Z8Z1u3Hx`;UlFJX+A{m8nD zkgQms;!LiUCuk^|0qa+WMQ+yyi>cZc37s?=+(XL-nwm^N6qgH!ww;Ip`mct2P+tfc z+4a=x`$a{c0C`gC2R^j}yQpq*Yz%0zB_^gL-V8U(E;);jJ?m^aW8r&Q?V+U?D< z?$Wp}d2${Snr0k&k#Niq(b5w2aQG0#<);mFrfQK_5dwrkK-N#EpOu%V7P;E5e_ir~ z`Y^cC!&U1q5Y;&dV3q5I%X4FxHz$vXrPfDJ1POSb5M)uTd>|CVGf;lKJ0znrm;~w#aJiio$kNQC z)P#mQpz9A056>AK{h(Rv46guiWrSrYubPRsoU!Ok--D;vKkf|BJrQ(V@>fC|ACAKW zMqNnH&d`wr0)R&%Qr7zTIOo}adpIkOLfO;Kq9=PlX2%`!wZ-#~Ava1c3xJs5-Djw& zSq6CX0Fx=E;k?9zcP{zk$Em>fN2vLMeaVE6Gk}ai5=7t5D}Va5@2q6=eP}$^XO#~( z$30lmx=Z9vu){IpZi_?ANupH&k&*i~30ylJ@z^_-e4c3vZJ=6fk<(mMfhc$&O~%*tZtsFK|B9ALrLp(Q;qEf}K0rx}V7 z3Mx)Tm^esCRAR(Wv(Ml>utN+C43pF7w*`23DtYe?Q;6w_N=sO#aWWKQm`a?hDfokB z%)|0D!STo+EL{H~Ro+H?+PH~LT*ty(K~6wGK*@>CH+KEdGu{n5f!=6Qe0(r>x)Jk+)ak%wQrP>Z=^Q$)W*xQh4g-kwOTh2WqfDD+Q^jRC$oZ8F|p&=V^TY1XC8>}-Ou z`#8^f*gCA>!{H2!8N0tUhrOpUgCZ`+#u;9UI5I|wZGA`(>v3e1Ztp1=4r0kv8ZaLr zbqn_vS?zv%2M8dAiLIpcO#ttTWt4ar!nV|x_WlZKO}NIw;#gHx!sa*}%r<&)b{UHn%b~2RnObXrpu_ zTgTRucjto?@AE6MK0zKSR$qPb&*yTtc>Eh$3me`;fLt>Dk5gRbT-oCoiL4=ki7};R z5t5oW@#!BoY>g1Va|}x6b<$VUqpA`r=daCurj}@D$4ffy{QHuXU1jdS2cI4#O&Cc$ zM%Egss@#<0eUBn>z>xHe=##eFgIa z-)tR^|FZ^sE8FLD%n=@cFQ7Ff^G({J3Fx|a5t6Y}_ahVh!i1=AjR$*=vqs!A=q}Zz zW}a(_+8xT4eLke3$wX{iAid9)UdXLIZu=P~(>hDsx4~jku?hB?xo_-24vk1Cb46;= zi3jo1oKWwCy1+_95~b=tG&J_*->0Wd2%W5g-&E0`D6}yt+1|0db?D?>;f~>^fWv4Y zY(~=u$#h6quG|!?tO_*$xh6qqMa(W-s2W+f3;u=m8#iqDWVI0*v3d9=tpX~Eo*zt( zHXEjTjsr6a|FTEcYs0pj(c^M2A!M3YVLs~R?QMTmwkPY7xyEl4y)U7!(O+JRZ8r~8 zG_0&M)12WDnNHvF=g*(%7+@Jz28YJJnYpZuM*-4zmk-X9k;a)hT92XslF8><3*yV;e z-VFpd>NGnXqs!I~OH@1|uYEOhF55ao{j3ooa&2ykk$pAV0idTDqpQJ>C24pOBGJq# z1pg?An3Kb=f*KnpaO35Ev}mV5#ArYGflgpm>U%7j^BtgR;%qRLjKYR+5n?KI!m$B( zAN~SzCC+u3)?Gr$IvKHAl$y~%RMO2j$5_ksrjt_(;Af-xf&sVX2k<%-EQj!LfRl_z zDUV!?Ohrr?ZX+YGB*4>q;<_ZMiRZtY74S9x{sa*l@$Zkj29V9cb@Z%9rC|w+=dE!~ z1T+SE@U26h83y*m114{CLSF-dJ#H0gtE#R2Y^92-__VUJ$j;B`8hR<1dMTU)dKoIX zy0$1VPO+Gm5J-mLT^JcCl`L5JlY{8gG(wS-aBUpg&KPQucG1*lb__IRT}6)F&;|#; z*X>!To}Tc_qh}&eTfLqADWHT9KC9c(fJP>Fx$VbS!Y#8c*TJOwi>f}1BOSnomF)mR zp>)cf_VM#;ePig2&DF+393o=9lh5N6k&>(efS0wW88)^>0pS+zNkijLxcE}@=va?7 zjo-)teonnl@92~xl29}k{5qRq{fQs7AOFw^F+^B;OOld2R%9qhV z!VO<{8QrgB%{Ei84|xWLR1x71t_p1=1t4xBHyWU+J322?KtE;;}oRFYKuqnoX`S(&lmsAi#!(zzLVFlAwbj*+!@cRi0E0Y;?AP~ft!#hQxGF2}Cd!FmE9 z0>EVzBZY32u_orY2ep8xsIC<~&eO1l8bro1AO0qJ)uDIbzX9cM_05362?M!zXC3&P zQ|MJby1e{R@BycZjYnqRLv+~C0Sgl$o=aL~b>BN`rkt(km4|G_hR)t!@(l{E+b3!( zV6{AL!Yb*alOw)41J(TLSGAZGwqNh?tbtfvEy{k_{FQW*hDj>&$ERj<#D{GQs2(Z!k42_r zUVG;;v29fXhEB!HLo6qhEtDog=?+9@PL&(S5-D$J{_Af|Q~TMRUKVjiE3G*y_A(kO zu)i{O(lPfy^%eWM`6knqxtxBIyM3vI5=npKY9~wLi6ecQ{ojAes*mjXR~(M!2F+yz zvMUny#$Z}{`Vcn_cKBYQ50f#2U-#BPhZRP`@E$#?^McMF+#78@q4Gvew>M2fT)fKY z;QDeTbP!2x%^1Hu*GkhhqCi zk*KIBCUAe6>hw*wp0BNh)k?Y=j{y1A!hQ92SUihmsWuf&;CMNcCqxA%iuyeRK%? zse;(-4t_|7&`5!0%0#5J`KytFN*mhK?8^jq@y%Bq{pmcKB1HNl{Wm=bW%&?5)Qyykxfyqy@kspu1IAkRA;Taduevmkf+WJPWlH z-UHT2s8r(=*o1yf-TL!+vSYIE-KBt1;HjmUg;5tQi--3V<$!`8Wbm2508+_dPA(A6 zZ3RDc*y#uYcI7@kK1Kk`Aod^#HrT~FQX{!V4_4?P<>%Ph*xQ>T(ZzC${(=MQC9)Kd z&s6;f*g!ATtI6N?So-X6?cw{L*v1rOYH*n zqeL^ggaT4?1_?19io{F`(ZMgFF3}uohCOby@7>#r*PjTPZGa^u>FW>l#%kc)>na8( z2yf<-g5x1jLq^_kDg0Gace@&A4fUO~&yz=E;sh7=%Yid5Ns5_wL62zbqymq8Fq& zsW5$ipHB(tX#(loLV%dzC$V9N3H9(!Q@}QFF!-K>&-vYPxmJ{Lgv!6Z;wO5?VN^-U zj@PF8BjL`DRW@xZaRlng;EjfttH)3o3qvd0CXRhF0zk8ai-sc>@I(`4X-__- z*{qJXlt5)Jnz|sF%>t@S$~MP!y+E-S-u4fvW)(79t(x352(A5p3aBsrPZ)~-0o!C( z&$BEa_8Qu1TZsnC*Kty^$L>WG)0Yux^2t*K>s66wl9Q8_KC zw-NjFNi1*jkuk9Lm%Cn<_m70^!$ZR$w0KYyft=OPdXpt~nIPP)9|GmI8_`YvUn`6LkF`{C9~}^rc~&WJaj)CJ?Fwn3VX5 zP?&)k?tx@oUEOi4sjpUzsJ;l_V|W?F&D1-^ZywYpI%*&I>(2+y6EzN2GO8(p{zVxX zNXE#qkCV8`D{a3Pg6?%*C^Dh9A|_1d6f*P9Xbyc!#Zzpp2JOReH65l2hF zR|*DIqPH<;lKnEW#~~5Rg{2&`*S9X5$?*9tar_Uc#s?@N&?L zrbbi$Lt0uzGFGvtL}dbds_VCWx>t{Z!$dIzqh)VFyOVm=`84|=Hy2k>na;Z#uTD6E z`v&F&82Pd~+rkz{xskpkkTfmJa&Oq=%0L2Y69UHK*!lbgQs~0d<(7$k%gx@{c+9CM zM~E5l+a7M-yxADC{U0?8Di}hak!-l_1jXr%4Q42uSjoFszaz<&qZCLZW+R|%=jh#z zxFJuu$v);d#kH(H2=YArg`wH4`$drO-Jj0sKs5BKh5eVM9021h8$Vb9;>dsy-V?wB zcb0_NPnZk^^i&Vvc&F+4m$sF5hrJF_Etplbgtxx?{`gXy#GLLe%xH1y zWFOA*Clx!cqDW?aj1z7V7<{L&lJ!*y#b<=Lr6R+G@rYAm<(w9^`736@uDO%Wc{e~& z6f>cO6Sz=a9e8M$-^j-=oBck1sa_QA*~Z;&*Y5P={q7`vrm0*QmC_(D@U z3=hBIAst;yY|{1GVV!?gKXCO`e|7%%nW+_q{(phpf4!)B5oU>sh%AHrzwZR@MQQbN zbKc8E^L%Lkn$Y3&qqsWockc9b(myDX=>lq?<2B~_2wa{ft(g9RGV-(m#N}rIGkTenm6bhu_s+R`3<2y6&=D__ zpvgcy0U_GLE5seXol;EIK-wSol>G}EXzRjRd;yNJF*~T~Z`Lir>^nCLlxwlk^5}IHm z0y>cFT0!E)kfBj|1_eosP&OkAi$Y0BiHsRS-Gy1qKB<62VINZ*9OLq7Czi_^8&z*Q zCsqJCLZ{53`5c-9Ce+L#{)Et&U`T4<1+N*tj@op!!Z zP`|lxT8~8GU2QDXJrv-FJADNQ2!8 zjzVZ=q$X{D3X}+Z=;p_xOw7#YQ`c&V0U+&}=Blt_p@_p#g$~>llsaV?m)x+8^VqTQ z6~v;yFc(o?Zi@r^G>+b!nL)}`F(^>lO>qFv{o zDEI+qYexx=qPQ)&-0jzolVf7ioS4ILp&vtxCPX3MJgcv7y~PwVmEIL%+Ht01S$Vnb z!Wg<+5zG5X`>UM4IH5KMtQW69=n;%jEq|$rgK}aV>yVp*YM^p;YQm~8dxl6~xy#^L zh$0R{(eTD7#gZm?&p@PsXT+v0f#hC`6kxo?6s6b55*V$9Nm%nW^0u7FCeCeI*A zs-wxSFLZ!W0=cqC(-bvC<(G5S?}&jtP(UVA2r?X>erUNLdb(kxwPXr@arW!mEBPzO z;CuPV&wP_`%4b`5#U6{se2Y!wgT>>{uusOohml~EDRQ+5Gfb%UK; z!gT{)Zc7u25O)mt{cA?GZ82Fp?SRX+a3Add5BQ(fH)lxCYVw6_aM_Rv$L}DN-}2f! z`|raNF&YSHjTl|6MVU3hy_C>HnaGySS42uSeTD5vk4Df;PILmVV(n8{KSS}V`p@atrnlSMFy8((z^~%3W|Qx@c~G1}K=7Bj9nX&h(gzmmi0RpN4%)yPkmdF>)(em+jWd z95d?qXG73*gtSisbZD{bdASh>%M5piqSkE$26A{h_%}P z=*e5dog!B8U4ddywu~SkBok$zIw(^3w?nXf2=dR$8FX-F-OdFz38x^kY4U`6nt?>z z&Y)v)&?9)G+LV!77+@!;0jt&*#)m6FDDv*#ubd@;$p>aaFvUDVD< zlKTxJU`;-KfmvwX)_&+V?fXde5LFR9Mf@+cuQ^wp$Sf??7>tpkaE?{{<|Dkn55Iqm ztoLhdUKG}ltXB5%;27zHJ53>`>ZK6G{c17)w>#Jf`7^Mq=L+YbMZJqH@_^qTAR`Do zF6C*W|vS-t?^AiT8{N9nx_ZA&`iouW#(!!wUO?#;W--%;;! z&j$jh>TzYmqNP#(NjDLPt>;-_BJRADR#2hk4#;1Y3K8<;lO%; zn2(p`^U*2_?feX%8SEYqzE~cvz}TwBZKX(Im>g0a??OPLP$wXo!}gDTSfp^d@*Sa` zhPA0CxDs@Qu9a0Xw7Q3dl;hnBt%@2l97ao&qBa z9}|&v_HuEZx_lo8G}ud-eVc4Wl@Dx%Uxd)r+D3;BME1KboR1@e&fdxgOKu~f>5L=C zo%G+nip^x(ewI(V{5T-sy@ZaP1K8-NvmSF$Lfyt}HCbN&7S-HED1@J^S_=UKD7^AM z)P=HsVeo68CC&kqrw|A_HVNinV79D~?+@sB4gr6RAs@O}_o$yOe{F+9B1S~jQ;WXJ zFmGgQ$ANY+c|mS9^+*f4fS^51g64vDo(z5bxCG&Sf9rOX5@zry>?LNE=%Rw~G?|_3 zdy2rK@T!&=Rz-kW(>F2wz|Vw`J^}8v4PBU>y#To6kZ+0DK}QFIPdJA$8R~TXiQ~PI zsFPM*Fj*4*>{1P|^z08JjMKWPq+7-R@`2;0W{ZP-bl~;!Gw}h7vg#}}4U#N*+m5ff zzveS^mKrlRK@@q}!`+^&?ng|$B1<^U9`rR_T>;$K9+jJo!X>%1q{!B6bE@`mXkK?bpv~8kJ-bwTriL#3UuL zHl1@wK-;sv0a;fx`GrTYz5J1c&HiIm(z8=>%~NeK_t=@h%| zA&SxHv4^>Q`;aZXdP$gob?le)PLe=un=45_*l+$q0J{^nSX7+t+>+Rull}C@i)+-p z=hl(NH-Tm~+RR#3wKq<}EL!~7bTw}dwY4{h;!*!Ym%aDv7DgofCaq2kA#E=??)MvN zP8*R<`f9KFR(8Bms6mu~ZXs(fUc(9s>HmDqx+kXvRdotUt7J1t;7*`r?(gV=WqSYE zQ8pSk?t&vN!&EZGj50KqcR92U&T^bTw!Y9^IEh1x@wnxk-CFB{xdb_Q2RE*vvb;^A zT_>abNKIzPNcG~%M}L>Dac=vmaitqK7F?pt**A$TjOQ*i)HT2w;@y65k0*Pi_m>kB z3PEzq%zMhn&F-{&dEMKjV*vVi${ISD`T1U6nSAIne~r7516!iUkqck zm;JWKQQdiqX!8zkPsTISYw=%&VGem$i@UUxBiGnCP}BnL9xhWfi=7 zwSRWBP4V-9xrtE9w;>0#4c>ePMej{OCb>1U<6VKvE+^MNrrIJy zXN8-GoySLgBvs(Wam8k_t2Dz0PihkDH_7(UNR5KKZ@UU(jCm`L=H4FL(o2&7=rZJDJ%f70lA#}Of*XG z4S|7ySp?y>9t1#`iGWTz3Es~v6IfEca}A+Ye0k~|EE%6*#ts|(`1!L3PK(p#Vi1jx zblriWCl#8Z=#Gq`<~d6MJ+TiSY&zqI&S2-W5VLRa>f(d1KF_vjf5`$=NQ+i+8tRBx=XY-O6QVhIYv$)cHDk zdR8mWkP<_qaNqsSgvMWsTN6eY5g?2(aGNH&p~QH1aFa9!8^`F!u+qX(c3n^eNO#x3hN9$GeHA9mtXD9?L-H6rL1)<^+v(v`2ViyhngqRQdskPiKCj2^5VCuDFe}lM z|2jaOnB4Hc{&d_^(~a3Q9eTT3p{Sdi_W`Q5)f7}$A#x8Lk_#{xp7;reVLO2Dm=>fS z?L*bVRzdPnzMC(_BOz+zD`K68qb|MBvSh|_{*NpnIc>2!?0I=>tef~W;vZc{+RS~Y z4kJ@M*vl}fE7YjO8drfNn#Cmd^!GnYE0wGbn6xJeJ+|}p7^}oUN5ku{wTyXkkrJ2x{Ez5A;ubH2B#9`*` z>&v=$J8_1;)aSK&jRdpW^M?jQ@m$GZw7o?hW^Y)D?V4-GQfUW;&H6DGk5x^YwI1$X zt|NO)Y^=t72y(!^3Zpyrls>b8~Z)vx!Tr zEDcG|d_6}KbHmO30bcH$PE0Bit*fg;P+*&eLq>M?-HeDhV6uZd7+0^RJ+DAj833EI z0TsAF5K4Rv(yV$S_(}JP_+`K^Y*+G<5I+{o4ddY}92go7^+~5rHZUx$Fo92?vSbju zmTfU7m9|{RK}1Bv5GB;{-{?+Fu+K)0!)}s~fC@{JkX4M2CfTF)RFg*@8rdJ`57G;5 z#M$Ys0zh=Xy1IJ&?uw=$oWItEr*k8m=3c#hTa4my!?R)mr_uH$KUHV$ulEE(d0RRN z4_hppczV2Oowx|1>^3zuWk`kjY_qijGYd3KCE@PCwtl#8!=sW9Tq;Q(A|m!|oxo@k zhngt%V`#_*RSy>x{bvEGxYt3t=(Mase~tv2^ML3ZVlCF5-mnDO??%pyH_Ac;b)(;cH0Re?Du4ZdNX?a$P3e7(=KAU&zY4 z&U2$Ps1El+Ra~}K{;vp$8xF6QQ))haVnt-m3zk^)R=evR8_+d?pdeQt!f>?%wLQ4EpnKDG`_QLZ*|n35?vC1<8bwN z3Q7u*_(z>N-*MSB>K$n>_^0Ccu;d7B+qM!ROJ*OH#q4Kg(Xv`+O<{~-29125&aSS^@`zBxfz|F2WY_zX zQ?XNQ;Rr~eOGC}lxiop_88#54CAw;r(C+eyiw7oZjQusG&Efi!*{0QLE}iwahG#OA8eABb>idd(X8VU*;)Jix>MC_B^_e(CIyv2QnhW0+ z=iKm1aqHE+(Q|&xT`H*24s7i?@}N!BC#1VA&%#x}>S-~PPH|;xOI_<=vecEl3o-xs z!85|&!kFv!OKOCv4n-@*PnaB9Q<(^JyZGwWzCEZ%!C`&7=|XN^&mDo{C5 z&pV*(u0OtWdP-_~M&#qMW<4tfjktM_h>fTLRrv3jDAju|R*wJshm!7FtXZd2$*}lM zK1%ReDNAa2XKHnM37MW99+a_koI;E{U!!I7v@X1Wy@lisHBh70j z;**z%V_;`r;v9odU0evdwyHCMid&=i}~7NwC*H9M?YVbng(a zRf1PEmS6Zb_1WiqD^cQlJ4BOrfaI5rkgkc9c=Dy^jWRCrEiR0RUFW&xY8pb$3vY>6&-d1)@!ppCoNf;G*gz0iMs)7psx%b~AXQ9^fz<`;_+A4ma5hcgY&BK#f&bD_1 z$HiU49%pA~6Uh0v7T#Jl2q$rZyu1mqeo&%+1nP-?(wIl0GP-g1u3qgow2ZgVC|xP~ z_2*}G=Gz@2;4yoe-@)uD0Tua)Dp2)U5pkNuf(^C!-F^y z0KCW@C#ChDjU$RJ7=K9S@78{UI77nak9`s+g!t}w`=p&7%;Ec#yw6~_{ZBPI3aCxa zlmr#X7Q?$zp5gh!D98Q=$YS=Few*oW3jd{X=#ci-AQUDOlappv)eyST;QKu8k8NV- zbQu-^dxAPjp$jc<1B3uaF(JAqp5H;&~ z6vX*h+>#BZh_8%z@Zbe|7q)IrPR>%>${nY&*xsb1uqF6$V^@rvokYd#+kHDE&|%2X|uevX?1~ktmH;L6q9{8%*&rHK^y#of`$yWzYj_rw#HsG^m*BAeLh{^6)sp zoVgVorF8O8XRUc8@4)YLl2xhP)6L>T9?Rw@jL1g4^XtK8deyz5I6K5`RUZqJk)qeI)<3n$H0H_8ng9Dph zyReHGA1_J#Jg?h4Hj~9mn|&G=C(z`7BjtFrY^vxtV<1$Iv7y(`9cEsR(%{957i<;E zViV4;4OeppgoC^VrmS%<5d!CTXNOo&NZZD5@LZjSUY29-kaq%Ezl&8I{_8faem0Hr zpGwaAM$I1yr3oqMHsZ5GQEt!~8XBg~^RT3GNY|+{FCSJFbby;EAF$B&tf)tijD7r~ zcoeU5B5zzs?g(@;@imEhJIXS-+#%~HBS`zN#Z3+ZAi|Pdg9e?oQQtk7QYBIt}8+Ty~{Zizh?SFmC9Cto~!&>~M@km=P15~CjEf`S=M<_V$vI~5H z7^ZfBnK3Q5JUsScnXp%wVwC*t@NnIMT{kzs?=B0CR=TxX?vc3y(+=d}_5F1Kr-KQ= zz?hzJMW#n`S692tP3qMSfxS9idYez~(JTnacFe4ep@Q{gLOojl8Zz%{GEQQ$3xnnF0*Tz-!W=(vVACc|(}0u*XFQ3FYsm9y0j z`STopM1PY4NQ#1GRYs*88g4>iLlsLsXJ)nnMGMQ=_rIsBhl%5>5 zvSCxI%m+vq!SQD)g>luY+6}Q-(3Mm`RWA=HVAXg5yEH4$|M+nYSynGO7iPaLyn>%j zgNl~j1DPi1z^rQDIXm^b@JO6?JN_H@H9fyq@H$ITIzH{6k`@sujUFk65qqU;a zJRudZ75NcrCr_S?&%#r{i1ou>7K=@;at_{`qc6vSZhr>o9zTBV+BF$?VpRvmz+ce7 zj75$UHz`R)@$DW1fB!fwOh9I2_PXMAh1Q$`K3 zU@LDGgqXB(1F=a}lHAazx{5+Vt2Rnmyg$}fR<;T`o#Krj)y_k%R5|no%wZH2;+zlM zu}A}wGbKQ4Le8yQEAS+rDBDKOK%$elxxFJHWf`1WfF z1@RKnG!kW&h~K=$@4gLJp{u+gKYxE0O+j3IE#`A%&@wVI+EI9%N%rHC!aTKX%p}5|BamGFK%-7Hxp&#fdFZlTJ$kZMxVglBmKX)!;d~|ZM!JEY0r@ngC?n{Ea zEDGs?Z3|yCGrNUuC_GIJxyZE;1Bx)gP9%@>Y7tyKI5*SFvkwrt=VCpK!&Z7=r}K>M zu**xs%oH_$vSEMC@19goF#h^JYjT6){e#%R?N`cOq({H~(W3ldG$1 z04KW8PSV<7(>=0Bc>`@7|@ew6rud zgYo%L&PI=8WJ_u@)3}Su+Tu?Xidx)dL#pql_2_GQgm?5@7mR=PiWwbrneH}pi=bBh z=Bqw_Yykb4>saKxcDu_v91;-tb(W|C8LInhmr>o-ccHPy4ne=cW(7>E>G1a`WZUPB zzuV0p(>4;IU1e9?iKd^ckHV2NE5+x*;Vht%5^_QPB-cZReQBZEt}&uI&3WE4&ukWU zPXD~!I{9=;YGkJ3rM=U=*{kdL3S}0b(Sr`_cE|Zqv%Ix7;iv0MTU+!3CU^heKd(K@ zs^rf?>cZemSDlz*roW0c0;i0R$9X zL@ibLuPnq9xU(c|YKJtcT3yq*kNT7({pN1)F4bGbhcU$~rI=s%bDp$%X;cmhMuZB+#wM%Vyw~fb4ODlQj z^YN*KkfP}4Pi4w!7sHH8`?nOMJjo~r@X&>|ekQpBk9+2LKdQHF0s`#e)s>Zn&b-Bo*IaLVrNb;VMN0wAoBE@b?mW`r-GW%*6 z!z*v^hH4g>eQ1NuRFn8iLs^u?ycZFy&C&%s8alukMZ>qak$4^DBvo8ov+*rF5(OmHUL**uDCv*1 z`~g}#fZ9^eAH^c=`0?Xf{&>XO7ips|#HiIjI}9ounqQkD83Y8X`J={;1;%-Wz(zTa zlh4)sfA&>h>1iJs2|{OF>y1SEDs~d-8xaw)z3D=0PV)Ti- z5OKv)1qIcE9Wm3o12-meDgg12q?7CW z{?zy|SEZkik4a$kAUAxC-cUYD>Nqu`hj`uf_lN%Q;bwxu;hD>Vl9D%=$4M}UH^#hx0Ppa4sNEpIZ8uT|c{52_FTTlg{4_K_X-e*itgKm7YgZU6A-b(;%6 z=c4V=XhDMCIw*#pUfNZB5oOjTly9{|IAH0%X4^IWZbj-vJG%cEDy$(S`xZV{>pU!) z^^2vW!k#@FiFSgGI7;Le=Flri!0A#uo|KdXgZf^H+&gR-z2pg*bL|kZ&2thYtPl2; zWgs(I0;rG`FABZ`i@O0HN?hsHs2u|MO0>_uJw#Rg3z|=rbQ1h|9SRIoX%Nq}LQN=D zjHCH6u5PPr3QfTX*WrEnq1jJ@va%bH(D8vS_6e>cuF*31NZ7w#Xn%i0!hW=UXK881 z92B`^3|8$BAr?07I(Jkw2rKIY)~ZVSMhGGi&tcqm1qhnQBGQaPmp2E{cdIN{D5#YJ zq~)okBURZ8zK%Ql)jXIRc24jMdvLx19}{2HPNAT|ToaWv0R1ZW(2pMx&26O?wlZL$~Xb z1-|A79N1%o=TXRdEfBu!C#FLmmjnUEOz5=NWe`Ha(`39+?z|G(C-8M)d{6Fchx?{G z`(E4;=X^xg^WEsT{a16Z+-60^l(e&0Nvw||Y*39pc+=w19Jbp~XO8(m{r=&(!-4kNJ2bxEJnmd?KOZx z4<2Ncm5DwhpD?N2<#pxC)8e1&hXlz_X|eu`{#@SK-R==G1`bh+^}qk^Z)7O?f4?pc z?E%x_p~HZTLh9|W*Saij5CV%O21v_`j(dRT06m*3Q4Q@Pz|r3QVlH-IQY zU5;>AI zH1!9|7I9v$wyRo8Uo8Wa4MJ$ zg~APpZDWfbFBbfJ{2{<43aLnXM0H(iz$AU}z=3uvKS)$hBY5P6ESl>sq6`^FigltI zG4*xA%#}gXB9AvZZstFG_H2xo7o8q2sE|+I_^kQ5?*R2gAdScA)I|8BM?oUTU$j3b z)rIs-xCQ2Mby!u;&&`Tl&Jj0Ag`kC`^$zCRV3`|IksJ;%xPGg!uy3Lm)EB-u@H{o| zGt)LNjai+ylfTd#LweRRvn=1geJqbcL0;NQ=pdGvC%WJQcw+pnYs`==nl(;Psa2eS zyGMVGnbx{|LE=A}JPmWkMi&Lwd3nJ4*5TFVMVVHvpge^-|Fkl0LtR6AivQ@>RUw_Js%>ehj6UZ-eR@05ePw8?m0R#+ge5FrL1>RAeaQnt4`nV!?Yr_2)e`h;xP{llwN@nzV-$c?GzDm*aT%TZo=s z>NbHL8y9f}3ADFRfa8#U0rR{Wv6T|vh6MBtwNr%tB%T-F9xBe6MQ(QK(_jAQsC*afWDP>Rm&Z_ZUHa@)fUO^+v$NVFh+@kRVVoCzenN|PQuv#&!146 z{O6BCYO`KB9?at4;Ep1FAhq#UlC%cmlpcczr5v5P*oWP^9e38Z0d&`k{^=iaJ+7nqRU*&UqHkN%!EUam&_{3=q*DZ0FguzClH^MMt9~bM5A#)3c}2!-9nUo zP#)k=TEB_n2H`?zuK3N(m-@&&-I#HRXj`ev_rC{09K(t7p|5H`^Ky;DheOlE@W2#B zsiWY;chfR>q=6XPMsBdCTPFumsGs?$yf!EO{z}Tk^z?32$PsbSCfjUEMiq%u()Sm3 zKY=K(O$v@%t$Fc8_f-`X6{$9Ick{<7-o||Po$`PLc{36M38xv z?FDP%pA_Eix*A^UzS}dp`7fUct1{(Pp8a}h5^-6~G>!VpyvLXQS=j5^Ar^Z~+^SUB z82EmI;cgb%z#>gyw6HDAODI?CV8ULlJFT;Kg@$mw$#NO}=Y%r(6t;3he?jU@X|8MJ zr};yFmzq2Nr7kwbHxTjyhZRGX=H`DpL~t7a|Nnr6$iL~oU&q@r`X`nsC&z!9QJJ*p z4G_`L4E%q~Yc#F;M^qCQ-MOC0Dl_7?>8N^O*0X4Z`rFIgQsu)UOk(a#;d3y_jr`e^ z_Q31N_rv_sse*ik-kbSUQlKzgzr^i3sXU^n7_S^r&T!KWT!qdPUZ^TmaPQ;gfBg6X z11#E-d7yGJiHRaQjD%iAWaM#w)RHmo?#p!i(K2?xG0$!pgt9nxGrfibVJw2V(WJeC z>smt=5`|7o8e=Q#LSV7d`t|GMlg6emtX^|B{2GeXaXs=U4{ORDrQM~gSK}_`eS7biBmBGV83(uz zPc*GQ7j`357Zhy}%>i_$pJi_;x*LRk>b;hqVBfG|73N~$9bt5O1wN=~9O&eV2Yc)^ zZL^{MR>rKysy=cQfn4PXpyHGzjwic7kBB{gpAw9)05KqikO}0qCnf`uh1vn4$5YcU zEEqXoO2CpIVkL@5080^9ldmm#%4>8hOx}f5E5AR+b+I6_gU-n8@az5W`Bj2Qv#jdC7j5-X|cS2sdbFGA9!S znqx~;n}ayAP*a>nwTY1^5_|XNZ7)VK^9oP7A#r3p2`&L@6fvUtbH)Z~!(Un!u^d^c z3$2`8U0r_V>p3_&!K7!>CWczpgM89vL(l*Z_<)a#kqr?KABtO_#H2q{#1>~P<_rMO z$-cHmfiRw=z)fjf#`5~{V+tGxukl10X4VwsY$8ZG>@A|(x8HVtbRFXn_}`&(H_ZH= z)fLGFIoG}HfQxN8XkKt7GRTk#c|0@jxT-0=WBs*T;M+sli%v3Bnogw3pnw{cj7_+j0mA5mo@N{{|B8}ocL!v;Rt7!-1&xPj54ruT7A|9S~tG%rUFG3ryS|2M^*|)#6)jN#+wduZMIuw_9h|4<(PUUbE&FzQ+c+HMBys2~YZ?u2jwygk?4vTiSkA`4>RdZY%sw z^WT2ZX9J50FZ6Mj@Te<4-LLT;V*bsTPaXWZcfO;Z=moMa@OyA>Sv=Wh;#Hghd|G)l*~-fq7N8T|-Kpr$5)dENME zhcfx|nvn9!|N3Z)x&uY|guf7b2|1efN!Am5{P;ggn7i=8=Hpz!;ye7W3ovnHmDa|4 zCNYXQ65L^e{aRzmylw&*SpiOqGXa*vn>2|GB6dpP-*1mO>0n}eg>|BpR@_RVx~yHh zw!O3SgKlw4%SKVr`4Oq!fq~VFRE6;I7thAhG3Y}d%Dp0@foqx)C8EEy+^8s?jI1n< zIWhXBh#tCBbm`i)mFnsxF?j$bqDe>*6+*rD#l@b9{+s|#z;z%mx%eAM4bUxR?8<>I z&SRY`;pK%QfAt~<&^jmWLsPJ z+v;9KE!{sf^s)XS_APr1FnGxc9h+=(ON(TY1qM0CBMPz)n=0FW?^kz5vGpnS^{9_ zqJB4GHVuz+N;eM&NAaI~6OZXe(7$NhnVUF*K292$=hR#mOt6yxUOL6y{VD0xp5C_) zpzGzA1pvJSGKi01BphlKl?#*yus^e&GBk`BxA^pA6_9kH5KKwle&rDa_9uh6HOkN* zLeUVMpm1N>+7k~pfrDbVZ2t5|Mrnc^s_~ZbfY$mR?l%drj5&a6w=vTHd(S$h3lk2FA>N9d#a^UL?Ufp@$sqwJMt-1qUmV1-5`5KF+pUTrq? zwF2_;+z9J83(7`Uc|b!0)q?B7JTn{H*4e=d0Re#(@BWM*t{uXQfI1MmQ-TXvWUCj8 zHoLziJ(=e4!Z?rjA(RMNUlCS7M3}xk`HsABNma8~kzCW>JnAa~u0U>anL}Wg{ZVe`Pm0+gB{=#+AI4EIJHhwl?RHzcU+qdF}vxZAftN zlAD{umlu*^QeszW4f|Z<)JZ^;uvvRH#jRYax-2YUGir5qwAa03$?#(L_9v3=UzWfp@5SR z5dU=#GEbZpad51^N=wt7;GW6Cfbh8{K%Ix>z1}(SiobL%YTH;;E|Pn(ln+2ND1gJ) z=daF%4eKc#5GtodLtxo}*6Aqo^4eQ(m+wD%#zrv{1jcHNMX64;AOrN;GOv^X!E6Ia z88ICIaPQyKJ_8ttRIVGaz=qN|>u^h&Vk&pvbH>%wtY@?DrRN&E33}fXT zP*qks^EY*-VNb7Q;Qr*!n?o|oPfY1#LjD$I9S~^jC>SIb+l03-~)BgBNt*of@7Jb=i3G z&c$k9*VCZ?9JR(;Fkm>k5n^P@rKukva3Mo0A@y??a; zNs+=cNOhF4Q$TklMSE2xb^Rw%cLs3cbZMocp4(!5vXqaXUr9Sp(P^r(CSe`znnkUi z(pDw*g=;yY(BkzR&rxt_(R(?^C%r?u9=62#qfE3c4YP$$(|?|_nSNA$=};%D8~S=m zgs<0=z_Z{CidIQz7B#kr5+T+=%eW_=QV7{_Zf#b~CwvPg@(bN&Ca&L;`$EIn*o zEMK6q_CG(WGg!%|MBlNWU?gXTzlA*;E6AiuHk|y7%TxD^PD>D^HZ^)K{NK{W!qaC) z@xew(Ai)8%>px0R100#J#>`brB#h;VheNXXUqrK3*SxBvhDI!}N|eRIPG>9mF?jU|gf``;XRUvcHJJfGMN+v2tU{*I@glnPkwW)d% zC-|D9AU0$2&_|(eyIeH-^QSwGmCNv%pq?R;nMD^%sf!8Ryr!?-yy=28At>va4YOaw zT3kr%uI;_O#k%q6RJmO9a7>Yc#L%excc3baxsV*XynBhtN)ee1jBq}VIgFcG zL2QP;wJ^&M|BQ;jS#t>@5#c&yqzB|VR1bj-s>yM<65u+BI3>Ncu*TxND%6b^MR~Lj z%}{1J5`C6KNXJ(0&8*Fj^5iWd{n(Z-S+Z|ptX6%~2Dz`S3J&ATu_0C+3xcc1#NIw5 zTIYD~Uy8py63{ljN7-!=juC1F5PwmJj8V1`#`Y!Ws#U8n16?m(9?;1s=w96?V(6Sa zfS+nOAbDp6+4K(ZqV_OTGxpi>GKQMJro8-+lq+^r0HJcG zl^6y8+n$UQfrt@NGE?8{yo8tl!?dPfe01C&s3Hv;K*RtGC#N?Uof=<)P%vU9@<$Ld zP*&w5S5URN3p%E=Rt$Ji&;WSRNJ+S4$owqHVxZI!<#2;^fPrMUWRQhdh1(jA^<#H& zR(C*l#2B@c@9e>S$2ywUd2j|}U#6a)CRU`}+}sae4v=b*5b6Eb@HEsQN12d}J$-!z zpx+|iEgAlnmsjQLit>{5!KpbYRXseB)H@7rV3BMkAWRL~FIZXRY&w^36%g>bK%CFd zFo~4r@QODX9q39R<+;W?P>7)AO0eTjgN*qGKCUtv$@Z7&ZLCq}y}U=e%hnMT0$BS# zq}IdweMjqUyojhMBl2WS`lW11mU=X{Z`*8iFkv!RZcN&XediYTf-|T9thY+~m8)09 zY^IbkI#5Mj-LDvEfN!I}Zxaj)fMw+2Z^6_udR*DBn$L;NDL0u=$N~@7>(A&iFNbvY zQB@y$?sjOuVjKW&DIxV%#kk@&1hLETSj4n6U`m}+JPV%+@85j%_N~~_(l%K*prYRo zD&;ixJj&<@9Sg86Qo;i)iGTDLG@D9i&u&BBzcTot&HRPM#UIcywnM~qNH2fuEibRT zGWv^{IGXimM zK!O2B7Ew0dyYb<@{`3w2oQ3+N4s)DA{~|4JuwsABZ#(Sky1DvIpgB5lSp<3)?tv&J z%3pJTFQ!c&z~XOd=51?hYh}1G4&}&A>?shBPJX*_`IdJ8JLO?V_R{ zcp1Mt>z6M9*R<_*d?$nk#4Hr|PLcm6a53Tqk~2kDLLs_4ZH&PAH8XP)YO*SVOW(%a z+-6?vTXYEVS|x2(;FyC94mMHI3FGx&BZgP=(Jwvr{Maf?lUWMp#siPr-7nTBaaRZ; zh3y6v^-_pgJdxMp?c;L;GSi(E1)sO4xgto3XXnnHDnU&Ud5n&Z)@oBr%oLH_=h>Z*JI!fZ35=uN@yu)%EVNN9aRtWM^mdX`cxJ zMgvfY{p((ECXb;e^*j*FOgq$V%yEnP=NLj4ckVDk-oZ}grzc~e_H75%5ix+xcFiBG z-BeoZJLipikYL0{G=TPS?Whi1{xxbcF*+!PTM5m8Yu*-4R9$v~!19Wv)dmtq!( z(r>M5b0Oy?dqGHJuoZd1ImLF14+qnK_G2e5kqizLH9GZsaajefZMXR zVQfb4@zD9cdyC2rS>M2X&AV~KM(-NCP=O9JZ&4>_F9|HOMUrS% zMic_(qU#z-q=Vt)GiX3D=KA@wKX^Lb!TJ0x7d(x8q!*LF5K>ohefOOvGN1kEmSQNn z{lvw^4XK#F{*uKMbi82?>iSVk9}P|u!(w@b>e$d>IUQXW{EWUdfC$Vus4CcrjPw`E z$rw(I|JvP{s23!n26ZoW?_T4^DgE>dJaTe!mwTue+vIbNn>dF<-oPa256&VwJe>5g zs4*pvCukS7pO1U%)oNEJi>>e-o_|AGgr?$iVQJJr#Ur9NmR(Bpv_x%C0bm{n36ze^ z!4B_#Pa>&-vH&Rd%g>r7+;#~BHzbO~v9-&#Sq{!vpG2}SGvF0hetLwSO8Zxh(EToB za#4#QcQEtl0vbiX@{+>B1HRGLYVL}F^8|&0b|aKOG@AsQO3^^ZhVD^A_ilFHk5q`~ z$9m7*h0ygNl_VUonc`nUXy~{~n|WWP>$&^{*o8{*xr66HXe=-}QK?Tn!12~bz-yK*BU;BxcrCQBSU8wubs+En=#(&B- zZcr*e_XbltIEgZWB^LFNkg|mm!^DQVW=0h**(p8Lb6it9lpBpLLFaj3&D;Q*5v^lF zGcnP!&929OpbTfbrI!BD5jaG&HNMOFGSj#xjB5j#B?Wqpw1kOYXt1xP9U4kpc{%lI z{hUg`>|HjiM0FG%r?Cr;B3ggL$J1r^Ma9ITv6wHx7SIoghF0T#&C4UkRxQRvf215s zY#|}zV2H%k8f0WlDu=9}4_Q`1RromG5mT<0z)`yzwf=5fVMhQLyvVg#w+&vWf$Sim zBhW=0L5b$U9J6xqW=Rzk+S3Wv9|#yaD5){=^o}DVrvwG)$Pz%L61KuA#KMfa60B_=wViH(&lLFn>Er_6D+E0zHL!$2@ zm#oEs*C56nnw;>>9yNY!go0;|Pbm6wYF5VzLC^yhpeW#~Fmj z!ZR&E>_~PuJF%(3SgJE&2R`UAX3-c@p~+f`n$*y&5PUQp4#kY}(y^awl?_`NZc-qI z5Q0+SMWt~|4aQcPAX2k^c=$s9v2u^rSv@>!e8}QVtVCHMJr4$H%XFqQBt=}VOk7g* zIOHQM^5#$6Y4v^7QnY;K%FB;N%9T(SJqFKhXjUA^lX!I3Or+dZ;if6HoL=yi2#2lV zD-h z6{$2r0brYmq=AIlFw&YC%T6?+oT$+2IRLtSKwT>GiBQp}heHvHQa*kU8bXcpf_-F` zJrS84o-ein2yWIk>}kJv*j&TQ6#$2kCbDn0FLUGN(3FKah<*z-u|1v-6P1HNWn zgx&hKy(W-EQpz;!tcvWARz3EZds4f^AJOJHU)XWcX4PhOsvkj2= zlfWFwVmz0dk;a?~E|a%?a4=D_7&j3pp0ZRB`mUSz@872lBR}jJl?xI}I2k;;-Ig4NV4yM?}y=Y5!@)4pi;|P0ikU2OS%4dQ$75_EH9= zSA2z-+W<$V73S|g4w)>q?4(eh5OgXUbc;aZ6=l*S)AOwss*u*e(?bV1$+3iZ>_I+# zzb+2(6&4y{*c@{aR=t%FgVr#lw&Q69TDdZ}bJ?Hl(eq$!CIe&7rc$<%ty*+)UeS$t z%NWiF>iON^g;`zaqmxn4?bFwf=)bmW*De8Zf4jaa9vO@#vtWdjX?TTE0E=}VFeT2v zdEPAWzxj(DNg}qT>7~hL=kfjF020Xhidvir$GF@h)1f9}1r(Dz5t4GR(9+a&8B$Ab zVEGO34C04&OgCQsG2?q&NyaofsQ+F?RzvEs_BVZu`3}dJN{Z8DfSfL*fA|vkyQhS z`SbngO#cAVjcGYyU~qYd)nD{{23wOMs>{c4mj{*|RLXmRKO%S30bfOqBc3Cl%)Csz z4mJ<-)Nds4V%q^b^+)S<)-$9JGepc@g=x-HGhGFp*LyUg)P`8l$iEOf#wpjsid|tX z$}-3}ky*5xgw7ZJB5^viSCL8yR3DP<+}lsX)bW5wAPwfu124u6H?aW=yt@P6i#P-# z$xS4(L3Qw$zWy`2Q^Re!ez<%>p^6fPTR>Ee?9%>#+7+F+@ApN=J!Duhn2Q()_}qM; z8vRNqK5X;>-aXfToHk;fLnBy#Tf9BQi<{(?9Ag4Q0^TJqx(-B->>?%!o6JsUH>aOO zrS;{fMZoUlHaHFm? z#KJ&rkGfy^X_6U^hW_EhP5 z;YoUny{rJNOWC~=co=J2TJDPw7_;=AyP7tKwst8Xn9aZo&nj5`!mrKbls( z$UK0~Q}P%({V~lMEE=|c>pv~H*&ux3{<$3%R;XL7PY_n<)HBP`Nf4j){G_CGz_Ww@il%ziPGCho!VkeVvmo)xykw{ z8GV<}-XT*nQ&XMJC@spqJK29I6!h6>#+(w8%_{3NJj<}}ZAKD)BG3?Xw({avAnrSW zG#Q#bc`#CVKsFuouJ=P@^dUPL&36HQnyuWEnYMP3e>_^0$Fn2A&|#zXTv3EouD3~8 z!+bsF5PhL#W@js-z_4vQUJp?|=8+^#i+#djMh|fkY3T!8(eWZau{u?8Nh0tP;md=k zq#yreU)($lCc>G0o?L%perSEV)t|GW%xOY?U4;z|>?kwM0y3dHenupK=!c2Q5zOIA zyEh2+knl!_(lgFCnl41jP!JMJI;2CrH&MYLH6L%z{yI z^aKDzwq@BE8s^P%a$HzP3=pCbv!djC^E?M!a+Bqb(JQVL}s`KL9F#7oP#HQ9rvYAroPV2f2otvy4ph7XW7M7e|JR4|d9XKB z>pmJANU>!RJhOy|=us@FRwIG=1~w1!4B;A})KbF8Xri!%>w7uKH?G%shju)Oqd@sT zz!u$sTH-bcDQ|k5e`>O$aM%BLJx;H+nn&;xoE8Om1c~eO6=o^m22$KytD}LLpp0BL zKR+*lN`;=D{9wKW6Ec6Sha`Iw$TY5z7~R#oMRR`dgOESsgJ*^zk^N0q>7NoX;(0=+t18+x%S*4_q`W)HaM~rJf8FUhCHOjw>(o85_9D~nsQQ&V|LDIxCLrR z+hqg??yK~4FG6opC_wU<&_PSeyZqqX}Y;+|8Bw232p^o0Z!HeEPW!KM`4js4iZKUOaINQS48gV zpQwS7PB)WR4F^UvzLcRE(dGx_0W)2RLduW|F1RQyS6phD+bP7PkQ#3kz%BclJ2JAe z`9vm)Q|}c9*yv*$KIblwh2c2)Fyt*oJh1>2S3Ja)i-XiR_u;$x40!mcOA!E=uX`5V z{Ax2(eL%+KsweFv)^y-HCw|_(d;!k4w10ST4crD31Z=K0Q>LdfKn(f=cm97o>mW~I z;6S+*FOO<}6j&MT+9@f}gvG@mMia(OH$Z|!MT{sj*uSCBC5IjSPZ`J+j(0f^E9FAfR@L&|o)(%o5Th@VO_(*D^7gTe&*(VmD0bwmN_p{ndE#V)UCg zSG005;C2lA*)O;W-Fw23go5f)27GX8N{V*Q4u?%(^Hy5l|3r`_0Q-@FX&5-E{50_y zfpj3C)p5NBz?y(TWrUX^NgiP(@To64hUB}Mamd<=r{gFGIkr*ml#+KaG<3fvmt$k0 zEd>D`je^qmof-&LtsQ^v-MhCM_f7SU0E##?yvn%FYaT?#!=LsHeJ_^4M!9f))cG}_ zzn~exs*VtyIk=YWinmjK<<6m1V|QI6kYhha29+*{ZNtsG9Z^{TbljloNxXorL zjA?m{jR&)uE&FXLZjDzqlU7y@JtZ?J<8m5nAIXjRWnC(UJprV}N(gh@&{C2_C8Vsf zk@S9&9u!?C(tz595pcszsOyxU#*`D%1=>m_yD~lx3Wd}}B*7)71tP^YL`zdN{uwY1 ziY)I7O~{Y3z$B5XJ~FfjCs&+>e~{t~J#Inc3$d+1=w zinZ`Zb@2f$>s3YQsaC?f#uhLJd+TECkYYN@PT;ib0&4SIU7?f6?7yZx*SB}Ur1=6e zzafoCoE{7>Vss+{`!oirf${O4!;mYkxsJ)Aw;w*lWI|ktFB z;4z`Y)3LHbHDSsi*HId{*3m@?;9Z&b(y+(IXETB}VYu$>d{wao3d79NDH5u}!3CR- zJZ8!1^j$%2f;)uu%su(&SA|Z%rVNvp> zb}tq7V7{8+G%enU>?BL7jGms}AK0m(_(YtU27}Xw1!LxM6!r!L&I){YitT{Z zTx_(LjUf*CvfLngvVKlQ+Q zqA~RS#}9v)GirRtKu($9HzR34)jL5?r;!1lJka7r(nyrk4ore&CzC)dE?%r=i^Uea z@|4PbW>ZzNl6w8RnwZewVe80#A&VBA%4D14f}Pir(OwkM7Jw%+X_%v2X26t*|FLNx z4K$=BddCoy@s~Dn(4}uDp=tybExKfDTZqb&t%&sKbzgV-8b2;~?z>C4Bv&`5IY>@# zv?ZV9uq#_aiOpQ60>x!!t`EBFS(9jr|4^^tm?9gu5%0UvuaFWwyS~@5( z(K_<2G#FZ931&OuXC4l<2cEZ-Uew$r&eMnwVGQ^-iuz3Q$P!l_G*3-aX18|lI5i{~ zXAG%`-@G`gIIsoCO`RM-ybqg2VfR-(5;J6czXSa(F=Oa%LpMIs6rRm1pf#f@e;KnM zmeSGD!4X7)2gy_gRB~UoyLjqw;R}EoTWN0Ix6}1}=5#XlyMQYczs{0_XV3O7n2x+F zh<(U%)P_s}}a7`C|WF}FSVw;%Df zEsNcE+i2Y(RwerHWe=yBzIB(JwR_W7S@lEnTHd3R`ycjIPEm2ieO=U7A9wXp)x#qt4G*_YZb`M2bcGhOi z`!6!Zk*g`6AG~4Gvc2JTAVn{;b3J6Mjm1=u==x` zCM*v^S_}~66L1=~S#|{hfm^UIdyK3s?dj;)54sbsP~}kW71f>p>}~ zbKYEZdUXaHb1GP#Lz_^`Ig(b74ps{K@)I^Bb{o;@A^AV)Y~^^Okb_NpT_U|O#(u|iJ_-BY zVra~KycfdXR$~BC9GcmdbMIB~o|MyEZ+EzTSmheBjFQrRmz7+Db;A;`Ps!pz*e);s z0D_aVZ>}1!ZrpenJZz=YW*clA=&~3}O#ExnrTg&NO;C?@^Tc7f~gfpWe{LYIm1)f@GGvcIdqk}+=gJC zJAW!Hq7|cXf1JX$Y}w+Dp8Qxl&xW^PHaW~t@2u^7$Iv^ za3@M7R^KsX!oR^*oYMoJ)EDG+E)EU}MH)tT(SZX8NL)XM?`y;-$2SeKzpREmUlP`> zXnFLT7L$%}I(sxGbk{?FQZ%Tg0xN&$Rv#7?xHL>rRJ{^z1Hv4k`BYN44-dncqPoG! zbEvstxvJRS3-J2|4DZE6MBum)@xl60eLrzCKjWbm4O521W4}M5)m}l{zq$zQ^-gb_ zo^tlkA=-sc-)-T)J?z`K!qk5bpI@n`zwzZpC*Uw`E` zq7R9nkv|^xSNO=Q$+7t8$RO8y7VbECe35-70jaS$V|yP@G?PMAXnnXcX5BPPPgT66$GVEKq&J z^C?ik6b+93mbV{J3fbz;z+nyGl_9E9SOMhOk>JavHUsrS?(61ob|jkic6YzRc0@)F z_agk7%oAvsKakw?2KLMpv`bJemm}pbALWVl)rbDnYoNy(T6Qm-zQsD>s9+7RL(?_v zY8-E<_ABML9$cKCv|)>&pqG=AvrD_7B|N2u4rFY=Ib)E7;(AVN$p8RFjPAZ+NQHks z*5H&3YuhGY^xkLQo-(hD$Y(c2$$7RV4Sq^Pl6QD|Cta>lH8%Lnx1pHUyxqWyQl&&= zoc3Bmp*-WmJR!7FKi;~aWaL6%7I3{F6u0NIhQXBA!H41PZGkeD%n`qz^sNm|#hF}| z1E4sTlNs_2S22=GMpC|DIRFZQsre)Pme)TwIU7;cV@3~M`?QXNjxiTn`1z) zP)pV>e%63+1@oHj;kbRH(be1q=4J` zY9?n=FVndhB|k;AUk4>lKLpP)tOAFgy{l@?-(Xmus4g;hSS+U{G1D}5OC+KKcw{cU z@4Svm_9^PiuPZl{nV-*w4Ask%Y10KN(VPx_d82;q;T_VDq{1t;^ylrZK46AaV1}gr zo&yTdkKUQ1Ng7&EY&DO{MxcmN1L-by$>Cs#1qgXEjm&RwsoV7*qpfTdFS5HNdF8XP zh-k%llyPEv?{s-@48TF77#Tr521X%U8_`ng4$$y5$v!}H#yUan&lfE7V`T+e!1k`B zCu%-5#VXJh2qGEn4vvnOdpf>01;H+Sau?=O2!>5{?cl?4UvgTDqKc_;Ov z)6;XuF%vFh)(&mkk>c$}IWp7pNzleV4c6nm z^-{&*Bf3Q{IgTL1T6u1t2iI^`r^Lu2_^iyT30}&>wen##z^FTB5Pq8Cm^g;A^W#u=#1C*Mxu$||T;mke|s0U zcO}I;Uy@9dPHx(G{p{*iO))`F*1@!0@m#VptYWDmvlowkO_Kc_%4$|S@F zK+bpl4o#JXxi8UMCK<$Ptrk-5a7?)xbo{s)oF{6q{r=X2DS-iv7m}ys%$HxfhG{^z z4_56j(faGc{*7V7#{J2SbpvIVNDp1Ha^>@^KrAKJTGwSoDBGVWRh+O)bG>ny+j8%Z z?R`fsr|&tJ{CACXCgcipNj_`+lVYB2r+LI4{#Z9RO+m|aQMaiU7y$oF@}{1=?5YiL zVLgAh_T|)$qk&t7yrSlER<(%i>+m4=jJxM9>m}}t0u`rJ`xN8n$Ang|TBYTz069*@ z>;gmq+Hms@4AzH$p;eo_YVq22NkrF=xrQ$lOh@&xt?b)oz7V%OmCi20B8Y=73YpF0 z!}Ah?uz(>^=Kydl2*}h>vyup#T42x+)SJTyY%-R_f(HzkFdu&m_=ls2PNtb{XN0#Y zc}6bva~`GACTw0fojXw5g<{@iHL{$tTBOxvse$_*jZ}3%cTMQ_j%C?ehJGt5EUZCG z@*N{Cqsh7M`VGOzSms{d-mPE1CSV7fDBgJSC?59%PiIHc*GFlplTX#ziDO0!*d3Aq zYjNoJ<2(sNN}@}L6rmm1Kr_!c{_{D0Zo^*tJ`?BPzHR^c4Az3Pa#4X$6j)A-z?PK? zw2e$+B+-&96kW+QI}(IP;w#q7fBpC|z?V%(3AE{xy6@ZZZ`wLKKi@5YXMvVZt(;x0 zfDEkPb3S|#vHz#r%B<@8u_8ihB78c|J)uHqTap{l!=v>3;RYA!4;@WjC z;`w0BO`uSTMt3vu+F_l~dP0;#wt6Knsmt~Sw`}`;w^r!{#ckO#$_cP5C%}esve^8E z#%d)M2b#y79oR9oi0?6);4Gqh_MEKE!s&Dl)Vh)b-1`2gEL4A9+6tymY4QuQ_H>)C zqS;V#xQ_nf-Z?T4`Z#31iEs5}0r%Z%OqkkwkQI}0md%1%JAq`%$gKx=oyx;dm~FFO z+IY*)sFSST%pj02-7Z)cro|#Ms(o<((>kG)T&rNCWOGPz)(xzOLS#y_`vyAtWR1R>SxuwuL`GnaGqxj#)j7Py7z>>Uqx?_?S9CXkt~wY&!$b zzix%{s+<;Ls4PR#Jus=Nrlt-4x50+{*4BgdkR}sDA?zPt_VB1;CVdT{e@o~@cV$m1 zV#;yn#-P=bZ9|h7HodE~_+7k4ByFN~vksv3zaXV}yI*bmL`xFf*iRq}GcY6*Z-E{P zKG>8DcDx4lqi7YNL$xctmDJx~;kP;rCw@AoDH`3gBQ=Ayv2@rCDro*#vpVPz#H#2h zo@B5D<#7mXKaOx44Mlmz120D-=Jy@T$1dXJrwyjIDF3*S4+Q+K=H@6TJ)BVW&i^ZpG-osvmgjIjEW#)DHto#!@@Kb63ltCFjb*bo`KLO6` z$D2%PshBM9RKBS<-DbLuiw3EtRb^xEY^w$?(1 zkpRQe^KP;}f#9Y+KZR^)bzGV^oUu@9KR2=mYZ*o6>-hb|(kcJ(&C*&m^Kwr{Gs$Y| z?&>m~oVi5j<^Z+I|6%OA19INq{%>1_MCwMeS{mwh=oAf-D51TV1}UM^)}Ye5g|@T{ z4ce22Ra7*PG*qN1i9z<5e#>zT zIcl!gl@5LQVF)KyJfv{}qpsMv@B!hW!R?5i@B@s)q=&v_zfIT5Wh++Por!U9*;l~4 z>@aBfdw@LyM$zG4MUVGThcob9I;wvhUbRltMdYRABJyXm=~7B+=J%av7Cn86ciJoF z0t6=3Y+JWpTnkZ(9G@JP(lh~qSY?crlLz_8@?UKQ1%PN8TItw~p#%?9F5Mj4&8LjQa=O;rmaQ@DX(I&}U9O95BGWd=FwWd|S zd7}mq7)Z8ExcwPIyFn9ZWN2DmtgQd42JZkH&hUc*EgHxN?85@#_unturyaQ09yHqD z^w)T^Wd=hx@oIWfq0Kmr62wZDTw1Q(i5P6M&saF){dY#Qt=XZirTp)B@I*BvNXBmu z?2*x);o;#tE&Fg}{a$T@qNXtuwSsbf2_|`aHK??|tnUI!yz%8)SD|Dsd1R1SYm{%B z8XC(gLjPmdZ4FuJkv?1aO0q|kbim|z_vHW=Ury@^F&XKq^bgw!(SQcoP8FWu#21e^ zf#+81SXoW~jGv8tbXAzEFeyeY7P8t5*c@qfhh#F2shg-wjb(w1V6WLeFLfDGgy++^ zPnbQ)@%r3}gl*P8zQh&4CY1eHKNLwKJED%_e^_f@=#bF%yb_W))t0ivW0m7|29GVY zjqdI-?i=f=_j?)@I6oTCuU_0D$t<3$6{}PALPz13weF+Fjkp`V5t^fb&MmE6x-+u? z*H0u?n_!;z!=XPA8SrlQc#6r@yy?|0RvCc`0%PC#thoNE>ZE17wXF6`9jB0<#MSNR zd1r7Mp2G2;2>s|gG>ik$f%52o_JTBO&Nd4uQQf|ydzyVpAX)z8yiHQ)+6CZ-z$XDa zqhE?K>Pehq&R0n zUVk^#kyt}2a7}qb8w2Iwm!$Gw>RF!v-hpTK#w92`WMA?l{U>2qiEsj#e(o2FbdF0MydoXSWi*^=i6#NZ2VXxmfo?ECs011#cwBY*944kJ+5uo z0~RWz8wTF>b$L1WP`hp4{AB6F#=c!xjEf^2yK~#VP4Yq85{KjE9au40f@|aWeBCjP zSuI(aOPjnxzrxfz!P}ONwlB zKNFpHq~xgnUA1j`gEK~Mu53`ySCuWu5H zMZ6UORMcZJZ=L`B^9x2aaLW%dL+hFCQchTkx$-VQjtLYIy)k)NY);p@Z3p4qrHkzm zxd%{^=~nHf(b#F_`?<_L7N<@1pg0RlfUmDoQmoVvg#TwCqtNS{n3y<=J4eKS7!;O` zm1PiD7JhBSo6d4}!>%?1SaR+;N{U4SQX{BK`V`T{BSBG_`zAP9+le8(^5h`Tb#C*s z4jSmo(`~@(WJ6zH)3$4ghvGUD>fq8$f`Mn0jBjcz*3Capn;b$2)_pK;Prr_U3eUap zd4F&_t}Z&l4lmFun1qWD;%F6}{0vp#F(5K*Cb*xj$^~+qgVU6lDY1K|K&&0ENI1Q8 zP)Tp!J_OJt=XXF5m;5ihu*jJ~Jhxw1VWO)So{=Gpy>~hqF%sC3eQ@EtnuK0f0mWQh zh?yHY_gj6MrNj_`;T+p{fwh#tL8Z?H9Eu2ivQN&oW2M5clAB*ov|b$x-6SHfbP6TzmGYgfi(+0H}5$^3iGt zLBfxRGmRP67WR-gycnUnjFedxBr*k z-lHg&S%-H$Ti3dXV)4#mUO`cj3x2Tl*>;@TiWQ)TJKKDuoPWKp;O+{)b4MQCKqvok zn34GQ?Q3Y;b$1NPp+Qk`+a7u)7225R;`+{7T zL-F80%LCQ23F!w0?OnfkvxASbT|PetSBnZpwIU)1R>ckV9Z*!Z?Q*-0H58>_w&_No zRmlK2Lt>K20@2A>6tMwGd}>X zq%0$IZFTl~TjY6Kz?AQB7j&u@B$nnshhP9ofRW|WD@bbMppUGs(XPg+XAZGbE|&bH zPo8}nc?9Rtvp5D1$xlD*Bq)JrfIB|V@PN1XFJIyU!-}|;{5(~^hCFyqv@;si`tqKB zB#yO9;<%(O)_P9ZMb@4|3zo0y_biH7rDr#-=ZS%CwzW;a^))PaUe#Zq@m`yVSNNPp zP|OGG?y|36zthsN6b=oS2Nz5~WuAWC&8P7&;t(C)%P&+Ro!m_PMr8Kvvb=jUARx!# z2jwKDe#)n{)e~t7bG04CA>THCI|Z)c0OhGQaDpaF>7<6)SdCGBK_z#J(Zzod54`~1 zf)25|vfLHC({Vh%gzNUq99v2Wq@a%PsVovJuUs6F_|j;_RQR~jTBZ+PbIZILrUWRg za^%Mu93nh|La6-*=ihOzGQJvFR~9Go%xV39``3?g?&p|KjvqSl%`nbva+;T%*Q5q| zDEa7QCY0;{4Yh0^~s2uJiUO9T=HSy zW2hCeR;0dMyf5DU(CKTVJQO}U8i#FU3v=b?&-&(fa8OdOq{FFNHv&ii6N7iyEmIZ{Uxd zz$-OK!`XS|&Bq_&%pNaHDBD`Fya9swdz?fvtYRI?prYIpG|9Lv$)X5-}t9BNQ>;p^9=+9@x3hY7n3?2$jeGL%y zJ?8eL0>BZl>9f{OcrTr?AN0JoLuKe>cM?GN1E(snN57ba{~5dY<~jj&?L z6Ciw}=fv;SF_TWj6ViXt|VA23G~HLxySfy5Gi z1E0s%M<@?Cnf`Klz|;})pW*kdA?47Q4V;{Ti^Oq=Z}`Ie<cX^;eZ2y3cPG>&!R^EOmOu+m803mn zd?UGjwA{JOk0Bwf3a3sLh#4LlzV$M**IJTi1=sKp4=Ot!{HT*wYIVScMIu;G_4l?TSZBN2A@g zG}t%s0=;8MWTb_)6q*Nql_XyaC#;zA0{0|Xqp9@7;t+I}a6G^KdL@YKj%&mfhJLCJ=P|Xi^#PY6Fg)P_)kl6qpic0iqGqys77=3Ad==ojD?g{V6im;X z-TGGxaPjXuuQ0F|nP8`hTIgdX8CY}4AgTF;xS+waZz?B3VN38~jh+L@DSI6h6ht=$ zmYoHT;!;B|C?+i=nkv)L$J!KB0xn=pDI>fk(m4lxG>xCXJa7Xm4Y5F)|J|ur_AOi9 z5?nv@1sn#LnEjRMAWKE?h6Pj~4|+*NkB%E{$YkYmR~n1__{CAWav-L<)NmG@+9#;e z)havDTt0;IM$d^v4@0(lB2*$I6I#f08$^)i-~p*Zv5}EgXTVuC{Ebet2^TZnSOV?g z>WzE61a1P#$-!(%EeANV99`dr#^JHIf47?=f=$#P8@Zg=$V#nOXJcI}Fv5qNTT0=* zMqp&TwQucC&&?3WipzsX{s@K<1sWCq7%?ouq*2^^6Y|YqteMm0yNT*geF?vdDNZs_ zvUq&zOSlxH>qc+zHX;}PeV4T7rQ)KVNp!yK&=VWMPeUaPFMPgL+fUimX<(FVRaM9%5 z#hCqtNd~7T?&b||O>qBak2uD>wv4fT07hoh%Y|lOm2HMm?gJn|+GCSAhP%rl%1OMW zzm^5S$(sP8QToz7T40Hg5-*db%a-j@xe4S`P((yYL(=HEsRbGxQ~ZVhui9R}HG8^F z*17<9^$v%~L$g>gVM&tgOO%mR^EHrzX8%zAe)TRvi9V<6fVtYG7YL?#^UGU*dCX!N ze7BH0B9^qroWPM5Q_;$22WBkLEj=~SeIf&lab|(D2bWPc(29+!Jj`8_)!je#oX)Us zuyD`Tbk)(_s_@}~iq$)C?m(micVtm~ec_Ng3^j?0M7qYr;ry@t-NLJKGcRiXD7+s^ z>N6ExuxZff!DAf#PdS822W0#}CFtoqWG+I+SEI;vvkeAdI8JD3k&*FT+c}RVB=HYJK+3w7`uqdR zH3n`So}HUKY@d-{qwvL2jxB>C${Mikkh!((+`;W1krv@kr>hB-?!4fzBdTO3Zuc)D zJR!dcvX6m7v;0gB5q!skxOAX5#5DJ|E#=^LHS_`a|CH2e@uRJSvUq}r^np+=2xLs3 zZ{cZHjp)-1@RS69;{+D@0Wd{nC8b*>s#j&W`1pK5ddcFiHSHt=AAcUU86R1)m7|do z#YEm8{B#_b(3-U*7)%$&;>Ng-OHh@?eSgLCjL$0pBJ9(Pd498fZ)M(CE{{ z0H~x)88O^8x#%E49_VOF=ccL62fuib0|diRG75=I_2r>9{d?#8)9^opY>hVq5u5Sb z+Ze{`0v^1=;H=g;Kg4`ldybKLmjB`JW5FXowig3m=Ve{`%E^)TQ?Zv9YGjDxD00W)SUU$EB+{tiEkzLLJK7X0>3QSElc?{3wEUc%d{B^u3{K1niql zC@MW+t<`NvX(nutCMP~GGh};$T}Q5V4vI3I@HkDwA|jH(t~>TdI}}!-(WoLKvc&H7 z>(*(_&&?JEu7Hog2#1y2zg4Gjgv5^?fN@TlXmfL*l(reG1$>Ki;d! z3GnC)SgWeNi#^ugroL!jNzvLlvEgR_{QTs#qInbo?ceN!&w2Lmk4!fxQIPHF^Yl#y z=%iNW=GrhqGE9lG^yxStU9-4IS*UdYEVt4YfO5RNaE~N-7dX9ssEh7^{cA7zq?Xl~fGx_rTf(j7`2fF0718O|hcGsu7=6 za9UcL`WO#t9eS5<_?$xkyVFk1G}7jD!37fvaB^zO;_L22yyEv5DFu7BtXpS1&OQjX zLxLkV zsokd^VO`vQEO;%q>5}@ZDg;R}`)zwxv23^^!3SI`@51M1Q#xVBb{m$Sr`^O2oZ}#j zY=uZzK@5#JW#>OTnGRlf3r!>xtp4R>TgmP#1w53s3oH*hXY_Gf7eq4u{JEw5;ws8= zs>x-@z0;lEer8Mc!evp98w<^IU!UbK%0BMyxn0+|K}|hC(T6?-O-E6WWqrajKy)c# zK5WPfy#Yxjz8@i)Gai~OkT=BvCJh)Z`TaEjI&IoQvyJ#Y2x?Y#ujt^z0d*AD0$VTE zKC^*qP6=BvG;T5Y32~$+0R?39%VFK7e&MBOUq{fqpP7$BO+0XUwC6+s4Or1(T;|{c zC5Q8YGoHY@nd($(Pcs)1R)=cOF($nKjzA3!9>Q@Z66R)sJ_K8o4f+sn2IKBPPusPgKBYWOhZW_`?6xY5Z91W3V`vkC@(OK880`UkIQ&k; z?)4A|o1PPbRl`BICkGKTU{Q-HI-1n3xDEJCrf5EUQUk&boc;8R9hE~RFeGZ@jxQQ< zL`gXz^@}jKdIS9O>!xA6Q{T11<0C<8AawxLh(cq6_ELlUCg$Bs-P`2XL2;i_iTLw3 z9c?{mv(D$v04Qk!RbDtkk|$f9IAkc3?4fK3%P*Cif69!vV3yT<4zj4|<_&!7-y1u@ z^?tq32qg9{orKk=Q$d}d2j3`H&CA1+O}wk+#M1=iM>UtzmO$JjA4hc#S})cek>jRm%imK`VPt(R-2x@b-`ZMya>BW4YDXLC*A}xA*VK0+=&cVBdA} z@by(RU$Vx#XJ9~xwG;c@m2x>KIt~bVX5-)x%#Fr;aCBG#ulChgSahpAPH!YHdQzd^ z*}#7kgI*I(rd7t6tPT0(09<`S1s@4JrKo5MbQLVux^>S%v}8C&>saDbffiRq#%v>2 z!yKZcZrd^!uATk6$d?}IF-KqoeHe;V7(1RYzaZ;19w0!*;D)absXB~Pm(uVd0z;8$7}tC8GohFD1qQK zG{O>`z!Q4(Y5eMims!1@BljzsT9T?7Z-y#cF~+OD13JFyG2TP9Et#i1pY`I2Sbxr* zDFz6}@RnKW6P|+~Y?nK7-=O#3P-_BLOh|O}TS;jXI_mi8pBHhZu<7)IP`WWEp>eq# z&9$AUbbF=i@teMA-`|0i@CwUXCO$n5+Gx`i=*4(xR~=5k6!ab^-P{8^RvEE=t#M=yQb98VSGeD$lbLn#gM~?^0bZM2H7246~kY?E_zxdHtqJgsX8Nf zX3TGDnaA^$gcf7keSgc=lNT061>_7hMwiT39G?9L*SfWg{e2)aZvhCXrinf@uX%)x zQlkE^&*&WZK#JI6JfBa>r=`SS;0X)7nO#pg$Qo!_rIILRt+$w>`vQIM7NP`{8Fg`X zeg{ZoAm%76ie!;|JqISzBe>9Is#k5qHgu2#=@il;(g^yGUWf4sR1fb1giHBy-vHyqM-SAp z3;r0%GBlzX3^&cRV4Cv&s7)RlrjKW3euFK5*N@}6ub$QecC<bl6!Xs{Ar;#>3-j}^bSWD(SbYTR z3p&~i3anbr?5O|_US!hWQc!C?i9>Jvi_cb@h9l^K54cX{D$}9m$Z0fixgj8jS2hjl z{)UX>_xf>^r%CzwKGMp1Zc0a!Wm_N*Y_O7wC=zf6h}a|0ckUI8&n^&N7F8)@s5hf;h5#zg1yzzNi_x&yQ2tAXsoZR*DNxUOR7l5_X16edkZ3zsf zPRE-Aa`b9>H`Xle+J?=j4j@LLKwJ8!3Ikcs`%}2_-l2QY-ta>2uBn+>J^CiW-NN$g zP?j6I9Ey9%VgNNPB+euWTGt!rXiT>nKTSZS1eCtJ`ce~R7`777&flSD!Sd&fy#-gR*Rx>Uy)!$S zfGXY9ZDcXoIv+@-J@1co*CNrHMA5sJWy2?FGGY^+vg@Gi<^E4JlHYb?T2Z^ISVDkjj8XxXEEY z>l|-p^o++N4*eG#Zum!dIgxm*lLp%S0A^zx01e5?BoXX2Uj+)6Hm(y*PS7ky$TFe%XJLfXfQcr3 zsvk*0#}P2=KTPgL=}#Aac08-vDoU(`xFX$CPF#(OdP-n-Rc?Ji| zU;d=4AfwZUM0AR&l42SRm`-}y49Kd~MB;(a#&axc&cn2Z(bP z+xH=5y{3K$pYpXwa9D>*jQ2OafJCgq?#gNghSP+G1b0m~g15dRsbP`yVMypM2@OGI zgGSi0bKPQ(L;|U7L1W?37Z-b==<(xhyy<)~D~6U?4-&0$KKg;;Ze%h%!vh0Y!~KqH za;`EU3jo|8Z%OY-G|_vhKY!yYC~8j%I)IW?7q=TZS8q^>yo?FnFf97TRaa?{H1PS5 zI32Miw@n%n7?n5ycApO4tzQ+8g-Zo0P4Rd_1{#AJ@eez~P<)Z8DjE-i#l69+jQ670 z@yTKP2K<<5Xt_?DFvIU=UC7oL$9>T9_%YH8%vl6seXues6A&L`H^C5sFREn~fN;LV z9JZDP`X-_eSWW}XvP+E}C)RmTlJ@*G)b53DY`0$Fw!QAKi0PMJX&Q7Qm@nG>Q7NQy z*h-H{HR9kVb~vY4#O3Z171iJ)3(r@zMM7437-t)c|LtjB*&?9W6=U|kz1?#~{y|V8 z3dc`^+*JUaslL|-hawTY)a@bizz-ij6xX7$?{R+da+D~)dkQwx+t;8S1hleoMt5%R z4CDl-_~0}j%7Mrq)qW||DH6zgEWTC zS4z=mJu8iVg=f6*z*bU7OLufXD-T)%@a!q`J4Cz;CLS89?fdsPchvd`((=mI4+y}G zb{Vk}@n#fCj1SQu9qCG1asKf4#twd#Qx~KU&F@(~#$X{My=Y(McSFaL1C&pjftL|G zn)%Il><1KH2DhB5D^omN;sFBk;0c>4_T|I>_G9M5Top~H#;tw)9_NDN)Dk9CCm|L8 zZLaE{mz%iNxb3-qK=H#p@44<{V+_rnZi@*e`A^ptz_y$7+1f!7>nq8pl-5uAjf=h8 zwj}2CVv0A*zfXgC;a}PDui@lh+5X4BDu=V}=E?h?zrE6ZIN3Wup4+BQM%*`d^mtU> z7^KCk;-wB%hy36TeAk|u=J{Kk4XhR9;{QB>jf|nW7x>WS5fRV3c1h` z^NqS#660MrgG^hH>Rg`g)$Q$q=fJ^~fF*E>m6VY97JN#I#h(QlRCGk_Iu&e0;e&g2 zoz58yfc$1lWMxr=@1yBs5F$Z{p0$YmBHp@qDwz}_+cm)M@80W<4hPADs`VTIAc<}z zvThGqB!*NU1-KNpJ-!Gi`~l=iA3EBR3BZ+GgNFc@9#Xf50+@mFNgb`tf3v#ckf<`3LAISemnms7qQ#tv-u=+%-A;1lTO9(d=|ywFaO*B5Ju{; z81v5nxzA7Dq>bVK1rDML^;iTsfLh&!s8o-JN4nu@?qp?v;Le>d_$qLu+`-NW%_ney zwye3=6%5h!pXiL`D^}#7nM?~hN~#1@!HsUe5n5%2{#KQnnHxao9ha@n!~jPlHDd#o zvUq+jb#1BOUP?K-lXhL2500jVFGtQfY-#)RwQVb=lz+au{aZxrcd2v$^X%UwLj#|0uvuDn{1Jmy7EBNshPJhLoO8{{Q*DSc( z5OrK9)9C7(Af0i<4!s90$wV;JWK6IhkfhKsLgEhz;rZ|;PDE97pz4*|!RxkRX{)D{ zQM%Ndyflp&2)oHx95B`dD&z<9u_}qiC;`VDTcLyrz0I+6HTo3*C*(H6;k%d!%%!Hj z?POfJQe>m2gNr`4D}BG*Jp1SyCaGU|CcUnrnlbE#S8lgm89m{W^x6tiRgBJ7S?+Hm zXr538T)fFzM3Rzn0jUPerpb6Sp4nPeiY-6>zP_1`SMdEbWS5}nCzv=wWCTB+Mfgzi z0<#a0*$4Bp=E56?Tuq>AwWjpmS|`S41L@gcs{Hzob1SJIiNcUDbiRyIrPzFdrSsK_ z6^L}^AgX1yzQ067ZXu&F^)k!ILxYk?tZaLeE?ppn-9v|gX6)T)0z2L>FoglLmXHHH zXKr3j*@4wkPZ^giU)A9(!ddUme7qqQPY9cRwx!z;*|savTI6VMP^zW-JX*&>Kps$z zca`brkg@=XBkNnQXb-fMa}N|;fwlNN(ccV-%pN&Rc||5@7jTonL9aoQsk*U<9<*Ag zS_)YAGl;@VkVti(o8)C$ zxw6Aw86(FyE_w`#nWvX5AlP((t$`Ov)qxn$Z z#pJP*KnIEv7uV42b|fCbG$hlFWnyOd$lmJC!NU3m8XG=%_nti4dN`t!8%NXH-nQ&e6>#!4PtZAMl2#bUTT4Mp8 z{nFii&wLG?Hn_gOw*{+k=lpw5KLQ5?D;ky=7At=WMPkV|ioEP0H7Zc{@VpYKi?A_h z6yUk(dlzU5tuf%`;(Fc8oVM@axf>A0`nY6rIgE^r)}Lwevv8RjDh5X39|) z7lKLI{G5vcA)2k3*`&)JNzPw?gm@zrM_r7tdy@lzATktK!m7l2aedoXbsJttN(s4< z)?x?Yynh%m=VdpKO%}wsB7Q@oK!Bok|MRrUqP@Fu+IDChCF{)j%}k@@mHiic*$RMM3Ix0BWWNoldlxRm~b+i43N2e+x>i0mOAw%o>5X-HQo3;*< zCm&YTm~X6~>fHW#wkkzh7sedC>^WD;%^6ocKl@OUr66VX?1R+Pb>db=OqfNUPgC~g zYjXQu7**idJbIBGb9D$Z16g;@+ux3k7Ak(!E&N2IS$*$)gN(mZr7c_38Ejg{oD_2L z8m<%m&nEW74w>%(E-pc;Zc5?EL%2O9AjWgHomm{5XG@**qJP9%;_ShJmq$DT&J8F( zb{AK1SHG6i=)+b$)IYubtgy8C<|*DkSk-GUc%~eN)gpE&$ATTzuQAxFBUqL*){XfcP&{}-r=Pi|bSr4m151Q1I8Z1xOaEbKkwmb1P-M}*b6L^= z+FmzR53R~A{5&i(k7BgIUS9H%|03yUtM>o?rZ}r_v6POL7~QuaRiM7DT=n$zvk~U8 z|NS|`#?nl1<-JX94G`7gXCS*2qrxmY4NO?0gP%T!WPUbGf zBlt9BTQzV?EgTXX;i>}gm{IaxbQc1SlR0qm8DUO!szzg%S%c1yNe*DCVw*j{S zGs)fL6k;{`(?J}qe@p^w(zLP?lsL)U>1&NhhWPH;nVC_ zv#7vaCJ^!pw>U!PBNLpE)pHA+xC-A*1oZ8Sgxm_IfFpb>0La)+4CT~G-;7&0^v1*=C$(+^j6mJ%K5+SHeYuG69d2E~O+blhl7NijzN z#pa;GFobquA^91?BRTw#Lv)okwDI0m>$YsM8p=Jf|5AsCk~kRMN;1`iVcD)R(vu)B zK?Fkf4(6KMt@m<+~c#c#r^lWh4|A`-f)nU~5WqElPPQicU2Pl`8L$a6|B^D1AT|+=1y#e{pwGHMl6R04j60daFbi89p;R&AN%=JL`>YR z4G>qMNrWv>gY?HgCnhx0Ho<^jf=^q|Nij-Hxj_QNPT`1{(@2tqID9adx|JZNDnBq( z{6akp2VdlkdN^>?N%Fy-&52;V^=PDkR&;#+7*po^ApvJkP}**gIcJB|gm7+k^9N{P z5(Q5kkj5cg`a7YCib+~rlMZ6~&J7wO+|#KTzTnvhfue_J{^_*n@*(kB%mKgowXPGg zPT*$3k$}h>B!f5I2FRXbo{dPw0--vhm2K+RLlL{7{`s0LgdLr7Has}^Fy6U*u~;s7(g|%gRr^g02)_V71dIZ5ryC$o zGPoVRe%05_e6Td2Cf^1HU+;i}k%Ts+Q!VoQFu@X=7?jrN`^~|3!*uQiN~|6Xfly5W zf(TOepXBq4Bl9T)Gx-^7sk|0DK+(C5!^Q!l80hI}`pie3K<}a=E9+HGC7SjdTMm5e zasUN$4~6xWF&(1y2ymdrBV^q}9X?0F3X;RVV7Ll&aFM+HZEexxO|etZaJ>g|c79^O z4#P<gsdO~y;1q~O6-*p2E27A^CTQw8uacW6*-oCZq|~^%73Fl z`wo^UlbQ&eJr{soa63A)+Zq`LRx~+;<(nf#kgZpsAA7WfYE+f(A~)$SaVlh8geHu1 zqbJ-PU{xXU0p${?%!dHT!n=q1eGWGmboW^J4RZ**ZcroC1M3s2AgsALk=FGtp=|gx zG`x%Qlxl)Lxb@WE88}Qz-ZvB@)aftzpu!*T-@gwg+CDzA zzJhi%M$Oj~C$*ZyZ$YnC2kY{nJ!0WiW==>J$u{RL==(_;|De4cS_2S+BK}Y!Y(n&E z#fBF!*OCP#ax@~rgY>YlAdesfB)~V=R_*>v!b63n4AkA>;n_c^&uT+74!he zV$)65A1&in++|i3^5sG>;!W?+k!AIE%Zm>$B$1$B4L3khSR5PjY-CaY9{ULkM_ z26m)tsUs zO+$i71bZiLyu8OJz_}RN(SbTLy~2Wmz(aI&-Hfjs5fre&su4K3w$(ZomUwecxXBt{ z=0iBbA9WNr%PM1Ey@=kE1d{dLes=3)qi5HOyG@LZP4oJ|F|uZ;3a!MjpI-Zq*Z!O1 zg4h1gD)E7-KQb^dZ`uP>Gag3~4EE4U2x!h{xy6*7e+*~ENeap~KmMBEqvIF96oE&{ zwewK=UgEsp6TbdM^N4`5yT!{onJ4QiE!PXxRps9gm3Vj~KGeQ}5q*bCUK(-x@>2MS z3$H`uq2$IzkUvd@OP-3zQ<|HJnq4gOeI!vT`pJxi?f8@(lu)c1IG-s#$`PmJavf=m z*MZj{Xo-6&oUJN0Hs|8s3gKJFzPEO3-c9_FAvy7aV&p=;zm6hgK)*KrdVp8qmoN|Ne_XaO!IEklwH#7nkn`_&U%W6%<~v_W*v#9#;@feLeO}bp_OUidEk~;*nS&1 z8*!J2Ig3JBAr#gBbtBJpj_<|_Yg$hy2%Z%#YmO>$17k<=-hc~)viD#Bd!o@XCf+BG z*ZsDiZNC8FRW|w<3)_&Xa_HC>1YLi=D^Buvi__sio!tg#MYR86_K0GPfJgnu0(cjD z!xyd5n6fjEq3UadINxm_wkjD@SI!y(_CRMJzmk#HWd=uo80y5m_cOHb+G>h^LY85Suf61{u@9y-I%`l@4y4s z@$2AuzNt({>(7{HN#wMvfIHv4kb#3Zq~0P7ksk+>PmqNf3Y@q^*I6`@JjS4-NE|9` zdHMG3Thmpy?a9b@BdpA}ca6g;s3yTq-Y}jaNjd{lO=n|w8HDS61#S45=ZHTmZR6o2 zeQZiRlRE=xmsc}Mf|es~ig)uE4(h%B!;qFUT3G_TC?I!m#7pWR^O6N`6GpNu$F%z> zPT;mSo2eH9x$-1xl?BT$0H72!_&jCI3=Cf^g0YI^*1x5Rb<-w`3Huv#dJ+-Yf4zbS zB7QC?PS%ld62xjQtJx{P?vY_x3`mPKg*9k_?qQ^CD$z%^IXl&#Qw!7ercDZfQ1?xK zhHZwVsw@jT62!F$5sNprO1E`QAe1VJ*nt<6!RTwC3kQ~Q9ZQTC?7+*6^@iq$i0DD!Y~Tk?D5t{kfHPY9&dddr6qLD<#o@d=ejvsR7+vkxE8fw01I_?tox4Ld z1uJkuJ^+XjF>?V*tY5eqbm+=h5(jQIxN-<(?L<593c^T{%^*;unT91Cez~PlJ)~Z*2f$#qVwl@Tf;%C{XP$Os$NlcKUG#1pB21xXx`(2 z325oH0VqQ(n7Or-%O(j&k%88t_xOCU-?mbHsvVU zL(7J6$Jr$N9mX)`;n;*~yH(6a(rLy-X%F9Ox)8ZvaY6=;@?Fksq zfh3JeaM?-bYnqyxunNRZ#t9AUk-UN{+QgELqvd$AAhgPRd|B47e}QcrMd1@8BgP~) zl!iyz6>=CCmbRW=lu(-gaYPz|aG&t1%0`lx=ilC76tYod8Op`LVsAOVdLhm1;C(C! zW89MD>kC~Lf@6Xm4J{{TenE}?2`Mr}WK+1Cti5&Qv}raa#%#PoOEx*jE zgKP4n;zMCe2a1PmnxDUZu?Es0e$>_25RRO2?Uue#PiZtNI}uAtj1*34 zbEM4FzE>#94LW+-duqv9uI8bJPbV2ihh+tv%tP~Lk7qRMmYh6lvD4*zMxdHIC4WJy zi*O8sirZ_{Y^s=l*d)y@qZnC=rKd2BG5skGNRqMsag3L#P^^&?$3OPLU+;{39EGG9 z3L`H-RWeRrT9>#l@Ix7ea(?xzeP-Pmr_M@W1Z%M%VHTej<`(m-|Ig26b4*U|q;yD- z(HEhDD%S#R2dw{>-wPQse&?qDzu!qzDhtyz8J0J`kbg5@udunY@~}YB5)W7N(_7=b zIec?%_1-JEYB7zaNF3#7@;Gcl*`^EKHZkj>k0d4_Ag0;qmEckR{W}xs)y)UY)G=P( z0Bx(j6(6MrH(A}T0fH@^0~cBoJU=N4oI1mZHl}Gd&cAANJ$h8R#FgUCBYAc2v2EK! zloop#T>I5_Ai+1mi~j`6?XS#74zg^xs=4dk?KO;i+e((NT(s1L@}2twtBS``n0IX2 zr6puVpH#L!IS?HEdDgAw&I@h(!QkGoJJBU~TCF=Q$kM+oJO|qctCYTd%rLAaNV{DW zf%vvyQ)j3IW?IQJXV1P0B})d>DzDNi{&fwH;kpgwK)t#Hf<}`Q;N5wcDpI@Ry$F){ zL=rQxg@_zDmqKa7&7$YcMdWa66;-t~HD!^cuD3ii9B#)W2x_m7XHgD)>pgZ8V5@JM zn(he5fq&3aQ3={;!D!UPRq^mw<4cOSDg24qWkovChjQe0p$kYrh~44|JQzU>QbG1? zH(M4bgw)tLOjnhIjiCOCmdC=W7<2G1)Ve?4jHC=OMsUR-ublw#g*DxHsVdwnb|ir9 zc?Z2T;~R*BEx;7r;1E~IlL&b_-9*H;szeU!f7>t?13Zix!KNl+`}e;?%g)sLsufWc zrx3)Td3E|&kSz2*qIN$%RCY|0^Ax4Ax`O)m1r8tv@4x9SI=_MEKLzILrvDmVos6FU zOI2)RR*axTY{PMeRU5~Gk{16BfDSxFZqfUGUb*Np$@2^kXV;7+F*Zi4ZoAzG3>2kyVlev}$O5yx z<{Zj?F0l~N44}$^gyvlUWYLFk6n^oqhr*(1>8Bi$f1 zXaz-UWscxJCZlD@O4G)mU!=j~UWBUF*m`a=u{p;(Lnq|@xybftJqLl4KxBK3{DzL4 zL?B+ELj{rvvkoEK9qY-72RH5>qu>^^jXk>?Eb^Z!x}`^$H#V-@l-MnRwA9mUp-j~`I30&?a0z|dQ(e_ zZMcKI{TWb!{`tHxP8k$yC36BnJPQ=fzjqNOY|(liikvf0123sde!kF@M;@^9l3en`c%Schf-Fg1Y~pA-OBbPH%nU$;^TJi#wVsC_&9 zaKNQCc)conSJZLu-#9T6;jWJE#@nRJmDLe}!BHc!0l4C!DM8Aw6hIv0NQq+o{BM}nO{WQm|jZ;5}11)&k4hV|>xZgLgw(0>W zgo{X`w~(IHP!`YrbBARSu6LMM?$|NkOLVkge9bZRjg1+&;Z!AH zzU-)&YMO$%$2DK-WJtPnv#QHjL08}P;(>F0jVCBZcR)%Rap}&VVAyT^a4S&lM>%8G z*D%AH^^Iw6n(JRhc?fqeo36X_g6|F%u5ts8K#6F(t zRO^8IX9NFGf4?Gdr20we`q5);qtTw8OG1SW4fw9pdJl->5ak8=7QY9R(Eg0$q5MY> zLnlKU8BhBrelUm&g)X6H-f!G5el+^q*?b(xpsDqe=^PLlU?I|a{@{r#y`7zh4GawM zLoxFsF)dDr&Ogy>2W^lS&sS`}OqTIxl#veh`BwC~rA2qxZ5f5>IpwMOdLBh1*_U~Q z&F(q*w;_?FVZQv5>H`_1E_4|DPUqn%UAA=TrEVe(hmtyh-2{@G1p^NaAmFPQDc4j5 zeas-$lA==3jj7uxJx6uYCXK@nWymY-G3J#JitH>@8G1B?!@VZWy@I~f%+JGvQr}w& zGWf+k(ow?x!p4DgDcrS8)s>a?0W{orgKn-k7FP9;z`{YYdAv~|HYn&hhP@Z+BwUOX zMd1p7ty-jMF~;JN>j(eRYD8RL1C2(q;te9oLf-~wcG)%1q~kR#~GqbGoZswMC>3WK*{1+!l_nj9Y16~wPzgB1uG+Ns*l<3wTyP$LL?BN(2a+Ib(EFq+a8ism zk`y=&k6qxYU)bIK4zUcexq08ZZ4F>p7Kd@zXJJIY5J~et=AZrhb?nOkcc@?pT3uQI zJsMmap*QNGsw-({72rnFA2^umydhK^^~yuL;8%xjeb*E02N_Go7K7#OEtus=RTGuN zt4hIu{9Jq_l0<8`L0H35x^o%*FB0ywd7|LsHF%4R1}p{QdBMJbBfbxMLUCbu>a5$DaoSymJ zc@sJUq0J`H^-Ru<#}pWj_60*625H(Ic`~laW4aC%8o~t)9HeVXyMiR-K$oU%Uxud( znB>N)Qi8-IT_og2JsS2aLlWHs!IkxW>dZJckl3#nNE;g9jHGI^CTz-r*XFZ zGvnV{LC%doU$0+0Yh|ElJ%+F}eO4h%a96Qd{5^U2l@RMyHQ3wJ6E^hdG1?Ekf?kN% z8HK64t`!)917kIeW6c#n3S8f*4Zd^wGb+_8Dk^+1Roj<=<=`(ZOn&EhQxi;AL(Kh9 zWS!t4vZuwx#JZ**9QnwFHm|Q%{dfr9p*3roOE}&__=dKmYEV}x;bfW6$ZsI|d25X*5AS*y$2j~_eMG4)ppI-c8b_dJ`(z4SIXI{E}AY`y6o2Tr%~ z{*8!CIhJ3Xn3(wU+AoTc*_$E{Mvr?3oPY5(E+!^;;A0U;e+7G$jir&V^L;>#W18$o zJ$0txE`M$SDQvp;CnV}r0t8Y|IgTmGp$x(4%Ap(w?~?S&!7OWpOxr%Vn}K;h6W8md zEg8rG<$<4@=1?_BQUo1hXD|gr*>vYlCCMO8m%z|qc1ii9B@pCic@Y^p zJdQH~GBk)#K9Q|s8B7$d0NRsNsR0{seg*}U(-qW zC;#5<%`vhs$rdt4PMvKd5xwDek>ODEUi5W@Tl79ljSG{2MiQkOA@K^{YyvP@Zc7FV zRP_xSR*5B!I5t42u6PiG#UJ5RMOPR$$l*_Hc_SEq7G$USfTP-R!GrftLF8?kA!ik3wN2)Mrb zr*Z0DwDmE?C?(f%?%h|eH6B5^j;+JbhZ!gzDWq%N)3akaJ2NG$`r}PQp^xoBWr~Zn z4sgU$j8-pnQb>d~(mg->yTN!iPt0!#PMnWR$d3Wopip}5mCGZil9I_8A+kth9a>y7e3HMGgrf8)*u=&F~{iYfiAk@WzYCK$AUMNN}(~p6r5ifZ> zi4Njkv0_F19visCw?hAWbl$j z8T$JABr{%y2EV}x>=i4@n4O&^n2Zb!qUb|thl(=N)KX;7o5|4Nut^_%jJptvBVd9< z0`%JE*jL!j$(`#Cf%RC81ECW9l`)YLAXI51C3D9r3Z1C87o5*cR;ctnCpFc9UK^u) zhgcEQGE@&u?e6oB*cWUvcvgA?O(YitLIw37+2-{-2Hj>M*;A`rlzR^LOTA8n1m^?m zCPyG3*N-HOsxuF7T0eARJtxHt$wG{Y;r-ZOuWobf_;C{=uCIE5UD?FT7Alcz45!hX z`uf{_V#Hxb#(an&uz{lcM~sn6xJ@`d#*E3%OFb*ZjNTPFeQi&)(NnA#d#=umk2fE+vt$Hz z8dF4??bg(XPT&&`0QEE`ih1nIh~-0B%QClN81HV*K4M0-^sQx zP5UxnC#o397`N~29Olfx(^ea>pCM*ngnsqA;d3TFefXDxQ2Xl;#A-V6S5JEBb6AfL zlD@0o4HfVMW?s*sBS(+EM>}R}@_Tw(6>rY!Qi#IE{R0AmZ?Lek%Ay49{cV7p9`MVu zq6E}RMlRm+_D;!IstK38O6mN%Sr?boZ(qHNQNT%7Z^+vhZEZ1d zvVfP7ou8Ah!Psjy%7@Fdl&M(m$Ps0nwpS5R#0q8rm;XL$C%kHiz}|kB_~Y;r6hrf2 z*g7&8d*OBW?RKFTAG?6PB;fsOa(jfGr|8V7bV8&!&&?E_cPWKzrVH8lBFl${@k@2H z3kuLMhlU6 z|0W3_I4O{4$PDOxg1z%N8k_6^WtA`S>Ca)n~_}C;|l*?{u`p92&|;i zq~oo@=N^;tj%ccTIX9zvD{-%Qgnc0*IC$1+>J|@IZ2mJx;3KFaOusRG(>{MQGc!C4 zc)!A`^(@l}NL=-iENRy32E&f)SEE?y(OUpT5m>jSc{dPCZ}7f-E04hH2!~jbR=s@m zH}2FT_8dL*zXp@oa3^~Cn^L+&Zs|8doNJ*x7yTFk?nLZ(CDdYUK4+OmGp?3ajg1FY zlA`dPr08(ocP{!Sa7rJ+mFAb~8%d!j4jd}cd%@G-Ov86o&K8MUf0gyLyR*-d%^?;V z+*d|)uu#_BUphLT0>v=V=}hC>vEv%?9;Hc=jo}!S0Pvz_ziDg?Pm{#1+UFSfEUrf` z))FPX!8vR_SXdw6IoM4$uHeweW(1`*+zKH^1YzClLrj6thcI@Nz<~vziVADHF$BMe zrAXI55Y2EC<=WQpTUjd+8Xsx7Mw{C(V|amBvN0ABUIoBWYp{`U0Xq6@+^4NnK+_#= zk6%S0gx>2haN~?myPlGEHqk=p@vpCy93ai{zDQ-LMF?U;8&;!MeZAi zZ8q;Q^*y<&&95^2E&zbL`|VOs((CG!;{QyA!iMPvD>i;7vKL}WNF{;IS{4=-7wDut zB{Gb1$Jw#Qw_28fb%2l1Sy@;P0Th!lBZB4fQD}5M>*jE`VB`aPM&Po7S0f}i0qXwl z(o(4Thy$Om0-|Gm7&)^QoM?d$!~$qn{ydBk;Hk4G?(J zs57Y6mrG;zL1uaan{MkS%ZhvL#W9OrhHo)`kN0+{`Y;IytMwqqet+*1+_5&2-}}`u zf^KNuO3C~t;89O^+I#P{_hOHIBI7LS7Lrp9tYU6?N3r}isL9y{jak^0Hsu6Kp`tm8 z(Uyg-&qV5Fo+E8}9FK{xeV*fOdZ(sKuGmSzJC6z;JZdyN=hU)(fQb^e@}EX9j>~d( zPvC;Yl!G_y&BvDaANw*ybA>5dJIF1zkZbsGth#XD=hKUuJ*^W2buXUM%_wWW^m*xj z9)vRT@H=ogPCCKYT$-I{L&FLrt^e~K7Zq|>45UeZyzIkJ5sskWD6Ktz9_C#p4BT2v z7JgG17EK+$V2G!4;eV8IpL#KP+-`I3Bf`NA{C~lVQ$7lz>GirfV$g)X;D{|&pxgru&KUX~1`kX* zJQH?Ery#kS@NmQ1fJU;$^)reXeZV3`Tr%-MAXt%*t=5B(oR3bQ z!8t|S9=J)g+UD+@3BC3>c%5;uZ>W8thE68|#}-~>dzrM8vvW`B1^AiKydCAM077GD zfPv;Nf>6AT37_3Nh8T<2HG%VKKEc83;Q>*7eSvM3fPTT?F`Tp zT(9VmmGQQD8P5#4&#%W7>+8G7qaF#+&w-cAs&$~>)x~O93*z`bB?@N|IU5m7qQp&z z=kcDq7j3!;Ph$@(r-TZjz-gpCcKFj^5(vY_3-(S_iG@628cDzzpP95(Zzd}&TTRF& zvVRjkFm-;h2*6#JgC630xtQG#*3t3to*#`c;N>7SyM&5+uVXM6$L!{Z)#z!Fn}?0{ z!}+%3PamMEbOm7-C&Nhs6r8!s zO^8es=N6+Noa3lb-&*4nxGJdN@mPP48qT@Hs>?5KPOOh`LwA+dWVkc^XapSTjK1zrD!RO$FTj?2dtM_b&En7|8`N)Fsey*Zw8_ZZvj(!MirjU zi-YHh;N#Cmgs0WhuN<0<1n);cuFmRb&#uC5?bVVZ0{*ZLdP}ofLjrLllgX19)qH(T zYu%TPrKKQ!>kuqs*|D`@mx`qz7RO8DnV$TCjf4c~G9fe}3XXqvhC+sQ!;v`NhlhtXh9@JVq7;$0k=+^mz>tZ*mbw$Kt|8rtf~Cd( zI|EBC)r6BnF$i5Uo@uZ1kLR%LteSI&#SXg;4&@i$y}KEt@VgEdLe8PrH~c^By>~p; z{r^6EYD=QbBARAaLlUX9L}p5onUYavHWd<)GNK~8>=k9NjEt0(S(2S1d-FS9uIux? z@85m@evjXM|Nr&){Bd2M>vTHL_xt^Nj^lY8$5Zq)#L%&5V${1am)T= zfYlC6e@C*1UHN&@(=enOy&7x^ygUs`dT{GQhC?Urra|O)3ZlBw0z45$^ zOgJ&LVU(r@>x-N0P`Xn93LWt=22Kola<;=vnz0uFP|@hRS)}hq0~m$=uEHt5wXJPX z;M@kvb~$ah1z@2b28gBt-H07?(3MS8-q6=4>~#wP<34Dwff~iK?1Dkn!CUP?{B($R z?}+6@t1jxRYWUgm`yf`Pf)e(tbQ&bo=cMqpze7gjy7@4>?A1*9i=z8tw7{_@_;Y76 zuLWX*?lJ&%anKQc7jznGC^)mq0--C%yS&O$scFJFe(vK#*JM_Q?vR;{EuKXWGk|LJ zR`FVZ$!`h!0R1)ROoorh8ogXhGurz)37l4Y$6)}~Oakgy4O=X-O+$gxU)l^8mu1+{ z3k^*QdUw@d5lqBn+K>h_8;tQUSiGU3FmFVHrmTl02wPKWd(|g&>VzD?jcHMcy!s~rhtVC4Fw)#Gj=Ty{T2R+ zn{gMkb6_d(tFt5$UalbxBFrSDXBfRwQnb~uKkk?gChbhEQWziX_ zRgRxnBN0&7l@jlMM1AUjr(-aA1t!nP=XYqB#Fx=-4@IxsKh{VsA#c|Gh3T5-m&NT| z1o~D;(44?CPZ!Ay(kuM*ueupcgx#Kl*AIv4RK6IMj7r6R0EJTM!fAP&iSJogJhd@;W<{j4M|xdyEsd(8y}_!ze?n^#@LcV`Qi@1k3y@cn?1!Z%Ga8& zK1Z%3OHnBOA6%&^ch~TUw1k&FawNdsVdI6&w-d7~DR+;ee4?mP3uyjEJw&O}87vP; zY~rL)#xVxPAH=!?PPk#KZM-5iWSqB%bvAV5(b{_VpqxMNT1wg5iLRQjgLD+iEXqep z7?s+Glh4g5+7ftqx|*}Vt0pRnF*ONa2R;Tpx@MH!TpqZpO3((kNv8rm{5^CYyjFAA1VHH}~-ZVKmc>o}4I4d6dFmMED z0-n~V>B|y~Pw_d%Wl!_+9ES#}R<2P*edVUxZBhWi$9?dOxES>ibWY5<1mV0X!?eS# z5_CLOj9cGA1sc8pFY^<(^Cq61Yhg_WU9th-Lij%Db{cFYVfMES#u59Y{@g`O=_=5o z=j4WjY+LA9S_rLKBH@wY%=WadMwP%n=v}e)Fn2=k~V*j z34tfTMbt;ewmWr!Ug;wwUWgU|L-Hf=&$57Wke2JJ83AkN2}yK*-Ph(~W{XHg?JDu#X5*)vG4tFK^DN7FR1N<~XX06{DaNk9v%Q9cM| zc*!d%=Oh+FUxeP!bYc(zeM7GqQpr%)1cL1vJ?yx&D1Yeft(v|~3mzyp0O5BVeg+LP z1)QD1(z7x$I&eekjw?q!a@o!}K+W=WEe`3w9;27) zkTvVHy1EVVs^=DpCR~@ zFp1{N>42V{Oup81uz|taRPPF2k6cYnP4QuMU!-4bpAP!%1o-2k)xA1MM(&c0M(t;O zcfY`LTX44J1K2sFoaDe33;3qsyL%RPFscz+Rp{B!}D-dGC8ku z^Q;vhFS25)WdTYoVwHYLfbNwAw)c?5TWD}p_qZe65u)|ADGN)>C@^2+d{=IQysFIr zl%2FWe6H&2Nrx#3zAYCOs8Y1iQ(wbaNaInaPW|_bFuEcM)PinTBf9gaXoVicp9j1| z7SK+R&F3LTsj545kxz_~7vmcAK{_X}F+X7}uxW@9kCS%2D58UDkmko8wraAvtTh5? zr!m@#xNf4&x{g)p%Y48Mg1zysNE;SD-Z)XQzAgtzYl0`H%kVRy+&?>m`nMH*zWE1?^znu|fSG&VK{IWt&!grXbQ zO-1>IV01SOT10a#VeR@M6cpHoyMM}5`8)`1O)9HK-&NqCnd?DGxP@sK_E^+r6Km>X z+vb**fs+2#jQGE-)a%zPr*o*Aq4|%TRUP17i^b7p-A<|}a97;Q%fP)(w807@NN|c5 zegUht;Q$SycmayPV*m@_Kr`nhu1PED_=yq3xy?1ms&H*!)vIo7RL#`F%r(hiBX~%s zCp->nSy0sWA6Y@Uh5C_^gX7lFfn!u&BI0CdD$w=JlUh)zbTQ=Qp~DaAHuOM{&wWPd zK}@blf(P?#V^F5yxQB?9O1xykz0KwE%C-;deu~_dvp1ZONLZz(%lD0=Y?8W$jq(f+ zH)RE$K(9BQYEQu(R{{wytNzPgjrO8=VUEI98Q*I|jD;&$kH`z>Q}%+ML0JWt{jcr3 zcZ+d@^@kV_(6Crjv}J{P*GYJ7<7Uo^#p*d4!M85^XEpAGdu#^CL7!) zDJgQ8Cei;zf+jDrAMbyfrSgCMQ5|2k%LWQp4e0)13sHpEu~`4*^IDs7Cx~$s2Wo-B zcgsA*4aKF~a@TiJC4?|@uQqGHNrx$ViU8i3LUA!QTbo>LLos?&T0t#)bSS;~Rj=#6 zf0vS?{8}>@pGZ?bv8zaZP+#y_`z!U};A8f`>dx7-`nfZgvrtU6DTUq-Q!aO2PsF+5 zYS@VW>^kV{70X+0@}Z3mXYFvD+E(@PqhdM-`iulP^PaHP0G`E7>@YCtk5VK%l6lnW z5^XR6e+k8!;uT_yKz5(jO5i+`5s%v_S?)4Bh<^2_t=c27Cy8)BTof!v zZ1e&KMBSqZ>r|{83$x*PjbVWv2qCeGR|(vVaKZSAXhcy%pXVVjUKY4wDnZkum~+R3 zSjZY|#301Dv)B!b2_eeHfxh9{OGR;$*4)1`7T0q%8m=*zt;{my`AflL-w=m=Q=u9z~O z@eTRIFf49k231r}ZUd8mdPBd4KoNT2n;=4^%{gKwA9vI#2aZl@3fqw)F)=5DwzzJ3 zPEG|l8g*`ELxPCw);0kfLIz=)-;`6vw;!B$vM2@Sxlqa=PFL~GT77)7Bi(lFddmXI zBbYiNFoFtFSy92e{43a|0$=2qa~siwL_$>faT2L%Klt{`;qg$1gETzn{XccV+anrt zGuWR}Vra+#@qZyag7FI);aZ?LF$njbCFx9oLRznpkpsa(IF2VnX*ZX=%W{%=!s3)c ztN0OeJkmLl%O&@Wbq5Uh$W9oz_-)6&%a=#CEx$HJIrGD+V|O=O2f>i(30Zgx2MopS zyV|Ul79D>9iUPFwoSo*)@#R;4T>dz6A;Kf0qY+U5$4*YQzUxId0su&N^aYn;@S0Fb z`_n*yx0kWX`1%hYsk-~+KU{!@vLY8$*vYp*O^Y zFw)o_md2jw8=}=Y0QQHW>Z<4^uK9{cJ+x(zcWy!3|8a7VTu30&Xpb}=ofY(%uL*}d zf_SC*)qDWLK3>5c`mq;AXM1MR1#BpT3(p>6?<491QREjiY8%ReBy9KL%p?~|fbSw} zh)cajPwf$0;Zy+EUTdpIP68!BXULMOurJ}fh&w8rrPc5Q zvxbE+e9XjUSclL<%gJ&Oz6o%+4w6JvSyWT=I8h@@IY8o=J-X&kyJdcEWkb#S8-#8< z5kmfwECU(uG6Y{+4AsT(0ZSaK2}wOUfA(B}1o6;sNJjJ0_=vD$!<`P6pp`oE0PkJI zy0fnnOq?$T>@1ui{^|8GBWvIX4ck+vb6jmkl7t9-B%N0rTbTty&#*cS+BJt8u>m9VX;RT z`v||h!g1bmP*jubknR+Db?89`+NXVSl3<*^HsBzH(<}utlwjXA?CSo}wW=y{nQcl8 zEA%$NJ{4TmzD^YAJD==@yUh}mVYJR4;%E3@Nj zo|7A#sn!O2ZQ(!XBQ!Z2m3`TQ@@HRpb4u@ser&n=cZq7NA?2NPSwX!I!`(iw5J>IK zrn)PN)+LOdcS21!<>)z$ReX~9!kSd+=e=c=uUsDluax45xX*JklU0QyzhP;u)+>rJ z4VO#+c%uIw|C`G^kI3PBLJE|3tNo%X)BdZE0=n#V+=-yl4~uulrlA1}#$xnpauD6l zK4Q^(wvokesVI<}(so})S^sA0q8QyuN)QV&<@%@0LS=im334sD{O{ftJYLrQm&41Z zi=(JnVIf~QJ?kT45?(5!EaNNpSTD&eyu?;b@U=*fS@8T?6GZCARFp$I_uU-B(9)VI z;W4<_6$=q-0Avk?YJpymH;P)J8huQBE*MnE0dWm_7)4hD0ptJAs9klG@&^O{z2wo} z$_6qLaiFVxgwlE~3ZhFJz%!lvSxU3NA>9;K!6IkQoJo3@^8Wn|D47-a_@Jqwo*2ZO zdt5gi3+d+O0m0}B(*e~QVnxh6$SU0}(GKcC-YBe1^ic?F^nmW!43p7u-QPr`rG=qp z;xcKoy-x>k{tj5s@>3n^eX<1HiskcKEaTOA={qG?ZsF4d;4Eb8h(9gSybmDOd6uf6 zhaw|tG}4}>)x`!-4#Cy?%cU!2_d!%krSUquH{d`RRKri zJks)o+>JtDYX*`|^yL`@jDDc!7X@%6@C|E`7-`s9PM(Bg@@jy|7200FVe0_t>X$d6 z$|buE-7e>yn1aai3xa@0%#X3tK;8yW{izBN><6@@z-x0>Sa#9y`aGM92w9E@LVVz# zCQz(Yw6(*ESTSpk1na&<0?xx5o?%T@Br=fS!}Yg7xgPZX~rJh<2R&3Ax#B3vkSXlySuL?V)!UlG1}!m z?3gC0+QI^k$PtTlD7mSw=GirNtM$_3UI6iZjV?ckotzBv6SijW?0UtA{%Q%oQ92M& z;^p7hs5jLD794<>JrWd4i#PxDciQyJ$7QqizF;ZmSA>mvOtg0b5=`E-MbC?us=<{e zU@chBdstWk+XaS=4jp>$pa)-%)9-SD=YeZ2+QEteZym3nRxY~L_}UHH$82nDZso8v z6kz%i*E@nH&&)d+Adf@`;T3_=xvjI9r|~jBAV>F4u``^d8VIq$Ew^V_eS{*?PdB&?=WXo$DC@+NKc* zL=zqK{&FPGWMP!pH1eybC*Zah_&g!;l0YSVZ+l^^s{Sq)dI#c>F;iv(3n~3Ja4ZAB z_bYeMquj0ZS3AsHc#*y@?)QwzIf*@e7zuLqg$MkBFE`hFcji!E3#c7B&CI|E3Sq^u z`e%6y3@%;TM=^CU2Ce^u$eInTg(&b7Z0rl2v8Gp`fg66Qy5#Qn5{EaWVJ`pjgv)Q$ zK%%+j1>`Ih4-R!HkcpS_96);$;HPndoS+znE?n8_sw&JiEiKdKiQx$~IOF*e*a@8< z;pht=YfSZd{mTI_euOfH$o+w)6Nur271$Do@&J!XR6V!^J_c_m@LfO8C6m}<%Hg6#H z09PM9GxK$G4)vAboW!?EF4)p?kf>lC}Tlcm7LA`jR3tiJeMWI-Gg zz*81turpDz)yOp6ai|Ofao6%^yJf^}QJ$2=NN6_VWOYi!T}n=3h{XPuVi6*(JvFzR zm$xFu;?j2+9syPnU02framay=n0$g2X{b_p1!+(92pOWg%Ze=16T!UDQWxvu*OeR8 zMR~|?czR}iK|6|y*9;$mCW8;%*1R&;uktYk(4LQzvDXI7{yb3Z5P;$9AYQr=)6=+thUnsn% zwO&I{gTFjJR>VKfeQW3#C5&K-c&DSk)3dL;XN5^Fx;)}dIS49Xo87|kw$aB5dS&qk z9g{k3RxdYqNX1z5V&Jp%Lw7?%ROyKRV0i&BNM!6Ia+o|faTY2sXLMK%e5B*5KQ@>y zmT$b^V1RsGr7O_Y*ledJyFg`3O9I2Dd`4*};pc1A-;np|lg6}J;LA_58+-95nFo^_ zpkLG80;p2);ooSr|JUE_U^W=Z>~cFOXZe5nY_vu}{Uq_L@hyK>V5&1k*R~pjFqa1= zhSHhjEoxs*(9hKc;i~OEHN)K#u0o~niYh8(44h?rKNb}o?^_Cn;6s;y1*P=MOsn6& z|E6N>KHK>HyJju>25+Xrms{T~KtT=LyA zX)n4O0RnV8xh*xfwbA&z&n1?-xy!ccc{)aKLBZ0%pDJt(^vNcWia)5Ub<8;o0kC(@wt#j`p7DUs z)z#O~Kk51It|&9Lw7iCy$k#_?$Mv$WH6A{RX6)VzJ9nkf8C;u6B5s>4si^P(6Hq=t zf-pUZawTbG0M5Pe9Kk3A)EyY1g~SVjuyPHJLDM5Lza@|l6Pa7X4f2f8X|w}bJ`?cg z{-kYBoQvjc{=g=1V4HR!*uH9H<=N=p$w}gZNjw%eU^h8t3T7GDIC=0>NK!A{;~o&z z$>bOWDP)W59VE;=vcgIqlL(Ejc%keV$)7TryjUb;bTv9=drBeQ__ zZ{O;nMXlp^MhsoHru*Ck>@kJJW}(yIm=o8z$`2qL5inS&jLdzO*;zR2X($KSjOi$f zfhDX?S7{5Y8jhTFaCGF|v7;!86&aT#em`Ao{I} zMq^G8Bb6UZ9oSwKfuNgn=K328bP^)87%z`!Uo`6G4xA64Rl5)8El<^I~!#T1MbX%=Q6S9(BkB z&K!Xje(U^sdkj3zgFnrG+NnH#Gc3^0V$}8QTQY&@fs{9nDi$NEpG5>rn*%cK4UPcK zj$KvnbW7KZLlgSji5THybi(Q|jA2j&X8A3wxYrTnvOC-c7^V^W90lZd%%og~LA0FN zW`x{w0HdvzQ5*?kx3I-Q2qrW{hRa4AsK;S;vBlvwxTfjwCu||=bE1LY>Tnx~KO+;< z9=0xYl~G6uRYPkjl?2(NsBp^>8ZazLqgc;8W)H_G0TW361lxaAt$SZiE>1HQdg}a# zGg$?x*4-0PCD+zoyxas_YWe3Nz@;#H1g4&w8ImC5D4>o6oATaEj0OOw3R$s zQx}qK*7=-qQ153!T)2kKcPEJ(26*~;tROp~$KDRc8{lk|r+KVE+X+!L=^b%6Lk|o= zfNeWjTB`sa6RJBr_L+LHJGzqWfDMCq-tNUq66qD%;<$9T&2To3MJm=+O&CT6?u!L~K6v-h>1#P0|+2@K19l&WJibM;QiX7HgM$BL5ez?%NF4Gz%!FxPZ z1|VGx7_ytL1FEGpp$~LD!Im9*vnjV7JN*(F^w92}=y7y(ybP}^c`uOqXi9W8y3UQm~f@Qvd!YnM#^b2 z$)G%?J0txP<_r~w*&$5smPk*#Jm@Ne^$(^S!Gf*x(2p$AlO~k$*JM=E3D*(6I8GHtW6-(W}M@J_b6M;x@O${O-FqzQo*?Z+(b+?`g z#u_igG&`k8>;KC}RUK*yx3QQ@$*<%$pa}0I{LL>OI@Qy`2aTRZm=JbM5R&RNs zWipD;l0I?5b&QlLKW&44VG;%$o0;30a*X)ihS7^8=tPL6mpl8jYMm?J|Js>V??r!8 z?!={RN2&y>$23;Y;~g{VlGWk8qdu*%l47>p(w}osQ?D;|+5ClLNof|c@GjLy3!aaz zrrc4N7+UWK0-MRZ@A+h6D(kkKl#j@5mr@Uw+uvu?_*1OBR8Z}R0Ee|(1tGB+-PAIg z#T(l$zp?tf@`l#1(uxEBsvx7)OWV(r1;TfE zF=PGrWvNE$muUnZ3sIf`f<_*mD(OL)f7ytkHY#8juqdw7gpjxKkG42#_;(ceSZtMen&bmLt{r!YwCccDw zDjCiSlQKqn`X_VhzPp#%YD!pa#|LuDkP*5lKCS#*MK6ps%`Ggd95LcC<6Fk6F>OH! zpT?H=7rnjS`oyU-3a*M`*091Nzm0=+zlVQis#nV=`~S~irlWAk$(*H23XRl$H?Ky z{0O9WDg*6UO;*SmBzm{WKC*rz{IfCOuQ*uTo{ zJqFnoXI9FC<*{>s8^@Q4TdK*LA^fK?RKAP_A(~!bh@2WapnV}v$^nsP z&h0*Mph4S(qNThLX-hByE6vo!GPcJc-o`2if(jeTzZPCF zPYC78e{F<9wP0WYf#qYZ24a$Rb1cW$jPF-5B>`#0QwA2 z=_Vv}X>&5ZC&{MLqA6%CZ=#4xn}MHP9r+6R)~GGPPI_X@L9{rS`XTd6NCYDbqSisP zNE8MIt)K&6mwa!yeRhVhSI5!}q7Y&<6ms4G_>$EFjB~k?Hlvh!qn` zgv!Oe7PFxA@IYjHrvOkz_uR{$z++&rf1MD_A~1vVMNn0;y&r`4uEm_<+SDNIotAe6 zOW61{0k2@2UqaSa2UpQ}=KkX*JR)F+=Uf}((aaSCgrhKdV+*dmBTViNwk$xuBnPu1 zh*?35!6mLJBfGTzeskL?_vcdLvgaYj6=`$mYgI6ihuDOoxblC-Vz^3?Z6bk2p*;M* z6)bERY4Myq=OEJb^TjqY!TP5{5etIHkT>Oal5phr@1q>mkN`;i>XqDP; z1mLvyuo&y&iz3j+rfwWZp=pT$NK02n7%TjKHJtB&B%km$Oq|jjR(y5e>cX^5eLu}+ z{vW-&ZEX`C$$fBgWPaC{VHC)BSj`Wabw7qcNt5%ams@~R0f+pa_cBKTYb3RWeJ~3* zEpNt>Ha-(#IE%Kr?BKh>#`tnBA~-oR6g(X4COVoB>m$Z2F?4QUD;Oj4=C9+|rF;xb$mW2n5)m|)OFmRj10 z;A}U;`Ki1y8KF)Oky|xd5Ca+=IIDJ567e@#i7ZqGG%?dBgOusjdH|K$MX;>*mT(zh z$E;tS{rw+dqBveD1^-W2r@i9$0V^gAj!gAiIVpR$l4tC%!!efhPTs@WFEiwWsv%JC z?_&X3Eb(g2#Sw{wQqb+QLg`1$=fD?$uHedhd7A{Hi53@u++o*+?}+v==v1nG_Yr*} z8Cfq2*a>E=bbxLTxs-D>?NugFpoxoMY*z{!6*t|zYAMIK%MfOSE__EU!&(`c+IP^L zG1#RsZ%W0>Qen@*|H6GUY*~xW1qupW2*hZq4pt}QVDHm3Mj{+TBfImx10-nB>W3;4 zPrWq!6Ti9-C}S7nFA9W9fCv)FK(0wOo?RaN+kQ*ky>N~sjbflRT3O-&;xPg{N9rDW zVpD?gTL>!&ONw6Lg`}Zbgslce`!KMB?Z>)TiWbnAsG#n@iu?(nEgfb+o$TV)LkVP{ z|FguS_z$m)F9>aCX7aO1tl%cZOE*0PZ`s;+HnZcgN_z89HLBve;Ilj!Je0e7!U!A* zw>Gk$NL+--KG-8667hU@3cf^23)ygCPSorB<}P}b$cnQyJ^cvivRSJ zG8LT!hFR6QbknCMzr|9&j_4;&{3HXFs{14B|DpQ3t+Ng~=JX}G@I&j6ut-40*GGYX zcJ@9J>0?7K>GI#2`y?8PL(V1m(VlK=}9hnac_-b3{I025-=jw}~qfm=z%Gw~KuG?>jR?OAIyicLcn6B!WRqw~Oe zds(3}j85SCsj)DMF+5x`aID)GvVk+Gwi3(hJgDA4oyA5D1on7e_sxW0M68=yEwB(` zjUJ4J9_El4lZkK{)H)U4l8NpsS^!Hus)(ybz!@~i%|L{S!zT!%*TA6H_%j2&+>0aM z9HO!77xC8ITL|LScQ|`_tia(CfOKmtiv{mMr33LT{=-FVB1n>W009~Z!s8@vK8_cF z#sP6Lt4M-K_J_K#$arRrp4^KA9`U)j(_|y0<_tmD(dU`=D3N_o&Pz_qk@^L6uFjG) zVM?#R@A!8*vtD1CEQ>(=3DzBHfPoreLTz3YP(2Pvj_4P;N)@{fOk-4s1!R4miQ`w- zedU8%4m>`=94(aK6^Il+?14n3k)o&fQ$&vmWO7mT4w^M+!4Q zvhSJvCMxZ5d@xi-qQ*Q9Q4)>m>LECY64f6H&kgy`B#(AQVJ_GG>z5(SKe{r&ae?gw7O_b!&8vt$2no5G zZ|#C9VI9)sH9ZV|6!HD_r&dx1(GyarUdsoORz+7g;zSFjw%~pFo7b;jFs}SBQiTx- z5PP@3k&wHyTwmSY%3d8pxhqfqFm(F*!yYhZ zBmkfmRtz03jepM93;=Q8e)9KILg)MSJuio79iaLJK?`3V-5Jp+7~1}BPIVcaZ_Tr} zc424&`92+;bjzsWlo9suG=)-wYIo->)Y6k6FK9RJ(o{ z{hB_0#|6j?tmJD`@#-0Ts!19xKkNZ~b!P9X4_f`4rXCRG0Fq1E9B2(H%hY=oHa1xz zSTWv!qR0^DF3?It5Fkxt4|7}InhH^PO7`-?X!Ns-t+a z)-HpxU0?+20#k#O6jPmye&jyD)QSOiYJUF~2uYJ5C<@?`!B!5gFKMLtDuo`D6J}_s zTMR32U?!w7VQOlsP3i>x(BR-|;v2*i3CE`2@I+UP=D@Wl{TNt;h_b&?^$`}~>JNuj z6Us#crgBI3tX=FOsCvO&9X!l?i35QE%9LaaC2OFvgoMFJmavO6a1i-W{uk#gG?cO< zldPh~L5drZ7yhFvg(69t2s{ma&;s$kDo?*z9|ZpiMIs-r^$-D;7*4QZW85syue;#1 zaq#wc4IUp{n9|S~5|Nl$S$X`=V21Wj5rp@W<2j8Mg(=bfpoga?S=C8z_!-z#zuYyG zf0nsiOJut195 zlbG#8I7g@e21{7;jWJpjgmXn`Nd|CzPw10$VZ#B~x6964`MB-x)(qL0dB~v%;p>Ec zw*&$Y7-DXfWa|9dV5{r+ZatY>5^^*33sT%NtWCVzPFT1fR#>+3@`=Jz6) zJt?uyn45ve%f%& z^&=kEbMuQ2YhoR9L%Nzh{AQe@44wsB%+LNF9?Ksd1GOPey{}Jd$+o#*?b@}e85z-r zY*O=`bgBYNVwbO6Q8^&T-+*r9hj~_%vx2<5u9K5yqiDnT;f;@45j7@7*Q{Anyr@v| zH%GCeeRwk>aZ!JNOq>;2jnp`GWT&{;8o7rXH}Owd21mhVS@dj>N6{(Gg6G@}pZ&VL z=J1g7u&?Ag>HbhC^50i{Ec~&GcO)~EJ9cr=XKu0jq{Hp)JH^#E1krEXneX+QLyN24 zT~dyxUUH~UCaz$qD_?5=rVh4;4<9rC`#!PdffeIAbbh9}PWu(OUU9p7NXlW|YTY9$ zh6w4BKqYbc<`28slRK*YJo+khbmFMcB_Z}*! z2&btQ@QPuZ@*`g` z6RR@^Cd>q%59N#+S)n|}$>EOqPaP*69rNN$92N$(E@jMjMdjsf8@Byye<5*f#K)PP z`O&G_DSTdU0Ohf*Wh@2Lr&OyrnKPy)v$Mq=eyrqNH&-C!&`A^b&I}4VY<)l9DDD9^ zLubga!<#rOvStFcYIHjL$*8->PI^+EtpLJz&va%~U&qk!S4=@&>V8pCE|>|)q^RxX zJ;K4*R#)fycX6sftJcY(W9~aQuIVXbIOm^$y-`AhiNoaEP^RB^>`TZK?1~F?s%<)_ zVD88c`gKwI&hyZ@zYnW5*!=8xWbHb_3Y6Wlue7;22;V-@K+9oqER+TFlse_dm$V#J zM?_}GMYLj*nl7SaBqV#bn=>3xycWNaTDWtlNRy2R^+wkii`{3RC_wO&Z_$>LxzXpY&j@(>zZ{e_q|2eBmU-0GoEydT}r+ApI>M}V7ax0j)1Im-73V6_roVFK%G%b`e3=@8r#@_$u#>F5 zZqZt)^S0&3)EtB04bhk3O@on(@&h8UJ#)Pnud13~URzVMQG!FExX0_XUbW_>Sh1w% z#|G^0o{l6^$A%7D2@aST>~4p9y)>SSU;FraOvQdo*f9tO;^_r2lpf&nP*<2VBS?*wohcNNX-b zOZLj)hdiI^p0K#}m)yT!qA`EiNopYMfKnVT)6tm3fgR+l9y(a`Hv=r&Q#yn`PEuHqihrh->P-+a@D z9r})(xOp=+V%Qu}LFdk$$(TpMqM|R)+x&`s!x*B);<)?;Mo)m$bu|3PXUsK=h~MoJhIPM#m1FBNi9`eK;jndE1kKNg}?P<2LXR;jdU z(EaFmcubqkXZ!Dw({>BEwbm&ioF57c?|!MTkBni*4wPa#=jjjlJ6AeppD8LThQ+X> z4rWTYXjCGqX*aN^w7mP{zOBq%YF=jt8r??G z?&CEiq^oym3$GK(8&^K(Q_TzN#~Kn9Av3s=od<&iuf^gKj2W zG+NX5e?Ipq2?bZ()uaohb-_<<>J-k8zH2}DS64I5qG;SjVwudqVsL0EOI%#sg@DL} zguRA$eIM@Qv~Y zZ=R*$`QVDHx~AsFmpvb^zb(4;KECzAyg14tm$p9_GiYZPZt3Vy6=^FriefKL@nYhn z`k0M`8mguY`JJ^xe>{whjd@=1%6P-RSd4w6>fpy=>-hM1&+7x!d!*JNF2?yL(A>WZ zFZ`4xl{sU}oNqS|CymAs$zI9m@dx3^-OYL7?# zJZc#%In*Kb&9|lC`Lu@Yq(tY;DN6|v?GsVONXeEBr@|QLkp1xwXSd{g;a9Hd_KXXY zUuo=~+y8vQ-uIP}M8U(y+$dcxOi!0fIW7MRo-5mbekGb^N+`sVJJ$S#SNX!+n->nw zM~CL7%$62UmNTK$;$viFjI#0+7uV35tqX*owRJ-&<;jamF|D$?M{|Ml+2xWv(*VgW zkMPbNY8f_D&X=m~!rr-^Oc470t=|8c-AaV#)GOyjTVxJSD-nvYJN2e*dH?w>y^Rd7 zv`&_9B7cc2$(Y6y+~+03eC`($Bjb;b#XlW?0rhfNDJgpj>7BHsf39{|QqE^?O5tFy zFm?IZqkbEdbUf6d(Vm&9yfDt@Uvlk9p*4?yyBxXh=(ZKwi1$ zz?T2~?o_6;b41rU>xR|a#gm+dr<~}pOP-tWW`Ea@mmTw5M<-K#wpoenJZa>iGG|^I zm|7iJZ5CY}$Xh-U*7MOn?1xgoE|q-eIQ`10bEgjP>&(H|s?|HaJz^!P5%`uX2g+Y= z7w7!(Xd!B;xt7lxdxDAojA}q)Ow3uBx7=zLUBs6?(v>fmi77;NE$~pJc&24oja#wQP@F=R8 zsWVr9r_U78IfWT&k?IP(1f_FTDOp*(4zu;47gZk%InPuTL;9WWot1UC(~U(_F~ggL zU!5M-En7B$L4(Es=(c&YC@dp+VM)fL2@$g_Mu(^IX>5C#RP_xE4L2iqso2T2-+E83 zx~l5oql+UxG=qbKyaMGou76?56wgFguSXjJ`GnxO%Qn0QKWz(Tmi5KH- z9FZ~LRlnbuO=@Z8vuZ$iUfxykIF6s2dQ(5Zm_Hhj9K%=s=I8{kj)lek=$`EnAF!}o zX+5e59ew>%(_>Og7C1C9b`M9n9i>*UUR``Be}tC&CzLYocJgux3N%~2xpcN1-0F>l z7Q92*uvRjlB7y_PZ`uRS8LZGN`Y@5~7dM^5P>z2#FZB1omW$D|RV2#`Pfpak>Vr=Yf z=t9DeJ2|`F>AY`q%g;Z0s(d1JaUe8;qv_M9^QWljyif1Sh1VFe(yw1}KaEVRtPcJX zz15MQXv2n|wQVyZncr@8KGK?xh*+4(pUP8c{`T#>>|tZkmtR_1Vq@4*=1#3D=-^C6 zsYqKor^3-sAA2~-$jAtZsEqA4PwRss?XzuWR#_UwoC~#_yse>}vtQhcSNNT@%r#iG zW994T0bVv%76vUc5dBO@Bomja#UP6eDQDk>@JiKaQw)wWYQ7etDOSiihtZNl9<4r^jnnxfDsy$OTrpMMv*Z9egyU=vrPG=&73lTw|KWe0&pKLL zi-E3tw63jXe`68I(`b3-DrILh^l>O{-q=aLsrLZOmlmIv`O#{)6W-+cR=ar>)vjH; zQd*38`1pz$6eR8?B=nCczWnr{wpNL9OhJKe>(;IC$I#OYdhy~u`awU1qaZQA8PA5+ z6NReR>0Ky)X40L$mX$qVG>wmoyRVt7FxXdHAtEe%7vBXAMxD=Zyi&4EwiaWzf%z2` zWnyBYAJU)9$DjNB?yo-`DI)NBCBFF6r<(@$zjB;x@ppcJW|tjVn2LhBQuyU3&#zas zw9Ys?OHqCR73D!!aAk{+%dzcuwS^zzf5*1dPj*eseQ=74kALdt7irUm_FP(8I;HIo zemN#41}(OXOqL`E9s9<$M5`;DXfR9JEYbdwVuq z9n>Mp%KD!V;LZjG2fNC@`H=H{A}O;f``fJz8#fjYSn6KCzD7ZEg3;@A*N%Ykzw8rP zvX%|3!r@+hBR0bO_TA6OI0$HT3mW6NuZOmJ;{xArG<5rRt9)|u-7k}C*SQPDF$+GEl~yK03@hBE4uFfdtZ_jn4?uVb(5GdS=fvs}>6 z#Mt-;#t-Y(xES2NEj6xPF+D97EPvzN`<8|V|F45Tc#vq<-GB1Tq_4Ys_rm6@Dk?6x zAFEuB%bh>ZyWYvm$4AyVIWA6l{4l2Uf9Dp+nl8!@%=~!iUf>y*alUO}Am(o*KK}e& zT3Updc3NJZz(O7-@jX4_>o3MLZFHAj@38Lv_SMHuEN!55nszwaD7lKXM|WkQ;eYYs zg|L{|I`FJDax_BaGDS?DZ6zxwa0D3^`EASlQWKx3425Uz|DT0~iOy zNZ!p*7eINfsG;GNot+)E^;2Ex@RXi`!CAYZ^o)!>+xFu46k|fq_vp=8R2OhT+$?DA z-zTWVrCsQ{?>mJ44Lh4VI(*=z5aYzt*wiFT*VWV0!@wf^{N+o(Ma@f>SgbFP=zqVq zZwGqE*`>6!eFhoot5#4YBqi}B@qEVwt?^MWv{B);2KWjwHrteBWvia9l0*4w&+{P* zo#__{S|>lt9K=(5?;aH{DXQAY=;)p=RoZV`l%2c`jf_;X^W^?w-uqf2Ww+f>R-bRu z7fkTLNM409DCp%&X%!U)IWCpz9u$k?5m&EViT{=VrM=w?Rg_xdMLb|XLD=Svf4JJ^ zcy&$9iss~NJha{H{w>DOCOe9YSKvd0H5xJ`z0c3zNP)M!8>%8}5jwXIoljQi#$t>6 z6F>M;lOAgU9+pMG88pF6VBS|y&nC;}UfEzZu`HOzf&Xkh$( z=LkjHz+fHbY>Jjn?9b2*CpWQ8SR-z=wY35KDTGhP&+jZ7A9W1lG!|GcT)22KB0pbK zsp}k8-<;HL8J^;-cw%;N>Qkh+wZ}fHm0bQKcn|;+x}zXRZ96_S)dlAM$C?_z3w3qM ztlp=^LgWclj13Gj1$$SmxF=mPrnB!kV?b@E=~=4iU%!5(Y=783G?di95RE(a+uAOV zLseCke3+j%)JXURXk6gHO2& z8gF2+r4qLh1elqb8E>~49EeCwRkC{S|1RmwuE$ym0dRhZWzsrNGobS)UaqdL?mlWz z%G}{&x)b}TSFKQXQ%i1&L>=FVBe)gsh0>itGnoZDipt?)()E29@D&i%&A05YUq7ub z$hzTNN8k3!%1Xx7`|(8JgHhpuNlZ+1z1qHQqx*%geg`h7{(kx-Aixcu%^;&S)7kUG zo4X4-GU|yJXEz1b4_MX}1VCF=0{&Y=hsP94e4{7lLjRdfQ}M9Q!{Bc9y<-$9KvkQa zE^2CWR900fUA*`J)4-T2OKWRAYikyA+qAUGKYn}|p{e1H9T5Bxmm->J&UPb09XjL= zD^-8Tq~^J^pXS1v21`M6P`j >XlTh5MDw&YgNK$9#%d_?Xx=M!eF;i1gC`eb(a;NM# zk_wT5TfqMGBX;S`>%33nxxU-?%3iSZ-Mt0R%ECelrDR+0rVVQdbN*DDSJ}0Fr5l3$ zpFQIfXD(c{WzNQ@e#sQrDYkJ*?egWPn(Pd;I%Z<*L9bq2%>9GA6Lp`0D1M<%S{hG< zFdVZQvcvI+pz|qCa`*IHuS(@-Im|EOTzlO3)-AsEyNz$(md)CyOKp;hH~!GxuF)`O zX>hD+aN?Y;+)vxy=QqOY7drTTDz2T7m8B^wFHgFGccJQ2x zzU$F3T>kUdkI>uy;R5{BZRj~+KMT8421!ZDO;rdhvQueaEXH>C(8a{YDjldkmW~4t zDDG`ba2mVd&y^6cGv^7wJ8z05R-!4dYJ$XA%*lMr<7o;ytUyr|P& z9k$^5wKV5&6qwErFghudpIa`hl3Q_)0#1X7l#~w;AXiC?QvjA&Sy>hRwY9wO-(P`Q z^Ti3fTkqL$8HKlc%OrB1e;tx@@;Nrxi!-OI3t$ZDf;sDlKX>$iBq5{K(KzoDD2_Eg zb(BvqP?7|-3gVS)cpSC%U#r6HhG%JlaUb-JNL%;ddxdX!Bi~Spv9mH z;8UDpKL$Uq|V-HL(k6M*x5yvMxB%dE>#a;o(5_%RW`jEjD_23`%cb z`KC693pE2lre=8O_DTVaRyi@JS+P6~q`bX?g1W}Wd-v4KzDjot@bj~Xnz4<@`#3mZ zcR*D19JLEDBfX2k2&$2jl?*criz%<%;Q=DwV!UPGtZQa!>ZXf_nQt`9bfa3_vPHP1 zx%sU4ZI9+Fg`K89Ad)$2$cFo%GmK|-werfc*4C|v+KMPzCfJd!?pO5`gZZNO${C;; zb!fpkgp!EJNa@x~C@F1la1j)7ra7L`3HbXu@@pa9Y!kz}O5IAMz$&XB5?ouo*8pK* z<>U;!Zv80ZeCTI)Sb#p{a7KA&mv?k%0&{3#%=skkG2q&q&xRPs`>OX!@Plsymgf!| zZmy`T^lZ};RUtR5L_DM(KPTo>mWI<3#zKe=~uy&Ovre_z~iv=m4`20zTCy9<55=Y zUXvNNTYKlly%Tnh)f82Op8ZO63WvP+T+QR^L%+tlB z?$-6RD_FhDyl&rAsq8e>wy_cWJ&*bpRcQJAe6A&(a#z$J{>WOJ-4%Bkz-xYL_x)3K zbr_x)!@n}gP33t@u9M#fA(LpMXUWs_0oQ3yUOsEdCWiV~jQ5Uh-}7O&@3+&r>u<@( zP~*0spxVh7LOu{(?1vZ8FQ7O5JJJ)@S_i29|6%&*5 zFG`R9sanExpNk8o0QdsD6|@Ypq-qnkyM0^8kpF%C0D7E9G4ySJCR1({BZfrOw36ke zRLup}5A$4<8;!Uc*VE82U0Q)06|g(U+omZ-?fGM7F{aQ)jDO8uCAicX9OxeyIF9

s%_vQZ@oW~U~hnNQp4KD+1cy{*$+MDv9C-zV~kBqWO{J#kL&2{ zz&ut>w{(8q0j2CtRBRtK>v%2Ka725Im3;NE`F5~044G8+a$(8vlzYYx_OA`0?gHtJ z`x_G!~{sL z+ttsyr_v)Lek$_UW6ZtD`|K#iT}?hulk@HIB5mQq0n4(hy|hl?7>!27C|;WnWw0A<@`zm? znH%gXOMaJ;aXh|J7cEN9mT!^Nj`aLnzVBRje_WX(S$WsS^JjZ9XV6a%%%ht>D>L<7 zjcuER4}^5ry`tZ@u>x?3+PLE4Et+`efHJeX7YDw#wpqU&qJO{SC5{ zlH{`kv%cN3k>EgDibzROw97ZSb?bC>T9>7G*BZHf8JA=vP%>?jKCHXRUI}1NN~~^I z#ivi+wkCEGuTnm5{Iu=hkt6(jE~A}S{&AFb!-GBFK2=p!O|L3(2UX)FyWhlw)%3!m z|L;&#F}!BBx!O0=?;bmUp7wrG*ny~NRBAfX>Od)K8yl^{>}?{B`IqWGypJUSdMRSphe5JQ5;)+XeUTJuBo25TQ472J8vmkEY-y`(NUzM=$NJ8WWNC zgNd0r0*@bL6|5!e6-jLQ@c@8~-HMX7sh=N?1ju|iVIRm7BL7!xed5RHoindK4o}G@ z%8G}`D;4ruUcVF$9K!=%ci9k5 z-s$c?%0Gc}cs?__ecR{qrgtsInT~UJ8ahhtID|l~pzVO7^hEQB14b*=15rI&+1R2v zXpu&G_bRI=igx*#;TFfPJtZx@5;g9ob*r>VD4je0u)a;4eIvP_85yc0*?8*z&Nu`; ze@<=xwYR4S!q^B?sfIJt>!L~T8naXY7~*_%40_DAHa6w~=2cXv zjxh?Y3qp}Ps<&Ty{a@$AaHRXv($YGyb^v^_n|C}82zmL^<#XT46sdzr%}hDiv-~SP zI-DvFtgMIbj`(v8-?w9qTiFS^%wrVPX9VUD?4mu-8dRN1xa)y?^Wbb0pO3V`PVLBA zR_n>9cxt>JKaOj4>VH&US-GApW^2@!fL`{TU7jn~j&JSla+gg%qNpfJLK%Nb;8J+s z%Vym_=2@8E>{z#A+)ffalyhZy+D`55YK- zhqh{yJ8Q{)5XYX4qY36TSU&=wLUrcWs^d@W&i=B@e%Kj>vgg~kZ_1Q@jKnhGu?jFQ zH7m;l(hdxr^^lH#{oeX>si&`xb8d$YLYdi>+yJh!$6wnzg?VXf+%{TUWNA!e;KpQ? z1w>+ea+0h4yVAwkQqOm_1}BY-;{6>^oF3dm#h_jA<|CdOz?!;4ddKO1Sc<2<|$k7{R|5S5;L2$`u868xbIm0r+rW5?hQeTWhkN7 z8!Z4q6L~YZVT}u_ic%=Kqu1ZT*#o#KDk@6eJST@H=Nre6c{mw<_-YiNi#E%UxR}m%96@|SsAHb}dz$u2pzk^V@* z1K%)D^>F?3{=W~>uX9~}%=c;aZ0d^phB*Hz!`Ydc57DamS6}dzqkH(p3e}4lL^Tgt zGC^BFGZ7gc-g)fsrH!N8z&FCKJ6}yHrj15gvD-d#oZt8M@WTUJ&$owjyI)qKlk~YN zc&S~3*}}qN(^UD_uU}WL{=WLSB9riCHMJ)-Kc^bg0Bc6ax&z2fNVJ9JxhN&&>zVslB8buS?DyJy-mhUr?~@f3$ZU z?p*e78)a`Hddeo*is&24&dds>>?A3pFPUYQ@t~|w$oR@0QK^ubkj$hdBV}b2EsgiQ zpXc|!$NNY8939VbJkO)=xbM$>UFUV4=XG81dTsvv_2JKHdFq9wSGLsg?tOa$o9(uy zOZ+)j8l158kmCrBVOQ+@+#Gl*QE_*BTig8znT8k7$1E8kO1b?mLz9DUqr)7TG(0?f zqqLL>On}o;GE`S$svy-kI=u~O1DqR;bW`HO9vc9oSws_0B~0E<73wHW6+15xr~nI0 zoc>@z_BHRhc8p(ux#jyCmvyS*Xr05FnwPxvtCALVfq>{MyAshFs#(%6u%vRaG`? z{6H*D^2cz+N*z=!SGejS&)-R+K5%%QJ?ph<=4;8k57y;|cV2yb1acN&%bURKZ7~*{ zuHD?TV>bD~r4q*;rRWKSB_4+b@Nuy4$HhfMYA;1T0j%j`g(-vx1}iH*Kyg!`$f$mM zNtq>eZg}uUZq5E3Igh?zXm)a}tz*IrrHs#pr+JLUz*M4K*)KhJLwmrb9EVv~abFp3 z-ol@vn>X7Q6+iWH#Xb-3nU2e3u{-)`eogP#d!blI?WNGk>P{GE2zlefXDA#+Vonc` zHbMCnhUwRRP0PyKGW!QdMoLNwwGu%y)jh3#{_Gjgx%E88o14~nnU3vFHzs&LMu2CS z3ut%ov4DSn+|v^|;0|ob9PCIYlcS~u5NFNR)IB6>UVX%!q2UPK9XU2;KeP6uT5-0f zhzA%b-M$^|8-cp&UZ{FRjvNmP3M#Z-LefAa_Bk4=1~7=BW@*2%vbK!mh=H3TYYMQ} z7>@2G^0T?tkQqWRIE>4`-;9nHtA@Ljf_yyr_%Lcb!0aSQ4Ok@Qe(%+2On1Lj2@c(n{~UD)wcnZqxsGx9Pkhu?XtE`!V1esob% zEVyc9evLEj8RBP5SQjkkujggWMNVJq<@L+Nj;q}z=cKOoh_eO~k%^`iD#oDq=9QnO zy6hAEV}b*2Jmtm3#8elUzr2f=Vq$|@-EoFA|i08yowO&s>WMH#2bu0m=)i zs=(V&13sc5oH1AvPX`$LRN|_}z+iPC-|&i`sGE5j;0R;T$pb#;!Rq1)gcSq^Gk4p1YyS&8Xb zrN*7=Z)q<74i!&6sB-P^{&kO?7K&xYQc;Tzfz9nxE2vm)w+K)z&_@GPQNp?aPr^S{ zNLD;HHa0#$osg3wFk8EqL~3n{eCE*s?L=bx_7$wv0#e|?*R@#Ua(pOadH8TFaFvX_ zd;u!bEeU#3@m;PYe^!PXNml=@$IW!)>VzkK%E&NC9(e9#X_>P6C#cbWi+uw!B5@l1QnA!@9l(FVPq+Fn^yM3(DQdd?W+T&D|<0=4fKPRU@?(SwH$rOmCZ zAeJrImLMDNnBLTdv0*)ei;9Zs=qh#Kd3ANwnG3y~n=4OCXCko)S26}M zx#eG-D?&);ot&8nIgq05^z!9Pn7Tz_=zHYJC=HJ_22N1&MBveYj2L(1UPq2L&TsN! zsJNjnEsBQu{ei|ib!P%)9twc&ZHo{GL@lnUNSI+H^HtoHm6b((1aVC3{CN#xF%V>{ zZy`<9V-l0)$K7iAAyrDG?3fEJuB)@kQal66H83!6P<^3ZX{(qoIymYZIjbBV%84(B z!0_WN_rdob_x6?ZA8$YBdS4X;gOF{K_?0f#*4jRezx+*$9t`rI_J7cStD~Da%{|lg z;?>0k%<3@$btjVZEbsd$?lm}c|M8q?JgaEokI$rcg(=TZLAFkD7UmwO@La@5-9{To zSySil_7_&g`esO;E+n1#AUEIy0m>8_l`_bdgF$9Q!hZ0;E{N)Thz0~5L-tm5jkxTJ zcAjC8gD41(H#q1=u*s})gn~96+@ioKT>@gN)J`NpuVC({VqUECv!kgf-(g_3 z#898V_gEe&jn3)(1*`a?pg;?bm|Js7O^Vdnj!ofL85` zt>^Bw<+O;7?aB1`)a;yuf+yiv0mZ5qSc!bdnj z!5OqofGxnAT7B3;Aed-qi7`%wd4N7v;*JRtN?{_okM{B^o-F4wyxFe7aw%|;Ya1ON zI31>qGz3@Y8%(vH_M^Xn6%s6Nd`i*YQyv~#etv6LQf(@L(W?z72)V2z#O3zys)`C- z)(E1n3(vSn zP|fRln@q|c4mRz&MO7$V2&S+FmlCNJ8X{%A(7MbdplZnDHXuzWa0(3Ll;9Y?sC|rx z4U=D%nS1HQOrLE{$OR#Lu|7>$i6x%+jSrw$hFq$TPj-Y7*T z96fbP8rX${VWR@l8@lTYFD8Klj56WF5!_H={nx-LIf(dvqVYeoC6x|#I|&|CPF%ld zl**e>0nxrnoRggkh@t#a=5c8Ba)0 z=Y`(e3T2s0=0+ciQD9#>Xbu)uR)g?;j{8cy+_hZpp=`pv_`0sBqC%gbw@LAumP}sD zoq!78E+%yi!#ncqFSov<{a9^xh28LDQ~u1mT~S>WXVM}W`sO3-X|r?xwo+-3tO*t=*9Ot)~OC1FfxiCj@Red$PmHtB}BE` z@PxZpoU7Zo;iHj}^x;#xQKp_r;wc!20V}B%@{I$bo)90=4#U0AAyh*UgCkpma&kz1 zOo*!HDg9V`j*JZ;!ni>RXU@Px`t_?<(!BvwD*?{-ZHRCWzjeq{EjU!s&ra~p)#pCY znQgAkNK{5q_4#|@wQm?e*BX=t4*9x9D5-qiMS-uKxG}sN<2xb)j|vHdhMyM>tqIjawC8&)

+nU3ezJf#=U4d0Q~-+ku9 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 SJ@<9u88Of`)v45SjQAf8l#)#V literal 188323 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

#>Kp`%%!E~KIf1$~pQ}es;1>Bk(@zF5 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 From 33a9e08dc9b65abc3f3e18d14253f95c79e0f749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 8 May 2024 19:20:43 +0800 Subject: [PATCH 033/125] dynamic batch --- funasr/auto/auto_model.py | 20 +++++++++++-------- funasr/models/sense_voice/model.py | 30 +++++++++++++++++++++-------- funasr/models/sense_voice/search.py | 9 ++++----- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/funasr/auto/auto_model.py b/funasr/auto/auto_model.py index 577c328a6..97eb325da 100644 --- a/funasr/auto/auto_model.py +++ b/funasr/auto/auto_model.py @@ -364,7 +364,6 @@ class AutoModel: if len(sorted_data) > 0 and len(sorted_data[0]) > 0: batch_size = max(batch_size, sorted_data[0][0][1] - sorted_data[0][0][0]) - batch_size_ms_cum = 0 beg_idx = 0 beg_asr_total = time.time() time_speech_total_per_sample = speech_lengths / 16000 @@ -373,19 +372,22 @@ class AutoModel: # pbar_sample = tqdm(colour="blue", total=n, dynamic_ncols=True) all_segments = [] + max_len_in_batch = 0 + end_idx = 1 for j, _ in enumerate(range(0, n)): # pbar_sample.update(1) - batch_size_ms_cum += sorted_data[j][0][1] - sorted_data[j][0][0] + sample_length = sorted_data[j][0][1] - sorted_data[j][0][0] + potential_batch_length = max(max_len_in_batch, sample_length) * (j + 1 - beg_idx) + # batch_size_ms_cum += sorted_data[j][0][1] - sorted_data[j][0][0] if ( j < n - 1 - and (batch_size_ms_cum + sorted_data[j + 1][0][1] - sorted_data[j + 1][0][0]) - < batch_size - and (sorted_data[j + 1][0][1] - sorted_data[j + 1][0][0]) - < batch_size_threshold_ms + and sample_length < batch_size_threshold_ms + and potential_batch_length < batch_size ): + max_len_in_batch = max(max_len_in_batch, sample_length) + end_idx += 1 continue - batch_size_ms_cum = 0 - end_idx = j + 1 + speech_j, speech_lengths_j = slice_padding_audio_samples( speech, speech_lengths, sorted_data[beg_idx:end_idx] ) @@ -410,6 +412,8 @@ class AutoModel: ) results[_b]["spk_embedding"] = spk_res[0]["spk_embedding"] beg_idx = end_idx + end_idx += 1 + max_len_in_batch = sample_length if len(results) < 1: continue results_sorted.extend(results) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 00bc85b5d..56e61e7ab 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -516,16 +516,23 @@ class SenseVoiceRWKV(nn.Module): # Paramterts for rich decoding self.beam_search.emo_unk = tokenizer.encode( - DecodingOptions.get("emo_unk_token", "<|SPECIAL_TOKEN_1|>"), allowed_special="all")[0] + DecodingOptions.get("emo_unk_token", "<|SPECIAL_TOKEN_1|>"), allowed_special="all" + )[0] self.beam_search.emo_unk_score = 1 self.beam_search.emo_tokens = tokenizer.encode( - DecodingOptions.get("emo_target_tokens", "<|HAPPY|><|SAD|><|ANGRY|>"), allowed_special="all") + DecodingOptions.get("emo_target_tokens", "<|HAPPY|><|SAD|><|ANGRY|>"), + allowed_special="all", + ) self.beam_search.emo_scores = DecodingOptions.get("emo_target_threshold", [0.1, 0.1, 0.1]) self.beam_search.event_bg_token = tokenizer.encode( - DecodingOptions.get("gain_tokens_bg", "<|Speech|><|BGM|><|Applause|><|Laughter|>"), allowed_special="all") + DecodingOptions.get("gain_tokens_bg", "<|Speech|><|BGM|><|Applause|><|Laughter|>"), + allowed_special="all", + ) self.beam_search.event_ed_token = tokenizer.encode( - DecodingOptions.get("gain_tokens_ed", "<|/Speech|><|/BGM|><|/Applause|><|/Laughter|>"), allowed_special="all") + DecodingOptions.get("gain_tokens_ed", "<|/Speech|><|/BGM|><|/Applause|><|/Laughter|>"), + allowed_special="all", + ) self.beam_search.event_score_ga = DecodingOptions.get("gain_tokens_score", [1, 1, 1, 1]) encoder_out, encoder_out_lens = self.encode( @@ -859,16 +866,23 @@ class SenseVoiceFSMN(nn.Module): # Paramterts for rich decoding self.beam_search.emo_unk = tokenizer.encode( - DecodingOptions.get("emo_unk_token", "<|SPECIAL_TOKEN_1|>"), allowed_special="all")[0] + DecodingOptions.get("emo_unk_token", "<|SPECIAL_TOKEN_1|>"), allowed_special="all" + )[0] self.beam_search.emo_unk_score = 1 self.beam_search.emo_tokens = tokenizer.encode( - DecodingOptions.get("emo_target_tokens", "<|HAPPY|><|SAD|><|ANGRY|>"), allowed_special="all") + DecodingOptions.get("emo_target_tokens", "<|HAPPY|><|SAD|><|ANGRY|>"), + allowed_special="all", + ) self.beam_search.emo_scores = DecodingOptions.get("emo_target_threshold", [0.1, 0.1, 0.1]) self.beam_search.event_bg_token = tokenizer.encode( - DecodingOptions.get("gain_tokens_bg", "<|Speech|><|BGM|><|Applause|><|Laughter|>"), allowed_special="all") + DecodingOptions.get("gain_tokens_bg", "<|Speech|><|BGM|><|Applause|><|Laughter|>"), + allowed_special="all", + ) self.beam_search.event_ed_token = tokenizer.encode( - DecodingOptions.get("gain_tokens_ed", "<|/Speech|><|/BGM|><|/Applause|><|/Laughter|>"), allowed_special="all") + DecodingOptions.get("gain_tokens_ed", "<|/Speech|><|/BGM|><|/Applause|><|/Laughter|>"), + allowed_special="all", + ) self.beam_search.event_score_ga = DecodingOptions.get("gain_tokens_score", [1, 1, 1, 1]) encoder_out, encoder_out_lens = self.encode( diff --git a/funasr/models/sense_voice/search.py b/funasr/models/sense_voice/search.py index 4400ce75d..3a1a049d1 100644 --- a/funasr/models/sense_voice/search.py +++ b/funasr/models/sense_voice/search.py @@ -54,7 +54,6 @@ class BeamSearch(torch.nn.Module): event_bg_token: List[int] = field(default_factory=lambda: [58946, 58948, 58950, 58952]), event_ed_token: List[int] = field(default_factory=lambda: [58947, 58949, 58951, 58953]), event_score_ga: List[float] = field(default_factory=lambda: [1, 1, 5, 25]), - token_list: List[str] = None, pre_beam_ratio: float = 1.5, pre_beam_score_key: str = None, @@ -209,16 +208,17 @@ class BeamSearch(torch.nn.Module): last_token = yseq[-1] if last_token in self.emo_tokens + [self.emo_unk]: - # prevent output event after emotation token + # prevent output event after emotation token score[self.event_bg_token] = -np.inf - for eve_bg, eve_ed, eve_ga in zip(self.event_bg_token, self.event_ed_token, self.event_score_ga): + for eve_bg, eve_ed, eve_ga in zip( + self.event_bg_token, self.event_ed_token, self.event_score_ga + ): score_offset = get_score(yseq, eve_bg, eve_ed) score[eve_bg] += score_offset[0] score[eve_ed] += score_offset[1] score[eve_bg] += math.log(eve_ga) - score[self.emo_unk] += math.log(self.emo_unk_score) for emo, emo_th in zip(self.emo_tokens, self.emo_scores): if score.argmax() == emo and score[emo] < math.log(emo_th): @@ -232,7 +232,6 @@ class BeamSearch(torch.nn.Module): return scores, states - def score_partial( self, hyp: Hypothesis, ids: torch.Tensor, x: torch.Tensor ) -> Tuple[Dict[str, torch.Tensor], Dict[str, Any]]: From f775e0e41c2be08f7db17cbbe77b6ec2757969fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 9 May 2024 10:15:44 +0800 Subject: [PATCH 034/125] start_data_split_i=0 --- funasr/bin/train.py | 1 + 1 file changed, 1 insertion(+) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index 7695e51c5..643df71d3 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -223,6 +223,7 @@ def main(**kwargs): torch.cuda.empty_cache() + trainer.start_data_split_i = 0 trainer.validate_epoch( model=model, dataloader_val=dataloader_val, epoch=epoch + 1, writer=writer ) From 664fd7abc82def968310b9f202a901ac675b901d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 9 May 2024 17:54:31 +0800 Subject: [PATCH 035/125] total_time/accum_grad --- funasr/train_utils/trainer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index 01e2924d9..d46a21c18 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -382,8 +382,6 @@ class Trainer: ): torch.cuda.empty_cache() - time3 = time.perf_counter() - speed_stats["forward_time"] = f"{time3 - time2:0.3f}" loss, stats, weight = retval stats = {k: v for k, v in stats.items() if v is not None} if self.use_ddp or self.use_fsdp: @@ -400,12 +398,15 @@ class Trainer: loss *= self.world_size # Scale the loss since we're not updating for every mini-batch loss = loss / accum_grad + + time3 = time.perf_counter() + speed_stats["forward_time"] = f"{time3 - time2:0.3f}" if self.use_fp16: scaler.scale(loss).backward() else: loss.backward() time4 = time.perf_counter() - speed_stats["backward_time"] = f"{time4 - time3:0.3f}" + speed_stats["backward_and_AllReaduce_time"] = f"{time4 - time3:0.3f}" self.train_loss_avg = ( self.train_loss_avg * (self.step_in_epoch - 1) + loss.detach().cpu().item() @@ -454,7 +455,7 @@ class Trainer: scheduler.step() # Clear gradients for the next accumulation stage optim.zero_grad(set_to_none=True) - total_time = f"{time.perf_counter() - time5:0.3f}" + total_time = f"{(time.perf_counter() - time5)/accum_grad:0.3f}" time5 = time.perf_counter() speed_stats["optim_time"] = f"{time5 - time4:0.3f}" From 64bf6dd8a1e8b6db43965ff0069a43674dfe4f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 9 May 2024 18:47:52 +0800 Subject: [PATCH 036/125] total_time/accum_grad --- funasr/datasets/audio_datasets/espnet_samplers.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/funasr/datasets/audio_datasets/espnet_samplers.py b/funasr/datasets/audio_datasets/espnet_samplers.py index e155cd7fc..528f59333 100644 --- a/funasr/datasets/audio_datasets/espnet_samplers.py +++ b/funasr/datasets/audio_datasets/espnet_samplers.py @@ -146,10 +146,9 @@ class EspnetStyleBatchSampler(DistributedSampler): start_idx = self.rank * batches_per_rank end_idx = start_idx + batches_per_rank rank_batches = buffer_batches[start_idx + self.start_step : end_idx] - if self.start_step > 0: - logging.info( - f"Warning, rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num_before: {end_idx-start_idx}, now: {len(rank_batches)}" - ) + logging.info( + f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {end_idx-start_idx}, batch_num_after_step: {len(rank_batches)}" + ) # Return an iterator over the batches for the current rank return iter(rank_batches) From e299cfecaf979833d9c4d7c70e44cb92ea066afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 9 May 2024 20:02:37 +0800 Subject: [PATCH 037/125] total_time/accum_grad --- funasr/train_utils/trainer.py | 49 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index d46a21c18..28fbb2973 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -384,18 +384,19 @@ class Trainer: loss, stats, weight = retval stats = {k: v for k, v in stats.items() if v is not None} - if self.use_ddp or self.use_fsdp: - # Apply weighted averaging for loss and stats - loss = (loss * weight.type(loss.dtype)).sum() - # if distributed, this method can also apply all_reduce() - # stats, weight = recursive_average(stats, weight, distributed=True) - if self.use_ddp or self.use_fsdp: - dist.all_reduce(weight, op=dist.ReduceOp.SUM) - # Now weight is summation over all workers - loss /= weight.sum() # shape:[1] -> shape:[] - # Multiply world_size because DistributedDataParallel - # automatically normalizes the gradient by world_size. - loss *= self.world_size + # if self.use_ddp or self.use_fsdp: + # # Apply weighted averaging for loss and stats + # loss = (loss * weight.type(loss.dtype)).sum() + # # if distributed, this method can also apply all_reduce() + # # stats, weight = recursive_average(stats, weight, distributed=True) + # if self.use_ddp or self.use_fsdp: + # dist.all_reduce(weight, op=dist.ReduceOp.SUM) + # # Now weight is summation over all workers + # loss /= weight.sum() # shape:[1] -> shape:[] + # # Multiply world_size because DistributedDataParallel + # # automatically normalizes the gradient by world_size. + # loss *= self.world_size + loss *= self.world_size # Scale the loss since we're not updating for every mini-batch loss = loss / accum_grad @@ -416,17 +417,6 @@ class Trainer: self.train_acc_avg * (self.step_in_epoch - 1) + stats["acc"].detach().cpu().item() ) / self.step_in_epoch - if self.use_ddp or self.use_fsdp: - train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( - self.device - ) - train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( - self.device - ) - dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) - self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size - self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size # Perform an optimizer step only after accumulating enough gradients if (batch_idx + 1) % accum_grad == 0: @@ -457,6 +447,19 @@ class Trainer: optim.zero_grad(set_to_none=True) total_time = f"{(time.perf_counter() - time5)/accum_grad:0.3f}" time5 = time.perf_counter() + + if self.use_ddp or self.use_fsdp: + train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( + self.device + ) + train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( + self.device + ) + dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) + self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size + self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size + speed_stats["optim_time"] = f"{time5 - time4:0.3f}" speed_stats["total_time"] = total_time From 9be30f99dd09cfe0de929266ec43c1b95abb6d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 10 May 2024 10:16:28 +0800 Subject: [PATCH 038/125] update avg slice --- funasr/bin/train.py | 2 ++ funasr/train_utils/trainer.py | 55 +++++++++++++++++------------------ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index 643df71d3..c3556d1b9 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -241,6 +241,8 @@ def main(**kwargs): f"estimated to finish {trainer.max_epoch} " f"epoch: {(trainer.max_epoch - epoch) * time_escaped:.3f} hours\n" ) + trainer.train_acc_avg = 0.0 + trainer.train_loss_avg = 0.0 if trainer.rank == 0: average_checkpoints(trainer.output_dir, trainer.avg_nbest_model) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index 28fbb2973..33dd351b4 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -384,19 +384,19 @@ class Trainer: loss, stats, weight = retval stats = {k: v for k, v in stats.items() if v is not None} - # if self.use_ddp or self.use_fsdp: - # # Apply weighted averaging for loss and stats - # loss = (loss * weight.type(loss.dtype)).sum() - # # if distributed, this method can also apply all_reduce() - # # stats, weight = recursive_average(stats, weight, distributed=True) - # if self.use_ddp or self.use_fsdp: - # dist.all_reduce(weight, op=dist.ReduceOp.SUM) - # # Now weight is summation over all workers - # loss /= weight.sum() # shape:[1] -> shape:[] - # # Multiply world_size because DistributedDataParallel - # # automatically normalizes the gradient by world_size. - # loss *= self.world_size - loss *= self.world_size + if self.use_ddp or self.use_fsdp: + # Apply weighted averaging for loss and stats + loss = (loss * weight.type(loss.dtype)).sum() + # if distributed, this method can also apply all_reduce() + # stats, weight = recursive_average(stats, weight, distributed=True) + if self.use_ddp or self.use_fsdp: + dist.all_reduce(weight, op=dist.ReduceOp.SUM) + # Now weight is summation over all workers + loss /= weight.sum() # shape:[1] -> shape:[] + # Multiply world_size because DistributedDataParallel + # automatically normalizes the gradient by world_size. + loss *= self.world_size + # loss *= self.world_size # Scale the loss since we're not updating for every mini-batch loss = loss / accum_grad @@ -417,6 +417,17 @@ class Trainer: self.train_acc_avg * (self.step_in_epoch - 1) + stats["acc"].detach().cpu().item() ) / self.step_in_epoch + if self.use_ddp or self.use_fsdp: + train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( + self.device + ) + train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( + self.device + ) + dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) + self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size + self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size # Perform an optimizer step only after accumulating enough gradients if (batch_idx + 1) % accum_grad == 0: @@ -448,18 +459,6 @@ class Trainer: total_time = f"{(time.perf_counter() - time5)/accum_grad:0.3f}" time5 = time.perf_counter() - if self.use_ddp or self.use_fsdp: - train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( - self.device - ) - train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( - self.device - ) - dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) - self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size - self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size - speed_stats["optim_time"] = f"{time5 - time4:0.3f}" speed_stats["total_time"] = total_time @@ -666,9 +665,9 @@ class Trainer: f"data_slice: {data_split_i}/{data_split_num}, " f"step_in_slice: {batch_idx + 1}/{batch_num_epoch}, step_in_epoch: {step_in_epoch}, total step: {self.batch_total}, " f"(loss_avg_rank: {loss:.3f}), " - f"(loss_avg_epoch: {loss_avg_epoch:.3f}), " - f"(ppl_avg_epoch: {math.exp(loss_avg_epoch):.3e}), " - f"(acc_avg_epoch: {acc_avg_epoch:.3f}), " + f"(loss_avg_slice: {loss_avg_epoch:.3f}), " + f"(ppl_avg_slice: {math.exp(loss_avg_epoch):.3e}), " + f"(acc_avg_slice: {acc_avg_epoch:.3f}), " f"(lr: {lr:.3e}), " f"{[(k, round(v.detach().cpu().item(), 3)) for k, v in stats.items()]}, " f"{speed_stats}, " From 0a545ab9c24cc10d6fea255a1852d7e5c464a363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 11 May 2024 10:52:45 +0800 Subject: [PATCH 039/125] update avg slice --- funasr/train_utils/trainer.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index 33dd351b4..50f99f023 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -410,24 +410,14 @@ class Trainer: speed_stats["backward_and_AllReaduce_time"] = f"{time4 - time3:0.3f}" self.train_loss_avg = ( - self.train_loss_avg * (self.step_in_epoch - 1) + loss.detach().cpu().item() - ) / self.step_in_epoch + self.train_loss_avg * (batch_idx + kwargs.get("start_step", 0)) + + loss.detach().cpu().item() + ) / (batch_idx + kwargs.get("start_step", 0) + 1) if "acc" in stats: self.train_acc_avg = ( - self.train_acc_avg * (self.step_in_epoch - 1) + self.train_acc_avg * (batch_idx + kwargs.get("start_step", 0)) + stats["acc"].detach().cpu().item() - ) / self.step_in_epoch - if self.use_ddp or self.use_fsdp: - train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( - self.device - ) - train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( - self.device - ) - dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) - self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size - self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size + ) / (batch_idx + kwargs.get("start_step", 0) + 1) # Perform an optimizer step only after accumulating enough gradients if (batch_idx + 1) % accum_grad == 0: @@ -456,6 +446,19 @@ class Trainer: scheduler.step() # Clear gradients for the next accumulation stage optim.zero_grad(set_to_none=True) + + if self.use_ddp or self.use_fsdp: + train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( + self.device + ) + train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( + self.device + ) + dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) + self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size + self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size + total_time = f"{(time.perf_counter() - time5)/accum_grad:0.3f}" time5 = time.perf_counter() From 7d06f581dbe603e98fe10bd296ce0ef3494d7a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 11 May 2024 19:40:29 +0800 Subject: [PATCH 040/125] sensevoice sanm --- funasr/models/sense_voice/model.py | 416 +++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 56e61e7ab..a633a8d13 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -966,3 +966,419 @@ class SenseVoiceFSMN(nn.Module): ibest_writer["text"][key[i]] = text return results, meta_data + + +@tables.register("model_classes", "SenseVoiceSANM") +class SenseVoiceSANM(nn.Module): + + def __init__( + self, + specaug: str = None, + specaug_conf: dict = None, + normalize: str = None, + normalize_conf: dict = None, + encoder: str = None, + encoder_conf: dict = None, + decoder: str = None, + decoder_conf: dict = None, + input_size: int = 80, + vocab_size: int = -1, + ignore_id: int = -1, + blank_id: int = 0, + sos: int = 1, + eos: int = 2, + lsm_weight: float = 0.0, + length_normalized_loss: bool = False, + report_cer: bool = True, + report_wer: bool = True, + sym_space: str = "", + sym_blank: str = "", + # extract_feats_in_collect_stats: bool = True, + share_embedding: bool = False, + # preencoder: Optional[AbsPreEncoder] = None, + # postencoder: Optional[AbsPostEncoder] = None, + **kwargs, + ): + + super().__init__() + + if specaug is not None: + specaug_class = tables.specaug_classes.get(specaug) + specaug = specaug_class(**specaug_conf) + if normalize is not None: + normalize_class = tables.normalize_classes.get(normalize) + normalize = normalize_class(**normalize_conf) + encoder_class = tables.encoder_classes.get(encoder) + encoder = encoder_class(input_size=input_size, **encoder_conf) + encoder_output_size = encoder.output_size() + + decoder_class = tables.decoder_classes.get(decoder) + decoder = decoder_class( + vocab_size=vocab_size, + encoder_output_size=encoder_output_size, + **decoder_conf, + ) + + self.blank_id = blank_id + self.sos = sos if sos is not None else vocab_size - 1 + self.eos = eos if eos is not None else vocab_size - 1 + self.vocab_size = vocab_size + self.ignore_id = ignore_id + + self.specaug = specaug + self.normalize = normalize + self.encoder = encoder + + self.decoder = decoder + + self.criterion_att = LabelSmoothingLoss( + size=vocab_size, + padding_idx=ignore_id, + smoothing=lsm_weight, + normalize_length=length_normalized_loss, + ) + + self.error_calculator = None + + self.share_embedding = share_embedding + if self.share_embedding: + self.decoder.embed = None + + self.length_normalized_loss = length_normalized_loss + self.beam_search = None + + def forward( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + text: torch.Tensor, + text_lengths: torch.Tensor, + **kwargs, + ): + target_mask = kwargs.get("target_mask", None) + + # import pdb; + # pdb.set_trace() + if len(text_lengths.size()) > 1: + text_lengths = text_lengths[:, 0] + if len(speech_lengths.size()) > 1: + speech_lengths = speech_lengths[:, 0] + + batch_size, frames, _ = speech.shape + _, text_tokens = text.shape + + if self.activation_checkpoint: + from torch.utils.checkpoint import checkpoint + + encoder_out, encoder_out_lens = checkpoint( + self.encode, speech, speech_lengths, use_reentrant=False + ) + else: + encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) + + loss_att, acc_att, cer_att, wer_att = self._calc_att_loss( + encoder_out, encoder_out_lens, text, text_lengths, target_mask=target_mask + ) + + loss = loss_att + stats = {} + stats["acc"] = acc_att + stats["loss"] = torch.clone(loss.detach()) + stats["batch_size"] = batch_size + stats["batch_size_x_frames"] = frames * batch_size + stats["batch_size_real_frames"] = speech_lengths.sum().item() + stats["padding_frames"] = stats["batch_size_x_frames"] - stats["batch_size_real_frames"] + stats["batch_size_x_tokens"] = text_tokens * batch_size + stats["batch_size_real_tokens"] = text_lengths.sum().item() + stats["padding_tokens"] = stats["batch_size_x_tokens"] - stats["batch_size_real_tokens"] + stats["batch_size_x_frames_plus_tokens"] = (text_tokens + frames) * batch_size + + # force_gatherable: to-device and to-tensor if scalar for DataParallel + if self.length_normalized_loss: + batch_size = int((text_lengths + 1).sum()) + loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) + return loss, stats, weight + + def encode( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + **kwargs, + ): + """Frontend + Encoder. Note that this method is used by asr_inference.py + Args: + speech: (Batch, Length, ...) + speech_lengths: (Batch, ) + ind: int + """ + with autocast(False): + + # Data augmentation + if self.specaug is not None and self.training: + speech, speech_lengths = self.specaug(speech, speech_lengths) + + # Forward encoder + # feats: (Batch, Length, Dim) + # -> encoder_out: (Batch, Length2, Dim2) + + encoder_out, encoder_out_lens, _ = self.encoder(speech, speech_lengths) + if isinstance(encoder_out, (tuple, list)): + encoder_out = encoder_out[0] + + return encoder_out, encoder_out_lens + + def _calc_att_loss( + self, + encoder_out: torch.Tensor, + encoder_out_lens: torch.Tensor, + ys_pad: torch.Tensor, + ys_pad_lens: torch.Tensor, + **kwargs, + ): + target_mask = kwargs.get("target_mask", None) + stats = {} + + # 1. Forward decoder + decoder_out = self.decoder(encoder_out, encoder_out_lens, ys_pad, ys_pad_lens) + if isinstance(decoder_out, (list, tuple)): + decoder_out = decoder_out[0] + + # 2. Compute attention loss + mask = torch.ones_like(ys_pad) * (-1) + ys_pad_mask = (ys_pad * target_mask + mask * (1 - target_mask)).to(torch.int64) + ys_pad_mask[ys_pad_mask == 0] = -1 + loss_att = self.criterion_att(decoder_out[:, :-1, :], ys_pad_mask[:, 1:]) + + with torch.no_grad(): + preds = torch.argmax(decoder_out, -1) + acc_att = compute_accuracy( + preds[:, :-1], ys_pad_mask[:, 1:], ignore_label=self.ignore_id + ) + + return loss_att, acc_att, None, None + + def init_beam_search( + self, + **kwargs, + ): + from .search import BeamSearch + + from funasr.models.transformer.scorers.length_bonus import LengthBonus + + # 1. Build ASR model + scorers = {} + + scorers.update( + decoder=self.decoder, + length_bonus=LengthBonus(self.vocab_size), + ) + + weights = dict( + decoder=1.0, + ctc=0.0, + lm=0.0, + ngram=0.0, + length_bonus=kwargs.get("penalty", 0.0), + ) + beam_search = BeamSearch( + beam_size=kwargs.get("beam_size", 5), + weights=weights, + scorers=scorers, + sos=None, + eos=None, + vocab_size=self.vocab_size, + token_list=None, + pre_beam_score_key="full", + ) + + self.beam_search = beam_search + + def inference( + self, + data_in, + data_lengths=None, + key: list = None, + tokenizer=None, + frontend=None, + **kwargs, + ): + if kwargs.get("batch_size", 1) > 1: + raise NotImplementedError("batch decoding is not implemented") + + # init beamsearch + if not hasattr(self, "beam_search") or self.beam_search is None: + logging.info("enable beam_search") + self.init_beam_search(**kwargs) + self.nbest = kwargs.get("nbest", 1) + + if frontend is None and not hasattr(self, "frontend"): + frontend_class = tables.frontend_classes.get("WhisperFrontend") + frontend = frontend_class( + n_mels=self.model.dims.n_mels, do_pad_trim=kwargs.get("do_pad_trim", True) + ) + self.frontend = frontend + else: + frontend = frontend if frontend is not None else self.frontend + + meta_data = {} + if ( + isinstance(data_in, torch.Tensor) and kwargs.get("data_type", "sound") == "fbank" + ): # fbank + speech, speech_lengths = data_in, data_lengths + if len(speech.shape) < 3: + speech = speech[None, :, :] + if speech_lengths is None: + speech_lengths = speech.shape[1] + else: + # extract fbank feats + time1 = time.perf_counter() + audio_sample_list = load_audio_text_image_video( + data_in, + fs=frontend.fs if hasattr(frontend, "fs") else 16000, + audio_fs=kwargs.get("fs", 16000), + data_type=kwargs.get("data_type", "sound"), + tokenizer=tokenizer, + ) + + if ( + isinstance(kwargs.get("data_type", None), (list, tuple)) + and len(kwargs.get("data_type", [])) > 1 + ): + audio_sample_list, text_token_int_list = audio_sample_list + text_token_int = text_token_int_list[0] + else: + text_token_int = None + + time2 = time.perf_counter() + meta_data["load_data"] = f"{time2 - time1:0.3f}" + speech, speech_lengths = extract_fbank( + audio_sample_list, data_type=kwargs.get("data_type", "sound"), frontend=frontend + ) + time3 = time.perf_counter() + meta_data["extract_feat"] = f"{time3 - time2:0.3f}" + frame_shift = frontend.frame_shift if hasattr(frontend, "frame_shift") else 10 + lfr_n = frontend.lfr_n if hasattr(frontend, "lfr_n") else 1 + meta_data["batch_data_time"] = speech_lengths.sum().item() * frame_shift * lfr_n / 1000 + + speech = speech.to(device=kwargs["device"])[0, :, :] + speech_lengths = speech_lengths.to(device=kwargs["device"]) + + DecodingOptions = kwargs.get("DecodingOptions", {}) + task = DecodingOptions.get("task", "ASR") + if isinstance(task, str): + task = [task] + task = "".join([f"<|{x}|>" for x in task]) + initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") + + language = DecodingOptions.get("language", None) + language = None if language == "auto" else language + + sos = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt + sos_int = tokenizer.encode(sos, allowed_special="all") + eos = kwargs.get("model_conf").get("eos") + eos_int = tokenizer.encode(eos, allowed_special="all") + self.beam_search.sos = sos_int + self.beam_search.eos = eos_int[0] + + # Paramterts for rich decoding + self.beam_search.emo_unk = tokenizer.encode( + DecodingOptions.get("emo_unk_token", "<|SPECIAL_TOKEN_1|>"), allowed_special="all" + )[0] + self.beam_search.emo_unk_score = 1 + self.beam_search.emo_tokens = tokenizer.encode( + DecodingOptions.get("emo_target_tokens", "<|HAPPY|><|SAD|><|ANGRY|>"), + allowed_special="all", + ) + self.beam_search.emo_scores = DecodingOptions.get("emo_target_threshold", [0.1, 0.1, 0.1]) + + self.beam_search.event_bg_token = tokenizer.encode( + DecodingOptions.get("gain_tokens_bg", "<|Speech|><|BGM|><|Applause|><|Laughter|>"), + allowed_special="all", + ) + self.beam_search.event_ed_token = tokenizer.encode( + DecodingOptions.get("gain_tokens_ed", "<|/Speech|><|/BGM|><|/Applause|><|/Laughter|>"), + allowed_special="all", + ) + self.beam_search.event_score_ga = DecodingOptions.get("gain_tokens_score", [1, 1, 1, 1]) + + encoder_out, encoder_out_lens = self.encode( + speech[None, :, :].permute(0, 2, 1), speech_lengths + ) + + if text_token_int is not None: + i = 0 + results = [] + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"1best_recog"] + + # 1. Forward decoder + ys_pad = torch.tensor(sos_int + text_token_int, dtype=torch.int64).to(kwargs["device"])[ + None, : + ] + ys_pad_lens = torch.tensor([len(sos_int + text_token_int)], dtype=torch.int64).to( + kwargs["device"] + )[None, :] + decoder_out = self.model.decoder( + x=ys_pad, xa=encoder_out, hlens=encoder_out_lens, ys_in_lens=ys_pad_lens + ) + + token_int = decoder_out.argmax(-1)[0, :].tolist() + text = tokenizer.decode(token_int) + + result_i = {"key": key[i], "text": text} + results.append(result_i) + + if ibest_writer is not None: + # ibest_writer["token"][key[i]] = " ".join(token) + ibest_writer["text"][key[i]] = text + return results, meta_data + + # c. Passed the encoder result and the beam search + nbest_hyps = self.beam_search( + x=encoder_out[0], + maxlenratio=kwargs.get("maxlenratio", 0.0), + minlenratio=kwargs.get("minlenratio", 0.0), + ) + + nbest_hyps = nbest_hyps[: self.nbest] + + results = [] + b, n, d = encoder_out.size() + for i in range(b): + + for nbest_idx, hyp in enumerate(nbest_hyps): + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"{nbest_idx + 1}best_recog"] + + # remove sos/eos and get results + last_pos = -1 + if isinstance(hyp.yseq, list): + token_int = hyp.yseq[1:last_pos] + else: + token_int = hyp.yseq[1:last_pos].tolist() + + # # remove blank symbol id, which is assumed to be 0 + # token_int = list( + # filter( + # lambda x: x != self.eos and x != self.sos and x != self.blank_id, token_int + # ) + # ) + + # Change integer-ids to tokens + # token = tokenizer.ids2tokens(token_int) + text = tokenizer.decode(token_int) + + result_i = {"key": key[i], "text": text} + results.append(result_i) + + if ibest_writer is not None: + # ibest_writer["token"][key[i]] = " ".join(token) + ibest_writer["text"][key[i]] = text + + return results, meta_data From 4a99a0ac273956a7f8e6608e71aafbb5202fcca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 11 May 2024 21:55:14 +0800 Subject: [PATCH 041/125] sensevoice sanm --- .../datasets/sense_voice_datasets/datasets.py | 24 +++++++++++++++---- funasr/models/sense_voice/model.py | 12 ++++------ funasr/tokenizer/sentencepiece_tokenizer.py | 8 +++++-- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index ee2f13dca..690a1c56c 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -53,6 +53,12 @@ class SenseVoiceDataset(torch.utils.data.Dataset): self.prompt_ids_len = 0 self.retry = kwargs.get("retry", 5) + self.permute = False + from funasr.frontends.whisper_frontend import WhisperFrontend + + if isinstance(self.frontend, WhisperFrontend): + self.permute = True + def get_source_len(self, index): item = self.index_ds[index] return self.index_ds.get_source_len(item) @@ -92,7 +98,8 @@ class SenseVoiceDataset(torch.utils.data.Dataset): if speech_lengths > self.batch_size: continue - speech = speech.permute(0, 2, 1) + if self.permute: + speech = speech.permute(0, 2, 1) target = item["target"] if self.preprocessor_text: target = self.preprocessor_text(target) @@ -100,8 +107,14 @@ class SenseVoiceDataset(torch.utils.data.Dataset): task = item.get("prompt", "<|ASR|>") text_language = item.get("text_language", "<|zh|>") - prompt = f"{self.sos}{task}{text_language}" - prompt_ids = self.tokenizer.encode(prompt, allowed_special="all") + if isinstance(self.sos, str): + prompt = f"{self.sos}{task}{text_language}" + prompt_ids = self.tokenizer.encode(prompt, allowed_special="all") + else: + prompt = f"{task}{text_language}" + prompt_ids = self.tokenizer.encode(prompt, allowed_special="all") + prompt_ids = [self.sos] + prompt_ids + prompt_ids_len = len(prompt_ids) - 1 # [sos, task] self.prompt_ids_len = prompt_ids_len @@ -110,7 +123,10 @@ class SenseVoiceDataset(torch.utils.data.Dataset): if target_ids_len > 200: continue - eos = self.tokenizer.encode(self.eos, allowed_special="all") # [eos] + if isinstance(self.eos, str): + eos = self.tokenizer.encode(self.eos, allowed_special="all") # [eos] + else: + eos = [self.eos] ids = prompt_ids + target_ids + eos # [sos, task, lid, text, eos] ids_lengths = len(ids) diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index a633a8d13..127d5a0a5 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -1005,9 +1005,7 @@ class SenseVoiceSANM(nn.Module): if specaug is not None: specaug_class = tables.specaug_classes.get(specaug) specaug = specaug_class(**specaug_conf) - if normalize is not None: - normalize_class = tables.normalize_classes.get(normalize) - normalize = normalize_class(**normalize_conf) + encoder_class = tables.encoder_classes.get(encoder) encoder = encoder_class(input_size=input_size, **encoder_conf) encoder_output_size = encoder.output_size() @@ -1026,7 +1024,7 @@ class SenseVoiceSANM(nn.Module): self.ignore_id = ignore_id self.specaug = specaug - self.normalize = normalize + self.encoder = encoder self.decoder = decoder @@ -1040,12 +1038,9 @@ class SenseVoiceSANM(nn.Module): self.error_calculator = None - self.share_embedding = share_embedding - if self.share_embedding: - self.decoder.embed = None - self.length_normalized_loss = length_normalized_loss self.beam_search = None + self.activation_checkpoint = kwargs.get("activation_checkpoint", False) def forward( self, @@ -1139,6 +1134,7 @@ class SenseVoiceSANM(nn.Module): stats = {} # 1. Forward decoder + ys_pad[ys_pad == -1] = 0 decoder_out = self.decoder(encoder_out, encoder_out_lens, ys_pad, ys_pad_lens) if isinstance(decoder_out, (list, tuple)): decoder_out = decoder_out[0] diff --git a/funasr/tokenizer/sentencepiece_tokenizer.py b/funasr/tokenizer/sentencepiece_tokenizer.py index ff4b3a2ba..1be1b8158 100644 --- a/funasr/tokenizer/sentencepiece_tokenizer.py +++ b/funasr/tokenizer/sentencepiece_tokenizer.py @@ -20,6 +20,7 @@ class SentencepiecesTokenizer(BaseTokenizer): # "TypeError: can't pickle SwigPyObject objects", # when giving it as argument of "multiprocessing.Process()". self.sp = None + self._build_sentence_piece_processor() def __repr__(self): return f'{self.__class__.__name__}(model="{self.bpemodel}")' @@ -38,10 +39,13 @@ class SentencepiecesTokenizer(BaseTokenizer): self._build_sentence_piece_processor() return self.sp.DecodePieces(list(tokens)) - def encode(self, line: str) -> List[int]: + def encode(self, line: str, **kwargs) -> List[int]: self._build_sentence_piece_processor() return self.sp.EncodeAsIds(line) - def decode(self, line: List[int]): + def decode(self, line: List[int], **kwargs): self._build_sentence_piece_processor() return self.sp.DecodeIds(line) + + def get_vocab_size(self): + return self.sp.GetPieceSize() From 403033a15f418d505582950f6b5b58f105a86945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 14 May 2024 15:45:35 +0800 Subject: [PATCH 042/125] add --- docs/images/wechat.png | Bin 161343 -> 160542 bytes .../emotion2vec/demo.py | 3 +- funasr/bin/train_ds.py | 241 ++++++ funasr/train_utils/trainer_ds.py | 800 ++++++++++++++++++ funasr/utils/misc.py | 14 +- 5 files changed, 1051 insertions(+), 7 deletions(-) create mode 100644 funasr/bin/train_ds.py create mode 100644 funasr/train_utils/trainer_ds.py diff --git a/docs/images/wechat.png b/docs/images/wechat.png index a0ee69308ea58f27eee7e93fc10d2793f28de09b..0ae18907cfcd63a4db277fa09f5f8e8829670978 100644 GIT binary patch literal 160542 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%0DE<_oP? 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 literal 161343 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%0AZQ>|JxSSg^ORC;hK79iw8-Rt_!V4>* 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 -p5e z&Fp~zlvzje?Y)>DCe5s=@TofD%X`9!de^szFJbKQE~PUAx9JF4C@_5P&+vy|9XQ9Q zdeDa14)ihN4M6pry6ci)pulgo#Gye0x~rdL1V(fGufPA`y+wxco(z_k;NF4nmWP&? z%UCn~7#RF$51NL3TQ3Frz^~#oIAdTq0k;qP;C9E;Xs$^}Q08{0o@)|z=loB?6*r+% zgSvWdP!wU9?{W9qgwNUXCcHq5836uvn#(2V3`p4m`lF<#mOyiloY>gRxJyNZ))Q98 zElXrqg`g=W@CZEkm(YAHYe5Fun2u8Q7E9v=YAX_fLK`}?(lL9AmRB1#CaM{M&(BVL z$JN9QE}wM(I{rB~L%@^pPlkOv7*Y8N7EdO8_$64RmE ziGQjqIIpl!hNbbWoW}8#hsJyg;RqZ=j_*q#jh54xF?a;Agr|;EHFg=rh}Fk!j_+2a zb^Cz>ksf+9K)5A24y&UMMkDqic2+fKPF_#8DXOWB9w$vNqFsTmc>DSb zXh+Ne4MBSK9A&N^1Iv%VOFmt^0)ZYGRTv3}=f!QmbTS6V=JYy$ z2N*r6G!t8ne}hvH(#Fa8VPi?893R6}7eK)&o|VkVJ=B($E-*n{eJQ+m+d;a6z{$Aa zKZ8lR9>b^nXxz}F{V^2db=Kzf&znx`qlA@a%O|i#!C}leb_EsNAX9+mbn41~n?c5%-a2qj27mLG#D!iY4u^@m}H}-xK6sf3D-+YgXb) zXxood;RjY<7WI`XlI9eV3=R;3mn>6fIrJ$-TC@ccF|zMe+`V?CFi$z>(Z1T5r`LBr zSow~wdVf)}0}fge?AAOG2d9v-;TZ{LXcs=O4K2(?S@FkP^PxTyvpuBU_+|l=3=qN-D{|gJH$t%f3fu* z@KpZ&|M*dTNC}m4lqiHyI--&pQnE!xGLw&)qnkbFS-pzhC1yUhjtMzwivF)Wr;(C$g@Io4KZfh8p=cL-h7K zCsm^wd#=3OpWy!)Qrro3v3{iXplr@F=nlC@I_AU%7FAC7dbuzjG98dh4T}f&H z(`G+cH8ecbsr-jo|IzF*xFR^)DRy6~;yWl%-~4t--ZEWl`1>{f4I$z0=uw$p%=|-S z+^ayCv=wV7s9cWOel#ts%=c`HZwkQkB#9yzkZ!h(7Hzw#?vebrVHYpYeRLlDJNEN)~ zu~1$9VCuYvBdQ2p&( z5tNXKd}r9#+iUTCu!M+iG2(4+tlE4L+T{ED`}Jp*fBtMj!c*L|L-Whg(WYDs{0SKi{IlkEJzHl|9L^D&3-)W3)Sqf8kzXiP1Au z>2ZH1x-z|!&%UZzc>==h8nkI~e*i71gW`4YLl*deEuQo3ZSa-8Jm}0^<-l3v3oI=W zVbZgkfkdi#elVhh$|iIEX%r~qyc-kY@zy?g^$DmBgSV?*x^m?T)2?00d-m*UG1);! zT~k;0hVQPy5s!QK?h$sO7Y)p;tV$@_k1Y4&0xck?Os0ejTgo6rh%EObBq<>?o_Wyx z_Nt-Nk8)cCe?g$MrrN0$Ep{%l6k8?PrRF0Q|HZ?OPcr;}2@zI%+icu;SO z1>sgd-Q@A~$W@I$zgKd67R9D+?QZI|+@v+Lc3#zZ zs3Q<~C*lU{?y6-QZB3Ge80^#1yxN09hQ{~|BSEL!_gs>aQD|^Z0QNmw`I>N1xf5md zJ`e7k_v?!1ZBU2q49Exs;uVK4DmHFJyIEaBW6R~v^xG{TK1@Vz0JJcy>Ev__e^O#h zqv+!UuJa_Gb0UbK6jS5$wZ-!Xjn){+3QgW1;7#u(78P9}e$rSM^D4535N7urIr27u zr#?s|H#fL|rN8Kwl(yf7ZG4^S7ejKLx1P$%)&Y(8-0}Oo!r8MSUDGfqz0NZ%(K&T$ zy|y!(q)TUiQa^z$=Y~8uc73!{OiOFO-kZVEKs@wrv9{$UsNY^07#_LYUAFBrY>)zn zDj?y~s^#~U0TzDXP{pG?vNz2=Mmo&(d06(i?0>WXPpQTQ9*ks2Y}vYX-|pS+DMc)%V1MPStE=VzNZAaMvap-^ zEAT~L;6YtmoHn~}-+o$8ZwC=AX2GqdG}MyguypkboU&%GHU|U-?h_Y}c&EB%?OJ8( zS(PYpg`wKeZx7WIPH#JQ>vw*+sMx#KR!yt^d{GRj#hA2v_a585kMV+gP#t;-+yEf) zYG8avqHq1qIDXOON^j0_qPCR!{Zsb3K?Qje>(NKZ^%fp=WxJ%@BCI-6>kA5@;0Zlo zkZ&>j2O7R+l$`IkeTKj}7Bfy+R>rf_(;vaNaq4Qp+;;5-1fES$2DT5IKY#M%2~ndp z!?sqw&Gb{*Jwg`=Xn8Q)P|>MZswdEIzIYoq=|(ZhedlIf5umlYk+Lo>`E8EFW~Wb` zO3#zPRlaJF&916C^^w(Se%z8tR-Nf18EkN%0rMqS2p8VZsWEwhNl>WgJbd`JkQdzc?K6Jc)7h8s~K%c84^Q?b1R%Cj!9%Ud@xAGj7SNxNagmeksG<5E8pot89c zJ`U`Q4iD$kkMiln0MK*M)lTbw`aKvW-6X zW|gLw81KNC1ZpMBjR-ZB(T%u%u)f8~Sd=DRLfdd^R_B()m5vgjhP-GRn;YbVROx%h z1%_mue^oxApKnehWq%tTi)0&1tDHC{D3P5g@lo**snU}Q`|y2(hUA;dTeCN9MwPU~ zhBI8LF0_1hGFMDBxYgAZRq;K6#ocr@bs3w}n%TCO2%G1%Fj z#C0i#!SU4%*{S>Yn>|TANM&;)wXi?eY32C2|La?w^ru;FxaLLco@qZf*U&a5xU>5M zxlnkmjnaR8b-XAMFS^Ip!z|4$k?N5BWppld(}X461l3^J>Zj$rFB4g}Zr%EN1lq;r zWn@2I-c!7Hy}fB1ot-xZXZ!ef7Z+)-PDwi-bz5trMn}ro{8$SXt*|!H zvdYSHk=_Q+Jw4Z@^l%*@Rr+ z><~D5G%V%7`3kwV8=+#B;WjIV3oXxzboJxjf-nuPWi<<(xtR7dKYts5s_e@P;FlEf& zadq1vO_z*{&kB{}V*A+e`m^7tNG4^4-BhHMgZjoCkp?}S$PB2pMKqYoUkub2{Dv$~ zsm9sSu^CL}FoYLs``H;8rGXDb$%|z4BburDQI5GTy|HqpV-pX9(jifSjmQJYlgZgU zrhXvZE+4Ld#7OCC{*Sv>i?5fq`PD~DMZ37V?&IO{_L&@r!ruQdvBb7ziwsP4322m( z4j7_ZnMES+;Z!~V4GE8fgF~Lp$2+4-OK6$Y5n#t3bBE&o!d4M@+Tea_+BQDTXMhUt zh8#GrCuFEQp`N6%*J-Byh_cCQZ6%;9^Yrj#jmwSD6SN@oE18J@{`px`O-61AJ~dDHimC(uY;YveH`Ai zORP^QAu;g-n79}{X5cbAj$PwLh4-W^$7zl)>q?(q)_$fFF#t0{dmG=gVBviLu~w30 zt(mNO?|^>JGX*we)>!zF?B>QmJSwxWu!Mj4fxaiO#Ar}YwQyzrTqXsXF1I5KU3S=m zj7uE{CdsH9!ryou5_OnlUHtjeChHqSfD@6alR#fQa4*ZV3Lml@su+zBom>JUl$QP(CDlGsYvhl7Y+^lP8X@ava6p zUJBBqE?Rjn6QwBeCs4w7Wqj?{h22fEzMhjCE#b`vOMutW{6)axeVY6XV(6RYJk!@a&n$( zPjLWccfaLWJCbnMv*R9~-7{z|%}}vqEM>mxd;4jhXhoo3;up`mcl9D^Fs29T?r@on z*F8n@kt-2RzeYwzgv}dRAH2@!g_gi#q$NSd4096>A(gvSj}6@V6PbObkB{jygxv`c z9>oYfG=V8uW`uTYQT(W>>MX-QjVMIfe1i$82=)Br_cUHnMO(DQ)wI`VH z;f|n_pe}E;kF|*EC^t&gPR0Y3p09_q3{TAPNfaf_wOn%6Q52ke9d9^ilP-8^F(8sg zhh{=IyTzaW>+Shg9v4gMe}j9cZjJYR(?f|+?b(#y!#}v_YH5#(Ar0iGyX`0qy-0dU zi=yCYCrVv2F`y5hU(nfL-3hPGa`y^8)k zQaUQ6Vs&E4{3riysfn$0E8oWb%;Ep~E2Kv68#Z3F!@EMZl2+a?S<)GX|L3}HgiOas zyz$^y8Z>YcUo5d(^UP33>OqVIiFNC0lGYBB)}8H4L&ZCpQ0d_+z(X43O)psU?Tmo#+QN~46RwShF3^Pa zmRrP{EQJg3WrM8X85x;7Z4<@^$@tAi_*3+wU-52mhV)Lj`uJU-Pp^lEEmHI3PM&-^ z@d1Tu2D(DCbGhOh>w%hy9#gBVmH%zWh-M zS>bOsv~PNLd|pL+A^Yk;0|zH(ZhHrA;cJ9^#YO!~3$Lg>N^r2-mMz5fd?2ptihom+ zTFMN@WtkY(lH9eh?_8WN`$JkD25|pkP;@LWciKIlDA#%2r{5}5z{$VC43%SUzjC^M zO}VZB&kSFAo&&4nmx&4GP(j19m;KR1oBt$o&65(e|bjg8IMCc1-RR8cZ-jM~3w zs5_(X#eo_g5AoHP(?yA~jD9Y&B&reJ5i zfNk`>Xm<-#ZAs{`uNUI?kNy4qyB2OPYt=sGAIP=$M#u8vSTq4YDm$Fe&$aVHH>&k* z@ zB@F_dhRbo^b!==7YCErHwC&r&%R1AI*E&SQP^T2=1UE^hL%*YU3L6rTdC{-w`wD)j zi!vZ2^yQaFt<(jcKsf0>oz$OShh`QQz9rY9v#sx+y^j0byOL)&bXs}zabRF+zsrnr zs*~nRoyP!yP6mprL>?XmKddeYRqVx?x|CR7tJldgXA5l}YMvOd96Po{!Gs5paVf>1U(P%)<^mlXW)ly#XtLpOaR=}!T2svi%Fc9LcuUQl65&DP5xY+>dp4QB3N3ghLG{LCMf`u>g4V3WXvg>T zYofO86L&M)YYm#BNZloFZ2wbc1TjqfV2>C-DkU&g(ZpsKBXOKtK=prh(Esmm@jo@g zsfvb{`uYdGeSLc`m>Nz_P97~OqM`oaPBUq2Ql~p+CTOABwDW{|#MiLO`b~-FNe|aw zI^e#k`Y8Fq!-vmN*wS`&c0imVjr{%AVMpHW=u1=#y`^Pgne7_~4`>ghqL7V-IsPB# zMB^;H-1p(b>|+m81Q|&4?gSJNU~5AZ7hqZA0D7IOs*)Uq9)iGnz>1`pj{F!jMn099 zS%%Ho+WKYlA6VpAV#vsX2}ETQY|8}mTf9|UGHoym#l*9D3?_nrqM{--KiGFS);E5J z)O1UD5s<-F2%!Ty5C>Y{Ib4k)KiGNXIY2_`7k>L;V7SYtohqRDeAej4pWh2o(?5P} z_HBmYCT7u591xex46vxDD4pWJs-X+B>dAhk_5@Yu;}RoY$6aum&yBWi^`*c*71se= zH4&iS`f}caf-wx4Kw_{9)m}}a{IgHQ@6xew2;aJJA--851GxL#c-I+Td6Xf3*$yGr zJl4L$Bi|BrzjW@dKZiaD~5*9|AR{ za@c9sBE|mo(3i={24LrUdczuL9hA1iJ|$~E z7l^n&Gc)r!xfV=hHFzjx6C?pY=kw>%jc#+#fu#D{ z&*tszof+-6q!1_$Nqr6G=F|tDw6+$&PL5FULtT=wL&ORl*r7)8QlwKQlb7e-J|ynr z&=06a!(P>5f95V<2O{3m6F{jzRX`BOIiu=uWMyMmM@*lbZ4_+V{ zU9kx=<2TNn9}@D%d#ySeY)or?_JpNJTn2|)ey zC2!>66#F$K$_7(%^14B@iMM+R;$da!xYZWo!papKstI^UN4?hU z;zhk}viIwaY;7qMNJ*Fa0oOfUxpnsJb^w<8S@{U7s40|qrB2R5a-acw#i$G6CqmB6 zoWgLD(6LOo{gb+;>QUJ#^Qc6qMK;#f-iPMMYQ6x%>lU9amoGkr8*}Dj24Y# zQUfz)ZGV0HHGic$S&P3u_4MaHHjpoB;HZVGZ~F{`n$}-_f-Dr`IMfa&HF1!Dhn|`N9q-{#%? z5o_g#>ebiJPk6Z>7WrXR$jKDEzdSamR;0go*4Sw*vc5vsbEgl;$)OVu3JV)n)7EW8 zRJh~ekx-6m;-yV^euHuwg6eX;t>Q}C$j=JDkADA&;(_Yiqn26Y5SAXtokwKALB=*uP zy?$IaKmfD(0zj}WkWOfs5>*H!3~9&Mhh@Pd5GK#-g=n1AfXdVrE}(O5f;&jdRM?`) z9mx`Z1Z3%qo?f`ssv>(aGYWg!ex)@T0wDP#QNbg?3*MO3Zcla0%3(=Q`7rjIg(U5B zellXs;Iq~8?C#y}cN#VpW6!;TH(JBC8{R4_ z2u*DRK*-!~d+f-ISC{xo`P1^>_Yn~C;eF9hpVr=`-&NC=hN7APsJST((Nc|h4pR-m z=)c!t49`>U%T#ueXxj;Sy#5L?+bZ)&fYPZ`M$OI5`nBdLKs!-FnQbve=zfVR6BFy9 z*&0U$!A;q|U$2Zn2B&@Q-~SLV!D2e@#cVKWVEC;uI!%}DVNJJdO5M}K_eH2iuRGSQ z9jyDeCfGZ(PxQN>1brBRm7s8%n7BM0?}LcGp?v+OO=chia*4|6wOOraG+k5NNrn+e zI?O!br9o+a7`$T~Ie+agheVv4nvHK1Fio_3c)&6g4i1h^Pyu`e64Ftq1~Z|Fr=7cm zb>G=v;H+rEDt5z9#G*->S02uZE)=N%))5c2(hSb?%A=ThF!~yb`0cE$0!(r6Be(Rt zx%KC_j3}9odLBf~sm9XB_ufPkCC>E6eWIjn@72XwI+WBh^21z3T zIaX*IJxvHC<$z(KfF`vyzm!xoUd5xy4OKs68PNe90KT^LQ)Bj=4;m9i1H&Af+hdjo z7WfJZ#N2)zMX=gf&e+%ggYkUFm4U+gIeXs0#LAV-xKdj#)UE_>Ve@@AJ3ZTPk0Hf# zLfzWe9QR8|g*fDdX4TS!2%7$d=ckRO7>t}(F>_XNY29&KA$pV9roxZ|JV&c;sJvco zYYW|~ohCILjUzBgsRWC6*wcf;d*9Dvw}4?oW6RJwnyvSw!BdfeUy#E+2wuG>CGuMjsZqyE|8d?SEX-N&Fzn@0K zyK&Mu_Lh@{VQ=ZWNmQC&z!_lN^gaR{QiI2#nNz0Z7>GMfP0b5a!tuotN<_W0W&u5- z9oPdiem*|C?#jNNQlfK%MYi9Pl*79Ek3kS3O#5L<>qMk)siJ}c!Lh2{xRG6OrrC3^ z2m8^^ju1bpeV0s))aWL)oE(d%&30+06hP|4)*SW4LOz47=v4!ArnVCsrr2x_FG5tG#jG{*%2hz{GL#*MtxpvIM0K1P z8ahG9&eZ(SxoIdV`Khs_@4t2H)()a&c+%OaGR-H>@AbBy{-V$xudsDHnaul2>P@=q@{Q-b zzN196!&*1jD9p(T+i#E`#xDp|z?DpFc-yRR=vZ{XEOR?z*vyl6h8WOk zq)`aw5993I`Q^cCi`jniRPgijqnn30&}M%RIxrKAdV5QRJAlj?fRZ1l7_wtF&Li%+!Sae-{%(;5QV;H3 zwmXj}VP{|JWxxR^VEiAtllSX)oBCl$dCpg`LBh+o`t$gFWvHmAhy(_uZE7Ke0GuEc zlJ62@e19p$-~K&?!JX`qwTZx6@T2CtIL1pwD&_-BD15nFm}6<7hxLSd z%`Y)vPxaGBuMIPTbpKcw-AIlDaPa}t|3qp{VQ{%N*(=&6?u2=yh~jMm{%}TXXG!_^ zU@o9E3iJ_@=TCpLK5o61g?RIlueQsSrI81hg*Es~H&*!>q5SS(Q_UgBZ z6VP3NsR=!J_HiIKKGRfS`hWMtOBYNwh!rT`6w1saaVLm?AX_oiCukWXt7>$I};}|v6&gBn-U3z=St{eZ+ z0t^lsrHTW2tkBTVz*i`Cr|NZWLCd6UhxwX2E;YygqfL*y4J)#Cpg5}9O5D!(!6y+{ zIzdqE8M1fmVGlG_Chexaw8@?1JoV+EXhjKRM!P&E2LP%qJyS3?-jjkyphi42@FOZ# z1ii*w`0f@SxvraAVXOFE2KEMYq+ZiEaWCV)7L!d0w!EeUWf+DWpR}SUs(IvT<{D06 zVa+9JM2x^N0BdS&KrHzOm`h3@9|lp{b%4T}zl&?sh8A)T~DM;TWimcHg(DSK_FQT6;o@8Q?R z)$=OKDk}7dZ?wU=c!)5Wp039N)k4mfmbS4;FE~T0MteCPxn{HI)Q9x~uR=4ky*UFV zeEw+&D&m$l7br4Ol|e zIj^#o>xr=C7EtRwVw)20@+(Eqs63woXzLz=dX|_vxB3!D)!YKs8c`9-r0+j|#Nf8# z^^c_0nMRvp)}mQN&g8J`4^#)~A#Nk|N(!9Fn=d0H3J~@d+kNCh>8>g%DT((g{)p@= ztp?qRC6LY>%tYdcIRtsZ7lt;ADb3SI$EtZ#58ARFwQOO>yZst3=)XSR`4~0i2`s_4 zm)MMQA3b737!tic)!)~jL^{faZ>3{|%{z<1I-gtQX*3I695KCsTLKjAyh{1r!3|r# z-43)|0n^r?$}rZ484bknin3?-)!{TXl8;`FOy5a_(U^fMGwlu8kSTU$JwcY z==0F*S+QxS8JMl5remxzMf3dY%41W+Fd4`3p0}!2^nR3iT+D`{CctSS5fK6+ z-v8#>^+Q1L`!5jCUybR~?1%u8p%oi!(pmSx@+k1KD`iI`lRT@Q-%`Ad*a>%lafF0~RAAWOH;*vq)6{Q=h%Z`yzKA$ZQO9X6%(hU!UI>JNmQmz-m;Gl-3 zS6{e*(9(np*EB`p8;XdHCLQxMZC~Nkk<`5?iULF{z=bngP&<8y7q5Cb6~JK4%L3<@w15DGTwG01zsX?nYeseq3`Ap=u`4l7c~%^kIw*yJ zOnUSZ@MTa?5SQk2aB~Fi@IdHw9cUP+eC6lPEjaJY=Kpfh}rCyH@N z|Aab9%23St^Q;kF16Ckro{Iyst2u~*B+gG@2G#*}ef@~F|%Aii~-ZbeL2k$)8P0nX3%iiRf!1tQG4c5g|$|I$qMu%gN69tLy05WIYL z15yg<*t5z&b{3EAA?=F(6I4r|M{Dn;bg+|1(wB%^K+3!j;ir3S_|r?|7X8%1h#aRC z{OOy!fTc+X(N?z)P|0e zg>(YE4eV%0B%8CVPt6)+i_DDn3$@#Yi(hv_kfD!R5ti^7LXfdE%n5M)fMXwUYr>`B zWnv8*4U}bG=nkQsrL7-$b?ykEAQGvmu#>$@M@;Nl9}M)z(9fU=-g?l0!}f z7?ZMrmUgr64@@#(DUfuWj#pcRYLS>jqsAfviYN}e5+HXeH*o^Owpx8gO2#=+TS?M+ z5fQA(=ia7{?w#?CZ2~KIIVjkSSnvdXGwMPN{8f$;?;3Z8Z1u3Hx`;UlFJX+A{m8nD zkgQms;!LiUCuk^|0qa+WMQ+yyi>cZc37s?=+(XL-nwm^N6qgH!ww;Ip`mct2P+tfc z+4a=x`$a{c0C`gC2R^j}yQpq*Yz%0zB_^gL-V8U(E;);jJ?m^aW8r&Q?V+U?D< z?$Wp}d2${Snr0k&k#Niq(b5w2aQG0#<);mFrfQK_5dwrkK-N#EpOu%V7P;E5e_ir~ z`Y^cC!&U1q5Y;&dV3q5I%X4FxHz$vXrPfDJ1POSb5M)uTd>|CVGf;lKJ0znrm;~w#aJiio$kNQC z)P#mQpz9A056>AK{h(Rv46guiWrSrYubPRsoU!Ok--D;vKkf|BJrQ(V@>fC|ACAKW zMqNnH&d`wr0)R&%Qr7zTIOo}adpIkOLfO;Kq9=PlX2%`!wZ-#~Ava1c3xJs5-Djw& zSq6CX0Fx=E;k?9zcP{zk$Em>fN2vLMeaVE6Gk}ai5=7t5D}Va5@2q6=eP}$^XO#~( z$30lmx=Z9vu){IpZi_?ANupH&k&*i~30ylJ@z^_-e4c3vZJ=6fk<(mMfhc$&O~%*tZtsFK|B9ALrLp(Q;qEf}K0rx}V7 z3Mx)Tm^esCRAR(Wv(Ml>utN+C43pF7w*`23DtYe?Q;6w_N=sO#aWWKQm`a?hDfokB z%)|0D!STo+EL{H~Ro+H?+PH~LT*ty(K~6wGK*@>CH+KEdGu{n5f!=6Qe0(r>x)Jk+)ak%wQrP>Z=^Q$)W*xQh4g-kwOTh2WqfDD+Q^jRC$oZ8F|p&=V^TY1XC8>}-Ou z`#8^f*gCA>!{H2!8N0tUhrOpUgCZ`+#u;9UI5I|wZGA`(>v3e1Ztp1=4r0kv8ZaLr zbqn_vS?zv%2M8dAiLIpcO#ttTWt4ar!nV|x_WlZKO}NIw;#gHx!sa*}%r<&)b{UHn%b~2RnObXrpu_ zTgTRucjto?@AE6MK0zKSR$qPb&*yTtc>Eh$3me`;fLt>Dk5gRbT-oCoiL4=ki7};R z5t5oW@#!BoY>g1Va|}x6b<$VUqpA`r=daCurj}@D$4ffy{QHuXU1jdS2cI4#O&Cc$ zM%Egss@#<0eUBn>z>xHe=##eFgIa z-)tR^|FZ^sE8FLD%n=@cFQ7Ff^G({J3Fx|a5t6Y}_ahVh!i1=AjR$*=vqs!A=q}Zz zW}a(_+8xT4eLke3$wX{iAid9)UdXLIZu=P~(>hDsx4~jku?hB?xo_-24vk1Cb46;= zi3jo1oKWwCy1+_95~b=tG&J_*->0Wd2%W5g-&E0`D6}yt+1|0db?D?>;f~>^fWv4Y zY(~=u$#h6quG|!?tO_*$xh6qqMa(W-s2W+f3;u=m8#iqDWVI0*v3d9=tpX~Eo*zt( zHXEjTjsr6a|FTEcYs0pj(c^M2A!M3YVLs~R?QMTmwkPY7xyEl4y)U7!(O+JRZ8r~8 zG_0&M)12WDnNHvF=g*(%7+@Jz28YJJnYpZuM*-4zmk-X9k;a)hT92XslF8><3*yV;e z-VFpd>NGnXqs!I~OH@1|uYEOhF55ao{j3ooa&2ykk$pAV0idTDqpQJ>C24pOBGJq# z1pg?An3Kb=f*KnpaO35Ev}mV5#ArYGflgpm>U%7j^BtgR;%qRLjKYR+5n?KI!m$B( zAN~SzCC+u3)?Gr$IvKHAl$y~%RMO2j$5_ksrjt_(;Af-xf&sVX2k<%-EQj!LfRl_z zDUV!?Ohrr?ZX+YGB*4>q;<_ZMiRZtY74S9x{sa*l@$Zkj29V9cb@Z%9rC|w+=dE!~ z1T+SE@U26h83y*m114{CLSF-dJ#H0gtE#R2Y^92-__VUJ$j;B`8hR<1dMTU)dKoIX zy0$1VPO+Gm5J-mLT^JcCl`L5JlY{8gG(wS-aBUpg&KPQucG1*lb__IRT}6)F&;|#; z*X>!To}Tc_qh}&eTfLqADWHT9KC9c(fJP>Fx$VbS!Y#8c*TJOwi>f}1BOSnomF)mR zp>)cf_VM#;ePig2&DF+393o=9lh5N6k&>(efS0wW88)^>0pS+zNkijLxcE}@=va?7 zjo-)teonnl@92~xl29}k{5qRq{fQs7AOFw^F+^B;OOld2R%9qhV z!VO<{8QrgB%{Ei84|xWLR1x71t_p1=1t4xBHyWU+J322?KtE;;}oRFYKuqnoX`S(&lmsAi#!(zzLVFlAwbj*+!@cRi0E0Y;?AP~ft!#hQxGF2}Cd!FmE9 z0>EVzBZY32u_orY2ep8xsIC<~&eO1l8bro1AO0qJ)uDIbzX9cM_05362?M!zXC3&P zQ|MJby1e{R@BycZjYnqRLv+~C0Sgl$o=aL~b>BN`rkt(km4|G_hR)t!@(l{E+b3!( zV6{AL!Yb*alOw)41J(TLSGAZGwqNh?tbtfvEy{k_{FQW*hDj>&$ERj<#D{GQs2(Z!k42_r zUVG;;v29fXhEB!HLo6qhEtDog=?+9@PL&(S5-D$J{_Af|Q~TMRUKVjiE3G*y_A(kO zu)i{O(lPfy^%eWM`6knqxtxBIyM3vI5=npKY9~wLi6ecQ{ojAes*mjXR~(M!2F+yz zvMUny#$Z}{`Vcn_cKBYQ50f#2U-#BPhZRP`@E$#?^McMF+#78@q4Gvew>M2fT)fKY z;QDeTbP!2x%^1Hu*GkhhqCi zk*KIBCUAe6>hw*wp0BNh)k?Y=j{y1A!hQ92SUihmsWuf&;CMNcCqxA%iuyeRK%? zse;(-4t_|7&`5!0%0#5J`KytFN*mhK?8^jq@y%Bq{pmcKB1HNl{Wm=bW%&?5)Qyykxfyqy@kspu1IAkRA;Taduevmkf+WJPWlH z-UHT2s8r(=*o1yf-TL!+vSYIE-KBt1;HjmUg;5tQi--3V<$!`8Wbm2508+_dPA(A6 zZ3RDc*y#uYcI7@kK1Kk`Aod^#HrT~FQX{!V4_4?P<>%Ph*xQ>T(ZzC${(=MQC9)Kd z&s6;f*g!ATtI6N?So-X6?cw{L*v1rOYH*n zqeL^ggaT4?1_?19io{F`(ZMgFF3}uohCOby@7>#r*PjTPZGa^u>FW>l#%kc)>na8( z2yf<-g5x1jLq^_kDg0Gace@&A4fUO~&yz=E;sh7=%Yid5Ns5_wL62zbqymq8Fq& zsW5$ipHB(tX#(loLV%dzC$V9N3H9(!Q@}QFF!-K>&-vYPxmJ{Lgv!6Z;wO5?VN^-U zj@PF8BjL`DRW@xZaRlng;EjfttH)3o3qvd0CXRhF0zk8ai-sc>@I(`4X-__- z*{qJXlt5)Jnz|sF%>t@S$~MP!y+E-S-u4fvW)(79t(x352(A5p3aBsrPZ)~-0o!C( z&$BEa_8Qu1TZsnC*Kty^$L>WG)0Yux^2t*K>s66wl9Q8_KC zw-NjFNi1*jkuk9Lm%Cn<_m70^!$ZR$w0KYyft=OPdXpt~nIPP)9|GmI8_`YvUn`6LkF`{C9~}^rc~&WJaj)CJ?Fwn3VX5 zP?&)k?tx@oUEOi4sjpUzsJ;l_V|W?F&D1-^ZywYpI%*&I>(2+y6EzN2GO8(p{zVxX zNXE#qkCV8`D{a3Pg6?%*C^Dh9A|_1d6f*P9Xbyc!#Zzpp2JOReH65l2hF zR|*DIqPH<;lKnEW#~~5Rg{2&`*S9X5$?*9tar_Uc#s?@N&?L zrbbi$Lt0uzGFGvtL}dbds_VCWx>t{Z!$dIzqh)VFyOVm=`84|=Hy2k>na;Z#uTD6E z`v&F&82Pd~+rkz{xskpkkTfmJa&Oq=%0L2Y69UHK*!lbgQs~0d<(7$k%gx@{c+9CM zM~E5l+a7M-yxADC{U0?8Di}hak!-l_1jXr%4Q42uSjoFszaz<&qZCLZW+R|%=jh#z zxFJuu$v);d#kH(H2=YArg`wH4`$drO-Jj0sKs5BKh5eVM9021h8$Vb9;>dsy-V?wB zcb0_NPnZk^^i&Vvc&F+4m$sF5hrJF_Etplbgtxx?{`gXy#GLLe%xH1y zWFOA*Clx!cqDW?aj1z7V7<{L&lJ!*y#b<=Lr6R+G@rYAm<(w9^`736@uDO%Wc{e~& z6f>cO6Sz=a9e8M$-^j-=oBck1sa_QA*~Z;&*Y5P={q7`vrm0*QmC_(D@U z3=hBIAst;yY|{1GVV!?gKXCO`e|7%%nW+_q{(phpf4!)B5oU>sh%AHrzwZR@MQQbN zbKc8E^L%Lkn$Y3&qqsWockc9b(myDX=>lq?<2B~_2wa{ft(g9RGV-(m#N}rIGkTenm6bhu_s+R`3<2y6&=D__ zpvgcy0U_GLE5seXol;EIK-wSol>G}EXzRjRd;yNJF*~T~Z`Lir>^nCLlxwlk^5}IHm z0y>cFT0!E)kfBj|1_eosP&OkAi$Y0BiHsRS-Gy1qKB<62VINZ*9OLq7Czi_^8&z*Q zCsqJCLZ{53`5c-9Ce+L#{)Et&U`T4<1+N*tj@op!!Z zP`|lxT8~8GU2QDXJrv-FJADNQ2!8 zjzVZ=q$X{D3X}+Z=;p_xOw7#YQ`c&V0U+&}=Blt_p@_p#g$~>llsaV?m)x+8^VqTQ z6~v;yFc(o?Zi@r^G>+b!nL)}`F(^>lO>qFv{o zDEI+qYexx=qPQ)&-0jzolVf7ioS4ILp&vtxCPX3MJgcv7y~PwVmEIL%+Ht01S$Vnb z!Wg<+5zG5X`>UM4IH5KMtQW69=n;%jEq|$rgK}aV>yVp*YM^p;YQm~8dxl6~xy#^L zh$0R{(eTD7#gZm?&p@PsXT+v0f#hC`6kxo?6s6b55*V$9Nm%nW^0u7FCeCeI*A zs-wxSFLZ!W0=cqC(-bvC<(G5S?}&jtP(UVA2r?X>erUNLdb(kxwPXr@arW!mEBPzO z;CuPV&wP_`%4b`5#U6{se2Y!wgT>>{uusOohml~EDRQ+5Gfb%UK; z!gT{)Zc7u25O)mt{cA?GZ82Fp?SRX+a3Add5BQ(fH)lxCYVw6_aM_Rv$L}DN-}2f! z`|raNF&YSHjTl|6MVU3hy_C>HnaGySS42uSeTD5vk4Df;PILmVV(n8{KSS}V`p@atrnlSMFy8((z^~%3W|Qx@c~G1}K=7Bj9nX&h(gzmmi0RpN4%)yPkmdF>)(em+jWd z95d?qXG73*gtSisbZD{bdASh>%M5piqSkE$26A{h_%}P z=*e5dog!B8U4ddywu~SkBok$zIw(^3w?nXf2=dR$8FX-F-OdFz38x^kY4U`6nt?>z z&Y)v)&?9)G+LV!77+@!;0jt&*#)m6FDDv*#ubd@;$p>aaFvUDVD< zlKTxJU`;-KfmvwX)_&+V?fXde5LFR9Mf@+cuQ^wp$Sf??7>tpkaE?{{<|Dkn55Iqm ztoLhdUKG}ltXB5%;27zHJ53>`>ZK6G{c17)w>#Jf`7^Mq=L+YbMZJqH@_^qTAR`Do zF6C*W|vS-t?^AiT8{N9nx_ZA&`iouW#(!!wUO?#;W--%;;! z&j$jh>TzYmqNP#(NjDLPt>;-_BJRADR#2hk4#;1Y3K8<;lO%; zn2(p`^U*2_?feX%8SEYqzE~cvz}TwBZKX(Im>g0a??OPLP$wXo!}gDTSfp^d@*Sa` zhPA0CxDs@Qu9a0Xw7Q3dl;hnBt%@2l97ao&qBa z9}|&v_HuEZx_lo8G}ud-eVc4Wl@Dx%Uxd)r+D3;BME1KboR1@e&fdxgOKu~f>5L=C zo%G+nip^x(ewI(V{5T-sy@ZaP1K8-NvmSF$Lfyt}HCbN&7S-HED1@J^S_=UKD7^AM z)P=HsVeo68CC&kqrw|A_HVNinV79D~?+@sB4gr6RAs@O}_o$yOe{F+9B1S~jQ;WXJ zFmGgQ$ANY+c|mS9^+*f4fS^51g64vDo(z5bxCG&Sf9rOX5@zry>?LNE=%Rw~G?|_3 zdy2rK@T!&=Rz-kW(>F2wz|Vw`J^}8v4PBU>y#To6kZ+0DK}QFIPdJA$8R~TXiQ~PI zsFPM*Fj*4*>{1P|^z08JjMKWPq+7-R@`2;0W{ZP-bl~;!Gw}h7vg#}}4U#N*+m5ff zzveS^mKrlRK@@q}!`+^&?ng|$B1<^U9`rR_T>;$K9+jJo!X>%1q{!B6bE@`mXkK?bpv~8kJ-bwTriL#3UuL zHl1@wK-;sv0a;fx`GrTYz5J1c&HiIm(z8=>%~NeK_t=@h%| zA&SxHv4^>Q`;aZXdP$gob?le)PLe=un=45_*l+$q0J{^nSX7+t+>+Rull}C@i)+-p z=hl(NH-Tm~+RR#3wKq<}EL!~7bTw}dwY4{h;!*!Ym%aDv7DgofCaq2kA#E=??)MvN zP8*R<`f9KFR(8Bms6mu~ZXs(fUc(9s>HmDqx+kXvRdotUt7J1t;7*`r?(gV=WqSYE zQ8pSk?t&vN!&EZGj50KqcR92U&T^bTw!Y9^IEh1x@wnxk-CFB{xdb_Q2RE*vvb;^A zT_>abNKIzPNcG~%M}L>Dac=vmaitqK7F?pt**A$TjOQ*i)HT2w;@y65k0*Pi_m>kB z3PEzq%zMhn&F-{&dEMKjV*vVi${ISD`T1U6nSAIne~r7516!iUkqck zm;JWKQQdiqX!8zkPsTISYw=%&VGem$i@UUxBiGnCP}BnL9xhWfi=7 zwSRWBP4V-9xrtE9w;>0#4c>ePMej{OCb>1U<6VKvE+^MNrrIJy zXN8-GoySLgBvs(Wam8k_t2Dz0PihkDH_7(UNR5KKZ@UU(jCm`L=H4FL(o2&7=rZJDJ%f70lA#}Of*XG z4S|7ySp?y>9t1#`iGWTz3Es~v6IfEca}A+Ye0k~|EE%6*#ts|(`1!L3PK(p#Vi1jx zblriWCl#8Z=#Gq`<~d6MJ+TiSY&zqI&S2-W5VLRa>f(d1KF_vjf5`$=NQ+i+8tRBx=XY-O6QVhIYv$)cHDk zdR8mWkP<_qaNqsSgvMWsTN6eY5g?2(aGNH&p~QH1aFa9!8^`F!u+qX(c3n^eNO#x3hN9$GeHA9mtXD9?L-H6rL1)<^+v(v`2ViyhngqRQdskPiKCj2^5VCuDFe}lM z|2jaOnB4Hc{&d_^(~a3Q9eTT3p{Sdi_W`Q5)f7}$A#x8Lk_#{xp7;reVLO2Dm=>fS z?L*bVRzdPnzMC(_BOz+zD`K68qb|MBvSh|_{*NpnIc>2!?0I=>tef~W;vZc{+RS~Y z4kJ@M*vl}fE7YjO8drfNn#Cmd^!GnYE0wGbn6xJeJ+|}p7^}oUN5ku{wTyXkkrJ2x{Ez5A;ubH2B#9`*` z>&v=$J8_1;)aSK&jRdpW^M?jQ@m$GZw7o?hW^Y)D?V4-GQfUW;&H6DGk5x^YwI1$X zt|NO)Y^=t72y(!^3Zpyrls>b8~Z)vx!Tr zEDcG|d_6}KbHmO30bcH$PE0Bit*fg;P+*&eLq>M?-HeDhV6uZd7+0^RJ+DAj833EI z0TsAF5K4Rv(yV$S_(}JP_+`K^Y*+G<5I+{o4ddY}92go7^+~5rHZUx$Fo92?vSbju zmTfU7m9|{RK}1Bv5GB;{-{?+Fu+K)0!)}s~fC@{JkX4M2CfTF)RFg*@8rdJ`57G;5 z#M$Ys0zh=Xy1IJ&?uw=$oWItEr*k8m=3c#hTa4my!?R)mr_uH$KUHV$ulEE(d0RRN z4_hppczV2Oowx|1>^3zuWk`kjY_qijGYd3KCE@PCwtl#8!=sW9Tq;Q(A|m!|oxo@k zhngt%V`#_*RSy>x{bvEGxYt3t=(Mase~tv2^ML3ZVlCF5-mnDO??%pyH_Ac;b)(;cH0Re?Du4ZdNX?a$P3e7(=KAU&zY4 z&U2$Ps1El+Ra~}K{;vp$8xF6QQ))haVnt-m3zk^)R=evR8_+d?pdeQt!f>?%wLQ4EpnKDG`_QLZ*|n35?vC1<8bwN z3Q7u*_(z>N-*MSB>K$n>_^0Ccu;d7B+qM!ROJ*OH#q4Kg(Xv`+O<{~-29125&aSS^@`zBxfz|F2WY_zX zQ?XNQ;Rr~eOGC}lxiop_88#54CAw;r(C+eyiw7oZjQusG&Efi!*{0QLE}iwahG#OA8eABb>idd(X8VU*;)Jix>MC_B^_e(CIyv2QnhW0+ z=iKm1aqHE+(Q|&xT`H*24s7i?@}N!BC#1VA&%#x}>S-~PPH|;xOI_<=vecEl3o-xs z!85|&!kFv!OKOCv4n-@*PnaB9Q<(^JyZGwWzCEZ%!C`&7=|XN^&mDo{C5 z&pV*(u0OtWdP-_~M&#qMW<4tfjktM_h>fTLRrv3jDAju|R*wJshm!7FtXZd2$*}lM zK1%ReDNAa2XKHnM37MW99+a_koI;E{U!!I7v@X1Wy@lisHBh70j z;**z%V_;`r;v9odU0evdwyHCMid&=i}~7NwC*H9M?YVbng(a zRf1PEmS6Zb_1WiqD^cQlJ4BOrfaI5rkgkc9c=Dy^jWRCrEiR0RUFW&xY8pb$3vY>6&-d1)@!ppCoNf;G*gz0iMs)7psx%b~AXQ9^fz<`;_+A4ma5hcgY&BK#f&bD_1 z$HiU49%pA~6Uh0v7T#Jl2q$rZyu1mqeo&%+1nP-?(wIl0GP-g1u3qgow2ZgVC|xP~ z_2*}G=Gz@2;4yoe-@)uD0Tua)Dp2)U5pkNuf(^C!-F^y z0KCW@C#ChDjU$RJ7=K9S@78{UI77nak9`s+g!t}w`=p&7%;Ec#yw6~_{ZBPI3aCxa zlmr#X7Q?$zp5gh!D98Q=$YS=Few*oW3jd{X=#ci-AQUDOlappv)eyST;QKu8k8NV- zbQu-^dxAPjp$jc<1B3uaF(JAqp5H;&~ z6vX*h+>#BZh_8%z@Zbe|7q)IrPR>%>${nY&*xsb1uqF6$V^@rvokYd#+kHDE&|%2X|uevX?1~ktmH;L6q9{8%*&rHK^y#of`$yWzYj_rw#HsG^m*BAeLh{^6)sp zoVgVorF8O8XRUc8@4)YLl2xhP)6L>T9?Rw@jL1g4^XtK8deyz5I6K5`RUZqJk)qeI)<3n$H0H_8ng9Dph zyReHGA1_J#Jg?h4Hj~9mn|&G=C(z`7BjtFrY^vxtV<1$Iv7y(`9cEsR(%{957i<;E zViV4;4OeppgoC^VrmS%<5d!CTXNOo&NZZD5@LZjSUY29-kaq%Ezl&8I{_8faem0Hr zpGwaAM$I1yr3oqMHsZ5GQEt!~8XBg~^RT3GNY|+{FCSJFbby;EAF$B&tf)tijD7r~ zcoeU5B5zzs?g(@;@imEhJIXS-+#%~HBS`zN#Z3+ZAi|Pdg9e?oQQtk7QYBIt}8+Ty~{Zizh?SFmC9Cto~!&>~M@km=P15~CjEf`S=M<_V$vI~5H z7^ZfBnK3Q5JUsScnXp%wVwC*t@NnIMT{kzs?=B0CR=TxX?vc3y(+=d}_5F1Kr-KQ= zz?hzJMW#n`S692tP3qMSfxS9idYez~(JTnacFe4ep@Q{gLOojl8Zz%{GEQQ$3xnnF0*Tz-!W=(vVACc|(}0u*XFQ3FYsm9y0j z`STopM1PY4NQ#1GRYs*88g4>iLlsLsXJ)nnMGMQ=_rIsBhl%5>5 zvSCxI%m+vq!SQD)g>luY+6}Q-(3Mm`RWA=HVAXg5yEH4$|M+nYSynGO7iPaLyn>%j zgNl~j1DPi1z^rQDIXm^b@JO6?JN_H@H9fyq@H$ITIzH{6k`@sujUFk65qqU;a zJRudZ75NcrCr_S?&%#r{i1ou>7K=@;at_{`qc6vSZhr>o9zTBV+BF$?VpRvmz+ce7 zj75$UHz`R)@$DW1fB!fwOh9I2_PXMAh1Q$`K3 zU@LDGgqXB(1F=a}lHAazx{5+Vt2Rnmyg$}fR<;T`o#Krj)y_k%R5|no%wZH2;+zlM zu}A}wGbKQ4Le8yQEAS+rDBDKOK%$elxxFJHWf`1WfF z1@RKnG!kW&h~K=$@4gLJp{u+gKYxE0O+j3IE#`A%&@wVI+EI9%N%rHC!aTKX%p}5|BamGFK%-7Hxp&#fdFZlTJ$kZMxVglBmKX)!;d~|ZM!JEY0r@ngC?n{Ea zEDGs?Z3|yCGrNUuC_GIJxyZE;1Bx)gP9%@>Y7tyKI5*SFvkwrt=VCpK!&Z7=r}K>M zu**xs%oH_$vSEMC@19goF#h^JYjT6){e#%R?N`cOq({H~(W3ldG$1 z04KW8PSV<7(>=0Bc>`@7|@ew6rud zgYo%L&PI=8WJ_u@)3}Su+Tu?Xidx)dL#pql_2_GQgm?5@7mR=PiWwbrneH}pi=bBh z=Bqw_Yykb4>saKxcDu_v91;-tb(W|C8LInhmr>o-ccHPy4ne=cW(7>E>G1a`WZUPB zzuV0p(>4;IU1e9?iKd^ckHV2NE5+x*;Vht%5^_QPB-cZReQBZEt}&uI&3WE4&ukWU zPXD~!I{9=;YGkJ3rM=U=*{kdL3S}0b(Sr`_cE|Zqv%Ix7;iv0MTU+!3CU^heKd(K@ zs^rf?>cZemSDlz*roW0c0;i0R$9X zL@ibLuPnq9xU(c|YKJtcT3yq*kNT7({pN1)F4bGbhcU$~rI=s%bDp$%X;cmhMuZB+#wM%Vyw~fb4ODlQj z^YN*KkfP}4Pi4w!7sHH8`?nOMJjo~r@X&>|ekQpBk9+2LKdQHF0s`#e)s>Zn&b-Bo*IaLVrNb;VMN0wAoBE@b?mW`r-GW%*6 z!z*v^hH4g>eQ1NuRFn8iLs^u?ycZFy&C&%s8alukMZ>qak$4^DBvo8ov+*rF5(OmHUL**uDCv*1 z`~g}#fZ9^eAH^c=`0?Xf{&>XO7ips|#HiIjI}9ounqQkD83Y8X`J={;1;%-Wz(zTa zlh4)sfA&>h>1iJs2|{OF>y1SEDs~d-8xaw)z3D=0PV)Ti- z5OKv)1qIcE9Wm3o12-meDgg12q?7CW z{?zy|SEZkik4a$kAUAxC-cUYD>Nqu`hj`uf_lN%Q;bwxu;hD>Vl9D%=$4M}UH^#hx0Ppa4sNEpIZ8uT|c{52_FTTlg{4_K_X-e*itgKm7YgZU6A-b(;%6 z=c4V=XhDMCIw*#pUfNZB5oOjTly9{|IAH0%X4^IWZbj-vJG%cEDy$(S`xZV{>pU!) z^^2vW!k#@FiFSgGI7;Le=Flri!0A#uo|KdXgZf^H+&gR-z2pg*bL|kZ&2thYtPl2; zWgs(I0;rG`FABZ`i@O0HN?hsHs2u|MO0>_uJw#Rg3z|=rbQ1h|9SRIoX%Nq}LQN=D zjHCH6u5PPr3QfTX*WrEnq1jJ@va%bH(D8vS_6e>cuF*31NZ7w#Xn%i0!hW=UXK881 z92B`^3|8$BAr?07I(Jkw2rKIY)~ZVSMhGGi&tcqm1qhnQBGQaPmp2E{cdIN{D5#YJ zq~)okBURZ8zK%Ql)jXIRc24jMdvLx19}{2HPNAT|ToaWv0R1ZW(2pMx&26O?wlZL$~Xb z1-|A79N1%o=TXRdEfBu!C#FLmmjnUEOz5=NWe`Ha(`39+?z|G(C-8M)d{6Fchx?{G z`(E4;=X^xg^WEsT{a16Z+-60^l(e&0Nvw||Y*39pc+=w19Jbp~XO8(m{r=&(!-4kNJ2bxEJnmd?KOZx z4<2Ncm5DwhpD?N2<#pxC)8e1&hXlz_X|eu`{#@SK-R==G1`bh+^}qk^Z)7O?f4?pc z?E%x_p~HZTLh9|W*Saij5CV%O21v_`j(dRT06m*3Q4Q@Pz|r3QVlH-IQY zU5;>AI zH1!9|7I9v$wyRo8Uo8Wa4MJ$ zg~APpZDWfbFBbfJ{2{<43aLnXM0H(iz$AU}z=3uvKS)$hBY5P6ESl>sq6`^FigltI zG4*xA%#}gXB9AvZZstFG_H2xo7o8q2sE|+I_^kQ5?*R2gAdScA)I|8BM?oUTU$j3b z)rIs-xCQ2Mby!u;&&`Tl&Jj0Ag`kC`^$zCRV3`|IksJ;%xPGg!uy3Lm)EB-u@H{o| zGt)LNjai+ylfTd#LweRRvn=1geJqbcL0;NQ=pdGvC%WJQcw+pnYs`==nl(;Psa2eS zyGMVGnbx{|LE=A}JPmWkMi&Lwd3nJ4*5TFVMVVHvpge^-|Fkl0LtR6AivQ@>RUw_Js%>ehj6UZ-eR@05ePw8?m0R#+ge5FrL1>RAeaQnt4`nV!?Yr_2)e`h;xP{llwN@nzV-$c?GzDm*aT%TZo=s z>NbHL8y9f}3ADFRfa8#U0rR{Wv6T|vh6MBtwNr%tB%T-F9xBe6MQ(QK(_jAQsC*afWDP>Rm&Z_ZUHa@)fUO^+v$NVFh+@kRVVoCzenN|PQuv#&!146 z{O6BCYO`KB9?at4;Ep1FAhq#UlC%cmlpcczr5v5P*oWP^9e38Z0d&`k{^=iaJ+7nqRU*&UqHkN%!EUam&_{3=q*DZ0FguzClH^MMt9~bM5A#)3c}2!-9nUo zP#)k=TEB_n2H`?zuK3N(m-@&&-I#HRXj`ev_rC{09K(t7p|5H`^Ky;DheOlE@W2#B zsiWY;chfR>q=6XPMsBdCTPFumsGs?$yf!EO{z}Tk^z?32$PsbSCfjUEMiq%u()Sm3 zKY=K(O$v@%t$Fc8_f-`X6{$9Ick{<7-o||Po$`PLc{36M38xv z?FDP%pA_Eix*A^UzS}dp`7fUct1{(Pp8a}h5^-6~G>!VpyvLXQS=j5^Ar^Z~+^SUB z82EmI;cgb%z#>gyw6HDAODI?CV8ULlJFT;Kg@$mw$#NO}=Y%r(6t;3he?jU@X|8MJ zr};yFmzq2Nr7kwbHxTjyhZRGX=H`DpL~t7a|Nnr6$iL~oU&q@r`X`nsC&z!9QJJ*p z4G_`L4E%q~Yc#F;M^qCQ-MOC0Dl_7?>8N^O*0X4Z`rFIgQsu)UOk(a#;d3y_jr`e^ z_Q31N_rv_sse*ik-kbSUQlKzgzr^i3sXU^n7_S^r&T!KWT!qdPUZ^TmaPQ;gfBg6X z11#E-d7yGJiHRaQjD%iAWaM#w)RHmo?#p!i(K2?xG0$!pgt9nxGrfibVJw2V(WJeC z>smt=5`|7o8e=Q#LSV7d`t|GMlg6emtX^|B{2GeXaXs=U4{ORDrQM~gSK}_`eS7biBmBGV83(uz zPc*GQ7j`357Zhy}%>i_$pJi_;x*LRk>b;hqVBfG|73N~$9bt5O1wN=~9O&eV2Yc)^ zZL^{MR>rKysy=cQfn4PXpyHGzjwic7kBB{gpAw9)05KqikO}0qCnf`uh1vn4$5YcU zEEqXoO2CpIVkL@5080^9ldmm#%4>8hOx}f5E5AR+b+I6_gU-n8@az5W`Bj2Qv#jdC7j5-X|cS2sdbFGA9!S znqx~;n}ayAP*a>nwTY1^5_|XNZ7)VK^9oP7A#r3p2`&L@6fvUtbH)Z~!(Un!u^d^c z3$2`8U0r_V>p3_&!K7!>CWczpgM89vL(l*Z_<)a#kqr?KABtO_#H2q{#1>~P<_rMO z$-cHmfiRw=z)fjf#`5~{V+tGxukl10X4VwsY$8ZG>@A|(x8HVtbRFXn_}`&(H_ZH= z)fLGFIoG}HfQxN8XkKt7GRTk#c|0@jxT-0=WBs*T;M+sli%v3Bnogw3pnw{cj7_+j0mA5mo@N{{|B8}ocL!v;Rt7!-1&xPj54ruT7A|9S~tG%rUFG3ryS|2M^*|)#6)jN#+wduZMIuw_9h|4<(PUUbE&FzQ+c+HMBys2~YZ?u2jwygk?4vTiSkA`4>RdZY%sw z^WT2ZX9J50FZ6Mj@Te<4-LLT;V*bsTPaXWZcfO;Z=moMa@OyA>Sv=Wh;#Hghd|G)l*~-fq7N8T|-Kpr$5)dENME zhcfx|nvn9!|N3Z)x&uY|guf7b2|1efN!Am5{P;ggn7i=8=Hpz!;ye7W3ovnHmDa|4 zCNYXQ65L^e{aRzmylw&*SpiOqGXa*vn>2|GB6dpP-*1mO>0n}eg>|BpR@_RVx~yHh zw!O3SgKlw4%SKVr`4Oq!fq~VFRE6;I7thAhG3Y}d%Dp0@foqx)C8EEy+^8s?jI1n< zIWhXBh#tCBbm`i)mFnsxF?j$bqDe>*6+*rD#l@b9{+s|#z;z%mx%eAM4bUxR?8<>I z&SRY`;pK%QfAt~<&^jmWLsPJ z+v;9KE!{sf^s)XS_APr1FnGxc9h+=(ON(TY1qM0CBMPz)n=0FW?^kz5vGpnS^{9_ zqJB4GHVuz+N;eM&NAaI~6OZXe(7$NhnVUF*K292$=hR#mOt6yxUOL6y{VD0xp5C_) zpzGzA1pvJSGKi01BphlKl?#*yus^e&GBk`BxA^pA6_9kH5KKwle&rDa_9uh6HOkN* zLeUVMpm1N>+7k~pfrDbVZ2t5|Mrnc^s_~ZbfY$mR?l%drj5&a6w=vTHd(S$h3lk2FA>N9d#a^UL?Ufp@$sqwJMt-1qUmV1-5`5KF+pUTrq? zwF2_;+z9J83(7`Uc|b!0)q?B7JTn{H*4e=d0Re#(@BWM*t{uXQfI1MmQ-TXvWUCj8 zHoLziJ(=e4!Z?rjA(RMNUlCS7M3}xk`HsABNma8~kzCW>JnAa~u0U>anL}Wg{ZVe`Pm0+gB{=#+AI4EIJHhwl?RHzcU+qdF}vxZAftN zlAD{umlu*^QeszW4f|Z<)JZ^;uvvRH#jRYax-2YUGir5qwAa03$?#(L_9v3=UzWfp@5SR z5dU=#GEbZpad51^N=wt7;GW6Cfbh8{K%Ix>z1}(SiobL%YTH;;E|Pn(ln+2ND1gJ) z=daF%4eKc#5GtodLtxo}*6Aqo^4eQ(m+wD%#zrv{1jcHNMX64;AOrN;GOv^X!E6Ia z88ICIaPQyKJ_8ttRIVGaz=qN|>u^h&Vk&pvbH>%wtY@?DrRN&E33}fXT zP*qks^EY*-VNb7Q;Qr*!n?o|oPfY1#LjD$I9S~^jC>SIb+l03-~)BgBNt*of@7Jb=i3G z&c$k9*VCZ?9JR(;Fkm>k5n^P@rKukva3Mo0A@y??a; zNs+=cNOhF4Q$TklMSE2xb^Rw%cLs3cbZMocp4(!5vXqaXUr9Sp(P^r(CSe`znnkUi z(pDw*g=;yY(BkzR&rxt_(R(?^C%r?u9=62#qfE3c4YP$$(|?|_nSNA$=};%D8~S=m zgs<0=z_Z{CidIQz7B#kr5+T+=%eW_=QV7{_Zf#b~CwvPg@(bN&Ca&L;`$EIn*o zEMK6q_CG(WGg!%|MBlNWU?gXTzlA*;E6AiuHk|y7%TxD^PD>D^HZ^)K{NK{W!qaC) z@xew(Ai)8%>px0R100#J#>`brB#h;VheNXXUqrK3*SxBvhDI!}N|eRIPG>9mF?jU|gf``;XRUvcHJJfGMN+v2tU{*I@glnPkwW)d% zC-|D9AU0$2&_|(eyIeH-^QSwGmCNv%pq?R;nMD^%sf!8Ryr!?-yy=28At>va4YOaw zT3kr%uI;_O#k%q6RJmO9a7>Yc#L%excc3baxsV*XynBhtN)ee1jBq}VIgFcG zL2QP;wJ^&M|BQ;jS#t>@5#c&yqzB|VR1bj-s>yM<65u+BI3>Ncu*TxND%6b^MR~Lj z%}{1J5`C6KNXJ(0&8*Fj^5iWd{n(Z-S+Z|ptX6%~2Dz`S3J&ATu_0C+3xcc1#NIw5 zTIYD~Uy8py63{ljN7-!=juC1F5PwmJj8V1`#`Y!Ws#U8n16?m(9?;1s=w96?V(6Sa zfS+nOAbDp6+4K(ZqV_OTGxpi>GKQMJro8-+lq+^r0HJcG zl^6y8+n$UQfrt@NGE?8{yo8tl!?dPfe01C&s3Hv;K*RtGC#N?Uof=<)P%vU9@<$Ld zP*&w5S5URN3p%E=Rt$Ji&;WSRNJ+S4$owqHVxZI!<#2;^fPrMUWRQhdh1(jA^<#H& zR(C*l#2B@c@9e>S$2ywUd2j|}U#6a)CRU`}+}sae4v=b*5b6Eb@HEsQN12d}J$-!z zpx+|iEgAlnmsjQLit>{5!KpbYRXseB)H@7rV3BMkAWRL~FIZXRY&w^36%g>bK%CFd zFo~4r@QODX9q39R<+;W?P>7)AO0eTjgN*qGKCUtv$@Z7&ZLCq}y}U=e%hnMT0$BS# zq}IdweMjqUyojhMBl2WS`lW11mU=X{Z`*8iFkv!RZcN&XediYTf-|T9thY+~m8)09 zY^IbkI#5Mj-LDvEfN!I}Zxaj)fMw+2Z^6_udR*DBn$L;NDL0u=$N~@7>(A&iFNbvY zQB@y$?sjOuVjKW&DIxV%#kk@&1hLETSj4n6U`m}+JPV%+@85j%_N~~_(l%K*prYRo zD&;ixJj&<@9Sg86Qo;i)iGTDLG@D9i&u&BBzcTot&HRPM#UIcywnM~qNH2fuEibRT zGWv^{IGXimM zK!O2B7Ew0dyYb<@{`3w2oQ3+N4s)DA{~|4JuwsABZ#(Sky1DvIpgB5lSp<3)?tv&J z%3pJTFQ!c&z~XOd=51?hYh}1G4&}&A>?shBPJX*_`IdJ8JLO?V_R{ zcp1Mt>z6M9*R<_*d?$nk#4Hr|PLcm6a53Tqk~2kDLLs_4ZH&PAH8XP)YO*SVOW(%a z+-6?vTXYEVS|x2(;FyC94mMHI3FGx&BZgP=(Jwvr{Maf?lUWMp#siPr-7nTBaaRZ; zh3y6v^-_pgJdxMp?c;L;GSi(E1)sO4xgto3XXnnHDnU&Ud5n&Z)@oBr%oLH_=h>Z*JI!fZ35=uN@yu)%EVNN9aRtWM^mdX`cxJ zMgvfY{p((ECXb;e^*j*FOgq$V%yEnP=NLj4ckVDk-oZ}grzc~e_H75%5ix+xcFiBG z-BeoZJLipikYL0{G=TPS?Whi1{xxbcF*+!PTM5m8Yu*-4R9$v~!19Wv)dmtq!( z(r>M5b0Oy?dqGHJuoZd1ImLF14+qnK_G2e5kqizLH9GZsaajefZMXR zVQfb4@zD9cdyC2rS>M2X&AV~KM(-NCP=O9JZ&4>_F9|HOMUrS% zMic_(qU#z-q=Vt)GiX3D=KA@wKX^Lb!TJ0x7d(x8q!*LF5K>ohefOOvGN1kEmSQNn z{lvw^4XK#F{*uKMbi82?>iSVk9}P|u!(w@b>e$d>IUQXW{EWUdfC$Vus4CcrjPw`E z$rw(I|JvP{s23!n26ZoW?_T4^DgE>dJaTe!mwTue+vIbNn>dF<-oPa256&VwJe>5g zs4*pvCukS7pO1U%)oNEJi>>e-o_|AGgr?$iVQJJr#Ur9NmR(Bpv_x%C0bm{n36ze^ z!4B_#Pa>&-vH&Rd%g>r7+;#~BHzbO~v9-&#Sq{!vpG2}SGvF0hetLwSO8Zxh(EToB za#4#QcQEtl0vbiX@{+>B1HRGLYVL}F^8|&0b|aKOG@AsQO3^^ZhVD^A_ilFHk5q`~ z$9m7*h0ygNl_VUonc`nUXy~{~n|WWP>$&^{*o8{*xr66HXe=-}QK?Tn!12~bz-yK*BU;BxcrCQBSU8wubs+En=#(&B- zZcr*e_XbltIEgZWB^LFNkg|mm!^DQVW=0h**(p8Lb6it9lpBpLLFaj3&D;Q*5v^lF zGcnP!&929OpbTfbrI!BD5jaG&HNMOFGSj#xjB5j#B?Wqpw1kOYXt1xP9U4kpc{%lI z{hUg`>|HjiM0FG%r?Cr;B3ggL$J1r^Ma9ITv6wHx7SIoghF0T#&C4UkRxQRvf215s zY#|}zV2H%k8f0WlDu=9}4_Q`1RromG5mT<0z)`yzwf=5fVMhQLyvVg#w+&vWf$Sim zBhW=0L5b$U9J6xqW=Rzk+S3Wv9|#yaD5){=^o}DVrvwG)$Pz%L61KuA#KMfa60B_=wViH(&lLFn>Er_6D+E0zHL!$2@ zm#oEs*C56nnw;>>9yNY!go0;|Pbm6wYF5VzLC^yhpeW#~Fmj z!ZR&E>_~PuJF%(3SgJE&2R`UAX3-c@p~+f`n$*y&5PUQp4#kY}(y^awl?_`NZc-qI z5Q0+SMWt~|4aQcPAX2k^c=$s9v2u^rSv@>!e8}QVtVCHMJr4$H%XFqQBt=}VOk7g* zIOHQM^5#$6Y4v^7QnY;K%FB;N%9T(SJqFKhXjUA^lX!I3Or+dZ;if6HoL=yi2#2lV zD-h z6{$2r0brYmq=AIlFw&YC%T6?+oT$+2IRLtSKwT>GiBQp}heHvHQa*kU8bXcpf_-F` zJrS84o-ein2yWIk>}kJv*j&TQ6#$2kCbDn0FLUGN(3FKah<*z-u|1v-6P1HNWn zgx&hKy(W-EQpz;!tcvWARz3EZds4f^AJOJHU)XWcX4PhOsvkj2= zlfWFwVmz0dk;a?~E|a%?a4=D_7&j3pp0ZRB`mUSz@872lBR}jJl?xI}I2k;;-Ig4NV4yM?}y=Y5!@)4pi;|P0ikU2OS%4dQ$75_EH9= zSA2z-+W<$V73S|g4w)>q?4(eh5OgXUbc;aZ6=l*S)AOwss*u*e(?bV1$+3iZ>_I+# zzb+2(6&4y{*c@{aR=t%FgVr#lw&Q69TDdZ}bJ?Hl(eq$!CIe&7rc$<%ty*+)UeS$t z%NWiF>iON^g;`zaqmxn4?bFwf=)bmW*De8Zf4jaa9vO@#vtWdjX?TTE0E=}VFeT2v zdEPAWzxj(DNg}qT>7~hL=kfjF020Xhidvir$GF@h)1f9}1r(Dz5t4GR(9+a&8B$Ab zVEGO34C04&OgCQsG2?q&NyaofsQ+F?RzvEs_BVZu`3}dJN{Z8DfSfL*fA|vkyQhS z`SbngO#cAVjcGYyU~qYd)nD{{23wOMs>{c4mj{*|RLXmRKO%S30bfOqBc3Cl%)Csz z4mJ<-)Nds4V%q^b^+)S<)-$9JGepc@g=x-HGhGFp*LyUg)P`8l$iEOf#wpjsid|tX z$}-3}ky*5xgw7ZJB5^viSCL8yR3DP<+}lsX)bW5wAPwfu124u6H?aW=yt@P6i#P-# z$xS4(L3Qw$zWy`2Q^Re!ez<%>p^6fPTR>Ee?9%>#+7+F+@ApN=J!Duhn2Q()_}qM; z8vRNqK5X;>-aXfToHk;fLnBy#Tf9BQi<{(?9Ag4Q0^TJqx(-B->>?%!o6JsUH>aOO zrS;{fMZoUlHaHFm? z#KJ&rkGfy^X_6U^hW_EhP5 z;YoUny{rJNOWC~=co=J2TJDPw7_;=AyP7tKwst8Xn9aZo&nj5`!mrKbls( z$UK0~Q}P%({V~lMEE=|c>pv~H*&ux3{<$3%R;XL7PY_n<)HBP`Nf4j){G_CGz_Ww@il%ziPGCho!VkeVvmo)xykw{ z8GV<}-XT*nQ&XMJC@spqJK29I6!h6>#+(w8%_{3NJj<}}ZAKD)BG3?Xw({avAnrSW zG#Q#bc`#CVKsFuouJ=P@^dUPL&36HQnyuWEnYMP3e>_^0$Fn2A&|#zXTv3EouD3~8 z!+bsF5PhL#W@js-z_4vQUJp?|=8+^#i+#djMh|fkY3T!8(eWZau{u?8Nh0tP;md=k zq#yreU)($lCc>G0o?L%perSEV)t|GW%xOY?U4;z|>?kwM0y3dHenupK=!c2Q5zOIA zyEh2+knl!_(lgFCnl41jP!JMJI;2CrH&MYLH6L%z{yI z^aKDzwq@BE8s^P%a$HzP3=pCbv!djC^E?M!a+Bqb(JQVL}s`KL9F#7oP#HQ9rvYAroPV2f2otvy4ph7XW7M7e|JR4|d9XKB z>pmJANU>!RJhOy|=us@FRwIG=1~w1!4B;A})KbF8Xri!%>w7uKH?G%shju)Oqd@sT zz!u$sTH-bcDQ|k5e`>O$aM%BLJx;H+nn&;xoE8Om1c~eO6=o^m22$KytD}LLpp0BL zKR+*lN`;=D{9wKW6Ec6Sha`Iw$TY5z7~R#oMRR`dgOESsgJ*^zk^N0q>7NoX;(0=+t18+x%S*4_q`W)HaM~rJf8FUhCHOjw>(o85_9D~nsQQ&V|LDIxCLrR z+hqg??yK~4FG6opC_wU<&_PSeyZqqX}Y;+|8Bw232p^o0Z!HeEPW!KM`4js4iZKUOaINQS48gV zpQwS7PB)WR4F^UvzLcRE(dGx_0W)2RLduW|F1RQyS6phD+bP7PkQ#3kz%BclJ2JAe z`9vm)Q|}c9*yv*$KIblwh2c2)Fyt*oJh1>2S3Ja)i-XiR_u;$x40!mcOA!E=uX`5V z{Ax2(eL%+KsweFv)^y-HCw|_(d;!k4w10ST4crD31Z=K0Q>LdfKn(f=cm97o>mW~I z;6S+*FOO<}6j&MT+9@f}gvG@mMia(OH$Z|!MT{sj*uSCBC5IjSPZ`J+j(0f^E9FAfR@L&|o)(%o5Th@VO_(*D^7gTe&*(VmD0bwmN_p{ndE#V)UCg zSG005;C2lA*)O;W-Fw23go5f)27GX8N{V*Q4u?%(^Hy5l|3r`_0Q-@FX&5-E{50_y zfpj3C)p5NBz?y(TWrUX^NgiP(@To64hUB}Mamd<=r{gFGIkr*ml#+KaG<3fvmt$k0 zEd>D`je^qmof-&LtsQ^v-MhCM_f7SU0E##?yvn%FYaT?#!=LsHeJ_^4M!9f))cG}_ zzn~exs*VtyIk=YWinmjK<<6m1V|QI6kYhha29+*{ZNtsG9Z^{TbljloNxXorL zjA?m{jR&)uE&FXLZjDzqlU7y@JtZ?J<8m5nAIXjRWnC(UJprV}N(gh@&{C2_C8Vsf zk@S9&9u!?C(tz595pcszsOyxU#*`D%1=>m_yD~lx3Wd}}B*7)71tP^YL`zdN{uwY1 ziY)I7O~{Y3z$B5XJ~FfjCs&+>e~{t~J#Inc3$d+1=w zinZ`Zb@2f$>s3YQsaC?f#uhLJd+TECkYYN@PT;ib0&4SIU7?f6?7yZx*SB}Ur1=6e zzafoCoE{7>Vss+{`!oirf${O4!;mYkxsJ)Aw;w*lWI|ktFB z;4z`Y)3LHbHDSsi*HId{*3m@?;9Z&b(y+(IXETB}VYu$>d{wao3d79NDH5u}!3CR- zJZ8!1^j$%2f;)uu%su(&SA|Z%rVNvp> zb}tq7V7{8+G%enU>?BL7jGms}AK0m(_(YtU27}Xw1!LxM6!r!L&I){YitT{Z zTx_(LjUf*CvfLngvVKlQ+Q zqA~RS#}9v)GirRtKu($9HzR34)jL5?r;!1lJka7r(nyrk4ore&CzC)dE?%r=i^Uea z@|4PbW>ZzNl6w8RnwZewVe80#A&VBA%4D14f}Pir(OwkM7Jw%+X_%v2X26t*|FLNx z4K$=BddCoy@s~Dn(4}uDp=tybExKfDTZqb&t%&sKbzgV-8b2;~?z>C4Bv&`5IY>@# zv?ZV9uq#_aiOpQ60>x!!t`EBFS(9jr|4^^tm?9gu5%0UvuaFWwyS~@5( z(K_<2G#FZ931&OuXC4l<2cEZ-Uew$r&eMnwVGQ^-iuz3Q$P!l_G*3-aX18|lI5i{~ zXAG%`-@G`gIIsoCO`RM-ybqg2VfR-(5;J6czXSa(F=Oa%LpMIs6rRm1pf#f@e;KnM zmeSGD!4X7)2gy_gRB~UoyLjqw;R}EoTWN0Ix6}1}=5#XlyMQYczs{0_XV3O7n2x+F zh<(U%)P_s}}a7`C|WF}FSVw;%Df zEsNcE+i2Y(RwerHWe=yBzIB(JwR_W7S@lEnTHd3R`ycjIPEm2ieO=U7A9wXp)x#qt4G*_YZb`M2bcGhOi z`!6!Zk*g`6AG~4Gvc2JTAVn{;b3J6Mjm1=u==x` zCM*v^S_}~66L1=~S#|{hfm^UIdyK3s?dj;)54sbsP~}kW71f>p>}~ zbKYEZdUXaHb1GP#Lz_^`Ig(b74ps{K@)I^Bb{o;@A^AV)Y~^^Okb_NpT_U|O#(u|iJ_-BY zVra~KycfdXR$~BC9GcmdbMIB~o|MyEZ+EzTSmheBjFQrRmz7+Db;A;`Ps!pz*e);s z0D_aVZ>}1!ZrpenJZz=YW*clA=&~3}O#ExnrTg&NO;C?@^Tc7f~gfpWe{LYIm1)f@GGvcIdqk}+=gJC zJAW!Hq7|cXf1JX$Y}w+Dp8Qxl&xW^PHaW~t@2u^7$Iv^ za3@M7R^KsX!oR^*oYMoJ)EDG+E)EU}MH)tT(SZX8NL)XM?`y;-$2SeKzpREmUlP`> zXnFLT7L$%}I(sxGbk{?FQZ%Tg0xN&$Rv#7?xHL>rRJ{^z1Hv4k`BYN44-dncqPoG! zbEvstxvJRS3-J2|4DZE6MBum)@xl60eLrzCKjWbm4O521W4}M5)m}l{zq$zQ^-gb_ zo^tlkA=-sc-)-T)J?z`K!qk5bpI@n`zwzZpC*Uw`E` zq7R9nkv|^xSNO=Q$+7t8$RO8y7VbECe35-70jaS$V|yP@G?PMAXnnXcX5BPPPgT66$GVEKq&J z^C?ik6b+93mbV{J3fbz;z+nyGl_9E9SOMhOk>JavHUsrS?(61ob|jkic6YzRc0@)F z_agk7%oAvsKakw?2KLMpv`bJemm}pbALWVl)rbDnYoNy(T6Qm-zQsD>s9+7RL(?_v zY8-E<_ABML9$cKCv|)>&pqG=AvrD_7B|N2u4rFY=Ib)E7;(AVN$p8RFjPAZ+NQHks z*5H&3YuhGY^xkLQo-(hD$Y(c2$$7RV4Sq^Pl6QD|Cta>lH8%Lnx1pHUyxqWyQl&&= zoc3Bmp*-WmJR!7FKi;~aWaL6%7I3{F6u0NIhQXBA!H41PZGkeD%n`qz^sNm|#hF}| z1E4sTlNs_2S22=GMpC|DIRFZQsre)Pme)TwIU7;cV@3~M`?QXNjxiTn`1z) zP)pV>e%63+1@oHj;kbRH(be1q=4J` zY9?n=FVndhB|k;AUk4>lKLpP)tOAFgy{l@?-(Xmus4g;hSS+U{G1D}5OC+KKcw{cU z@4Svm_9^PiuPZl{nV-*w4Ask%Y10KN(VPx_d82;q;T_VDq{1t;^ylrZK46AaV1}gr zo&yTdkKUQ1Ng7&EY&DO{MxcmN1L-by$>Cs#1qgXEjm&RwsoV7*qpfTdFS5HNdF8XP zh-k%llyPEv?{s-@48TF77#Tr521X%U8_`ng4$$y5$v!}H#yUan&lfE7V`T+e!1k`B zCu%-5#VXJh2qGEn4vvnOdpf>01;H+Sau?=O2!>5{?cl?4UvgTDqKc_;Ov z)6;XuF%vFh)(&mkk>c$}IWp7pNzleV4c6nm z^-{&*Bf3Q{IgTL1T6u1t2iI^`r^Lu2_^iyT30}&>wen##z^FTB5Pq8Cm^g;A^W#u=#1C*Mxu$||T;mke|s0U zcO}I;Uy@9dPHx(G{p{*iO))`F*1@!0@m#VptYWDmvlowkO_Kc_%4$|S@F zK+bpl4o#JXxi8UMCK<$Ptrk-5a7?)xbo{s)oF{6q{r=X2DS-iv7m}ys%$HxfhG{^z z4_56j(faGc{*7V7#{J2SbpvIVNDp1Ha^>@^KrAKJTGwSoDBGVWRh+O)bG>ny+j8%Z z?R`fsr|&tJ{CACXCgcipNj_`+lVYB2r+LI4{#Z9RO+m|aQMaiU7y$oF@}{1=?5YiL zVLgAh_T|)$qk&t7yrSlER<(%i>+m4=jJxM9>m}}t0u`rJ`xN8n$Ang|TBYTz069*@ z>;gmq+Hms@4AzH$p;eo_YVq22NkrF=xrQ$lOh@&xt?b)oz7V%OmCi20B8Y=73YpF0 z!}Ah?uz(>^=Kydl2*}h>vyup#T42x+)SJTyY%-R_f(HzkFdu&m_=ls2PNtb{XN0#Y zc}6bva~`GACTw0fojXw5g<{@iHL{$tTBOxvse$_*jZ}3%cTMQ_j%C?ehJGt5EUZCG z@*N{Cqsh7M`VGOzSms{d-mPE1CSV7fDBgJSC?59%PiIHc*GFlplTX#ziDO0!*d3Aq zYjNoJ<2(sNN}@}L6rmm1Kr_!c{_{D0Zo^*tJ`?BPzHR^c4Az3Pa#4X$6j)A-z?PK? zw2e$+B+-&96kW+QI}(IP;w#q7fBpC|z?V%(3AE{xy6@ZZZ`wLKKi@5YXMvVZt(;x0 zfDEkPb3S|#vHz#r%B<@8u_8ihB78c|J)uHqTap{l!=v>3;RYA!4;@WjC z;`w0BO`uSTMt3vu+F_l~dP0;#wt6Knsmt~Sw`}`;w^r!{#ckO#$_cP5C%}esve^8E z#%d)M2b#y79oR9oi0?6);4Gqh_MEKE!s&Dl)Vh)b-1`2gEL4A9+6tymY4QuQ_H>)C zqS;V#xQ_nf-Z?T4`Z#31iEs5}0r%Z%OqkkwkQI}0md%1%JAq`%$gKx=oyx;dm~FFO z+IY*)sFSST%pj02-7Z)cro|#Ms(o<((>kG)T&rNCWOGPz)(xzOLS#y_`vyAtWR1R>SxuwuL`GnaGqxj#)j7Py7z>>Uqx?_?S9CXkt~wY&!$b zzix%{s+<;Ls4PR#Jus=Nrlt-4x50+{*4BgdkR}sDA?zPt_VB1;CVdT{e@o~@cV$m1 zV#;yn#-P=bZ9|h7HodE~_+7k4ByFN~vksv3zaXV}yI*bmL`xFf*iRq}GcY6*Z-E{P zKG>8DcDx4lqi7YNL$xctmDJx~;kP;rCw@AoDH`3gBQ=Ayv2@rCDro*#vpVPz#H#2h zo@B5D<#7mXKaOx44Mlmz120D-=Jy@T$1dXJrwyjIDF3*S4+Q+K=H@6TJ)BVW&i^ZpG-osvmgjIjEW#)DHto#!@@Kb63ltCFjb*bo`KLO6` z$D2%PshBM9RKBS<-DbLuiw3EtRb^xEY^w$?(1 zkpRQe^KP;}f#9Y+KZR^)bzGV^oUu@9KR2=mYZ*o6>-hb|(kcJ(&C*&m^Kwr{Gs$Y| z?&>m~oVi5j<^Z+I|6%OA19INq{%>1_MCwMeS{mwh=oAf-D51TV1}UM^)}Ye5g|@T{ z4ce22Ra7*PG*qN1i9z<5e#>zT zIcl!gl@5LQVF)KyJfv{}qpsMv@B!hW!R?5i@B@s)q=&v_zfIT5Wh++Por!U9*;l~4 z>@aBfdw@LyM$zG4MUVGThcob9I;wvhUbRltMdYRABJyXm=~7B+=J%av7Cn86ciJoF z0t6=3Y+JWpTnkZ(9G@JP(lh~qSY?crlLz_8@?UKQ1%PN8TItw~p#%?9F5Mj4&8LjQa=O;rmaQ@DX(I&}U9O95BGWd=FwWd|S zd7}mq7)Z8ExcwPIyFn9ZWN2DmtgQd42JZkH&hUc*EgHxN?85@#_unturyaQ09yHqD z^w)T^Wd=hx@oIWfq0Kmr62wZDTw1Q(i5P6M&saF){dY#Qt=XZirTp)B@I*BvNXBmu z?2*x);o;#tE&Fg}{a$T@qNXtuwSsbf2_|`aHK??|tnUI!yz%8)SD|Dsd1R1SYm{%B z8XC(gLjPmdZ4FuJkv?1aO0q|kbim|z_vHW=Ury@^F&XKq^bgw!(SQcoP8FWu#21e^ zf#+81SXoW~jGv8tbXAzEFeyeY7P8t5*c@qfhh#F2shg-wjb(w1V6WLeFLfDGgy++^ zPnbQ)@%r3}gl*P8zQh&4CY1eHKNLwKJED%_e^_f@=#bF%yb_W))t0ivW0m7|29GVY zjqdI-?i=f=_j?)@I6oTCuU_0D$t<3$6{}PALPz13weF+Fjkp`V5t^fb&MmE6x-+u? z*H0u?n_!;z!=XPA8SrlQc#6r@yy?|0RvCc`0%PC#thoNE>ZE17wXF6`9jB0<#MSNR zd1r7Mp2G2;2>s|gG>ik$f%52o_JTBO&Nd4uQQf|ydzyVpAX)z8yiHQ)+6CZ-z$XDa zqhE?K>Pehq&R0n zUVk^#kyt}2a7}qb8w2Iwm!$Gw>RF!v-hpTK#w92`WMA?l{U>2qiEsj#e(o2FbdF0MydoXSWi*^=i6#NZ2VXxmfo?ECs011#cwBY*944kJ+5uo z0~RWz8wTF>b$L1WP`hp4{AB6F#=c!xjEf^2yK~#VP4Yq85{KjE9au40f@|aWeBCjP zSuI(aOPjnxzrxfz!P}ONwlB zKNFpHq~xgnUA1j`gEK~Mu53`ySCuWu5H zMZ6UORMcZJZ=L`B^9x2aaLW%dL+hFCQchTkx$-VQjtLYIy)k)NY);p@Z3p4qrHkzm zxd%{^=~nHf(b#F_`?<_L7N<@1pg0RlfUmDoQmoVvg#TwCqtNS{n3y<=J4eKS7!;O` zm1PiD7JhBSo6d4}!>%?1SaR+;N{U4SQX{BK`V`T{BSBG_`zAP9+le8(^5h`Tb#C*s z4jSmo(`~@(WJ6zH)3$4ghvGUD>fq8$f`Mn0jBjcz*3Capn;b$2)_pK;Prr_U3eUap zd4F&_t}Z&l4lmFun1qWD;%F6}{0vp#F(5K*Cb*xj$^~+qgVU6lDY1K|K&&0ENI1Q8 zP)Tp!J_OJt=XXF5m;5ihu*jJ~Jhxw1VWO)So{=Gpy>~hqF%sC3eQ@EtnuK0f0mWQh zh?yHY_gj6MrNj_`;T+p{fwh#tL8Z?H9Eu2ivQN&oW2M5clAB*ov|b$x-6SHfbP6TzmGYgfi(+0H}5$^3iGt zLBfxRGmRP67WR-gycnUnjFedxBr*k z-lHg&S%-H$Ti3dXV)4#mUO`cj3x2Tl*>;@TiWQ)TJKKDuoPWKp;O+{)b4MQCKqvok zn34GQ?Q3Y;b$1NPp+Qk`+a7u)7225R;`+{7T zL-F80%LCQ23F!w0?OnfkvxASbT|PetSBnZpwIU)1R>ckV9Z*!Z?Q*-0H58>_w&_No zRmlK2Lt>K20@2A>6tMwGd}>X zq%0$IZFTl~TjY6Kz?AQB7j&u@B$nnshhP9ofRW|WD@bbMppUGs(XPg+XAZGbE|&bH zPo8}nc?9Rtvp5D1$xlD*Bq)JrfIB|V@PN1XFJIyU!-}|;{5(~^hCFyqv@;si`tqKB zB#yO9;<%(O)_P9ZMb@4|3zo0y_biH7rDr#-=ZS%CwzW;a^))PaUe#Zq@m`yVSNNPp zP|OGG?y|36zthsN6b=oS2Nz5~WuAWC&8P7&;t(C)%P&+Ro!m_PMr8Kvvb=jUARx!# z2jwKDe#)n{)e~t7bG04CA>THCI|Z)c0OhGQaDpaF>7<6)SdCGBK_z#J(Zzod54`~1 zf)25|vfLHC({Vh%gzNUq99v2Wq@a%PsVovJuUs6F_|j;_RQR~jTBZ+PbIZILrUWRg za^%Mu93nh|La6-*=ihOzGQJvFR~9Go%xV39``3?g?&p|KjvqSl%`nbva+;T%*Q5q| zDEa7QCY0;{4Yh0^~s2uJiUO9T=HSy zW2hCeR;0dMyf5DU(CKTVJQO}U8i#FU3v=b?&-&(fa8OdOq{FFNHv&ii6N7iyEmIZ{Uxd zz$-OK!`XS|&Bq_&%pNaHDBD`Fya9swdz?fvtYRI?prYIpG|9Lv$)X5-}t9BNQ>;p^9=+9@x3hY7n3?2$jeGL%y zJ?8eL0>BZl>9f{OcrTr?AN0JoLuKe>cM?GN1E(snN57ba{~5dY<~jj&?L z6Ciw}=fv;SF_TWj6ViXt|VA23G~HLxySfy5Gi z1E0s%M<@?Cnf`Klz|;})pW*kdA?47Q4V;{Ti^Oq=Z}`Ie<cX^;eZ2y3cPG>&!R^EOmOu+m803mn zd?UGjwA{JOk0Bwf3a3sLh#4LlzV$M**IJTi1=sKp4=Ot!{HT*wYIVScMIu;G_4l?TSZBN2A@g zG}t%s0=;8MWTb_)6q*Nql_XyaC#;zA0{0|Xqp9@7;t+I}a6G^KdL@YKj%&mfhJLCJ=P|Xi^#PY6Fg)P_)kl6qpic0iqGqys77=3Ad==ojD?g{V6im;X z-TGGxaPjXuuQ0F|nP8`hTIgdX8CY}4AgTF;xS+waZz?B3VN38~jh+L@DSI6h6ht=$ zmYoHT;!;B|C?+i=nkv)L$J!KB0xn=pDI>fk(m4lxG>xCXJa7Xm4Y5F)|J|ur_AOi9 z5?nv@1sn#LnEjRMAWKE?h6Pj~4|+*NkB%E{$YkYmR~n1__{CAWav-L<)NmG@+9#;e z)havDTt0;IM$d^v4@0(lB2*$I6I#f08$^)i-~p*Zv5}EgXTVuC{Ebet2^TZnSOV?g z>WzE61a1P#$-!(%EeANV99`dr#^JHIf47?=f=$#P8@Zg=$V#nOXJcI}Fv5qNTT0=* zMqp&TwQucC&&?3WipzsX{s@K<1sWCq7%?ouq*2^^6Y|YqteMm0yNT*geF?vdDNZs_ zvUq&zOSlxH>qc+zHX;}PeV4T7rQ)KVNp!yK&=VWMPeUaPFMPgL+fUimX<(FVRaM9%5 z#hCqtNd~7T?&b||O>qBak2uD>wv4fT07hoh%Y|lOm2HMm?gJn|+GCSAhP%rl%1OMW zzm^5S$(sP8QToz7T40Hg5-*db%a-j@xe4S`P((yYL(=HEsRbGxQ~ZVhui9R}HG8^F z*17<9^$v%~L$g>gVM&tgOO%mR^EHrzX8%zAe)TRvi9V<6fVtYG7YL?#^UGU*dCX!N ze7BH0B9^qroWPM5Q_;$22WBkLEj=~SeIf&lab|(D2bWPc(29+!Jj`8_)!je#oX)Us zuyD`Tbk)(_s_@}~iq$)C?m(micVtm~ec_Ng3^j?0M7qYr;ry@t-NLJKGcRiXD7+s^ z>N6ExuxZff!DAf#PdS822W0#}CFtoqWG+I+SEI;vvkeAdI8JD3k&*FT+c}RVB=HYJK+3w7`uqdR zH3n`So}HUKY@d-{qwvL2jxB>C${Mikkh!((+`;W1krv@kr>hB-?!4fzBdTO3Zuc)D zJR!dcvX6m7v;0gB5q!skxOAX5#5DJ|E#=^LHS_`a|CH2e@uRJSvUq}r^np+=2xLs3 zZ{cZHjp)-1@RS69;{+D@0Wd{nC8b*>s#j&W`1pK5ddcFiHSHt=AAcUU86R1)m7|do z#YEm8{B#_b(3-U*7)%$&;>Ng-OHh@?eSgLCjL$0pBJ9(Pd498fZ)M(CE{{ z0H~x)88O^8x#%E49_VOF=ccL62fuib0|diRG75=I_2r>9{d?#8)9^opY>hVq5u5Sb z+Ze{`0v^1=;H=g;Kg4`ldybKLmjB`JW5FXowig3m=Ve{`%E^)TQ?Zv9YGjDxD00W)SUU$EB+{tiEkzLLJK7X0>3QSElc?{3wEUc%d{B^u3{K1niql zC@MW+t<`NvX(nutCMP~GGh};$T}Q5V4vI3I@HkDwA|jH(t~>TdI}}!-(WoLKvc&H7 z>(*(_&&?JEu7Hog2#1y2zg4Gjgv5^?fN@TlXmfL*l(reG1$>Ki;d! z3GnC)SgWeNi#^ugroL!jNzvLlvEgR_{QTs#qInbo?ceN!&w2Lmk4!fxQIPHF^Yl#y z=%iNW=GrhqGE9lG^yxStU9-4IS*UdYEVt4YfO5RNaE~N-7dX9ssEh7^{cA7zq?Xl~fGx_rTf(j7`2fF0718O|hcGsu7=6 za9UcL`WO#t9eS5<_?$xkyVFk1G}7jD!37fvaB^zO;_L22yyEv5DFu7BtXpS1&OQjX zLxLkV zsokd^VO`vQEO;%q>5}@ZDg;R}`)zwxv23^^!3SI`@51M1Q#xVBb{m$Sr`^O2oZ}#j zY=uZzK@5#JW#>OTnGRlf3r!>xtp4R>TgmP#1w53s3oH*hXY_Gf7eq4u{JEw5;ws8= zs>x-@z0;lEer8Mc!evp98w<^IU!UbK%0BMyxn0+|K}|hC(T6?-O-E6WWqrajKy)c# zK5WPfy#Yxjz8@i)Gai~OkT=BvCJh)Z`TaEjI&IoQvyJ#Y2x?Y#ujt^z0d*AD0$VTE zKC^*qP6=BvG;T5Y32~$+0R?39%VFK7e&MBOUq{fqpP7$BO+0XUwC6+s4Or1(T;|{c zC5Q8YGoHY@nd($(Pcs)1R)=cOF($nKjzA3!9>Q@Z66R)sJ_K8o4f+sn2IKBPPusPgKBYWOhZW_`?6xY5Z91W3V`vkC@(OK880`UkIQ&k; z?)4A|o1PPbRl`BICkGKTU{Q-HI-1n3xDEJCrf5EUQUk&boc;8R9hE~RFeGZ@jxQQ< zL`gXz^@}jKdIS9O>!xA6Q{T11<0C<8AawxLh(cq6_ELlUCg$Bs-P`2XL2;i_iTLw3 z9c?{mv(D$v04Qk!RbDtkk|$f9IAkc3?4fK3%P*Cif69!vV3yT<4zj4|<_&!7-y1u@ z^?tq32qg9{orKk=Q$d}d2j3`H&CA1+O}wk+#M1=iM>UtzmO$JjA4hc#S})cek>jRm%imK`VPt(R-2x@b-`ZMya>BW4YDXLC*A}xA*VK0+=&cVBdA} z@by(RU$Vx#XJ9~xwG;c@m2x>KIt~bVX5-)x%#Fr;aCBG#ulChgSahpAPH!YHdQzd^ z*}#7kgI*I(rd7t6tPT0(09<`S1s@4JrKo5MbQLVux^>S%v}8C&>saDbffiRq#%v>2 z!yKZcZrd^!uATk6$d?}IF-KqoeHe;V7(1RYzaZ;19w0!*;D)absXB~Pm(uVd0z;8$7}tC8GohFD1qQK zG{O>`z!Q4(Y5eMims!1@BljzsT9T?7Z-y#cF~+OD13JFyG2TP9Et#i1pY`I2Sbxr* zDFz6}@RnKW6P|+~Y?nK7-=O#3P-_BLOh|O}TS;jXI_mi8pBHhZu<7)IP`WWEp>eq# z&9$AUbbF=i@teMA-`|0i@CwUXCO$n5+Gx`i=*4(xR~=5k6!ab^-P{8^RvEE=t#M=yQb98VSGeD$lbLn#gM~?^0bZM2H7246~kY?E_zxdHtqJgsX8Nf zX3TGDnaA^$gcf7keSgc=lNT061>_7hMwiT39G?9L*SfWg{e2)aZvhCXrinf@uX%)x zQlkE^&*&WZK#JI6JfBa>r=`SS;0X)7nO#pg$Qo!_rIILRt+$w>`vQIM7NP`{8Fg`X zeg{ZoAm%76ie!;|JqISzBe>9Is#k5qHgu2#=@il;(g^yGUWf4sR1fb1giHBy-vHyqM-SAp z3;r0%GBlzX3^&cRV4Cv&s7)RlrjKW3euFK5*N@}6ub$QecC<bl6!Xs{Ar;#>3-j}^bSWD(SbYTR z3p&~i3anbr?5O|_US!hWQc!C?i9>Jvi_cb@h9l^K54cX{D$}9m$Z0fixgj8jS2hjl z{)UX>_xf>^r%CzwKGMp1Zc0a!Wm_N*Y_O7wC=zf6h}a|0ckUI8&n^&N7F8)@s5hf;h5#zg1yzzNi_x&yQ2tAXsoZR*DNxUOR7l5_X16edkZ3zsf zPRE-Aa`b9>H`Xle+J?=j4j@LLKwJ8!3Ikcs`%}2_-l2QY-ta>2uBn+>J^CiW-NN$g zP?j6I9Ey9%VgNNPB+euWTGt!rXiT>nKTSZS1eCtJ`ce~R7`777&flSD!Sd&fy#-gR*Rx>Uy)!$S zfGXY9ZDcXoIv+@-J@1co*CNrHMA5sJWy2?FGGY^+vg@Gi<^E4JlHYb?T2Z^ISVDkjj8XxXEEY z>l|-p^o++N4*eG#Zum!dIgxm*lLp%S0A^zx01e5?BoXX2Uj+)6Hm(y*PS7ky$TFe%XJLfXfQcr3 zsvk*0#}P2=KTPgL=}#Aac08-vDoU(`xFX$CPF#(OdP-n-Rc?Ji| zU;d=4AfwZUM0AR&l42SRm`-}y49Kd~MB;(a#&axc&cn2Z(bP z+xH=5y{3K$pYpXwa9D>*jQ2OafJCgq?#gNghSP+G1b0m~g15dRsbP`yVMypM2@OGI zgGSi0bKPQ(L;|U7L1W?37Z-b==<(xhyy<)~D~6U?4-&0$KKg;;Ze%h%!vh0Y!~KqH za;`EU3jo|8Z%OY-G|_vhKY!yYC~8j%I)IW?7q=TZS8q^>yo?FnFf97TRaa?{H1PS5 zI32Miw@n%n7?n5ycApO4tzQ+8g-Zo0P4Rd_1{#AJ@eez~P<)Z8DjE-i#l69+jQ670 z@yTKP2K<<5Xt_?DFvIU=UC7oL$9>T9_%YH8%vl6seXues6A&L`H^C5sFREn~fN;LV z9JZDP`X-_eSWW}XvP+E}C)RmTlJ@*G)b53DY`0$Fw!QAKi0PMJX&Q7Qm@nG>Q7NQy z*h-H{HR9kVb~vY4#O3Z171iJ)3(r@zMM7437-t)c|LtjB*&?9W6=U|kz1?#~{y|V8 z3dc`^+*JUaslL|-hawTY)a@bizz-ij6xX7$?{R+da+D~)dkQwx+t;8S1hleoMt5%R z4CDl-_~0}j%7Mrq)qW||DH6zgEWTC zS4z=mJu8iVg=f6*z*bU7OLufXD-T)%@a!q`J4Cz;CLS89?fdsPchvd`((=mI4+y}G zb{Vk}@n#fCj1SQu9qCG1asKf4#twd#Qx~KU&F@(~#$X{My=Y(McSFaL1C&pjftL|G zn)%Il><1KH2DhB5D^omN;sFBk;0c>4_T|I>_G9M5Top~H#;tw)9_NDN)Dk9CCm|L8 zZLaE{mz%iNxb3-qK=H#p@44<{V+_rnZi@*e`A^ptz_y$7+1f!7>nq8pl-5uAjf=h8 zwj}2CVv0A*zfXgC;a}PDui@lh+5X4BDu=V}=E?h?zrE6ZIN3Wup4+BQM%*`d^mtU> z7^KCk;-wB%hy36TeAk|u=J{Kk4XhR9;{QB>jf|nW7x>WS5fRV3c1h` z^NqS#660MrgG^hH>Rg`g)$Q$q=fJ^~fF*E>m6VY97JN#I#h(QlRCGk_Iu&e0;e&g2 zoz58yfc$1lWMxr=@1yBs5F$Z{p0$YmBHp@qDwz}_+cm)M@80W<4hPADs`VTIAc<}z zvThGqB!*NU1-KNpJ-!Gi`~l=iA3EBR3BZ+GgNFc@9#Xf50+@mFNgb`tf3v#ckf<`3LAISemnms7qQ#tv-u=+%-A;1lTO9(d=|ywFaO*B5Ju{; z81v5nxzA7Dq>bVK1rDML^;iTsfLh&!s8o-JN4nu@?qp?v;Le>d_$qLu+`-NW%_ney zwye3=6%5h!pXiL`D^}#7nM?~hN~#1@!HsUe5n5%2{#KQnnHxao9ha@n!~jPlHDd#o zvUq+jb#1BOUP?K-lXhL2500jVFGtQfY-#)RwQVb=lz+au{aZxrcd2v$^X%UwLj#|0uvuDn{1Jmy7EBNshPJhLoO8{{Q*DSc( z5OrK9)9C7(Af0i<4!s90$wV;JWK6IhkfhKsLgEhz;rZ|;PDE97pz4*|!RxkRX{)D{ zQM%Ndyflp&2)oHx95B`dD&z<9u_}qiC;`VDTcLyrz0I+6HTo3*C*(H6;k%d!%%!Hj z?POfJQe>m2gNr`4D}BG*Jp1SyCaGU|CcUnrnlbE#S8lgm89m{W^x6tiRgBJ7S?+Hm zXr538T)fFzM3Rzn0jUPerpb6Sp4nPeiY-6>zP_1`SMdEbWS5}nCzv=wWCTB+Mfgzi z0<#a0*$4Bp=E56?Tuq>AwWjpmS|`S41L@gcs{Hzob1SJIiNcUDbiRyIrPzFdrSsK_ z6^L}^AgX1yzQ067ZXu&F^)k!ILxYk?tZaLeE?ppn-9v|gX6)T)0z2L>FoglLmXHHH zXKr3j*@4wkPZ^giU)A9(!ddUme7qqQPY9cRwx!z;*|savTI6VMP^zW-JX*&>Kps$z zca`brkg@=XBkNnQXb-fMa}N|;fwlNN(ccV-%pN&Rc||5@7jTonL9aoQsk*U<9<*Ag zS_)YAGl;@VkVti(o8)C$ zxw6Aw86(FyE_w`#nWvX5AlP((t$`Ov)qxn$Z z#pJP*KnIEv7uV42b|fCbG$hlFWnyOd$lmJC!NU3m8XG=%_nti4dN`t!8%NXH-nQ&e6>#!4PtZAMl2#bUTT4Mp8 z{nFii&wLG?Hn_gOw*{+k=lpw5KLQ5?D;ky=7At=WMPkV|ioEP0H7Zc{@VpYKi?A_h z6yUk(dlzU5tuf%`;(Fc8oVM@axf>A0`nY6rIgE^r)}Lwevv8RjDh5X39|) z7lKLI{G5vcA)2k3*`&)JNzPw?gm@zrM_r7tdy@lzATktK!m7l2aedoXbsJttN(s4< z)?x?Yynh%m=VdpKO%}wsB7Q@oK!Bok|MRrUqP@Fu+IDChCF{)j%}k@@mHiic*$RMM3Ix0BWWNoldlxRm~b+i43N2e+x>i0mOAw%o>5X-HQo3;*< zCm&YTm~X6~>fHW#wkkzh7sedC>^WD;%^6ocKl@OUr66VX?1R+Pb>db=OqfNUPgC~g zYjXQu7**idJbIBGb9D$Z16g;@+ux3k7Ak(!E&N2IS$*$)gN(mZr7c_38Ejg{oD_2L z8m<%m&nEW74w>%(E-pc;Zc5?EL%2O9AjWgHomm{5XG@**qJP9%;_ShJmq$DT&J8F( zb{AK1SHG6i=)+b$)IYubtgy8C<|*DkSk-GUc%~eN)gpE&$ATTzuQAxFBUqL*){XfcP&{}-r=Pi|bSr4m151Q1I8Z1xOaEbKkwmb1P-M}*b6L^= z+FmzR53R~A{5&i(k7BgIUS9H%|03yUtM>o?rZ}r_v6POL7~QuaRiM7DT=n$zvk~U8 z|NS|`#?nl1<-JX94G`7gXCS*2qrxmY4NO?0gP%T!WPUbGf zBlt9BTQzV?EgTXX;i>}gm{IaxbQc1SlR0qm8DUO!szzg%S%c1yNe*DCVw*j{S zGs)fL6k;{`(?J}qe@p^w(zLP?lsL)U>1&NhhWPH;nVC_ zv#7vaCJ^!pw>U!PBNLpE)pHA+xC-A*1oZ8Sgxm_IfFpb>0La)+4CT~G-;7&0^v1*=C$(+^j6mJ%K5+SHeYuG69d2E~O+blhl7NijzN z#pa;GFobquA^91?BRTw#Lv)okwDI0m>$YsM8p=Jf|5AsCk~kRMN;1`iVcD)R(vu)B zK?Fkf4(6KMt@m<+~c#c#r^lWh4|A`-f)nU~5WqElPPQicU2Pl`8L$a6|B^D1AT|+=1y#e{pwGHMl6R04j60daFbi89p;R&AN%=JL`>YR z4G>qMNrWv>gY?HgCnhx0Ho<^jf=^q|Nij-Hxj_QNPT`1{(@2tqID9adx|JZNDnBq( z{6akp2VdlkdN^>?N%Fy-&52;V^=PDkR&;#+7*po^ApvJkP}**gIcJB|gm7+k^9N{P z5(Q5kkj5cg`a7YCib+~rlMZ6~&J7wO+|#KTzTnvhfue_J{^_*n@*(kB%mKgowXPGg zPT*$3k$}h>B!f5I2FRXbo{dPw0--vhm2K+RLlL{7{`s0LgdLr7Has}^Fy6U*u~;s7(g|%gRr^g02)_V71dIZ5ryC$o zGPoVRe%05_e6Td2Cf^1HU+;i}k%Ts+Q!VoQFu@X=7?jrN`^~|3!*uQiN~|6Xfly5W zf(TOepXBq4Bl9T)Gx-^7sk|0DK+(C5!^Q!l80hI}`pie3K<}a=E9+HGC7SjdTMm5e zasUN$4~6xWF&(1y2ymdrBV^q}9X?0F3X;RVV7Ll&aFM+HZEexxO|etZaJ>g|c79^O z4#P<gsdO~y;1q~O6-*p2E27A^CTQw8uacW6*-oCZq|~^%73Fl z`wo^UlbQ&eJr{soa63A)+Zq`LRx~+;<(nf#kgZpsAA7WfYE+f(A~)$SaVlh8geHu1 zqbJ-PU{xXU0p${?%!dHT!n=q1eGWGmboW^J4RZ**ZcroC1M3s2AgsALk=FGtp=|gx zG`x%Qlxl)Lxb@WE88}Qz-ZvB@)aftzpu!*T-@gwg+CDzA zzJhi%M$Oj~C$*ZyZ$YnC2kY{nJ!0WiW==>J$u{RL==(_;|De4cS_2S+BK}Y!Y(n&E z#fBF!*OCP#ax@~rgY>YlAdesfB)~V=R_*>v!b63n4AkA>;n_c^&uT+74!he zV$)65A1&in++|i3^5sG>;!W?+k!AIE%Zm>$B$1$B4L3khSR5PjY-CaY9{ULkM_ z26m)tsUs zO+$i71bZiLyu8OJz_}RN(SbTLy~2Wmz(aI&-Hfjs5fre&su4K3w$(ZomUwecxXBt{ z=0iBbA9WNr%PM1Ey@=kE1d{dLes=3)qi5HOyG@LZP4oJ|F|uZ;3a!MjpI-Zq*Z!O1 zg4h1gD)E7-KQb^dZ`uP>Gag3~4EE4U2x!h{xy6*7e+*~ENeap~KmMBEqvIF96oE&{ zwewK=UgEsp6TbdM^N4`5yT!{onJ4QiE!PXxRps9gm3Vj~KGeQ}5q*bCUK(-x@>2MS z3$H`uq2$IzkUvd@OP-3zQ<|HJnq4gOeI!vT`pJxi?f8@(lu)c1IG-s#$`PmJavf=m z*MZj{Xo-6&oUJN0Hs|8s3gKJFzPEO3-c9_FAvy7aV&p=;zm6hgK)*KrdVp8qmoN|Ne_XaO!IEklwH#7nkn`_&U%W6%<~v_W*v#9#;@feLeO}bp_OUidEk~;*nS&1 z8*!J2Ig3JBAr#gBbtBJpj_<|_Yg$hy2%Z%#YmO>$17k<=-hc~)viD#Bd!o@XCf+BG z*ZsDiZNC8FRW|w<3)_&Xa_HC>1YLi=D^Buvi__sio!tg#MYR86_K0GPfJgnu0(cjD z!xyd5n6fjEq3UadINxm_wkjD@SI!y(_CRMJzmk#HWd=uo80y5m_cOHb+G>h^LY85Suf61{u@9y-I%`l@4y4s z@$2AuzNt({>(7{HN#wMvfIHv4kb#3Zq~0P7ksk+>PmqNf3Y@q^*I6`@JjS4-NE|9` zdHMG3Thmpy?a9b@BdpA}ca6g;s3yTq-Y}jaNjd{lO=n|w8HDS61#S45=ZHTmZR6o2 zeQZiRlRE=xmsc}Mf|es~ig)uE4(h%B!;qFUT3G_TC?I!m#7pWR^O6N`6GpNu$F%z> zPT;mSo2eH9x$-1xl?BT$0H72!_&jCI3=Cf^g0YI^*1x5Rb<-w`3Huv#dJ+-Yf4zbS zB7QC?PS%ld62xjQtJx{P?vY_x3`mPKg*9k_?qQ^CD$z%^IXl&#Qw!7ercDZfQ1?xK zhHZwVsw@jT62!F$5sNprO1E`QAe1VJ*nt<6!RTwC3kQ~Q9ZQTC?7+*6^@iq$i0DD!Y~Tk?D5t{kfHPY9&dddr6qLD<#o@d=ejvsR7+vkxE8fw01I_?tox4Ld z1uJkuJ^+XjF>?V*tY5eqbm+=h5(jQIxN-<(?L<593c^T{%^*;unT91Cez~PlJ)~Z*2f$#qVwl@Tf;%C{XP$Os$NlcKUG#1pB21xXx`(2 z325oH0VqQ(n7Or-%O(j&k%88t_xOCU-?mbHsvVU zL(7J6$Jr$N9mX)`;n;*~yH(6a(rLy-X%F9Ox)8ZvaY6=;@?Fksq zfh3JeaM?-bYnqyxunNRZ#t9AUk-UN{+QgELqvd$AAhgPRd|B47e}QcrMd1@8BgP~) zl!iyz6>=CCmbRW=lu(-gaYPz|aG&t1%0`lx=ilC76tYod8Op`LVsAOVdLhm1;C(C! zW89MD>kC~Lf@6Xm4J{{TenE}?2`Mr}WK+1Cti5&Qv}raa#%#PoOEx*jE zgKP4n;zMCe2a1PmnxDUZu?Es0e$>_25RRO2?Uue#PiZtNI}uAtj1*34 zbEM4FzE>#94LW+-duqv9uI8bJPbV2ihh+tv%tP~Lk7qRMmYh6lvD4*zMxdHIC4WJy zi*O8sirZ_{Y^s=l*d)y@qZnC=rKd2BG5skGNRqMsag3L#P^^&?$3OPLU+;{39EGG9 z3L`H-RWeRrT9>#l@Ix7ea(?xzeP-Pmr_M@W1Z%M%VHTej<`(m-|Ig26b4*U|q;yD- z(HEhDD%S#R2dw{>-wPQse&?qDzu!qzDhtyz8J0J`kbg5@udunY@~}YB5)W7N(_7=b zIec?%_1-JEYB7zaNF3#7@;Gcl*`^EKHZkj>k0d4_Ag0;qmEckR{W}xs)y)UY)G=P( z0Bx(j6(6MrH(A}T0fH@^0~cBoJU=N4oI1mZHl}Gd&cAANJ$h8R#FgUCBYAc2v2EK! zloop#T>I5_Ai+1mi~j`6?XS#74zg^xs=4dk?KO;i+e((NT(s1L@}2twtBS``n0IX2 zr6puVpH#L!IS?HEdDgAw&I@h(!QkGoJJBU~TCF=Q$kM+oJO|qctCYTd%rLAaNV{DW zf%vvyQ)j3IW?IQJXV1P0B})d>DzDNi{&fwH;kpgwK)t#Hf<}`Q;N5wcDpI@Ry$F){ zL=rQxg@_zDmqKa7&7$YcMdWa66;-t~HD!^cuD3ii9B#)W2x_m7XHgD)>pgZ8V5@JM zn(he5fq&3aQ3={;!D!UPRq^mw<4cOSDg24qWkovChjQe0p$kYrh~44|JQzU>QbG1? zH(M4bgw)tLOjnhIjiCOCmdC=W7<2G1)Ve?4jHC=OMsUR-ublw#g*DxHsVdwnb|ir9 zc?Z2T;~R*BEx;7r;1E~IlL&b_-9*H;szeU!f7>t?13Zix!KNl+`}e;?%g)sLsufWc zrx3)Td3E|&kSz2*qIN$%RCY|0^Ax4Ax`O)m1r8tv@4x9SI=_MEKLzILrvDmVos6FU zOI2)RR*axTY{PMeRU5~Gk{16BfDSxFZqfUGUb*Np$@2^kXV;7+F*Zi4ZoAzG3>2kyVlev}$O5yx z<{Zj?F0l~N44}$^gyvlUWYLFk6n^oqhr*(1>8Bi$f1 zXaz-UWscxJCZlD@O4G)mU!=j~UWBUF*m`a=u{p;(Lnq|@xybftJqLl4KxBK3{DzL4 zL?B+ELj{rvvkoEK9qY-72RH5>qu>^^jXk>?Eb^Z!x}`^$H#V-@l-MnRwA9mUp-j~`I30&?a0z|dQ(e_ zZMcKI{TWb!{`tHxP8k$yC36BnJPQ=fzjqNOY|(liikvf0123sde!kF@M;@^9l3en`c%Schf-Fg1Y~pA-OBbPH%nU$;^TJi#wVsC_&9 zaKNQCc)conSJZLu-#9T6;jWJE#@nRJmDLe}!BHc!0l4C!DM8Aw6hIv0NQq+o{BM}nO{WQm|jZ;5}11)&k4hV|>xZgLgw(0>W zgo{X`w~(IHP!`YrbBARSu6LMM?$|NkOLVkge9bZRjg1+&;Z!AH zzU-)&YMO$%$2DK-WJtPnv#QHjL08}P;(>F0jVCBZcR)%Rap}&VVAyT^a4S&lM>%8G z*D%AH^^Iw6n(JRhc?fqeo36X_g6|F%u5ts8K#6F(t zRO^8IX9NFGf4?Gdr20we`q5);qtTw8OG1SW4fw9pdJl->5ak8=7QY9R(Eg0$q5MY> zLnlKU8BhBrelUm&g)X6H-f!G5el+^q*?b(xpsDqe=^PLlU?I|a{@{r#y`7zh4GawM zLoxFsF)dDr&Ogy>2W^lS&sS`}OqTIxl#veh`BwC~rA2qxZ5f5>IpwMOdLBh1*_U~Q z&F(q*w;_?FVZQv5>H`_1E_4|DPUqn%UAA=TrEVe(hmtyh-2{@G1p^NaAmFPQDc4j5 zeas-$lA==3jj7uxJx6uYCXK@nWymY-G3J#JitH>@8G1B?!@VZWy@I~f%+JGvQr}w& zGWf+k(ow?x!p4DgDcrS8)s>a?0W{orgKn-k7FP9;z`{YYdAv~|HYn&hhP@Z+BwUOX zMd1p7ty-jMF~;JN>j(eRYD8RL1C2(q;te9oLf-~wcG)%1q~kR#~GqbGoZswMC>3WK*{1+!l_nj9Y16~wPzgB1uG+Ns*l<3wTyP$LL?BN(2a+Ib(EFq+a8ism zk`y=&k6qxYU)bIK4zUcexq08ZZ4F>p7Kd@zXJJIY5J~et=AZrhb?nOkcc@?pT3uQI zJsMmap*QNGsw-({72rnFA2^umydhK^^~yuL;8%xjeb*E02N_Go7K7#OEtus=RTGuN zt4hIu{9Jq_l0<8`L0H35x^o%*FB0ywd7|LsHF%4R1}p{QdBMJbBfbxMLUCbu>a5$DaoSymJ zc@sJUq0J`H^-Ru<#}pWj_60*625H(Ic`~laW4aC%8o~t)9HeVXyMiR-K$oU%Uxud( znB>N)Qi8-IT_og2JsS2aLlWHs!IkxW>dZJckl3#nNE;g9jHGI^CTz-r*XFZ zGvnV{LC%doU$0+0Yh|ElJ%+F}eO4h%a96Qd{5^U2l@RMyHQ3wJ6E^hdG1?Ekf?kN% z8HK64t`!)917kIeW6c#n3S8f*4Zd^wGb+_8Dk^+1Roj<=<=`(ZOn&EhQxi;AL(Kh9 zWS!t4vZuwx#JZ**9QnwFHm|Q%{dfr9p*3roOE}&__=dKmYEV}x;bfW6$ZsI|d25X*5AS*y$2j~_eMG4)ppI-c8b_dJ`(z4SIXI{E}AY`y6o2Tr%~ z{*8!CIhJ3Xn3(wU+AoTc*_$E{Mvr?3oPY5(E+!^;;A0U;e+7G$jir&V^L;>#W18$o zJ$0txE`M$SDQvp;CnV}r0t8Y|IgTmGp$x(4%Ap(w?~?S&!7OWpOxr%Vn}K;h6W8md zEg8rG<$<4@=1?_BQUo1hXD|gr*>vYlCCMO8m%z|qc1ii9B@pCic@Y^p zJdQH~GBk)#K9Q|s8B7$d0NRsNsR0{seg*}U(-qW zC;#5<%`vhs$rdt4PMvKd5xwDek>ODEUi5W@Tl79ljSG{2MiQkOA@K^{YyvP@Zc7FV zRP_xSR*5B!I5t42u6PiG#UJ5RMOPR$$l*_Hc_SEq7G$USfTP-R!GrftLF8?kA!ik3wN2)Mrb zr*Z0DwDmE?C?(f%?%h|eH6B5^j;+JbhZ!gzDWq%N)3akaJ2NG$`r}PQp^xoBWr~Zn z4sgU$j8-pnQb>d~(mg->yTN!iPt0!#PMnWR$d3Wopip}5mCGZil9I_8A+kth9a>y7e3HMGgrf8)*u=&F~{iYfiAk@WzYCK$AUMNN}(~p6r5ifZ> zi4Njkv0_F19visCw?hAWbl$j z8T$JABr{%y2EV}x>=i4@n4O&^n2Zb!qUb|thl(=N)KX;7o5|4Nut^_%jJptvBVd9< z0`%JE*jL!j$(`#Cf%RC81ECW9l`)YLAXI51C3D9r3Z1C87o5*cR;ctnCpFc9UK^u) zhgcEQGE@&u?e6oB*cWUvcvgA?O(YitLIw37+2-{-2Hj>M*;A`rlzR^LOTA8n1m^?m zCPyG3*N-HOsxuF7T0eARJtxHt$wG{Y;r-ZOuWobf_;C{=uCIE5UD?FT7Alcz45!hX z`uf{_V#Hxb#(an&uz{lcM~sn6xJ@`d#*E3%OFb*ZjNTPFeQi&)(NnA#d#=umk2fE+vt$Hz z8dF4??bg(XPT&&`0QEE`ih1nIh~-0B%QClN81HV*K4M0-^sQx zP5UxnC#o397`N~29Olfx(^ea>pCM*ngnsqA;d3TFefXDxQ2Xl;#A-V6S5JEBb6AfL zlD@0o4HfVMW?s*sBS(+EM>}R}@_Tw(6>rY!Qi#IE{R0AmZ?Lek%Ay49{cV7p9`MVu zq6E}RMlRm+_D;!IstK38O6mN%Sr?boZ(qHNQNT%7Z^+vhZEZ1d zvVfP7ou8Ah!Psjy%7@Fdl&M(m$Ps0nwpS5R#0q8rm;XL$C%kHiz}|kB_~Y;r6hrf2 z*g7&8d*OBW?RKFTAG?6PB;fsOa(jfGr|8V7bV8&!&&?E_cPWKzrVH8lBFl${@k@2H z3kuLMhlU6 z|0W3_I4O{4$PDOxg1z%N8k_6^WtA`S>Ca)n~_}C;|l*?{u`p92&|;i zq~oo@=N^;tj%ccTIX9zvD{-%Qgnc0*IC$1+>J|@IZ2mJx;3KFaOusRG(>{MQGc!C4 zc)!A`^(@l}NL=-iENRy32E&f)SEE?y(OUpT5m>jSc{dPCZ}7f-E04hH2!~jbR=s@m zH}2FT_8dL*zXp@oa3^~Cn^L+&Zs|8doNJ*x7yTFk?nLZ(CDdYUK4+OmGp?3ajg1FY zlA`dPr08(ocP{!Sa7rJ+mFAb~8%d!j4jd}cd%@G-Ov86o&K8MUf0gyLyR*-d%^?;V z+*d|)uu#_BUphLT0>v=V=}hC>vEv%?9;Hc=jo}!S0Pvz_ziDg?Pm{#1+UFSfEUrf` z))FPX!8vR_SXdw6IoM4$uHeweW(1`*+zKH^1YzClLrj6thcI@Nz<~vziVADHF$BMe zrAXI55Y2EC<=WQpTUjd+8Xsx7Mw{C(V|amBvN0ABUIoBWYp{`U0Xq6@+^4NnK+_#= zk6%S0gx>2haN~?myPlGEHqk=p@vpCy93ai{zDQ-LMF?U;8&;!MeZAi zZ8q;Q^*y<&&95^2E&zbL`|VOs((CG!;{QyA!iMPvD>i;7vKL}WNF{;IS{4=-7wDut zB{Gb1$Jw#Qw_28fb%2l1Sy@;P0Th!lBZB4fQD}5M>*jE`VB`aPM&Po7S0f}i0qXwl z(o(4Thy$Om0-|Gm7&)^QoM?d$!~$qn{ydBk;Hk4G?(J zs57Y6mrG;zL1uaan{MkS%ZhvL#W9OrhHo)`kN0+{`Y;IytMwqqet+*1+_5&2-}}`u zf^KNuO3C~t;89O^+I#P{_hOHIBI7LS7Lrp9tYU6?N3r}isL9y{jak^0Hsu6Kp`tm8 z(Uyg-&qV5Fo+E8}9FK{xeV*fOdZ(sKuGmSzJC6z;JZdyN=hU)(fQb^e@}EX9j>~d( zPvC;Yl!G_y&BvDaANw*ybA>5dJIF1zkZbsGth#XD=hKUuJ*^W2buXUM%_wWW^m*xj z9)vRT@H=ogPCCKYT$-I{L&FLrt^e~K7Zq|>45UeZyzIkJ5sskWD6Ktz9_C#p4BT2v z7JgG17EK+$V2G!4;eV8IpL#KP+-`I3Bf`NA{C~lVQ$7lz>GirfV$g)X;D{|&pxgru&KUX~1`kX* zJQH?Ery#kS@NmQ1fJU;$^)reXeZV3`Tr%-MAXt%*t=5B(oR3bQ z!8t|S9=J)g+UD+@3BC3>c%5;uZ>W8thE68|#}-~>dzrM8vvW`B1^AiKydCAM077GD zfPv;Nf>6AT37_3Nh8T<2HG%VKKEc83;Q>*7eSvM3fPTT?F`Tp zT(9VmmGQQD8P5#4&#%W7>+8G7qaF#+&w-cAs&$~>)x~O93*z`bB?@N|IU5m7qQp&z z=kcDq7j3!;Ph$@(r-TZjz-gpCcKFj^5(vY_3-(S_iG@628cDzzpP95(Zzd}&TTRF& zvVRjkFm-;h2*6#JgC630xtQG#*3t3to*#`c;N>7SyM&5+uVXM6$L!{Z)#z!Fn}?0{ z!}+%3PamMEbOm7-C&Nhs6r8!s zO^8es=N6+Noa3lb-&*4nxGJdN@mPP48qT@Hs>?5KPOOh`LwA+dWVkc^XapSTjK1zrD!RO$FTj?2dtM_b&En7|8`N)Fsey*Zw8_ZZvj(!MirjU zi-YHh;N#Cmgs0WhuN<0<1n);cuFmRb&#uC5?bVVZ0{*ZLdP}ofLjrLllgX19)qH(T zYu%TPrKKQ!>kuqs*|D`@mx`qz7RO8DnV$TCjf4c~G9fe}3XXqvhC+sQ!;v`NhlhtXh9@JVq7;$0k=+^mz>tZ*mbw$Kt|8rtf~Cd( zI|EBC)r6BnF$i5Uo@uZ1kLR%LteSI&#SXg;4&@i$y}KEt@VgEdLe8PrH~c^By>~p; z{r^6EYD=QbBARAaLlUX9L}p5onUYavHWd<)GNK~8>=k9NjEt0(S(2S1d-FS9uIux? z@85m@evjXM|Nr&){Bd2M>vTHL_xt^Nj^lY8$5Zq)#L%&5V${1am)T= zfYlC6e@C*1UHN&@(=enOy&7x^ygUs`dT{GQhC?Urra|O)3ZlBw0z45$^ zOgJ&LVU(r@>x-N0P`Xn93LWt=22Kola<;=vnz0uFP|@hRS)}hq0~m$=uEHt5wXJPX z;M@kvb~$ah1z@2b28gBt-H07?(3MS8-q6=4>~#wP<34Dwff~iK?1Dkn!CUP?{B($R z?}+6@t1jxRYWUgm`yf`Pf)e(tbQ&bo=cMqpze7gjy7@4>?A1*9i=z8tw7{_@_;Y76 zuLWX*?lJ&%anKQc7jznGC^)mq0--C%yS&O$scFJFe(vK#*JM_Q?vR;{EuKXWGk|LJ zR`FVZ$!`h!0R1)ROoorh8ogXhGurz)37l4Y$6)}~Oakgy4O=X-O+$gxU)l^8mu1+{ z3k^*QdUw@d5lqBn+K>h_8;tQUSiGU3FmFVHrmTl02wPKWd(|g&>VzD?jcHMcy!s~rhtVC4Fw)#Gj=Ty{T2R+ zn{gMkb6_d(tFt5$UalbxBFrSDXBfRwQnb~uKkk?gChbhEQWziX_ zRgRxnBN0&7l@jlMM1AUjr(-aA1t!nP=XYqB#Fx=-4@IxsKh{VsA#c|Gh3T5-m&NT| z1o~D;(44?CPZ!Ay(kuM*ueupcgx#Kl*AIv4RK6IMj7r6R0EJTM!fAP&iSJogJhd@;W<{j4M|xdyEsd(8y}_!ze?n^#@LcV`Qi@1k3y@cn?1!Z%Ga8& zK1Z%3OHnBOA6%&^ch~TUw1k&FawNdsVdI6&w-d7~DR+;ee4?mP3uyjEJw&O}87vP; zY~rL)#xVxPAH=!?PPk#KZM-5iWSqB%bvAV5(b{_VpqxMNT1wg5iLRQjgLD+iEXqep z7?s+Glh4g5+7ftqx|*}Vt0pRnF*ONa2R;Tpx@MH!TpqZpO3((kNv8rm{5^CYyjFAA1VHH}~-ZVKmc>o}4I4d6dFmMED z0-n~V>B|y~Pw_d%Wl!_+9ES#}R<2P*edVUxZBhWi$9?dOxES>ibWY5<1mV0X!?eS# z5_CLOj9cGA1sc8pFY^<(^Cq61Yhg_WU9th-Lij%Db{cFYVfMES#u59Y{@g`O=_=5o z=j4WjY+LA9S_rLKBH@wY%=WadMwP%n=v}e)Fn2=k~V*j z34tfTMbt;ewmWr!Ug;wwUWgU|L-Hf=&$57Wke2JJ83AkN2}yK*-Ph(~W{XHg?JDu#X5*)vG4tFK^DN7FR1N<~XX06{DaNk9v%Q9cM| zc*!d%=Oh+FUxeP!bYc(zeM7GqQpr%)1cL1vJ?yx&D1Yeft(v|~3mzyp0O5BVeg+LP z1)QD1(z7x$I&eekjw?q!a@o!}K+W=WEe`3w9;27) zkTvVHy1EVVs^=DpCR~@ zFp1{N>42V{Oup81uz|taRPPF2k6cYnP4QuMU!-4bpAP!%1o-2k)xA1MM(&c0M(t;O zcfY`LTX44J1K2sFoaDe33;3qsyL%RPFscz+Rp{B!}D-dGC8ku z^Q;vhFS25)WdTYoVwHYLfbNwAw)c?5TWD}p_qZe65u)|ADGN)>C@^2+d{=IQysFIr zl%2FWe6H&2Nrx#3zAYCOs8Y1iQ(wbaNaInaPW|_bFuEcM)PinTBf9gaXoVicp9j1| z7SK+R&F3LTsj545kxz_~7vmcAK{_X}F+X7}uxW@9kCS%2D58UDkmko8wraAvtTh5? zr!m@#xNf4&x{g)p%Y48Mg1zysNE;SD-Z)XQzAgtzYl0`H%kVRy+&?>m`nMH*zWE1?^znu|fSG&VK{IWt&!grXbQ zO-1>IV01SOT10a#VeR@M6cpHoyMM}5`8)`1O)9HK-&NqCnd?DGxP@sK_E^+r6Km>X z+vb**fs+2#jQGE-)a%zPr*o*Aq4|%TRUP17i^b7p-A<|}a97;Q%fP)(w807@NN|c5 zegUht;Q$SycmayPV*m@_Kr`nhu1PED_=yq3xy?1ms&H*!)vIo7RL#`F%r(hiBX~%s zCp->nSy0sWA6Y@Uh5C_^gX7lFfn!u&BI0CdD$w=JlUh)zbTQ=Qp~DaAHuOM{&wWPd zK}@blf(P?#V^F5yxQB?9O1xykz0KwE%C-;deu~_dvp1ZONLZz(%lD0=Y?8W$jq(f+ zH)RE$K(9BQYEQu(R{{wytNzPgjrO8=VUEI98Q*I|jD;&$kH`z>Q}%+ML0JWt{jcr3 zcZ+d@^@kV_(6Crjv}J{P*GYJ7<7Uo^#p*d4!M85^XEpAGdu#^CL7!) zDJgQ8Cei;zf+jDrAMbyfrSgCMQ5|2k%LWQp4e0)13sHpEu~`4*^IDs7Cx~$s2Wo-B zcgsA*4aKF~a@TiJC4?|@uQqGHNrx$ViU8i3LUA!QTbo>LLos?&T0t#)bSS;~Rj=#6 zf0vS?{8}>@pGZ?bv8zaZP+#y_`z!U};A8f`>dx7-`nfZgvrtU6DTUq-Q!aO2PsF+5 zYS@VW>^kV{70X+0@}Z3mXYFvD+E(@PqhdM-`iulP^PaHP0G`E7>@YCtk5VK%l6lnW z5^XR6e+k8!;uT_yKz5(jO5i+`5s%v_S?)4Bh<^2_t=c27Cy8)BTof!v zZ1e&KMBSqZ>r|{83$x*PjbVWv2qCeGR|(vVaKZSAXhcy%pXVVjUKY4wDnZkum~+R3 zSjZY|#301Dv)B!b2_eeHfxh9{OGR;$*4)1`7T0q%8m=*zt;{my`AflL-w=m=Q=u9z~O z@eTRIFf49k231r}ZUd8mdPBd4KoNT2n;=4^%{gKwA9vI#2aZl@3fqw)F)=5DwzzJ3 zPEG|l8g*`ELxPCw);0kfLIz=)-;`6vw;!B$vM2@Sxlqa=PFL~GT77)7Bi(lFddmXI zBbYiNFoFtFSy92e{43a|0$=2qa~siwL_$>faT2L%Klt{`;qg$1gETzn{XccV+anrt zGuWR}Vra+#@qZyag7FI);aZ?LF$njbCFx9oLRznpkpsa(IF2VnX*ZX=%W{%=!s3)c ztN0OeJkmLl%O&@Wbq5Uh$W9oz_-)6&%a=#CEx$HJIrGD+V|O=O2f>i(30Zgx2MopS zyV|Ul79D>9iUPFwoSo*)@#R;4T>dz6A;Kf0qY+U5$4*YQzUxId0su&N^aYn;@S0Fb z`_n*yx0kWX`1%hYsk-~+KU{!@vLY8$*vYp*O^Y zFw)o_md2jw8=}=Y0QQHW>Z<4^uK9{cJ+x(zcWy!3|8a7VTu30&Xpb}=ofY(%uL*}d zf_SC*)qDWLK3>5c`mq;AXM1MR1#BpT3(p>6?<491QREjiY8%ReBy9KL%p?~|fbSw} zh)cajPwf$0;Zy+EUTdpIP68!BXULMOurJ}fh&w8rrPc5Q zvxbE+e9XjUSclL<%gJ&Oz6o%+4w6JvSyWT=I8h@@IY8o=J-X&kyJdcEWkb#S8-#8< z5kmfwECU(uG6Y{+4AsT(0ZSaK2}wOUfA(B}1o6;sNJjJ0_=vD$!<`P6pp`oE0PkJI zy0fnnOq?$T>@1ui{^|8GBWvIX4ck+vb6jmkl7t9-B%N0rTbTty&#*cS+BJt8u>m9VX;RT z`v||h!g1bmP*jubknR+Db?89`+NXVSl3<*^HsBzH(<}utlwjXA?CSo}wW=y{nQcl8 zEA%$NJ{4TmzD^YAJD==@yUh}mVYJR4;%E3@Nj zo|7A#sn!O2ZQ(!XBQ!Z2m3`TQ@@HRpb4u@ser&n=cZq7NA?2NPSwX!I!`(iw5J>IK zrn)PN)+LOdcS21!<>)z$ReX~9!kSd+=e=c=uUsDluax45xX*JklU0QyzhP;u)+>rJ z4VO#+c%uIw|C`G^kI3PBLJE|3tNo%X)BdZE0=n#V+=-yl4~uulrlA1}#$xnpauD6l zK4Q^(wvokesVI<}(so})S^sA0q8QyuN)QV&<@%@0LS=im334sD{O{ftJYLrQm&41Z zi=(JnVIf~QJ?kT45?(5!EaNNpSTD&eyu?;b@U=*fS@8T?6GZCARFp$I_uU-B(9)VI z;W4<_6$=q-0Avk?YJpymH;P)J8huQBE*MnE0dWm_7)4hD0ptJAs9klG@&^O{z2wo} z$_6qLaiFVxgwlE~3ZhFJz%!lvSxU3NA>9;K!6IkQoJo3@^8Wn|D47-a_@Jqwo*2ZO zdt5gi3+d+O0m0}B(*e~QVnxh6$SU0}(GKcC-YBe1^ic?F^nmW!43p7u-QPr`rG=qp z;xcKoy-x>k{tj5s@>3n^eX<1HiskcKEaTOA={qG?ZsF4d;4Eb8h(9gSybmDOd6uf6 zhaw|tG}4}>)x`!-4#Cy?%cU!2_d!%krSUquH{d`RRKri zJks)o+>JtDYX*`|^yL`@jDDc!7X@%6@C|E`7-`s9PM(Bg@@jy|7200FVe0_t>X$d6 z$|buE-7e>yn1aai3xa@0%#X3tK;8yW{izBN><6@@z-x0>Sa#9y`aGM92w9E@LVVz# zCQz(Yw6(*ESTSpk1na&<0?xx5o?%T@Br=fS!}Yg7xgPZX~rJh<2R&3Ax#B3vkSXlySuL?V)!UlG1}!m z?3gC0+QI^k$PtTlD7mSw=GirNtM$_3UI6iZjV?ckotzBv6SijW?0UtA{%Q%oQ92M& z;^p7hs5jLD794<>JrWd4i#PxDciQyJ$7QqizF;ZmSA>mvOtg0b5=`E-MbC?us=<{e zU@chBdstWk+XaS=4jp>$pa)-%)9-SD=YeZ2+QEteZym3nRxY~L_}UHH$82nDZso8v z6kz%i*E@nH&&)d+Adf@`;T3_=xvjI9r|~jBAV>F4u``^d8VIq$Ew^V_eS{*?PdB&?=WXo$DC@+NKc* zL=zqK{&FPGWMP!pH1eybC*Zah_&g!;l0YSVZ+l^^s{Sq)dI#c>F;iv(3n~3Ja4ZAB z_bYeMquj0ZS3AsHc#*y@?)QwzIf*@e7zuLqg$MkBFE`hFcji!E3#c7B&CI|E3Sq^u z`e%6y3@%;TM=^CU2Ce^u$eInTg(&b7Z0rl2v8Gp`fg66Qy5#Qn5{EaWVJ`pjgv)Q$ zK%%+j1>`Ih4-R!HkcpS_96);$;HPndoS+znE?n8_sw&JiEiKdKiQx$~IOF*e*a@8< z;pht=YfSZd{mTI_euOfH$o+w)6Nur271$Do@&J!XR6V!^J_c_m@LfO8C6m}<%Hg6#H z09PM9GxK$G4)vAboW!?EF4)p?kf>lC}Tlcm7LA`jR3tiJeMWI-Gg zz*81turpDz)yOp6ai|Ofao6%^yJf^}QJ$2=NN6_VWOYi!T}n=3h{XPuVi6*(JvFzR zm$xFu;?j2+9syPnU02framay=n0$g2X{b_p1!+(92pOWg%Ze=16T!UDQWxvu*OeR8 zMR~|?czR}iK|6|y*9;$mCW8;%*1R&;uktYk(4LQzvDXI7{yb3Z5P;$9AYQr=)6=+thUnsn% zwO&I{gTFjJR>VKfeQW3#C5&K-c&DSk)3dL;XN5^Fx;)}dIS49Xo87|kw$aB5dS&qk z9g{k3RxdYqNX1z5V&Jp%Lw7?%ROyKRV0i&BNM!6Ia+o|faTY2sXLMK%e5B*5KQ@>y zmT$b^V1RsGr7O_Y*ledJyFg`3O9I2Dd`4*};pc1A-;np|lg6}J;LA_58+-95nFo^_ zpkLG80;p2);ooSr|JUE_U^W=Z>~cFOXZe5nY_vu}{Uq_L@hyK>V5&1k*R~pjFqa1= zhSHhjEoxs*(9hKc;i~OEHN)K#u0o~niYh8(44h?rKNb}o?^_Cn;6s;y1*P=MOsn6& z|E6N>KHK>HyJju>25+Xrms{T~KtT=LyA zX)n4O0RnV8xh*xfwbA&z&n1?-xy!ccc{)aKLBZ0%pDJt(^vNcWia)5Ub<8;o0kC(@wt#j`p7DUs z)z#O~Kk51It|&9Lw7iCy$k#_?$Mv$WH6A{RX6)VzJ9nkf8C;u6B5s>4si^P(6Hq=t zf-pUZawTbG0M5Pe9Kk3A)EyY1g~SVjuyPHJLDM5Lza@|l6Pa7X4f2f8X|w}bJ`?cg z{-kYBoQvjc{=g=1V4HR!*uH9H<=N=p$w}gZNjw%eU^h8t3T7GDIC=0>NK!A{;~o&z z$>bOWDP)W59VE;=vcgIqlL(Ejc%keV$)7TryjUb;bTv9=drBeQ__ zZ{O;nMXlp^MhsoHru*Ck>@kJJW}(yIm=o8z$`2qL5inS&jLdzO*;zR2X($KSjOi$f zfhDX?S7{5Y8jhTFaCGF|v7;!86&aT#em`Ao{I} zMq^G8Bb6UZ9oSwKfuNgn=K328bP^)87%z`!Uo`6G4xA64Rl5)8El<^I~!#T1MbX%=Q6S9(BkB z&K!Xje(U^sdkj3zgFnrG+NnH#Gc3^0V$}8QTQY&@fs{9nDi$NEpG5>rn*%cK4UPcK zj$KvnbW7KZLlgSji5THybi(Q|jA2j&X8A3wxYrTnvOC-c7^V^W90lZd%%og~LA0FN zW`x{w0HdvzQ5*?kx3I-Q2qrW{hRa4AsK;S;vBlvwxTfjwCu||=bE1LY>Tnx~KO+;< z9=0xYl~G6uRYPkjl?2(NsBp^>8ZazLqgc;8W)H_G0TW361lxaAt$SZiE>1HQdg}a# zGg$?x*4-0PCD+zoyxas_YWe3Nz@;#H1g4&w8ImC5D4>o6oATaEj0OOw3R$s zQx}qK*7=-qQ153!T)2kKcPEJ(26*~;tROp~$KDRc8{lk|r+KVE+X+!L=^b%6Lk|o= zfNeWjTB`sa6RJBr_L+LHJGzqWfDMCq-tNUq66qD%;<$9T&2To3MJm=+O&CT6?u!L~K6v-h>1#P0|+2@K19l&WJibM;QiX7HgM$BL5ez?%NF4Gz%!FxPZ z1|VGx7_ytL1FEGpp$~LD!Im9*vnjV7JN*(F^w92}=y7y(ybP}^c`uOqXi9W8y3UQm~f@Qvd!YnM#^b2 z$)G%?J0txP<_r~w*&$5smPk*#Jm@Ne^$(^S!Gf*x(2p$AlO~k$*JM=E3D*(6I8GHtW6-(W}M@J_b6M;x@O${O-FqzQo*?Z+(b+?`g z#u_igG&`k8>;KC}RUK*yx3QQ@$*<%$pa}0I{LL>OI@Qy`2aTRZm=JbM5R&RNs zWipD;l0I?5b&QlLKW&44VG;%$o0;30a*X)ihS7^8=tPL6mpl8jYMm?J|Js>V??r!8 z?!={RN2&y>$23;Y;~g{VlGWk8qdu*%l47>p(w}osQ?D;|+5ClLNof|c@GjLy3!aaz zrrc4N7+UWK0-MRZ@A+h6D(kkKl#j@5mr@Uw+uvu?_*1OBR8Z}R0Ee|(1tGB+-PAIg z#T(l$zp?tf@`l#1(uxEBsvx7)OWV(r1;TfE zF=PGrWvNE$muUnZ3sIf`f<_*mD(OL)f7ytkHY#8juqdw7gpjxKkG42#_;(ceSZtMen&bmLt{r!YwCccDw zDjCiSlQKqn`X_VhzPp#%YD!pa#|LuDkP*5lKCS#*MK6ps%`Ggd95LcC<6Fk6F>OH! zpT?H=7rnjS`oyU-3a*M`*091Nzm0=+zlVQis#nV=`~S~irlWAk$(*H23XRl$H?Ky z{0O9WDg*6UO;*SmBzm{WKC*rz{IfCOuQ*uTo{ zJqFnoXI9FC<*{>s8^@Q4TdK*LA^fK?RKAP_A(~!bh@2WapnV}v$^nsP z&h0*Mph4S(qNThLX-hByE6vo!GPcJc-o`2if(jeTzZPCF zPYC78e{F<9wP0WYf#qYZ24a$Rb1cW$jPF-5B>`#0QwA2 z=_Vv}X>&5ZC&{MLqA6%CZ=#4xn}MHP9r+6R)~GGPPI_X@L9{rS`XTd6NCYDbqSisP zNE8MIt)K&6mwa!yeRhVhSI5!}q7Y&<6ms4G_>$EFjB~k?Hlvh!qn` zgv!Oe7PFxA@IYjHrvOkz_uR{$z++&rf1MD_A~1vVMNn0;y&r`4uEm_<+SDNIotAe6 zOW61{0k2@2UqaSa2UpQ}=KkX*JR)F+=Uf}((aaSCgrhKdV+*dmBTViNwk$xuBnPu1 zh*?35!6mLJBfGTzeskL?_vcdLvgaYj6=`$mYgI6ihuDOoxblC-Vz^3?Z6bk2p*;M* z6)bERY4Myq=OEJb^TjqY!TP5{5etIHkT>Oal5phr@1q>mkN`;i>XqDP; z1mLvyuo&y&iz3j+rfwWZp=pT$NK02n7%TjKHJtB&B%km$Oq|jjR(y5e>cX^5eLu}+ z{vW-&ZEX`C$$fBgWPaC{VHC)BSj`Wabw7qcNt5%ams@~R0f+pa_cBKTYb3RWeJ~3* zEpNt>Ha-(#IE%Kr?BKh>#`tnBA~-oR6g(X4COVoB>m$Z2F?4QUD;Oj4=C9+|rF;xb$mW2n5)m|)OFmRj10 z;A}U;`Ki1y8KF)Oky|xd5Ca+=IIDJ567e@#i7ZqGG%?dBgOusjdH|K$MX;>*mT(zh z$E;tS{rw+dqBveD1^-W2r@i9$0V^gAj!gAiIVpR$l4tC%!!efhPTs@WFEiwWsv%JC z?_&X3Eb(g2#Sw{wQqb+QLg`1$=fD?$uHedhd7A{Hi53@u++o*+?}+v==v1nG_Yr*} z8Cfq2*a>E=bbxLTxs-D>?NugFpoxoMY*z{!6*t|zYAMIK%MfOSE__EU!&(`c+IP^L zG1#RsZ%W0>Qen@*|H6GUY*~xW1qupW2*hZq4pt}QVDHm3Mj{+TBfImx10-nB>W3;4 zPrWq!6Ti9-C}S7nFA9W9fCv)FK(0wOo?RaN+kQ*ky>N~sjbflRT3O-&;xPg{N9rDW zVpD?gTL>!&ONw6Lg`}Zbgslce`!KMB?Z>)TiWbnAsG#n@iu?(nEgfb+o$TV)LkVP{ z|FguS_z$m)F9>aCX7aO1tl%cZOE*0PZ`s;+HnZcgN_z89HLBve;Ilj!Je0e7!U!A* zw>Gk$NL+--KG-8667hU@3cf^23)ygCPSorB<}P}b$cnQyJ^cvivRSJ zG8LT!hFR6QbknCMzr|9&j_4;&{3HXFs{14B|DpQ3t+Ng~=JX}G@I&j6ut-40*GGYX zcJ@9J>0?7K>GI#2`y?8PL(V1m(VlK=}9hnac_-b3{I025-=jw}~qfm=z%Gw~KuG?>jR?OAIyicLcn6B!WRqw~Oe zds(3}j85SCsj)DMF+5x`aID)GvVk+Gwi3(hJgDA4oyA5D1on7e_sxW0M68=yEwB(` zjUJ4J9_El4lZkK{)H)U4l8NpsS^!Hus)(ybz!@~i%|L{S!zT!%*TA6H_%j2&+>0aM z9HO!77xC8ITL|LScQ|`_tia(CfOKmtiv{mMr33LT{=-FVB1n>W009~Z!s8@vK8_cF z#sP6Lt4M-K_J_K#$arRrp4^KA9`U)j(_|y0<_tmD(dU`=D3N_o&Pz_qk@^L6uFjG) zVM?#R@A!8*vtD1CEQ>(=3DzBHfPoreLTz3YP(2Pvj_4P;N)@{fOk-4s1!R4miQ`w- zedU8%4m>`=94(aK6^Il+?14n3k)o&fQ$&vmWO7mT4w^M+!4Q zvhSJvCMxZ5d@xi-qQ*Q9Q4)>m>LECY64f6H&kgy`B#(AQVJ_GG>z5(SKe{r&ae?gw7O_b!&8vt$2no5G zZ|#C9VI9)sH9ZV|6!HD_r&dx1(GyarUdsoORz+7g;zSFjw%~pFo7b;jFs}SBQiTx- z5PP@3k&wHyTwmSY%3d8pxhqfqFm(F*!yYhZ zBmkfmRtz03jepM93;=Q8e)9KILg)MSJuio79iaLJK?`3V-5Jp+7~1}BPIVcaZ_Tr} zc424&`92+;bjzsWlo9suG=)-wYIo->)Y6k6FK9RJ(o{ z{hB_0#|6j?tmJD`@#-0Ts!19xKkNZ~b!P9X4_f`4rXCRG0Fq1E9B2(H%hY=oHa1xz zSTWv!qR0^DF3?It5Fkxt4|7}InhH^PO7`-?X!Ns-t+a z)-HpxU0?+20#k#O6jPmye&jyD)QSOiYJUF~2uYJ5C<@?`!B!5gFKMLtDuo`D6J}_s zTMR32U?!w7VQOlsP3i>x(BR-|;v2*i3CE`2@I+UP=D@Wl{TNt;h_b&?^$`}~>JNuj z6Us#crgBI3tX=FOsCvO&9X!l?i35QE%9LaaC2OFvgoMFJmavO6a1i-W{uk#gG?cO< zldPh~L5drZ7yhFvg(69t2s{ma&;s$kDo?*z9|ZpiMIs-r^$-D;7*4QZW85syue;#1 zaq#wc4IUp{n9|S~5|Nl$S$X`=V21Wj5rp@W<2j8Mg(=bfpoga?S=C8z_!-z#zuYyG zf0nsiOJut195 zlbG#8I7g@e21{7;jWJpjgmXn`Nd|CzPw10$VZ#B~x6964`MB-x)(qL0dB~v%;p>Ec zw*&$Y7-DXfWa|9dV5{r+ZatY>5^^*33sT%NtWCVzPFT1fR#>+3@`=Jz6) zJt?uyn45ve%f%& z^&=kEbMuQ2YhoR9L%Nzh{AQe@44wsB%+LNF9?Ksd1GOPey{}Jd$+o#*?b@}e85z-r zY*O=`bgBYNVwbO6Q8^&T-+*r9hj~_%vx2<5u9K5yqiDnT;f;@45j7@7*Q{Anyr@v| zH%GCeeRwk>aZ!JNOq>;2jnp`GWT&{;8o7rXH}Owd21mhVS@dj>N6{(Gg6G@}pZ&VL z=J1g7u&?Ag>HbhC^50i{Ec~&GcO)~EJ9cr=XKu0jq{Hp)JH^#E1krEXneX+QLyN24 zT~dyxUUH~UCaz$qD_?5=rVh4;4<9rC`#!PdffeIAbbh9}PWu(OUU9p7NXlW|YTY9$ zh6w4BKqYbc<`28slRK*YJo+khbmFMcB_Z}*! z2&btQ@QPuZ@*`g` z6RR@^Cd>q%59N#+S)n|}$>EOqPaP*69rNN$92N$(E@jMjMdjsf8@Byye<5*f#K)PP z`O&G_DSTdU0Ohf*Wh@2Lr&OyrnKPy)v$Mq=eyrqNH&-C!&`A^b&I}4VY<)l9DDD9^ zLubga!<#rOvStFcYIHjL$*8->PI^+EtpLJz&va%~U&qk!S4=@&>V8pCE|>|)q^RxX zJ;K4*R#)fycX6sftJcY(W9~aQuIVXbIOm^$y-`AhiNoaEP^RB^>`TZK?1~F?s%<)_ zVD88c`gKwI&hyZ@zYnW5*!=8xWbHb_3Y6Wlue7;22;V-@K+9oqER+TFlse_dm$V#J zM?_}GMYLj*nl7SaBqV#bn=>3xycWNaTDWtlNRy2R^+wkii`{3RC_wO&Z_$>LxzXpY&j@(>zZ{e_q|2eBmU-0GoEydT}r+ApI>M}V7ax0j)1Im-73V6_roVFK%G%b`e3=@8r#@_$u#>F5 zZqZt)^S0&3)EtB04bhk3O@on(@&h8UJ#)Pnud13~URzVMQG!FExX0_XUbW_>Sh1w% z#|G^0o{l6^$A%7D2@aST>~4p9y)>SSU;FraOvQdo*f9tO;^_r2lpf&nP*<2VBS?*wohcNNX-b zOZLj)hdiI^p0K#}m)yT!qA`EiNopYMfKnVT)6tm3fgR+l9y(a`Hv=r&Q#yn`PEuHqihrh->P-+a@D z9r})(xOp=+V%Qu}LFdk$$(TpMqM|R)+x&`s!x*B);<)?;Mo)m$bu|3PXUsK=h~MoJhIPM#m1FBNi9`eK;jndE1kKNg}?P<2LXR;jdU z(EaFmcubqkXZ!Dw({>BEwbm&ioF57c?|!MTkBni*4wPa#=jjjlJ6AeppD8LThQ+X> z4rWTYXjCGqX*aN^w7mP{zOBq%YF=jt8r??G z?&CEiq^oym3$GK(8&^K(Q_TzN#~Kn9Av3s=od<&iuf^gKj2W zG+NX5e?Ipq2?bZ()uaohb-_<<>J-k8zH2}DS64I5qG;SjVwudqVsL0EOI%#sg@DL} zguRA$eIM@Qv~Y zZ=R*$`QVDHx~AsFmpvb^zb(4;KECzAyg14tm$p9_GiYZPZt3Vy6=^FriefKL@nYhn z`k0M`8mguY`JJ^xe>{whjd@=1%6P-RSd4w6>fpy=>-hM1&+7x!d!*JNF2?yL(A>WZ zFZ`4xl{sU}oNqS|CymAs$zI9m@dx3^-OYL7?# zJZc#%In*Kb&9|lC`Lu@Yq(tY;DN6|v?GsVONXeEBr@|QLkp1xwXSd{g;a9Hd_KXXY zUuo=~+y8vQ-uIP}M8U(y+$dcxOi!0fIW7MRo-5mbekGb^N+`sVJJ$S#SNX!+n->nw zM~CL7%$62UmNTK$;$viFjI#0+7uV35tqX*owRJ-&<;jamF|D$?M{|Ml+2xWv(*VgW zkMPbNY8f_D&X=m~!rr-^Oc470t=|8c-AaV#)GOyjTVxJSD-nvYJN2e*dH?w>y^Rd7 zv`&_9B7cc2$(Y6y+~+03eC`($Bjb;b#XlW?0rhfNDJgpj>7BHsf39{|QqE^?O5tFy zFm?IZqkbEdbUf6d(Vm&9yfDt@Uvlk9p*4?yyBxXh=(ZKwi1$ zz?T2~?o_6;b41rU>xR|a#gm+dr<~}pOP-tWW`Ea@mmTw5M<-K#wpoenJZa>iGG|^I zm|7iJZ5CY}$Xh-U*7MOn?1xgoE|q-eIQ`10bEgjP>&(H|s?|HaJz^!P5%`uX2g+Y= z7w7!(Xd!B;xt7lxdxDAojA}q)Ow3uBx7=zLUBs6?(v>fmi77;NE$~pJc&24oja#wQP@F=R8 zsWVr9r_U78IfWT&k?IP(1f_FTDOp*(4zu;47gZk%InPuTL;9WWot1UC(~U(_F~ggL zU!5M-En7B$L4(Es=(c&YC@dp+VM)fL2@$g_Mu(^IX>5C#RP_xE4L2iqso2T2-+E83 zx~l5oql+UxG=qbKyaMGou76?56wgFguSXjJ`GnxO%Qn0QKWz(Tmi5KH- z9FZ~LRlnbuO=@Z8vuZ$iUfxykIF6s2dQ(5Zm_Hhj9K%=s=I8{kj)lek=$`EnAF!}o zX+5e59ew>%(_>Og7C1C9b`M9n9i>*UUR``Be}tC&CzLYocJgux3N%~2xpcN1-0F>l z7Q92*uvRjlB7y_PZ`uRS8LZGN`Y@5~7dM^5P>z2#FZB1omW$D|RV2#`Pfpak>Vr=Yf z=t9DeJ2|`F>AY`q%g;Z0s(d1JaUe8;qv_M9^QWljyif1Sh1VFe(yw1}KaEVRtPcJX zz15MQXv2n|wQVyZncr@8KGK?xh*+4(pUP8c{`T#>>|tZkmtR_1Vq@4*=1#3D=-^C6 zsYqKor^3-sAA2~-$jAtZsEqA4PwRss?XzuWR#_UwoC~#_yse>}vtQhcSNNT@%r#iG zW994T0bVv%76vUc5dBO@Bomja#UP6eDQDk>@JiKaQw)wWYQ7etDOSiihtZNl9<4r^jnnxfDsy$OTrpMMv*Z9egyU=vrPG=&73lTw|KWe0&pKLL zi-E3tw63jXe`68I(`b3-DrILh^l>O{-q=aLsrLZOmlmIv`O#{)6W-+cR=ar>)vjH; zQd*38`1pz$6eR8?B=nCczWnr{wpNL9OhJKe>(;IC$I#OYdhy~u`awU1qaZQA8PA5+ z6NReR>0Ky)X40L$mX$qVG>wmoyRVt7FxXdHAtEe%7vBXAMxD=Zyi&4EwiaWzf%z2` zWnyBYAJU)9$DjNB?yo-`DI)NBCBFF6r<(@$zjB;x@ppcJW|tjVn2LhBQuyU3&#zas zw9Ys?OHqCR73D!!aAk{+%dzcuwS^zzf5*1dPj*eseQ=74kALdt7irUm_FP(8I;HIo zemN#41}(OXOqL`E9s9<$M5`;DXfR9JEYbdwVuq z9n>Mp%KD!V;LZjG2fNC@`H=H{A}O;f``fJz8#fjYSn6KCzD7ZEg3;@A*N%Ykzw8rP zvX%|3!r@+hBR0bO_TA6OI0$HT3mW6NuZOmJ;{xArG<5rRt9)|u-7k}C*SQPDF$+GEl~yK03@hBE4uFfdtZ_jn4?uVb(5GdS=fvs}>6 z#Mt-;#t-Y(xES2NEj6xPF+D97EPvzN`<8|V|F45Tc#vq<-GB1Tq_4Ys_rm6@Dk?6x zAFEuB%bh>ZyWYvm$4AyVIWA6l{4l2Uf9Dp+nl8!@%=~!iUf>y*alUO}Am(o*KK}e& zT3Updc3NJZz(O7-@jX4_>o3MLZFHAj@38Lv_SMHuEN!55nszwaD7lKXM|WkQ;eYYs zg|L{|I`FJDax_BaGDS?DZ6zxwa0D3^`EASlQWKx3425Uz|DT0~iOy zNZ!p*7eINfsG;GNot+)E^;2Ex@RXi`!CAYZ^o)!>+xFu46k|fq_vp=8R2OhT+$?DA z-zTWVrCsQ{?>mJ44Lh4VI(*=z5aYzt*wiFT*VWV0!@wf^{N+o(Ma@f>SgbFP=zqVq zZwGqE*`>6!eFhoot5#4YBqi}B@qEVwt?^MWv{B);2KWjwHrteBWvia9l0*4w&+{P* zo#__{S|>lt9K=(5?;aH{DXQAY=;)p=RoZV`l%2c`jf_;X^W^?w-uqf2Ww+f>R-bRu z7fkTLNM409DCp%&X%!U)IWCpz9u$k?5m&EViT{=VrM=w?Rg_xdMLb|XLD=Svf4JJ^ zcy&$9iss~NJha{H{w>DOCOe9YSKvd0H5xJ`z0c3zNP)M!8>%8}5jwXIoljQi#$t>6 z6F>M;lOAgU9+pMG88pF6VBS|y&nC;}UfEzZu`HOzf&Xkh$( z=LkjHz+fHbY>Jjn?9b2*CpWQ8SR-z=wY35KDTGhP&+jZ7A9W1lG!|GcT)22KB0pbK zsp}k8-<;HL8J^;-cw%;N>Qkh+wZ}fHm0bQKcn|;+x}zXRZ96_S)dlAM$C?_z3w3qM ztlp=^LgWclj13Gj1$$SmxF=mPrnB!kV?b@E=~=4iU%!5(Y=783G?di95RE(a+uAOV zLseCke3+j%)JXURXk6gHO2& z8gF2+r4qLh1elqb8E>~49EeCwRkC{S|1RmwuE$ym0dRhZWzsrNGobS)UaqdL?mlWz z%G}{&x)b}TSFKQXQ%i1&L>=FVBe)gsh0>itGnoZDipt?)()E29@D&i%&A05YUq7ub z$hzTNN8k3!%1Xx7`|(8JgHhpuNlZ+1z1qHQqx*%geg`h7{(kx-Aixcu%^;&S)7kUG zo4X4-GU|yJXEz1b4_MX}1VCF=0{&Y=hsP94e4{7lLjRdfQ}M9Q!{Bc9y<-$9KvkQa zE^2CWR900fUA*`J)4-T2OKWRAYikyA+qAUGKYn}|p{e1H9T5Bxmm->J&UPb09XjL= zD^-8Tq~^J^pXS1v21`M6P`j >XlTh5MDw&YgNK$9#%d_?Xx=M!eF;i1gC`eb(a;NM# zk_wT5TfqMGBX;S`>%33nxxU-?%3iSZ-Mt0R%ECelrDR+0rVVQdbN*DDSJ}0Fr5l3$ zpFQIfXD(c{WzNQ@e#sQrDYkJ*?egWPn(Pd;I%Z<*L9bq2%>9GA6Lp`0D1M<%S{hG< zFdVZQvcvI+pz|qCa`*IHuS(@-Im|EOTzlO3)-AsEyNz$(md)CyOKp;hH~!GxuF)`O zX>hD+aN?Y;+)vxy=QqOY7drTTDz2T7m8B^wFHgFGccJQ2x zzU$F3T>kUdkI>uy;R5{BZRj~+KMT8421!ZDO;rdhvQueaEXH>C(8a{YDjldkmW~4t zDDG`ba2mVd&y^6cGv^7wJ8z05R-!4dYJ$XA%*lMr<7o;ytUyr|P& z9k$^5wKV5&6qwErFghudpIa`hl3Q_)0#1X7l#~w;AXiC?QvjA&Sy>hRwY9wO-(P`Q z^Ti3fTkqL$8HKlc%OrB1e;tx@@;Nrxi!-OI3t$ZDf;sDlKX>$iBq5{K(KzoDD2_Eg zb(BvqP?7|-3gVS)cpSC%U#r6HhG%JlaUb-JNL%;ddxdX!Bi~Spv9mH z;8UDpKL$Uq|V-HL(k6M*x5yvMxB%dE>#a;o(5_%RW`jEjD_23`%cb z`KC693pE2lre=8O_DTVaRyi@JS+P6~q`bX?g1W}Wd-v4KzDjot@bj~Xnz4<@`#3mZ zcR*D19JLEDBfX2k2&$2jl?*criz%<%;Q=DwV!UPGtZQa!>ZXf_nQt`9bfa3_vPHP1 zx%sU4ZI9+Fg`K89Ad)$2$cFo%GmK|-werfc*4C|v+KMPzCfJd!?pO5`gZZNO${C;; zb!fpkgp!EJNa@x~C@F1la1j)7ra7L`3HbXu@@pa9Y!kz}O5IAMz$&XB5?ouo*8pK* z<>U;!Zv80ZeCTI)Sb#p{a7KA&mv?k%0&{3#%=skkG2q&q&xRPs`>OX!@Plsymgf!| zZmy`T^lZ};RUtR5L_DM(KPTo>mWI<3#zKe=~uy&Ovre_z~iv=m4`20zTCy9<55=Y zUXvNNTYKlly%Tnh)f82Op8ZO63WvP+T+QR^L%+tlB z?$-6RD_FhDyl&rAsq8e>wy_cWJ&*bpRcQJAe6A&(a#z$J{>WOJ-4%Bkz-xYL_x)3K zbr_x)!@n}gP33t@u9M#fA(LpMXUWs_0oQ3yUOsEdCWiV~jQ5Uh-}7O&@3+&r>u<@( zP~*0spxVh7LOu{(?1vZ8FQ7O5JJJ)@S_i29|6%&*5 zFG`R9sanExpNk8o0QdsD6|@Ypq-qnkyM0^8kpF%C0D7E9G4ySJCR1({BZfrOw36ke zRLup}5A$4<8;!Uc*VE82U0Q)06|g(U+omZ-?fGM7F{aQ)jDO8uCAicX9OxeyIF9

s%_vQZ@oW~U~hnNQp4KD+1cy{*$+MDv9C-zV~kBqWO{J#kL&2{ zz&ut>w{(8q0j2CtRBRtK>v%2Ka725Im3;NE`F5~044G8+a$(8vlzYYx_OA`0?gHtJ z`x_G!~{sL z+ttsyr_v)Lek$_UW6ZtD`|K#iT}?hulk@HIB5mQq0n4(hy|hl?7>!27C|;WnWw0A<@`zm? znH%gXOMaJ;aXh|J7cEN9mT!^Nj`aLnzVBRje_WX(S$WsS^JjZ9XV6a%%%ht>D>L<7 zjcuER4}^5ry`tZ@u>x?3+PLE4Et+`efHJeX7YDw#wpqU&qJO{SC5{ zlH{`kv%cN3k>EgDibzROw97ZSb?bC>T9>7G*BZHf8JA=vP%>?jKCHXRUI}1NN~~^I z#ivi+wkCEGuTnm5{Iu=hkt6(jE~A}S{&AFb!-GBFK2=p!O|L3(2UX)FyWhlw)%3!m z|L;&#F}!BBx!O0=?;bmUp7wrG*ny~NRBAfX>Od)K8yl^{>}?{B`IqWGypJUSdMRSphe5JQ5;)+XeUTJuBo25TQ472J8vmkEY-y`(NUzM=$NJ8WWNC zgNd0r0*@bL6|5!e6-jLQ@c@8~-HMX7sh=N?1ju|iVIRm7BL7!xed5RHoindK4o}G@ z%8G}`D;4ruUcVF$9K!=%ci9k5 z-s$c?%0Gc}cs?__ecR{qrgtsInT~UJ8ahhtID|l~pzVO7^hEQB14b*=15rI&+1R2v zXpu&G_bRI=igx*#;TFfPJtZx@5;g9ob*r>VD4je0u)a;4eIvP_85yc0*?8*z&Nu`; ze@<=xwYR4S!q^B?sfIJt>!L~T8naXY7~*_%40_DAHa6w~=2cXv zjxh?Y3qp}Ps<&Ty{a@$AaHRXv($YGyb^v^_n|C}82zmL^<#XT46sdzr%}hDiv-~SP zI-DvFtgMIbj`(v8-?w9qTiFS^%wrVPX9VUD?4mu-8dRN1xa)y?^Wbb0pO3V`PVLBA zR_n>9cxt>JKaOj4>VH&US-GApW^2@!fL`{TU7jn~j&JSla+gg%qNpfJLK%Nb;8J+s z%Vym_=2@8E>{z#A+)ffalyhZy+D`55YK- zhqh{yJ8Q{)5XYX4qY36TSU&=wLUrcWs^d@W&i=B@e%Kj>vgg~kZ_1Q@jKnhGu?jFQ zH7m;l(hdxr^^lH#{oeX>si&`xb8d$YLYdi>+yJh!$6wnzg?VXf+%{TUWNA!e;KpQ? z1w>+ea+0h4yVAwkQqOm_1}BY-;{6>^oF3dm#h_jA<|CdOz?!;4ddKO1Sc<2<|$k7{R|5S5;L2$`u868xbIm0r+rW5?hQeTWhkN7 z8!Z4q6L~YZVT}u_ic%=Kqu1ZT*#o#KDk@6eJST@H=Nre6c{mw<_-YiNi#E%UxR}m%96@|SsAHb}dz$u2pzk^V@* z1K%)D^>F?3{=W~>uX9~}%=c;aZ0d^phB*Hz!`Ydc57DamS6}dzqkH(p3e}4lL^Tgt zGC^BFGZ7gc-g)fsrH!N8z&FCKJ6}yHrj15gvD-d#oZt8M@WTUJ&$owjyI)qKlk~YN zc&S~3*}}qN(^UD_uU}WL{=WLSB9riCHMJ)-Kc^bg0Bc6ax&z2fNVJ9JxhN&&>zVslB8buS?DyJy-mhUr?~@f3$ZU z?p*e78)a`Hddeo*is&24&dds>>?A3pFPUYQ@t~|w$oR@0QK^ubkj$hdBV}b2EsgiQ zpXc|!$NNY8939VbJkO)=xbM$>UFUV4=XG81dTsvv_2JKHdFq9wSGLsg?tOa$o9(uy zOZ+)j8l158kmCrBVOQ+@+#Gl*QE_*BTig8znT8k7$1E8kO1b?mLz9DUqr)7TG(0?f zqqLL>On}o;GE`S$svy-kI=u~O1DqR;bW`HO9vc9oSws_0B~0E<73wHW6+15xr~nI0 zoc>@z_BHRhc8p(ux#jyCmvyS*Xr05FnwPxvtCALVfq>{MyAshFs#(%6u%vRaG`? z{6H*D^2cz+N*z=!SGejS&)-R+K5%%QJ?ph<=4;8k57y;|cV2yb1acN&%bURKZ7~*{ zuHD?TV>bD~r4q*;rRWKSB_4+b@Nuy4$HhfMYA;1T0j%j`g(-vx1}iH*Kyg!`$f$mM zNtq>eZg}uUZq5E3Igh?zXm)a}tz*IrrHs#pr+JLUz*M4K*)KhJLwmrb9EVv~abFp3 z-ol@vn>X7Q6+iWH#Xb-3nU2e3u{-)`eogP#d!blI?WNGk>P{GE2zlefXDA#+Vonc` zHbMCnhUwRRP0PyKGW!QdMoLNwwGu%y)jh3#{_Gjgx%E88o14~nnU3vFHzs&LMu2CS z3ut%ov4DSn+|v^|;0|ob9PCIYlcS~u5NFNR)IB6>UVX%!q2UPK9XU2;KeP6uT5-0f zhzA%b-M$^|8-cp&UZ{FRjvNmP3M#Z-LefAa_Bk4=1~7=BW@*2%vbK!mh=H3TYYMQ} z7>@2G^0T?tkQqWRIE>4`-;9nHtA@Ljf_yyr_%Lcb!0aSQ4Ok@Qe(%+2On1Lj2@c(n{~UD)wcnZqxsGx9Pkhu?XtE`!V1esob% zEVyc9evLEj8RBP5SQjkkujggWMNVJq<@L+Nj;q}z=cKOoh_eO~k%^`iD#oDq=9QnO zy6hAEV}b*2Jmtm3#8elUzr2f=Vq$|@-EoFA|i08yowO&s>WMH#2bu0m=)i zs=(V&13sc5oH1AvPX`$LRN|_}z+iPC-|&i`sGE5j;0R;T$pb#;!Rq1)gcSq^Gk4p1YyS&8Xb zrN*7=Z)q<74i!&6sB-P^{&kO?7K&xYQc;Tzfz9nxE2vm)w+K)z&_@GPQNp?aPr^S{ zNLD;HHa0#$osg3wFk8EqL~3n{eCE*s?L=bx_7$wv0#e|?*R@#Ua(pOadH8TFaFvX_ zd;u!bEeU#3@m;PYe^!PXNml=@$IW!)>VzkK%E&NC9(e9#X_>P6C#cbWi+uw!B5@l1QnA!@9l(FVPq+Fn^yM3(DQdd?W+T&D|<0=4fKPRU@?(SwH$rOmCZ zAeJrImLMDNnBLTdv0*)ei;9Zs=qh#Kd3ANwnG3y~n=4OCXCko)S26}M zx#eG-D?&);ot&8nIgq05^z!9Pn7Tz_=zHYJC=HJ_22N1&MBveYj2L(1UPq2L&TsN! zsJNjnEsBQu{ei|ib!P%)9twc&ZHo{GL@lnUNSI+H^HtoHm6b((1aVC3{CN#xF%V>{ zZy`<9V-l0)$K7iAAyrDG?3fEJuB)@kQal66H83!6P<^3ZX{(qoIymYZIjbBV%84(B z!0_WN_rdob_x6?ZA8$YBdS4X;gOF{K_?0f#*4jRezx+*$9t`rI_J7cStD~Da%{|lg z;?>0k%<3@$btjVZEbsd$?lm}c|M8q?JgaEokI$rcg(=TZLAFkD7UmwO@La@5-9{To zSySil_7_&g`esO;E+n1#AUEIy0m>8_l`_bdgF$9Q!hZ0;E{N)Thz0~5L-tm5jkxTJ zcAjC8gD41(H#q1=u*s})gn~96+@ioKT>@gN)J`NpuVC({VqUECv!kgf-(g_3 z#898V_gEe&jn3)(1*`a?pg;?bm|Js7O^Vdnj!ofL85` zt>^Bw<+O;7?aB1`)a;yuf+yiv0mZ5qSc!bdnj z!5OqofGxnAT7B3;Aed-qi7`%wd4N7v;*JRtN?{_okM{B^o-F4wyxFe7aw%|;Ya1ON zI31>qGz3@Y8%(vH_M^Xn6%s6Nd`i*YQyv~#etv6LQf(@L(W?z72)V2z#O3zys)`C- z)(E1n3(vSn zP|fRln@q|c4mRz&MO7$V2&S+FmlCNJ8X{%A(7MbdplZnDHXuzWa0(3Ll;9Y?sC|rx z4U=D%nS1HQOrLE{$OR#Lu|7>$i6x%+jSrw$hFq$TPj-Y7*T z96fbP8rX${VWR@l8@lTYFD8Klj56WF5!_H={nx-LIf(dvqVYeoC6x|#I|&|CPF%ld zl**e>0nxrnoRggkh@t#a=5c8Ba)0 z=Y`(e3T2s0=0+ciQD9#>Xbu)uR)g?;j{8cy+_hZpp=`pv_`0sBqC%gbw@LAumP}sD zoq!78E+%yi!#ncqFSov<{a9^xh28LDQ~u1mT~S>WXVM}W`sO3-X|r?xwo+-3tO*t=*9Ot)~OC1FfxiCj@Red$PmHtB}BE` z@PxZpoU7Zo;iHj}^x;#xQKp_r;wc!20V}B%@{I$bo)90=4#U0AAyh*UgCkpma&kz1 zOo*!HDg9V`j*JZ;!ni>RXU@Px`t_?<(!BvwD*?{-ZHRCWzjeq{EjU!s&ra~p)#pCY znQgAkNK{5q_4#|@wQm?e*BX=t4*9x9D5-qiMS-uKxG}sN<2xb)j|vHdhMyM>tqIjawC8&)

+nU3ezJf#=U4d0Q~-+ku9 zi4Wly_sPo0K(dycT}w(%#=`&ugsp<*qQZ$T#*f)4Po4grbyVQ<{{1tsVQs|DN!=Gw zkh=o9T|794Y5|WGn##`b4rc?^-qHiT!{s8BU3IeZ@-E=PP(Uhfpc)z)%E->v1x~PS zGo7hXE7xOm{L?5!cK_hCsswK}0frWxP$w~7T0phvjKBVt0*3+%0;hlNm-Szm`INKj?7lOT_?EgA-kI&rHRI?cM|v@! z4MML@fkan!M#kkMQ#rwl_hLq}tQNN4eN_?A&~)H>MaxJ34WsPCk|vAynwsPe6`M#{ zcBeEx?dvmoQ-Ax&X&tU-PoJ6+bg8yK3!QemQc~9~TN%9aU|j?nyALU|`W`;aPY8e* zRYOR3ac8^XR%v$K=>+i^AYJaNG^NqMeTrqjdFJ4+$&9Yy#WLefB-*d$D*4NSi7K*~k1t*L!Mj)Cm6{EPpr4^BvXGbis45@_S>Oi9xl4vwBO?Ns|^o!vd@I1yt zwoU8@vprhFV4{|i`pTor^iiBg`a}d5J!{a`s8=5oGbkr8 z-I6X+c%s%BOt#3|RoiqK>MW27;K^#!(fDkx29E8FS0P4C&HniNd2rsX zTNsYF2`~^IUnupaR+SU=MM)_oRL&nSI3QyMpl3PVP%Byt|;=*ON=+-8JjKB@M;taKZo ze6!GP!1;xxfMY;JBv)3y4r8iDVP~P9vLYr*VmRpaGQh`-OFM=PMtB8 z?jE$M)}oh|gVWZrFrpEO<@S60w?|tSEv>AgFu!>6ABA1o8cYc=JpGwQP`>e5AtoPp z4@=?RG(Cj2`zrda$8AIH3wXLA$!>n4dgCV*6?ch&j;7Vw7a(O0X>U*yNKzuV;mEI# zl#}uFAP7%BO-8#)c9iAuBCVMd?OD|Nv5~JG*mnMum*HW9+XFQ%EK+DtgVm2CJzhGS+Fj9B-VlY74pjE%|liij-^ky-jUFTFG|HXg@_CrtHgx#rari>6SR zpLQf2tD7Lvr=0|(Hb=W#qPU`Ma&E5Rh>_0kX4oA8onpR!B6jN$C%ez@`oFyBu zzt{^t60~s~k`)gN9lBCNcg&!dA&WiT+Ie-6ZVBUy`2+?cD^~;`>mNr~u6Ev%}Z*V;4z9=K!Hx6YKaU3Hk zsL?g&r0&E%IB)RI{{gX9YW9K0KmIq&?$N$Elvi832}S%Ce>;2o^EZx~8FuedP!L-4 z9K^Vpxs_KVBXm{IrD<1|Fc3_9yU8Vj-UW#A_vb~p2gW%0U8cf1J~5FE-W8%bf-^7| z0JZzXxhHjSq;67h)atz0Q09qR4+SRQ8nrY74S2C-j7F%Ay6o)Te&#Nb3vqT4M^G1{ z;hp^Cs#k8`xkAgd-AYOaDwrJ~T{1yd0ePabG; zkQdO5!ave|rpA^_VtJFaU%u69HA8mjoaDtq$|(ok&qKMtm5xtq7{hU?C|%~Uq=GJ~ z?hTd>4!K`KSWCDWHhSX_l$>f(J;h(`kaw1pjTaBc(}roXt!}e$y3D{u;d=;}$w-?Q z(<&2w|2|K(-ld3K-8vHF_~(TfogGjznxmf;_vMoJ`pu=5zI%yn&B?wQG2!)*=mWdh zGaX@i({eS0LpmMQj_J)^3orco!|rE@>ZpzI@bG|dN&f8>6to3IBEDlg=6ERV+7*ce zsoPcq;9++7aEa8z7ieY0mQsp90sMHdZm2C+bJcXl@F@ktMGEH$iA1u{kkKg^xB<2X z9y!$P=8@tnz88v*@4g1Mf=h8K1#U2WFEcn$P$8s>+4dIVgjf1N&*FMpvS~5WmYaOD3IsbREDwgD4Kv z2zZR-HFf?e76fcv`-36r*Q=k6r`g!YuCKdB`CqdcWU9Y&N8Wmfz9M#` zJcmX3P-qi^-~^1AnB$nGQ(1ik|C8{9->R! z-ZtkM#7zZ!F$e z4Q<(|CEY)%?I0l3)z`Pr+EP@17d}>nHFKjqJN}73c+JMfZRuv_1~yBWZ8=L2&ZWW3 z3=v^4hJsp?%-?*_&h9UGZi|up)w#0ScGt;amCRZJ1l4zZmxwZ*Zi=JS*MGaw@%I7VEE%6a^JEg* zX>l%21~}DST}(^kfi<~AYdZtYR@hB_`e(_E!SPWNdry0KkWxdeaWkR8Aj_pM`q)?5 zWKD9%>>EZo;5i2R$|FzZS}%wsEuCqJy?g({G`yDOWd*D)NWjXOn2}HrHOgL5s_mK$ zNn;N$2%?sR4MTB>0%ysf_fDY@kAXJAOKFw#2pn10)0ZH_wjaBMS{%w?d z{|CoP$=y}3*EkdU*NHcpDU}%WYp5;Oej_X3{Pg?xlW+^8ckjy6hp<#tzpx4WHGi<` zxzY0?y#mH{M!HC+eK@R$FZhGm?SqYh;M&Xc9=R(`Vk+N`ZTBey?x>W)!HCS(f*->C z_gAUmDT$tqc$rrBu_WLLa1b$kH|&=B?Gs& zzSw)Z{OxRH)vb!bZ>ZL_jVEahfPhwg!5R!@RSBo6a!c^WcW|lL?tvc}9?aRdXt+k9 zEo^e^e1%o#I_)sy_9v*U1%bgW$ys&{pCCa5e!$Bj=wgi1L<}qO`^c9q@nU z*SDgll#mvoyFh4XgUhg>^BBg9ZdHA*3t0uqn1xk-s9Wv#W_hvL`%kQGY+z&mwLdox zgaj|ZEzwy?_*PMI zfszQXGLnHs&VeN%wp&$+%n5ptFx^+@@HU^<6+U8gydhW@G)(JR@1UR~LHCwEepIjf zsktH*gC}ohaWV11dH9{lq;0U}5`+l$wN!7<3Xn&1zXaWq=tufH-sZ}tOR5Np#-^sN z?n)BIK(yH%5=gft$}+4^ zMvZ>A^C@_1tu4JdAg_jTl0Ky=}}aM3yo8X`f(fLqAJMCFfP z>u|r(t;{+#HD$3Z4-%XeFC*%9A75Py;GlI%@{4yWy)q;SFdyNF@loLv_|XXUEiVt9 z`5XY&z+wc}85+vl(12 zXf8IT+pa}iCw5VPaY)?hLprX>QOMNrEg7ibN?ICiWQ(_$fq4hNVDiV_lqVlLn6053 zm#j&q&;+CD%R(cC2$!z)`f7mP7#p=8tuW!i7h;oI3J!b<8YS?>(zQ6I3f$7C`UL~U zGbD(*7G9bCXKg*Z*ytiTHWK2YqV#IsSEd#HhJ#|IF{i!$nJz>0EqQnt1_ha8G7*Y6 zs&!3OifrlRIqn|Wu_{Pbp0f-vX;qkVD(~2K+ZZ zJVFS!gA1-P@&}4#sFSR+);}^qNJ#?wK>3H^ap+T%C|erpPK#x+v2{7vazimtiE|*F zF(M2zZJOO`iBtwUOns$MWab+TfrD1}AzZ=1e~FhxeHM32K|>=ECH97cwZ@powBz6Y z!u$>V0s@Z)2f2WiGnTK!#F(=D+m1Z5ADIe`b;0SJoCC2iH2$Zd`3ejD;{P@`cL65r z{QD!;_WynZqXz!-vy=Fc|Ni{rpBEvys9PE4-dZBqw&x4kU@1>!D{Sm SJ@<9u88Of`)v45SjQAf8l#)#V diff --git a/examples/industrial_data_pretraining/emotion2vec/demo.py b/examples/industrial_data_pretraining/emotion2vec/demo.py index f33dfee1f..bc1d9a248 100644 --- a/examples/industrial_data_pretraining/emotion2vec/demo.py +++ b/examples/industrial_data_pretraining/emotion2vec/demo.py @@ -6,8 +6,9 @@ from funasr import AutoModel # model="iic/emotion2vec_base" +# model="iic/emotion2vec_base_finetuned" model = AutoModel( - model="iic/emotion2vec_base_finetuned", + model="/Users/zhifu/Downloads/modelscope_models/emotion2vec_plus_seed", # vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", # vad_model_revision="master", # vad_kwargs={"max_single_segment_time": 2000}, diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py new file mode 100644 index 000000000..e4db533d5 --- /dev/null +++ b/funasr/bin/train_ds.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +# -*- encoding: utf-8 -*- + +import os +import sys +import torch +import torch.nn as nn +import hydra +import logging +import time +import argparse +from io import BytesIO + +from contextlib import nullcontext +import torch.distributed as dist + +from omegaconf import DictConfig, OmegaConf +from torch.cuda.amp import autocast, GradScaler +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.distributed.fsdp import FullyShardedDataParallel as FSDP +from torch.distributed.algorithms.join import Join +from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler +from funasr.train_utils.average_nbest_models import average_checkpoints + +from funasr.register import tables +from funasr.optimizers import optim_classes +from funasr.train_utils.trainer_ds import Trainer +from funasr.schedulers import scheduler_classes +from funasr.train_utils.initialize import initialize +from funasr.download.download_from_hub import download_model +from funasr.models.lora.utils import mark_only_lora_as_trainable +from funasr.train_utils.set_all_random_seed import set_all_random_seed +from funasr.train_utils.load_pretrained_model import load_pretrained_model +from funasr.utils.misc import prepare_model_dir +from funasr.train_utils.model_summary import model_summary +from funasr import AutoModel + +try: + import deepspeed +except: + deepspeed = None + + +@hydra.main(config_name=None, version_base=None) +def main_hydra(kwargs: DictConfig): + if kwargs.get("debug", False): + import pdb + + pdb.set_trace() + + assert "model" in kwargs + if "model_conf" not in kwargs: + logging.info("download models from model hub: {}".format(kwargs.get("hub", "ms"))) + kwargs = download_model(is_training=kwargs.get("is_training", True), **kwargs) + + main(**kwargs) + + +def main(**kwargs): + + # set random seed + set_all_random_seed(kwargs.get("seed", 0)) + torch.backends.cudnn.enabled = kwargs.get("cudnn_enabled", torch.backends.cudnn.enabled) + torch.backends.cudnn.benchmark = kwargs.get("cudnn_benchmark", torch.backends.cudnn.benchmark) + torch.backends.cudnn.deterministic = kwargs.get("cudnn_deterministic", True) + # open tf32 + torch.backends.cuda.matmul.allow_tf32 = kwargs.get("enable_tf32", True) + + rank = int(os.environ.get("RANK", 0)) + local_rank = int(os.environ.get("LOCAL_RANK", 0)) + world_size = int(os.environ.get("WORLD_SIZE", 1)) + + if local_rank == 0: + tables.print() + + use_ddp = world_size > 1 + use_fsdp = kwargs.get("use_fsdp", False) + use_deepspeed = kwargs.get("use_deepspeed", False) + if use_deepspeed: + logging.info(f"use_deepspeed: {use_deepspeed}") + deepspeed.init_distributed(dist_backend=kwargs.get("backend", "nccl")) + elif use_ddp or use_fsdp: + logging.info(f"use_ddp: {use_ddp}, use_fsdp: {use_fsdp}") + dist.init_process_group(backend=kwargs.get("backend", "nccl"), init_method="env://") + torch.cuda.set_device(local_rank) + + logging.info("Build model, frontend, tokenizer") + device = kwargs.get("device", "cuda") + kwargs["device"] = "cpu" + model = AutoModel(**kwargs) + + # save config.yaml + if rank == 0: + prepare_model_dir(**kwargs) + + # parse kwargs + kwargs = model.kwargs + kwargs["device"] = device + tokenizer = kwargs["tokenizer"] + frontend = kwargs["frontend"] + model = model.model + del kwargs["model"] + + # freeze_param + freeze_param = kwargs.get("freeze_param", None) + if freeze_param is not None: + if "," in freeze_param: + freeze_param = eval(freeze_param) + if not isinstance(freeze_param, (list, tuple)): + freeze_param = (freeze_param,) + logging.info("freeze_param is not None: %s", freeze_param) + for t in freeze_param: + for k, p in model.named_parameters(): + if k.startswith(t + ".") or k == t: + logging.info(f"Setting {k}.requires_grad = False") + p.requires_grad = False + if local_rank == 0: + logging.info(f"{model_summary(model)}") + + trainer = Trainer( + rank=rank, + local_rank=local_rank, + world_size=world_size, + use_ddp=use_ddp, + use_fsdp=use_fsdp, + device=kwargs["device"], + output_dir=kwargs.get("output_dir", "./exp"), + **kwargs.get("train_conf"), + ) + + model = trainer.warp_model(model) + + kwargs["device"] = next(model.parameters()).device + trainer.device = kwargs["device"] + + # optim + logging.info("Build optim") + optim = kwargs.get("optim", "adam") + assert optim in optim_classes + optim_class = optim_classes.get(optim) + optim = optim_class(model.parameters(), **kwargs.get("optim_conf")) + + # scheduler + logging.info("Build scheduler") + scheduler = kwargs.get("scheduler", "warmuplr") + assert scheduler in scheduler_classes + scheduler_class = scheduler_classes.get(scheduler) + scheduler = scheduler_class(optim, **kwargs.get("scheduler_conf")) + + if use_deepspeed: + args = OmegaConf.create({"deepspeed_config": kwargs.get("deepspeed_config", "")}) + model, optimizer, _, scheduler = deepspeed.initialize( + args=args, + model=model, + optimizer=optim, + lr_scheduler=scheduler, + model_parameters=model.parameters(), + ) + + # dataset + logging.info("Build dataloader") + dataloader_class = tables.dataloader_classes.get( + kwargs["dataset_conf"].get("dataloader", "DataloaderMapStyle") + ) + dataloader = dataloader_class(**kwargs) + # dataloader_tr, dataloader_val = dataloader_class(**kwargs) + + scaler = GradScaler(enabled=trainer.use_fp16) if trainer.use_fp16 else None + scaler = ShardedGradScaler(enabled=trainer.use_fp16) if trainer.use_fsdp else scaler + + trainer.resume_checkpoint( + model=model, + optim=optim, + scheduler=scheduler, + scaler=scaler, + ) + + tensorboard_dir = os.path.join(kwargs.get("output_dir"), "tensorboard") + os.makedirs(tensorboard_dir, exist_ok=True) + try: + from tensorboardX import SummaryWriter + + writer = SummaryWriter(tensorboard_dir) # if trainer.rank == 0 else None + except: + writer = None + + dataloader_tr, dataloader_val = None, None + for epoch in range(trainer.start_epoch, trainer.max_epoch): + time1 = time.perf_counter() + + for data_split_i in range(trainer.start_data_split_i, dataloader.data_split_num): + dataloader_tr, dataloader_val = dataloader.build_iter( + epoch, data_split_i=data_split_i, start_step=trainer.start_step + ) + + trainer.train_epoch( + model=model, + optim=optim, + scheduler=scheduler, + scaler=scaler, + dataloader_train=dataloader_tr, + dataloader_val=dataloader_val, + epoch=epoch, + writer=writer, + data_split_i=data_split_i, + data_split_num=dataloader.data_split_num, + start_step=trainer.start_step, + ) + trainer.start_step = 0 + + torch.cuda.empty_cache() + + trainer.start_data_split_i = 0 + trainer.validate_epoch( + model=model, dataloader_val=dataloader_val, epoch=epoch + 1, writer=writer + ) + scheduler.step() + trainer.step_in_epoch = 0 + trainer.save_checkpoint( + epoch + 1, model=model, optim=optim, scheduler=scheduler, scaler=scaler + ) + + time2 = time.perf_counter() + time_escaped = (time2 - time1) / 3600.0 + logging.info( + f"rank: {local_rank}, " + f"time_escaped_epoch: {time_escaped:.3f} hours, " + f"estimated to finish {trainer.max_epoch} " + f"epoch: {(trainer.max_epoch - epoch) * time_escaped:.3f} hours\n" + ) + trainer.train_acc_avg = 0.0 + trainer.train_loss_avg = 0.0 + + if trainer.rank == 0: + average_checkpoints(trainer.output_dir, trainer.avg_nbest_model) + + trainer.close() + + +if __name__ == "__main__": + main_hydra() diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py new file mode 100644 index 000000000..71889214d --- /dev/null +++ b/funasr/train_utils/trainer_ds.py @@ -0,0 +1,800 @@ +import math +import os +import time +import torch +import logging +from tqdm import tqdm +from datetime import datetime +import torch.distributed as dist +from torch.cuda.amp import autocast, GradScaler +from contextlib import nullcontext, contextmanager +from pathlib import Path +from torch.nn.parallel import DistributedDataParallel as DDP +from torch.distributed.fsdp import FullyShardedDataParallel as FSDP +from funasr.train_utils.device_funcs import to_device +from funasr.train_utils.recursive_op import recursive_average +from funasr.train_utils.average_nbest_models import average_checkpoints +from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler + +try: + import wandb +except: + wandb = None + + +@contextmanager +def maybe_autocast(enabled): + if enabled: + with autocast(): + yield + else: + yield + + +class Trainer: + """ + A simple trainer class for training a PyTorch model, saving checkpoints at the end of each epoch, + and optionally resuming from a saved checkpoint. + + Attributes: + max_epoch (int): Maximum number of epochs for training. + model (torch.nn.Module): The model to be trained. + optim (torch.optim.Optimizer): The optimizer to use for training. + scheduler (torch.optim.lr_scheduler._LRScheduler): The learning rate scheduler. + dataloader_train (torch.utils.data.DataLoader): DataLoader for the training dataset. + dataloader_val (torch.utils.data.DataLoader): DataLoader for the validation dataset. + output_dir (str): Directory where model checkpoints will be saved. + resume (str, optional): Path to a checkpoint to resume training from. + """ + + def __init__( + self, + rank=0, + local_rank=0, + world_size=1, + use_ddp: bool = False, + use_fsdp: bool = False, + use_fp16: bool = False, + use_deepspeed: bool = False, + output_dir: str = "./", + **kwargs, + ): + """ + Initializes the Trainer class with the model, optimizer, scheduler, dataloaders, and other settings. + + Args: + model (torch.nn.Module): The model to be trained. + optim (torch.optim.Optimizer): The optimizer to use for training. + scheduler (torch.optim.lr_scheduler._LRScheduler): The learning rate scheduler. + dataloader_train (torch.utils.data.DataLoader): The DataLoader for the training dataset. + dataloader_val (torch.utils.data.DataLoader): The DataLoader for the validation dataset. + **kwargs: Additional keyword arguments: + max_epoch (int): The maximum number of epochs for training. + output_dir (str): The directory where model checkpoints will be saved. Default is './'. + resume (str, optional): The file path to a checkpoint to resume training from. + """ + self.rank = kwargs.get("rank", 0) + self.local_rank = local_rank + self.world_size = world_size + self.use_ddp = use_ddp + self.use_fsdp = use_fsdp + self.use_deepspeed = use_deepspeed + self.device = kwargs.get("device", "cuda") + + self.output_dir = output_dir + if not os.path.exists(self.output_dir): + os.makedirs(self.output_dir, exist_ok=True) + self.resume = kwargs.get("resume", True) + self.start_epoch = 0 + self.max_epoch = kwargs.get("max_epoch", 100) + + # self.kwargs = kwargs + self.log_interval = kwargs.get("log_interval", 50) + self.batch_total = 0 + self.use_fp16 = use_fp16 + self.save_checkpoint_interval = kwargs.get("save_checkpoint_interval", 5000) + self.validate_interval = kwargs.get("validate_interval", 5000) + self.keep_nbest_models = kwargs.get("keep_nbest_models", 500) + self.avg_keep_nbest_models_type = kwargs.get("avg_keep_nbest_models_type", "acc") + self.avg_nbest_model = kwargs.get("avg_nbest_model", 10) + self.accum_grad = kwargs.get("accum_grad", 1) + self.grad_clip = kwargs.get("grad_clip", 10.0) + self.grad_clip_type = kwargs.get("grad_clip_type", 2.0) + + self.train_acc_avg = 0.0 + self.train_loss_avg = 0.0 + self.val_acc_avg = 0.0 + self.val_loss_avg = 0.0 + self.best_acc_idx = 0 + self.saved_ckpts = {} + self.step_or_epoch = -1 + self.best_step_or_epoch = "" + self.val_acc_step_or_eoch = {} + self.val_loss_step_or_eoch = {} + + self.reset_gpu_cache = kwargs.get("reset_gpu_cache", False) + self.start_data_split_i = 0 + self.start_step = 0 + self.step_in_epoch = 0 + self.use_wandb = kwargs.get("use_wandb", False) + if self.use_wandb: + wandb.login(key=kwargs.get("wandb_token")) + wandb.init( + config=kwargs, + project=kwargs.get("wandb_project", "my_project"), + entity=kwargs.get("wandb_team", "my_team"), + name=kwargs.get("wandb_exp_name", "my_exp"), + dir=output_dir, + job_type="training", + reinit=True, + ) + + def save_checkpoint( + self, + epoch, + step=None, + model=None, + optim=None, + scheduler=None, + scaler=None, + step_in_epoch=None, + **kwargs, + ): + """ + Saves a checkpoint containing the model's state, the optimizer's state, + and the scheduler's state at the end of the given epoch. This method is + intended to be called at the end of each epoch to save the training progress. + + Args: + epoch (int): The epoch number at which the checkpoint is being saved. + """ + + step_in_epoch = None if step is None else step_in_epoch + if self.rank == 0: + logging.info(f"Save checkpoint: {epoch}, rank: {self.local_rank}\n") + # self.step_or_epoch += 1 + state = { + "epoch": epoch, + "state_dict": model.state_dict(), + "optimizer": optim.state_dict(), + "scheduler": scheduler.state_dict(), + "saved_ckpts": self.saved_ckpts, + "val_acc_step_or_eoch": self.val_acc_step_or_eoch, + "val_loss_step_or_eoch": self.val_loss_step_or_eoch, + "best_step_or_epoch": self.best_step_or_epoch, + "avg_keep_nbest_models_type": self.avg_keep_nbest_models_type, + "step": step, + "step_in_epoch": step_in_epoch, + "data_split_i": kwargs.get("data_split_i", 0), + "data_split_num": kwargs.get("data_split_num", 1), + "batch_total": self.batch_total, + "train_loss_avg": kwargs.get("train_loss_avg", 0), + "train_acc_avg": kwargs.get("train_acc_avg", 0), + } + step = step_in_epoch + if hasattr(model, "module"): + state["state_dict"] = model.module.state_dict() + + if scaler: + state["scaler_state"] = scaler.state_dict() + # Create output directory if it does not exist + os.makedirs(self.output_dir, exist_ok=True) + if step is None: + ckpt_name = f"model.pt.ep{epoch}" + else: + ckpt_name = f"model.pt.ep{epoch}.{step}" + filename = os.path.join(self.output_dir, ckpt_name) + torch.save(state, filename) + + logging.info(f"\nCheckpoint saved to {filename}\n") + latest = Path(os.path.join(self.output_dir, f"model.pt")) + torch.save(state, latest) + if self.best_step_or_epoch == "": + self.best_step_or_epoch = ckpt_name + + if self.avg_keep_nbest_models_type == "acc": + if ( + self.val_acc_step_or_eoch[ckpt_name] + >= self.val_acc_step_or_eoch[self.best_step_or_epoch] + ): + self.best_step_or_epoch = ckpt_name + best_ckpt = Path(os.path.join(self.output_dir, f"model.pt.best")) + torch.save(state, best_ckpt) + logging.info( + f"Update best acc: {self.val_acc_step_or_eoch[self.best_step_or_epoch]:.4f}, {best_ckpt}" + ) + else: + logging.info( + f"No improvement in acc: {self.val_acc_step_or_eoch[ckpt_name]:.4f} < {self.val_acc_step_or_eoch[self.best_step_or_epoch]:.4f}, {os.path.join(self.output_dir, self.best_step_or_epoch)}" + ) + elif self.avg_keep_nbest_models_type == "loss": + if ( + self.val_loss_step_or_eoch[ckpt_name] + <= self.val_loss_step_or_eoch[self.best_step_or_epoch] + ): + self.best_step_or_epoch = ckpt_name + best_ckpt = Path(os.path.join(self.output_dir, f"model.pt.best")) + torch.save(state, best_ckpt) + logging.info( + f"Update best loss: {self.val_loss_step_or_eoch[self.best_step_or_epoch]:.4f}, {best_ckpt}" + ) + else: + logging.info( + f"No improvement in loss: {self.val_loss_step_or_eoch[ckpt_name]:.4f} > {self.val_loss_step_or_eoch[self.best_step_or_epoch]:.4f}, {os.path.join(self.output_dir, self.best_step_or_epoch)}" + ) + else: + print("Undo") + self.saved_ckpts[ckpt_name] = getattr( + self, f"val_{self.avg_keep_nbest_models_type}_step_or_eoch" + )[ckpt_name] + if self.keep_nbest_models > 0: + if len(self.saved_ckpts) > self.keep_nbest_models: + if self.avg_keep_nbest_models_type == "acc": + key = min(self.saved_ckpts, key=self.saved_ckpts.get) + else: + key = max(self.saved_ckpts, key=self.saved_ckpts.get) + if key in self.saved_ckpts: + del self.saved_ckpts[key] + filename = os.path.join(self.output_dir, key) + logging.info(f"Delete: {filename}") + if os.path.exists(filename): + os.remove(filename) + + if self.use_ddp or self.use_fsdp: + dist.barrier() + + def resume_checkpoint( + self, + model=None, + optim=None, + scheduler=None, + scaler=None, + ): + """ + Resumes training from a checkpoint at the given file path. + Loads the model's state, the optimizer's state, and the scheduler's state. + + Args: + resume_path (str): The file path to the checkpoint to resume from. + """ + if self.resume: + ckpt = os.path.join(self.output_dir, "model.pt") + if os.path.isfile(ckpt): + checkpoint = torch.load(ckpt, map_location="cpu") + self.start_epoch = checkpoint["epoch"] + # self.model.load_state_dict(checkpoint['state_dict']) + src_state = checkpoint["state_dict"] + dst_state = model.state_dict() + for k in dst_state.keys(): + if not k.startswith("module.") and "module." + k in src_state.keys(): + k_ddp = "module." + k + elif k.startswith("module.") and "module." + k not in src_state.keys(): + k_ddp = k.replace("module.", "", 1) + else: + k_ddp = k + if k_ddp in src_state.keys(): + dst_state[k] = src_state[k_ddp] + else: + print(f"Miss key in ckpt: model: {k}, ckpt: {k_ddp}") + + model.load_state_dict(dst_state) + optim.load_state_dict(checkpoint["optimizer"]) + scheduler.load_state_dict(checkpoint["scheduler"]) + if scaler is not None and "scaler_state" in checkpoint: + scaler.load_state_dict(checkpoint["scaler_state"]) + + self.saved_ckpts = checkpoint["saved_ckpts"] + self.val_acc_step_or_eoch = ( + checkpoint["val_acc_step_or_eoch"] + if "val_acc_step_or_eoch" in checkpoint + else {} + ) + self.val_loss_step_or_eoch = ( + checkpoint["val_loss_step_or_eoch"] + if "val_loss_step_or_eoch" in checkpoint + else {} + ) + self.best_step_or_epoch = ( + checkpoint["best_step_or_epoch"] if "best_step_or_epoch" in checkpoint else "" + ) + self.start_data_split_i = ( + checkpoint["data_split_i"] if "data_split_i" in checkpoint else 0 + ) + self.batch_total = checkpoint["batch_total"] if "batch_total" in checkpoint else 0 + self.start_step = checkpoint["step"] if "step" in checkpoint else 0 + self.start_step = 0 if self.start_step is None else self.start_step + self.step_in_epoch = ( + checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 + ) + self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch + print(checkpoint["train_acc_avg"]) + self.train_acc_avg = ( + checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 + ) + self.train_loss_avg = ( + checkpoint["train_loss_avg"] if "train_loss_avg" in checkpoint else 0 + ) + model.to(self.device) + print(f"Checkpoint loaded successfully from '{ckpt}'") + else: + print(f"No checkpoint found at '{ckpt}', does not resume status!") + + if self.use_ddp or self.use_fsdp: + dist.barrier() + + def train_epoch( + self, + model=None, + optim=None, + scheduler=None, + scaler=None, + dataloader_train=None, + dataloader_val=None, + epoch=None, + writer=None, + **kwargs, + ): + """ + Defines the training process for a single epoch with gradient accumulation. + Args: + epoch (int): The current epoch number. + """ + if self.use_ddp or self.use_fsdp: + dist.barrier() + logging.info(f"Train epoch: {epoch}, rank: {self.rank}\n") + model.train() + + # Set the number of steps for gradient accumulation + accum_grad = self.accum_grad + # Initialize the gradient accumulation + optim.zero_grad() + speed_stats = {} + + iterator_stop = torch.tensor(0).to(self.device) + + dataloader_train.batch_sampler.set_epoch(epoch) + time_beg = time.perf_counter() + time5 = time_beg + for batch_idx, batch in enumerate(dataloader_train): + if self.use_ddp or self.use_fsdp: + dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) + if iterator_stop > 0: + break + self.batch_total += 1 + self.step_in_epoch += 1 + time1 = time.perf_counter() + speed_stats["data_load"] = f"{time1-time_beg:0.3f}" + + batch = to_device(batch, self.device) + + my_context = nullcontext + if self.use_ddp or self.use_fsdp: + my_context = model.no_sync if batch_idx % accum_grad != 0 else my_context + with my_context(): + time2 = time.perf_counter() + loss_dict = {} + self.forward_step(model, batch, loss_dict=loss_dict) + + time3 = time.perf_counter() + speed_stats["forward_time"] = f"{time3 - time2:0.3f}" + self.backward_step(model, scaler, loss_dict=loss_dict) + + time4 = time.perf_counter() + speed_stats["backward_and_AllReaduce_time"] = f"{time4 - time3:0.3f}" + + # self.train_loss_avg = ( + # self.train_loss_avg * (batch_idx + kwargs.get("start_step", 0)) + # + loss.detach().cpu().item() + # ) / (batch_idx + kwargs.get("start_step", 0) + 1) + # if "acc" in stats: + # self.train_acc_avg = ( + # self.train_acc_avg * (batch_idx + kwargs.get("start_step", 0)) + # + stats["acc"].detach().cpu().item() + # ) / (batch_idx + kwargs.get("start_step", 0) + 1) + + self.update_step(model, optim, scheduler, scaler, loss_dict) + # Perform an optimizer step only after accumulating enough gradients + + if self.step_in_epoch % self.validate_interval == 0: + self.validate_epoch( + model=model, + dataloader_val=dataloader_val, + epoch=epoch, + writer=writer, + step=batch_idx + 1, + step_in_epoch=self.step_in_epoch, + ) + + if self.step_in_epoch % self.save_checkpoint_interval == 0: + self.save_checkpoint( + epoch, + model=model, + optim=optim, + scheduler=scheduler, + scaler=scaler, + step=batch_idx + 1, + step_in_epoch=self.step_in_epoch, + data_split_i=kwargs.get("data_split_i", 0), + data_split_num=kwargs.get("data_split_num", 1), + train_loss_avg=self.train_loss_avg, + train_acc_avg=self.train_acc_avg, + ) + + time_beg = time.perf_counter() + else: + if self.use_ddp or self.use_fsdp: + iterator_stop.fill_(1) + dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) + + if self.use_ddp or self.use_fsdp: + dist.barrier() + iterator_stop = torch.tensor(0).to(self.device) + + def forward_step(self, model, batch, loss_dict={}): + with maybe_autocast(self.use_fp16): + retval = model(**batch) + + if ( + self.reset_gpu_cache + and (torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024) > 70 + ): + torch.cuda.empty_cache() + + loss, stats, weight = retval + stats = {k: v for k, v in stats.items() if v is not None} + # if self.use_ddp or self.use_fsdp: + # # Apply weighted averaging for loss and stats + # loss = (loss * weight.type(loss.dtype)).sum() + # # if distributed, this method can also apply all_reduce() + # # stats, weight = recursive_average(stats, weight, distributed=True) + # if self.use_ddp or self.use_fsdp: + # dist.all_reduce(weight, op=dist.ReduceOp.SUM) + # # Now weight is summation over all workers + # loss /= weight.sum() # shape:[1] -> shape:[] + # # Multiply world_size because DistributedDataParallel + # # automatically normalizes the gradient by world_size. + # loss *= self.world_size + # loss *= self.world_size + # Scale the loss since we're not updating for every mini-batch + + loss_dict["loss"] = loss + loss_dict["stats"] = stats + loss_dict["weight"] = weight + + def backward_step(self, model, scaler, loss_dict={}): + loss = loss_dict["loss"] + + if self.use_deepspeed: + scaled_loss = model.backward(loss) + else: + loss = loss / self.accum_grad + if self.use_fp16: + scaler.scale(loss).backward() + else: + loss.backward() + + def update_step(self, model, optim, scheduler, scaler, batch_idx=0, loss_dict=loss_dict): + if (batch_idx + 1) % self.accum_grad == 0: + # Perform gradient clipping if it is set + if self.grad_clip > 0: + grad_norm = torch.nn.utils.clip_grad_norm_( + model.parameters(), + max_norm=self.grad_clip, + norm_type=self.grad_clip_type, + ) + if not torch.isfinite(grad_norm): + logging.warning(f"The grad norm is {grad_norm}. Skipping updating the model.") + optim.zero_grad() # Reset gradients + return + + # Execute an optimization step (update model parameters) + if self.use_ddp or self.use_fsdp: + dist.barrier() + if self.use_fp16: + scaler.step(optim) + scaler.update() + else: + optim.step() + scheduler.step() + # Clear gradients for the next accumulation stage + optim.zero_grad(set_to_none=True) + + if self.use_ddp or self.use_fsdp: + train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( + self.device + ) + train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( + self.device + ) + dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) + self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size + self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size + + total_time = f"{(time.perf_counter() - time5) / accum_grad:0.3f}" + time5 = time.perf_counter() + + speed_stats["optim_time"] = f"{time5 - time4:0.3f}" + + speed_stats["total_time"] = total_time + lr = scheduler.get_last_lr()[0] + batch_num_epoch = 1 + if hasattr(dataloader_train, "__len__"): + batch_num_epoch = len(dataloader_train) + self.log( + epoch, + batch_idx, + log_step=batch_idx + kwargs.get("start_step", 0), + step_in_epoch=self.step_in_epoch, + batch_num_epoch=batch_num_epoch, + lr=lr, + loss=loss.detach().cpu().item(), + speed_stats=speed_stats, + stats=stats, + writer=writer, + tag="train", + data_split_i=kwargs.get("data_split_i", 0), + data_split_num=kwargs.get("data_split_num", 1), + ) + + def validate_epoch( + self, + model=None, + dataloader_val=None, + epoch=None, + writer=None, + **kwargs, + ): + """ + Defines the validation process for a single epoch. + Should be implemented with the actual model validation steps. + + Args: + epoch (int): The current epoch number. + """ + if self.use_ddp or self.use_fsdp: + dist.barrier() + logging.info(f"Validate epoch: {epoch}, rank: {self.rank}\n") + model.eval() + + with torch.no_grad(): + + speed_stats = {} + time5 = time.perf_counter() + iterator_stop = torch.tensor(0).to(self.device) + dataloader_val.batch_sampler.set_epoch(epoch) + for batch_idx, batch in enumerate(dataloader_val): + if self.use_ddp or self.use_fsdp: + dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) + if iterator_stop > 0: + break + time1 = time.perf_counter() + speed_stats["data_load"] = f"{time1 - time5:0.3f}" + batch = to_device(batch, self.device) + time2 = time.perf_counter() + retval = model(**batch) + time3 = time.perf_counter() + speed_stats["forward_time"] = f"{time3 - time2:0.3f}" + loss, stats, weight = retval + stats = {k: v for k, v in stats.items() if v is not None} + if self.use_ddp or self.use_fsdp: + # Apply weighted averaging for loss and stats + loss = (loss * weight.type(loss.dtype)).sum() + # if distributed, this method can also apply all_reduce() + # stats, weight = recursive_average(stats, weight, distributed=True) + if self.use_ddp or self.use_fsdp: + dist.all_reduce(weight, op=dist.ReduceOp.SUM) + # Now weight is summation over all workers + loss /= weight.sum() # shape:[1] -> shape:[] + # Multiply world_size because DistributedDataParallel + # automatically normalizes the gradient by world_size. + loss *= self.world_size + # Scale the loss since we're not updating for every mini-batch + loss = loss + time4 = time.perf_counter() + + self.val_loss_avg = (self.val_loss_avg * batch_idx + loss.detach().cpu().item()) / ( + batch_idx + 1 + ) + if "acc" in stats: + self.val_acc_avg = ( + self.val_acc_avg * batch_idx + stats["acc"].detach().cpu().item() + ) / (batch_idx + 1) + if self.use_ddp or self.use_fsdp: + val_loss_avg = torch.tensor(self.val_loss_avg, dtype=torch.float32).to( + self.device + ) + val_acc_avg = torch.tensor(self.val_acc_avg, dtype=torch.float32).to( + self.device + ) + dist.all_reduce(val_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(val_acc_avg, op=dist.ReduceOp.SUM) + self.val_loss_avg = val_loss_avg.detach().cpu().item() / self.world_size + self.val_acc_avg = val_acc_avg.detach().cpu().item() / self.world_size + time5 = time.perf_counter() + batch_num_epoch = 1 + if hasattr(dataloader_val, "__len__"): + batch_num_epoch = len(dataloader_val) + self.log( + epoch, + batch_idx, + batch_num_epoch=batch_num_epoch, + lr=0.0, + loss=loss.detach().cpu().item(), + speed_stats=speed_stats, + stats=stats, + writer=writer, + tag="val", + ) + + else: + if self.use_ddp or self.use_fsdp: + iterator_stop.fill_(1) + dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) + + if kwargs.get("step_in_epoch", None) is None: + ckpt_name = f"model.pt.ep{epoch}" + else: + ckpt_name = f'model.pt.ep{epoch}.{kwargs.get("step_in_epoch")}' + self.val_acc_step_or_eoch[ckpt_name] = self.val_acc_avg + self.val_loss_step_or_eoch[ckpt_name] = self.val_loss_avg + model.train() + + if self.use_ddp or self.use_fsdp: + dist.barrier() + iterator_stop = torch.tensor(0).to(self.device) + + def log( + self, + epoch=0, + batch_idx=0, + step_in_epoch=0, + batch_num_epoch=-1, + lr=0.0, + loss=0.0, + speed_stats=None, + stats=None, + writer=None, + tag="train", + data_split_i=0, + data_split_num=1, + log_step=None, + **kwargs, + ): + + if (batch_idx + 1) % self.log_interval == 0: + batch_idx = log_step if log_step is not None else batch_idx + gpu_info = ( + "GPU, memory: usage: {:.3f} GB, " + "peak: {:.3f} GB, " + "cache: {:.3f} GB, " + "cache_peak: {:.3f} GB".format( + torch.cuda.memory_allocated() / 1024 / 1024 / 1024, + torch.cuda.max_memory_allocated() / 1024 / 1024 / 1024, + torch.cuda.memory_reserved() / 1024 / 1024 / 1024, + torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, + ) + ) + + loss_avg_epoch = getattr(self, f"{tag}_loss_avg") + acc_avg_epoch = getattr(self, f"{tag}_acc_avg") + description = ( + f"{tag}, " + f"rank: {self.rank}, " + f"epoch: {epoch}/{self.max_epoch}, " + f"data_slice: {data_split_i}/{data_split_num}, " + f"step_in_slice: {batch_idx + 1}/{batch_num_epoch}, step_in_epoch: {step_in_epoch}, total step: {self.batch_total}, " + f"(loss_avg_rank: {loss:.3f}), " + f"(loss_avg_slice: {loss_avg_epoch:.3f}), " + f"(ppl_avg_slice: {math.exp(loss_avg_epoch):.3e}), " + f"(acc_avg_slice: {acc_avg_epoch:.3f}), " + f"(lr: {lr:.3e}), " + f"{[(k, round(v.detach().cpu().item(), 3)) for k, v in stats.items()]}, " + f"{speed_stats}, " + f"{gpu_info}" + ) + logging.info(description) + + description_dict = { + f"rank{self.rank}_loss/{tag}": loss, + f"rank{self.rank}_lr/{tag}": lr, + } + + if writer is not None: + writer.add_scalar(f"rank{self.rank}_loss/{tag}", loss, self.batch_total) + writer.add_scalar(f"rank{self.rank}_lr/{tag}", lr, self.batch_total) + for key, var in stats.items(): + writer.add_scalar( + f"stats_rank{self.rank}_{key}/{tag}", var.item(), self.batch_total + ) + description_dict[f"stats_rank{self.rank}_{key}/{tag}"] = var.item() + for key, var in speed_stats.items(): + writer.add_scalar( + f"stats_rank{self.rank}_{key}/{tag}", eval(var), self.batch_total + ) + description_dict[f"stats_rank{self.rank}_{key}/{tag}"] = eval(var) + if self.use_wandb and wandb is not None: + wandb.log( + description_dict, + setp=self.batch_total, + ) + + def close(self, writer=None): + + if self.use_ddp or self.use_fsdp: + dist.barrier() + + if writer is not None: + writer.close() + + if self.use_ddp or self.use_fsdp: + torch.distributed.destroy_process_group() + + def warp_model(self, model, **kwargs): + + if self.use_deepspeed: + from deepspeed.runtime.zero.stage_1_and_2 import ( + estimate_zero2_model_states_mem_needs_all_live, + ) + from deepspeed.runtime.zero.stage3 import estimate_zero3_model_states_mem_needs_all_live + from deepspeed.utils.zero_to_fp32 import convert_zero_checkpoint_to_fp32_state_dict + + local_world_size = int(os.environ.get("LOCAL_WORLD_SIZE", 1)) + world_size = int(os.environ.get("WORLD_SIZE", 1)) + + # NOTE(xcsong): look in detail how the memory estimator API works: + # https://deepspeed.readthedocs.io/en/latest/memory.html#discussion + if int(os.environ.get("RANK", 0)) == 0: + logging.info("Estimating model states memory needs (zero2)...") + estimate_zero2_model_states_mem_needs_all_live( + model, + num_gpus_per_node=local_world_size, + num_nodes=world_size // local_world_size, + ) + logging.info("Estimating model states memory needs (zero3)...") + estimate_zero3_model_states_mem_needs_all_live( + model, + num_gpus_per_node=local_world_size, + num_nodes=world_size // local_world_size, + ) + device = None # Init device later + pass # Init DeepSpeed later + + elif self.use_ddp: + local_rank = int(os.environ.get("LOCAL_RANK", 0)) + model = model.cuda(local_rank) + model = DDP( + model, + device_ids=[local_rank], + find_unused_parameters=kwargs.get("train_conf", {}).get( + "find_unused_parameters", False + ), + ) + # elif self.use_fsdp: + # # model = FSDP(model).cuda(local_rank) + # + # def custom_auto_wrap_policy( + # module: nn.Module, + # recurse: bool, + # nonwrapped_numel: int, + # # Additional custom arguments + # min_num_params: int = int(1e8), + # ) -> bool: + # # 根据自定义逻辑决定是否包装模块 + # is_large = unwrapped_params >= min_num_params + # requires_grad_uniform = len({p.requires_grad for p in module.parameters()}) == 1 + # return is_large and requires_grad_uniform + # + # # Configure a custom `min_num_params` + # my_auto_wrap_policy = functools.partial(custom_auto_wrap_policy, min_num_params=int(1e5)) + # torch.cuda.set_device(local_rank) + # model = FSDP( + # model, + # auto_wrap_policy=custom_auto_wrap_policy, + # mixed_precision=None, + # device_id=torch.cuda.current_device(), + # ) + else: + model = model.to(device=kwargs.get("device", "cuda")) + + return model diff --git a/funasr/utils/misc.py b/funasr/utils/misc.py index 9f01955fa..4613cb316 100644 --- a/funasr/utils/misc.py +++ b/funasr/utils/misc.py @@ -70,14 +70,16 @@ def prepare_model_dir(**kwargs): yaml_file = os.path.join(kwargs.get("output_dir", "./"), "config.yaml") OmegaConf.save(config=kwargs, f=yaml_file) - print(kwargs) + logging.info(f"kwargs: {kwargs}") logging.info("config.yaml is saved to: %s", yaml_file) - # model_path = kwargs.get("model_path") - # if model_path is not None: - # config_json = os.path.join(model_path, "configuration.json") - # if os.path.exists(config_json): - # shutil.copy(config_json, os.path.join(kwargs.get("output_dir", "./"), "configuration.json")) + model_path = kwargs.get("model_path", None) + if model_path is not None: + config_json = os.path.join(model_path, "configuration.json") + if os.path.exists(config_json): + shutil.copy( + config_json, os.path.join(kwargs.get("output_dir", "./"), "configuration.json") + ) def extract_filename_without_extension(file_path): From 699b006ee5a6d0748fc9d37f7c068af7c98c2c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 14 May 2024 17:13:29 +0800 Subject: [PATCH 043/125] add --- examples/industrial_data_pretraining/emotion2vec/demo.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/industrial_data_pretraining/emotion2vec/demo.py b/examples/industrial_data_pretraining/emotion2vec/demo.py index bc1d9a248..99d96ae53 100644 --- a/examples/industrial_data_pretraining/emotion2vec/demo.py +++ b/examples/industrial_data_pretraining/emotion2vec/demo.py @@ -7,8 +7,12 @@ from funasr import AutoModel # model="iic/emotion2vec_base" # model="iic/emotion2vec_base_finetuned" +# model="iic/emotion2vec_plus_seed_modelscope" +# model="iic/emotion2vec_plus_base_modelscope" +model = "iic/emotion2vec_plus_large_modelscope" + model = AutoModel( - model="/Users/zhifu/Downloads/modelscope_models/emotion2vec_plus_seed", + model=model, # vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", # vad_model_revision="master", # vad_kwargs={"max_single_segment_time": 2000}, From 22025a68d9e3ece0767b5b30b13f985a769c143c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 14 May 2024 17:18:43 +0800 Subject: [PATCH 044/125] add --- examples/industrial_data_pretraining/sense_voice/demo.py | 1 + examples/industrial_data_pretraining/sense_voice/demo_fsmn.py | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/industrial_data_pretraining/sense_voice/demo.py b/examples/industrial_data_pretraining/sense_voice/demo.py index ed583f0f8..b3af796ba 100644 --- a/examples/industrial_data_pretraining/sense_voice/demo.py +++ b/examples/industrial_data_pretraining/sense_voice/demo.py @@ -21,6 +21,7 @@ DecodingOptions = { "language": "auto", "fp16": True, "gain_event": True, + "beam_size": 5, } res = model.generate(input=input_wav, batch_size_s=0, DecodingOptions=DecodingOptions) diff --git a/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py index e063e1fde..ce4bdf8a2 100644 --- a/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py +++ b/examples/industrial_data_pretraining/sense_voice/demo_fsmn.py @@ -21,6 +21,7 @@ DecodingOptions = { "language": "auto", "fp16": True, "gain_event": True, + "beam_size": 5, } res = model.generate(input=input_wav, batch_size_s=0, DecodingOptions=DecodingOptions, beam_size=5) From 2362a9a852fe9624f0562c947e1ef16da6eaa688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 15 May 2024 10:52:15 +0800 Subject: [PATCH 045/125] add --- examples/industrial_data_pretraining/emotion2vec/demo.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/industrial_data_pretraining/emotion2vec/demo.py b/examples/industrial_data_pretraining/emotion2vec/demo.py index 99d96ae53..71f69bb11 100644 --- a/examples/industrial_data_pretraining/emotion2vec/demo.py +++ b/examples/industrial_data_pretraining/emotion2vec/demo.py @@ -7,9 +7,9 @@ from funasr import AutoModel # model="iic/emotion2vec_base" # model="iic/emotion2vec_base_finetuned" -# model="iic/emotion2vec_plus_seed_modelscope" -# model="iic/emotion2vec_plus_base_modelscope" -model = "iic/emotion2vec_plus_large_modelscope" +# model="iic/emotion2vec_plus_seed" +# model="iic/emotion2vec_plus_base" +model = "iic/emotion2vec_plus_large" model = AutoModel( model=model, @@ -19,6 +19,7 @@ model = AutoModel( ) wav_file = f"{model.model_path}/example/test.wav" + res = model.generate( wav_file, output_dir="./outputs", granularity="utterance", extract_embedding=False ) From 3d269543bfd232a514ccfb5c382f235ebd5cb53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 15 May 2024 16:37:58 +0800 Subject: [PATCH 046/125] deepspeed --- examples/industrial_data_pretraining/sense_voice/demo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/industrial_data_pretraining/sense_voice/demo.py b/examples/industrial_data_pretraining/sense_voice/demo.py index b3af796ba..530399955 100644 --- a/examples/industrial_data_pretraining/sense_voice/demo.py +++ b/examples/industrial_data_pretraining/sense_voice/demo.py @@ -7,8 +7,8 @@ from funasr import AutoModel model = AutoModel( model="/Users/zhifu/Downloads/modelscope_models/SenseVoiceModelscope", - vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", - vad_kwargs={"max_single_segment_time": 30000}, + # vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", + # vad_kwargs={"max_single_segment_time": 30000}, ) From 0ef6f0813c4fbce20c83a1da829ff2aa08df2127 Mon Sep 17 00:00:00 2001 From: zhifu gao Date: Wed, 15 May 2024 19:02:00 +0800 Subject: [PATCH 047/125] update with main (#1731) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * c++ runtime adapt to 1.0 (#1724) * adapt vad runtime to 1.0 * add json * change yml name * add func LoadVocabFromJson * add token file for InitAsr * add token path for OfflineStream * add funcOpenYaml * add token file for InitPunc * add token file for stream * update punc-model * update funasr-wss-server * update runtime_sdk_download_tool.py * update docker list * Delete docs/images/wechat.png * Add files via upload * Emo2Vec限定选择的情感类别 (#1730) * 限定选择的情感类别 * 使用none来禁用情感标签输出 * 修改输出接口 * 使用unuse来禁用token --------- Co-authored-by: 常材 * bugfix * v1.0.27 * update docs * hf hub * Fix incorrect assignment of 'end' attribute to 'start' in sentences list comprehension (#1680) --------- Co-authored-by: Yabin Li Co-authored-by: gaochangfeng <54253717+gaochangfeng@users.noreply.github.com> Co-authored-by: 常材 Co-authored-by: nsdou <168500039+nsdou@users.noreply.github.com> --- README.md | 1 + README_zh.md | 1 + funasr/download/download_from_hub.py | 82 ++++++++++++++++++- funasr/download/name_maps_from_hub.py | 4 +- funasr/download/runtime_sdk_download_tool.py | 16 ++-- funasr/models/emotion2vec/model.py | 9 +- .../sense_voice/whisper_lib/decoding.py | 4 +- funasr/version.txt | 2 +- runtime/docs/SDK_advanced_guide_offline.md | 5 +- runtime/docs/SDK_advanced_guide_offline_en.md | 5 +- .../docs/SDK_advanced_guide_offline_en_zh.md | 5 +- runtime/docs/SDK_advanced_guide_offline_zh.md | 5 +- runtime/docs/SDK_advanced_guide_online.md | 5 +- runtime/docs/SDK_advanced_guide_online_zh.md | 5 +- runtime/docs/docker_offline_cpu_en_lists | 2 +- runtime/docs/docker_offline_cpu_zh_lists | 2 +- runtime/docs/docker_online_cpu_zh_lists | 2 +- runtime/onnxruntime/CMakeLists.txt | 12 +++ runtime/onnxruntime/include/com-define.h | 7 +- runtime/onnxruntime/include/model.h | 6 +- runtime/onnxruntime/include/punc-model.h | 2 +- .../onnxruntime/src/ct-transformer-online.cpp | 4 +- .../onnxruntime/src/ct-transformer-online.h | 2 +- runtime/onnxruntime/src/ct-transformer.cpp | 4 +- runtime/onnxruntime/src/ct-transformer.h | 2 +- runtime/onnxruntime/src/fsmn-vad.cpp | 2 +- runtime/onnxruntime/src/model.cpp | 8 +- runtime/onnxruntime/src/offline-stream.cpp | 11 ++- runtime/onnxruntime/src/paraformer.cpp | 16 ++-- runtime/onnxruntime/src/paraformer.h | 6 +- runtime/onnxruntime/src/phone-set.cpp | 21 ++++- runtime/onnxruntime/src/phone-set.h | 2 + runtime/onnxruntime/src/punc-model.cpp | 4 +- runtime/onnxruntime/src/tokenizer.cpp | 55 +++++++++++++ runtime/onnxruntime/src/tokenizer.h | 2 + runtime/onnxruntime/src/tpass-stream.cpp | 11 ++- runtime/onnxruntime/src/vocab.cpp | 21 ++++- runtime/onnxruntime/src/vocab.h | 2 + runtime/python/http/server.py | 2 +- runtime/quick_start.md | 8 +- runtime/quick_start_zh.md | 8 +- runtime/readme.md | 3 + runtime/readme_cn.md | 3 + .../websocket/bin/funasr-wss-server-2pass.cpp | 14 ++-- runtime/websocket/bin/funasr-wss-server.cpp | 12 +-- 45 files changed, 318 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 8b093bcf4..ba23f3fcd 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ ## What's new: +- 2024/05/15: Offline File Transcription Service 4.5, Offline File Transcription Service of English 1.6,Real-time Transcription Service 1.10 released,adapting to FunASR 1.0 model structure;([docs](runtime/readme.md)) - 2024/03/05:Added the Qwen-Audio and Qwen-Audio-Chat large-scale audio-text multimodal models, which have topped multiple audio domain leaderboards. These models support speech dialogue, [usage](examples/industrial_data_pretraining/qwen_audio). - 2024/03/05:Added support for the Whisper-large-v3 model, a multitasking model that can perform multilingual speech recognition, speech translation, and language identification. It can be downloaded from the[modelscope](examples/industrial_data_pretraining/whisper/demo.py), and [openai](examples/industrial_data_pretraining/whisper/demo_from_openai.py). - 2024/03/05: Offline File Transcription Service 4.4, Offline File Transcription Service of English 1.5,Real-time Transcription Service 1.9 released,docker image supports ARM64 platform, update modelscope;([docs](runtime/readme.md)) diff --git a/README_zh.md b/README_zh.md index 963469a43..44f92e63b 100644 --- a/README_zh.md +++ b/README_zh.md @@ -29,6 +29,7 @@ FunASR希望在语音识别的学术研究和工业应用之间架起一座桥 ## 最新动态 +- 2024/05/15: 中文离线文件转写服务 4.5、英文离线文件转写服务 1.6、中文实时语音听写服务 1.10 发布,适配FunASR 1.0模型结构;详细信息参阅([部署文档](runtime/readme_cn.md)) - 2024/03/05:新增加Qwen-Audio与Qwen-Audio-Chat音频文本模态大模型,在多个音频领域测试榜单刷榜,中支持语音对话,详细用法见 [示例](examples/industrial_data_pretraining/qwen_audio)。 - 2024/03/05:新增加Whisper-large-v3模型支持,多语言语音识别/翻译/语种识别,支持从 [modelscope](examples/industrial_data_pretraining/whisper/demo.py)仓库下载,也支持从 [openai](examples/industrial_data_pretraining/whisper/demo_from_openai.py)仓库下载模型。 - 2024/03/05: 中文离线文件转写服务 4.4、英文离线文件转写服务 1.5、中文实时语音听写服务 1.9 发布,docker镜像支持arm64平台,升级modelscope版本;详细信息参阅([部署文档](runtime/readme_cn.md)) diff --git a/funasr/download/download_from_hub.py b/funasr/download/download_from_hub.py index 43f5b67e6..075b13118 100644 --- a/funasr/download/download_from_hub.py +++ b/funasr/download/download_from_hub.py @@ -10,7 +10,7 @@ def download_model(**kwargs): if hub == "ms": kwargs = download_from_ms(**kwargs) elif hub == "hf": - pass + kwargs = download_from_hf(**kwargs) elif hub == "openai": model_or_path = kwargs.get("model") if os.path.exists(model_or_path): @@ -87,6 +87,67 @@ def download_from_ms(**kwargs): return kwargs +def download_from_hf(**kwargs): + model_or_path = kwargs.get("model") + if model_or_path in name_maps_hf: + model_or_path = name_maps_hf[model_or_path] + model_revision = kwargs.get("model_revision", "master") + if not os.path.exists(model_or_path) and "model_path" not in kwargs: + try: + model_or_path = get_or_download_model_dir_hf( + model_or_path, + model_revision, + is_training=kwargs.get("is_training"), + check_latest=kwargs.get("check_latest", True), + ) + except Exception as e: + print(f"Download: {model_or_path} failed!: {e}") + + kwargs["model_path"] = model_or_path if "model_path" not in kwargs else kwargs["model_path"] + + if os.path.exists(os.path.join(model_or_path, "configuration.json")): + with open(os.path.join(model_or_path, "configuration.json"), "r", encoding="utf-8") as f: + conf_json = json.load(f) + + cfg = {} + if "file_path_metas" in conf_json: + add_file_root_path(model_or_path, conf_json["file_path_metas"], cfg) + cfg.update(kwargs) + if "config" in cfg: + config = OmegaConf.load(cfg["config"]) + kwargs = OmegaConf.merge(config, cfg) + kwargs["model"] = config["model"] + elif os.path.exists(os.path.join(model_or_path, "config.yaml")) and os.path.exists( + os.path.join(model_or_path, "model.pt") + ): + config = OmegaConf.load(os.path.join(model_or_path, "config.yaml")) + kwargs = OmegaConf.merge(config, kwargs) + init_param = os.path.join(model_or_path, "model.pb") + kwargs["init_param"] = init_param + if os.path.exists(os.path.join(model_or_path, "tokens.txt")): + kwargs["tokenizer_conf"]["token_list"] = os.path.join(model_or_path, "tokens.txt") + if os.path.exists(os.path.join(model_or_path, "tokens.json")): + kwargs["tokenizer_conf"]["token_list"] = os.path.join(model_or_path, "tokens.json") + if os.path.exists(os.path.join(model_or_path, "seg_dict")): + kwargs["tokenizer_conf"]["seg_dict"] = os.path.join(model_or_path, "seg_dict") + if os.path.exists(os.path.join(model_or_path, "bpe.model")): + kwargs["tokenizer_conf"]["bpemodel"] = os.path.join(model_or_path, "bpe.model") + kwargs["model"] = config["model"] + if os.path.exists(os.path.join(model_or_path, "am.mvn")): + kwargs["frontend_conf"]["cmvn_file"] = os.path.join(model_or_path, "am.mvn") + if os.path.exists(os.path.join(model_or_path, "jieba_usr_dict")): + kwargs["jieba_usr_dict"] = os.path.join(model_or_path, "jieba_usr_dict") + if isinstance(kwargs, DictConfig): + kwargs = OmegaConf.to_container(kwargs, resolve=True) + if os.path.exists(os.path.join(model_or_path, "requirements.txt")): + requirements = os.path.join(model_or_path, "requirements.txt") + print(f"Detect model requirements, begin to install it: {requirements}") + from funasr.utils.install_model_requirements import install_requirements + + install_requirements(requirements) + return kwargs + + def add_file_root_path(model_or_path: str, file_path_metas: dict, cfg={}): if isinstance(file_path_metas, dict): @@ -136,3 +197,22 @@ def get_or_download_model_dir( model, revision=model_revision, user_agent={Invoke.KEY: key, ThirdParty.KEY: "funasr"} ) return model_cache_dir + + +def get_or_download_model_dir_hf( + model, + model_revision=None, + is_training=False, + check_latest=True, +): + """Get local model directory or download model if necessary. + + Args: + model (str): model id or path to local model directory. + model_revision (str, optional): model version number. + :param is_training: + """ + from huggingface_hub import snapshot_download + + model_cache_dir = snapshot_download(model) + return model_cache_dir diff --git a/funasr/download/name_maps_from_hub.py b/funasr/download/name_maps_from_hub.py index 87a89fcc6..3bb25a7ca 100644 --- a/funasr/download/name_maps_from_hub.py +++ b/funasr/download/name_maps_from_hub.py @@ -14,7 +14,9 @@ name_maps_ms = { "Qwen-Audio": "Qwen/Qwen-Audio", } -name_maps_hf = {} +name_maps_hf = { + "": "", +} name_maps_openai = { "Whisper-tiny.en": "tiny.en", diff --git a/funasr/download/runtime_sdk_download_tool.py b/funasr/download/runtime_sdk_download_tool.py index 7776a7116..96c67355e 100644 --- a/funasr/download/runtime_sdk_download_tool.py +++ b/funasr/download/runtime_sdk_download_tool.py @@ -20,6 +20,7 @@ def main(): args = parser.parse_args() model_dir = args.model_name + output_dir = args.model_name if not Path(args.model_name).exists(): from modelscope.hub.snapshot_download import snapshot_download @@ -27,6 +28,7 @@ def main(): model_dir = snapshot_download( args.model_name, cache_dir=args.export_dir, revision=args.model_revision ) + output_dir = os.path.join(args.export_dir, args.model_name) except: raise "model_dir must be model_name in modelscope or local path downloaded from modelscope, but is {}".format( model_dir @@ -37,15 +39,13 @@ def main(): model_file = os.path.join(model_dir, "model_quant.onnx") if not os.path.exists(model_file): print(".onnx is not exist, begin to export onnx") - from funasr.bin.export_model import ModelExport + from funasr import AutoModel - export_model = ModelExport( - cache_dir=args.export_dir, - onnx=True, - device="cpu", - quant=args.quantize, - ) - export_model.export(model_dir) + export_model = AutoModel(model=args.model_name, output_dir=output_dir) + export_model.export( + quantize=args.quantize, + type=args.type, + ) if __name__ == "__main__": diff --git a/funasr/models/emotion2vec/model.py b/funasr/models/emotion2vec/model.py index 48b87160f..d18e1844c 100644 --- a/funasr/models/emotion2vec/model.py +++ b/funasr/models/emotion2vec/model.py @@ -249,10 +249,17 @@ class Emotion2vec(torch.nn.Module): if self.proj: x = x.mean(dim=1) x = self.proj(x) + for idx, lab in enumerate(labels): + x[:,idx] = -np.inf if lab.startswith("unuse") else x[:,idx] x = torch.softmax(x, dim=-1) scores = x[0].tolist() - result_i = {"key": key[i], "labels": labels, "scores": scores} + select_label = [lb for lb in labels if not lb.startswith("unuse")] + select_score = [scores[idx] for idx, lb in enumerate(labels) if not lb.startswith("unuse")] + + # result_i = {"key": key[i], "labels": labels, "scores": scores} + result_i = {"key": key[i], "labels": select_label, "scores": select_score} + if extract_embedding: result_i["feats"] = feats results.append(result_i) diff --git a/funasr/models/sense_voice/whisper_lib/decoding.py b/funasr/models/sense_voice/whisper_lib/decoding.py index 609d6a607..a468efaa9 100644 --- a/funasr/models/sense_voice/whisper_lib/decoding.py +++ b/funasr/models/sense_voice/whisper_lib/decoding.py @@ -63,8 +63,8 @@ def detect_language( else: x = x.to(mel.device) # FIX(funasr): sense vocie - # logits = model.logits(x[:, :-1], mel)[:, -1] - logits = model.logits(x[:, :], mel)[:, -1] + logits = model.logits(x[:, :-1], mel)[:, -1] + # logits = model.logits(x[:, :], mel)[:, -1] # collect detected languages; suppress all non-language tokens mask = torch.ones(logits.shape[-1], dtype=torch.bool) diff --git a/funasr/version.txt b/funasr/version.txt index 7717884db..3f11ef630 100644 --- a/funasr/version.txt +++ b/funasr/version.txt @@ -1 +1 @@ -1.0.26 \ No newline at end of file +1.0.27 \ No newline at end of file diff --git a/runtime/docs/SDK_advanced_guide_offline.md b/runtime/docs/SDK_advanced_guide_offline.md index d975b53d9..799727f8f 100644 --- a/runtime/docs/SDK_advanced_guide_offline.md +++ b/runtime/docs/SDK_advanced_guide_offline.md @@ -12,6 +12,7 @@ This document serves as a development guide for the FunASR offline file transcri | TIME | INFO | IMAGE VERSION | IMAGE ID | |------------|----------------------------------------------------------------------------------------------------------------------------------|------------------------------|--------------| +| 2024.05.15 | Adapting to FunASR 1.0 model structure | funasr-runtime-sdk-cpu-0.4.5 | 058b9882ae67 | | 2024.03.05 | docker image supports ARM64 platform, update modelscope | funasr-runtime-sdk-cpu-0.4.4 | 2dc87b86dc49 | | 2024.01.25 | Optimized the VAD (Voice Activity Detection) data processing method, significantly reducing peak memory usage; memory leak optimization| funasr-runtime-sdk-cpu-0.4.2 | befdc7b179ed | | 2024.01.08 | optimized format sentence-level timestamps | funasr-runtime-sdk-cpu-0.4.1 | 0250f8ef981b | @@ -34,9 +35,9 @@ If you do not have Docker installed, please refer to [Docker Installation](https ### Pulling and launching images Use the following command to pull and launch the Docker image for the FunASR runtime-SDK: ```shell -sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 +sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 -sudo docker run -p 10095:10095 -it --privileged=true -v /root:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 +sudo docker run -p 10095:10095 -it --privileged=true -v /root:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 ``` Introduction to command parameters: diff --git a/runtime/docs/SDK_advanced_guide_offline_en.md b/runtime/docs/SDK_advanced_guide_offline_en.md index 220c10c68..4f61416a3 100644 --- a/runtime/docs/SDK_advanced_guide_offline_en.md +++ b/runtime/docs/SDK_advanced_guide_offline_en.md @@ -6,6 +6,7 @@ This document serves as a development guide for the FunASR offline file transcri | TIME | INFO | IMAGE VERSION | IMAGE ID | |------------|-----------------------------------------|---------------------------------|--------------| +| 2024.05.15 | Adapting to FunASR 1.0 model structure | funasr-runtime-sdk-en-cpu-0.1.6 | 84d781d07997 | | 2024.03.05 | docker image supports ARM64 platform, update modelscope | funasr-runtime-sdk-en-cpu-0.1.5 | 7cca2abc5901 | | 2024.01.25 | Optimized the VAD (Voice Activity Detection) data processing method, significantly reducing peak memory usage; memory leak optimization| funasr-runtime-sdk-en-cpu-0.1.3 | c00f9ce7a195 | | 2024.01.03 | fixed known crash issues as well as memory leak problems | funasr-runtime-sdk-en-cpu-0.1.2 | 0cdd9f4a4bb5 | @@ -24,9 +25,9 @@ If you do not have Docker installed, please refer to [Docker Installation](https ### Pulling and launching images Use the following command to pull and launch the Docker image for the FunASR runtime-SDK: ```shell -sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.5 +sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.6 -sudo docker run -p 10097:10095 -it --privileged=true -v /root:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.5 +sudo docker run -p 10097:10095 -it --privileged=true -v /root:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.6 ``` Introduction to command parameters: ```text diff --git a/runtime/docs/SDK_advanced_guide_offline_en_zh.md b/runtime/docs/SDK_advanced_guide_offline_en_zh.md index b1ce1ee5d..3d6534312 100644 --- a/runtime/docs/SDK_advanced_guide_offline_en_zh.md +++ b/runtime/docs/SDK_advanced_guide_offline_en_zh.md @@ -6,6 +6,7 @@ FunASR提供可一键本地或者云端服务器部署的英文离线文件转 | 时间 | 详情 | 镜像版本 | 镜像ID | |------------|---------------|---------------------------------|--------------| +| 2024.05.15 | 适配FunASR 1.0模型结构 | funasr-runtime-sdk-en-cpu-0.1.6 | 84d781d07997 | | 2024.03.05 | docker镜像支持arm64平台,升级modelscope版本 | funasr-runtime-sdk-en-cpu-0.1.5 | 7cca2abc5901 | | 2024.01.25 | 优化vad数据处理方式,大幅降低峰值内存占用;内存泄漏优化 | funasr-runtime-sdk-en-cpu-0.1.3 | c00f9ce7a195 | | 2024.01.03 | 修复已知的crash问题及内存泄漏问题 | funasr-runtime-sdk-en-cpu-0.1.2 | 0cdd9f4a4bb5 | @@ -39,11 +40,11 @@ docker安装失败请参考 [Docker Installation](https://alibaba-damo-academy.g 通过下述命令拉取并启动FunASR runtime-SDK的docker镜像: ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.5 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.6 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10097:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.5 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-en-cpu-0.1.6 ``` ### 服务端启动 diff --git a/runtime/docs/SDK_advanced_guide_offline_zh.md b/runtime/docs/SDK_advanced_guide_offline_zh.md index ef4cfd23e..1cecb8881 100644 --- a/runtime/docs/SDK_advanced_guide_offline_zh.md +++ b/runtime/docs/SDK_advanced_guide_offline_zh.md @@ -10,6 +10,7 @@ FunASR离线文件转写软件包,提供了一款功能强大的语音离线 | 时间 | 详情 | 镜像版本 | 镜像ID | |------------|---------------------------------------------------|------------------------------|--------------| +| 2024.05.15 | 适配FunASR 1.0模型结构 | funasr-runtime-sdk-cpu-0.4.5 | 058b9882ae67 | | 2024.03.05 | docker镜像支持arm64平台,升级modelscope版本 | funasr-runtime-sdk-cpu-0.4.4 | 2dc87b86dc49 | | 2024.01.25 | 优化vad数据处理方式,大幅降低峰值内存占用;内存泄漏优化| funasr-runtime-sdk-cpu-0.4.2 | befdc7b179ed | | 2024.01.08 | 优化句子级时间戳json格式 | funasr-runtime-sdk-cpu-0.4.1 | 0250f8ef981b | @@ -48,11 +49,11 @@ docker安装失败请参考 [Docker Installation](https://alibaba-damo-academy.g ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10095:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 ``` ### 服务端启动 diff --git a/runtime/docs/SDK_advanced_guide_online.md b/runtime/docs/SDK_advanced_guide_online.md index 34b601c31..be9e5e8e8 100644 --- a/runtime/docs/SDK_advanced_guide_online.md +++ b/runtime/docs/SDK_advanced_guide_online.md @@ -8,6 +8,7 @@ FunASR Real-time Speech Recognition Software Package integrates real-time versio | TIME | INFO | IMAGE VERSION | IMAGE ID | |------------|-------------------------------------------------------------------------------------|-------------------------------------|--------------| +| 2024.05.15 | Adapting to FunASR 1.0 model structure | funasr-runtime-sdk-online-cpu-0.1.10 | 1c2adfcff84d | | 2024.03.05 | docker image supports ARM64 platform, update modelscope | funasr-runtime-sdk-online-cpu-0.1.9 | 4a875e08c7a2 | | 2024.01.25 | Optimization of the client-side | funasr-runtime-sdk-online-cpu-0.1.7 | 2aa23805572e | | 2024.01.03 | The 2pass-offline mode supports Ngram language model decoding and WFST hotwords, while also addressing known crash issues and memory leak problems | funasr-runtime-sdk-online-cpu-0.1.6 | f99925110d27 | @@ -29,9 +30,9 @@ If you do not have Docker installed, please refer to [Docker Installation](https ### Pull Docker Image Use the following command to pull and start the FunASR software package docker image: ```shell -sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 +sudo docker pull registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 mkdir -p ./funasr-runtime-resources/models -sudo docker run -p 10096:10095 -it --privileged=true -v $PWD/funasr-runtime-resources/models:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 +sudo docker run -p 10096:10095 -it --privileged=true -v $PWD/funasr-runtime-resources/models:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 ``` ### Launching the Server diff --git a/runtime/docs/SDK_advanced_guide_online_zh.md b/runtime/docs/SDK_advanced_guide_online_zh.md index 4b72e6d31..26ca4bcb3 100644 --- a/runtime/docs/SDK_advanced_guide_online_zh.md +++ b/runtime/docs/SDK_advanced_guide_online_zh.md @@ -12,6 +12,7 @@ FunASR实时语音听写软件包,集成了实时版本的语音端点检测 | 时间 | 详情 | 镜像版本 | 镜像ID | |:-----------|:----------------------------------|--------------------------------------|--------------| +| 2024.05.15 | 适配FunASR 1.0模型结构 | funasr-runtime-sdk-online-cpu-0.1.10 | 1c2adfcff84d | | 2024.03.05 | docker镜像支持arm64平台,升级modelscope版本 | funasr-runtime-sdk-online-cpu-0.1.9 | 4a875e08c7a2 | | 2024.01.25 | 客户端优化| funasr-runtime-sdk-online-cpu-0.1.7 | 2aa23805572e | | 2024.01.03 | 2pass-offline模式支持Ngram语言模型解码、wfst热词,同时修复已知的crash问题及内存泄漏问题 | funasr-runtime-sdk-online-cpu-0.1.6 | f99925110d27 | @@ -38,11 +39,11 @@ docker安装失败请参考 [Docker Installation](https://alibaba-damo-academy.g ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10096:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 ``` ### 服务端启动 diff --git a/runtime/docs/docker_offline_cpu_en_lists b/runtime/docs/docker_offline_cpu_en_lists index 52b14a884..40e5852df 100644 --- a/runtime/docs/docker_offline_cpu_en_lists +++ b/runtime/docs/docker_offline_cpu_en_lists @@ -1,7 +1,7 @@ DOCKER: + funasr-runtime-sdk-en-cpu-0.1.6 funasr-runtime-sdk-en-cpu-0.1.5 funasr-runtime-sdk-en-cpu-0.1.4 - funasr-runtime-sdk-en-cpu-0.1.3 DEFAULT_ASR_MODEL: damo/speech_paraformer-large_asr_nat-en-16k-common-vocab10020-onnx DEFAULT_VAD_MODEL: diff --git a/runtime/docs/docker_offline_cpu_zh_lists b/runtime/docs/docker_offline_cpu_zh_lists index ccd5d95db..e3d9efcf7 100644 --- a/runtime/docs/docker_offline_cpu_zh_lists +++ b/runtime/docs/docker_offline_cpu_zh_lists @@ -1,5 +1,5 @@ DOCKER: - funasr-runtime-sdk-cpu-0.4.4 + funasr-runtime-sdk-cpu-0.4.5 funasr-runtime-sdk-cpu-0.3.0 funasr-runtime-sdk-cpu-0.2.2 DEFAULT_ASR_MODEL: diff --git a/runtime/docs/docker_online_cpu_zh_lists b/runtime/docs/docker_online_cpu_zh_lists index c4ac16b64..4cb5ca045 100644 --- a/runtime/docs/docker_online_cpu_zh_lists +++ b/runtime/docs/docker_online_cpu_zh_lists @@ -1,7 +1,7 @@ DOCKER: + funasr-runtime-sdk-online-cpu-0.1.10 funasr-runtime-sdk-online-cpu-0.1.9 funasr-runtime-sdk-online-cpu-0.1.8 - funasr-runtime-sdk-online-cpu-0.1.7 DEFAULT_ASR_MODEL: damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx diff --git a/runtime/onnxruntime/CMakeLists.txt b/runtime/onnxruntime/CMakeLists.txt index 3450be78a..d8e623e1d 100644 --- a/runtime/onnxruntime/CMakeLists.txt +++ b/runtime/onnxruntime/CMakeLists.txt @@ -18,6 +18,17 @@ else() message("Little endian system") endif() +# json +include(FetchContent) +if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third_party/json/ChangeLog.md ) +FetchContent_Declare(json + URL https://github.com/nlohmann/json/archive/refs/tags/v3.11.2.tar.gz +SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/json +) + +FetchContent_MakeAvailable(json) +endif() + # for onnxruntime IF(WIN32) file(REMOVE ${PROJECT_SOURCE_DIR}/third_party/glog/src/config.h @@ -36,6 +47,7 @@ include_directories(${PROJECT_SOURCE_DIR}/third_party/yaml-cpp/include) include_directories(${PROJECT_SOURCE_DIR}/third_party/jieba/include) include_directories(${PROJECT_SOURCE_DIR}/third_party/jieba/include/limonp/include) include_directories(${PROJECT_SOURCE_DIR}/third_party/kaldi) +include_directories(${PROJECT_SOURCE_DIR}/third_party/json/include) if(ENABLE_GLOG) include_directories(${PROJECT_SOURCE_DIR}/third_party/glog/src) diff --git a/runtime/onnxruntime/include/com-define.h b/runtime/onnxruntime/include/com-define.h index 9cb1f2c96..d4edd5bc5 100644 --- a/runtime/onnxruntime/include/com-define.h +++ b/runtime/onnxruntime/include/com-define.h @@ -49,13 +49,14 @@ namespace funasr { // hotword embedding compile model #define MODEL_EB_NAME "model_eb.onnx" #define QUANT_MODEL_NAME "model_quant.onnx" -#define VAD_CMVN_NAME "vad.mvn" -#define VAD_CONFIG_NAME "vad.yaml" +#define VAD_CMVN_NAME "am.mvn" +#define VAD_CONFIG_NAME "config.yaml" #define AM_CMVN_NAME "am.mvn" #define AM_CONFIG_NAME "config.yaml" #define LM_CONFIG_NAME "config.yaml" -#define PUNC_CONFIG_NAME "punc.yaml" +#define PUNC_CONFIG_NAME "config.yaml" #define MODEL_SEG_DICT "seg_dict" +#define TOKEN_PATH "tokens.json" #define HOTWORD "hotword" // #define NN_HOTWORD "nn-hotword" diff --git a/runtime/onnxruntime/include/model.h b/runtime/onnxruntime/include/model.h index 33caec806..f5c4027d2 100644 --- a/runtime/onnxruntime/include/model.h +++ b/runtime/onnxruntime/include/model.h @@ -12,9 +12,9 @@ class Model { virtual void StartUtterance() = 0; virtual void EndUtterance() = 0; virtual void Reset() = 0; - virtual void InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){}; - virtual void InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){}; - virtual void InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){}; + virtual void InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){}; + virtual void InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){}; + virtual void InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){}; virtual void InitLm(const std::string &lm_file, const std::string &lm_config, const std::string &lex_file){}; virtual void InitFstDecoder(){}; virtual std::string Forward(float *din, int len, bool input_finished, const std::vector> &hw_emb={{0.0}}, void* wfst_decoder=nullptr){return "";}; diff --git a/runtime/onnxruntime/include/punc-model.h b/runtime/onnxruntime/include/punc-model.h index 214c7700a..3cec2c1cf 100644 --- a/runtime/onnxruntime/include/punc-model.h +++ b/runtime/onnxruntime/include/punc-model.h @@ -11,7 +11,7 @@ namespace funasr { class PuncModel { public: virtual ~PuncModel(){}; - virtual void InitPunc(const std::string &punc_model, const std::string &punc_config, int thread_num)=0; + virtual void InitPunc(const std::string &punc_model, const std::string &punc_config, const std::string &token_file, int thread_num)=0; virtual std::string AddPunc(const char* sz_input, std::string language="zh-cn"){return "";}; virtual std::string AddPunc(const char* sz_input, std::vector& arr_cache, std::string language="zh-cn"){return "";}; }; diff --git a/runtime/onnxruntime/src/ct-transformer-online.cpp b/runtime/onnxruntime/src/ct-transformer-online.cpp index 4e9136ed4..92fe41e96 100644 --- a/runtime/onnxruntime/src/ct-transformer-online.cpp +++ b/runtime/onnxruntime/src/ct-transformer-online.cpp @@ -11,7 +11,7 @@ CTTransformerOnline::CTTransformerOnline() { } -void CTTransformerOnline::InitPunc(const std::string &punc_model, const std::string &punc_config, int thread_num){ +void CTTransformerOnline::InitPunc(const std::string &punc_model, const std::string &punc_config, const std::string &token_file, int thread_num){ session_options.SetIntraOpNumThreads(thread_num); session_options.SetGraphOptimizationLevel(ORT_ENABLE_ALL); session_options.DisableCpuMemArena(); @@ -43,7 +43,7 @@ void CTTransformerOnline::InitPunc(const std::string &punc_model, const std::str for (auto& item : m_strOutputNames) m_szOutputNames.push_back(item.c_str()); - m_tokenizer.OpenYaml(punc_config.c_str()); + m_tokenizer.OpenYaml(punc_config.c_str(), token_file.c_str()); } CTTransformerOnline::~CTTransformerOnline() diff --git a/runtime/onnxruntime/src/ct-transformer-online.h b/runtime/onnxruntime/src/ct-transformer-online.h index ea7edb7fa..13f40a0c1 100644 --- a/runtime/onnxruntime/src/ct-transformer-online.h +++ b/runtime/onnxruntime/src/ct-transformer-online.h @@ -26,7 +26,7 @@ private: public: CTTransformerOnline(); - void InitPunc(const std::string &punc_model, const std::string &punc_config, int thread_num); + void InitPunc(const std::string &punc_model, const std::string &punc_config, const std::string &token_file, int thread_num); ~CTTransformerOnline(); vector Infer(vector input_data, int nCacheSize); string AddPunc(const char* sz_input, vector &arr_cache, std::string language="zh-cn"); diff --git a/runtime/onnxruntime/src/ct-transformer.cpp b/runtime/onnxruntime/src/ct-transformer.cpp index 8f8d95310..d1a7813b1 100644 --- a/runtime/onnxruntime/src/ct-transformer.cpp +++ b/runtime/onnxruntime/src/ct-transformer.cpp @@ -11,7 +11,7 @@ CTTransformer::CTTransformer() { } -void CTTransformer::InitPunc(const std::string &punc_model, const std::string &punc_config, int thread_num){ +void CTTransformer::InitPunc(const std::string &punc_model, const std::string &punc_config, const std::string &token_file, int thread_num){ session_options.SetIntraOpNumThreads(thread_num); session_options.SetGraphOptimizationLevel(ORT_ENABLE_ALL); session_options.DisableCpuMemArena(); @@ -39,7 +39,7 @@ void CTTransformer::InitPunc(const std::string &punc_model, const std::string &p for (auto& item : m_strOutputNames) m_szOutputNames.push_back(item.c_str()); - m_tokenizer.OpenYaml(punc_config.c_str()); + m_tokenizer.OpenYaml(punc_config.c_str(), token_file.c_str()); m_tokenizer.JiebaInit(punc_config); } diff --git a/runtime/onnxruntime/src/ct-transformer.h b/runtime/onnxruntime/src/ct-transformer.h index b33dcf55b..f38fe12a4 100644 --- a/runtime/onnxruntime/src/ct-transformer.h +++ b/runtime/onnxruntime/src/ct-transformer.h @@ -26,7 +26,7 @@ private: public: CTTransformer(); - void InitPunc(const std::string &punc_model, const std::string &punc_config, int thread_num); + void InitPunc(const std::string &punc_model, const std::string &punc_config, const std::string &token_file, int thread_num); ~CTTransformer(); vector Infer(vector input_data); string AddPunc(const char* sz_input, std::string language="zh-cn"); diff --git a/runtime/onnxruntime/src/fsmn-vad.cpp b/runtime/onnxruntime/src/fsmn-vad.cpp index c83227405..42ce83b45 100644 --- a/runtime/onnxruntime/src/fsmn-vad.cpp +++ b/runtime/onnxruntime/src/fsmn-vad.cpp @@ -30,7 +30,7 @@ void FsmnVad::LoadConfigFromYaml(const char* filename){ try{ YAML::Node frontend_conf = config["frontend_conf"]; - YAML::Node post_conf = config["vad_post_conf"]; + YAML::Node post_conf = config["model_conf"]; this->vad_sample_rate_ = frontend_conf["fs"].as(); this->vad_silence_duration_ = post_conf["max_end_silence_time"].as(); diff --git a/runtime/onnxruntime/src/model.cpp b/runtime/onnxruntime/src/model.cpp index 646f26029..8b5e33f65 100644 --- a/runtime/onnxruntime/src/model.cpp +++ b/runtime/onnxruntime/src/model.cpp @@ -8,6 +8,7 @@ Model *CreateModel(std::map& model_path, int thread_nu string am_model_path; string am_cmvn_path; string am_config_path; + string token_path; am_model_path = PathAppend(model_path.at(MODEL_DIR), MODEL_NAME); if(model_path.find(QUANTIZE) != model_path.end() && model_path.at(QUANTIZE) == "true"){ @@ -15,10 +16,11 @@ Model *CreateModel(std::map& model_path, int thread_nu } am_cmvn_path = PathAppend(model_path.at(MODEL_DIR), AM_CMVN_NAME); am_config_path = PathAppend(model_path.at(MODEL_DIR), AM_CONFIG_NAME); + token_path = PathAppend(model_path.at(MODEL_DIR), TOKEN_PATH); Model *mm; mm = new Paraformer(); - mm->InitAsr(am_model_path, am_cmvn_path, am_config_path, thread_num); + mm->InitAsr(am_model_path, am_cmvn_path, am_config_path, token_path, thread_num); return mm; }else if(type == ASR_ONLINE){ // online @@ -26,6 +28,7 @@ Model *CreateModel(std::map& model_path, int thread_nu string de_model_path; string am_cmvn_path; string am_config_path; + string token_path; en_model_path = PathAppend(model_path.at(MODEL_DIR), ENCODER_NAME); de_model_path = PathAppend(model_path.at(MODEL_DIR), DECODER_NAME); @@ -35,10 +38,11 @@ Model *CreateModel(std::map& model_path, int thread_nu } am_cmvn_path = PathAppend(model_path.at(MODEL_DIR), AM_CMVN_NAME); am_config_path = PathAppend(model_path.at(MODEL_DIR), AM_CONFIG_NAME); + token_path = PathAppend(model_path.at(MODEL_DIR), TOKEN_PATH); Model *mm; mm = new Paraformer(); - mm->InitAsr(en_model_path, de_model_path, am_cmvn_path, am_config_path, thread_num); + mm->InitAsr(en_model_path, de_model_path, am_cmvn_path, am_config_path, token_path, thread_num); return mm; }else{ LOG(ERROR)<<"Wrong ASR_TYPE : " << type; diff --git a/runtime/onnxruntime/src/offline-stream.cpp b/runtime/onnxruntime/src/offline-stream.cpp index ae8cf184f..7d86f9bc1 100644 --- a/runtime/onnxruntime/src/offline-stream.cpp +++ b/runtime/onnxruntime/src/offline-stream.cpp @@ -32,6 +32,7 @@ OfflineStream::OfflineStream(std::map& model_path, int string am_model_path; string am_cmvn_path; string am_config_path; + string token_path; string hw_compile_model_path; string seg_dict_path; @@ -57,8 +58,9 @@ OfflineStream::OfflineStream(std::map& model_path, int } am_cmvn_path = PathAppend(model_path.at(MODEL_DIR), AM_CMVN_NAME); am_config_path = PathAppend(model_path.at(MODEL_DIR), AM_CONFIG_NAME); + token_path = PathAppend(model_path.at(MODEL_DIR), TOKEN_PATH); - asr_handle->InitAsr(am_model_path, am_cmvn_path, am_config_path, thread_num); + asr_handle->InitAsr(am_model_path, am_cmvn_path, am_config_path, token_path, thread_num); } // Lm resource @@ -79,20 +81,23 @@ OfflineStream::OfflineStream(std::map& model_path, int if(model_path.find(PUNC_DIR) != model_path.end()){ string punc_model_path; string punc_config_path; + string token_path; punc_model_path = PathAppend(model_path.at(PUNC_DIR), MODEL_NAME); if(model_path.find(PUNC_QUANT) != model_path.end() && model_path.at(PUNC_QUANT) == "true"){ punc_model_path = PathAppend(model_path.at(PUNC_DIR), QUANT_MODEL_NAME); } punc_config_path = PathAppend(model_path.at(PUNC_DIR), PUNC_CONFIG_NAME); + token_path = PathAppend(model_path.at(PUNC_DIR), TOKEN_PATH); if (access(punc_model_path.c_str(), F_OK) != 0 || - access(punc_config_path.c_str(), F_OK) != 0 ) + access(punc_config_path.c_str(), F_OK) != 0 || + access(token_path.c_str(), F_OK) != 0) { LOG(INFO) << "PUNC model file is not exist, skip load punc model."; }else{ punc_handle = make_unique(); - punc_handle->InitPunc(punc_model_path, punc_config_path, thread_num); + punc_handle->InitPunc(punc_model_path, punc_config_path, token_path, thread_num); use_punc = true; } } diff --git a/runtime/onnxruntime/src/paraformer.cpp b/runtime/onnxruntime/src/paraformer.cpp index c56421cca..a57fb9b84 100644 --- a/runtime/onnxruntime/src/paraformer.cpp +++ b/runtime/onnxruntime/src/paraformer.cpp @@ -18,7 +18,7 @@ Paraformer::Paraformer() } // offline -void Paraformer::InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){ +void Paraformer::InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){ LoadConfigFromYaml(am_config.c_str()); // knf options fbank_opts_.frame_opts.dither = 0; @@ -65,13 +65,13 @@ void Paraformer::InitAsr(const std::string &am_model, const std::string &am_cmvn m_szInputNames.push_back(item.c_str()); for (auto& item : m_strOutputNames) m_szOutputNames.push_back(item.c_str()); - vocab = new Vocab(am_config.c_str()); - phone_set_ = new PhoneSet(am_config.c_str()); + vocab = new Vocab(token_file.c_str()); + phone_set_ = new PhoneSet(token_file.c_str()); LoadCmvn(am_cmvn.c_str()); } // online -void Paraformer::InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){ +void Paraformer::InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){ LoadOnlineConfigFromYaml(am_config.c_str()); // knf options @@ -143,15 +143,15 @@ void Paraformer::InitAsr(const std::string &en_model, const std::string &de_mode for (auto& item : de_strOutputNames) de_szOutputNames_.push_back(item.c_str()); - vocab = new Vocab(am_config.c_str()); - phone_set_ = new PhoneSet(am_config.c_str()); + vocab = new Vocab(token_file.c_str()); + phone_set_ = new PhoneSet(token_file.c_str()); LoadCmvn(am_cmvn.c_str()); } // 2pass -void Paraformer::InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num){ +void Paraformer::InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num){ // online - InitAsr(en_model, de_model, am_cmvn, am_config, thread_num); + InitAsr(en_model, de_model, am_cmvn, am_config, token_file, thread_num); // offline try { diff --git a/runtime/onnxruntime/src/paraformer.h b/runtime/onnxruntime/src/paraformer.h index 5bb9477bf..417c2d7b8 100644 --- a/runtime/onnxruntime/src/paraformer.h +++ b/runtime/onnxruntime/src/paraformer.h @@ -42,11 +42,11 @@ namespace funasr { public: Paraformer(); ~Paraformer(); - void InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, int thread_num); + void InitAsr(const std::string &am_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num); // online - void InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num); + void InitAsr(const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num); // 2pass - void InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, int thread_num); + void InitAsr(const std::string &am_model, const std::string &en_model, const std::string &de_model, const std::string &am_cmvn, const std::string &am_config, const std::string &token_file, int thread_num); void InitHwCompiler(const std::string &hw_model, int thread_num); void InitSegDict(const std::string &seg_dict_model); std::vector> CompileHotwordEmbedding(std::string &hotwords); diff --git a/runtime/onnxruntime/src/phone-set.cpp b/runtime/onnxruntime/src/phone-set.cpp index 167fa010a..60eb1019d 100644 --- a/runtime/onnxruntime/src/phone-set.cpp +++ b/runtime/onnxruntime/src/phone-set.cpp @@ -13,7 +13,7 @@ using namespace std; namespace funasr { PhoneSet::PhoneSet(const char *filename) { ifstream in(filename); - LoadPhoneSetFromYaml(filename); + LoadPhoneSetFromJson(filename); } PhoneSet::~PhoneSet() { @@ -35,6 +35,25 @@ void PhoneSet::LoadPhoneSetFromYaml(const char* filename) { } } +void PhoneSet::LoadPhoneSetFromJson(const char* filename) { + nlohmann::json json_array; + std::ifstream file(filename); + if (file.is_open()) { + file >> json_array; + file.close(); + } else { + LOG(INFO) << "Error loading token file, token file error or not exist."; + exit(-1); + } + + int id = 0; + for (const auto& element : json_array) { + phone_.push_back(element); + phn2Id_.emplace(element, id); + id++; + } +} + int PhoneSet::Size() const { return phone_.size(); } diff --git a/runtime/onnxruntime/src/phone-set.h b/runtime/onnxruntime/src/phone-set.h index 972910408..cb1a2a755 100644 --- a/runtime/onnxruntime/src/phone-set.h +++ b/runtime/onnxruntime/src/phone-set.h @@ -5,6 +5,7 @@ #include #include #include +#include "nlohmann/json.hpp" #define UNIT_BEG_SIL_SYMBOL "" #define UNIT_END_SIL_SYMBOL "" #define UNIT_BLK_SYMBOL "" @@ -28,6 +29,7 @@ class PhoneSet { vector phone_; unordered_map phn2Id_; void LoadPhoneSetFromYaml(const char* filename); + void LoadPhoneSetFromJson(const char* filename); }; } // namespace funasr diff --git a/runtime/onnxruntime/src/punc-model.cpp b/runtime/onnxruntime/src/punc-model.cpp index 54b8d6a46..9af03db29 100644 --- a/runtime/onnxruntime/src/punc-model.cpp +++ b/runtime/onnxruntime/src/punc-model.cpp @@ -14,14 +14,16 @@ PuncModel *CreatePuncModel(std::map& model_path, int t } string punc_model_path; string punc_config_path; + string token_file; punc_model_path = PathAppend(model_path.at(MODEL_DIR), MODEL_NAME); if(model_path.find(QUANTIZE) != model_path.end() && model_path.at(QUANTIZE) == "true"){ punc_model_path = PathAppend(model_path.at(MODEL_DIR), QUANT_MODEL_NAME); } punc_config_path = PathAppend(model_path.at(MODEL_DIR), PUNC_CONFIG_NAME); + token_file = PathAppend(model_path.at(MODEL_DIR), TOKEN_PATH); - mm->InitPunc(punc_model_path, punc_config_path, thread_num); + mm->InitPunc(punc_model_path, punc_config_path, token_file, thread_num); return mm; } diff --git a/runtime/onnxruntime/src/tokenizer.cpp b/runtime/onnxruntime/src/tokenizer.cpp index 761828269..06d64d86f 100644 --- a/runtime/onnxruntime/src/tokenizer.cpp +++ b/runtime/onnxruntime/src/tokenizer.cpp @@ -127,6 +127,61 @@ bool CTokenizer::OpenYaml(const char* sz_yamlfile) return m_ready; } +bool CTokenizer::OpenYaml(const char* sz_yamlfile, const char* token_file) +{ + YAML::Node m_Config; + try{ + m_Config = YAML::LoadFile(sz_yamlfile); + }catch(exception const &e){ + LOG(INFO) << "Error loading file, yaml file error or not exist."; + exit(-1); + } + + try + { + YAML::Node conf_seg_jieba = m_Config["seg_jieba"]; + if (conf_seg_jieba.IsDefined()){ + seg_jieba = conf_seg_jieba.as(); + } + + auto Puncs = m_Config["model_conf"]["punc_list"]; + if (Puncs.IsSequence()) + { + for (size_t i = 0; i < Puncs.size(); ++i) + { + if (Puncs[i].IsScalar()) + { + m_id2punc.push_back(Puncs[i].as()); + m_punc2id.insert(make_pair(Puncs[i].as(), i)); + } + } + } + + nlohmann::json json_array; + std::ifstream file(token_file); + if (file.is_open()) { + file >> json_array; + file.close(); + } else { + LOG(INFO) << "Error loading token file, token file error or not exist."; + return false; + } + + int i = 0; + for (const auto& element : json_array) { + m_id2token.push_back(element); + m_token2id[element] = i; + i++; + } + } + catch (YAML::BadFile& e) { + LOG(ERROR) << "Read error!"; + return false; + } + m_ready = true; + return m_ready; +} + vector CTokenizer::Id2String(vector input) { vector result; diff --git a/runtime/onnxruntime/src/tokenizer.h b/runtime/onnxruntime/src/tokenizer.h index 166061bd4..81aea7ed3 100644 --- a/runtime/onnxruntime/src/tokenizer.h +++ b/runtime/onnxruntime/src/tokenizer.h @@ -8,6 +8,7 @@ #include "cppjieba/DictTrie.hpp" #include "cppjieba/HMMModel.hpp" #include "cppjieba/Jieba.hpp" +#include "nlohmann/json.hpp" namespace funasr { class CTokenizer { @@ -27,6 +28,7 @@ public: CTokenizer(); ~CTokenizer(); bool OpenYaml(const char* sz_yamlfile); + bool OpenYaml(const char* sz_yamlfile, const char* token_file); void ReadYaml(const YAML::Node& node); vector Id2String(vector input); vector String2Ids(vector input); diff --git a/runtime/onnxruntime/src/tpass-stream.cpp b/runtime/onnxruntime/src/tpass-stream.cpp index b723e0fa1..7681a4db0 100644 --- a/runtime/onnxruntime/src/tpass-stream.cpp +++ b/runtime/onnxruntime/src/tpass-stream.cpp @@ -35,6 +35,7 @@ TpassStream::TpassStream(std::map& model_path, int thr string de_model_path; string am_cmvn_path; string am_config_path; + string token_path; string hw_compile_model_path; string seg_dict_path; @@ -60,8 +61,9 @@ TpassStream::TpassStream(std::map& model_path, int thr } am_cmvn_path = PathAppend(model_path.at(ONLINE_MODEL_DIR), AM_CMVN_NAME); am_config_path = PathAppend(model_path.at(ONLINE_MODEL_DIR), AM_CONFIG_NAME); + token_path = PathAppend(model_path.at(MODEL_DIR), TOKEN_PATH); - asr_handle->InitAsr(am_model_path, en_model_path, de_model_path, am_cmvn_path, am_config_path, thread_num); + asr_handle->InitAsr(am_model_path, en_model_path, de_model_path, am_cmvn_path, am_config_path, token_path, thread_num); }else{ LOG(ERROR) <<"Can not find offline-model-dir or online-model-dir"; exit(-1); @@ -85,20 +87,23 @@ TpassStream::TpassStream(std::map& model_path, int thr if(model_path.find(PUNC_DIR) != model_path.end()){ string punc_model_path; string punc_config_path; + string token_path; punc_model_path = PathAppend(model_path.at(PUNC_DIR), MODEL_NAME); if(model_path.find(PUNC_QUANT) != model_path.end() && model_path.at(PUNC_QUANT) == "true"){ punc_model_path = PathAppend(model_path.at(PUNC_DIR), QUANT_MODEL_NAME); } punc_config_path = PathAppend(model_path.at(PUNC_DIR), PUNC_CONFIG_NAME); + token_path = PathAppend(model_path.at(PUNC_DIR), TOKEN_PATH); if (access(punc_model_path.c_str(), F_OK) != 0 || - access(punc_config_path.c_str(), F_OK) != 0 ) + access(punc_config_path.c_str(), F_OK) != 0 || + access(token_path.c_str(), F_OK) != 0) { LOG(INFO) << "PUNC model file is not exist, skip load punc model."; }else{ punc_online_handle = make_unique(); - punc_online_handle->InitPunc(punc_model_path, punc_config_path, thread_num); + punc_online_handle->InitPunc(punc_model_path, punc_config_path, token_path, thread_num); use_punc = true; } } diff --git a/runtime/onnxruntime/src/vocab.cpp b/runtime/onnxruntime/src/vocab.cpp index 6991376a9..1416dd314 100644 --- a/runtime/onnxruntime/src/vocab.cpp +++ b/runtime/onnxruntime/src/vocab.cpp @@ -14,7 +14,7 @@ namespace funasr { Vocab::Vocab(const char *filename) { ifstream in(filename); - LoadVocabFromYaml(filename); + LoadVocabFromJson(filename); } Vocab::Vocab(const char *filename, const char *lex_file) { @@ -43,6 +43,25 @@ void Vocab::LoadVocabFromYaml(const char* filename){ } } +void Vocab::LoadVocabFromJson(const char* filename){ + nlohmann::json json_array; + std::ifstream file(filename); + if (file.is_open()) { + file >> json_array; + file.close(); + } else { + LOG(INFO) << "Error loading token file, token file error or not exist."; + exit(-1); + } + + int i = 0; + for (const auto& element : json_array) { + vocab.push_back(element); + token_id[element] = i; + i++; + } +} + void Vocab::LoadLex(const char* filename){ std::ifstream file(filename); std::string line; diff --git a/runtime/onnxruntime/src/vocab.h b/runtime/onnxruntime/src/vocab.h index 19e364867..36fabf446 100644 --- a/runtime/onnxruntime/src/vocab.h +++ b/runtime/onnxruntime/src/vocab.h @@ -6,6 +6,7 @@ #include #include #include +#include "nlohmann/json.hpp" using namespace std; namespace funasr { @@ -16,6 +17,7 @@ class Vocab { std::map lex_map; bool IsEnglish(string ch); void LoadVocabFromYaml(const char* filename); + void LoadVocabFromJson(const char* filename); void LoadLex(const char* filename); public: diff --git a/runtime/python/http/server.py b/runtime/python/http/server.py index 720d4ce8f..8bff9c970 100644 --- a/runtime/python/http/server.py +++ b/runtime/python/http/server.py @@ -117,7 +117,7 @@ async def api_recognition(audio: UploadFile = File(..., description="audio file" for sentence in rec_result["sentence_info"]: # 每句话的时间戳 sentences.append( - {"text": sentence["text"], "start": sentence["start"], "end": sentence["start"]} + {"text": sentence["text"], "start": sentence["start"], "end": sentence["end"]} ) ret = {"text": text, "sentences": sentences, "code": 0} logger.info(f"识别结果:{ret}") diff --git a/runtime/quick_start.md b/runtime/quick_start.md index 44ca41aea..d0f7c0e5c 100644 --- a/runtime/quick_start.md +++ b/runtime/quick_start.md @@ -47,11 +47,11 @@ Use the following command to pull and launch the FunASR software package Docker ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10096:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 ``` ###### Server Start @@ -93,11 +93,11 @@ Use the following command to pull and launch the FunASR software package Docker ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10095:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 ``` ###### Server Start diff --git a/runtime/quick_start_zh.md b/runtime/quick_start_zh.md index 0bbe04e19..556602082 100644 --- a/runtime/quick_start_zh.md +++ b/runtime/quick_start_zh.md @@ -48,11 +48,11 @@ sudo bash install_docker.sh ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10096:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.9 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.10 ``` ###### 服务端启动 @@ -92,11 +92,11 @@ python3 funasr_wss_client.py --host "127.0.0.1" --port 10096 --mode 2pass ```shell sudo docker pull \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 mkdir -p ./funasr-runtime-resources/models sudo docker run -p 10095:10095 -it --privileged=true \ -v $PWD/funasr-runtime-resources/models:/workspace/models \ - registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.4 + registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5 ``` ###### 服务端启动 diff --git a/runtime/readme.md b/runtime/readme.md index 2f6546b32..28a063da8 100644 --- a/runtime/readme.md +++ b/runtime/readme.md @@ -17,6 +17,7 @@ Currently, the FunASR runtime-SDK supports the deployment of file transcription To meet the needs of different users, we have prepared different tutorials with text and images for both novice and advanced developers. ### Whats-new +- 2024/05/15: Adapting to FunASR 1.0 model structure, docker image version funasr-runtime-sdk-en-cpu-0.1.6 (84d781d07997). - 2024/03/05: docker image supports ARM64 platform, update modelscope, docker image version funasr-runtime-sdk-en-cpu-0.1.5 (7cca2abc5901). - 2024/01/25: Optimized the VAD (Voice Activity Detection) data processing method,significantly reducing peak memory usage,memory leak optimization, docker image version funasr-runtime-sdk-en-cpu-0.1.3 (c00f9ce7a195). - 2024/01/03: Fixed known crash issues as well as memory leak problems, docker image version funasr-runtime-sdk-en-cpu-0.1.2 (0cdd9f4a4bb5). @@ -42,6 +43,7 @@ The FunASR real-time speech-to-text service software package not only performs r In order to meet the needs of different users for different scenarios, different tutorials are prepared: ### Whats-new +- 2024/05/15: Real-time Transcription Service 1.10 released,adapting to FunASR 1.0 model structure, docker image version funasr-runtime-sdk-online-cpu-0.1.10 (1c2adfcff84d) - 2024/03/05: Real-time Transcription Service 1.9 released,docker image supports ARM64 platform, update modelscope, docker image version funasr-runtime-sdk-online-cpu-0.1.9 (4a875e08c7a2) - 2024/01/25: Real-time Transcription Service 1.7 released,optimization of the client-side, docker image version funasr-runtime-sdk-online-cpu-0.1.7 (2aa23805572e) - 2024/01/03: Real-time Transcription Service 1.6 released,The 2pass-offline mode supports Ngram language model decoding and WFST hotwords, while also addressing known crash issues and memory leak problems, docker image version funasr-runtime-sdk-online-cpu-0.1.6 (f99925110d27) @@ -72,6 +74,7 @@ Currently, the FunASR runtime-SDK supports the deployment of file transcription To meet the needs of different users, we have prepared different tutorials with text and images for both novice and advanced developers. ### Whats-new +- 2024/05/15: File Transcription Service 4.5 released, adapting to FunASR 1.0 model structure, docker image version funasr-runtime-sdk-cpu-0.4.5 (058b9882ae67) - 2024/03/05: File Transcription Service 4.4 released, docker image supports ARM64 platform, update modelscope, docker image version funasr-runtime-sdk-cpu-0.4.4 (2dc87b86dc49) - 2024/01/25: File Transcription Service 4.2 released, optimized the VAD (Voice Activity Detection) data processing method, significantly reducing peak memory usage, memory leak optimization, docker image version funasr-runtime-sdk-cpu-0.4.2 (befdc7b179ed) - 2024/01/08: File Transcription Service 4.1 released, optimized format sentence-level timestamps, docker image version funasr-runtime-sdk-cpu-0.4.1 (0250f8ef981b) diff --git a/runtime/readme_cn.md b/runtime/readme_cn.md index 13cd8eb4f..9cb7b58d9 100644 --- a/runtime/readme_cn.md +++ b/runtime/readme_cn.md @@ -19,6 +19,7 @@ FunASR是由阿里巴巴通义实验室语音团队开源的一款语音识别 为了支持不同用户的需求,针对不同场景,准备了不同的图文教程: ### 最新动态 +- 2024/05/15: 英文离线文件转写服务 1.6 发布,适配FunASR 1.0模型结构,dokcer镜像版本funasr-runtime-sdk-en-cpu-0.1.6 (84d781d07997) - 2024/03/05: 英文离线文件转写服务 1.5 发布,docker镜像支持arm64平台,升级modelscope版本,dokcer镜像版本funasr-runtime-sdk-en-cpu-0.1.5 (7cca2abc5901) - 2024/01/25: 英文离线文件转写服务 1.3 发布,优化vad数据处理方式,大幅降低峰值内存占用,内存泄漏优化,dokcer镜像版本funasr-runtime-sdk-en-cpu-0.1.3 (c00f9ce7a195) - 2024/01/03: 英文离线文件转写服务 1.2 发布,修复已知的crash问题及内存泄漏问题,dokcer镜像版本funasr-runtime-sdk-en-cpu-0.1.2 (0cdd9f4a4bb5) @@ -36,6 +37,7 @@ FunASR实时语音听写服务软件包,既可以实时地进行语音转文 为了支持不同用户的需求,针对不同场景,准备了不同的图文教程: ### 最新动态 +- 2024/05/15: 中文实时语音听写服务 1.10 发布,适配FunASR 1.0模型结构,dokcer镜像版本funasr-runtime-sdk-online-cpu-0.1.10 (1c2adfcff84d) - 2024/03/05: 中文实时语音听写服务 1.9 发布,docker镜像支持arm64平台,升级modelscope版本,dokcer镜像版本funasr-runtime-sdk-online-cpu-0.1.9 (4a875e08c7a2) - 2024/01/25: 中文实时语音听写服务 1.7 发布,客户端优化,dokcer镜像版本funasr-runtime-sdk-online-cpu-0.1.7 (2aa23805572e) - 2024/01/03: 中文实时语音听写服务 1.6 发布,2pass-offline模式支持Ngram语言模型解码、wfst热词,同时修复已知的crash问题及内存泄漏问题,dokcer镜像版本funasr-runtime-sdk-online-cpu-0.1.6 (f99925110d27) @@ -58,6 +60,7 @@ FunASR实时语音听写服务软件包,既可以实时地进行语音转文 为了支持不同用户的需求,针对不同场景,准备了不同的图文教程: ### 最新动态 +- 2024/05/15: 中文离线文件转写服务 4.5 发布,适配FunASR 1.0模型结构,dokcer镜像版本funasr-runtime-sdk-cpu-0.4.5 (058b9882ae67) - 2024/03/05: 中文离线文件转写服务 4.4 发布,docker镜像支持arm64平台,升级modelscope版本,dokcer镜像版本funasr-runtime-sdk-cpu-0.4.4 (2dc87b86dc49) - 2024/01/25: 中文离线文件转写服务 4.2 发布,优化vad数据处理方式,大幅降低峰值内存占用,内存泄漏优化,dokcer镜像版本funasr-runtime-sdk-cpu-0.4.2 (befdc7b179ed) - 2024/01/08: 中文离线文件转写服务 4.1 发布,优化句子级时间戳json格式,dokcer镜像版本funasr-runtime-sdk-cpu-0.4.1 (0250f8ef981b) diff --git a/runtime/websocket/bin/funasr-wss-server-2pass.cpp b/runtime/websocket/bin/funasr-wss-server-2pass.cpp index 4bc413cc5..d42679bec 100644 --- a/runtime/websocket/bin/funasr-wss-server-2pass.cpp +++ b/runtime/websocket/bin/funasr-wss-server-2pass.cpp @@ -55,11 +55,11 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg offline_model_revision( "", "offline-model-revision", "ASR offline model revision", false, - "v1.2.1", "string"); + "v2.0.4", "string"); TCLAP::ValueArg online_model_revision( "", "online-model-revision", "ASR online model revision", false, - "v1.0.6", "string"); + "v2.0.4", "string"); TCLAP::ValueArg quantize( "", QUANTIZE, @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) { "model_quant.onnx, vad.yaml, vad.mvn", false, "damo/speech_fsmn_vad_zh-cn-16k-common-onnx", "string"); TCLAP::ValueArg vad_revision( - "", "vad-revision", "VAD model revision", false, "v1.2.0", "string"); + "", "vad-revision", "VAD model revision", false, "v2.0.4", "string"); TCLAP::ValueArg vad_quant( "", VAD_QUANT, "true (Default), load the model of model_quant.onnx in vad_dir. If set " @@ -85,7 +85,7 @@ int main(int argc, char* argv[]) { "model_quant.onnx, punc.yaml", false, "damo/punc_ct-transformer_zh-cn-common-vad_realtime-vocab272727-onnx", "string"); TCLAP::ValueArg punc_revision( - "", "punc-revision", "PUNC model revision", false, "v1.0.2", "string"); + "", "punc-revision", "PUNC model revision", false, "v2.0.4", "string"); TCLAP::ValueArg punc_quant( "", PUNC_QUANT, "true (Default), load the model of model_quant.onnx in punc_dir. If " @@ -262,17 +262,17 @@ int main(int argc, char* argv[]) { size_t found = s_offline_asr_path.find("speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404"); if (found != std::string::npos) { - model_path["offline-model-revision"]="v1.2.4"; + model_path["offline-model-revision"]="v2.0.4"; } found = s_offline_asr_path.find("speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404"); if (found != std::string::npos) { - model_path["offline-model-revision"]="v1.0.5"; + model_path["offline-model-revision"]="v2.0.5"; } found = s_offline_asr_path.find("speech_paraformer-large_asr_nat-en-16k-common-vocab10020"); if (found != std::string::npos) { - model_path["model-revision"]="v1.0.0"; + model_path["model-revision"]="v2.0.4"; s_itn_path=""; s_lm_path=""; } diff --git a/runtime/websocket/bin/funasr-wss-server.cpp b/runtime/websocket/bin/funasr-wss-server.cpp index bff4f6612..5bb7def57 100644 --- a/runtime/websocket/bin/funasr-wss-server.cpp +++ b/runtime/websocket/bin/funasr-wss-server.cpp @@ -50,7 +50,7 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg model_revision( "", "model-revision", "ASR model revision", - false, "v1.2.1", "string"); + false, "v2.0.4", "string"); TCLAP::ValueArg quantize( "", QUANTIZE, "true (Default), load the model of model_quant.onnx in model_dir. If set " @@ -63,7 +63,7 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg vad_revision( "", "vad-revision", "VAD model revision", - false, "v1.2.0", "string"); + false, "v2.0.4", "string"); TCLAP::ValueArg vad_quant( "", VAD_QUANT, "true (Default), load the model of model_quant.onnx in vad_dir. If set " @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) { TCLAP::ValueArg punc_revision( "", "punc-revision", "PUNC model revision", - false, "v1.1.7", "string"); + false, "v2.0.4", "string"); TCLAP::ValueArg punc_quant( "", PUNC_QUANT, "true (Default), load the model of model_quant.onnx in punc_dir. If set " @@ -233,17 +233,17 @@ int main(int argc, char* argv[]) { // modify model-revision by model name size_t found = s_asr_path.find("speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404"); if (found != std::string::npos) { - model_path["model-revision"]="v1.2.4"; + model_path["model-revision"]="v2.0.4"; } found = s_asr_path.find("speech_paraformer-large-contextual_asr_nat-zh-cn-16k-common-vocab8404"); if (found != std::string::npos) { - model_path["model-revision"]="v1.0.5"; + model_path["model-revision"]="v2.0.5"; } found = s_asr_path.find("speech_paraformer-large_asr_nat-en-16k-common-vocab10020"); if (found != std::string::npos) { - model_path["model-revision"]="v1.0.0"; + model_path["model-revision"]="v2.0.4"; s_itn_path=""; s_lm_path=""; } From 075d9117d9a2db57d46db669d2511a460275519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 15 May 2024 19:35:12 +0800 Subject: [PATCH 048/125] docs --- README.md | 10 ++++++---- README_zh.md | 28 +++++++++++++++------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ba23f3fcd..e02b3e229 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ ## What's new: +- 2024/05/15:emotion recognition models are new supported. [emotion2vec+large](https://modelscope.cn/models/iic/emotion2vec_plus_large/summary),[emotion2vec+base](https://modelscope.cn/models/iic/emotion2vec_plus_base/summary),[emotion2vec+seed](https://modelscope.cn/models/iic/emotion2vec_plus_seed/summary). currently supports the following categories: 0: angry 1: happy 2: neutral 3: sad 4: unknown. - 2024/05/15: Offline File Transcription Service 4.5, Offline File Transcription Service of English 1.6,Real-time Transcription Service 1.10 released,adapting to FunASR 1.0 model structure;([docs](runtime/readme.md)) - 2024/03/05:Added the Qwen-Audio and Qwen-Audio-Chat large-scale audio-text multimodal models, which have topped multiple audio domain leaderboards. These models support speech dialogue, [usage](examples/industrial_data_pretraining/qwen_audio). - 2024/03/05:Added support for the Whisper-large-v3 model, a multitasking model that can perform multilingual speech recognition, speech translation, and language identification. It can be downloaded from the[modelscope](examples/industrial_data_pretraining/whisper/demo.py), and [openai](examples/industrial_data_pretraining/whisper/demo_from_openai.py). @@ -84,10 +85,11 @@ FunASR has open-sourced a large number of pre-trained models on industrial data. | fsmn-vad
( [⭐](https://modelscope.cn/models/damo/speech_fsmn_vad_zh-cn-16k-common-pytorch/summary) [🤗](https://huggingface.co/funasr/fsmn-vad) ) | voice activity detection | 5000 hours, Mandarin and English | 0.4M | | fa-zh
( [⭐](https://modelscope.cn/models/damo/speech_timestamp_prediction-v1-16k-offline/summary) [🤗](https://huggingface.co/funasr/fa-zh) ) | timestamp prediction | 5000 hours, Mandarin | 38M | | cam++
( [⭐](https://modelscope.cn/models/iic/speech_campplus_sv_zh-cn_16k-common/summary) [🤗](https://huggingface.co/funasr/campplus) ) | speaker verification/diarization | 5000 hours | 7.2M | -| Whisper-large-v2
([⭐](https://www.modelscope.cn/models/iic/speech_whisper-large_asr_multilingual/summary) [🍀](https://github.com/openai/whisper) ) | speech recognition, with timestamps, non-streaming | multilingual | 1550 M | -| Whisper-large-v3
([⭐](https://www.modelscope.cn/models/iic/Whisper-large-v3/summary) [🍀](https://github.com/openai/whisper) ) | speech recognition, with timestamps, non-streaming | multilingual | 1550 M | -| Qwen-Audio
([⭐](examples/industrial_data_pretraining/qwen_audio/demo.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio) ) | audio-text multimodal models (pretraining) | multilingual | 8B | -| Qwen-Audio-Chat
([⭐](examples/industrial_data_pretraining/qwen_audio/demo_chat.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio-Chat) ) | audio-text multimodal models (chat) | multilingual | 8B | +| Whisper-large-v2
([⭐](https://www.modelscope.cn/models/iic/speech_whisper-large_asr_multilingual/summary) [🍀](https://github.com/openai/whisper) ) | speech recognition, with timestamps, non-streaming | multilingual | 1550 M | +| Whisper-large-v3
([⭐](https://www.modelscope.cn/models/iic/Whisper-large-v3/summary) [🍀](https://github.com/openai/whisper) ) | speech recognition, with timestamps, non-streaming | multilingual | 1550 M | +| Qwen-Audio
([⭐](examples/industrial_data_pretraining/qwen_audio/demo.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio) ) | audio-text multimodal models (pretraining) | multilingual | 8B | +| Qwen-Audio-Chat
([⭐](examples/industrial_data_pretraining/qwen_audio/demo_chat.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio-Chat) ) | audio-text multimodal models (chat) | multilingual | 8B | +| emotion2vec+large
([⭐](https://modelscope.cn/models/iic/emotion2vec_plus_large/summary) [🤗](https://huggingface.co/emotion2vec/emotion2vec_plus_large) ) | speech emotion recongintion | 40000 hours | 300M | diff --git a/README_zh.md b/README_zh.md index 44f92e63b..d3c9ff6bc 100644 --- a/README_zh.md +++ b/README_zh.md @@ -29,6 +29,7 @@ FunASR希望在语音识别的学术研究和工业应用之间架起一座桥 ## 最新动态 +- 2024/05/15:新增加情感识别模型,[emotion2vec+large](https://modelscope.cn/models/iic/emotion2vec_plus_large/summary),[emotion2vec+base](https://modelscope.cn/models/iic/emotion2vec_plus_base/summary),[emotion2vec+seed](https://modelscope.cn/models/iic/emotion2vec_plus_seed/summary),输出情感类别为:生气/angry,开心/happy,中立/neutral,难过/sad。 - 2024/05/15: 中文离线文件转写服务 4.5、英文离线文件转写服务 1.6、中文实时语音听写服务 1.10 发布,适配FunASR 1.0模型结构;详细信息参阅([部署文档](runtime/readme_cn.md)) - 2024/03/05:新增加Qwen-Audio与Qwen-Audio-Chat音频文本模态大模型,在多个音频领域测试榜单刷榜,中支持语音对话,详细用法见 [示例](examples/industrial_data_pretraining/qwen_audio)。 - 2024/03/05:新增加Whisper-large-v3模型支持,多语言语音识别/翻译/语种识别,支持从 [modelscope](examples/industrial_data_pretraining/whisper/demo.py)仓库下载,也支持从 [openai](examples/industrial_data_pretraining/whisper/demo_from_openai.py)仓库下载模型。 @@ -75,19 +76,20 @@ FunASR开源了大量在工业数据上预训练模型,您可以在[模型许 (注:⭐ 表示ModelScope模型仓库,🤗 表示Huggingface模型仓库,🍀表示OpenAI模型仓库) -| 模型名字 | 任务详情 | 训练数据 | 参数量 | -|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------:|:------------:|:----:| -| paraformer-zh
([⭐](https://www.modelscope.cn/models/damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch/summary) [🤗](https://huggingface.co/funasr/paraformer-tp) ) | 语音识别,带时间戳输出,非实时 | 60000小时,中文 | 220M | -| paraformer-zh-streaming
( [⭐](https://modelscope.cn/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online/summary) [🤗](https://huggingface.co/funasr/paraformer-zh-streaming) ) | 语音识别,实时 | 60000小时,中文 | 220M | -| paraformer-en
( [⭐](https://www.modelscope.cn/models/damo/speech_paraformer-large-vad-punc_asr_nat-en-16k-common-vocab10020/summary) [🤗](https://huggingface.co/funasr/paraformer-en) ) | 语音识别,非实时 | 50000小时,英文 | 220M | -| conformer-en
( [⭐](https://modelscope.cn/models/damo/speech_conformer_asr-en-16k-vocab4199-pytorch/summary) [🤗](https://huggingface.co/funasr/conformer-en) ) | 语音识别,非实时 | 50000小时,英文 | 220M | -| ct-punc
( [⭐](https://modelscope.cn/models/damo/punc_ct-transformer_cn-en-common-vocab471067-large/summary) [🤗](https://huggingface.co/funasr/ct-punc) ) | 标点恢复 | 100M,中文与英文 | 1.1B | -| fsmn-vad
( [⭐](https://modelscope.cn/models/damo/speech_fsmn_vad_zh-cn-16k-common-pytorch/summary) [🤗](https://huggingface.co/funasr/fsmn-vad) ) | 语音端点检测,实时 | 5000小时,中文与英文 | 0.4M | -| fa-zh
( [⭐](https://modelscope.cn/models/damo/speech_timestamp_prediction-v1-16k-offline/summary) [🤗](https://huggingface.co/funasr/fa-zh) ) | 字级别时间戳预测 | 50000小时,中文 | 38M | -| cam++
( [⭐](https://modelscope.cn/models/iic/speech_campplus_sv_zh-cn_16k-common/summary) [🤗](https://huggingface.co/funasr/campplus) ) | 说话人确认/分割 | 5000小时 | 7.2M | -| Whisper-large-v3
([⭐](https://www.modelscope.cn/models/iic/Whisper-large-v3/summary) [🍀](https://github.com/openai/whisper) ) | 语音识别,带时间戳输出,非实时 | 多语言 | 1550 M | -| Qwen-Audio
([⭐](examples/industrial_data_pretraining/qwen_audio/demo.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio) ) | 音频文本多模态大模型(预训练) | 多语言 | 8B | -| Qwen-Audio-Chat
([⭐](examples/industrial_data_pretraining/qwen_audio/demo_chat.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio-Chat) ) | 音频文本多模态大模型(chat版本) | 多语言 | 8B | +| 模型名字 | 任务详情 | 训练数据 | 参数量 | +|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------:|:--------------:|:------:| +| paraformer-zh
([⭐](https://www.modelscope.cn/models/damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch/summary) [🤗](https://huggingface.co/funasr/paraformer-tp) ) | 语音识别,带时间戳输出,非实时 | 60000小时,中文 | 220M | +| paraformer-zh-streaming
( [⭐](https://modelscope.cn/models/damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online/summary) [🤗](https://huggingface.co/funasr/paraformer-zh-streaming) ) | 语音识别,实时 | 60000小时,中文 | 220M | +| paraformer-en
( [⭐](https://www.modelscope.cn/models/damo/speech_paraformer-large-vad-punc_asr_nat-en-16k-common-vocab10020/summary) [🤗](https://huggingface.co/funasr/paraformer-en) ) | 语音识别,非实时 | 50000小时,英文 | 220M | +| conformer-en
( [⭐](https://modelscope.cn/models/damo/speech_conformer_asr-en-16k-vocab4199-pytorch/summary) [🤗](https://huggingface.co/funasr/conformer-en) ) | 语音识别,非实时 | 50000小时,英文 | 220M | +| ct-punc
( [⭐](https://modelscope.cn/models/damo/punc_ct-transformer_cn-en-common-vocab471067-large/summary) [🤗](https://huggingface.co/funasr/ct-punc) ) | 标点恢复 | 100M,中文与英文 | 1.1B | +| fsmn-vad
( [⭐](https://modelscope.cn/models/damo/speech_fsmn_vad_zh-cn-16k-common-pytorch/summary) [🤗](https://huggingface.co/funasr/fsmn-vad) ) | 语音端点检测,实时 | 5000小时,中文与英文 | 0.4M | +| fa-zh
( [⭐](https://modelscope.cn/models/damo/speech_timestamp_prediction-v1-16k-offline/summary) [🤗](https://huggingface.co/funasr/fa-zh) ) | 字级别时间戳预测 | 50000小时,中文 | 38M | +| cam++
( [⭐](https://modelscope.cn/models/iic/speech_campplus_sv_zh-cn_16k-common/summary) [🤗](https://huggingface.co/funasr/campplus) ) | 说话人确认/分割 | 5000小时 | 7.2M | +| Whisper-large-v3
([⭐](https://www.modelscope.cn/models/iic/Whisper-large-v3/summary) [🍀](https://github.com/openai/whisper) ) | 语音识别,带时间戳输出,非实时 | 多语言 | 1550 M | +| Qwen-Audio
([⭐](examples/industrial_data_pretraining/qwen_audio/demo.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio) ) | 音频文本多模态大模型(预训练) | 多语言 | 8B | +| Qwen-Audio-Chat
([⭐](examples/industrial_data_pretraining/qwen_audio/demo_chat.py) [🤗](https://huggingface.co/Qwen/Qwen-Audio-Chat) ) | 音频文本多模态大模型(chat版本) | 多语言 | 8B | +| emotion2vec+large
([⭐](https://modelscope.cn/models/iic/emotion2vec_plus_large/summary) [🤗](https://huggingface.co/emotion2vec/emotion2vec_plus_large) ) | 情感识别模型 | 40000小时,4种情感类别 | 300M | ## 快速开始 From a974a44fcd101099629beba58c15c35b894794af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 16 May 2024 14:31:25 +0800 Subject: [PATCH 049/125] docs --- funasr/frontends/whisper_frontend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/frontends/whisper_frontend.py b/funasr/frontends/whisper_frontend.py index acf32dbc7..1bd8aecdd 100644 --- a/funasr/frontends/whisper_frontend.py +++ b/funasr/frontends/whisper_frontend.py @@ -33,7 +33,7 @@ class WhisperFrontend(nn.Module): self.win_length = N_FFT self.hop_length = HOP_LENGTH self.pad_samples = N_SAMPLES - self.frame_shift = self.hop_length + self.frame_shift = int(self.hop_length / self.fs * 1000) self.lfr_n = 1 self.n_mels = n_mels if whisper_model == "large-v3" or whisper_model == "large": From f68ae892be3e59c20a033f18d5f61db7f633801f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 17 May 2024 10:32:34 +0800 Subject: [PATCH 050/125] deepspeed --- funasr/bin/train_ds.py | 38 +---- funasr/train_utils/trainer_ds.py | 229 ++++++++++++++++--------------- 2 files changed, 119 insertions(+), 148 deletions(-) diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index e4db533d5..032a0cf80 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -133,29 +133,7 @@ def main(**kwargs): kwargs["device"] = next(model.parameters()).device trainer.device = kwargs["device"] - # optim - logging.info("Build optim") - optim = kwargs.get("optim", "adam") - assert optim in optim_classes - optim_class = optim_classes.get(optim) - optim = optim_class(model.parameters(), **kwargs.get("optim_conf")) - - # scheduler - logging.info("Build scheduler") - scheduler = kwargs.get("scheduler", "warmuplr") - assert scheduler in scheduler_classes - scheduler_class = scheduler_classes.get(scheduler) - scheduler = scheduler_class(optim, **kwargs.get("scheduler_conf")) - - if use_deepspeed: - args = OmegaConf.create({"deepspeed_config": kwargs.get("deepspeed_config", "")}) - model, optimizer, _, scheduler = deepspeed.initialize( - args=args, - model=model, - optimizer=optim, - lr_scheduler=scheduler, - model_parameters=model.parameters(), - ) + model, optim, scheduler = trainer.warp_optim_scheduler(model, kwargs) # dataset logging.info("Build dataloader") @@ -175,15 +153,6 @@ def main(**kwargs): scaler=scaler, ) - tensorboard_dir = os.path.join(kwargs.get("output_dir"), "tensorboard") - os.makedirs(tensorboard_dir, exist_ok=True) - try: - from tensorboardX import SummaryWriter - - writer = SummaryWriter(tensorboard_dir) # if trainer.rank == 0 else None - except: - writer = None - dataloader_tr, dataloader_val = None, None for epoch in range(trainer.start_epoch, trainer.max_epoch): time1 = time.perf_counter() @@ -201,7 +170,6 @@ def main(**kwargs): dataloader_train=dataloader_tr, dataloader_val=dataloader_val, epoch=epoch, - writer=writer, data_split_i=data_split_i, data_split_num=dataloader.data_split_num, start_step=trainer.start_step, @@ -211,9 +179,7 @@ def main(**kwargs): torch.cuda.empty_cache() trainer.start_data_split_i = 0 - trainer.validate_epoch( - model=model, dataloader_val=dataloader_val, epoch=epoch + 1, writer=writer - ) + trainer.validate_epoch(model=model, dataloader_val=dataloader_val, epoch=epoch + 1) scheduler.step() trainer.step_in_epoch = 0 trainer.save_checkpoint( diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 71889214d..f3a0309b8 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -128,6 +128,14 @@ class Trainer: job_type="training", reinit=True, ) + tensorboard_dir = os.path.join(output_dir, "tensorboard") + os.makedirs(tensorboard_dir, exist_ok=True) + try: + from tensorboardX import SummaryWriter + + self.writer = SummaryWriter(tensorboard_dir) # if trainer.rank == 0 else None + except: + self.writer = None def save_checkpoint( self, @@ -331,7 +339,6 @@ class Trainer: dataloader_train=None, dataloader_val=None, epoch=None, - writer=None, **kwargs, ): """ @@ -356,14 +363,19 @@ class Trainer: time_beg = time.perf_counter() time5 = time_beg for batch_idx, batch in enumerate(dataloader_train): - if self.use_ddp or self.use_fsdp: - dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) - if iterator_stop > 0: - break + loss_dict = { + "speed_stats": {}, + "epoch": epoch, + "batch_idx": batch_idx, + "data_split_i": kwargs.get("data_split_i", 0), + "data_split_num": kwargs.get("data_split_num", 1), + "log_step": batch_idx + kwargs.get("start_step", 0), + } + self.batch_total += 1 self.step_in_epoch += 1 time1 = time.perf_counter() - speed_stats["data_load"] = f"{time1-time_beg:0.3f}" + loss_dict["speed_stats"]["data_load"] = f"{time1-time_beg:0.3f}" batch = to_device(batch, self.device) @@ -372,28 +384,28 @@ class Trainer: my_context = model.no_sync if batch_idx % accum_grad != 0 else my_context with my_context(): time2 = time.perf_counter() - loss_dict = {} + self.forward_step(model, batch, loss_dict=loss_dict) time3 = time.perf_counter() - speed_stats["forward_time"] = f"{time3 - time2:0.3f}" + loss_dict["speed_stats"]["forward_time"] = f"{time3 - time2:0.3f}" self.backward_step(model, scaler, loss_dict=loss_dict) time4 = time.perf_counter() - speed_stats["backward_and_AllReaduce_time"] = f"{time4 - time3:0.3f}" - - # self.train_loss_avg = ( - # self.train_loss_avg * (batch_idx + kwargs.get("start_step", 0)) - # + loss.detach().cpu().item() - # ) / (batch_idx + kwargs.get("start_step", 0) + 1) - # if "acc" in stats: - # self.train_acc_avg = ( - # self.train_acc_avg * (batch_idx + kwargs.get("start_step", 0)) - # + stats["acc"].detach().cpu().item() - # ) / (batch_idx + kwargs.get("start_step", 0) + 1) + loss_dict["speed_stats"]["backward_time"] = f"{time4 - time3:0.3f}" self.update_step(model, optim, scheduler, scaler, loss_dict) - # Perform an optimizer step only after accumulating enough gradients + total_time = f"{(time.perf_counter() - time5) / accum_grad:0.3f}" + time5 = time.perf_counter() + + loss_dict["speed_stats"]["optim_time"] = f"{time5 - time4:0.3f}" + + loss_dict["speed_stats"]["total_time"] = total_time + + loss_dict["lr"] = scheduler.get_last_lr()[0] + loss_dict["batch_num_epoch"] = len(dataloader_train) + + self.log(loss_dict, tag="train") if self.step_in_epoch % self.validate_interval == 0: self.validate_epoch( @@ -434,28 +446,8 @@ class Trainer: with maybe_autocast(self.use_fp16): retval = model(**batch) - if ( - self.reset_gpu_cache - and (torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024) > 70 - ): - torch.cuda.empty_cache() - loss, stats, weight = retval stats = {k: v for k, v in stats.items() if v is not None} - # if self.use_ddp or self.use_fsdp: - # # Apply weighted averaging for loss and stats - # loss = (loss * weight.type(loss.dtype)).sum() - # # if distributed, this method can also apply all_reduce() - # # stats, weight = recursive_average(stats, weight, distributed=True) - # if self.use_ddp or self.use_fsdp: - # dist.all_reduce(weight, op=dist.ReduceOp.SUM) - # # Now weight is summation over all workers - # loss /= weight.sum() # shape:[1] -> shape:[] - # # Multiply world_size because DistributedDataParallel - # # automatically normalizes the gradient by world_size. - # loss *= self.world_size - # loss *= self.world_size - # Scale the loss since we're not updating for every mini-batch loss_dict["loss"] = loss loss_dict["stats"] = stats @@ -474,68 +466,36 @@ class Trainer: loss.backward() def update_step(self, model, optim, scheduler, scaler, batch_idx=0, loss_dict=loss_dict): - if (batch_idx + 1) % self.accum_grad == 0: - # Perform gradient clipping if it is set - if self.grad_clip > 0: - grad_norm = torch.nn.utils.clip_grad_norm_( - model.parameters(), - max_norm=self.grad_clip, - norm_type=self.grad_clip_type, - ) - if not torch.isfinite(grad_norm): - logging.warning(f"The grad norm is {grad_norm}. Skipping updating the model.") - optim.zero_grad() # Reset gradients - return - # Execute an optimization step (update model parameters) - if self.use_ddp or self.use_fsdp: - dist.barrier() - if self.use_fp16: - scaler.step(optim) - scaler.update() - else: - optim.step() - scheduler.step() - # Clear gradients for the next accumulation stage - optim.zero_grad(set_to_none=True) + if self.use_deepspeed: + model.step() + else: + if (batch_idx + 1) % self.accum_grad == 0: + # Perform gradient clipping if it is set + if self.grad_clip > 0: + grad_norm = torch.nn.utils.clip_grad_norm_( + model.parameters(), + max_norm=self.grad_clip, + norm_type=self.grad_clip_type, + ) + if not torch.isfinite(grad_norm): + logging.warning( + f"The grad norm is {grad_norm}. Skipping updating the model." + ) + optim.zero_grad() # Reset gradients + return - if self.use_ddp or self.use_fsdp: - train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to( - self.device - ) - train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to( - self.device - ) - dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) - self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size - self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size - - total_time = f"{(time.perf_counter() - time5) / accum_grad:0.3f}" - time5 = time.perf_counter() - - speed_stats["optim_time"] = f"{time5 - time4:0.3f}" - - speed_stats["total_time"] = total_time - lr = scheduler.get_last_lr()[0] - batch_num_epoch = 1 - if hasattr(dataloader_train, "__len__"): - batch_num_epoch = len(dataloader_train) - self.log( - epoch, - batch_idx, - log_step=batch_idx + kwargs.get("start_step", 0), - step_in_epoch=self.step_in_epoch, - batch_num_epoch=batch_num_epoch, - lr=lr, - loss=loss.detach().cpu().item(), - speed_stats=speed_stats, - stats=stats, - writer=writer, - tag="train", - data_split_i=kwargs.get("data_split_i", 0), - data_split_num=kwargs.get("data_split_num", 1), - ) + # Execute an optimization step (update model parameters) + if self.use_ddp or self.use_fsdp: + dist.barrier() + if self.use_fp16: + scaler.step(optim) + scaler.update() + else: + optim.step() + scheduler.step() + # Clear gradients for the next accumulation stage + optim.zero_grad(set_to_none=True) def validate_epoch( self, @@ -646,21 +606,22 @@ class Trainer: def log( self, - epoch=0, - batch_idx=0, - step_in_epoch=0, - batch_num_epoch=-1, - lr=0.0, - loss=0.0, - speed_stats=None, - stats=None, - writer=None, + loss_dict: dict = None, tag="train", - data_split_i=0, - data_split_num=1, - log_step=None, **kwargs, ): + loss = loss_dict["loss"].detach().cpu().item() + epoch = loss_dict["epoch"] + batch_idx = loss_dict["batch_idx"] + step_in_epoch = loss_dict["step_in_epoch"] + batch_num_epoch = loss_dict["batch_num_epoch"] + lr = loss_dict["lr"] + + speed_stats = loss_dict["speed_stats"] + stats = loss_dict["stats"] + data_split_i = loss_dict["data_split_i"] + data_split_num = loss_dict["data_split_num"] + log_step = loss_dict.get("log_step", None) if (batch_idx + 1) % self.log_interval == 0: batch_idx = log_step if log_step is not None else batch_idx @@ -700,6 +661,7 @@ class Trainer: f"rank{self.rank}_lr/{tag}": lr, } + writer = self.writer if writer is not None: writer.add_scalar(f"rank{self.rank}_loss/{tag}", loss, self.batch_total) writer.add_scalar(f"rank{self.rank}_lr/{tag}", lr, self.batch_total) @@ -798,3 +760,46 @@ class Trainer: model = model.to(device=kwargs.get("device", "cuda")) return model + + def warp_optim_scheduler(self, model, **kwargs): + + # optim + logging.info("Build optim") + optim = kwargs.get("optim", "adam") + assert optim in optim_classes + optim_class = optim_classes.get(optim) + optim = optim_class(model.parameters(), **kwargs.get("optim_conf")) + + # scheduler + logging.info("Build scheduler") + scheduler = kwargs.get("scheduler", "warmuplr") + assert scheduler in scheduler_classes + scheduler_class = scheduler_classes.get(scheduler) + scheduler = scheduler_class(optim, **kwargs.get("scheduler_conf")) + + if use_deepspeed: + deepspeed_config = kwargs.get("deepspeed_config", "") + with open(deepspeed_config, "r") as fin: + ds_configs = json.load(fin) + if "optimizer" in ds_configs: + # NOTE(xcsong): Disable custom optimizer if it is set in ds_config, + # extremely useful when enable cpu_offload, DeepspeedCpuAdam + # could be 4~5x faster than torch native adam + deepspeed_config = None + if "scheduler" in ds_configs: + scheduler = None + else: + + def scheduler(opt): + return scheduler_class(opt, **kwargs.get("scheduler_conf")) + + args = OmegaConf.create({"deepspeed_config": deepspeed_config}) + model, optimizer, _, scheduler = deepspeed.initialize( + args=args, + model=model, + optimizer=optim, + lr_scheduler=scheduler, + model_parameters=model.parameters(), + ) + + return model, optim, scheduler From d3ff05837bbc14749d09f44947633b87e8f2db0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 17 May 2024 11:47:27 +0800 Subject: [PATCH 051/125] deepspeed --- funasr/bin/train_ds.py | 2 +- funasr/models/sanm/attention.py | 16 ++++-- funasr/models/sense_voice/decoder.py | 4 +- .../models/sense_voice/whisper_lib/model.py | 4 +- funasr/train_utils/trainer_ds.py | 52 +++++++------------ 5 files changed, 38 insertions(+), 40 deletions(-) diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index 032a0cf80..b0931b016 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -133,7 +133,7 @@ def main(**kwargs): kwargs["device"] = next(model.parameters()).device trainer.device = kwargs["device"] - model, optim, scheduler = trainer.warp_optim_scheduler(model, kwargs) + model, optim, scheduler = trainer.warp_optim_scheduler(model, **kwargs) # dataset logging.info("Build dataloader") diff --git a/funasr/models/sanm/attention.py b/funasr/models/sanm/attention.py index da8850fe5..08f7dc7f5 100644 --- a/funasr/models/sanm/attention.py +++ b/funasr/models/sanm/attention.py @@ -100,7 +100,9 @@ class MultiHeadedAttention(nn.Module): n_batch = value.size(0) if mask is not None: mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) scores = scores.masked_fill(mask, min_value) self.attn = torch.softmax(scores, dim=-1).masked_fill( mask, 0.0 @@ -269,7 +271,9 @@ class MultiHeadedAttentionSANM(nn.Module): mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) scores = scores.masked_fill(mask, min_value) self.attn = torch.softmax(scores, dim=-1).masked_fill( mask, 0.0 @@ -673,7 +677,9 @@ class MultiHeadedAttentionCrossAtt(nn.Module): n_batch = value.size(0) if mask is not None: mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) # logging.info( # "scores: {}, mask_size: {}".format(scores.size(), mask.size())) scores = scores.masked_fill(mask, min_value) @@ -858,7 +864,9 @@ class MultiHeadSelfAttention(nn.Module): mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) scores = scores.masked_fill(mask, min_value) self.attn = torch.softmax(scores, dim=-1).masked_fill( mask, 0.0 diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 03b753246..60af29ab8 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -146,7 +146,9 @@ class MultiHeadAttention(nn.Module): qk = qk + mask[:n_ctx, :n_ctx] else: mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min) qk = qk.masked_fill(mask, min_value) qk = qk.float() diff --git a/funasr/models/sense_voice/whisper_lib/model.py b/funasr/models/sense_voice/whisper_lib/model.py index 40939df69..8b3d3ab1c 100644 --- a/funasr/models/sense_voice/whisper_lib/model.py +++ b/funasr/models/sense_voice/whisper_lib/model.py @@ -112,7 +112,9 @@ class MultiHeadAttention(nn.Module): qk = qk + mask[:n_ctx, :n_ctx] else: mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min) + min_value = -float( + "inf" + ) # min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min) qk = qk.masked_fill(mask, min_value) qk = qk.float() diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index f3a0309b8..aa3c5afb9 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -78,7 +78,7 @@ class Trainer: self.world_size = world_size self.use_ddp = use_ddp self.use_fsdp = use_fsdp - self.use_deepspeed = use_deepspeed + self.device = kwargs.get("device", "cuda") self.output_dir = output_dir @@ -137,6 +137,9 @@ class Trainer: except: self.writer = None + self.use_deepspeed = use_deepspeed + self.deepspeed_config = kwargs.get("deepspeed_config", "") + def save_checkpoint( self, epoch, @@ -443,7 +446,8 @@ class Trainer: iterator_stop = torch.tensor(0).to(self.device) def forward_step(self, model, batch, loss_dict={}): - with maybe_autocast(self.use_fp16): + dtype = torch.bfloat16 + with torch.cuda.amp.autocast(enabled=True, dtype=dtype, cache_enabled=False): retval = model(**batch) loss, stats, weight = retval @@ -465,7 +469,7 @@ class Trainer: else: loss.backward() - def update_step(self, model, optim, scheduler, scaler, batch_idx=0, loss_dict=loss_dict): + def update_step(self, model, optim, scheduler, scaler, batch_idx=0, loss_dict=None): if self.use_deepspeed: model.step() @@ -613,7 +617,7 @@ class Trainer: loss = loss_dict["loss"].detach().cpu().item() epoch = loss_dict["epoch"] batch_idx = loss_dict["batch_idx"] - step_in_epoch = loss_dict["step_in_epoch"] + step_in_epoch = self.step_in_epoch batch_num_epoch = loss_dict["batch_num_epoch"] lr = loss_dict["lr"] @@ -732,36 +736,18 @@ class Trainer: "find_unused_parameters", False ), ) - # elif self.use_fsdp: - # # model = FSDP(model).cuda(local_rank) - # - # def custom_auto_wrap_policy( - # module: nn.Module, - # recurse: bool, - # nonwrapped_numel: int, - # # Additional custom arguments - # min_num_params: int = int(1e8), - # ) -> bool: - # # 根据自定义逻辑决定是否包装模块 - # is_large = unwrapped_params >= min_num_params - # requires_grad_uniform = len({p.requires_grad for p in module.parameters()}) == 1 - # return is_large and requires_grad_uniform - # - # # Configure a custom `min_num_params` - # my_auto_wrap_policy = functools.partial(custom_auto_wrap_policy, min_num_params=int(1e5)) - # torch.cuda.set_device(local_rank) - # model = FSDP( - # model, - # auto_wrap_policy=custom_auto_wrap_policy, - # mixed_precision=None, - # device_id=torch.cuda.current_device(), - # ) + else: model = model.to(device=kwargs.get("device", "cuda")) return model def warp_optim_scheduler(self, model, **kwargs): + from funasr.optimizers import optim_classes + from funasr.schedulers import scheduler_classes + from omegaconf import OmegaConf, DictConfig + import json + import deepspeed # optim logging.info("Build optim") @@ -777,15 +763,16 @@ class Trainer: scheduler_class = scheduler_classes.get(scheduler) scheduler = scheduler_class(optim, **kwargs.get("scheduler_conf")) - if use_deepspeed: - deepspeed_config = kwargs.get("deepspeed_config", "") - with open(deepspeed_config, "r") as fin: + if self.use_deepspeed: + + args = OmegaConf.create({"deepspeed_config": self.deepspeed_config}) + with open(self.deepspeed_config, "r") as fin: ds_configs = json.load(fin) if "optimizer" in ds_configs: # NOTE(xcsong): Disable custom optimizer if it is set in ds_config, # extremely useful when enable cpu_offload, DeepspeedCpuAdam # could be 4~5x faster than torch native adam - deepspeed_config = None + optim = None if "scheduler" in ds_configs: scheduler = None else: @@ -793,7 +780,6 @@ class Trainer: def scheduler(opt): return scheduler_class(opt, **kwargs.get("scheduler_conf")) - args = OmegaConf.create({"deepspeed_config": deepspeed_config}) model, optimizer, _, scheduler = deepspeed.initialize( args=args, model=model, From 86ada491e01691c53fd72fa76b8c77294042f938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 17 May 2024 12:38:24 +0800 Subject: [PATCH 052/125] deepspeed --- funasr/bin/train_ds.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index b0931b016..03cb18479 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -130,8 +130,8 @@ def main(**kwargs): model = trainer.warp_model(model) - kwargs["device"] = next(model.parameters()).device - trainer.device = kwargs["device"] + kwargs["device"] = int(os.environ.get("LOCAL_RANK", 0)) + trainer.device = int(os.environ.get("LOCAL_RANK", 0)) model, optim, scheduler = trainer.warp_optim_scheduler(model, **kwargs) From 1ca314955fbe150db9a3f40193ca10736a9a4260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 17 May 2024 13:32:51 +0800 Subject: [PATCH 053/125] deepspeed --- funasr/train_utils/trainer_ds.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index aa3c5afb9..72f7b7500 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -397,7 +397,7 @@ class Trainer: time4 = time.perf_counter() loss_dict["speed_stats"]["backward_time"] = f"{time4 - time3:0.3f}" - self.update_step(model, optim, scheduler, scaler, loss_dict) + self.update_step(model, optim, scheduler, scaler, loss_dict=loss_dict) total_time = f"{(time.perf_counter() - time5) / accum_grad:0.3f}" time5 = time.perf_counter() @@ -415,7 +415,7 @@ class Trainer: model=model, dataloader_val=dataloader_val, epoch=epoch, - writer=writer, + writer=self.writer, step=batch_idx + 1, step_in_epoch=self.step_in_epoch, ) @@ -469,8 +469,8 @@ class Trainer: else: loss.backward() - def update_step(self, model, optim, scheduler, scaler, batch_idx=0, loss_dict=None): - + def update_step(self, model, optim, scheduler, scaler, loss_dict=None): + batch_idx = loss_dict["batch_idx"] if self.use_deepspeed: model.step() else: @@ -747,7 +747,6 @@ class Trainer: from funasr.schedulers import scheduler_classes from omegaconf import OmegaConf, DictConfig import json - import deepspeed # optim logging.info("Build optim") @@ -764,6 +763,7 @@ class Trainer: scheduler = scheduler_class(optim, **kwargs.get("scheduler_conf")) if self.use_deepspeed: + import deepspeed args = OmegaConf.create({"deepspeed_config": self.deepspeed_config}) with open(self.deepspeed_config, "r") as fin: From b85e140c3e4a7a7ccba59abfc67b63aac7a28dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 17 May 2024 17:28:56 +0800 Subject: [PATCH 054/125] update --- funasr/train_utils/trainer_ds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 72f7b7500..8afbc6d1b 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -398,7 +398,7 @@ class Trainer: loss_dict["speed_stats"]["backward_time"] = f"{time4 - time3:0.3f}" self.update_step(model, optim, scheduler, scaler, loss_dict=loss_dict) - total_time = f"{(time.perf_counter() - time5) / accum_grad:0.3f}" + total_time = f"{(time.perf_counter() - time5):0.3f}" time5 = time.perf_counter() loss_dict["speed_stats"]["optim_time"] = f"{time5 - time4:0.3f}" From ff8aaea64b6e7383a96adb14c0c71c21829d1695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 11:26:31 +0800 Subject: [PATCH 055/125] ds --- .../audio_datasets/espnet_samplers.py | 4 +- funasr/train_utils/trainer_ds.py | 461 ++++++++++++------ 2 files changed, 312 insertions(+), 153 deletions(-) diff --git a/funasr/datasets/audio_datasets/espnet_samplers.py b/funasr/datasets/audio_datasets/espnet_samplers.py index 528f59333..b358fa379 100644 --- a/funasr/datasets/audio_datasets/espnet_samplers.py +++ b/funasr/datasets/audio_datasets/espnet_samplers.py @@ -72,6 +72,7 @@ class EspnetStyleBatchSampler(DistributedSampler): self.min_token_length = kwargs.get("min_token_length", 0) self.length_scale_source = kwargs.get("length_scale_source", 1.0) self.start_step = start_step + self.batch_num = 1 if self.start_step > 0: logging.info(f"Warning, start_step > 0, dataloader start from step: {self.start_step}") # super().__init__(dataset, num_replicas=num_replicas, rank=rank, @@ -146,6 +147,7 @@ class EspnetStyleBatchSampler(DistributedSampler): start_idx = self.rank * batches_per_rank end_idx = start_idx + batches_per_rank rank_batches = buffer_batches[start_idx + self.start_step : end_idx] + self.batch_num = len(rank_batches) logging.info( f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {end_idx-start_idx}, batch_num_after_step: {len(rank_batches)}" ) @@ -154,7 +156,7 @@ class EspnetStyleBatchSampler(DistributedSampler): def __len__(self): # Calculate the number of batches per epoch for the current rank - return 1 + return self.batch_num def set_epoch(self, epoch): # Set the epoch for shuffling diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 8afbc6d1b..78cfceb37 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -23,12 +23,16 @@ except: @contextmanager -def maybe_autocast(enabled): - if enabled: - with autocast(): +def maybe_autocast(dtype=None, use_deepspeed=False): + if use_deepspeed: + with torch.cuda.amp.autocast(enabled=True, dtype=dtype, cache_enabled=False): yield else: - yield + if dtype == torch.float16: + with autocast(enabled=True): + yield + else: + yield class Trainer: @@ -91,7 +95,10 @@ class Trainer: # self.kwargs = kwargs self.log_interval = kwargs.get("log_interval", 50) self.batch_total = 0 + self.dtype = torch.float32 self.use_fp16 = use_fp16 + if self.use_fp16: + self.dtype = torch.float16 self.save_checkpoint_interval = kwargs.get("save_checkpoint_interval", 5000) self.validate_interval = kwargs.get("validate_interval", 5000) self.keep_nbest_models = kwargs.get("keep_nbest_models", 500) @@ -159,7 +166,113 @@ class Trainer: Args: epoch (int): The epoch number at which the checkpoint is being saved. """ + step_in_epoch = None if step is None else step_in_epoch + if self.use_deepspeed: + with torch.no_grad(): + model.save_checkpoint(save_dir=model_dir, tag=tag, client_state=info_dict) + logging.info(f"Save checkpoint: {epoch}, rank: {self.local_rank}\n") + # self.step_or_epoch += 1 + state = { + "epoch": epoch, + # "state_dict": model.state_dict(), + # "optimizer": optim.state_dict(), + # "scheduler": scheduler.state_dict(), + "saved_ckpts": self.saved_ckpts, + "val_acc_step_or_eoch": self.val_acc_step_or_eoch, + "val_loss_step_or_eoch": self.val_loss_step_or_eoch, + "best_step_or_epoch": self.best_step_or_epoch, + "avg_keep_nbest_models_type": self.avg_keep_nbest_models_type, + "step": step, + "step_in_epoch": step_in_epoch, + "data_split_i": kwargs.get("data_split_i", 0), + "data_split_num": kwargs.get("data_split_num", 1), + "batch_total": self.batch_total, + "train_loss_avg": kwargs.get("train_loss_avg", 0), + "train_acc_avg": kwargs.get("train_acc_avg", 0), + } + step = step_in_epoch + if hasattr(model, "module"): + state["state_dict"] = model.module.state_dict() + if scaler: + state["scaler_state"] = scaler.state_dict() + # Create output directory if it does not exist + os.makedirs(self.output_dir, exist_ok=True) + if step is None: + ckpt_name = f"model.pt.ep{epoch}" + else: + ckpt_name = f"model.pt.ep{epoch}.{step}" + filename = os.path.join(self.output_dir, ckpt_name) + + # torch.save(state, filename) + with torch.no_grad(): + model.save_checkpoint(save_dir=self.output_dir, tag=ckpt_name, client_state=state) + logging.info(f"\nCheckpoint saved to {filename}\n") + latest = Path(os.path.join(self.output_dir, f"model.pt")) + # torch.save(state, latest) + with torch.no_grad(): + model.save_checkpoint(save_dir=self.output_dir, tag=f"model.pt", client_state=state) + if self.best_step_or_epoch == "": + self.best_step_or_epoch = ckpt_name + + if self.avg_keep_nbest_models_type == "acc": + if ( + self.val_acc_step_or_eoch[ckpt_name] + >= self.val_acc_step_or_eoch[self.best_step_or_epoch] + ): + self.best_step_or_epoch = ckpt_name + best_ckpt = Path(os.path.join(self.output_dir, f"model.pt.best")) + # torch.save(state, best_ckpt) + with torch.no_grad(): + model.save_checkpoint( + save_dir=self.output_dir, tag=f"model.pt.best", client_state=state + ) + logging.info( + f"Update best acc: {self.val_acc_step_or_eoch[self.best_step_or_epoch]:.4f}, {best_ckpt}" + ) + else: + logging.info( + f"No improvement in acc: {self.val_acc_step_or_eoch[ckpt_name]:.4f} < {self.val_acc_step_or_eoch[self.best_step_or_epoch]:.4f}, {os.path.join(self.output_dir, self.best_step_or_epoch)}" + ) + elif self.avg_keep_nbest_models_type == "loss": + if ( + self.val_loss_step_or_eoch[ckpt_name] + <= self.val_loss_step_or_eoch[self.best_step_or_epoch] + ): + self.best_step_or_epoch = ckpt_name + best_ckpt = Path(os.path.join(self.output_dir, f"model.pt.best")) + # torch.save(state, best_ckpt) + with torch.no_grad(): + model.save_checkpoint( + save_dir=self.output_dir, tag=f"model.pt.best", client_state=state + ) + logging.info( + f"Update best loss: {self.val_loss_step_or_eoch[self.best_step_or_epoch]:.4f}, {best_ckpt}" + ) + else: + logging.info( + f"No improvement in loss: {self.val_loss_step_or_eoch[ckpt_name]:.4f} > {self.val_loss_step_or_eoch[self.best_step_or_epoch]:.4f}, {os.path.join(self.output_dir, self.best_step_or_epoch)}" + ) + else: + print("Undo") + self.saved_ckpts[ckpt_name] = getattr( + self, f"val_{self.avg_keep_nbest_models_type}_step_or_eoch" + )[ckpt_name] + if self.keep_nbest_models > 0: + if len(self.saved_ckpts) > self.keep_nbest_models: + if self.avg_keep_nbest_models_type == "acc": + key = min(self.saved_ckpts, key=self.saved_ckpts.get) + else: + key = max(self.saved_ckpts, key=self.saved_ckpts.get) + if key in self.saved_ckpts: + del self.saved_ckpts[key] + filename = os.path.join(self.output_dir, key) + logging.info(f"Delete: {filename}") + if os.path.exists(filename): + os.remove(filename) + + elif self.use_fsdp: + pass step_in_epoch = None if step is None else step_in_epoch if self.rank == 0: logging.info(f"Save checkpoint: {epoch}, rank: {self.local_rank}\n") @@ -269,66 +382,117 @@ class Trainer: resume_path (str): The file path to the checkpoint to resume from. """ if self.resume: - ckpt = os.path.join(self.output_dir, "model.pt") - if os.path.isfile(ckpt): - checkpoint = torch.load(ckpt, map_location="cpu") - self.start_epoch = checkpoint["epoch"] - # self.model.load_state_dict(checkpoint['state_dict']) - src_state = checkpoint["state_dict"] - dst_state = model.state_dict() - for k in dst_state.keys(): - if not k.startswith("module.") and "module." + k in src_state.keys(): - k_ddp = "module." + k - elif k.startswith("module.") and "module." + k not in src_state.keys(): - k_ddp = k.replace("module.", "", 1) - else: - k_ddp = k - if k_ddp in src_state.keys(): - dst_state[k] = src_state[k_ddp] - else: - print(f"Miss key in ckpt: model: {k}, ckpt: {k_ddp}") - model.load_state_dict(dst_state) - optim.load_state_dict(checkpoint["optimizer"]) - scheduler.load_state_dict(checkpoint["scheduler"]) - if scaler is not None and "scaler_state" in checkpoint: - scaler.load_state_dict(checkpoint["scaler_state"]) + if self.use_deepspeed: + ckpt = os.path.join(self.output_dir, "model.pt") + if os.path.isfile(ckpt): + _, checkpoint = model_engine.load_checkpoint(self.output_dir, "model.pt") - self.saved_ckpts = checkpoint["saved_ckpts"] - self.val_acc_step_or_eoch = ( - checkpoint["val_acc_step_or_eoch"] - if "val_acc_step_or_eoch" in checkpoint - else {} - ) - self.val_loss_step_or_eoch = ( - checkpoint["val_loss_step_or_eoch"] - if "val_loss_step_or_eoch" in checkpoint - else {} - ) - self.best_step_or_epoch = ( - checkpoint["best_step_or_epoch"] if "best_step_or_epoch" in checkpoint else "" - ) - self.start_data_split_i = ( - checkpoint["data_split_i"] if "data_split_i" in checkpoint else 0 - ) - self.batch_total = checkpoint["batch_total"] if "batch_total" in checkpoint else 0 - self.start_step = checkpoint["step"] if "step" in checkpoint else 0 - self.start_step = 0 if self.start_step is None else self.start_step - self.step_in_epoch = ( - checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 - ) - self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch - print(checkpoint["train_acc_avg"]) - self.train_acc_avg = ( - checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 - ) - self.train_loss_avg = ( - checkpoint["train_loss_avg"] if "train_loss_avg" in checkpoint else 0 - ) - model.to(self.device) - print(f"Checkpoint loaded successfully from '{ckpt}'") + self.saved_ckpts = checkpoint["saved_ckpts"] + self.val_acc_step_or_eoch = ( + checkpoint["val_acc_step_or_eoch"] + if "val_acc_step_or_eoch" in checkpoint + else {} + ) + self.val_loss_step_or_eoch = ( + checkpoint["val_loss_step_or_eoch"] + if "val_loss_step_or_eoch" in checkpoint + else {} + ) + self.best_step_or_epoch = ( + checkpoint["best_step_or_epoch"] + if "best_step_or_epoch" in checkpoint + else "" + ) + self.start_data_split_i = ( + checkpoint["data_split_i"] if "data_split_i" in checkpoint else 0 + ) + self.batch_total = ( + checkpoint["batch_total"] if "batch_total" in checkpoint else 0 + ) + self.start_step = checkpoint["step"] if "step" in checkpoint else 0 + self.start_step = 0 if self.start_step is None else self.start_step + self.step_in_epoch = ( + checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 + ) + self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch + print(checkpoint["train_acc_avg"]) + self.train_acc_avg = ( + checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 + ) + self.train_loss_avg = ( + checkpoint["train_loss_avg"] if "train_loss_avg" in checkpoint else 0 + ) + model.to(self.device) + print(f"Checkpoint loaded successfully from '{ckpt}'") + else: + print(f"No checkpoint found at '{ckpt}', does not resume status!") else: - print(f"No checkpoint found at '{ckpt}', does not resume status!") + + ckpt = os.path.join(self.output_dir, "model.pt") + if os.path.isfile(ckpt): + checkpoint = torch.load(ckpt, map_location="cpu") + self.start_epoch = checkpoint["epoch"] + # self.model.load_state_dict(checkpoint['state_dict']) + src_state = checkpoint["state_dict"] + dst_state = model.state_dict() + for k in dst_state.keys(): + if not k.startswith("module.") and "module." + k in src_state.keys(): + k_ddp = "module." + k + elif k.startswith("module.") and "module." + k not in src_state.keys(): + k_ddp = k.replace("module.", "", 1) + else: + k_ddp = k + if k_ddp in src_state.keys(): + dst_state[k] = src_state[k_ddp] + else: + print(f"Miss key in ckpt: model: {k}, ckpt: {k_ddp}") + + model.load_state_dict(dst_state) + optim.load_state_dict(checkpoint["optimizer"]) + scheduler.load_state_dict(checkpoint["scheduler"]) + if scaler is not None and "scaler_state" in checkpoint: + scaler.load_state_dict(checkpoint["scaler_state"]) + + self.saved_ckpts = checkpoint["saved_ckpts"] + self.val_acc_step_or_eoch = ( + checkpoint["val_acc_step_or_eoch"] + if "val_acc_step_or_eoch" in checkpoint + else {} + ) + self.val_loss_step_or_eoch = ( + checkpoint["val_loss_step_or_eoch"] + if "val_loss_step_or_eoch" in checkpoint + else {} + ) + self.best_step_or_epoch = ( + checkpoint["best_step_or_epoch"] + if "best_step_or_epoch" in checkpoint + else "" + ) + self.start_data_split_i = ( + checkpoint["data_split_i"] if "data_split_i" in checkpoint else 0 + ) + self.batch_total = ( + checkpoint["batch_total"] if "batch_total" in checkpoint else 0 + ) + self.start_step = checkpoint["step"] if "step" in checkpoint else 0 + self.start_step = 0 if self.start_step is None else self.start_step + self.step_in_epoch = ( + checkpoint["step_in_epoch"] if "step_in_epoch" in checkpoint else 0 + ) + self.step_in_epoch = 0 if self.step_in_epoch is None else self.step_in_epoch + print(checkpoint["train_acc_avg"]) + self.train_acc_avg = ( + checkpoint["train_acc_avg"] if "train_acc_avg" in checkpoint else 0 + ) + self.train_loss_avg = ( + checkpoint["train_loss_avg"] if "train_loss_avg" in checkpoint else 0 + ) + model.to(self.device) + print(f"Checkpoint loaded successfully from '{ckpt}'") + else: + print(f"No checkpoint found at '{ckpt}', does not resume status!") if self.use_ddp or self.use_fsdp: dist.barrier() @@ -349,7 +513,7 @@ class Trainer: Args: epoch (int): The current epoch number. """ - if self.use_ddp or self.use_fsdp: + if self.use_ddp or self.use_fsdp or self.use_deepspeed: dist.barrier() logging.info(f"Train epoch: {epoch}, rank: {self.rank}\n") model.train() @@ -366,6 +530,8 @@ class Trainer: time_beg = time.perf_counter() time5 = time_beg for batch_idx, batch in enumerate(dataloader_train): + self.batch_total += 1 + self.step_in_epoch += 1 loss_dict = { "speed_stats": {}, "epoch": epoch, @@ -373,10 +539,10 @@ class Trainer: "data_split_i": kwargs.get("data_split_i", 0), "data_split_num": kwargs.get("data_split_num", 1), "log_step": batch_idx + kwargs.get("start_step", 0), + "batch_total": self.batch_total, + "step_in_epoch": self.step_in_epoch, } - self.batch_total += 1 - self.step_in_epoch += 1 time1 = time.perf_counter() loss_dict["speed_stats"]["data_load"] = f"{time1-time_beg:0.3f}" @@ -408,6 +574,14 @@ class Trainer: loss_dict["lr"] = scheduler.get_last_lr()[0] loss_dict["batch_num_epoch"] = len(dataloader_train) + self.val_loss_avg = ( + self.val_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() + ) / (batch_idx + 1) + if "acc" in stats: + self.val_acc_avg = ( + self.val_acc_avg * batch_idx + loss_dict["stats"]["acc"].detach().cpu().item() + ) / (batch_idx + 1) + self.log(loss_dict, tag="train") if self.step_in_epoch % self.validate_interval == 0: @@ -436,18 +610,18 @@ class Trainer: ) time_beg = time.perf_counter() - else: - if self.use_ddp or self.use_fsdp: - iterator_stop.fill_(1) - dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) - if self.use_ddp or self.use_fsdp: - dist.barrier() - iterator_stop = torch.tensor(0).to(self.device) + if self.use_ddp or self.use_fsdp or self.use_deepspeed: + val_loss_avg = torch.tensor(self.val_loss_avg, dtype=torch.float32).to(self.device) + val_acc_avg = torch.tensor(self.val_acc_avg, dtype=torch.float32).to(self.device) + dist.all_reduce(val_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(val_acc_avg, op=dist.ReduceOp.SUM) + self.val_loss_avg = val_loss_avg.detach().cpu().item() / self.world_size + self.val_acc_avg = val_acc_avg.detach().cpu().item() / self.world_size def forward_step(self, model, batch, loss_dict={}): dtype = torch.bfloat16 - with torch.cuda.amp.autocast(enabled=True, dtype=dtype, cache_enabled=False): + with maybe_autocast(dtype=self.dtype, use_deepspeed=self.use_deepspeed): retval = model(**batch) loss, stats, weight = retval @@ -516,7 +690,7 @@ class Trainer: Args: epoch (int): The current epoch number. """ - if self.use_ddp or self.use_fsdp: + if self.use_ddp or self.use_fsdp or self.use_deepspeed: dist.barrier() logging.info(f"Validate epoch: {epoch}, rank: {self.rank}\n") model.eval() @@ -524,77 +698,61 @@ class Trainer: with torch.no_grad(): speed_stats = {} - time5 = time.perf_counter() - iterator_stop = torch.tensor(0).to(self.device) + time_beg = time.perf_counter() + time5 = time_beg + dataloader_val.batch_sampler.set_epoch(epoch) for batch_idx, batch in enumerate(dataloader_val): - if self.use_ddp or self.use_fsdp: - dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) - if iterator_stop > 0: - break - time1 = time.perf_counter() - speed_stats["data_load"] = f"{time1 - time5:0.3f}" - batch = to_device(batch, self.device) - time2 = time.perf_counter() - retval = model(**batch) - time3 = time.perf_counter() - speed_stats["forward_time"] = f"{time3 - time2:0.3f}" - loss, stats, weight = retval - stats = {k: v for k, v in stats.items() if v is not None} - if self.use_ddp or self.use_fsdp: - # Apply weighted averaging for loss and stats - loss = (loss * weight.type(loss.dtype)).sum() - # if distributed, this method can also apply all_reduce() - # stats, weight = recursive_average(stats, weight, distributed=True) - if self.use_ddp or self.use_fsdp: - dist.all_reduce(weight, op=dist.ReduceOp.SUM) - # Now weight is summation over all workers - loss /= weight.sum() # shape:[1] -> shape:[] - # Multiply world_size because DistributedDataParallel - # automatically normalizes the gradient by world_size. - loss *= self.world_size - # Scale the loss since we're not updating for every mini-batch - loss = loss - time4 = time.perf_counter() - self.val_loss_avg = (self.val_loss_avg * batch_idx + loss.detach().cpu().item()) / ( - batch_idx + 1 - ) + loss_dict = { + "speed_stats": {}, + "epoch": epoch, + "batch_idx": batch_idx, + "data_split_i": kwargs.get("data_split_i", 0), + "data_split_num": kwargs.get("data_split_num", 1), + "log_step": batch_idx + kwargs.get("start_step", 0), + "batch_total": batch_idx, + "step_in_epoch": step_in_epoch, + "lr": 0.0, + } + + time1 = time.perf_counter() + loss_dict["speed_stats"]["data_load"] = f"{time1 - time_beg:0.3f}" + + batch = to_device(batch, self.device) + + time2 = time.perf_counter() + + self.forward_step(model, batch, loss_dict=loss_dict) + + time3 = time.perf_counter() + loss_dict["speed_stats"]["forward_time"] = f"{time3 - time2:0.3f}" + + total_time = f"{(time.perf_counter() - time5):0.3f}" + time5 = time.perf_counter() + + loss_dict["speed_stats"]["total_time"] = total_time + + loss_dict["batch_num_epoch"] = len(dataloader_val) + + self.log(loss_dict, tag="val") + time_beg = time.perf_counter() + self.val_loss_avg = ( + self.val_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() + ) / (batch_idx + 1) if "acc" in stats: self.val_acc_avg = ( - self.val_acc_avg * batch_idx + stats["acc"].detach().cpu().item() + self.val_acc_avg * batch_idx + + loss_dict["stats"]["acc"].detach().cpu().item() ) / (batch_idx + 1) - if self.use_ddp or self.use_fsdp: - val_loss_avg = torch.tensor(self.val_loss_avg, dtype=torch.float32).to( - self.device - ) - val_acc_avg = torch.tensor(self.val_acc_avg, dtype=torch.float32).to( - self.device - ) - dist.all_reduce(val_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(val_acc_avg, op=dist.ReduceOp.SUM) - self.val_loss_avg = val_loss_avg.detach().cpu().item() / self.world_size - self.val_acc_avg = val_acc_avg.detach().cpu().item() / self.world_size - time5 = time.perf_counter() - batch_num_epoch = 1 - if hasattr(dataloader_val, "__len__"): - batch_num_epoch = len(dataloader_val) - self.log( - epoch, - batch_idx, - batch_num_epoch=batch_num_epoch, - lr=0.0, - loss=loss.detach().cpu().item(), - speed_stats=speed_stats, - stats=stats, - writer=writer, - tag="val", - ) - else: - if self.use_ddp or self.use_fsdp: - iterator_stop.fill_(1) - dist.all_reduce(iterator_stop, dist.ReduceOp.SUM) + if self.use_ddp or self.use_fsdp or self.use_deepspeed: + val_loss_avg = torch.tensor(self.val_loss_avg, dtype=torch.float32).to(self.device) + val_acc_avg = torch.tensor(self.val_acc_avg, dtype=torch.float32).to(self.device) + dist.all_reduce(val_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(val_acc_avg, op=dist.ReduceOp.SUM) + self.val_loss_avg = val_loss_avg.detach().cpu().item() / self.world_size + self.val_acc_avg = val_acc_avg.detach().cpu().item() / self.world_size if kwargs.get("step_in_epoch", None) is None: ckpt_name = f"model.pt.ep{epoch}" @@ -604,10 +762,6 @@ class Trainer: self.val_loss_step_or_eoch[ckpt_name] = self.val_loss_avg model.train() - if self.use_ddp or self.use_fsdp: - dist.barrier() - iterator_stop = torch.tensor(0).to(self.device) - def log( self, loss_dict: dict = None, @@ -617,7 +771,8 @@ class Trainer: loss = loss_dict["loss"].detach().cpu().item() epoch = loss_dict["epoch"] batch_idx = loss_dict["batch_idx"] - step_in_epoch = self.step_in_epoch + step_in_epoch = loss_dict["step_in_epoch"] + batch_total = loss_dict["batch_total"] batch_num_epoch = loss_dict["batch_num_epoch"] lr = loss_dict["lr"] @@ -648,7 +803,7 @@ class Trainer: f"rank: {self.rank}, " f"epoch: {epoch}/{self.max_epoch}, " f"data_slice: {data_split_i}/{data_split_num}, " - f"step_in_slice: {batch_idx + 1}/{batch_num_epoch}, step_in_epoch: {step_in_epoch}, total step: {self.batch_total}, " + f"step_in_slice: {batch_idx + 1}/{batch_num_epoch}, step_in_epoch: {step_in_epoch}, total step: {batch_total}, " f"(loss_avg_rank: {loss:.3f}), " f"(loss_avg_slice: {loss_avg_epoch:.3f}), " f"(ppl_avg_slice: {math.exp(loss_avg_epoch):.3e}), " @@ -667,22 +822,18 @@ class Trainer: writer = self.writer if writer is not None: - writer.add_scalar(f"rank{self.rank}_loss/{tag}", loss, self.batch_total) - writer.add_scalar(f"rank{self.rank}_lr/{tag}", lr, self.batch_total) + writer.add_scalar(f"rank{self.rank}_loss/{tag}", loss, batch_total) + writer.add_scalar(f"rank{self.rank}_lr/{tag}", lr, batch_total) for key, var in stats.items(): - writer.add_scalar( - f"stats_rank{self.rank}_{key}/{tag}", var.item(), self.batch_total - ) + writer.add_scalar(f"stats_rank{self.rank}_{key}/{tag}", var.item(), batch_total) description_dict[f"stats_rank{self.rank}_{key}/{tag}"] = var.item() for key, var in speed_stats.items(): - writer.add_scalar( - f"stats_rank{self.rank}_{key}/{tag}", eval(var), self.batch_total - ) + writer.add_scalar(f"stats_rank{self.rank}_{key}/{tag}", eval(var), batch_total) description_dict[f"stats_rank{self.rank}_{key}/{tag}"] = eval(var) if self.use_wandb and wandb is not None: wandb.log( description_dict, - setp=self.batch_total, + setp=batch_total, ) def close(self, writer=None): @@ -768,6 +919,12 @@ class Trainer: args = OmegaConf.create({"deepspeed_config": self.deepspeed_config}) with open(self.deepspeed_config, "r") as fin: ds_configs = json.load(fin) + + if "bf16" in ds_configs and ds_configs["bf16"]["enabled"]: + self.dtype = torch.bfloat16 + + if "fp16" in ds_configs and ds_configs["fp16"]["enabled"]: + self.dtype = torch.float16 if "optimizer" in ds_configs: # NOTE(xcsong): Disable custom optimizer if it is set in ds_config, # extremely useful when enable cpu_offload, DeepspeedCpuAdam From 1e1500adadf5c7ed3622efa0f48f51b48a78b31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 11:33:14 +0800 Subject: [PATCH 056/125] ds --- funasr/train_utils/trainer_ds.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 78cfceb37..88a853c58 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -577,7 +577,7 @@ class Trainer: self.val_loss_avg = ( self.val_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() ) / (batch_idx + 1) - if "acc" in stats: + if "acc" in loss_dict["stats"]: self.val_acc_avg = ( self.val_acc_avg * batch_idx + loss_dict["stats"]["acc"].detach().cpu().item() ) / (batch_idx + 1) @@ -740,7 +740,7 @@ class Trainer: self.val_loss_avg = ( self.val_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() ) / (batch_idx + 1) - if "acc" in stats: + if "acc" in loss_dict["stats"]: self.val_acc_avg = ( self.val_acc_avg * batch_idx + loss_dict["stats"]["acc"].detach().cpu().item() From b3b10158097b10aa26ee3469c5ba8fd20c745de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 11:41:53 +0800 Subject: [PATCH 057/125] ds --- funasr/train_utils/trainer_ds.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 88a853c58..8a52746d0 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -574,12 +574,12 @@ class Trainer: loss_dict["lr"] = scheduler.get_last_lr()[0] loss_dict["batch_num_epoch"] = len(dataloader_train) - self.val_loss_avg = ( - self.val_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() + self.train_loss_avg = ( + self.train_loss_avg * batch_idx + loss_dict["loss"].detach().cpu().item() ) / (batch_idx + 1) if "acc" in loss_dict["stats"]: - self.val_acc_avg = ( - self.val_acc_avg * batch_idx + loss_dict["stats"]["acc"].detach().cpu().item() + self.train_acc_avg = ( + self.train_acc_avg * batch_idx + loss_dict["stats"]["acc"].detach().cpu().item() ) / (batch_idx + 1) self.log(loss_dict, tag="train") @@ -612,12 +612,12 @@ class Trainer: time_beg = time.perf_counter() if self.use_ddp or self.use_fsdp or self.use_deepspeed: - val_loss_avg = torch.tensor(self.val_loss_avg, dtype=torch.float32).to(self.device) - val_acc_avg = torch.tensor(self.val_acc_avg, dtype=torch.float32).to(self.device) - dist.all_reduce(val_loss_avg, op=dist.ReduceOp.SUM) - dist.all_reduce(val_acc_avg, op=dist.ReduceOp.SUM) - self.val_loss_avg = val_loss_avg.detach().cpu().item() / self.world_size - self.val_acc_avg = val_acc_avg.detach().cpu().item() / self.world_size + train_loss_avg = torch.tensor(self.train_loss_avg, dtype=torch.float32).to(self.device) + train_acc_avg = torch.tensor(self.train_acc_avg, dtype=torch.float32).to(self.device) + dist.all_reduce(train_loss_avg, op=dist.ReduceOp.SUM) + dist.all_reduce(train_acc_avg, op=dist.ReduceOp.SUM) + self.train_loss_avg = train_loss_avg.detach().cpu().item() / self.world_size + self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size def forward_step(self, model, batch, loss_dict={}): dtype = torch.bfloat16 From a19ee46d2c9d4a98951cbc9f592ff459d75b9f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 13:40:26 +0800 Subject: [PATCH 058/125] ds --- funasr/train_utils/average_nbest_models.py | 3 ++- funasr/train_utils/trainer_ds.py | 10 ++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/funasr/train_utils/average_nbest_models.py b/funasr/train_utils/average_nbest_models.py index 0f0880425..b10c23145 100644 --- a/funasr/train_utils/average_nbest_models.py +++ b/funasr/train_utils/average_nbest_models.py @@ -62,7 +62,8 @@ def average_checkpoints(output_dir: str, last_n: int = 5, **kwargs): # Check if we have any state_dicts to average if len(state_dicts) < 1: - raise RuntimeError("No checkpoints found for averaging.") + print("No checkpoints found for averaging.") + return # Average or sum weights avg_state_dict = OrderedDict() diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 8a52746d0..fead9ca08 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -168,8 +168,7 @@ class Trainer: """ step_in_epoch = None if step is None else step_in_epoch if self.use_deepspeed: - with torch.no_grad(): - model.save_checkpoint(save_dir=model_dir, tag=tag, client_state=info_dict) + logging.info(f"Save checkpoint: {epoch}, rank: {self.local_rank}\n") # self.step_or_epoch += 1 state = { @@ -273,8 +272,7 @@ class Trainer: elif self.use_fsdp: pass - step_in_epoch = None if step is None else step_in_epoch - if self.rank == 0: + elif self.rank == 0: logging.info(f"Save checkpoint: {epoch}, rank: {self.local_rank}\n") # self.step_or_epoch += 1 state = { @@ -385,7 +383,7 @@ class Trainer: if self.use_deepspeed: ckpt = os.path.join(self.output_dir, "model.pt") - if os.path.isfile(ckpt): + if os.path.exists(ckpt): _, checkpoint = model_engine.load_checkpoint(self.output_dir, "model.pt") self.saved_ckpts = checkpoint["saved_ckpts"] @@ -712,7 +710,7 @@ class Trainer: "data_split_num": kwargs.get("data_split_num", 1), "log_step": batch_idx + kwargs.get("start_step", 0), "batch_total": batch_idx, - "step_in_epoch": step_in_epoch, + "step_in_epoch": batch_idx, "lr": 0.0, } From 62acaf1158e9019cd49089d92175d47989bb1841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 13:42:42 +0800 Subject: [PATCH 059/125] ds --- funasr/train_utils/trainer_ds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index fead9ca08..bb9fca66c 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -384,7 +384,7 @@ class Trainer: if self.use_deepspeed: ckpt = os.path.join(self.output_dir, "model.pt") if os.path.exists(ckpt): - _, checkpoint = model_engine.load_checkpoint(self.output_dir, "model.pt") + _, checkpoint = model.load_checkpoint(self.output_dir, "model.pt") self.saved_ckpts = checkpoint["saved_ckpts"] self.val_acc_step_or_eoch = ( From 3de70601df378664905c665d327c4c9d20c81598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 15:17:51 +0800 Subject: [PATCH 060/125] ds --- docs/images/wechat.png | Bin 160542 -> 185531 bytes funasr/train_utils/average_nbest_models.py | 10 ++++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/images/wechat.png b/docs/images/wechat.png index 0ae18907cfcd63a4db277fa09f5f8e8829670978..4b603fe32be2397dd53a52de5fd52c78d01eb559 100644 GIT binary patch literal 185531 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ⅈ;u~3u*XM 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

v%I35nVV2hly)z{N- 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%0DE<_oP? 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 diff --git a/funasr/train_utils/average_nbest_models.py b/funasr/train_utils/average_nbest_models.py index b10c23145..8553baa98 100644 --- a/funasr/train_utils/average_nbest_models.py +++ b/funasr/train_utils/average_nbest_models.py @@ -16,7 +16,7 @@ from collections import OrderedDict from functools import cmp_to_key -def _get_checkpoint_paths(output_dir: str, last_n: int = 5): +def _get_checkpoint_paths(output_dir: str, last_n: int = 5, use_deepspeed=False): """ Get the paths of the last 'last_n' checkpoints by parsing filenames in the output directory. @@ -29,7 +29,13 @@ def _get_checkpoint_paths(output_dir: str, last_n: int = 5): sorted_items = ( sorted_items[:last_n] if avg_keep_nbest_models_type == "acc" else sorted_items[-last_n:] ) - checkpoint_paths = [os.path.join(output_dir, key) for key, value in sorted_items[:last_n]] + checkpoint_paths = [] + for key, value in sorted_items[:last_n]: + if not use_deepspeed: + ckpt = os.path.join(output_dir, key) + else: + ckpt = os.path.join(output_dir, key, "mp_rank_00_model_states.pt") + except: print(f"{checkpoint} does not exist, avg the lastet checkpoint.") # List all files in the output directory From bbd300a91184d09dec56a3b06734051dbd5812e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 15:27:24 +0800 Subject: [PATCH 061/125] ds --- funasr/bin/train_ds.py | 4 +++- funasr/train_utils/average_nbest_models.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index 03cb18479..a4ae11b68 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -198,7 +198,9 @@ def main(**kwargs): trainer.train_loss_avg = 0.0 if trainer.rank == 0: - average_checkpoints(trainer.output_dir, trainer.avg_nbest_model) + average_checkpoints( + trainer.output_dir, trainer.avg_nbest_model, use_deepspeed=trainer.use_deepspeed + ) trainer.close() diff --git a/funasr/train_utils/average_nbest_models.py b/funasr/train_utils/average_nbest_models.py index 8553baa98..20da13022 100644 --- a/funasr/train_utils/average_nbest_models.py +++ b/funasr/train_utils/average_nbest_models.py @@ -16,7 +16,7 @@ from collections import OrderedDict from functools import cmp_to_key -def _get_checkpoint_paths(output_dir: str, last_n: int = 5, use_deepspeed=False): +def _get_checkpoint_paths(output_dir: str, last_n: int = 5, use_deepspeed=False, **kwargs): """ Get the paths of the last 'last_n' checkpoints by parsing filenames in the output directory. @@ -55,7 +55,7 @@ def average_checkpoints(output_dir: str, last_n: int = 5, **kwargs): Average the last 'last_n' checkpoints' model state_dicts. If a tensor is of type torch.int, perform sum instead of average. """ - checkpoint_paths = _get_checkpoint_paths(output_dir, last_n) + checkpoint_paths = _get_checkpoint_paths(output_dir, last_n, **kwargs) print(f"average_checkpoints: {checkpoint_paths}") state_dicts = [] From 1ff66c526057d3e3f18a3f9084f1359701f056e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 16:13:07 +0800 Subject: [PATCH 062/125] add --- funasr/train_utils/trainer_ds.py | 7 +++++-- funasr/utils/misc.py | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index bb9fca66c..e3f426cc1 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -15,6 +15,7 @@ from funasr.train_utils.device_funcs import to_device from funasr.train_utils.recursive_op import recursive_average from funasr.train_utils.average_nbest_models import average_checkpoints from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler +import funasr.utils.misc as misc_utils try: import wandb @@ -268,7 +269,8 @@ class Trainer: filename = os.path.join(self.output_dir, key) logging.info(f"Delete: {filename}") if os.path.exists(filename): - os.remove(filename) + # os.remove(filename) + misc_utils.smart_remove(filename) elif self.use_fsdp: pass @@ -360,7 +362,8 @@ class Trainer: filename = os.path.join(self.output_dir, key) logging.info(f"Delete: {filename}") if os.path.exists(filename): - os.remove(filename) + # os.remove(filename) + misc_utils.smart_remove(filename) if self.use_ddp or self.use_fsdp: dist.barrier() diff --git a/funasr/utils/misc.py b/funasr/utils/misc.py index 4613cb316..eb17f9723 100644 --- a/funasr/utils/misc.py +++ b/funasr/utils/misc.py @@ -94,3 +94,26 @@ def extract_filename_without_extension(file_path): filename, extension = os.path.splitext(filename_with_extension) # 返回不包含扩展名的文件名 return filename + + +def smart_remove(path): + """Intelligently removes files, empty directories, and non-empty directories recursively.""" + # Check if the provided path exists + if not os.path.exists(path): + print(f"{path} does not exist.") + return + + # If the path is a file, delete it + if os.path.isfile(path): + os.remove(path) + print(f"File {path} has been deleted.") + # If the path is a directory + elif os.path.isdir(path): + try: + # Attempt to remove an empty directory + os.rmdir(path) + print(f"Empty directory {path} has been deleted.") + except OSError: + # If the directory is not empty, remove it along with all its contents + shutil.rmtree(path) + print(f"Non-empty directory {path} has been recursively deleted.") From 47c14aff79bb902482b0a953a55d31bf130c7b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 16:20:45 +0800 Subject: [PATCH 063/125] add --- funasr/train_utils/trainer_ds.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index e3f426cc1..db92bc8d5 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -712,8 +712,8 @@ class Trainer: "data_split_i": kwargs.get("data_split_i", 0), "data_split_num": kwargs.get("data_split_num", 1), "log_step": batch_idx + kwargs.get("start_step", 0), - "batch_total": batch_idx, - "step_in_epoch": batch_idx, + "batch_total": batch_idx + 1, + "step_in_epoch": batch_idx + 1, "lr": 0.0, } From 97522b10f661b004fbdbe234aa55ffd192578ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 20 May 2024 17:05:31 +0800 Subject: [PATCH 064/125] bugfix --- funasr/train_utils/average_nbest_models.py | 9 ++++++++- funasr/train_utils/trainer_ds.py | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/funasr/train_utils/average_nbest_models.py b/funasr/train_utils/average_nbest_models.py index 20da13022..67f1e55e8 100644 --- a/funasr/train_utils/average_nbest_models.py +++ b/funasr/train_utils/average_nbest_models.py @@ -22,7 +22,13 @@ def _get_checkpoint_paths(output_dir: str, last_n: int = 5, use_deepspeed=False, in the output directory. """ try: - checkpoint = torch.load(os.path.join(output_dir, "model.pt"), map_location="cpu") + if not use_deepspeed: + checkpoint = torch.load(os.path.join(output_dir, "model.pt"), map_location="cpu") + else: + checkpoint = torch.load( + os.path.join(output_dir, "model.pt", "mp_rank_00_model_states.pt"), + map_location="cpu", + ) avg_keep_nbest_models_type = checkpoint["avg_keep_nbest_models_type"] val_step_or_eoch = checkpoint[f"val_{avg_keep_nbest_models_type}_step_or_eoch"] sorted_items = sorted(val_step_or_eoch.items(), key=lambda x: x[1], reverse=True) @@ -35,6 +41,7 @@ def _get_checkpoint_paths(output_dir: str, last_n: int = 5, use_deepspeed=False, ckpt = os.path.join(output_dir, key) else: ckpt = os.path.join(output_dir, key, "mp_rank_00_model_states.pt") + checkpoint_paths.append(ckpt) except: print(f"{checkpoint} does not exist, avg the lastet checkpoint.") diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index db92bc8d5..1a553f812 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -388,7 +388,7 @@ class Trainer: ckpt = os.path.join(self.output_dir, "model.pt") if os.path.exists(ckpt): _, checkpoint = model.load_checkpoint(self.output_dir, "model.pt") - + self.start_epoch = checkpoint["epoch"] self.saved_ckpts = checkpoint["saved_ckpts"] self.val_acc_step_or_eoch = ( checkpoint["val_acc_step_or_eoch"] From 319e8691fa93d55d18d249f9132027a2b3592d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 10:46:05 +0800 Subject: [PATCH 065/125] add --- examples/wenetspeech/transformer/README.md | 16 ++ .../conf/transformer_12e_6d_2048_256.yaml | 104 +++++++++ .../wenetspeech/transformer/demo_infer.sh | 1 + .../transformer/demo_train_or_finetune.sh | 1 + .../transformer/local/aishell_data_prep.sh | 66 ++++++ .../transformer/local/download_and_untar.sh | 105 +++++++++ examples/wenetspeech/transformer/run.sh | 203 ++++++++++++++++++ examples/wenetspeech/transformer/utils | 1 + 8 files changed, 497 insertions(+) create mode 100644 examples/wenetspeech/transformer/README.md create mode 100644 examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml create mode 120000 examples/wenetspeech/transformer/demo_infer.sh create mode 120000 examples/wenetspeech/transformer/demo_train_or_finetune.sh create mode 100755 examples/wenetspeech/transformer/local/aishell_data_prep.sh create mode 100755 examples/wenetspeech/transformer/local/download_and_untar.sh create mode 100755 examples/wenetspeech/transformer/run.sh create mode 120000 examples/wenetspeech/transformer/utils diff --git a/examples/wenetspeech/transformer/README.md b/examples/wenetspeech/transformer/README.md new file mode 100644 index 000000000..2435b553b --- /dev/null +++ b/examples/wenetspeech/transformer/README.md @@ -0,0 +1,16 @@ + +# Conformer Result + +## Training Config +- Feature info: using 80 dims fbank, global cmvn, speed perturb(0.9, 1.0, 1.1), specaugment +- Train info: lr 5e-4, batch_size 25000, 2 gpu(Tesla V100), acc_grad 1, 50 epochs +- Train config: conf/train_asr_transformer.yaml +- LM config: LM was not used +- Model size: 46M + +## Results (CER) + +| testset | CER(%) | +|:-----------:|:------:| +| dev | 4.97 | +| test | 5.37 | \ No newline at end of file diff --git a/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml b/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml new file mode 100644 index 000000000..efcf593a5 --- /dev/null +++ b/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml @@ -0,0 +1,104 @@ +# This is an example that demonstrates how to configure a model file. +# You can modify the configuration according to your own requirements. + +# to print the register_table: +# from funasr.register import tables +# tables.print() + +# network architecture +model: Transformer +model_conf: + ctc_weight: 0.3 + lsm_weight: 0.1 # label smoothing option + length_normalized_loss: false + +# encoder +encoder: TransformerEncoder +encoder_conf: + output_size: 256 # dimension of attention + attention_heads: 4 + linear_units: 2048 # the number of units of position-wise feed forward + num_blocks: 12 # the number of encoder blocks + dropout_rate: 0.1 + positional_dropout_rate: 0.1 + attention_dropout_rate: 0.0 + input_layer: conv2d # encoder architecture type + normalize_before: true + +# decoder +decoder: TransformerDecoder +decoder_conf: + attention_heads: 4 + linear_units: 2048 + num_blocks: 6 + dropout_rate: 0.1 + positional_dropout_rate: 0.1 + self_attention_dropout_rate: 0.0 + src_attention_dropout_rate: 0.0 + + +# frontend related +frontend: WavFrontend +frontend_conf: + fs: 16000 + window: hamming + n_mels: 80 + frame_length: 25 + frame_shift: 10 + lfr_m: 1 + lfr_n: 1 + +specaug: SpecAug +specaug_conf: + apply_time_warp: true + time_warp_window: 5 + time_warp_mode: bicubic + apply_freq_mask: true + freq_mask_width_range: + - 0 + - 30 + num_freq_mask: 2 + apply_time_mask: true + time_mask_width_range: + - 0 + - 40 + num_time_mask: 2 + +train_conf: + accum_grad: 1 + grad_clip: 5 + max_epoch: 150 + keep_nbest_models: 10 + log_interval: 50 + +optim: adam +optim_conf: + lr: 0.002 +scheduler: warmuplr +scheduler_conf: + warmup_steps: 30000 + +dataset: AudioDataset +dataset_conf: + index_ds: IndexDSJsonl + batch_sampler: EspnetStyleBatchSampler + batch_type: length # example or length + batch_size: 25000 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len; + max_token_length: 2048 # filter samples if source_token_len+target_token_len > max_token_length, + buffer_size: 1024 + shuffle: True + num_workers: 4 + preprocessor_speech: SpeechPreprocessSpeedPerturb + preprocessor_speech_conf: + speed_perturb: [0.9, 1.0, 1.1] + +tokenizer: CharTokenizer +tokenizer_conf: + unk_symbol: + +ctc_conf: + dropout_rate: 0.0 + ctc_type: builtin + reduce: true + ignore_nan_grad: true +normalize: null diff --git a/examples/wenetspeech/transformer/demo_infer.sh b/examples/wenetspeech/transformer/demo_infer.sh new file mode 120000 index 000000000..9d0a7a9e3 --- /dev/null +++ b/examples/wenetspeech/transformer/demo_infer.sh @@ -0,0 +1 @@ +../paraformer/demo_infer.sh \ No newline at end of file diff --git a/examples/wenetspeech/transformer/demo_train_or_finetune.sh b/examples/wenetspeech/transformer/demo_train_or_finetune.sh new file mode 120000 index 000000000..bbabdbe84 --- /dev/null +++ b/examples/wenetspeech/transformer/demo_train_or_finetune.sh @@ -0,0 +1 @@ +../paraformer/demo_train_or_finetune.sh \ No newline at end of file diff --git a/examples/wenetspeech/transformer/local/aishell_data_prep.sh b/examples/wenetspeech/transformer/local/aishell_data_prep.sh new file mode 100755 index 000000000..83f489b3c --- /dev/null +++ b/examples/wenetspeech/transformer/local/aishell_data_prep.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Copyright 2017 Xingyu Na +# Apache 2.0 + +#. ./path.sh || exit 1; + +if [ $# != 3 ]; then + echo "Usage: $0 " + echo " $0 /export/a05/xna/data/data_aishell/wav /export/a05/xna/data/data_aishell/transcript data" + exit 1; +fi + +aishell_audio_dir=$1 +aishell_text=$2/aishell_transcript_v0.8.txt +output_dir=$3 + +train_dir=$output_dir/data/local/train +dev_dir=$output_dir/data/local/dev +test_dir=$output_dir/data/local/test +tmp_dir=$output_dir/data/local/tmp + +mkdir -p $train_dir +mkdir -p $dev_dir +mkdir -p $test_dir +mkdir -p $tmp_dir + +# data directory check +if [ ! -d $aishell_audio_dir ] || [ ! -f $aishell_text ]; then + echo "Error: $0 requires two directory arguments" + exit 1; +fi + +# find wav audio file for train, dev and test resp. +find $aishell_audio_dir -iname "*.wav" > $tmp_dir/wav.flist +n=`cat $tmp_dir/wav.flist | wc -l` +[ $n -ne 141925 ] && \ + echo Warning: expected 141925 data data files, found $n + +grep -i "wav/train" $tmp_dir/wav.flist > $train_dir/wav.flist || exit 1; +grep -i "wav/dev" $tmp_dir/wav.flist > $dev_dir/wav.flist || exit 1; +grep -i "wav/test" $tmp_dir/wav.flist > $test_dir/wav.flist || exit 1; + +rm -r $tmp_dir + +# Transcriptions preparation +for dir in $train_dir $dev_dir $test_dir; do + echo Preparing $dir transcriptions + sed -e 's/\.wav//' $dir/wav.flist | awk -F '/' '{print $NF}' > $dir/utt.list + paste -d' ' $dir/utt.list $dir/wav.flist > $dir/wav.scp_all + utils/filter_scp.pl -f 1 $dir/utt.list $aishell_text > $dir/transcripts.txt + awk '{print $1}' $dir/transcripts.txt > $dir/utt.list + utils/filter_scp.pl -f 1 $dir/utt.list $dir/wav.scp_all | sort -u > $dir/wav.scp + sort -u $dir/transcripts.txt > $dir/text +done + +mkdir -p $output_dir/data/train $output_dir/data/dev $output_dir/data/test + +for f in wav.scp text; do + cp $train_dir/$f $output_dir/data/train/$f || exit 1; + cp $dev_dir/$f $output_dir/data/dev/$f || exit 1; + cp $test_dir/$f $output_dir/data/test/$f || exit 1; +done + +echo "$0: AISHELL data preparation succeeded" +exit 0; diff --git a/examples/wenetspeech/transformer/local/download_and_untar.sh b/examples/wenetspeech/transformer/local/download_and_untar.sh new file mode 100755 index 000000000..d98255915 --- /dev/null +++ b/examples/wenetspeech/transformer/local/download_and_untar.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +# Copyright 2014 Johns Hopkins University (author: Daniel Povey) +# 2017 Xingyu Na +# Apache 2.0 + +remove_archive=false + +if [ "$1" == --remove-archive ]; then + remove_archive=true + shift +fi + +if [ $# -ne 3 ]; then + echo "Usage: $0 [--remove-archive] " + echo "e.g.: $0 /export/a05/xna/data www.openslr.org/resources/33 data_aishell" + echo "With --remove-archive it will remove the archive after successfully un-tarring it." + echo " can be one of: data_aishell, resource_aishell." +fi + +data=$1 +url=$2 +part=$3 + +if [ ! -d "$data" ]; then + echo "$0: no such directory $data" + exit 1; +fi + +part_ok=false +list="data_aishell resource_aishell" +for x in $list; do + if [ "$part" == $x ]; then part_ok=true; fi +done +if ! $part_ok; then + echo "$0: expected to be one of $list, but got '$part'" + exit 1; +fi + +if [ -z "$url" ]; then + echo "$0: empty URL base." + exit 1; +fi + +if [ -f $data/$part/.complete ]; then + echo "$0: data part $part was already successfully extracted, nothing to do." + exit 0; +fi + +# sizes of the archive files in bytes. +sizes="15582913665 1246920" + +if [ -f $data/$part.tgz ]; then + size=$(/bin/ls -l $data/$part.tgz | awk '{print $5}') + size_ok=false + for s in $sizes; do if [ $s == $size ]; then size_ok=true; fi; done + if ! $size_ok; then + echo "$0: removing existing file $data/$part.tgz because its size in bytes $size" + echo "does not equal the size of one of the archives." + rm $data/$part.tgz + else + echo "$data/$part.tgz exists and appears to be complete." + fi +fi + +if [ ! -f $data/$part.tgz ]; then + if ! command -v wget >/dev/null; then + echo "$0: wget is not installed." + exit 1; + fi + full_url=$url/$part.tgz + echo "$0: downloading data from $full_url. This may take some time, please be patient." + + cd $data || exit 1 + if ! wget --no-check-certificate $full_url; then + echo "$0: error executing wget $full_url" + exit 1; + fi +fi + +cd $data || exit 1 + +if ! tar -xvzf $part.tgz; then + echo "$0: error un-tarring archive $data/$part.tgz" + exit 1; +fi + +touch $data/$part/.complete + +if [ $part == "data_aishell" ]; then + cd $data/$part/wav || exit 1 + for wav in ./*.tar.gz; do + echo "Extracting wav from $wav" + tar -zxf $wav && rm $wav + done +fi + +echo "$0: Successfully downloaded and un-tarred $data/$part.tgz" + +if $remove_archive; then + echo "$0: removing $data/$part.tgz file since --remove-archive option was supplied." + rm $data/$part.tgz +fi + +exit 0; diff --git a/examples/wenetspeech/transformer/run.sh b/examples/wenetspeech/transformer/run.sh new file mode 100755 index 000000000..3fb846519 --- /dev/null +++ b/examples/wenetspeech/transformer/run.sh @@ -0,0 +1,203 @@ +#!/usr/bin/env bash + + +CUDA_VISIBLE_DEVICES="0,1" + +# general configuration +feats_dir="../DATA" #feature output dictionary +exp_dir=`pwd` +lang=zh +token_type=char +stage=0 +stop_stage=5 + +# feature configuration +nj=32 + +inference_device="cuda" #"cpu" +inference_checkpoint="model.pt.avg10" +inference_scp="wav.scp" +inference_batch_size=1 + +# data +raw_data=../raw_data +data_url=www.openslr.org/resources/33 + +# exp tag +tag="exp1" +workspace=`pwd` + +master_port=12345 + +. utils/parse_options.sh || exit 1; + +# Set bash to 'debug' mode, it will exit on : +# -e 'error', -u 'undefined variable', -o ... 'error in pipeline', -x 'print commands', +set -e +set -u +set -o pipefail + +train_set=train +valid_set=dev +test_sets="dev test" + +config=transformer_12e_6d_2048_256.yaml +model_dir="baseline_$(basename "${config}" .yaml)_${lang}_${token_type}_${tag}" + + + +if [ ${stage} -le -1 ] && [ ${stop_stage} -ge -1 ]; then + echo "stage -1: Data Download" + mkdir -p ${raw_data} + local/download_and_untar.sh ${raw_data} ${data_url} data_aishell + local/download_and_untar.sh ${raw_data} ${data_url} resource_aishell +fi + +if [ ${stage} -le 0 ] && [ ${stop_stage} -ge 0 ]; then + echo "stage 0: Data preparation" + # Data preparation + local/aishell_data_prep.sh ${raw_data}/data_aishell/wav ${raw_data}/data_aishell/transcript ${feats_dir} + for x in train dev test; do + cp ${feats_dir}/data/${x}/text ${feats_dir}/data/${x}/text.org + paste -d " " <(cut -f 1 -d" " ${feats_dir}/data/${x}/text.org) <(cut -f 2- -d" " ${feats_dir}/data/${x}/text.org | tr -d " ") \ + > ${feats_dir}/data/${x}/text + utils/text2token.py -n 1 -s 1 ${feats_dir}/data/${x}/text > ${feats_dir}/data/${x}/text.org + mv ${feats_dir}/data/${x}/text.org ${feats_dir}/data/${x}/text + + # convert wav.scp text to jsonl + scp_file_list_arg="++scp_file_list='[\"${feats_dir}/data/${x}/wav.scp\",\"${feats_dir}/data/${x}/text\"]'" + python ../../../funasr/datasets/audio_datasets/scp2jsonl.py \ + ++data_type_list='["source", "target"]' \ + ++jsonl_file_out=${feats_dir}/data/${x}/audio_datasets.jsonl \ + ${scp_file_list_arg} + done +fi + +if [ ${stage} -le 1 ] && [ ${stop_stage} -ge 1 ]; then + echo "stage 1: Feature and CMVN Generation" + python ../../../funasr/bin/compute_audio_cmvn.py \ + --config-path "${workspace}/conf" \ + --config-name "${config}" \ + ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ + ++cmvn_file="${feats_dir}/data/${train_set}/cmvn.json" \ + +fi + +token_list=${feats_dir}/data/${lang}_token_list/$token_type/tokens.txt +echo "dictionary: ${token_list}" +if [ ${stage} -le 2 ] && [ ${stop_stage} -ge 2 ]; then + echo "stage 2: Dictionary Preparation" + mkdir -p ${feats_dir}/data/${lang}_token_list/$token_type/ + + echo "make a dictionary" + echo "" > ${token_list} + echo "" >> ${token_list} + echo "" >> ${token_list} + utils/text2token.py -s 1 -n 1 --space "" ${feats_dir}/data/$train_set/text | cut -f 2- -d" " | tr " " "\n" \ + | sort | uniq | grep -a -v -e '^\s*$' | awk '{print $0}' >> ${token_list} + echo "" >> ${token_list} +fi + +# LM Training Stage +if [ ${stage} -le 3 ] && [ ${stop_stage} -ge 3 ]; then + echo "stage 3: LM Training" +fi + +# ASR Training Stage +if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then + echo "stage 4: ASR Training" + + mkdir -p ${exp_dir}/exp/${model_dir} + current_time=$(date "+%Y-%m-%d_%H-%M") + log_file="${exp_dir}/exp/${model_dir}/train.log.txt.${current_time}" + echo "log_file: ${log_file}" + + export CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES + gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') + torchrun \ + --nnodes 1 \ + --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ + ../../../funasr/bin/train.py \ + --config-path "${workspace}/conf" \ + --config-name "${config}" \ + ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ + ++valid_data_set_list="${feats_dir}/data/${valid_set}/audio_datasets.jsonl" \ + ++tokenizer_conf.token_list="${token_list}" \ + ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ + ++output_dir="${exp_dir}/exp/${model_dir}" &> ${log_file} +fi + + + +# Testing Stage +if [ ${stage} -le 5 ] && [ ${stop_stage} -ge 5 ]; then + echo "stage 5: Inference" + + if [ ${inference_device} == "cuda" ]; then + nj=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') + else + inference_batch_size=1 + CUDA_VISIBLE_DEVICES="" + for JOB in $(seq ${nj}); do + CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"-1," + done + fi + + for dset in ${test_sets}; do + + inference_dir="${exp_dir}/exp/${model_dir}/inference-${inference_checkpoint}/${dset}" + _logdir="${inference_dir}/logdir" + echo "inference_dir: ${inference_dir}" + + mkdir -p "${_logdir}" + data_dir="${feats_dir}/data/${dset}" + key_file=${data_dir}/${inference_scp} + + split_scps= + for JOB in $(seq "${nj}"); do + split_scps+=" ${_logdir}/keys.${JOB}.scp" + done + utils/split_scp.pl "${key_file}" ${split_scps} + + gpuid_list_array=(${CUDA_VISIBLE_DEVICES//,/ }) + for JOB in $(seq ${nj}); do + { + id=$((JOB-1)) + gpuid=${gpuid_list_array[$id]} + + export CUDA_VISIBLE_DEVICES=${gpuid} + python ../../../funasr/bin/inference.py \ + --config-path="${exp_dir}/exp/${model_dir}" \ + --config-name="config.yaml" \ + ++init_param="${exp_dir}/exp/${model_dir}/${inference_checkpoint}" \ + ++tokenizer_conf.token_list="${token_list}" \ + ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ + ++input="${_logdir}/keys.${JOB}.scp" \ + ++output_dir="${inference_dir}/${JOB}" \ + ++device="${inference_device}" \ + ++ncpu=1 \ + ++disable_log=true \ + ++batch_size="${inference_batch_size}" &> ${_logdir}/log.${JOB}.txt + }& + + done + wait + + mkdir -p ${inference_dir}/1best_recog + for f in token score text; do + if [ -f "${inference_dir}/${JOB}/1best_recog/${f}" ]; then + for JOB in $(seq "${nj}"); do + cat "${inference_dir}/${JOB}/1best_recog/${f}" + done | sort -k1 >"${inference_dir}/1best_recog/${f}" + fi + done + + echo "Computing WER ..." + python utils/postprocess_text_zh.py ${inference_dir}/1best_recog/text ${inference_dir}/1best_recog/text.proc + python utils/postprocess_text_zh.py ${data_dir}/text ${inference_dir}/1best_recog/text.ref + python utils/compute_wer.py ${inference_dir}/1best_recog/text.ref ${inference_dir}/1best_recog/text.proc ${inference_dir}/1best_recog/text.cer + tail -n 3 ${inference_dir}/1best_recog/text.cer + done + +fi \ No newline at end of file diff --git a/examples/wenetspeech/transformer/utils b/examples/wenetspeech/transformer/utils new file mode 120000 index 000000000..1f2ce9d8f --- /dev/null +++ b/examples/wenetspeech/transformer/utils @@ -0,0 +1 @@ +../paraformer/utils \ No newline at end of file From e8fd84f5a4c8a7528e474f37b47d9fecde3534b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 14:14:42 +0800 Subject: [PATCH 066/125] wenetspeech --- examples/wenetspeech/conformer/README.md | 16 ++ .../conf/conformer_12e_6d_2048_512.yaml | 111 ++++++++++ examples/wenetspeech/conformer/demo_infer.sh | 1 + .../conformer/demo_train_or_finetune.sh | 1 + .../conformer/local/aishell_data_prep.sh | 66 ++++++ .../conformer/local/download_and_untar.sh | 105 +++++++++ examples/wenetspeech/conformer/run.sh | 201 ++++++++++++++++++ examples/wenetspeech/conformer/utils | 1 + 8 files changed, 502 insertions(+) create mode 100644 examples/wenetspeech/conformer/README.md create mode 100644 examples/wenetspeech/conformer/conf/conformer_12e_6d_2048_512.yaml create mode 120000 examples/wenetspeech/conformer/demo_infer.sh create mode 120000 examples/wenetspeech/conformer/demo_train_or_finetune.sh create mode 100755 examples/wenetspeech/conformer/local/aishell_data_prep.sh create mode 100755 examples/wenetspeech/conformer/local/download_and_untar.sh create mode 100755 examples/wenetspeech/conformer/run.sh create mode 120000 examples/wenetspeech/conformer/utils diff --git a/examples/wenetspeech/conformer/README.md b/examples/wenetspeech/conformer/README.md new file mode 100644 index 000000000..003cbacd1 --- /dev/null +++ b/examples/wenetspeech/conformer/README.md @@ -0,0 +1,16 @@ + +# Conformer Result + +## Training Config +- Feature info: using 80 dims fbank, global cmvn, speed perturb(0.9, 1.0, 1.1), specaugment +- Train info: lr 5e-4, batch_size 25000, 2 gpu(Tesla V100), acc_grad 1, 50 epochs +- Train config: conf/train_asr_transformer.yaml +- LM config: LM was not used +- Model size: 46M + +## Results (CER) + +| testset | CER(%) | +|:-----------:|:-------:| +| dev | 4.42 | +| test | 4.87 | \ No newline at end of file diff --git a/examples/wenetspeech/conformer/conf/conformer_12e_6d_2048_512.yaml b/examples/wenetspeech/conformer/conf/conformer_12e_6d_2048_512.yaml new file mode 100644 index 000000000..5277f23bf --- /dev/null +++ b/examples/wenetspeech/conformer/conf/conformer_12e_6d_2048_512.yaml @@ -0,0 +1,111 @@ +# This is an example that demonstrates how to configure a model file. +# You can modify the configuration according to your own requirements. + +# to print the register_table: +# from funasr.register import tables +# tables.print() + +# network architecture +model: Conformer +model_conf: + ctc_weight: 0.3 + lsm_weight: 0.1 # label smoothing option + length_normalized_loss: false + +# encoder +encoder: ConformerEncoder +encoder_conf: + output_size: 512 # dimension of attention + attention_heads: 8 + linear_units: 2048 # the number of units of position-wise feed forward + num_blocks: 12 # the number of encoder blocks + dropout_rate: 0.1 + positional_dropout_rate: 0.1 + attention_dropout_rate: 0.0 + input_layer: conv2d # encoder architecture type + normalize_before: true + rel_pos_type: latest + pos_enc_layer_type: rel_pos + selfattention_layer_type: rel_selfattn + activation_type: swish + macaron_style: true + use_cnn_module: true + cnn_module_kernel: 15 + +# decoder +decoder: TransformerDecoder +decoder_conf: + attention_heads: 8 + linear_units: 2048 + num_blocks: 6 + dropout_rate: 0.1 + positional_dropout_rate: 0.1 + self_attention_dropout_rate: 0.0 + src_attention_dropout_rate: 0.0 + + +# frontend related +frontend: WavFrontend +frontend_conf: + fs: 16000 + window: hamming + n_mels: 80 + frame_length: 25 + frame_shift: 10 + lfr_m: 1 + lfr_n: 1 + +specaug: SpecAug +specaug_conf: + apply_time_warp: true + time_warp_window: 5 + time_warp_mode: bicubic + apply_freq_mask: true + freq_mask_width_range: + - 0 + - 30 + num_freq_mask: 2 + apply_time_mask: true + time_mask_width_range: + - 0 + - 40 + num_time_mask: 2 + +train_conf: + accum_grad: 4 + grad_clip: 5 + max_epoch: 30 + keep_nbest_models: 10 + log_interval: 50 + +optim: adam +optim_conf: + lr: 0.0015 +scheduler: warmuplr +scheduler_conf: + warmup_steps: 30000 + +dataset: AudioDataset +dataset_conf: + index_ds: IndexDSJsonl + batch_sampler: EspnetStyleBatchSampler + batch_type: length # example or length + batch_size: 3200 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len; + max_token_length: 2048 # filter samples if source_token_len+target_token_len > max_token_length, + buffer_size: 1024 + shuffle: True + num_workers: 4 + preprocessor_speech: SpeechPreprocessSpeedPerturb + preprocessor_speech_conf: + speed_perturb: [0.9, 1.0, 1.1] + +tokenizer: CharTokenizer +tokenizer_conf: + unk_symbol: + +ctc_conf: + dropout_rate: 0.0 + ctc_type: builtin + reduce: true + ignore_nan_grad: true +normalize: null diff --git a/examples/wenetspeech/conformer/demo_infer.sh b/examples/wenetspeech/conformer/demo_infer.sh new file mode 120000 index 000000000..9d0a7a9e3 --- /dev/null +++ b/examples/wenetspeech/conformer/demo_infer.sh @@ -0,0 +1 @@ +../paraformer/demo_infer.sh \ No newline at end of file diff --git a/examples/wenetspeech/conformer/demo_train_or_finetune.sh b/examples/wenetspeech/conformer/demo_train_or_finetune.sh new file mode 120000 index 000000000..bbabdbe84 --- /dev/null +++ b/examples/wenetspeech/conformer/demo_train_or_finetune.sh @@ -0,0 +1 @@ +../paraformer/demo_train_or_finetune.sh \ No newline at end of file diff --git a/examples/wenetspeech/conformer/local/aishell_data_prep.sh b/examples/wenetspeech/conformer/local/aishell_data_prep.sh new file mode 100755 index 000000000..83f489b3c --- /dev/null +++ b/examples/wenetspeech/conformer/local/aishell_data_prep.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Copyright 2017 Xingyu Na +# Apache 2.0 + +#. ./path.sh || exit 1; + +if [ $# != 3 ]; then + echo "Usage: $0 " + echo " $0 /export/a05/xna/data/data_aishell/wav /export/a05/xna/data/data_aishell/transcript data" + exit 1; +fi + +aishell_audio_dir=$1 +aishell_text=$2/aishell_transcript_v0.8.txt +output_dir=$3 + +train_dir=$output_dir/data/local/train +dev_dir=$output_dir/data/local/dev +test_dir=$output_dir/data/local/test +tmp_dir=$output_dir/data/local/tmp + +mkdir -p $train_dir +mkdir -p $dev_dir +mkdir -p $test_dir +mkdir -p $tmp_dir + +# data directory check +if [ ! -d $aishell_audio_dir ] || [ ! -f $aishell_text ]; then + echo "Error: $0 requires two directory arguments" + exit 1; +fi + +# find wav audio file for train, dev and test resp. +find $aishell_audio_dir -iname "*.wav" > $tmp_dir/wav.flist +n=`cat $tmp_dir/wav.flist | wc -l` +[ $n -ne 141925 ] && \ + echo Warning: expected 141925 data data files, found $n + +grep -i "wav/train" $tmp_dir/wav.flist > $train_dir/wav.flist || exit 1; +grep -i "wav/dev" $tmp_dir/wav.flist > $dev_dir/wav.flist || exit 1; +grep -i "wav/test" $tmp_dir/wav.flist > $test_dir/wav.flist || exit 1; + +rm -r $tmp_dir + +# Transcriptions preparation +for dir in $train_dir $dev_dir $test_dir; do + echo Preparing $dir transcriptions + sed -e 's/\.wav//' $dir/wav.flist | awk -F '/' '{print $NF}' > $dir/utt.list + paste -d' ' $dir/utt.list $dir/wav.flist > $dir/wav.scp_all + utils/filter_scp.pl -f 1 $dir/utt.list $aishell_text > $dir/transcripts.txt + awk '{print $1}' $dir/transcripts.txt > $dir/utt.list + utils/filter_scp.pl -f 1 $dir/utt.list $dir/wav.scp_all | sort -u > $dir/wav.scp + sort -u $dir/transcripts.txt > $dir/text +done + +mkdir -p $output_dir/data/train $output_dir/data/dev $output_dir/data/test + +for f in wav.scp text; do + cp $train_dir/$f $output_dir/data/train/$f || exit 1; + cp $dev_dir/$f $output_dir/data/dev/$f || exit 1; + cp $test_dir/$f $output_dir/data/test/$f || exit 1; +done + +echo "$0: AISHELL data preparation succeeded" +exit 0; diff --git a/examples/wenetspeech/conformer/local/download_and_untar.sh b/examples/wenetspeech/conformer/local/download_and_untar.sh new file mode 100755 index 000000000..d98255915 --- /dev/null +++ b/examples/wenetspeech/conformer/local/download_and_untar.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +# Copyright 2014 Johns Hopkins University (author: Daniel Povey) +# 2017 Xingyu Na +# Apache 2.0 + +remove_archive=false + +if [ "$1" == --remove-archive ]; then + remove_archive=true + shift +fi + +if [ $# -ne 3 ]; then + echo "Usage: $0 [--remove-archive] " + echo "e.g.: $0 /export/a05/xna/data www.openslr.org/resources/33 data_aishell" + echo "With --remove-archive it will remove the archive after successfully un-tarring it." + echo " can be one of: data_aishell, resource_aishell." +fi + +data=$1 +url=$2 +part=$3 + +if [ ! -d "$data" ]; then + echo "$0: no such directory $data" + exit 1; +fi + +part_ok=false +list="data_aishell resource_aishell" +for x in $list; do + if [ "$part" == $x ]; then part_ok=true; fi +done +if ! $part_ok; then + echo "$0: expected to be one of $list, but got '$part'" + exit 1; +fi + +if [ -z "$url" ]; then + echo "$0: empty URL base." + exit 1; +fi + +if [ -f $data/$part/.complete ]; then + echo "$0: data part $part was already successfully extracted, nothing to do." + exit 0; +fi + +# sizes of the archive files in bytes. +sizes="15582913665 1246920" + +if [ -f $data/$part.tgz ]; then + size=$(/bin/ls -l $data/$part.tgz | awk '{print $5}') + size_ok=false + for s in $sizes; do if [ $s == $size ]; then size_ok=true; fi; done + if ! $size_ok; then + echo "$0: removing existing file $data/$part.tgz because its size in bytes $size" + echo "does not equal the size of one of the archives." + rm $data/$part.tgz + else + echo "$data/$part.tgz exists and appears to be complete." + fi +fi + +if [ ! -f $data/$part.tgz ]; then + if ! command -v wget >/dev/null; then + echo "$0: wget is not installed." + exit 1; + fi + full_url=$url/$part.tgz + echo "$0: downloading data from $full_url. This may take some time, please be patient." + + cd $data || exit 1 + if ! wget --no-check-certificate $full_url; then + echo "$0: error executing wget $full_url" + exit 1; + fi +fi + +cd $data || exit 1 + +if ! tar -xvzf $part.tgz; then + echo "$0: error un-tarring archive $data/$part.tgz" + exit 1; +fi + +touch $data/$part/.complete + +if [ $part == "data_aishell" ]; then + cd $data/$part/wav || exit 1 + for wav in ./*.tar.gz; do + echo "Extracting wav from $wav" + tar -zxf $wav && rm $wav + done +fi + +echo "$0: Successfully downloaded and un-tarred $data/$part.tgz" + +if $remove_archive; then + echo "$0: removing $data/$part.tgz file since --remove-archive option was supplied." + rm $data/$part.tgz +fi + +exit 0; diff --git a/examples/wenetspeech/conformer/run.sh b/examples/wenetspeech/conformer/run.sh new file mode 100755 index 000000000..202ca6672 --- /dev/null +++ b/examples/wenetspeech/conformer/run.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash + + +CUDA_VISIBLE_DEVICES="0,1" + +# general configuration +feats_dir="../DATA" #feature output dictionary +exp_dir=`pwd` +lang=zh +token_type=char +stage=0 +stop_stage=5 + +# feature configuration +nj=32 + +inference_device="cuda" #"cpu", "cuda:0", "cuda:1" +inference_checkpoint="model.pt.avg10" +inference_scp="wav.scp" +inference_batch_size=1 + +# data +raw_data=../raw_data +data_url=www.openslr.org/resources/33 + +# exp tag +tag="exp1" +workspace=`pwd` + +master_port=12345 + +. utils/parse_options.sh || exit 1; + +# Set bash to 'debug' mode, it will exit on : +# -e 'error', -u 'undefined variable', -o ... 'error in pipeline', -x 'print commands', +set -e +set -u +set -o pipefail + +set=L +train_set=train_l +valid_set=dev +test_sets="dev test_net test_meeting" + +asr_config=conf/conformer_12e_6d_2048_512.yaml +model_dir="baseline_$(basename "${asr_config}" .yaml)_${lang}_${token_type}_${tag}" + + + +if [ ${stage} -le -1 ] && [ ${stop_stage} -ge -1 ]; then + echo "For downloading data, please refer to https://github.com/wenet-e2e/WenetSpeech." + exit 0; +fi + +if [ ${stage} -le 0 ] && [ ${stop_stage} -ge 0 ]; then + echo "stage 0: Data preparation" + # Data preparation + local/data.sh --set ${set} --nj $nj --data_dir $feats_dir --WENETSPEECH $raw_data --train_cmd $train_cmd + mkdir $feats_dir/data + mv $feats_dir/$train_set $feats_dir/data/$train_set + for x in $test_sets; do + mv $feats_dir/$x $feats_dir/data/ + + # convert wav.scp text to jsonl + scp_file_list_arg="++scp_file_list='[\"${feats_dir}/data/${x}/wav.scp\",\"${feats_dir}/data/${x}/text\"]'" + python ../../../funasr/datasets/audio_datasets/scp2jsonl.py \ + ++data_type_list='["source", "target"]' \ + ++jsonl_file_out=${feats_dir}/data/${x}/audio_datasets.jsonl \ + ${scp_file_list_arg} + done +fi + + +if [ ${stage} -le 1 ] && [ ${stop_stage} -ge 1 ]; then + echo "stage 1: Feature and CMVN Generation" + python ../../../funasr/bin/compute_audio_cmvn.py \ + --config-path "${workspace}/conf" \ + --config-name "${config}" \ + ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ + ++cmvn_file="${feats_dir}/data/${train_set}/cmvn.json" \ + +fi + +token_list=${feats_dir}/data/${lang}_token_list/$token_type/tokens.txt +echo "dictionary: ${token_list}" +if [ ${stage} -le 2 ] && [ ${stop_stage} -ge 2 ]; then + echo "stage 2: Dictionary Preparation" + mkdir -p ${feats_dir}/data/${lang}_token_list/$token_type/ + + echo "make a dictionary" + echo "" > ${token_list} + echo "" >> ${token_list} + echo "" >> ${token_list} + utils/text2token.py -s 1 -n 1 --space "" --text_format "jsonl" ${feats_dir}/data/$train_set/audio_datasets.jsonl | cut -f 2- -d" " | tr " " "\n" \ + | sort | uniq | grep -a -v -e '^\s*$' | awk '{print $0}' >> ${token_list} + echo "" >> ${token_list} +fi + +# LM Training Stage +if [ ${stage} -le 3 ] && [ ${stop_stage} -ge 3 ]; then + echo "stage 3: LM Training" +fi + +# ASR Training Stage +if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then + echo "stage 4: ASR Training" + + mkdir -p ${exp_dir}/exp/${model_dir} + current_time=$(date "+%Y-%m-%d_%H-%M") + log_file="${exp_dir}/exp/${model_dir}/train.log.txt.${current_time}" + echo "log_file: ${log_file}" + + export CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES + gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') + torchrun \ + --nnodes 1 \ + --nproc_per_node ${gpu_num} \ + --master_port ${master_port} \ + ../../../funasr/bin/train.py \ + --config-path "${workspace}/conf" \ + --config-name "${config}" \ + ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ + ++valid_data_set_list="${feats_dir}/data/${valid_set}/audio_datasets.jsonl" \ + ++tokenizer_conf.token_list="${token_list}" \ + ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ + ++output_dir="${exp_dir}/exp/${model_dir}" &> ${log_file} +fi + + + +# Testing Stage +if [ ${stage} -le 5 ] && [ ${stop_stage} -ge 5 ]; then + echo "stage 5: Inference" + + if [ ${inference_device} == "cuda" ]; then + nj=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') + else + inference_batch_size=1 + CUDA_VISIBLE_DEVICES="" + for JOB in $(seq ${nj}); do + CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"-1," + done + fi + + for dset in ${test_sets}; do + + inference_dir="${exp_dir}/exp/${model_dir}/inference-${inference_checkpoint}/${dset}" + _logdir="${inference_dir}/logdir" + echo "inference_dir: ${inference_dir}" + + mkdir -p "${_logdir}" + data_dir="${feats_dir}/data/${dset}" + key_file=${data_dir}/${inference_scp} + + split_scps= + for JOB in $(seq "${nj}"); do + split_scps+=" ${_logdir}/keys.${JOB}.scp" + done + utils/split_scp.pl "${key_file}" ${split_scps} + + gpuid_list_array=(${CUDA_VISIBLE_DEVICES//,/ }) + for JOB in $(seq ${nj}); do + { + id=$((JOB-1)) + gpuid=${gpuid_list_array[$id]} + + export CUDA_VISIBLE_DEVICES=${gpuid} + python ../../../funasr/bin/inference.py \ + --config-path="${exp_dir}/exp/${model_dir}" \ + --config-name="config.yaml" \ + ++init_param="${exp_dir}/exp/${model_dir}/${inference_checkpoint}" \ + ++tokenizer_conf.token_list="${token_list}" \ + ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ + ++input="${_logdir}/keys.${JOB}.scp" \ + ++output_dir="${inference_dir}/${JOB}" \ + ++device="${inference_device}" \ + ++ncpu=1 \ + ++disable_log=true \ + ++batch_size="${inference_batch_size}" &> ${_logdir}/log.${JOB}.txt + }& + + done + wait + + mkdir -p ${inference_dir}/1best_recog + for f in token score text; do + if [ -f "${inference_dir}/${JOB}/1best_recog/${f}" ]; then + for JOB in $(seq "${nj}"); do + cat "${inference_dir}/${JOB}/1best_recog/${f}" + done | sort -k1 >"${inference_dir}/1best_recog/${f}" + fi + done + + echo "Computing WER ..." + python utils/postprocess_text_zh.py ${inference_dir}/1best_recog/text ${inference_dir}/1best_recog/text.proc + python utils/postprocess_text_zh.py ${data_dir}/text ${inference_dir}/1best_recog/text.ref + python utils/compute_wer.py ${inference_dir}/1best_recog/text.ref ${inference_dir}/1best_recog/text.proc ${inference_dir}/1best_recog/text.cer + tail -n 3 ${inference_dir}/1best_recog/text.cer + done + +fi diff --git a/examples/wenetspeech/conformer/utils b/examples/wenetspeech/conformer/utils new file mode 120000 index 000000000..be5e5a322 --- /dev/null +++ b/examples/wenetspeech/conformer/utils @@ -0,0 +1 @@ +../../aishell/paraformer/utils \ No newline at end of file From 97f488889b81aea7fe8f5eaaf459c0a1d2220f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 15:10:30 +0800 Subject: [PATCH 067/125] wenetspeech --- examples/wenetspeech/conformer/run.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/wenetspeech/conformer/run.sh b/examples/wenetspeech/conformer/run.sh index 202ca6672..0503a9ea0 100755 --- a/examples/wenetspeech/conformer/run.sh +++ b/examples/wenetspeech/conformer/run.sh @@ -42,8 +42,8 @@ train_set=train_l valid_set=dev test_sets="dev test_net test_meeting" -asr_config=conf/conformer_12e_6d_2048_512.yaml -model_dir="baseline_$(basename "${asr_config}" .yaml)_${lang}_${token_type}_${tag}" +config=conformer_12e_6d_2048_512.yaml +model_dir="baseline_$(basename "${config}" .yaml)_${lang}_${token_type}_${tag}" @@ -76,6 +76,7 @@ if [ ${stage} -le 1 ] && [ ${stop_stage} -ge 1 ]; then python ../../../funasr/bin/compute_audio_cmvn.py \ --config-path "${workspace}/conf" \ --config-name "${config}" \ + ++scale=0.1 \ ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ ++cmvn_file="${feats_dir}/data/${train_set}/cmvn.json" \ From b37e7b15e02fe8ac42c6591650dc2bfe86b1e8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 15:11:08 +0800 Subject: [PATCH 068/125] wenetspeech --- examples/aishell/paraformer/utils/text2token.py | 9 +++++++++ funasr/bin/compute_audio_cmvn.py | 10 ++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/aishell/paraformer/utils/text2token.py b/examples/aishell/paraformer/utils/text2token.py index 263cb9d1a..a89679f53 100755 --- a/examples/aishell/paraformer/utils/text2token.py +++ b/examples/aishell/paraformer/utils/text2token.py @@ -60,6 +60,12 @@ def get_parser(): read from SI1279.PHN file -> "sil b r ih sil k s aa r er n aa l sil t er n ih sil t ih v sil" """, ) + parser.add_argument( + "--text_format", + default="text", + type=str, + help="text, jsonl", + ) return parser @@ -82,6 +88,9 @@ def main(): line = f.readline() n = args.nchar while line: + if args.text_format == "jsonl": + data = json.loads(line.strip()) + line = data["target"] x = line.split() print(" ".join(x[: args.skip_ncols]), end=" ") a = " ".join(x[args.skip_ncols :]) diff --git a/funasr/bin/compute_audio_cmvn.py b/funasr/bin/compute_audio_cmvn.py index 91bb2ac84..697da94bb 100644 --- a/funasr/bin/compute_audio_cmvn.py +++ b/funasr/bin/compute_audio_cmvn.py @@ -52,7 +52,7 @@ def main(**kwargs): frontend=frontend, tokenizer=None, is_training=False, - **kwargs.get("dataset_conf") + **kwargs.get("dataset_conf"), ) # dataloader @@ -68,11 +68,13 @@ def main(**kwargs): dataset_train, collate_fn=dataset_train.collator, **batch_sampler_train ) - iter_stop = int(kwargs.get("scale", 1.0) * len(dataloader_train)) - total_frames = 0 for batch_idx, batch in enumerate(dataloader_train): - if batch_idx >= iter_stop: + iter_stop = int(kwargs.get("scale", -1.0) * len(dataloader_train)) + log_step = iter_stop // 100 + if batch_idx % log_step == 0: + print(f"prcessed: {batch_idx}/{iter_stop}") + if batch_idx >= iter_stop and iter_stop > 0.0: break fbank = batch["speech"].numpy()[0, :, :] From 0b764d335067c0ce1f5b185d5ff3799dbf3466e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 16:20:24 +0800 Subject: [PATCH 069/125] wenetspeech --- funasr/bin/compute_audio_cmvn.py | 1 + 1 file changed, 1 insertion(+) diff --git a/funasr/bin/compute_audio_cmvn.py b/funasr/bin/compute_audio_cmvn.py index 697da94bb..20c8e0ded 100644 --- a/funasr/bin/compute_audio_cmvn.py +++ b/funasr/bin/compute_audio_cmvn.py @@ -75,6 +75,7 @@ def main(**kwargs): if batch_idx % log_step == 0: print(f"prcessed: {batch_idx}/{iter_stop}") if batch_idx >= iter_stop and iter_stop > 0.0: + print(f"prcessed: {iter_stop}/{iter_stop}") break fbank = batch["speech"].numpy()[0, :, :] From 55e7a2d880b3322fd89bdb1a27373ffbd842f280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Wed, 22 May 2024 16:33:17 +0800 Subject: [PATCH 070/125] wenetspeech --- funasr/bin/compute_audio_cmvn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/funasr/bin/compute_audio_cmvn.py b/funasr/bin/compute_audio_cmvn.py index 20c8e0ded..e8ced5141 100644 --- a/funasr/bin/compute_audio_cmvn.py +++ b/funasr/bin/compute_audio_cmvn.py @@ -73,9 +73,9 @@ def main(**kwargs): iter_stop = int(kwargs.get("scale", -1.0) * len(dataloader_train)) log_step = iter_stop // 100 if batch_idx % log_step == 0: - print(f"prcessed: {batch_idx}/{iter_stop}") + logging.info(f"prcessed: {batch_idx}/{iter_stop}") if batch_idx >= iter_stop and iter_stop > 0.0: - print(f"prcessed: {iter_stop}/{iter_stop}") + logging.info(f"prcessed: {iter_stop}/{iter_stop}") break fbank = batch["speech"].numpy()[0, :, :] From 4e613ec064052bc1374f26c201e7ec334c12d587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 23 May 2024 09:55:47 +0800 Subject: [PATCH 071/125] wenetspeech --- examples/aishell/paraformer/utils/text2token.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/aishell/paraformer/utils/text2token.py b/examples/aishell/paraformer/utils/text2token.py index a89679f53..c39db1e57 100755 --- a/examples/aishell/paraformer/utils/text2token.py +++ b/examples/aishell/paraformer/utils/text2token.py @@ -8,6 +8,7 @@ import argparse import codecs import re import sys +import json is_python2 = sys.version_info[0] == 2 From 32e783664534bbb8d3b8ba64c2c2ecb42398eb00 Mon Sep 17 00:00:00 2001 From: zhifu gao Date: Thu, 6 Jun 2024 09:54:35 +0800 Subject: [PATCH 072/125] update with main (#1786) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add cmakelist * add paraformer-torch * add debug for funasr-onnx-offline * fix redefinition of jieba StdExtension.hpp * add loading torch models * update funasr-onnx-offline * add SwitchArg for wss-server * add SwitchArg for funasr-onnx-offline * update cmakelist * update funasr-onnx-offline-rtf * add define condition * add gpu define for offlne-stream * update com define * update offline-stream * update cmakelist * update func CompileHotwordEmbedding * add timestamp for paraformer-torch * add C10_USE_GLOG for paraformer-torch * update paraformer-torch * fix func FunASRWfstDecoderInit * update model.h * fix func FunASRWfstDecoderInit * fix tpass_stream * update paraformer-torch * add bladedisc for funasr-onnx-offline * update comdefine * update funasr-wss-server * add log for torch * fix GetValue BLADEDISC * fix log * update cmakelist * update warmup to 10 * update funasrruntime * add batch_size for wss-server * add batch for bins * add batch for offline-stream * add batch for paraformer * add batch for offline-stream * fix func SetBatchSize * add SetBatchSize for model * add SetBatchSize for model * fix func Forward * fix padding * update funasrruntime * add dec reset for batch * set batch default value * add argv for CutSplit * sort frame_queue * sorted msgs * fix FunOfflineInfer * add dynamic batch for fetch * fix FetchDynamic * update run_server.sh * update run_server.sh * cpp http post server support (#1739) * add cpp http server * add some comment * remove some comments * del debug infos * restore run_server.sh * adapt to new model struct * 修复了onnxruntime在macos下编译失败的错误 (#1748) * Add files via upload 增加macos的编译支持 * Add files via upload 增加macos支持 * Add files via upload target_link_directories(funasr PUBLIC ${ONNXRUNTIME_DIR}/lib) target_link_directories(funasr PUBLIC ${FFMPEG_DIR}/lib) 添加 if(APPLE) 限制 --------- Co-authored-by: Yabin Li * Delete docs/images/wechat.png * Add files via upload * fixed the issues about seaco-onnx timestamp * fix bug (#1764) 当语音识别结果包含 `http` 时,标点符号预测会把它会被当成 url * fix empty asr result (#1765) 解码结果为空的语音片段,text 用空字符串 * docs * docs * docs * docs * docs * keep empty speech result (#1772) * docs * docs * update wechat QRcode * Add python funasr api support for websocket srv (#1777) * add python funasr_api supoort * change little to README.md * add core tools stream * modified a little * fix bug for timeout * support for buffer decode * add ffmpeg decode for buffer * auto frontend * auto frontend * auto frontend * auto frontend * auto frontend * auto frontend * auto frontend * auto frontend * Dev gzf exp (#1785) * resume from step * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * batch * train_loss_avg train_acc_avg * train_loss_avg train_acc_avg * train_loss_avg train_acc_avg * log step * wav is not exist * wav is not exist * decoding * decoding * decoding * wechat * decoding key * decoding key * decoding key * decoding key * decoding key * decoding key * dynamic batch * start_data_split_i=0 * total_time/accum_grad * total_time/accum_grad * total_time/accum_grad * update avg slice * update avg slice * sensevoice sanm * sensevoice sanm * sensevoice sanm --------- Co-authored-by: 北念 * auto frontend --------- Co-authored-by: 雾聪 Co-authored-by: zhaomingwork <61895407+zhaomingwork@users.noreply.github.com> Co-authored-by: szsteven008 <97944818+szsteven008@users.noreply.github.com> Co-authored-by: Ephemeroptera <605686962@qq.com> Co-authored-by: 彭震东 Co-authored-by: Shi Xian <40013335+R1ckShi@users.noreply.github.com> Co-authored-by: 维石 Co-authored-by: 北念 --- funasr/auto/auto_frontend.py | 12 ++-- .../audio_datasets/espnet_samplers.py | 2 + funasr/models/llm_asr/adaptor.py | 63 +++++++++++++++++++ funasr/models/sense_voice/decoder.py | 1 + funasr/models/sense_voice/model.py | 28 ++++++--- .../models/sense_voice/whisper_lib/model.py | 19 +++++- funasr/models/transformer/encoder.py | 2 +- funasr/train_utils/trainer_ds.py | 1 - 8 files changed, 111 insertions(+), 17 deletions(-) diff --git a/funasr/auto/auto_frontend.py b/funasr/auto/auto_frontend.py index 696a51e08..501d1ab71 100644 --- a/funasr/auto/auto_frontend.py +++ b/funasr/auto/auto_frontend.py @@ -60,7 +60,7 @@ class AutoFrontend: result_list = [] num_samples = len(data_list) - pbar = tqdm(colour="blue", total=num_samples + 1, dynamic_ncols=True) + # pbar = tqdm(colour="blue", total=num_samples + 1, dynamic_ncols=True) time0 = time.perf_counter() for beg_idx in range(0, num_samples, batch_size): @@ -95,15 +95,15 @@ class AutoFrontend: "input": speech, "input_len": speech_lengths, "key": key_batch, - data_type: "fbank", + "data_type": "fbank", } result_list.append(batch) - pbar.update(1) - description = f"{meta_data}, " - pbar.set_description(description) + # pbar.update(1) + # description = f"{meta_data}, " + # pbar.set_description(description) time_end = time.perf_counter() - pbar.set_description(f"time escaped total: {time_end - time0:0.3f}") + # pbar.set_description(f"time escaped total: {time_end - time0:0.3f}") return result_list diff --git a/funasr/datasets/audio_datasets/espnet_samplers.py b/funasr/datasets/audio_datasets/espnet_samplers.py index b358fa379..004201e53 100644 --- a/funasr/datasets/audio_datasets/espnet_samplers.py +++ b/funasr/datasets/audio_datasets/espnet_samplers.py @@ -147,7 +147,9 @@ class EspnetStyleBatchSampler(DistributedSampler): start_idx = self.rank * batches_per_rank end_idx = start_idx + batches_per_rank rank_batches = buffer_batches[start_idx + self.start_step : end_idx] + self.batch_num = len(rank_batches) + logging.info( f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {end_idx-start_idx}, batch_num_after_step: {len(rank_batches)}" ) diff --git a/funasr/models/llm_asr/adaptor.py b/funasr/models/llm_asr/adaptor.py index 8c2a80434..9b79ed28a 100644 --- a/funasr/models/llm_asr/adaptor.py +++ b/funasr/models/llm_asr/adaptor.py @@ -1,5 +1,7 @@ import torch import torch.nn as nn +import torch.nn.functional as F +from funasr.models.transformer.utils.nets_utils import make_pad_mask from funasr.register import tables @@ -63,3 +65,64 @@ class EncoderProjectorQFormer(nn.Module): query_proj = self.norm(self.linear(query_output.last_hidden_state)) return query_proj + + +@tables.register("adaptor_classes", "Transformer") +class Transformer(nn.Module): + def __init__( + self, downsample_rate=2, encoder_dim=1280, llm_dim=4096, ffn_dim: int = 2048, **kwargs + ): + super().__init__() + self.k = downsample_rate + self.encoder_dim = encoder_dim + self.llm_dim = llm_dim + self.linear1 = nn.Linear(self.encoder_dim * self.k, ffn_dim) + self.relu = nn.ReLU() + self.linear2 = nn.Linear(ffn_dim, self.llm_dim) + from funasr.models.transformer.encoder import EncoderLayer + from funasr.models.transformer.attention import MultiHeadedAttention + from funasr.models.transformer.positionwise_feed_forward import PositionwiseFeedForward + + self.blocks = nn.ModuleList( + [ + EncoderLayer( + llm_dim, + MultiHeadedAttention( + kwargs.get("attention_heads", 8), + llm_dim, + kwargs.get("attention_dropout_rate", 0.0), + ), + PositionwiseFeedForward( + llm_dim, + llm_dim // 4, + kwargs.get("dropout_rate", 0.0), + ), + kwargs.get("dropout_rate", 0.0), + ) + for i in range(kwargs.get("n_layer", 2)) + ] + ) + + def forward(self, x, ilens=None): + + batch_size, seq_len, dim = x.size() + # num_frames_to_discard = seq_len % self.k + chunk_num = (seq_len - 1) // self.k + 1 + pad_num = chunk_num * self.k - seq_len + x = F.pad(x, (0, 0, 0, pad_num, 0, 0), value=0.0) + # if num_frames_to_discard > 0: + # x = x[:, :-num_frames_to_discard, :] + seq_len = x.size(1) + + x = x.contiguous() + x = x.view(batch_size, chunk_num, dim * self.k) + x = self.linear1(x) + x = self.relu(x) + x = self.linear2(x) + + olens = None + olens = (ilens - 1) // self.k + 1 + masks = (~make_pad_mask(olens)[:, None, :]).to(x.device) + for layer, block in enumerate(self.blocks): + x, masks = block(x, masks) + return x, olens diff --git a/funasr/models/sense_voice/decoder.py b/funasr/models/sense_voice/decoder.py index 60af29ab8..ff933d77b 100644 --- a/funasr/models/sense_voice/decoder.py +++ b/funasr/models/sense_voice/decoder.py @@ -360,6 +360,7 @@ class SenseVoiceDecoder(nn.Module): """Score.""" ys_mask = subsequent_mask(len(ys), device=x.device).unsqueeze(0) logp = self.forward(ys.unsqueeze(0), x.unsqueeze(0), cache=state) + logp = torch.log_softmax(logp, dim=-1) return logp.squeeze(0)[-1, :], state diff --git a/funasr/models/sense_voice/model.py b/funasr/models/sense_voice/model.py index 127d5a0a5..22272eefc 100644 --- a/funasr/models/sense_voice/model.py +++ b/funasr/models/sense_voice/model.py @@ -1264,15 +1264,29 @@ class SenseVoiceSANM(nn.Module): if isinstance(task, str): task = [task] task = "".join([f"<|{x}|>" for x in task]) - initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") + + sos = kwargs.get("model_conf").get("sos") + if isinstance(sos, str): + initial_prompt = kwargs.get("initial_prompt", f"<|startoftranscript|>{task}") - language = DecodingOptions.get("language", None) - language = None if language == "auto" else language + language = DecodingOptions.get("language", None) + language = None if language == "auto" else language - sos = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt - sos_int = tokenizer.encode(sos, allowed_special="all") + sos = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt + sos_int = tokenizer.encode(sos, allowed_special="all") + else: + language = DecodingOptions.get("language", None) + language = None if language == "auto" else language + initial_prompt = kwargs.get("initial_prompt", f"{task}") + initial_prompt_lid = f"{initial_prompt}<|{language}|>" if language is not None else initial_prompt + initial_prompt_lid_int = tokenizer.encode(initial_prompt_lid, allowed_special="all") + sos_int = [sos] + initial_prompt_lid_int eos = kwargs.get("model_conf").get("eos") - eos_int = tokenizer.encode(eos, allowed_special="all") + if isinstance(eos, str): + eos_int = tokenizer.encode(eos, allowed_special="all") + else: + eos_int = [eos] + self.beam_search.sos = sos_int self.beam_search.eos = eos_int[0] @@ -1298,7 +1312,7 @@ class SenseVoiceSANM(nn.Module): self.beam_search.event_score_ga = DecodingOptions.get("gain_tokens_score", [1, 1, 1, 1]) encoder_out, encoder_out_lens = self.encode( - speech[None, :, :].permute(0, 2, 1), speech_lengths + speech[None, :, :], speech_lengths ) if text_token_int is not None: diff --git a/funasr/models/sense_voice/whisper_lib/model.py b/funasr/models/sense_voice/whisper_lib/model.py index 8b3d3ab1c..3d0d6a819 100644 --- a/funasr/models/sense_voice/whisper_lib/model.py +++ b/funasr/models/sense_voice/whisper_lib/model.py @@ -27,9 +27,24 @@ class ModelDimensions: n_text_layer: int +# class LayerNorm(nn.LayerNorm): +# def forward(self, x: Tensor) -> Tensor: +# return super().forward(x.float()).type(x.dtype) + + class LayerNorm(nn.LayerNorm): - def forward(self, x: Tensor) -> Tensor: - return super().forward(x.float()).type(x.dtype) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def forward(self, input): + output = F.layer_norm( + input.float(), + self.normalized_shape, + self.weight.float() if self.weight is not None else None, + self.bias.float() if self.bias is not None else None, + self.eps, + ) + return output.type_as(input) class Linear(nn.Linear): diff --git a/funasr/models/transformer/encoder.py b/funasr/models/transformer/encoder.py index a6a85ae75..987924f0c 100644 --- a/funasr/models/transformer/encoder.py +++ b/funasr/models/transformer/encoder.py @@ -64,7 +64,7 @@ class EncoderLayer(nn.Module): stochastic_depth_rate=0.0, ): """Construct an EncoderLayer object.""" - super(EncoderLayer, self).__init__() + super().__init__() self.self_attn = self_attn self.feed_forward = feed_forward self.norm1 = LayerNorm(size) diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index 1a553f812..ec887cc8c 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -621,7 +621,6 @@ class Trainer: self.train_acc_avg = train_acc_avg.detach().cpu().item() / self.world_size def forward_step(self, model, batch, loss_dict={}): - dtype = torch.bfloat16 with maybe_autocast(dtype=self.dtype, use_deepspeed=self.use_deepspeed): retval = model(**batch) From 6a7d34392c5cc3bdb512670aadb7847ae7916741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 15:43:44 +0800 Subject: [PATCH 073/125] auto frontend --- .../llm_asr/conf/whisper_qwen_linear2.yaml | 78 +++++++++++++++++++ .../llm_asr/demo_train_or_finetune2.sh | 46 +++++++++++ 2 files changed, 124 insertions(+) create mode 100644 examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml create mode 100644 examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh diff --git a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml new file mode 100644 index 000000000..59e93a6c9 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml @@ -0,0 +1,78 @@ +# This is an example that demonstrates how to configure a model file. +# You can modify the configuration according to your own requirements. + +# to print the register_table: +# from funasr.register import tables +# tables.print() + +# network architecture +model: LLMASR2 +model_conf: + lsm_weight: 0.1 # label smoothing option + length_normalized_loss: true + +# encoder +audio_encoder: "/nfs/zhifu.gzf/init_model/SenseVoiceModelscope" +audio_encoder_conf: + hub: ms + freeze: true + +llm: Qwen1.5-7b-chat +llm_conf: + hub: hf + freeze: true + init_param_path: "/nfs/zhifu.gzf/init_model/qwen/Qwen1___5-7B-Chat_raw" + +audio_adaptor: Transformer +audio_adaptor_conf: + downsample_rate: 2 + llm_dim: 4096 + encoder_dim: 1280 + n_layer: 2 + +# frontend related +frontend: WhisperFrontend +frontend_conf: + fs: 16000 + whisper_model: large-v3 + do_pad_trim: true + permute: false # true: [bs, frames, dims]; false: [bs, dims, frames] + filters_path: "/nfs/zhifu.gzf/init_model/SenseVoiceModelscope/assets/mel_filters.npz" + + + +train_conf: + accum_grad: 1 + grad_clip: 5 + max_epoch: 15 + keep_nbest_models: 10 + log_interval: 10 + +optim: adamw +optim_conf: + lr: 0.0001 + weight_decay: 0.000000 + +scheduler: warmuplr +scheduler_conf: + warmup_steps: 1500 + +dataset: OpenAIDataset +dataset_conf: + index_ds: OpenAIIndexDSJsonl + batch_sampler: CustomDistributedBatchSampler + batch_type: example # example or length + batch_size: 4 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len; + max_token_length: 3000 # filter samples if source_token_len+target_token_len > max_token_length, + shuffle: True + num_workers: 0 + audio_adaptor_downsample_rate: ${audio_adaptor_conf.downsample_rate} + audio_encoder_downsample_rate: 2 +# prompt: "<|startoftranscription|><|zh|><|transcribe|><|zh|><|notimestamps|><|wo_itn|>" + + + +tokenizer: HuggingfaceTokenizer +tokenizer_conf: + init_param_path: "/nfs/zhifu.gzf/init_model/qwen/Qwen1___5-7B-Chat_raw" + diff --git a/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh b/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh new file mode 100644 index 000000000..b3aac2b70 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh @@ -0,0 +1,46 @@ +# Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved. +# MIT License (https://opensource.org/licenses/MIT) + + +# which gpu to train or finetune +export CUDA_VISIBLE_DEVICES="0" +gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') + +# data dir, which contains: train.json, val.json, tokens.jsonl/tokens.txt, am.mvn +#data_dir="/Users/zhifu/funasr1.0/data/list" + +## generate jsonl from wav.scp and text.txt +#python -m funasr.datasets.audio_datasets.scp2jsonl \ +#++scp_file_list='["/Users/zhifu/funasr1.0/test_local/wav.scp", "/Users/zhifu/funasr1.0/test_local/text.txt"]' \ +#++data_type_list='["source", "target"]' \ +#++jsonl_file_out=/Users/zhifu/funasr1.0/test_local/audio_datasets.jsonl + +train_data="/nfs/beinian.lzr/workspace/tools/speech2speech_tools/speech2text/out_dir/tmp_wav.jsonl" +val_data="/nfs/beinian.lzr/workspace/tools/speech2speech_tools/speech2text/out_dir/tmp_wav.jsonl" + +# exp output dir +output_dir="/Users/zhifu/funasr1.0/test_local/data_tmp/" +log_file="${output_dir}/log.txt" + +workspace=`pwd` +config="whisper_qwen_linear2.yaml" + +init_param="${output_dir}/model.pt" + +mkdir -p ${output_dir} +echo "log_file: ${log_file}" + +torchrun \ +--nnodes 1 \ +--nproc_per_node ${gpu_num} \ +../../../funasr/bin/train.py \ +--config-path "${workspace}/conf" \ +--config-name "${config}" \ +++train_data_set_list="${train_data}" \ +++valid_data_set_list="${val_data}" \ +++dataset_conf.batch_size=1 \ +++dataset_conf.num_workers=0 \ +++train_conf.max_epoch=15 \ +++optim_conf.lr=0.0001 \ +++init_param="${init_param}" \ +++output_dir="${output_dir}" &> ${log_file} & From 27256ed429c95ed8868a01f8555610393dd7b3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 15:45:32 +0800 Subject: [PATCH 074/125] auto frontend --- funasr/datasets/openai_datasets/__init__.py | 0 funasr/datasets/openai_datasets/datasets.py | 216 ++++++++++++ funasr/datasets/openai_datasets/index_ds.py | 95 ++++++ .../datasets/sense_voice_datasets/datasets.py | 1 + funasr/models/llm_asr/model.py | 318 ++++++++++++++++++ 5 files changed, 630 insertions(+) create mode 100644 funasr/datasets/openai_datasets/__init__.py create mode 100644 funasr/datasets/openai_datasets/datasets.py create mode 100644 funasr/datasets/openai_datasets/index_ds.py diff --git a/funasr/datasets/openai_datasets/__init__.py b/funasr/datasets/openai_datasets/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py new file mode 100644 index 000000000..9a542adb6 --- /dev/null +++ b/funasr/datasets/openai_datasets/datasets.py @@ -0,0 +1,216 @@ +import logging +import re +import torch +import random +import traceback +from funasr.register import tables +from funasr.utils.load_utils import extract_fbank, load_audio_text_image_video + + +@tables.register("dataset_classes", "OpenAIDataset") +class OpenAIDataset(torch.utils.data.Dataset): + """ + SenseVoiceDataset + """ + + def __init__( + self, + path, + index_ds: str = None, + frontend=None, + tokenizer=None, + int_pad_value: int = -1, + float_pad_value: float = 0.0, + **kwargs, + ): + super().__init__() + index_ds_class = tables.index_ds_classes.get(index_ds) + self.index_ds = index_ds_class(path, **kwargs) + preprocessor_speech = kwargs.get("preprocessor_speech", None) + if preprocessor_speech: + preprocessor_speech_class = tables.preprocessor_classes.get(preprocessor_speech) + preprocessor_speech = preprocessor_speech_class( + **kwargs.get("preprocessor_speech_conf") + ) + self.preprocessor_speech = preprocessor_speech + preprocessor_text = kwargs.get("preprocessor_text", None) + if preprocessor_text: + preprocessor_text_class = tables.preprocessor_classes.get(preprocessor_text) + preprocessor_text = preprocessor_text_class(**kwargs.get("preprocessor_text_conf")) + self.preprocessor_text = preprocessor_text + + self.frontend = frontend + self.fs = 16000 if frontend is None else frontend.fs + self.data_type = "sound" + self.tokenizer = tokenizer + + self.int_pad_value = int_pad_value + self.float_pad_value = float_pad_value + self.sos = kwargs.get("sos", "<|startoftranscript|>") + self.eos = kwargs.get("eos", "<|endoftext|>") + self.batch_size = kwargs.get("batch_size") + self.batch_type = kwargs.get("batch_type") + self.prompt_ids_len = 0 + self.retry = kwargs.get("retry", 5) + + self.permute = False + from funasr.frontends.whisper_frontend import WhisperFrontend + + if isinstance(self.frontend, WhisperFrontend): + self.permute = True + + self.pattern = re.compile(r"(<\|startofspeech\|>.*?<\|endofspeech\|>)") + + def get_source_len(self, index): + item = self.index_ds[index] + return self.index_ds.get_source_len(item) + + def get_target_len(self, index): + item = self.index_ds[index] + return self.index_ds.get_target_len(item) + + def __len__(self): + return len(self.index_ds) + + def __getitem__(self, index): + # import pdb; + # pdb.set_trace() + + output = None + for idx in range(self.retry): + if idx == 0: + index_cur = index + else: + index_cur = torch.randint(0, len(self.index_ds), ()).item() + + item = self.index_ds[index_cur] + + system = item["system"] + user = item["user"] + assistant = item["assistant"] + + input_ids, labels, fbank, fbank_lens, fbank_mask, fbank_beg = [], [], [], [], [], [] + + for i, (system_prompt, user_prompt, target_out) in enumerate( + zip(system, user, assistant) + ): + + source_input = f"<|im_start|>system\n{system_prompt}<|im_end|>\n<|im_start|>user\n{user_prompt}<|im_end|>\n<|im_start|>assistant\n" + + splits = self.pattern.split(source_input) + source_ids = [] + fbank_mask_i = [] + fbank_beg_i = [] + fbank_lens_i = [] + for k, sub_str in enumerate(splits): + if not sub_str.startswith("<|startofspeech|>"): + sub_token = self.tokenizer.encode(sub_str) + source_ids += sub_token + fbank_mask_i += [0] * len(sub_token) + else: + sub_str = sub_str.replace("<|startofspeech|>", "").replace( + "<|endofspeech|>", "" + ) + if sub_str.startswith("!"): + + data_src = load_audio_text_image_video(sub_str[1:], fs=self.fs) + + speech, speech_lengths = extract_fbank( + data_src, + data_type=self.data_type, + frontend=self.frontend, + is_final=True, + ) # speech: [b, T, d] + if self.permute: + speech = speech.permute(0, 2, 1) + if speech_lengths > self.batch_size: + continue + + fbank_lens = speech_lengths[0].item() + olens = 1 + (fbanks_len - 3 + 2 * 1) // 2 + olens = 1 + (olens - 3 + 2 * 1) // 2 + sub_token_len = (olens - 1) // 2 + 1 + sub_token = [0] * sub_token_len[0] + fbank_beg_i = [len(source_ids)] + source_ids += sub_token + fbank_mask_i += [1] * len(sub_token) + + source_mask = [-100] * len(source_ids) + target_out = f"{target_out}<|im_end|>" + target_ids = tokenizer.encode(target_out) + input_ids += source_ids + target_ids + labels += source_mask + target_ids + fbank_mask += fbank_mask_i + fbank_beg.append(fbank_beg_i) + + input_ids = torch.tensor(input_ids, dtype=torch.int64) + attention_mask = torch.tensor([len(input_ids)], dtype=torch.int32) + labels = torch.tensor(labels, dtype=torch.int64) + + fbank = speech[0, :, :] + fbank_lens = speech_lengths + fbank_mask = torch.tensor(fbank_mask, dtype=torch.float32) + fbank_beg = torch.tensor(fbank_beg, dtype=torch.int32) + + output = { + "speech": fbank, + "speech_lengths": fbank_lens, + "fbank_mask": fbank_mask, + "fbank_beg": fbank_beg, + "input_ids": input_ids, + "attention_mask": attention_mask, + "labels_ids": labels, + } + break + + return output + + def collator(self, samples: list = None): + outputs = {} + for sample in samples: + if sample is None: + continue + for key in sample.keys(): + if key not in outputs: + outputs[key] = [] + outputs[key].append(sample[key]) + + for key, data_list in outputs.items(): + if isinstance(data_list[0], torch.Tensor): + if data_list[0].dtype == torch.int64 or data_list[0].dtype == torch.int32: + + pad_value = self.int_pad_value + else: + pad_value = self.float_pad_value + + outputs[key] = torch.nn.utils.rnn.pad_sequence( + data_list, batch_first=True, padding_value=pad_value + ) + + if self.batch_type != "example": + for i in range(10): + outputs = self._filter_badcase(outputs, i=i) + + return outputs + + def _filter_badcase(self, outputs, i=0): + b, t, _ = outputs["speech"].shape + + if b * t > self.batch_size * 1.25: + beg = torch.randint(0, 2, ()).item() + if b < 2: + beg = 0 + logging.info( + f"Warning, b * t: {b * t} > {self.batch_size}, drop half data {i}th, beg:{beg}" + ) + for key, data_list in outputs.items(): + outputs[key] = outputs[key][beg : beg + b : 2] + + speech_lengths_max = outputs["speech_lengths"].max().item() + outputs["speech"] = outputs["speech"][:, :speech_lengths_max, :] + text_lengths_max = outputs["text_lengths"].max().item() + outputs["text"] = outputs["text"][:, :text_lengths_max] + target_mask_lengths_max = outputs["target_mask_lengths"].max().item() + outputs["target_mask"] = outputs["target_mask"][:, :target_mask_lengths_max] + + return outputs diff --git a/funasr/datasets/openai_datasets/index_ds.py b/funasr/datasets/openai_datasets/index_ds.py new file mode 100644 index 000000000..1c48cd241 --- /dev/null +++ b/funasr/datasets/openai_datasets/index_ds.py @@ -0,0 +1,95 @@ +import os +import json +import torch +import logging + +import librosa +import random +import torch.distributed as dist + +from funasr.register import tables + + +@tables.register("index_ds_classes", "OpenAIIndexDSJsonl") +class OpenAIIndexDSJsonl(torch.utils.data.Dataset): # torch.utils.data.Dataset + + def __init__(self, path: str, **kwargs): + super().__init__() + self.max_source_length = kwargs.get("max_source_length", 2048) + self.min_source_length = kwargs.get("min_source_length", 0) + self.max_target_length = kwargs.get("max_target_length", 2048) + self.min_target_length = kwargs.get("min_target_length", 0) + self.max_token_length = kwargs.get("max_token_length", 2200) + + is_training = kwargs.get("is_training", True) + if not (path.endswith(".jsonl") or path.endswith(".json")): + # jsonl list file + data_split_num = kwargs.get("data_split_num", 1) + data_split_i = kwargs.get("data_split_i", 0) + + if not is_training: + data_split_num = 1 + data_split_i = 0 + with open(path, encoding="utf-8") as fin: + file_list_all = fin.readlines() + + num_per_slice = (len(file_list_all) - 1) // data_split_num + 1 # 16 + file_list = file_list_all[ + data_split_i * num_per_slice : (data_split_i + 1) * num_per_slice + ] + logging.info( + f"is_training: {is_training}, data_split_num: {data_split_num}, data_split_i: {data_split_i}, \nfile_list: {file_list}, \nfile_list_all: {file_list_all}" + ) + + else: + file_list = [path] + + contents = [] + for file_json in file_list: + with open(file_json.strip(), encoding="utf-8") as fin: + for line in fin: + data = json.loads(line.strip())["messages"] + + system, user, assistant = [], [], [] + for i, item in enumerate(data): + role = item["role"] + content = item["content"] + if role == "system": + system.append(content) + elif role == "user": + user.append(content) + elif role == "assistant": + assistant.append(content) + + system = system * len(user) + + contents_i = {"system": system, "user": user, "assistant": assistant} + contents.append(contents_i) + + self.contents = contents + + logging.info("total_num of samplers: {}, {}".format(len(self.contents), path)) + + def __len__(self): + return len(self.contents) + + def __getitem__(self, index): + + data = self.contents[index] + + return data + + def get_source_len(self, data_dict): + return len(data_dict["system"]) + len(data_dict["user"]) + + def get_target_len(self, data_dict): + + return len(data_dict["assistant"]) + + +if __name__ == "__main__": + index_ds = OpenAIIndexDSJsonl( + path="/Users/zhifu/funasr1.0/test_local/data_tmp/tmp_wav_10.jsonl" + ) + print(index_ds.contents) + pass diff --git a/funasr/datasets/sense_voice_datasets/datasets.py b/funasr/datasets/sense_voice_datasets/datasets.py index 690a1c56c..c0beda102 100644 --- a/funasr/datasets/sense_voice_datasets/datasets.py +++ b/funasr/datasets/sense_voice_datasets/datasets.py @@ -1,5 +1,6 @@ import logging +import re import torch import random import traceback diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 4345f696d..11db0096d 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -341,3 +341,321 @@ class LLMASR(nn.Module): ibest_writer["text"][key[0]] = text return results, meta_data + + +@tables.register("model_classes", "LLMASR2") +class LLMASR2(nn.Module): + """ """ + + def __init__( + self, + specaug: str = None, + specaug_conf: dict = None, + normalize: str = None, + normalize_conf: dict = None, + audio_encoder: str = None, + audio_encoder_conf: dict = None, + audio_adaptor: str = None, + audio_adaptor_conf: dict = None, + decoder: str = None, + decoder_conf: dict = None, + ctc: str = None, + ctc_conf: dict = None, + ctc_weight: float = 0.5, + llm: str = None, + llm_conf: dict = None, + input_size: int = 80, + vocab_size: int = -1, + ignore_id: int = -1, + blank_id: int = 0, + sos: int = 1, + eos: int = 2, + lsm_weight: float = 0.0, + length_normalized_loss: bool = False, + report_cer: bool = True, + report_wer: bool = True, + sym_space: str = "", + sym_blank: str = "", + # extract_feats_in_collect_stats: bool = True, + share_embedding: bool = False, + # preencoder: Optional[AbsPreEncoder] = None, + # postencoder: Optional[AbsPostEncoder] = None, + **kwargs, + ): + + super().__init__() + + if specaug is not None: + specaug_class = tables.specaug_classes.get(specaug) + specaug = specaug_class(**specaug_conf) + if normalize is not None: + normalize_class = tables.normalize_classes.get(normalize) + normalize = normalize_class(**normalize_conf) + + # audio encoder + hub = audio_encoder_conf.get("hub", None) + if hub == "ms": + from funasr import AutoModel + + model = AutoModel(model=audio_encoder, model_revision="master") + # frontend = model.kwargs.get("frontend") + audio_encoder_output_size = model.model.encoder_output_size + + audio_encoder = model.model.model.encoder + + # self.frontend = frontend + + elif hub == "hf": + pass + else: + encoder_class = tables.encoder_classes.get(audio_encoder) + audio_encoder = encoder_class(input_size=input_size, **audio_encoder_conf) + audio_encoder_output_size = audio_encoder.output_size() + freeze = audio_encoder_conf.get("freeze", True) + if freeze: + for name, param in audio_encoder.named_parameters(): + param.requires_grad = False + audio_encoder.eval() + + self.audio_encoder = audio_encoder + + # llm + hub = llm_conf.get("hub", "hf") + self.llm = None + # if hub == "hf": + # from transformers import AutoModelForCausalLM, AutoTokenizer, AutoConfig + # + # init_param_path = llm_conf.get("init_param_path", "vicuna-7b-v1.5") + # + # model = AutoModelForCausalLM.from_pretrained( + # init_param_path, + # load_in_8bit=None, + # device_map=None, + # use_cache=None, + # ) + # freeze = llm_conf.get("freeze", True) + # if freeze: + # for name, param in model.named_parameters(): + # param.requires_grad = False + # model.eval() + # self.llm = model + + # adaptor + adaptor_class = tables.adaptor_classes.get(audio_adaptor) + audio_adaptor_conf["encoder_dim"] = audio_encoder_output_size + audio_adaptor = adaptor_class(**audio_adaptor_conf) + + self.audio_adaptor = audio_adaptor + + self.blank_id = blank_id + self.sos = sos if sos is not None else vocab_size - 1 + self.eos = eos if eos is not None else vocab_size - 1 + self.vocab_size = vocab_size + self.ignore_id = ignore_id + self.specaug = specaug + self.normalize = normalize + + self.criterion_att = LabelSmoothingLoss( + size=vocab_size, + padding_idx=ignore_id, + smoothing=lsm_weight, + normalize_length=length_normalized_loss, + ) + + self.error_calculator = None + + self.length_normalized_loss = length_normalized_loss + self.beam_search = None + + def forward( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + input_ids: torch.Tensor, + attention_mask: torch.Tensor, + labels_ids: torch.Tensor, + fbank_beg: torch.Tensor, + fbank_mask: torch.Tensor, + **kwargs, + ) -> Tuple[torch.Tensor, Dict[str, torch.Tensor], torch.Tensor]: + """Encoder + Decoder + Calc loss + Args: + speech: (Batch, Length, ...) + speech_lengths: (Batch, ) + text: (Batch, Length) + text_lengths: (Batch,) + """ + # import pdb; + # pdb.set_trace() + if len(speech_lengths.size()) > 1: + speech_lengths = speech_lengths[:, 0] + + batch_size = speech.shape[0] + + # audio encoder + encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) + + # audio_adaptor + encoder_out = self.audio_adaptor(encoder_out) + + input_ids[input_ids == -1] = 0 + input_ids[input_ids == -100] = 0 + if hasattr(self.llm.model, "embed_tokens"): + inputs_embeds = self.llm.model.embed_tokens(input_ids) + elif hasattr(self.llm.model.model, "embed_tokens"): + inputs_embeds = self.llm.model.model.embed_tokens(input_ids) + else: + inputs_embeds = self.llm.model.model.model.embed_tokens(input_ids) + + batch_size, token_num, dims = inputs_embeds.shape + _, l, _ = encoder_out.shape + for batch_idx in range(batch_size): + fbank_beg_idx = fbank_beg[batch_idx, 0].item() + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + l, :] = encoder_out[ + batch_idx, :l, : + ] + + model_outputs = self.llm( + inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids + ) + loss = model_outputs.loss + + stats = {} + with torch.no_grad(): + preds = torch.argmax(model_outputs.logits, -1) + acc_att = compute_accuracy(preds[:, :-1], labels_ids[:, 1:], ignore_label=-100) + stats["acc"] = acc_att + + stats["loss"] = torch.clone(loss.detach()) + + # force_gatherable: to-device and to-tensor if scalar for DataParallel + if self.length_normalized_loss: + batch_size = int((text_lengths + 1).sum()) + loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) + return loss, stats, weight + + def encode( + self, + speech: torch.Tensor, + speech_lengths: torch.Tensor, + **kwargs, + ): + speech = speech.permute(0, 2, 1) + res = self.audio_encoder(speech) + if isinstance(res, (list, tuple)): + encoder_out, encoder_out_lens = res[0], res[1] + else: + encoder_out, encoder_out_lens = res, speech_lengths + return encoder_out, encoder_out_lens + + def inference( + self, + data_in, + data_lengths=None, + key: list = None, + tokenizer=None, + frontend=None, + **kwargs, + ): + + prompt = kwargs.get("prompt", "Transcribe speech to text.") + + if kwargs.get("batch_size", 1) > 1: + raise NotImplementedError("batch decoding is not implemented") + + meta_data = {} + if ( + isinstance(data_in, torch.Tensor) and kwargs.get("data_type", "sound") == "fbank" + ): # fbank + speech, speech_lengths = data_in, data_lengths + if len(speech.shape) < 3: + speech = speech[None, :, :] + if speech_lengths is None: + speech_lengths = speech.shape[1] + else: + # extract fbank feats + time1 = time.perf_counter() + audio_sample_list = load_audio_text_image_video( + data_in, + fs=frontend.fs, + audio_fs=kwargs.get("fs", 16000), + data_type=kwargs.get("data_type", "sound"), + tokenizer=tokenizer, + ) + time2 = time.perf_counter() + meta_data["load_data"] = f"{time2 - time1:0.3f}" + speech, speech_lengths = extract_fbank( + audio_sample_list, data_type=kwargs.get("data_type", "sound"), frontend=frontend + ) + time3 = time.perf_counter() + meta_data["extract_feat"] = f"{time3 - time2:0.3f}" + meta_data["batch_data_time"] = ( + speech_lengths.sum().item() * frontend.frame_shift * frontend.lfr_n / 1000 + ) + + speech = speech.to(device=kwargs["device"]) + speech_lengths = speech_lengths.to(device=kwargs["device"]) + + # Encoder + encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) + + # adaptor + encoder_out = self.audio_adaptor(encoder_out) + + prompt_pre = "USER: \nINSTRUCTION: {}\nINPUT: ".format(prompt) + prompt_ids = tokenizer.encode(prompt_pre) + prompt_length = len(prompt_ids) + prompt_ids = torch.tensor(prompt_ids, dtype=torch.int64).to(kwargs["device"]) + + if hasattr(self.llm.model, "embed_tokens"): + inputs_embeds = self.llm.model.embed_tokens(prompt_ids) + elif hasattr(self.llm.model.model, "embed_tokens"): + inputs_embeds = self.llm.model.model.embed_tokens(prompt_ids) + else: + inputs_embeds = self.llm.model.model.model.embed_tokens(prompt_ids) + + inputs_embeds = torch.cat( + (inputs_embeds[None, :, :], encoder_out), dim=1 + ) # [prompt, audio] + attention_mask = torch.ones(inputs_embeds.size()[:-1], dtype=torch.long).to( + kwargs["device"] + ) + + preds = self.llm.generate( + inputs_embeds=inputs_embeds, + max_length=kwargs.get("max_length", 200), + max_new_tokens=kwargs.get("max_new_tokens", 200), + num_beams=kwargs.get("num_beams", 4), + do_sample=kwargs.get("do_sample", False), + min_length=kwargs.get("min_length", 1), + top_p=kwargs.get("top_p", 1.0), + repetition_penalty=kwargs.get("repetition_penalty", 1.0), + length_penalty=kwargs.get("length_penalty", 1.0), + temperature=kwargs.get("temperature", 1.0), + attention_mask=attention_mask, + bos_token_id=tokenizer.bos_token_id, + eos_token_id=tokenizer.eos_token_id, + pad_token_id=tokenizer.pad_token_id, + ) + + text = tokenizer.batch_decode(preds, add_special_tokens=False, skip_special_tokens=True) + + text = text[0].split(": ")[-1] + text = text.strip() + + # preds = torch.argmax(model_outputs.logits, -1) + + ibest_writer = None + if kwargs.get("output_dir") is not None: + if not hasattr(self, "writer"): + self.writer = DatadirWriter(kwargs.get("output_dir")) + ibest_writer = self.writer[f"{0 + 1}best_recog"] + + results = [] + result_i = {"key": key[0], "text": text} + results.append(result_i) + + if ibest_writer is not None: + ibest_writer["text"][key[0]] = text + + return results, meta_data From e9acc5db07daa51a22cd51ea9233ee09a38d726d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 18:36:22 +0800 Subject: [PATCH 075/125] auto frontend --- .../llm_asr/conf/whisper_qwen_linear2.yaml | 2 +- funasr/datasets/openai_datasets/datasets.py | 11 ++- funasr/models/llm_asr/model.py | 76 +++++-------------- 3 files changed, 26 insertions(+), 63 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml index 59e93a6c9..62d77e260 100644 --- a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml +++ b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml @@ -35,7 +35,7 @@ frontend: WhisperFrontend frontend_conf: fs: 16000 whisper_model: large-v3 - do_pad_trim: true + do_pad_trim: false permute: false # true: [bs, frames, dims]; false: [bs, dims, frames] filters_path: "/nfs/zhifu.gzf/init_model/SenseVoiceModelscope/assets/mel_filters.npz" diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 9a542adb6..9bd0698fb 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -123,21 +123,20 @@ class OpenAIDataset(torch.utils.data.Dataset): ) # speech: [b, T, d] if self.permute: speech = speech.permute(0, 2, 1) - if speech_lengths > self.batch_size: - continue + # if speech_lengths > self.batch_size: + # continue - fbank_lens = speech_lengths[0].item() - olens = 1 + (fbanks_len - 3 + 2 * 1) // 2 + olens = 1 + (speech_lengths[0].item() - 3 + 2 * 1) // 2 olens = 1 + (olens - 3 + 2 * 1) // 2 sub_token_len = (olens - 1) // 2 + 1 - sub_token = [0] * sub_token_len[0] + sub_token = [0] * sub_token_len fbank_beg_i = [len(source_ids)] source_ids += sub_token fbank_mask_i += [1] * len(sub_token) source_mask = [-100] * len(source_ids) target_out = f"{target_out}<|im_end|>" - target_ids = tokenizer.encode(target_out) + target_ids = self.tokenizer.encode(target_out) input_ids += source_ids + target_ids labels += source_mask + target_ids fbank_mask += fbank_mask_i diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 11db0096d..411b59d94 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -385,13 +385,6 @@ class LLMASR2(nn.Module): super().__init__() - if specaug is not None: - specaug_class = tables.specaug_classes.get(specaug) - specaug = specaug_class(**specaug_conf) - if normalize is not None: - normalize_class = tables.normalize_classes.get(normalize) - normalize = normalize_class(**normalize_conf) - # audio encoder hub = audio_encoder_conf.get("hub", None) if hub == "ms": @@ -422,23 +415,23 @@ class LLMASR2(nn.Module): # llm hub = llm_conf.get("hub", "hf") self.llm = None - # if hub == "hf": - # from transformers import AutoModelForCausalLM, AutoTokenizer, AutoConfig - # - # init_param_path = llm_conf.get("init_param_path", "vicuna-7b-v1.5") - # - # model = AutoModelForCausalLM.from_pretrained( - # init_param_path, - # load_in_8bit=None, - # device_map=None, - # use_cache=None, - # ) - # freeze = llm_conf.get("freeze", True) - # if freeze: - # for name, param in model.named_parameters(): - # param.requires_grad = False - # model.eval() - # self.llm = model + if hub == "hf": + from transformers import AutoModelForCausalLM, AutoTokenizer, AutoConfig + + init_param_path = llm_conf.get("init_param_path", "vicuna-7b-v1.5") + + model = AutoModelForCausalLM.from_pretrained( + init_param_path, + load_in_8bit=None, + device_map=None, + use_cache=None, + ) + freeze = llm_conf.get("freeze", True) + if freeze: + for name, param in model.named_parameters(): + param.requires_grad = False + model.eval() + self.llm = model # adaptor adaptor_class = tables.adaptor_classes.get(audio_adaptor) @@ -447,21 +440,6 @@ class LLMASR2(nn.Module): self.audio_adaptor = audio_adaptor - self.blank_id = blank_id - self.sos = sos if sos is not None else vocab_size - 1 - self.eos = eos if eos is not None else vocab_size - 1 - self.vocab_size = vocab_size - self.ignore_id = ignore_id - self.specaug = specaug - self.normalize = normalize - - self.criterion_att = LabelSmoothingLoss( - size=vocab_size, - padding_idx=ignore_id, - smoothing=lsm_weight, - normalize_length=length_normalized_loss, - ) - self.error_calculator = None self.length_normalized_loss = length_normalized_loss @@ -493,10 +471,10 @@ class LLMASR2(nn.Module): batch_size = speech.shape[0] # audio encoder - encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) + encoder_out, encoder_out_lens = self.audio_encoder(speech.permute(0, 2, 1), speech_lengths) # audio_adaptor - encoder_out = self.audio_adaptor(encoder_out) + encoder_out, encoder_out_lens = self.audio_adaptor(encoder_out, encoder_out_lens) input_ids[input_ids == -1] = 0 input_ids[input_ids == -100] = 0 @@ -530,24 +508,10 @@ class LLMASR2(nn.Module): # force_gatherable: to-device and to-tensor if scalar for DataParallel if self.length_normalized_loss: - batch_size = int((text_lengths + 1).sum()) + batch_size = int((labels_ids > 0 + 1).sum()) loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) return loss, stats, weight - def encode( - self, - speech: torch.Tensor, - speech_lengths: torch.Tensor, - **kwargs, - ): - speech = speech.permute(0, 2, 1) - res = self.audio_encoder(speech) - if isinstance(res, (list, tuple)): - encoder_out, encoder_out_lens = res[0], res[1] - else: - encoder_out, encoder_out_lens = res, speech_lengths - return encoder_out, encoder_out_lens - def inference( self, data_in, From 9633e64bb1d7aef3ea49fe1e4ed3d7fab838b52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 18:46:29 +0800 Subject: [PATCH 076/125] auto frontend --- funasr/train_utils/model_summary.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/funasr/train_utils/model_summary.py b/funasr/train_utils/model_summary.py index 4e92a33cf..842cd21fa 100644 --- a/funasr/train_utils/model_summary.py +++ b/funasr/train_utils/model_summary.py @@ -47,10 +47,18 @@ def to_bytes(dtype) -> int: def model_summary(model: torch.nn.Module) -> str: message = "Model structure:\n" message += str(model) - # for p in model.parameters(): - # print(f"{p.numel()}") - tot_params = sum(p.numel() for p in model.parameters()) - num_params = sum(p.numel() for p in model.parameters() if p.requires_grad) + + tot_params, num_params = 0, 0 + for name, param in model.named_parameters(): + print( + "name: {}, dtype: {}, device: {}, trainable: {}, shape: {}, numel: {}".format( + name, param.dtype, param.device, param.requires_grad, param.shape, param.numel() + ) + ) + tot_params += param.numel() + if param.requires_grad: + num_params += param.numel() + percent_trainable = "{:.1f}".format(num_params * 100.0 / tot_params) tot_params = get_human_readable_count(tot_params) num_params = get_human_readable_count(num_params) From 524237d7595c6f3839a12df30959c1504fab79b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 18:53:10 +0800 Subject: [PATCH 077/125] auto frontend --- .../llm_asr/demo_train_or_finetune2.sh | 1 + funasr/train_utils/trainer.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh b/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh index b3aac2b70..306e23db9 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_train_or_finetune2.sh @@ -41,6 +41,7 @@ torchrun \ ++dataset_conf.batch_size=1 \ ++dataset_conf.num_workers=0 \ ++train_conf.max_epoch=15 \ +++train_conf.save_checkpoint_interval=1000 \ ++optim_conf.lr=0.0001 \ ++init_param="${init_param}" \ ++output_dir="${output_dir}" &> ${log_file} & diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index 50f99f023..60fd96966 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -85,7 +85,12 @@ class Trainer: self.batch_total = 0 self.use_fp16 = use_fp16 self.save_checkpoint_interval = kwargs.get("save_checkpoint_interval", 5000) - self.validate_interval = kwargs.get("validate_interval", 5000) + self.validate_interval = kwargs.get("validate_interval", -1) + if self.validate_interval < 0: + self.validate_interval = self.save_checkpoint_interval + assert ( + self.save_checkpoint_interval == self.validate_interval + ), f"save_checkpoint_interval must equal to validate_interval" self.keep_nbest_models = kwargs.get("keep_nbest_models", 500) self.avg_keep_nbest_models_type = kwargs.get("avg_keep_nbest_models_type", "acc") self.avg_nbest_model = kwargs.get("avg_nbest_model", 10) From d6fedbfa77abee8b31340dc1a7aa344b84c8134c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 19:22:11 +0800 Subject: [PATCH 078/125] auto frontend --- .../deepspeed/ds_stage1.json | 33 +++++++++++++++ .../deepspeed/ds_stage2.json | 33 +++++++++++++++ .../deepspeed/ds_stage3.json | 41 +++++++++++++++++++ .../deepspeed/ds_z0_config.json | 28 +++++++++++++ .../deepspeed/ds_z2_config.json | 28 +++++++++++++ .../deepspeed/ds_z2_offload_config.json | 32 +++++++++++++++ .../deepspeed/ds_z3_config.json | 30 ++++++++++++++ .../deepspeed/ds_z3_offload_config.json | 38 +++++++++++++++++ funasr/models/llm_asr/model.py | 12 ++---- 9 files changed, 266 insertions(+), 9 deletions(-) create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_stage1.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_stage2.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_stage3.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_z0_config.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_z2_config.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_z2_offload_config.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_z3_config.json create mode 100644 examples/industrial_data_pretraining/deepspeed/ds_z3_offload_config.json diff --git a/examples/industrial_data_pretraining/deepspeed/ds_stage1.json b/examples/industrial_data_pretraining/deepspeed/ds_stage1.json new file mode 100644 index 000000000..51804c1f1 --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_stage1.json @@ -0,0 +1,33 @@ +{ + "train_micro_batch_size_per_gpu": 1, + "gradient_accumulation_steps": 1, + "steps_per_print": 100, + "gradient_clipping": 5, + "fp16": { + "enabled": false, + "auto_cast": false, + "loss_scale": 0, + "initial_scale_power": 16, + "loss_scale_window": 1000, + "hysteresis": 2, + "consecutive_hysteresis": false, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": true + }, + "zero_force_ds_cpu_optimizer": false, + "zero_optimization": { + "stage": 1, + "offload_optimizer": { + "device": "none", + "pin_memory": true + }, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients" : true + } +} diff --git a/examples/industrial_data_pretraining/deepspeed/ds_stage2.json b/examples/industrial_data_pretraining/deepspeed/ds_stage2.json new file mode 100644 index 000000000..c11b7d61e --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_stage2.json @@ -0,0 +1,33 @@ +{ + "train_micro_batch_size_per_gpu": 1, + "gradient_accumulation_steps": 1, + "steps_per_print": 100, + "gradient_clipping": 5, + "fp16": { + "enabled": false, + "auto_cast": false, + "loss_scale": 0, + "initial_scale_power": 16, + "loss_scale_window": 1000, + "hysteresis": 2, + "consecutive_hysteresis": false, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": true + }, + "zero_force_ds_cpu_optimizer": false, + "zero_optimization": { + "stage": 2, + "offload_optimizer": { + "device": "none", + "pin_memory": true + }, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": false, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients" : true + } +} diff --git a/examples/industrial_data_pretraining/deepspeed/ds_stage3.json b/examples/industrial_data_pretraining/deepspeed/ds_stage3.json new file mode 100644 index 000000000..ba382935a --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_stage3.json @@ -0,0 +1,41 @@ +{ + "train_micro_batch_size_per_gpu": 1, + "gradient_accumulation_steps": 1, + "steps_per_print": 100, + "gradient_clipping": 5, + "fp16": { + "enabled": false, + "auto_cast": false, + "loss_scale": 0, + "initial_scale_power": 16, + "loss_scale_window": 1000, + "hysteresis": 2, + "consecutive_hysteresis": false, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": true + }, + "zero_force_ds_cpu_optimizer": false, + "zero_optimization": { + "stage": 3, + "offload_optimizer": { + "device": "none", + "pin_memory": true + }, + "offload_param": { + "device": "none", + "pin_memory": true + }, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients" : true, + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "stage3_prefetch_bucket_size": 5e8, + "stage3_param_persistence_threshold": 1e5 + } +} diff --git a/examples/industrial_data_pretraining/deepspeed/ds_z0_config.json b/examples/industrial_data_pretraining/deepspeed/ds_z0_config.json new file mode 100644 index 000000000..ed326676a --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_z0_config.json @@ -0,0 +1,28 @@ +{ + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "zero_allow_untested_optimizer": true, + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "zero_optimization": { + "stage": 0, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients": true, + "round_robin_gradients": true + } +} \ No newline at end of file diff --git a/examples/industrial_data_pretraining/deepspeed/ds_z2_config.json b/examples/industrial_data_pretraining/deepspeed/ds_z2_config.json new file mode 100644 index 000000000..0a1bd1d87 --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_z2_config.json @@ -0,0 +1,28 @@ +{ + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "zero_allow_untested_optimizer": true, + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "zero_optimization": { + "stage": 2, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients": true, + "round_robin_gradients": true + } +} \ No newline at end of file diff --git a/examples/industrial_data_pretraining/deepspeed/ds_z2_offload_config.json b/examples/industrial_data_pretraining/deepspeed/ds_z2_offload_config.json new file mode 100644 index 000000000..7a3983647 --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_z2_offload_config.json @@ -0,0 +1,32 @@ +{ + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "zero_allow_untested_optimizer": true, + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "zero_optimization": { + "stage": 2, + "offload_optimizer": { + "device": "cpu", + "pin_memory": true + }, + "allgather_partitions": true, + "allgather_bucket_size": 5e8, + "overlap_comm": true, + "reduce_scatter": true, + "reduce_bucket_size": 5e8, + "contiguous_gradients": true, + "round_robin_gradients": true + } +} \ No newline at end of file diff --git a/examples/industrial_data_pretraining/deepspeed/ds_z3_config.json b/examples/industrial_data_pretraining/deepspeed/ds_z3_config.json new file mode 100644 index 000000000..ccf9560eb --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_z3_config.json @@ -0,0 +1,30 @@ +{ + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "zero_allow_untested_optimizer": true, + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "zero_optimization": { + "stage": 3, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto", + "stage3_prefetch_bucket_size": "auto", + "stage3_param_persistence_threshold": "auto", + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "stage3_gather_16bit_weights_on_model_save": true + } +} \ No newline at end of file diff --git a/examples/industrial_data_pretraining/deepspeed/ds_z3_offload_config.json b/examples/industrial_data_pretraining/deepspeed/ds_z3_offload_config.json new file mode 100644 index 000000000..026aabbcd --- /dev/null +++ b/examples/industrial_data_pretraining/deepspeed/ds_z3_offload_config.json @@ -0,0 +1,38 @@ +{ + "train_batch_size": "auto", + "train_micro_batch_size_per_gpu": "auto", + "gradient_accumulation_steps": "auto", + "gradient_clipping": "auto", + "zero_allow_untested_optimizer": true, + "fp16": { + "enabled": "auto", + "loss_scale": 0, + "loss_scale_window": 1000, + "initial_scale_power": 16, + "hysteresis": 2, + "min_loss_scale": 1 + }, + "bf16": { + "enabled": "auto" + }, + "zero_optimization": { + "stage": 3, + "offload_optimizer": { + "device": "cpu", + "pin_memory": true + }, + "offload_param": { + "device": "cpu", + "pin_memory": true + }, + "overlap_comm": true, + "contiguous_gradients": true, + "sub_group_size": 1e9, + "reduce_bucket_size": "auto", + "stage3_prefetch_bucket_size": "auto", + "stage3_param_persistence_threshold": "auto", + "stage3_max_live_parameters": 1e9, + "stage3_max_reuse_distance": 1e9, + "stage3_gather_16bit_weights_on_model_save": true + } +} \ No newline at end of file diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 411b59d94..0d9bf7f09 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -476,14 +476,8 @@ class LLMASR2(nn.Module): # audio_adaptor encoder_out, encoder_out_lens = self.audio_adaptor(encoder_out, encoder_out_lens) - input_ids[input_ids == -1] = 0 - input_ids[input_ids == -100] = 0 - if hasattr(self.llm.model, "embed_tokens"): - inputs_embeds = self.llm.model.embed_tokens(input_ids) - elif hasattr(self.llm.model.model, "embed_tokens"): - inputs_embeds = self.llm.model.model.embed_tokens(input_ids) - else: - inputs_embeds = self.llm.model.model.model.embed_tokens(input_ids) + input_ids[input_ids < 0] = 0 + inputs_embeds = self.llm.model.get_input_embeddings()(input_ids) batch_size, token_num, dims = inputs_embeds.shape _, l, _ = encoder_out.shape @@ -492,7 +486,7 @@ class LLMASR2(nn.Module): inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + l, :] = encoder_out[ batch_idx, :l, : ] - + labels_ids[labels_ids == -1] = -100 model_outputs = self.llm( inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids ) From 64941d99cc0f914de3c54eea49eaee385af30152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Thu, 6 Jun 2024 19:48:40 +0800 Subject: [PATCH 079/125] auto frontend --- funasr/train_utils/trainer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/train_utils/trainer.py b/funasr/train_utils/trainer.py index 60fd96966..afc632d12 100644 --- a/funasr/train_utils/trainer.py +++ b/funasr/train_utils/trainer.py @@ -481,7 +481,7 @@ class Trainer: step_in_epoch=self.step_in_epoch, batch_num_epoch=batch_num_epoch, lr=lr, - loss=loss.detach().cpu().item(), + loss=accum_grad * loss.detach().cpu().item(), speed_stats=speed_stats, stats=stats, writer=writer, From 4a99b828a834d1d3870abbe3ee477518470f3dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 01:58:14 +0800 Subject: [PATCH 080/125] auto frontend --- funasr/datasets/audio_datasets/samplers.py | 12 ++++++--- funasr/datasets/openai_datasets/datasets.py | 29 ++++++++++++++++----- funasr/datasets/openai_datasets/index_ds.py | 19 +++++++++++--- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index 18f8f91b4..7195addc1 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -364,6 +364,8 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): self.sort_size = sort_size * num_replicas self.max_token_length = kwargs.get("max_token_length", 2048) self.length_scale_source = kwargs.get("length_scale_source", 1.0) + self.start_step = kwargs.get("start_step", 2048) + super().__init__( dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle, drop_last=drop_last ) @@ -415,13 +417,17 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): rank_batches[i % self.num_replicas].append(batch) # Assign all batches for the current rank directly - final_batches = rank_batches[self.rank] + final_batches = rank_batches[self.rank][self.start_step :] + self.batch_num = len(final_batches) + logging.info( + f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {self.batch_num}" + ) return iter(final_batches) def __len__(self): - - return 1 + # Calculate the number of batches per epoch for the current rank + return self.batch_num def set_epoch(self, epoch): self.epoch = epoch diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 9bd0698fb..5813c3ba0 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -51,7 +51,7 @@ class OpenAIDataset(torch.utils.data.Dataset): self.batch_size = kwargs.get("batch_size") self.batch_type = kwargs.get("batch_type") self.prompt_ids_len = 0 - self.retry = kwargs.get("retry", 5) + self.retry = kwargs.get("retry", 10) self.permute = False from funasr.frontends.whisper_frontend import WhisperFrontend @@ -60,6 +60,8 @@ class OpenAIDataset(torch.utils.data.Dataset): self.permute = True self.pattern = re.compile(r"(<\|startofspeech\|>.*?<\|endofspeech\|>)") + # self.kwargs = kwargs + self.max_token_length = kwargs.get("max_token_length", 1024) def get_source_len(self, index): item = self.index_ds[index] @@ -77,7 +79,9 @@ class OpenAIDataset(torch.utils.data.Dataset): # pdb.set_trace() output = None + for idx in range(self.retry): + badcase_flag = False if idx == 0: index_cur = index else: @@ -112,9 +116,14 @@ class OpenAIDataset(torch.utils.data.Dataset): "<|endofspeech|>", "" ) if sub_str.startswith("!"): - - data_src = load_audio_text_image_video(sub_str[1:], fs=self.fs) - + try: + data_src = load_audio_text_image_video(sub_str[1:], fs=self.fs) + except Exception as e: + logging.error( + f"Loading wav failed! {str(e)}, {traceback.format_exc()}" + ) + badcase_flag = True + continue speech, speech_lengths = extract_fbank( data_src, data_type=self.data_type, @@ -134,6 +143,8 @@ class OpenAIDataset(torch.utils.data.Dataset): source_ids += sub_token fbank_mask_i += [1] * len(sub_token) + if badcase_flag: + continue source_mask = [-100] * len(source_ids) target_out = f"{target_out}<|im_end|>" target_ids = self.tokenizer.encode(target_out) @@ -142,6 +153,10 @@ class OpenAIDataset(torch.utils.data.Dataset): fbank_mask += fbank_mask_i fbank_beg.append(fbank_beg_i) + if len(input_ids) > self.max_token_length: + badcase_flag = True + if badcase_flag: + continue input_ids = torch.tensor(input_ids, dtype=torch.int64) attention_mask = torch.tensor([len(input_ids)], dtype=torch.int32) labels = torch.tensor(labels, dtype=torch.int64) @@ -186,9 +201,9 @@ class OpenAIDataset(torch.utils.data.Dataset): data_list, batch_first=True, padding_value=pad_value ) - if self.batch_type != "example": - for i in range(10): - outputs = self._filter_badcase(outputs, i=i) + # if self.batch_type != "example": + # for i in range(10): + # outputs = self._filter_badcase(outputs, i=i) return outputs diff --git a/funasr/datasets/openai_datasets/index_ds.py b/funasr/datasets/openai_datasets/index_ds.py index 1c48cd241..cc518f807 100644 --- a/funasr/datasets/openai_datasets/index_ds.py +++ b/funasr/datasets/openai_datasets/index_ds.py @@ -48,7 +48,10 @@ class OpenAIIndexDSJsonl(torch.utils.data.Dataset): # torch.utils.data.Dataset for file_json in file_list: with open(file_json.strip(), encoding="utf-8") as fin: for line in fin: - data = json.loads(line.strip())["messages"] + data_dict = json.loads(line.strip()) + data = data_dict["messages"] + speech_length = data_dict.get("speech_length", -1) // 8 + text_length = data_dict.get("text_length", 0) system, user, assistant = [], [], [] for i, item in enumerate(data): @@ -63,7 +66,12 @@ class OpenAIIndexDSJsonl(torch.utils.data.Dataset): # torch.utils.data.Dataset system = system * len(user) - contents_i = {"system": system, "user": user, "assistant": assistant} + contents_i = { + "system": system, + "user": user, + "assistant": assistant, + "source_len": speech_length + text_length, + } contents.append(contents_i) self.contents = contents @@ -80,11 +88,14 @@ class OpenAIIndexDSJsonl(torch.utils.data.Dataset): # torch.utils.data.Dataset return data def get_source_len(self, data_dict): - return len(data_dict["system"]) + len(data_dict["user"]) + source_len = data_dict.get("source_len", -1) + if source_len < 0: + source_len = len(data_dict["system"]) + len(data_dict["user"]) + return source_len def get_target_len(self, data_dict): - return len(data_dict["assistant"]) + return 0 if __name__ == "__main__": From 60b3c42d6d3d90b97918b10d506efd6c471e1ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 02:40:31 +0800 Subject: [PATCH 081/125] auto frontend --- funasr/models/transformer/attention.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/funasr/models/transformer/attention.py b/funasr/models/transformer/attention.py index e4add5cf8..6e6f75411 100644 --- a/funasr/models/transformer/attention.py +++ b/funasr/models/transformer/attention.py @@ -82,7 +82,10 @@ class MultiHeadedAttention(nn.Module): n_batch = value.size(0) if mask is not None: mask = mask.unsqueeze(1).eq(0) # (batch, 1, *, time2) - min_value = float(numpy.finfo(torch.tensor(0, dtype=scores.dtype).numpy().dtype).min) + + min_value = -float( + "inf" + ) # min_value = float(np.finfo(torch.tensor(0, dtype=qk.dtype).numpy().dtype).min) scores = scores.masked_fill(mask, min_value) self.attn = torch.softmax(scores, dim=-1).masked_fill( mask, 0.0 From b2be308de0a4d75c3645e55c26d33a58446a16ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 02:51:18 +0800 Subject: [PATCH 082/125] auto frontend --- funasr/models/llm_asr/model.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 0d9bf7f09..e2880c831 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -468,7 +468,7 @@ class LLMASR2(nn.Module): if len(speech_lengths.size()) > 1: speech_lengths = speech_lengths[:, 0] - batch_size = speech.shape[0] + batch_size, frames, _ = speech.shape # audio encoder encoder_out, encoder_out_lens = self.audio_encoder(speech.permute(0, 2, 1), speech_lengths) @@ -499,6 +499,13 @@ class LLMASR2(nn.Module): stats["acc"] = acc_att stats["loss"] = torch.clone(loss.detach()) + stats["batch_size"] = batch_size + stats["batch_size_x_frames"] = frames * batch_size + stats["batch_size_real_frames"] = speech_lengths.sum().item() + stats["padding_frames"] = stats["batch_size_x_frames"] - stats["batch_size_real_frames"] + stats["batch_size_x_tokens"] = token_num * batch_size + stats["batch_size_real_tokens"] = attention_mask.sum().item() + stats["padding_tokens"] = stats["batch_size_x_tokens"] - stats["batch_size_real_tokens"] # force_gatherable: to-device and to-tensor if scalar for DataParallel if self.length_normalized_loss: From 4eedd7ad45120598f10b84673401823719dda237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 03:05:01 +0800 Subject: [PATCH 083/125] auto frontend --- funasr/datasets/openai_datasets/datasets.py | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 5813c3ba0..73e9ec0ac 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -201,16 +201,16 @@ class OpenAIDataset(torch.utils.data.Dataset): data_list, batch_first=True, padding_value=pad_value ) - # if self.batch_type != "example": - # for i in range(10): - # outputs = self._filter_badcase(outputs, i=i) + if self.batch_type != "example": + for i in range(10): + outputs = self._filter_badcase(outputs, i=i) return outputs def _filter_badcase(self, outputs, i=0): - b, t, _ = outputs["speech"].shape + b, t = outputs["input_ids"].shape - if b * t > self.batch_size * 1.25: + if b * t > self.batch_size * 2: beg = torch.randint(0, 2, ()).item() if b < 2: beg = 0 @@ -219,12 +219,12 @@ class OpenAIDataset(torch.utils.data.Dataset): ) for key, data_list in outputs.items(): outputs[key] = outputs[key][beg : beg + b : 2] - - speech_lengths_max = outputs["speech_lengths"].max().item() - outputs["speech"] = outputs["speech"][:, :speech_lengths_max, :] - text_lengths_max = outputs["text_lengths"].max().item() - outputs["text"] = outputs["text"][:, :text_lengths_max] - target_mask_lengths_max = outputs["target_mask_lengths"].max().item() - outputs["target_mask"] = outputs["target_mask"][:, :target_mask_lengths_max] + # + # speech_lengths_max = outputs["speech_lengths"].max().item() + # outputs["speech"] = outputs["speech"][:, :speech_lengths_max, :] + # text_lengths_max = outputs["text_lengths"].max().item() + # outputs["text"] = outputs["text"][:, :text_lengths_max] + # target_mask_lengths_max = outputs["target_mask_lengths"].max().item() + # outputs["target_mask"] = outputs["target_mask"][:, :target_mask_lengths_max] return outputs From a0becf3cd81fcb534256927a53261730250cad3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 03:13:36 +0800 Subject: [PATCH 084/125] auto frontend --- funasr/datasets/openai_datasets/datasets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 73e9ec0ac..f6127b65a 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -215,7 +215,7 @@ class OpenAIDataset(torch.utils.data.Dataset): if b < 2: beg = 0 logging.info( - f"Warning, b * t: {b * t} > {self.batch_size}, drop half data {i}th, beg:{beg}" + f"Warning, b * t: {b * t} > {self.batch_size}, b: {b}, t: {t}, drop half data {i}th, beg:{beg}" ) for key, data_list in outputs.items(): outputs[key] = outputs[key][beg : beg + b : 2] From 0ba1bdd476c2079f1220904d5f2a217d78bdb64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 03:21:53 +0800 Subject: [PATCH 085/125] auto frontend --- funasr/datasets/openai_datasets/datasets.py | 76 +++++++++------------ 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index f6127b65a..8cb092639 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -180,51 +180,43 @@ class OpenAIDataset(torch.utils.data.Dataset): return output def collator(self, samples: list = None): - outputs = {} - for sample in samples: - if sample is None: - continue - for key in sample.keys(): - if key not in outputs: - outputs[key] = [] - outputs[key].append(sample[key]) - for key, data_list in outputs.items(): - if isinstance(data_list[0], torch.Tensor): - if data_list[0].dtype == torch.int64 or data_list[0].dtype == torch.int32: + for idx in range(self.retry): + badcase_flag = False - pad_value = self.int_pad_value - else: - pad_value = self.float_pad_value + outputs = {} + for sample in samples: + if sample is None: + continue + for key in sample.keys(): + if key not in outputs: + outputs[key] = [] + outputs[key].append(sample[key]) - outputs[key] = torch.nn.utils.rnn.pad_sequence( - data_list, batch_first=True, padding_value=pad_value - ) - - if self.batch_type != "example": - for i in range(10): - outputs = self._filter_badcase(outputs, i=i) - - return outputs - - def _filter_badcase(self, outputs, i=0): - b, t = outputs["input_ids"].shape - - if b * t > self.batch_size * 2: - beg = torch.randint(0, 2, ()).item() - if b < 2: - beg = 0 - logging.info( - f"Warning, b * t: {b * t} > {self.batch_size}, b: {b}, t: {t}, drop half data {i}th, beg:{beg}" - ) for key, data_list in outputs.items(): - outputs[key] = outputs[key][beg : beg + b : 2] - # - # speech_lengths_max = outputs["speech_lengths"].max().item() - # outputs["speech"] = outputs["speech"][:, :speech_lengths_max, :] - # text_lengths_max = outputs["text_lengths"].max().item() - # outputs["text"] = outputs["text"][:, :text_lengths_max] - # target_mask_lengths_max = outputs["target_mask_lengths"].max().item() - # outputs["target_mask"] = outputs["target_mask"][:, :target_mask_lengths_max] + if isinstance(data_list[0], torch.Tensor): + if data_list[0].dtype == torch.int64 or data_list[0].dtype == torch.int32: + + pad_value = self.int_pad_value + else: + pad_value = self.float_pad_value + + outputs[key] = torch.nn.utils.rnn.pad_sequence( + data_list, batch_first=True, padding_value=pad_value + ) + + if self.batch_type != "example": + b, t = outputs["input_ids"].shape + if b * t > self.batch_size * 2: + beg = torch.randint(0, 2, ()).item() + if b < 2: + beg = 0 + logging.info( + f"Warning, b * t: {b * t} > {self.batch_size}, b: {b}, t: {t}, drop half data {idx}th, beg:{beg}" + ) + samples = samples[beg : beg + b : 2] + continue + + break return outputs From d306728928691f37a6f7bcfdb8324879fe006908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 03:34:41 +0800 Subject: [PATCH 086/125] auto frontend --- funasr/datasets/openai_datasets/datasets.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 8cb092639..c51ace997 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -62,6 +62,7 @@ class OpenAIDataset(torch.utils.data.Dataset): self.pattern = re.compile(r"(<\|startofspeech\|>.*?<\|endofspeech\|>)") # self.kwargs = kwargs self.max_token_length = kwargs.get("max_token_length", 1024) + self.batch_size_scale_ratio_max = kwargs.get("batch_size_scale_ratio_max", 1.5) def get_source_len(self, index): item = self.index_ds[index] @@ -153,13 +154,13 @@ class OpenAIDataset(torch.utils.data.Dataset): fbank_mask += fbank_mask_i fbank_beg.append(fbank_beg_i) - if len(input_ids) > self.max_token_length: - badcase_flag = True + # if len(input_ids) > self.max_token_length: + # badcase_flag = True if badcase_flag: continue - input_ids = torch.tensor(input_ids, dtype=torch.int64) + input_ids = torch.tensor(input_ids, dtype=torch.int64)[: self.max_token_length] attention_mask = torch.tensor([len(input_ids)], dtype=torch.int32) - labels = torch.tensor(labels, dtype=torch.int64) + labels = torch.tensor(labels, dtype=torch.int64)[: self.max_token_length] fbank = speech[0, :, :] fbank_lens = speech_lengths @@ -207,7 +208,7 @@ class OpenAIDataset(torch.utils.data.Dataset): if self.batch_type != "example": b, t = outputs["input_ids"].shape - if b * t > self.batch_size * 2: + if b * t > self.batch_size * self.batch_size_scale_ratio_max: beg = torch.randint(0, 2, ()).item() if b < 2: beg = 0 From 8ba12df6f7f44c8e302f9291fab7a3e0a3a0b54d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 04:04:55 +0800 Subject: [PATCH 087/125] auto frontend --- funasr/models/llm_asr/model.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index e2880c831..66a69eb2c 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -483,8 +483,9 @@ class LLMASR2(nn.Module): _, l, _ = encoder_out.shape for batch_idx in range(batch_size): fbank_beg_idx = fbank_beg[batch_idx, 0].item() - inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + l, :] = encoder_out[ - batch_idx, :l, : + min_len = min(l, inputs_embeds.shape[1] - fbank_beg_idx) + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ + batch_idx, :min_len, : ] labels_ids[labels_ids == -1] = -100 model_outputs = self.llm( From 870fa4a37a194fb7919b53930064129b6d616cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 04:05:30 +0800 Subject: [PATCH 088/125] auto frontend --- funasr/datasets/audio_datasets/samplers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index 7195addc1..27fbdac25 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -417,7 +417,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): rank_batches[i % self.num_replicas].append(batch) # Assign all batches for the current rank directly - final_batches = rank_batches[self.rank][self.start_step :] + final_batches = rank_batches[self.rank] # [self.start_step :] self.batch_num = len(final_batches) logging.info( From c350b6becb887d578126e363306e7398782ef675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 04:32:26 +0800 Subject: [PATCH 089/125] auto frontend --- funasr/datasets/audio_datasets/samplers.py | 9 ++++++++- funasr/datasets/openai_datasets/datasets.py | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index 27fbdac25..2e271af6b 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -365,6 +365,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): self.max_token_length = kwargs.get("max_token_length", 2048) self.length_scale_source = kwargs.get("length_scale_source", 1.0) self.start_step = kwargs.get("start_step", 2048) + self.batch_size_sample_max = kwargs.get("batch_size_sample_max", 200) super().__init__( dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle, drop_last=drop_last @@ -388,19 +389,25 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): ) batch = [] max_len_in_batch = 0 + count = 0 for idx in buffer: original_sample_length = self.dataset.get_source_len(idx) if original_sample_length > self.max_token_length: continue sample_length = 1 if self.batch_type == "example" else original_sample_length potential_batch_length = max(max_len_in_batch, sample_length) * (len(batch) + 1) - if potential_batch_length <= self.batch_size: + if ( + potential_batch_length <= self.batch_size + and count <= self.batch_size_sample_max + ): batch.append(idx) max_len_in_batch = max(max_len_in_batch, sample_length) + count += 1 else: buffer_batches.append(batch) batch = [idx] max_len_in_batch = sample_length + count = 0 if batch: buffer_batches.append(batch) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index c51ace997..46735ba2c 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -154,13 +154,13 @@ class OpenAIDataset(torch.utils.data.Dataset): fbank_mask += fbank_mask_i fbank_beg.append(fbank_beg_i) - # if len(input_ids) > self.max_token_length: - # badcase_flag = True + if len(input_ids) > self.max_token_length: + badcase_flag = True if badcase_flag: continue - input_ids = torch.tensor(input_ids, dtype=torch.int64)[: self.max_token_length] + input_ids = torch.tensor(input_ids, dtype=torch.int64) # [: self.max_token_length] attention_mask = torch.tensor([len(input_ids)], dtype=torch.int32) - labels = torch.tensor(labels, dtype=torch.int64)[: self.max_token_length] + labels = torch.tensor(labels, dtype=torch.int64) # [: self.max_token_length] fbank = speech[0, :, :] fbank_lens = speech_lengths From 8d7f76af46cf0e77317ec8e84fcce6f208f24204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 11:40:46 +0800 Subject: [PATCH 090/125] auto frontend --- funasr/models/llm_asr/model.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 66a69eb2c..b13912346 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -480,10 +480,15 @@ class LLMASR2(nn.Module): inputs_embeds = self.llm.model.get_input_embeddings()(input_ids) batch_size, token_num, dims = inputs_embeds.shape - _, l, _ = encoder_out.shape + fbank_mask[fbank_mask < 0] = 0 + fbank_fake_lens = fbank_mask.sum(-1) + # _, l, _ = encoder_out.shape for batch_idx in range(batch_size): + + l = fbank_fake_lens[batch_idx].item() fbank_beg_idx = fbank_beg[batch_idx, 0].item() min_len = min(l, inputs_embeds.shape[1] - fbank_beg_idx) + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ batch_idx, :min_len, : ] From 162efb747f21f305851c682e5f7f0f3050d545a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 16:18:18 +0800 Subject: [PATCH 091/125] auto frontend --- funasr/models/llm_asr/adaptor.py | 41 +++++++++++++++++--------------- funasr/models/llm_asr/model.py | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/funasr/models/llm_asr/adaptor.py b/funasr/models/llm_asr/adaptor.py index 9b79ed28a..c93988328 100644 --- a/funasr/models/llm_asr/adaptor.py +++ b/funasr/models/llm_asr/adaptor.py @@ -83,25 +83,27 @@ class Transformer(nn.Module): from funasr.models.transformer.attention import MultiHeadedAttention from funasr.models.transformer.positionwise_feed_forward import PositionwiseFeedForward - self.blocks = nn.ModuleList( - [ - EncoderLayer( - llm_dim, - MultiHeadedAttention( - kwargs.get("attention_heads", 8), + self.blocks = None + if kwargs.get("n_layer", 2) > 0: + self.blocks = nn.ModuleList( + [ + EncoderLayer( llm_dim, - kwargs.get("attention_dropout_rate", 0.0), - ), - PositionwiseFeedForward( - llm_dim, - llm_dim // 4, + MultiHeadedAttention( + kwargs.get("attention_heads", 8), + llm_dim, + kwargs.get("attention_dropout_rate", 0.0), + ), + PositionwiseFeedForward( + llm_dim, + llm_dim // 4, + kwargs.get("dropout_rate", 0.0), + ), kwargs.get("dropout_rate", 0.0), - ), - kwargs.get("dropout_rate", 0.0), - ) - for i in range(kwargs.get("n_layer", 2)) - ] - ) + ) + for i in range(kwargs.get("n_layer", 2)) + ] + ) def forward(self, x, ilens=None): @@ -123,6 +125,7 @@ class Transformer(nn.Module): olens = None olens = (ilens - 1) // self.k + 1 masks = (~make_pad_mask(olens)[:, None, :]).to(x.device) - for layer, block in enumerate(self.blocks): - x, masks = block(x, masks) + if self.blocks is not None: + for layer, block in enumerate(self.blocks): + x, masks = block(x, masks) return x, olens diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index b13912346..d94058cca 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -481,7 +481,7 @@ class LLMASR2(nn.Module): batch_size, token_num, dims = inputs_embeds.shape fbank_mask[fbank_mask < 0] = 0 - fbank_fake_lens = fbank_mask.sum(-1) + fbank_fake_lens = fbank_mask.sum(-1).to(torch.int32) # _, l, _ = encoder_out.shape for batch_idx in range(batch_size): From 526c810bd7ab9fdab38d5ce279a064b8e5da8bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 18:44:14 +0800 Subject: [PATCH 092/125] auto frontend --- funasr/datasets/openai_datasets/datasets.py | 3 +++ funasr/models/llm_asr/model.py | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 46735ba2c..0d12a1c4f 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -155,6 +155,9 @@ class OpenAIDataset(torch.utils.data.Dataset): fbank_beg.append(fbank_beg_i) if len(input_ids) > self.max_token_length: + logging.info( + f"input_ids > max_token_length: {len(input_ids)}>{self.max_token_length}, {item}" + ) badcase_flag = True if badcase_flag: continue diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index d94058cca..a6a713481 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -485,13 +485,24 @@ class LLMASR2(nn.Module): # _, l, _ = encoder_out.shape for batch_idx in range(batch_size): - l = fbank_fake_lens[batch_idx].item() + fbank_fake_len = fbank_fake_lens[batch_idx].item() fbank_beg_idx = fbank_beg[batch_idx, 0].item() - min_len = min(l, inputs_embeds.shape[1] - fbank_beg_idx) + min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) + try: + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ + batch_idx, :min_len, : + ] + except Exception as e: + logging.error(f"{str(e)}, {traceback.format_exc()}") + logging.info( + f"batch_idx: {batch_idx}, inputs_embeds: {inputs_embeds.shape}, fbank_beg_idx: {fbank_beg_idx}, min_len: {min_len}, fbank_fake_len: {fbank_fake_len}" + ) + fbank_fake_len = encoder_out_lens[batch_idx].item() + min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ + batch_idx, :min_len, : + ] - inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ - batch_idx, :min_len, : - ] labels_ids[labels_ids == -1] = -100 model_outputs = self.llm( inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids From 834a8fd9e2e9d22034ee78ecb5a405c02a25b2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 19:27:08 +0800 Subject: [PATCH 093/125] auto frontend --- funasr/models/llm_asr/model.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index a6a713481..82ad134ff 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -488,6 +488,8 @@ class LLMASR2(nn.Module): fbank_fake_len = fbank_fake_lens[batch_idx].item() fbank_beg_idx = fbank_beg[batch_idx, 0].item() min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) + fbank_fake_len = encoder_out_lens[batch_idx].item() + min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) try: inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ batch_idx, :min_len, : From 45a42abc78328b5be7f717d53d61b8b7c69bea32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Fri, 7 Jun 2024 22:42:38 +0800 Subject: [PATCH 094/125] fix bug --- examples/wenetspeech/conformer/run.sh | 2 +- examples/wenetspeech/transformer/README.md | 16 -- .../conf/transformer_12e_6d_2048_256.yaml | 104 --------- .../wenetspeech/transformer/demo_infer.sh | 1 - .../transformer/demo_train_or_finetune.sh | 1 - .../transformer/local/aishell_data_prep.sh | 66 ------ .../transformer/local/download_and_untar.sh | 105 --------- examples/wenetspeech/transformer/run.sh | 203 ------------------ examples/wenetspeech/transformer/utils | 1 - 9 files changed, 1 insertion(+), 498 deletions(-) delete mode 100644 examples/wenetspeech/transformer/README.md delete mode 100644 examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml delete mode 120000 examples/wenetspeech/transformer/demo_infer.sh delete mode 120000 examples/wenetspeech/transformer/demo_train_or_finetune.sh delete mode 100755 examples/wenetspeech/transformer/local/aishell_data_prep.sh delete mode 100755 examples/wenetspeech/transformer/local/download_and_untar.sh delete mode 100755 examples/wenetspeech/transformer/run.sh delete mode 120000 examples/wenetspeech/transformer/utils diff --git a/examples/wenetspeech/conformer/run.sh b/examples/wenetspeech/conformer/run.sh index 0503a9ea0..6ae995a46 100755 --- a/examples/wenetspeech/conformer/run.sh +++ b/examples/wenetspeech/conformer/run.sh @@ -92,7 +92,7 @@ if [ ${stage} -le 2 ] && [ ${stop_stage} -ge 2 ]; then echo "" > ${token_list} echo "" >> ${token_list} echo "" >> ${token_list} - utils/text2token.py -s 1 -n 1 --space "" --text_format "jsonl" ${feats_dir}/data/$train_set/audio_datasets.jsonl | cut -f 2- -d" " | tr " " "\n" \ + utils/text2token.py -s 1 -n 1 --space "" ${feats_dir}/data/$train_set/text | cut -f 2- -d" " | tr " " "\n" \ | sort | uniq | grep -a -v -e '^\s*$' | awk '{print $0}' >> ${token_list} echo "" >> ${token_list} fi diff --git a/examples/wenetspeech/transformer/README.md b/examples/wenetspeech/transformer/README.md deleted file mode 100644 index 2435b553b..000000000 --- a/examples/wenetspeech/transformer/README.md +++ /dev/null @@ -1,16 +0,0 @@ - -# Conformer Result - -## Training Config -- Feature info: using 80 dims fbank, global cmvn, speed perturb(0.9, 1.0, 1.1), specaugment -- Train info: lr 5e-4, batch_size 25000, 2 gpu(Tesla V100), acc_grad 1, 50 epochs -- Train config: conf/train_asr_transformer.yaml -- LM config: LM was not used -- Model size: 46M - -## Results (CER) - -| testset | CER(%) | -|:-----------:|:------:| -| dev | 4.97 | -| test | 5.37 | \ No newline at end of file diff --git a/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml b/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml deleted file mode 100644 index efcf593a5..000000000 --- a/examples/wenetspeech/transformer/conf/transformer_12e_6d_2048_256.yaml +++ /dev/null @@ -1,104 +0,0 @@ -# This is an example that demonstrates how to configure a model file. -# You can modify the configuration according to your own requirements. - -# to print the register_table: -# from funasr.register import tables -# tables.print() - -# network architecture -model: Transformer -model_conf: - ctc_weight: 0.3 - lsm_weight: 0.1 # label smoothing option - length_normalized_loss: false - -# encoder -encoder: TransformerEncoder -encoder_conf: - output_size: 256 # dimension of attention - attention_heads: 4 - linear_units: 2048 # the number of units of position-wise feed forward - num_blocks: 12 # the number of encoder blocks - dropout_rate: 0.1 - positional_dropout_rate: 0.1 - attention_dropout_rate: 0.0 - input_layer: conv2d # encoder architecture type - normalize_before: true - -# decoder -decoder: TransformerDecoder -decoder_conf: - attention_heads: 4 - linear_units: 2048 - num_blocks: 6 - dropout_rate: 0.1 - positional_dropout_rate: 0.1 - self_attention_dropout_rate: 0.0 - src_attention_dropout_rate: 0.0 - - -# frontend related -frontend: WavFrontend -frontend_conf: - fs: 16000 - window: hamming - n_mels: 80 - frame_length: 25 - frame_shift: 10 - lfr_m: 1 - lfr_n: 1 - -specaug: SpecAug -specaug_conf: - apply_time_warp: true - time_warp_window: 5 - time_warp_mode: bicubic - apply_freq_mask: true - freq_mask_width_range: - - 0 - - 30 - num_freq_mask: 2 - apply_time_mask: true - time_mask_width_range: - - 0 - - 40 - num_time_mask: 2 - -train_conf: - accum_grad: 1 - grad_clip: 5 - max_epoch: 150 - keep_nbest_models: 10 - log_interval: 50 - -optim: adam -optim_conf: - lr: 0.002 -scheduler: warmuplr -scheduler_conf: - warmup_steps: 30000 - -dataset: AudioDataset -dataset_conf: - index_ds: IndexDSJsonl - batch_sampler: EspnetStyleBatchSampler - batch_type: length # example or length - batch_size: 25000 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len; - max_token_length: 2048 # filter samples if source_token_len+target_token_len > max_token_length, - buffer_size: 1024 - shuffle: True - num_workers: 4 - preprocessor_speech: SpeechPreprocessSpeedPerturb - preprocessor_speech_conf: - speed_perturb: [0.9, 1.0, 1.1] - -tokenizer: CharTokenizer -tokenizer_conf: - unk_symbol: - -ctc_conf: - dropout_rate: 0.0 - ctc_type: builtin - reduce: true - ignore_nan_grad: true -normalize: null diff --git a/examples/wenetspeech/transformer/demo_infer.sh b/examples/wenetspeech/transformer/demo_infer.sh deleted file mode 120000 index 9d0a7a9e3..000000000 --- a/examples/wenetspeech/transformer/demo_infer.sh +++ /dev/null @@ -1 +0,0 @@ -../paraformer/demo_infer.sh \ No newline at end of file diff --git a/examples/wenetspeech/transformer/demo_train_or_finetune.sh b/examples/wenetspeech/transformer/demo_train_or_finetune.sh deleted file mode 120000 index bbabdbe84..000000000 --- a/examples/wenetspeech/transformer/demo_train_or_finetune.sh +++ /dev/null @@ -1 +0,0 @@ -../paraformer/demo_train_or_finetune.sh \ No newline at end of file diff --git a/examples/wenetspeech/transformer/local/aishell_data_prep.sh b/examples/wenetspeech/transformer/local/aishell_data_prep.sh deleted file mode 100755 index 83f489b3c..000000000 --- a/examples/wenetspeech/transformer/local/aishell_data_prep.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash - -# Copyright 2017 Xingyu Na -# Apache 2.0 - -#. ./path.sh || exit 1; - -if [ $# != 3 ]; then - echo "Usage: $0 " - echo " $0 /export/a05/xna/data/data_aishell/wav /export/a05/xna/data/data_aishell/transcript data" - exit 1; -fi - -aishell_audio_dir=$1 -aishell_text=$2/aishell_transcript_v0.8.txt -output_dir=$3 - -train_dir=$output_dir/data/local/train -dev_dir=$output_dir/data/local/dev -test_dir=$output_dir/data/local/test -tmp_dir=$output_dir/data/local/tmp - -mkdir -p $train_dir -mkdir -p $dev_dir -mkdir -p $test_dir -mkdir -p $tmp_dir - -# data directory check -if [ ! -d $aishell_audio_dir ] || [ ! -f $aishell_text ]; then - echo "Error: $0 requires two directory arguments" - exit 1; -fi - -# find wav audio file for train, dev and test resp. -find $aishell_audio_dir -iname "*.wav" > $tmp_dir/wav.flist -n=`cat $tmp_dir/wav.flist | wc -l` -[ $n -ne 141925 ] && \ - echo Warning: expected 141925 data data files, found $n - -grep -i "wav/train" $tmp_dir/wav.flist > $train_dir/wav.flist || exit 1; -grep -i "wav/dev" $tmp_dir/wav.flist > $dev_dir/wav.flist || exit 1; -grep -i "wav/test" $tmp_dir/wav.flist > $test_dir/wav.flist || exit 1; - -rm -r $tmp_dir - -# Transcriptions preparation -for dir in $train_dir $dev_dir $test_dir; do - echo Preparing $dir transcriptions - sed -e 's/\.wav//' $dir/wav.flist | awk -F '/' '{print $NF}' > $dir/utt.list - paste -d' ' $dir/utt.list $dir/wav.flist > $dir/wav.scp_all - utils/filter_scp.pl -f 1 $dir/utt.list $aishell_text > $dir/transcripts.txt - awk '{print $1}' $dir/transcripts.txt > $dir/utt.list - utils/filter_scp.pl -f 1 $dir/utt.list $dir/wav.scp_all | sort -u > $dir/wav.scp - sort -u $dir/transcripts.txt > $dir/text -done - -mkdir -p $output_dir/data/train $output_dir/data/dev $output_dir/data/test - -for f in wav.scp text; do - cp $train_dir/$f $output_dir/data/train/$f || exit 1; - cp $dev_dir/$f $output_dir/data/dev/$f || exit 1; - cp $test_dir/$f $output_dir/data/test/$f || exit 1; -done - -echo "$0: AISHELL data preparation succeeded" -exit 0; diff --git a/examples/wenetspeech/transformer/local/download_and_untar.sh b/examples/wenetspeech/transformer/local/download_and_untar.sh deleted file mode 100755 index d98255915..000000000 --- a/examples/wenetspeech/transformer/local/download_and_untar.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2014 Johns Hopkins University (author: Daniel Povey) -# 2017 Xingyu Na -# Apache 2.0 - -remove_archive=false - -if [ "$1" == --remove-archive ]; then - remove_archive=true - shift -fi - -if [ $# -ne 3 ]; then - echo "Usage: $0 [--remove-archive] " - echo "e.g.: $0 /export/a05/xna/data www.openslr.org/resources/33 data_aishell" - echo "With --remove-archive it will remove the archive after successfully un-tarring it." - echo " can be one of: data_aishell, resource_aishell." -fi - -data=$1 -url=$2 -part=$3 - -if [ ! -d "$data" ]; then - echo "$0: no such directory $data" - exit 1; -fi - -part_ok=false -list="data_aishell resource_aishell" -for x in $list; do - if [ "$part" == $x ]; then part_ok=true; fi -done -if ! $part_ok; then - echo "$0: expected to be one of $list, but got '$part'" - exit 1; -fi - -if [ -z "$url" ]; then - echo "$0: empty URL base." - exit 1; -fi - -if [ -f $data/$part/.complete ]; then - echo "$0: data part $part was already successfully extracted, nothing to do." - exit 0; -fi - -# sizes of the archive files in bytes. -sizes="15582913665 1246920" - -if [ -f $data/$part.tgz ]; then - size=$(/bin/ls -l $data/$part.tgz | awk '{print $5}') - size_ok=false - for s in $sizes; do if [ $s == $size ]; then size_ok=true; fi; done - if ! $size_ok; then - echo "$0: removing existing file $data/$part.tgz because its size in bytes $size" - echo "does not equal the size of one of the archives." - rm $data/$part.tgz - else - echo "$data/$part.tgz exists and appears to be complete." - fi -fi - -if [ ! -f $data/$part.tgz ]; then - if ! command -v wget >/dev/null; then - echo "$0: wget is not installed." - exit 1; - fi - full_url=$url/$part.tgz - echo "$0: downloading data from $full_url. This may take some time, please be patient." - - cd $data || exit 1 - if ! wget --no-check-certificate $full_url; then - echo "$0: error executing wget $full_url" - exit 1; - fi -fi - -cd $data || exit 1 - -if ! tar -xvzf $part.tgz; then - echo "$0: error un-tarring archive $data/$part.tgz" - exit 1; -fi - -touch $data/$part/.complete - -if [ $part == "data_aishell" ]; then - cd $data/$part/wav || exit 1 - for wav in ./*.tar.gz; do - echo "Extracting wav from $wav" - tar -zxf $wav && rm $wav - done -fi - -echo "$0: Successfully downloaded and un-tarred $data/$part.tgz" - -if $remove_archive; then - echo "$0: removing $data/$part.tgz file since --remove-archive option was supplied." - rm $data/$part.tgz -fi - -exit 0; diff --git a/examples/wenetspeech/transformer/run.sh b/examples/wenetspeech/transformer/run.sh deleted file mode 100755 index 3fb846519..000000000 --- a/examples/wenetspeech/transformer/run.sh +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env bash - - -CUDA_VISIBLE_DEVICES="0,1" - -# general configuration -feats_dir="../DATA" #feature output dictionary -exp_dir=`pwd` -lang=zh -token_type=char -stage=0 -stop_stage=5 - -# feature configuration -nj=32 - -inference_device="cuda" #"cpu" -inference_checkpoint="model.pt.avg10" -inference_scp="wav.scp" -inference_batch_size=1 - -# data -raw_data=../raw_data -data_url=www.openslr.org/resources/33 - -# exp tag -tag="exp1" -workspace=`pwd` - -master_port=12345 - -. utils/parse_options.sh || exit 1; - -# Set bash to 'debug' mode, it will exit on : -# -e 'error', -u 'undefined variable', -o ... 'error in pipeline', -x 'print commands', -set -e -set -u -set -o pipefail - -train_set=train -valid_set=dev -test_sets="dev test" - -config=transformer_12e_6d_2048_256.yaml -model_dir="baseline_$(basename "${config}" .yaml)_${lang}_${token_type}_${tag}" - - - -if [ ${stage} -le -1 ] && [ ${stop_stage} -ge -1 ]; then - echo "stage -1: Data Download" - mkdir -p ${raw_data} - local/download_and_untar.sh ${raw_data} ${data_url} data_aishell - local/download_and_untar.sh ${raw_data} ${data_url} resource_aishell -fi - -if [ ${stage} -le 0 ] && [ ${stop_stage} -ge 0 ]; then - echo "stage 0: Data preparation" - # Data preparation - local/aishell_data_prep.sh ${raw_data}/data_aishell/wav ${raw_data}/data_aishell/transcript ${feats_dir} - for x in train dev test; do - cp ${feats_dir}/data/${x}/text ${feats_dir}/data/${x}/text.org - paste -d " " <(cut -f 1 -d" " ${feats_dir}/data/${x}/text.org) <(cut -f 2- -d" " ${feats_dir}/data/${x}/text.org | tr -d " ") \ - > ${feats_dir}/data/${x}/text - utils/text2token.py -n 1 -s 1 ${feats_dir}/data/${x}/text > ${feats_dir}/data/${x}/text.org - mv ${feats_dir}/data/${x}/text.org ${feats_dir}/data/${x}/text - - # convert wav.scp text to jsonl - scp_file_list_arg="++scp_file_list='[\"${feats_dir}/data/${x}/wav.scp\",\"${feats_dir}/data/${x}/text\"]'" - python ../../../funasr/datasets/audio_datasets/scp2jsonl.py \ - ++data_type_list='["source", "target"]' \ - ++jsonl_file_out=${feats_dir}/data/${x}/audio_datasets.jsonl \ - ${scp_file_list_arg} - done -fi - -if [ ${stage} -le 1 ] && [ ${stop_stage} -ge 1 ]; then - echo "stage 1: Feature and CMVN Generation" - python ../../../funasr/bin/compute_audio_cmvn.py \ - --config-path "${workspace}/conf" \ - --config-name "${config}" \ - ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ - ++cmvn_file="${feats_dir}/data/${train_set}/cmvn.json" \ - -fi - -token_list=${feats_dir}/data/${lang}_token_list/$token_type/tokens.txt -echo "dictionary: ${token_list}" -if [ ${stage} -le 2 ] && [ ${stop_stage} -ge 2 ]; then - echo "stage 2: Dictionary Preparation" - mkdir -p ${feats_dir}/data/${lang}_token_list/$token_type/ - - echo "make a dictionary" - echo "" > ${token_list} - echo "" >> ${token_list} - echo "" >> ${token_list} - utils/text2token.py -s 1 -n 1 --space "" ${feats_dir}/data/$train_set/text | cut -f 2- -d" " | tr " " "\n" \ - | sort | uniq | grep -a -v -e '^\s*$' | awk '{print $0}' >> ${token_list} - echo "" >> ${token_list} -fi - -# LM Training Stage -if [ ${stage} -le 3 ] && [ ${stop_stage} -ge 3 ]; then - echo "stage 3: LM Training" -fi - -# ASR Training Stage -if [ ${stage} -le 4 ] && [ ${stop_stage} -ge 4 ]; then - echo "stage 4: ASR Training" - - mkdir -p ${exp_dir}/exp/${model_dir} - current_time=$(date "+%Y-%m-%d_%H-%M") - log_file="${exp_dir}/exp/${model_dir}/train.log.txt.${current_time}" - echo "log_file: ${log_file}" - - export CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES - gpu_num=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') - torchrun \ - --nnodes 1 \ - --nproc_per_node ${gpu_num} \ - --master_port ${master_port} \ - ../../../funasr/bin/train.py \ - --config-path "${workspace}/conf" \ - --config-name "${config}" \ - ++train_data_set_list="${feats_dir}/data/${train_set}/audio_datasets.jsonl" \ - ++valid_data_set_list="${feats_dir}/data/${valid_set}/audio_datasets.jsonl" \ - ++tokenizer_conf.token_list="${token_list}" \ - ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ - ++output_dir="${exp_dir}/exp/${model_dir}" &> ${log_file} -fi - - - -# Testing Stage -if [ ${stage} -le 5 ] && [ ${stop_stage} -ge 5 ]; then - echo "stage 5: Inference" - - if [ ${inference_device} == "cuda" ]; then - nj=$(echo $CUDA_VISIBLE_DEVICES | awk -F "," '{print NF}') - else - inference_batch_size=1 - CUDA_VISIBLE_DEVICES="" - for JOB in $(seq ${nj}); do - CUDA_VISIBLE_DEVICES=$CUDA_VISIBLE_DEVICES"-1," - done - fi - - for dset in ${test_sets}; do - - inference_dir="${exp_dir}/exp/${model_dir}/inference-${inference_checkpoint}/${dset}" - _logdir="${inference_dir}/logdir" - echo "inference_dir: ${inference_dir}" - - mkdir -p "${_logdir}" - data_dir="${feats_dir}/data/${dset}" - key_file=${data_dir}/${inference_scp} - - split_scps= - for JOB in $(seq "${nj}"); do - split_scps+=" ${_logdir}/keys.${JOB}.scp" - done - utils/split_scp.pl "${key_file}" ${split_scps} - - gpuid_list_array=(${CUDA_VISIBLE_DEVICES//,/ }) - for JOB in $(seq ${nj}); do - { - id=$((JOB-1)) - gpuid=${gpuid_list_array[$id]} - - export CUDA_VISIBLE_DEVICES=${gpuid} - python ../../../funasr/bin/inference.py \ - --config-path="${exp_dir}/exp/${model_dir}" \ - --config-name="config.yaml" \ - ++init_param="${exp_dir}/exp/${model_dir}/${inference_checkpoint}" \ - ++tokenizer_conf.token_list="${token_list}" \ - ++frontend_conf.cmvn_file="${feats_dir}/data/${train_set}/am.mvn" \ - ++input="${_logdir}/keys.${JOB}.scp" \ - ++output_dir="${inference_dir}/${JOB}" \ - ++device="${inference_device}" \ - ++ncpu=1 \ - ++disable_log=true \ - ++batch_size="${inference_batch_size}" &> ${_logdir}/log.${JOB}.txt - }& - - done - wait - - mkdir -p ${inference_dir}/1best_recog - for f in token score text; do - if [ -f "${inference_dir}/${JOB}/1best_recog/${f}" ]; then - for JOB in $(seq "${nj}"); do - cat "${inference_dir}/${JOB}/1best_recog/${f}" - done | sort -k1 >"${inference_dir}/1best_recog/${f}" - fi - done - - echo "Computing WER ..." - python utils/postprocess_text_zh.py ${inference_dir}/1best_recog/text ${inference_dir}/1best_recog/text.proc - python utils/postprocess_text_zh.py ${data_dir}/text ${inference_dir}/1best_recog/text.ref - python utils/compute_wer.py ${inference_dir}/1best_recog/text.ref ${inference_dir}/1best_recog/text.proc ${inference_dir}/1best_recog/text.cer - tail -n 3 ${inference_dir}/1best_recog/text.cer - done - -fi \ No newline at end of file diff --git a/examples/wenetspeech/transformer/utils b/examples/wenetspeech/transformer/utils deleted file mode 120000 index 1f2ce9d8f..000000000 --- a/examples/wenetspeech/transformer/utils +++ /dev/null @@ -1 +0,0 @@ -../paraformer/utils \ No newline at end of file From d94821bbd6f0c53a86724e2c896df6d062432492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 16:44:34 +0800 Subject: [PATCH 095/125] fix bug --- .../llm_asr/demo_speech2text.py | 34 +++ .../llm_asr/infer_speech2text.sh | 9 + funasr/models/llm_asr/model.py | 236 +++++++++++------- 3 files changed, 195 insertions(+), 84 deletions(-) create mode 100644 examples/industrial_data_pretraining/llm_asr/demo_speech2text.py create mode 100644 examples/industrial_data_pretraining/llm_asr/infer_speech2text.sh diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py new file mode 100644 index 000000000..eb7e72f74 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# -*- encoding: utf-8 -*- +# Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved. +# MIT License (https://opensource.org/licenses/MIT) + +from funasr import AutoModel + +model = AutoModel( + model="iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch", + vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", + vad_kwargs={"max_single_segment_time": 60000}, + punc_model="iic/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", + # spk_model="iic/speech_campplus_sv_zh-cn_16k-common", +) + +res = model.generate( + input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav", + cache={}, +) + +print(res) + + +""" can not use currently +from funasr import AutoFrontend + +frontend = AutoFrontend(model="iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch") + +fbanks = frontend(input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav", batch_size=2) + +for batch_idx, fbank_dict in enumerate(fbanks): + res = model.generate(**fbank_dict) + print(res) +""" diff --git a/examples/industrial_data_pretraining/llm_asr/infer_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/infer_speech2text.sh new file mode 100644 index 000000000..bfdaca751 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/infer_speech2text.sh @@ -0,0 +1,9 @@ + + +python funasr/bin/inference.py \ +--config-path="/nfs/zhifu.gzf/ckpt/llm_asr_nar_exp1" \ +--config-name="config.yaml" \ +++init_param="/nfs/zhifu.gzf/ckpt/llm_asr_nar_exp1/model.pt.ep5" \ +++input="/Users/zhifu/funasr1.0/test_local/data_tmp/tmp_wav_10.jsonl" \ +++output_dir="/nfs/zhifu.gzf/ckpt/llm_asr_nar_exp1/inference/aishell2-dev_ios-funasr" \ +++device="cpu" \ No newline at end of file diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 82ad134ff..78d9340a8 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -18,6 +18,7 @@ from funasr.utils.load_utils import load_audio_text_image_video, extract_fbank from funasr.utils import postprocess_utils from funasr.utils.datadir_writer import DatadirWriter from funasr.register import tables +from funasr.train_utils.device_funcs import to_device @tables.register("model_classes", "LLMASR") @@ -488,8 +489,6 @@ class LLMASR2(nn.Module): fbank_fake_len = fbank_fake_lens[batch_idx].item() fbank_beg_idx = fbank_beg[batch_idx, 0].item() min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) - fbank_fake_len = encoder_out_lens[batch_idx].item() - min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) try: inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ batch_idx, :min_len, : @@ -506,6 +505,7 @@ class LLMASR2(nn.Module): ] labels_ids[labels_ids == -1] = -100 + model_outputs = self.llm( inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids ) @@ -532,6 +532,111 @@ class LLMASR2(nn.Module): loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) return loss, stats, weight + def data_template(self, data_in): + system, user, assistant = [], [], [] + for i, item in enumerate(data): + role = item["role"] + content = item["content"] + if role == "system": + system.append(content) + elif role == "user": + user.append(content) + elif role == "assistant": + assistant.append(content) + + system = system * len(user) + + contents = { + "system": system, + "user": user, + "assistant": assistant, + } + + return contents + + def data_load_speech(self, contents: dict, tokenizer, frontend, **kwargs): + + system = contents["system"] + user = contents["user"] + assistant = contents["assistant"] + pattern = re.compile(r"(<\|startofspeech\|>.*?<\|endofspeech\|>)") + input_ids, labels, fbank, fbank_lens, fbank_mask, fbank_beg = [], [], [], [], [], [] + + for i, (system_prompt, user_prompt, target_out) in enumerate(zip(system, user, assistant)): + + source_input = f"<|im_start|>system\n{system_prompt}<|im_end|>\n<|im_start|>user\n{user_prompt}<|im_end|>\n<|im_start|>assistant\n" + + splits = pattern.split(source_input) + source_ids = [] + fbank_mask_i = [] + fbank_beg_i = [] + fbank_lens_i = [] + for k, sub_str in enumerate(splits): + if not sub_str.startswith("<|startofspeech|>"): + sub_token = tokenizer.encode(sub_str) + source_ids += sub_token + fbank_mask_i += [0] * len(sub_token) + else: + sub_str = sub_str.replace("<|startofspeech|>", "").replace( + "<|endofspeech|>", "" + ) + if sub_str.startswith("!"): + try: + data_src = load_audio_text_image_video(sub_str[1:], fs=frontend.fs) + except Exception as e: + logging.error(f"Loading wav failed! {str(e)}, {traceback.format_exc()}") + + speech, speech_lengths = extract_fbank( + data_src, + data_type=kwargs.get("data_type", "sound"), + frontend=frontend, + is_final=True, + ) # speech: [b, T, d] + + if kwargs.get("permute", True): + speech = speech.permute(0, 2, 1) + + olens = 1 + (speech_lengths[0].item() - 3 + 2 * 1) // 2 + olens = 1 + (olens - 3 + 2 * 1) // 2 + sub_token_len = (olens - 1) // 2 + 1 + sub_token = [0] * sub_token_len + fbank_beg_i = [len(source_ids)] + source_ids += sub_token + fbank_mask_i += [1] * len(sub_token) + + source_mask = [-100] * len(source_ids) + target_out = f"{target_out}<|im_end|>" + target_ids = tokenizer.encode(target_out) + input_ids += source_ids + target_ids + labels += source_mask + target_ids + fbank_mask += fbank_mask_i + fbank_beg.append(fbank_beg_i) + + input_ids = torch.tensor(input_ids, dtype=torch.int64) # [: self.max_token_length] + attention_mask = torch.tensor([1] * len(input_ids), dtype=torch.int32) + labels = torch.tensor(labels, dtype=torch.int64) # [: self.max_token_length] + source_ids = torch.tensor(source_ids, dtype=torch.int64) + target_ids = torch.tensor(target_ids, dtype=torch.int64) + + fbank = speech[0, :, :] + fbank_lens = speech_lengths + fbank_mask = torch.tensor(fbank_mask, dtype=torch.float32) + fbank_beg = torch.tensor(fbank_beg, dtype=torch.int32) + + output = { + "speech": fbank[None, :, :], + "speech_lengths": fbank_lens[:, None], + "fbank_mask": fbank_mask[None, :], + "fbank_beg": fbank_beg[None,], + "input_ids": input_ids[None, :], + "attention_mask": attention_mask[None, :], + "labels_ids": labels[None, :], + "source_ids": source_ids[None, :], + "target_ids": target_ids[None, :], + } + + return output + def inference( self, data_in, @@ -542,92 +647,54 @@ class LLMASR2(nn.Module): **kwargs, ): - prompt = kwargs.get("prompt", "Transcribe speech to text.") + meta_data = {} + prompt = kwargs.get("prompt", None) if kwargs.get("batch_size", 1) > 1: raise NotImplementedError("batch decoding is not implemented") - meta_data = {} - if ( - isinstance(data_in, torch.Tensor) and kwargs.get("data_type", "sound") == "fbank" - ): # fbank - speech, speech_lengths = data_in, data_lengths - if len(speech.shape) < 3: - speech = speech[None, :, :] - if speech_lengths is None: - speech_lengths = speech.shape[1] - else: - # extract fbank feats - time1 = time.perf_counter() - audio_sample_list = load_audio_text_image_video( - data_in, - fs=frontend.fs, - audio_fs=kwargs.get("fs", 16000), - data_type=kwargs.get("data_type", "sound"), - tokenizer=tokenizer, + contents = self.data_template(data_in) + output = self.data_load_speech(contents, tokenizer, frontend, **kwargs) + batch = to_device(output, kwargs["device"]) + + # audio encoder + speech = batch["speech"] + speech_lengths = batch["speech_lengths"][:, 0] + encoder_out, encoder_out_lens = self.audio_encoder(speech.permute(0, 2, 1), speech_lengths) + + # audio_adaptor + encoder_out, encoder_out_lens = self.audio_adaptor(encoder_out, encoder_out_lens) + + input_ids = batch["input_ids"] + source_ids = batch["source_ids"] + if kwargs.get("tearchforing", False): + input_ids = source_ids + input_ids[input_ids < 0] = 0 + inputs_embeds = self.llm.model.get_input_embeddings()(input_ids) + + batch_size, token_num, dims = inputs_embeds.shape + fbank_beg = batch["fbank_beg"] + for batch_idx in range(batch_size): + + min_len = encoder_out_lens[batch_idx].item() + fbank_beg_idx = fbank_beg[batch_idx] + inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ + batch_idx, :min_len, : + ] + + if not kwargs.get("tearchforing", False): + + generated_ids = self.llm.generate( + inputs_embeds=inputs_embeds, max_new_tokens=kwargs.get("max_length", 512) ) - time2 = time.perf_counter() - meta_data["load_data"] = f"{time2 - time1:0.3f}" - speech, speech_lengths = extract_fbank( - audio_sample_list, data_type=kwargs.get("data_type", "sound"), frontend=frontend - ) - time3 = time.perf_counter() - meta_data["extract_feat"] = f"{time3 - time2:0.3f}" - meta_data["batch_data_time"] = ( - speech_lengths.sum().item() * frontend.frame_shift * frontend.lfr_n / 1000 - ) - - speech = speech.to(device=kwargs["device"]) - speech_lengths = speech_lengths.to(device=kwargs["device"]) - - # Encoder - encoder_out, encoder_out_lens = self.encode(speech, speech_lengths) - - # adaptor - encoder_out = self.audio_adaptor(encoder_out) - - prompt_pre = "USER: \nINSTRUCTION: {}\nINPUT: ".format(prompt) - prompt_ids = tokenizer.encode(prompt_pre) - prompt_length = len(prompt_ids) - prompt_ids = torch.tensor(prompt_ids, dtype=torch.int64).to(kwargs["device"]) - - if hasattr(self.llm.model, "embed_tokens"): - inputs_embeds = self.llm.model.embed_tokens(prompt_ids) - elif hasattr(self.llm.model.model, "embed_tokens"): - inputs_embeds = self.llm.model.model.embed_tokens(prompt_ids) - else: - inputs_embeds = self.llm.model.model.model.embed_tokens(prompt_ids) - - inputs_embeds = torch.cat( - (inputs_embeds[None, :, :], encoder_out), dim=1 - ) # [prompt, audio] - attention_mask = torch.ones(inputs_embeds.size()[:-1], dtype=torch.long).to( - kwargs["device"] - ) - - preds = self.llm.generate( - inputs_embeds=inputs_embeds, - max_length=kwargs.get("max_length", 200), - max_new_tokens=kwargs.get("max_new_tokens", 200), - num_beams=kwargs.get("num_beams", 4), - do_sample=kwargs.get("do_sample", False), - min_length=kwargs.get("min_length", 1), - top_p=kwargs.get("top_p", 1.0), - repetition_penalty=kwargs.get("repetition_penalty", 1.0), - length_penalty=kwargs.get("length_penalty", 1.0), - temperature=kwargs.get("temperature", 1.0), - attention_mask=attention_mask, - bos_token_id=tokenizer.bos_token_id, - eos_token_id=tokenizer.eos_token_id, - pad_token_id=tokenizer.pad_token_id, - ) - - text = tokenizer.batch_decode(preds, add_special_tokens=False, skip_special_tokens=True) - - text = text[0].split(": ")[-1] - text = text.strip() - - # preds = torch.argmax(model_outputs.logits, -1) + generated_ids = [ + output_ids[len(input_id) :] + for input_id, output_ids in zip(input_ids, generated_ids) + ] + response = tokenizer.batch_decode( + generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) + )[0] + label = contents["assistant"][0] ibest_writer = None if kwargs.get("output_dir") is not None: @@ -636,10 +703,11 @@ class LLMASR2(nn.Module): ibest_writer = self.writer[f"{0 + 1}best_recog"] results = [] - result_i = {"key": key[0], "text": text} + result_i = {"key": key[0], "text": response, "label": label} results.append(result_i) if ibest_writer is not None: ibest_writer["text"][key[0]] = text + ibest_writer["label"][key[0]] = label return results, meta_data From df00f5fc0b9f61068df74349f6e001640931efc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 16:54:14 +0800 Subject: [PATCH 096/125] fix bug --- .../llm_asr/demo_speech2text.py | 30 ++++++++----------- funasr/models/llm_asr/model.py | 2 +- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py index eb7e72f74..ed02373dd 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py @@ -6,29 +6,23 @@ from funasr import AutoModel model = AutoModel( - model="iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch", - vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", - vad_kwargs={"max_single_segment_time": 60000}, - punc_model="iic/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", - # spk_model="iic/speech_campplus_sv_zh-cn_16k-common", + model="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/4m-8gpu/exp6_speech2text_0607_linear_ddp", ) -res = model.generate( - input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav", - cache={}, +jsonl = ( + "/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData/aishell1_test_speech2text.jsonl" ) -print(res) +with open(jsonl, "r") as f: + lines = f.readlines() +for i, line in enumerate(lines): + data_dict = json.loads(line.strip()) + data = data_dict["messages"] -""" can not use currently -from funasr import AutoFrontend + res = model.generate( + input=data, + cache={}, + ) -frontend = AutoFrontend(model="iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch") - -fbanks = frontend(input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav", batch_size=2) - -for batch_idx, fbank_dict in enumerate(fbanks): - res = model.generate(**fbank_dict) print(res) -""" diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 78d9340a8..ff70c3ca6 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -532,7 +532,7 @@ class LLMASR2(nn.Module): loss, stats, weight = force_gatherable((loss, stats, batch_size), loss.device) return loss, stats, weight - def data_template(self, data_in): + def data_template(self, data): system, user, assistant = [], [], [] for i, item in enumerate(data): role = item["role"] From 310006dd60bf464c0fbeb2b81771eef53539f1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 17:19:32 +0800 Subject: [PATCH 097/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 0d12a1c4f..3bc6aa011 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -162,7 +162,7 @@ class OpenAIDataset(torch.utils.data.Dataset): if badcase_flag: continue input_ids = torch.tensor(input_ids, dtype=torch.int64) # [: self.max_token_length] - attention_mask = torch.tensor([len(input_ids)], dtype=torch.int32) + attention_mask = torch.tensor([1] * len(input_ids), dtype=torch.int32) labels = torch.tensor(labels, dtype=torch.int64) # [: self.max_token_length] fbank = speech[0, :, :] From e5be2853474189425947e66d795bf6130730bc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 17:49:36 +0800 Subject: [PATCH 098/125] fix bug --- funasr/models/llm_asr/model.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index ff70c3ca6..0955e8440 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -6,7 +6,7 @@ import torch import torch.nn as nn import torch.nn.functional as F from torch.cuda.amp import autocast - +import re from funasr.models.scama.utils import sequence_mask from funasr.losses.label_smoothing_loss import LabelSmoothingLoss from funasr.models.ctc.ctc import CTC @@ -560,21 +560,30 @@ class LLMASR2(nn.Module): user = contents["user"] assistant = contents["assistant"] pattern = re.compile(r"(<\|startofspeech\|>.*?<\|endofspeech\|>)") - input_ids, labels, fbank, fbank_lens, fbank_mask, fbank_beg = [], [], [], [], [], [] + input_ids, labels, source_ids, target_ids, fbank, fbank_lens, fbank_mask, fbank_beg = ( + [], + [], + [], + [], + [], + [], + [], + ) for i, (system_prompt, user_prompt, target_out) in enumerate(zip(system, user, assistant)): source_input = f"<|im_start|>system\n{system_prompt}<|im_end|>\n<|im_start|>user\n{user_prompt}<|im_end|>\n<|im_start|>assistant\n" splits = pattern.split(source_input) - source_ids = [] + source_ids_i = [] fbank_mask_i = [] fbank_beg_i = [] fbank_lens_i = [] + # target_ids_i = [] for k, sub_str in enumerate(splits): if not sub_str.startswith("<|startofspeech|>"): sub_token = tokenizer.encode(sub_str) - source_ids += sub_token + source_ids_i += sub_token fbank_mask_i += [0] * len(sub_token) else: sub_str = sub_str.replace("<|startofspeech|>", "").replace( @@ -600,14 +609,14 @@ class LLMASR2(nn.Module): olens = 1 + (olens - 3 + 2 * 1) // 2 sub_token_len = (olens - 1) // 2 + 1 sub_token = [0] * sub_token_len - fbank_beg_i = [len(source_ids)] - source_ids += sub_token + fbank_beg_i = [len(source_ids_i)] + source_ids_i += sub_token fbank_mask_i += [1] * len(sub_token) - source_mask = [-100] * len(source_ids) + source_mask = [-100] * len(source_ids_i) target_out = f"{target_out}<|im_end|>" target_ids = tokenizer.encode(target_out) - input_ids += source_ids + target_ids + input_ids += source_ids_i + target_ids labels += source_mask + target_ids fbank_mask += fbank_mask_i fbank_beg.append(fbank_beg_i) From 3d5e19792cd4bb510c2c0fc5749731d52b825c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 18:43:35 +0800 Subject: [PATCH 099/125] fix bug --- .../llm_asr/demo_speech2text.py | 4 ++- funasr/models/llm_asr/model.py | 28 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py index ed02373dd..072dcdff3 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py @@ -16,12 +16,14 @@ jsonl = ( with open(jsonl, "r") as f: lines = f.readlines() +tearchforing = True for i, line in enumerate(lines): data_dict = json.loads(line.strip()) data = data_dict["messages"] res = model.generate( - input=data, + input=[data], + tearchforing=tearchforing, cache={}, ) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 0955e8440..697f78dc7 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -568,6 +568,7 @@ class LLMASR2(nn.Module): [], [], [], + [], ) for i, (system_prompt, user_prompt, target_out) in enumerate(zip(system, user, assistant)): @@ -624,7 +625,7 @@ class LLMASR2(nn.Module): input_ids = torch.tensor(input_ids, dtype=torch.int64) # [: self.max_token_length] attention_mask = torch.tensor([1] * len(input_ids), dtype=torch.int32) labels = torch.tensor(labels, dtype=torch.int64) # [: self.max_token_length] - source_ids = torch.tensor(source_ids, dtype=torch.int64) + source_ids = torch.tensor(source_ids_i, dtype=torch.int64) target_ids = torch.tensor(target_ids, dtype=torch.int64) fbank = speech[0, :, :] @@ -662,7 +663,7 @@ class LLMASR2(nn.Module): if kwargs.get("batch_size", 1) > 1: raise NotImplementedError("batch decoding is not implemented") - contents = self.data_template(data_in) + contents = self.data_template(data_in[0]) output = self.data_load_speech(contents, tokenizer, frontend, **kwargs) batch = to_device(output, kwargs["device"]) @@ -676,7 +677,7 @@ class LLMASR2(nn.Module): input_ids = batch["input_ids"] source_ids = batch["source_ids"] - if kwargs.get("tearchforing", False): + if not kwargs.get("tearchforing", False): input_ids = source_ids input_ids[input_ids < 0] = 0 inputs_embeds = self.llm.model.get_input_embeddings()(input_ids) @@ -704,6 +705,23 @@ class LLMASR2(nn.Module): generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) )[0] label = contents["assistant"][0] + loss = None + else: + + labels_ids = batch["labels_ids"] + labels_ids[labels_ids == -1] = -100 + attention_mask = batch.get("attention_mask", None) + model_outputs = self.llm( + inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids + ) + + preds = torch.argmax(model_outputs.logits, -1)[:, source_ids.shape[1]] + response = tokenizer.batch_decode( + preds, + add_special_tokens=False, + skip_special_tokens=kwargs.get("skip_special_tokens", True), + )[0] + loss = model_outputs.loss ibest_writer = None if kwargs.get("output_dir") is not None: @@ -713,10 +731,12 @@ class LLMASR2(nn.Module): results = [] result_i = {"key": key[0], "text": response, "label": label} + if loss is not None: + result_i["loss"] = loss results.append(result_i) if ibest_writer is not None: - ibest_writer["text"][key[0]] = text + ibest_writer["text"][key[0]] = response ibest_writer["label"][key[0]] = label return results, meta_data From 2191795f742063b1c0a394fc2a65898445ccce65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 19:45:15 +0800 Subject: [PATCH 100/125] fix bug --- funasr/models/llm_asr/model.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 697f78dc7..f8c3efc77 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -692,6 +692,7 @@ class LLMASR2(nn.Module): batch_idx, :min_len, : ] + label = contents["assistant"][0] if not kwargs.get("tearchforing", False): generated_ids = self.llm.generate( @@ -704,7 +705,7 @@ class LLMASR2(nn.Module): response = tokenizer.batch_decode( generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) )[0] - label = contents["assistant"][0] + loss = None else: @@ -715,13 +716,13 @@ class LLMASR2(nn.Module): inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids ) - preds = torch.argmax(model_outputs.logits, -1)[:, source_ids.shape[1]] + preds = torch.argmax(model_outputs.logits, -1)[:, source_ids.shape[1] :] response = tokenizer.batch_decode( preds, add_special_tokens=False, skip_special_tokens=kwargs.get("skip_special_tokens", True), )[0] - loss = model_outputs.loss + loss = model_outputs.loss.item() ibest_writer = None if kwargs.get("output_dir") is not None: From 9fd3c47fd7ff191e1e07457b6bcffa1823e69b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 21:08:54 +0800 Subject: [PATCH 101/125] fix bug --- funasr/models/llm_asr/model.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index f8c3efc77..18791d004 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -19,6 +19,7 @@ from funasr.utils import postprocess_utils from funasr.utils.datadir_writer import DatadirWriter from funasr.register import tables from funasr.train_utils.device_funcs import to_device +import traceback @tables.register("model_classes", "LLMASR") @@ -489,6 +490,7 @@ class LLMASR2(nn.Module): fbank_fake_len = fbank_fake_lens[batch_idx].item() fbank_beg_idx = fbank_beg[batch_idx, 0].item() min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) + try: inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ batch_idx, :min_len, : @@ -499,7 +501,7 @@ class LLMASR2(nn.Module): f"batch_idx: {batch_idx}, inputs_embeds: {inputs_embeds.shape}, fbank_beg_idx: {fbank_beg_idx}, min_len: {min_len}, fbank_fake_len: {fbank_fake_len}" ) fbank_fake_len = encoder_out_lens[batch_idx].item() - min_len = min(fbank_fake_len, inputs_embeds.shape[1] - fbank_beg_idx) + min_len = min(fbank_fake_len, min_len) inputs_embeds[batch_idx, fbank_beg_idx : fbank_beg_idx + min_len, :] = encoder_out[ batch_idx, :min_len, : ] From 2a8d041806df41fa3719505d1b3379bbbd369574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sat, 8 Jun 2024 21:35:21 +0800 Subject: [PATCH 102/125] fix bug --- funasr/models/llm_asr/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 18791d004..5fde3ff6e 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -498,7 +498,7 @@ class LLMASR2(nn.Module): except Exception as e: logging.error(f"{str(e)}, {traceback.format_exc()}") logging.info( - f"batch_idx: {batch_idx}, inputs_embeds: {inputs_embeds.shape}, fbank_beg_idx: {fbank_beg_idx}, min_len: {min_len}, fbank_fake_len: {fbank_fake_len}" + f"batch_idx: {batch_idx}, inputs_embeds: {inputs_embeds.shape}, fbank_beg_idx: {fbank_beg_idx}, min_len: {min_len}, fbank_fake_len: {fbank_fake_len}, encoder_out: {encoder_out.shape}, encoder_out_lens: {encoder_out_lens[batch_idx].item()}" ) fbank_fake_len = encoder_out_lens[batch_idx].item() min_len = min(fbank_fake_len, min_len) From 1c8b46a233ac4a782d7170e20533f536761e25c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 00:21:44 +0800 Subject: [PATCH 103/125] fix bug --- funasr/bin/train_ds.py | 10 ++++++++++ funasr/datasets/audio_datasets/samplers.py | 17 ++++++++++------- funasr/datasets/dataloader_entry.py | 21 ++++++++++++--------- funasr/train_utils/trainer_ds.py | 6 ++++++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index a4ae11b68..21d747a59 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -158,6 +158,8 @@ def main(**kwargs): time1 = time.perf_counter() for data_split_i in range(trainer.start_data_split_i, dataloader.data_split_num): + time_slice_i = time.perf_counter() + dataloader_tr, dataloader_val = dataloader.build_iter( epoch, data_split_i=data_split_i, start_step=trainer.start_step ) @@ -178,6 +180,14 @@ def main(**kwargs): torch.cuda.empty_cache() + time_escaped = (time.perf_counter() - time1) / 3600.0 + logging.info( + f"rank: {local_rank}, " + f"time_escaped_epoch: {time_escaped:.3f} hours, " + f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours" + f"epoch: {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" + ) + trainer.start_data_split_i = 0 trainer.validate_epoch(model=model, dataloader_val=dataloader_val, epoch=epoch + 1) scheduler.step() diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index 2e271af6b..94e92094f 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -334,6 +334,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): drop_last=False, is_training: bool = True, sort_size: int = 1024, + start_step: int = 0, **kwargs, ): @@ -364,12 +365,14 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): self.sort_size = sort_size * num_replicas self.max_token_length = kwargs.get("max_token_length", 2048) self.length_scale_source = kwargs.get("length_scale_source", 1.0) - self.start_step = kwargs.get("start_step", 2048) self.batch_size_sample_max = kwargs.get("batch_size_sample_max", 200) - - super().__init__( - dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle, drop_last=drop_last - ) + self.start_step = start_step + self.batch_num = 1 + if self.start_step > 0: + logging.info(f"Warning, start_step > 0, dataloader start from step: {self.start_step}") + # super().__init__( + # dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle, drop_last=drop_last + # ) def __iter__(self): if self.shuffle: @@ -424,11 +427,11 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): rank_batches[i % self.num_replicas].append(batch) # Assign all batches for the current rank directly - final_batches = rank_batches[self.rank] # [self.start_step :] + final_batches = rank_batches[self.rank][self.start_step :] self.batch_num = len(final_batches) logging.info( - f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {self.batch_num}" + f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {rank_batches[self.rank]}, after: {self.batch_num}" ) return iter(final_batches) diff --git a/funasr/datasets/dataloader_entry.py b/funasr/datasets/dataloader_entry.py index 925b1d37f..055e4c8a7 100644 --- a/funasr/datasets/dataloader_entry.py +++ b/funasr/datasets/dataloader_entry.py @@ -49,14 +49,19 @@ class DataloaderMapStyle: def __init__(self, frontend=None, tokenizer=None, **kwargs): # dataset logging.info("Build dataloader") + dataset_class = tables.dataset_classes.get(kwargs.get("dataset", "AudioDataset")) - dataset_tr = dataset_class( - kwargs.get("train_data_set_list"), - frontend=frontend, - tokenizer=tokenizer, - is_training=True, - **kwargs.get("dataset_conf"), - ) + dataset_tr = None + # split dataset + self.data_split_num = kwargs["dataset_conf"].get("data_split_num", 1) + if self.data_split_num == 1: + dataset_tr = dataset_class( + kwargs.get("train_data_set_list"), + frontend=frontend, + tokenizer=tokenizer, + is_training=True, + **kwargs.get("dataset_conf"), + ) dataset_val = dataset_class( kwargs.get("valid_data_set_list"), frontend=frontend, @@ -69,8 +74,6 @@ class DataloaderMapStyle: self.dataset_val = dataset_val self.kwargs = kwargs - # split dataset - self.data_split_num = kwargs["dataset_conf"].get("data_split_num", 1) self.dataset_class = dataset_class self.frontend = frontend self.tokenizer = tokenizer diff --git a/funasr/train_utils/trainer_ds.py b/funasr/train_utils/trainer_ds.py index ec887cc8c..ec76531d6 100644 --- a/funasr/train_utils/trainer_ds.py +++ b/funasr/train_utils/trainer_ds.py @@ -167,6 +167,8 @@ class Trainer: Args: epoch (int): The epoch number at which the checkpoint is being saved. """ + if self.use_ddp or self.use_fsdp: + dist.barrier() step_in_epoch = None if step is None else step_in_epoch if self.use_deepspeed: @@ -760,6 +762,10 @@ class Trainer: ckpt_name = f'model.pt.ep{epoch}.{kwargs.get("step_in_epoch")}' self.val_acc_step_or_eoch[ckpt_name] = self.val_acc_avg self.val_loss_step_or_eoch[ckpt_name] = self.val_loss_avg + + if self.use_ddp or self.use_fsdp or self.use_deepspeed: + dist.barrier() + model.train() def log( From b75d1e89bb2f513a79bb07e9100ba1cd2bbcf40c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 00:32:57 +0800 Subject: [PATCH 104/125] fix bug --- funasr/bin/train.py | 9 +++++++++ funasr/bin/train_ds.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index c3556d1b9..1feb416bd 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -202,6 +202,7 @@ def main(**kwargs): time1 = time.perf_counter() for data_split_i in range(trainer.start_data_split_i, dataloader.data_split_num): + time_slice_i = time.perf_counter() dataloader_tr, dataloader_val = dataloader.build_iter( epoch, data_split_i=data_split_i, start_step=trainer.start_step ) @@ -223,6 +224,14 @@ def main(**kwargs): torch.cuda.empty_cache() + time_escaped = (time.perf_counter() - time_slice_i) / 3600.0 + logging.info( + f"rank: {local_rank}, " + f"time_escaped_epoch: {time_escaped:.3f} hours, " + f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours" + f"epoch: {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" + ) + trainer.start_data_split_i = 0 trainer.validate_epoch( model=model, dataloader_val=dataloader_val, epoch=epoch + 1, writer=writer diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index 21d747a59..d9b767915 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -180,7 +180,7 @@ def main(**kwargs): torch.cuda.empty_cache() - time_escaped = (time.perf_counter() - time1) / 3600.0 + time_escaped = (time.perf_counter() - time_slice_i) / 3600.0 logging.info( f"rank: {local_rank}, " f"time_escaped_epoch: {time_escaped:.3f} hours, " From dcd40590df7ab625b7934694c13d3d5fbc941f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 01:08:29 +0800 Subject: [PATCH 105/125] fix bug --- .../llm_asr/conf/whisper_qwen_linear2.yaml | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml index 62d77e260..c2f641977 100644 --- a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml +++ b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml @@ -59,17 +59,20 @@ scheduler_conf: dataset: OpenAIDataset dataset_conf: - index_ds: OpenAIIndexDSJsonl - batch_sampler: CustomDistributedBatchSampler - batch_type: example # example or length - batch_size: 4 # if batch_type is example, batch_size is the numbers of samples; if length, batch_size is source_token_len+target_token_len; - max_token_length: 3000 # filter samples if source_token_len+target_token_len > max_token_length, - shuffle: True - num_workers: 0 - audio_adaptor_downsample_rate: ${audio_adaptor_conf.downsample_rate} - audio_encoder_downsample_rate: 2 -# prompt: "<|startoftranscription|><|zh|><|transcribe|><|zh|><|notimestamps|><|wo_itn|>" - + index_ds: OpenAIIndexDSJsonl + batch_sampler: BatchSampler + batch_type: token + batch_size: 900 + max_token_length: 1024 + shuffle: true + sort_size: 1024 + batch_size_scale_ratio_max: 2 + num_workers: 4 + audio_adaptor_downsample_rate: ${audio_adaptor_conf.downsample_rate} + audio_encoder_downsample_rate: 2 + data_split_num: 512 + batch_size_sample_max: 15 + retry: 20 tokenizer: HuggingfaceTokenizer From 8bb997175304f7d11ab403a3705d3242c0f2d28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 01:35:15 +0800 Subject: [PATCH 106/125] fix bug --- funasr/datasets/audio_datasets/samplers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index 94e92094f..bddf18638 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -431,7 +431,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): self.batch_num = len(final_batches) logging.info( - f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {rank_batches[self.rank]}, after: {self.batch_num}" + f"rank: {self.rank}, dataloader start from step: {self.start_step}, batch_num: {len(rank_batches[self.rank])}, after: {self.batch_num}" ) return iter(final_batches) From 56986acaa78b0ea105d6b136905ecf6e8379cd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 02:05:49 +0800 Subject: [PATCH 107/125] fix bug --- funasr/datasets/audio_datasets/samplers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index bddf18638..f8f744c55 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -392,7 +392,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): ) batch = [] max_len_in_batch = 0 - count = 0 + count = 1 for idx in buffer: original_sample_length = self.dataset.get_source_len(idx) if original_sample_length > self.max_token_length: @@ -410,7 +410,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): buffer_batches.append(batch) batch = [idx] max_len_in_batch = sample_length - count = 0 + count = 1 if batch: buffer_batches.append(batch) From 3eee773814c392e497557bbad501e0add4c8eca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 02:11:42 +0800 Subject: [PATCH 108/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 3bc6aa011..9c74ef188 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -216,7 +216,7 @@ class OpenAIDataset(torch.utils.data.Dataset): if b < 2: beg = 0 logging.info( - f"Warning, b * t: {b * t} > {self.batch_size}, b: {b}, t: {t}, drop half data {idx}th, beg:{beg}" + f"Warning, b * t: {b * t} > {self.batch_size_scale_ratio_max} * {self.batch_size}, b: {b}, t: {t}, drop half data {idx}th, beg:{beg}" ) samples = samples[beg : beg + b : 2] continue From 7b34f8ffde38c038c804c18208c3f2b129182949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 02:18:25 +0800 Subject: [PATCH 109/125] fix bug --- .../llm_asr/conf/whisper_qwen_linear2.yaml | 2 +- .../conf/whisper_qwen_transformer.yaml | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_transformer.yaml diff --git a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml index c2f641977..483f219d2 100644 --- a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml +++ b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_linear2.yaml @@ -28,7 +28,7 @@ audio_adaptor_conf: downsample_rate: 2 llm_dim: 4096 encoder_dim: 1280 - n_layer: 2 + n_layer: 0 # frontend related frontend: WhisperFrontend diff --git a/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_transformer.yaml b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_transformer.yaml new file mode 100644 index 000000000..c2f641977 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/conf/whisper_qwen_transformer.yaml @@ -0,0 +1,81 @@ +# This is an example that demonstrates how to configure a model file. +# You can modify the configuration according to your own requirements. + +# to print the register_table: +# from funasr.register import tables +# tables.print() + +# network architecture +model: LLMASR2 +model_conf: + lsm_weight: 0.1 # label smoothing option + length_normalized_loss: true + +# encoder +audio_encoder: "/nfs/zhifu.gzf/init_model/SenseVoiceModelscope" +audio_encoder_conf: + hub: ms + freeze: true + +llm: Qwen1.5-7b-chat +llm_conf: + hub: hf + freeze: true + init_param_path: "/nfs/zhifu.gzf/init_model/qwen/Qwen1___5-7B-Chat_raw" + +audio_adaptor: Transformer +audio_adaptor_conf: + downsample_rate: 2 + llm_dim: 4096 + encoder_dim: 1280 + n_layer: 2 + +# frontend related +frontend: WhisperFrontend +frontend_conf: + fs: 16000 + whisper_model: large-v3 + do_pad_trim: false + permute: false # true: [bs, frames, dims]; false: [bs, dims, frames] + filters_path: "/nfs/zhifu.gzf/init_model/SenseVoiceModelscope/assets/mel_filters.npz" + + + +train_conf: + accum_grad: 1 + grad_clip: 5 + max_epoch: 15 + keep_nbest_models: 10 + log_interval: 10 + +optim: adamw +optim_conf: + lr: 0.0001 + weight_decay: 0.000000 + +scheduler: warmuplr +scheduler_conf: + warmup_steps: 1500 + +dataset: OpenAIDataset +dataset_conf: + index_ds: OpenAIIndexDSJsonl + batch_sampler: BatchSampler + batch_type: token + batch_size: 900 + max_token_length: 1024 + shuffle: true + sort_size: 1024 + batch_size_scale_ratio_max: 2 + num_workers: 4 + audio_adaptor_downsample_rate: ${audio_adaptor_conf.downsample_rate} + audio_encoder_downsample_rate: 2 + data_split_num: 512 + batch_size_sample_max: 15 + retry: 20 + + +tokenizer: HuggingfaceTokenizer +tokenizer_conf: + init_param_path: "/nfs/zhifu.gzf/init_model/qwen/Qwen1___5-7B-Chat_raw" + From 1186cd96a5a8fa3466c5e3e41f86f0280deb1410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 02:19:29 +0800 Subject: [PATCH 110/125] fix bug --- funasr/datasets/audio_datasets/samplers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/funasr/datasets/audio_datasets/samplers.py b/funasr/datasets/audio_datasets/samplers.py index f8f744c55..f7057de11 100644 --- a/funasr/datasets/audio_datasets/samplers.py +++ b/funasr/datasets/audio_datasets/samplers.py @@ -399,10 +399,7 @@ class CustomDistributedBufferDynamicBatchSampler(DistributedSampler): continue sample_length = 1 if self.batch_type == "example" else original_sample_length potential_batch_length = max(max_len_in_batch, sample_length) * (len(batch) + 1) - if ( - potential_batch_length <= self.batch_size - and count <= self.batch_size_sample_max - ): + if potential_batch_length <= self.batch_size and count < self.batch_size_sample_max: batch.append(idx) max_len_in_batch = max(max_len_in_batch, sample_length) count += 1 From 6e0d1388264f79ce5e2a3c8944de1bad491d30eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 03:26:32 +0800 Subject: [PATCH 111/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 9c74ef188..e13c15618 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -211,14 +211,15 @@ class OpenAIDataset(torch.utils.data.Dataset): if self.batch_type != "example": b, t = outputs["input_ids"].shape - if b * t > self.batch_size * self.batch_size_scale_ratio_max: - beg = torch.randint(0, 2, ()).item() - if b < 2: - beg = 0 + if b > 1 and b * t > self.batch_size * self.batch_size_scale_ratio_max: + # beg = torch.randint(0, 2, ()).item() + # if b < 2: + # beg = 0 logging.info( - f"Warning, b * t: {b * t} > {self.batch_size_scale_ratio_max} * {self.batch_size}, b: {b}, t: {t}, drop half data {idx}th, beg:{beg}" + f"Warning, b*t: {b}*{t}={b * t} > batch_size*relax: {self.batch_size_scale_ratio_max}*{self.batch_size}={self.batch_size_scale_ratio_max*self.batch_size}, drop half data {idx}th, beg:{beg}" ) - samples = samples[beg : beg + b : 2] + # samples = samples[beg : beg + b : 2] + samples = samples[:-1] continue break From 1163110135c625a8a3ebd94e050d9adb5b55bb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 03:29:41 +0800 Subject: [PATCH 112/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index e13c15618..9b36078f3 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -51,7 +51,7 @@ class OpenAIDataset(torch.utils.data.Dataset): self.batch_size = kwargs.get("batch_size") self.batch_type = kwargs.get("batch_type") self.prompt_ids_len = 0 - self.retry = kwargs.get("retry", 10) + self.retry = kwargs.get("retry", 100) self.permute = False from funasr.frontends.whisper_frontend import WhisperFrontend @@ -212,13 +212,9 @@ class OpenAIDataset(torch.utils.data.Dataset): if self.batch_type != "example": b, t = outputs["input_ids"].shape if b > 1 and b * t > self.batch_size * self.batch_size_scale_ratio_max: - # beg = torch.randint(0, 2, ()).item() - # if b < 2: - # beg = 0 logging.info( - f"Warning, b*t: {b}*{t}={b * t} > batch_size*relax: {self.batch_size_scale_ratio_max}*{self.batch_size}={self.batch_size_scale_ratio_max*self.batch_size}, drop half data {idx}th, beg:{beg}" + f"Warning, b*t: {b}*{t}={b * t} > batch_size*relax: {self.batch_size_scale_ratio_max}*{self.batch_size}={self.batch_size_scale_ratio_max*self.batch_size}, drop last data" ) - # samples = samples[beg : beg + b : 2] samples = samples[:-1] continue From 373fbd15e0af0fd1622d28110432bb91ec4cd445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 03:36:23 +0800 Subject: [PATCH 113/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 9b36078f3..07a7c319a 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -63,6 +63,7 @@ class OpenAIDataset(torch.utils.data.Dataset): # self.kwargs = kwargs self.max_token_length = kwargs.get("max_token_length", 1024) self.batch_size_scale_ratio_max = kwargs.get("batch_size_scale_ratio_max", 1.5) + self.batch_size_token_max = kwargs.get("batch_size_token_max", 2500) def get_source_len(self, index): item = self.index_ds[index] @@ -213,7 +214,7 @@ class OpenAIDataset(torch.utils.data.Dataset): b, t = outputs["input_ids"].shape if b > 1 and b * t > self.batch_size * self.batch_size_scale_ratio_max: logging.info( - f"Warning, b*t: {b}*{t}={b * t} > batch_size*relax: {self.batch_size_scale_ratio_max}*{self.batch_size}={self.batch_size_scale_ratio_max*self.batch_size}, drop last data" + f"Warning, {idx}th, b*t: {b}*{t}={b * t} > batch_size_sample_max: {self.batch_size_token_max}, drop last data" ) samples = samples[:-1] continue From 281e9835b6be56da5e41d788576559de9e71716b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 03:41:40 +0800 Subject: [PATCH 114/125] fix bug --- funasr/datasets/openai_datasets/datasets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/funasr/datasets/openai_datasets/datasets.py b/funasr/datasets/openai_datasets/datasets.py index 07a7c319a..8d243aced 100644 --- a/funasr/datasets/openai_datasets/datasets.py +++ b/funasr/datasets/openai_datasets/datasets.py @@ -212,7 +212,7 @@ class OpenAIDataset(torch.utils.data.Dataset): if self.batch_type != "example": b, t = outputs["input_ids"].shape - if b > 1 and b * t > self.batch_size * self.batch_size_scale_ratio_max: + if b > 1 and b * t > self.batch_size_token_max: logging.info( f"Warning, {idx}th, b*t: {b}*{t}={b * t} > batch_size_sample_max: {self.batch_size_token_max}, drop last data" ) From 1d27a1507b7a98d3d957f984bbab7e14523181fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 22:01:14 +0800 Subject: [PATCH 115/125] fix bug --- .../llm_asr/demo_speech2text.py | 27 ++++++-- .../llm_asr/demo_speech2text.sh | 63 +++++++++++++++++++ funasr/models/llm_asr/model.py | 12 ++-- 3 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py index 072dcdff3..dfbe95b35 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py @@ -3,20 +3,37 @@ # Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights Reserved. # MIT License (https://opensource.org/licenses/MIT) +import json +import os +import sys + from funasr import AutoModel -model = AutoModel( - model="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/4m-8gpu/exp6_speech2text_0607_linear_ddp", -) - +ckpt_dir = "/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/5m-8gpu/exp6_speech2text_linear_ddp_0609" +ckpt_id = "model.pt.ep0.90000" jsonl = ( "/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData/aishell1_test_speech2text.jsonl" ) +output_dir = f"{os.path.join(ckpt_dir, ckpt_id)}" + +ckpt_dir = sys.argv[1] +ckpt_id = sys.argv[2] +jsonl = sys.argv[3] +output_dir = sys.argv[4] +device = sys.argv[5] + +model = AutoModel( + model=ckpt_dir, + init_param=f"{os.path.join(ckpt_dir, ckpt_id)}", + output_dir=output_dir, + device=device, +) + with open(jsonl, "r") as f: lines = f.readlines() -tearchforing = True +tearchforing = False for i, line in enumerate(lines): data_dict = json.loads(line.strip()) data = data_dict["messages"] diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh new file mode 100644 index 000000000..4f521f286 --- /dev/null +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -0,0 +1,63 @@ + + + +ckpt_dir="/nfs/zhifu.gzf/ckpt/saves/qwen_1.5_7b/full/sft/asr_tts_text_exp1_ds_z3/checkpoint-11000" +ckpt_id="model.pt.ep0.90000" +jsonl_dir="/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData" +out_dir="${ckpt_dir}/asr" +mkdir -p ${out_dir} + +device="cuda:0" + +for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do + jsonl=${jsonl_dir}/${data_set} + output_dir=${out_dir}/${data_set} + + pred_file=${out_dir}/${data_set}/1best_recog/text_tn + ref_file=${out_dir}/${data_set}/1best_recog/label + + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} + + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false + +done + + +for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do + jsonl=${jsonl_dir}/${data_set} + output_dir=${out_dir}/${data_set} + + pred_file=${out_dir}/${data_set}/1best_recog/text_tn + ref_file=${out_dir}/${data_set}/1best_recog/label + + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + +done + +for data_set in "s2tt_en2zh.v20240605.test.jsonl"; do + jsonl=${jsonl_dir}/${data_set} + output_dir=${out_dir}/${data_set} + + pred_file=${out_dir}/${data_set}/1best_recog/text_tn + ref_file=${out_dir}/${data_set}/1best_recog/label + + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + +done + +for data_set in "s2tt_zh2en.v20240605.test.jsonl"; do + jsonl=${jsonl_dir}/${data_set} + output_dir=${out_dir}/${data_set} + + pred_file=${out_dir}/${data_set}/1best_recog/text_tn + ref_file=${out_dir}/${data_set}/1best_recog/label + + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + +done \ No newline at end of file diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 5fde3ff6e..aacbe45a4 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -700,10 +700,10 @@ class LLMASR2(nn.Module): generated_ids = self.llm.generate( inputs_embeds=inputs_embeds, max_new_tokens=kwargs.get("max_length", 512) ) - generated_ids = [ - output_ids[len(input_id) :] - for input_id, output_ids in zip(input_ids, generated_ids) - ] + # generated_ids = [ + # output_ids[len(input_id) :] + # for input_id, output_ids in zip(input_ids, generated_ids) + # ] response = tokenizer.batch_decode( generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) )[0] @@ -733,7 +733,8 @@ class LLMASR2(nn.Module): ibest_writer = self.writer[f"{0 + 1}best_recog"] results = [] - result_i = {"key": key[0], "text": response, "label": label} + response_clean = re.sub("[^\w\s\u3000\u4e00-\u9fff]+", "", response) + result_i = {"key": key[0], "text": response, "text_tn": response_clean, "label": label} if loss is not None: result_i["loss"] = loss results.append(result_i) @@ -741,5 +742,6 @@ class LLMASR2(nn.Module): if ibest_writer is not None: ibest_writer["text"][key[0]] = response ibest_writer["label"][key[0]] = label + ibest_writer["text_tn"][key[0]] = response_clean return results, meta_data From 7fc17b1aafb0c53ac83a86ecf4adbee3e10fdb86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Sun, 9 Jun 2024 22:40:49 +0800 Subject: [PATCH 116/125] fix bug --- .../llm_asr/demo_speech2text.py | 1 + .../llm_asr/demo_speech2text.sh | 28 +++++++++---------- funasr/models/llm_asr/model.py | 16 +++++++++-- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py index dfbe95b35..e5e3e2302 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.py @@ -15,6 +15,7 @@ jsonl = ( "/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData/aishell1_test_speech2text.jsonl" ) output_dir = f"{os.path.join(ckpt_dir, ckpt_id)}" +device = "cuda:0" ckpt_dir = sys.argv[1] ckpt_id = sys.argv[2] diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index 4f521f286..81f211fa8 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -1,10 +1,10 @@ -ckpt_dir="/nfs/zhifu.gzf/ckpt/saves/qwen_1.5_7b/full/sft/asr_tts_text_exp1_ds_z3/checkpoint-11000" +ckpt_dir="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/5m-8gpu/exp6_speech2text_linear_ddp_0609" ckpt_id="model.pt.ep0.90000" jsonl_dir="/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData" -out_dir="${ckpt_dir}/asr" +out_dir="${ckpt_dir}/inference-${ckpt_id}" mkdir -p ${out_dir} device="cuda:0" @@ -12,9 +12,9 @@ device="cuda:0" for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} - - pred_file=${out_dir}/${data_set}/1best_recog/text_tn - ref_file=${out_dir}/${data_set}/1best_recog/label + mkdir -p ${output_dir} + pred_file=${output_dir}/${data_set}/1best_recog/text_tn + ref_file=${output_dir}/${data_set}/1best_recog/label python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} @@ -26,9 +26,9 @@ done for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} - - pred_file=${out_dir}/${data_set}/1best_recog/text_tn - ref_file=${out_dir}/${data_set}/1best_recog/label + mkdir -p ${output_dir} + pred_file=${output_dir}/${data_set}/1best_recog/text_tn + ref_file=${output_dir}/${data_set}/1best_recog/label python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} @@ -39,9 +39,9 @@ done for data_set in "s2tt_en2zh.v20240605.test.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} - - pred_file=${out_dir}/${data_set}/1best_recog/text_tn - ref_file=${out_dir}/${data_set}/1best_recog/label + mkdir -p ${output_dir} + pred_file=${output_dir}/${data_set}/1best_recog/text_tn + ref_file=${output_dir}/${data_set}/1best_recog/label python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} @@ -52,9 +52,9 @@ done for data_set in "s2tt_zh2en.v20240605.test.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} - - pred_file=${out_dir}/${data_set}/1best_recog/text_tn - ref_file=${out_dir}/${data_set}/1best_recog/label + mkdir -p ${output_dir} + pred_file=${output_dir}/${data_set}/1best_recog/text_tn + ref_file=${output_dir}/${data_set}/1best_recog/label python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index aacbe45a4..21072b0f7 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -556,7 +556,7 @@ class LLMASR2(nn.Module): return contents - def data_load_speech(self, contents: dict, tokenizer, frontend, **kwargs): + def data_load_speech(self, contents: dict, tokenizer, frontend, meta_data={}, **kwargs): system = contents["system"] user = contents["user"] @@ -594,7 +594,10 @@ class LLMASR2(nn.Module): ) if sub_str.startswith("!"): try: + time1 = time.perf_counter() data_src = load_audio_text_image_video(sub_str[1:], fs=frontend.fs) + time2 = time.perf_counter() + meta_data["load_data"] = f"{time2 - time1:0.3f}" except Exception as e: logging.error(f"Loading wav failed! {str(e)}, {traceback.format_exc()}") @@ -605,6 +608,15 @@ class LLMASR2(nn.Module): is_final=True, ) # speech: [b, T, d] + time3 = time.perf_counter() + meta_data["extract_feat"] = f"{time3 - time2:0.3f}" + meta_data["batch_data_time"] = ( + speech_lengths.sum().item() + * frontend.frame_shift + * frontend.lfr_n + / 1000 + ) + if kwargs.get("permute", True): speech = speech.permute(0, 2, 1) @@ -666,7 +678,7 @@ class LLMASR2(nn.Module): raise NotImplementedError("batch decoding is not implemented") contents = self.data_template(data_in[0]) - output = self.data_load_speech(contents, tokenizer, frontend, **kwargs) + output = self.data_load_speech(contents, tokenizer, frontend, meta_data=meta_data, **kwargs) batch = to_device(output, kwargs["device"]) # audio encoder From f3dfbeed2d898175b2933195e5648f305d305b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 00:31:38 +0800 Subject: [PATCH 117/125] fix bug --- .../llm_asr/demo_speech2text.sh | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index 81f211fa8..6b5f228da 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -13,8 +13,8 @@ for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_oth jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} mkdir -p ${output_dir} - pred_file=${output_dir}/${data_set}/1best_recog/text_tn - ref_file=${output_dir}/${data_set}/1best_recog/label + pred_file=${output_dir}/1best_recog/text_tn + ref_file=${output_dir}/1best_recog/label python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} @@ -27,12 +27,12 @@ for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} mkdir -p ${output_dir} - pred_file=${output_dir}/${data_set}/1best_recog/text_tn - ref_file=${output_dir}/${data_set}/1best_recog/label + pred_file=${output_dir}/1best_recog/text_tn + ref_file=${output_dir}/1best_recog/label - python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false done @@ -40,12 +40,12 @@ for data_set in "s2tt_en2zh.v20240605.test.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} mkdir -p ${output_dir} - pred_file=${output_dir}/${data_set}/1best_recog/text_tn - ref_file=${output_dir}/${data_set}/1best_recog/label + pred_file=${output_dir}/1best_recog/text_tn + ref_file=${output_dir}/1best_recog/label - python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false done @@ -53,11 +53,11 @@ for data_set in "s2tt_zh2en.v20240605.test.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} mkdir -p ${output_dir} - pred_file=${output_dir}/${data_set}/1best_recog/text_tn - ref_file=${output_dir}/${data_set}/1best_recog/label + pred_file=${output_dir}/1best_recog/text_tn + ref_file=${output_dir}/1best_recog/label - python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false done \ No newline at end of file From 0a4fa37891f6d909f9f6463537b1261daec0e7f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 00:40:25 +0800 Subject: [PATCH 118/125] fix bug --- .../industrial_data_pretraining/llm_asr/demo_speech2text.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index 6b5f228da..c4e7afe88 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -32,7 +32,7 @@ for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true done @@ -45,7 +45,7 @@ for data_set in "s2tt_en2zh.v20240605.test.jsonl"; do python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=true done From 82530ddf974a706df5a6a1e258d80c8dbc3f1d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 09:19:16 +0800 Subject: [PATCH 119/125] fix bug --- .../industrial_data_pretraining/llm_asr/demo_speech2text.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index c4e7afe88..d7bd1cb22 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -1,6 +1,4 @@ - - ckpt_dir="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/5m-8gpu/exp6_speech2text_linear_ddp_0609" ckpt_id="model.pt.ep0.90000" jsonl_dir="/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData" @@ -9,6 +7,9 @@ mkdir -p ${out_dir} device="cuda:0" +ckpt_id=$1 +device=$2 + for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do jsonl=${jsonl_dir}/${data_set} output_dir=${out_dir}/${data_set} From 1cd2812d4653ade8d77b698c0fc1641005ff3d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 09:36:06 +0800 Subject: [PATCH 120/125] fix bug --- .../llm_asr/demo_speech2text.sh | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index d7bd1cb22..64cc45b39 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -10,18 +10,18 @@ device="cuda:0" ckpt_id=$1 device=$2 -for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do - jsonl=${jsonl_dir}/${data_set} - output_dir=${out_dir}/${data_set} - mkdir -p ${output_dir} - pred_file=${output_dir}/1best_recog/text_tn - ref_file=${output_dir}/1best_recog/label - - python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} - - python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false - -done +#for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do +# jsonl=${jsonl_dir}/${data_set} +# output_dir=${out_dir}/${data_set} +# mkdir -p ${output_dir} +# pred_file=${output_dir}/1best_recog/text_tn +# ref_file=${output_dir}/1best_recog/label +# +# python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} +# +# python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false +# +#done for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do From 5ca83889c2774d86178427b859c8acba3f9a9ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 10:10:47 +0800 Subject: [PATCH 121/125] fix bug --- .../llm_asr/demo_speech2text.sh | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh index 64cc45b39..d4c409bf2 100644 --- a/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh +++ b/examples/industrial_data_pretraining/llm_asr/demo_speech2text.sh @@ -1,27 +1,28 @@ -ckpt_dir="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/5m-8gpu/exp6_speech2text_linear_ddp_0609" + ckpt_id="model.pt.ep0.90000" -jsonl_dir="/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData" -out_dir="${ckpt_dir}/inference-${ckpt_id}" -mkdir -p ${out_dir} - device="cuda:0" ckpt_id=$1 device=$2 -#for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do -# jsonl=${jsonl_dir}/${data_set} -# output_dir=${out_dir}/${data_set} -# mkdir -p ${output_dir} -# pred_file=${output_dir}/1best_recog/text_tn -# ref_file=${output_dir}/1best_recog/label -# -# python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} -# -# python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false -# -#done +ckpt_dir="/nfs/beinian.lzr/workspace/GPT-4o/Exp/exp6/5m-8gpu/exp6_speech2text_linear_ddp_0609" +jsonl_dir="/nfs/beinian.lzr/workspace/GPT-4o/Data/Speech2Text/TestData" + +out_dir="${ckpt_dir}/inference-${ckpt_id}" +mkdir -p ${out_dir} +for data_set in "librispeech_test_clean_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do + jsonl=${jsonl_dir}/${data_set} + output_dir=${out_dir}/${data_set} + mkdir -p ${output_dir} + pred_file=${output_dir}/1best_recog/text_tn + ref_file=${output_dir}/1best_recog/label + + python ./demo_speech2text.py ${ckpt_dir} ${ckpt_id} ${jsonl} ${output_dir} ${device} + + python /mnt/workspace/zhifu.gzf/codebase/FunASR/funasr/metrics/wer.py ++ref_file=${ref_file} ++hyp_file=${pred_file} ++cer_file=${pred_file}.cer ++cn_postprocess=false + +done for data_set in "aishell1_test_speech2text.jsonl" "aishell2_ios_test_speech2text.jsonl" "librispeech_test_other_speech2text.jsonl"; do From ea85c483ad59c6b17766ca19e1c13b7297598c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Mon, 10 Jun 2024 21:47:58 +0800 Subject: [PATCH 122/125] fix bug --- funasr/bin/train.py | 4 ++-- funasr/bin/train_ds.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/funasr/bin/train.py b/funasr/bin/train.py index 1feb416bd..1a3048153 100644 --- a/funasr/bin/train.py +++ b/funasr/bin/train.py @@ -228,8 +228,8 @@ def main(**kwargs): logging.info( f"rank: {local_rank}, " f"time_escaped_epoch: {time_escaped:.3f} hours, " - f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours" - f"epoch: {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" + f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {dataloader.data_split_num-data_split_i} slices, {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours, " + f"epoch: {trainer.max_epoch - epoch} epochs, {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" ) trainer.start_data_split_i = 0 diff --git a/funasr/bin/train_ds.py b/funasr/bin/train_ds.py index d9b767915..5b1d4fd3b 100644 --- a/funasr/bin/train_ds.py +++ b/funasr/bin/train_ds.py @@ -184,8 +184,8 @@ def main(**kwargs): logging.info( f"rank: {local_rank}, " f"time_escaped_epoch: {time_escaped:.3f} hours, " - f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours" - f"epoch: {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" + f"estimated to finish {dataloader.data_split_num} data_slices, remaining: {dataloader.data_split_num-data_split_i} slices, {(dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours, " + f"epoch: {trainer.max_epoch - epoch} epochs, {((trainer.max_epoch - epoch - 1)*dataloader.data_split_num + dataloader.data_split_num-data_split_i)*time_escaped:.3f} hours\n" ) trainer.start_data_split_i = 0 From 23008c7cac4be72d99f2172660c3975bbc54a5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 11 Jun 2024 11:48:42 +0800 Subject: [PATCH 123/125] fp16 --- funasr/models/llm_asr/model.py | 60 +++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 21072b0f7..5f1530992 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -706,37 +706,43 @@ class LLMASR2(nn.Module): batch_idx, :min_len, : ] - label = contents["assistant"][0] - if not kwargs.get("tearchforing", False): + llm_dtype = kwargs.get("llm_dtype", "fp32") + dtype_map = {"bf16": torch.bfloat16, "fp16": torch.float16, "fp32": torch.float32} + with torch.cuda.amp.autocast(dtype=dtype_map[llm_dtype]): + label = contents["assistant"][0] + self.llm = self.llm.to(dtype_map[llm_dtype]) + inputs_embeds = inputs_embeds.to(dtype_map[llm_dtype]) + attention_mask = attention_mask.to(dtype_map[llm_dtype]) + if not kwargs.get("tearchforing", False): - generated_ids = self.llm.generate( - inputs_embeds=inputs_embeds, max_new_tokens=kwargs.get("max_length", 512) - ) - # generated_ids = [ - # output_ids[len(input_id) :] - # for input_id, output_ids in zip(input_ids, generated_ids) - # ] - response = tokenizer.batch_decode( - generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) - )[0] + generated_ids = self.llm.generate( + inputs_embeds=inputs_embeds, max_new_tokens=kwargs.get("max_length", 512) + ) + # generated_ids = [ + # output_ids[len(input_id) :] + # for input_id, output_ids in zip(input_ids, generated_ids) + # ] + response = tokenizer.batch_decode( + generated_ids, skip_special_tokens=kwargs.get("skip_special_tokens", True) + )[0] - loss = None - else: + loss = None + else: - labels_ids = batch["labels_ids"] - labels_ids[labels_ids == -1] = -100 - attention_mask = batch.get("attention_mask", None) - model_outputs = self.llm( - inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids - ) + labels_ids = batch["labels_ids"] + labels_ids[labels_ids == -1] = -100 + attention_mask = batch.get("attention_mask", None) + model_outputs = self.llm( + inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids + ) - preds = torch.argmax(model_outputs.logits, -1)[:, source_ids.shape[1] :] - response = tokenizer.batch_decode( - preds, - add_special_tokens=False, - skip_special_tokens=kwargs.get("skip_special_tokens", True), - )[0] - loss = model_outputs.loss.item() + preds = torch.argmax(model_outputs.logits, -1)[:, source_ids.shape[1] :] + response = tokenizer.batch_decode( + preds, + add_special_tokens=False, + skip_special_tokens=kwargs.get("skip_special_tokens", True), + )[0] + loss = model_outputs.loss.item() ibest_writer = None if kwargs.get("output_dir") is not None: From 63e60cc43ddab5d28908e5e84e26a0553eb120f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 11 Jun 2024 13:49:57 +0800 Subject: [PATCH 124/125] fp16 --- funasr/auto/auto_model.py | 2 ++ funasr/models/llm_asr/model.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/funasr/auto/auto_model.py b/funasr/auto/auto_model.py index 7b5a02fff..22b1ac0ec 100644 --- a/funasr/auto/auto_model.py +++ b/funasr/auto/auto_model.py @@ -233,6 +233,8 @@ class AutoModel: # fp16 if kwargs.get("fp16", False): model.to(torch.float16) + elif kwargs.get("bf16", False): + model.to(torch.bfloat16) return model, kwargs def __call__(self, *args, **cfg): diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index 5f1530992..f72b2c814 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -684,6 +684,13 @@ class LLMASR2(nn.Module): # audio encoder speech = batch["speech"] speech_lengths = batch["speech_lengths"][:, 0] + # fp16 + if kwargs.get("fp16", False): + speech = speech.to(torch.float16) + encoder_out_lens = encoder_out_lens.to(torch.float16) + elif kwargs.get("bf16", False): + speech = speech.to(torch.bfloat16) + encoder_out_lens = encoder_out_lens.to(torch.bfloat16) encoder_out, encoder_out_lens = self.audio_encoder(speech.permute(0, 2, 1), speech_lengths) # audio_adaptor From a8653d897db4872055632e1fd9f3595291e787b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 11 Jun 2024 13:56:24 +0800 Subject: [PATCH 125/125] fixbug --- funasr/models/llm_asr/model.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/funasr/models/llm_asr/model.py b/funasr/models/llm_asr/model.py index f72b2c814..519918c0f 100644 --- a/funasr/models/llm_asr/model.py +++ b/funasr/models/llm_asr/model.py @@ -717,9 +717,9 @@ class LLMASR2(nn.Module): dtype_map = {"bf16": torch.bfloat16, "fp16": torch.float16, "fp32": torch.float32} with torch.cuda.amp.autocast(dtype=dtype_map[llm_dtype]): label = contents["assistant"][0] - self.llm = self.llm.to(dtype_map[llm_dtype]) - inputs_embeds = inputs_embeds.to(dtype_map[llm_dtype]) - attention_mask = attention_mask.to(dtype_map[llm_dtype]) + # self.llm = self.llm.to(dtype_map[llm_dtype]) + # inputs_embeds = inputs_embeds.to(dtype_map[llm_dtype]) + if not kwargs.get("tearchforing", False): generated_ids = self.llm.generate( @@ -739,6 +739,7 @@ class LLMASR2(nn.Module): labels_ids = batch["labels_ids"] labels_ids[labels_ids == -1] = -100 attention_mask = batch.get("attention_mask", None) + # attention_mask = attention_mask.to(dtype_map[llm_dtype]) model_outputs = self.llm( inputs_embeds=inputs_embeds, attention_mask=attention_mask, labels=labels_ids )