Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions kokoro/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ def __init__(
lang_code: Language code for G2P processing
model: KModel instance, True to create new model, False for no model
trf: Whether to use transformer-based G2P
device: Override default device selection ('cuda' or 'cpu', or None for auto)
If None, will auto-select cuda if available
If 'cuda' and not available, will explicitly raise an error
device: Override default device selection ('cuda', 'xpu', 'mps' or 'cpu', or None for auto)
If None, will auto-select cuda, then xpu, then mps if available
If an accelerator is explicitly requested and not available, will explicitly raise an error
"""
if repo_id is None:
repo_id = 'hexgrad/Kokoro-82M'
Expand All @@ -92,15 +92,23 @@ def __init__(
if isinstance(model, KModel):
self.model = model
elif model:
xpu_available = hasattr(torch, 'xpu') and torch.xpu.is_available()
if device == 'cuda' and not torch.cuda.is_available():
raise RuntimeError("CUDA requested but not available")
if device == 'xpu' and not xpu_available:
raise RuntimeError("XPU requested but not available")
if device == 'mps' and not torch.backends.mps.is_available():
raise RuntimeError("MPS requested but not available")
if device == 'mps' and os.environ.get('PYTORCH_ENABLE_MPS_FALLBACK') != '1':
raise RuntimeError("MPS requested but fallback not enabled")
if device is None:
if torch.cuda.is_available():
device = 'cuda'
elif xpu_available:
# Intel GPU (Arc / integrated Xe/Arc, e.g. Meteor Lake+) via
# PyTorch's native xpu backend (built in since torch 2.5,
# no intel-extension-for-pytorch required).
device = 'xpu'
elif os.environ.get('PYTORCH_ENABLE_MPS_FALLBACK') == '1' and torch.backends.mps.is_available():
device = 'mps'
else:
Expand All @@ -109,8 +117,11 @@ def __init__(
self.model = KModel(repo_id=repo_id).to(device).eval()
except RuntimeError as e:
if device == 'cuda':
raise RuntimeError(f"""Failed to initialize model on CUDA: {e}.
raise RuntimeError(f"""Failed to initialize model on CUDA: {e}.
Try setting device='cpu' or check CUDA installation.""")
if device == 'xpu':
raise RuntimeError(f"""Failed to initialize model on XPU: {e}.
Try setting device='cpu' or check Intel GPU driver installation.""")
raise
self.voices = {}
if lang_code in 'ab':
Expand Down
46 changes: 46 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,25 @@ dependencies = [
"transformers"
]

[project.optional-dependencies]
# See NOTES.md / draft-pr.md for why this is `cpu`+`xpu` extras rather than
# a single opt-in `xpu` extra layered on the bare `torch` above: uv's
# resolver treats an unconstrained `torch` requirement as satisfiable by
# *any* source that matches, including the xpu-indexed wheel once one is
# introduced anywhere in the graph -- it collapses to one universal answer
# instead of forking per-extra, so a plain `uv sync` silently installed
# `torch==2.13.0+xpu` even with no extra requested (reproduced empirically,
# see draft-pr.md). Declaring `cpu` as an explicit, mutually-exclusive
# alternative (uv's own documented pattern for cuda/rocm/xpu) is what
# actually keeps the two forks separate.
cpu = [
"torch>=2.5"
]
xpu = [
"torch>=2.5",
"triton-xpu; sys_platform == 'linux'"
]

[project.scripts]
kokoro = "kokoro.__main__:main"

Expand All @@ -36,3 +55,30 @@ only-packages = true
[project.urls]
Homepage = "https://github.com/hexgrad/kokoro"
Repository = "https://github.com/hexgrad/kokoro"

[tool.uv]
conflicts = [
[
{ extra = "cpu" },
{ extra = "xpu" },
],
]

[tool.uv.sources]
torch = [
{ index = "pytorch-cpu", extra = "cpu" },
{ index = "pytorch-xpu", extra = "xpu" },
]
triton-xpu = [
{ index = "pytorch-xpu", extra = "xpu" }
]

[[tool.uv.index]]
name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

[[tool.uv.index]]
name = "pytorch-xpu"
url = "https://download.pytorch.org/whl/xpu"
explicit = true
Loading