omnius 1.0.679 → 1.0.681
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/assets/voice/detect-torch.py +306 -0
- package/dist/index.js +5103 -4851
- package/docs/guides/telegram.md +27 -3
- package/docs/reference/configuration.md +7 -0
- package/docs/rest/endpoints/voice-vision.md +16 -0
- package/npm-shrinkwrap.json +8 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -234,6 +234,7 @@ The same surface drives the **Generate** tab in the web UI (`http://127.0.0.1:11
|
|
|
234
234
|
- `/indicator` reconciles daemon ownership and health before launching the tray; the tray polls every 10 seconds and turns its version row into a retryable verified-update action only when an update exists.
|
|
235
235
|
- Dashboard, tray, and TUI update actions now share an exact-version global transaction with live phase/output and package, executable, daemon, hash, restart, and tray verification.
|
|
236
236
|
- TTS exposes GLaDOS, Overwatch, `luxtts:announcer-testchamber03`, and configurable Voicebox models; ASR independently exposes Whisper, managed `transcribe-cli`, Nemotron readiness, and pinned Microsoft VibeVoice ASR with Jetson/ARM64 CUDA-aware setup.
|
|
237
|
+
- LuxTTS auto-setup on Jetson ARM64 requires CPU ONNX Runtime at import time, validates CUDA Torch separately against the host runtime, preserves existing caches during repair, and never substitutes generic PyPI Torch or automatic sudo for an AGX Orin deployment.
|
|
237
238
|
- `/realtime` and REST `realtime: true` provide short, natural, SOUL.md-aware conversation for ASR/TTS clients.
|
|
238
239
|
- Endpoint setup and sponsor setup aggregate models from all enabled endpoints, including external OpenAI-compatible routers.
|
|
239
240
|
- `/sponsor` can expose text inference and media generation for image, video, sound, and music with per-modality limits.
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
detect-torch.py — Reusable PyTorch version and install URL detection.
|
|
4
|
+
|
|
5
|
+
Detects the current platform/architecture/GPU environment and outputs
|
|
6
|
+
the correct pip install arguments for PyTorch + torchaudio.
|
|
7
|
+
|
|
8
|
+
Supports:
|
|
9
|
+
- x86_64 Linux with NVIDIA CUDA (cu118, cu121, cu124)
|
|
10
|
+
- x86_64 Linux CPU-only
|
|
11
|
+
- aarch64 Linux (ARM) CPU-only
|
|
12
|
+
- aarch64 Linux Jetson (NVIDIA GPU via JetPack wheels)
|
|
13
|
+
- macOS x86_64 (CPU)
|
|
14
|
+
- macOS arm64 / Apple Silicon (MPS via default PyPI)
|
|
15
|
+
- Windows x86_64 (CUDA or CPU)
|
|
16
|
+
|
|
17
|
+
Output: JSON to stdout with fields:
|
|
18
|
+
{
|
|
19
|
+
"platform": "linux",
|
|
20
|
+
"arch": "x86_64" | "aarch64" | "arm64",
|
|
21
|
+
"accelerator": "cuda" | "mps" | "cpu",
|
|
22
|
+
"cuda_version": "12.4" | null,
|
|
23
|
+
"is_jetson": false,
|
|
24
|
+
"pip_args": ["torch", "torchaudio", "--index-url", "..."],
|
|
25
|
+
"pip_args_str": "torch torchaudio --index-url ...",
|
|
26
|
+
"description": "x86_64 Linux CUDA 12.4"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Usage from shell:
|
|
30
|
+
python3 scripts/detect-torch.py
|
|
31
|
+
python3 scripts/detect-torch.py --pip-args # just the pip install args
|
|
32
|
+
python3 scripts/detect-torch.py --index-url # just the --index-url value
|
|
33
|
+
|
|
34
|
+
Usage from Node.js (via child_process):
|
|
35
|
+
const result = execSync('python3 scripts/detect-torch.py').toString();
|
|
36
|
+
const spec = JSON.parse(result);
|
|
37
|
+
await shell(`pip install ${spec.pip_args_str}`);
|
|
38
|
+
|
|
39
|
+
Derived from hydra/service_router/.services/depth_any/app.py bootstrap logic.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
import json
|
|
43
|
+
import os
|
|
44
|
+
import platform
|
|
45
|
+
import subprocess
|
|
46
|
+
import sys
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def detect_cuda_version():
|
|
51
|
+
"""Detect NVIDIA CUDA version from nvidia-smi or nvcc."""
|
|
52
|
+
# Try nvidia-smi first (works even without nvcc)
|
|
53
|
+
try:
|
|
54
|
+
result = subprocess.run(
|
|
55
|
+
["nvidia-smi", "--query-gpu=driver_version", "--format=csv,noheader,nounits"],
|
|
56
|
+
capture_output=True, text=True, timeout=5
|
|
57
|
+
)
|
|
58
|
+
if result.returncode == 0:
|
|
59
|
+
# nvidia-smi works — now get CUDA version
|
|
60
|
+
result2 = subprocess.run(
|
|
61
|
+
["nvidia-smi"],
|
|
62
|
+
capture_output=True, text=True, timeout=5
|
|
63
|
+
)
|
|
64
|
+
if result2.returncode == 0:
|
|
65
|
+
import re
|
|
66
|
+
match = re.search(r"CUDA Version:\s*(\d+\.\d+)", result2.stdout)
|
|
67
|
+
if match:
|
|
68
|
+
return match.group(1)
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# Try nvcc (Jetson, or systems with CUDA toolkit)
|
|
73
|
+
try:
|
|
74
|
+
result = subprocess.run(
|
|
75
|
+
["nvcc", "--version"],
|
|
76
|
+
capture_output=True, text=True, timeout=5
|
|
77
|
+
)
|
|
78
|
+
if result.returncode == 0:
|
|
79
|
+
import re
|
|
80
|
+
match = re.search(r"release (\d+\.\d+)", result.stdout)
|
|
81
|
+
if match:
|
|
82
|
+
return match.group(1)
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def is_jetson():
|
|
90
|
+
"""Detect NVIDIA Jetson (aarch64 + /etc/nv_tegra_release)."""
|
|
91
|
+
return (
|
|
92
|
+
platform.machine().lower() in ("aarch64", "arm64")
|
|
93
|
+
and Path("/etc/nv_tegra_release").exists()
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def jetson_torch_wheel_url():
|
|
98
|
+
"""Find the best Jetson PyTorch wheel URL from NVIDIA's index."""
|
|
99
|
+
import re
|
|
100
|
+
import urllib.request
|
|
101
|
+
|
|
102
|
+
py_tag = f"cp{sys.version_info.major}{sys.version_info.minor}"
|
|
103
|
+
|
|
104
|
+
# Check env override first
|
|
105
|
+
env_wheel = os.environ.get("JETSON_TORCH_WHEEL")
|
|
106
|
+
if env_wheel:
|
|
107
|
+
return env_wheel
|
|
108
|
+
|
|
109
|
+
# Try NVIDIA's Jetson wheel index
|
|
110
|
+
release_text = ""
|
|
111
|
+
try:
|
|
112
|
+
release_text = Path("/etc/nv_tegra_release").read_text()
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
# Determine JetPack version -> index URL
|
|
117
|
+
indexes = []
|
|
118
|
+
if "R36" in release_text and "REVISION: 4" in release_text:
|
|
119
|
+
indexes.extend([
|
|
120
|
+
"https://developer.download.nvidia.com/compute/redist/jp/v61",
|
|
121
|
+
"https://developer.download.nvidia.com/compute/redist/jp/v60",
|
|
122
|
+
])
|
|
123
|
+
elif "R36" in release_text:
|
|
124
|
+
indexes.append("https://developer.download.nvidia.com/compute/redist/jp/v60")
|
|
125
|
+
elif "R35" in release_text:
|
|
126
|
+
indexes.append("https://developer.download.nvidia.com/compute/redist/jp/v51")
|
|
127
|
+
else:
|
|
128
|
+
indexes.extend([
|
|
129
|
+
"https://developer.download.nvidia.com/compute/redist/jp/v60",
|
|
130
|
+
"https://developer.download.nvidia.com/compute/redist/jp/v51",
|
|
131
|
+
])
|
|
132
|
+
|
|
133
|
+
for idx_url in indexes:
|
|
134
|
+
try:
|
|
135
|
+
with urllib.request.urlopen(f"{idx_url}/pytorch/", timeout=10) as resp:
|
|
136
|
+
html = resp.read().decode("utf-8", "ignore")
|
|
137
|
+
pattern = rf'href="(torch-([0-9a-zA-Z\\.\\+]+)\\.nv[^"]*{py_tag}[^"]*linux_aarch64\\.whl)"'
|
|
138
|
+
matches = re.findall(pattern, html)
|
|
139
|
+
best = None
|
|
140
|
+
for fname, ver in matches:
|
|
141
|
+
base_ver = ver.split("+")[0]
|
|
142
|
+
parts = tuple(int(x) for x in base_ver.split(".")[:3] if x.isdigit())
|
|
143
|
+
if best is None or parts > best[0]:
|
|
144
|
+
best = (parts, fname, base_ver)
|
|
145
|
+
if best:
|
|
146
|
+
return f"{idx_url}/pytorch/{best[1]}"
|
|
147
|
+
except Exception:
|
|
148
|
+
continue
|
|
149
|
+
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def detect_torch_spec():
|
|
154
|
+
"""Detect the optimal PyTorch install spec for this system."""
|
|
155
|
+
machine = platform.machine().lower()
|
|
156
|
+
system = platform.system().lower()
|
|
157
|
+
|
|
158
|
+
spec = {
|
|
159
|
+
"platform": system,
|
|
160
|
+
"arch": machine,
|
|
161
|
+
"accelerator": "cpu",
|
|
162
|
+
"cuda_version": None,
|
|
163
|
+
"is_jetson": False,
|
|
164
|
+
"pip_args": [],
|
|
165
|
+
"pip_args_str": "",
|
|
166
|
+
"torchaudio_version": None,
|
|
167
|
+
"error": None,
|
|
168
|
+
"description": "",
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# ── macOS ──────────────────────────────────────────────────────────
|
|
172
|
+
if system == "darwin":
|
|
173
|
+
if machine in ("arm64", "aarch64"):
|
|
174
|
+
# Apple Silicon — MPS acceleration via default PyPI wheels
|
|
175
|
+
spec["accelerator"] = "mps"
|
|
176
|
+
spec["pip_args"] = ["torch", "torchaudio"]
|
|
177
|
+
spec["description"] = "macOS Apple Silicon (MPS)"
|
|
178
|
+
else:
|
|
179
|
+
# Intel Mac — CPU only
|
|
180
|
+
spec["pip_args"] = ["torch", "torchaudio"]
|
|
181
|
+
spec["description"] = "macOS Intel (CPU)"
|
|
182
|
+
spec["pip_args_str"] = " ".join(spec["pip_args"])
|
|
183
|
+
return spec
|
|
184
|
+
|
|
185
|
+
# ── Windows ────────────────────────────────────────────────────────
|
|
186
|
+
if system == "windows":
|
|
187
|
+
cuda_ver = detect_cuda_version()
|
|
188
|
+
if cuda_ver:
|
|
189
|
+
spec["accelerator"] = "cuda"
|
|
190
|
+
spec["cuda_version"] = cuda_ver
|
|
191
|
+
major_minor = cuda_ver.split(".")
|
|
192
|
+
cu_tag = f"cu{major_minor[0]}{major_minor[1]}" if len(major_minor) >= 2 else "cu124"
|
|
193
|
+
spec["pip_args"] = ["torch", "torchaudio", "--index-url", f"https://download.pytorch.org/whl/{cu_tag}"]
|
|
194
|
+
spec["description"] = f"Windows CUDA {cuda_ver}"
|
|
195
|
+
else:
|
|
196
|
+
spec["pip_args"] = ["torch", "torchaudio", "--index-url", "https://download.pytorch.org/whl/cpu"]
|
|
197
|
+
spec["description"] = "Windows CPU"
|
|
198
|
+
spec["pip_args_str"] = " ".join(spec["pip_args"])
|
|
199
|
+
return spec
|
|
200
|
+
|
|
201
|
+
# ── Linux ──────────────────────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
# Check for Jetson first (aarch64 + NVIDIA GPU via JetPack)
|
|
204
|
+
if is_jetson():
|
|
205
|
+
spec["is_jetson"] = True
|
|
206
|
+
spec["accelerator"] = "cuda"
|
|
207
|
+
spec["cuda_version"] = detect_cuda_version()
|
|
208
|
+
|
|
209
|
+
wheel_url = jetson_torch_wheel_url()
|
|
210
|
+
if wheel_url:
|
|
211
|
+
# Jetson needs wheel URL directly (not index-url)
|
|
212
|
+
spec["pip_args"] = [wheel_url]
|
|
213
|
+
spec["pip_args_str"] = wheel_url
|
|
214
|
+
import re
|
|
215
|
+
version_match = re.search(r"/torch-(\d+)\.(\d+)", wheel_url)
|
|
216
|
+
if version_match:
|
|
217
|
+
spec["torchaudio_version"] = f"{version_match.group(1)}.{version_match.group(2)}.0"
|
|
218
|
+
spec["description"] = f"Jetson aarch64 CUDA {spec['cuda_version'] or '?'} (JetPack wheel)"
|
|
219
|
+
else:
|
|
220
|
+
# Generic PyPI ARM Torch is not a JetPack ABI contract. Fail
|
|
221
|
+
# closed instead of installing a wheel that can report an old or
|
|
222
|
+
# insufficient driver on otherwise healthy Orin hardware.
|
|
223
|
+
spec["error"] = (
|
|
224
|
+
"No environment-matched NVIDIA Jetson Torch wheel was found. "
|
|
225
|
+
"Set JETSON_TORCH_WHEEL to an exact wheel for this L4T, CUDA, "
|
|
226
|
+
"Python ABI, and architecture."
|
|
227
|
+
)
|
|
228
|
+
spec["description"] = f"Jetson aarch64 CUDA {spec['cuda_version'] or '?'} (unsupported until an exact wheel is supplied)"
|
|
229
|
+
return spec
|
|
230
|
+
|
|
231
|
+
# Non-Jetson aarch64 (ARM server, Raspberry Pi, etc.)
|
|
232
|
+
if machine in ("aarch64", "arm64", "armv7l"):
|
|
233
|
+
cuda_ver = detect_cuda_version()
|
|
234
|
+
if cuda_ver:
|
|
235
|
+
spec["accelerator"] = "cuda"
|
|
236
|
+
spec["cuda_version"] = cuda_ver
|
|
237
|
+
# ARM + CUDA (e.g., Grace Hopper) — use generic pip (PyTorch publishes aarch64+cuda wheels on PyPI)
|
|
238
|
+
spec["pip_args"] = ["torch", "torchaudio"]
|
|
239
|
+
spec["description"] = f"Linux aarch64 CUDA {cuda_ver}"
|
|
240
|
+
else:
|
|
241
|
+
# ARM CPU — PyTorch publishes aarch64 CPU wheels on PyPI since 2.0+
|
|
242
|
+
# Do NOT use --index-url whl/cpu (no aarch64 there)
|
|
243
|
+
spec["pip_args"] = ["torch", "torchaudio"]
|
|
244
|
+
spec["description"] = "Linux aarch64 CPU"
|
|
245
|
+
spec["pip_args_str"] = " ".join(spec["pip_args"])
|
|
246
|
+
return spec
|
|
247
|
+
|
|
248
|
+
# x86_64 Linux
|
|
249
|
+
cuda_ver = detect_cuda_version()
|
|
250
|
+
if cuda_ver:
|
|
251
|
+
spec["accelerator"] = "cuda"
|
|
252
|
+
spec["cuda_version"] = cuda_ver
|
|
253
|
+
# Map CUDA version to PyTorch index tag
|
|
254
|
+
major = int(cuda_ver.split(".")[0])
|
|
255
|
+
minor = int(cuda_ver.split(".")[1]) if "." in cuda_ver else 0
|
|
256
|
+
if major >= 12 and minor >= 4:
|
|
257
|
+
cu_tag = "cu124"
|
|
258
|
+
elif major >= 12 and minor >= 1:
|
|
259
|
+
cu_tag = "cu121"
|
|
260
|
+
elif major >= 11 and minor >= 8:
|
|
261
|
+
cu_tag = "cu118"
|
|
262
|
+
else:
|
|
263
|
+
cu_tag = "cu121" # default fallback
|
|
264
|
+
spec["pip_args"] = ["torch", "torchaudio", "--index-url", f"https://download.pytorch.org/whl/{cu_tag}"]
|
|
265
|
+
spec["description"] = f"Linux x86_64 CUDA {cuda_ver} ({cu_tag})"
|
|
266
|
+
else:
|
|
267
|
+
spec["pip_args"] = ["torch", "torchaudio", "--index-url", "https://download.pytorch.org/whl/cpu"]
|
|
268
|
+
spec["description"] = "Linux x86_64 CPU"
|
|
269
|
+
|
|
270
|
+
spec["pip_args_str"] = " ".join(spec["pip_args"])
|
|
271
|
+
return spec
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def main():
|
|
275
|
+
spec = detect_torch_spec()
|
|
276
|
+
|
|
277
|
+
if len(sys.argv) > 1:
|
|
278
|
+
flag = sys.argv[1]
|
|
279
|
+
if flag == "--pip-args":
|
|
280
|
+
print(spec["pip_args_str"])
|
|
281
|
+
return
|
|
282
|
+
elif flag == "--index-url":
|
|
283
|
+
for i, arg in enumerate(spec["pip_args"]):
|
|
284
|
+
if arg == "--index-url" and i + 1 < len(spec["pip_args"]):
|
|
285
|
+
print(spec["pip_args"][i + 1])
|
|
286
|
+
return
|
|
287
|
+
print("") # no index-url (use default PyPI)
|
|
288
|
+
return
|
|
289
|
+
elif flag == "--description":
|
|
290
|
+
print(spec["description"])
|
|
291
|
+
return
|
|
292
|
+
elif flag == "--accelerator":
|
|
293
|
+
print(spec["accelerator"])
|
|
294
|
+
return
|
|
295
|
+
elif flag == "--json":
|
|
296
|
+
pass # fall through to JSON output
|
|
297
|
+
else:
|
|
298
|
+
print(f"Unknown flag: {flag}", file=sys.stderr)
|
|
299
|
+
print("Usage: detect-torch.py [--pip-args|--index-url|--description|--accelerator|--json]", file=sys.stderr)
|
|
300
|
+
sys.exit(1)
|
|
301
|
+
|
|
302
|
+
print(json.dumps(spec, indent=2))
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
if __name__ == "__main__":
|
|
306
|
+
main()
|