From f2d3e8de1c9b03267b487f06ce921e1976fe4ef8 Mon Sep 17 00:00:00 2001 From: joetvinson Date: Fri, 6 Jun 2025 16:18:03 +0800 Subject: [PATCH 1/2] Improve Modal deployment script --- modal_webui.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 modal_webui.py diff --git a/modal_webui.py b/modal_webui.py new file mode 100644 index 0000000..65c156b --- /dev/null +++ b/modal_webui.py @@ -0,0 +1,61 @@ +"""Deploy the Gradio web UI to Modal. + +This script mirrors the approach in Modal's Streamlit example. It packages +``webui.py`` inside a container image and exposes it via ``modal serve`` or +``modal deploy``. +""" + +import os +import shlex +import subprocess +from pathlib import Path + +from huggingface_hub import snapshot_download +import modal + + +# Path to the local Gradio interface script +webui_script_local_path = Path(__file__).parent / "webui.py" +# Location inside the container +webui_script_remote_path = "/root/webui.py" + +# Build the container image with dependencies and the web UI script +image = ( + modal.Image.debian_slim(python_version="3.11") + .apt_install("ffmpeg", "git-lfs") + .run_commands("git lfs install") + .pip_install_from_requirements("requirements.txt") + .add_local_file(webui_script_local_path, webui_script_remote_path) +) + +app = modal.App(name="spark-tts-webui", image=image) + +# Ensure the webui script is present +if not webui_script_local_path.exists(): + raise RuntimeError( + "webui.py not found! Place modal_webui.py next to webui.py." + ) + + +@app.function(gpu="A100") +@modal.web_server(7860) +def run(model_dir="pretrained_models/Spark-TTS-0.5B", device: int = 0): + """Start the Gradio UI inside a Modal container.""" + + # Ensure the model is downloaded + model_path = Path(model_dir) + if not model_path.exists(): + os.makedirs(model_dir, exist_ok=True) + snapshot_download( + "SparkAudio/Spark-TTS-0.5B", + local_dir=model_dir, + ) + + target = shlex.quote(webui_script_remote_path) + model_dir = shlex.quote(str(model_path)) + cmd = ( + f"python {target} --model_dir {model_dir} --device {device} " + f"--server_name 0.0.0.0 --server_port 7860" + ) + subprocess.Popen(cmd, shell=True) + From b044443abddf804db6696ae6f272722d6c7239d7 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 6 Jun 2025 08:57:58 +0000 Subject: [PATCH 2/2] I've made an enhancement to the Modal WebUI to handle concurrent inputs. The `modal_webui.py` script is what I use to deploy the SparkTTS Gradio web UI on Modal. With this change, I've added the `@modal.concurrent(max_inputs=10)` decorator to the main `run` function. This is in line with Modal's best practices and examples for deploying web server applications (like Gradio, Streamlit, ComfyUI) that are started via `subprocess.Popen`. Adding this decorator allows the Modal container to accept multiple simultaneous client connections from you (up to 10 in this case), which should improve responsiveness if multiple users are interacting with it. The actual processing of these requests by the SparkTTS model will still depend on the underlying Gradio server and GPU capacity. I reviewed the script and found it to be otherwise correctly implementing Modal's guidelines for non-ASGI web servers. --- modal_webui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modal_webui.py b/modal_webui.py index 65c156b..6cf83ec 100644 --- a/modal_webui.py +++ b/modal_webui.py @@ -39,6 +39,7 @@ @app.function(gpu="A100") @modal.web_server(7860) +@modal.concurrent(max_inputs=10) # Added this line def run(model_dir="pretrained_models/Spark-TTS-0.5B", device: int = 0): """Start the Gradio UI inside a Modal container."""