Before claude rewrite

This commit is contained in:
James Ketr 2025-09-17 14:06:18 -07:00
parent ed8967f394
commit 6620c0ac74
9 changed files with 2021 additions and 449 deletions

View File

@ -12,3 +12,4 @@
**/*.key
**/package-lock.json
**/*.pyc
**/VibeVoice

View File

@ -15,7 +15,7 @@
- Always run tests inside the appropriate Docker containers using `docker compose exec`
- Use `uv run` for Python commands in voicebot and server containers
- Tests should be placed in the `tests/` directory (bind mounted to `/tests` in containers)
- Use proper PYTHONPATH when running Python code: `PYTHONPATH=/shared:/voicebot` for voicebot, `PYTHONPATH=/shared:/server` for server
- Use proper PYTHONPATH when running Python code: `PYTHONPATH=/:/voicebot` for voicebot, `PYTHONPATH=/:/server` for server
- Check container logs with `docker compose logs --since 10m SERVICE_NAME` for debugging
### Voicebot Testing (Python with uv)

View File

@ -2,228 +2,3 @@ body {
font-family: 'Droid Sans', 'Arial Narrow', Arial, sans-serif;
overflow: hidden;
}
#root {
width: 100vw;
/* height: 100vh; breaks on mobile -- not needed */
}
.Table {
display: flex;
position: absolute;
top: 0;
left: 0;
width: 100%;
bottom: 0;
flex-direction: row;
/* background-image: url("./assets/tabletop.png"); */
}
.Table .Dialogs {
z-index: 10000;
display: flex;
justify-content: space-around;
align-items: center;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.Table .Dialogs .Dialog {
display: flex;
position: absolute;
flex-shrink: 1;
flex-direction: column;
padding: 0.25rem;
left: 0;
right: 0;
top: 0;
bottom: 0;
justify-content: space-around;
align-items: center;
z-index: 60000;
}
.Table .Dialogs .Dialog > div {
display: flex;
padding: 1rem;
flex-direction: column;
}
.Table .Dialogs .Dialog > div > div:first-child {
padding: 1rem;
}
.Table .Dialogs .TurnNoticeDialog {
background-color: #7a680060;
}
.Table .Dialogs .ErrorDialog {
background-color: #40000060;
}
.Table .Dialogs .WarningDialog {
background-color: #00000060;
}
.Table .Game {
position: relative;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.Table .Board {
display: flex;
position: relative;
flex-grow: 1;
z-index: 500;
}
.Table .PlayersStatus {
z-index: 500; /* Under Hand */
}
.Table .PlayersStatus.ActivePlayer {
z-index: 1500; /* On top of Hand */
}
.Table .Hand {
display: flex;
position: relative;
height: 11rem;
z-index: 10000;
}
.Table .Sidebar {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 25rem;
max-width: 25rem;
overflow: hidden;
z-index: 5000;
}
.Table .Sidebar .Chat {
display: flex;
position: relative;
flex-grow: 1;
}
.Table .Trade {
display: flex;
position: relative;
z-index: 25000;
align-self: center;
}
.Table .Dialogs {
position: absolute;
display: flex;
top: 0;
bottom: 0;
right: 0;
left: 0;
justify-content: space-around;
align-items: center;
z-index: 20000;
pointer-events: none;
}
.Table .Dialogs > * {
pointer-events: all;
}
.Table .ViewCard {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.Table .Winner {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.Table .HouseRules {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.Table .ChooseCard {
display: flex;
position: relative;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.Table button {
margin: 0.25rem;
background-color: white;
border: 1px solid black; /* why !important */
}
.Table .MuiButton-text {
padding: 0.25rem 0.55rem;
}
.Table button:disabled {
opacity: 0.5;
border: 1px solid #ccc; /* why !important */
}
.Table .ActivitiesBox {
display: flex;
flex-direction: column;
position: absolute;
left: 1em;
top: 1em;
}
.Table .DiceRoll {
display: flex;
flex-direction: column;
position: relative;
/*
left: 1rem;
top: 5rem;*/
flex-wrap: wrap;
justify-content: left;
align-items: left;
z-index: 1000;
}
.Table .DiceRoll div:not(:last-child) {
border: 1px solid black;
background-color: white;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
}
.Table .DiceRoll div:last-child {
display: flex;
flex-direction: row;
}
.Table .DiceRoll .Dice {
margin: 0.25rem;
width: 2.75rem;
height: 2.75rem;
border-radius: 0.5rem;
}

View File

@ -191,8 +191,8 @@ const LobbyView: React.FC<LobbyProps> = (props: LobbyProps) => {
sx={{
p: { xs: 1, sm: 2 },
m: { xs: 0, sm: 2 },
width: { xs: "100%", sm: "fit-content" },
maxWidth: { xs: "100%", sm: 600 },
// width: { xs: "100%", sm: "fit-content" },
// maxWidth: { xs: "100%", sm: 600 },
}}
>
{readyState !== ReadyState.OPEN || !session ? (
@ -299,7 +299,7 @@ const App = () => {
<Box
sx={{
p: { xs: 1, sm: 2 },
maxWidth: { xs: "100%", sm: 800 },
// maxWidth: { xs: "100%", sm: 800 },
margin: "0 auto",
height: "100vh",
overflowY: "auto",

View File

@ -1,6 +1,6 @@
.lobby-chat {
min-width: 300px;
max-width: 400px;
max-width: 100%;
}
.chat-messages {
@ -35,9 +35,9 @@
border-bottom-left-radius: 4px !important;
}
@media (max-width: 768px) {
/* @media (max-width: 768px) {
.lobby-chat {
min-width: 250px;
max-width: 300px;
}
}
} */

View File

@ -1,32 +1,13 @@
/*@media only screen and (max-height: 512px) {
html {
font-size: 6.75px;
}
}
@media only screen and (min-height: 513px) and (max-height: 800px) {*/
html {
font-size: 2vh;/*10px;*/
}
/*}
@media only screen and (min-height: 2000px) {
html {
font-size: 30px;
}
}*/
html {
height: 100%;
height: 100dvh;
width: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
display: block;
position: relative;
height: 100%;
width: 100%;
height: 100dvh;
padding: 0;

1574
voicebot/bots/vibevoice.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -58,13 +58,153 @@ AudioArray = npt.NDArray[np.float32]
ModelConfig = Dict[str, Union[str, int, bool]]
CalibrationData = List[Dict[str, Any]]
_device = "GPU.1" # Default to Intel Arc B580 GPU
# Global lock to serialize calls into the OpenVINO model.generate/decode
# since some backends are not safe for concurrent generate calls.
_generate_global_lock = threading.Lock()
def _do_generate_once(model, *args, **kwargs):
"""Submit a single generate call to the serialized worker and return result.
Raises any exception raised by the underlying generate call.
"""
return _submit_generate_to_worker(model.generate, *args, **kwargs)
def _safe_generate_with_retries(model, *args, max_retries: int = 20, initial_delay: float = 0.05, **kwargs):
"""Call model.generate while handling OpenVINO 'Infer Request is busy' by retrying.
This helper retries on RuntimeError containing 'Infer Request is busy' with
exponential backoff. It raises the last exception if retries are exhausted.
"""
delay = initial_delay
last_exc = None
for attempt in range(1, max_retries + 1):
try:
# Submit the actual blocking generate to the serialized worker
return _do_generate_once(model, *args, **kwargs)
except RuntimeError as e:
last_exc = e
msg = str(e)
# Match the specific OpenVINO busy error message
if "Infer Request is busy" in msg:
logger.warning(
f"OpenVINO infer busy (attempt {attempt}/{max_retries}), retrying after {delay:.3f}s..."
)
time.sleep(delay)
delay = min(delay * 2.0, 1.0)
continue
# Not the busy error - re-raise immediately
raise
except Exception:
raise
# Retries exhausted
logger.error(f"OpenVINO generate retries exhausted ({max_retries}) - raising last error: {last_exc}")
raise last_exc
# Global serialized generate worker to ensure OpenVINO infer requests are not
# called concurrently across threads. Some OpenVINO backends will error with
# "Infer Request is busy" if multiple infer calls overlap on the same
# compiled model; queueing here serializes calls at the process level.
_generate_queue = Queue()
_generate_worker_started = False
def _generate_worker() -> None:
while True:
fn, args, kwargs, ev, out = _generate_queue.get()
try:
# Perform internal retries if OpenVINO reports the request as busy.
delay = 0.02
max_inner_retries = 20
last_exc = None
for attempt in range(1, max_inner_retries + 1):
try:
res = fn(*args, **kwargs)
out['result'] = res
out['exc'] = None
break
except RuntimeError as e:
last_exc = e
msg = str(e)
if "Infer Request is busy" in msg:
# log at debug to avoid noise but keep visibility
logger.debug(f"Worker: infer busy (attempt {attempt}/{max_inner_retries}), sleeping {delay:.3f}s")
time.sleep(delay)
delay = min(delay * 2.0, 1.0)
continue
# not a busy error - surface immediately
out['result'] = None
out['exc'] = e
break
except Exception as e:
out['result'] = None
out['exc'] = e
break
else:
# exhausted retries
out['result'] = None
out['exc'] = last_exc
finally:
try:
ev.set()
except Exception:
pass
def _ensure_generate_worker() -> None:
global _generate_worker_started
if _generate_worker_started:
return
t = threading.Thread(target=_generate_worker, daemon=True)
t.start()
_generate_worker_started = True
def _submit_generate_to_worker(fn, *args, **kwargs):
"""Submit a blocking generate fn to the serialized worker and wait for result."""
_ensure_generate_worker()
ev = threading.Event()
out: Dict[str, Any] = {}
_generate_queue.put((fn, args, kwargs, ev, out))
ev.wait()
if out.get('exc'):
raise out['exc']
return out.get('result')
async def _safe_generate_with_retries_async(model, *args, max_retries: int = 20, initial_delay: float = 0.05, **kwargs):
"""Async variant of the generate retry helper that uses asyncio.sleep.
Should be awaited from asynchronous contexts to avoid blocking the event loop.
"""
delay = initial_delay
last_exc = None
for attempt in range(1, max_retries + 1):
try:
# Delegate to the serialized worker in an executor so the event loop
# isn't blocked waiting on the worker event.
loop = asyncio.get_running_loop()
return await loop.run_in_executor(None, lambda: _do_generate_once(model, *args, **kwargs))
except RuntimeError as e:
last_exc = e
msg = str(e)
if "Infer Request is busy" in msg:
logger.warning(
f"OpenVINO infer busy (async attempt {attempt}/{max_retries}), retrying after {delay:.3f}s..."
)
await asyncio.sleep(delay)
delay = min(delay * 2.0, 1.0)
continue
raise
except Exception:
raise
logger.error(f"OpenVINO async generate retries exhausted ({max_retries}) - raising last error: {last_exc}")
raise last_exc
def get_available_devices() -> list[dict[str, Any]]:
"""List available OpenVINO devices with their properties."""
try:
@ -125,9 +265,27 @@ def print_available_devices(device: str | None = None):
logger.info(f" Type: {d.get('type')}")
def find_best_device(preferred_type: str = "DISCRETE") -> str:
"""Find the best available OpenVINO device, preferring the specified type (e.g., 'DISCRETE', 'INTEGRATED', 'CPU', 'GPU')."""
devices = get_available_devices()
if not devices:
logger.warning("No OpenVINO devices found, defaulting to CPU")
return "CPU"
for d in devices:
device_type = str(d.get("type", "")).upper()
if device_type == preferred_type.upper():
logger.info(f"Using preferred device: {preferred_type}")
return d.get("name", "CPU")
logger.info("Preferred device not found, using first available device")
return devices[0].get("name", "CPU")
_device = find_best_device(preferred_type="Type.DISCRETE")
print_available_devices(_device)
class AudioQueueItem(BaseModel):
"""Audio data with timestamp for processing queue."""
@ -536,11 +694,39 @@ class OpenVINOWhisperModel:
logger.info("Whisper processor loaded successfully")
# Export the model to OpenVINO IR if not already converted
try:
self.ov_model = OVModelForSpeechSeq2Seq.from_pretrained( # type: ignore
self.model_id, export=True, device=self.device
) # type: ignore
logger.info("Whisper model exported as OpenVINO IR")
except Exception as export_e:
logger.warning(f"Initial OpenVINO export failed: {export_e}")
# Retry using processor-derived example_inputs if possible
try:
if self.processor is None:
self.processor = WhisperProcessor.from_pretrained(self.model_id, use_fast=True) # type: ignore
dummy_audio = np.random.randn(16000).astype(np.float32)
try:
example_inputs = self.processor(# type: ignore
dummy_audio, sampling_rate=16000, return_tensors="pt"
).input_features # type: ignore
except Exception as ex_inputs:
logger.warning(f"Failed to generate example_inputs for export retry: {ex_inputs}")
example_inputs = None
if example_inputs is not None:
self.ov_model = OVModelForSpeechSeq2Seq.from_pretrained( # type: ignore
self.model_id, export=True, device=self.device, example_inputs=example_inputs
)
else:
self.ov_model = OVModelForSpeechSeq2Seq.from_pretrained( # type: ignore
self.model_id, export=True, device=self.device
)
logger.info("Whisper model exported as OpenVINO IR (retry with example_inputs)")
except Exception as retry_export_e:
logger.error(f"Export retry failed: {retry_export_e}")
raise
# # Try to load quantized model first if it exists
# if self.config.enable_quantization and self.quantized_model_path.exists():
@ -599,6 +785,60 @@ class OpenVINOWhisperModel:
except Exception as e:
logger.error(f"Model conversion failed: {e}")
# If conversion failed due to example_input / tracing mismatch
# try converting again by providing a correctly-shaped example
# input derived from the Whisper processor. This can resolve
# mismatches between the default example and model signatures.
try:
logger.info("Retrying conversion with processor-derived example_inputs...")
if self.processor is None:
# Ensure processor is available
self.processor = WhisperProcessor.from_pretrained(self.model_id, use_fast=True) # type: ignore
# Create a short dummy audio (1s) to produce input_features
try:
dummy_audio = np.random.randn(16000).astype(np.float32)
example_inputs = self.processor(# type: ignore
dummy_audio, sampling_rate=16000, return_tensors="pt"
).input_features # type: ignore
except Exception as ex_inputs:
logger.warning(f"Failed to generate example_inputs from processor: {ex_inputs}")
example_inputs = None
# Attempt conversion again, supplying example_inputs if available
if example_inputs is not None:
ov_model = OVModelForSpeechSeq2Seq.from_pretrained( # type: ignore
self.model_id,
ov_config=self.config.to_ov_config(),
export=True,
compile=False,
example_inputs=example_inputs,
load_in_8bit=False,
)
else:
ov_model = OVModelForSpeechSeq2Seq.from_pretrained( # type: ignore
self.model_id,
ov_config=self.config.to_ov_config(),
export=True,
compile=False,
load_in_8bit=False,
)
if hasattr(ov_model, 'half'):
ov_model.half() # type: ignore
ov_model.save_pretrained(self.model_path) # type: ignore
logger.info("Model converted and saved in FP16 format (retry with example_inputs)")
self.ov_model = ov_model # type: ignore
self._compile_model()
return
except TypeError as te:
# from_pretrained may not accept example_inputs in some versions
logger.warning(f"Conversion retry with example_inputs not supported: {te}")
except Exception as retry_e:
logger.warning(f"Retry conversion with example_inputs failed: {retry_e}")
# If all conversion attempts fail, propagate to fallback path
logger.warning("Falling back to basic conversion without advanced export options")
raise
def _convert_model_basic(self) -> None:
@ -816,8 +1056,8 @@ class OpenVINOWhisperModel:
) # type: ignore
# Run inference to collect calibration data
_ = self.ov_model.generate( # type: ignore
inputs.input_features, max_new_tokens=10 # type: ignore
_ = _safe_generate_with_retries( # type: ignore
self.ov_model, inputs.input_features, max_new_tokens=10
)
if i % 5 == 0:
@ -957,7 +1197,7 @@ class OpenVINOWhisperModel:
# Run warmup iterations
for i in range(3):
_ = self.ov_model.generate(dummy_features, max_new_tokens=10)# type: ignore
_ = _safe_generate_with_retries(self.ov_model, dummy_features, max_new_tokens=10) # type: ignore
if i == 0:
logger.debug("First warmup iteration completed")
except Exception as e:
@ -1482,9 +1722,7 @@ class OptimizedAudioProcessor:
# Serialize access to the underlying OpenVINO generation call
# to avoid concurrency problems with the OpenVINO runtime.
with _generate_global_lock:
gen_out = ov_model.ov_model.generate(# type: ignore
input_features, generation_config=gen_cfg# type: ignore
)
gen_out = _safe_generate_with_retries(ov_model.ov_model, input_features, generation_config=gen_cfg) # type: ignore
# Try to extract sequences if present
if hasattr(gen_out, "sequences"): # type: ignore
@ -1886,9 +2124,8 @@ class OptimizedAudioProcessor:
logger.info(f"{self.peer_name}: calling model.generate (async lock) (final)")
else:
logger.debug(f"{self.peer_name}: calling model.generate (async lock)")
generation_output = ov_model.ov_model.generate( # type: ignore
input_features, generation_config=generation_config
)
# Use async-safe retry wrapper to avoid blocking event loop
generation_output = await _safe_generate_with_retries_async(ov_model.ov_model, input_features, generation_config=generation_config) # type: ignore
finally:
self._generate_lock.release()
elif hasattr(self, "_generate_lock") and isinstance(self._generate_lock, threading.Lock):
@ -1897,17 +2134,13 @@ class OptimizedAudioProcessor:
logger.info(f"{self.peer_name}: calling model.generate (thread lock) (final)")
else:
logger.debug(f"{self.peer_name}: calling model.generate (thread lock)")
generation_output = ov_model.ov_model.generate( # type: ignore
input_features, generation_config=generation_config
)
generation_output = _safe_generate_with_retries(ov_model.ov_model, input_features, generation_config=generation_config) # type: ignore
else:
if is_final:
logger.info(f"{self.peer_name}: calling model.generate (no lock) (final)")
else:
logger.debug(f"{self.peer_name}: calling model.generate (no lock)")
generation_output = ov_model.ov_model.generate( # type: ignore
input_features, generation_config=generation_config
)
generation_output = _safe_generate_with_retries(ov_model.ov_model, input_features, generation_config=generation_config) # type: ignore
if is_final:
logger.info(f"{self.peer_name}: model.generate complete (final) (type={type(generation_output)})")
@ -2686,7 +2919,7 @@ def get_config_schema() -> Dict[str, Any]:
"default_value": _device,
"required": True,
"options": [
{"value": "GPU.1", "label": "Intel Arc GPU (GPU.1)"},
# {"value": "GPU.1", "label": "Intel Arc GPU (GPU.1)"},
{"value": "GPU", "label": "GPU"},
{"value": "CPU", "label": "CPU"}
]
@ -2959,7 +3192,7 @@ def handle_config_update(lobby_id: str, config_values: Dict[str, Any]) -> bool:
if "device" in config_values:
new_device = config_values["device"] # type: ignore
available_devices = [d["name"] for d in get_available_devices()]
if new_device in available_devices or new_device in ["CPU", "GPU", "GPU.1"]:
if new_device in available_devices or new_device in ["CPU", "GPU"]:#, "GPU.1"]:
_device = new_device
_ov_config.device = new_device
config_applied = True

View File

@ -1,175 +1,183 @@
about-time
aiofiles
aiohappyeyeballs
aiohttp
aioice
aiortc
aiosignal
alive-progress
annotated-types
anthropic
anyio
attrs
audioread
autograd
av
brotli
certifi
cffi
charset-normalizer
click
cma
contourpy
cryptography
cycler
datasets
decorator
deprecated
dill
distro
dnspython
fastapi
ffmpy
filelock
fonttools
frozenlist
fsspec
google-crc32c
gradio
gradio-client
grapheme
graphemeu
groovy
h11
hf-xet
httpcore
httpx
huggingface-hub
idna
ifaddr
iniconfig
jinja2
jiter
jiwer
joblib
jsonschema
jsonschema-specifications
kiwisolver
lazy-loader
librosa
llvmlite
markdown-it-py
markupsafe
matplotlib
mdurl
ml-dtypes
more-itertools
mpmath
msgpack
multidict
multiprocess
natsort
networkx
ninja
nncf
numba
numpy
nvidia-cublas-cu12
nvidia-cuda-cupti-cu12
nvidia-cuda-nvrtc-cu12
nvidia-cuda-runtime-cu12
nvidia-cudnn-cu12
nvidia-cufft-cu12
nvidia-cufile-cu12
nvidia-curand-cu12
nvidia-cusolver-cu12
nvidia-cusparse-cu12
nvidia-cusparselt-cu12
nvidia-nccl-cu12
nvidia-nvjitlink-cu12
nvidia-nvtx-cu12
onnx
openai
about-time==4.2.1
absl-py==2.3.1
accelerate==1.6.0
aiofiles==24.1.0
aiohappyeyeballs==2.6.1
aiohttp==3.12.15
aioice==0.10.1
aiortc==1.13.0
aiosignal==1.4.0
alive-progress==3.2.0
annotated-types==0.7.0
anthropic==0.67.0
anyio==4.10.0
attrs==25.3.0
audioread==3.0.1
autograd==1.8.0
av==14.4.0
brotli==1.1.0
certifi==2025.8.3
cffi==2.0.0
charset-normalizer==3.4.3
click==8.2.1
cma==4.3.0
contourpy==1.3.3
cryptography==45.0.7
cycler==0.12.1
datasets==4.1.0
decorator==5.2.1
deprecated==1.2.18
diffusers==0.35.1
dill==0.4.0
distro==1.9.0
dnspython==2.8.0
fastapi==0.116.1
ffmpy==0.6.1
filelock==3.19.1
fonttools==4.59.2
frozenlist==1.7.0
fsspec==2025.9.0
google-crc32c==1.7.1
gradio==5.45.0
gradio-client==1.13.0
grapheme==0.6.0
graphemeu==0.8.0
groovy==0.1.2
h11==0.16.0
hf-xet==1.1.10
httpcore==1.0.9
httpx==0.28.1
huggingface-hub==0.34.5
idna==3.10
ifaddr==0.2.0
importlib-metadata==8.7.0
iniconfig==2.1.0
jinja2==3.1.6
jiter==0.11.0
jiwer==4.0.0
joblib==1.5.2
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
kiwisolver==1.4.9
lazy-loader==0.4
librosa==0.11.0
llvmlite==0.44.0
markdown-it-py==4.0.0
markupsafe==3.0.2
matplotlib==3.10.6
mdurl==0.1.2
ml-collections==1.1.0
ml-dtypes==0.5.3
more-itertools==10.8.0
mpmath==1.3.0
msgpack==1.1.1
multidict==6.6.4
multiprocess==0.70.16
natsort==8.4.0
networkx==3.4.2
ninja==1.13.0
nncf==2.18.0
numba==0.61.2
numpy==2.2.6
nvidia-cublas-cu12==12.8.4.1
nvidia-cuda-cupti-cu12==12.8.90
nvidia-cuda-nvrtc-cu12==12.8.93
nvidia-cuda-runtime-cu12==12.8.90
nvidia-cudnn-cu12==9.10.2.21
nvidia-cufft-cu12==11.3.3.83
nvidia-cufile-cu12==1.13.1.3
nvidia-curand-cu12==10.3.9.90
nvidia-cusolver-cu12==11.7.3.90
nvidia-cusparse-cu12==12.5.8.93
nvidia-cusparselt-cu12==0.7.1
nvidia-nccl-cu12==2.27.3
nvidia-nvjitlink-cu12==12.8.93
nvidia-nvtx-cu12==12.8.90
onnx==1.19.0
openai==1.107.2
openai-whisper @ git+https://github.com/openai/whisper.git@c0d2f624c09dc18e709e37c2ad90c039a4eb72a2
opencv-python
openvino
openvino-genai
openvino-telemetry
openvino-tokenizers
optimum
opencv-python==4.12.0.88
openvino==2025.3.0
openvino-genai==2025.3.0.0
openvino-telemetry==2025.2.0
openvino-tokenizers==2025.3.0.0
optimum==1.27.0
optimum-intel @ git+https://github.com/huggingface/optimum-intel.git@b9c151fec6b414d9ca78be8643d08e267b133bfc
orjson
packaging
pandas
pillow
platformdirs
pluggy
pooch
propcache
protobuf
psutil
pyarrow
pycparser
pydantic
pydantic-core
pydot
pydub
pyee
pygments
pylibsrtp
pymoo
pyopencl
pyopenssl
pyparsing
pytest
pytest-asyncio
python-dateutil
python-ffmpeg
python-multipart
pytools
pytz
pyyaml
rapidfuzz
referencing
regex
requests
resampy
rich
rpds-py
ruff
safehttpx
safetensors
scikit-learn
scipy
semantic-version
setuptools
shellingham
siphash24
six
sniffio
soundfile
soxr
speechrecognition
starlette
sympy
tabulate
threadpoolctl
tiktoken
tokenizers
tomlkit
torch
torchvision
tqdm
transformers
triton
typer
typing-extensions
typing-inspection
tzdata
urllib3
uvicorn
watchdog
websockets
wrapt
xxhash
yarl
orjson==3.11.3
packaging==25.0
pandas==2.3.2
peft==0.17.1
pillow==11.3.0
platformdirs==4.4.0
pluggy==1.6.0
pooch==1.8.2
propcache==0.3.2
protobuf==6.32.1
psutil==7.0.0
pyarrow==21.0.0
pycparser==2.23
pydantic==2.11.9
pydantic-core==2.33.2
pydot==3.0.4
pydub==0.25.1
pyee==13.0.0
pygments==2.19.2
pylibsrtp==0.12.0
pymoo==0.6.1.5
pyopencl==2025.2.6
pyopenssl==25.2.0
pyparsing==3.2.4
pytest==8.4.2
pytest-asyncio==1.2.0
python-dateutil==2.9.0.post0
python-ffmpeg==2.0.12
python-multipart==0.0.20
pytools==2025.2.4
pytz==2025.2
pyyaml==6.0.2
rapidfuzz==3.14.1
referencing==0.36.2
regex==2025.9.1
requests==2.32.5
resampy==0.4.3
rich==14.1.0
rpds-py==0.27.1
ruff==0.13.0
safehttpx==0.1.6
safetensors==0.6.2
scikit-learn==1.7.2
scipy==1.16.2
semantic-version==2.10.0
setuptools==80.9.0
shellingham==1.5.4
siphash24==1.8
six==1.17.0
sniffio==1.3.1
soundfile==0.13.1
soxr==1.0.0
speechrecognition==3.14.3
starlette==0.47.3
sympy==1.14.0
tabulate==0.9.0
threadpoolctl==3.6.0
tiktoken==0.11.0
tokenizers==0.21.4
tomlkit==0.13.3
torch==2.8.0
torchvision==0.23.0
tqdm==4.67.1
transformers==4.53.3
triton==3.4.0
typer==0.17.4
typing-extensions==4.15.0
typing-inspection==0.4.1
tzdata==2025.2
urllib3==2.5.0
uvicorn==0.35.0
-e file:///voicebot/VibeVoice
watchdog==6.0.0
websockets==15.0.1
wrapt==1.17.3
xxhash==3.5.0
yarl==1.20.1
zipp==3.23.0