MiMo-V2.5-ASR / app.py
ailuntz's picture
Clarify cpu-basic MLX runtime limits
85967d5 verified
Raw
History Blame Contribute Delete
3.48 kB
#!/usr/bin/env python3
"""Gradio Space for MiMo-V2.5-ASR MLX."""
from __future__ import annotations
import os
import time
from functools import lru_cache
from pathlib import Path
os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "1")
def _install_gxx_wrapper() -> None:
"""Make MLX CPU JIT tolerate GCC's built-in _Float* typedefs on Spaces."""
wrapper_dir = Path("/tmp/mimo_mlx_bin")
wrapper_dir.mkdir(parents=True, exist_ok=True)
wrapper = wrapper_dir / "g++"
if not wrapper.exists():
wrapper.write_text("#!/usr/bin/env bash\nexec /usr/bin/g++ -fpermissive \"$@\"\n", encoding="utf-8")
wrapper.chmod(0o755)
os.environ["PATH"] = f"{wrapper_dir}:{os.environ.get('PATH', '')}"
_install_gxx_wrapper()
import gradio as gr
from mlx_audio.stt import load
MODEL_ID = os.environ.get("MIMO_MLX_MODEL", "mlx-community/MiMo-V2.5-ASR-MLX")
MODEL_DIR = os.environ.get("MIMO_MLX_MODEL_DIR", "/models/MiMo-V2.5-ASR-MLX")
AUDIO_TOKENIZER_DIR = os.environ.get(
"MIMO_AUDIO_TOKENIZER_DIR",
"/models/MiMo-Audio-Tokenizer",
)
LANGUAGES = {"Auto": None, "Chinese": "zh", "English": "en"}
def _model_source() -> str:
if os.path.exists(os.path.join(MODEL_DIR, "config.json")):
return MODEL_DIR
return MODEL_ID
@lru_cache(maxsize=1)
def load_asr_model():
kwargs = {}
if os.path.exists(os.path.join(AUDIO_TOKENIZER_DIR, "config.json")):
kwargs["audio_tokenizer_dir"] = AUDIO_TOKENIZER_DIR
return load(_model_source(), **kwargs)
def transcribe(audio_path: str | None, language_label: str, max_tokens: int):
if not audio_path:
return "", "Upload or record an audio file."
start = time.perf_counter()
was_loaded = load_asr_model.cache_info().currsize > 0
load_start = time.perf_counter()
model = load_asr_model()
load_elapsed = time.perf_counter() - load_start
infer_start = time.perf_counter()
result = model.generate(
audio_path,
language=LANGUAGES.get(language_label),
max_tokens=int(max_tokens),
)
infer_elapsed = time.perf_counter() - infer_start
total_elapsed = time.perf_counter() - start
load_text = "cached" if was_loaded else f"{load_elapsed:.2f}s"
status = (
f"Done. elapsed={total_elapsed:.2f}s, "
f"model_load={load_text}, infer={infer_elapsed:.2f}s"
)
return result.text, status
with gr.Blocks(title="MiMo-V2.5-ASR MLX") as demo:
gr.Markdown("# MiMo-V2.5-ASR MLX")
gr.Markdown(
"This Space uses MLX CPU fallback on Linux. It can verify that the model "
"loads, but full ASR on cpu-basic may exceed the request timeout. "
"Run locally on Apple Silicon for the intended MLX GPU path."
)
with gr.Row():
with gr.Column():
audio = gr.Audio(label="Audio", type="filepath", sources=["upload", "microphone"])
language = gr.Radio(
choices=list(LANGUAGES.keys()),
value="Auto",
label="Language",
)
max_tokens = gr.Slider(1, 128, value=16, step=1, label="Max Tokens")
button = gr.Button("Transcribe", variant="primary")
with gr.Column():
transcript = gr.Textbox(label="Transcript", lines=8)
status = gr.Textbox(label="Status")
button.click(transcribe, [audio, language, max_tokens], [transcript, status])
if __name__ == "__main__":
demo.queue(max_size=4, default_concurrency_limit=1).launch()