CoolFace
Apppublic

doby4u/chattts

sourceHugging Facemitupdated 2y agoView on Hugging Face
2likes
core.py150 linesDownload Raw Back to ChatTTS
1 2import os3import logging4from omegaconf import OmegaConf5 6import torch7from vocos import Vocos8from .model.dvae import DVAE9from .model.gpt import GPT_warpper10from .utils.gpu_utils import select_device11from .utils.io_utils import get_latest_modified_file12from .infer.api import refine_text, infer_code13 14from huggingface_hub import snapshot_download15 16logging.basicConfig(level = logging.INFO)17 18 19class Chat:20    def __init__(self, ):21        self.pretrain_models = {}22        self.logger = logging.getLogger(__name__)23        24    def check_model(self, level = logging.INFO, use_decoder = False):25        not_finish = False26        check_list = ['vocos', 'gpt', 'tokenizer']27        28        if use_decoder:29            check_list.append('decoder')30        else:31            check_list.append('dvae')32            33        for module in check_list:34            if module not in self.pretrain_models:35                self.logger.log(logging.WARNING, f'{module} not initialized.')36                not_finish = True37                38        if not not_finish:39            self.logger.log(level, f'All initialized.')40            41        return not not_finish42        43    def load_models(self, source='huggingface', force_redownload=False, local_path='<LOCAL_PATH>'):44        if source == 'huggingface':45            hf_home = os.getenv('HF_HOME', os.path.expanduser("~/.cache/huggingface"))46            try:47                download_path = get_latest_modified_file(os.path.join(hf_home, 'hub/models--2Noise--ChatTTS/snapshots'))48            except:49                download_path = None50            if download_path is None or force_redownload: 51                self.logger.log(logging.INFO, f'Download from HF: https://huggingface.co/2Noise/ChatTTS')52                download_path = snapshot_download(repo_id="2Noise/ChatTTS", allow_patterns=["*.pt", "*.yaml"])53            else:54                self.logger.log(logging.INFO, f'Load from cache: {download_path}')55            self._load(**{k: os.path.join(download_path, v) for k, v in OmegaConf.load(os.path.join(download_path, 'config', 'path.yaml')).items()})56        elif source == 'local':57            self.logger.log(logging.INFO, f'Load from local: {local_path}')58            self._load(**{k: os.path.join(local_path, v) for k, v in OmegaConf.load(os.path.join(local_path, 'config', 'path.yaml')).items()})59        60    def _load(61        self, 62        vocos_config_path: str = None, 63        vocos_ckpt_path: str = None,64        dvae_config_path: str = None,65        dvae_ckpt_path: str = None,66        gpt_config_path: str = None,67        gpt_ckpt_path: str = None,68        decoder_config_path: str = None,69        decoder_ckpt_path: str = None,70        tokenizer_path: str = None,71        device: str = None72    ):73        if not device:74            device = select_device(4096)75            self.logger.log(logging.INFO, f'use {device}')76            77        if vocos_config_path:78            vocos = Vocos.from_hparams(vocos_config_path).to(device).eval()79            assert vocos_ckpt_path, 'vocos_ckpt_path should not be None'80            vocos.load_state_dict(torch.load(vocos_ckpt_path))81            self.pretrain_models['vocos'] = vocos82            self.logger.log(logging.INFO, 'vocos loaded.')83        84        if dvae_config_path:85            cfg = OmegaConf.load(dvae_config_path)86            dvae = DVAE(**cfg).to(device).eval()87            assert dvae_ckpt_path, 'dvae_ckpt_path should not be None'88            dvae.load_state_dict(torch.load(dvae_ckpt_path, map_location='cpu'))89            self.pretrain_models['dvae'] = dvae90            self.logger.log(logging.INFO, 'dvae loaded.')91            92        if gpt_config_path:93            cfg = OmegaConf.load(gpt_config_path)94            gpt = GPT_warpper(**cfg).to(device).eval()95            assert gpt_ckpt_path, 'gpt_ckpt_path should not be None'96            gpt.load_state_dict(torch.load(gpt_ckpt_path, map_location='cpu'))97            self.pretrain_models['gpt'] = gpt98            self.logger.log(logging.INFO, 'gpt loaded.')99            100        if decoder_config_path:101            cfg = OmegaConf.load(decoder_config_path)102            decoder = DVAE(**cfg).to(device).eval()103            assert decoder_ckpt_path, 'decoder_ckpt_path should not be None'104            decoder.load_state_dict(torch.load(decoder_ckpt_path, map_location='cpu'))105            self.pretrain_models['decoder'] = decoder106            self.logger.log(logging.INFO, 'decoder loaded.')107        108        if tokenizer_path:109            tokenizer = torch.load(tokenizer_path, map_location='cpu')110            tokenizer.padding_side = 'left'111            self.pretrain_models['tokenizer'] = tokenizer112            self.logger.log(logging.INFO, 'tokenizer loaded.')113            114        self.check_model()115    116    def infer(117        self, 118        text, 119        skip_refine_text=False, 120        refine_text_only=False, 121        params_refine_text={}, 122        params_infer_code={}, 123        use_decoder=False124    ):125        126        assert self.check_model(use_decoder=use_decoder)127        128        if not skip_refine_text:129            text_tokens = refine_text(self.pretrain_models, text, **params_refine_text)['ids']130            text_tokens = [i[i < self.pretrain_models['tokenizer'].convert_tokens_to_ids('[break_0]')] for i in text_tokens]131            text = self.pretrain_models['tokenizer'].batch_decode(text_tokens)132            if refine_text_only:133                return text134            135        text = [params_infer_code.get('prompt', '') + i for i in text]136        params_infer_code.pop('prompt', '')137        result = infer_code(self.pretrain_models, text, **params_infer_code, return_hidden=use_decoder)138        139        if use_decoder:140            mel_spec = [self.pretrain_models['decoder'](i[None].permute(0,2,1)) for i in result['hiddens']]141        else:142            mel_spec = [self.pretrain_models['dvae'](i[None].permute(0,2,1)) for i in result['ids']]143            144        wav = [self.pretrain_models['vocos'].decode(i).cpu().numpy() for i in mel_spec]145        146        return wav147        148        149 150