This commit is contained in:
2024-02-14 17:49:51 +01:00
parent 79d81b96b1
commit 0594458865
22 changed files with 223 additions and 124 deletions

View File

@@ -1 +0,0 @@
from .gradio_ui import GenerateUI

View File

@@ -1,51 +0,0 @@
import importlib
import json
import os
import gradio as gr
from src import engines
class GenerateUI:
def __init__(self):
self.engines = self.get_engines()
def get_engines(self):
engines_d = {}
with open(os.path.join(os.getcwd(), "src", "engines", "engines.json"), "r") as f:
engine_types = json.load(f)
for engine_type, engine_list in engine_types.items():
engines_d[engine_type] = {}
for engine_name in engine_list:
module = importlib.import_module(f"src.engines.{engine_type}.{engine_name}")
engine_class = getattr(module, engine_name)
engines_d[engine_type][engine_name] = engine_class
return engines_d
def launch_ui(self):
with gr.Blocks() as main_block:
for engine_type, engines in self.engines.items():
switch_dropdown = gr.Dropdown(list(engines.keys()), label=engine_type)
engine_blocks = []
for engine_name, engine_class in engines.items():
with gr.Blocks(elem_id=f"{engine_type}_{engine_name}_block", visible=False) as engine_block:
options = engine_class().get_options()
for option in options:
engine_block.add(option)
engine_blocks.append(engine_block)
def switch_engine(engine_name, engine_blocks=engine_blocks, switch_dropdown=switch_dropdown):
for block in engine_blocks:
block.visible = block.elem_id.startswith(f"{engine_type}_{engine_name}")
switch_dropdown.change(switch_engine, inputs=[switch_dropdown], outputs=engine_blocks)
# Initially show the first engine's options
if engines:
first_engine_name = list(engines.keys())[0]
switch_engine(first_engine_name)
main_block.launch()
if __name__ == "__main__":
ui_generator = GenerateUI()
ui_generator.launch_ui()

View File

@@ -1,4 +1,4 @@
from interfaces import GenerateUI from ui import GenerateUI
if __name__ == "__main__": if __name__ == "__main__":
ui_generator = GenerateUI() ui_generator = GenerateUI()

View File

@@ -62,4 +62,5 @@ typing_extensions==4.9.0
tzdata==2024.1 tzdata==2024.1
urllib3==2.2.0 urllib3==2.2.0
uvicorn==0.27.1 uvicorn==0.27.1
websockets==11.0.3 websockets==11.0.3
TTS

View File

@@ -1 +1 @@
from . import engines from . import engines

View File

@@ -1,10 +1,16 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
import gradio as gr import gradio as gr
class BaseEngine(ABC): class BaseEngine(ABC):
options: list num_options: int
name: str name: str
description: str description: str
def __init__(self): def __init__(self):
pass pass
@classmethod
@abstractmethod
def get_options():
...

View File

@@ -0,0 +1,10 @@
from abc import ABC, abstractmethod
from ..BaseEngine import BaseEngine
import openai
class BaseLLMEngine(BaseEngine):
@abstractmethod
def generate(self, system_prompt: str, chat_prompt: str, max_tokens: int, temperature: float, top_p: float, frequency_penalty: float, presence_penalty: float) -> str:
pass

View File

@@ -0,0 +1,29 @@
import openai
import gradio as gr
from abc import ABC, abstractmethod
from .BaseLLMEngine import BaseLLMEngine
OPENAI_POSSIBLE_MODELS = [
"gpt-3.5-turbo-0125",
"gpt-4-turbo-preview",
]
class OpenaiLLMEngine(BaseLLMEngine):
num_options = 1
name = "OpenAI"
description = "OpenAI language model engine."
def generate(self, system_prompt: str, chat_prompt: str, max_tokens: int = 512, temperature: float = 1.0, json_mode: bool= False, top_p: float = 1, frequency_penalty: float = 0, presence_penalty: float = 0) -> str:
... # TODO: Implement this method
def get_options(self) -> list:
return [
gr.Dropdown(
label="Model",
choices=OPENAI_POSSIBLE_MODELS,
max_choices=1,
value=OPENAI_POSSIBLE_MODELS[0]
)
]

View File

@@ -0,0 +1 @@
from .BaseLLMEngine import BaseLLMEngine

View File

@@ -0,0 +1,10 @@
from abc import ABC, abstractmethod
from ..BaseEngine import BaseEngine
class BaseScriptEngine(BaseEngine):
pass
@abstractmethod
def generate(self) -> str:
pass

