diff --git a/modules/ChatTTS/example.ipynb b/modules/ChatTTS/example.ipynb
deleted file mode 100644
index b229e702a2cbab53cf03fe2712bc27a4ebad25e3..0000000000000000000000000000000000000000
--- a/modules/ChatTTS/example.ipynb
+++ /dev/null
@@ -1,407 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import torch\n",
- "torch._dynamo.config.cache_size_limit = 64\n",
- "torch._dynamo.config.suppress_errors = True\n",
- "torch.set_float32_matmul_precision('high')\n",
- "\n",
- "import ChatTTS\n",
- "from IPython.display import Audio"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Load Models"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "chat = ChatTTS.Chat()\n",
- "chat.load_models()\n",
- "\n",
- "# Use force_redownload=True if the weights updated.\n",
- "# chat.load_models(force_redownload=True)\n",
- "\n",
- "# If you download the weights manually, set source='locals'.\n",
- "# chat.load_models(source='local', local_path='YOUR LOCAL PATH')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Inference"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Batch infer"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:ChatTTS.core:All initialized.\n",
- " 28%|██▊ | 106/384 [00:00<00:01, 140.38it/s]\n",
- " 47%|████▋ | 960/2048 [00:07<00:08, 133.25it/s]\n"
- ]
- }
- ],
- "source": [
- "texts = [\"So we found being competitive and collaborative was a huge way of staying motivated towards our goals, so one person to call when you fall off, one person who gets you back on then one person to actually do the activity with.\",]*3 \\\n",
- " + [\"我觉得像我们这些写程序的人,他,我觉得多多少少可能会对开源有一种情怀在吧我觉得开源是一个很好的形式。现在其实最先进的技术掌握在一些公司的手里的话,就他们并不会轻易的开放给所有的人用。\"]*3 \n",
- " \n",
- "wavs = chat.infer(texts)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Audio(wavs[0], rate=24_000, autoplay=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Audio(wavs[3], rate=24_000, autoplay=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Custom params"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:ChatTTS.core:All initialized.\n",
- " 14%|█▍ | 53/384 [00:00<00:02, 146.65it/s]\n",
- " 22%|██▏ | 452/2048 [00:03<00:11, 140.51it/s]\n"
- ]
- }
- ],
- "source": [
- "params_infer_code = {'prompt':'[speed_5]', 'temperature':.3}\n",
- "params_refine_text = {'prompt':'[oral_2][laugh_0][break_6]'}\n",
- "\n",
- "wav = chat.infer('四川美食可多了,有麻辣火锅、宫保鸡丁、麻婆豆腐、担担面、回锅肉、夫妻肺片等,每样都让人垂涎三尺。', \\\n",
- " params_refine_text=params_refine_text, params_infer_code=params_infer_code)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Audio(wav[0], rate=24_000, autoplay=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### fix random speaker"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [],
- "source": [
- "rand_spk = chat.sample_random_speaker()\n",
- "params_infer_code = {'spk_emb' : rand_spk, }\n",
- "\n",
- "wav = chat.infer('四川美食确实以辣闻名,但也有不辣的选择。比如甜水面、赖汤圆、蛋烘糕、叶儿粑等,这些小吃口味温和,甜而不腻,也很受欢迎。', \\\n",
- " params_refine_text=params_refine_text, params_infer_code=params_infer_code)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Audio(wav[0], rate=24_000, autoplay=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Two stage control"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:ChatTTS.core:All initialized.\n",
- " 23%|██▎ | 87/384 [00:00<00:01, 150.60it/s]\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['so we found being competitive and collaborative [uv_break] was a huge way of staying [uv_break] motivated towards our goals, [uv_break] so [uv_break] one person to call [uv_break] when you fall off, [uv_break] one person who [uv_break] gets you back [uv_break] on then [uv_break] one person [uv_break] to actually do the activity with.']"
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "text = \"So we found being competitive and collaborative was a huge way of staying motivated towards our goals, so one person to call when you fall off, one person who gets you back on then one person to actually do the activity with.\"\n",
- "chat.infer(text, refine_text_only=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:ChatTTS.core:All initialized.\n",
- " 49%|████▊ | 995/2048 [00:07<00:07, 141.85it/s]\n"
- ]
- }
- ],
- "source": [
- "text = 'so we found being competitive and collaborative [uv_break] was a huge way of staying [uv_break] motivated towards our goals, [uv_break] so [uv_break] one person to call [uv_break] when you fall off, [uv_break] one person who [uv_break] gets you back [uv_break] on then [uv_break] one person [uv_break] to actually do the activity with.'\n",
- "wav = chat.infer(text, skip_refine_text=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## LLM Call"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [],
- "source": [
- "from ChatTTS.experimental.llm import llm_api\n",
- "\n",
- "API_KEY = ''\n",
- "client = llm_api(api_key=API_KEY,\n",
- " base_url=\"https://api.deepseek.com\",\n",
- " model=\"deepseek-chat\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:httpx:HTTP Request: POST https://api.deepseek.com/chat/completions \"HTTP/1.1 200 OK\"\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "四川美食可多了, 有麻辣火锅、宫保鸡丁、麻婆豆腐、担担面、回锅肉、夫妻肺片、串串香、龙抄手、宜宾燃面、乐山钵钵鸡等, 每样都让人垂涎三尺。\n"
- ]
- },
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:httpx:HTTP Request: POST https://api.deepseek.com/chat/completions \"HTTP/1.1 200 OK\"\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "四川美食可多了,有麻辣火锅、宫保鸡丁、麻婆豆腐、担担面、回锅肉、夫妻肺片、串串香、龙抄手、宜宾燃面、乐山钵钵鸡等,每样都让人垂涎三尺。\n"
- ]
- }
- ],
- "source": [
- "user_question = '四川有哪些好吃的美食呢?'\n",
- "text = client.call(user_question, prompt_version = 'deepseek')\n",
- "print(text)\n",
- "text = client.call(text, prompt_version = 'deepseek_TN')\n",
- "print(text)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "INFO:ChatTTS.core:All initialized.\n",
- " 20%|█▉ | 75/384 [00:00<00:02, 144.93it/s]\n",
- " 32%|███▏ | 647/2048 [00:04<00:09, 140.27it/s]\n"
- ]
- }
- ],
- "source": [
- "params_infer_code = {'spk_emb' : rand_spk, 'temperature':.3}\n",
- "\n",
- "wav = chat.infer(text, params_infer_code=params_infer_code)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.8"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/modules/api/impl/base_api.py b/modules/api/impl/base_api.py
deleted file mode 100644
index d7ba73ba3ad0914cceca42d53c5aed8a325dc716..0000000000000000000000000000000000000000
--- a/modules/api/impl/base_api.py
+++ /dev/null
@@ -1,48 +0,0 @@
-from pydantic import BaseModel
-
-
-from modules.speaker import speaker_mgr
-
-
-from modules.data import styles_mgr
-
-
-from modules.api import utils as api_utils
-from modules.api.Api import APIManager
-
-
-async def list_styles():
- return {"message": "ok", "data": styles_mgr.list_items()}
-
-
-async def list_speakers():
- return {
- "message": "ok",
- "data": [spk.to_json() for spk in speaker_mgr.list_speakers()],
- }
-
-
-class CreateSpeaker(BaseModel):
- seed: int
- name: str = ""
-
-
-async def create_speaker(request: CreateSpeaker):
- speaker = speaker_mgr.create_speaker(request.seed, request.name)
- return {"message": "ok", "data": speaker.to_json()}
-
-
-async def refresh_speakers():
- speaker_mgr.refresh_speakers()
- return {"message": "ok"}
-
-
-def setup(app: APIManager):
- app.get("/v1/styles/list", response_model=api_utils.BaseResponse)(list_styles)
- app.get("/v1/speakers/list", response_model=api_utils.BaseResponse)(list_speakers)
- app.post("/v1/speaker/create", response_model=api_utils.BaseResponse)(
- create_speaker
- )
- app.post("/v1/speaker/refresh", response_model=api_utils.BaseResponse)(
- refresh_speakers
- )
diff --git a/modules/devices.py b/modules/devices.py
deleted file mode 100644
index ad35a256f7568389a08830e4b2c90831a1176df9..0000000000000000000000000000000000000000
--- a/modules/devices.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import torch
-
-
-def torch_gc():
- if torch.cuda.is_available():
- with torch.cuda.device("cuda"):
- torch.cuda.empty_cache()
- torch.cuda.ipc_collect()
diff --git a/modules/normalization.py b/modules/normalization.py
index 6eedff23e16d62c570814f8b598b77807c517046..5cdf6688eed4395c23b41a8261b89b9de0c6a068 100644
--- a/modules/normalization.py
+++ b/modules/normalization.py
@@ -143,6 +143,8 @@ def replace_unk_tokens(text):
把不在字典里的字符替换为 " , "
"""
chat_tts = models.load_chat_tts()
+ if "tokenizer" not in chat_tts.pretrain_models:
+ return text
tokenizer = chat_tts.pretrain_models["tokenizer"]
vocab = tokenizer.get_vocab()
vocab_set = set(vocab.keys())
diff --git a/modules/utils/normalization.py b/modules/utils/normalization.py
deleted file mode 100644
index 241486b9e131b8226130431a690406a35c3be308..0000000000000000000000000000000000000000
--- a/modules/utils/normalization.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from modules.utils.zh_normalization.text_normlization import *
-
-character_map = {
- ":": ",",
- ";": ",",
- "!": "。",
- "(": ",",
- ")": ",",
- "【": ",",
- "】": ",",
- "『": ",",
- "』": ",",
- "「": ",",
- "」": ",",
- "《": ",",
- "》": ",",
- "-": ",",
- "‘": " ",
- "“": " ",
- "’": " ",
- "”": " ",
- ":": ",",
- ";": ",",
- "!": ".",
- "(": ",",
- ")": ",",
- # '[': ',',
- # ']': ',',
- ">": ",",
- "<": ",",
- "-": ",",
-}
-
-character_to_word = {
- " & ": " and ",
-}
-
-
-def apply_character_to_word(text):
- for k, v in character_to_word.items():
- text = text.replace(k, v)
- return text
-
-
-def apply_character_map(text):
- translation_table = str.maketrans(character_map)
- return text.translate(translation_table)
-
-
-def insert_spaces_between_uppercase(s):
- # 使用正则表达式在每个相邻的大写字母之间插入空格
- return re.sub(
- r"(?<=[A-Z])(?=[A-Z])|(?<=[a-z])(?=[A-Z])|(?<=[\u4e00-\u9fa5])(?=[A-Z])|(?<=[A-Z])(?=[\u4e00-\u9fa5])",
- " ",
- s,
- )
-
-
-def ensure_suffix(a: str, b: str, c: str):
- a = a.strip()
- if not a.endswith(b):
- a += c
- return a
-
-
-email_domain_map = {
- "outlook.com": "Out look",
- "hotmail.com": "Hot mail",
- "yahoo.com": "雅虎",
-}
-
-
-# 找到所有 email 并将 name 分割为单个字母,@替换为 at ,. 替换为 dot,常见域名替换为单词
-#
-# 例如:
-# zhzluke96@outlook.com => z h z l u k e 9 6 at out look dot com
-def email_detect(text):
- email_pattern = re.compile(r"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})")
-
- def replace(match):
- email = match.group(1)
- name, domain = email.split("@")
- name = " ".join(name)
- if domain in email_domain_map:
- domain = email_domain_map[domain]
- domain = domain.replace(".", " dot ")
- return f"{name} at {domain}"
-
- return email_pattern.sub(replace, text)
-
-
-def pre_normalize(text):
- # NOTE: 效果一般...
- # text = email_detect(text)
- return text
-
-
-def post_normalize(text):
- text = insert_spaces_between_uppercase(text)
- text = apply_character_map(text)
- text = apply_character_to_word(text)
- return text
-
-
-def text_normalize(text, is_end=False):
- # https://github.com/PaddlePaddle/PaddleSpeech/tree/develop/paddlespeech/t2s/frontend/zh_normalization
- tx = TextNormalizer()
-
- # 匹配 \[.+?\] 的部分
- pattern = re.compile(r"(\[.+?\])|([^[]+)")
-
- def normalize_part(part):
- part = pre_normalize(part)
- sentences = tx.normalize(part)
- dest_text = ""
- for sentence in sentences:
- dest_text += post_normalize(sentence)
- return dest_text
-
- def replace(match):
- if match.group(1):
- return f" {match.group(1)} "
- else:
- return normalize_part(match.group(2))
-
- result = pattern.sub(replace, text)
-
- # NOTE: 加了会有杂音...
- # if is_end:
- # 加这个是为了防止吞字
- # result = ensure_suffix(result, "[uv_break]", "。。。[uv_break]。。。")
-
- return result
-
-
-if __name__ == "__main__":
- print(
- text_normalize(
- "ChatTTS是专门为对话场景设计的文本转语音模型,例如LLM助手对话任务。它支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练。在HuggingFace中开源的版本为4万小时训练且未SFT的版本."
- )
- )
- print(
- text_normalize(
- " [oral_9] [laugh_0] [break_0] 电 [speed_0] 影 [speed_0] 中 梁朝伟 [speed_9] 扮演的陈永仁的编号27149"
- )
- )
- print(text_normalize(" 明天有62%的概率降雨"))