本地搭建ChatTTS WebUi

打印 上一主题 下一主题

主题 525|帖子 525|积分 1575

声明

声明:本教程基于modelscope.cn的演示站举行本地搭建,情况为Windows
作者GitHub地点:https://github.com/2noise/ChatTTS
Webui体验地点:https://modelscope.cn/studios/AI-ModelScope/ChatTTS-demo/summary
第一步 克隆代码

先在终端输入以下内容,克隆modelscope的文件到本地
  1. git clone https://www.modelscope.cn/studios/AI-ModelScope/ChatTTS-demo.git
复制代码
克隆好之后进入文件目录

到了目录之后直接实行安装txt中的内容太慢了,换成国内源很快就能下好
  1. pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
复制代码
第二步 安装库

下好之后也不能立马实行,必要在手动安装一些库

依此实行以下命令
  1. pip install modelscope -i https://pypi.tuna.tsinghua.edu.cn/simple
  2. pip install gradio -i https://pypi.tuna.tsinghua.edu.cn/simple
复制代码
上面安装没有题目,实行以下代码
  1. python app.py
复制代码
启动期待步伐下载完成(白条可能会卡住不动,因为他是一次显示很多的,看一下网络宽带有占用就行了,不要暂停步伐!)

错误解决

我就碰到一个错误,说什么Windows不支持,然后我根据错误修改了一些代码我就能运行了,由于我第一次搭建是拿物理电脑搭建的,解决运行之后想着写一篇文章,然后用虚拟机继续搭建,碰到的错误又不一样了,烦死了,于是我直接把我物理机的core.py中的内容复制到虚拟机中的core.py就能运行了,直接复制以下代码覆盖克隆下来的core.py
core.py在ChatTTS目录下面
  1. import os
  2. import logging
  3. from omegaconf import OmegaConf
  4. import platform
  5. import torch
  6. from vocos import Vocos
  7. from .model.dvae import DVAE
  8. from .model.gpt import GPT_warpper
  9. from .utils.gpu_utils import select_device
  10. from .utils.infer_utils import count_invalid_characters, detect_language
  11. from .utils.io_utils import get_latest_modified_file
  12. from .infer.api import refine_text, infer_code
  13. from huggingface_hub import snapshot_download
  14. logging.basicConfig(level = logging.INFO)
  15. class Chat:
  16.     def __init__(self, ):
  17.         self.pretrain_models = {}
  18.         self.normalizer = {}
  19.         self.logger = logging.getLogger(__name__)
  20.         
  21.     def check_model(self, level = logging.INFO, use_decoder = False):
  22.         not_finish = False
  23.         check_list = ['vocos', 'gpt', 'tokenizer']
  24.         
  25.         if use_decoder:
  26.             check_list.append('decoder')
  27.         else:
  28.             check_list.append('dvae')
  29.             
  30.         for module in check_list:
  31.             if module not in self.pretrain_models:
  32.                 self.logger.log(logging.WARNING, f'{module} not initialized.')
  33.                 not_finish = True
  34.                
  35.         if not not_finish:
  36.             self.logger.log(level, f'All initialized.')
  37.             
  38.         return not not_finish
  39.         
  40.     def load_models(self, source='huggingface', force_redownload=False, local_path='<LOCAL_PATH>', **kwargs):
  41.         if source == 'huggingface':
  42.             hf_home = os.getenv('HF_HOME', os.path.expanduser("~/.cache/huggingface"))
  43.             try:
  44.                 download_path = get_latest_modified_file(os.path.join(hf_home, 'hub/models--2Noise--ChatTTS/snapshots'))
  45.             except:
  46.                 download_path = None
  47.             if download_path is None or force_redownload:
  48.                 self.logger.log(logging.INFO, f'Download from HF: https://huggingface.co/2Noise/ChatTTS')
  49.                 download_path = snapshot_download(repo_id="2Noise/ChatTTS", allow_patterns=["*.pt", "*.yaml"])
  50.             else:
  51.                 self.logger.log(logging.INFO, f'Load from cache: {download_path}')
  52.         elif source == 'local':
  53.             self.logger.log(logging.INFO, f'Load from local: {local_path}')
  54.             download_path = local_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()}, **kwargs)
  56.         
  57.     def _load(
  58.         self,
  59.         vocos_config_path: str = None,
  60.         vocos_ckpt_path: str = None,
  61.         dvae_config_path: str = None,
  62.         dvae_ckpt_path: str = None,
  63.         gpt_config_path: str = None,
  64.         gpt_ckpt_path: str = None,
  65.         decoder_config_path: str = None,
  66.         decoder_ckpt_path: str = None,
  67.         tokenizer_path: str = None,
  68.         device: str = None,
  69.         compile: bool = True,
  70.     ):
  71.         if not device:
  72.             device = select_device(4096)
  73.             self.logger.log(logging.INFO, f'use {device}')
  74.             
  75.         if vocos_config_path:
  76.             vocos = Vocos.from_hparams(vocos_config_path).to(device).eval()
  77.             assert vocos_ckpt_path, 'vocos_ckpt_path should not be None'
  78.             vocos.load_state_dict(torch.load(vocos_ckpt_path))
  79.             self.pretrain_models['vocos'] = vocos
  80.             self.logger.log(logging.INFO, 'vocos loaded.')
  81.         
  82.         if dvae_config_path:
  83.             cfg = OmegaConf.load(dvae_config_path)
  84.             dvae = DVAE(**cfg).to(device).eval()
  85.             assert dvae_ckpt_path, 'dvae_ckpt_path should not be None'
  86.             dvae.load_state_dict(torch.load(dvae_ckpt_path, map_location='cpu'))
  87.             self.pretrain_models['dvae'] = dvae
  88.             self.logger.log(logging.INFO, 'dvae loaded.')
  89.             
  90.         if gpt_config_path:
  91.             cfg = OmegaConf.load(gpt_config_path)
  92.             gpt = GPT_warpper(**cfg).to(device).eval()
  93.             assert gpt_ckpt_path, 'gpt_ckpt_path should not be None'
  94.             gpt.load_state_dict(torch.load(gpt_ckpt_path, map_location='cpu'))
  95.             if platform.system() != 'Windows':
  96.                 gpt.gpt.forward = torch.compile(gpt.gpt.forward, backend='inductor', dynamic=True)
  97.             self.pretrain_models['gpt'] = gpt
  98.             spk_stat_path = os.path.join(os.path.dirname(gpt_ckpt_path), 'spk_stat.pt')
  99.             assert os.path.exists(spk_stat_path), f'Missing spk_stat.pt: {spk_stat_path}'
  100.             self.pretrain_models['spk_stat'] = torch.load(spk_stat_path).to(device)
  101.             self.logger.log(logging.INFO, 'gpt loaded.')
  102.             
  103.         if decoder_config_path:
  104.             cfg = OmegaConf.load(decoder_config_path)
  105.             decoder = DVAE(**cfg).to(device).eval()
  106.             assert decoder_ckpt_path, 'decoder_ckpt_path should not be None'
  107.             decoder.load_state_dict(torch.load(decoder_ckpt_path, map_location='cpu'))
  108.             self.pretrain_models['decoder'] = decoder
  109.             self.logger.log(logging.INFO, 'decoder loaded.')
  110.         
  111.         if tokenizer_path:
  112.             tokenizer = torch.load(tokenizer_path, map_location='cpu')
  113.             tokenizer.padding_side = 'left'
  114.             self.pretrain_models['tokenizer'] = tokenizer
  115.             self.logger.log(logging.INFO, 'tokenizer loaded.')
  116.             
  117.         self.check_model()
  118.    
  119.     def infer(
  120.         self,
  121.         text,
  122.         skip_refine_text=False,
  123.         refine_text_only=False,
  124.         params_refine_text={},
  125.         params_infer_code={'prompt':'[speed_5]'},
  126.         use_decoder=True,
  127.         do_text_normalization=False,
  128.         lang=None,
  129.     ):
  130.         
  131.         assert self.check_model(use_decoder=use_decoder)
  132.         
  133.         if not isinstance(text, list):
  134.             text = [text]
  135.         
  136.         if do_text_normalization:
  137.             for i, t in enumerate(text):
  138.                 _lang = detect_language(t) if lang is None else lang
  139.                 self.init_normalizer(_lang)
  140.                 text[i] = self.normalizer[_lang].normalize(t, verbose=False, punct_post_process=True)
  141.             
  142.         for i in text:
  143.             invalid_characters = count_invalid_characters(i)
  144.             if len(invalid_characters):
  145.                 self.logger.log(logging.WARNING, f'Invalid characters found! : {invalid_characters}')
  146.                
  147.         if not skip_refine_text:
  148.             text_tokens = refine_text(self.pretrain_models, text, **params_refine_text)['ids']
  149.             text_tokens = [i[i < self.pretrain_models['tokenizer'].convert_tokens_to_ids('[break_0]')] for i in text_tokens]
  150.             text = self.pretrain_models['tokenizer'].batch_decode(text_tokens)
  151.             if refine_text_only:
  152.                 return text
  153.             
  154.         text = [params_infer_code.get('prompt', '') + i for i in text]
  155.         params_infer_code.pop('prompt', '')
  156.         result = infer_code(self.pretrain_models, text, **params_infer_code, return_hidden=use_decoder)
  157.         
  158.         if use_decoder:
  159.             mel_spec = [self.pretrain_models['decoder'](i[None].permute(0,2,1)) for i in result['hiddens']]
  160.         else:
  161.             mel_spec = [self.pretrain_models['dvae'](i[None].permute(0,2,1)) for i in result['ids']]
  162.             
  163.         wav = [self.pretrain_models['vocos'].decode(i).cpu().numpy() for i in mel_spec]
  164.         
  165.         return wav
  166.    
  167.     def sample_random_speaker(self, ):
  168.         
  169.         dim = self.pretrain_models['gpt'].gpt.layers[0].mlp.gate_proj.in_features
  170.         std, mean = self.pretrain_models['spk_stat'].chunk(2)
  171.         return torch.randn(dim, device=std.device) * std + mean
  172.    
  173.     def init_normalizer(self, lang):
  174.         
  175.         if lang not in self.normalizer:
  176.             from nemo_text_processing.text_normalization.normalize import Normalizer
  177.             self.normalizer[lang] = Normalizer(input_case='cased', lang=lang)
复制代码
运行结果

实行app.py之后会得到一个地点,访问即可

访问就可以天生了


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

玛卡巴卡的卡巴卡玛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表