Spaces:
Running
Running
import streamlit as st | |
import torch | |
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM | |
import urllib.parse | |
# Set Streamlit page configuration | |
st.set_page_config( | |
page_title="Text-to-Music Generator π΅", | |
page_icon="π΅", | |
layout="wide", | |
initial_sidebar_state="expanded", | |
) | |
# Add custom CSS for styling | |
st.markdown(""" | |
<style> | |
body { | |
background-color: #eaf6fb; | |
color: #003366; | |
font-family: 'Arial', sans-serif; | |
} | |
.stButton>button { | |
background-color: #4dabf5; | |
color: white; | |
font-weight: bold; | |
border-radius: 12px; | |
padding: 10px 20px; | |
} | |
.stButton>button:hover { | |
background-color: #007bb5; | |
} | |
.stTextArea textarea { | |
border: 2px solid #4dabf5; | |
border-radius: 8px; | |
} | |
iframe { | |
border: 2px solid #4dabf5; | |
border-radius: 8px; | |
} | |
.title { | |
text-align: center; | |
font-size: 36px; | |
font-weight: bold; | |
color: #003366; | |
} | |
.description { | |
text-align: center; | |
font-size: 18px; | |
color: #005792; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Initialize the Hugging Face model and tokenizer | |
def load_model(): | |
tokenizer = AutoTokenizer.from_pretrained('sander-wood/text-to-music') | |
model = AutoModelForSeq2SeqLM.from_pretrained('sander-wood/text-to-music') | |
return tokenizer, model | |
# Load model and tokenizer | |
tokenizer, model = load_model() | |
# Streamlit App UI | |
st.markdown("<div class='title'>π΅ Text-to-Music Generator π΅</div>", unsafe_allow_html=True) | |
st.markdown(""" | |
<div class='description'> | |
Enter a textual description, and the model will generate music in ABC notation. | |
You can use tools like [abc2midi](http://abc.sourceforge.net/abcMIDI/) to convert the notation into a playable file. | |
</div> | |
""", unsafe_allow_html=True) | |
# Input Fields | |
with st.container(): | |
text_input = st.text_area( | |
"Enter a description for the music:", | |
placeholder="e.g., This is a traditional Irish dance music.", | |
) | |
max_length = st.slider( | |
"Maximum Length of Generated Music:", min_value=128, max_value=2048, value=1024, step=128 | |
) | |
top_p = st.slider( | |
"Top-p (Nucleus Sampling):", min_value=0.1, max_value=1.0, value=0.9, step=0.05 | |
) | |
temperature = st.slider( | |
"Temperature (Sampling Diversity):", min_value=0.1, max_value=2.0, value=1.0, step=0.1 | |
) | |
# Generate Music Button | |
if st.button("Generate Music πΆ"): | |
if not text_input.strip(): | |
st.error("Please enter a valid description!") | |
else: | |
st.info("Generating music... This might take a few seconds.") | |
try: | |
# Tokenize input | |
input_ids = tokenizer(text_input, return_tensors='pt', truncation=True, max_length=max_length)['input_ids'] | |
# Generate music using efficient beam search sampling | |
generated_ids = model.generate( | |
input_ids, | |
max_length=max_length, | |
do_sample=True, | |
top_p=top_p, | |
temperature=temperature, | |
eos_token_id=tokenizer.eos_token_id, | |
) | |
# Decode generated music | |
tune = tokenizer.decode(generated_ids[0], skip_special_tokens=True) | |
tune = "X:1\n" + tune | |
st.success("Music generated successfully!") | |
# Display raw generated music in the app | |
st.text_area("Generated Music (ABC Notation):", value=tune, height=300) | |
# Encode tune for URL and embed ABCJS Editor | |
encoded_tune = urllib.parse.quote(tune) | |
editor_url = f"https://www.abcjs.net/abcjs-editor?abc={encoded_tune}" | |
st.markdown(f""" | |
### ABCJS Editor Preview | |
You can edit or play the music below: | |
<iframe src="{editor_url}" width="100%" height="500" style="border:none;"></iframe> | |
""", unsafe_allow_html=True) | |
except Exception as e: | |
st.error(f"An error occurred: {e}") | |