{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xYJFXKP9xhQM"
   },
   "source": [
    "## Clone Repo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "hegwDOfffwzw"
   },
   "outputs": [],
   "source": [
    "!cd /content\n",
    "!rm -rf sample_data ChatTTS\n",
    "!git clone https://github.com/2noise/ChatTTS.git"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Install Requirements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -r /content/ChatTTS/requirements.txt\n",
    "!ldconfig /usr/lib64-nvidia"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zdzEFoknxqTH"
   },
   "source": [
    "## Import Packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "lDSQ6Xf-bSre"
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "\n",
    "torch._dynamo.config.cache_size_limit = 64\n",
    "torch._dynamo.config.suppress_errors = True\n",
    "torch.set_float32_matmul_precision(\"high\")\n",
    "\n",
    "from ChatTTS import ChatTTS\n",
    "from ChatTTS.tools.logger import get_logger\n",
    "from ChatTTS.tools.normalizer import normalizer_en_nemo_text, normalizer_zh_tn\n",
    "from IPython.display import Audio"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vBzG5gxcbSrf"
   },
   "source": [
    "## Load Models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "e0QSkngRbSrg"
   },
   "outputs": [],
   "source": [
    "logger = get_logger(\"ChatTTS\", format_root=True)\n",
    "chat = ChatTTS.Chat(logger)\n",
    "\n",
    "# try to load normalizer\n",
    "try:\n",
    "    chat.normalizer.register(\"en\", normalizer_en_nemo_text())\n",
    "except ValueError as e:\n",
    "    logger.error(e)\n",
    "except:\n",
    "    logger.warning(\"Package nemo_text_processing not found!\")\n",
    "    logger.warning(\n",
    "        \"Run: conda install -c conda-forge pynini=2.1.5 && pip install nemo_text_processing\",\n",
    "    )\n",
    "try:\n",
    "    chat.normalizer.register(\"zh\", normalizer_zh_tn())\n",
    "except ValueError as e:\n",
    "    logger.error(e)\n",
    "except:\n",
    "    logger.warning(\"Package WeTextProcessing not found!\")\n",
    "    logger.warning(\n",
    "        \"Run: conda install -c conda-forge pynini=2.1.5 && pip install WeTextProcessing\",\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3Ty427FZNH30"
   },
   "source": [
    "### Here are three choices for loading models,"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NInF7Lk1NH30"
   },
   "source": [
    "#### 1. Load models from Hugging Face (recommend)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "VVtNlNosNH30"
   },
   "outputs": [],
   "source": [
    "# use force_redownload=True if the weights have been updated.\n",
    "chat.load(source=\"huggingface\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "AhBD5WUPNH30"
   },
   "source": [
    "#### 2. Load models from local directories 'asset' and 'config'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "83UwV6SGNH31"
   },
   "outputs": [],
   "source": [
    "chat.load()\n",
    "# chat.load(source='local') same as above"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "c0qjGPNkNH31"
   },
   "source": [
    "#### 3. Load models from a custom path"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "oCSBx0Q7NH31"
   },
   "outputs": [],
   "source": [
    "# write the model path into custom_path\n",
    "chat.load(source=\"custom\", custom_path=\"YOUR CUSTOM PATH\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "VoEki3XMNH31"
   },
   "source": [
    "### You can also unload models to save the memory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3FdsTSxoNH31"
   },
   "outputs": [],
   "source": [
    "chat.unload()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "bAUs0rGQbSrh"
   },
   "source": [
    "## Inference"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NPZ2SFksbSrh"
   },
   "source": [
    "### Batch infer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Su9FmUYAbSrh"
   },
   "outputs": [],
   "source": [
    "texts = [\n",
    "    \"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",
    "] * 3 + [\n",
    "    \"我觉得像我们这些写程序的人，他，我觉得多多少少可能会对开源有一种情怀在吧我觉得开源是一个很好的形式。现在其实最先进的技术掌握在一些公司的手里的话，就他们并不会轻易的开放给所有的人用。\"\n",
    "] * 3\n",
    "\n",
    "wavs = chat.infer(texts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "YQRwB8lpbSri"
   },
   "outputs": [],
   "source": [
    "Audio(wavs[0], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "LuFG6m7AbSri"
   },
   "outputs": [],
   "source": [
    "Audio(wavs[3], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oLhAGvkfbSrj"
   },
   "source": [
    "### Custom params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "kma0HBEBbSrj"
   },
   "outputs": [],
   "source": [
    "params_infer_code = ChatTTS.Chat.InferCodeParams(\n",
    "    prompt=\"[speed_5]\",\n",
    "    temperature=0.3,\n",
    ")\n",
    "params_refine_text = ChatTTS.Chat.RefineTextParams(\n",
    "    prompt=\"[oral_2][laugh_0][break_6]\",\n",
    ")\n",
    "\n",
    "wav = chat.infer(\n",
    "    \"四川美食可多了，有麻辣火锅、宫保鸡丁、麻婆豆腐、担担面、回锅肉、夫妻肺片等，每样都让人垂涎三尺。\",\n",
    "    params_refine_text=params_refine_text,\n",
    "    params_infer_code=params_infer_code,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Nl_mT9KpbSrj"
   },
   "outputs": [],
   "source": [
    "Audio(wav[0], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "JfAba-tTbSrk"
   },
   "source": [
    "### fix random speaker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Qh7dcWrAbSrk"
   },
   "outputs": [],
   "source": [
    "rand_spk = chat.sample_random_speaker()\n",
    "print(rand_spk)  # save it for later timbre recovery\n",
    "\n",
    "params_infer_code = ChatTTS.Chat.InferCodeParams(\n",
    "    spk_emb=rand_spk,\n",
    ")\n",
    "\n",
    "wav = chat.infer(\n",
    "    \"四川美食确实以辣闻名，但也有不辣的选择。比如甜水面、赖汤圆、蛋烘糕、叶儿粑等，这些小吃口味温和，甜而不腻，也很受欢迎。\",\n",
    "    params_infer_code=params_infer_code,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "0ljWDWzabSrk"
   },
   "outputs": [],
   "source": [
    "Audio(wav[0], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zero shot (simulate speaker)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ChatTTS.tools.audio import load_audio\n",
    "\n",
    "spk_smp = chat.sample_audio_speaker(load_audio(\"sample.mp3\", 24000))\n",
    "print(spk_smp)  # save it in order to load the speaker without sample audio next time\n",
    "\n",
    "params_infer_code = ChatTTS.Chat.InferCodeParams(\n",
    "    spk_smp=spk_smp,\n",
    "    txt_smp=\"与sample.mp3内容完全一致的文本转写。\",\n",
    ")\n",
    "\n",
    "wav = chat.infer(\n",
    "    \"四川美食确实以辣闻名，但也有不辣的选择。比如甜水面、赖汤圆、蛋烘糕、叶儿粑等，这些小吃口味温和，甜而不腻，也很受欢迎。\",\n",
    "    params_infer_code=params_infer_code,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Audio(wav[0], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "u1q-BcUKbSrl"
   },
   "source": [
    "### Two stage control"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3hAAc0lJbSrl"
   },
   "outputs": [],
   "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",
    "refined_text = chat.infer(text, refine_text_only=True)\n",
    "refined_text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "0GVJxhd3BKQX"
   },
   "outputs": [],
   "source": [
    "wav = chat.infer(refined_text, skip_refine_text=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ngyMht74BicY"
   },
   "outputs": [],
   "source": [
    "Audio(wav[0], rate=24_000, autoplay=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GG5AMbQbbSrl"
   },
   "source": [
    "## LLM Call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3rkfwc3UbSrl"
   },
   "outputs": [],
   "source": [
    "from ChatTTS.tools.llm import ChatOpenAI\n",
    "\n",
    "API_KEY = \"\"\n",
    "client = ChatOpenAI(\n",
    "    api_key=API_KEY, base_url=\"https://api.deepseek.com\", model=\"deepseek-chat\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "TTkIsXozbSrm"
   },
   "outputs": [],
   "source": [
    "user_question = \"四川有哪些好吃的美食呢?\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3yT8uNz-RVy1"
   },
   "outputs": [],
   "source": [
    "text = client.call(user_question, prompt_version=\"deepseek\")\n",
    "text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "6qddpv7lRW-3"
   },
   "outputs": [],
   "source": [
    "text = client.call(text, prompt_version=\"deepseek_TN\")\n",
    "text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "qNhCJG4VbSrm"
   },
   "outputs": [],
   "source": [
    "wav = chat.infer(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Wq1XQHmFRQI3"
   },
   "outputs": [],
   "source": [
    "Audio(wav[0], rate=24_000, autoplay=True)"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [
    "bAUs0rGQbSrh"
   ],
   "gpuType": "T4",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "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": 0
}
