Custom node pack implementing Mistral's Voxtral-4B-TTS-2603 model with direct PyTorch inference (no vLLM dependency), enabling native MPS/Mac support alongside CUDA. Three-component architecture: - Mistral LLM backbone (26 layers, 3072 dim, GQA, RoPE) - Flow-matching acoustic transformer (3 layers, 8-step Euler ODE, CFG) - Neural audio codec decoder (4-stage ALiBi transformer + conv upsampling) Features: - 20 preset voices across 9 languages - 24 kHz mono output - BF16/FP16/FP32 dtype support - HuggingFace Hub auto-download with caching - ComfyUI AUDIO output format Nodes: - FL_VoxtralTTS_ModelLoader: download and load model - FL_VoxtralTTS_Generate: text + voice → audio Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 lines
976 B
Python
31 lines
976 B
Python
"""Audio format conversion utilities for ComfyUI."""
|
|
|
|
import torch
|
|
import numpy as np
|
|
|
|
|
|
def numpy_to_comfyui_audio(audio_array: np.ndarray, sample_rate: int) -> dict:
|
|
"""Convert numpy audio to ComfyUI AUDIO dict.
|
|
|
|
Args:
|
|
audio_array: 1D float32 numpy array
|
|
sample_rate: Sample rate in Hz
|
|
|
|
Returns:
|
|
{"waveform": Tensor[1, 1, samples], "sample_rate": int}
|
|
"""
|
|
if audio_array.ndim == 1:
|
|
tensor = torch.from_numpy(audio_array).float().unsqueeze(0).unsqueeze(0)
|
|
elif audio_array.ndim == 2:
|
|
tensor = torch.from_numpy(audio_array).float().unsqueeze(0)
|
|
else:
|
|
tensor = torch.from_numpy(audio_array).float()
|
|
|
|
return {"waveform": tensor, "sample_rate": sample_rate}
|
|
|
|
|
|
def empty_audio(sample_rate: int = 24000) -> dict:
|
|
"""Return 1 second of silence as a ComfyUI AUDIO dict."""
|
|
silence = torch.zeros(1, 1, sample_rate, dtype=torch.float32)
|
|
return {"waveform": silence, "sample_rate": sample_rate}
|