benjamin5607 commited on
Commit
13bbb40
ยท
verified ยท
1 Parent(s): 9653416

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -61
app.py CHANGED
@@ -5,10 +5,15 @@ import torch
5
  import numpy as np
6
  import scipy.io.wavfile
7
  import gradio as gr
 
 
8
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
9
- from groq import Groq # pip install groq
 
 
 
 
10
 
11
- # 1. ๋ชจ๋ธ ์‹ฑ๊ธ€ํ†ค ๊ด€๋ฆฌ ํด๋ž˜์Šค (๋ฉ”๋ชจ๋ฆฌ ํšจ์œจํ™”)
12
  class ModelManager:
13
  _llm_pipeline = None
14
  _music_pipeline = None
@@ -17,102 +22,84 @@ class ModelManager:
17
  @classmethod
18
  def get_qwen(cls):
19
  if cls._llm_pipeline is None:
 
20
  model_id = "Qwen/Qwen2.5-0.5B-Instruct"
21
  tokenizer = AutoTokenizer.from_pretrained(model_id)
22
- # CPU ํ™˜๊ฒฝ ์ตœ์ ํ™” ๋กœ๋”ฉ
23
- model = AutoModelForCausalLM.from_pretrained(
24
- model_id,
25
- device_map="cpu",
26
- torch_dtype=torch.float32,
27
- low_cpu_mem_usage=True
28
- )
29
  cls._llm_pipeline = pipeline("text-generation", model=model, tokenizer=tokenizer)
30
  return cls._llm_pipeline
31
 
32
  @classmethod
33
  def get_groq(cls):
34
- api_key = os.getenv("GROQ_API_KEY")
35
- if cls._groq_client is None and api_key:
36
- cls._groq_client = Groq(api_key=api_key)
37
  return cls._groq_client
38
 
39
  @classmethod
40
  def get_music(cls):
41
  if cls._music_pipeline is None:
42
- # CPU์—์„œ ๊ฐ€์žฅ ๊ฐ€๋ฒผ์šด ์Œ์•… ๋ชจ๋ธ ์œ ์ง€
43
  cls._music_pipeline = pipeline("text-to-audio", "facebook/musicgen-small", device="cpu")
44
  return cls._music_pipeline
45
 
46
- # 2. ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
 
 
 
 
 
 
 
47
  async def band_consulting(user_input, member_name, lang_code):
48
  req_id = str(uuid.uuid4())[:8]
 
49
  music_path = f"/tmp/m_{req_id}.wav"
50
 
51
- # ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ ์„ค์ •
52
- system_prompt = f"You are {member_name}, a rock star. Talk in {lang_code}. Format: 5 lines max + [TAB] details + [MUSIC: prompt]."
53
 
54
  ai_text_raw = ""
55
-
56
- # ์—”์ง„ ์„ ํƒ (Groq ์šฐ์„  -> ์‹คํŒจ ์‹œ ๋กœ์ปฌ Qwen)
57
  groq_client = ModelManager.get_groq()
58
  if groq_client:
59
  try:
60
- chat_completion = groq_client.chat.completions.create(
61
- messages=[
62
- {"role": "system", "content": system_prompt},
63
- {"role": "user", "content": user_input}
64
- ],
65
- model="llama-3.3-70b-versatile",
66
  )
67
- ai_text_raw = chat_completion.choices[0].message.content
68
- except Exception as e:
69
- print(f"Groq Error, switching to Qwen: {e}")
70
 
71
- # Groq ์‹คํŒจ ์‹œ ํ˜น์€ ๋ฏธ์„ค์ • ์‹œ ๋กœ์ปฌ Qwen ์‚ฌ์šฉ
72
  if not ai_text_raw:
73
- try:
74
- qwen = ModelManager.get_qwen()
75
- messages = [
76
- {"role": "system", "content": system_prompt},
77
- {"role": "user", "content": user_input}
78
- ]
79
- text = qwen.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
80
- output = qwen(text, max_new_tokens=512, do_sample=True, temperature=0.7)
81
- ai_text_raw = output[0]['generated_text'].split("assistant\n")[-1]
82
- except Exception as e:
83
- ai_text_raw = "์ด๋ด ๋ฆฌ๋”, ์ง€๊ธˆ์€ ๋ง๋ณด๋‹ค ์—ฐ์ฃผ์•ผ! [TAB] ์ฆ‰ํฅ ์—ฐ์ฃผ ๊ฐ€๋™ [MUSIC: heavy rock guitar riff]"
84
 
