error404-api / app.py
benjamin5607's picture
Update app.py
13bbb40 verified
Raw
History Blame
4.43 kB
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
@classmethod
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
@classmethod
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
@classmethod
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()