DramaboxTTS / src /higgs_backend.py
Daankular's picture
Convert Space to Higgs Audio v3 only
15d0571 verified
Raw
History Blame Contribute Delete
2.92 kB
#!/usr/bin/env python3
"""Higgs Audio v3 (4B) TTS backend for ZeroGPU.
Ported from the `transformers`-native demo at
multimodalart/higgs-audio-v3-tts, which wraps bosonai/higgs-audio-v3-tts-4b
via multimodalart/higgs-audio-v3-tts-4b-transformers.
``load()`` is called once at app startup. ZeroGPU's CUDA emulation packs the
model tensors before a real GPU is assigned to the decorated request handler.
"""
import logging
import os
import torch
MODEL_REPO = "multimodalart/higgs-audio-v3-tts-4b-transformers"
_tokenizer = None
_model = None
_sample_rate = None
def load():
"""Load the tokenizer, model, and audio codec onto cuda. Idempotent."""
global _tokenizer, _model, _sample_rate
if _model is not None:
return
from transformers import AutoModelForCausalLM, AutoTokenizer
logging.info(f"Loading Higgs Audio v3 ({MODEL_REPO})…")
token = os.environ.get("HF_TOKEN")
_tokenizer = AutoTokenizer.from_pretrained(
MODEL_REPO,
token=token,
trust_remote_code=True,
)
_model = (
AutoModelForCausalLM.from_pretrained(
MODEL_REPO,
token=token,
trust_remote_code=True,
dtype=torch.bfloat16,
)
.to("cuda")
.eval()
)
_model.get_audio_codec() # preload the 24 kHz codec
_sample_rate = _model.config.sample_rate
logging.info("Higgs Audio v3 ready.")
def generate(text, voice_ref=None, reference_text=None, temperature=0.7,
top_p=0.95, top_k=50, max_new_tokens=2048, seed=-1):
"""Generate speech with Higgs Audio v3.
voice_ref: optional path to a reference clip for zero-shot cloning.
reference_text: optional transcript of voice_ref — improves cloning when
provided, but generation works without it.
Returns (waveform: 1-D numpy array, sample_rate: int).
"""
if _model is None:
raise RuntimeError("Higgs Audio v3 is not loaded — call higgs_backend.load() at startup.")
import soundfile as sf
if seed is not None and int(seed) >= 0:
torch.manual_seed(int(seed))
kwargs = dict(
max_new_tokens=int(max_new_tokens),
temperature=float(temperature),
top_p=float(top_p) if float(top_p) < 1.0 else None,
top_k=int(top_k) if int(top_k) > 0 else None,
)
if voice_ref:
data, sr = sf.read(voice_ref, dtype="float32", always_2d=True) # [L, C]
wav = torch.from_numpy(data).mean(dim=1) # to mono [L]
kwargs["reference_audio"] = wav
kwargs["reference_sample_rate"] = sr
if reference_text and reference_text.strip():
kwargs["reference_text"] = reference_text.strip()
audio = _model.generate_speech(text, _tokenizer, **kwargs)
if audio.numel() == 0:
raise RuntimeError("Higgs Audio v3 produced no audio — try again or adjust the text.")
return audio.numpy(), _sample_rate