85
- # 3. ํŒŒ์‹ฑ ๋ฐ ์Œ์•… ์ƒ์„ฑ
86
  tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL | re.IGNORECASE)
87
  music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
88
-
89
  tab_display = tab_match.group(1).strip() if tab_match else "์ƒ์„ธ ์•…๋ณด ์ค€๋น„ ์ค‘..."
90
  clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL | re.IGNORECASE)
91
  clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text, flags=re.IGNORECASE).strip()
92
- music_p = music_match.group(1).strip() if music_match else "rock music"
 
 
 
 
 
93
 
94
- # ์Œ์•… ์ƒ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ
95
  music_gen = ModelManager.get_music()
96
- try:
97
- # CPU ํ™˜๊ฒฝ์„ ์œ„ํ•ด ํ† ํฐ ์ˆ˜๋ฅผ ์ค„์—ฌ ํƒ€์ž„์•„์›ƒ ๋ฐฉ์ง€
98
- music_output = music_gen(music_p, forward_params={"max_new_tokens": 256})
99
- audio_data = np.squeeze(music_output["audio"])
100
- audio_int16 = (audio_data * 32767).astype(np.int16)
101
- scipy.io.wavfile.write(music_path, music_output["sampling_rate"], audio_int16)
102
- except:
103
- music_path = None
104
 
105
- # TTS์šฉ ํ…์ŠคํŠธ (๊ธฐ์กด ๊ตฌ์กฐ ์œ ์ง€)
106
- tts_text = "\n".join(clean_text.split('\n')[:5])
107
-
108
- return tts_text, None, music_path, tab_display # voice_path๋Š” edge_tts ๋“ฑ์—์„œ ์ฒ˜๋ฆฌ
109
 
110
- # 3. Gradio ์ธํ„ฐํŽ˜์ด์Šค (Minimal)
111
  with gr.Blocks() as demo:
112
- i1 = gr.Textbox(visible=False); i2 = gr.Textbox(visible=False); i3 = gr.Textbox(visible=False)
113
- o1 = gr.Textbox(visible=False); o2 = gr.Audio(visible=False); o3 = gr.Audio(visible=False); o4 = gr.Textbox(visible=False)
114
-
115
- btn = gr.Button("GO", visible=False)
116
- btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict")
117
 
118
  demo.queue().launch()
 
5
  import numpy as np
6
  import scipy.io.wavfile
7
  import gradio as gr
8
+ import edge_tts
9
+ import asyncio
10
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
11
+ from groq import Groq
12
+
13
+ # API ํ‚ค ๋ฐ ํ™˜๊ฒฝ ์„ค์ •
14
+ GENAI_KEY = os.getenv("GEMINI_KEY") # ๊ธฐ์กด ํ‚ค ์œ ์ง€ ์‹œ
15
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
16
 
 
17
  class ModelManager:
18
  _llm_pipeline = None
19
  _music_pipeline = None
 
22
  @classmethod
23
  def get_qwen(cls):
24
  if cls._llm_pipeline is None:
25
+ # CPU ์ตœ์ ํ™” ๋ฒ„์ „ Qwen 0.5B
26
  model_id = "Qwen/Qwen2.5-0.5B-Instruct"
27
  tokenizer = AutoTokenizer.from_pretrained(model_id)
28
+ model = AutoModelForCausalLM.from_pretrained(model_id, device_map="cpu", torch_dtype=torch.float32)
 
 
 
 
 
 
29
  cls._llm_pipeline = pipeline("text-generation", model=model, tokenizer=tokenizer)
30
  return cls._llm_pipeline
31
 
32
  @classmethod
33
  def get_groq(cls):
34
+ if cls._groq_client is None and GROQ_API_KEY:
35
+ cls._groq_client = Groq(api_key=GROQ_API_KEY)
 
36
  return cls._groq_client
37
 
38
  @classmethod
39
  def get_music(cls):
40
  if cls._music_pipeline is None:
 
41
  cls._music_pipeline = pipeline("text-to-audio", "facebook/musicgen-small", device="cpu")
42
  return cls._music_pipeline
43
 
44
+ # 8์ธ ๋ฉค๋ฒ„ ๋ณด์ด์Šค ๋งคํ•‘
45
+ MEMBERS_VOICE = {
46
+ "์„œ์œค (Korea)": "ko-KR-SunHiNeural", "Chloe (USA)": "en-US-AriaNeural",
47
+ "Naomi (Japan)": "ja-JP-NanamiNeural", "Beatrice (Brazil)": "pt-BR-FranciscaNeural",
48
+ "Elena (Spain)": "es-ES-ElviraNeural", "Amira (Egypt)": "ar-EG-SalmaNeural",
49
+ "Liwei (China)": "zh-CN-XiaoxiaoNeural", "Sophie (France)": "fr-FR-DeniseNeural"
50
+ }
51
+
52
  async def band_consulting(user_input, member_name, lang_code):
