Spaces:
Running
Running
| import os | |
| import sys | |
| import re | |
| import gradio as gr | |
| # ββ Setup: add ACE-Step-1.5 to sys.path so acestep.* imports work ββ | |
| ACE_ROOT = os.path.join(os.path.dirname(__file__), "ACE-Step-1.5") | |
| sys.path.insert(0, ACE_ROOT) | |
| os.environ["ACESTEP_GENERATION_TIMEOUT"] = "1200" | |
| from acestep.handler import AceStepHandler | |
| from acestep.inference import GenerationParams, GenerationConfig, generate_music | |
| # ββ Globals ββ | |
| DIT_HANDLER = None | |
| def initialize_model(): | |
| global DIT_HANDLER | |
| print("[System] Loading ACE-Step 1.5 model...") | |
| DIT_HANDLER = AceStepHandler() | |
| status_msg, success = DIT_HANDLER.initialize_service( | |
| project_root=ACE_ROOT, | |
| config_path="acestep-v15-turbo", | |
| device="auto", | |
| offload_to_cpu=False, | |
| ) | |
| if not success: | |
| raise RuntimeError(f"Model initialization failed: {status_msg}") | |
| print("[System] Model loaded successfully!") | |
| # Load model on startup (first request will wait if not ready) | |
| try: | |
| initialize_model() | |
| except Exception as e: | |
| print(f"[ERROR] Failed to load model at startup: {e}") | |
| print("[INFO] Model will be loaded on first request instead") | |
| # ββ Groq LLM ββ | |
| def generate_lyrics_and_tags(story, genre, mood, tempo, vocals_enabled): | |
| from groq import Groq | |
| api_key = os.environ.get("GROQ_API_KEY") | |
| if not api_key: | |
| raise ValueError("GROQ_API_KEY not set. Add it in HF Space Secrets.") | |
| client = Groq(api_key=api_key) | |
| system_prompt = """You are an expert music producer and songwriter. Based on a user's story and preferences, create compelling song lyrics and musical style tags.""" | |
| user_prompt = f"""Story: {story} | |
| Musical Preferences: | |
| - Genre: {genre} | |
| - Mood: {mood} | |
| - Tempo: {tempo} | |
| - Vocals: {'Yes - write lyrics to be sung' if vocals_enabled else 'Instrumental only'} | |
| Generate: | |
| 1. Full song lyrics with [Verse], [Chorus], [Bridge] sections. | |
| 2. Musical style tags: genre, BPM, key, instruments, production style (comma-separated). | |
| Format: | |
| === LYRICS === | |
| [lyrics] | |
| === STYLE TAGS === | |
| [comma-separated style tags]""" | |
| response = client.chat.completions.create( | |
| model="llama-3.3-70b-versatile", | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_prompt}, | |
| ], | |
| temperature=0.7, | |
| max_tokens=2000, | |
| ) | |
| content = response.choices[0].message.content | |
| lyrics = "" | |
| style_tags = "pop, 120bpm" | |
| lyrics_match = re.search(r'=== LYRICS ===\s*(.*?)(?:=== STYLE TAGS ===|$)', content, re.DOTALL) | |
| if lyrics_match: | |
| lyrics = lyrics_match.group(1).strip() | |
| tags_match = re.search(r'=== STYLE TAGS ===\s*(.*?)$', content, re.DOTALL) | |
| if tags_match: | |
| style_tags = tags_match.group(1).strip() | |
| return lyrics, style_tags | |
| # ββ ACE-Step Generation ββ | |
| def generate_audio(lyrics, style_tags): | |
| global DIT_HANDLER | |
| if DIT_HANDLER is None: | |
| print("[System] Loading model on demand...") | |
| initialize_model() | |
| save_dir = os.path.join(os.path.dirname(__file__), "generated_songs") | |
| os.makedirs(save_dir, exist_ok=True) | |
| params = GenerationParams( | |
| task_type="text2music", | |
| thinking=False, | |
| caption=style_tags, | |
| lyrics=lyrics, | |
| duration=60, | |
| inference_steps=8, | |
| ) | |
| gen_config = GenerationConfig( | |
| batch_size=1, | |
| audio_format="wav", | |
| ) | |
| result = generate_music( | |
| DIT_HANDLER, None, params=params, config=gen_config, save_dir=save_dir | |
| ) | |
| if result.success and result.audios: | |
| return result.audios[0]["path"] | |
| else: | |
| raise RuntimeError(f"Generation failed: {result.status_message}") | |
| # ββ Gradio Interface ββ | |
| def generate_song(story, genre, mood, tempo, vocals_enabled, progress=gr.Progress()): | |
| try: | |
| progress(0.1, desc="Analyzing story and generating lyrics...") | |
| lyrics, style_tags = generate_lyrics_and_tags( | |
| story, genre, mood, tempo, vocals_enabled | |
| ) | |
| print(f"\n--- Generated Lyrics ---\n{lyrics}") | |
| print(f"\n--- Style Tags ---\n{style_tags}") | |
| progress(0.3, desc="Creating music (1-3 minutes on GPU)...") | |
| audio_path = generate_audio(lyrics, style_tags) | |
| progress(1.0, desc="Complete!") | |
| return audio_path, lyrics, style_tags | |
| except Exception as e: | |
| raise gr.Error(str(e)) | |
| DESCRIPTION = """ | |
| # π΅ AI Song Generator | |
| Tell your story and get a custom song generated by AI in under 3 minutes. | |
| """ | |
| with gr.Blocks(title="AI Song Generator", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown(DESCRIPTION) | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| story = gr.Textbox( | |
| label="Your Story", | |
| placeholder="Tell me about your experience, moment, or idea for a song...", | |
| lines=5, | |
| ) | |
| with gr.Row(): | |
| genre = gr.Dropdown( | |
| label="Genre", | |
| choices=["Pop", "Rock", "Hip-Hop", "Electronic", "R&B", "Lo-fi", "Jazz", "Classical", "Folk", "Indie"], | |
| value="Pop", | |
| ) | |
| mood = gr.Dropdown( | |
| label="Mood", | |
| choices=["Happy", "Energetic", "Triumphant", "Romantic", "Dreamy", "Melancholic", "Calm", "Dark"], | |
| value="Happy", | |
| ) | |
| with gr.Row(): | |
| tempo = gr.Dropdown( | |
| label="Tempo", | |
| choices=["Slow (60-80 BPM)", "Medium (90-120 BPM)", "Fast (130-160 BPM)"], | |
| value="Medium (90-120 BPM)", | |
| ) | |
| vocals = gr.Checkbox( | |
| label="Include vocals", | |
| value=True, | |
| ) | |
| generate_btn = gr.Button("π΅ Generate Song", variant="primary", size="lg") | |
| with gr.Column(scale=2): | |
| audio_output = gr.Audio(label="Your Song", type="filepath") | |
| with gr.Accordion("Show Lyrics", open=False): | |
| lyrics_output = gr.Textbox(label="Generated Lyrics", lines=10) | |
| with gr.Accordion("Show Style Tags", open=False): | |
| tags_output = gr.Textbox(label="Style Tags", lines=3) | |
| generate_btn.click( | |
| fn=generate_song, | |
| inputs=[story, genre, mood, tempo, vocals], | |
| outputs=[audio_output, lyrics_output, tags_output], | |
| ) | |
| gr.Markdown("---\nβ‘ Powered by ACE-Step 1.5 Turbo Β· π§ Groq Β· Built with Gradio") | |
| if __name__ == "__main__": | |
| demo.launch() |