Szeyu commited on
Commit
1da8d3f
·
verified ·
1 Parent(s): b21b469

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -36
app.py CHANGED
@@ -33,16 +33,14 @@ st.markdown(
33
  unsafe_allow_html=True
34
  )
35
 
36
- # ------------------ Lazy Model Loading ------------------
37
  def load_models():
38
  """
39
- Lazy-load the required pipelines and store them in session state.
40
- This avoids heavy model initialization during container build.
41
-
42
  Pipelines:
43
- 1. Captioner: Turns an image into descriptive text.
44
  2. Storyer: Generates a humorous children's story using aspis/gpt2-genre-story-generation.
45
- 3. TTS: Converts text into audio.
46
  """
47
  if "captioner" not in st.session_state:
48
  st.session_state.captioner = pipeline(
@@ -60,32 +58,31 @@ def load_models():
60
  model="facebook/mms-tts-eng"
61
  )
62
 
63
- # ------------------ Helper Functions ------------------
64
- def generate_caption(image):
 
65
  """
66
- Generate a caption from the image using the captioner model.
 
67
  """
68
- caption_results = st.session_state.captioner(image)
69
- return caption_results[0]["generated_text"]
 
 
 
70
 
71
- def generate_story(caption):
 
72
  """
73
- Generate a humorous and engaging children's story based on the caption.
74
-
75
- The prompt instructs the model to write a funny, warm, and imaginative story for ages 3-10
76
- (50-100 words) in a playful authorial tone. It explicitly requests details such as:
77
- - A clear venue/location (e.g., a park, school, or home),
78
- - Specific characters (e.g., a little girl named Lily or a boy named Jack),
79
- - Humorous actions.
80
  """
81
  prompt = (
82
  f"Write a funny, warm, and imaginative children's story for ages 3-10, 50-100 words, "
83
  f"in third-person narrative, as if the author is playfully describing the scene in the image: {caption}. "
84
- "Explicitly mention the exact venue or location (such as a park, school, or home), describe specific characters "
85
  "(for example, a little girl named Lily or a boy named Jack), and detail the humorous actions they perform. "
86
  "Ensure the story is playful, engaging, and ends with a complete sentence."
87
  )
88
- # Using sampling parameters that work well with the smaller GPT-2 genre model.
89
  raw_story = st.session_state.storyer(
90
  prompt,
91
  max_new_tokens=100,
@@ -96,11 +93,11 @@ def generate_story(caption):
96
  words = raw_story.split()
97
  return " ".join(words[:100])
98
 
99
- def generate_audio(story):
 
100
  """
101
- Convert the story text to audio.
102
- The text is split into 300-character chunks (to reduce the number of TTS calls),
103
- the audio chunks are concatenated, and then saved into an in‑memory WAV buffer.
104
  """
105
  chunks = textwrap.wrap(story, width=300)
106
  audio_chunks = [st.session_state.tts(chunk)["audio"].squeeze() for chunk in chunks]
@@ -114,31 +111,30 @@ def generate_audio(story):
114
  uploaded_file = st.file_uploader("Choose a Picture...", type=["jpg", "jpeg", "png"])
115
  if uploaded_file is not None:
116
  try:
117
- # Open and display the uploaded image
118
- image = Image.open(uploaded_file).convert("RGB")
 
 
119
  st.image(image, caption="Your Amazing Picture!", use_column_width=True)
120
  st.markdown("<h3 style='text-align: center;'>Ready for your story?</h3>", unsafe_allow_html=True)
121
-
122
  if st.button("Story, Please!"):
123
- with st.spinner("Loading models and processing your picture..."):
124
- load_models()
125
- caption = generate_caption(image)
126
  st.markdown("<h3 style='text-align: center;'>Caption:</h3>", unsafe_allow_html=True)
127
  st.write(caption)
128
 
129
- with st.spinner("Creating a fun story just for you..."):
130
- story = generate_story(caption)
131
  st.markdown("<h3 style='text-align: center;'>Your Story:</h3>", unsafe_allow_html=True)
132
  st.write(story)
133
 
134
- with st.spinner("Turning your story into a magical song..."):
135
- audio_buffer = generate_audio(story)
136
  st.audio(audio_buffer, format="audio/wav", start_time=0)
137
  st.markdown(
138
  "<p style='text-align: center; font-weight: bold;'>Enjoy your magical story! 🎶</p>",
139
  unsafe_allow_html=True
140
  )
141
-
142
  except Exception as e:
143
  st.error("Oops! Something went wrong. Please try a different picture or check the file format!")
144
  st.error(f"Error details: {e}")
 
33
  unsafe_allow_html=True
34
  )
