Text-to-Speech
Transformers
ONNX
Safetensors
English
Chinese
bailing_moe_v3_audio
feature-extraction
audio
speech
automatic-speech-recognition
audio-understanding
audio-reasoning
speech-to-text
conversational
mixture-of-experts
custom_code
Instructions to use eshmoideas/Ming-audio with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use eshmoideas/Ming-audio with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-to-speech", model="eshmoideas/Ming-audio", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("eshmoideas/Ming-audio", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
File size: 4,852 Bytes
6bd8f62 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | """Audio processor for BailingMoE V3 Audio Hugging Face inference."""
from pathlib import Path
import torch
import torchaudio
import soundfile as sf
import whisper
from transformers import AutoTokenizer, BatchFeature
from transformers.processing_utils import ProcessorMixin
from .configuration_bailing_moe_v3_audio import BailingMoeV3AudioConfig
class BailingMoeV3AudioProcessor(ProcessorMixin):
attributes = ["tokenizer"]
tokenizer_class = "AutoTokenizer"
ASR_PROMPT = (
"Please recognize the language of this speech and transcribe it, "
"placing a `\t` between the identified language and the transcribe."
)
def __init__(self, tokenizer, audio_config=None):
super().__init__(tokenizer)
self.audio_config = audio_config
@classmethod
def from_pretrained(cls, pretrained_model_name_or_path, **kwargs):
tokenizer = AutoTokenizer.from_pretrained(pretrained_model_name_or_path, **kwargs)
config = BailingMoeV3AudioConfig.from_pretrained(
pretrained_model_name_or_path, **kwargs
)
return cls(tokenizer, config.audio_config)
def _load_audio(self, audio):
if isinstance(audio, (str, Path)):
samples, sample_rate = sf.read(str(audio), dtype="float32", always_2d=True)
waveform = torch.from_numpy(samples.T.copy())
elif isinstance(audio, tuple) and len(audio) == 2:
waveform, sample_rate = audio
waveform = torch.as_tensor(waveform)
else:
raise TypeError("audio must be a path or a (waveform, sample_rate) tuple")
if waveform.ndim == 1:
waveform = waveform.unsqueeze(0)
if waveform.ndim != 2:
raise ValueError("waveform must have shape [samples] or [channels, samples]")
waveform = waveform.float()
if sample_rate != 16000:
waveform = torchaudio.functional.resample(waveform, sample_rate, 16000)
return waveform.mean(dim=0)
def _num_audio_tokens(self, mel_length):
config = self.audio_config
chunk_size = getattr(config, "whisper_chunk_size", 3000)
kernels = config.downsampler_kernel_size_list
strides = config.downsampler_stride_list
paddings = getattr(config, "downsampler_padding_list", None)
paddings = paddings or [kernel // 2 for kernel in kernels]
total = 0
for offset in range(0, mel_length, chunk_size):
length = min(chunk_size, mel_length - offset)
length = (length + 2 - 3) // 2 + 1
for kernel, stride, padding in zip(kernels, strides, paddings):
length = (length + 2 * padding - kernel) // stride + 1
total += length
return total
def __call__(self, audio, text=None, return_tensors="pt"):
messages = None
if isinstance(audio, list) and audio and isinstance(audio[0], dict):
messages = audio
audio_items = [
item["audio"]
for message in messages
if isinstance(message.get("content"), list)
for item in message["content"]
if item.get("type") == "audio"
]
if len(audio_items) != 1:
raise ValueError("exactly one audio item is required")
audio = audio_items[0]
waveform = self._load_audio(audio)
n_mels = getattr(self.audio_config, "n_mels", 128)
mel = whisper.log_mel_spectrogram(waveform, n_mels=n_mels)
mel = mel.transpose(0, 1).unsqueeze(0).contiguous()
mel_length = mel.shape[1]
audio_start = "<|audio_start|>"
audio_token = "<|audio_pad|>"
audio_end = "<|audio_end|>"
if messages is None:
prompt = (
audio_start
+ audio_token * self._num_audio_tokens(mel_length)
+ audio_end
+ (text or self.ASR_PROMPT)
)
else:
prompt = self.tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True,
enable_thinking=False,
)
placeholder = audio_start + audio_token + audio_end
if prompt.count(placeholder) != 1:
raise ValueError("chat prompt must contain exactly one audio placeholder")
prompt = prompt.replace(
placeholder,
audio_start + audio_token * self._num_audio_tokens(mel_length) + audio_end,
)
inputs = self.tokenizer(prompt, return_tensors=return_tensors)
inputs.pop("token_type_ids", None)
inputs["audio_feats"] = mel
inputs["audio_feats_lengths"] = torch.tensor([[mel_length]], dtype=torch.long)
return BatchFeature(inputs)
__all__ = ["BailingMoeV3AudioProcessor"]
|