View File

@@ -0,0 +1,18 @@
from .BaseScriptEngine import BaseScriptEngine
import gradio as gr
class ShowerThoughtsScriptEngine(BaseScriptEngine):
name = "Shower Thoughts"
description = "Generate a Shower Thoughts script"
num_options = 0
def __init__(self, options: list[list | tuple | str | int | float | bool | None]):
super().__init__()
def generate(self, text: str, path: str) -> str:
pass
@classmethod
def get_options(cls) -> list:
return []

View File

@@ -0,0 +1,2 @@
from .BaseScriptEngine import BaseScriptEngine
from .ShowerThoughtsScriptEngine import ShowerThoughtsScriptEngine

View File

@@ -7,4 +7,4 @@ class BaseTTSEngine(BaseEngine):
@abstractmethod @abstractmethod
def synthesize(self, text: str, path: str) -> str: def synthesize(self, text: str, path: str) -> str:
pass pass

View File

@@ -1,7 +1,9 @@
import gradio as gr import gradio as gr
import TTS
# import TTS
import os import os
import torch
# import torch
from .BaseTTSEngine import BaseTTSEngine from .BaseTTSEngine import BaseTTSEngine
@@ -88,20 +90,7 @@ class CoquiTTSEngine(BaseTTSEngine):
"ko", # Korean "ko", # Korean
"hi", # Hindi "hi", # Hindi
] ]
options = [ num_options = 2
{
"type": "dropdown",
"label": "Voice",
"choices": voices,
"max": 1,
},
{
"type": "dropdown",
"label": "Language",
"choices": languages,
"max": 1,
},
]
def __init__(self, options: list): def __init__(self, options: list):
super().__init__() super().__init__()
@@ -110,10 +99,28 @@ class CoquiTTSEngine(BaseTTSEngine):
self.language = options[1][0] self.language = options[1][0]
os.environ["COQUI_TOS_AGREED"] = "1" os.environ["COQUI_TOS_AGREED"] = "1"
self.tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")
device = "cuda" if torch.cuda.is_available() else "cpu" # self.tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")
self.tts.to(device) # device = "cuda" if torch.cuda.is_available() else "cpu"
# self.tts.to(device)
def synthesize(self, text: str, path: str) -> str: def synthesize(self, text: str, path: str) -> str:
self.tts.tts_to_file(text=text, file_path=path, lang=self.language, speaker=self.voice) # self.tts.tts_to_file(text=text, file_path=path, lang=self.language, speaker=self.voice)
return path return path
@classmethod
def get_options(cls) -> list:
return [
gr.Dropdown(
label="Voice",
choices=cls.voices,
max_choices=1,
value=cls.voices[0],
),
gr.Dropdown(
label="Language",
choices=cls.languages,
max_choices=1,
value=cls.languages[0],
),
]

View File

@@ -1,38 +1,19 @@
from .BaseTTSEngine import BaseTTSEngine from .BaseTTSEngine import BaseTTSEngine
import gradio as gr import gradio as gr
class ElevenLabsTTSEngine(BaseTTSEngine): class ElevenLabsTTSEngine(BaseTTSEngine):
options = [
{
"type": "dropdown",
"label": "Voice",
"choices": [
"Zofija Kendrick",
"Narelle Moon",
"Barbora MacLean",
"Alexandra Hisakawa",
"Alma María",
"Rosemary Okafor",
"Ige Behringer",
"Filip Traverse",
"Damjan Chapman",
"Wulf Carlevaro",
"Aaron Dreschner",
"Kumar Dahl",
"Eugenio Mataracı",
"Ferran Simen",
"Xavier Hayasaka",
"Luis Moray",
"Marcos Rudaski",
],
}
]
name = "ElevenLabs" name = "ElevenLabs"
description = "ElevenLabs TTS engine." description = "ElevenLabs TTS engine."
num_options = 0
def __init__(self, options: list[list | tuple | str | int | float | bool | None]): def __init__(self, options: list[list | tuple | str | int | float | bool | None]):
self.voice = options[0][0] # self.voice = options[0][0]
super().__init__() super().__init__()
def synthesize(self, text: str, path: str) -> str: def synthesize(self, text: str, path: str) -> str:
pass pass
@classmethod
def get_options(cls) -> list:
return []

View File

