{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "oxl2bna8ztl2"
},
"source": [
"**2022/08/12 更新和汉化,排除tensorflow版本问题,使用 https://github.com/CjangCjengh/tacotron2-japanese 库中的cleaner省去罗马音环节**\n",
"**2022/08/12 Updates and use Chinese instead. Tensorflow version problem solved.**\n",
"**Use cleaners in repo https://github.com/CjangCjengh/tacotron2-japanese to auto-generate roman words.**\n",
"
\n",
"\n",
"**Updated 2022/03/14 and the unpickling error is solved. The training part works as of 2022/03/14**\n",
"\n",
"**2022/03/15 Speech synsthesis with HiFi-GAN works** \n",
"\n",
"**2022/03/16 Speech synsthesis with Waveglow should work again now (tested)** \n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"source": [
"**Tacotron 2 Training and Synthesis Notebook**\n",
"originally based on the following notebooks\n",
"https://github.com/NVIDIA/tacotron2,\n",
"https://bit.ly/3F4DkH2\n",
"and those presented in Adam is cool and stuff (https://youtu.be/LQAOCXdU8p8 and https://youtu.be/XLt_K_692Mc)\n",
"\n",
"
\n",
"\n",
"**Tacotron 2 训练和语音合成笔记本**\n",
"基于\n",
"https://github.com/NVIDIA/tacotron2,\n",
"https://bit.ly/3F4DkH2,\n",
"https://colab.research.google.com/drive/1VAuIqEAnrmCig3Edt5zFgQdckY9TDi3N\n",
"\n",
"还要感谢Adam is cool and stuff频道的视频 (https://youtu.be/LQAOCXdU8p8 and https://youtu.be/XLt_K_692Mc)\n",
"\n",
"感谢CjangCjengh的cleaner支持和视频灵感 (https://www.bilibili.com/video/BV1rV4y177Z7)"
],
"metadata": {
"id": "2CuJ5rIAIv1H"
}
},
{
"cell_type": "markdown",
"metadata": {
"id": "M5rkhiBCXbMY"
},
"source": [
"**使用LJ Speech数据集预先训练权重的WaveGlow模型可以从这个地址下载:https://catalog.ngc.nvidia.com/orgs/nvidia/models/waveglow_ljs_256channels**\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "r2D2Mt80bamF"
},
"source": [
"# 准备数据 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:13:05.594388Z",
"iopub.status.busy": "2022-08-12T04:13:05.593773Z",
"iopub.status.idle": "2022-08-12T04:13:11.760149Z",
"shell.execute_reply": "2022-08-12T04:13:11.758823Z",
"shell.execute_reply.started": "2022-08-12T04:13:05.594273Z"
},
"id": "67u1nnaJcyPt",
"trusted": true
},
"outputs": [],
"source": [
"#@title 下载 Tacotron 2\n",
"!git clone https://github.com/CjangCjengh/tacotron2-japanese tacotron2\n",
"!git submodule init\n",
"!git submodule update"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2022-08-12T04:13:20.371238Z",
"iopub.status.busy": "2022-08-12T04:13:20.370604Z",
"iopub.status.idle": "2022-08-12T04:18:18.664088Z",
"shell.execute_reply": "2022-08-12T04:18:18.662898Z",
"shell.execute_reply.started": "2022-08-12T04:13:20.371200Z"
},
"trusted": true,
"cellView": "form",
"id": "ujgAmihAIZg1"
},
"outputs": [],
"source": [
"#@title 安装依赖\n",
"!pip install -U tensorflow==1.15.2\n",
"!pip install -q unidecode tensorboardX\n",
"!pip install librosa==0.8.0\n",
"!pip install pysoundfile==0.9.0.post1\n",
"!pip install unidecode==1.3.4\n",
"!pip install pyopenjtalk==0.2.0\n",
"!pip install inflect==5.6.2\n",
"!pip install janome==0.4.2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"trusted": true,
"cellView": "form",
"id": "TAouEAY7IZg7"
},
"outputs": [],
"source": [
"#@title 加载Google云端硬盘\n",
"from google.colab import drive\n",
"drive.mount('drive')"
]
},
{
"cell_type": "code",
"source": [
"#@title 创建文件夹和下载预训练模型\n",
"import os\n",
"if os.getcwd() != '/content/tacotron2':\n",
" os.chdir('/content/tacotron2')\n",
"! gdown --id 1c5ZTuT7J08wLUoVZ2KkUs_VdZuJ86ZqA\n",
"if not os.path.isdir(\"wavs\"):\n",
" os.mkdir('wavs')\n",
"if not os.path.isdir(\"outdir\"):\n",
" os.mkdir(\"outdir\")"
],
"metadata": {
"cellView": "form",
"id": "-tH9g-WrJ0Ro"
},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pMt_D2p7c7Dl"
},
"source": [
"### 上传数据\n",
"\n",
"`text file` 是音频文件列表\n",
"\n",
"`audio files` 是音频文件"
]
},
{
"cell_type": "markdown",
"source": [
"![Tacotron2InstructionImages.jpg](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCALQBQADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKbJIkMbPIyoijJZjgCgB1FZ9h4h0rVJmistTs7yVesdvOjsPwBrQoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKyPFniKDwj4a1LWblS1vYwtO4Xrgdaq+BPHOlfETw1aa3o9ytxa3CBvlOSpxyDQB0NFFFABRRRQAUUUUAFFFFAHmH7Qnxij+C/gObVliE9/MTFaRt90vjvX5/ah+1T8VNQu5J4/Fl1Zq5LCGPG1c9hX0z/AMFFs/8ACvfDGDj/AImR/wDQRXwhQB6b/wANOfFf/odb78hSN+058VyP+R2vh+ArzOigD70/ZZ/a0HjHyvDXjC6VNZ6Q3khwJvY+9fWIYHkHIr8XYpZLeZJYZGhmQ5WRDhlPsa2P+E88VDgeJ9WA/wCvpqAP2KzRmvx1/wCE88V/9DRq3/gU1H/CeeK/+ho1b/wKagD9iqWvx/0v4o+MtFvI7u28S6k80TBlWW4ZlJHqK/SX9mb4vTfGL4cw6leKBqFq32e5ZejuB1oA9booooAKKKZNMlvG0krrHGoyzucAD1JoAfXH/F7P/CsfEuCVP2GTkHB6V5j8QP26vgx8M9dm0jW/F0KXsPDi3QyqPxHFMP7TXw4+OXwx8Ujwl4ktr6RbKQeTIfLdvlPRTyaAPhj/AIJXyTN+0N4mElzcTDZc/LLMzDqexNfrRX5Lf8Erv+Th/E/+5c/zNfpV8Yvjn4P+A3h+HWvGepHTNPlcxpKIy+WAzjAoA7+kZtqk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76za2yRX9rkBo5AMdPSvYdY17S/D+m3GoajeW9nZwIXkmlcBVUd6/Lnxr/wTL+K3wz8Qm6+FPiZru2di4D3P2bbz90gHmqVt+wb+0x8RL6DT/GfiX7BpDnbLLDqJfCnrlc80Afot8IP2jPAfxvvNUtvCWsRX9zp8hSWNRyVBxvHsTXp9eJ/sw/sq+Fv2YfCh07RU+1anOM3mpOoDzH+gr2ygAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAPmT9vbwff+JvhbYXdlC8yaXdG4mCDJC4AzX55CRccnafQ8Gv2jurWG+t5Le4iWaGRSrxuMhgexFeQah+yJ8LNUvJLm48NRmWRizFZGAyfagD8u/MT+8v50eYn95fzr9O/+GNPhN/0LKf9/W/xo/4Y0+E3/Qsp/wB/W/xoA/MTzE/vL+dHmJ/eX86/Tv8A4Y0+E3/Qsp/39b/Gj/hjT4Tf9Cyn/f1v8aAPzE8xP7y/nR5if3l/Ov07/wCGNPhN/wBCyn/f1v8AGj/hjT4Tf9Cyn/f1v8aAPzEMi44O4+i8mv0Y/YV8G6h4T+Es819C0I1K6N1EHGCUIxmuu0n9kn4XaLfRXdr4aiWaNgylnZhkexr163t47WFIYY1iiQbVRBgAegFAElFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAEVxcxWdvJPPIsMMY3NI5wFHqTXk2o/tYfC7S7yS2uPFFus0bFWAVjyPwrhf28vGV/4W+FtjaWM7wLql0baYocErgHGa/O/y17jcfVuTQB+oP8Aw2B8J/8AoaoP++G/woP7YXwnUZPiqD/vhv8ACvy+8pP7i/lR5Sf3F/KgD9kPCvi7SPG2jxapot7Hf2Uv3ZIzWxX5afs/ftBar8EtdUF3utAmP+kWhOce6+9fWA/4KBfDfAzDqoP/AF7/AP16APpuivmX/h4F8Nv+eOq/+A//ANej/h4F8Nv+eOq/+A//ANegD6aor5x0n9vD4b6tfw2u7ULbzGC+ZNBtQZ7k5r6E0vVLTWtPgvrGdLm0nUPHLGcqwPcUAWqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACq+oXYsLG4uSpcQxs5Ud8DNWKzvEX/IB1H/r3f/0E0AfLHwf/AOChGkfFz44XHw4t/CV/p9zDO8BvpZVMZK98Yr64r8df2Mf+T79Q/wCwhNX7FUAFFFFABRRRQAUUUUAFFFFABXzr+1p+2Lp37KdrpM9/4evNdGoSeWotZAuz65FfRVfmz/wWA/5BPhD/AK+B/OgD7u+C/wAT4PjH8OdJ8W21lJp0OoJvW3mYFk+pruK8J/Yh/wCTafB//XA/zr3agAooooAKKK+Uv26P2wNd/ZSsfDk+i+H7PXDqkrRuLqRk2Y7jBoA+raK88/Z/+JV38X/hD4b8X31nHp91qlv5z28LEqhyRgE/SvQ6ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDkfi5qd1ovwy8S39lJ5N3b2MkkUg7MBkGvIv2V/wBp6z+LGh22kaxKtt4kgjCsHOBOAOo969T+N/8AySLxd/2Dpv8A0GvyX8O6ve+H7qz1HTrh7W9tyHjkQ4ORQB+0FFfPP7Mf7Ttl8VtLi0fWJUtfEluoVlY4E+O496+hqACiiigAooooAKKKKAPkj/gov/yT3wv/ANhJv/QRXwhX3f8A8FF/+Se+F/8AsJN/6CK+EKACiiigAooooAKKKKAEZRIpUjINfoX+wL4gvNb+E19DdStIllemCEMc7Vx0FfnrX3x/wTt/5Jbrv/YTP8qAPq6iiigAryb9o79o7wz+zZ4Fk1/X5PNn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iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAorJ8VeKtM8F6Fdavq9ylpY2yF3kY/oK+YNS/4KIeF7O8kit/Deo3kSsQsySKAw9elAH1rRXyB/w8a8O/9Clqn/fxf8KD/wAFGvD3/Qpaof8Atov+FAH1/RXAfB/40aB8ZvD66jpEnlzL/rbSRh5kZ967+gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo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InGCFHGfxr7AoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK474peHfEHiTwrcQeGdcl0LVlBaKaMZ3H0NdjRQB+Yni748fG/wH4gudG1nxTeW15AxX5owAw9RWP/AMNT/Fr/AKHK6/74FfeX7Qv7PWlfGjw/IRGttrsC5t7pRgk/3TX5peMPCOq+AdeudH1q2a1vIGK/MMBx6j1oA7pv2qPiyoyfGd1j/cFfSf7Lp+MfxKvI/EHiTxZe2/h2M5SFkANx/wDWry79lv8AZbuviNfweIvEcD2+gQsGihcYM5H9K/QnTdOttJsYbOzhW3toVCJGgwABQBYpaKKACiiigAooooA+SP8Agov/AMk+8L/9hJv/AEEV8IV93/8ABRj/AJJ94X/7CTf+givhCgAooooAKKKKACiiigAr74/4J2/8kt13/sJn+VfA9ffH/BO3/kluu/8AYTP8qAPq6iiigAr5G/4Kb/8AJuN3/wBdv6V9c18jf8FOP+Tcbv8A67f0oA5X/gk6f+LGXg7eev8AKvs3xV4V0vxt4fvdE1q0W+0u8Ty57d87XX0OK+Mv+CTv/JDLz/ruv8q+iP2rfiVefCb4CeLfEmnHbqFrakQN6MeM/lmgDzLU/F37Of7FMuoPptrpmi6s/FxZ6b+8ufxBPFcTJ/wVy+CisymDXjjj/jxP+NfMn7AX7MGjftWa34k8dfES5uNXFndACF5TvkkcFgS3oPSv0v0v9m34ZaPZxW0PgvSWSMYDS2ys34k0Afj/AHHxG0P4nft3aB4u8IRTWWg6prls0EUieW/X5sr2ya/VL9uDxnd+A/2ZfGWqWExgvFtxHGynB+Y4P6Zr80fi3pOmaF/wUnsrDRre3tNNh160EUFqAI09QAPev0b/AOCgWgy+IP2VvGUNvG0txHCsqKvseaAPlb/gkH8OtO1ePxb47uYlk1S3uPscbsMld4LE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stBc2twhWSGQRJlWH4j2IIr6WqOO3iiklkSJEklIMjqoBcgYGT344qSqxVd4qtKs1Zy1FRp+xpqmugUUUVymwUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB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1/8A4J9/tWXWgat53/CL3c/lTIx4ltycI6++TX7E6HrVp4i0ez1OwmW4s7qJZYpEOQVIzQB+Q3/BTb/k9LQP+vaw/wDQ1r9eNB/5Aenf9e0f/oIr8iP+Cokcun/tfaJqU8TJZJaWb+cR8p2spYA/QV+kHwv/AGpvhn4+sdEsdH8T2txqFzBGqWozv3bQCMfWgD2aiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK8i+K3wBsPi18QvC+tas/mabo8b7rX/no5OR+Feu0UAQ2dnBp9rFbW0SwwRKFSNBgACpqKKACiiigAooooAKKKKACvya/aG/5Lt43/AOv9q/WWvzu/bA+BGvaB8Qb7xRp9lLf6VqjmWSSFSxSQ/wAOBQB81UVa/sfVP+gTqH/gM/8AhR/Y+qf9AnUP/AZ/8KAKtFWv7H1T/oE6h/4DP/hR/Y+qf9AnUP8AwGf/AAoAq0Va/sfVP+gTqH/gM/8AhR/Y+qf9AnUP/AZ/8KAKtWdJ/wCQ5pX/AF+Q/wDoYpf7H1T/AKBOof8AgM/+FepfAP4D+Ifib430/dp09npNrKs1xczxlNuCCOCOaAP1A0r/AJBdn/1xT/0EVaqO3hFvbxRDkRqF/IYqSgAooooA8M/aY/ZF8HftN6bAmtiTT9Vtxth1O2UGVF7rz1FeX/s6/wDBN3w1+zz8ULLxtY+LNU1e8tIpIkt7qNVTDDBPBr7DooAr6hp9tqlnNaXkEdzbTKUkikUMrA9QRXxx8V/+CWnwx+IWsPqGj3N14QeRi8kenqGVmPU8nivs+igD4N8I/wDBI34faDrVveat4m1XxFaxNuazu0UI/tnNfaHgf4f6D8N/DdvoPhrTYdJ023XbHDCuMe5Pc10VFAHxh4y/4JpaD8Rfi7J468T+N9Y1eR7nz/7PljXygoORGDnoMV9jabp8Gk6fbWVrGsVvbxrFGijACgYAqzRQB87ftWfsV+Fv2qY9Nk1PULjQtTsm/wCP+yQNJImOEOT0Fdx+zv8ABOX4B+AYPCg8TX3iWytTi2kv1AeJf7owTkV6jRQB4x+0l+yt4Q/aY0CGy8QRta31uc22o26jzYv8a8Y+BP8AwTN8L/A34hWXiu08W6rqtxanKW9zGoT9DX2dRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFMkhjmXbIiyL6MMin0UAVf7Ls/8An0g/79r/AIUf2XZ/8+kH/ftf8KtUUAVf7Ls/+fSD/v2v+FH9l2f/AD6Qf9+1/wAKtUUAVf7Ls/8An0g/79r/AIUf2XZ/8+kH/ftf8KtUUAVf7Ls/+fSD/v2v+FTQ28VuCIokjB67FAqSigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiuP8AiH8WfC/wtskufEWpJZLIcKg+Zz77fSgDsKK8F/4be+Ev/Qdm/wDAZqP+G3vhL/0HZv8AwGagD3qivGfDP7Xnwx8Wa3b6VYa632uc7UE0RRSfqa9lVg6hlIZSMgjoaAFooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiivjT44f8ABQs/B345Wvw8/wCEMk1LzmVfty3AUDcwHT8aAPsuiq+n3X26wtrnbs86JZNvpkA4/WrFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFJS18u/tVfG/V/gr8TPBF9ZsZdNmhkF3a9nXcefrQB9RUVy/w7+Imj/Ezw3baxo9ys0MigugPzRt3BFdRQAUUUUAFFFFABRRRQAV+WX7VPii98TfG/xFDeTPJFp05toUY8Ko9q/U2vya/aG/5Lt42/6/2oA892j0FG0egpaKABC0ciyRsY5FO5XXgg+tfWnwT/bmHgvwymk+MbS61RoBtguLYZYr6NmvkuigD75/4eIeCP8AoCav/wB8Cj/h4h4I/wCgJq//AHwK+BqKAPvn/h4h4I/6Aer/APfAr0X4R/tWeDfi9qh0yyabTtQYfure8wGk9lr8wa1fCOq3GheLtGvrORoblLuNVdTg4LAGgD9kaKraa5k0+1duWaJSfyFWaACiivGf2uvE3jHwb8CfEGteBbtbPxDZKssUjxCQbQfm4+lAHs1FfGP/AATi/ag8UfHzwtr9r441GG/8QWVyTG8UQjHldMYHvX1R8SvF0HgTwHruuzyrCLK0klRm6bwp2j88UAdNRX5hfsYft8fEL4j/AB+Tw9431O3utG1VmgsbeOEIY33HBz34xX6e0AFFfml43/bB+LPib9tCP4Z+DNbt7TRV1H7C8bWyueCMnd9K++/iN8TNG+DvgG48S+KbxYLOziXzZO7yY6Ae5FAHZUV+VnjD/goh8ZfjR4ie0+EPhuaw0+OQxrci3+0CTnhmP8NZOs/tdftW/BfVYL3xvp5v9LjIaVI7ELGw9C/agD9aaK8P/ZV/an0H9p7wa2p6fGLHVbbi808tkxHpn6V8n/toftRfGP8AZx/aE06G312BPA+oSJPFaNagsIh99d1AH6QUVheBvE0XjPwdo2uQEGLULWO4GD/eUGvMP2wPjZN8BvgjrHiOzkWHU2At7ORxkLK33Tjv0oA9sor4w/4Jw/Fz4r/G/wAM614n+IGsQ6lpbEQ2KxW4jw4PzHI61237Xn7bnh79mOxhsYYF1zxVdDdFpyPgIvTcx7H2oA+maK/I9f2sf2uPG3m6xoGmz2Oky5khhbTd2F7YOOa9F+AP/BTDxJofiy18I/GXR5LGeaQIdTki8lkJOOU9KAP0roqvp99Bqljb3ltIJbe4jWWN16MpGQfyr5A/bS/b80/9nq4Phfw5bx6x4smT5/nGy0z0Le/tQB9j0V+QWi/tZfteeIoX1WwtLmTTV/eBTpX31/2Tjmuk+IH/AAU+8e/8Kzh0iHSn8I/EO2lxcNdwZ8yMD72w9M0AfqzX45/ttf8AJ7+mf9dIv/QxX6D/ALCvxV8T/GT9n/SPEni28jv9Znd1kmjjCA4PHAr8+P22v+T39M/66Rf+higD9fdA/wCQDpv/AF7R/wDoIq/VDQP+QDpv/XtH/wCgivlX9r79v3Qf2dbseHdHtV8QeK5F+a3V/kgzwCT3Oe1AH1zRX5Gw/tUftfeKIX1bSbC4ttOk/eRxNpmTt6jHHNeh/A3/AIKdeIvDfia18K/GXRJbKaSUJJqTReU8eTgEx+maAP0vormte1S417wDfX/ha8je6ubJpbC6TDruK5U+9fBX7Fn7Y/xH8aftDax8PfiHq8GpESSQWyxwCMq6denWgD9GqKazLGpZiFUDJJ6Cvym8Xf8ABRj4h6f+07LpVnqduvgqDVBp72fkAk/PtLbqAP1boqvYXcd/YwXMTrJHMiurKcggjNfAn/BQf9rzx78J/iN4b8H/AA71WDTL+cqLrzYRKXL/AHOvSgD9A6K5D4RTa/cfDPw5L4omFx4gks0e9lVNoaQ8k47dq6+gAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr4W/wCCjX/Iy+Cv+uE38zX3TXwt/wAFGv8AkZfBX/XCX+ZoA8K+B/xw1j4K+JI7u0kabSpWAurMk7SvqB61+m3w7+I2jfEzw3baxo9ys0MqgtHn5o29CK/IOGGS6njggjaaeVtqRqMlie1foV+xt8CdZ+Gmiy6zrN1JFNqCbl0/Pyxg9yOxoA+mqKKKACiiigAooooAK/Jr9ob/AJLt42/6/wBq/WWvya/aG/5Lt43/AOv9qAPPqKKKACiiigAooooAKs6T/wAhzSv+vyH/ANDFVqs6T/yHNK/6/If/AEMUAfsnpX/ILs/+uKf+girVVdK/5Bdn/wBcU/8AQRVqgArI8XaLH4k8L6tpcsaypd2ssO1hkZZSB+prXooA/Ir9hHU5PgR+2X4i8FX0jKly72Ijc/xlywNfU3/BUr4onwb8A38PWzlNS16QRw7TyQvJAr5h/bY0FvgL+274X8cW2Vi1C4XUXkHCht20g1q/tieJJ/2j/wBrL4d+CtMYXdpaJa32IzuUq+C4/KgDw7xr8JdR/Zjh+EPxNtjJt1CKK7k7GOZmAI/I1+xtx4+tpfgv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ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACvjT9qj9kvWfFnieTxT4QiF3Pdc3NlnDF/7wPpX2XRQB+WP/DJ/wAW/wDoUZf+/q0f8Mn/ABb/AOhRl/7+rX6nUUAflj/wyf8AFv8A6FGX/v6tH/DJ/wAW/wDoUZf+/q1+p1FAH5Y/8Mn/ABb/AOhRl/7+rR/wyf8AFv8A6FGX/v6tfqdRQB+WP/DJ/wAW/wDoUZf+/q16p8A/2M/E83jC01Txnaf2Xp9k4k+ysQzSsOQARX31RQA2OMRRqijCqAB+FOoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK+E/2rP+CdMvxC8YXXxA+HettoPip3NzMhJzLJ/sH+E192UUAfka3w4/bZ0u2fTIIdYuoFyi3JvRuI9a7v9n//AIJr+LPFni618ZfGXVZLh0kEr6bO2+aRgc/M3pX6b0UAV9PsYNLsbeztoxFbwRrHGijhVAwBViiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK5zV/H2jaF4q0zw/fXS2+oajG0lurnAfacEfWgDo6KKKACiiigAooooAKKKKACvk79pz9ry9+Hevf8ACNeFI4n1KLm4upVDLGf7uK+sa/Jz9oiRn+O3jXcSdt8wGe1AHaf8NvfFj/oIaf8A+Aoo/wCG3vix/wBBDT//AAFFeEUUAfRnhb9ur4h2OvWk2uS2d9pQYCeGKAK23uQa+9Ph98QdH+JXhu21jRrlZ4JVBZQfmRvQ1+P9dL4S+JfizwDHLH4c1660mOX76wtwaAP2Bor8n/8AhpD4p/8AQ7ah+dH/AA0h8U/+h21D86AP1gor8n/+GkPin/0O2ofnXqnwC/a/8V6P4ys9O8WajJrOlXriJ5pj88ZJwCKAP0MopkMgmiSRfusoYfjT6ACiisPxl440H4e6HLrPiTVbfRtLiID3V021Fz0yaANyiuZ8B/Erwt8T9Ll1Hwprlnr1jFJ5Tz2b7lVvQ+9dFcTx2sEk0riOKNS7u3RVAySaAJKK4fwb8cPAXxB1660Xw34q03WdVtVLTWlrLudAOCSK7igAorz7xF+0B8OfCfiNdA1jxhpen6yxCiymlxISe2MV30MyXEKSxsHjdQysOhB5BoAfRXG+OPjF4J+GskaeKPE+naI8gyq3cwUkfSsHQv2nvhT4m1CKw0vx5ot7eSttSGO45Y+lAHqFFIrB1DKQynkEdDXnus/tC/Dfw94tPhfUvGWl2XiASLEdPml2y7z0GMdaAPQ6KarCRQykMrDII71T1vW7Dw3pN1qeqXUdjp9qhkmuJjhI1HUk0AXqK4n4ffGvwL8Vp7qHwh4o0/xBLaqGnWyk3+WD0J4rrNS1K00ezlu764jtbWJdzyysFVR6k0AWqK8kn/a1+DlrcPDL8RNDSVTtZTccg/lXoPhTxpoXjnTF1HQNVtdWsmOBNayBhQBtUUUUAFFFfLH7VH7VH/CItdeC/Bd0reIiPL1DVIyCunKRyiHoZiP++Op5wB2YXC1cZVVGirt/gYVq0MPBzm9D6mVg3Q57cUteY/s0bv8AhSHhjdJJKwScGSVy7t/pEnLMeSfU16dXPUh7OcodnY0hLmipdwooorMsKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAr4c/4KGX1zpfjLwJe2czW13DFK8cqHBBDGvuOvhb/AIKNf8jL4K/64S/zNAHp37LP7U1t8RbKHw74imW28QQqFSRzgTgf1r6br8YLG+udLvobyzma2uoWDxyocEEV+in7JP7Q118WtGfSNWt5P7W09MPdAfJIB3z60AfRdFFFABRRRQAUUUUAFfk1+0N/yXbxt/1/tX6y1+TX7Q3/ACXbxv8A9f7UAefUUUUAFFFFABRRRQAVa0n/AJDmldv9Mh/9DFVas6T/AMhzSv8Ar8h/9DFAH7J6X/yC7P8A64p/6CKtVV0r/kF2f/XFP/QRVqgAryX9qr4axfFj4D+K/D8sayeZatOqsM8o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fnpWx4L0W68SeMtF06xiaa6kuo2CIMnAYE195/8ADv34b/8APbVf/Aj/AOtXoXwp/Zl8FfCG/a+0i0knvcYS4u23tH/untQB6jp8Zi0+2RhhliVT+AFWKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDI8WeE9J8c+Hb7QtdsY9R0q9j8ua3lHBHUEEchgQCGGCCAQQRX5wfHn4Dat8C/ESxStLqPhm9kK6bqzDknk+RNjgSgA4PAcDIwQyr+m1ZHizwnpPjjw9faHrljFqOl3kflzW8o4I6gg9QwIBDDBBAIIIr2srzSpltS61g91/XU8/GYOGLhZ6SWzOI/Zp/5Ij4a/3bj/ANKJa9Orm/h14Jt/hz4M03w5a3U97bWKukc9zgysGdn+YjqfmxnvjNdJXl1pKdWUo7Ns7KacYRT6IKKKKxNAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z)"
],
"metadata": {
"id": "6tKrpYzpg8t0"
}
},
{
"cell_type": "markdown",
"metadata": {
"id": "IOETvfJdbfYO"
},
"source": [
"# 准备模型"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2022-08-12T04:22:26.512807Z",
"iopub.status.busy": "2022-08-12T04:22:26.512405Z",
"iopub.status.idle": "2022-08-12T04:22:48.851514Z",
"shell.execute_reply": "2022-08-12T04:22:48.850448Z",
"shell.execute_reply.started": "2022-08-12T04:22:26.512767Z"
},
"trusted": true,
"cellView": "form",
"id": "VKFIe_5pIZg9"
},
"outputs": [],
"source": [
"#@title 训练模型的代码\n",
"%matplotlib inline\n",
"\n",
"import time\n",
"import argparse\n",
"import math\n",
"from numpy import finfo\n",
"\n",
"import torch\n",
"from distributed import apply_gradient_allreduce\n",
"import torch.distributed as dist\n",
"from torch.utils.data.distributed import DistributedSampler\n",
"from torch.utils.data import DataLoader\n",
"\n",
"from model import Tacotron2\n",
"from data_utils import TextMelLoader, TextMelCollate\n",
"from loss_function import Tacotron2Loss\n",
"from logger import Tacotron2Logger\n",
"from hparams import create_hparams\n",
" \n",
"import random\n",
"import numpy as np\n",
"\n",
"import layers\n",
"from utils import load_wav_to_torch, load_filepaths_and_text\n",
"from text import text_to_sequence\n",
"from math import e\n",
"#from tqdm import tqdm # Terminal\n",
"#from tqdm import tqdm_notebook as tqdm # Legacy Notebook TQDM\n",
"from tqdm.notebook import tqdm # Modern Notebook TQDM\n",
"from distutils.dir_util import copy_tree\n",
"import matplotlib.pylab as plt\n",
"\n",
"def download_from_google_drive(file_id, file_name):\n",
" # download a file from the Google Drive link\n",
" !rm -f ./cookie\n",
" !curl -c ./cookie -s -L \"https://drive.google.com/uc?export=download&id={file_id}\" > /dev/null\n",
" confirm_text = !awk '/download/ {print $NF}' ./cookie\n",
" confirm_text = confirm_text[0]\n",
" !curl -Lb ./cookie \"https://drive.google.com/uc?export=download&confirm={confirm_text}&id={file_id}\" -o {file_name}\n",
"\n",
"def create_mels():\n",
" print(\"Generating Mels\")\n",
" stft = layers.TacotronSTFT(\n",
" hparams.filter_length, hparams.hop_length, hparams.win_length,\n",
" hparams.n_mel_channels, hparams.sampling_rate, hparams.mel_fmin,\n",
" hparams.mel_fmax)\n",
" def save_mel(filename):\n",
" audio, sampling_rate = load_wav_to_torch(filename)\n",
" if sampling_rate != stft.sampling_rate:\n",
" raise ValueError(\"{} {} SR doesn't match target {} SR\".format(filename, \n",
" sampling_rate, stft.sampling_rate))\n",
" audio_norm = audio / hparams.max_wav_value\n",
" audio_norm = audio_norm.unsqueeze(0)\n",
" audio_norm = torch.autograd.Variable(audio_norm, requires_grad=False)\n",
" melspec = stft.mel_spectrogram(audio_norm)\n",
" melspec = torch.squeeze(melspec, 0).cpu().numpy()\n",
" np.save(filename.replace('.wav', ''), melspec)\n",
"\n",
" import glob\n",
" wavs = glob.glob('wavs/*.wav')\n",
" for i in tqdm(wavs):\n",
" save_mel(i)\n",
"\n",
"\n",
"def reduce_tensor(tensor, n_gpus):\n",
" rt = tensor.clone()\n",
" dist.all_reduce(rt, op=dist.reduce_op.SUM)\n",
" rt /= n_gpus\n",
" return rt\n",
"\n",
"\n",
"def init_distributed(hparams, n_gpus, rank, group_name):\n",
" assert torch.cuda.is_available(), \"Distributed mode requires CUDA.\"\n",
" print(\"Initializing Distributed\")\n",
"\n",
" # Set cuda device so everything is done on the right GPU.\n",
" torch.cuda.set_device(rank % torch.cuda.device_count())\n",
"\n",
" # Initialize distributed communication\n",
" dist.init_process_group(\n",
" backend=hparams.dist_backend, init_method=hparams.dist_url,\n",
" world_size=n_gpus, rank=rank, group_name=group_name)\n",
"\n",
" print(\"Done initializing distributed\")\n",
"\n",
"\n",
"def prepare_dataloaders(hparams):\n",
" # Get data, data loaders and collate function ready\n",
" trainset = TextMelLoader(hparams.training_files, hparams)\n",
" valset = TextMelLoader(hparams.validation_files, hparams)\n",
" collate_fn = TextMelCollate(hparams.n_frames_per_step)\n",
"\n",
" if hparams.distributed_run:\n",
" train_sampler = DistributedSampler(trainset)\n",
" shuffle = False\n",
" else:\n",
" train_sampler = None\n",
" shuffle = True\n",
"\n",
" train_loader = DataLoader(trainset, num_workers=1, shuffle=shuffle,\n",
" sampler=train_sampler,\n",
" batch_size=hparams.batch_size, pin_memory=False,\n",
" drop_last=True, collate_fn=collate_fn)\n",
" return train_loader, valset, collate_fn\n",
"\n",
"\n",
"def prepare_directories_and_logger(output_directory, log_directory, rank):\n",
" if rank == 0:\n",
" if not os.path.isdir(output_directory):\n",
" os.makedirs(output_directory)\n",
" os.chmod(output_directory, 0o775)\n",
" logger = Tacotron2Logger(os.path.join(output_directory, log_directory))\n",
" else:\n",
" logger = None\n",
" return logger\n",
"\n",
"\n",
"def load_model(hparams):\n",
" model = Tacotron2(hparams).cuda()\n",
" if hparams.fp16_run:\n",
" model.decoder.attention_layer.score_mask_value = finfo('float16').min\n",
"\n",
" if hparams.distributed_run:\n",
" model = apply_gradient_allreduce(model)\n",
"\n",
" return model\n",
"\n",
"\n",
"def warm_start_model(checkpoint_path, model, ignore_layers):\n",
" assert os.path.isfile(checkpoint_path)\n",
" print(\"Warm starting model from checkpoint '{}'\".format(checkpoint_path))\n",
" checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')\n",
" model_dict = checkpoint_dict['state_dict']\n",
" if len(ignore_layers) > 0:\n",
" model_dict = {k: v for k, v in model_dict.items()\n",
" if k not in ignore_layers}\n",
" dummy_dict = model.state_dict()\n",
" dummy_dict.update(model_dict)\n",
" model_dict = dummy_dict\n",
" model.load_state_dict(model_dict)\n",
" return model\n",
"\n",
"\n",
"def load_checkpoint(checkpoint_path, model, optimizer):\n",
" assert os.path.isfile(checkpoint_path)\n",
" print(\"Loading checkpoint '{}'\".format(checkpoint_path))\n",
" checkpoint_dict = torch.load(checkpoint_path, map_location='cpu')\n",
" model.load_state_dict(checkpoint_dict['state_dict'])\n",
" optimizer.load_state_dict(checkpoint_dict['optimizer'])\n",
" learning_rate = checkpoint_dict['learning_rate']\n",
" iteration = checkpoint_dict['iteration']\n",
" print(\"Loaded checkpoint '{}' from iteration {}\" .format(\n",
" checkpoint_path, iteration))\n",
" return model, optimizer, learning_rate, iteration\n",
"\n",
"\n",
"def save_checkpoint(model, optimizer, learning_rate, iteration, filepath):\n",
" print(\"Saving model and optimizer state at iteration {} to {}\".format(\n",
" iteration, filepath))\n",
" try:\n",
" torch.save({'iteration': iteration,\n",
" 'state_dict': model.state_dict(),\n",
" 'optimizer': optimizer.state_dict(),\n",
" 'learning_rate': learning_rate}, filepath)\n",
" except KeyboardInterrupt:\n",
" print(\"interrupt received while saving, waiting for save to complete.\")\n",
" torch.save({'iteration': iteration,'state_dict': model.state_dict(),'optimizer': optimizer.state_dict(),'learning_rate': learning_rate}, filepath)\n",
" print(\"Model Saved\")\n",
"\n",
"def plot_alignment(alignment, info=None):\n",
" %matplotlib inline\n",
" fig, ax = plt.subplots(figsize=(int(alignment_graph_width/100), int(alignment_graph_height/100)))\n",
" im = ax.imshow(alignment, cmap='inferno', aspect='auto', origin='lower',\n",
" interpolation='none')\n",
" ax.autoscale(enable=True, axis=\"y\", tight=True)\n",
" fig.colorbar(im, ax=ax)\n",
" xlabel = 'Decoder timestep'\n",
" if info is not None:\n",
" xlabel += '\\n\\n' + info\n",
" plt.xlabel(xlabel)\n",
" plt.ylabel('Encoder timestep')\n",
" plt.tight_layout()\n",
" fig.canvas.draw()\n",
" plt.show()\n",
"\n",
"def validate(model, criterion, valset, iteration, batch_size, n_gpus,\n",
" collate_fn, logger, distributed_run, rank, epoch, start_eposh, learning_rate):\n",
" \"\"\"Handles all the validation scoring and printing\"\"\"\n",
" model.eval()\n",
" with torch.no_grad():\n",
" val_sampler = DistributedSampler(valset) if distributed_run else None\n",
" val_loader = DataLoader(valset, sampler=val_sampler, num_workers=1,\n",
" shuffle=False, batch_size=batch_size,\n",
" pin_memory=False, collate_fn=collate_fn)\n",
"\n",
" val_loss = 0.0\n",
" for i, batch in enumerate(val_loader):\n",
" x, y = model.parse_batch(batch)\n",
" y_pred = model(x)\n",
" loss = criterion(y_pred, y)\n",
" if distributed_run:\n",
" reduced_val_loss = reduce_tensor(loss.data, n_gpus).item()\n",
" else:\n",
" reduced_val_loss = loss.item()\n",
" val_loss += reduced_val_loss\n",
" val_loss = val_loss / (i + 1)\n",
"\n",
" model.train()\n",
" if rank == 0:\n",
" print(\"Epoch: {} Validation loss {}: {:9f} Time: {:.1f}m LR: {:.6f}\".format(epoch, iteration, val_loss,(time.perf_counter()-start_eposh)/60, learning_rate))\n",
" logger.log_validation(val_loss, model, y, y_pred, iteration)\n",
" if hparams.show_alignments:\n",
" %matplotlib inline\n",
" _, mel_outputs, gate_outputs, alignments = y_pred\n",
" idx = random.randint(0, alignments.size(0) - 1)\n",
" plot_alignment(alignments[idx].data.cpu().numpy().T)\n",
"\n",
"def train(output_directory, log_directory, checkpoint_path, warm_start, n_gpus,\n",
" rank, group_name, hparams, log_directory2):\n",
" \"\"\"Training and validation logging results to tensorboard and stdout\n",
"\n",
" Params\n",
" ------\n",
" output_directory (string): directory to save checkpoints\n",
" log_directory (string) directory to save tensorboard logs\n",
" checkpoint_path(string): checkpoint path\n",
" n_gpus (int): number of gpus\n",
" rank (int): rank of current gpu\n",
" hparams (object): comma separated list of \"name=value\" pairs.\n",
" \"\"\"\n",
" if hparams.distributed_run:\n",
" init_distributed(hparams, n_gpus, rank, group_name)\n",
"\n",
" torch.manual_seed(hparams.seed)\n",
" torch.cuda.manual_seed(hparams.seed)\n",
"\n",
" model = load_model(hparams)\n",
" learning_rate = hparams.learning_rate\n",
" optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate,\n",
" weight_decay=hparams.weight_decay)\n",
"\n",
" if hparams.fp16_run:\n",
" from apex import amp\n",
" model, optimizer = amp.initialize(\n",
" model, optimizer, opt_level='O2')\n",
"\n",
" if hparams.distributed_run:\n",
" model = apply_gradient_allreduce(model)\n",
"\n",
" criterion = Tacotron2Loss()\n",
"\n",
" logger = prepare_directories_and_logger(\n",
" output_directory, log_directory, rank)\n",
"\n",
" train_loader, valset, collate_fn = prepare_dataloaders(hparams)\n",
"\n",
" # Load checkpoint if one exists\n",
" iteration = 0\n",
" epoch_offset = 0\n",
" if checkpoint_path is not None and os.path.isfile(checkpoint_path):\n",
" if warm_start:\n",
" model = warm_start_model(\n",
" checkpoint_path, model, hparams.ignore_layers)\n",
" else:\n",
" model, optimizer, _learning_rate, iteration = load_checkpoint(\n",
" checkpoint_path, model, optimizer)\n",
" if hparams.use_saved_learning_rate:\n",
" learning_rate = _learning_rate\n",
" iteration += 1 # next iteration is iteration + 1\n",
" epoch_offset = max(0, int(iteration / len(train_loader)))\n",
" else:\n",
" os.path.isfile(\"tacotron2_statedict.pt\")\n",
" model = warm_start_model(\"tacotron2_statedict.pt\", model, hparams.ignore_layers)\n",
" # download LJSpeech pretrained model if no checkpoint already exists\n",
" \n",
" start_eposh = time.perf_counter()\n",
" learning_rate = 0.0\n",
" model.train()\n",
" is_overflow = False\n",
" # ================ MAIN TRAINNIG LOOP! ===================\n",
" for epoch in tqdm(range(epoch_offset, hparams.epochs)):\n",
" print(\"\\nStarting Epoch: {} Iteration: {}\".format(epoch, iteration))\n",
" start_eposh = time.perf_counter() # eposh is russian, not a typo\n",
" for i, batch in tqdm(enumerate(train_loader), total=len(train_loader)):\n",
" start = time.perf_counter()\n",
" if iteration < hparams.decay_start: learning_rate = hparams.A_\n",
" else: iteration_adjusted = iteration - hparams.decay_start; learning_rate = (hparams.A_*(e**(-iteration_adjusted/hparams.B_))) + hparams.C_\n",
" learning_rate = max(hparams.min_learning_rate, learning_rate) # output the largest number\n",
" for param_group in optimizer.param_groups:\n",
" param_group['lr'] = learning_rate\n",
"\n",
" model.zero_grad()\n",
" x, y = model.parse_batch(batch)\n",
" y_pred = model(x)\n",
"\n",
" loss = criterion(y_pred, y)\n",
" if hparams.distributed_run:\n",
" reduced_loss = reduce_tensor(loss.data, n_gpus).item()\n",
" else:\n",
" reduced_loss = loss.item()\n",
" if hparams.fp16_run:\n",
" with amp.scale_loss(loss, optimizer) as scaled_loss:\n",
" scaled_loss.backward()\n",
" else:\n",
" loss.backward()\n",
"\n",
" if hparams.fp16_run:\n",
" grad_norm = torch.nn.utils.clip_grad_norm_(\n",
" amp.master_params(optimizer), hparams.grad_clip_thresh)\n",
" is_overflow = math.isnan(grad_norm)\n",
" else:\n",
" grad_norm = torch.nn.utils.clip_grad_norm_(\n",
" model.parameters(), hparams.grad_clip_thresh)\n",
"\n",
" optimizer.step()\n",
"\n",
" if not is_overflow and rank == 0:\n",
" duration = time.perf_counter() - start\n",
" logger.log_training(\n",
" reduced_loss, grad_norm, learning_rate, duration, iteration)\n",
" #print(\"Batch {} loss {:.6f} Grad Norm {:.6f} Time {:.6f}\".format(iteration, reduced_loss, grad_norm, duration), end='\\r', flush=True)\n",
"\n",
" iteration += 1\n",
" validate(model, criterion, valset, iteration,\n",
" hparams.batch_size, n_gpus, collate_fn, logger,\n",
" hparams.distributed_run, rank, epoch, start_eposh, learning_rate)\n",
" save_checkpoint(model, optimizer, learning_rate, iteration, checkpoint_path)\n",
" if log_directory2 != None:\n",
" copy_tree(log_directory, log_directory2)\n",
"def check_dataset(hparams):\n",
" from utils import load_wav_to_torch, load_filepaths_and_text\n",
" import os\n",
" import numpy as np\n",
" def check_arr(filelist_arr):\n",
" for i, file in enumerate(filelist_arr):\n",
" if len(file) > 2:\n",
" print(\"|\".join(file), \"\\nhas multiple '|', this may not be an error.\")\n",
" if hparams.load_mel_from_disk and '.wav' in file[0]:\n",
" print(\"[WARNING]\", file[0], \" in filelist while expecting .npy .\")\n",
" else:\n",
" if not hparams.load_mel_from_disk and '.npy' in file[0]:\n",
" print(\"[WARNING]\", file[0], \" in filelist while expecting .wav .\")\n",
" if (not os.path.exists(file[0])):\n",
" print(\"|\".join(file), \"\\n[WARNING] does not exist.\")\n",
" if len(file[1]) < 3:\n",
" print(\"|\".join(file), \"\\n[info] has no/very little text.\")\n",
" if not ((file[1].strip())[-1] in r\"!?,.;:\"):\n",
" print(\"|\".join(file), \"\\n[info] has no ending punctuation.\")\n",
" mel_length = 1\n",
" if hparams.load_mel_from_disk and '.npy' in file[0]:\n",
" melspec = torch.from_numpy(np.load(file[0], allow_pickle=True))\n",
" mel_length = melspec.shape[1]\n",
" if mel_length == 0:\n",
" print(\"|\".join(file), \"\\n[WARNING] has 0 duration.\")\n",
" print(\"Checking Training Files\")\n",
" audiopaths_and_text = load_filepaths_and_text(hparams.training_files) # get split lines from training_files text file.\n",
" check_arr(audiopaths_and_text)\n",
" print(\"Checking Validation Files\")\n",
" audiopaths_and_text = load_filepaths_and_text(hparams.validation_files) # get split lines from validation_files text file.\n",
" check_arr(audiopaths_and_text)\n",
" print(\"Finished Checking\")\n",
"\n",
"warm_start=False #sorry about that\n",
"n_gpus=1\n",
"rank=0\n",
"group_name=None\n",
"\n",
"# ---- 这是定义的默认参数,可以不用管 ----\n",
"hparams = create_hparams()\n",
"model_filename = 'current_model'\n",
"hparams.training_files = \"filelists/clipper_train_filelist.txt\"\n",
"hparams.validation_files = \"filelists/clipper_val_filelist.txt\"\n",
"#hparams.use_mmi=True, # not used in this notebook\n",
"#hparams.use_gaf=True, # not used in this notebook\n",
"#hparams.max_gaf=0.5, # not used in this notebook\n",
"#hparams.drop_frame_rate = 0.2 # not used in this notebook\n",
"hparams.p_attention_dropout=0.1\n",
"hparams.p_decoder_dropout=0.1\n",
"hparams.decay_start = 15000\n",
"hparams.A_ = 5e-4\n",
"hparams.B_ = 8000\n",
"hparams.C_ = 0\n",
"hparams.min_learning_rate = 1e-5\n",
"generate_mels = True\n",
"hparams.show_alignments = True\n",
"alignment_graph_height = 600\n",
"alignment_graph_width = 1000\n",
"hparams.batch_size = 32\n",
"hparams.load_mel_from_disk = True\n",
"hparams.ignore_layers = []\n",
"hparams.epochs = 10000\n",
"\n",
"torch.backends.cudnn.enabled = hparams.cudnn_enabled\n",
"torch.backends.cudnn.benchmark = hparams.cudnn_benchmark\n",
"output_directory = '/content/drive/MyDrive/colab/outdir' # Location to save Checkpoints\n",
"log_directory = '/content/tacotron2/logs' # Location to save Log files locally\n",
"log_directory2 = '/content/drive/MyDrive/colab/logs' # Location to copy log files (done at the end of each epoch to cut down on I/O)e\n",
"checkpoint_path = output_directory+(r'/')+model_filename\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:23:09.697053Z",
"iopub.status.busy": "2022-08-12T04:23:09.696148Z",
"iopub.status.idle": "2022-08-12T04:23:09.701991Z",
"shell.execute_reply": "2022-08-12T04:23:09.700529Z",
"shell.execute_reply.started": "2022-08-12T04:23:09.697015Z"
},
"id": "GKRvQ1EWiVhn",
"trusted": true
},
"outputs": [],
"source": [
"#@title 给你的模型取名(写字母数字)\n",
"model_filename = \"test\" #@param {type:\"string\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {
"iopub.execute_input": "2022-08-12T04:23:14.426817Z",
"iopub.status.busy": "2022-08-12T04:23:14.426455Z",
"iopub.status.idle": "2022-08-12T04:23:14.433170Z",
"shell.execute_reply": "2022-08-12T04:23:14.432204Z",
"shell.execute_reply.started": "2022-08-12T04:23:14.426786Z"
},
"trusted": true,
"cellView": "form",
"id": "ew2HzQl2IZhH"
},
"outputs": [],
"source": [
"#@title 添加之前训练的模型到输出文件夹\n",
"\n",
"#@markdown 如果之前训练过**同名**模型: 在Google云端硬盘分享模型,设置为任何人可见,然后把share id放在这里即可(参考gdown用法)\n",
"\n",
"#@markdown 如果第一次训练 : 直接跳过\n",
"os.chdir(\"outdir\")\n",
"# ! gdown --id \n",
"os.chdir(\"..\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:23:21.495804Z",
"iopub.status.busy": "2022-08-12T04:23:21.494800Z",
"iopub.status.idle": "2022-08-12T04:23:21.504471Z",
"shell.execute_reply": "2022-08-12T04:23:21.503429Z",
"shell.execute_reply.started": "2022-08-12T04:23:21.495754Z"
},
"id": "JzevuoJnkIsi",
"trusted": true
},
"outputs": [],
"source": [
"#@title 设置参数\n",
"\n",
"#@markdown **这两个参数是最重要的。**\n",
"\n",
"#@markdown 这个参数控制模型训练得多快。**不要设置太大,否则显卡会炸。**如果数据集比较大,设置在30左右比较好。\n",
"\n",
"#@markdown 如果数据集里音频文件的数量和这个参数差不多,训练会失败。\n",
"\n",
"hparams.batch_size = 8 #@param {type:\"integer\"}\n",
"\n",
"#@markdown 这个参数控制训练的次数\n",
"hparams.epochs = 1000 #@param {type:\"integer\"}\n",
"\n",
"#The rest aren't that important\n",
"hparams.p_attention_dropout=0.1\n",
"hparams.p_decoder_dropout=0.1\n",
"hparams.decay_start = 15000 # wait till decay_start to start decaying learning rate\n",
"hparams.A_ = 5e-4 # Start/Max Learning Rate\n",
"hparams.B_ = 8000 # Decay Rate\n",
"hparams.C_ = 0 # Shift learning rate equation by this value\n",
"hparams.min_learning_rate = 1e-5 # Min Learning Rate\n",
"generate_mels = True # Don't change\n",
"hparams.show_alignments = True\n",
"alignment_graph_height = 600\n",
"alignment_graph_width = 1000\n",
"hparams.load_mel_from_disk = True\n",
"hparams.ignore_layers = [] # Layers to reset (None by default, other than foreign languages this param can be ignored)\n",
"\n",
"torch.backends.cudnn.enabled = hparams.cudnn_enabled\n",
"torch.backends.cudnn.benchmark = hparams.cudnn_benchmark\n",
"output_directory = '/content/drive/MyDrive/colab/outdir' # Location to save Checkpoints\n",
"log_directory = '/content/tacotron2/logs' # Location to save Log files locally\n",
"log_directory2 = '/content/drive/MyDrive/colab/logs' # Location to copy log files (done at the end of each epoch to cut down on I/O)\n",
"checkpoint_path = output_directory+(r'/')+model_filename"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:23:25.281471Z",
"iopub.status.busy": "2022-08-12T04:23:25.280625Z",
"iopub.status.idle": "2022-08-12T04:23:26.307536Z",
"shell.execute_reply": "2022-08-12T04:23:26.305920Z",
"shell.execute_reply.started": "2022-08-12T04:23:25.281432Z"
},
"id": "yehA2fOliyUI",
"trusted": true
},
"outputs": [],
"source": [
"#@title 数据集文件列表\n",
"#@markdown 如果要求不高,两个列表用同一个文件即可\n",
"\n",
"#@markdown 训练集文件列表\n",
"training_files_name = \"list.txt\" #@param {type:\"string\"}\n",
"#@markdown 验证集文件列表\n",
"validation_files_name = \"list.txt\" #@param {type:\"string\"}\n",
"#@markdown 预处理文本的cleaner\n",
"\n",
"hparams_prefix = \"/content/tacotron2/filelists/\"\n",
"text_cleaner='japanese_phrase_cleaners' #@param {type:\"string\"}\n",
"text_cleaners=[text_cleaner]\n",
"#@markdown ### 各种cleaner的效果示例\n",
"#@markdown ### 1. 'japanese_cleaners'\n",
"#@markdown #### 处理前\n",
"#@markdown 何かあったらいつでも話して下さい。学院のことじゃなく、私事に関することでも何でも\n",
"#@markdown #### 处理后\n",
"#@markdown nanikaacltaraitsudemohanashItekudasai.gakuiNnokotojanaku,shijinikaNsurukotodemonanidemo.\n",
"#@markdown ### 2. 'japanese_tokenization_cleaners'\n",
"#@markdown #### 处理前\n",
"#@markdown 何かあったらいつでも話して下さい。学院のことじゃなく、私事に関することでも何でも\n",
"#@markdown #### 处理后\n",
"#@markdown nani ka acl tara itsu demo hanashi te kudasai. gakuiN no koto ja naku, shiji nikaNsuru koto de mo naNdemo.\n",
"#@markdown ### 3. 'japanese_accent_cleaners'\n",
"#@markdown #### 处理前\n",
"#@markdown 何かあったらいつでも話して下さい。学院のことじゃなく、私事に関することでも何でも\n",
"#@markdown #### 处理后\n",
"#@markdown :na)nika a)cltara i)tsudemo ha(na)shIte ku(dasa)i.:ga(kuiNno ko(to)janaku,:shi)jini ka(Nsu)ru ko(to)demo na)nidemo.\n",
"#@markdown ### 4. 'japanese_phrase_cleaners'\n",
"#@markdown #### 处理前\n",
"#@markdown 何かあったらいつでも話して下さい。学院のことじゃなく、私事に関することでも何でも\n",
"#@markdown #### 处理后\n",
"#@markdown nanika acltara itsudemo hanashIte kudasai. gakuiNno kotojanaku, shijini kaNsuru kotodemo nanidemo.\n",
"\n",
"training_files = hparams_prefix + training_files_name\n",
"validation_files = hparams_prefix + validation_files_name\n",
"\n",
"hparams.training_files = training_files\n",
"hparams.validation_files = validation_files\n",
"hparams.text_cleaners = text_cleaners"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:23:32.743603Z",
"iopub.status.busy": "2022-08-12T04:23:32.743060Z",
"iopub.status.idle": "2022-08-12T04:24:06.307565Z",
"shell.execute_reply": "2022-08-12T04:24:06.306350Z",
"shell.execute_reply.started": "2022-08-12T04:23:32.743559Z"
},
"id": "b_xMcYMfkc9L",
"trusted": true
},
"outputs": [],
"source": [
"#@title 生成MEL谱\n",
"# ---- Replace .wav with .npy in filelists ----\n",
"!sed -i -- 's,.wav|,.npy|,g' filelists/*.txt\n",
"# ---- Replace .wav with .npy in filelists ----\n",
"if generate_mels:\n",
" create_mels()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:24:09.055998Z",
"iopub.status.busy": "2022-08-12T04:24:09.055604Z",
"iopub.status.idle": "2022-08-12T04:24:09.263224Z",
"shell.execute_reply": "2022-08-12T04:24:09.261774Z",
"shell.execute_reply.started": "2022-08-12T04:24:09.055966Z"
},
"id": "oJXxqs6kkgLw",
"trusted": true
},
"outputs": [],
"source": [
"#@title 检查数据集\n",
"#@markdown 没有error就算成功\n",
"check_dataset(hparams)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "62-cfyIubje_"
},
"source": [
"#训练"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {
"iopub.execute_input": "2022-08-12T04:25:58.143443Z",
"iopub.status.busy": "2022-08-12T04:25:58.143025Z",
"iopub.status.idle": "2022-08-12T04:26:55.002866Z",
"shell.execute_reply": "2022-08-12T04:26:55.001342Z",
"shell.execute_reply.started": "2022-08-12T04:25:58.143406Z"
},
"id": "qJTrZhShk8ZR",
"trusted": true
},
"outputs": [],
"source": [
"#@title 开始训练\n",
"#@markdown Validation loss 越小,拟合效果可能越好\n",
"print('FP16 Run:', hparams.fp16_run)\n",
"print('Dynamic Loss Scaling:', hparams.dynamic_loss_scaling)\n",
"print('Distributed Run:', hparams.distributed_run)\n",
"print('cuDNN Enabled:', hparams.cudnn_enabled)\n",
"print('cuDNN Benchmark:', hparams.cudnn_benchmark)\n",
"train(output_directory, log_directory, checkpoint_path,\n",
" warm_start, n_gpus, rank, group_name, hparams, log_directory2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jDGVcS77b25R"
},
"source": [
"#语音合成"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "V6pX7t0cVlj9"
},
"source": [
"##用HiFi-GAN转换##"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "mwsEA9fP4qfZ",
"cellView": "form"
},
"outputs": [],
"source": [
"#@markdown 配置:\n",
"\n",
"#@markdown 重新运行即可应用配置的更改\n",
"\n",
"#国际 HiFi-GAN 模型(有点机器音): 1qpgI41wNXFcH-iKq1Y42JlBC9j0je8PW\n",
"#@markdown 你训练好的tacotron2模型的路径填在`Tacotron2_Model`这里\n",
"Tacotron2_Model = '/content/drive/MyDrive/YOURMODEL'#@param {type:\"string\"}\n",
"TACOTRON2_ID = Tacotron2_Model\n",
"HIFIGAN_ID = \"1qpgI41wNXFcH-iKq1Y42JlBC9j0je8PW\"\n",
"#@markdown 选择预处理文本的cleaner\n",
"text_cleaner = 'japanese_phrase_cleaners'#@param {type:\"string\"}\n",
"\n",
"# Check if Initilized\n",
"try:\n",
" initilized\n",
"except NameError:\n",
" print(\"Setting up, please wait.\\n\")\n",
" !pip install tqdm -q\n",
" from tqdm.notebook import tqdm\n",
" with tqdm(total=5, leave=False) as pbar:\n",
" %tensorflow_version 1.x\n",
" import os\n",
" from os.path import exists, join, basename, splitext\n",
" !pip install gdown\n",
" git_repo_url = 'https://github.com/CjangCjengh/tacotron2-japanese.git'\n",
" project_name = splitext(basename(git_repo_url))[0]\n",
" if not exists(project_name):\n",
" # clone and install\n",
" !git clone -q --recursive {git_repo_url}\n",
" !git clone -q --recursive https://github.com/SortAnon/hifi-gan\n",
" !pip install -q librosa unidecode\n",
" pbar.update(1) # downloaded TT2 and HiFi-GAN\n",
" import sys\n",
" sys.path.append('hifi-gan')\n",
" sys.path.append(project_name)\n",
" import time\n",
" import matplotlib\n",
" import matplotlib.pylab as plt\n",
" import gdown\n",
" d = 'https://drive.google.com/uc?id='\n",
"\n",
" %matplotlib inline\n",
" import IPython.display as ipd\n",
" import numpy as np\n",
" import torch\n",
" import json\n",
" from hparams import create_hparams\n",
" from model import Tacotron2\n",
" from layers import TacotronSTFT\n",
" from audio_processing import griffin_lim\n",
" from text import text_to_sequence\n",
" from env import AttrDict\n",
" from meldataset import MAX_WAV_VALUE\n",
" from models import Generator\n",
"\n",
" pbar.update(1) # initialized Dependancies\n",
"\n",
" graph_width = 900\n",
" graph_height = 360\n",
" def plot_data(data, figsize=(int(graph_width/100), int(graph_height/100))):\n",
" %matplotlib inline\n",
" fig, axes = plt.subplots(1, len(data), figsize=figsize)\n",
" for i in range(len(data)):\n",
" axes[i].imshow(data[i], aspect='auto', origin='bottom', \n",
" interpolation='none', cmap='inferno')\n",
" fig.canvas.draw()\n",
" plt.show()\n",
"\n",
" # Setup Pronounciation Dictionary\n",
" !gdown --id '1E12g_sREdcH5vuZb44EZYX8JjGWQ9rRp'\n",
" thisdict = {}\n",
" for line in reversed((open('merged.dict.txt', \"r\").read()).splitlines()):\n",
" thisdict[(line.split(\" \",1))[0]] = (line.split(\" \",1))[1].strip()\n",
"\n",
" pbar.update(1) # Downloaded and Set up Pronounciation Dictionary\n",
"\n",
" def ARPA(text, punctuation=r\"!?,.;\", EOS_Token=True):\n",
" out = ''\n",
" for word_ in text.split(\" \"):\n",
" word=word_; end_chars = ''\n",
" while any(elem in word for elem in punctuation) and len(word) > 1:\n",
" if word[-1] in punctuation: end_chars = word[-1] + end_chars; word = word[:-1]\n",
" else: break\n",
" try:\n",
" word_arpa = thisdict[word.upper()]\n",
" word = \"{\" + str(word_arpa) + \"}\"\n",
" except KeyError: pass\n",
" out = (out + \" \" + word + end_chars).strip()\n",
" if EOS_Token and out[-1] != \";\": out += \";\"\n",
" return out\n",
"\n",
" def get_hifigan(MODEL_ID):\n",
" # Download HiFi-GAN\n",
" hifigan_pretrained_model = 'hifimodel'\n",
" gdown.download(d+MODEL_ID, hifigan_pretrained_model, quiet=False)\n",
" if not exists(hifigan_pretrained_model):\n",
" raise Exception(\"HiFI-GAN model failed to download!\")\n",
"\n",
" # Load HiFi-GAN\n",
" conf = os.path.join(\"hifi-gan\", \"config_v1.json\")\n",
" with open(conf) as f:\n",
" json_config = json.loads(f.read())\n",
" h = AttrDict(json_config)\n",
" torch.manual_seed(h.seed)\n",
" hifigan = Generator(h).to(torch.device(\"cuda\"))\n",
" state_dict_g = torch.load(hifigan_pretrained_model, map_location=torch.device(\"cuda\"))\n",
" hifigan.load_state_dict(state_dict_g[\"generator\"])\n",
" hifigan.eval()\n",
" hifigan.remove_weight_norm()\n",
" return hifigan, h\n",
"\n",
" hifigan, h = get_hifigan(HIFIGAN_ID)\n",
" pbar.update(1) # Downloaded and Set up HiFi-GAN\n",
"\n",
" def has_MMI(STATE_DICT):\n",
" return any(True for x in STATE_DICT.keys() if \"mi.\" in x)\n",
"\n",
" def get_Tactron2(MODEL_ID):\n",
" # Download Tacotron2\n",
" tacotron2_pretrained_model = TACOTRON2_ID\n",
" if not exists(tacotron2_pretrained_model):\n",
" raise Exception(\"Tacotron2 model failed to download!\")\n",
" # Load Tacotron2 and Config\n",
" hparams = create_hparams()\n",
" hparams.sampling_rate = 22050\n",
" hparams.max_decoder_steps = 3000 # Max Duration\n",
" hparams.gate_threshold = 0.25 # Model must be 25% sure the clip is over before ending generation\n",
" model = Tacotron2(hparams)\n",
" state_dict = torch.load(tacotron2_pretrained_model)['state_dict']\n",
" if has_MMI(state_dict):\n",
" raise Exception(\"ERROR: This notebook does not currently support MMI models.\")\n",
" model.load_state_dict(state_dict)\n",
" _ = model.cuda().eval().half()\n",
" return model, hparams\n",
"\n",
" model, hparams = get_Tactron2(TACOTRON2_ID)\n",
" previous_tt2_id = TACOTRON2_ID\n",
"\n",
" pbar.update(1) # Downloaded and Set up Tacotron2\n",
"\n",
" # Extra Info\n",
" def end_to_end_infer(text, pronounciation_dictionary, show_graphs):\n",
" for i in [x for x in text.split(\"\\n\") if len(x)]:\n",
" if not pronounciation_dictionary:\n",
" if i[-1] != \";\": i=i+\";\" \n",
" else: i = ARPA(i)\n",
" with torch.no_grad(): # save VRAM by not including gradients\n",
" sequence = np.array(text_to_sequence(i, [text_cleaner]))[None, :]\n",
" sequence = torch.autograd.Variable(torch.from_numpy(sequence)).cuda().long()\n",
" mel_outputs, mel_outputs_postnet, _, alignments = model.inference(sequence)\n",
" if show_graphs:\n",
" plot_data((mel_outputs_postnet.float().data.cpu().numpy()[0],\n",
" alignments.float().data.cpu().numpy()[0].T))\n",
" y_g_hat = hifigan(mel_outputs_postnet.float())\n",
" audio = y_g_hat.squeeze()\n",
" audio = audio * MAX_WAV_VALUE\n",
" print(\"\")\n",
" ipd.display(ipd.Audio(audio.cpu().numpy().astype(\"int16\"), rate=hparams.sampling_rate))\n",
" from IPython.display import clear_output\n",
" clear_output()\n",
" initilized = \"Ready\"\n",
"\n",
"if previous_tt2_id != TACOTRON2_ID:\n",
" print(\"Updating Models\")\n",
" model, hparams = get_Tactron2(TACOTRON2_ID)\n",
" hifigan, h = get_hifigan(HIFIGAN_ID)\n",
" previous_tt2_id = TACOTRON2_ID\n",
"\n",
"pronounciation_dictionary = False #@param {type:\"boolean\"}\n",
"# disables automatic ARPAbet conversion, useful for inputting your own ARPAbet pronounciations or just for testing\n",
"show_graphs = True #@param {type:\"boolean\"}\n",
"max_duration = 25 #this does nothing\n",
"model.decoder.max_decoder_steps = 1000 #@param {type:\"integer\"}\n",
"stop_threshold = 0.324 #@param {type:\"number\"}\n",
"model.decoder.gate_threshold = stop_threshold\n",
"\n",
"#@markdown ---\n",
"\n",
"print(f\"Current Config:\\npronounciation_dictionary: {pronounciation_dictionary}\\nshow_graphs: {show_graphs}\\nmax_duration (in seconds): {max_duration}\\nstop_threshold: {stop_threshold}\\n\\n\")\n",
"\n",
"time.sleep(1)\n",
"print(\"输入要转换成语音的文本.\")\n",
"contents = []\n",
"while True:\n",
" try:\n",
" print(\"-\"*50)\n",
" line = input()\n",
" if line == \"\":\n",
" continue\n",
" end_to_end_infer(line, pronounciation_dictionary, show_graphs)\n",
" except EOFError:\n",
" break\n",
" except KeyboardInterrupt:\n",
" print(\"程序终止...\")\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Uitul995V0Jw"
},
"source": [
"##用 Waveglow##\n",
"(个人不建议使用)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "EXR9p7AeSuL6"
},
"outputs": [],
"source": [
"#@title 安装 Tacotron 和 Waveglow\n",
"!pip install -U tensorflow==1.15.2\n",
"import os\n",
"from os.path import exists, join, basename, splitext\n",
"!pip install gdown\n",
"git_repo_url = 'https://github.com/CjangCjengh/tacotron2-japanese.git'\n",
"project_name = splitext(basename(git_repo_url))[0]\n",
"if not exists(project_name):\n",
" # clone and install\n",
" !git clone -q --recursive {git_repo_url}\n",
" !cd {project_name}/waveglow && git checkout 2fd4e63\n",
" !pip install -q librosa unidecode\n",
" \n",
"import sys\n",
"sys.path.append(join(project_name, 'waveglow/'))\n",
"sys.path.append(project_name)\n",
"import time\n",
"import matplotlib\n",
"import matplotlib.pylab as plt\n",
"import gdown\n",
"d = 'https://drive.google.com/uc?id='"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "liDdgta-SyPP"
},
"outputs": [],
"source": [
"#@title 加载预训练模型\n",
"force_download_TT2 = True\n",
"tacotron2_pretrained_model = '/PATH/Your Tactron2 Model'#@param {type:\"string\"}\n",
"waveglow_pretrained_model = '/PATH/waveglow_256channels_ljs_v3.pt'#@param {type:\"string\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Q0BWBVdCS9ty",
"cellView": "form"
},
"outputs": [],
"source": [
"#@title 安装 Tacotron 和 Waveglow \n",
"%matplotlib inline\n",
"import IPython.display as ipd\n",
"import numpy as np\n",
"import torch\n",
"\n",
"from hparams import create_hparams\n",
"from model import Tacotron2\n",
"from layers import TacotronSTFT\n",
"from audio_processing import griffin_lim\n",
"from text import text_to_sequence\n",
"from denoiser import Denoiser\n",
"\n",
"graph_width = 900\n",
"graph_height = 360\n",
"def plot_data(data, figsize=(int(graph_width/100), int(graph_height/100))):\n",
" %matplotlib inline\n",
" fig, axes = plt.subplots(1, len(data), figsize=figsize)\n",
" for i in range(len(data)):\n",
" axes[i].imshow(data[i], aspect='auto', origin='bottom', \n",
" interpolation='none', cmap='inferno')\n",
" fig.canvas.draw()\n",
" plt.show()\n",
"\n",
"!gdown --id '1E12g_sREdcH5vuZb44EZYX8JjGWQ9rRp'\n",
"thisdict = {}\n",
"for line in reversed((open('merged.dict.txt', \"r\").read()).splitlines()):\n",
" thisdict[(line.split(\" \",1))[0]] = (line.split(\" \",1))[1].strip()\n",
"def ARPA(text):\n",
" out = ''\n",
" for word_ in text.split(\" \"):\n",
" word=word_; end_chars = ''\n",
" while any(elem in word for elem in r\"!?,.;\") and len(word) > 1:\n",
" if word[-1] == '!': end_chars = '!' + end_chars; word = word[:-1]\n",
" if word[-1] == '?': end_chars = '?' + end_chars; word = word[:-1]\n",
" if word[-1] == ',': end_chars = ',' + end_chars; word = word[:-1]\n",
" if word[-1] == '.': end_chars = '.' + end_chars; word = word[:-1]\n",
" if word[-1] == ';': end_chars = ';' + end_chars; word = word[:-1]\n",
" else: break\n",
" try: word_arpa = thisdict[word.upper()]\n",
" except: word_arpa = ''\n",
" if len(word_arpa)!=0: word = \"{\" + str(word_arpa) + \"}\"\n",
" out = (out + \" \" + word + end_chars).strip()\n",
" if out[-1] != \";\": out = out + \";\"\n",
" return out\n",
"\n",
"#torch.set_grad_enabled(False)\n",
"\n",
"# initialize Tacotron2 with the pretrained model\n",
"hparams = create_hparams()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "Sqe-jWarTCw6"
},
"outputs": [],
"source": [
"#@title 参数\n",
"# Load Tacotron2 (run this cell every time you change the model)\n",
"hparams.sampling_rate = 22050 # Don't change this\n",
"hparams.max_decoder_steps = 1000 # How long the audio will be before it cuts off (1000 is about 11 seconds)\n",
"hparams.gate_threshold = 0.1 # Model must be 90% sure the clip is over before ending generation (the higher this number is, the more likely that the AI will keep generating until it reaches the Max Decoder Steps)\n",
"model = Tacotron2(hparams)\n",
"model.load_state_dict(torch.load(tacotron2_pretrained_model)['state_dict'])\n",
"_ = model.cuda().eval().half()\n",
"\n",
"# Load WaveGlow\n",
"waveglow = torch.load(waveglow_pretrained_model)['model']\n",
"waveglow.cuda().eval().half()\n",
"for k in waveglow.convinv:\n",
" k.float()\n",
"denoiser = Denoiser(waveglow)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "FiRVI-J3TNnc"
},
"outputs": [],
"source": [
"#@title 开始合成!\n",
"text = 'Your Text Here'#@param {type:\"string\"}\n",
"sigma = 0.8\n",
"denoise_strength = 0.324\n",
"raw_input = True # disables automatic ARPAbet conversion, useful for inputting your own ARPAbet pronounciations or just for testing.\n",
" # should be True if synthesizing a non-English language\n",
"\n",
"for i in text.split(\"\\n\"):\n",
" if len(i) < 1: continue;\n",
" print(i)\n",
" if raw_input:\n",
" if i[-1] != \";\": i=i+\";\" \n",
" else: i = ARPA(i)\n",
" print(i)\n",
" with torch.no_grad(): # save VRAM by not including gradients\n",
" sequence = np.array(text_to_sequence(i, ['english_cleaners']))[None, :]\n",
" sequence = torch.autograd.Variable(torch.from_numpy(sequence)).cuda().long()\n",
" mel_outputs, mel_outputs_postnet, _, alignments = model.inference(sequence)\n",
" plot_data((mel_outputs_postnet.float().data.cpu().numpy()[0],\n",
" alignments.float().data.cpu().numpy()[0].T))\n",
" audio = waveglow.infer(mel_outputs_postnet, sigma=sigma); print(\"\"); ipd.display(ipd.Audio(audio[0].data.cpu().numpy(), rate=hparams.sampling_rate))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.12"
},
"colab": {
"name": "tacotron2训练和语音合成.ipynb",
"provenance": [],
"collapsed_sections": []
},
"accelerator": "GPU",
"gpuClass": "standard"
},
"nbformat": 4,
"nbformat_minor": 0
}