#!/usr/bin/env python3 """Gradio Web Studio / Hugging Face Space для модели Luna 1.0 (RU / EN Chat + Audio). Запуск: pip install gradio python app.py """ from __future__ import annotations import os from pathlib import Path from transformers import AutoModel MODEL_DIR = os.environ.get("LUNA_MODEL_PATH", str(Path(__file__).resolve().parent)) def create_demo(): import gradio as gr luna = AutoModel.from_pretrained(MODEL_DIR, trust_remote_code=True) voice_names = list(luna.list_voices().keys()) def reply_and_speak(message, history, voice, language, max_tokens, temperature, add_chime): history = history or [] out = luna.chat_and_speak( prompt=message, history=history, language=language, voice=voice, chime=True if add_chime else None, max_new_tokens=int(max_tokens), temperature=float(temperature), ) new_history = list(history) + [ {"role": "user", "content": message}, {"role": "assistant", "content": out.text}, ] return "", new_history, (out.sample_rate, out.waveform) def synthesize_only(text, voice, language, speed, add_chime, ambient): amb = None if ambient == "none" else ambient out = luna.speak( text=text, language=language, voice=voice, speaking_rate=float(speed), chime=bool(add_chime), ambient=amb, ) info = f"Длительность / Duration: {out.duration_sec:.2f}s | Язык / Lang: {out.language} | {out.sample_rate} Hz" return (out.sample_rate, out.waveform), info def create_sfx(effect, duration): out = luna.create_audio_fx(effect=effect, duration_sec=float(duration)) return (out.sample_rate, out.waveform) with gr.Blocks(title="Luna 1.0 — RU/EN Chat & Audio Studio") as demo: gr.Markdown( "# 🌙 Luna 1.0 — Bilingual (RU / EN) Chat & Neural Audio Model\n" "Двуязычная диалоговая модель (русский + английский) с мгновенной голосовой озвучкой ответов, " "пресетами тембра и генератором атмосферного аудио." ) with gr.Tab("💬 Диалог + Озвучка (Chat & Speak)"): chatbot = gr.Chatbot(type="messages", height=360, label="Luna 1.0") audio_out = gr.Audio(label="Голосовой ответ Луны / Spoken Reply", autoplay=True) msg = gr.Textbox( label="Ваше сообщение / Your message", placeholder="Напишите по-русски или по-английски… / Type in Russian or English…", ) with gr.Row(): voice_dd = gr.Dropdown(voice_names, value="luna_warm", label="Голос / Voice Preset") lang_dd = gr.Dropdown(["auto", "ru", "en"], value="auto", label="Язык / Language") chime_cb = gr.Checkbox(value=False, label="Приветственный аккорд (Chime)") with gr.Row(): max_tok = gr.Slider(32, 320, value=140, step=16, label="Max new tokens") temp = gr.Slider(0.1, 1.2, value=0.7, step=0.05, label="Temperature") send_btn = gr.Button("Отправить и озвучить / Send & Speak", variant="primary") send_btn.click( reply_and_speak, inputs=[msg, chatbot, voice_dd, lang_dd, max_tok, temp, chime_cb], outputs=[msg, chatbot, audio_out], ) msg.submit( reply_and_speak, inputs=[msg, chatbot, voice_dd, lang_dd, max_tok, temp, chime_cb], outputs=[msg, chatbot, audio_out], ) with gr.Tab("🎙️ Озвучка текста RU/EN (TTS Studio)"): tts_text = gr.Textbox( lines=4, value="Привет! Меня зовут Luna 1.0. Hello! I can speak both Russian and English seamlessly!", label="Текст для озвучки / Text to synthesize", ) with gr.Row(): tts_voice = gr.Dropdown(voice_names, value="luna_warm", label="Пресет голоса") tts_lang = gr.Dropdown(["auto", "ru", "en"], value="auto", label="Язык") tts_speed = gr.Slider(0.75, 1.35, value=1.0, step=0.05, label="Скорость речи") with gr.Row(): tts_chime = gr.Checkbox(value=True, label="Добавить аккорд Luna") tts_amb = gr.Dropdown(["none", "lunar", "warm", "focus"], value="lunar", label="Эмбиент-фон") tts_btn = gr.Button("Синтезировать аудио / Generate Speech", variant="primary") tts_audio = gr.Audio(label="Результат WAV") tts_meta = gr.Textbox(label="Параметры сигнала", interactive=False) tts_btn.click( synthesize_only, inputs=[tts_text, tts_voice, tts_lang, tts_speed, tts_chime, tts_amb], outputs=[tts_audio, tts_meta], ) with gr.Tab("🌌 Звуки и Эмбиент (Audio FX)"): with gr.Row(): sfx_kind = gr.Dropdown( ["chime", "outro", "lunar_pad", "success", "thinking", "scifi_pulse", "heartbeat", "gentle_rain"], value="lunar_pad", label="Тип аудиоэффекта / Sound Structure", ) sfx_dur = gr.Slider(1.0, 10.0, value=3.5, step=0.5, label="Длительность (сек)") sfx_btn = gr.Button("Создать звук / Create Audio", variant="primary") sfx_audio = gr.Audio(label="Сгенерированный звук") sfx_btn.click(create_sfx, inputs=[sfx_kind, sfx_dur], outputs=[sfx_audio]) return demo if __name__ == "__main__": app = create_demo() app.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", "7860")))