@@ -1,3 +1,3 @@
from .BaseTTSEngine import BaseTTSEngine from .BaseTTSEngine import BaseTTSEngine
from .CoquiTTSEngine import CoquiTTSEngine from .CoquiTTSEngine import CoquiTTSEngine
from .ElevenLabsTTSEngine import ElevenLabsTTSEngine from .ElevenLabsTTSEngine import ElevenLabsTTSEngine

View File

@@ -1,2 +1,8 @@
from . import TTSEngine from . import TTSEngine
from .BaseEngine import BaseEngine from .BaseEngine import BaseEngine
from . import ScriptEngine
ENGINES = {
"TTSEngine": [TTSEngine.CoquiTTSEngine, TTSEngine.ElevenLabsTTSEngine],
"ScriptEngine": [ScriptEngine.ShowerThoughtsScriptEngine],
}

View File

@@ -1,4 +0,0 @@
from src.engines.BaseEngine import AbstractEngine
class AbstractScriptEngine(AbstractEngine):
pass

View File

@@ -1,6 +0,0 @@
from AbstractScriptEngine import AbstractScriptEngine
class ComicalScriptEngine(AbstractScriptEngine):
def __init__(self):
super().__init__()
self.options = {"comicality": ["Low", "Medium", "High"]}

View File

@@ -1,6 +0,0 @@
from AbstractScriptEngine import AbstractScriptEngine
class DramaticScriptEngine(AbstractScriptEngine):
def __init__(self):
super().__init__()
self.options = {"tone": ["Serious", "Light-hearted"]}

1
ui/__init__.py Normal file
View File

@@ -0,0 +1 @@
from .gradio_ui import GenerateUI

95
ui/gradio_ui.py Normal file
View File

@@ -0,0 +1,95 @@
import os
import gradio as gr
from src.engines import ENGINES
class GenerateUI:
def __init__(self):
self.css = """.generate_button {
font-size: 5rem !important
}
"""
def get_switcher_func(self, engine_names: list[str]) -> list[gr.update]:
def switch(selected: str):
returnable = []
for i, name in enumerate(engine_names):
returnable.append(gr.update(visible=name == selected))
return returnable
return switch
def launch_ui(self):
ui = gr.TabbedInterface(
*self.get_interfaces(),
"Viral Automator",
"NoCrypt/miku",
css=self.css
)
ui.launch()
def get_interfaces(self) -> tuple[list[gr.Blocks], list[str]]:
"""
Returns a tuple containing a list of gr.Blocks interfaces and a list of interface names.
Returns:
tuple[list[gr.Blocks], list[str]]: A tuple containing a list of gr.Blocks interfaces and a list of interface names.
"""
return ([self.get_generate_interface()], ["Generate"])
def get_generate_interface(self) -> gr.Blocks:
with gr.Blocks() as interface:
with gr.Row() as row:
inputs = []
with gr.Blocks() as col1:
for engine_type, engines in ENGINES.items():
with gr.Tab(engine_type) as engine_tab:
engine_names = [engine.name for engine in engines]
engine_dropdown = gr.Dropdown(
choices=engine_names, value=engine_names[0]
)
inputs.append(engine_dropdown)
engine_rows = []
for i, engine in enumerate(engines):
with gr.Row(visible=(i == 0)) as engine_row:
engine_rows.append(engine_row)
options = engine.get_options()
inputs.extend(options)
switcher = self.get_switcher_func(engine_names)
engine_dropdown.change(
switcher, inputs=engine_dropdown, outputs=engine_rows
)
with gr.Blocks() as col2:
button = gr.Button("🚀", size="lg", variant="primary", elem_classes="generate_button")
button.click(self.repack_options, inputs=inputs)
return interface
def repack_options(self, *args):
"""
Repacks the options provided as arguments into a dictionary based on the selected engine.
Args:
*args: Variable number of arguments representing the options for each engine.
Returns:
dict: A dictionary containing the repacked options, where the keys are the engine types and the values are the corresponding engine options.
"""
options = {}
args = list(args)
for engine_type, engines in ENGINES.items():
engine_name = args.pop(0)
for engine in engines:
if engine.name == engine_name:
options[engine_type] = engine(options=args[: engine.num_options])
args = args[engine.num_options :]
else:
# we don't care about this, it's not the selected engine, we throw it away
args = args[engine.num_options :]
print(options)
if __name__ == "__main__":
ui_generator = GenerateUI()
ui_generator.launch_ui()