Spaces:
Sleeping
Sleeping
| import os | |
| import re | |
| import uuid | |
| import torch | |
| import numpy as np | |
| import scipy.io.wavfile | |
| import gradio as gr | |
| import edge_tts | |
| import asyncio | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline | |
| from groq import Groq | |
| # API ν€ λ° νκ²½ μ€μ | |
| GENAI_KEY = os.getenv("GEMINI_KEY") # κΈ°μ‘΄ ν€ μ μ§ μ | |
| GROQ_API_KEY = os.getenv("GROQ_API_KEY") | |
| class ModelManager: | |
| _llm_pipeline = None | |
| _music_pipeline = None | |
| _groq_client = None | |
| def get_qwen(cls): | |
| if cls._llm_pipeline is None: | |
| # CPU μ΅μ ν λ²μ Qwen 0.5B | |
| model_id = "Qwen/Qwen2.5-0.5B-Instruct" | |
| tokenizer = AutoTokenizer.from_pretrained(model_id) | |
| model = AutoModelForCausalLM.from_pretrained(model_id, device_map="cpu", torch_dtype=torch.float32) | |
| cls._llm_pipeline = pipeline("text-generation", model=model, tokenizer=tokenizer) | |
| return cls._llm_pipeline | |
| def get_groq(cls): | |
| if cls._groq_client is None and GROQ_API_KEY: | |
| cls._groq_client = Groq(api_key=GROQ_API_KEY) | |
| return cls._groq_client | |
| def get_music(cls): | |
| if cls._music_pipeline is None: | |
| cls._music_pipeline = pipeline("text-to-audio", "facebook/musicgen-small", device="cpu") | |
| return cls._music_pipeline | |
| # 8μΈ λ©€λ² λ³΄μ΄μ€ λ§€ν | |
| MEMBERS_VOICE = { | |
| "μμ€ (Korea)": "ko-KR-SunHiNeural", "Chloe (USA)": "en-US-AriaNeural", | |
| "Naomi (Japan)": "ja-JP-NanamiNeural", "Beatrice (Brazil)": "pt-BR-FranciscaNeural", | |
| "Elena (Spain)": "es-ES-ElviraNeural", "Amira (Egypt)": "ar-EG-SalmaNeural", | |
| "Liwei (China)": "zh-CN-XiaoxiaoNeural", "Sophie (France)": "fr-FR-DeniseNeural" | |
| } | |
| async def band_consulting(user_input, member_name, lang_code): | |
| req_id = str(uuid.uuid4())[:8] | |
| voice_path = f"/tmp/v_{req_id}.mp3" | |
| music_path = f"/tmp/m_{req_id}.wav" | |
| system_prompt = f"λΉμ μ λ°΄λ λ©€λ² {member_name}μ λλ€. {lang_code}λ‘ λ΅λ³νμΈμ. 5μ€ μ΄λ΄ μμ½, μμΈ μ€λͺ μ [TAB]μ, μμ ν둬ννΈλ [MUSIC: μμ΄ν둬ννΈ]μ λ£μΌμΈμ." | |
| ai_text_raw = "" | |
| # 1. Groq μλ | |
| groq_client = ModelManager.get_groq() | |
| if groq_client: | |
| try: | |
| res = groq_client.chat.completions.create( | |
| messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": user_input}], | |
| model="llama-3.3-70b-versatile" | |
| ) | |
| ai_text_raw = res.choices[0].message.content | |
| except: pass | |
| # 2. λ‘컬 Qwen Fallback | |
| if not ai_text_raw: | |
| qwen = ModelManager.get_qwen() | |
| out = qwen(f"<|im_start|>system\n{system_prompt}<|im_end|>\n<|im_start|>user\n{user_input}<|im_end|>\nassistant\n", max_new_tokens=512) | |
| ai_text_raw = out[0]['generated_text'].split("assistant\n")[-1] | |
| # νμ± | |
| tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL | re.IGNORECASE) | |
| music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE) | |
| tab_display = tab_match.group(1).strip() if tab_match else "μμΈ μ 보 μ€λΉ μ€..." | |
| clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL | re.IGNORECASE) | |
| clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text, flags=re.IGNORECASE).strip() | |
| # 3. TTS μμ± μμ± (볡ꡬ) | |
| tts_text = "\n".join(clean_text.split('\n')[:5]) | |
| voice_name = MEMBERS_VOICE.get(member_name, "ko-KR-SunHiNeural") | |
| communicate = edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', tts_text), voice_name) | |
| await communicate.save(voice_path) | |
| # 4. μμ μμ± (κΈΈμ΄ μ°μ₯: 512 ν ν° = μ½ 12μ΄) | |
| music_gen = ModelManager.get_music() | |
| music_p = music_match.group(1).strip() if music_match else "energetic rock guitar solo" | |
| music_output = music_gen(music_p, forward_params={"max_new_tokens": 512}) | |
| audio_data = np.squeeze(music_output["audio"]) | |
| audio_int16 = (audio_data * 32767).astype(np.int16) | |
| scipy.io.wavfile.write(music_path, music_output["sampling_rate"], audio_int16) | |
| return tts_text, voice_path, music_path, tab_display | |
| with gr.Blocks() as demo: | |
| i1 = gr.Textbox(); i2 = gr.Textbox(); i3 = gr.Textbox() | |
| o1 = gr.Textbox(); o2 = gr.Audio(); o3 = gr.Audio(); o4 = gr.Textbox() | |
| btn = gr.Button("GO"); btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict") | |
| demo.queue().launch() |