RootAccess4Life's picture
Upload folder using huggingface_hub
7be2f44 verified
Raw
History Blame Contribute Delete
23.8 kB
import contextlib
import io
import importlib
import os
import sys
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest import mock
REQUIRED_MODEL_FILES = [
"config.yaml",
"bpe.model",
"gpt.pth",
"s2mel.pth",
"wav2vec2bert_stats.pt",
"feat1.pt",
"feat2.pt",
]
REQUIRED_MODEL_DIRS = [
"qwen0.6bemo4-merge",
]
AUX_MODEL_FILES = [
"hf_cache/semantic_codec_model.safetensors",
"hf_cache/campplus_cn_common.bin",
"hf_cache/bigvgan/config.json",
"hf_cache/bigvgan/bigvgan_generator.pt",
]
AUX_MODEL_DIRS = [
"hf_cache/w2v-bert-2.0",
]
def make_model_dir(path):
path.mkdir(parents=True)
for filename in REQUIRED_MODEL_FILES:
(path / filename).write_text("placeholder", encoding="utf-8")
for dirname in REQUIRED_MODEL_DIRS:
(path / dirname).mkdir()
for filename in AUX_MODEL_FILES:
target = path / filename
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text("placeholder", encoding="utf-8")
for dirname in AUX_MODEL_DIRS:
target = path / dirname
target.mkdir(parents=True, exist_ok=True)
(target / "config.json").write_text("placeholder", encoding="utf-8")
def fake_torch():
return SimpleNamespace(
cuda=SimpleNamespace(is_available=lambda: False, device_count=lambda: 0),
xpu=SimpleNamespace(is_available=lambda: False, device_count=lambda: 0),
backends=SimpleNamespace(mps=SimpleNamespace(is_available=lambda: False)),
)
def patched_imports():
real_import_module = importlib.import_module
def import_module(name, package=None):
if name == "torch":
return fake_torch()
if name in {"torchaudio", "indextts"}:
return SimpleNamespace(__name__=name)
return real_import_module(name, package)
return mock.patch("importlib.import_module", side_effect=import_module)
def user_state_paths(temp_path):
if sys.platform == "win32":
return {
"env": {
"APPDATA": str(temp_path / "roaming"),
"LOCALAPPDATA": str(temp_path / "local"),
},
"config_path": temp_path / "roaming" / "IndexTTS" / "config.toml",
"model_dir": temp_path / "local" / "IndexTTS" / "models" / "IndexTTS-2",
}
if sys.platform == "darwin":
app_support = temp_path / "Library" / "Application Support" / "IndexTTS"
return {
"env": {"HOME": str(temp_path)},
"config_path": app_support / "config.toml",
"model_dir": app_support / "models" / "IndexTTS-2",
}
return {
"env": {
"XDG_CONFIG_HOME": str(temp_path / "config"),
"XDG_DATA_HOME": str(temp_path / "data"),
},
"config_path": temp_path / "config" / "indextts" / "config.toml",
"model_dir": temp_path / "data" / "indextts" / "models" / "IndexTTS-2",
}
class ConfigCommandTests(unittest.TestCase):
def run_cli(self, args, **kwargs):
from indextts.cli_v2 import main
stdout = io.StringIO()
stderr = io.StringIO()
with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):
exit_code = main(args, **kwargs)
return exit_code, stdout.getvalue(), stderr.getvalue()
def test_init_creates_persistent_config_and_default_model_directory_without_model_files(self):
with tempfile.TemporaryDirectory() as temp_dir:
state = user_state_paths(Path(temp_dir))
with mock.patch.dict(os.environ, state["env"], clear=False):
exit_code, stdout, stderr = self.run_cli(["init"])
config_text = state["config_path"].read_text(encoding="utf-8")
model_dir_files = list(state["model_dir"].iterdir())
self.assertEqual(exit_code, 0)
self.assertIn(f"Config: {state['config_path']}", stdout)
self.assertIn(f"Model directory: {state['model_dir']}", stdout)
self.assertEqual(stderr, "")
self.assertIn(f'model_dir = "{state["model_dir"].as_posix()}"', config_text)
self.assertEqual(model_dir_files, [])
def test_init_with_model_dir_persists_the_requested_model_directory(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "custom-models"
with mock.patch.dict(os.environ, state["env"], clear=False):
exit_code, stdout, stderr = self.run_cli(["init", "--model-dir", str(model_dir)])
config_text = state["config_path"].read_text(encoding="utf-8")
model_dir_exists = model_dir.is_dir()
self.assertEqual(exit_code, 0)
self.assertIn(f"Model directory: {model_dir}", stdout)
self.assertEqual(stderr, "")
self.assertTrue(model_dir_exists)
self.assertIn(f'model_dir = "{model_dir.as_posix()}"', config_text)
def test_config_path_prints_the_persistent_config_file_location(self):
with tempfile.TemporaryDirectory() as temp_dir:
state = user_state_paths(Path(temp_dir))
with mock.patch.dict(os.environ, state["env"], clear=False):
exit_code, stdout, stderr = self.run_cli(["config", "path"])
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"{state['config_path']}\n")
self.assertEqual(stderr, "")
def test_config_set_model_dir_persists_the_model_resource_directory(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "persisted-models"
with mock.patch.dict(os.environ, state["env"], clear=False):
exit_code, stdout, stderr = self.run_cli(["config", "set", "model_dir", str(model_dir)])
config_text = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"model_dir = {model_dir}\n")
self.assertEqual(stderr, "")
self.assertIn(f'model_dir = "{model_dir.as_posix()}"', config_text)
def test_config_set_runtime_preferences_persists_device_and_boolean_values(self):
with tempfile.TemporaryDirectory() as temp_dir:
state = user_state_paths(Path(temp_dir))
with mock.patch.dict(os.environ, state["env"], clear=False):
first = self.run_cli(["config", "set", "default_device", "cuda:0"])
second = self.run_cli(["config", "set", "use_fp16", "true"])
third = self.run_cli(["config", "set", "use_deepspeed", "false"])
fourth = self.run_cli(["config", "set", "use_cuda_kernel", "true"])
config_text = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(first, (0, "default_device = cuda:0\n", ""))
self.assertEqual(second, (0, "use_fp16 = true\n", ""))
self.assertEqual(third, (0, "use_deepspeed = false\n", ""))
self.assertEqual(fourth, (0, "use_cuda_kernel = true\n", ""))
self.assertIn('default_device = "cuda:0"', config_text)
self.assertIn("use_fp16 = true", config_text)
self.assertIn("use_deepspeed = false", config_text)
self.assertIn("use_cuda_kernel = true", config_text)
def test_config_set_boolean_preference_rejects_non_boolean_values(self):
with tempfile.TemporaryDirectory() as temp_dir:
state = user_state_paths(Path(temp_dir))
with mock.patch.dict(os.environ, state["env"], clear=False):
exit_code, stdout, stderr = self.run_cli(["config", "set", "use_fp16", "yes"])
config_exists = state["config_path"].exists()
self.assertEqual(exit_code, 1)
self.assertEqual(stdout, "")
self.assertIn("ERROR: use_fp16 must be true or false", stderr)
self.assertFalse(config_exists)
def test_config_get_prints_the_current_persistent_config(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "models"
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
self.run_cli(["config", "set", "default_device", "cpu"])
exit_code, stdout, stderr = self.run_cli(["config", "get"])
self.assertEqual(exit_code, 0)
self.assertIn(f'model_dir = "{model_dir.as_posix()}"', stdout)
self.assertIn('default_device = "cpu"', stdout)
self.assertEqual(stderr, "")
def test_check_uses_persisted_model_dir_when_command_line_and_environment_do_not_override_it(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "persisted-models"
make_model_dir(model_dir)
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
with patched_imports():
exit_code, stdout, stderr = self.run_cli(["check"])
self.assertEqual(exit_code, 0)
self.assertIn(f"OK: model directory {model_dir}", stdout)
self.assertEqual(stderr, "")
def test_check_model_dir_resolution_prioritizes_command_line_then_environment_then_config(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
cli_model_dir = temp_path / "cli-models"
env_model_dir = temp_path / "env-models"
persisted_model_dir = temp_path / "persisted-models"
for model_dir in [cli_model_dir, env_model_dir, persisted_model_dir]:
make_model_dir(model_dir)
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(persisted_model_dir)])
with patched_imports():
cli_result = self.run_cli(
["check", "--model-dir", str(cli_model_dir)],
)
with mock.patch.dict(os.environ, {"INDEXTTS2_MODEL_DIR": str(env_model_dir)}, clear=False):
with patched_imports():
env_result = self.run_cli(["check"])
with patched_imports():
config_result = self.run_cli(["check"])
self.assertIn(f"OK: model directory {cli_model_dir}", cli_result[1])
self.assertIn(f"OK: model directory {env_model_dir}", env_result[1])
self.assertIn(f"OK: model directory {persisted_model_dir}", config_result[1])
def test_check_initializes_default_state_and_checks_the_platform_default_model_dir(self):
with tempfile.TemporaryDirectory() as temp_dir:
state = user_state_paths(Path(temp_dir))
with mock.patch.dict(os.environ, state["env"], clear=False):
with mock.patch.dict(os.environ, {"INDEXTTS2_MODEL_DIR": ""}, clear=False):
exit_code, stdout, stderr = self.run_cli(["check"])
config_text = state["config_path"].read_text(encoding="utf-8")
model_dir_exists = state["model_dir"].is_dir()
self.assertEqual(exit_code, 2)
self.assertEqual(stdout, "")
self.assertIn("ERROR: missing required model files", stderr)
self.assertIn(state["model_dir"].as_posix(), config_text)
self.assertTrue(model_dir_exists)
def test_check_with_command_model_dir_still_initializes_default_state_without_persisting_override(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
cli_model_dir = temp_path / "cli-models"
make_model_dir(cli_model_dir)
with mock.patch.dict(os.environ, state["env"], clear=False):
with patched_imports():
exit_code, stdout, stderr = self.run_cli(["check", "--model-dir", str(cli_model_dir)])
config_text = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(exit_code, 0)
self.assertIn(f"OK: model directory {cli_model_dir}", stdout)
self.assertEqual(stderr, "")
self.assertIn(f'model_dir = "{state["model_dir"].as_posix()}"', config_text)
self.assertNotIn(cli_model_dir.as_posix(), config_text)
def test_synth_uses_persisted_model_dir_and_runtime_preferences_by_default(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "models"
voice_path = temp_path / "voice.wav"
output_path = temp_path / "out.wav"
calls = []
make_model_dir(model_dir)
voice_path.write_bytes(b"voice")
class FakeIndexTTS2:
def __init__(self, **kwargs):
calls.append(("init", kwargs))
def infer(self, **kwargs):
calls.append(("infer", kwargs))
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
self.run_cli(["config", "set", "default_device", "cpu"])
self.run_cli(["config", "set", "use_fp16", "true"])
self.run_cli(["config", "set", "use_deepspeed", "true"])
self.run_cli(["config", "set", "use_cuda_kernel", "true"])
exit_code, stdout, stderr = self.run_cli(
[
"synth",
"--text",
"hello",
"--voice",
str(voice_path),
"--output",
str(output_path),
],
tts_factory=FakeIndexTTS2,
)
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"Generated: {output_path}\n")
self.assertEqual(stderr, "")
self.assertEqual(
calls[0][1],
{
"cfg_path": str(model_dir / "config.yaml"),
"model_dir": str(model_dir),
"use_fp16": True,
"device": "cpu",
"use_cuda_kernel": True,
"use_deepspeed": True,
},
)
def test_batch_uses_persisted_model_dir_and_runtime_preferences_by_default(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "models"
voice_path = temp_path / "voice.wav"
batch_file = temp_path / "batch.jsonl"
output_path = temp_path / "out.wav"
calls = []
make_model_dir(model_dir)
voice_path.write_bytes(b"voice")
batch_file.write_text('{"text": "hello", "voice": "voice.wav", "output": "out.wav"}\n', encoding="utf-8")
class FakeIndexTTS2:
def __init__(self, **kwargs):
calls.append(("init", kwargs))
def infer(self, **kwargs):
calls.append(("infer", kwargs))
Path(kwargs["output_path"]).write_bytes(b"audio")
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
self.run_cli(["config", "set", "default_device", "cpu"])
self.run_cli(["config", "set", "use_fp16", "true"])
self.run_cli(["config", "set", "use_deepspeed", "true"])
self.run_cli(["config", "set", "use_cuda_kernel", "true"])
exit_code, stdout, stderr = self.run_cli(
["batch", "--batch-file", str(batch_file)],
tts_factory=FakeIndexTTS2,
)
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"Generated: {output_path}\nBatch complete: 1 tasks generated\n")
self.assertEqual(stderr, "")
self.assertEqual(
calls[0][1],
{
"cfg_path": str(model_dir / "config.yaml"),
"model_dir": str(model_dir),
"use_fp16": True,
"device": "cpu",
"use_cuda_kernel": True,
"use_deepspeed": True,
},
)
def test_batch_command_line_can_disable_persisted_boolean_runtime_preferences_for_one_run(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "models"
voice_path = temp_path / "voice.wav"
batch_file = temp_path / "batch.jsonl"
calls = []
make_model_dir(model_dir)
voice_path.write_bytes(b"voice")
batch_file.write_text('{"text": "hello", "voice": "voice.wav", "output": "out.wav"}\n', encoding="utf-8")
class FakeIndexTTS2:
def __init__(self, **kwargs):
calls.append(("init", kwargs))
def infer(self, **kwargs):
calls.append(("infer", kwargs))
Path(kwargs["output_path"]).write_bytes(b"audio")
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
self.run_cli(["config", "set", "use_fp16", "true"])
self.run_cli(["config", "set", "use_deepspeed", "true"])
self.run_cli(["config", "set", "use_cuda_kernel", "true"])
before_config = state["config_path"].read_text(encoding="utf-8")
exit_code, stdout, stderr = self.run_cli(
[
"batch",
"--batch-file",
str(batch_file),
"--no-fp16",
"--no-deepspeed",
"--no-cuda-kernel",
],
tts_factory=FakeIndexTTS2,
)
after_config = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(exit_code, 0)
self.assertIn("Batch complete: 1 tasks generated", stdout)
self.assertEqual(stderr, "")
self.assertEqual(before_config, after_config)
self.assertEqual(calls[0][1]["use_fp16"], False)
self.assertEqual(calls[0][1]["use_deepspeed"], False)
self.assertEqual(calls[0][1]["use_cuda_kernel"], False)
def test_synth_command_line_overrides_do_not_rewrite_persistent_config(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
persisted_model_dir = temp_path / "persisted-models"
cli_model_dir = temp_path / "cli-models"
voice_path = temp_path / "voice.wav"
output_path = temp_path / "out.wav"
calls = []
make_model_dir(persisted_model_dir)
make_model_dir(cli_model_dir)
voice_path.write_bytes(b"voice")
class FakeIndexTTS2:
def __init__(self, **kwargs):
calls.append(("init", kwargs))
def infer(self, **kwargs):
calls.append(("infer", kwargs))
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(persisted_model_dir)])
self.run_cli(["config", "set", "default_device", "cpu"])
self.run_cli(["config", "set", "use_fp16", "false"])
before_config = state["config_path"].read_text(encoding="utf-8")
exit_code, stdout, stderr = self.run_cli(
[
"synth",
"--text",
"hello",
"--voice",
str(voice_path),
"--output",
str(output_path),
"--model-dir",
str(cli_model_dir),
"--device",
"cuda:0",
"--fp16",
"--deepspeed",
"--cuda-kernel",
],
tts_factory=FakeIndexTTS2,
)
after_config = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"Generated: {output_path}\n")
self.assertEqual(stderr, "")
self.assertEqual(before_config, after_config)
self.assertEqual(calls[0][1]["model_dir"], str(cli_model_dir))
self.assertEqual(calls[0][1]["device"], "cuda:0")
self.assertEqual(calls[0][1]["use_fp16"], True)
self.assertEqual(calls[0][1]["use_deepspeed"], True)
self.assertEqual(calls[0][1]["use_cuda_kernel"], True)
def test_synth_command_line_can_disable_persisted_boolean_runtime_preferences_for_one_run(self):
with tempfile.TemporaryDirectory() as temp_dir:
temp_path = Path(temp_dir)
state = user_state_paths(temp_path)
model_dir = temp_path / "models"
voice_path = temp_path / "voice.wav"
output_path = temp_path / "out.wav"
calls = []
make_model_dir(model_dir)
voice_path.write_bytes(b"voice")
class FakeIndexTTS2:
def __init__(self, **kwargs):
calls.append(("init", kwargs))
def infer(self, **kwargs):
calls.append(("infer", kwargs))
with mock.patch.dict(os.environ, state["env"], clear=False):
self.run_cli(["config", "set", "model_dir", str(model_dir)])
self.run_cli(["config", "set", "use_fp16", "true"])
self.run_cli(["config", "set", "use_deepspeed", "true"])
self.run_cli(["config", "set", "use_cuda_kernel", "true"])
before_config = state["config_path"].read_text(encoding="utf-8")
exit_code, stdout, stderr = self.run_cli(
[
"synth",
"--text",
"hello",
"--voice",
str(voice_path),
"--output",
str(output_path),
"--no-fp16",
"--no-deepspeed",
"--no-cuda-kernel",
],
tts_factory=FakeIndexTTS2,
)
after_config = state["config_path"].read_text(encoding="utf-8")
self.assertEqual(exit_code, 0)
self.assertEqual(stdout, f"Generated: {output_path}\n")
self.assertEqual(stderr, "")
self.assertEqual(before_config, after_config)
self.assertEqual(calls[0][1]["use_fp16"], False)
self.assertEqual(calls[0][1]["use_deepspeed"], False)
self.assertEqual(calls[0][1]["use_cuda_kernel"], False)
if __name__ == "__main__":
unittest.main()