mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-03-13 19:34:02 +03:00
commit
30323b875c
293
MMVCTrainerFrontendDemo.ipynb
Normal file
293
MMVCTrainerFrontendDemo.ipynb
Normal file
@ -0,0 +1,293 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"collapsed_sections": [],
|
||||
"authorship_tag": "ABX9TyNeYcg5YiUjFhkeVj9OycIp",
|
||||
"include_colab_link": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"gpuClass": "standard"
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "view-in-github",
|
||||
"colab_type": "text"
|
||||
},
|
||||
"source": [
|
||||
"<a href=\"https://colab.research.google.com/github/w-okada/voice-changer/blob/dev/MMVCTrainerFrontendDemo.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"Voice Changer Simple (デモ版)\n",
|
||||
"---\n",
|
||||
"\n",
|
||||
"このノートはVoice ChangerをColab上で動かすデモ版です。\n",
|
||||
"\n",
|
||||
"正式版はローカルPCのDocker上で動かすアプリケーションです。\n",
|
||||
"\n",
|
||||
"正式版は、多くの場合より少ないタイムラグで滑らかに音声を変換できます。\n",
|
||||
"\n",
|
||||
"詳細な使用方法はこちらの[リポジトリ](https://github.com/w-okada/voice-changer)からご確認ください。\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "Lbbmx_Vjl0zo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# GPUを確認\n",
|
||||
"GPUを用いたほうが高速に処理が行えます。\n",
|
||||
"\n",
|
||||
"下記のコマンドでGPUが確認できない場合は、上のメニューから\n",
|
||||
"\n",
|
||||
"「ランタイム」→「ランタイムの変更」→「ハードウェア アクセラレータ」\n",
|
||||
"\n",
|
||||
"でGPUを選択してください。"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "oUKi1NYMmXrr"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (1) GPUの確認\n",
|
||||
"!nvidia-smi"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "vV1t7PBRm-o6",
|
||||
"outputId": "15081c48-84f0-4798-be64-38cf15c28966"
|
||||
},
|
||||
"execution_count": 1,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# リポジトリのクローン\n",
|
||||
"リポジトリをクローンします"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "sLBfykjBnjWc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (2) リポジトリのクローン\n",
|
||||
"!git clone --depth 1 https://github.com/isletennos/MMVC_Trainer.git -b v1.3.1.3 /MMVC_Trainer\n",
|
||||
"!git clone --depth 1 https://github.com/w-okada/voice-changer.git -b dev\n",
|
||||
"%cd voice-changer/demo/\n",
|
||||
"\n",
|
||||
"!cp ../template/setting_mmvc_colab.json ../frontend/dist/assets/setting.json"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "86wTFmqsNMnD",
|
||||
"outputId": "5151e168-15ec-4e4e-b50c-07867876294e"
|
||||
},
|
||||
"execution_count": 2,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"fatal: destination path '/MMVC_Trainer' already exists and is not an empty directory.\n",
|
||||
"fatal: destination path 'voice-changer' already exists and is not an empty directory.\n",
|
||||
"/content/voice-changer/demo\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# モジュールのインストール\n",
|
||||
"\n",
|
||||
"必要なモジュールをインストールします。"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "8Na2PbLZSWgZ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (3) 設定ファイルの確認\n",
|
||||
"!apt-get install -y espeak libsndfile1-dev &> /dev/null\n",
|
||||
"!pip install unidecode &> /dev/null\n",
|
||||
"!pip install phonemizer &> /dev/null\n",
|
||||
"!pip install retry &> /dev/null\n",
|
||||
"!pip install python-socketio &> /dev/null\n",
|
||||
"!pip install fastapi &> /dev/null\n",
|
||||
"!pip install python-multipart &> /dev/null\n",
|
||||
"!pip install uvicorn &> /dev/null\n",
|
||||
"!pip install websockets &> /dev/null\n",
|
||||
"!pip install pyOpenSSL &> /dev/null\n",
|
||||
"!pip install pyopenjtalk==0.2.0 &> /dev/null\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "LwZAAuqxX7yY"
|
||||
},
|
||||
"execution_count": 3,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# サーバの起動\n",
|
||||
"\n",
|
||||
"サーバを起動します。(4-1)\n",
|
||||
"\n",
|
||||
"サーバの起動状況を確認します。(4-2) \n",
|
||||
"\n",
|
||||
"このセルは繰り返し実行することになるのでCtrl+Retでセルを実行してください。\n",
|
||||
"\n",
|
||||
"下記のようなテキストが表示されたら起動完了です。\n",
|
||||
"\n",
|
||||
"**`DEBUG:asyncio:Using selector: EpollSelector`**\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
" Phase name:__main__\n",
|
||||
" PHASE3:__main__\n",
|
||||
" PHASE1:__main__\n",
|
||||
"Start MMVC SocketIO Server\n",
|
||||
" CONFIG:None, MODEL:None\n",
|
||||
"DEBUG:asyncio:Using selector: EpollSelector\n",
|
||||
"```\n",
|
||||
"\n"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "-_2OcN9Borke"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"!mkdir -p /MMVC_Trainer/info\n",
|
||||
"!mkdir -p /MMVC_Trainer/logs"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "pwUQ0_RzGK_g"
|
||||
},
|
||||
"execution_count": 4,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (4-1) サーバの起動\n",
|
||||
"import random\n",
|
||||
"PORT = 10000 + random.randint(1, 9999)\n",
|
||||
"LOG_FILE = f\"LOG_FILE_{PORT}\"\n",
|
||||
"\n",
|
||||
"get_ipython().system_raw(f'python3 MMVCServerSIO.py -p {PORT} --colab True >{LOG_FILE} 2>&1 &')\n",
|
||||
"#print(f\"PORT:{PORT}, LOG_FILE:{LOG_FILE}\")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "G-nMdPxEW1rc"
|
||||
},
|
||||
"execution_count": 5,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (4-2) サーバの起動確認\n",
|
||||
"!sleep 5\n",
|
||||
"!tail -20 {LOG_FILE}"
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "chu06KpAjEK6",
|
||||
"outputId": "26995bdf-063e-43ee-84fd-4aecc7e7b7e6"
|
||||
},
|
||||
"execution_count": 6,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"\u001b[32m Phase name:__main__\u001b[0m\n",
|
||||
"\u001b[32m PHASE3:__main__\u001b[0m\n",
|
||||
"\u001b[32m PHASE1:__main__\u001b[0m\n",
|
||||
"\u001b[17mStart MMVC SocketIO Server\u001b[0m\n",
|
||||
"\u001b[34m CONFIG:None, MODEL:None\u001b[0m\n",
|
||||
"DEBUG:asyncio:Using selector: EpollSelector\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"# プロキシを起動\n",
|
||||
"ウェブサーバへのアクセスをするためのプロキシを起動します。\n",
|
||||
"\n",
|
||||
"表示されたURLをクリックして開くと別タブでアプリが開きます。\n",
|
||||
"\n",
|
||||
"Colabなので、ロードにある程度時間がかかります(30秒くらい)。"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "WhxcFLQEpctq"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (5) プロキシを起動\n",
|
||||
"from google.colab.output import eval_js\n",
|
||||
"proxy = eval_js( \"google.colab.kernel.proxyPort(\" + str(PORT) + \")\" )\n",
|
||||
"print(f\"{proxy}trainer/\")"
|
||||
],
|
||||
"metadata": {
|
||||
"id": "nkRjZm95l87C",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 34
|
||||
},
|
||||
"outputId": "845d1582-d776-4154-984c-e256dcce6b38"
|
||||
},
|
||||
"execution_count": 7,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"https://ffm3z64cmhr-496ff2e9c6d22116-12768-colab.googleusercontent.com/trainer/\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
"colab": {
|
||||
"provenance": [],
|
||||
"collapsed_sections": [],
|
||||
"authorship_tag": "ABX9TyNuz5ToQB/hiwJTFCBOyGT/",
|
||||
"authorship_tag": "ABX9TyP6Wv8fttT+X2Op6MmqB/kg",
|
||||
"include_colab_link": true
|
||||
},
|
||||
"kernelspec": {
|
||||
@ -82,7 +82,7 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "Eihm8H2X-7wm",
|
||||
"outputId": "e51016e6-7f6e-4b95-8822-a4713017a6a6"
|
||||
"outputId": "76331fb1-5ef8-40e6-a381-258b5e425853"
|
||||
},
|
||||
"execution_count": 1,
|
||||
"outputs": [
|
||||
@ -122,7 +122,7 @@
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"# (2) リポジトリのクローン\n",
|
||||
"!git clone https://github.com/w-okada/voice-changer.git\n",
|
||||
"!git clone --depth 1 https://github.com/w-okada/voice-changer.git -b ver_1.0\n",
|
||||
"%cd voice-changer/docs/\n"
|
||||
],
|
||||
"metadata": {
|
||||
@ -130,7 +130,7 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "86wTFmqsNMnD",
|
||||
"outputId": "63e02151-2e55-49f3-8219-ba16cbb28233"
|
||||
"outputId": "40471833-d720-41c9-f4a7-ac15fbf18e14"
|
||||
},
|
||||
"execution_count": 3,
|
||||
"outputs": [
|
||||
@ -139,12 +139,22 @@
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"Cloning into 'voice-changer'...\n",
|
||||
"remote: Enumerating objects: 499, done.\u001b[K\n",
|
||||
"remote: Counting objects: 100% (83/83), done.\u001b[K\n",
|
||||
"remote: Compressing objects: 100% (65/65), done.\u001b[K\n",
|
||||
"remote: Total 499 (delta 26), reused 30 (delta 18), pack-reused 416\u001b[K\n",
|
||||
"Receiving objects: 100% (499/499), 21.10 MiB | 13.43 MiB/s, done.\n",
|
||||
"Resolving deltas: 100% (253/253), done.\n",
|
||||
"remote: Enumerating objects: 81, done.\u001b[K\n",
|
||||
"remote: Counting objects: 100% (81/81), done.\u001b[K\n",
|
||||
"remote: Compressing objects: 100% (68/68), done.\u001b[K\n",
|
||||
"remote: Total 81 (delta 12), reused 53 (delta 5), pack-reused 0\u001b[K\n",
|
||||
"Unpacking objects: 100% (81/81), done.\n",
|
||||
"Note: checking out 'f8823cb7e2025f13227f5918408cceda224bf9f0'.\n",
|
||||
"\n",
|
||||
"You are in 'detached HEAD' state. You can look around, make experimental\n",
|
||||
"changes and commit them, and you can discard any commits you make in this\n",
|
||||
"state without impacting any branches by performing another checkout.\n",
|
||||
"\n",
|
||||
"If you want to create a new branch to retain commits you create, you may\n",
|
||||
"do so (now or later) by using -b with the checkout command again. Example:\n",
|
||||
"\n",
|
||||
" git checkout -b <new-branch-name>\n",
|
||||
"\n",
|
||||
"/content/voice-changer/docs\n"
|
||||
]
|
||||
}
|
||||
@ -184,7 +194,7 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "rpWUobjlBCNF",
|
||||
"outputId": "0dd8bbc1-dd1e-47fe-fef6-fbc22540dc7a"
|
||||
"outputId": "285e0259-16af-4932-e78b-bec94f337e9c"
|
||||
},
|
||||
"execution_count": 5,
|
||||
"outputs": [
|
||||
@ -244,7 +254,7 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "LwZAAuqxX7yY",
|
||||
"outputId": "627e09e8-bc64-4110-ce0a-5b3f84e8bf1d"
|
||||
"outputId": "ea2b3b39-d571-4d47-a38b-d0e657a335cd"
|
||||
},
|
||||
"execution_count": 6,
|
||||
"outputs": [
|
||||
@ -254,20 +264,20 @@
|
||||
"text": [
|
||||
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
|
||||
"Requirement already satisfied: flask in /usr/local/lib/python3.7/dist-packages (1.1.4)\n",
|
||||
"Requirement already satisfied: Jinja2<3.0,>=2.10.1 in /usr/local/lib/python3.7/dist-packages (from flask) (2.11.3)\n",
|
||||
"Requirement already satisfied: Werkzeug<2.0,>=0.15 in /usr/local/lib/python3.7/dist-packages (from flask) (1.0.1)\n",
|
||||
"Requirement already satisfied: click<8.0,>=5.1 in /usr/local/lib/python3.7/dist-packages (from flask) (7.1.2)\n",
|
||||
"Requirement already satisfied: itsdangerous<2.0,>=0.24 in /usr/local/lib/python3.7/dist-packages (from flask) (1.1.0)\n",
|
||||
"Requirement already satisfied: Werkzeug<2.0,>=0.15 in /usr/local/lib/python3.7/dist-packages (from flask) (1.0.1)\n",
|
||||
"Requirement already satisfied: Jinja2<3.0,>=2.10.1 in /usr/local/lib/python3.7/dist-packages (from flask) (2.11.3)\n",
|
||||
"Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/dist-packages (from Jinja2<3.0,>=2.10.1->flask) (2.0.1)\n",
|
||||
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
|
||||
"Collecting flask_cors\n",
|
||||
" Downloading Flask_Cors-3.0.10-py2.py3-none-any.whl (14 kB)\n",
|
||||
"Requirement already satisfied: Flask>=0.9 in /usr/local/lib/python3.7/dist-packages (from flask_cors) (1.1.4)\n",
|
||||
"Requirement already satisfied: Six in /usr/local/lib/python3.7/dist-packages (from flask_cors) (1.15.0)\n",
|
||||
"Requirement already satisfied: itsdangerous<2.0,>=0.24 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (1.1.0)\n",
|
||||
"Requirement already satisfied: Flask>=0.9 in /usr/local/lib/python3.7/dist-packages (from flask_cors) (1.1.4)\n",
|
||||
"Requirement already satisfied: Werkzeug<2.0,>=0.15 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (1.0.1)\n",
|
||||
"Requirement already satisfied: click<8.0,>=5.1 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (7.1.2)\n",
|
||||
"Requirement already satisfied: itsdangerous<2.0,>=0.24 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (1.1.0)\n",
|
||||
"Requirement already satisfied: Jinja2<3.0,>=2.10.1 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (2.11.3)\n",
|
||||
"Requirement already satisfied: click<8.0,>=5.1 in /usr/local/lib/python3.7/dist-packages (from Flask>=0.9->flask_cors) (7.1.2)\n",
|
||||
"Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.7/dist-packages (from Jinja2<3.0,>=2.10.1->Flask>=0.9->flask_cors) (2.0.1)\n",
|
||||
"Installing collected packages: flask-cors\n",
|
||||
"Successfully installed flask-cors-3.0.10\n"
|
||||
@ -333,25 +343,25 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "chu06KpAjEK6",
|
||||
"outputId": "a42873c4-2826-4b54-f497-01adb1683875"
|
||||
"outputId": "6f5cbed9-65a7-4570-f58a-5447e402947c"
|
||||
},
|
||||
"execution_count": 8,
|
||||
"execution_count": 10,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"name": "stdout",
|
||||
"text": [
|
||||
"[2022-09-13 22:45:22,054] INFO in recorderServer: START APP\n",
|
||||
"[2022-11-08 19:11:17,679] INFO in recorderServer: START APP\n",
|
||||
" * Serving Flask app \"recorderServer\" (lazy loading)\n",
|
||||
" * Environment: production\n",
|
||||
" WARNING: This is a development server. Do not use it in a production deployment.\n",
|
||||
" Use a production WSGI server instead.\n",
|
||||
" * Debug mode: on\n",
|
||||
"[2022-09-13 22:45:22,062] INFO in _internal: * Running on http://0.0.0.0:8018/ (Press CTRL+C to quit)\n",
|
||||
"[2022-09-13 22:45:22,063] INFO in _internal: * Restarting with stat\n",
|
||||
"[2022-09-13 22:45:22,238] INFO in recorderServer: START APP\n",
|
||||
"[2022-09-13 22:45:22,244] WARNING in _internal: * Debugger is active!\n",
|
||||
"[2022-09-13 22:45:22,268] INFO in _internal: * Debugger PIN: 334-166-753\n"
|
||||
"[2022-11-08 19:11:17,696] INFO in _internal: * Running on http://0.0.0.0:8018/ (Press CTRL+C to quit)\n",
|
||||
"[2022-11-08 19:11:17,697] INFO in _internal: * Restarting with stat\n",
|
||||
"[2022-11-08 19:11:17,893] INFO in recorderServer: START APP\n",
|
||||
"[2022-11-08 19:11:17,900] WARNING in _internal: * Debugger is active!\n",
|
||||
"[2022-11-08 19:11:17,930] INFO in _internal: * Debugger PIN: 225-344-519\n"
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -384,9 +394,9 @@
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 34
|
||||
},
|
||||
"outputId": "768df0ee-9499-430b-ab4f-c602311114ae"
|
||||
"outputId": "7d2664b8-945c-4ee6-b49f-51f7f96cf388"
|
||||
},
|
||||
"execution_count": 9,
|
||||
"execution_count": 11,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "display_data",
|
||||
@ -443,7 +453,7 @@
|
||||
"metadata": {
|
||||
"id": "3PhrmCD2LaCH"
|
||||
},
|
||||
"execution_count": 43,
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
@ -469,7 +479,7 @@
|
||||
"id": "f5l6ggSyACLs",
|
||||
"outputId": "4db3571a-46e6-4fd9-c560-628cf4af9284"
|
||||
},
|
||||
"execution_count": 57,
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
@ -492,7 +502,7 @@
|
||||
"metadata": {
|
||||
"id": "UEVb2GGZSesY"
|
||||
},
|
||||
"execution_count": 71,
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
@ -542,7 +552,7 @@
|
||||
"id": "L8UsVp3dDs4R",
|
||||
"outputId": "5d640caf-87b0-45a6-aa0c-76295e537f6a"
|
||||
},
|
||||
"execution_count": 73,
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
|
@ -20,9 +20,23 @@ from datetime import datetime
|
||||
import torch
|
||||
import numpy as np
|
||||
|
||||
|
||||
from mods.ssl import create_self_signed_cert
|
||||
from mods.VoiceChanger import VoiceChanger
|
||||
# from mods.Whisper import Whisper
|
||||
|
||||
|
||||
# File Uploader
|
||||
from mods.FileUploader import upload_file, concat_file_chunks
|
||||
|
||||
# Trainer Rest Internal
|
||||
from mods.Trainer_Speakers import mod_get_speakers
|
||||
from mods.Trainer_Speaker import mod_delete_speaker
|
||||
from mods.Trainer_Speaker_Voices import mod_get_speaker_voices
|
||||
from mods.Trainer_Speaker_Voice import mod_get_speaker_voice
|
||||
from mods.Trainer_MultiSpeakerSetting import mod_get_multi_speaker_setting, mod_post_multi_speaker_setting
|
||||
from mods.Trainer_Models import mod_get_models
|
||||
from mods.Trainer_Model import mod_get_model, mod_delete_model
|
||||
from mods.Trainer_Training import mod_post_pre_training, mod_post_start_training, mod_post_stop_training, mod_get_related_files, mod_get_tail_training_log
|
||||
|
||||
class UvicornSuppressFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
@ -131,6 +145,24 @@ args = parser.parse_args()
|
||||
printMessage(f"Phase name:{__name__}", level=2)
|
||||
thisFilename = os.path.basename(__file__)[:-3]
|
||||
|
||||
from typing import Callable, List
|
||||
from fastapi import Body, FastAPI, HTTPException, Request, Response
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.routing import APIRoute
|
||||
class ValidationErrorLoggingRoute(APIRoute):
|
||||
def get_route_handler(self) -> Callable:
|
||||
original_route_handler = super().get_route_handler()
|
||||
|
||||
async def custom_route_handler(request: Request) -> Response:
|
||||
try:
|
||||
return await original_route_handler(request)
|
||||
except Exception as exc:
|
||||
print("Exception", request.url, str(exc))
|
||||
body = await request.body()
|
||||
detail = {"errors": exc.errors(), "body": body.decode()}
|
||||
raise HTTPException(status_code=422, detail=detail)
|
||||
|
||||
return custom_route_handler
|
||||
|
||||
if __name__ == thisFilename or args.colab == True:
|
||||
printMessage(f"PHASE3:{__name__}", level=2)
|
||||
@ -139,6 +171,7 @@ if __name__ == thisFilename or args.colab == True:
|
||||
MODEL = args.m
|
||||
|
||||
app_fastapi = FastAPI()
|
||||
app_fastapi.router.route_class = ValidationErrorLoggingRoute
|
||||
app_fastapi.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
@ -149,6 +182,10 @@ if __name__ == thisFilename or args.colab == True:
|
||||
|
||||
app_fastapi.mount("/front", StaticFiles(directory="../frontend/dist", html=True), name="static")
|
||||
|
||||
app_fastapi.mount("/trainer", StaticFiles(directory="../frontend/dist", html=True), name="static")
|
||||
|
||||
app_fastapi.mount("/recorder", StaticFiles(directory="../frontend/dist", html=True), name="static")
|
||||
|
||||
sio = socketio.AsyncServer(
|
||||
async_mode='asgi',
|
||||
cors_allowed_origins='*'
|
||||
@ -178,36 +215,20 @@ if __name__ == thisFilename or args.colab == True:
|
||||
return {"result": "Index"}
|
||||
|
||||
|
||||
UPLOAD_DIR = "model_upload_dir"
|
||||
############
|
||||
# File Uploder
|
||||
# ##########
|
||||
UPLOAD_DIR = "upload_dir"
|
||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||
# Can colab receive post request "ONLY" at root path?
|
||||
@app_fastapi.post("/upload_model_file")
|
||||
async def upload_file(configFile:UploadFile = File(...), modelFile: UploadFile = File(...)):
|
||||
if configFile and modelFile:
|
||||
for file in [modelFile, configFile]:
|
||||
filename = file.filename
|
||||
fileobj = file.file
|
||||
upload_dir = open(os.path.join(UPLOAD_DIR, filename),'wb+')
|
||||
shutil.copyfileobj(fileobj, upload_dir)
|
||||
upload_dir.close()
|
||||
namespace.loadModel(os.path.join(UPLOAD_DIR, configFile.filename), os.path.join(UPLOAD_DIR, modelFile.filename))
|
||||
return {"uploaded files": f"{configFile.filename}, {modelFile.filename} "}
|
||||
return {"Error": "uploaded file is not found."}
|
||||
|
||||
MODEL_DIR = "/MMVC_Trainer/logs"
|
||||
os.makedirs(MODEL_DIR, exist_ok=True)
|
||||
|
||||
@app_fastapi.post("/upload_file")
|
||||
async def post_upload_file(
|
||||
file:UploadFile = File(...),
|
||||
filename: str = Form(...)
|
||||
):
|
||||
|
||||
if file and filename:
|
||||
fileobj = file.file
|
||||
upload_dir = open(os.path.join(UPLOAD_DIR, filename),'wb+')
|
||||
shutil.copyfileobj(fileobj, upload_dir)
|
||||
upload_dir.close()
|
||||
return {"uploaded files": f"{filename} "}
|
||||
return {"Error": "uploaded file is not found."}
|
||||
return upload_file(UPLOAD_DIR, file, filename)
|
||||
|
||||
@app_fastapi.post("/load_model")
|
||||
async def post_load_model(
|
||||
@ -216,33 +237,40 @@ if __name__ == thisFilename or args.colab == True:
|
||||
configFilename: str = Form(...)
|
||||
):
|
||||
|
||||
target_file_name = modelFilename
|
||||
with open(os.path.join(UPLOAD_DIR, target_file_name), "ab") as target_file:
|
||||
for i in range(modelFilenameChunkNum):
|
||||
filename = f"{modelFilename}_{i}"
|
||||
chunk_file_path = os.path.join(UPLOAD_DIR,filename)
|
||||
stored_chunk_file = open(chunk_file_path, 'rb')
|
||||
target_file.write(stored_chunk_file.read())
|
||||
stored_chunk_file.close()
|
||||
os.unlink(chunk_file_path)
|
||||
target_file.close()
|
||||
print(f'File saved to: {target_file_name}')
|
||||
modelFilePath = concat_file_chunks(UPLOAD_DIR, modelFilename, modelFilenameChunkNum,UPLOAD_DIR)
|
||||
print(f'File saved to: {modelFilePath}')
|
||||
configFilePath = os.path.join(UPLOAD_DIR, configFilename)
|
||||
|
||||
print(f'Load: {configFilename}, {target_file_name}')
|
||||
namespace.loadModel(os.path.join(UPLOAD_DIR, configFilename), os.path.join(UPLOAD_DIR, target_file_name))
|
||||
return {"File saved to": f"{target_file_name}"}
|
||||
namespace.loadModel(configFilePath, modelFilePath)
|
||||
return {"load": f"{modelFilePath}, {configFilePath}"}
|
||||
|
||||
@app_fastapi.post("/load_model_for_train")
|
||||
async def post_load_model_for_train(
|
||||
modelGFilename: str = Form(...),
|
||||
modelGFilenameChunkNum: int = Form(...),
|
||||
modelDFilename: str = Form(...),
|
||||
modelDFilenameChunkNum: int = Form(...),
|
||||
):
|
||||
|
||||
|
||||
modelGFilePath = concat_file_chunks(UPLOAD_DIR, modelGFilename, modelGFilenameChunkNum, MODEL_DIR)
|
||||
modelDFilePath = concat_file_chunks(UPLOAD_DIR, modelDFilename, modelDFilenameChunkNum,MODEL_DIR)
|
||||
return {"File saved": f"{modelGFilePath}, {modelDFilePath}"}
|
||||
|
||||
|
||||
@app_fastapi.post("/extract_voices")
|
||||
async def post_load_model(
|
||||
zipFilename: str = Form(...),
|
||||
zipFileChunkNum: int = Form(...),
|
||||
):
|
||||
zipFilePath = concat_file_chunks(UPLOAD_DIR, zipFilename, zipFileChunkNum, UPLOAD_DIR)
|
||||
shutil.unpack_archive(zipFilePath, "/MMVC_Trainer/dataset/textful/")
|
||||
return {"Zip file unpacked": f"{zipFilePath}"}
|
||||
|
||||
@app_fastapi.get("/transcribe")
|
||||
def get_transcribe():
|
||||
try:
|
||||
namespace.transcribe()
|
||||
except Exception as e:
|
||||
print("TRANSCRIBE PROCESSING!!!! EXCEPTION!!!", e)
|
||||
print(traceback.format_exc())
|
||||
return str(e)
|
||||
|
||||
############
|
||||
# Voice Changer
|
||||
# ##########
|
||||
@app_fastapi.post("/test")
|
||||
async def post_test(voice:VoiceModel):
|
||||
try:
|
||||
@ -284,6 +312,68 @@ if __name__ == thisFilename or args.colab == True:
|
||||
return str(e)
|
||||
|
||||
|
||||
# Trainer REST API ※ ColabがTop直下のパスにしかPOSTを投げれないようなので"REST風"
|
||||
@app_fastapi.get("/get_speakers")
|
||||
async def get_speakers():
|
||||
return mod_get_speakers()
|
||||
|
||||
@app_fastapi.delete("/delete_speaker")
|
||||
async def delete_speaker(speaker:str= Form(...)):
|
||||
return mod_delete_speaker(speaker)
|
||||
|
||||
@app_fastapi.get("/get_speaker_voices")
|
||||
async def get_speaker_voices(speaker:str):
|
||||
return mod_get_speaker_voices(speaker)
|
||||
|
||||
@app_fastapi.get("/get_speaker_voice")
|
||||
async def get_speaker_voices(speaker:str, voice:str):
|
||||
return mod_get_speaker_voice(speaker, voice)
|
||||
|
||||
|
||||
@app_fastapi.get("/get_multi_speaker_setting")
|
||||
async def get_multi_speaker_setting():
|
||||
return mod_get_multi_speaker_setting()
|
||||
|
||||
@app_fastapi.post("/post_multi_speaker_setting")
|
||||
async def post_multi_speaker_setting(setting: str = Form(...)):
|
||||
return mod_post_multi_speaker_setting(setting)
|
||||
|
||||
@app_fastapi.get("/get_models")
|
||||
async def get_models():
|
||||
return mod_get_models()
|
||||
|
||||
@app_fastapi.get("/get_model")
|
||||
async def get_model(model:str):
|
||||
return mod_get_model(model)
|
||||
|
||||
@app_fastapi.delete("/delete_model")
|
||||
async def delete_model(model:str= Form(...)):
|
||||
return mod_delete_model(model)
|
||||
|
||||
|
||||
@app_fastapi.post("/post_pre_training")
|
||||
async def post_pre_training(batch:int= Form(...)):
|
||||
return mod_post_pre_training(batch)
|
||||
|
||||
@app_fastapi.post("/post_start_training")
|
||||
async def post_start_training():
|
||||
print("POST START TRAINING..")
|
||||
return mod_post_start_training()
|
||||
|
||||
@app_fastapi.post("/post_stop_training")
|
||||
async def post_stop_training():
|
||||
print("POST STOP TRAINING..")
|
||||
return mod_post_stop_training()
|
||||
|
||||
@app_fastapi.get("/get_related_files")
|
||||
async def get_related_files():
|
||||
return mod_get_related_files()
|
||||
|
||||
@app_fastapi.get("/get_tail_training_log")
|
||||
async def get_tail_training_log(num:int):
|
||||
return mod_get_tail_training_log(num)
|
||||
|
||||
|
||||
if __name__ == '__mp_main__':
|
||||
printMessage(f"PHASE2:{__name__}", level=2)
|
||||
|
||||
|
27
demo/mods/FileUploader.py
Executable file
27
demo/mods/FileUploader.py
Executable file
@ -0,0 +1,27 @@
|
||||
import os, shutil
|
||||
from fastapi import UploadFile
|
||||
|
||||
# UPLOAD_DIR = "model_upload_dir"
|
||||
|
||||
def upload_file(upload_dirname:str, file:UploadFile, filename: str):
|
||||
if file and filename:
|
||||
fileobj = file.file
|
||||
upload_dir = open(os.path.join(upload_dirname, filename),'wb+')
|
||||
shutil.copyfileobj(fileobj, upload_dir)
|
||||
upload_dir.close()
|
||||
return {"uploaded files": f"{filename} "}
|
||||
return {"Error": "uploaded file is not found."}
|
||||
|
||||
def concat_file_chunks(upload_dirname:str, filename:str, chunkNum:int, dest_dirname:str):
|
||||
target_file_name = os.path.join(dest_dirname, filename)
|
||||
with open(target_file_name, "ab") as target_file:
|
||||
for i in range(chunkNum):
|
||||
chunkName = f"{filename}_{i}"
|
||||
chunk_file_path = os.path.join(upload_dirname, chunkName)
|
||||
stored_chunk_file = open(chunk_file_path, 'rb')
|
||||
target_file.write(stored_chunk_file.read())
|
||||
stored_chunk_file.close()
|
||||
os.unlink(chunk_file_path)
|
||||
target_file.close()
|
||||
return target_file_name
|
||||
|
13
demo/mods/Trainer_Model.py
Executable file
13
demo/mods/Trainer_Model.py
Executable file
@ -0,0 +1,13 @@
|
||||
|
||||
from fastapi.responses import FileResponse
|
||||
import os
|
||||
|
||||
def mod_get_model(modelFile:str):
|
||||
modelPath = os.path.join("/MMVC_Trainer/logs", modelFile)
|
||||
return FileResponse(path=modelPath)
|
||||
|
||||
def mod_delete_model(modelFile:str):
|
||||
modelPath = os.path.join("/MMVC_Trainer/logs", modelFile)
|
||||
os.unlink(modelPath)
|
||||
return {"Model deleted": f"{modelFile}"}
|
||||
|
21
demo/mods/Trainer_Models.py
Executable file
21
demo/mods/Trainer_Models.py
Executable file
@ -0,0 +1,21 @@
|
||||
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from trainer_mods.files import get_file_list
|
||||
import os
|
||||
|
||||
def mod_get_models():
|
||||
gModels = get_file_list(f'/MMVC_Trainer/logs/G*.pth')
|
||||
dModels = get_file_list(f'/MMVC_Trainer/logs/D*.pth')
|
||||
models = []
|
||||
models.extend(gModels)
|
||||
models.extend(dModels)
|
||||
models = [ os.path.basename(x) for x in models]
|
||||
|
||||
models = sorted(models)
|
||||
data = {
|
||||
"models":models
|
||||
}
|
||||
json_compatible_item_data = jsonable_encoder(data)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
||||
|
26
demo/mods/Trainer_MultiSpeakerSetting.py
Executable file
26
demo/mods/Trainer_MultiSpeakerSetting.py
Executable file
@ -0,0 +1,26 @@
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
import os
|
||||
|
||||
MULTI_SPEAKER_SETTING_PATH = "/MMVC_Trainer/dataset/multi_speaker_correspondence.txt"
|
||||
def mod_get_multi_speaker_setting():
|
||||
data = {}
|
||||
if os.path.isfile(MULTI_SPEAKER_SETTING_PATH) == False:
|
||||
with open(MULTI_SPEAKER_SETTING_PATH, "w") as f:
|
||||
f.write("")
|
||||
f.flush()
|
||||
f.close()
|
||||
|
||||
with open(MULTI_SPEAKER_SETTING_PATH, "r") as f:
|
||||
setting = f.read()
|
||||
data["multi_speaker_setting"] = setting
|
||||
json_compatible_item_data = jsonable_encoder(data)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
||||
|
||||
|
||||
def mod_post_multi_speaker_setting(setting:str):
|
||||
with open(MULTI_SPEAKER_SETTING_PATH, "w") as f:
|
||||
f.write(setting)
|
||||
f.flush()
|
||||
f.close()
|
||||
return {"Write Multispeaker setting": f"{setting}"}
|
15
demo/mods/Trainer_Speaker.py
Executable file
15
demo/mods/Trainer_Speaker.py
Executable file
@ -0,0 +1,15 @@
|
||||
import shutil
|
||||
from mods.Trainer_MultiSpeakerSetting import MULTI_SPEAKER_SETTING_PATH
|
||||
|
||||
def mod_delete_speaker(speaker:str):
|
||||
shutil.rmtree(f"/MMVC_Trainer/dataset/textful/{speaker}")
|
||||
|
||||
with open(MULTI_SPEAKER_SETTING_PATH, "r") as f:
|
||||
setting = f.readlines()
|
||||
|
||||
filtered = filter(lambda x: x.startswith(f"{speaker}|")==False, setting)
|
||||
with open(MULTI_SPEAKER_SETTING_PATH, "w") as f:
|
||||
f.writelines(list(filtered))
|
||||
f.flush()
|
||||
f.close()
|
||||
return {"Speaker deleted": f"{speaker}"}
|
28
demo/mods/Trainer_Speaker_Voice.py
Executable file
28
demo/mods/Trainer_Speaker_Voice.py
Executable file
@ -0,0 +1,28 @@
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
import os, base64
|
||||
|
||||
def mod_get_speaker_voice(speaker:str, voice:str):
|
||||
wav_file = f'/MMVC_Trainer/dataset/textful/{speaker}/wav/{voice}.wav'
|
||||
text_file = f'/MMVC_Trainer/dataset/textful/{speaker}/text/{voice}.txt'
|
||||
readable_text_file = f'/MMVC_Trainer/dataset/textful/{speaker}/readable_text/{voice}.txt'
|
||||
|
||||
data = {}
|
||||
if os.path.exists(wav_file):
|
||||
with open(wav_file, "rb") as f:
|
||||
wav_data = f.read()
|
||||
wav_data_base64 = base64.b64encode(wav_data).decode('utf-8')
|
||||
data["wav"] = wav_data_base64
|
||||
|
||||
|
||||
if os.path.exists(text_file):
|
||||
with open(text_file, "r") as f:
|
||||
text_data = f.read()
|
||||
data["text"] = text_data
|
||||
|
||||
if os.path.exists(readable_text_file):
|
||||
with open(readable_text_file, "r") as f:
|
||||
text_data = f.read()
|
||||
data["readable_text"] = text_data
|
||||
json_compatible_item_data = jsonable_encoder(data)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
22
demo/mods/Trainer_Speaker_Voices.py
Executable file
22
demo/mods/Trainer_Speaker_Voices.py
Executable file
@ -0,0 +1,22 @@
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from trainer_mods.files import get_file_list
|
||||
import os
|
||||
|
||||
def mod_get_speaker_voices(speaker:str):
|
||||
voices = get_file_list(f'/MMVC_Trainer/dataset/textful/{speaker}/wav/*.wav')
|
||||
|
||||
texts = get_file_list(f'/MMVC_Trainer/dataset/textful/{speaker}/text/*.txt')
|
||||
|
||||
readable_texts = get_file_list(f'/MMVC_Trainer/dataset/textful/{speaker}/readable_text/*.txt')
|
||||
|
||||
items = voices
|
||||
items.extend(texts)
|
||||
items.extend(readable_texts)
|
||||
items = [ os.path.splitext(os.path.basename(x))[0] for x in items]
|
||||
items = sorted(set(items))
|
||||
data = {
|
||||
"voices":items
|
||||
}
|
||||
json_compatible_item_data = jsonable_encoder(data)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
15
demo/mods/Trainer_Speakers.py
Executable file
15
demo/mods/Trainer_Speakers.py
Executable file
@ -0,0 +1,15 @@
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from trainer_mods.files import get_dir_list
|
||||
import os
|
||||
# CreateはFileUploaderで実装。
|
||||
|
||||
def mod_get_speakers():
|
||||
os.makedirs("/MMVC_Trainer/dataset/textful", exist_ok=True)
|
||||
speakers = get_dir_list("/MMVC_Trainer/dataset/textful/")
|
||||
|
||||
data = {
|
||||
"speakers":sorted(speakers)
|
||||
}
|
||||
json_compatible_item_data = jsonable_encoder(data)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
167
demo/mods/Trainer_Training.py
Executable file
167
demo/mods/Trainer_Training.py
Executable file
@ -0,0 +1,167 @@
|
||||
import subprocess,os
|
||||
from trainer_mods.files import get_file_list
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
||||
LOG_DIR = "/MMVC_Trainer/info"
|
||||
train_proc = None
|
||||
|
||||
SUCCESS = 0
|
||||
ERROR = -1
|
||||
### Submodule for Pre train
|
||||
def sync_exec(cmd:str, log_path:str):
|
||||
shortCmdStr = cmd[:20]
|
||||
try:
|
||||
with open(log_path, 'w') as log_file:
|
||||
proc = subprocess.run(cmd, shell=True, text=True, stdout=log_file, stderr=log_file, cwd="/MMVC_Trainer")
|
||||
print(f"{shortCmdStr} returncode:{proc.returncode}")
|
||||
if proc.returncode != 0:
|
||||
print(f"{shortCmdStr} exception:")
|
||||
return (ERROR, f"returncode:{proc.returncode}")
|
||||
except Exception as e:
|
||||
print(f"{shortCmdStr} exception:", str(e))
|
||||
return (ERROR, str(e))
|
||||
return (SUCCESS, "success")
|
||||
|
||||
def sync_exec_with_stdout(cmd:str, log_path:str):
|
||||
shortCmdStr = cmd[:20]
|
||||
try:
|
||||
with open(log_path, 'w') as log_file:
|
||||
proc = subprocess.run(cmd, shell=True, text=True, stdout=subprocess.PIPE,
|
||||
stderr=log_file, cwd="/MMVC_Trainer")
|
||||
print(f"STDOUT{shortCmdStr}",proc.stdout)
|
||||
except Exception as e:
|
||||
print(f"{shortCmdStr} exception:", str(e))
|
||||
return (ERROR, str(e))
|
||||
return (SUCCESS, proc.stdout)
|
||||
|
||||
|
||||
def create_dataset():
|
||||
cmd = "python3 create_dataset_jtalk.py -f train_config -s 24000 -m dataset/multi_speaker_correspondence.txt"
|
||||
log_file = os.path.join(LOG_DIR, "log_create_dataset_jtalk.txt")
|
||||
res = sync_exec(cmd, log_file)
|
||||
return res
|
||||
|
||||
def set_batch_size(batch:int):
|
||||
cmd = "sed -i 's/\"batch_size\": [0-9]*/\"batch_size\": " + str(batch) + "/' /MMVC_Trainer/configs/baseconfig.json"
|
||||
log_file = os.path.join(LOG_DIR, "log_set_batch_size.txt")
|
||||
res = sync_exec(cmd, log_file)
|
||||
return res
|
||||
|
||||
def set_dummy_device_count():
|
||||
cmd = 'sed -ie "s/torch.cuda.device_count()/1/" /MMVC_Trainer/train_ms.py'
|
||||
log_file = os.path.join(LOG_DIR, "log_set_dummy_device_count.txt")
|
||||
res = sync_exec(cmd, log_file)
|
||||
return res
|
||||
|
||||
### Submodule for Train
|
||||
def exec_training():
|
||||
global train_proc
|
||||
log_file = os.path.join(LOG_DIR, "training.txt")
|
||||
|
||||
# トレーニング開始確認(二重起動回避)
|
||||
if train_proc != None:
|
||||
status = train_proc.poll()
|
||||
if status != None:
|
||||
print("Training have ended.", status)
|
||||
train_proc = None
|
||||
else:
|
||||
print("Training have stated.")
|
||||
return (ERROR, "Training have started")
|
||||
|
||||
try:
|
||||
with open(log_file, 'w') as log_file:
|
||||
cmd = 'python3 train_ms.py -c configs/train_config.json -m ./'
|
||||
print("exec:",cmd)
|
||||
train_proc = subprocess.Popen("exec "+cmd, shell=True, text=True, stdout=log_file, stderr=log_file, cwd="/MMVC_Trainer")
|
||||
print("Training stated")
|
||||
print(f"returncode:{train_proc.returncode}")
|
||||
except Exception as e:
|
||||
print("start training exception:", str(e))
|
||||
return (ERROR, str(e))
|
||||
|
||||
return (SUCCESS, "success")
|
||||
|
||||
def stop_training():
|
||||
global train_proc
|
||||
if train_proc == None:
|
||||
print("Training have not stated.")
|
||||
return (ERROR, "Training have not stated.")
|
||||
|
||||
status = train_proc.poll()
|
||||
if status != None:
|
||||
print("Training have already ended.", status)
|
||||
train_proc = None
|
||||
return (ERROR, "Training have already ended. " + status)
|
||||
else:
|
||||
train_proc.kill()
|
||||
print("Training have stoped.")
|
||||
return (SUCCESS, "success")
|
||||
|
||||
### Main
|
||||
def mod_post_pre_training(batch:int):
|
||||
res = set_batch_size(batch)
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Preprocess(set_batch_size) failed. {res[1]}"}
|
||||
|
||||
res = set_dummy_device_count()
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Preprocess(set_dummy_device_count) failed. {res[1]}"}
|
||||
|
||||
res = create_dataset()
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Preprocess failed(create_dataset). {res[1]}"}
|
||||
|
||||
return {"result":"success", "detail": f"Preprocess succeeded. {res[1]}"}
|
||||
|
||||
|
||||
def mod_post_start_training():
|
||||
res = exec_training()
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Start training failed. {res[1]}"}
|
||||
|
||||
return {"result":"success", "detail": f"Start training succeeded. {res[1]}"}
|
||||
|
||||
def mod_post_stop_training():
|
||||
res = stop_training()
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Stop training failed. {res[1]}"}
|
||||
|
||||
return {"result":"success", "detail": f"Stop training succeeded. {res[1]}"}
|
||||
|
||||
### DEBUG
|
||||
def mod_get_related_files():
|
||||
files = get_file_list(os.path.join(LOG_DIR,"*"))
|
||||
files.extend([
|
||||
"/MMVC_Trainer/dataset/multi_speaker_correspondence.txt",
|
||||
"/MMVC_Trainer/train_ms.py",
|
||||
])
|
||||
files.extend(
|
||||
get_file_list("/MMVC_Trainer/configs/*")
|
||||
)
|
||||
|
||||
res = []
|
||||
for f in files:
|
||||
size = os.path.getsize(f)
|
||||
data = ""
|
||||
if size < 1024*1024:
|
||||
with open(f, "r") as input:
|
||||
data = input.read()
|
||||
|
||||
res.append({
|
||||
"name":f,
|
||||
"size":size,
|
||||
"data":data
|
||||
})
|
||||
|
||||
json_compatible_item_data = jsonable_encoder(res)
|
||||
return JSONResponse(content=json_compatible_item_data)
|
||||
|
||||
def mod_get_tail_training_log(num:int):
|
||||
training_log_file = os.path.join(LOG_DIR, "training.txt")
|
||||
res = sync_exec(f"cat {training_log_file} | sed -e 's/.*\r//' > /tmp/out","/dev/null")
|
||||
cmd = f'tail -n {num} /tmp/out'
|
||||
res = sync_exec_with_stdout(cmd, "/dev/null")
|
||||
if res[0] == ERROR:
|
||||
return {"result":"failed", "detail": f"Tail training log failed. {res[1]}"}
|
||||
return {"result":"success", "detail":res[1]}
|
19
demo/trainer_mods/files.py
Executable file
19
demo/trainer_mods/files.py
Executable file
@ -0,0 +1,19 @@
|
||||
import os,glob
|
||||
|
||||
|
||||
def get_file_list(top_dir):
|
||||
for root, dirs, files in os.walk(top_dir):
|
||||
for dir in dirs:
|
||||
dirPath = os.path.join(root, dir)
|
||||
print(f'dirPath = {dirPath}')
|
||||
|
||||
for file in files:
|
||||
filePath = os.path.join(root, file)
|
||||
print(f'filePath = {filePath}')
|
||||
|
||||
|
||||
def get_dir_list(top_dir):
|
||||
return os.listdir(top_dir)
|
||||
|
||||
def get_file_list(top_dir):
|
||||
return glob.glob(top_dir)
|
@ -1,4 +1,4 @@
|
||||
FROM dannadori/voice-changer-internal:20221104_061809 as front
|
||||
FROM dannadori/voice-changer-internal:20221109_051139 as front
|
||||
FROM debian:bullseye-slim as base
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
@ -60,7 +60,6 @@ COPY --from=base --chmod=777 /usr/local/lib/python3.9/dist-packages /usr/local/l
|
||||
COPY --from=front --chmod=777 /MMVC_Trainer /MMVC_Trainer
|
||||
RUN chmod 0777 /MMVC_Trainer
|
||||
|
||||
WORKDIR /MMVC_Trainer
|
||||
ADD /setup.sh /MMVC_Trainer/
|
||||
ADD /exec.sh /MMVC_Trainer/
|
||||
|
||||
@ -69,6 +68,10 @@ COPY --from=front --chmod=777 /voice-changer-internal/frontend/dist /voice-chang
|
||||
COPY --from=front --chmod=777 /voice-changer-internal/voice-change-service /voice-changer-internal/voice-change-service
|
||||
RUN chmod 0777 /voice-changer-internal/voice-change-service
|
||||
|
||||
|
||||
## 歴史的な経緯でsetup.shをMMVC_Trainerに置いているのでそこを起動時のWORKDIRにしている。
|
||||
WORKDIR /MMVC_Trainer
|
||||
|
||||
# ##### Soft VC
|
||||
# COPY --from=front /hubert /hubert
|
||||
# COPY --from=front /acoustic-model /acoustic-model
|
@ -39,16 +39,17 @@ if [ "${MODE}" = "MMVC" ] ; then
|
||||
# python3 MMVCServerSIO.py $PARAMS 2>stderr.txt
|
||||
# fi
|
||||
echo "MMVCを起動します"
|
||||
python3 MMVCServerSIO.py $PARAMS 2>stderr.txt
|
||||
python3 MMVCServerSIO.py $PARAMS #2>stderr.txt
|
||||
|
||||
elif [ "${MODE}" = "MMVC_TRAIN" ] ; then
|
||||
python3 create_dataset_jtalk.py -f train_config -s 24000 -m dataset/multi_speaker_correspondence.txt
|
||||
# date_tag=`date +%Y%m%d%H%M%S`
|
||||
sed -ie 's/80000/8000/' train_ms.py
|
||||
sed -ie "s/\"batch_size\": 10/\"batch_size\": $batch_size/" configs/train_config.json
|
||||
sed -ie "s/torch.cuda.device_count()/1/" train_ms.py
|
||||
python3 -m tensorboard.main --logdir logs --port 6006 --host 0.0.0.0 &
|
||||
python3 train_ms.py $PARAMS
|
||||
cd /voice-changer-internal/voice-change-service
|
||||
# python3 create_dataset_jtalk.py -f train_config -s 24000 -m dataset/multi_speaker_correspondence.txt
|
||||
# # date_tag=`date +%Y%m%d%H%M%S`
|
||||
# sed -ie 's/80000/8000/' train_ms.py
|
||||
# sed -ie "s/\"batch_size\": 10/\"batch_size\": $batch_size/" configs/train_config.json
|
||||
# sed -ie "s/torch.cuda.device_count()/1/" train_ms.py
|
||||
python3 -m tensorboard.main --logdir /MMVC_Trainer/logs --port 6006 --host 0.0.0.0 &
|
||||
python3 MMVCServerSIO.py $PARAMS
|
||||
# if ${resume_flag}; then
|
||||
# echo "トレーニング再開。バッチサイズ: ${batch_size}。"
|
||||
# python3 train_ms.py -c configs/train_config.json -m vc
|
@ -3,11 +3,12 @@
|
||||
# 参考:https://programwiz.org/2022/03/22/how-to-write-shell-script-for-option-parsing/
|
||||
|
||||
set -eu
|
||||
|
||||
echo "1"
|
||||
# 実行ユーザ作成
|
||||
USER_ID=${LOCAL_UID:-9001}
|
||||
GROUP_ID=${LOCAL_GID:-9001}
|
||||
|
||||
echo "2"
|
||||
echo "exec with [UID : $USER_ID, GID: $GROUP_ID]"
|
||||
useradd -u $USER_ID -o -m user
|
||||
groupmod -g $GROUP_ID user
|
1
docs/assets/icons/help-circle.svg
Normal file
1
docs/assets/icons/help-circle.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-help-circle"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
After Width: | Height: | Size: 365 B |
BIN
docs/assets/icons/zun.png
Normal file
BIN
docs/assets/icons/zun.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -2,6 +2,9 @@
|
||||
"app_title": "voice-recorder",
|
||||
"storage_type":"local",
|
||||
"use_mel_spectrogram":true,
|
||||
"current_text":"ITA-emotion",
|
||||
"current_text_index":0,
|
||||
"sample_rate":48000,
|
||||
"text": [
|
||||
{
|
||||
"title": "ITA-emotion",
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,12 +5,6 @@
|
||||
(c) 2013-2017 Mozilla, Apache License 2.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com
|
||||
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||
* Copyright 2022 Fonticons, Inc.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
@ -19,7 +13,7 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
* wavesurfer.js 6.2.0 (2022-05-16)
|
||||
* wavesurfer.js 6.4.0 (2022-11-05)
|
||||
* https://wavesurfer-js.org
|
||||
* @license BSD-3-Clause
|
||||
*/
|
||||
|
4
frontend/dist/assets/setting_recorder.json
vendored
Executable file
4
frontend/dist/assets/setting_recorder.json
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"app_title": "recorder",
|
||||
"majar_mode": "docker"
|
||||
}
|
4
frontend/dist/assets/setting_trainer.json
vendored
Executable file
4
frontend/dist/assets/setting_trainer.json
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"app_title": "trainer",
|
||||
"majar_mode": "docker"
|
||||
}
|
2
frontend/dist/index.html
vendored
2
frontend/dist/index.html
vendored
@ -1 +1 @@
|
||||
<!doctype html><html lang="ja" style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>voice recorder</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div><noscript><strong>javascriptを有効にしてください</strong></noscript></body></html>
|
||||
<!doctype html><html lang="ja" style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>Realtime Voice Changer (Train/VC)</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div><noscript><strong>javascriptを有効にしてください</strong></noscript></body></html>
|
2
frontend/dist/index.js
vendored
2
frontend/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -4,7 +4,7 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build:docker": "date +%Y%m%d%H%M%S > trainer/dummy && DOCKER_BUILDKIT=1 docker build -f trainer/Dockerfile trainer/ -t voice-changer",
|
||||
"build:docker": "date +%Y%m%d%H%M%S > docker/dummy && DOCKER_BUILDKIT=1 docker build -f docker/Dockerfile docker/ -t voice-changer",
|
||||
"copy:frontend":"docker run -v `pwd`/frontend/dist:/frontend/dist --entrypoint /bin/bash -ti voice-changer -c \"cp -r /voice-changer-internal/frontend/dist/* /frontend/dist\"",
|
||||
"copy:backend":"docker run -v `pwd`/demo:/demo --entrypoint /bin/bash -ti voice-changer -c \"cp -r /voice-changer-internal/voice-change-service/* /demo/\"",
|
||||
"create:demo":"run-p copy:frontend copy:backend",
|
||||
|
21
start2.sh
21
start2.sh
@ -1,20 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
DOCKER_IMAGE=dannadori/voice-changer:20221104_062009
|
||||
#DOCKER_IMAGE=voice-changer
|
||||
|
||||
#DOCKER_IMAGE=dannadori/voice-changer:20221108_105937
|
||||
DOCKER_IMAGE=voice-changer
|
||||
|
||||
MODE=$1
|
||||
PARAMS=${@:2:($#-1)}
|
||||
|
||||
### DEFAULT VAR ###
|
||||
DEFAULT_EX_PORT=18888
|
||||
DEFAULT_EX_TB_PORT=16006
|
||||
DEFAULT_USE_GPU=on # on|off
|
||||
# DEFAULT_VERBOSE=off # on|off
|
||||
|
||||
### ENV VAR ###
|
||||
EX_PORT=${EX_PORT:-${DEFAULT_EX_PORT}}
|
||||
EX_TB_PORT=${EX_TB_PORT:-${DEFAULT_EX_TB_PORT}}
|
||||
USE_GPU=${USE_GPU:-${DEFAULT_USE_GPU}}
|
||||
# VERBOSE=${VERBOSE:-${DEFAULT_VERBOSE}}
|
||||
|
||||
@ -30,16 +31,16 @@ if [ "${MODE}" = "MMVC_TRAIN" ]; then
|
||||
echo "トレーニングを開始します"
|
||||
|
||||
docker run -it --gpus all --shm-size=128M \
|
||||
-v `pwd`/exp/${name}/dataset:/MMVC_Trainer/dataset \
|
||||
-v `pwd`/exp/${name}/logs:/MMVC_Trainer/logs \
|
||||
-v `pwd`/exp/${name}/filelists:/MMVC_Trainer/filelists \
|
||||
-v `pwd`/vc_resources:/resources \
|
||||
-v `pwd`/work_dir/logs:/MMVC_Trainer/logs \
|
||||
-v `pwd`/work_dir/dataset:/MMVC_Trainer/dataset \
|
||||
-v `pwd`/work_dir/info:/MMVC_Trainer/info \
|
||||
-e LOCAL_UID=$(id -u $USER) \
|
||||
-e LOCAL_GID=$(id -g $USER) \
|
||||
-e EX_PORT=${EX_PORT} -e EX_TB_PORT=${EX_TB_PORT} \
|
||||
-e EX_IP="`hostname -I`" \
|
||||
-e EX_PORT=${EX_PORT} \
|
||||
-e VERBOSE=${VERBOSE} \
|
||||
-p ${EX_PORT}:6006 $DOCKER_IMAGE "$@"
|
||||
-p ${EX_PORT}:8080 -p ${EX_TB_PORT}:6006 \
|
||||
$DOCKER_IMAGE "$@"
|
||||
|
||||
|
||||
elif [ "${MODE}" = "MMVC" ]; then
|
||||
if [ "${USE_GPU}" = "on" ]; then
|
||||
|
53
template.sh
53
template.sh
@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
EXP_NAME=$1
|
||||
|
||||
echo $EXP_NAME
|
||||
|
||||
# (A)
|
||||
mkdir -p exp/${EXP_NAME}/logs
|
||||
mkdir -p exp/${EXP_NAME}/filelists
|
||||
|
||||
mkdir -p exp/${EXP_NAME}/dataset
|
||||
echo "00_myvoice|107" > exp/${EXP_NAME}/dataset/multi_speaker_correspondence.txt
|
||||
echo "01_target_zundamon|100" >> exp/${EXP_NAME}/dataset/multi_speaker_correspondence.txt
|
||||
echo "02_target_tsumugi|103" >> exp/${EXP_NAME}/dataset/multi_speaker_correspondence.txt
|
||||
echo "03_target_metan|102" >> exp/${EXP_NAME}/dataset/multi_speaker_correspondence.txt
|
||||
echo "04_target_ksora|101" >> exp/${EXP_NAME}/dataset/multi_speaker_correspondence.txt
|
||||
|
||||
# (B) トレーニングデータ作成
|
||||
# (B-0) my voice
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/00_myvoice/text
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/00_myvoice/wav
|
||||
cp dataset/00_myvoice/wav/* exp/${EXP_NAME}/dataset/textful/00_myvoice/wav/
|
||||
cp dataset/00_myvoice/text/* exp/${EXP_NAME}/dataset/textful/00_myvoice/text/
|
||||
|
||||
|
||||
# (B-1) ずんだもん
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/01_target_zundamon/
|
||||
unzip -j dataset/1225_zundamon.zip 1225_zundamon/wav/* -d exp/${EXP_NAME}/dataset/textful/01_target_zundamon/wav/
|
||||
unzip -j dataset/1225_zundamon.zip 1225_zundamon/text/* -d exp/${EXP_NAME}/dataset/textful/01_target_zundamon/text/
|
||||
|
||||
# (B-2) 春日部つむぎ
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/02_target_tsumugi/
|
||||
unzip -j dataset/344_tsumugi.zip 344_tsumugi/wav/* -d exp/${EXP_NAME}/dataset/textful/02_target_tsumugi/wav/
|
||||
unzip -j dataset/344_tsumugi.zip 344_tsumugi/text/* -d exp/${EXP_NAME}/dataset/textful/02_target_tsumugi/text/
|
||||
|
||||
# (B-3) 四国めたん
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/03_target_metan/
|
||||
unzip -j dataset/459_methane.zip 459_methane/wav/* -d exp/${EXP_NAME}/dataset/textful/03_target_metan/wav/
|
||||
unzip -j dataset/459_methane.zip 459_methane/text/* -d exp/${EXP_NAME}/dataset/textful/03_target_metan/text/
|
||||
|
||||
# (B-4) 九州そら
|
||||
mkdir -p exp/${EXP_NAME}/dataset/textful/04_target_ksora/
|
||||
unzip -j dataset/912_sora.zip 912_sora/wav/* -d exp/${EXP_NAME}/dataset/textful/04_target_ksora/wav/
|
||||
unzip -j dataset/912_sora.zip 912_sora/text/* -d exp/${EXP_NAME}/dataset/textful/04_target_ksora/text/
|
||||
|
||||
## 004_expまで。
|
||||
# echo $1
|
||||
# mkdir -p ${EXP_NAME}/00_myvoice/text
|
||||
# mkdir -p ${EXP_NAME}/00_myvoice/wav
|
||||
# mkdir -p ${EXP_NAME}/logs
|
||||
# mkdir -p ${EXP_NAME}/filelists
|
||||
|
||||
|
133
trainer/exec_.sh
133
trainer/exec_.sh
@ -1,133 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 参考:https://programwiz.org/2022/03/22/how-to-write-shell-script-for-option-parsing/
|
||||
|
||||
set -eu
|
||||
|
||||
echo "------"
|
||||
echo "$@"
|
||||
echo "------"
|
||||
|
||||
usage() {
|
||||
echo "
|
||||
usage:
|
||||
For training
|
||||
$0 [-t] [-b batch_size] [-r]
|
||||
-t: flag for training mode
|
||||
-b: batch_size.
|
||||
-r: flag for resuming training.
|
||||
For changing voice
|
||||
$0 [-v] [-c config] [-m model]
|
||||
-v: flag for voice change mode
|
||||
-c: config
|
||||
-m: model name
|
||||
For help
|
||||
$0 [-h]
|
||||
-h: show this help
|
||||
" >&2
|
||||
}
|
||||
warn () {
|
||||
echo "! ! ! $1 ! ! !"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
training_flag=false
|
||||
batch_size=10
|
||||
resume_flag=false
|
||||
|
||||
voice_change_flag=false
|
||||
config=
|
||||
model=
|
||||
|
||||
escape_flag=false
|
||||
|
||||
# オプション解析
|
||||
while getopts tb:rvc:m:hx OPT; do
|
||||
case $OPT in
|
||||
t)
|
||||
training_flag=true
|
||||
;;
|
||||
b)
|
||||
batch_size="$OPTARG"
|
||||
;;
|
||||
r)
|
||||
resume_flag=true
|
||||
;;
|
||||
v)
|
||||
voice_change_flag=true
|
||||
;;
|
||||
c)
|
||||
config="$OPTARG"
|
||||
;;
|
||||
m)
|
||||
model="$OPTARG"
|
||||
;;
|
||||
h | \?)
|
||||
usage && exit 1
|
||||
;;
|
||||
x)
|
||||
escape_flag=true
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
# ## コマンドライン引数から、オプション引数分を削除
|
||||
# # shift $((OPTIND - 1))
|
||||
|
||||
# # モード解析
|
||||
# if $training_flag && $voice_change_flag; then
|
||||
# warn "-t(トレーニングモード) と -v(ボイチェンモード)は同時に指定できません。"
|
||||
# exit 1
|
||||
# elif $training_flag; then
|
||||
# echo "■■■ ト レ ー ニ ン グ モ ー ド ■■■"
|
||||
# elif $voice_change_flag; then
|
||||
# echo "■■■ ボ イ チ ェ ン モ ー ド ■■■"
|
||||
# elif $escape_flag; then
|
||||
# /bin/bash
|
||||
# else
|
||||
# warn "-t(トレーニングモード) と -v(ボイチェンモード)のいずれかを指定してください。"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
|
||||
|
||||
if $training_flag; then
|
||||
|
||||
|
||||
python3 create_dataset_jtalk.py -f train_config -s 24000 -m dataset/multi_speaker_correspondence.txt
|
||||
# date_tag=`date +%Y%m%d%H%M%S`
|
||||
sed -ie 's/80000/8000/' train_ms.py
|
||||
sed -ie "s/\"batch_size\": 10/\"batch_size\": $batch_size/" configs/train_config.json
|
||||
sed -ie "s/torch.cuda.device_count()/1/" train_ms.py
|
||||
python3 -m tensorboard.main --logdir logs --port 6006 --host 0.0.0.0 &
|
||||
|
||||
if ${resume_flag}; then
|
||||
echo "トレーニング再開。バッチサイズ: ${batch_size}。"
|
||||
python3 train_ms.py -c configs/train_config.json -m vc
|
||||
else
|
||||
echo "トレーニング開始。バッチサイズ: ${batch_size}。"
|
||||
python3 train_ms.py -c configs/train_config.json -m vc -fg fine_model/G_180000.pth -fd fine_model/D_180000.pth
|
||||
fi
|
||||
fi
|
||||
|
||||
if $voice_change_flag; then
|
||||
if [[ -z "$config" ]]; then
|
||||
warn "コンフィグファイル(-c)を指定してください"
|
||||
fi
|
||||
if [[ -z "$model" ]]; then
|
||||
warn "モデルファイル(-m)を指定してください"
|
||||
fi
|
||||
|
||||
cd /voice-changer-internal/voice-change-service
|
||||
|
||||
cp -r /resources/* .
|
||||
if [[ -e ./setting.json ]]; then
|
||||
cp ./setting.json ../frontend/dist/assets/setting.json
|
||||
fi
|
||||
echo "-----------!!"
|
||||
echo $config $model
|
||||
echo $model
|
||||
python3 serverSIO.py -p 8080 -c $config -m $model --https True --httpsSelfSigned True
|
||||
fi
|
5
work_dir/.gitignore
vendored
Normal file
5
work_dir/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*
|
||||
!.gitignore
|
||||
!logs
|
||||
!info
|
||||
!dataset
|
3
work_dir/dataset/.gitignore
vendored
Normal file
3
work_dir/dataset/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
!textful
|
Loading…
x
Reference in New Issue
Block a user