Files
filliptmandClaude Opus 4.6 60f6897263 Initial implementation of Voxtral-4B TTS direct inference for ComfyUI
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>
2026-03-26 20:09:20 -05:00

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}