omnius 1.0.816 → 1.0.818

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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/index.js
3
- size: 34785482 bytes
4
- sha256: f8f780895f6b7e602bc6b54c06246a210372d0dde51d59977535e8e20ce25d89
3
+ size: 35351446 bytes
4
+ sha256: 10a8553236a1d111a1007db137fd98e738b5410dc573bc10242ff3d5a2604212
@@ -0,0 +1,95 @@
1
+ """Private parent-owned CUDA lease channel. This module imports only stdlib.
2
+
3
+ The parent acquires before spawning us. It alone holds the negotiator token.
4
+ Every model operation shares one prepare/synchronize/ready critical section.
5
+ """
6
+ import json
7
+ import os
8
+ import re
9
+ import socket
10
+ import threading
11
+ from contextlib import contextmanager
12
+
13
+
14
+ class CudaLeaseFatal(BaseException):
15
+ """Cannot be swallowed by ordinary ASR/consensus error recovery."""
16
+
17
+
18
+ def _terminate(message):
19
+ os.write(2, ("Live Whisper CUDA lease failed: " + str(message) + "\n").encode())
20
+ # Includes consensus-thread failures: no other thread may keep using CUDA.
21
+ os._exit(70)
22
+
23
+
24
+ class WhisperCudaControl:
25
+ def __init__(self, channel, fatal=_terminate):
26
+ self.channel = channel
27
+ self.fatal = fatal
28
+ self.lock = threading.Lock()
29
+ self.sequence = 0
30
+ self.active = False
31
+ self.failed = False
32
+
33
+ @classmethod
34
+ def from_environment(cls):
35
+ uuid = os.environ.get("CUDA_VISIBLE_DEVICES", "")
36
+ if (os.environ.get("OMNIUS_ASR_GPU_CONTROL_FD") != "3"
37
+ or os.environ.get("OMNIUS_ASR_CUDA_DEVICE") != "0"
38
+ or not re.fullmatch(r"GPU-[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}", uuid)):
39
+ raise CudaLeaseFatal("Live Whisper requires its Omnius scoped CUDA supervisor (FD 3 and one explicit GPU UUID); direct/unleased launch is refused before CUDA imports.")
40
+ try:
41
+ channel = socket.socket(fileno=3)
42
+ # live-whisper may exec its managed venv before loading dependencies.
43
+ os.set_inheritable(3, True)
44
+ return cls(channel)
45
+ except Exception as error:
46
+ raise CudaLeaseFatal("Live Whisper GPU control FD 3 is unavailable") from error
47
+
48
+ def abort(self, error):
49
+ self.failed = True
50
+ self.fatal(str(error))
51
+ raise CudaLeaseFatal(str(error))
52
+
53
+ def request(self, action):
54
+ if self.failed:
55
+ self.abort("previous control failure")
56
+ self.sequence += 1
57
+ try:
58
+ self.channel.sendall((json.dumps({"id": self.sequence, "action": action, "device": "cuda:0"}) + "\n").encode())
59
+ data = bytearray()
60
+ while not data.endswith(b"\n"):
61
+ part = self.channel.recv(1)
62
+ if not part or len(data) >= 8192:
63
+ raise ValueError("closed or oversized parent response")
64
+ data.extend(part)
65
+ reply = json.loads(data)
66
+ if reply != {"id": self.sequence, "ok": True}:
67
+ raise ValueError("parent refused CUDA operation")
68
+ except Exception as error:
69
+ self.abort(error)
70
+
71
+ def loaded(self, synchronize):
72
+ with self.lock:
73
+ try:
74
+ synchronize()
75
+ self.request("ready")
76
+ self.active = True
77
+ except Exception as error:
78
+ self.abort(error)
79
+
80
+ @contextmanager
81
+ def operation(self, synchronize):
82
+ with self.lock:
83
+ if not self.active or self.failed:
84
+ self.abort("CUDA operation before resident acknowledgement")
85
+ self.request("prepare")
86
+ self.active = False
87
+ try:
88
+ yield
89
+ finally:
90
+ try:
91
+ synchronize()
92
+ self.request("ready")
93
+ self.active = True
94
+ except Exception as error:
95
+ self.abort(error)
@@ -30,7 +30,9 @@ Protocol:
30
30
  {"type":"error","message":"..."}
31
31
 
32
32
  Usage:
