Spaces:
Sleeping
Sleeping
| import os, re, uuid, torch, scipy.io.wavfile, edge_tts, asyncio, random | |
| import numpy as np | |
| import gradio as gr | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline | |
| from groq import Groq | |
| class ModelManager: | |
| _llm_pipeline = None | |
| _music_pipeline = None | |
| _groq_client = None | |
| def get_qwen(cls): | |
| if cls._llm_pipeline is None: | |
| 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): | |
| key = os.getenv("GROQ_API_KEY") | |
| if cls._groq_client is None and key: | |
| cls._groq_client = Groq(api_key=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_CONFIG = { | |
| "์์ค (Korea)": {"voice": "ko-KR-SunHiNeural", "lang": "Korean"}, | |
| "Chloe (USA)": {"voice": "en-US-AriaNeural", "lang": "English"}, | |
| "Naomi (Japan)": {"voice": "ja-JP-NanamiNeural", "lang": "Japanese"}, | |
| "Beatrice (Brazil)": {"voice": "pt-BR-FranciscaNeural", "lang": "Portuguese"}, | |
| "Elena (Spain)": {"voice": "es-ES-ElviraNeural", "lang": "Spanish"}, | |
| "Amira (Egypt)": {"voice": "ar-EG-SalmaNeural", "lang": "Arabic"}, | |
| "Liwei (China)": {"voice": "zh-CN-XiaoxiaoNeural", "lang": "Chinese"}, | |
| "Sophie (France)": {"voice": "fr-FR-DeniseNeural", "lang": "French"} | |
| } | |
| async def band_consulting(user_input, member_name, consult_lang, g_inst, b_inst, d_inst, chords): | |
| req_id = str(uuid.uuid4())[:8] | |
| voice_path = f"/tmp/v_{req_id}.mp3" | |
| music_path = f"/tmp/m_{req_id}.wav" | |
| # 1. ๋ฉค๋ฒ ์ ์ ๋ก์ง: ์์ด๊ฐ ์ ํ๋๋ฉด ๋๋ค ๋ฉค๋ฒ๊ฐ ๋ด๋น | |
| actual_member = member_name | |
| if consult_lang == "English": | |
| actual_member = random.choice(list(MEMBERS_CONFIG.keys())) | |
| target_lang = MEMBERS_CONFIG[actual_member]["lang"] if consult_lang == "Native" else consult_lang | |
| jam_context = f"Guitar: {g_inst}, Bass: {b_inst}, Drums: {d_inst}, Chords: {chords}" | |
| system_prompt = f"""You are {actual_member}. Respond ONLY in {target_lang}. | |
| Provide 5-7 lines of professional music advice. | |
| [TAB] Section: Detailed chords/tabs. | |
| [MUSIC] Section: English prompt reflecting: {jam_context}""" | |
| ai_text_raw = "" | |
| 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 | |
| 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=1024) | |
| 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 "No Data" | |
| 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() | |
| # TTS | |
| voice_name = MEMBERS_CONFIG[actual_member]["voice"] | |
| communicate = edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', clean_text), voice_name) | |
| await communicate.save(voice_path) | |
| # MusicGen (12์ด) | |
| music_gen = ModelManager.get_music() | |
| music_p = music_match.group(1).strip() if music_match else "rock" | |
| 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 f"[{actual_member}] {clean_text}", voice_path, music_path, tab_display | |
| with gr.Blocks() as demo: | |
| in_list = [gr.Textbox(visible=False) for _ in range(7)] | |
| out_list = [gr.Textbox(visible=False), gr.Audio(visible=False), gr.Audio(visible=False), gr.Textbox(visible=False)] | |
| btn = gr.Button("API", visible=False) | |
| btn.click(band_consulting, in_list, out_list, api_name="predict") | |
| demo.queue().launch() |