Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """Gradio Space for Hy-MT2 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/hymt2_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_lm import generate, load | |
| from mlx_lm.sample_utils import make_logits_processors, make_sampler | |
| MODEL_ID = os.environ.get("HYMT2_MLX_MODEL", "mlx-community/Hy-MT2-1.8B-4bit") | |
| MODEL_DIR = os.environ.get("HYMT2_MLX_MODEL_DIR", "/models/Hy-MT2-1.8B-4bit") | |
| LANGUAGES = [ | |
| "English", "Chinese", "Traditional Chinese", "Japanese", "Korean", "French", | |
| "German", "Spanish", "Portuguese", "Russian", "Arabic", "Hindi", "Vietnamese", | |
| "Thai", "Indonesian", "Turkish", "Ukrainian", | |
| ] | |
| def _model_source() -> str: | |
| if os.path.exists(os.path.join(MODEL_DIR, "config.json")): | |
| return MODEL_DIR | |
| return MODEL_ID | |
| def load_translation_model(): | |
| return load(_model_source()) | |
| def build_prompt(text: str, target_lang: str) -> str: | |
| return ( | |
| f"Translate the following text into {target_lang}. " | |
| "Note that you should only output the translated result without any " | |
| "additional explanation:\n\n" | |
| f"{text.strip()}" | |
| ) | |
| def translate(text: str, target_lang: str, max_tokens: int): | |
| if not text or not text.strip(): | |
| return "", "Enter text to translate." | |
| start = time.perf_counter() | |
| was_loaded = load_translation_model.cache_info().currsize > 0 | |
| load_start = time.perf_counter() | |
| model, tokenizer = load_translation_model() | |
| load_elapsed = time.perf_counter() - load_start | |
| prompt = build_prompt(text, target_lang) | |
| if getattr(tokenizer, "has_chat_template", False): | |
| prompt = tokenizer.apply_chat_template( | |
| [{"role": "user", "content": prompt}], | |
| tokenize=False, | |
| add_generation_prompt=True, | |
| ) | |
| sampler = make_sampler(0.7, 0.6, 0.0, 1, 20) | |
| logits_processors = make_logits_processors( | |
| repetition_penalty=1.05, | |
| repetition_context_size=20, | |
| ) | |
| infer_start = time.perf_counter() | |
| output = generate( | |
| model, | |
| tokenizer, | |
| prompt, | |
| max_tokens=int(max_tokens), | |
| sampler=sampler, | |
| logits_processors=logits_processors, | |
| verbose=False, | |
| ) | |
| 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 output.strip(), status | |
| with gr.Blocks(title="Hy-MT2 MLX") as demo: | |
| gr.Markdown("# Hy-MT2 MLX") | |
| gr.Markdown( | |
| "This Space uses MLX CPU fallback on Linux. It can verify that the model " | |
| "loads, but full translation 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(): | |
| source = gr.Textbox( | |
| label="Source Text", | |
| lines=6, | |
| value="今天天气真好。", | |
| ) | |
| target = gr.Dropdown(LANGUAGES, value="English", label="Target Language") | |
| max_tokens = gr.Slider(1, 128, value=16, step=1, label="Max Tokens") | |
| button = gr.Button("Translate", variant="primary") | |
| with gr.Column(): | |
| output = gr.Textbox(label="Translation", lines=8) | |
| status = gr.Textbox(label="Status") | |
| button.click(translate, [source, target, max_tokens], [output, status]) | |
| gr.Examples( | |
| examples=[ | |
| ["今天天气真好。", "English", 64], | |
| ["The meeting has been moved to next Monday.", "Chinese", 64], | |
| ], | |
| inputs=[source, target, max_tokens], | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue(max_size=4, default_concurrency_limit=1).launch() | |