33
- arecord -f S16_LE -r 16000 -c 1 -t raw -q - | python3 live-whisper.py --model base
33
+ Started by Omnius with a parent-owned scoped GPU lease and private FD 3.
34
+ Configure OMNIUS_ASR_CUDA_VISIBLE_DEVICES with one capable full GPU UUID.
35
+ Direct pipes/Nexus launches without this supervisor fail before CUDA imports.
34
36
  """
35
37
 
36
38
  import sys
@@ -42,13 +44,19 @@ import time
42
44
  import threading
43
45
  from collections import deque
44
46
  from pathlib import Path
47
+ from asr_cuda_control import WhisperCudaControl
48
+
49
+ # Fail before dependency/bootstrap imports can initialize CUDA. The FD remains
50
+ # inheritable across the managed-venv exec, and the parent already owns a grant.
51
+ CUDA_CONTROL = WhisperCudaControl.from_environment()
45
52
 
46
53
  # ---------------------------------------------------------------------------
47
54
  # Configuration
48
55
  # ---------------------------------------------------------------------------
49
56
 
50
57
  SCRIPT_DIR = Path(__file__).resolve().parent
51
- VENV = SCRIPT_DIR / ".whisper-venv"
58
+ VENV = Path(os.environ.get("OMNIUS_ASR_PYTHON_VENV", "").strip() or
59
+ str(Path.home() / ".omnius" / "runtimes" / "asr" / "whisper-venv")).expanduser()
52
60
  PY = VENV / "bin" / "python"
53
61
  PIP = VENV / "bin" / "pip"
54
62
 
@@ -238,7 +246,7 @@ def _in_venv() -> bool:
238
246
 
239
247
 
240
248
  def _ensure_venv():
241
- if VENV.exists():
249
+ if PY.exists():
242
250
  return
243
251
  emit_status("Creating Python venv for Whisper...")
244
252
  import venv
@@ -264,7 +272,7 @@ def _ensure_deps():
264
272
  if need:
265
273
  emit_status(f"Installing: {', '.join(need)}...")
266
274
  subprocess.check_call(
267
- [str(PIP), "install", *need],
275
+ [sys.executable, "-m", "pip", "install", *need],
268
276
  stdout=subprocess.DEVNULL, stderr=subprocess.PIPE,
269
277
  )
270
278
  for mod in ["numpy", "whisper"]:
@@ -278,7 +286,7 @@ def _ensure_deps():
278
286
  except ImportError:
279
287
  try:
280
288
  subprocess.check_call(
281
- [str(PIP), "install", "pyusb"],
289
+ [sys.executable, "-m", "pip", "install", "pyusb"],
282
290
  stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
283
291
  )
284
292
  except Exception:
@@ -534,6 +542,8 @@ def main():
534
542
  import whisper
535
543
 
536
544
  device = select_whisper_device()
545
+ if device != "cuda:0":
546
+ CUDA_CONTROL.abort("Scoped live Whisper requires logical cuda:0; CPU fallback is refused")
537
547
  emit_status(f"Loading Whisper {args.model} model on {device}...")
538
548
  try:
539
549
  model_dir = whisper_model_dir()
@@ -568,6 +578,8 @@ def main():
568
578
  emit_status("ReSpeaker DSP active: hardware VAD, echo cancellation, DOA.")
569
579
 
570
580
  fp16 = str(device).startswith("cuda")
581
+ import torch
582
+ CUDA_CONTROL.loaded(lambda: torch.cuda.synchronize(device))
571
583
  emit({
572
584
  "type": "ready",
573
585
  "model": args.model,
@@ -583,13 +595,15 @@ def main():
583
595
  silent, _ = digitally_silent_pcm16(samples)
584
596
  if silent:
585
597
  return {"text": "", "segments": []}
586
- return m.transcribe(
587
- samples,
588
- fp16=fp16,
589
- language=args.language,
590
- no_speech_threshold=0.6,
591
- condition_on_previous_text=False,
592
- )
598
+ # Primary, partial and consensus calls share the same lease/lock.
599
+ with CUDA_CONTROL.operation(lambda: torch.cuda.synchronize(device)):
600
+ return m.transcribe(
601
+ samples,
602
+ fp16=fp16,
603
+ language=args.language,
604
+ no_speech_threshold=0.6,
605
+ condition_on_previous_text=False,
606
+ )
593
607
 
594
608
  # Shared PCM intake
595
609
  audio_buf = np.zeros(0, dtype=np.float32)
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.816",
3
+ "version": "1.0.818",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.816",
9
+ "version": "1.0.818",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
@@ -2602,9 +2602,9 @@
2602
2602
  }
2603
2603
  },
2604
2604
  "node_modules/bare-fs": {
2605
- "version": "4.8.2",
2606
- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.2.tgz",
2607
- "integrity": "sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==",
2605
+ "version": "4.8.3",
2606
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.8.3.tgz",
2607
+ "integrity": "sha512-KQi9ShyPS/nOCtKpma7At8wbq4ORSNUmD67hsZrPcaWJcEmL8PHyS2xVWT308y8/LvHFOUTytTTDsD8dInx6bA==",
2608
2608
  "license": "Apache-2.0",
2609
2609
  "optional": true,
2610
2610
  "dependencies": {
@@ -5522,9 +5522,9 @@
5522
5522
  "license": "MIT"
5523
5523
  },
5524
5524
  "node_modules/readable-stream": {
5525
- "version": "4.7.0",
5526
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
5527
- "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
5525
+ "version": "4.8.0",
5526
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.8.0.tgz",
5527
+ "integrity": "sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==",
5528
5528
  "license": "MIT",
5529
5529
  "dependencies": {
5530
5530
  "abort-controller": "^3.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.816",
3
+ "version": "1.0.818",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/library.js",