35
 
36
+ # ------------------ Model Loading ------------------
37
  def load_models():
38
  """
39
+ Lazy-load the pipelines and store them in session state.
 
 
40
  Pipelines:
41
+ 1. Captioner: Generates descriptive text from an image.
42
  2. Storyer: Generates a humorous children's story using aspis/gpt2-genre-story-generation.
43
+ 3. TTS: Converts text into spoken audio.
44
  """
45
  if "captioner" not in st.session_state:
46
  st.session_state.captioner = pipeline(
 
58
  model="facebook/mms-tts-eng"
59
  )
60
 
61
+ # ------------------ Caching Functions ------------------
62
+ @st.cache_data(show_spinner=False)
63
+ def get_caption(image_bytes):
64
  """
65
+ Convert the image bytes into a lower resolution image to speed up captioning,
66
+ then generate and return the caption.
67
  """
68
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
69
+ # Resize the image to speed up processing (keeping aspect ratio)
70
+ image.thumbnail((384, 384))
71
+ caption = st.session_state.captioner(image)[0]["generated_text"]
72
+ return caption
73
 
74
+ @st.cache_data(show_spinner=False)
75
+ def get_story(caption):
76
  """
77
+ Generate a humorous and engaging children's story using the caption.
 
 
 
 
 
 
78
  """
79
  prompt = (
80
  f"Write a funny, warm, and imaginative children's story for ages 3-10, 50-100 words, "
81
  f"in third-person narrative, as if the author is playfully describing the scene in the image: {caption}. "
82
+ "Explicitly mention the exact venue or location (e.g. a park, school, or home), describe specific characters "
83
  "(for example, a little girl named Lily or a boy named Jack), and detail the humorous actions they perform. "
84
  "Ensure the story is playful, engaging, and ends with a complete sentence."
85
  )
 
86
  raw_story = st.session_state.storyer(
87
  prompt,
88
  max_new_tokens=100,
 
93
  words = raw_story.split()
94
  return " ".join(words[:100])
95
 
96
+ @st.cache_data(show_spinner=False)
97
+ def get_audio(story):
98
  """
99
+ Convert the generated story text into audio.
100
+ The text is split into 300-character chunks to reduce repeated TTS calls.
 
101
  """
102
  chunks = textwrap.wrap(story, width=300)
103
  audio_chunks = [st.session_state.tts(chunk)["audio"].squeeze() for chunk in chunks]
 
111
  uploaded_file = st.file_uploader("Choose a Picture...", type=["jpg", "jpeg", "png"])
112
  if uploaded_file is not None:
113
  try:
114
+ load_models() # Ensure models are loaded once
115
+ image_bytes = uploaded_file.getvalue()
116
+ # Display image
117
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
118
  st.image(image, caption="Your Amazing Picture!", use_column_width=True)
119
  st.markdown("<h3 style='text-align: center;'>Ready for your story?</h3>", unsafe_allow_html=True)
 
120
  if st.button("Story, Please!"):
121
+ with st.spinner("Generating caption..."):
122
+ caption = get_caption(image_bytes)
 
123
  st.markdown("<h3 style='text-align: center;'>Caption:</h3>", unsafe_allow_html=True)
124
  st.write(caption)
125
 
126
+ with st.spinner("Generating story..."):
127
+ story = get_story(caption)
128
  st.markdown("<h3 style='text-align: center;'>Your Story:</h3>", unsafe_allow_html=True)
129
  st.write(story)
130
 
131
+ with st.spinner("Generating audio..."):
132
+ audio_buffer = get_audio(story)
133
  st.audio(audio_buffer, format="audio/wav", start_time=0)
134
  st.markdown(
135
  "<p style='text-align: center; font-weight: bold;'>Enjoy your magical story! 🎶</p>",
136
  unsafe_allow_html=True
137
  )
 
138
  except Exception as e:
139
  st.error("Oops! Something went wrong. Please try a different picture or check the file format!")
140
  st.error(f"Error details: {e}")