53
  req_id = str(uuid.uuid4())[:8]
54
+ voice_path = f"/tmp/v_{req_id}.mp3"
55
  music_path = f"/tmp/m_{req_id}.wav"
56
 
57
+ system_prompt = f"๋‹น์‹ ์€ ๋ฐด๋“œ ๋ฉค๋ฒ„ {member_name}์ž…๋‹ˆ๋‹ค. {lang_code}๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”. 5์ค„ ์ด๋‚ด ์š”์•ฝ, ์ƒ์„ธ ์„ค๋ช…์€ [TAB]์—, ์Œ์•… ํ”„๋กฌํ”„ํŠธ๋Š” [MUSIC: ์˜์–ดํ”„๋กฌํ”„ํŠธ]์— ๋„ฃ์œผ์„ธ์š”."
 
58
 
59
  ai_text_raw = ""
60
+ # 1. Groq ์‹œ๋„
 
61
  groq_client = ModelManager.get_groq()
62
  if groq_client:
63
  try:
64
+ res = groq_client.chat.completions.create(
65
+ messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": user_input}],
66
+ model="llama-3.3-70b-versatile"
 
 
 
67
  )
68
+ ai_text_raw = res.choices[0].message.content
69
+ except: pass
 
70
 
71
+ # 2. ๋กœ์ปฌ Qwen Fallback
72
  if not ai_text_raw:
73
+ qwen = ModelManager.get_qwen()
74
+ 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)
75
+ ai_text_raw = out[0]['generated_text'].split("assistant\n")[-1]
 
 
 
 
 
 
 
 
76
 
77
+ # ํŒŒ์‹ฑ
78
  tab_match = re.search(r'\[TAB\](.*?)(\[|$)', ai_text_raw, re.DOTALL | re.IGNORECASE)
79
  music_match = re.search(r'\[MUSIC:(.*?)\]', ai_text_raw, re.IGNORECASE)
 
80
  tab_display = tab_match.group(1).strip() if tab_match else "์ƒ์„ธ ์•…๋ณด ์ค€๋น„ ์ค‘..."
81
  clean_text = re.sub(r'\[TAB\].*?(\[|$)', '', ai_text_raw, flags=re.DOTALL | re.IGNORECASE)
82
  clean_text = re.sub(r'\[MUSIC:.*?\]', '', clean_text, flags=re.IGNORECASE).strip()
83
+
84
+ # 3. TTS ์Œ์„ฑ ์ƒ์„ฑ (๋ณต๊ตฌ)
85
+ tts_text = "\n".join(clean_text.split('\n')[:5])
86
+ voice_name = MEMBERS_VOICE.get(member_name, "ko-KR-SunHiNeural")
87
+ communicate = edge_tts.Communicate(re.sub(r'[\*\#\-\_\~\|]', '', tts_text), voice_name)
88
+ await communicate.save(voice_path)
89
 
90
+ # 4. ์Œ์•… ์ƒ์„ฑ (๊ธธ์ด ์—ฐ์žฅ: 512 ํ† ํฐ = ์•ฝ 12์ดˆ)
91
  music_gen = ModelManager.get_music()
92
+ music_p = music_match.group(1).strip() if music_match else "energetic rock guitar solo"
93
+ music_output = music_gen(music_p, forward_params={"max_new_tokens": 512})
94
+ audio_data = np.squeeze(music_output["audio"])
95
+ audio_int16 = (audio_data * 32767).astype(np.int16)
96
+ scipy.io.wavfile.write(music_path, music_output["sampling_rate"], audio_int16)
 
 
 
97
 
98
+ return tts_text, voice_path, music_path, tab_display
 
 
 
99
 
 
100
  with gr.Blocks() as demo:
101
+ i1 = gr.Textbox(); i2 = gr.Textbox(); i3 = gr.Textbox()
102
+ o1 = gr.Textbox(); o2 = gr.Audio(); o3 = gr.Audio(); o4 = gr.Textbox()
103
+ btn = gr.Button("GO"); btn.click(band_consulting, [i1, i2, i3], [o1, o2, o3, o4], api_name="predict")
 
 
104
 
105
  demo.queue().launch()