dots.tts / src /dots_tts /cli.py
YuMS's picture
add inference code with AOTI support for hf space
804ee23
Raw
History Blame Contribute Delete
4.68 kB
from __future__ import annotations
import argparse
from pathlib import Path
def parse_args(argv=None):
parser = argparse.ArgumentParser(description="dots.tts inference CLI.")
template_choices = ("tts", "instruction_tts", "text_to_audio", "tts_interleave")
parser.add_argument(
"--model-name-or-path",
required=True,
help="Local pretrained directory or Hugging Face repo id",
)
parser.add_argument(
"--revision", default=None, help="Optional Hugging Face revision"
)
parser.add_argument(
"--cache-dir", default=None, help="Optional Hugging Face cache dir"
)
parser.add_argument("--text", type=str, required=True, help="Input text")
parser.add_argument("--output", default="output.wav", help="Output wav file path")
parser.add_argument(
"--precision", type=str, default="bfloat16", help="Inference precision"
)
parser.add_argument(
"--seed",
type=int,
default=42,
help="Random seed for inference.",
)
parser.add_argument(
"--prompt-audio", type=str, default=None, help="Path to prompt audio"
)
parser.add_argument(
"--prompt-text", type=str, default=None, help="Transcript of prompt audio"
)
parser.add_argument(
"--language",
type=str,
default=None,
help="Language tag mode. Default: none. Supported values: none, auto_detect, or a language code/name such as EN/en/english/chinese.",
)
parser.add_argument(
"--template-name",
choices=template_choices,
default=None,
help="Named template preset for generation.",
)
parser.add_argument(
"--ode-method", type=str, default="euler", help="ODE solver method"
)
parser.add_argument(
"--num-steps", type=int, default=10, help="Diffusion sampling steps"
)
parser.add_argument(
"--guidance-scale",
type=float,
default=1.2,
help="Classifier-free guidance scale",
)
parser.add_argument(
"--speaker-scale",
type=float,
default=1.5,
help="Scale applied to the reference speaker embedding",
)
parser.add_argument(
"--max-generate-length",
type=int,
default=500,
help="Maximum total audio patch count (prompt + generated)",
)
parser.add_argument(
"--normalize-text",
action="store_true",
help="Whether to normalize text before inference",
)
parser.add_argument(
"--profile-inference",
action="store_true",
help="Collect per-module inference timing statistics",
)
return parser.parse_args(argv)
def main(argv=None):
args = parse_args(argv)
import soundfile as sf
from loguru import logger
from dots_tts.runtime import DotsTtsRuntime
from dots_tts.utils.logging import configure_logging
from dots_tts.utils.util import seed_everything
configure_logging()
seed_everything(args.seed)
output_path = Path(args.output)
output_path.parent.mkdir(parents=True, exist_ok=True)
logger.info(
"CLI command started: model={} output={} seed={}",
args.model_name_or_path,
output_path,
args.seed,
)
try:
runtime = DotsTtsRuntime.from_pretrained(
args.model_name_or_path,
revision=args.revision,
cache_dir=args.cache_dir,
precision=args.precision,
max_generate_length=args.max_generate_length,
)
result = runtime.generate(
text=args.text,
prompt_audio_path=args.prompt_audio,
prompt_text=args.prompt_text,
language=args.language,
template_name=args.template_name,
ode_method=args.ode_method,
num_steps=args.num_steps,
guidance_scale=args.guidance_scale,
speaker_scale=args.speaker_scale,
normalize_text=args.normalize_text,
profile_inference=args.profile_inference,
)
sf.write(
output_path,
result["audio"].float().cpu().squeeze().numpy(),
result["sample_rate"],
)
except Exception:
logger.exception(
"CLI inference failed: model={} output={}",
args.model_name_or_path,
output_path,
)
raise
logger.info(
"CLI output written: request_id={} output={} sample_rate={} samples={}",
result["fid"],
output_path,
result["sample_rate"],
int(result["audio"].shape[-1]),
)
if __name__ == "__main__":
raise SystemExit(main())